/* $Id: config.c 22459 2006-07-16 08:17:54Z benny $ */ /*- * Copyright (c) 2003-2006 Benedikt Meurer * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_MEMORY_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef XFCE_DISABLE_DEPRECATED #undef XFCE_DISABLE_DEPRECATED #endif #include #include #include #include #include #define BORDER 6 enum { TARGET_RAW_DATA, TARGET_XDS, TARGET_URI, TARGET_STRING, }; enum { PREVIEW_COLUMN, TITLE_COLUMN, NAME_COLUMN, N_COLUMNS, }; static GtkTargetEntry dst_targets[] = { { "text/uri-list", 0, TARGET_URI }, { "STRING", 0, TARGET_STRING }, }; static gsize dst_ntargets = sizeof (dst_targets) / sizeof (*dst_targets); static GtkTargetEntry src_targets[] = { { "XdndDirectSave0", 0, TARGET_XDS }, }; static gsize src_ntargets = sizeof (src_targets) / sizeof (*src_targets); static gboolean config_load_theme_for_iter (GtkListStore *store, GtkTreeIter *iter, const gchar *name) { BalouTheme *theme; GdkPixbuf *preview; gchar title[128]; theme = balou_theme_load (name); if (G_UNLIKELY (theme == NULL)) return FALSE; g_snprintf (title, 128, "%s\n%s", balou_theme_get_name (theme), balou_theme_get_description (theme)); preview = balou_theme_generate_preview (theme, 52, 43); gtk_list_store_set (store, iter, PREVIEW_COLUMN, preview, TITLE_COLUMN, title, NAME_COLUMN, name, -1); balou_theme_destroy (theme); g_object_unref (preview); return TRUE; } static GtkTreeModel* config_load_themelist (void) { GtkListStore *store; GtkTreeIter iter; gchar **themes; gchar *name; gchar *endp; guint n; store = gtk_list_store_new (N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); themes = xfce_resource_match (XFCE_RESOURCE_THEMES, "*/balou/themerc", TRUE); if (G_LIKELY (themes != NULL)) { for (n = 0; themes[n] != NULL; ++n) { name = themes[n]; endp = strchr (name, '/'); if (G_UNLIKELY (endp == NULL)) continue; else *endp = '\0'; gtk_list_store_append (store, &iter); if (!config_load_theme_for_iter (store, &iter, name)) gtk_list_store_remove (store, &iter); } g_strfreev (themes); } return GTK_TREE_MODEL (store); } static gboolean config_find_theme (const gchar *theme_name, GtkTreeView *treeview, GtkTreeIter *iter) { GtkTreeModel *model; gboolean match; gchar *name; model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); if (gtk_tree_model_get_iter_first (model, iter)) { do { gtk_tree_model_get (model, iter, NAME_COLUMN, &name, -1); match = (strcmp (name, theme_name) == 0); g_free (name); if (match) return TRUE; } while (gtk_tree_model_iter_next (model, iter)); } return FALSE; } static void config_select_theme (const gchar *selected_theme, GtkTreeView *treeview) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; selection = gtk_tree_view_get_selection (treeview); model = gtk_tree_view_get_model (treeview); if (config_find_theme (selected_theme, treeview, &iter)) gtk_tree_selection_select_iter (selection, &iter); else if (gtk_tree_model_get_iter_first (model, &iter)) gtk_tree_selection_select_iter (selection, &iter); } static gboolean config_reload_theme (const gchar *name, GtkTreeView *treeview) { GtkListStore *store; GtkTreeIter iter; store = GTK_LIST_STORE (gtk_tree_view_get_model (treeview)); if (!config_find_theme (name, treeview, &iter)) gtk_list_store_append (store, &iter); if (!config_load_theme_for_iter (store, &iter, name)) { gtk_list_store_remove (store, &iter); return FALSE; } config_select_theme (name, treeview); return TRUE; } static gboolean config_do_install_theme (const gchar *path, GtkTreeView *treeview) { gchar *standard_output; gchar *standard_error; gint exit_status; gboolean result; gchar *target; gchar *argv[4]; g_return_val_if_fail (path != NULL, FALSE); target = xfce_resource_save_location (XFCE_RESOURCE_THEMES, NULL, TRUE); if (G_UNLIKELY (target == NULL)) { g_warning ("Unable to determine save location for themes."); return FALSE; } argv[0] = BALOU_INSTALL_THEME; argv[1] = (gchar *) path; argv[2] = target; argv[3] = NULL; result = g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &standard_output, &standard_error, &exit_status, NULL); g_free (target); if (G_UNLIKELY (!result)) { g_warning ("Unable to execute %s", BALOU_INSTALL_THEME); return FALSE; } g_strstrip (standard_output); g_strstrip (standard_error); if (G_UNLIKELY (exit_status != 0)) { g_warning ("%s failed: %s", BALOU_INSTALL_THEME, standard_error); g_free (standard_output); g_free (standard_error); return FALSE; } result = config_reload_theme (standard_output, treeview); g_free (standard_output); g_free (standard_error); return result; } static void config_dropped (GtkWidget *treeview, GdkDragContext *context, gint x, gint y, GtkSelectionData *data, guint info, guint time, gpointer user_data) { gboolean succeed = FALSE; GList *fnames; fnames = gnome_uri_list_extract_filenames ((const gchar *) data->data); if (fnames != NULL) { if (g_list_length (fnames) == 1) { succeed = TRUE; if (!config_do_install_theme ((const gchar *) fnames->data, GTK_TREE_VIEW (treeview))) succeed = FALSE; } gnome_uri_list_free_strings (fnames); } gtk_drag_finish (context, succeed, FALSE, time); } static void config_install_theme (GtkWidget *item, GtkWidget *menu) { GtkTreeView *treeview; GtkWidget *toplevel; GtkWidget *chooser; gchar *file; treeview = GTK_TREE_VIEW (g_object_get_data (G_OBJECT (menu), "tree-view")); toplevel = gtk_widget_get_toplevel (GTK_WIDGET (treeview)); chooser = xfce_file_chooser_new (_("Choose theme file to install..."), GTK_WINDOW (toplevel), XFCE_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_OK) { file = xfce_file_chooser_get_filename (XFCE_FILE_CHOOSER (chooser)); if (!config_do_install_theme (file, treeview)) { xfce_err (_("Unable to install splash theme from file %s, " "please check that the file is a valid splash " "theme archive."), file); } g_free (file); } gtk_widget_destroy (chooser); } #ifdef RM_CMD static void config_remove_theme (GtkWidget *item, GtkWidget *menu) { GtkTreeModel *model; GtkTreeView *treeview; GtkTreeIter *iter; gboolean result; gchar *directory; gchar *resource; gchar *name; gchar* argv[4]; gint status; iter = (GtkTreeIter *) g_object_get_data (G_OBJECT (menu), "iter"); if (G_UNLIKELY (iter == NULL)) return; treeview = GTK_TREE_VIEW (g_object_get_data (G_OBJECT (menu), "tree-view")); model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); gtk_tree_model_get (model, iter, NAME_COLUMN, &name, -1); if (G_UNLIKELY (name == NULL)) return; resource = g_strconcat (name, "/balou/", NULL); directory = xfce_resource_lookup (XFCE_RESOURCE_THEMES, resource); g_free (resource); argv[0] = RM_CMD; argv[1] = "-rf"; argv[2] = directory; argv[3] = NULL; result = g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, NULL, NULL, &status, NULL); if (!result || status != 0) { xfce_err (_("Unable to remove splash theme \"%s\" from directory " "%s."), name, directory); } else { gtk_list_store_remove (GTK_LIST_STORE (model), iter); } g_free (directory); g_free (name); } #endif static gboolean config_do_export_theme (const gchar *name, const gchar *file) { gboolean result; gchar *standard_error; gchar *resource; gchar *themerc; gchar *argv[4]; gint status; resource = g_strconcat (name, "/balou/themerc", NULL); themerc = xfce_resource_lookup (XFCE_RESOURCE_THEMES, resource); g_free (resource); argv[0] = BALOU_EXPORT_THEME; argv[1] = themerc; argv[2] = (gchar *) file; argv[3] = NULL; result = g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, NULL, &standard_error, &status, NULL); g_free (themerc); if (result) { g_strstrip (standard_error); if (status != 0) { g_warning ("%s failed: %s", BALOU_EXPORT_THEME, standard_error); result = FALSE; } g_free (standard_error); } else { g_warning ("Unable to execute %s", BALOU_EXPORT_THEME); } return result; } static void config_export_theme (GtkWidget *item, GtkWidget *menu) { GtkTreeModel *model; GtkTreeView *treeview; GtkTreeIter *iter; GtkWidget *toplevel; GtkWidget *dialog; gchar *file; gchar *name; iter = (GtkTreeIter *) g_object_get_data (G_OBJECT (menu), "iter"); if (G_UNLIKELY (iter == NULL)) return; treeview = GTK_TREE_VIEW (g_object_get_data (G_OBJECT (menu), "tree-view")); model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); gtk_tree_model_get (model, iter, NAME_COLUMN, &name, -1); if (G_UNLIKELY (name == NULL)) return; toplevel = gtk_widget_get_toplevel (GTK_WIDGET (treeview)); dialog = xfce_file_chooser_new (_("Choose theme filename..."), GTK_WINDOW (toplevel), XFCE_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); file = g_strconcat (name, ".tar.gz", NULL); xfce_file_chooser_set_current_name (XFCE_FILE_CHOOSER (dialog), file); g_free (file); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { file = xfce_file_chooser_get_filename (XFCE_FILE_CHOOSER (dialog)); config_do_export_theme (name, file); g_free (file); } gtk_widget_destroy (dialog); g_free (name); } static void config_popup_menu (GtkWidget *treeview, GdkEventButton *event, GtkTreeModel *model, GtkTreeIter *iter) { GtkWidget *menu; GtkWidget *item; gboolean writable; gchar *directory; gchar *resource; gchar *name; guint button; guint time; menu = (GtkWidget *) g_object_get_data (G_OBJECT (treeview), "popup-menu"); if (GTK_IS_WIDGET (menu)) { if (event != NULL) { button = event->button; time = event->time; } else { button = 0; time = gtk_get_current_event_time (); } #ifdef RM_CMD if (iter != NULL) { gtk_tree_model_get (model, iter, NAME_COLUMN, &name, -1); resource = g_strconcat (name, "/", NULL); directory = xfce_resource_lookup (XFCE_RESOURCE_THEMES, resource); g_free (resource); writable = (access (directory, W_OK) == 0); g_free (directory); g_free (name); } else #endif { writable = FALSE; } item = GTK_WIDGET (g_object_get_data (G_OBJECT (menu), "remove-theme")); gtk_widget_set_sensitive (item, writable); g_object_set_data_full (G_OBJECT (menu), "iter", g_memdup (iter, sizeof (*iter)), (GDestroyNotify) g_free); g_object_set_data (G_OBJECT (menu), "tree-view", treeview); gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, button, time); } } static gboolean config_button_press_handler (GtkWidget *treeview, GdkEventButton *event) { GtkTreeModel *model; GtkTreePath *path; GtkTreeIter iter; if (event->button != 3 || event->type != GDK_BUTTON_PRESS) return FALSE; if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (treeview), event->x, event->y, &path, NULL, NULL, NULL)) return FALSE; model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); if (!gtk_tree_model_get_iter (model, &iter, path)) return FALSE; config_popup_menu (treeview, event, model, &iter); return TRUE; } static gboolean config_popup_menu_handler (GtkWidget *treeview) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return FALSE; config_popup_menu (treeview, NULL, model, &iter); return TRUE; } static GtkWidget* config_create_popupmenu (void) { GtkWidget *menu; GtkWidget *item; GtkWidget *image; menu = gtk_menu_new (); item = gtk_image_menu_item_new_with_mnemonic (_("_Install new theme")); image = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); g_object_set_data (G_OBJECT (menu), "install-theme", item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (config_install_theme), menu); gtk_widget_show (item); item = gtk_image_menu_item_new_with_mnemonic (_("_Remove theme")); image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); g_object_set_data (G_OBJECT (menu), "remove-theme", item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); #ifdef RM_CMD g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (config_remove_theme), menu); #else gtk_widget_set_sensitive (item, FALSE); #endif gtk_widget_show (item); item = gtk_separator_menu_item_new (); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); item = gtk_image_menu_item_new_with_mnemonic (_("_Export theme")); image = gtk_image_new_from_stock (GTK_STOCK_SAVE, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); g_object_set_data (G_OBJECT (menu), "export-theme", item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (config_export_theme), menu); gtk_widget_show (item); return menu; } static gchar* extract_local_path (gchar *uri) { gchar *our_host_name; if (*uri == '/') { gchar *path; if (uri[1] != '/') return uri; /* Just a local path - no host part */ path = strchr(uri + 2, '/'); if (!path) return NULL; /* //something */ if (path - uri == 2) return path; /* ///path */ our_host_name = xfce_gethostname (); if (strlen(our_host_name) == path - uri - 2 && strncmp(uri + 2, our_host_name, path - uri - 2) == 0) { g_free (our_host_name); return path; /* //myhost/path */ } g_free (our_host_name); return NULL; /* From a different host */ } else { if (strncasecmp(uri, "file:", 5)) return NULL; /* Don't know this format */ uri += 5; if (*uri == '/') return extract_local_path (uri); return NULL; } } static void config_drag_begin (GtkWidget *treeview, GdkDragContext *context) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; gchar *filename; gchar *name; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; gtk_tree_model_get (model, &iter, NAME_COLUMN, &name, -1); filename = g_strconcat (name, ".tar.gz", NULL); gdk_property_change (context->source_window, gdk_atom_intern ("XdndDirectSave0", FALSE), gdk_atom_intern ("text/plain", FALSE), 8, GDK_PROP_MODE_REPLACE, (const guchar *)filename, strlen (filename)); g_free (filename); g_free (name); } static void config_drag_data_get (GtkWidget *treeview, GdkDragContext *context, GtkSelectionData *selection_data, guint info, guint32 time) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; gchar *name; guchar *prop_text; gint prop_len; gchar *to_send = "E"; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; gtk_tree_model_get (model, &iter, NAME_COLUMN, &name, -1); switch (info) { case TARGET_XDS: if (gdk_property_get (context->source_window, gdk_atom_intern ("XdndDirectSave0", FALSE), gdk_atom_intern ("text/plain", FALSE), 0, 1024, FALSE, NULL, NULL, &prop_len, &prop_text) && prop_text != NULL) { gchar *localpath; /* Zero-Terminate the string */ prop_text = g_realloc (prop_text, prop_len + 1); prop_text[prop_len] = '\0'; localpath = extract_local_path ((gchar *)prop_text); if (localpath != NULL) { if (config_do_export_theme (name, localpath)) to_send = "S"; } else to_send = "F"; g_dataset_set_data (context, "XDS-sent", to_send); g_free (prop_text); } break; } gtk_selection_data_set (selection_data, gdk_atom_intern ("XA_STRING", FALSE), 8, (const guchar *)to_send, 1); g_free (name); } static void config_drag_end (GtkWidget *treeview, GdkDragContext *context) { /* nothing to do here */ } static void config_store (GtkTreeView *treeview, XfsmSplashRc *rc) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; gchar *name; selection = gtk_tree_view_get_selection (treeview); if (gtk_tree_selection_get_selected (selection, &model, &iter)) { gtk_tree_model_get (model, &iter, NAME_COLUMN, &name, -1); if (name != NULL) { xfsm_splash_rc_write_entry (rc, "Theme", name); g_free (name); } } } static gboolean config_selection_changed (GtkTreeSelection *selection, gpointer user_data) { GtkTreeModel *model; GtkTreeIter iter; GtkTreeView *treeview; GdkPixbuf *icon; if (gtk_tree_selection_get_selected (selection, &model, &iter)) { treeview = gtk_tree_selection_get_tree_view (selection); gtk_tree_model_get (model, &iter, PREVIEW_COLUMN, &icon, -1); gtk_drag_source_set_icon_pixbuf (GTK_WIDGET (treeview), icon); g_object_unref (icon); } return FALSE; } GtkWidget* config_create (XfsmSplashRc *rc) { GtkTreeSelection *selection; GtkTreeViewColumn *column; GtkCellRenderer *renderer; GtkTreeModel *model; GtkWidget *treeview; GtkWidget *frame; GtkWidget *popup; GtkWidget *page; GtkWidget *swin; GtkWidget *vbox; const gchar *theme; theme = xfsm_splash_rc_read_entry (rc, "Theme", "Default"); page = gtk_vbox_new (FALSE, BORDER); gtk_container_set_border_width (GTK_CONTAINER (page), BORDER); frame = xfce_framebox_new (_("Balou theme"), TRUE); gtk_box_pack_start (GTK_BOX (page), frame, TRUE, TRUE, 0); vbox = gtk_vbox_new (FALSE, 0); xfce_framebox_add (XFCE_FRAMEBOX (frame), vbox); swin = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), GTK_SHADOW_ETCHED_IN); gtk_box_pack_start (GTK_BOX (vbox), swin, TRUE, TRUE, 0); gtk_widget_show (swin); model = config_load_themelist (); treeview = gtk_tree_view_new_with_model (model); gtk_widget_set_size_request (treeview, -1, 100); g_object_unref (G_OBJECT (model)); config_select_theme (theme, GTK_TREE_VIEW (treeview)); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection), GTK_SELECTION_SINGLE); g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (config_selection_changed), NULL); g_idle_add ((GSourceFunc)config_selection_changed, selection); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); gtk_container_add (GTK_CONTAINER (swin), treeview); /* add tree view columns */ column = gtk_tree_view_column_new (); renderer = gtk_cell_renderer_pixbuf_new (); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_set_attributes (column, renderer, "pixbuf", PREVIEW_COLUMN, NULL); renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_column_set_attributes (column, renderer, "markup", TITLE_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); /* Drag&Drop support (destination) */ gtk_drag_dest_set (treeview, GTK_DEST_DEFAULT_ALL, dst_targets, dst_ntargets, GDK_ACTION_COPY); g_signal_connect (G_OBJECT (treeview), "drag_data_received", G_CALLBACK (config_dropped), NULL); /* Drag&Drop support (source) */ gtk_drag_source_set (treeview, GDK_BUTTON1_MASK, src_targets, src_ntargets, GDK_ACTION_COPY | GDK_ACTION_PRIVATE); g_signal_connect (G_OBJECT (treeview), "drag_begin", G_CALLBACK (config_drag_begin), NULL); g_signal_connect (G_OBJECT (treeview), "drag_data_get", G_CALLBACK (config_drag_data_get), NULL); g_signal_connect (G_OBJECT (treeview), "drag_end", G_CALLBACK (config_drag_end), NULL); /* popup menu */ popup = config_create_popupmenu (); g_object_set_data (G_OBJECT (treeview), "popup-menu", popup); g_signal_connect (G_OBJECT (treeview), "popup-menu", G_CALLBACK (config_popup_menu_handler), NULL); g_signal_connect (G_OBJECT (treeview), "button-press-event", G_CALLBACK (config_button_press_handler), NULL); g_signal_connect_swapped (G_OBJECT (treeview), "destroy", G_CALLBACK (gtk_widget_destroy), popup); g_signal_connect (G_OBJECT (treeview), "destroy", G_CALLBACK (config_store), rc); return page; } static void config_configure (XfsmSplashConfig *config, GtkWidget *parent) { GtkWidget *dialog; GtkWidget *ui; dialog = gtk_dialog_new_with_buttons (_("Configure Balou..."), GTK_WINDOW (parent), GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); ui = config_create (config->rc); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), ui, TRUE, TRUE, 6); gtk_widget_show_all (ui); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); } static GdkPixbuf* config_preview (XfsmSplashConfig *config) { const gchar *name; BalouTheme *theme; GdkPixbuf *pixbuf = NULL; name = xfsm_splash_rc_read_entry (config->rc, "Theme", NULL); if (G_UNLIKELY (name == NULL)) return NULL; theme = balou_theme_load (name); pixbuf = balou_theme_generate_preview (theme, 320, 240); balou_theme_destroy (theme); return pixbuf; } G_MODULE_EXPORT void config_init (XfsmSplashConfig *config) { config->name = g_strdup (_("Balou")); config->description = g_strdup (_("Balou Splash Engine")); config->version = g_strdup (VERSION); config->author = g_strdup ("Benedikt Meurer"); config->homepage = g_strdup ("http://www.xfce.org/"); config->configure = config_configure; config->preview = config_preview; }