~kalgasnik/lightdm-gtk-greeter/gtk-710888-GtkInfoBar-visibility

« back to all changes in this revision

Viewing changes to src/lightdm-gtk-greeter.c

  • Committer: Sean Davis
  • Date: 2014-09-27 11:40:13 UTC
  • mfrom: (303.1.3 one-window-layout)
  • Revision ID: smd.seandavis@gmail.com-20140927114013-6gsqcn0e4vkb2u23
Merge one-window-layout branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright (C) 2010-2011 Robert Ancell.
3
3
 * Author: Robert Ancell <robert.ancell@canonical.com>
4
 
 * 
 
4
 *
5
5
 * This program is free software: you can redistribute it and/or modify it under
6
6
 * the terms of the GNU General Public License as published by the Free Software
7
7
 * Foundation, either version 3 of the License, or (at your option) any later
53
53
#include "src/lightdm-gtk-greeter-css-fallback.h"
54
54
#include "src/lightdm-gtk-greeter-css-application.h"
55
55
 
 
56
 
56
57
static LightDMGreeter *greeter;
57
58
 
58
59
/* State file */
60
61
static gchar *state_filename;
61
62
static void save_state_file (void);
62
63
 
63
 
/* Login Window Widgets */
64
 
static GtkWindow *login_window;
65
 
static GtkImage *user_image;
66
 
static GtkComboBox *user_combo;
67
 
static GtkEntry *username_entry, *password_entry;
68
 
static GtkLabel *message_label;
69
 
static GtkInfoBar *info_bar;
70
 
static GtkButton *cancel_button, *login_button;
71
 
 
72
 
/* Panel Widgets */
73
 
static GtkWindow *panel_window;
74
 
static GtkWidget *menubar;
75
 
static GtkWidget *power_menuitem, *session_menuitem, *language_menuitem, *a11y_menuitem,
76
 
                 *layout_menuitem, *clock_menuitem, *host_menuitem;
77
 
static GtkWidget *suspend_menuitem, *hibernate_menuitem, *restart_menuitem, *shutdown_menuitem;
78
 
static GtkWidget *contrast_menuitem, *font_menuitem, *keyboard_menuitem, *reader_menuitem;
79
 
static GtkWidget *clock_label, *session_badge;
80
 
static GtkMenu *session_menu, *language_menu, *layout_menu;
81
 
 
 
64
/* Screen window */
 
65
static GtkOverlay *screen_overlay;
 
66
 
 
67
/* Login window */
 
68
static GtkWidget    *login_window;
 
69
static GtkImage     *user_image;
 
70
static GtkComboBox  *user_combo;
 
71
static GtkEntry     *username_entry, *password_entry;
 
72
static GtkLabel     *message_label;
 
73
static GtkInfoBar   *info_bar;
 
74
static GtkButton    *cancel_button, *login_button;
 
75
 
 
76
/* Panel */
 
77
static GtkWidget    *panel_window, *menubar;
 
78
static GtkWidget    *power_menuitem, *session_menuitem, *language_menuitem, *a11y_menuitem,
 
79
                    *layout_menuitem, *clock_menuitem, *host_menuitem;
 
80
static GtkWidget    *suspend_menuitem, *hibernate_menuitem, *restart_menuitem, *shutdown_menuitem;
 
81
static GtkWidget    *contrast_menuitem, *font_menuitem, *keyboard_menuitem, *reader_menuitem;
 
82
static GtkWidget    *clock_label, *session_badge;
 
83
static GtkMenu      *session_menu, *language_menu, *layout_menu;
 
84
 
 
85
/* Power window */
 
86
static GtkWidget    *power_window;
 
87
static GtkButton    *power_ok_button, *power_cancel_button;
 
88
static GtkLabel     *power_title, *power_text;
 
89
static GtkImage     *power_icon;
 
90
 
 
91
static const gchar *POWER_WINDOW_DATA_LOOP = "power-window-loop";           /* <GMainLoop*> */
 
92
static const gchar *POWER_WINDOW_DATA_RESPONSE = "power-window-response";   /* <GtkResponseType> */
 
93
 
 
94
static gboolean show_power_prompt (const gchar *action, const gchar* icon, const gchar* title, const gchar* message);
 
95
void power_button_clicked_cb (GtkButton *button, gpointer user_data);
 
96
gboolean power_window_key_press_event_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
 
97
 
 
98
/* Handling window position */
82
99
typedef struct
83
100
{
84
101
    gint value;
93
110
typedef struct
94
111
{
95
112
    DimensionPosition x, y;
 
113
    /* Flag to use width and height fileds */
 
114
    gboolean use_size;
 
115
    DimensionPosition width, height;
96
116
} WindowPosition;
97
117
 
 
118
static WindowPosition* key_file_get_position (GKeyFile *key_file, const gchar *group_name, const gchar *key, const WindowPosition *default_value);
98
119
/* Function translate user defined coordinates to absolute value */
99
120
static gint get_absolute_position (const DimensionPosition *p, gint screen, gint window);
100
 
static const WindowPosition WINDOW_POS_CENTER   = {.x = { 50, +1, TRUE,   0}, .y = { 50, +1, TRUE,   0}};
101
 
static const WindowPosition WINDOW_POS_TOP_LEFT = {.x = {  0, +1, FALSE, -1}, .y = {  0, +1, FALSE, -1}};
102
 
static const WindowPosition ONBOARD_WINDOW_POS  = {.x = { 50, +1, TRUE,   0}, .y = {  0, -1, FALSE, +1}};
103
 
static const WindowPosition ONBOARD_WINDOW_SIZE = {.x = {610,  0, FALSE,  0}, .y = {210,  0, FALSE,  0}};
104
 
static WindowPosition main_window_pos;
105
 
static WindowPosition panel_window_pos;
106
 
 
107
 
static gchar *default_font_name, *default_theme_name, *default_icon_theme_name;
 
121
gboolean screen_overlay_get_child_position_cb (GtkWidget *overlay, GtkWidget *widget, GdkRectangle *allocation, gpointer user_data);
 
122
 
 
123
static const gchar *WINDOW_DATA_POSITION = "window-position"; /* <WindowPosition*> */
 
124
 
 
125
/* Some default positions */
 
126
static const WindowPosition WINDOW_POS_CENTER   = {.x = { 50, +1, TRUE,   0}, .y = { 50, +1, TRUE,   0}, .use_size = FALSE};
 
127
static const WindowPosition KEYBOARD_POSITION   = {.x = { 50, +1, TRUE,   0}, .y = {  0, -1, FALSE, +1}, .use_size = TRUE,
 
128
                                                   .width = {50, 0, TRUE, 0}, .height = {25, 0, TRUE, 0}};
 
129
 
 
130
/* Configuration */
 
131
static gboolean key_file_get_boolean_extended (GKeyFile *key_file, const gchar *group_name, const gchar *key, gboolean default_value);
 
132
 
 
133
/* Clock */
108
134
static gchar *clock_format;
 
135
static gboolean clock_timeout_thread (void);
 
136
 
 
137
/* Message label */
 
138
static gboolean message_label_is_empty (void);
 
139
static void set_message_label (LightDMMessageType type, const gchar *text);
 
140
 
 
141
/* User image */
109
142
static GdkPixbuf *default_user_pixbuf = NULL;
110
143
static gchar *default_user_icon = "avatar-default";
 
144
static void set_user_image (const gchar *username);
111
145
 
 
146
/* External command (keyboard, reader) */
112
147
typedef struct
113
148
{
114
149
    gchar **argv;
121
156
 
122
157
static MenuCommand *menu_command_parse (const gchar *value, GtkWidget *menu_item);
123
158
static MenuCommand *menu_command_parse_extended (const gchar *value, GtkWidget *menu_item,
124
 
                                                       const gchar *xid_supported, const gchar *xid_arg,
125
 
                                                       const WindowPosition *size);
 
159
                                                 const gchar *xid_app, const gchar *xid_arg);
126
160
static gboolean menu_command_run (MenuCommand *command);
127
161
static gboolean menu_command_stop (MenuCommand *command);
128
 
static void command_terminated_cb (GPid pid, gint status, MenuCommand *command);
 
162
static void menu_command_terminated_cb (GPid pid, gint status, MenuCommand *command);
129
163
 
130
164
static MenuCommand *a11y_keyboard_command;
131
165
static MenuCommand *a11y_reader_command;
132
166
 
133
167
static void a11y_menuitem_toggled_cb (GtkCheckMenuItem *item, const gchar* name);
134
168
 
135
 
/* Pending Questions */
136
 
static GSList *pending_questions = NULL;
137
 
 
138
 
/* Current choices */
 
169
/* Session */
139
170
static gchar *current_session;
 
171
static gboolean is_valid_session (GList* items, const gchar* session);
 
172
static gchar* get_session (void);
 
173
static void set_session (const gchar *session);
 
174
void session_selected_cb (GtkMenuItem *menuitem, gpointer user_data);
 
175
 
 
176
/* Sesion language */
140
177
static gchar *current_language;
 
178
static gchar* get_language (void);
 
179
static void set_language (const gchar *language);
 
180
void language_selected_cb (GtkMenuItem *menuitem, gpointer user_data);
141
181
 
142
182
/* Screensaver values */
143
183
static int timeout, interval, prefer_blanking, allow_exposures;
144
184
 
 
185
/* Handling monitors backgrounds */
145
186
static GreeterBackground *greeter_background;
146
187
 
 
188
/* Authentication state */
147
189
static gboolean cancelling = FALSE, prompted = FALSE;
148
190
static gboolean prompt_active = FALSE, password_prompted = FALSE;
149
191
 
 
192
/* Pending questions */
 
193
static GSList *pending_questions = NULL;
 
194
 
150
195
typedef struct
151
196
{
152
197
    gboolean is_prompt;
158
203
    gchar *text;
159
204
} PAMConversationMessage;
160
205
 
161
 
static const gchar *LANGUAGE_DATA_CODE = "language-code";
162
 
static const gchar *SESSION_DATA_KEY = "session-key";
163
 
static const gchar *LAYOUT_DATA_LABEL = "layout-label";
164
 
#ifdef HAVE_LIBXKLAVIER
165
 
static const gchar *LAYOUT_DATA_GROUP = "layout-group";
166
 
#else
167
 
static const gchar *LAYOUT_DATA_NAME = "layout-name";
168
 
#endif
 
206
static void pam_message_finalize (PAMConversationMessage *message);
 
207
static void process_prompts (LightDMGreeter *greeter);
 
208
static void show_prompt_cb (LightDMGreeter *greeter, const gchar *text, LightDMPromptType type);
169
209
 
170
 
#ifdef HAVE_LIBXKLAVIER
171
 
static XklEngine *xkl_engine;
172
 
#endif
 
210
/* Panel and indicators */
173
211
 
174
212
typedef enum
175
213
{
181
219
 
182
220
static const gchar *PANEL_ITEM_STYLE = "panel-item";
183
221
static const gchar *PANEL_ITEM_STYLE_HOVERED = "panel-item-hovered";
184
 
static const gchar *PANEL_ITEM_STYLES[] = 
 
222
static const gchar *PANEL_ITEM_STYLES[] =
185
223
{
186
224
    "panel-item-indicator",
187
225
    "panel-item-spacer",
192
230
static const gchar *PANEL_ITEM_DATA_INDEX = "panel-item-data-index";
193
231
 
194
232
#ifdef HAVE_LIBINDICATOR
195
 
static const gchar *INDICATOR_ITEM_DATA_OBJECT    = "indicator-item-data-object";
196
 
static const gchar *INDICATOR_ITEM_DATA_ENTRY     = "indicator-item-data-entry";
197
 
static const gchar *INDICATOR_ITEM_DATA_BOX       = "indicator-item-data-box";
198
 
static const gchar *INDICATOR_DATA_MENUITEMS      = "indicator-data-menuitems";
199
 
#endif
200
 
 
201
 
static gboolean
202
 
key_file_get_boolean_extended (GKeyFile *key_file, const gchar *group_name, const gchar *key, gboolean default_value)
203
 
{
204
 
    GError* error = NULL;
205
 
    gboolean result = g_key_file_get_boolean (key_file, group_name, key, &error);
206
 
    if (error)
207
 
    {
208
 
        g_clear_error (&error);
209
 
        return default_value;
210
 
    }
211
 
    return result;
212
 
}
 
233
static const gchar *INDICATOR_ITEM_DATA_OBJECT = "indicator-item-data-object";  /* <IndicatorObject*> */
 
234
static const gchar *INDICATOR_ITEM_DATA_ENTRY  = "indicator-item-data-entry";   /* <IndicatorObjectEntry*> */
 
235
static const gchar *INDICATOR_ITEM_DATA_BOX    = "indicator-item-data-box";     /* <GtkBox*> */
 
236
static const gchar *INDICATOR_DATA_MENUITEMS   = "indicator-data-menuitems";    /* <GHashTable*> */
 
237
#endif
 
238
 
 
239
static const gchar *LANGUAGE_DATA_CODE = "language-code";   /* <gchar*> e.g. "de_DE.UTF-8" */
 
240
static const gchar *SESSION_DATA_KEY = "session-key";       /* <gchar*> session name */
 
241
 
 
242
/* Layout indicator */
 
243
#ifdef HAVE_LIBXKLAVIER
 
244
static XklEngine *xkl_engine;
 
245
static const gchar *LAYOUT_DATA_GROUP = "layout-group";     /* <gchar*> */
 
246
#else
 
247
static const gchar *LAYOUT_DATA_NAME = "layout-name";       /* <gchar*> */
 
248
#endif
 
249
static const gchar *LAYOUT_DATA_LABEL = "layout-label";     /* <gchar*> e.g. "English (US)" */
 
250
 
 
251
static gboolean panel_item_enter_notify_cb (GtkWidget *widget, GdkEvent *event, gpointer enter);
 
252
static void panel_add_item (GtkWidget *widget, gint index, GreeterPanelItemType item_type);
 
253
static gboolean menu_item_accel_closure_cb (GtkAccelGroup *accel_group, GObject *acceleratable, guint keyval, GdkModifierType modifier, gpointer data);
 
254
/* Maybe unnecessary (in future) trick to enable accelerators for hidden/detached menu items */
 
255
static void reassign_menu_item_accel (GtkWidget *item);
 
256
 
 
257
#ifdef START_INDICATOR_SERVICES
 
258
static void init_indicators (GKeyFile* config, GPid* indicator_pid, GPid* spi_pid);
 
259
#else
 
260
static void init_indicators (GKeyFile* config);
 
261
#endif
 
262
 
 
263
static void layout_selected_cb (GtkCheckMenuItem *menuitem, gpointer user_data);
 
264
static void update_layouts_menu (void);
 
265
static void update_layouts_menu_state (void);
 
266
#ifdef HAVE_LIBXKLAVIER
 
267
static void xkl_state_changed_cb (XklEngine *engine, XklEngineStateChange change, gint group, gboolean restore, gpointer user_data);
 
268
static void xkl_config_changed_cb (XklEngine *engine, gpointer user_data);
 
269
static GdkFilterReturn xkl_xevent_filter (GdkXEvent *xev, GdkEvent *event, gpointer  data);
 
270
#endif
 
271
 
 
272
/* a11y indicator */
 
273
static gchar *default_font_name,
 
274
             *default_theme_name,
 
275
             *default_icon_theme_name;
 
276
void a11y_font_cb (GtkCheckMenuItem *item);
 
277
void a11y_contrast_cb (GtkCheckMenuItem *item);
 
278
void a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data);
 
279
void a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data);
 
280
 
 
281
/* Power indciator */
 
282
static void power_menu_cb (GtkWidget *menuitem, gpointer userdata);
 
283
void suspend_cb (GtkWidget *widget, LightDMGreeter *greeter);
 
284
void hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter);
 
285
void restart_cb (GtkWidget *widget, LightDMGreeter *greeter);
 
286
void shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter);
 
287
 
 
288
/* State file */
213
289
 
214
290
static void
215
291
save_state_file (void)
236
312
    }
237
313
}
238
314
 
 
315
/* Power window */
 
316
 
 
317
static gboolean
 
318
show_power_prompt (const gchar *action, const gchar* icon, const gchar* title, const gchar* message)
 
319
{
 
320
    gchar *new_message = NULL;
 
321
 
 
322
    /* Check if there are still users logged in, count them and if so, display a warning */
 
323
    gint logged_in_users = 0;
 
324
    GList *items = lightdm_user_list_get_users (lightdm_user_list_get_instance ());
 
325
    GList *item;
 
326
    for (item = items; item; item = item->next)
 
327
    {
 
328
        LightDMUser *user = item->data;
 
329
        if (lightdm_user_get_logged_in (user))
 
330
            logged_in_users++;
 
331
    }
 
332
 
 
333
    if (logged_in_users > 0)
 
334
    {
 
335
        gchar *warning = g_strdup_printf (ngettext ("Warning: There is still %d user logged in.",
 
336
                                                    "Warning: There are still %d users logged in.",
 
337
                                                    logged_in_users),
 
338
                                          logged_in_users);
 
339
        message = new_message = g_markup_printf_escaped ("<b>%s</b>\n%s", warning, message);
 
340
        g_free (warning);
 
341
    }
 
342
 
 
343
    gchar *dialog_name = g_strconcat (action, "_dialog", NULL);
 
344
    gchar *button_name = g_strconcat (action, "_button", NULL);
 
345
 
 
346
    gtk_widget_set_name (power_window, dialog_name);
 
347
    gtk_widget_set_name (GTK_WIDGET (power_ok_button), button_name);
 
348
    gtk_button_set_label (power_ok_button, title);
 
349
    gtk_label_set_label (power_title, title);
 
350
    gtk_label_set_markup (power_text, message);
 
351
    gtk_image_set_from_icon_name (power_icon, icon, GTK_ICON_SIZE_DIALOG);
 
352
 
 
353
    g_free (button_name);
 
354
    g_free (dialog_name);
 
355
    g_free (new_message);
 
356
 
 
357
    GMainLoop *loop = g_main_loop_new (NULL, FALSE);
 
358
    g_object_set_data (G_OBJECT (power_window), POWER_WINDOW_DATA_LOOP, loop);
 
359
    g_object_set_data (G_OBJECT (power_window), POWER_WINDOW_DATA_RESPONSE, GINT_TO_POINTER (GTK_RESPONSE_CANCEL));
 
360
 
 
361
    GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (screen_overlay))));
 
362
    gboolean session_enabled = gtk_widget_get_sensitive (session_menuitem);
 
363
    gboolean language_enabled = gtk_widget_get_sensitive (language_menuitem);
 
364
 
 
365
    gtk_widget_set_sensitive (power_menuitem, FALSE);
 
366
    gtk_widget_set_sensitive (session_menuitem, FALSE);
 
367
    gtk_widget_set_sensitive (language_menuitem, FALSE);
 
368
    gtk_widget_hide (login_window);
 
369
    gtk_widget_show (power_window);
 
370
    gtk_widget_grab_focus (GTK_WIDGET (power_ok_button));
 
371
 
 
372
    g_main_loop_run (loop);
 
373
    GtkResponseType response = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (power_window), POWER_WINDOW_DATA_RESPONSE));
 
374
    g_main_loop_unref (loop);
 
375
 
 
376
    gtk_widget_hide (power_window);
 
377
    gtk_widget_show (login_window);
 
378
    gtk_widget_set_sensitive (power_menuitem, TRUE);
 
379
    gtk_widget_set_sensitive (session_menuitem, session_enabled);
 
380
    gtk_widget_set_sensitive (language_menuitem, language_enabled);
 
381
 
 
382
    if (focused)
 
383
        gtk_widget_grab_focus (focused);
 
384
 
 
385
    return response == GTK_RESPONSE_YES;
 
386
}
 
387
 
 
388
void
 
389
power_button_clicked_cb (GtkButton *button, gpointer user_data)
 
390
{
 
391
    GMainLoop *loop = g_object_get_data (G_OBJECT (power_window), POWER_WINDOW_DATA_LOOP);
 
392
    if (g_main_loop_is_running (loop))
 
393
        g_main_loop_quit (loop);
 
394
 
 
395
    g_object_set_data (G_OBJECT (power_window), POWER_WINDOW_DATA_RESPONSE,
 
396
                       GINT_TO_POINTER (button == power_ok_button ? GTK_RESPONSE_YES : GTK_RESPONSE_CANCEL));
 
397
}
 
398
 
 
399
gboolean
 
400
power_window_key_press_event_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
 
401
{
 
402
    if (event->keyval == GDK_KEY_Escape)
 
403
    {
 
404
        power_button_clicked_cb (power_cancel_button, NULL);
 
405
        return TRUE;
 
406
    }
 
407
    return FALSE;
 
408
}
 
409
 
 
410
/* Handling window position */
 
411
 
 
412
static gboolean
 
413
read_position_from_str (const gchar *s, DimensionPosition *x)
 
414
{
 
415
    DimensionPosition p;
 
416
    gchar *end = NULL;
 
417
    gchar **parts = g_strsplit (s, ",", 2);
 
418
    if (parts[0])
 
419
    {
 
420
        p.value = g_ascii_strtoll (parts[0], &end, 10);
 
421
        p.percentage = end && end[0] == '%';
 
422
        p.sign = (p.value < 0 || (p.value == 0 && parts[0][0] == '-')) ? -1 : +1;
 
423
        if (p.value < 0)
 
424
            p.value *= -1;
 
425
        if (g_strcmp0(parts[1], "start") == 0)
 
426
            p.anchor = -1;
 
427
        else if (g_strcmp0(parts[1], "center") == 0)
 
428
            p.anchor = 0;
 
429
        else if (g_strcmp0(parts[1], "end") == 0)
 
430
            p.anchor = +1;
 
431
        else
 
432
            p.anchor = p.sign > 0 ? -1 : +1;
 
433
        *x = p;
 
434
    }
 
435
    else
 
436
        x = NULL;
 
437
    g_strfreev (parts);
 
438
    return x != NULL;
 
439
}
 
440
 
 
441
static WindowPosition*
 
442
key_file_get_position (GKeyFile *key_file, const gchar *group_name, const gchar *key, const WindowPosition *default_value)
 
443
{
 
444
    WindowPosition* pos = g_new0 (WindowPosition, 1);
 
445
    gchar *value = g_key_file_get_value (key_file, group_name, key, NULL);
 
446
 
 
447
    *pos = *default_value;
 
448
 
 
449
    if (value)
 
450
    {
 
451
        gchar *x = value;
 
452
        gchar *y = strchr (value, ' ');
 
453
        if (y)
 
454
            (y++)[0] = '\0';
 
455
 
 
456
        if (read_position_from_str (x, &pos->x))
 
457
            /* If there is no y-part then y = x */
 
458
            if (!y || !read_position_from_str (y, &pos->y))
 
459
                pos->y = pos->x;
 
460
 
 
461
        gchar *size_delim = strchr (y ? y : x, ';');
 
462
        if (size_delim)
 
463
        {
 
464
            gchar *x = size_delim + 1;
 
465
            if (read_position_from_str (x, &pos->width))
 
466
            {
 
467
                y = strchr (x, ' ');
 
468
                if (y)
 
469
                    (y++)[0] = '\0';
 
470
                if (!y || !read_position_from_str (y, &pos->height))
 
471
                    if (!default_value->use_size)
 
472
                        pos->height = pos->width;
 
473
                pos->use_size = TRUE;
 
474
            }
 
475
        }
 
476
 
 
477
        g_free (value);
 
478
    }
 
479
 
 
480
    return pos;
 
481
}
 
482
 
 
483
static gint
 
484
get_absolute_position (const DimensionPosition *p, gint screen, gint window)
 
485
{
 
486
    gint x = p->percentage ? (screen*p->value)/100 : p->value;
 
487
    x = p->sign < 0 ? screen - x : x;
 
488
    if (p->anchor > 0)
 
489
        x -= window;
 
490
    else if (p->anchor == 0)
 
491
        x -= window/2;
 
492
 
 
493
    if (x < 0)                     /* Offscreen: left/top */
 
494
        return 0;
 
495
    else if (x + window > screen)  /* Offscreen: right/bottom */
 
496
        return screen - window;
 
497
    else
 
498
        return x;
 
499
}
 
500
 
 
501
gboolean
 
502
screen_overlay_get_child_position_cb (GtkWidget *overlay, GtkWidget *widget, GdkRectangle *allocation, gpointer user_data)
 
503
{
 
504
    const WindowPosition *pos = g_object_get_data (G_OBJECT (widget), WINDOW_DATA_POSITION);
 
505
    if (!pos)
 
506
        return FALSE;
 
507
 
 
508
    gint screen_width = gtk_widget_get_allocated_width (overlay);
 
509
    gint screen_height = gtk_widget_get_allocated_height (overlay);
 
510
 
 
511
    if (pos->use_size)
 
512
    {
 
513
        allocation->width = get_absolute_position (&pos->width, screen_width, 0);
 
514
        allocation->height = get_absolute_position (&pos->height, screen_height, 0);
 
515
    }
 
516
    else
 
517
    {
 
518
        gtk_widget_get_preferred_width (widget, NULL, &allocation->width);
 
519
        gtk_widget_get_preferred_height (widget, NULL, &allocation->height);
 
520
    }
 
521
 
 
522
    allocation->x = get_absolute_position (&pos->x, screen_width, allocation->width);
 
523
    allocation->y = get_absolute_position (&pos->y, screen_height, allocation->height);
 
524
 
 
525
    /* Do not overlap panel window */
 
526
    gint panel_height = gtk_widget_get_allocated_height (panel_window);
 
527
    if (panel_height && gtk_widget_get_visible (panel_window))
 
528
    {
 
529
        GtkAlign valign = gtk_widget_get_valign (panel_window);
 
530
        if (valign == GTK_ALIGN_START && allocation->y < panel_height)
 
531
            allocation->y = panel_height;
 
532
        else if (valign == GTK_ALIGN_END && screen_height - allocation->y - allocation->height < panel_height)
 
533
            allocation->y = screen_height - allocation->height - panel_height;
 
534
    }
 
535
 
 
536
    return TRUE;
 
537
}
 
538
 
 
539
/* Configuration */
 
540
 
 
541
static gboolean
 
542
key_file_get_boolean_extended (GKeyFile *key_file, const gchar *group_name, const gchar *key, gboolean default_value)
 
543
{
 
544
    GError* error = NULL;
 
545
    gboolean result = g_key_file_get_boolean (key_file, group_name, key, &error);
 
546
    if (error)
 
547
    {
 
548
        g_clear_error (&error);
 
549
        return default_value;
 
550
    }
 
551
    return result;
 
552
}
 
553
 
 
554
/* Clock */
 
555
 
 
556
static gboolean
 
557
clock_timeout_thread (void)
 
558
{
 
559
    time_t rawtime;
 
560
    struct tm * timeinfo;
 
561
    gchar time_str[50];
 
562
    gchar *markup;
 
563
 
 
564
    time (&rawtime);
 
565
    timeinfo = localtime (&rawtime);
 
566
 
 
567
    strftime (time_str, 50, clock_format, timeinfo);
 
568
    markup = g_markup_printf_escaped ("<b>%s</b>", time_str);
 
569
    if (g_strcmp0 (markup, gtk_label_get_label (GTK_LABEL (clock_label))) != 0)
 
570
        gtk_label_set_markup (GTK_LABEL (clock_label), markup);
 
571
    g_free (markup);
 
572
 
 
573
    return TRUE;
 
574
}
 
575
 
 
576
/* Message label */
 
577
 
 
578
static gboolean
 
579
message_label_is_empty (void)
 
580
{
 
581
    return gtk_label_get_text (message_label)[0] == '\0';
 
582
}
 
583
 
 
584
static void
 
585
set_message_label (LightDMMessageType type, const gchar *text)
 
586
{
 
587
    if (type == LIGHTDM_MESSAGE_TYPE_INFO)
 
588
        gtk_info_bar_set_message_type (info_bar, GTK_MESSAGE_INFO);
 
589
    else
 
590
        gtk_info_bar_set_message_type (info_bar, GTK_MESSAGE_ERROR);
 
591
    gtk_label_set_text (message_label, text);
 
592
    gtk_widget_set_visible (GTK_WIDGET (info_bar), text && text[0]);
 
593
}
 
594
 
 
595
/* User image */
 
596
 
 
597
static void
 
598
set_user_image (const gchar *username)
 
599
{
 
600
    const gchar *path;
 
601
    LightDMUser *user = NULL;
 
602
    GdkPixbuf *image = NULL;
 
603
    GError *error = NULL;
 
604
 
 
605
    if (!gtk_widget_get_visible (GTK_WIDGET (user_image)))
 
606
        return;
 
607
 
 
608
    if (username)
 
609
        user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username);
 
610
 
 
611
    if (user)
 
612
    {
 
613
        path = lightdm_user_get_image (user);
 
614
        if (path)
 
615
        {
 
616
            image = gdk_pixbuf_new_from_file_at_scale (path, 80, 80, FALSE, &error);
 
617
            if (image)
 
618
            {
 
619
                gtk_image_set_from_pixbuf (GTK_IMAGE (user_image), image);
 
620
                g_object_unref (image);
 
621
                return;
 
622
            }
 
623
            else
 
624
            {
 
625
                g_warning ("Failed to load user image: %s", error->message);
 
626
                g_clear_error (&error);
 
627
            }
 
628
        }
 
629
    }
 
630
 
 
631
    if (default_user_pixbuf)
 
632
        gtk_image_set_from_pixbuf (GTK_IMAGE (user_image), default_user_pixbuf);
 
633
    else
 
634
        gtk_image_set_from_icon_name (GTK_IMAGE (user_image), default_user_icon, GTK_ICON_SIZE_DIALOG);
 
635
}
 
636
 
239
637
/* MenuCommand */
240
638
 
241
639
static MenuCommand*
242
640
menu_command_parse (const gchar *value, GtkWidget *menu_item)
243
641
{
244
 
    return menu_command_parse_extended (value, menu_item, NULL, NULL, NULL);
 
642
    return menu_command_parse_extended (value, menu_item, NULL, NULL);
245
643
}
246
644
 
247
645
static MenuCommand*
248
 
menu_command_parse_extended (const gchar *value, GtkWidget *menu_item,
249
 
                             const gchar *xid_supported, const gchar *xid_arg,
250
 
                             const WindowPosition *size)
 
646
menu_command_parse_extended (const gchar *value,    /* String to parse */
 
647
                             GtkWidget *menu_item,  /* Menu item to connect */
 
648
                             const gchar *xid_app,  /* Program that have "xembed" mode support */
 
649
                             const gchar *xid_arg)  /* Argument that must be added to command line */
251
650
{
252
651
    if (!value)
253
652
        return NULL;
269
668
    command->argc = argc;
270
669
    command->argv = argv;
271
670
 
272
 
    if (g_strcmp0 (argv[0], xid_supported) == 0)
 
671
    if (g_strcmp0 (argv[0], xid_app) == 0)
273
672
    {
274
673
        gboolean have_xid_arg = FALSE;
275
674
        gint i;
301
700
 
302
701
        if (have_xid_arg)
303
702
        {
304
 
            GdkRectangle screen;
305
 
            command->widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
306
 
            gdk_screen_get_monitor_geometry (gdk_screen_get_default (),
307
 
                                             /* must be replaced with background->active_monitor */
308
 
                                             gdk_screen_get_primary_monitor (gdk_screen_get_default ()),
309
 
                                             &screen);
310
 
            gtk_widget_set_size_request (command->widget,
311
 
                                         get_absolute_position (&size->x, screen.width, 0),
312
 
                                         get_absolute_position (&size->y, screen.height, 0));
 
703
            command->widget = gtk_event_box_new ();
 
704
            gtk_overlay_add_overlay (screen_overlay, command->widget);
313
705
        }
314
706
    }
315
707
    return command;
350
742
                else
351
743
                    g_warning ("Failed to get '%s' socket: unrecognized output", command->argv[0]);
352
744
 
353
 
                g_free(text);
 
745
                g_free (text);
354
746
            }
355
747
        }
356
748
    }
360
752
                                 G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
361
753
                                 NULL, NULL, &command->pid, &error);
362
754
        if (spawned)
363
 
            g_child_watch_add (command->pid, (GChildWatchFunc)command_terminated_cb, command);
 
755
            g_child_watch_add (command->pid, (GChildWatchFunc)menu_command_terminated_cb, command);
364
756
    }
365
757
 
366
 
    if(!spawned)
 
758
    if (!spawned)
367
759
    {
368
760
        if (error)
369
761
            g_warning ("Command spawning error: '%s'", error->message);
370
762
        command->pid = 0;
371
763
        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (command->menu_item), FALSE);
372
764
    }
373
 
    g_clear_error(&error);
 
765
    g_clear_error (&error);
374
766
    return spawned;
375
767
}
376
768
 
393
785
}
394
786
 
395
787
static void
396
 
command_terminated_cb (GPid pid, gint status, MenuCommand *command)
 
788
menu_command_terminated_cb (GPid pid, gint status, MenuCommand *command)
397
789
{
398
790
    menu_command_stop (command);
399
791
}
405
797
    save_state_file ();
406
798
}
407
799
 
 
800
/* Session */
 
801
 
 
802
static gboolean
 
803
is_valid_session (GList* items, const gchar* session)
 
804
{
 
805
    for (; items; items = g_list_next (items))
 
806
        if (g_strcmp0 (session, lightdm_session_get_key (items->data)) == 0)
 
807
            return TRUE;
 
808
    return FALSE;
 
809
}
 
810
 
 
811
static gchar*
 
812
get_session (void)
 
813
{
 
814
    return g_strdup (current_session);
 
815
}
 
816
 
 
817
static void
 
818
set_session (const gchar *session)
 
819
{
 
820
    gchar *last_session = NULL;
 
821
    GList *sessions = lightdm_get_sessions ();
 
822
 
 
823
    /* Validation */
 
824
    if (!session || !is_valid_session (sessions, session))
 
825
    {
 
826
        /* previous session */
 
827
        last_session = g_key_file_get_value (state, "greeter", "last-session", NULL);
 
828
        if (last_session && g_strcmp0 (session, last_session) != 0 &&
 
829
            is_valid_session (sessions, last_session))
 
830
            session = last_session;
 
831
        else
 
832
        {
 
833
            /* default */
 
834
            const gchar* default_session = lightdm_greeter_get_default_session_hint (greeter);
 
835
            if (g_strcmp0 (session, default_session) != 0 &&
 
836
                is_valid_session (sessions, default_session))
 
837
                session = default_session;
 
838
            /* first in the sessions list */
 
839
            else if (sessions)
 
840
                session = lightdm_session_get_key (sessions->data);
 
841
            /* give up */
 
842
            else
 
843
                session = NULL;
 
844
        }
 
845
    }
 
846
 
 
847
    if (gtk_widget_get_visible (session_menuitem))
 
848
    {
 
849
        GList *menu_iter = NULL;
 
850
        GList *menu_items = gtk_container_get_children (GTK_CONTAINER (session_menu));
 
851
        if (session)
 
852
        {
 
853
            for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next (menu_iter))
 
854
                if (g_strcmp0 (session, g_object_get_data (G_OBJECT (menu_iter->data), SESSION_DATA_KEY)) == 0)
 
855
                {
 
856
                    /* Set menuitem-image to session-badge */
 
857
                    GtkIconTheme *icon_theme = gtk_icon_theme_get_default ();
 
858
                    gchar* session_name = g_ascii_strdown (session, -1);
 
859
                    gchar* icon_name = g_strdup_printf ("%s_badge-symbolic", session_name);
 
860
                    g_free (session_name);
 
861
                    if (gtk_icon_theme_has_icon (icon_theme, icon_name))
 
862
                        gtk_image_set_from_icon_name (GTK_IMAGE (session_badge), icon_name, GTK_ICON_SIZE_MENU);
 
863
                    else
 
864
                        gtk_image_set_from_icon_name (GTK_IMAGE (session_badge), "document-properties-symbolic", GTK_ICON_SIZE_MENU);
 
865
                    g_free (icon_name);
 
866
                    break;
 
867
                }
 
868
        }
 
869
        if (!menu_iter)
 
870
            menu_iter = menu_items;
 
871
 
 
872
        if (menu_iter)
 
873
                gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_iter->data), TRUE);
 
874
    }
 
875
 
 
876
    g_free (current_session);
 
877
    current_session = g_strdup (session);
 
878
    g_free (last_session);
 
879
}
 
880
 
 
881
void
 
882
session_selected_cb (GtkMenuItem *menuitem, gpointer user_data)
 
883
{
 
884
    if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem)))
 
885
       set_session (g_object_get_data (G_OBJECT (menuitem), SESSION_DATA_KEY));
 
886
}
 
887
 
 
888
 
 
889
/* Session language */
 
890
 
 
891
static gchar*
 
892
get_language (void)
 
893
{
 
894
    GList *menu_items, *menu_iter;
 
895
 
 
896
    /* if the user manually selected a language, use it */
 
897
    if (current_language)
 
898
        return g_strdup (current_language);
 
899
 
 
900
    menu_items = gtk_container_get_children (GTK_CONTAINER (language_menu));
 
901
    for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next (menu_iter))
 
902
    {
 
903
        if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menu_iter->data)))
 
904
            return g_strdup (g_object_get_data (G_OBJECT (menu_iter->data), LANGUAGE_DATA_CODE));
 
905
    }
 
906
 
 
907
    return NULL;
 
908
}
 
909
 
 
910
static void
 
911
set_language (const gchar *language)
 
912
{
 
913
    const gchar *default_language = NULL;
 
914
    GList *menu_items, *menu_iter;
 
915
 
 
916
    if (!gtk_widget_get_visible (language_menuitem))
 
917
    {
 
918
        g_free (current_language);
 
919
        current_language = g_strdup (language);
 
920
        return;
 
921
    }
 
922
 
 
923
    menu_items = gtk_container_get_children (GTK_CONTAINER (language_menu));
 
924
 
 
925
    if (language)
 
926
    {
 
927
        for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next (menu_iter))
 
928
        {
 
929
            gchar *s;
 
930
            gboolean matched;
 
931
            s = g_strdup (g_object_get_data (G_OBJECT (menu_iter->data), LANGUAGE_DATA_CODE));
 
932
            matched = g_strcmp0 (s, language) == 0;
 
933
            g_free (s);
 
934
            if (matched)
 
935
            {
 
936
                gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_iter->data), TRUE);
 
937
                g_free (current_language);
 
938
                current_language = g_strdup (language);
 
939
                gtk_menu_item_set_label (GTK_MENU_ITEM (language_menuitem),language);
 
940
                return;
 
941
            }
 
942
        }
 
943
    }
 
944
 
 
945
    /* If failed to find this language, then try the default */
 
946
    if (lightdm_get_language ())
 
947
    {
 
948
        default_language = lightdm_language_get_code (lightdm_get_language ());
 
949
        gtk_menu_item_set_label (GTK_MENU_ITEM (language_menuitem), default_language);
 
950
    }
 
951
    if (default_language && g_strcmp0 (default_language, language) != 0)
 
952
        set_language (default_language);
 
953
    /* If all else fails, just use the first language from the menu */
 
954
    else
 
955
    {
 
956
        for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next (menu_iter))
 
957
        {
 
958
            if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menu_iter->data)))
 
959
            {
 
960
                gtk_menu_item_set_label (GTK_MENU_ITEM (language_menuitem), g_strdup (g_object_get_data (G_OBJECT (menu_iter->data), LANGUAGE_DATA_CODE)));
 
961
                break;
 
962
            }
 
963
        }
 
964
    }
 
965
}
 
966
 
 
967
void
 
968
language_selected_cb (GtkMenuItem *menuitem, gpointer user_data)
 
969
{
 
970
    if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem)))
 
971
    {
 
972
       gchar *language = g_object_get_data (G_OBJECT (menuitem), LANGUAGE_DATA_CODE);
 
973
       set_language (language);
 
974
    }
 
975
}
 
976
 
 
977
/* Pending questions */
 
978
 
408
979
static void
409
980
pam_message_finalize (PAMConversationMessage *message)
410
981
{
412
983
    g_free (message);
413
984
}
414
985
 
 
986
static void
 
987
process_prompts (LightDMGreeter *greeter)
 
988
{
 
989
    if (!pending_questions)
 
990
        return;
 
991
 
 
992
    /* always allow the user to change username again */
 
993
    gtk_widget_set_sensitive (GTK_WIDGET (username_entry), TRUE);
 
994
    gtk_widget_set_sensitive (GTK_WIDGET (password_entry), TRUE);
 
995
 
 
996
    /* Special case: no user selected from list, so PAM asks us for the user
 
997
     * via a prompt. For that case, use the username field */
 
998
    if (!prompted && pending_questions && !pending_questions->next &&
 
999
        ((PAMConversationMessage *) pending_questions->data)->is_prompt &&
 
1000
        ((PAMConversationMessage *) pending_questions->data)->type.prompt != LIGHTDM_PROMPT_TYPE_SECRET &&
 
1001
        gtk_widget_get_visible ((GTK_WIDGET (username_entry))) &&
 
1002
        lightdm_greeter_get_authentication_user (greeter) == NULL)
 
1003
    {
 
1004
        prompted = TRUE;
 
1005
        prompt_active = TRUE;
 
1006
        gtk_widget_grab_focus (GTK_WIDGET (username_entry));
 
1007
        gtk_widget_show (GTK_WIDGET (password_entry));
 
1008
        return;
 
1009
    }
 
1010
 
 
1011
    while (pending_questions)
 
1012
    {
 
1013
        PAMConversationMessage *message = (PAMConversationMessage *) pending_questions->data;
 
1014
        pending_questions = g_slist_remove (pending_questions, (gconstpointer) message);
 
1015
 
 
1016
        if (!message->is_prompt)
 
1017
        {
 
1018
            /* FIXME: this doesn't show multiple messages, but that was
 
1019
             * already the case before. */
 
1020
            set_message_label (message->type.message, message->text);
 
1021
            continue;
 
1022
        }
 
1023
 
 
1024
        gtk_widget_show (GTK_WIDGET (password_entry));
 
1025
        gtk_widget_grab_focus (GTK_WIDGET (password_entry));
 
1026
        gtk_entry_set_text (password_entry, "");
 
1027
        gtk_entry_set_visibility (password_entry, message->type.prompt != LIGHTDM_PROMPT_TYPE_SECRET);
 
1028
        if (message_label_is_empty () && password_prompted)
 
1029
        {
 
1030
            /* No message was provided beforehand and this is not the
 
1031
             * first password prompt, so use the prompt as label,
 
1032
             * otherwise the user will be completely unclear of what
 
1033
             * is going on. Actually, the fact that prompt messages are
 
1034
             * not shown is problematic in general, especially if
 
1035
             * somebody uses a custom PAM module that wants to ask
 
1036
             * something different. */
 
1037
            gchar *str = message->text;
 
1038
            if (g_str_has_suffix (str, ": "))
 
1039
                str = g_strndup (str, strlen (str) - 2);
 
1040
            else if (g_str_has_suffix (str, ":"))
 
1041
                str = g_strndup (str, strlen (str) - 1);
 
1042
            set_message_label (LIGHTDM_MESSAGE_TYPE_INFO, str);
 
1043
            if (str != message->text)
 
1044
                g_free (str);
 
1045
        }
 
1046
        gtk_widget_grab_focus (GTK_WIDGET (password_entry));
 
1047
        prompted = TRUE;
 
1048
        password_prompted = TRUE;
 
1049
        prompt_active = TRUE;
 
1050
 
 
1051
        /* If we have more stuff after a prompt, assume that other prompts are pending,
 
1052
         * so stop here. */
 
1053
        break;
 
1054
    }
 
1055
}
 
1056
 
 
1057
/* Panel and indicators */
 
1058
 
415
1059
static gboolean
416
1060
panel_item_enter_notify_cb (GtkWidget *widget, GdkEvent *event, gpointer enter)
417
1061
{
442
1086
    if (item_type == PANEL_ITEM_INDICATOR)
443
1087
    {
444
1088
        g_signal_connect (G_OBJECT (widget), "enter-notify-event",
445
 
                          G_CALLBACK (panel_item_enter_notify_cb), GINT_TO_POINTER(TRUE));
 
1089
                          G_CALLBACK (panel_item_enter_notify_cb), GINT_TO_POINTER (TRUE));
446
1090
        g_signal_connect (G_OBJECT (widget), "leave-notify-event",
447
 
                          G_CALLBACK (panel_item_enter_notify_cb), GINT_TO_POINTER(FALSE));
 
1091
                          G_CALLBACK (panel_item_enter_notify_cb), GINT_TO_POINTER (FALSE));
448
1092
    }
449
1093
 
450
1094
    gtk_widget_show (widget);
495
1139
    box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
496
1140
    menuitem = gtk_menu_item_new ();
497
1141
 
498
 
    gtk_widget_add_events(GTK_WIDGET(menuitem), GDK_SCROLL_MASK);
 
1142
    gtk_widget_add_events (GTK_WIDGET (menuitem), GDK_SCROLL_MASK);
499
1143
 
500
1144
    g_object_set_data (G_OBJECT (menuitem), INDICATOR_ITEM_DATA_BOX, box);
501
1145
    g_object_set_data (G_OBJECT (menuitem), INDICATOR_ITEM_DATA_OBJECT, io);
506
1150
    g_signal_connect (G_OBJECT (menuitem), "scroll-event", G_CALLBACK (indicator_entry_scrolled_cb), NULL);
507
1151
 
508
1152
    if (entry->image)
509
 
        gtk_box_pack_start (GTK_BOX(box), GTK_WIDGET(entry->image), FALSE, FALSE, 1);
 
1153
        gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (entry->image), FALSE, FALSE, 1);
510
1154
 
511
1155
    if (entry->label)
512
 
        gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(entry->label), FALSE, FALSE, 1);
 
1156
        gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (entry->label), FALSE, FALSE, 1);
513
1157
 
514
1158
    if (entry->menu)
515
1159
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), GTK_WIDGET (entry->menu));
516
1160
 
517
1161
    gtk_container_add (GTK_CONTAINER (menuitem), box);
518
1162
    gtk_widget_show (box);
519
 
    panel_add_item(menuitem, index, PANEL_ITEM_INDICATOR);
 
1163
    panel_add_item (menuitem, index, PANEL_ITEM_INDICATOR);
520
1164
 
521
1165
    return menuitem;
522
1166
}
832
1476
    }
833
1477
}
834
1478
 
835
 
static gboolean
836
 
is_valid_session (GList* items, const gchar* session)
837
 
{
838
 
    for (; items; items = g_list_next (items))
839
 
        if (g_strcmp0 (session, lightdm_session_get_key (items->data)) == 0)
840
 
            return TRUE;
841
 
    return FALSE;
842
 
}
843
 
 
844
 
static gchar *
845
 
get_session (void)
846
 
{
847
 
    return g_strdup (current_session);
848
 
}
849
 
 
850
 
static void
851
 
set_session (const gchar *session)
852
 
{
853
 
    gchar *last_session = NULL;
854
 
    GList *sessions = lightdm_get_sessions ();
855
 
 
856
 
    /* Validation */
857
 
    if (!session || !is_valid_session (sessions, session))
858
 
    {
859
 
        /* previous session */
860
 
        last_session = g_key_file_get_value (state, "greeter", "last-session", NULL);
861
 
        if (last_session && g_strcmp0 (session, last_session) != 0 &&
862
 
            is_valid_session (sessions, last_session))
863
 
            session = last_session;
 
1479
/* Layout indicator */
 
1480
 
 
1481
static void
 
1482
layout_selected_cb (GtkCheckMenuItem *menuitem, gpointer user_data)
 
1483
{
 
1484
    if (gtk_check_menu_item_get_active (menuitem))
 
1485
    {
 
1486
        #ifdef HAVE_LIBXKLAVIER
 
1487
        gint group = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), LAYOUT_DATA_GROUP));
 
1488
        xkl_engine_lock_group (xkl_engine, group);
 
1489
        #else
 
1490
        const gchar *name = g_object_get_data (G_OBJECT (menuitem), LAYOUT_DATA_NAME);
 
1491
        GList *item;
 
1492
        for (item = lightdm_get_layouts (); item; item = g_list_next (item))
 
1493
        {
 
1494
            if (g_strcmp0 (name, lightdm_layout_get_name (item->data)) == 0)
 
1495
            {
 
1496
                lightdm_set_layout (item->data);
 
1497
                gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem),
 
1498
                                         g_object_get_data (G_OBJECT (menuitem), LAYOUT_DATA_LABEL));
 
1499
                break;
 
1500
            }
 
1501
        }
 
1502
        #endif
 
1503
    }
 
1504
}
 
1505
 
 
1506
static void
 
1507
update_layouts_menu (void)
 
1508
{
 
1509
    #ifdef HAVE_LIBXKLAVIER
 
1510
    XklConfigRegistry *registry;
 
1511
    XklConfigRec *config;
 
1512
    XklConfigItem *config_item;
 
1513
    GSList *menu_group = NULL;
 
1514
    gint i;
 
1515
 
 
1516
    g_list_free_full (gtk_container_get_children (GTK_CONTAINER (layout_menu)),
 
1517
                      (GDestroyNotify)gtk_widget_destroy);
 
1518
 
 
1519
    config = xkl_config_rec_new ();
 
1520
    if (!xkl_config_rec_get_from_server (config, xkl_engine))
 
1521
    {
 
1522
        g_object_unref (config);
 
1523
        g_warning ("Failed to get Xkl configuration from server");
 
1524
        return;
 
1525
    }
 
1526
 
 
1527
    config_item = xkl_config_item_new ();
 
1528
    registry = xkl_config_registry_get_instance (xkl_engine);
 
1529
    xkl_config_registry_load (registry, FALSE);
 
1530
 
 
1531
    for (i = 0; config->layouts[i] != NULL; ++i)
 
1532
    {
 
1533
        const gchar *layout = config->layouts[i] ? config->layouts[i] : "";
 
1534
        const gchar *variant = config->variants[i] ? config->variants[i] : "";
 
1535
        gchar *label = strlen (variant) > 0 ? g_strdup_printf ("%s_%s", layout, variant) : g_strdup (layout);
 
1536
 
 
1537
        GtkWidget *menuitem = gtk_radio_menu_item_new (menu_group);
 
1538
        menu_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
 
1539
 
 
1540
        g_snprintf (config_item->name, sizeof (config_item->name), "%s", variant);
 
1541
        if (xkl_config_registry_find_variant (registry, layout, config_item))
 
1542
            gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), config_item->description);
864
1543
        else
865
1544
        {
866
 
            /* default */
867
 
            const gchar* default_session = lightdm_greeter_get_default_session_hint (greeter);
868
 
            if (g_strcmp0 (session, default_session) != 0 &&
869
 
                is_valid_session (sessions, default_session))
870
 
                session = default_session;
871
 
            /* first in the sessions list */
872
 
            else if (sessions)
873
 
                session = lightdm_session_get_key (sessions->data);
874
 
            /* give up */
 
1545
            g_snprintf (config_item->name, sizeof (config_item->name), "%s", layout);
 
1546
            if (xkl_config_registry_find_layout (registry, config_item))
 
1547
                gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), config_item->description);
875
1548
            else
876
 
                session = NULL;
877
 
        }
878
 
    }
879
 
 
880
 
    if (gtk_widget_get_visible (session_menuitem))
881
 
    {
882
 
        GList *menu_iter = NULL;
883
 
        GList *menu_items = gtk_container_get_children (GTK_CONTAINER (session_menu));
884
 
        if (session)
885
 
        {
886
 
            for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next(menu_iter))
887
 
                if (g_strcmp0 (session, g_object_get_data (G_OBJECT (menu_iter->data), SESSION_DATA_KEY)) == 0)
888
 
                {
889
 
                    /* Set menuitem-image to session-badge */
890
 
                    GtkIconTheme *icon_theme = gtk_icon_theme_get_default();
891
 
                    gchar* session_name = g_ascii_strdown (session, -1);
892
 
                    gchar* icon_name = g_strdup_printf ("%s_badge-symbolic", session_name);
893
 
                    g_free (session_name);
894
 
                    if (gtk_icon_theme_has_icon(icon_theme, icon_name))
895
 
                        gtk_image_set_from_icon_name (GTK_IMAGE(session_badge), icon_name, GTK_ICON_SIZE_MENU);
896
 
                    else
897
 
                        gtk_image_set_from_icon_name (GTK_IMAGE(session_badge), "document-properties-symbolic", GTK_ICON_SIZE_MENU);
898
 
                    g_free (icon_name);
899
 
                    break;
900
 
                }
901
 
        }
902
 
        if (!menu_iter)
903
 
            menu_iter = menu_items;
904
 
 
905
 
        if (menu_iter)
906
 
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_iter->data), TRUE);
907
 
    }
908
 
 
909
 
    g_free (current_session);
910
 
    current_session = g_strdup(session);
911
 
    g_free (last_session);
912
 
}
913
 
 
914
 
static gchar *
915
 
get_language (void)
916
 
{
917
 
    GList *menu_items, *menu_iter;
918
 
 
919
 
    /* if the user manually selected a language, use it */
920
 
    if (current_language)
921
 
        return g_strdup (current_language);
922
 
 
923
 
    menu_items = gtk_container_get_children(GTK_CONTAINER(language_menu));    
924
 
    for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next(menu_iter))
925
 
    {
926
 
        if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_iter->data)))
927
 
            return g_strdup(g_object_get_data (G_OBJECT (menu_iter->data), LANGUAGE_DATA_CODE));
928
 
    }
929
 
 
930
 
    return NULL;
931
 
}
932
 
 
933
 
static void
934
 
set_language (const gchar *language)
935
 
{
936
 
    const gchar *default_language = NULL;    
937
 
    GList *menu_items, *menu_iter;
938
 
 
939
 
    if (!gtk_widget_get_visible (language_menuitem))
940
 
    {
941
 
        g_free (current_language);
942
 
        current_language = g_strdup (language);
943
 
        return;
944
 
    }
945
 
 
946
 
    menu_items = gtk_container_get_children(GTK_CONTAINER(language_menu));
947
 
 
948
 
    if (language)
949
 
    {
950
 
        for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next(menu_iter))
951
 
        {
952
 
            gchar *s;
953
 
            gboolean matched;
954
 
            s = g_strdup (g_object_get_data (G_OBJECT (menu_iter->data), LANGUAGE_DATA_CODE));
955
 
            matched = g_strcmp0 (s, language) == 0;
956
 
            g_free (s);
957
 
            if (matched)
958
 
            {
959
 
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_iter->data), TRUE);
960
 
                g_free (current_language);
961
 
                current_language = g_strdup(language);
962
 
                gtk_menu_item_set_label(GTK_MENU_ITEM(language_menuitem),language);
963
 
                return;
964
 
            }
965
 
        }
966
 
    }
967
 
 
968
 
    /* If failed to find this language, then try the default */
969
 
    if (lightdm_get_language ())
970
 
    {
971
 
        default_language = lightdm_language_get_code (lightdm_get_language ());
972
 
        gtk_menu_item_set_label(GTK_MENU_ITEM (language_menuitem), default_language);
973
 
    }
974
 
    if (default_language && g_strcmp0 (default_language, language) != 0)
975
 
        set_language (default_language);
976
 
    /* If all else fails, just use the first language from the menu */
977
 
    else
978
 
    {
979
 
        for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next(menu_iter))
980
 
        {
981
 
            if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_iter->data)))
982
 
            {
983
 
                gtk_menu_item_set_label (GTK_MENU_ITEM (language_menuitem), g_strdup (g_object_get_data (G_OBJECT (menu_iter->data), LANGUAGE_DATA_CODE)));
984
 
                break;
985
 
            }
986
 
        }
987
 
    }
988
 
}
989
 
 
990
 
static void
991
 
set_message_label (LightDMMessageType type, const gchar *text)
992
 
{
993
 
    if (type == LIGHTDM_MESSAGE_TYPE_INFO)
994
 
        gtk_info_bar_set_message_type (info_bar, GTK_MESSAGE_INFO);
995
 
    else
996
 
        gtk_info_bar_set_message_type (info_bar, GTK_MESSAGE_ERROR);
997
 
    gtk_label_set_text (message_label, text);
998
 
    gtk_widget_set_visible (GTK_WIDGET (info_bar), text && text[0]);
 
1549
                gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), label);
 
1550
        }
 
1551
 
 
1552
        g_object_set_data_full (G_OBJECT (menuitem), LAYOUT_DATA_LABEL, label, g_free);
 
1553
        g_object_set_data (G_OBJECT (menuitem), LAYOUT_DATA_GROUP, GINT_TO_POINTER (i));
 
1554
 
 
1555
        g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (layout_selected_cb), NULL);
 
1556
        gtk_menu_shell_append (GTK_MENU_SHELL (layout_menu), menuitem);
 
1557
        gtk_widget_show (GTK_WIDGET (menuitem));
 
1558
    }
 
1559
 
 
1560
    g_object_unref (registry);
 
1561
    g_object_unref (config_item);
 
1562
    g_object_unref (config);
 
1563
    #else
 
1564
    GSList *menu_group = NULL;
 
1565
    GList *item;
 
1566
 
 
1567
    g_list_free_full (gtk_container_get_children (GTK_CONTAINER (layout_menu)),
 
1568
                      (GDestroyNotify)gtk_widget_destroy);
 
1569
 
 
1570
    for (item = lightdm_get_layouts (); item; item = g_list_next (item))
 
1571
    {
 
1572
        LightDMLayout *layout = item->data;
 
1573
        GtkWidget *menuitem = gtk_radio_menu_item_new (menu_group);
 
1574
        menu_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
 
1575
 
 
1576
        g_object_set_data_full (G_OBJECT (menuitem), LAYOUT_DATA_LABEL,
 
1577
                                g_strdelimit (g_strdup (lightdm_layout_get_name (layout)), "\t ", '_'), g_free);
 
1578
        g_object_set_data_full (G_OBJECT (menuitem), LAYOUT_DATA_NAME,
 
1579
                                g_strdup (lightdm_layout_get_name (layout)), g_free);
 
1580
 
 
1581
        g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (layout_selected_cb), NULL);
 
1582
        gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), lightdm_layout_get_description (layout));
 
1583
        gtk_menu_shell_append (GTK_MENU_SHELL (layout_menu), menuitem);
 
1584
        gtk_widget_show (GTK_WIDGET (menuitem));
 
1585
    }
 
1586
    #endif
 
1587
}
 
1588
 
 
1589
static void
 
1590
update_layouts_menu_state (void)
 
1591
{
 
1592
    #ifdef HAVE_LIBXKLAVIER
 
1593
    XklState *state = xkl_engine_get_current_state (xkl_engine);
 
1594
    GList *menu_items = gtk_container_get_children (GTK_CONTAINER (layout_menu));
 
1595
    GtkCheckMenuItem *menu_item = g_list_nth_data (menu_items, state->group);
 
1596
 
 
1597
    if (menu_item)
 
1598
    {
 
1599
        gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem),
 
1600
                                 g_object_get_data (G_OBJECT (menu_item), LAYOUT_DATA_LABEL));
 
1601
        gtk_check_menu_item_set_active (menu_item, TRUE);
 
1602
    }
 
1603
    else
 
1604
        gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem), "??");
 
1605
    g_list_free (menu_items);
 
1606
    #else
 
1607
    LightDMLayout *layout = lightdm_get_layout ();
 
1608
    g_return_if_fail (layout != NULL);
 
1609
 
 
1610
    const gchar *name = lightdm_layout_get_name (layout);
 
1611
    GList *menu_items = gtk_container_get_children (GTK_CONTAINER (layout_menu));
 
1612
    GList *menu_iter;
 
1613
    for (menu_iter = menu_items; menu_iter; menu_iter = g_list_next (menu_iter))
 
1614
    {
 
1615
        if (g_strcmp0 (name, g_object_get_data (G_OBJECT (menu_iter->data), LAYOUT_DATA_NAME)) == 0)
 
1616
        {
 
1617
            gtk_check_menu_item_set_active (menu_iter->data, TRUE);
 
1618
            gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem),
 
1619
                                     g_object_get_data (G_OBJECT (menu_iter->data), LAYOUT_DATA_LABEL));
 
1620
            break;
 
1621
        }
 
1622
    }
 
1623
    g_list_free (menu_items);
 
1624
    #endif
 
1625
}
 
1626
 
 
1627
#ifdef HAVE_LIBXKLAVIER
 
1628
static void
 
1629
xkl_state_changed_cb (XklEngine *engine, XklEngineStateChange change, gint group,
 
1630
                      gboolean restore, gpointer user_data)
 
1631
{
 
1632
    if (change == GROUP_CHANGED)
 
1633
        update_layouts_menu_state ();
 
1634
}
 
1635
 
 
1636
static void
 
1637
xkl_config_changed_cb (XklEngine *engine, gpointer user_data)
 
1638
{
 
1639
    /* tip: xkl_config_rec_get_from_server() return old settings */
 
1640
    update_layouts_menu ();
 
1641
    update_layouts_menu_state ();
 
1642
}
 
1643
 
 
1644
static GdkFilterReturn
 
1645
xkl_xevent_filter (GdkXEvent *xev, GdkEvent *event, gpointer  data)
 
1646
{
 
1647
    XEvent *xevent = (XEvent *) xev;
 
1648
    xkl_engine_filter_events (xkl_engine, xevent);
 
1649
    return GDK_FILTER_CONTINUE;
 
1650
}
 
1651
#endif
 
1652
 
 
1653
/* a11y indciator */
 
1654
 
 
1655
void
 
1656
a11y_font_cb (GtkCheckMenuItem *item)
 
1657
{
 
1658
    if (gtk_check_menu_item_get_active (item))
 
1659
    {
 
1660
        gchar *font_name, **tokens;
 
1661
        guint length;
 
1662
 
 
1663
        g_object_get (gtk_settings_get_default (), "gtk-font-name", &font_name, NULL);
 
1664
        tokens = g_strsplit (font_name, " ", -1);
 
1665
        length = g_strv_length (tokens);
 
1666
        if (length > 1)
 
1667
        {
 
1668
            gint size = atoi (tokens[length - 1]);
 
1669
            if (size > 0)
 
1670
            {
 
1671
                g_free (tokens[length - 1]);
 
1672
                tokens[length - 1] = g_strdup_printf ("%d", size + 10);
 
1673
                g_free (font_name);
 
1674
                font_name = g_strjoinv (" ", tokens);
 
1675
            }
 
1676
        }
 
1677
        g_strfreev (tokens);
 
1678
 
 
1679
        g_object_set (gtk_settings_get_default (), "gtk-font-name", font_name, NULL);
 
1680
    }
 
1681
    else
 
1682
    {
 
1683
        g_object_set (gtk_settings_get_default (), "gtk-font-name", default_font_name, NULL);
 
1684
    }
 
1685
}
 
1686
 
 
1687
void
 
1688
a11y_contrast_cb (GtkCheckMenuItem *item)
 
1689
{
 
1690
    if (gtk_check_menu_item_get_active (item))
 
1691
    {
 
1692
        g_object_set (gtk_settings_get_default (), "gtk-theme-name", "HighContrast", NULL);
 
1693
        g_object_set (gtk_settings_get_default (), "gtk-icon-theme-name", "HighContrast", NULL);
 
1694
    }
 
1695
    else
 
1696
    {
 
1697
        g_object_set (gtk_settings_get_default (), "gtk-theme-name", default_theme_name, NULL);
 
1698
        g_object_set (gtk_settings_get_default (), "gtk-icon-theme-name", default_icon_theme_name, NULL);
 
1699
    }
 
1700
}
 
1701
 
 
1702
void
 
1703
a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data)
 
1704
{
 
1705
    if (gtk_check_menu_item_get_active (item))
 
1706
        menu_command_run (a11y_keyboard_command);
 
1707
    else
 
1708
        menu_command_stop (a11y_keyboard_command);
 
1709
}
 
1710
 
 
1711
void
 
1712
a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data)
 
1713
{
 
1714
    if (gtk_check_menu_item_get_active (item))
 
1715
        menu_command_run (a11y_reader_command);
 
1716
    else
 
1717
        menu_command_stop (a11y_reader_command);
 
1718
}
 
1719
 
 
1720
/* Power indicator */
 
1721
 
 
1722
static void
 
1723
power_menu_cb (GtkWidget *menuitem, gpointer userdata)
 
1724
{
 
1725
    gtk_widget_set_sensitive (suspend_menuitem, lightdm_get_can_suspend ());
 
1726
    gtk_widget_set_sensitive (hibernate_menuitem, lightdm_get_can_hibernate ());
 
1727
    gtk_widget_set_sensitive (restart_menuitem, lightdm_get_can_restart ());
 
1728
    gtk_widget_set_sensitive (shutdown_menuitem, lightdm_get_can_shutdown ());
 
1729
}
 
1730
 
 
1731
void
 
1732
suspend_cb (GtkWidget *widget, LightDMGreeter *greeter)
 
1733
{
 
1734
    lightdm_suspend (NULL);
 
1735
}
 
1736
 
 
1737
void
 
1738
hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter)
 
1739
{
 
1740
    lightdm_hibernate (NULL);
 
1741
}
 
1742
 
 
1743
void
 
1744
restart_cb (GtkWidget *widget, LightDMGreeter *greeter)
 
1745
{
 
1746
    if (show_power_prompt ("restart", "view-refresh-symbolic",
 
1747
                           _("Restart"),
 
1748
                           _("Are you sure you want to close all programs and restart the computer?")))
 
1749
        lightdm_restart (NULL);
 
1750
}
 
1751
 
 
1752
void
 
1753
shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter)
 
1754
{
 
1755
    if (show_power_prompt ("shutdown", "system-shutdown-symbolic",
 
1756
                           _("Shut Down"),
 
1757
                           _("Are you sure you want to close all programs and shut down the computer?")))
 
1758
        lightdm_shutdown (NULL);
999
1759
}
1000
1760
 
1001
1761
static void
1032
1792
}
1033
1793
 
1034
1794
static void
1035
 
set_user_image (const gchar *username)
1036
 
{
1037
 
    const gchar *path;
1038
 
    LightDMUser *user = NULL;
1039
 
    GdkPixbuf *image = NULL;
1040
 
    GError *error = NULL;
1041
 
 
1042
 
    if(!gtk_widget_get_visible (GTK_WIDGET (user_image)))
1043
 
        return;
1044
 
 
1045
 
    if (username)
1046
 
        user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username);
1047
 
 
1048
 
    if (user)
1049
 
    {
1050
 
        path = lightdm_user_get_image (user);
1051
 
        if (path)
1052
 
        {
1053
 
            image = gdk_pixbuf_new_from_file_at_scale (path, 80, 80, FALSE, &error);
1054
 
            if (image)
1055
 
            {
1056
 
                gtk_image_set_from_pixbuf (GTK_IMAGE (user_image), image);
1057
 
                g_object_unref (image);
1058
 
                return;
1059
 
            }
1060
 
            else
1061
 
            {
1062
 
                g_warning ("Failed to load user image: %s", error->message);
1063
 
                g_clear_error (&error);
1064
 
            }
1065
 
        }
1066
 
    }
1067
 
    
1068
 
    if (default_user_pixbuf)
1069
 
        gtk_image_set_from_pixbuf (GTK_IMAGE (user_image), default_user_pixbuf);
1070
 
    else
1071
 
        gtk_image_set_from_icon_name (GTK_IMAGE (user_image), default_user_icon, GTK_ICON_SIZE_DIALOG);
1072
 
}
1073
 
 
1074
 
/* Function translate user defined coordinates to absolute value */
1075
 
static gint
1076
 
get_absolute_position (const DimensionPosition *p, gint screen, gint window)
1077
 
{
1078
 
    gint x = p->percentage ? (screen*p->value)/100 : p->value;
1079
 
    x = p->sign < 0 ? screen - x : x;
1080
 
    if (p->anchor > 0)
1081
 
        x -= window;
1082
 
    else if (p->anchor == 0)
1083
 
        x -= window/2;
1084
 
 
1085
 
    if (x < 0)                     /* Offscreen: left/top */
1086
 
        return 0;
1087
 
    else if (x + window > screen)  /* Offscreen: right/bottom */
1088
 
        return screen - window;
1089
 
    else
1090
 
        return x;
1091
 
}
1092
 
 
1093
 
static void
1094
 
center_window (GtkWindow *window, GtkAllocation *allocation, const WindowPosition *pos)
1095
 
{   
1096
 
    const GdkRectangle *monitor_geometry = greeter_background_get_active_monitor_geometry (greeter_background);
1097
 
    GtkAllocation *new_allocation = NULL;
1098
 
    if (!allocation)
1099
 
    {
1100
 
        allocation = new_allocation = g_new0 (GtkAllocation, 1);
1101
 
        gtk_widget_get_allocation (GTK_WIDGET (window), new_allocation);
1102
 
    }
1103
 
    if (monitor_geometry)
1104
 
        gtk_window_move (window,
1105
 
                         monitor_geometry->x + get_absolute_position (&pos->x, monitor_geometry->width, allocation->width),
1106
 
                         monitor_geometry->y + get_absolute_position (&pos->y, monitor_geometry->height, allocation->height));
1107
 
    g_free (new_allocation);
1108
 
}
1109
 
 
1110
 
static void
1111
 
active_monitor_changed_cb (GreeterBackground *background, gpointer user_data)
1112
 
{
1113
 
    const GdkRectangle *monitor_geometry = greeter_background_get_active_monitor_geometry (greeter_background);
1114
 
    if (monitor_geometry)
1115
 
    {
1116
 
        GdkGeometry hints;
1117
 
        hints.min_width = monitor_geometry->width;
1118
 
        hints.max_width = monitor_geometry->width;
1119
 
        hints.min_height = -1;
1120
 
        hints.max_height = -1;
1121
 
        gtk_window_set_geometry_hints (panel_window, GTK_WIDGET(panel_window),
1122
 
                                       &hints, GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
1123
 
    }
1124
 
}
1125
 
 
1126
 
static void
1127
1795
start_authentication (const gchar *username)
1128
1796
{
1129
1797
    cancelling = FALSE;
1243
1911
    g_free (session);
1244
1912
}
1245
1913
 
1246
 
void
1247
 
session_selected_cb(GtkMenuItem *menuitem, gpointer user_data);
1248
 
G_MODULE_EXPORT
1249
 
void
1250
 
session_selected_cb(GtkMenuItem *menuitem, gpointer user_data)
1251
 
{
1252
 
    if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)))
1253
 
       set_session(g_object_get_data (G_OBJECT (menuitem), SESSION_DATA_KEY));
1254
 
}
1255
 
 
1256
 
void
1257
 
language_selected_cb(GtkMenuItem *menuitem, gpointer user_data);
1258
 
G_MODULE_EXPORT
1259
 
void
1260
 
language_selected_cb(GtkMenuItem *menuitem, gpointer user_data)
1261
 
{
1262
 
    if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)))
1263
 
    {
1264
 
       gchar *language = g_object_get_data (G_OBJECT (menuitem), LANGUAGE_DATA_CODE);
1265
 
       set_language(language);
1266
 
    }
1267
 
}
1268
 
 
1269
 
static void
1270
 
power_menu_cb (GtkWidget *menuitem, gpointer userdata)
1271
 
{
1272
 
    gtk_widget_set_sensitive (suspend_menuitem, lightdm_get_can_suspend());
1273
 
    gtk_widget_set_sensitive (hibernate_menuitem, lightdm_get_can_hibernate());
1274
 
    gtk_widget_set_sensitive (restart_menuitem, lightdm_get_can_restart());
1275
 
    gtk_widget_set_sensitive (shutdown_menuitem, lightdm_get_can_shutdown());
1276
 
}
1277
 
 
1278
1914
gboolean
1279
1915
password_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
1280
1916
G_MODULE_EXPORT
1282
1918
password_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
1283
1919
{
1284
1920
    if ((event->keyval == GDK_KEY_Up || event->keyval == GDK_KEY_Down) &&
1285
 
        gtk_widget_get_visible(GTK_WIDGET(user_combo)))
 
1921
        gtk_widget_get_visible (GTK_WIDGET (user_combo)))
1286
1922
    {
1287
1923
        gboolean available;
1288
1924
        GtkTreeIter iter;
1318
1954
gboolean
1319
1955
username_focus_out_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
1320
1956
{
1321
 
    if (!g_strcmp0(gtk_entry_get_text(username_entry), "") == 0)
1322
 
        start_authentication(gtk_entry_get_text(username_entry));
 
1957
    if (!g_strcmp0(gtk_entry_get_text (username_entry), "") == 0)
 
1958
        start_authentication (gtk_entry_get_text (username_entry));
1323
1959
    return FALSE;
1324
1960
}
1325
1961
 
1355
1991
    case GDK_KEY_F9: case GDK_KEY_F10:
1356
1992
    case GDK_KEY_F11: case GDK_KEY_F12:
1357
1993
        gtk_menu_shell_cancel (GTK_MENU_SHELL (menubar));
1358
 
        gtk_window_present (login_window);
1359
1994
        return TRUE;
1360
1995
    default:
1361
1996
        return FALSE;
1400
2035
    {
1401
2036
        gtk_widget_show (GTK_WIDGET (username_entry));
1402
2037
        gtk_widget_show (GTK_WIDGET (cancel_button));
1403
 
        user_tooltip = g_strdup(_("Other"));
 
2038
        user_tooltip = g_strdup (_("Other"));
1404
2039
    }
1405
2040
    else
1406
2041
    {
1407
2042
        gtk_widget_hide (GTK_WIDGET (username_entry));
1408
2043
        gtk_widget_hide (GTK_WIDGET (cancel_button));
1409
 
        user_tooltip = g_strdup(username);
 
2044
        user_tooltip = g_strdup (username);
1410
2045
    }
1411
2046
 
1412
2047
    /* At this moment we do not have information about possible prompts
1417
2052
 
1418
2053
    if (g_strcmp0 (username, "*guest") == 0)
1419
2054
    {
1420
 
        user_tooltip = g_strdup(_("Guest Session"));
 
2055
        user_tooltip = g_strdup (_("Guest Session"));
1421
2056
        gtk_widget_hide (GTK_WIDGET (password_entry));
1422
2057
        gtk_widget_grab_focus (GTK_WIDGET (user_combo));
1423
2058
    }
1454
2089
 
1455
2090
        gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 0, &user, -1);
1456
2091
 
1457
 
        set_displayed_user(greeter, user);
 
2092
        set_displayed_user (greeter, user);
1458
2093
 
1459
2094
        g_free (user);
1460
2095
    }
1461
2096
    set_message_label (LIGHTDM_MESSAGE_TYPE_INFO, NULL);
1462
2097
}
1463
2098
 
1464
 
static const gchar*
1465
 
get_message_label (void)
1466
 
{
1467
 
    return gtk_label_get_text (message_label);
1468
 
}
1469
 
 
1470
 
static void
1471
 
process_prompts (LightDMGreeter *greeter)
1472
 
{
1473
 
    if (!pending_questions)
1474
 
        return;
1475
 
 
1476
 
    /* always allow the user to change username again */
1477
 
    gtk_widget_set_sensitive (GTK_WIDGET (username_entry), TRUE);
1478
 
    gtk_widget_set_sensitive (GTK_WIDGET (password_entry), TRUE);
1479
 
 
1480
 
    /* Special case: no user selected from list, so PAM asks us for the user
1481
 
     * via a prompt. For that case, use the username field */
1482
 
    if (!prompted && pending_questions && !pending_questions->next &&
1483
 
        ((PAMConversationMessage *) pending_questions->data)->is_prompt &&
1484
 
        ((PAMConversationMessage *) pending_questions->data)->type.prompt != LIGHTDM_PROMPT_TYPE_SECRET &&
1485
 
        gtk_widget_get_visible ((GTK_WIDGET (username_entry))) &&
1486
 
        lightdm_greeter_get_authentication_user (greeter) == NULL)
1487
 
    {
1488
 
        prompted = TRUE;
1489
 
        prompt_active = TRUE;
1490
 
        gtk_widget_grab_focus (GTK_WIDGET (username_entry));
1491
 
        gtk_widget_show (GTK_WIDGET (password_entry));
1492
 
        return;
1493
 
    }
1494
 
 
1495
 
    while (pending_questions)
1496
 
    {
1497
 
        PAMConversationMessage *message = (PAMConversationMessage *) pending_questions->data;
1498
 
        pending_questions = g_slist_remove (pending_questions, (gconstpointer) message);
1499
 
 
1500
 
        if (!message->is_prompt)
1501
 
        {
1502
 
            /* FIXME: this doesn't show multiple messages, but that was
1503
 
             * already the case before. */
1504
 
            set_message_label (message->type.message, message->text);
1505
 
            continue;
1506
 
        }
1507
 
 
1508
 
        gtk_widget_show (GTK_WIDGET (password_entry));
1509
 
        gtk_widget_grab_focus (GTK_WIDGET (password_entry));
1510
 
        gtk_entry_set_text (password_entry, "");
1511
 
        gtk_entry_set_visibility (password_entry, message->type.prompt != LIGHTDM_PROMPT_TYPE_SECRET);
1512
 
        if (get_message_label()[0] == 0 && password_prompted)
1513
 
        {
1514
 
            /* No message was provided beforehand and this is not the
1515
 
             * first password prompt, so use the prompt as label,
1516
 
             * otherwise the user will be completely unclear of what
1517
 
             * is going on. Actually, the fact that prompt messages are
1518
 
             * not shown is problematic in general, especially if
1519
 
             * somebody uses a custom PAM module that wants to ask
1520
 
             * something different. */
1521
 
            gchar *str = message->text;
1522
 
            if (g_str_has_suffix (str, ": "))
1523
 
                str = g_strndup (str, strlen (str) - 2);
1524
 
            else if (g_str_has_suffix (str, ":"))
1525
 
                str = g_strndup (str, strlen (str) - 1);
1526
 
            set_message_label (LIGHTDM_MESSAGE_TYPE_INFO, str);
1527
 
            if (str != message->text)
1528
 
                g_free (str);
1529
 
        }
1530
 
        gtk_widget_grab_focus (GTK_WIDGET (password_entry));
1531
 
        prompted = TRUE;
1532
 
        password_prompted = TRUE;
1533
 
        prompt_active = TRUE;
1534
 
 
1535
 
        /* If we have more stuff after a prompt, assume that other prompts are pending,
1536
 
         * so stop here. */
1537
 
        break;
1538
 
    }
1539
 
}
1540
 
 
1541
2099
void login_cb (GtkWidget *widget);
1542
2100
G_MODULE_EXPORT
1543
2101
void
1545
2103
{
1546
2104
    /* Reset to default screensaver values */
1547
2105
    if (lightdm_greeter_get_lock_hint (greeter))
1548
 
        XSetScreenSaver(gdk_x11_display_get_xdisplay(gdk_display_get_default ()), timeout, interval, prefer_blanking, allow_exposures);        
 
2106
        XSetScreenSaver (gdk_x11_display_get_xdisplay (gdk_display_get_default ()), timeout, interval, prefer_blanking, allow_exposures);
1549
2107
 
1550
2108
    gtk_widget_set_sensitive (GTK_WIDGET (username_entry), FALSE);
1551
2109
    gtk_widget_set_sensitive (GTK_WIDGET (password_entry), FALSE);
1659
2217
        /* If an error message is already printed we do not print it this statement
1660
2218
         * The error message probably comes from the PAM module that has a better knowledge
1661
2219
         * of the failure. */
1662
 
        gboolean have_pam_error = get_message_label()[0] &&
 
2220
        gboolean have_pam_error = !message_label_is_empty () &&
1663
2221
                                  gtk_info_bar_get_message_type (info_bar) != GTK_MESSAGE_ERROR;
1664
2222
        if (prompted)
1665
2223
        {
1676
2234
    }
1677
2235
}
1678
2236
 
1679
 
void suspend_cb (GtkWidget *widget, LightDMGreeter *greeter);
1680
 
G_MODULE_EXPORT
1681
 
void
1682
 
suspend_cb (GtkWidget *widget, LightDMGreeter *greeter)
1683
 
{
1684
 
    lightdm_suspend (NULL);
1685
 
}
1686
 
 
1687
 
void hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter);
1688
 
G_MODULE_EXPORT
1689
 
void
1690
 
hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter)
1691
 
{
1692
 
    lightdm_hibernate (NULL);
1693
 
}
1694
 
 
1695
 
static gboolean
1696
 
show_power_prompt (const gchar* action, const gchar* message, const gchar* icon,
1697
 
                   const gchar* dialog_name, const gchar* button_name)
1698
 
{
1699
 
    GtkWidget *dialog;
1700
 
    GtkWidget *image;
1701
 
    GtkWidget *button;
1702
 
    gboolean   result;
1703
 
    const GList *items, *item;
1704
 
    gint logged_in_users = 0;
1705
 
    gchar *warning;
1706
 
    
1707
 
    /* Check if there are still users logged in, count them and if so, display a warning */
1708
 
    items = lightdm_user_list_get_users (lightdm_user_list_get_instance ());
1709
 
    for (item = items; item; item = item->next)
1710
 
    {
1711
 
        LightDMUser *user = item->data;
1712
 
        if (lightdm_user_get_logged_in (user))
1713
 
            logged_in_users++;
1714
 
    }
1715
 
    if (logged_in_users > 0)
1716
 
    {
1717
 
        if (logged_in_users > 1)
1718
 
            warning = g_strdup_printf (_("Warning: There are still %d users logged in."), logged_in_users);
1719
 
        else
1720
 
            warning = g_strdup_printf (_("Warning: There is still %d user logged in."), logged_in_users);
1721
 
        message = g_markup_printf_escaped ("<b>%s</b>\n%s", warning, message);
1722
 
        g_free (warning);
1723
 
    }
1724
 
 
1725
 
    /* Prepare the dialog */
1726
 
    dialog = gtk_message_dialog_new (NULL,
1727
 
                                     GTK_DIALOG_MODAL,
1728
 
                                     GTK_MESSAGE_OTHER,
1729
 
                                     GTK_BUTTONS_NONE,
1730
 
                                     "%s", action);
1731
 
    gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);        
1732
 
    button = gtk_dialog_add_button(GTK_DIALOG (dialog), _("Cancel"), GTK_RESPONSE_CANCEL);
1733
 
    gtk_widget_set_name(button, "cancel_button");
1734
 
    button = gtk_dialog_add_button(GTK_DIALOG (dialog), action, GTK_RESPONSE_OK);
1735
 
    gtk_widget_set_name(button, button_name);
1736
 
 
1737
 
    /* Add the icon */
1738
 
    image = gtk_image_new_from_icon_name(icon, GTK_ICON_SIZE_DIALOG);
1739
 
    gtk_message_dialog_set_image(GTK_MESSAGE_DIALOG(dialog), image);
1740
 
 
1741
 
    /* Make the dialog themeable and attractive */
1742
 
    gtk_style_context_add_class (GTK_STYLE_CONTEXT (gtk_widget_get_style_context (GTK_WIDGET (dialog))), "lightdm-gtk-greeter");
1743
 
    gtk_widget_set_name (dialog, dialog_name);
1744
 
    gtk_container_set_border_width (GTK_CONTAINER (dialog), 18);
1745
 
 
1746
 
    greeter_background_add_subwindow (greeter_background, GTK_WINDOW (dialog));
1747
 
 
1748
 
    /* Hide the login window and show the dialog */
1749
 
    gtk_widget_hide (GTK_WIDGET (login_window));
1750
 
    gtk_widget_show_all (dialog);
1751
 
    center_window (GTK_WINDOW (dialog), NULL, &WINDOW_POS_CENTER);
1752
 
 
1753
 
    result = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK;
1754
 
 
1755
 
    greeter_background_remove_subwindow(greeter_background, GTK_WINDOW (dialog));
1756
 
    gtk_widget_destroy (dialog);
1757
 
    gtk_widget_show (GTK_WIDGET (login_window));
1758
 
    gtk_widget_queue_resize(GTK_WIDGET (login_window));
1759
 
 
1760
 
    return result;
1761
 
}
1762
 
 
1763
 
void restart_cb (GtkWidget *widget, LightDMGreeter *greeter);
1764
 
G_MODULE_EXPORT
1765
 
void
1766
 
restart_cb (GtkWidget *widget, LightDMGreeter *greeter)
1767
 
{
1768
 
    if (show_power_prompt(_("Restart"), _("Are you sure you want to close all programs and restart the computer?"),
1769
 
                          "view-refresh-symbolic", "restart_dialog", "restart_button"))
1770
 
        lightdm_restart (NULL);
1771
 
}
1772
 
 
1773
 
void shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter);
1774
 
G_MODULE_EXPORT
1775
 
void
1776
 
shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter)
1777
 
{
1778
 
    if (show_power_prompt(_("Shut Down"), _("Are you sure you want to close all programs and shut down the computer?"),
1779
 
                          "system-shutdown-symbolic", "shutdown_dialog", "shutdown_button"))
1780
 
        lightdm_shutdown (NULL);
1781
 
}
1782
 
 
1783
2237
static void
1784
2238
user_added_cb (LightDMUserList *user_list, LightDMUser *user, LightDMGreeter *greeter)
1785
2239
{
1856
2310
    gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
1857
2311
}
1858
2312
 
1859
 
void a11y_font_cb (GtkCheckMenuItem *item);
1860
 
G_MODULE_EXPORT
1861
 
void
1862
 
a11y_font_cb (GtkCheckMenuItem *item)
1863
 
{
1864
 
    if (gtk_check_menu_item_get_active (item))
1865
 
    {
1866
 
        gchar *font_name, **tokens;
1867
 
        guint length;
1868
 
 
1869
 
        g_object_get (gtk_settings_get_default (), "gtk-font-name", &font_name, NULL);
1870
 
        tokens = g_strsplit (font_name, " ", -1);
1871
 
        length = g_strv_length (tokens);
1872
 
        if (length > 1)
1873
 
        {
1874
 
            gint size = atoi (tokens[length - 1]);
1875
 
            if (size > 0)
1876
 
            {
1877
 
                g_free (tokens[length - 1]);
1878
 
                tokens[length - 1] = g_strdup_printf ("%d", size + 10);
1879
 
                g_free (font_name);
1880
 
                font_name = g_strjoinv (" ", tokens);
1881
 
            }
1882
 
        }
1883
 
        g_strfreev (tokens);
1884
 
 
1885
 
        g_object_set (gtk_settings_get_default (), "gtk-font-name", font_name, NULL);
1886
 
    }
1887
 
    else
1888
 
    {
1889
 
        g_object_set (gtk_settings_get_default (), "gtk-font-name", default_font_name, NULL);
1890
 
    }
1891
 
}
1892
 
 
1893
 
void a11y_contrast_cb (GtkCheckMenuItem *item);
1894
 
G_MODULE_EXPORT
1895
 
void
1896
 
a11y_contrast_cb (GtkCheckMenuItem *item)
1897
 
{
1898
 
    if (gtk_check_menu_item_get_active (item))
1899
 
    {
1900
 
        g_object_set (gtk_settings_get_default (), "gtk-theme-name", "HighContrast", NULL);
1901
 
        g_object_set (gtk_settings_get_default (), "gtk-icon-theme-name", "HighContrast", NULL);
1902
 
    }
1903
 
    else
1904
 
    {
1905
 
        g_object_set (gtk_settings_get_default (), "gtk-theme-name", default_theme_name, NULL);
1906
 
        g_object_set (gtk_settings_get_default (), "gtk-icon-theme-name", default_icon_theme_name, NULL);
1907
 
    }
1908
 
}
1909
 
 
1910
 
void a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data);
1911
 
G_MODULE_EXPORT
1912
 
void
1913
 
a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data)
1914
 
{
1915
 
    if (gtk_check_menu_item_get_active (item))
1916
 
        menu_command_run (a11y_keyboard_command);
1917
 
    else
1918
 
        menu_command_stop (a11y_keyboard_command);
1919
 
}
1920
 
 
1921
 
void a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data);
1922
 
G_MODULE_EXPORT
1923
 
void
1924
 
a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data)
1925
 
{
1926
 
    if (gtk_check_menu_item_get_active (item))
1927
 
        menu_command_run (a11y_reader_command);
1928
 
    else
1929
 
        menu_command_stop (a11y_reader_command);
1930
 
}
1931
 
 
1932
2313
static void
1933
2314
load_user_list (void)
1934
2315
{
1988
2369
    {
1989
2370
        gchar *name;
1990
2371
        gboolean matched = FALSE;
1991
 
        
 
2372
 
1992
2373
        if (selected_user)
1993
2374
        {
1994
2375
            do
2009
2390
            gtk_tree_model_get_iter_first (model, &iter);
2010
2391
            gtk_tree_model_get (model, &iter, 0, &name, -1);
2011
2392
            gtk_combo_box_set_active_iter (user_combo, &iter);
2012
 
            set_displayed_user(greeter, name);
2013
 
            g_free(name);
 
2393
            set_displayed_user (greeter, name);
 
2394
            g_free (name);
2014
2395
        }
2015
 
        
 
2396
 
2016
2397
    }
2017
2398
 
2018
2399
    g_free (last_user);
2019
2400
}
2020
2401
 
2021
 
static gboolean
2022
 
clock_timeout_thread (void)
2023
 
{
2024
 
    time_t rawtime;
2025
 
    struct tm * timeinfo;
2026
 
    gchar time_str[50];
2027
 
    gchar *markup;
2028
 
    
2029
 
    time ( &rawtime );
2030
 
    timeinfo = localtime ( &rawtime );
2031
 
    
2032
 
    strftime(time_str, 50, clock_format, timeinfo);
2033
 
    markup = g_markup_printf_escaped("<b>%s</b>", time_str);
2034
 
    if (g_strcmp0(markup, gtk_label_get_label (GTK_LABEL (clock_label))) != 0)
2035
 
        gtk_label_set_markup (GTK_LABEL (clock_label), markup);
2036
 
    g_free(markup);
2037
 
    
2038
 
    return TRUE;
2039
 
}
2040
 
 
2041
 
static gboolean
2042
 
read_position_from_str (const gchar *s, DimensionPosition *x)
2043
 
{
2044
 
    DimensionPosition p;
2045
 
    gchar *end = NULL;
2046
 
    gchar **parts = g_strsplit(s, ",", 2);
2047
 
    if (parts[0])
2048
 
    {
2049
 
        p.value = g_ascii_strtoll(parts[0], &end, 10);
2050
 
        p.percentage = end && end[0] == '%';
2051
 
        p.sign = (p.value < 0 || (p.value == 0 && parts[0][0] == '-')) ? -1 : +1;
2052
 
        if (p.value < 0)
2053
 
            p.value *= -1;
2054
 
        if (g_strcmp0(parts[1], "start") == 0)
2055
 
            p.anchor = -1;
2056
 
        else if (g_strcmp0(parts[1], "center") == 0)
2057
 
            p.anchor = 0;
2058
 
        else if (g_strcmp0(parts[1], "end") == 0)
2059
 
            p.anchor = +1;
2060
 
        else
2061
 
            p.anchor = p.sign > 0 ? -1 : +1;
2062
 
        *x = p;
2063
 
    }
2064
 
    else
2065
 
        x = NULL;
2066
 
    g_strfreev (parts);
2067
 
    return x != NULL;
2068
 
}
2069
 
 
2070
2402
static GdkFilterReturn
2071
2403
focus_upon_map (GdkXEvent *gxevent, GdkEvent *event, gpointer  data)
2072
2404
{
2112
2444
    return GDK_FILTER_CONTINUE;
2113
2445
}
2114
2446
 
2115
 
/* Layout functions and callbacks */
2116
 
 
2117
 
static void
2118
 
layout_selected_cb(GtkCheckMenuItem *menuitem, gpointer user_data)
2119
 
{
2120
 
    if (gtk_check_menu_item_get_active (menuitem))
2121
 
    {
2122
 
        #ifdef HAVE_LIBXKLAVIER
2123
 
        gint group = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), LAYOUT_DATA_GROUP));
2124
 
        xkl_engine_lock_group (xkl_engine, group);
2125
 
        #else
2126
 
        const gchar *name = g_object_get_data (G_OBJECT (menuitem), LAYOUT_DATA_NAME);
2127
 
        GList *item;
2128
 
        for (item = lightdm_get_layouts (); item; item = g_list_next (item))
2129
 
        {
2130
 
            if (g_strcmp0 (name, lightdm_layout_get_name (item->data)) == 0)
2131
 
            {
2132
 
                lightdm_set_layout (item->data);
2133
 
                gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem),
2134
 
                                         g_object_get_data (G_OBJECT (menuitem), LAYOUT_DATA_LABEL));
2135
 
                break;
2136
 
            }
2137
 
        }
2138
 
        #endif
2139
 
    }
2140
 
}
2141
 
 
2142
 
static void
2143
 
update_layouts_menu (void)
2144
 
{
2145
 
    #ifdef HAVE_LIBXKLAVIER
2146
 
    XklConfigRegistry *registry;
2147
 
    XklConfigRec *config;
2148
 
    XklConfigItem *config_item;
2149
 
    GSList *menu_group = NULL;
2150
 
    gint i;
2151
 
 
2152
 
    g_list_free_full (gtk_container_get_children (GTK_CONTAINER (layout_menu)),
2153
 
                      (GDestroyNotify)gtk_widget_destroy);
2154
 
 
2155
 
    config = xkl_config_rec_new ();
2156
 
    if (!xkl_config_rec_get_from_server (config, xkl_engine))
2157
 
    {
2158
 
        g_object_unref (config);
2159
 
        g_warning ("Failed to get Xkl configuration from server");
2160
 
        return;
2161
 
    }
2162
 
 
2163
 
    config_item = xkl_config_item_new ();
2164
 
    registry = xkl_config_registry_get_instance (xkl_engine);
2165
 
    xkl_config_registry_load (registry, FALSE);
2166
 
 
2167
 
    for (i = 0; config->layouts[i] != NULL; ++i)
2168
 
    {
2169
 
        const gchar *layout = config->layouts[i] ? config->layouts[i] : "";
2170
 
        const gchar *variant = config->variants[i] ? config->variants[i] : "";
2171
 
        gchar *label = strlen (variant) > 0 ? g_strdup_printf ("%s_%s", layout, variant) : g_strdup (layout);
2172
 
 
2173
 
        GtkWidget *menuitem = gtk_radio_menu_item_new (menu_group);
2174
 
        menu_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
2175
 
 
2176
 
        g_snprintf (config_item->name, sizeof (config_item->name), "%s", variant);
2177
 
        if (xkl_config_registry_find_variant (registry, layout, config_item))
2178
 
            gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), config_item->description);
2179
 
        else
2180
 
        {
2181
 
            g_snprintf (config_item->name, sizeof (config_item->name), "%s", layout);
2182
 
            if (xkl_config_registry_find_layout (registry, config_item))
2183
 
                gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), config_item->description);
2184
 
            else
2185
 
                gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), label);
2186
 
        }
2187
 
 
2188
 
        g_object_set_data_full (G_OBJECT (menuitem), LAYOUT_DATA_LABEL, label, g_free);
2189
 
        g_object_set_data (G_OBJECT (menuitem), LAYOUT_DATA_GROUP, GINT_TO_POINTER (i));
2190
 
 
2191
 
        g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (layout_selected_cb), NULL);
2192
 
        gtk_menu_shell_append (GTK_MENU_SHELL (layout_menu), menuitem);
2193
 
        gtk_widget_show (GTK_WIDGET (menuitem));
2194
 
    }
2195
 
 
2196
 
    g_object_unref (registry);
2197
 
    g_object_unref (config_item);
2198
 
    g_object_unref (config);
2199
 
    #else
2200
 
    GSList *menu_group = NULL;
2201
 
    GList *item;
2202
 
 
2203
 
    g_list_free_full (gtk_container_get_children (GTK_CONTAINER (layout_menu)),
2204
 
                      (GDestroyNotify)gtk_widget_destroy);
2205
 
 
2206
 
    for (item = lightdm_get_layouts (); item; item = g_list_next (item))
2207
 
    {
2208
 
        LightDMLayout *layout = item->data;
2209
 
        GtkWidget *menuitem = gtk_radio_menu_item_new (menu_group);
2210
 
        menu_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
2211
 
 
2212
 
        g_object_set_data_full (G_OBJECT (menuitem), LAYOUT_DATA_LABEL,
2213
 
                                g_strdelimit (g_strdup (lightdm_layout_get_name (layout)), "\t ", '_'), g_free);
2214
 
        g_object_set_data_full (G_OBJECT (menuitem), LAYOUT_DATA_NAME,
2215
 
                                g_strdup (lightdm_layout_get_name (layout)), g_free);
2216
 
 
2217
 
        g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (layout_selected_cb), NULL);
2218
 
        gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), lightdm_layout_get_description (layout));
2219
 
        gtk_menu_shell_append (GTK_MENU_SHELL (layout_menu), menuitem);
2220
 
        gtk_widget_show (GTK_WIDGET (menuitem));
2221
 
    }
2222
 
    #endif
2223
 
}
2224
 
 
2225
 
static void
2226
 
update_layouts_menu_state (void)
2227
 
{
2228
 
    #ifdef HAVE_LIBXKLAVIER
2229
 
    XklState *state = xkl_engine_get_current_state (xkl_engine);
2230
 
    GList *menu_items = gtk_container_get_children (GTK_CONTAINER (layout_menu));
2231
 
    GtkCheckMenuItem *menu_item = g_list_nth_data (menu_items, state->group);
2232
 
 
2233
 
    if (menu_item)
2234
 
    {
2235
 
        gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem),
2236
 
                                 g_object_get_data (G_OBJECT (menu_item), LAYOUT_DATA_LABEL));
2237
 
        gtk_check_menu_item_set_active(menu_item, TRUE);
2238
 
    }
2239
 
    else
2240
 
        gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem), "??");
2241
 
    g_list_free (menu_items);
2242
 
    #else
2243
 
    LightDMLayout *layout = lightdm_get_layout ();
2244
 
    g_return_if_fail (layout != NULL);
2245
 
 
2246
 
    const gchar *name = lightdm_layout_get_name (layout);
2247
 
    GList *menu_items = gtk_container_get_children (GTK_CONTAINER (layout_menu));
2248
 
    GList *menu_iter;
2249
 
    for (menu_iter = menu_items; menu_iter; menu_iter = g_list_next (menu_iter))
2250
 
    {
2251
 
        if (g_strcmp0 (name, g_object_get_data (G_OBJECT (menu_iter->data), LAYOUT_DATA_NAME)) == 0)
2252
 
        {
2253
 
            gtk_check_menu_item_set_active (menu_iter->data, TRUE);
2254
 
            gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem),
2255
 
                                     g_object_get_data (G_OBJECT (menu_iter->data), LAYOUT_DATA_LABEL));
2256
 
            break;
2257
 
        }
2258
 
    }
2259
 
    g_list_free (menu_items);
2260
 
    #endif
2261
 
}
2262
 
 
2263
 
#ifdef HAVE_LIBXKLAVIER
2264
 
static void
2265
 
xkl_state_changed_cb (XklEngine *engine, XklEngineStateChange change, gint group,
2266
 
                      gboolean restore, gpointer user_data)
2267
 
{
2268
 
    if (change == GROUP_CHANGED)
2269
 
        update_layouts_menu_state ();
2270
 
}
2271
 
 
2272
 
static void
2273
 
xkl_config_changed_cb (XklEngine *engine, gpointer user_data)
2274
 
{
2275
 
    /* tip: xkl_config_rec_get_from_server() return old settings */
2276
 
    update_layouts_menu ();
2277
 
    update_layouts_menu_state ();
2278
 
}
2279
 
 
2280
 
static GdkFilterReturn
2281
 
xkl_xevent_filter (GdkXEvent *xev, GdkEvent *event, gpointer  data)
2282
 
{
2283
 
    XEvent *xevent = (XEvent *) xev;
2284
 
    xkl_engine_filter_events (xkl_engine, xevent);
2285
 
    return GDK_FILTER_CONTINUE;
2286
 
}
2287
 
#endif
2288
 
 
2289
2447
int
2290
2448
main (int argc, char **argv)
2291
2449
{
2318
2476
    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
2319
2477
    textdomain (GETTEXT_PACKAGE);
2320
2478
 
2321
 
    g_unix_signal_add(SIGTERM, (GSourceFunc)gtk_main_quit, NULL);
 
2479
    g_unix_signal_add (SIGTERM, (GSourceFunc)gtk_main_quit, NULL);
2322
2480
 
2323
2481
    /* init gtk */
2324
2482
    gtk_init (&argc, &argv);
2325
 
    
 
2483
 
2326
2484
#ifdef HAVE_LIBIDO
2327
2485
    ido_init ();
2328
2486
#endif
2345
2503
    g_clear_error (&error);
2346
2504
 
2347
2505
    greeter = lightdm_greeter_new ();
2348
 
    g_signal_connect (greeter, "show-prompt", G_CALLBACK (show_prompt_cb), NULL);  
 
2506
    g_signal_connect (greeter, "show-prompt", G_CALLBACK (show_prompt_cb), NULL);
2349
2507
    g_signal_connect (greeter, "show-message", G_CALLBACK (show_message_cb), NULL);
2350
2508
    g_signal_connect (greeter, "authentication-complete", G_CALLBACK (authentication_complete_cb), NULL);
2351
2509
    g_signal_connect (greeter, "autologin-timer-expired", G_CALLBACK (lightdm_greeter_authenticate_autologin), NULL);
2362
2520
    if (value)
2363
2521
        screensaver_timeout = g_ascii_strtoll (value, &end_ptr, 0);
2364
2522
    g_free (value);
2365
 
    
2366
 
    display = gdk_x11_display_get_xdisplay(gdk_display_get_default ());
 
2523
 
 
2524
    display = gdk_x11_display_get_xdisplay (gdk_display_get_default ());
2367
2525
    if (lightdm_greeter_get_lock_hint (greeter))
2368
2526
    {
2369
2527
        XGetScreenSaver (display, &timeout, &interval, &prefer_blanking, &allow_exposures);
2400
2558
    }
2401
2559
    else
2402
2560
    {
2403
 
        value = g_strdup("Sans 10");
 
2561
        value = g_strdup ("Sans 10");
2404
2562
        g_object_set (gtk_settings_get_default (), "gtk-font-name", value, NULL);
2405
2563
    }
2406
 
    g_object_get (gtk_settings_get_default (), "gtk-font-name", &default_font_name, NULL);  
 
2564
    g_object_get (gtk_settings_get_default (), "gtk-font-name", &default_font_name, NULL);
2407
2565
    value = g_key_file_get_value (config, "greeter", "xft-dpi", NULL);
2408
2566
    if (value)
2409
2567
        g_object_set (gtk_settings_get_default (), "gtk-xft-dpi", (int) (1024 * atof (value)), NULL);
2429
2587
        return EXIT_FAILURE;
2430
2588
    }
2431
2589
    g_clear_error (&error);
2432
 
    
 
2590
 
 
2591
    /* Screen window */
 
2592
    screen_overlay = GTK_OVERLAY (gtk_builder_get_object (builder, "screen_overlay"));
 
2593
 
2433
2594
    /* Login window */
2434
 
    login_window = GTK_WINDOW (gtk_builder_get_object (builder, "login_window"));
 
2595
    login_window = GTK_WIDGET (gtk_builder_get_object (builder, "login_window"));
2435
2596
    user_image = GTK_IMAGE (gtk_builder_get_object (builder, "user_image"));
2436
2597
    user_combo = GTK_COMBO_BOX (gtk_builder_get_object (builder, "user_combobox"));
2437
2598
    username_entry = GTK_ENTRY (gtk_builder_get_object (builder, "username_entry"));
2441
2602
    cancel_button = GTK_BUTTON (gtk_builder_get_object (builder, "cancel_button"));
2442
2603
    login_button = GTK_BUTTON (gtk_builder_get_object (builder, "login_button"));
2443
2604
 
2444
 
    /* Panel */
2445
 
    panel_window = GTK_WINDOW (gtk_builder_get_object (builder, "panel_window"));
 
2605
    /* Panel window*/
 
2606
    panel_window = GTK_WIDGET (gtk_builder_get_object (builder, "panel_window"));
2446
2607
    menubar = GTK_WIDGET (gtk_builder_get_object (builder, "menubar"));
2447
2608
    session_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "session_menuitem"));
2448
2609
    session_menu = GTK_MENU (gtk_builder_get_object (builder, "session_menu"));
2455
2616
    reader_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "reader_menuitem"));
2456
2617
    power_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "power_menuitem"));
2457
2618
    layout_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "layout_menuitem"));
2458
 
    layout_menu = GTK_MENU(gtk_builder_get_object (builder, "layout_menu"));
 
2619
    layout_menu = GTK_MENU (gtk_builder_get_object (builder, "layout_menu"));
2459
2620
    clock_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "clock_menuitem"));
2460
2621
    host_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "host_menuitem"));
2461
2622
 
 
2623
    /* Power dialog */
 
2624
    power_window = GTK_WIDGET (gtk_builder_get_object (builder, "power_window"));
 
2625
    power_ok_button = GTK_BUTTON (gtk_builder_get_object (builder, "power_ok_button"));
 
2626
    power_cancel_button = GTK_BUTTON (gtk_builder_get_object (builder, "power_cancel_button"));
 
2627
    power_title = GTK_LABEL (gtk_builder_get_object (builder, "power_title"));
 
2628
    power_text = GTK_LABEL (gtk_builder_get_object (builder, "power_text"));
 
2629
    power_icon = GTK_IMAGE (gtk_builder_get_object (builder, "power_icon"));
 
2630
 
 
2631
    gtk_overlay_add_overlay (screen_overlay, login_window);
 
2632
    gtk_overlay_add_overlay (screen_overlay, panel_window);
 
2633
    gtk_overlay_add_overlay (screen_overlay, power_window);
 
2634
 
2462
2635
    gtk_accel_map_add_entry ("<Login>/a11y/font", GDK_KEY_F1, 0);
2463
2636
    gtk_accel_map_add_entry ("<Login>/a11y/contrast", GDK_KEY_F2, 0);
2464
2637
    gtk_accel_map_add_entry ("<Login>/a11y/keyboard", GDK_KEY_F3, 0);
2471
2644
    init_indicators (config);
2472
2645
#endif
2473
2646
 
2474
 
    if (g_key_file_get_boolean(config, "greeter", "hide-user-image", NULL))
 
2647
    /* Hide empty panel */
 
2648
    GList *menubar_items = gtk_container_get_children (GTK_CONTAINER (menubar));
 
2649
    if (!menubar_items)
 
2650
        gtk_widget_hide (GTK_WIDGET (panel_window));
 
2651
    else
 
2652
        g_list_free (menubar_items);
 
2653
 
 
2654
    if (g_key_file_get_boolean (config, "greeter", "hide-user-image", NULL))
2475
2655
    {
2476
2656
        gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, "user_image_border")));
2477
2657
        gtk_widget_hide (GTK_WIDGET (user_image));  /* Hide to mark image is disabled */
2519
2699
            radiomenuitem = gtk_radio_menu_item_new_with_label (sessions, lightdm_session_get_name (session));
2520
2700
            g_object_set_data (G_OBJECT (radiomenuitem), SESSION_DATA_KEY, (gpointer) lightdm_session_get_key (session));
2521
2701
            sessions = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (radiomenuitem));
2522
 
            g_signal_connect(G_OBJECT(radiomenuitem), "activate", G_CALLBACK(session_selected_cb), NULL);
2523
 
            gtk_menu_shell_append (GTK_MENU_SHELL(session_menu), radiomenuitem);
 
2702
            g_signal_connect (G_OBJECT (radiomenuitem), "activate", G_CALLBACK (session_selected_cb), NULL);
 
2703
            gtk_menu_shell_append (GTK_MENU_SHELL (session_menu), radiomenuitem);
2524
2704
            gtk_widget_show (GTK_WIDGET (radiomenuitem));
2525
2705
        }
2526
2706
        set_session (NULL);
2556
2736
            radiomenuitem = gtk_radio_menu_item_new_with_label (languages, label);
2557
2737
            g_object_set_data (G_OBJECT (radiomenuitem), LANGUAGE_DATA_CODE, (gpointer) code);
2558
2738
            languages = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (radiomenuitem));
2559
 
            g_signal_connect(G_OBJECT(radiomenuitem), "activate", G_CALLBACK(language_selected_cb), NULL);
2560
 
            gtk_menu_shell_append (GTK_MENU_SHELL(language_menu), radiomenuitem);
 
2739
            g_signal_connect (G_OBJECT (radiomenuitem), "activate", G_CALLBACK (language_selected_cb), NULL);
 
2740
            gtk_menu_shell_append (GTK_MENU_SHELL (language_menu), radiomenuitem);
2561
2741
            gtk_widget_show (GTK_WIDGET (radiomenuitem));
2562
2742
        }
2563
2743
        set_language (NULL);
2566
2746
    /* a11y menu */
2567
2747
    if (gtk_widget_get_visible (a11y_menuitem))
2568
2748
    {
2569
 
        if (gtk_icon_theme_has_icon(icon_theme, "preferences-desktop-accessibility-symbolic"))
 
2749
        if (gtk_icon_theme_has_icon (icon_theme, "preferences-desktop-accessibility-symbolic"))
2570
2750
            image = gtk_image_new_from_icon_name ("preferences-desktop-accessibility-symbolic", GTK_ICON_SIZE_MENU);
2571
2751
        else
2572
2752
            image = gtk_image_new_from_icon_name ("preferences-desktop-accessibility", GTK_ICON_SIZE_MENU);
2575
2755
    }
2576
2756
 
2577
2757
    value = g_key_file_get_value (config, "greeter", "keyboard", NULL);
2578
 
    a11y_keyboard_command = menu_command_parse_extended (value, keyboard_menuitem, "onboard", "--xid",
2579
 
                                                         &ONBOARD_WINDOW_SIZE);
 
2758
    a11y_keyboard_command = menu_command_parse_extended (value, keyboard_menuitem, "onboard", "--xid");
2580
2759
    g_free (value);
2581
2760
 
2582
2761
    gtk_widget_set_visible (keyboard_menuitem, a11y_keyboard_command != NULL);
2583
 
    if (a11y_keyboard_command)
2584
 
        g_signal_connect (a11y_keyboard_command->widget, "size-allocate", G_CALLBACK (center_window), (gpointer)&ONBOARD_WINDOW_POS);
2585
2762
 
2586
2763
    value = g_key_file_get_value (config, "greeter", "reader", NULL);
2587
2764
    a11y_reader_command = menu_command_parse (value, reader_menuitem);
2591
2768
    /* Power menu */
2592
2769
    if (gtk_widget_get_visible (power_menuitem))
2593
2770
    {
2594
 
        if (gtk_icon_theme_has_icon(icon_theme, "system-shutdown-symbolic"))
 
2771
        if (gtk_icon_theme_has_icon (icon_theme, "system-shutdown-symbolic"))
2595
2772
            image = gtk_image_new_from_icon_name ("system-shutdown-symbolic", GTK_ICON_SIZE_MENU);
2596
2773
        else
2597
2774
            image = gtk_image_new_from_icon_name ("system-shutdown", GTK_ICON_SIZE_MENU);
2603
2780
        restart_menuitem = (GTK_WIDGET (gtk_builder_get_object (builder, "restart_menuitem")));
2604
2781
        shutdown_menuitem = (GTK_WIDGET (gtk_builder_get_object (builder, "shutdown_menuitem")));
2605
2782
 
2606
 
        g_signal_connect (G_OBJECT (power_menuitem),"activate", G_CALLBACK(power_menu_cb), NULL);
 
2783
        g_signal_connect (G_OBJECT (power_menuitem),"activate", G_CALLBACK (power_menu_cb), NULL);
2607
2784
    }
2608
2785
 
2609
2786
    /* Layout menu */
2656
2833
    GdkRGBA lightdm_gtk_greeter_override_defaults;
2657
2834
    css_provider = gtk_css_provider_new ();
2658
2835
    gtk_css_provider_load_from_data (css_provider, lightdm_gtk_greeter_css_application, lightdm_gtk_greeter_css_application_length, NULL);
2659
 
    gtk_style_context_add_provider_for_screen(gdk_screen_get_default (), GTK_STYLE_PROVIDER (css_provider),
2660
 
                                              GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 
2836
    gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (css_provider),
 
2837
                                               GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
2661
2838
    css_provider = gtk_css_provider_new ();
2662
2839
    guint fallback_css_priority = GTK_STYLE_PROVIDER_PRIORITY_APPLICATION;
2663
2840
    if (gtk_style_context_lookup_color (gtk_widget_get_style_context (GTK_WIDGET (login_window)),
2665
2842
                                        &lightdm_gtk_greeter_override_defaults))
2666
2843
        fallback_css_priority = GTK_STYLE_PROVIDER_PRIORITY_FALLBACK;
2667
2844
    gtk_css_provider_load_from_data (css_provider, lightdm_gtk_greeter_css_fallback, lightdm_gtk_greeter_css_fallback_length, NULL);
2668
 
    gtk_style_context_add_provider_for_screen(gdk_screen_get_default (), GTK_STYLE_PROVIDER (css_provider),
2669
 
                                              fallback_css_priority);
 
2845
    gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (css_provider),
 
2846
                                               fallback_css_priority);
2670
2847
 
2671
2848
    /* Background */
2672
 
    greeter_background = greeter_background_new ();
 
2849
    greeter_background = greeter_background_new (GTK_WIDGET (screen_overlay));
2673
2850
 
2674
2851
    value = g_key_file_get_value (config, "greeter", "active-monitor", NULL);
2675
2852
    greeter_background_set_active_monitor_config (greeter_background, value ? value : "#cursor");
2688
2865
    {
2689
2866
        if (!g_str_has_prefix (*config_group, CONFIG_MONITOR_PREFIX))
2690
2867
            continue;
2691
 
        const gchar *name = *config_group + sizeof(CONFIG_MONITOR_PREFIX);
 
2868
        const gchar *name = *config_group + sizeof (CONFIG_MONITOR_PREFIX);
2692
2869
        while (*name && g_ascii_isspace (*name))
2693
2870
            ++name;
2694
2871
        g_debug ("Monitor configuration found: '%s'", name);
2708
2885
    }
2709
2886
    g_strfreev (config_groups);
2710
2887
 
2711
 
    g_signal_connect (G_OBJECT (greeter_background), "active-monitor-changed", G_CALLBACK (active_monitor_changed_cb), NULL);
2712
 
    greeter_background_add_subwindow (greeter_background, login_window);
2713
 
    greeter_background_add_subwindow (greeter_background, panel_window);
 
2888
    greeter_background_add_accel_group (greeter_background, GTK_ACCEL_GROUP (gtk_builder_get_object (builder, "a11y_accelgroup")));
 
2889
    greeter_background_add_accel_group (greeter_background, GTK_ACCEL_GROUP (gtk_builder_get_object (builder, "power_accelgroup")));
 
2890
 
2714
2891
    greeter_background_connect (greeter_background, gdk_screen_get_default ());
2715
2892
 
2716
2893
    if (lightdm_greeter_get_hide_users_hint (greeter))
2726
2903
    }
2727
2904
 
2728
2905
    /* Windows positions */
2729
 
    main_window_pos = WINDOW_POS_CENTER;
2730
 
    value = g_key_file_get_value (config, "greeter", "position", NULL);
2731
 
    if (value)
2732
 
    {
2733
 
        gchar *x = value;
2734
 
        gchar *y = strchr(value, ' ');
2735
 
        if (y)
2736
 
            (y++)[0] = '\0';
2737
 
        
2738
 
        if (read_position_from_str (x, &main_window_pos.x))
2739
 
            /* If there is no y-part then y = x */
2740
 
            if (!y || !read_position_from_str (y, &main_window_pos.y))
2741
 
                main_window_pos.y = main_window_pos.x;
2742
 
 
2743
 
        g_free (value);
2744
 
    }
2745
 
    panel_window_pos = WINDOW_POS_TOP_LEFT;
2746
 
 
2747
 
    gtk_builder_connect_signals(builder, greeter);
2748
 
 
2749
 
    gtk_widget_show (GTK_WIDGET (panel_window));
2750
 
    center_window (panel_window, NULL, &panel_window_pos);
2751
 
    g_signal_connect (GTK_WIDGET (panel_window), "size-allocate", G_CALLBACK (center_window), &panel_window_pos);
2752
 
 
2753
 
    gtk_widget_show (GTK_WIDGET (login_window));
2754
 
    center_window (login_window, NULL, &main_window_pos);
2755
 
    g_signal_connect (GTK_WIDGET (login_window), "size-allocate", G_CALLBACK (center_window), &main_window_pos);
2756
 
    gdk_window_focus (gtk_widget_get_window (GTK_WIDGET (login_window)), GDK_CURRENT_TIME);
 
2906
    g_object_set_data_full (G_OBJECT (login_window), WINDOW_DATA_POSITION,
 
2907
                            key_file_get_position (config, "greeter", "position", &WINDOW_POS_CENTER), g_free);
 
2908
 
 
2909
    value = g_key_file_get_value (config, "greeter", "panel-position", NULL);
 
2910
    if (g_strcmp0 (value, "bottom") == 0)
 
2911
        gtk_widget_set_valign (panel_window, GTK_ALIGN_END);
 
2912
    g_free (value);
 
2913
 
 
2914
    if (a11y_keyboard_command)
 
2915
        g_object_set_data_full (G_OBJECT (a11y_keyboard_command->widget), WINDOW_DATA_POSITION,
 
2916
                                key_file_get_position (config, "greeter", "keyboard-position", &KEYBOARD_POSITION), g_free);
 
2917
 
 
2918
    gtk_builder_connect_signals (builder, greeter);
2757
2919
 
2758
2920
    values = g_key_file_get_string_list (config, "greeter", "a11y-states", NULL, NULL);
2759
2921
    if (values && *values)
2799
2961
    gdk_window_set_events (root_window, gdk_window_get_events (root_window) | GDK_SUBSTRUCTURE_MASK);
2800
2962
    gdk_window_add_filter (root_window, focus_upon_map, NULL);
2801
2963
 
 
2964
    gtk_widget_show (GTK_WIDGET (screen_overlay));
 
2965
 
2802
2966
    gtk_main ();
2803
2967
 
2804
2968
#ifdef START_INDICATOR_SERVICES