1 /*
2 * Based on code from gtk-theme-switch2.
3 * Copyright Maher Awamy <muhri@muhri.net>
4 * Aaron Lehman <aaronl@vitelus.com>
5 */
6
7 #include <stdlib.h>
8 #include <dirent.h>
9 #include <unistd.h>
10 #include <string.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <errno.h>
14
15 #include <glib.h>
16 #include <gtk/gtk.h>
17
18 #include "themes.h"
19
20 GtkSettings *settings;
21
22 /* Sets rc_file to the rc_file of the theme if the result is true.
23 * It is the caller's repsonsibility to free rc_file */
24 static gboolean
is_themedir(gchar * path)25 is_themedir (gchar *path)
26 {
27 gboolean is_gtk_theme = FALSE;
28 gchar *test_rc_file;
29 struct stat info;
30
31 test_rc_file = g_strdup_printf ("%s/gtk-2.0/gtkrc",path);
32 if (stat(test_rc_file, &info) == 0 && (S_ISREG(info.st_mode) || S_ISLNK(info.st_mode)))
33 is_gtk_theme = TRUE;
34
35 g_free (test_rc_file);
36
37 return is_gtk_theme;
38 }
39
40 GList*
get_themes(void)41 get_themes (void)
42 {
43 gchar *homedir;
44 gchar *dirname;
45 DIR *dir;
46 struct dirent *dent;
47 struct stat stats;
48 gchar *origdir=g_get_current_dir(); /* back up cwd */
49 GList *list=0;
50 gchar *full_path;
51
52 homedir = (gchar*)getenv ("HOME");
53 settings = gtk_settings_get_default ();
54
55 dirname = g_strconcat(homedir,"/.themes",NULL);
56 chdir (dirname);
57 dir = opendir (dirname);
58 if (dir)
59 {
60 while ((dent = readdir (dir)))
61 {
62 stat(dent->d_name,&stats);
63 if (!S_ISDIR(stats.st_mode)) continue;
64 if (strcmp(dent->d_name,"." ) == 0) continue;
65 if (strcmp(dent->d_name,"..") == 0) continue;
66
67 full_path = g_strconcat (homedir, "/.themes/", dent->d_name, NULL);
68 if (!is_themedir (full_path))
69 {
70 g_free (full_path);
71 continue;
72 }
73 list = g_list_insert_sorted(list, dent->d_name, (GCompareFunc)strcmp);
74 }
75 }
76
77 g_free (dirname);
78
79 dirname = (gchar*)gtk_rc_get_theme_dir();
80 chdir (dirname);
81 dir = opendir (dirname);
82 if (dir)
83 {
84 while ((dent = readdir (dir)))
85 {
86 stat(dent->d_name,&stats);
87 if (!S_ISDIR(stats.st_mode)) continue;
88 if (strcmp(dent->d_name, "." ) == 0) continue;
89 if (strcmp(dent->d_name, "..") == 0) continue;
90
91 full_path = g_strconcat (dirname, "/", dent->d_name, NULL);
92 if (!is_themedir (full_path))
93 {
94 g_free (full_path);
95 continue;
96 }
97 list = g_list_insert_sorted(list, dent->d_name, (GCompareFunc)strcmp);
98 }
99 }
100
101 chdir (origdir); /* Go back to where we were */
102 g_free (dirname);
103 g_free (origdir);
104
105 return list;
106 }
107
108 static void
select_theme(gpointer data,gpointer userdata)109 select_theme (gpointer data, gpointer userdata)
110 {
111 GList *children = gtk_container_get_children (GTK_CONTAINER (data));
112 GtkWidget *label = g_list_first (children)->data;
113 const gchar *theme = gtk_label_get_label (GTK_LABEL (label));
114
115 gtk_settings_set_string_property (settings, "gtk-theme-name", theme, "gtkrc:0");
116 }
117
118 static void
add_theme(gpointer data,gpointer user_data)119 add_theme (gpointer data, gpointer user_data)
120 {
121 GtkWidget *menu = (GtkWidget*)user_data;
122 GtkWidget *item = gtk_menu_item_new_with_label ((gchar*)data);
123
124 gtk_menu_append (menu, item);
125 g_signal_connect (G_OBJECT (item), "activate", (GCallback)select_theme, NULL);
126 }
127
128 void
create_themes_menu(GtkWidget * menuitem)129 create_themes_menu (GtkWidget *menuitem)
130 {
131 GtkWidget *menu = gtk_menu_new ();
132 GList *themes = get_themes ();
133
134 g_list_foreach (themes, add_theme, menu);
135
136 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
137 gtk_widget_show_all (menu);
138 }
139
140
141
142