79e326e6b90e5c3c7ae5d09c835ef94d9ec8fd63
[lxde/lxappearance.git] / src / main-dlg.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <gtk/gtk.h>
6 #include <gdk/gdkx.h>
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11
12 #include "main-dlg.h"
13 #include "main-dlg-ui.h"
14 #include "glade-support.h"
15
16 /* for kill & waitpid */
17 #include <sys/types.h>
18 #include <signal.h>
19 #include <sys/wait.h>
20
21 #define GET_WIDGET( name ) name = lookup_widget( dlg, #name )
22 #define INIT_LIST(name, prop) \
23 GET_WIDGET( name##_view ); \
24 name##_list = init_tree_view( name##_view, G_CALLBACK(on_list_sel_changed), prop ); \
25 load_##name##s( name##_list );
26
27 static GtkTreeView* gtk_theme_view = NULL;
28 static GtkListStore* gtk_theme_list = NULL;
29
30 static GtkTreeView* icon_theme_view = NULL;
31 static GtkListStore* icon_theme_list = NULL;
32
33 static char* gtk_theme_name = NULL;
34 static char* icon_theme_name = NULL;
35 static char* font_name = NULL;
36
37 static char tmp_rc_file[] = "/tmp/gtkrc-2.0-XXXXXX";
38 static char* rc_file = NULL;
39
40 /*
41 static GtkTreeView* font_view = NULL;
42 static GtkListStore* font_list = NULL;
43 */
44 static GtkWidget* demo_box = NULL;
45 static GtkWidget* demo_socket = NULL;
46 static GPid demo_pid = 0;
47
48 static void load_demo_process()
49 {
50 char* argv[5];
51 char wid[16];
52
53 if( demo_pid > 0 ) /* kill old demo */
54 {
55 int stat;
56 // if( demo_socket )
57 // gtk_widget_destroy( demo_socket );
58 kill( demo_pid, SIGTERM );
59 waitpid( demo_pid, &stat, 0 );
60 demo_pid = 0;
61 }
62
63 if( !demo_socket )
64 {
65 demo_socket = gtk_socket_new();
66 g_signal_connect( demo_socket, "plug-removed", G_CALLBACK(gtk_true), NULL );
67 gtk_widget_show( demo_socket );
68 gtk_container_add( (GtkContainer*)demo_box, demo_socket );
69 }
70
71 g_snprintf( wid, 16, "%ld", gtk_socket_get_id(demo_socket) );
72
73 argv[0] = g_get_prgname();
74 argv[1] = "demo";
75 argv[2] = wid;
76 argv[3] = tmp_rc_file;
77 argv[4] = NULL;
78 g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &demo_pid, NULL );
79 }
80
81 static void write_rc_file( const char* path )
82 {
83 FILE* f;
84 if( f = fopen( path, "w" ) )
85 {
86 fputs( "# DO NOT EDIT! This file will be overwritten by LXAppearance.\n"
87 "# Any customization should be done in ~/.gtkrc-2.0.mine\n\n", f );
88
89 fprintf( f, "gtk-theme-name=\"%s\"\n", gtk_theme_name );
90 fprintf( f, "gtk-icon-theme-name=\"%s\"\n", icon_theme_name );
91 fprintf( f, "gtk-font-name=\"%s\"\n", font_name );
92 fprintf( f, "include \"%s/.gtkrc-2.0.mine\"\n", g_get_home_dir() );
93
94 fclose( f );
95 }
96 }
97
98 static void reload_theme()
99 {
100
101 gtk_rc_reparse_all();
102 }
103
104 static void on_list_sel_changed( GtkTreeSelection* sel, const char* prop )
105 {
106 GtkTreeIter it;
107 GtkTreeModel* model;
108 if( gtk_tree_selection_get_selected( sel, &model, &it ) )
109 {
110 char* name;
111 gtk_tree_model_get( model, &it, 0, &name, -1 );
112
113 if( model == gtk_theme_list ) /* gtk+ theme */
114 {
115 if( name && gtk_theme_name && 0 == strcmp( name, gtk_theme_name ) )
116 goto out;
117 g_free( gtk_theme_name );
118 gtk_theme_name = name;
119 }
120 else if( model == icon_theme_list ) /* icon theme */
121 {
122 if( name && icon_theme_name && 0 == strcmp( name, icon_theme_name ) )
123 goto out;
124 g_free( icon_theme_name );
125 icon_theme_name = name;
126 }
127 write_rc_file( tmp_rc_file );
128 //gtk_rc_reparse_all_for_settings(gtk_settings_get_default(), TRUE);
129 load_demo_process();
130 return;
131 out:
132 g_free( name );
133 }
134 }
135
136 static GtkListStore* init_tree_view( GtkTreeView* view, GCallback on_sel_changed, const char* prop )
137 {
138 GtkTreeViewColumn* col;
139 GtkListStore* list;
140 GtkTreeSelection* sel;
141 col = gtk_tree_view_column_new_with_attributes( NULL, gtk_cell_renderer_text_new(), "text", 0, NULL );
142 gtk_tree_view_append_column( view, col );
143 sel = gtk_tree_view_get_selection(view);
144 g_signal_connect( sel, "changed", on_sel_changed, prop );
145
146 list = gtk_list_store_new( 1, G_TYPE_STRING );
147 gtk_tree_view_set_model( view, (GtkTreeModel*)list );
148 g_object_unref( list );
149 return list;
150 }
151
152 static void load_themes_from_dir( GtkListStore* list,
153 const char* dir_path,
154 const char* lookup,
155 GtkTreeSelection* sel,
156 const char* init_sel )
157 {
158 GDir* dir;
159 if( dir = g_dir_open( dir_path, 0, NULL ) )
160 {
161 char* name;
162 while( name = g_dir_read_name( dir ) )
163 {
164 char* file = g_build_filename( dir_path, name, lookup, NULL );
165 if( g_file_test( file, G_FILE_TEST_EXISTS ) )
166 {
167 GtkTreeIter it;
168 gtk_list_store_append( list, &it );
169 gtk_list_store_set( list, &it, 0, name, -1 );
170 if( 0 == strcmp( name, init_sel ) )
171 {
172 GtkTreeView* view;
173 GtkTreePath* tp;
174 gtk_tree_selection_select_iter( sel, &it );
175 view = gtk_tree_selection_get_tree_view( sel );
176 tp = gtk_tree_model_get_path( (GtkTreeModel*)list, &it );
177 gtk_tree_view_scroll_to_cell( view, tp, NULL, FALSE, 0, 0 );
178 gtk_tree_path_free( tp );
179 }
180 }
181 g_free( file );
182 }
183 g_dir_close( dir );
184 }
185 }
186
187 static void load_from_data_dirs( GtkListStore* list,
188 const char* relative_path,
189 const char* lookup,
190 GtkTreeSelection* sel,
191 const char* init_sel )
192 {
193 const char* const *dirs = g_get_system_data_dirs();
194 const char* const *dir;
195 char* dir_path;
196 for( dir = dirs; *dir; ++dir )
197 {
198 dir_path = g_build_filename( *dir, relative_path, NULL );
199 load_themes_from_dir( list, dir_path, lookup, sel, init_sel );
200 g_free( dir_path );
201 }
202 dir_path = g_build_filename( g_get_user_data_dir(), relative_path, NULL );
203 load_themes_from_dir( list, dir_path, lookup, sel, init_sel );
204 g_free( dir_path );
205 }
206
207 static void load_gtk_themes( GtkListStore* list )
208 {
209 GtkTreeSelection* sel = gtk_tree_view_get_selection( gtk_theme_view );
210 load_from_data_dirs( list, "themes", "gtk-2.0", sel, gtk_theme_name );
211 }
212
213 static void load_icon_themes( GtkListStore* list )
214 {
215 char* path;
216 GtkTreeSelection* sel = gtk_tree_view_get_selection( icon_theme_view );
217 load_from_data_dirs( list, "icons", "index.theme", sel, icon_theme_name );
218 path = g_build_filename( g_get_home_dir(), ".icons", NULL );
219 load_themes_from_dir( list, path, "index.theme", sel, icon_theme_name );
220 g_free( path );
221 }
222
223 /*
224 static void load_fonts( GtkListStore* list )
225 {
226
227 }
228 */
229
230 void main_dlg_init( GtkWidget* dlg )
231 {
232 char* files[] = { tmp_rc_file, NULL };
233 char** def_files = gtk_rc_get_default_files();
234 char** file;
235
236 for( file = def_files; *file; ++file )
237 {
238 if( 0 == access( *file, W_OK ) )
239 rc_file = *file;
240 }
241 if( rc_file )
242 rc_file = g_strdup( rc_file );
243 else
244 rc_file = g_build_filename( g_get_home_dir(), ".gtkrc-2.0", NULL );
245 mkstemp( tmp_rc_file );
246
247 g_object_get( gtk_settings_get_default(), "gtk-theme-name", &gtk_theme_name, NULL );
248 if( ! gtk_theme_name )
249 gtk_theme_name = g_strdup( "Raleigh" );
250 g_object_get( gtk_settings_get_default(), "gtk-icon-theme-name", &icon_theme_name, NULL );
251 if( ! icon_theme_name )
252 gtk_theme_name = g_strdup( "hicolor" );
253 g_object_get( gtk_settings_get_default(), "gtk-font-name", &font_name, NULL );
254 if( ! font_name )
255 font_name = g_strdup( "Sans 10" );
256
257 write_rc_file( tmp_rc_file );
258
259 INIT_LIST( gtk_theme, "gtk-theme-name" )
260 INIT_LIST( icon_theme, "gtk-icon-theme-name" )
261 gtk_font_button_set_font_name( (GtkFontButton*)lookup_widget(dlg, "font"), font_name );
262
263 /* INIT_LIST( font, "gtk-font-name" ) */
264
265 GET_WIDGET( demo_box );
266
267 gtk_widget_show( demo_box );
268 // gtk_widget_set_app_paintable( demo_socket, TRUE );
269 gtk_widget_realize( dlg );
270 load_demo_process();
271 }
272
273 static void reload_all_programs( gboolean icon_only )
274 {
275 GdkEventClient event;
276 event.type = GDK_CLIENT_EVENT;
277 event.send_event = TRUE;
278 event.window = NULL;
279
280 if( icon_only )
281 event.message_type = gdk_atom_intern("_GTK_LOAD_ICONTHEMES", FALSE);
282 else
283 event.message_type = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
284
285 event.data_format = 8;
286 gdk_event_send_clientmessage_toall((GdkEvent *)&event);
287 }
288
289 void
290 on_apply_clicked (GtkButton *button,
291 gpointer user_data)
292 {
293 write_rc_file( rc_file );
294 reload_all_programs( FALSE );
295 }
296
297
298 void
299 on_font_changed (GtkFontButton *fontbutton,
300 gpointer user_data)
301 {
302 const char* name = gtk_font_button_get_font_name(fontbutton);
303 if( name && font_name && 0 == strcmp( font_name ) )
304 return;
305 g_free( font_name );
306 font_name = g_strdup( name );
307 write_rc_file( tmp_rc_file );
308 load_demo_process();
309 }
310