283
281
void a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data);
284
282
void a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data);
286
/* Power indciator */
284
/* Power indicator */
287
285
static void power_menu_cb (GtkWidget *menuitem, gpointer userdata);
288
286
void suspend_cb (GtkWidget *widget, LightDMGreeter *greeter);
289
287
void hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter);
290
288
void restart_cb (GtkWidget *widget, LightDMGreeter *greeter);
291
289
void shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter);
291
static void read_monitor_configuration (const gchar *group, const gchar *name);
293
struct SavedFocusData
293
299
gpointer greeter_save_focus(GtkWidget* widget);
294
300
void greeter_restore_focus(const gpointer saved_data);
296
struct SavedFocusData
304
read_monitor_configuration (const gchar *group, const gchar *name)
306
g_debug ("[Configuration] Monitor configuration found: '%s'", name);
308
gchar *background = config_get_string (group, CONFIG_KEY_BACKGROUND, NULL);
309
greeter_background_set_monitor_config (greeter_background, name, background,
310
config_get_bool (group, CONFIG_KEY_USER_BACKGROUND, -1),
311
config_get_bool (group, CONFIG_KEY_LAPTOP, -1),
312
config_get_int (group, CONFIG_KEY_T_DURATION, -1),
313
config_get_enum (group, CONFIG_KEY_T_TYPE,
314
TRANSITION_TYPE_FALLBACK,
315
"none", TRANSITION_TYPE_NONE,
316
"linear", TRANSITION_TYPE_LINEAR,
317
"ease-in-out", TRANSITION_TYPE_EASE_IN_OUT, NULL));
303
322
greeter_save_focus(GtkWidget* widget)
317
336
greeter_restore_focus(const gpointer saved_data)
322
338
struct SavedFocusData *data = saved_data;
323
if (GTK_IS_WIDGET (data->widget))
324
gtk_widget_grab_focus (data->widget);
340
if (!saved_data || !GTK_IS_WIDGET (data->widget))
343
gtk_widget_grab_focus (data->widget);
325
344
if (GTK_IS_EDITABLE(data->widget) && data->editable_pos > -1)
326
345
gtk_editable_set_position(GTK_EDITABLE(data->widget), data->editable_pos);
332
save_state_file (void)
349
infobar_revealed_cb_710888 (GObject *gobject, GParamSpec *pspec, gpointer user_data)
334
GError *error = NULL;
335
gsize data_length = 0;
336
gchar *data = g_key_file_to_data (state, &data_length, &error);
340
g_warning ("Failed to save state file: %s", error->message);
341
g_clear_error (&error);
346
g_file_set_contents (state_filename, data, data_length, &error);
349
g_warning ("Failed to save state file: %s", error->message);
350
g_clear_error (&error);
351
gtk_widget_set_visible (GTK_WIDGET (info_bar), !message_label_is_empty ());
356
354
/* Terminating */
1421
1435
#ifdef HAVE_LIBINDICATOR
1422
1436
gboolean inited = FALSE;
1424
gboolean fallback = FALSE;
1426
1439
const gchar *DEFAULT_LAYOUT[] = {"~host", "~spacer", "~clock", "~spacer",
1427
1440
"~session", "~language", "~a11y", "~power", NULL};
1429
if (g_key_file_has_key (config, "greeter", "indicators", NULL))
1430
{ /* no option = default list, empty value = empty list */
1431
names = g_key_file_get_string_list (config, "greeter", "indicators", &length, NULL);
1433
else if (g_key_file_has_key (config, "greeter", "show-indicators", NULL))
1434
{ /* fallback mode: no option = empty value = default list */
1435
names = g_key_file_get_string_list (config, "greeter", "show-indicators", &length, NULL);
1440
if (!names || fallback)
1442
gchar **names = config_get_string_list (NULL, CONFIG_KEY_INDICATORS, NULL);
1442
1444
names = (gchar**)DEFAULT_LAYOUT;
1443
length = g_strv_length (names);
1445
length = g_strv_length (names);
1446
1447
builtin_items = g_hash_table_new (g_str_hash, g_str_equal);
2513
2538
set_displayed_user (greeter, name);
2519
2543
g_free (last_user);
2522
2546
static GdkFilterReturn
2523
focus_upon_map (GdkXEvent *gxevent, GdkEvent *event, gpointer data)
2547
wm_window_filter (GdkXEvent *gxevent, GdkEvent *event, gpointer data)
2525
XEvent* xevent = (XEvent*)gxevent;
2526
GdkWindow* keyboard_win = a11y_keyboard_command && a11y_keyboard_command->widget ?
2527
gtk_widget_get_window (GTK_WIDGET (a11y_keyboard_command->widget)) : NULL;
2549
XEvent *xevent = (XEvent*)gxevent;
2528
2550
if (xevent->type == MapNotify)
2530
Window xwin = xevent->xmap.window;
2531
Window keyboard_xid = 0;
2532
GdkDisplay* display = gdk_x11_lookup_xdisplay (xevent->xmap.display);
2533
GdkWindow* win = gdk_x11_window_foreign_new_for_display (display, xwin);
2552
GdkDisplay *display = gdk_x11_lookup_xdisplay (xevent->xmap.display);
2553
GdkWindow *win = gdk_x11_window_foreign_new_for_display (display, xevent->xmap.window);
2534
2554
GdkWindowTypeHint win_type = gdk_window_get_type_hint (win);
2536
/* Check to see if this window is our onboard window, since we don't want to focus it. */
2538
keyboard_xid = gdk_x11_window_get_xid (keyboard_win);
2540
if (xwin != keyboard_xid
2541
&& win_type != GDK_WINDOW_TYPE_HINT_TOOLTIP
2542
&& win_type != GDK_WINDOW_TYPE_HINT_NOTIFICATION)
2556
if (win_type != GDK_WINDOW_TYPE_HINT_COMBO &&
2557
win_type != GDK_WINDOW_TYPE_HINT_TOOLTIP &&
2558
win_type != GDK_WINDOW_TYPE_HINT_NOTIFICATION)
2560
if (win_type == GDK_WINDOW_TYPE_HINT_DESKTOP ||
2561
win_type == GDK_WINDOW_TYPE_HINT_DIALOG)
2544
2563
gdk_window_focus (win, GDK_CURRENT_TIME);
2545
/* Make sure to keep keyboard above */
2547
gdk_window_raise (keyboard_win);
2550
2565
else if (xevent->type == UnmapNotify)
2568
int revert_to = RevertToNone;
2554
2570
XGetInputFocus (xevent->xunmap.display, &xwin, &revert_to);
2556
2571
if (revert_to == RevertToNone)
2558
gdk_window_focus (gtk_widget_get_window (GTK_WIDGET (login_window)), GDK_CURRENT_TIME);
2559
/* Make sure to keep keyboard above */
2561
gdk_window_raise (keyboard_win);
2572
gdk_window_lower (gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET (screen_overlay))));
2564
2575
return GDK_FILTER_CONTINUE;
2611
2622
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
2612
2623
textdomain (GETTEXT_PACKAGE);
2614
g_unix_signal_add (SIGTERM, (GSourceFunc)sigterm_cb, NULL);
2616
config = g_key_file_new ();
2617
g_key_file_load_from_file (config, CONFIG_FILE, G_KEY_FILE_NONE, &error);
2618
if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
2619
g_warning ("Failed to load configuration from %s: %s\n", CONFIG_FILE, error->message);
2620
g_clear_error (&error);
2622
if (g_key_file_get_boolean (config, "greeter", "allow-debugging", NULL))
2625
g_unix_signal_add (SIGTERM, (GSourceFunc)sigterm_cb, /* is_callback */ GINT_TO_POINTER (TRUE));
2629
if (config_get_bool (NULL, CONFIG_KEY_DEBUGGING, FALSE))
2623
2630
g_log_set_default_handler (debug_log_handler, NULL);
2662
2669
#ifdef HAVE_LIBIDO
2670
g_debug ("Initializing IDO library");
2666
state_dir = g_build_filename (g_get_user_cache_dir (), "lightdm-gtk-greeter", NULL);
2667
g_mkdir_with_parents (state_dir, 0775);
2668
state_filename = g_build_filename (state_dir, "state", NULL);
2671
state = g_key_file_new ();
2672
g_key_file_load_from_file (state, state_filename, G_KEY_FILE_NONE, &error);
2673
if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
2674
g_warning ("Failed to load state from %s: %s\n", state_filename, error->message);
2675
g_clear_error (&error);
2677
2674
greeter = lightdm_greeter_new ();
2678
2675
g_signal_connect (greeter, "show-prompt", G_CALLBACK (show_prompt_cb), NULL);
2679
2676
g_signal_connect (greeter, "show-message", G_CALLBACK (show_message_cb), NULL);
2680
2677
g_signal_connect (greeter, "authentication-complete", G_CALLBACK (authentication_complete_cb), NULL);
2681
g_signal_connect (greeter, "autologin-timer-expired", G_CALLBACK (lightdm_greeter_authenticate_autologin), NULL);
2678
g_signal_connect (greeter, "autologin-timer-expired", G_CALLBACK (timed_autologin_cb), NULL);
2682
2679
if (!lightdm_greeter_connect_sync (greeter, NULL))
2683
2680
return EXIT_FAILURE;
2686
2683
gdk_window_set_cursor (gdk_get_default_root_window (), gdk_cursor_new (GDK_LEFT_PTR));
2688
2685
/* Make the greeter behave a bit more like a screensaver if used as un/lock-screen by blanking the screen */
2689
gchar* end_ptr = NULL;
2690
int screensaver_timeout = 60;
2691
value = g_key_file_get_value (config, "greeter", "screensaver-timeout", NULL);
2693
screensaver_timeout = g_ascii_strtoll (value, &end_ptr, 0);
2696
display = gdk_x11_display_get_xdisplay (gdk_display_get_default ());
2697
2686
if (lightdm_greeter_get_lock_hint (greeter))
2688
Display *display = gdk_x11_display_get_xdisplay (gdk_display_get_default ());
2699
2689
XGetScreenSaver (display, &timeout, &interval, &prefer_blanking, &allow_exposures);
2700
2690
XForceScreenSaver (display, ScreenSaverActive);
2701
XSetScreenSaver (display, screensaver_timeout, 0, ScreenSaverActive, DefaultExposures);
2691
XSetScreenSaver (display, config_get_int (NULL, CONFIG_KEY_SCREENSAVER_TIMEOUT, 60), 0,
2692
ScreenSaverActive, DefaultExposures);
2704
2695
/* Set GTK+ settings */
2705
value = g_key_file_get_value (config, "greeter", "theme-name", NULL);
2696
value = config_get_string (NULL, CONFIG_KEY_THEME, NULL);
2708
g_debug ("Using Gtk+ theme %s", value);
2699
g_debug ("[Configuration] Changing GTK+ theme to '%s'", value);
2709
2700
g_object_set (gtk_settings_get_default (), "gtk-theme-name", value, NULL);
2712
2703
g_object_get (gtk_settings_get_default (), "gtk-theme-name", &default_theme_name, NULL);
2713
g_debug ("Default Gtk+ theme is '%s'", default_theme_name);
2704
g_debug ("[Configuration] GTK+ theme: '%s'", default_theme_name);
2715
value = g_key_file_get_value (config, "greeter", "icon-theme-name", NULL);
2706
value = config_get_string (NULL, CONFIG_KEY_ICON_THEME, NULL);
2718
g_debug ("Using icon theme %s", value);
2709
g_debug ("[Configuration] Changing icons theme to '%s'", value);
2719
2710
g_object_set (gtk_settings_get_default (), "gtk-icon-theme-name", value, NULL);
2722
2713
g_object_get (gtk_settings_get_default (), "gtk-icon-theme-name", &default_icon_theme_name, NULL);
2723
g_debug ("Default theme is '%s'", default_icon_theme_name);
2714
g_debug ("[Configuration] Icons theme: '%s'", default_icon_theme_name);
2725
value = g_key_file_get_value (config, "greeter", "font-name", NULL);
2716
value = config_get_string (NULL, CONFIG_KEY_FONT, "Sans 10");
2728
g_debug ("Using font %s", value);
2729
g_object_set (gtk_settings_get_default (), "gtk-font-name", value, NULL);
2733
value = g_strdup ("Sans 10");
2734
g_object_set (gtk_settings_get_default (), "gtk-font-name", value, NULL);
2719
g_debug ("[Configuration] Changing font to '%s'", value);
2720
g_object_set (gtk_settings_get_default (), "gtk-font-name", value, NULL);
2736
2723
g_object_get (gtk_settings_get_default (), "gtk-font-name", &default_font_name, NULL);
2737
value = g_key_file_get_value (config, "greeter", "xft-dpi", NULL);
2739
g_object_set (gtk_settings_get_default (), "gtk-xft-dpi", (int) (1024 * atof (value)), NULL);
2740
value = g_key_file_get_value (config, "greeter", "xft-antialias", NULL);
2742
g_object_set (gtk_settings_get_default (), "gtk-xft-antialias", g_strcmp0 (value, "true") == 0, NULL);
2744
value = g_key_file_get_value (config, "greeter", "xft-hintstyle", NULL);
2724
g_debug ("[Configuration] Font: '%s'", default_font_name);
2726
if (config_has_key (NULL, CONFIG_KEY_DPI))
2727
g_object_set (gtk_settings_get_default (), "gtk-xft-dpi", 1024*config_get_int (NULL, CONFIG_KEY_DPI, 96), NULL);
2729
if (config_has_key (NULL, CONFIG_KEY_ANTIALIAS))
2730
g_object_set (gtk_settings_get_default (), "gtk-xft-antialias", config_get_bool (NULL, CONFIG_KEY_ANTIALIAS, FALSE), NULL);
2732
value = config_get_string (NULL, CONFIG_KEY_HINT_STYLE, NULL);
2746
2735
g_object_set (gtk_settings_get_default (), "gtk-xft-hintstyle", value, NULL);
2748
value = g_key_file_get_value (config, "greeter", "xft-rgba", NULL);
2739
value = config_get_string (NULL, CONFIG_KEY_RGBA, NULL);
2750
2742
g_object_set (gtk_settings_get_default (), "gtk-xft-rgba", value, NULL);
2753
2746
#ifdef AT_SPI_COMMAND
2754
2747
spawn_line_pid (AT_SPI_COMMAND, G_SPAWN_SEARCH_PATH, NULL);
2929
2934
gtk_container_add (GTK_CONTAINER (a11y_menuitem), image);
2932
value = g_key_file_get_value (config, "greeter", "keyboard", NULL);
2933
a11y_keyboard_command = menu_command_parse_extended ("keyboard", value, keyboard_menuitem, "onboard", "--xid");
2937
value = config_get_string (NULL, CONFIG_KEY_KEYBOARD, NULL);
2940
a11y_keyboard_command = menu_command_parse_extended ("keyboard", value, keyboard_menuitem, "onboard", "--xid");
2936
2943
gtk_widget_set_visible (keyboard_menuitem, a11y_keyboard_command != NULL);
2938
value = g_key_file_get_value (config, "greeter", "reader", NULL);
2939
a11y_reader_command = menu_command_parse ("reader", value, reader_menuitem);
2947
value = config_get_string (NULL, CONFIG_KEY_READER, NULL);
2950
a11y_reader_command = menu_command_parse ("reader", value, reader_menuitem);
2940
2953
gtk_widget_set_visible (reader_menuitem, a11y_reader_command != NULL);
2943
2955
/* Power menu */
2944
2956
if (gtk_widget_get_visible (power_menuitem))
3023
3033
/* Background */
3024
3034
greeter_background = greeter_background_new (GTK_WIDGET (screen_overlay));
3026
value = g_key_file_get_value (config, "greeter", "active-monitor", NULL);
3036
value = config_get_string (NULL, CONFIG_KEY_ACTIVE_MONITOR, NULL);
3027
3037
greeter_background_set_active_monitor_config (greeter_background, value ? value : "#cursor");
3028
3038
g_free (value);
3030
const gchar *CONFIG_MONITOR_PREFIX = "monitor:";
3040
read_monitor_configuration (CONFIG_GROUP_DEFAULT, GREETER_BACKGROUND_DEFAULT);
3031
3042
gchar **config_group;
3032
gchar **config_groups = g_key_file_get_groups (config, NULL);
3043
gchar **config_groups = config_get_groups (CONFIG_GROUP_MONITOR);
3033
3044
for (config_group = config_groups; *config_group; ++config_group)
3035
gchar *name_to_free = NULL;
3036
const gchar *name = *config_group;
3038
if (g_strcmp0 (*config_group, "greeter") != 0)
3040
if (!g_str_has_prefix (name, CONFIG_MONITOR_PREFIX))
3042
name = *config_group + sizeof (CONFIG_MONITOR_PREFIX);
3043
while (*name && g_ascii_isspace (*name))
3047
name = name_to_free = g_strdup (GREETER_BACKGROUND_DEFAULT);
3049
g_debug ("Monitor configuration found: '%s'", name);
3051
GError *user_bg_error = NULL, *laptop_error = NULL, *duration_error = NULL;
3052
gboolean user_bg = g_key_file_get_boolean (config, *config_group, "user-background", &user_bg_error);
3053
gboolean laptop = g_key_file_get_boolean (config, *config_group, "laptop", &laptop_error);
3054
gchar *background = g_key_file_get_value (config, *config_group, "background", NULL);
3055
gchar *tr_type = g_key_file_get_string (config, *config_group, "transition-type", NULL);
3056
gint tr_duration = g_key_file_get_integer (config, *config_group, "transition-duration", &duration_error);
3058
greeter_background_set_monitor_config (greeter_background, name, background,
3059
user_bg, user_bg_error == NULL,
3060
laptop, laptop_error == NULL,
3061
duration_error == NULL ? tr_duration : -1,
3065
g_free (background);
3066
g_free (name_to_free);
3067
g_clear_error (&user_bg_error);
3068
g_clear_error (&laptop_error);
3046
const gchar *name = *config_group + sizeof (CONFIG_GROUP_MONITOR);
3047
while (*name && g_ascii_isspace (*name))
3050
read_monitor_configuration (*config_group, name);
3070
3052
g_strfreev (config_groups);
3089
3071
/* Windows positions */
3090
g_object_set_data_full (G_OBJECT (login_window), WINDOW_DATA_POSITION,
3091
key_file_get_position (config, "greeter", "position", &WINDOW_POS_CENTER), g_free);
3093
value = g_key_file_get_value (config, "greeter", "panel-position", NULL);
3094
if (g_strcmp0 (value, "bottom") == 0)
3095
gtk_widget_set_valign (panel_window, GTK_ALIGN_END);
3072
value = config_get_string (NULL, CONFIG_KEY_POSITION, NULL);
3073
g_object_set_data_full (G_OBJECT (login_window), WINDOW_DATA_POSITION, str_to_position (value, &WINDOW_POS_CENTER), g_free);
3096
3074
g_free (value);
3077
gtk_widget_set_valign (panel_window, config_get_enum (NULL, CONFIG_KEY_PANEL_POSITION, GTK_ALIGN_START,
3078
"bottom", GTK_ALIGN_END,
3079
"top", GTK_ALIGN_START, NULL));
3098
3081
if (a11y_keyboard_command)
3099
g_object_set_data_full (G_OBJECT (a11y_keyboard_command->widget), WINDOW_DATA_POSITION,
3100
key_file_get_position (config, "greeter", "keyboard-position", &KEYBOARD_POSITION), g_free);
3083
value = config_get_string (NULL, CONFIG_KEY_KEYBOARD_POSITION, NULL);
3084
g_object_set_data_full (G_OBJECT (a11y_keyboard_command->widget), WINDOW_DATA_POSITION, str_to_position (value, &KEYBOARD_POSITION), g_free);
3102
3088
gtk_builder_connect_signals (builder, greeter);
3104
values = g_key_file_get_string_list (config, "greeter", "a11y-states", NULL, NULL);
3105
if (values && *values)
3090
gchar **a11y_states = config_get_string_list (NULL, CONFIG_KEY_A11Y_STATES, NULL);
3091
if (a11y_states && *a11y_states)
3107
3093
GHashTable *items = g_hash_table_new (g_str_hash, g_str_equal);
3108
3094
g_hash_table_insert (items, "contrast", contrast_menuitem);
3131
3117
gtk_widget_get_visible (GTK_WIDGET (item)))
3133
3119
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3134
g_key_file_get_boolean (state, "a11y-states", value, NULL));
3120
config_get_bool (STATE_SECTION_A11Y, value, FALSE));
3135
3121
g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (a11y_menuitem_toggled_cb), g_strdup (value));
3139
3125
g_hash_table_unref (items);
3141
g_strfreev (values);
3127
g_strfreev (a11y_states);
3143
/* focus fix (source: unity-greeter) */
3129
/* There is no window manager, so we need to implement some of its functionality */
3144
3130
GdkWindow* root_window = gdk_get_default_root_window ();
3145
3131
gdk_window_set_events (root_window, gdk_window_get_events (root_window) | GDK_SUBSTRUCTURE_MASK);
3146
gdk_window_add_filter (root_window, focus_upon_map, NULL);
3132
gdk_window_add_filter (root_window, wm_window_filter, NULL);
3148
3134
gtk_widget_show (GTK_WIDGET (screen_overlay));
3136
g_debug ("Run Gtk loop...");
3138
g_debug ("Gtk loop exits");
3152
g_slist_foreach (pids_to_close, (GFunc)close_pid, NULL);
3140
sigterm_cb (/* is_callback */ GINT_TO_POINTER (FALSE));
3154
3142
return EXIT_SUCCESS;