1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 main.c for ObConf, the configuration tool for Openbox
4 Copyright (c) 2003-2008 Dana Jansens
5 Copyright (c) 2003 Tim Riley
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 See the COPYING file for a copy of the GNU General Public License.
23 #include "appearance.h"
29 #include "preview_update.h"
33 #define SN_API_NOT_YET_FROZEN
35 #undef SN_API_NOT_YET_FROZEN
38 GtkWidget *mainwin = NULL;
39 GtkWidget *tabstrip = NULL;
45 gchar *obc_config_file = NULL;
50 static gchar *obc_theme_install = NULL;
51 static gchar *obc_theme_archive = NULL;
53 void obconf_error(gchar *msg, gboolean modal)
57 d = gtk_message_dialog_new(mainwin ? GTK_WINDOW(mainwin) : NULL,
58 GTK_DIALOG_DESTROY_WITH_PARENT,
62 gtk_window_set_title(GTK_WINDOW(d), _("ObConf Error"));
64 gtk_dialog_run(GTK_DIALOG(d));
66 g_signal_connect_swapped(GTK_OBJECT(d), "response",
67 G_CALLBACK(gtk_widget_destroy),
73 static void print_version()
75 g_print("ObConf %s\n", PACKAGE_VERSION);
76 g_print(_("Copyright (c)"));
77 g_print(" 2003-2008 Dana Jansens\n");
78 g_print(_("Copyright (c)"));
79 g_print(" 2003 Tim Riley\n");
80 g_print(_("Copyright (c)"));
81 g_print(" 2007 Javeed Shaikh\n\n");
82 g_print("This program comes with ABSOLUTELY NO WARRANTY.\n");
83 g_print("This is free software, and you are welcome to redistribute it\n");
84 g_print("under certain conditions. See the file COPYING for details.\n\n");
89 static void print_help()
91 g_print(_("Syntax: obconf [options] [ARCHIVE.obt]\n"));
92 g_print(_("\nOptions:\n"));
93 g_print(_(" --help Display this help and exit\n"));
94 g_print(_(" --version Display the version and exit\n"));
95 g_print(_(" --install ARCHIVE.obt Install the given theme archive and select it\n"));
96 g_print(_(" --archive THEME Create a theme archive from the given theme directory\n"));
97 g_print(_(" --config-file FILE Specify the path to the config file to use\n"));
98 g_print(_(" --tab NUMBER Switch to tab number NUMBER on startup\n"));
99 g_print(_("\nPlease report bugs at %s\n\n"), PACKAGE_BUGREPORT);
104 static void parse_args(int argc, char **argv)
108 for (i = 1; i < argc; ++i) {
109 if (!strcmp(argv[i], "--help"))
111 if (!strcmp(argv[i], "--version"))
113 else if (!strcmp(argv[i], "--install")) {
114 if (i == argc - 1) /* no args left */
115 g_printerr(_("--install requires an argument\n"));
117 obc_theme_install = argv[++i];
119 else if (!strcmp(argv[i], "--archive")) {
120 if (i == argc - 1) /* no args left */
121 g_printerr(_("--archive requires an argument\n"));
123 obc_theme_archive = argv[++i];
125 else if (!strcmp(argv[i], "--config-file")) {
126 if (i == argc - 1) /* no args left */
127 g_printerr(_("--config-file requires an argument\n"));
129 obc_config_file = argv[++i];
131 else if (!strcmp(argv[i], "--tab")) {
132 if (i == argc - 1) /* no args left */
133 g_printerr(_("--tab requires an argument\n"));
135 obc_tab = MAX(atoi(argv[++i]) - 1, 0);
138 obc_theme_install = argv[i];
142 static gboolean get_all(Window win, Atom prop, Atom type, gint size,
143 guchar **data, guint *num)
145 gboolean ret = FALSE;
147 guchar *xdata = NULL;
150 gulong ret_items, bytes_left;
152 res = XGetWindowProperty(GDK_DISPLAY(), win, prop, 0l, G_MAXLONG,
153 FALSE, type, &ret_type, &ret_size,
154 &ret_items, &bytes_left, &xdata);
155 if (res == Success) {
156 if (ret_size == size && ret_items > 0) {
159 *data = g_malloc(ret_items * (size / 8));
160 for (i = 0; i < ret_items; ++i)
163 (*data)[i] = xdata[i];
166 ((guint16*)*data)[i] = ((gushort*)xdata)[i];
169 ((guint32*)*data)[i] = ((gulong*)xdata)[i];
172 g_assert_not_reached(); /* unhandled size */
182 static gboolean prop_get_string_utf8(Window win, Atom prop, gchar **ret)
188 if (get_all(win, prop,
189 gdk_x11_get_xatom_by_name("UTF8_STRING"),
190 8,(guchar**)&raw, &num))
192 str = g_strndup(raw, num); /* grab the first string from the list */
194 if (g_utf8_validate(str, -1, NULL)) {
203 int main(int argc, char **argv)
206 gboolean exit_with_error = FALSE;
208 bindtextdomain(PACKAGE_NAME, LOCALEDIR);
209 bind_textdomain_codeset(PACKAGE_NAME, "UTF-8");
210 textdomain(PACKAGE_NAME);
212 gtk_init(&argc, &argv);
213 parse_args(argc, argv);
215 if (obc_theme_archive) {
216 archive_create(obc_theme_archive);
220 p = g_build_filename(GLADEDIR, "obconf.glade", NULL);
221 glade = glade_xml_new(p, NULL, NULL);
225 obconf_error(_("Failed to load the obconf.glade interface file. You have probably failed to install ObConf properly."), TRUE);
226 exit_with_error = TRUE;
229 paths = obt_paths_new();
230 parse_i = obt_xml_instance_new();
231 rrinst = RrInstanceNew(GDK_DISPLAY(), gdk_x11_get_default_screen());
233 if (!obc_config_file) {
236 if (prop_get_string_utf8(GDK_ROOT_WINDOW(),
237 gdk_x11_get_xatom_by_name("_OB_CONFIG_FILE"),
240 obc_config_file = g_filename_from_utf8(p, -1, NULL, NULL, NULL);
245 xmlIndentTreeOutput = 1;
246 if (!((obc_config_file &&
247 obt_xml_load_file(parse_i, obc_config_file, "openbox_config")) ||
248 obt_xml_load_config_file(parse_i, "openbox", "rc.xml",
251 obconf_error(_("Failed to load an rc.xml. You have probably failed to install Openbox properly."), TRUE);
252 exit_with_error = TRUE;
255 doc = obt_xml_doc(parse_i);
256 root = obt_xml_root(parse_i);
259 /* look for parsing errors */
261 xmlErrorPtr e = xmlGetLastError();
263 char *a = g_strdup_printf
264 (_("Error while parsing the Openbox configuration file. Your configuration file is not valid XML.\n\nMessage: %s"),
266 obconf_error(a, TRUE);
268 exit_with_error = TRUE;
272 if (!exit_with_error) {
273 glade_xml_signal_autoconnect(glade);
276 gchar *s = g_strdup_printf
277 ("<span weight=\"bold\" size=\"xx-large\">ObConf %s</span>",
279 gtk_label_set_markup(GTK_LABEL
280 (glade_xml_get_widget(glade, "title_label")),
286 appearance_setup_tab();
288 moveresize_setup_tab();
290 desktops_setup_tab();
294 mainwin = get_widget("main_window");
295 tabstrip = glade_xml_get_widget(glade, "tabstrip");
297 if (obc_theme_install)
298 theme_install(obc_theme_install);
302 /* the main window is not shown here ! it is shown when the theme
303 previews are completed */
306 preview_update_set_active_font(NULL);
307 preview_update_set_inactive_font(NULL);
308 preview_update_set_menu_header_font(NULL);
309 preview_update_set_menu_item_font(NULL);
310 preview_update_set_osd_active_font(NULL);
311 preview_update_set_osd_inactive_font(NULL);
312 preview_update_set_title_layout(NULL);
315 RrInstanceFree(rrinst);
316 obt_xml_instance_unref(parse_i);
317 obt_paths_unref(paths);
323 gboolean on_main_window_delete_event(GtkWidget *w, GdkEvent *e, gpointer d)
329 void on_close_clicked()
334 void obconf_show_main()
337 SnLauncheeContext *sn_cx;
339 if (GTK_WIDGET_VISIBLE(mainwin)) return;
341 gtk_widget_show_all(mainwin);
343 /* Focus on the tab number specified by --tab. */
345 gtk_notebook_set_current_page(GTK_NOTEBOOK(tabstrip), obc_tab);
348 sn_d = sn_display_new(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
351 sn_cx = sn_launchee_context_new_from_environment
352 (sn_d, gdk_screen_get_number(gdk_display_get_default_screen
353 (gdk_display_get_default())));
356 sn_launchee_context_setup_window
357 (sn_cx, GDK_WINDOW_XWINDOW(GDK_WINDOW(mainwin->window)));
360 sn_launchee_context_complete(sn_cx);
363 sn_launchee_context_unref(sn_cx);
364 sn_display_unref(sn_d);