4
* Copyright 2009 PCMan <pcman.tw@gmail.com>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
28
#include <glib/gi18n.h>
40
COL_SESSION_DESKTOP_FILE,
50
#define VCONFIG_FILE "/var/lib/lxdm/lxdm.conf"
52
static GKeyFile *config;
53
static GKeyFile * var_config;
54
static GtkWidget* win;
55
static GtkWidget* prompt;
56
static GtkWidget* login_entry;
57
static GtkWidget* user_list;
59
static GtkWidget* sessions;
60
static GtkWidget* lang;
62
static GtkWidget* exit_btn;
64
static GtkWidget* exit_menu;
65
static GtkWidget *lang_menu;
67
static char* user = NULL;
68
static char* pass = NULL;
69
static char* session_exec = NULL;
70
static char* session_desktop_file = NULL;
72
static char* ui_file = NULL;
73
static char *ui_nobody = NULL;
75
static GdkPixbuf *bg_img = NULL;
76
static GdkColor bg_color = {0};
78
static GIOChannel *greeter_io;
80
static void do_reboot(void)
85
static void do_shutdown(void)
90
static void on_screen_size_changed(GdkScreen* scr, GtkWindow* win)
92
gtk_window_resize( win, gdk_screen_get_width(scr), gdk_screen_get_height(scr) );
95
static void on_entry_activate(GtkEntry* entry)
100
user = g_strdup( gtk_entry_get_text( GTK_ENTRY(entry) ) );
101
gtk_entry_set_text(GTK_ENTRY(entry), "");
102
gtk_label_set_text( GTK_LABEL(prompt), _("Password:") );
103
if(strchr(user, ' '))
109
gtk_entry_set_visibility(entry, FALSE);
114
char *session_lang = "";
116
if( gtk_combo_box_get_active_iter(GTK_COMBO_BOX(sessions), &it) )
118
GtkTreeModel* model = gtk_combo_box_get_model( GTK_COMBO_BOX(sessions) );
119
gtk_tree_model_get(model, &it, 1, &session_exec, 2, &session_desktop_file, -1);
123
/* FIXME: fatal error */
126
tmp = g_strdup( gtk_entry_get_text(entry) );
127
pass=g_base64_encode((guchar*)tmp,strlen(tmp)+1);
130
if( lang && gtk_combo_box_get_active_iter(GTK_COMBO_BOX(lang), &it) )
132
GtkTreeModel* model = gtk_combo_box_get_model( GTK_COMBO_BOX(lang) );
133
gtk_tree_model_get(model, &it, 1, &session_lang, -1);
134
//FIXME: is session leaked?
137
tmp = g_key_file_get_string(var_config, "base", "last_session", NULL);
138
if( g_strcmp0(tmp, session_desktop_file) )
140
g_key_file_set_string(var_config, "base", "last_session", session_desktop_file);
144
tmp = g_key_file_get_string(var_config, "base", "last_lang", NULL);
145
if( g_strcmp0(tmp, session_lang) )
147
g_key_file_set_string(var_config, "base", "last_lang", session_lang);
151
printf("login user=%s pass=%s session=%s lang=%s\n",
152
user, pass, session_exec, session_lang);
154
/* password check failed */
160
gtk_widget_hide(prompt);
161
gtk_widget_hide( GTK_WIDGET(entry) );
163
gtk_label_set_text( GTK_LABEL(prompt), _("User:") );
164
gtk_entry_set_text(GTK_ENTRY(entry), "");
165
gtk_entry_set_visibility(GTK_ENTRY(entry), TRUE);
169
static void load_sessions()
172
GtkTreeIter it, active_it = {0};
174
char *path, *file_name, *name, *exec;
176
GDir* dir = g_dir_open(XSESSIONS_DIR, 0, NULL);
180
last = g_key_file_get_string(var_config, "base", "last_session", NULL);
182
list = gtk_list_store_new(N_SESSION_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
183
kf = g_key_file_new();
184
while( ( file_name = (char*)g_dir_read_name(dir) ) != NULL )
186
path = g_build_filename(XSESSIONS_DIR, file_name, NULL);
187
if( g_key_file_load_from_file(kf, path, 0, NULL) )
189
name = g_key_file_get_locale_string(kf, "Desktop Entry", "Name", NULL, NULL);
190
if(!name || !name[0])
196
exec = g_key_file_get_string(kf, "Desktop Entry", "Exec", NULL);
197
if(!exec || !exec[0])
199
/* bad session config file */
205
g_free(exec); /* we just test it, and not use it */
208
if( !strcmp(name, "LXDE") )
209
gtk_list_store_prepend(list, &it);
211
gtk_list_store_append(list, &it);
212
gtk_list_store_set(list, &it,
213
COL_SESSION_NAME, name,
214
COL_SESSION_EXEC, exec,
215
COL_SESSION_DESKTOP_FILE, file_name, -1);
216
if( last && g_strcmp0(path, last) == 0 )
229
gtk_list_store_prepend(list, &it);
230
gtk_list_store_set(list, &it,
231
COL_SESSION_NAME, _("Default"),
232
COL_SESSION_EXEC, "",
233
COL_SESSION_DESKTOP_FILE, "__default__", -1);
234
if( last && g_strcmp0("__default__", last) == 0 )
238
gtk_combo_box_set_model( GTK_COMBO_BOX(sessions), GTK_TREE_MODEL(list) );
239
#if GTK_CHECK_VERSION(2,23,90)
240
gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(sessions), 0);
242
gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(sessions), 0);
244
if( active_it.stamp )
245
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(sessions), &active_it);
247
gtk_combo_box_set_active(GTK_COMBO_BOX(sessions), 0);
249
g_object_unref(list);
252
static void load_lang_cb(void *arg, char *lang, char *desc)
254
GtkListStore* list = (GtkListStore*)arg;
256
gchar *temp,*p,*lang2;
258
lang2=g_strdup(lang);
262
if(lang2[0] && lang2[0]!='~')
263
temp=g_strdup_printf("%s\t%s",lang2,desc?desc:"");
267
gtk_list_store_append(list, &it);
268
gtk_list_store_set(list, &it,
269
COL_LANG_DISPNAME, temp,
274
static gint lang_cmpr(GtkTreeModel *list,GtkTreeIter *a,GtkTreeIter *b,gpointer user_data)
278
gtk_tree_model_get(list,a,1,&as,-1);
279
gtk_tree_model_get(list,b,1,&bs,-1);
281
g_free(as);g_free(bs);
285
static void on_menu_lang_select(GtkMenuItem *item,gpointer user_data)
288
char *sel=(char*)user_data;
294
if(!sel || !sel[0]) return;
296
list=gtk_combo_box_get_model(GTK_COMBO_BOX(lang));
297
res=gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list),&iter);
298
for(i=0;res==TRUE;i++)
300
gtk_tree_model_get(GTK_TREE_MODEL(list),&iter,1,&temp,-1);
301
if(!strcmp(temp,sel))
308
res=gtk_tree_model_iter_next(GTK_TREE_MODEL(list),&iter);
312
gtk_combo_box_set_active(GTK_COMBO_BOX(lang),active);
315
gtk_list_store_append((GtkListStore*)list, &iter);
316
temp=(char*)gtk_menu_item_get_label(item);
317
gtk_list_store_set((GtkListStore*)list, &iter,
318
COL_LANG_DISPNAME, temp,
320
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(lang),&iter);
323
static void load_menu_lang_cb(void *arg, char *lang, char *desc)
325
GtkWidget *menu=GTK_WIDGET(arg);
328
gchar *temp,*p,*lang2;
330
lang2=g_strdup(lang);
334
if(lang2[0] && lang2[0]!='~')
335
temp=g_strdup_printf("%s\t%s",lang2,desc?desc:"");
340
item = gtk_menu_item_new_with_label(temp);
341
g_signal_connect(item, "activate", G_CALLBACK(on_menu_lang_select), g_strdup(lang));
342
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
346
static void show_all_languages(void)
350
lang_menu=gtk_menu_new();
351
lxdm_load_langs(var_config,TRUE,lang_menu,load_menu_lang_cb);
352
gtk_widget_show_all(lang_menu);
354
gtk_menu_popup(GTK_MENU(lang_menu),NULL,NULL,NULL,NULL,0,gtk_get_current_event_time());
357
static void on_lang_changed(GtkComboBox *widget)
360
if( gtk_combo_box_get_active_iter(widget, &it) )
362
GtkListStore *list=(GtkListStore*)gtk_combo_box_get_model(GTK_COMBO_BOX(lang));
364
gtk_tree_model_get(GTK_TREE_MODEL(list), &it, 1, &lang, -1);
367
gtk_combo_box_set_active(widget,0);
368
show_all_languages();
374
static void load_langs()
380
list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
381
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(list),0,GTK_SORT_ASCENDING);
382
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(list),0,lang_cmpr,NULL,NULL);
383
lxdm_load_langs(var_config,FALSE,list, load_lang_cb);
384
lang_str = g_key_file_get_string(var_config, "base", "last_lang", NULL);
385
if(lang_str && lang_str[0])
390
res=gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list),&iter);
391
if(res) for(i=0;;i++)
394
gtk_tree_model_get(GTK_TREE_MODEL(list),&iter,1,&lang,-1);
395
if(!strcmp(lang,lang_str))
402
res=gtk_tree_model_iter_next(GTK_TREE_MODEL(list),&iter);
407
gtk_combo_box_set_model( GTK_COMBO_BOX(lang), GTK_TREE_MODEL(list) );
408
#if GTK_CHECK_VERSION(2,23,90)
409
gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(lang), 0);
411
gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(lang), 0);
413
gtk_combo_box_set_active(GTK_COMBO_BOX(lang), active < 0 ? 0 : active);
414
g_object_unref(list);
416
g_signal_connect(G_OBJECT(lang),"changed",G_CALLBACK(on_lang_changed),NULL);
419
static void on_exit_clicked(GtkButton* exit_btn, gpointer user_data)
421
gtk_menu_popup( GTK_MENU(exit_menu), NULL, NULL, NULL, NULL,
422
0, gtk_get_current_event_time() );
425
static void load_exit()
428
exit_menu = gtk_menu_new();
429
item = gtk_image_menu_item_new_with_mnemonic( _("_Reboot") );
430
g_signal_connect(item, "activate", G_CALLBACK(do_reboot), NULL);
431
gtk_menu_shell_append(GTK_MENU_SHELL(exit_menu), item);
433
item = gtk_image_menu_item_new_with_mnemonic( _("_Shutdown") );
434
g_signal_connect(item, "activate", G_CALLBACK(do_shutdown), NULL);
435
gtk_menu_shell_append(GTK_MENU_SHELL(exit_menu), item);
437
gtk_widget_show_all(exit_menu);
438
g_signal_connect(exit_btn, "clicked", G_CALLBACK(on_exit_clicked), NULL);
441
static gboolean on_expose(GtkWidget* widget, GdkEventExpose* evt, gpointer user_data)
445
#if GTK_CHECK_VERSION(2,18,0)
446
if(! gtk_widget_get_has_window(widget))
448
if( !GTK_WIDGET_REALIZED(widget) )
451
#if GTK_CHECK_VERSION(2,14,0)
452
cr = gdk_cairo_create(gtk_widget_get_window(widget));
454
cr = gdk_cairo_create(widget->window);
458
cairo_matrix_t matrix;
459
double x = 0, y = 0, sx, sy;
460
cairo_get_matrix(cr, &matrix);
461
sx = (double)gdk_screen_width() / (double)gdk_pixbuf_get_width(bg_img);
462
sy = (double)gdk_screen_height() / (double)gdk_pixbuf_get_height(bg_img);
463
cairo_scale(cr, sx, sy);
464
gdk_cairo_set_source_pixbuf(cr, bg_img, x, y);
466
cairo_set_matrix(cr, &matrix);
470
gdk_cairo_set_source_color(cr, &bg_color);
471
cairo_rectangle( cr, 0, 0, gdk_screen_width(), gdk_screen_height() );
478
static gboolean on_combobox_entry_button_release(GtkWidget* w, GdkEventButton* evt, GtkComboBox* combo)
481
g_object_get(combo, "popup-shown", &shown, NULL);
483
gtk_combo_box_popdown(combo);
485
gtk_combo_box_popup(combo);
489
static void fix_combobox_entry(GtkWidget* combo)
491
GtkWidget* edit = gtk_bin_get_child(GTK_BIN(combo));
492
gtk_editable_set_editable( (GtkEditable*)edit, FALSE );
493
#if GTK_CHECK_VERSION(2,18,0)
494
gtk_widget_set_can_focus(edit, FALSE);
496
GTK_WIDGET_UNSET_FLAGS(edit, GTK_CAN_FOCUS);
498
g_signal_connect(edit, "button-release-event", G_CALLBACK(on_combobox_entry_button_release), combo);
501
static void on_evt_box_expose(GtkWidget* widget, GdkEventExpose* evt, gpointer user_data)
503
#if GTK_CHECK_VERSION(2,18,0)
504
if (gtk_widget_is_drawable(widget))
506
if (GTK_WIDGET_DRAWABLE (widget))
509
GtkWidgetClass* klass = (GtkWidgetClass*)G_OBJECT_GET_CLASS(widget);
510
gtk_paint_flat_box (gtk_widget_get_style(widget),
511
#if GTK_CHECK_VERSION(2,14,0)
512
gtk_widget_get_window(widget),
516
#if GTK_CHECK_VERSION(2,18,0)
517
gtk_widget_get_state(widget), GTK_SHADOW_NONE,
519
widget->state, GTK_SHADOW_NONE,
521
&evt->area, widget, "eventbox",
523
klass->expose_event (widget, evt);
527
static gboolean on_timeout(GtkLabel* label)
533
tmbuf = localtime(&t);
534
strftime(buf, 128, "%c", tmbuf);
535
gtk_label_set_text(label, buf);
539
static void on_user_select(GtkIconView *iconview)
541
GList *list=gtk_icon_view_get_selected_items(iconview);
543
GtkTreeModel *model=gtk_icon_view_get_model(iconview);
546
gtk_tree_model_get_iter(model,&iter,list->data);
547
g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
549
gtk_tree_model_get(model,&iter,2,&name,-1);
550
gtk_widget_hide(user_list);
553
gtk_entry_set_text(GTK_ENTRY(login_entry),name);
555
on_entry_activate(GTK_ENTRY(login_entry));
556
gtk_widget_show(login_entry);
557
gtk_widget_grab_focus(login_entry);
559
gtk_label_set_text( GTK_LABEL(prompt), _("Password:") );
560
gtk_widget_show(prompt);
570
gtk_entry_set_text(GTK_ENTRY(login_entry),"");
571
gtk_widget_show(login_entry);
572
gtk_widget_grab_focus(login_entry);
573
gtk_label_set_text( GTK_LABEL(prompt), _("User:") );
574
gtk_widget_show(prompt);
578
static gboolean load_user_list(GtkWidget *widget)
587
lxcom_send("/var/run/lxdm/lxdm.sock","USER_LIST",&res);
590
printf("log USER_LIST fail\n");
594
if(!g_key_file_load_from_data(kf,res,-1,0,NULL))
598
printf("log USER_LIST data bad\n");
603
gtk_icon_view_set_selection_mode(GTK_ICON_VIEW(widget),GTK_SELECTION_SINGLE);
604
gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(widget),0);
605
gtk_icon_view_set_markup_column(GTK_ICON_VIEW(widget),1);
606
gtk_icon_view_set_orientation(GTK_ICON_VIEW(widget),GTK_ORIENTATION_HORIZONTAL);
607
model=gtk_list_store_new(5,GDK_TYPE_PIXBUF,G_TYPE_STRING,
608
G_TYPE_STRING,G_TYPE_STRING,G_TYPE_BOOLEAN);
609
gtk_icon_view_set_model(GTK_ICON_VIEW(widget),GTK_TREE_MODEL(model));
610
g_signal_connect(G_OBJECT(widget),"item-activated",G_CALLBACK(on_user_select),NULL);
611
g_signal_connect(G_OBJECT(widget),"selection-changed",G_CALLBACK(on_user_select),NULL);
613
users=g_key_file_get_groups(kf,&count);
614
if(!users || count<=0)
617
printf("USER_LIST 0 user\n");
622
// TODO: better ui needed
627
char *gecos,*face_path,*display;
629
GdkPixbuf *face=NULL;
630
gtk_list_store_append(model,&iter);
631
gecos=g_key_file_get_string(kf,users[i],"gecos",0);
632
face_path=g_key_file_get_string(kf,users[i],"face",0);
633
login=g_key_file_get_boolean(kf,users[i],"login",0);
635
face=gdk_pixbuf_new_from_file_at_scale(face_path,48,48,TRUE,NULL);
638
/* TODO: load some default face */
639
face=gdk_pixbuf_new_from_file_at_scale(ui_nobody,48,48,TRUE,NULL);
641
display=g_strdup_printf("<span font_size=\"x-large\">%s</span>%s%s%s%s",
642
gecos?gecos:users[i],
643
(gecos&&strcmp(gecos,users[i]))?"(":"",
644
(gecos&&strcmp(gecos,users[i]))?users[i]:"",
645
(gecos&&strcmp(gecos,users[i]))?")":"",
646
login?_("\n<i>logged in</i>"):"");
647
// don't translate it now, not freeze
648
gtk_list_store_set(model,&iter,0,face,1,display,2,users[i],3,gecos,4,login,-1);
649
if(face) g_object_unref(G_OBJECT(face));
658
gtk_list_store_append(model,&iter);
659
gtk_list_store_set(model,&iter,1,_("More ..."),2,"",3,"",4,FALSE,-1);
663
static void create_win()
670
builder = gtk_builder_new();
671
gtk_builder_add_from_file(builder, ui_file ? ui_file : LXDM_DATA_DIR "/lxdm.glade", NULL);
672
win = (GtkWidget*)gtk_builder_get_object(builder, "lxdm");
674
Remove resize grip in Ubuntu 11.04 which break background painting
675
see https://bugs.launchpad.net/ubuntu/+source/lxdm/+bug/703658
677
gtk_window_set_has_resize_grip(GTK_WINDOW(win), FALSE);
679
/* set widget names according to their object id in GtkBuilder xml */
680
objs = gtk_builder_get_objects(builder);
681
for( l = objs; l; l = l->next )
683
GtkWidget* widget = (GtkWidget*)l->data;
684
gtk_widget_set_name( widget, gtk_buildable_get_name( (GtkBuildable*)widget ) );
686
gtk_widget_path(widget, NULL, &path, NULL);
690
if( bg_img ) /* only paint our own background if custom background image is set. */
692
gtk_widget_set_app_paintable(win, TRUE);
693
g_signal_connect(win, "expose-event", G_CALLBACK(on_expose), NULL);
694
} /* otherwise, let gtk theme paint it. */
696
scr = gtk_widget_get_screen(win);
697
g_signal_connect(scr, "size-changed", G_CALLBACK(on_screen_size_changed), win);
699
user_list=(GtkWidget*)gtk_builder_get_object(builder,"user_list");
702
//TODO: load user list, connect select_changed,activate signal
703
// Use GtkIconView may enough
706
prompt = (GtkWidget*)gtk_builder_get_object(builder, "prompt");
707
login_entry = (GtkWidget*)gtk_builder_get_object(builder, "login_entry");
709
g_signal_connect(login_entry, "activate", G_CALLBACK(on_entry_activate), NULL);
711
sessions = (GtkWidget*)gtk_builder_get_object(builder, "sessions");
712
gtk_widget_set_name(sessions, "sessions");
713
fix_combobox_entry(sessions);
716
w = (GtkWidget*)gtk_builder_get_object(builder, "bottom_pane");
717
if( g_key_file_get_integer(config, "display", "bottom_pane", 0) )
719
/* hacks to let GtkEventBox paintable with gtk pixmap engine. */
720
#if GTK_CHECK_VERSION(2,18,0)
721
if(gtk_widget_get_app_paintable(w))
723
if(GTK_WIDGET_APP_PAINTABLE(w))
725
g_signal_connect(w, "expose-event", G_CALLBACK(on_evt_box_expose), NULL);
728
gtk_event_box_set_visible_window(GTK_EVENT_BOX(w), FALSE);
730
if( g_key_file_get_integer(config, "display", "lang", 0) == 0 )
733
w = (GtkWidget*)gtk_builder_get_object(builder, "lang_box");
739
lang = (GtkWidget*)gtk_builder_get_object(builder, "lang");
740
gtk_widget_set_name(lang, "lang");
741
fix_combobox_entry(lang);
745
if( (w = (GtkWidget*)gtk_builder_get_object(builder, "time"))!=NULL )
747
guint timeout = g_timeout_add(1000, (GSourceFunc)on_timeout, w);
748
g_signal_connect_swapped(w, "destroy",
749
G_CALLBACK(g_source_remove), GUINT_TO_POINTER(timeout));
750
on_timeout((GtkLabel*)w);
753
exit_btn = (GtkWidget*)gtk_builder_get_object(builder, "exit");
756
g_object_unref(builder);
758
gtk_window_set_default_size( GTK_WINDOW(win), gdk_screen_get_width(scr), gdk_screen_get_height(scr) );
759
gtk_window_present( GTK_WINDOW(win) );
760
gtk_widget_realize(login_entry);
762
if(user_list && !g_key_file_get_integer(config,"userlist","disable",NULL) &&
763
load_user_list(user_list))
765
gtk_widget_hide(login_entry);
771
gtk_widget_hide(user_list);
774
gtk_widget_grab_focus(login_entry);
778
int set_background(void)
782
GdkWindow* root = gdk_get_default_root_window();
783
GdkCursor* cursor = gdk_cursor_new(GDK_LEFT_PTR);
785
gdk_window_set_cursor(root, cursor);
787
bg = g_key_file_get_string(config, "display", "bg", 0);
789
bg = g_strdup("#222E45");
790
style = g_key_file_get_string(config, "display", "bg_style", 0);
796
/* default the bg stretch */
797
if(!style || strcmp(style, "stretch") == 0 )
799
GdkPixbuf *tmp=gdk_pixbuf_new_from_file(bg,0);
802
bg_img=gdk_pixbuf_scale_simple(tmp,
811
bg_img = gdk_pixbuf_new_from_file(bg, 0);
816
bg = g_strdup("#222E45");
820
gdk_color_parse(bg, &bg_color);
827
static gboolean on_lxdm_command(GIOChannel *source, GIOCondition condition, gpointer data)
832
if( !(G_IO_IN & condition) )
834
ret = g_io_channel_read_line(source, &str, NULL, NULL, NULL);
835
if( ret != G_IO_STATUS_NORMAL )
838
if( !strncmp(str, "quit", 4) || !strncmp(str, "exit",4))
840
else if( !strncmp(str, "reset", 5) )
852
gtk_label_set_text( GTK_LABEL(prompt), _("User:"));
853
gtk_widget_show(prompt);
856
gtk_widget_hide(login_entry);
857
gtk_icon_view_unselect_all(GTK_ICON_VIEW(user_list));
858
gtk_widget_show(user_list);
862
gtk_widget_show(login_entry);
863
gtk_widget_grab_focus(login_entry);
870
void listen_stdin(void)
872
greeter_io = g_io_channel_unix_new(0);
873
g_io_add_watch(greeter_io, G_IO_IN, on_lxdm_command, NULL);
876
void set_root_background(void)
878
GdkWindow *root = gdk_get_default_root_window();
883
GdkColormap *map = (GdkColormap*)gdk_drawable_get_colormap(root);
884
gdk_colormap_alloc_color(map, &bg_color, TRUE, TRUE);
885
gdk_window_set_background(root, &bg_color);
889
GdkPixmap *pix = NULL;
890
gdk_pixbuf_render_pixmap_and_mask(bg_img, &pix, NULL, 0);
891
/* call x directly, because gdk will ref the pixmap */
892
//gdk_window_set_back_pixmap(root,pix,FALSE);
893
XSetWindowBackgroundPixmap( GDK_WINDOW_XDISPLAY(root),
894
GDK_WINDOW_XID(root), GDK_PIXMAP_XID(pix) );
897
gdk_window_clear(root);
900
static void apply_theme(const char* theme_name)
902
char* theme_dir = g_build_filename(LXDM_DATA_DIR "/themes", theme_name, NULL);
903
char* rc = g_build_filename(theme_dir, "gtkrc", NULL);
905
ui_file = g_build_filename(theme_dir, "greeter.ui", NULL);
907
if( g_file_test(rc, G_FILE_TEST_EXISTS) )
913
if( !g_file_test(ui_file, G_FILE_TEST_EXISTS) )
919
ui_nobody = g_build_filename(theme_dir, "nobody.png", NULL);
920
if( !g_file_test(ui_nobody, G_FILE_TEST_EXISTS) )
931
int main(int arc, char *arg[])
936
config = g_key_file_new();
937
g_key_file_load_from_file(config, CONFIG_FILE, G_KEY_FILE_KEEP_COMMENTS, NULL);
939
var_config = g_key_file_new();
940
g_key_file_set_list_separator(var_config, ' ');
941
g_key_file_load_from_file(var_config,VCONFIG_FILE,G_KEY_FILE_KEEP_COMMENTS, NULL);
943
gtk_init(&arc, &arg);
945
/* this will override LC_MESSAGES */
946
unsetenv("LANGUAGE");
948
bindtextdomain("lxdm", "/usr/share/locale");
951
p=gtk_settings_get_default();
954
setenv("GTK_IM_MODULE","gtk-im-context-simple",1);
955
gtk_settings_set_string_property(p,"gtk-im-module","gtk-im-context-simple",0);
956
gtk_settings_set_long_property(p,"gtk-show-input-method-menu",0,0);
960
set_root_background();
963
theme_name = g_key_file_get_string(config, "display", "gtk_theme", NULL);
966
GtkSettings* settings = gtk_settings_get_default();
967
g_object_set(settings, "gtk-theme-name", theme_name, NULL);
971
/* load gtkrc-based themes */
972
theme_name = g_key_file_get_string(config, "display", "theme", NULL);
973
if( theme_name ) /* theme is specified */
975
apply_theme(theme_name);
979
/* create the login window */
982
/* use line buffered stdout for inter-process-communcation of
983
* single-line-commands */
984
setvbuf(stdout, NULL, _IOLBF, 0 );
988
g_key_file_free(config);
989
g_key_file_free(var_config);