diff options
Diffstat (limited to 'gui/gdmlogin.c')
-rw-r--r-- | gui/gdmlogin.c | 3597 |
1 files changed, 0 insertions, 3597 deletions
diff --git a/gui/gdmlogin.c b/gui/gdmlogin.c deleted file mode 100644 index 4255b839..00000000 --- a/gui/gdmlogin.c +++ /dev/null @@ -1,3597 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * GDM - The GNOME Display Manager - * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" - -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <fcntl.h> -#include <unistd.h> -#include <ctype.h> -#include <signal.h> -#include <dirent.h> -#include <locale.h> -#include <pwd.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/wait.h> - -#include <X11/X.h> -#include <X11/Xlib.h> -#include <X11/XKBlib.h> - -#include <glib/gi18n.h> -#include <gdk/gdkx.h> -#include <gdk/gdkkeysyms.h> - -#if HAVE_PAM -#include <security/pam_appl.h> -#define PW_ENTRY_SIZE PAM_MAX_RESP_SIZE -#else -#define PW_ENTRY_SIZE GDM_MAX_PASS -#endif - -#include "vicious.h" - -#include "gdm.h" -#include "gdmuser.h" -#include "gdmcomm.h" -#include "gdmcommon.h" -#include "gdmsession.h" -#include "gdmwm.h" -#include "gdmlanguages.h" -#include "gdmconfig.h" -#include "misc.h" - -/* set the DOING_GDM_DEVELOPMENT env variable if you aren't running - * within the protocol */ -static gboolean DOING_GDM_DEVELOPMENT = FALSE; -static gboolean browser_ok = TRUE; -static gboolean disable_sys_config_chooser_buttons = FALSE; -static gboolean GdmLockPosition = FALSE; -static gboolean GdmSetPosition = FALSE; -static gint GdmPositionX; -static gint GdmPositionY; - -#define LAST_LANGUAGE "Last" -#define DEFAULT_LANGUAGE "Default" -#define GTK_KEY "gtk-2.0" - -enum { - GREETER_ULIST_ICON_COLUMN = 0, - GREETER_ULIST_LABEL_COLUMN, - GREETER_ULIST_LOGIN_COLUMN -}; - -enum { - GDM_BACKGROUND_NONE = 0, - GDM_BACKGROUND_IMAGE_AND_COLOR = 1, - GDM_BACKGROUND_COLOR = 2, - GDM_BACKGROUND_IMAGE = 3, -}; - -static GtkWidget *login; -static GtkWidget *logo_frame = NULL; -static GtkWidget *logo_image = NULL; -static GtkWidget *table = NULL; -static GtkWidget *welcome; -static GtkWidget *label; -static GtkWidget *icon_button = NULL; -static GtkWidget *title_box = NULL; -static GtkWidget *clock_label = NULL; -static GtkWidget *entry; -static GtkWidget *ok_button; -static GtkWidget *cancel_button; -static GtkWidget *msg; -static GtkWidget *auto_timed_msg; -static GtkWidget *err_box; -static guint err_box_clear_handler = 0; -static gboolean require_quarter = FALSE; -static GtkWidget *icon_win = NULL; -static GtkWidget *sessmenu; -static GtkWidget *langmenu; - -static gboolean login_is_local = FALSE; - -static GtkWidget *browser; -static GtkTreeModel *browser_model; -static GdkPixbuf *defface; - -/* Eew. Loads of global vars. It's hard to be event controlled while maintaining state */ -static GSList *languages = NULL; -static GList *users = NULL; -static GList *users_string = NULL; -static gint size_of_users = 0; - -static const gchar *curlang = NULL; -static gchar *curuser = NULL; -static gchar *session = NULL; -static gchar *language = NULL; - -static gint savelang = GTK_RESPONSE_NO; - -/* back_prog_timeout_event_id: event of the timer. - * back_prog_watcher_event_id: event of the background program watcher. - * back_prog_pid: process ID of the background program. - * back_prog_has_run: true if the background program has run - * at least once. - * back_prog_watching_events: true if we are watching for user events. - * back_prog_delayed: true if the execution of the program has - * been delayed. - */ -static gint back_prog_timeout_event_id = -1; -static gint back_prog_watcher_event_id = -1; -static gint back_prog_pid = -1; -static gboolean back_prog_has_run = FALSE; -static gboolean back_prog_watching_events = FALSE; -static gboolean back_prog_delayed = FALSE; - -static guint timed_handler_id = 0; - -#if FIXME -static char *selected_browser_user = NULL; -#endif -static gboolean selecting_user = TRUE; - -extern GList *sessions; -extern GHashTable *sessnames; -extern gchar *default_session; -extern const gchar *current_session; -extern gboolean session_dir_whacked_out; -extern gint gdm_timed_delay; - -static void login_window_resize (gboolean force); - -/* Background program logic */ -static void back_prog_on_exit (GPid pid, gint status, gpointer data); -static gboolean back_prog_on_timeout (gpointer data); -static gboolean back_prog_delay_timeout (GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer data); -static void back_prog_watch_events (void); -static gchar * back_prog_get_path (void); -static void back_prog_launch_after_timeout (void); -static void back_prog_run (void); -static void back_prog_stop (void); - -/* - * This function is called when the background program exits. - * It will add a timer to restart the program after the - * restart delay has elapsed, if this is enabled. - */ -static void -back_prog_on_exit (GPid pid, gint status, gpointer data) -{ - g_assert (back_prog_timeout_event_id == -1); - - back_prog_watcher_event_id = -1; - back_prog_pid = -1; - - back_prog_launch_after_timeout (); -} - -/* - * This function starts the background program (if any) when - * the background program timer triggers, unless the execution - * has been delayed. - */ -static gboolean -back_prog_on_timeout (gpointer data) -{ - g_assert (back_prog_watcher_event_id == -1); - g_assert (back_prog_pid == -1); - - back_prog_timeout_event_id = -1; - - if (back_prog_delayed) { - back_prog_launch_after_timeout (); - } else { - back_prog_run (); - } - - return FALSE; -} - -/* - * This function is called to delay the execution of the background - * program when the user is doing something (when we detect an event). - */ -static gboolean -back_prog_delay_timeout (GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer data) -{ - back_prog_delayed = TRUE; - return TRUE; -} - -/* - * This function creates signal listeners to catch user events. - * That allows us to avoid spawning the background program - * when the user is doing something. - */ -static void -back_prog_watch_events (void) - { - guint sid; - - if (back_prog_watching_events) - return; - - back_prog_watching_events = TRUE; - - sid = g_signal_lookup ("activate", GTK_TYPE_MENU_ITEM); - g_signal_add_emission_hook (sid, 0, back_prog_delay_timeout, - NULL, NULL); - - sid = g_signal_lookup ("key_press_event", GTK_TYPE_WIDGET); - g_signal_add_emission_hook (sid, 0, back_prog_delay_timeout, - NULL, NULL); - - sid = g_signal_lookup ("button_press_event", GTK_TYPE_WIDGET); - g_signal_add_emission_hook (sid, 0, back_prog_delay_timeout, - NULL, NULL); - } - -/* - * This function returns the path of the background program - * if there is one. Otherwise, NULL is returned. - */ -static gchar * -back_prog_get_path (void) -{ - gchar *backprog = gdm_config_get_string (GDM_KEY_BACKGROUND_PROGRAM); - - if ((gdm_config_get_int (GDM_KEY_BACKGROUND_TYPE) == GDM_BACKGROUND_NONE || - gdm_config_get_bool (GDM_KEY_RUN_BACKGROUND_PROGRAM_ALWAYS)) && - ! ve_string_empty (backprog)) { - return backprog; - } else - return NULL; -} - -/* - * This function creates a timer to start the background - * program after the requested delay (in seconds) has elapsed. - */ -static void -back_prog_launch_after_timeout () -{ - int timeout; - - g_assert (back_prog_timeout_event_id == -1); - g_assert (back_prog_watcher_event_id == -1); - g_assert (back_prog_pid == -1); - - /* No program to run. */ - if (! back_prog_get_path ()) - return; - - /* First time. */ - if (! back_prog_has_run) { - timeout = gdm_config_get_int (GDM_KEY_BACKGROUND_PROGRAM_INITIAL_DELAY); - - /* Already run, but we are allowed to restart it. */ - } else if (gdm_config_get_bool (GDM_KEY_RESTART_BACKGROUND_PROGRAM)) { - timeout = gdm_config_get_int (GDM_KEY_BACKGROUND_PROGRAM_RESTART_DELAY); - - /* Already run, but we are not allowed to restart it. */ - } else { - return; - } - - back_prog_delayed = FALSE; - back_prog_watch_events (); - back_prog_timeout_event_id = g_timeout_add (timeout * 1000, - back_prog_on_timeout, - NULL); -} - -/* - * This function starts the background program (if any). - */ -static void -back_prog_run (void) -{ - GPid pid = -1; - GError *error = NULL; - gchar *command = NULL; - gchar **back_prog_argv = NULL; - - g_assert (back_prog_timeout_event_id == -1); - g_assert (back_prog_watcher_event_id == -1); - g_assert (back_prog_pid == -1); - - command = back_prog_get_path (); - if (! command) - return; - - gdm_common_debug ("Running background program <%s>", command); - - /* Focus new windows. We want to give focus to the background program. */ - gdm_wm_focus_new_windows (TRUE); - - back_prog_argv = ve_split (command); - - /* Don't reap child automatically: we want to catch the event. */ - if (! g_spawn_async (".", - back_prog_argv, - NULL, - (GSpawnFlags) (G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD), - NULL, - NULL, - &pid, - &error)) { - - GtkWidget *dialog; - gchar *msg; - - gdm_common_debug ("Cannot run background program %s : %s", command, error->message); - msg = g_strdup_printf (_("Cannot run command '%s': %s."), - command, - error->message); - - dialog = ve_hig_dialog_new (NULL, - GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Cannot start background application"), - msg); - g_free (msg); - - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - g_error_free (error); - g_strfreev (back_prog_argv); - - return; - } - - g_strfreev (back_prog_argv); - back_prog_watcher_event_id = g_child_watch_add (pid, - back_prog_on_exit, - NULL); - back_prog_pid = pid; - back_prog_has_run = TRUE; -} - -/* - * This function stops the background program if it is running, - * and removes any associated timer or watcher. - */ -static void -back_prog_stop (void) -{ - if (back_prog_timeout_event_id != -1) { - GSource *source = g_main_context_find_source_by_id - (NULL, back_prog_timeout_event_id); - if (source != NULL) - g_source_destroy (source); - - back_prog_timeout_event_id = -1; - } - - if (back_prog_watcher_event_id != -1) { - GSource *source = g_main_context_find_source_by_id - (NULL, back_prog_watcher_event_id); - if (source != NULL) - g_source_destroy (source); - - back_prog_watcher_event_id = -1; - } - - if (back_prog_pid != -1) { - if (kill (back_prog_pid, SIGTERM) == 0) { - waitpid (back_prog_pid, NULL, 0); - } - - back_prog_pid = -1; - } -} - -/* - * Timed Login: Timer - */ -static gboolean -gdm_timer (gpointer data) -{ - if (gdm_timed_delay <= 0) { - /* timed interruption */ - printf ("%c%c%c\n", STX, BEL, GDM_INTERRUPT_TIMED_LOGIN); - fflush (stdout); - } else { - gchar *autologin_msg; - - /* Note that this message is not handled the same way as in - * the greeter, we don't parse it through the enriched text. - */ - autologin_msg = gdm_common_expand_text ( - _("User %u will login in %t")); - gtk_label_set_text (GTK_LABEL (auto_timed_msg), autologin_msg); - gtk_widget_show (GTK_WIDGET (auto_timed_msg)); - g_free (autologin_msg); - login_window_resize (FALSE /* force */); - } - - gdm_timed_delay--; - return TRUE; -} - -/* - * Timed Login: On GTK events, increase delay to at least 30 - * seconds, or the GDM_KEY_TIMED_LOGIN_DELAY, whichever is higher - */ -static gboolean -gdm_timer_up_delay (GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer data) -{ - if (gdm_timed_delay < 30) - gdm_timed_delay = 30; - if (gdm_timed_delay < gdm_config_get_int (GDM_KEY_TIMED_LOGIN_DELAY)) - gdm_timed_delay = gdm_config_get_int (GDM_KEY_TIMED_LOGIN_DELAY); - return TRUE; -} - -/* The reaping stuff */ -static time_t last_reap_delay = 0; - -static gboolean -delay_reaping (GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer data) -{ - last_reap_delay = time (NULL); - return TRUE; -} - -static void -gdm_kill_thingies (void) -{ - back_prog_stop (); -} - -static gboolean -reap_flexiserver (gpointer data) -{ - int reapminutes = gdm_config_get_int (GDM_KEY_FLEXI_REAP_DELAY_MINUTES); - - if (reapminutes > 0 && - ((time (NULL) - last_reap_delay) / 60) > reapminutes) { - gdm_kill_thingies (); - _exit (DISPLAY_REMANAGE); - } - return TRUE; -} - - -static gboolean -gdm_event (GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer data) -{ - GdkEvent *event; - - /* HAAAAAAAAAAAAAAAAACK */ - /* Since the user has not logged in yet and may have left/right - * mouse buttons switched, we just translate every right mouse click - * to a left mouse click */ - if (n_param_values != 2 || - !G_VALUE_HOLDS (¶m_values[1], GDK_TYPE_EVENT)) - return FALSE; - - event = g_value_get_boxed (¶m_values[1]); - if ((event->type == GDK_BUTTON_PRESS || - event->type == GDK_2BUTTON_PRESS || - event->type == GDK_3BUTTON_PRESS || - event->type == GDK_BUTTON_RELEASE) - && event->button.button == 3) - event->button.button = 1; - - /* Support Ctrl-U for blanking the username/password entry */ - if (event->type == GDK_KEY_PRESS && - (event->key.state & GDK_CONTROL_MASK) && - (event->key.keyval == GDK_u || - event->key.keyval == GDK_U)) { - - gtk_entry_set_text (GTK_ENTRY (entry), ""); - } - - return TRUE; -} - -static void -gdm_login_done (int sig) -{ - gdm_kill_thingies (); - _exit (EXIT_SUCCESS); -} - -static void -set_screen_pos (GtkWidget *widget, int x, int y) -{ - int width, height; - - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_WIDGET (widget)); - - gtk_window_get_size (GTK_WINDOW (widget), &width, &height); - - /* allow negative values, to be like standard X geometry ones */ - if (x < 0) - x = gdm_wm_screen.width + x - width; - if (y < 0) - y = gdm_wm_screen.height + y - height; - - if (x < gdm_wm_screen.x) - x = gdm_wm_screen.x; - if (y < gdm_wm_screen.y) - y = gdm_wm_screen.y; - if (x > gdm_wm_screen.x + gdm_wm_screen.width - width) - x = gdm_wm_screen.x + gdm_wm_screen.width - width; - if (y > gdm_wm_screen.y + gdm_wm_screen.height - height) - y = gdm_wm_screen.y + gdm_wm_screen.height - height; - - gtk_window_move (GTK_WINDOW (widget), x, y); -} - -static guint set_pos_id = 0; - -static gboolean -set_pos_idle (gpointer data) -{ - if (GdmSetPosition) { - set_screen_pos (login, GdmPositionX, GdmPositionY); - } else { - gdm_wm_center_window (GTK_WINDOW (login)); - } - set_pos_id = 0; - return FALSE; -} - -static void -login_window_resize (gboolean force) -{ - /* allow opt out if we don't really need - * a resize */ - if ( ! force) { - GtkRequisition req; - int width, height; - - gtk_window_get_size (GTK_WINDOW (login), &width, &height); - gtk_widget_size_request (login, &req); - - if (req.width <= width && req.height <= height) - return; - } - - GTK_WINDOW (login)->need_default_size = TRUE; - gtk_container_check_resize (GTK_CONTAINER (login)); - - if (set_pos_id == 0) - set_pos_id = g_idle_add (set_pos_idle, NULL); -} - - -typedef struct _CursorOffset { - int x; - int y; -} CursorOffset; - -static gboolean -within_rect (GdkRectangle *rect, int x, int y) -{ - return - x >= rect->x && - x <= rect->x + rect->width && - y >= rect->y && - y <= rect->y + rect->height; -} - -/* switch to the xinerama screen where x,y are */ -static void -set_screen_to_pos (int x, int y) -{ - if ( ! within_rect (&gdm_wm_screen, x, y)) { - int i; - /* If not within gdm_wm_screen boundaries, - * maybe we want to switch xinerama - * screen */ - for (i = 0; i < gdm_wm_screens; i++) { - if (within_rect (&gdm_wm_allscreens[i], x, y)) { - gdm_wm_set_screen (i); - break; - } - } - } -} - -static void -gdm_run_gdmconfig (GtkWidget *w, gpointer data) -{ - gtk_widget_set_sensitive (browser, FALSE); - - /* we should be now fine for focusing new windows */ - gdm_wm_focus_new_windows (TRUE); - - /* configure interruption */ - printf ("%c%c%c\n", STX, BEL, GDM_INTERRUPT_CONFIGURE); - fflush (stdout); -} - -static void -gdm_login_restart_handler (void) -{ - if (gdm_wm_warn_dialog ( - _("Are you sure you want to restart the computer?"), "", - _("_Restart"), NULL, TRUE) == GTK_RESPONSE_YES) { - - closelog (); - - gdm_kill_thingies (); - _exit (DISPLAY_REBOOT); - } -} - - -static void -gdm_login_halt_handler (void) -{ - if (gdm_wm_warn_dialog ( - _("Are you sure you want to Shut Down the computer?"), "", - _("Shut _Down"), NULL, TRUE) == GTK_RESPONSE_YES) { - - closelog (); - - gdm_kill_thingies (); - _exit (DISPLAY_HALT); - } -} - -static void -gdm_login_use_chooser_handler (void) -{ - closelog (); - - gdm_kill_thingies (); - _exit (DISPLAY_RUN_CHOOSER); -} - -static void -gdm_login_suspend_handler (void) -{ - if (gdm_wm_warn_dialog ( - _("Are you sure you want to suspend the computer?"), "", - _("_Suspend"), NULL, TRUE) == GTK_RESPONSE_YES) { - - /* suspend interruption */ - printf ("%c%c%c\n", STX, BEL, GDM_INTERRUPT_SUSPEND); - fflush (stdout); - } -} - -static void -gdm_theme_handler (GtkWidget *widget, gpointer data) -{ - const char *theme_name = (const char *)data; - - printf ("%c%c%c%s\n", STX, BEL, GDM_INTERRUPT_THEME, theme_name); - - fflush (stdout); - - gdm_set_theme (theme_name); - - login_window_resize (FALSE); - gdm_wm_center_window (GTK_WINDOW (login)); -} - -static void -gdm_login_language_lookup (const gchar* savedlang) -{ - /* Don't save language unless told otherwise */ - savelang = GTK_RESPONSE_NO; - - if (savedlang == NULL) - savedlang = ""; - - /* If a different language is selected */ - if (curlang != NULL && strcmp (curlang, LAST_LANGUAGE) != 0) { - g_free (language); - if (strcmp (curlang, DEFAULT_LANGUAGE) == 0) - language = g_strdup (""); - else - language = g_strdup (curlang); - - /* User's saved language is not the chosen one */ - if (strcmp (savedlang, language) != 0) { - gchar *firstmsg; - gchar *secondmsg; - char *curname, *savedname; - - if (strcmp (curlang, DEFAULT_LANGUAGE) == 0) { - curname = g_strdup (_("System Default")); - } else { - curname = gdm_lang_name (curlang, - FALSE /* never_encoding */, - TRUE /* no_group */, - TRUE /* untranslated */, - TRUE /* markup */); - } - if (strcmp (savedlang, "") == 0) { - savedname = g_strdup (_("System Default")); - } else { - savedname = gdm_lang_name (savedlang, - FALSE /* never_encoding */, - TRUE /* no_group */, - TRUE /* untranslated */, - TRUE /* markup */); - } - - firstmsg = g_strdup_printf (_("Do you wish to make %s the default for future sessions?"), - curname); - secondmsg = g_strdup_printf (_("You have chosen %s for this session, but your default setting is %s."), - curname, savedname); - g_free (curname); - g_free (savedname); - - savelang = gdm_wm_query_dialog (firstmsg, secondmsg, - _("Make _Default"), _("Just For _This Session"), TRUE); - g_free (firstmsg); - g_free (secondmsg); - } - } else { - g_free (language); - language = g_strdup (savedlang); - } -} - -static int dance_handler = 0; - -static gboolean -dance (gpointer data) -{ - static double t1 = 0.0, t2 = 0.0; - double xm, ym; - int x, y; - static int width = -1; - static int height = -1; - - if (width == -1) - width = gdm_wm_screen.width; - if (height == -1) - height = gdm_wm_screen.height; - - if (login == NULL || - login->window == NULL) { - dance_handler = 0; - return FALSE; - } - - xm = cos (2.31 * t1); - ym = sin (1.03 * t2); - - t1 += 0.03 + (rand () % 10) / 500.0; - t2 += 0.03 + (rand () % 10) / 500.0; - - x = gdm_wm_screen.x + (width / 2) + (width / 5) * xm; - y = gdm_wm_screen.y + (height / 2) + (height / 5) * ym; - - set_screen_pos (login, - x - login->allocation.width / 2, - y - login->allocation.height / 2); - - return TRUE; -} - -static gboolean -evil (const char *user) -{ - static gboolean old_lock; - - if (dance_handler == 0 && - /* do not translate */ - strcmp (user, "Start Dancing") == 0) { - gdm_common_setup_cursor (GDK_UMBRELLA); - dance_handler = g_timeout_add (50, dance, NULL); - old_lock = GdmLockPosition; - GdmLockPosition = TRUE; - gtk_entry_set_text (GTK_ENTRY (entry), ""); - return TRUE; - } else if (dance_handler != 0 && - /* do not translate */ - strcmp (user, "Stop Dancing") == 0) { - gdm_common_setup_cursor (GDK_LEFT_PTR); - g_source_remove (dance_handler); - dance_handler = 0; - GdmLockPosition = old_lock; - gdm_wm_center_window (GTK_WINDOW (login)); - gtk_entry_set_text (GTK_ENTRY (entry), ""); - return TRUE; - /* do not translate */ - } else if (strcmp (user, "Gimme Random Cursor") == 0) { - gdm_common_setup_cursor (((rand () >> 3) % (GDK_LAST_CURSOR/2)) * 2); - gtk_entry_set_text (GTK_ENTRY (entry), ""); - return TRUE; - /* do not translate */ - } else if (strcmp (user, "Require Quater") == 0 || - strcmp (user, "Require Quarter") == 0) { - /* btw, note that I misspelled quarter before and - * thus this checks for Quater as well as Quarter to - * keep compatibility which is obviously important for - * something like this */ - require_quarter = TRUE; - gtk_entry_set_text (GTK_ENTRY (entry), ""); - return TRUE; - } - - return FALSE; -} - -static void -gdm_login_enter (GtkWidget *entry) -{ - const char *login_string; - const char *str; - char *tmp; - - if (entry == NULL) - return; - - gtk_widget_set_sensitive (entry, FALSE); - gtk_widget_set_sensitive (ok_button, FALSE); - gtk_widget_set_sensitive (cancel_button, FALSE); - - login_string = gtk_entry_get_text (GTK_ENTRY (entry)); - - str = gtk_label_get_text (GTK_LABEL (label)); - if (str != NULL && - (strcmp (str, _("Username:")) == 0 || - strcmp (str, _("_Username:")) == 0) && - /* If in timed login mode, and if this is the login - * entry. Then an enter by itself is sort of like I want to - * log in as the timed user, really. */ - ve_string_empty (login_string) && - timed_handler_id != 0) { - /* timed interruption */ - printf ("%c%c%c\n", STX, BEL, GDM_INTERRUPT_TIMED_LOGIN); - fflush (stdout); - return; - } - - if (str != NULL && - (strcmp (str, _("Username:")) == 0 || - strcmp (str, _("_Username:")) == 0) && - /* evilness */ - evil (login_string)) { - /* obviously being 100% reliable is not an issue for - this test */ - gtk_widget_set_sensitive (entry, TRUE); - gtk_widget_set_sensitive (ok_button, TRUE); - gtk_widget_set_sensitive (cancel_button, TRUE); - gtk_widget_grab_focus (entry); - gtk_window_set_focus (GTK_WINDOW (login), entry); - return; - } - - /* clear the err_box */ - if (err_box_clear_handler > 0) - g_source_remove (err_box_clear_handler); - err_box_clear_handler = 0; - gtk_label_set_text (GTK_LABEL (err_box), ""); - - tmp = ve_locale_from_utf8 (gtk_entry_get_text (GTK_ENTRY (entry))); - printf ("%c%s\n", STX, tmp); - fflush (stdout); - g_free (tmp); -} - -static void -gdm_login_ok_button_press (GtkButton *button, GtkWidget *entry) -{ - gdm_login_enter (entry); -} - -static void -gdm_login_cancel_button_press (GtkButton *button, GtkWidget *entry) -{ - GtkTreeSelection *selection; - - if (browser != NULL) { - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (browser)); - gtk_tree_selection_unselect_all (selection); - } - - printf ("%c%c%c\n", STX, BEL, - GDM_INTERRUPT_CANCEL); - fflush (stdout); -} - -static gboolean -gdm_login_focus_in (GtkWidget *widget, GdkEventFocus *event) -{ - if (title_box != NULL) - gtk_widget_set_state (title_box, GTK_STATE_SELECTED); - - if (icon_button != NULL) - gtk_widget_set_state (icon_button, GTK_STATE_NORMAL); - - return FALSE; -} - -static gboolean -gdm_login_focus_out (GtkWidget *widget, GdkEventFocus *event) -{ - if (title_box != NULL) - gtk_widget_set_state (title_box, GTK_STATE_NORMAL); - - return FALSE; -} - -static void -gdm_login_session_handler (GtkWidget *widget) -{ - gchar *s; - - current_session = g_object_get_data (G_OBJECT (widget), SESSION_NAME); - - s = g_strdup_printf (_("%s session selected"), gdm_session_name (current_session)); - - gtk_label_set_text (GTK_LABEL (msg), s); - g_free (s); - - login_window_resize (FALSE /* force */); -} - -static void -gdm_login_session_init (GtkWidget *menu) -{ - GSList *sessgrp = NULL; - GList *tmp; - GtkWidget *item; - int num = 1; - char *label; - - current_session = NULL; - - if (gdm_config_get_bool (GDM_KEY_SHOW_LAST_SESSION)) { - current_session = LAST_SESSION; - item = gtk_radio_menu_item_new_with_mnemonic (NULL, _("_Last")); - g_object_set_data (G_OBJECT (item), - SESSION_NAME, - LAST_SESSION); - sessgrp = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (gdm_login_session_handler), - NULL); - gtk_widget_show (GTK_WIDGET (item)); - item = gtk_menu_item_new (); - gtk_widget_set_sensitive (item, FALSE); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (GTK_WIDGET (item)); - } - - gdm_session_list_init (); - - for (tmp = sessions; tmp != NULL; tmp = tmp->next) { - GdmSession *session; - char *file; - - file = (char *) tmp->data; - session = g_hash_table_lookup (sessnames, file); - - if (num < 10 && - (strcmp (file, GDM_SESSION_FAILSAFE_GNOME) != 0) && - (strcmp (file, GDM_SESSION_FAILSAFE_XTERM) != 0)) - label = g_strdup_printf ("_%d. %s", num, session->name); - else - label = g_strdup (session->name); - num++; - - item = gtk_radio_menu_item_new_with_mnemonic (sessgrp, label); - g_free (label); - g_object_set_data_full (G_OBJECT (item), SESSION_NAME, - g_strdup (file), (GDestroyNotify) g_free); - - sessgrp = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (gdm_login_session_handler), NULL); - gtk_widget_show (GTK_WIDGET (item)); - } - - /* Select the proper session */ - { - GSList *tmp; - - tmp = sessgrp; - while (tmp != NULL) { - GtkWidget *w = tmp->data; - const char *n; - - n = g_object_get_data (G_OBJECT (w), SESSION_NAME); - - if (n && strcmp (n, current_session) == 0) { - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), - TRUE); - break; - } - - tmp = tmp->next; - } - } -} - - -static void -gdm_login_language_handler (GtkWidget *widget) -{ - gchar *s; - char *name; - - if (!widget) - return; - - curlang = g_object_get_data (G_OBJECT (widget), "Language"); - name = gdm_lang_name (curlang, - FALSE /* never_encoding */, - TRUE /* no_group */, - TRUE /* untranslated */, - TRUE /* makrup */); - s = g_strdup_printf (_("%s language selected"), name); - g_free (name); - gtk_label_set_markup (GTK_LABEL (msg), s); - g_free (s); - - login_window_resize (FALSE /* force */); -} - - -static GtkWidget * -gdm_login_language_menu_new (void) -{ - GtkWidget *menu; - GtkWidget *item, *ammenu, *nzmenu, *omenu; - GList *langlist, *li; - gboolean has_other_locale = FALSE; - GtkWidget *other_menu; - const char *g1; - const char *g2; - char *menulabel; - /* Start numbering with 3 since 1-2 is used for toplevel menu */ - int g1_num = 3; - int g2_num = 3; - int other_num = 3; - int num; - - langlist = gdm_lang_read_locale_file (gdm_config_get_string (GDM_KEY_LOCALE_FILE)); - - if (langlist == NULL) - return NULL; - - menu = gtk_menu_new (); - - curlang = LAST_LANGUAGE; - - item = gtk_radio_menu_item_new_with_mnemonic (NULL, _("_Last")); - languages = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (gdm_login_language_handler), - NULL); - gtk_widget_show (GTK_WIDGET (item)); - g_object_set_data (G_OBJECT (item), - "Language", - LAST_LANGUAGE); - - item = gtk_radio_menu_item_new_with_mnemonic (languages, _("_System Default")); - languages = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (gdm_login_language_handler), - NULL); - gtk_widget_show (GTK_WIDGET (item)); - g_object_set_data (G_OBJECT (item), - "Language", - DEFAULT_LANGUAGE); - - item = gtk_menu_item_new (); - gtk_widget_set_sensitive (item, FALSE); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (GTK_WIDGET (item)); - - menulabel = g_strdup_printf ("_1. %s", gdm_lang_group1()); - item = gtk_menu_item_new_with_mnemonic (menulabel); - g_free (menulabel); - ammenu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), GTK_WIDGET (ammenu)); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (GTK_WIDGET (item)); - - menulabel = g_strdup_printf ("_2. %s", gdm_lang_group2()); - item = gtk_menu_item_new_with_mnemonic (menulabel); - g_free (menulabel); - nzmenu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), nzmenu); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (GTK_WIDGET (item)); - - other_menu = item = gtk_menu_item_new_with_mnemonic (_("_Other")); - omenu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), omenu); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (GTK_WIDGET (item)); - - g1 = gdm_lang_group1 (); - g2 = gdm_lang_group2 (); - - for (li = langlist; li != NULL; li = li->next) { - char *lang = li->data; - char *name; - char *untranslated; - char *group; - char *p; - GtkWidget *box, *l; - - li->data = NULL; - - group = name = gdm_lang_name (lang, - FALSE /* never_encoding */, - FALSE /* no_group */, - FALSE /* untranslated */, - FALSE /* markup */); - if (name == NULL) { - g_free (lang); - continue; - } - - untranslated = gdm_lang_untranslated_name (lang, - TRUE /* markup */); - - p = strchr (name, '|'); - if (p != NULL) { - *p = '\0'; - name = p+1; - } - - box = gtk_hbox_new (FALSE, 5); - gtk_widget_show (box); - - if (strcmp (group, g1) == 0) - num = g1_num++; - else if (strcmp (group, g2) == 0) - num = g2_num++; - else - num = other_num++; - - if (num < 10) - menulabel = g_strdup_printf ("_%d. %s", num, name); - else if ((num -10) + (int)'a' <= (int)'z') - menulabel = g_strdup_printf ("_%c. %s", - (char)(num-10)+'a', - name); - else - menulabel = g_strdup (name); - - l = gtk_label_new_with_mnemonic (menulabel); - if ( ! gdm_lang_name_translated (lang)) - gtk_widget_set_direction (l, GTK_TEXT_DIR_LTR); - gtk_widget_show (l); - gtk_box_pack_start (GTK_BOX (box), l, FALSE, FALSE, 0); - - if (untranslated != NULL) { - l = gtk_label_new (untranslated); - /* we really wantd LTR here for the widget */ - gtk_widget_set_direction (l, GTK_TEXT_DIR_LTR); - gtk_label_set_use_markup (GTK_LABEL (l), TRUE); - gtk_widget_show (l); - gtk_box_pack_end (GTK_BOX (box), l, FALSE, FALSE, 0); - } - - item = gtk_radio_menu_item_new (languages); - gtk_container_add (GTK_CONTAINER (item), box); - languages = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); - g_object_set_data_full (G_OBJECT (item), - "Language", - g_strdup (lang), - (GDestroyNotify) g_free); - - if (strcmp (group, g1) == 0) { - gtk_menu_shell_append (GTK_MENU_SHELL (ammenu), item); - } else if (strcmp (group, g2) == 0) { - gtk_menu_shell_append (GTK_MENU_SHELL (nzmenu), item); - } else { - gtk_menu_shell_append (GTK_MENU_SHELL (omenu), item); - has_other_locale = TRUE; - } - - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (gdm_login_language_handler), - NULL); - gtk_widget_show (GTK_WIDGET (item)); - - g_free (lang); - g_free (group); - g_free (untranslated); - } - if ( ! has_other_locale) - gtk_widget_destroy (other_menu); - - g_list_free (langlist); - - return menu; -} - -static gboolean -theme_allowed (const char *theme) -{ - gchar * themestoallow = gdm_config_get_string (GDM_KEY_GTK_THEMES_TO_ALLOW); - char **vec; - int i; - - if (ve_string_empty (themestoallow) || - g_ascii_strcasecmp (themestoallow, "all") == 0) - return TRUE; - - vec = g_strsplit (themestoallow, ",", 0); - if (vec == NULL || vec[0] == NULL) - return TRUE; - - for (i = 0; vec[i] != NULL; i++) { - if (strcmp (vec[i], theme) == 0) { - g_strfreev (vec); - return TRUE; - } - } - - g_strfreev (vec); - - return FALSE; -} - -static GSList * -build_theme_list (void) -{ - DIR *dir; - struct dirent *de; - gchar *theme_dir; - GSList *theme_list = NULL; - - theme_dir = gtk_rc_get_theme_dir (); - dir = opendir (theme_dir); - - while ((de = readdir (dir))) { - char *name; - if (de->d_name[0] == '.') - continue; - if ( ! theme_allowed (de->d_name)) - continue; - name = g_build_filename (theme_dir, de->d_name, GTK_KEY, NULL); - if (g_file_test (name, G_FILE_TEST_IS_DIR)) - theme_list = g_slist_append (theme_list, g_strdup (de->d_name)); - g_free (name); - } - g_free (theme_dir); - closedir (dir); - - return theme_list; -} - -static GtkWidget * -gdm_login_theme_menu_new (void) -{ - GSList *theme_list; - GtkWidget *item; - GtkWidget *menu; - int num = 1; - - if ( ! gdm_config_get_bool (GDM_KEY_ALLOW_GTK_THEME_CHANGE)) - return NULL; - - menu = gtk_menu_new (); - - for (theme_list = build_theme_list (); - theme_list != NULL; - theme_list = theme_list->next) { - char *menu_item_name; - char *theme_name = theme_list->data; - theme_list->data = NULL; - - if (num < 10) - menu_item_name = g_strdup_printf ("_%d. %s", num, _(theme_name)); - else if ((num -10) + (int)'a' <= (int)'z') - menu_item_name = g_strdup_printf ("_%c. %s", - (char)(num-10)+'a', - _(theme_name)); - else - menu_item_name = g_strdup (theme_name); - num++; - - item = gtk_menu_item_new_with_mnemonic (menu_item_name); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (GTK_WIDGET (item)); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (gdm_theme_handler), theme_name); - g_free (menu_item_name); - } - g_slist_free (theme_list); - return menu; -} - -static gboolean -err_box_clear (gpointer data) -{ - if (err_box != NULL) - gtk_label_set_text (GTK_LABEL (err_box), ""); - - err_box_clear_handler = 0; - return FALSE; -} - -static void -browser_set_user (const char *user) -{ - gboolean old_selecting_user = selecting_user; - GtkTreeSelection *selection; - GtkTreeIter iter = {0}; - GtkTreeModel *tm = NULL; - - if (browser == NULL) - return; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (browser)); - gtk_tree_selection_unselect_all (selection); - - if (ve_string_empty (user)) - return; - - selecting_user = FALSE; - - tm = gtk_tree_view_get_model (GTK_TREE_VIEW (browser)); - - if (gtk_tree_model_get_iter_first (tm, &iter)) - { - do - { - char *login; - gtk_tree_model_get (tm, &iter, GREETER_ULIST_LOGIN_COLUMN, - &login, -1); - if (login != NULL && strcmp (user, login) == 0) - { - GtkTreePath *path = gtk_tree_model_get_path (tm, &iter); - gtk_tree_selection_select_iter (selection, &iter); - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (browser), - path, NULL, - FALSE, 0.0, 0.0); - gtk_tree_path_free (path); - break; - } - - } - while (gtk_tree_model_iter_next (tm, &iter)); - } - selecting_user = old_selecting_user; -} - -static Display * -get_parent_display (void) -{ - static gboolean tested = FALSE; - static Display *dsp = NULL; - - if (tested) - return dsp; - - tested = TRUE; - - if (g_getenv ("GDM_PARENT_DISPLAY") != NULL) - { - char *old_xauth = g_strdup (g_getenv ("XAUTHORITY")); - if (g_getenv ("GDM_PARENT_XAUTHORITY") != NULL) - { - g_setenv ("XAUTHORITY", - g_getenv ("GDM_PARENT_XAUTHORITY"), TRUE); - } - dsp = XOpenDisplay (g_getenv ("GDM_PARENT_DISPLAY")); - if (old_xauth != NULL) - g_setenv ("XAUTHORITY", old_xauth, TRUE); - else - g_unsetenv ("XAUTHORITY"); - g_free (old_xauth); - } - - return dsp; -} - -static gboolean -greeter_is_capslock_on (void) -{ - XkbStateRec states; - Display *dsp; - - /* HACK! incredible hack, if GDM_PARENT_DISPLAY is set we get - * indicator state from the parent display, since we must be inside an - * Xnest */ - dsp = get_parent_display (); - if (dsp == NULL) - dsp = GDK_DISPLAY (); - - if (XkbGetState (dsp, XkbUseCoreKbd, &states) != Success) - return FALSE; - - return (states.locked_mods & LockMask) != 0; -} - -static gboolean -gdm_login_ctrl_handler (GIOChannel *source, GIOCondition cond, gint fd) -{ - gchar buf[PIPE_SIZE]; - gsize len; - char *tmp; - gint i, x, y; - GtkWidget *dlg; - static gboolean replace_msg = TRUE; - static gboolean messages_to_give = FALSE; - - /* If this is not incoming i/o then return */ - if (cond != G_IO_IN) - return (TRUE); - - /* Read random garbage from i/o channel until STX is found */ - do { - g_io_channel_read_chars (source, buf, 1, &len, NULL); - - if (len != 1) - return (TRUE); - } while (buf[0] && buf[0] != STX); - - - /* Read opcode */ - g_io_channel_read_chars (source, buf, 1, &len, NULL); - - /* If opcode couldn't be read */ - if (len != 1) - return (TRUE); - - /* Parse opcode */ - switch (buf[0]) { - case GDM_SETLOGIN: - /* somebody is trying to fool us this is the user that - * wants to log in, and well, we are the gullible kind */ - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); - buf[len-1] = '\0'; - g_free (curuser); - curuser = g_strdup (buf); - if (browser_ok && gdm_config_get_bool (GDM_KEY_BROWSER)) - browser_set_user (curuser); - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_PROMPT: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); - buf[len-1] = '\0'; - - tmp = ve_locale_to_utf8 (buf); - if (strcmp (tmp, _("Username:")) == 0) { - gdm_common_login_sound (gdm_config_get_string (GDM_KEY_SOUND_PROGRAM), - gdm_config_get_string (GDM_KEY_SOUND_ON_LOGIN_FILE), - gdm_config_get_bool (GDM_KEY_SOUND_ON_LOGIN)); - gtk_label_set_text_with_mnemonic (GTK_LABEL (label), _("_Username:")); - } else { - gtk_label_set_text (GTK_LABEL (label), tmp); - } - g_free (tmp); - - gtk_widget_show (GTK_WIDGET (label)); - gtk_entry_set_text (GTK_ENTRY (entry), ""); - gtk_entry_set_max_length (GTK_ENTRY (entry), PW_ENTRY_SIZE); - gtk_entry_set_visibility (GTK_ENTRY (entry), TRUE); - gtk_widget_set_sensitive (entry, TRUE); - gtk_widget_set_sensitive (ok_button, TRUE); - gtk_widget_set_sensitive (cancel_button, TRUE); - gtk_widget_grab_focus (entry); - gtk_window_set_focus (GTK_WINDOW (login), entry); - gtk_widget_show (entry); - - /* replace rather then append next message string */ - replace_msg = TRUE; - - /* the user has seen messages */ - messages_to_give = FALSE; - - login_window_resize (FALSE /* force */); - break; - - case GDM_NOECHO: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); - buf[len-1] = '\0'; - - tmp = ve_locale_to_utf8 (buf); - if (strcmp (tmp, _("Password:")) == 0) { - gtk_label_set_text_with_mnemonic (GTK_LABEL (label), _("_Password:")); - } else { - gtk_label_set_text (GTK_LABEL (label), tmp); - } - g_free (tmp); - - gtk_widget_show (GTK_WIDGET (label)); - gtk_entry_set_text (GTK_ENTRY (entry), ""); - gtk_entry_set_max_length (GTK_ENTRY (entry), PW_ENTRY_SIZE); - gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE); - gtk_widget_set_sensitive (entry, TRUE); - gtk_widget_set_sensitive (ok_button, TRUE); - gtk_widget_set_sensitive (cancel_button, TRUE); - gtk_widget_grab_focus (entry); - gtk_window_set_focus (GTK_WINDOW (login), entry); - gtk_widget_show (entry); - - /* replace rather then append next message string */ - replace_msg = TRUE; - - /* the user has seen messages */ - messages_to_give = FALSE; - - login_window_resize (FALSE /* force */); - break; - - case GDM_MSG: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); - buf[len-1] = '\0'; - - /* the user has not yet seen messages */ - messages_to_give = TRUE; - - /* HAAAAAAACK. Sometimes pam sends many many messages, SO - * we try to collect them until the next prompt or reset or - * whatnot */ - if ( ! replace_msg && - /* empty message is for clearing */ - ! ve_string_empty (buf)) { - const char *oldtext; - oldtext = gtk_label_get_text (GTK_LABEL (msg)); - if ( ! ve_string_empty (oldtext)) { - char *newtext; - tmp = ve_locale_to_utf8 (buf); - newtext = g_strdup_printf ("%s\n%s", oldtext, tmp); - g_free (tmp); - gtk_label_set_text (GTK_LABEL (msg), newtext); - g_free (newtext); - } else { - tmp = ve_locale_to_utf8 (buf); - gtk_label_set_text (GTK_LABEL (msg), tmp); - g_free (tmp); - } - } else { - tmp = ve_locale_to_utf8 (buf); - gtk_label_set_text (GTK_LABEL (msg), tmp); - g_free (tmp); - } - replace_msg = FALSE; - - gtk_widget_show (GTK_WIDGET (msg)); - printf ("%c\n", STX); - fflush (stdout); - - login_window_resize (FALSE /* force */); - - break; - - case GDM_ERRBOX: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); - buf[len-1] = '\0'; - tmp = ve_locale_to_utf8 (buf); - gtk_label_set_text (GTK_LABEL (err_box), tmp); - g_free (tmp); - if (err_box_clear_handler > 0) - g_source_remove (err_box_clear_handler); - if (ve_string_empty (buf)) - err_box_clear_handler = 0; - else - err_box_clear_handler = g_timeout_add (30000, - err_box_clear, - NULL); - printf ("%c\n", STX); - fflush (stdout); - - login_window_resize (FALSE /* force */); - break; - - case GDM_ERRDLG: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); - buf[len-1] = '\0'; - - /* we should be now fine for focusing new windows */ - gdm_wm_focus_new_windows (TRUE); - - tmp = ve_locale_to_utf8 (buf); - dlg = ve_hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - tmp, - ""); - g_free (tmp); - - gdm_wm_center_window (GTK_WINDOW (dlg)); - - gdm_wm_no_login_focus_push (); - gtk_dialog_run (GTK_DIALOG (dlg)); - gtk_widget_destroy (dlg); - gdm_wm_no_login_focus_pop (); - - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_SESS: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); - buf[len-1] = '\0'; - tmp = ve_locale_to_utf8 (buf); - session = gdm_session_lookup (tmp); - g_free (tmp); - if (gdm_get_save_session () == GTK_RESPONSE_CANCEL) { - printf ("%c%s\n", STX, GDM_RESPONSE_CANCEL); - } else { - tmp = ve_locale_from_utf8 (session); - printf ("%c%s\n", STX, tmp); - g_free (tmp); - } - fflush (stdout); - break; - - case GDM_LANG: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); - buf[len-1] = '\0'; - gdm_login_language_lookup (buf); - if (savelang == GTK_RESPONSE_CANCEL) - printf ("%c%s\n", STX, GDM_RESPONSE_CANCEL); - else - printf ("%c%s\n", STX, language); - fflush (stdout); - break; - - case GDM_SSESS: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ - - if (gdm_get_save_session () == GTK_RESPONSE_YES) - printf ("%cY\n", STX); - else - printf ("%c\n", STX); - fflush (stdout); - - break; - - case GDM_SLANG: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ - - if (savelang == GTK_RESPONSE_YES) - printf ("%cY\n", STX); - else - printf ("%c\n", STX); - fflush (stdout); - - break; - - case GDM_RESET: - if (gdm_config_get_bool (GDM_KEY_QUIVER) && - login->window != NULL && - icon_win == NULL && - GTK_WIDGET_VISIBLE (login)) { - Window lw = GDK_WINDOW_XWINDOW (login->window); - - gdm_wm_get_window_pos (lw, &x, &y); - - for (i = 32 ; i > 0 ; i = i/4) { - gdm_wm_move_window_now (lw, i+x, y); - usleep (200); - gdm_wm_move_window_now (lw, x, y); - usleep (200); - gdm_wm_move_window_now (lw, -i+x, y); - usleep (200); - gdm_wm_move_window_now (lw, x, y); - usleep (200); - } - } - /* fall thru to reset */ - - case GDM_RESETOK: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); - buf[len-1] = '\0'; - - if (curuser != NULL) { - g_free (curuser); - curuser = NULL; - } - - gtk_widget_set_sensitive (entry, TRUE); - gtk_widget_set_sensitive (ok_button, TRUE); - gtk_widget_set_sensitive (cancel_button, TRUE); - - if (browser_ok && gdm_config_get_bool (GDM_KEY_BROWSER)) - gtk_widget_set_sensitive (GTK_WIDGET (browser), TRUE); - - tmp = ve_locale_to_utf8 (buf); - gtk_label_set_text (GTK_LABEL (msg), tmp); - g_free (tmp); - gtk_widget_show (GTK_WIDGET (msg)); - - printf ("%c\n", STX); - fflush (stdout); - - login_window_resize (FALSE /* force */); - break; - - case GDM_QUIT: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ - - if (timed_handler_id != 0) { - g_source_remove (timed_handler_id); - timed_handler_id = 0; - } - - if (require_quarter) { - /* we should be now fine for focusing new windows */ - gdm_wm_focus_new_windows (TRUE); - - dlg = ve_hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_INFO, - GTK_BUTTONS_OK, - /* translators: This is a nice and evil eggie text, translate - * to your favourite currency */ - _("Please insert 25 cents " - "to log in."), - ""); - gdm_wm_center_window (GTK_WINDOW (dlg)); - - gdm_wm_no_login_focus_push (); - gtk_dialog_run (GTK_DIALOG (dlg)); - gtk_widget_destroy (dlg); - gdm_wm_no_login_focus_pop (); - } - - /* Hide the login window now */ - gtk_widget_hide (login); - - if (messages_to_give) { - const char *oldtext; - oldtext = gtk_label_get_text (GTK_LABEL (msg)); - - if ( ! ve_string_empty (oldtext)) { - /* we should be now fine for focusing new windows */ - gdm_wm_focus_new_windows (TRUE); - - dlg = ve_hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_INFO, - GTK_BUTTONS_OK, - oldtext, - ""); - gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); - gdm_wm_center_window (GTK_WINDOW (dlg)); - - gdm_wm_no_login_focus_push (); - gtk_dialog_run (GTK_DIALOG (dlg)); - gtk_widget_destroy (dlg); - gdm_wm_no_login_focus_pop (); - } - messages_to_give = FALSE; - } - - gdm_kill_thingies (); - - gdk_flush (); - - printf ("%c\n", STX); - fflush (stdout); - - /* screw gtk_main_quit, we want to make sure we definately die */ - _exit (EXIT_SUCCESS); - break; - - case GDM_STARTTIMER: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ - - /* - * Timed Login: Start Timer Loop - */ - - if (timed_handler_id == 0 && - gdm_config_get_bool (GDM_KEY_TIMED_LOGIN_ENABLE) && - ! ve_string_empty (gdm_config_get_string (GDM_KEY_TIMED_LOGIN)) && - gdm_config_get_int (GDM_KEY_TIMED_LOGIN_DELAY) > 0) { - gdm_timed_delay = gdm_config_get_int (GDM_KEY_TIMED_LOGIN_DELAY); - timed_handler_id = g_timeout_add (1000, gdm_timer, NULL); - } - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_STOPTIMER: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ - - /* - * Timed Login: Stop Timer Loop - */ - - if (timed_handler_id != 0) { - g_source_remove (timed_handler_id); - timed_handler_id = 0; - } - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_DISABLE: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ - if (clock_label != NULL) - GTK_WIDGET_SET_FLAGS (clock_label->parent, GTK_SENSITIVE); - gtk_widget_set_sensitive (login, FALSE); - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_ENABLE: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ - gtk_widget_set_sensitive (login, TRUE); - if (clock_label != NULL) - GTK_WIDGET_UNSET_FLAGS (clock_label->parent, GTK_SENSITIVE); - printf ("%c\n", STX); - fflush (stdout); - break; - - /* These are handled separately so ignore them here and send - * back a NULL response so that the daemon quits sending them */ - case GDM_NEEDPIC: - case GDM_READPIC: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_NOFOCUS: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ - - gdm_wm_no_login_focus_push (); - - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_FOCUS: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ - - gdm_wm_no_login_focus_pop (); - - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_SAVEDIE: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ - - /* Set busy cursor */ - gdm_common_setup_cursor (GDK_WATCH); - - gdm_wm_save_wm_order (); - - gdm_kill_thingies (); - gdk_flush (); - - _exit (EXIT_SUCCESS); - - case GDM_QUERY_CAPSLOCK: - g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ - - if (greeter_is_capslock_on ()) - printf ("%cY\n", STX); - else - printf ("%c\n", STX); - fflush (stdout); - - break; - - default: - gdm_kill_thingies (); - gdm_common_fail_greeter ("Unexpected greeter command received: '%c'", buf[0]); - break; - } - - return (TRUE); -} - - -static void -gdm_login_browser_populate (void) -{ - GList *li; - - for (li = users; li != NULL; li = li->next) { - GdmUser *usr = li->data; - GtkTreeIter iter = {0}; - char *label; - char *login, *gecos; - - login = g_markup_escape_text (usr->login, -1); - gecos = g_markup_escape_text (usr->gecos, -1); - - label = g_strdup_printf ("<b>%s</b>\n%s", - login, - gecos); - - g_free (login); - g_free (gecos); - gtk_list_store_append (GTK_LIST_STORE (browser_model), &iter); - gtk_list_store_set (GTK_LIST_STORE (browser_model), &iter, - GREETER_ULIST_ICON_COLUMN, usr->picture, - GREETER_ULIST_LOGIN_COLUMN, usr->login, - GREETER_ULIST_LABEL_COLUMN, label, - -1); - g_free (label); - } -} - - -static void -user_selected (GtkTreeSelection *selection, gpointer data) -{ - GtkTreeModel *tm = NULL; - GtkTreeIter iter = {0}; - -#ifdef FIXME - g_free (selected_browser_user); - selected_browser_user = NULL; -#endif - - if (gtk_tree_selection_get_selected (selection, &tm, &iter)) { - char *login; - gtk_tree_model_get (tm, &iter, GREETER_ULIST_LOGIN_COLUMN, - &login, -1); - if (login != NULL) { - const char *str = gtk_label_get_text (GTK_LABEL (label)); - - if (selecting_user && - str != NULL && - (strcmp (str, _("Username:")) == 0 || - strcmp (str, _("_Username:")) == 0)) { - gtk_entry_set_text (GTK_ENTRY (entry), login); - } -#ifdef FIXME - selected_browser_user = g_strdup (login); -#endif - if (selecting_user) { - printf ("%c%c%c%s\n", STX, BEL, - GDM_INTERRUPT_SELECT_USER, login); - fflush (stdout); - } - } - } -} - -static void -browser_change_focus (GtkWidget *widget, GdkEventButton *event, gpointer data) -{ - gtk_widget_grab_focus (entry); -} - -static gboolean -gdm_login_handle_pressed (GtkWidget *widget, GdkEventButton *event) -{ - gint xp, yp; - GdkModifierType mask; - CursorOffset *p; - GdkCursor *fleur_cursor; - - if (login == NULL || - login->window == NULL || - event->type != GDK_BUTTON_PRESS || - GdmLockPosition) - return FALSE; - - gdk_window_raise (login->window); - - p = g_new0 (CursorOffset, 1); - g_object_set_data_full (G_OBJECT (widget), "offset", p, - (GDestroyNotify)g_free); - - gdk_window_get_pointer (login->window, &xp, &yp, &mask); - p->x = xp; - p->y = yp; - - gtk_grab_add (widget); - fleur_cursor = gdk_cursor_new (GDK_FLEUR); - gdk_pointer_grab (widget->window, TRUE, - GDK_BUTTON_RELEASE_MASK | - GDK_BUTTON_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK, - NULL, - fleur_cursor, - GDK_CURRENT_TIME); - gdk_cursor_unref (fleur_cursor); - gdk_flush (); - - return TRUE; -} - -static gboolean -gdm_login_handle_released (GtkWidget *widget, GdkEventButton *event) -{ - gtk_grab_remove (widget); - gdk_pointer_ungrab (GDK_CURRENT_TIME); - - g_object_set_data (G_OBJECT (widget), "offset", NULL); - - return TRUE; -} - - -static gboolean -gdm_login_handle_motion (GtkWidget *widget, GdkEventMotion *event) -{ - int xp, yp; - CursorOffset *p; - GdkModifierType mask; - - p = g_object_get_data (G_OBJECT (widget), "offset"); - - if (p == NULL) - return FALSE; - - gdk_window_get_pointer (gdk_get_default_root_window (), &xp, &yp, &mask); - - set_screen_to_pos (xp, yp); - - GdmSetPosition = TRUE; - GdmPositionX = xp - p->x; - GdmPositionY = yp - p->y; - - if (GdmPositionX < 0) - GdmPositionX = 0; - if (GdmPositionY < 0) - GdmPositionY = 0; - - set_screen_pos (GTK_WIDGET (login), GdmPositionX, GdmPositionY); - - return TRUE; -} - -static GtkWidget * -create_handle (void) -{ - GtkWidget *hbox, *w; - - title_box = gtk_event_box_new (); - g_signal_connect (G_OBJECT (title_box), "button_press_event", - G_CALLBACK (gdm_login_handle_pressed), - NULL); - g_signal_connect (G_OBJECT (title_box), "button_release_event", - G_CALLBACK (gdm_login_handle_released), - NULL); - g_signal_connect (G_OBJECT (title_box), "motion_notify_event", - G_CALLBACK (gdm_login_handle_motion), - NULL); - - hbox = gtk_hbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (title_box), hbox); - w = gtk_label_new (_("GNOME Desktop Manager")); - gtk_misc_set_padding (GTK_MISC (w), 4, 4); - gtk_box_pack_start (GTK_BOX (hbox), w, - TRUE, TRUE, 4); - - gtk_widget_show_all (title_box); - - return title_box; -} - -static gboolean -update_clock (void) -{ - struct tm *the_tm; - gchar *str; - gint time_til_next_min; - - if (clock_label == NULL) - return FALSE; - - str = gdm_common_get_clock (&the_tm); - gtk_label_set_text (GTK_LABEL (clock_label), str); - g_free (str); - - /* account for leap seconds */ - time_til_next_min = 60 - the_tm->tm_sec; - time_til_next_min = (time_til_next_min>=0?time_til_next_min:0); - - g_timeout_add (time_til_next_min*1000, update_clock, NULL); - return FALSE; -} - -/* doesn't check for executability, just for existence */ -static gboolean -bin_exists (const char *command) -{ - char *bin; - - if (ve_string_empty (command)) - return FALSE; - - /* Note, check only for existence, not for executability */ - bin = ve_first_word (command); - if (bin != NULL && - g_access (bin, F_OK) == 0) { - g_free (bin); - return TRUE; - } else { - g_free (bin); - return FALSE; - } -} - -static gboolean -window_browser_event (GtkWidget *window, GdkEvent *event, gpointer data) -{ - switch (event->type) { - /* FIXME: Fix fingering cuz it's cool */ -#ifdef FIXME - case GDK_KEY_PRESS: - if ((event->key.state & GDK_CONTROL_MASK) && - (event->key.keyval == GDK_f || - event->key.keyval == GDK_F) && - selected_browser_user != NULL) { - GtkWidget *d, *less; - char *command; - d = gtk_dialog_new_with_buttons (_("Finger"), - NULL /* parent */, - 0 /* flags */, - GTK_STOCK_OK, - GTK_RESPONSE_OK, - NULL); - gtk_dialog_set_has_separator (GTK_DIALOG (d), FALSE); - less = gnome_less_new (); - gtk_widget_show (less); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (d)->vbox), - less, - TRUE, - TRUE, - 0); - - /* hack to make this be the size of a terminal */ - gnome_less_set_fixed_font (GNOME_LESS (less), TRUE); - { - int i; - char buf[82]; - GtkWidget *text = GTK_WIDGET (GNOME_LESS (less)->text); - GdkFont *font = GNOME_LESS (less)->font; - for (i = 0; i < 81; i++) - buf[i] = 'X'; - buf[i] = '\0'; - gtk_widget_set_size_request - (text, - gdk_string_width (font, buf) + 30, - gdk_string_height (font, buf)*24+30); - } - - command = g_strconcat ("finger ", - selected_browser_user, - NULL); - gnome_less_show_command (GNOME_LESS (less), command); - - gtk_widget_grab_focus (GTK_WIDGET (less)); - - gtk_window_set_modal (GTK_WINDOW (d), TRUE); - gdm_wm_center_window (GTK_WINDOW (d)); - - gdm_wm_no_login_focus_push (); - gtk_dialog_run (GTK_DIALOG (d)); - gtk_widget_destroy (d); - gdm_wm_no_login_focus_pop (); - } - break; -#endif - default: - break; - } - - return FALSE; -} - -static gboolean -key_press_event (GtkWidget *entry, GdkEventKey *event, gpointer data) -{ - if ((event->keyval == GDK_Tab || - event->keyval == GDK_KP_Tab) && - (event->state & (GDK_CONTROL_MASK|GDK_MOD1_MASK|GDK_SHIFT_MASK)) == 0) { - gdm_login_enter (entry); - return TRUE; - } - - return FALSE; -} - -static void -gdm_set_welcomemsg (void) -{ - gchar *greeting; - gchar *welcomemsg = gdm_common_get_welcomemsg (); - gchar *fullwelcomemsg = g_strdup_printf ( - "<big><big><big>%s</big></big></big>", welcomemsg); - - greeting = gdm_common_expand_text (fullwelcomemsg); - gtk_label_set_markup (GTK_LABEL (welcome), greeting); - - g_free (fullwelcomemsg); - g_free (welcomemsg); - g_free (greeting); -} - -static void -gdm_login_gui_init (void) -{ - GtkWidget *frame1, *frame2, *ebox; - GtkWidget *mbox, *menu, *menubar, *item; - GtkWidget *stack, *hline1, *hline2, *handle; - GtkWidget *bbox = NULL; - GtkWidget /**help_button,*/ *button_box; - gint rows; - GdkPixbuf *pb; - GtkWidget *frame; - int lw, lh; - gboolean have_logo = FALSE; - GtkWidget *thememenu; - const gchar *theme_name; - - theme_name = g_getenv ("GDM_GTK_THEME"); - if (ve_string_empty (theme_name)) - theme_name = gdm_config_get_string (GDM_KEY_GTK_THEME); - - if ( ! ve_string_empty (gdm_config_get_string (GDM_KEY_GTKRC))) - gtk_rc_parse (gdm_config_get_string (GDM_KEY_GTKRC)); - - if ( ! ve_string_empty (theme_name)) { - gdm_set_theme (theme_name); - } - - login = gtk_window_new (GTK_WINDOW_TOPLEVEL); - g_object_ref (login); - g_object_set_data_full (G_OBJECT (login), "login", login, - (GDestroyNotify) g_object_unref); - - gtk_widget_set_events (login, GDK_ALL_EVENTS_MASK); - - gtk_window_set_title (GTK_WINDOW (login), _("GDM Login")); - /* connect for fingering */ - if (browser_ok && gdm_config_get_bool (GDM_KEY_BROWSER)) - g_signal_connect (G_OBJECT (login), "event", - G_CALLBACK (window_browser_event), - NULL); - - frame1 = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_OUT); - gtk_container_set_border_width (GTK_CONTAINER (frame1), 0); - gtk_container_add (GTK_CONTAINER (login), frame1); - g_object_set_data_full (G_OBJECT (login), "frame1", frame1, - (GDestroyNotify) gtk_widget_unref); - gtk_widget_ref (GTK_WIDGET (frame1)); - gtk_widget_show (GTK_WIDGET (frame1)); - - frame2 = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN); - gtk_container_set_border_width (GTK_CONTAINER (frame2), 2); - gtk_container_add (GTK_CONTAINER (frame1), frame2); - g_object_set_data_full (G_OBJECT (login), "frame2", frame2, - (GDestroyNotify) gtk_widget_unref); - gtk_widget_ref (GTK_WIDGET (frame2)); - gtk_widget_show (GTK_WIDGET (frame2)); - - mbox = gtk_vbox_new (FALSE, 0); - gtk_widget_ref (mbox); - g_object_set_data_full (G_OBJECT (login), "mbox", mbox, - (GDestroyNotify) gtk_widget_unref); - gtk_widget_show (mbox); - gtk_container_add (GTK_CONTAINER (frame2), mbox); - - if (gdm_config_get_bool (GDM_KEY_TITLE_BAR)) { - handle = create_handle (); - gtk_box_pack_start (GTK_BOX (mbox), handle, FALSE, FALSE, 0); - } - - menubar = gtk_menu_bar_new (); - gtk_widget_ref (GTK_WIDGET (menubar)); - gtk_box_pack_start (GTK_BOX (mbox), menubar, FALSE, FALSE, 0); - - menu = gtk_menu_new (); - gdm_login_session_init (menu); - sessmenu = gtk_menu_item_new_with_mnemonic (_("_Session")); - gtk_menu_shell_append (GTK_MENU_SHELL (menubar), sessmenu); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (sessmenu), menu); - gtk_widget_show (GTK_WIDGET (sessmenu)); - - menu = gdm_login_language_menu_new (); - if (menu != NULL) { - langmenu = gtk_menu_item_new_with_mnemonic (_("_Language")); - gtk_menu_shell_append (GTK_MENU_SHELL (menubar), langmenu); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (langmenu), menu); - gtk_widget_show (GTK_WIDGET (langmenu)); - } - - if (disable_sys_config_chooser_buttons == FALSE && - gdm_config_get_bool (GDM_KEY_SYSTEM_MENU)) { - - gboolean got_anything = FALSE; - - menu = gtk_menu_new (); - - if (gdm_config_get_bool (GDM_KEY_CHOOSER_BUTTON)) { - item = gtk_menu_item_new_with_mnemonic (_("Remote Login via _XDMCP...")); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (gdm_login_use_chooser_handler), - NULL); - gtk_widget_show (item); - got_anything = TRUE; - } - - if (gdm_config_get_bool (GDM_KEY_CONFIG_AVAILABLE) && - bin_exists (gdm_config_get_string (GDM_KEY_CONFIGURATOR))) { - item = gtk_menu_item_new_with_mnemonic (_("_Configure Login Manager...")); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (gdm_run_gdmconfig), - NULL); - gtk_widget_show (item); - got_anything = TRUE; - } - - if (gdm_working_command_exists (gdm_config_get_string (GDM_KEY_REBOOT))) { - item = gtk_menu_item_new_with_mnemonic (_("_Restart")); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (gdm_login_restart_handler), - NULL); - gtk_widget_show (GTK_WIDGET (item)); - got_anything = TRUE; - } - - if (gdm_working_command_exists (gdm_config_get_string (GDM_KEY_HALT))) { - item = gtk_menu_item_new_with_mnemonic (_("Shut _Down")); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (gdm_login_halt_handler), - NULL); - gtk_widget_show (GTK_WIDGET (item)); - got_anything = TRUE; - } - - if (gdm_working_command_exists (gdm_config_get_string (GDM_KEY_SUSPEND))) { - item = gtk_menu_item_new_with_mnemonic (_("_Suspend")); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (gdm_login_suspend_handler), - NULL); - gtk_widget_show (GTK_WIDGET (item)); - got_anything = TRUE; - } - - if (got_anything) { - item = gtk_menu_item_new_with_mnemonic (_("_Actions")); - gtk_menu_shell_append (GTK_MENU_SHELL (menubar), item); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu); - gtk_widget_show (GTK_WIDGET (item)); - } - } - - menu = gdm_login_theme_menu_new (); - if (menu != NULL) { - thememenu = gtk_menu_item_new_with_mnemonic (_("_Theme")); - gtk_menu_shell_append (GTK_MENU_SHELL (menubar), thememenu); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (thememenu), menu); - gtk_widget_show (GTK_WIDGET (thememenu)); - } - - /* Add a quit/disconnect item when in xdmcp mode or flexi mode */ - /* Do note that the order is important, we always want "Quit" for - * flexi, even if not local (non-local xnest). and Disconnect - * only for xdmcp */ - if ( ! ve_string_empty (g_getenv ("GDM_FLEXI_SERVER"))) { - item = gtk_menu_item_new_with_mnemonic (_("_Quit")); - } else if (ve_string_empty (g_getenv ("GDM_IS_LOCAL"))) { - item = gtk_menu_item_new_with_mnemonic (_("D_isconnect")); - } else { - item = NULL; - } - if (item != NULL) { - gtk_menu_shell_append (GTK_MENU_SHELL (menubar), item); - gtk_widget_show (GTK_WIDGET (item)); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (gtk_main_quit), NULL); - } - - /* The clock */ - clock_label = gtk_label_new (""); - gtk_widget_show (clock_label); - item = gtk_menu_item_new (); - gtk_container_add (GTK_CONTAINER (item), clock_label); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menubar), item); - gtk_menu_item_set_right_justified (GTK_MENU_ITEM (item), TRUE); - GTK_WIDGET_UNSET_FLAGS (item, GTK_SENSITIVE); - - g_signal_connect (G_OBJECT (clock_label), "destroy", - G_CALLBACK (gtk_widget_destroyed), - &clock_label); - - update_clock (); - - if (browser_ok && gdm_config_get_bool (GDM_KEY_BROWSER)) - rows = 2; - else - rows = 1; - - table = gtk_table_new (rows, 2, FALSE); - gtk_widget_ref (table); - g_object_set_data_full (G_OBJECT (login), "table", table, - (GDestroyNotify) gtk_widget_unref); - gtk_widget_show (table); - gtk_box_pack_start (GTK_BOX (mbox), table, TRUE, TRUE, 0); - gtk_container_set_border_width (GTK_CONTAINER (table), 10); - gtk_table_set_row_spacings (GTK_TABLE (table), 10); - gtk_table_set_col_spacings (GTK_TABLE (table), 10); - - if (browser_ok && gdm_config_get_bool (GDM_KEY_BROWSER)) { - int height; - GtkTreeSelection *selection; - GtkTreeViewColumn *column; - - browser = gtk_tree_view_new (); - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (browser), FALSE); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (browser), - FALSE); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (browser)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - - g_signal_connect (selection, "changed", - G_CALLBACK (user_selected), - NULL); - - g_signal_connect (browser, "button_release_event", - G_CALLBACK (browser_change_focus), - NULL); - - browser_model = (GtkTreeModel *)gtk_list_store_new (3, - GDK_TYPE_PIXBUF, - G_TYPE_STRING, - G_TYPE_STRING); - gtk_tree_view_set_model (GTK_TREE_VIEW (browser), browser_model); - column = gtk_tree_view_column_new_with_attributes - (_("Icon"), - gtk_cell_renderer_pixbuf_new (), - "pixbuf", GREETER_ULIST_ICON_COLUMN, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (browser), column); - - column = gtk_tree_view_column_new_with_attributes - (_("Username"), - gtk_cell_renderer_text_new (), - "markup", GREETER_ULIST_LABEL_COLUMN, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (browser), column); - - bbox = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (bbox), - GTK_SHADOW_IN); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (bbox), - GTK_POLICY_NEVER, - GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER (bbox), browser); - - height = size_of_users + 4 /* some padding */; - if (height > gdm_wm_screen.height * 0.25) - height = gdm_wm_screen.height * 0.25; - - gtk_widget_set_size_request (GTK_WIDGET (bbox), -1, height); - } - - if (gdm_config_get_string (GDM_KEY_LOGO) != NULL) { - pb = gdk_pixbuf_new_from_file (gdm_config_get_string (GDM_KEY_LOGO), NULL); - } else { - pb = NULL; - } - - if (pb != NULL) { - have_logo = TRUE; - logo_image = gtk_image_new_from_pixbuf (pb); - lw = gdk_pixbuf_get_width (pb); - lh = gdk_pixbuf_get_height (pb); - g_object_unref (G_OBJECT (pb)); - } else { - logo_image = gtk_image_new (); - lw = lh = 100; - } - - /* this will make the logo always left justified */ - logo_frame = gtk_alignment_new (0, 0.10, 0, 0); - gtk_widget_show (logo_frame); - - frame = gtk_frame_new (NULL); - gtk_widget_show (frame); - gtk_frame_set_shadow_type (GTK_FRAME (frame), - GTK_SHADOW_IN); - - ebox = gtk_event_box_new (); - gtk_widget_show (ebox); - gtk_container_add (GTK_CONTAINER (ebox), logo_image); - gtk_container_add (GTK_CONTAINER (frame), ebox); - gtk_container_add (GTK_CONTAINER (logo_frame), frame); - - if (lw > gdm_wm_screen.width / 2) - lw = gdm_wm_screen.width / 2; - else - lw = -1; - if (lh > (2 * gdm_wm_screen.height) / 3) - lh = (2 * gdm_wm_screen.height) / 3; - else - lh = -1; - if (lw > -1 || lh > -1) - gtk_widget_set_size_request (logo_image, lw, lh); - gtk_widget_show (GTK_WIDGET (logo_image)); - - stack = gtk_table_new (7, 1, FALSE); - gtk_widget_ref (stack); - g_object_set_data_full (G_OBJECT (login), "stack", stack, - (GDestroyNotify) gtk_widget_unref); - gtk_widget_show (stack); - - /* Welcome msg */ - welcome = gtk_label_new (NULL); - gdm_set_welcomemsg (); - gtk_widget_set_name (welcome, _("Welcome")); - gtk_widget_ref (welcome); - g_object_set_data_full (G_OBJECT (login), "welcome", welcome, - (GDestroyNotify) gtk_widget_unref); - gtk_widget_show (welcome); - gtk_table_attach (GTK_TABLE (stack), welcome, 0, 1, 0, 1, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 15); - - /* Put in error box here */ - err_box = gtk_label_new (NULL); - gtk_widget_set_name (err_box, "Error box"); - gtk_widget_set_size_request (err_box, -1, 40); - g_signal_connect (G_OBJECT (err_box), "destroy", - G_CALLBACK (gtk_widget_destroyed), - &err_box); - gtk_label_set_line_wrap (GTK_LABEL (err_box), TRUE); - gtk_table_attach (GTK_TABLE (stack), err_box, 0, 1, 1, 2, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - - - hline1 = gtk_hseparator_new (); - gtk_widget_ref (hline1); - g_object_set_data_full (G_OBJECT (login), "hline1", hline1, - (GDestroyNotify) gtk_widget_unref); - gtk_widget_show (hline1); - gtk_table_attach (GTK_TABLE (stack), hline1, 0, 1, 2, 3, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 6); - - label = gtk_label_new_with_mnemonic (_("_Username:")); - gtk_widget_ref (label); - g_object_set_data_full (G_OBJECT (login), "label", label, - (GDestroyNotify) gtk_widget_unref); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (stack), label, 0, 1, 3, 4, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - gtk_misc_set_padding (GTK_MISC (label), 10, 5); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - - entry = gtk_entry_new (); - g_signal_connect (G_OBJECT (entry), "key_press_event", - G_CALLBACK (key_press_event), NULL); - if (gdm_config_get_bool (GDM_KEY_ENTRY_INVISIBLE)) - gtk_entry_set_invisible_char (GTK_ENTRY (entry), 0); - else if (gdm_config_get_bool (GDM_KEY_ENTRY_CIRCLES)) - gtk_entry_set_invisible_char (GTK_ENTRY (entry), 0x25cf); - gtk_entry_set_max_length (GTK_ENTRY (entry), PW_ENTRY_SIZE); - gtk_widget_set_size_request (entry, 250, -1); - gtk_widget_ref (entry); - g_object_set_data_full (G_OBJECT (login), "entry", entry, - (GDestroyNotify) gtk_widget_unref); - gtk_entry_set_text (GTK_ENTRY (entry), ""); - gtk_widget_show (entry); - gtk_table_attach (GTK_TABLE (stack), entry, 0, 1, 4, 5, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 10, 0); - g_signal_connect (G_OBJECT(entry), "activate", - G_CALLBACK (gdm_login_enter), - NULL); - - /* cursor blinking is evil on remote displays, don't do it forever */ - gdm_common_setup_blinking (); - gdm_common_setup_blinking_entry (entry); - - hline2 = gtk_hseparator_new (); - gtk_widget_ref (hline2); - g_object_set_data_full (G_OBJECT (login), "hline2", hline2, - (GDestroyNotify) gtk_widget_unref); - gtk_widget_show (hline2); - gtk_table_attach (GTK_TABLE (stack), hline2, 0, 1, 5, 6, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 10); - - msg = gtk_label_new (_("Please enter your username")); - gtk_widget_set_name (msg, "Message"); - gtk_label_set_line_wrap (GTK_LABEL (msg), TRUE); - gtk_label_set_justify (GTK_LABEL (msg), GTK_JUSTIFY_LEFT); - gtk_table_attach (GTK_TABLE (stack), msg, 0, 1, 6, 7, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 10); - gtk_widget_set_size_request (msg, -1, 30); - - gtk_widget_ref (msg); - g_object_set_data_full (G_OBJECT (login), "msg", msg, - (GDestroyNotify) gtk_widget_unref); - gtk_widget_show (msg); - - auto_timed_msg = gtk_label_new (""); - gtk_widget_set_name (auto_timed_msg, "Message"); - gtk_label_set_line_wrap (GTK_LABEL (auto_timed_msg), TRUE); - gtk_label_set_justify (GTK_LABEL (auto_timed_msg), GTK_JUSTIFY_LEFT); - gtk_table_attach (GTK_TABLE (stack), auto_timed_msg, 0, 1, 7, 8, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 10); - gtk_widget_set_size_request (auto_timed_msg, -1, 15); - - gtk_widget_ref (auto_timed_msg); - gtk_widget_show (auto_timed_msg); - - /* FIXME: No Documentation yet.... */ - /*help_button = gtk_button_new_from_stock (GTK_STOCK_OK); - GTK_WIDGET_UNSET_FLAGS (help_button, GTK_CAN_FOCUS); - gtk_widget_show (help_button);*/ - - ok_button = gtk_button_new_from_stock (GTK_STOCK_OK); - GTK_WIDGET_UNSET_FLAGS (ok_button, GTK_CAN_FOCUS); - g_signal_connect (G_OBJECT (ok_button), "clicked", - G_CALLBACK (gdm_login_ok_button_press), - entry); - gtk_widget_show (ok_button); - - cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL); - GTK_WIDGET_UNSET_FLAGS (cancel_button, GTK_CAN_FOCUS); - g_signal_connect (G_OBJECT (cancel_button), "clicked", - G_CALLBACK (gdm_login_cancel_button_press), - entry); - gtk_widget_show (cancel_button); - - button_box = gtk_hbutton_box_new (); - gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box), - GTK_BUTTONBOX_END); - gtk_box_set_spacing (GTK_BOX (button_box), 10); - -#if 0 - gtk_box_pack_end (GTK_BOX (button_box), GTK_WIDGET (help_button), - FALSE, TRUE, 0); - gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (button_box), help_button, TRUE); -#endif - - gtk_box_pack_end (GTK_BOX (button_box), GTK_WIDGET (cancel_button), - FALSE, TRUE, 0); - gtk_box_pack_end (GTK_BOX (button_box), GTK_WIDGET (ok_button), - FALSE, TRUE, 0); - gtk_widget_show (button_box); - - gtk_table_attach (GTK_TABLE (stack), button_box, 0, 1, 8, 9, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 10, 10); - - /* Put it nicely together */ - - if (bbox != NULL) { - gtk_table_attach (GTK_TABLE (table), bbox, 0, 2, 0, 1, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); - gtk_table_attach (GTK_TABLE (table), logo_frame, 0, 1, 1, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - gtk_table_attach (GTK_TABLE (table), stack, 1, 2, 1, 2, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - } else { - gtk_table_attach (GTK_TABLE (table), logo_frame, 0, 1, 0, 1, - (GtkAttachOptions) (0), - (GtkAttachOptions) (GTK_FILL), 0, 0); - gtk_table_attach (GTK_TABLE (table), stack, 1, 2, 0, 1, - (GtkAttachOptions) (0), - (GtkAttachOptions) (GTK_FILL), 0, 0); - } - - gtk_widget_grab_focus (entry); - gtk_window_set_focus (GTK_WINDOW (login), entry); - g_object_set (G_OBJECT (login), - "allow_grow", TRUE, - "allow_shrink", TRUE, - "resizable", TRUE, - NULL); - - /* do it now, and we'll also do it later */ - if (GdmSetPosition) { - set_screen_pos (login, GdmPositionX, GdmPositionY); - } else { - gdm_wm_center_window (GTK_WINDOW (login)); - } - - g_signal_connect (G_OBJECT (login), "focus_in_event", - G_CALLBACK (gdm_login_focus_in), - NULL); - g_signal_connect (G_OBJECT (login), "focus_out_event", - G_CALLBACK (gdm_login_focus_out), - NULL); - - gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); - - /* normally disable the prompt first */ - if ( ! DOING_GDM_DEVELOPMENT) { - gtk_widget_set_sensitive (entry, FALSE); - gtk_widget_set_sensitive (ok_button, FALSE); - gtk_widget_set_sensitive (cancel_button, FALSE); - } - - gtk_widget_show_all (GTK_WIDGET (login)); - if ( ! have_logo) { - gtk_table_set_col_spacings (GTK_TABLE (table), 0); - gtk_widget_hide (logo_frame); - } -} - -static void -set_root (GdkPixbuf *pb) -{ - GdkPixmap *pm; - gint width, height; - - g_return_if_fail (pb != NULL); - - gdk_drawable_get_size (gdk_get_default_root_window (), &width, &height); - pm = gdk_pixmap_new (gdk_get_default_root_window (), - width, height, -1); - - - /* paranoia */ - if (pm == NULL) - return; - - gdk_draw_pixbuf (pm, NULL, pb, 0, 0, 0, 0, -1, -1, - GDK_RGB_DITHER_MAX, 0, 0); - - gdk_error_trap_push (); - - gdk_window_set_back_pixmap (gdk_get_default_root_window (), - pm, - FALSE /* parent_relative */); - - g_object_unref (G_OBJECT (pm)); - - gdk_window_clear (gdk_get_default_root_window ()); - - gdk_flush (); - gdk_error_trap_pop (); -} - -static GdkPixbuf * -render_scaled_back (const GdkPixbuf *pb) -{ - int i; - int width, height; - - GdkPixbuf *back = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - gdk_pixbuf_get_has_alpha (pb), - 8, - gdk_screen_width (), - gdk_screen_height ()); - - width = gdk_pixbuf_get_width (pb); - height = gdk_pixbuf_get_height (pb); - - for (i = 0; i < gdm_wm_screens; i++) { - gdk_pixbuf_scale (pb, back, - gdm_wm_allscreens[i].x, - gdm_wm_allscreens[i].y, - gdm_wm_allscreens[i].width, - gdm_wm_allscreens[i].height, - gdm_wm_allscreens[i].x /* offset_x */, - gdm_wm_allscreens[i].y /* offset_y */, - (double) gdm_wm_allscreens[i].width / width, - (double) gdm_wm_allscreens[i].height / height, - GDK_INTERP_BILINEAR); - } - - return back; -} - -static void -add_color_to_pb (GdkPixbuf *pb, GdkColor *color) -{ - int width = gdk_pixbuf_get_width (pb); - int height = gdk_pixbuf_get_height (pb); - int rowstride = gdk_pixbuf_get_rowstride (pb); - guchar *pixels = gdk_pixbuf_get_pixels (pb); - gboolean has_alpha = gdk_pixbuf_get_has_alpha (pb); - int i; - int cr = color->red >> 8; - int cg = color->green >> 8; - int cb = color->blue >> 8; - - if ( ! has_alpha) - return; - - for (i = 0; i < height; i++) { - int ii; - guchar *p = pixels + (rowstride * i); - for (ii = 0; ii < width; ii++) { - int r = p[0]; - int g = p[1]; - int b = p[2]; - int a = p[3]; - - p[0] = (r * a + cr * (255 - a)) >> 8; - p[1] = (g * a + cg * (255 - a)) >> 8; - p[2] = (b * a + cb * (255 - a)) >> 8; - p[3] = 255; - - p += 4; - } - } -} - -/* setup background color/image */ -static void -setup_background (void) -{ - GdkColor color; - GdkPixbuf *pb = NULL; - gchar *bg_color = gdm_config_get_string (GDM_KEY_BACKGROUND_COLOR); - gchar *bg_image = gdm_config_get_string (GDM_KEY_BACKGROUND_IMAGE); - gint bg_type = gdm_config_get_int (GDM_KEY_BACKGROUND_TYPE); - - if ((bg_type == GDM_BACKGROUND_IMAGE || - bg_type == GDM_BACKGROUND_IMAGE_AND_COLOR) && - ! ve_string_empty (bg_image)) - pb = gdk_pixbuf_new_from_file (bg_image, NULL); - - /* Load background image */ - if (pb != NULL) { - if (gdk_pixbuf_get_has_alpha (pb)) { - if (bg_type == GDM_BACKGROUND_IMAGE_AND_COLOR) { - if (bg_color == NULL || - bg_color[0] == '\0' || - ! gdk_color_parse (bg_color, - &color)) { - gdk_color_parse ("#000000", &color); - } - add_color_to_pb (pb, &color); - } - } - if (gdm_config_get_bool (GDM_KEY_BACKGROUND_SCALE_TO_FIT)) { - GdkPixbuf *spb = render_scaled_back (pb); - g_object_unref (G_OBJECT (pb)); - pb = spb; - } - - /* paranoia */ - if (pb != NULL) { - set_root (pb); - g_object_unref (G_OBJECT (pb)); - } - /* Load background color */ - } else if (bg_type != GDM_BACKGROUND_NONE && - bg_type != GDM_BACKGROUND_IMAGE) { - gdm_common_setup_background_color (bg_color); - /* Load default background */ - } else { - gchar *blank_color = g_strdup ("#000000"); - gdm_common_setup_background_color (blank_color); - } -} - -enum { - RESPONSE_RESTART, - RESPONSE_REBOOT, - RESPONSE_CLOSE -}; - -/* - * If new configuration keys are added to this program, make sure to add the - * key to the gdm_read_config and gdm_reread_config functions. Note if the - * number of configuration values used by gdmlogin is greater than - * GDM_SUP_MAX_MESSAGES defined in daemon/gdm.h (currently defined to be 80), - * consider bumping that number so that all the config can be read in one - * socket connection. - */ -static void -gdm_read_config (void) -{ - /* Read config data in bulk */ - gdmcomm_comm_bulk_start (); - - gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG)); - - /* - * Read all the keys at once and close sockets connection so we do - * not have to keep the socket open. - */ - gdm_config_get_string (GDM_KEY_BACKGROUND_COLOR); - gdm_config_get_string (GDM_KEY_BACKGROUND_IMAGE); - gdm_config_get_string (GDM_KEY_BACKGROUND_PROGRAM); - gdm_config_get_string (GDM_KEY_CONFIGURATOR); - gdm_config_get_string (GDM_KEY_DEFAULT_FACE); - gdm_config_get_string (GDM_KEY_DEFAULT_SESSION); - gdm_config_get_string (GDM_KEY_EXCLUDE); - gdm_config_get_string (GDM_KEY_GTK_THEME); - gdm_config_get_string (GDM_KEY_GTK_THEMES_TO_ALLOW); - gdm_config_get_string (GDM_KEY_GTKRC); - gdm_config_get_string (GDM_KEY_HALT); - gdm_config_get_string (GDM_KEY_INCLUDE); - gdm_config_get_string (GDM_KEY_INFO_MSG_FILE); - gdm_config_get_string (GDM_KEY_INFO_MSG_FONT); - gdm_config_get_string (GDM_KEY_LOCALE_FILE); - gdm_config_get_string (GDM_KEY_LOGO); - gdm_config_get_string (GDM_KEY_REBOOT); - gdm_config_get_string (GDM_KEY_REMOTE_WELCOME); - gdm_config_get_string (GDM_KEY_SESSION_DESKTOP_DIR); - gdm_config_get_string (GDM_KEY_SOUND_PROGRAM); - gdm_config_get_string (GDM_KEY_SOUND_ON_LOGIN_FILE); - gdm_config_get_string (GDM_KEY_SUSPEND); - gdm_config_get_string (GDM_KEY_TIMED_LOGIN); - gdm_config_get_string (GDM_KEY_USE_24_CLOCK); - gdm_config_get_string (GDM_KEY_WELCOME); - - gdm_config_get_int (GDM_KEY_BACKGROUND_TYPE); - gdm_config_get_int (GDM_KEY_BACKGROUND_PROGRAM_INITIAL_DELAY); - gdm_config_get_int (GDM_KEY_BACKGROUND_PROGRAM_RESTART_DELAY); - gdm_config_get_int (GDM_KEY_FLEXI_REAP_DELAY_MINUTES); - gdm_config_get_int (GDM_KEY_MAX_ICON_HEIGHT); - gdm_config_get_int (GDM_KEY_MAX_ICON_WIDTH); - gdm_config_get_int (GDM_KEY_MINIMAL_UID); - gdm_config_get_int (GDM_KEY_TIMED_LOGIN_DELAY); - gdm_config_get_int (GDM_KEY_XINERAMA_SCREEN); - - gdm_config_get_bool (GDM_KEY_ALLOW_GTK_THEME_CHANGE); - gdm_config_get_bool (GDM_KEY_ALLOW_REMOTE_ROOT); - gdm_config_get_bool (GDM_KEY_ALLOW_ROOT); - gdm_config_get_bool (GDM_KEY_BACKGROUND_REMOTE_ONLY_COLOR); - gdm_config_get_bool (GDM_KEY_BACKGROUND_SCALE_TO_FIT); - gdm_config_get_bool (GDM_KEY_BROWSER); - gdm_config_get_bool (GDM_KEY_CHOOSER_BUTTON); - gdm_config_get_bool (GDM_KEY_CONFIG_AVAILABLE); - gdm_config_get_bool (GDM_KEY_DEFAULT_REMOTE_WELCOME); - gdm_config_get_bool (GDM_KEY_DEFAULT_WELCOME); - gdm_config_get_bool (GDM_KEY_ENTRY_CIRCLES); - gdm_config_get_bool (GDM_KEY_ENTRY_INVISIBLE); - gdm_config_get_bool (GDM_KEY_INCLUDE_ALL); - gdm_config_get_bool (GDM_KEY_QUIVER); - gdm_config_get_bool (GDM_KEY_RUN_BACKGROUND_PROGRAM_ALWAYS); - gdm_config_get_bool (GDM_KEY_RESTART_BACKGROUND_PROGRAM); - gdm_config_get_bool (GDM_KEY_SHOW_GNOME_FAILSAFE); - gdm_config_get_bool (GDM_KEY_SHOW_LAST_SESSION); - gdm_config_get_bool (GDM_KEY_SHOW_XTERM_FAILSAFE); - gdm_config_get_bool (GDM_KEY_SOUND_ON_LOGIN); - gdm_config_get_bool (GDM_KEY_SYSTEM_MENU); - gdm_config_get_bool (GDM_KEY_TIMED_LOGIN_ENABLE); - gdm_config_get_bool (GDM_KEY_TITLE_BAR); - - /* Keys not to include in reread_config */ - gdm_config_get_bool (GDM_KEY_LOCK_POSITION); - gdm_config_get_int (GDM_KEY_POSITION_X); - gdm_config_get_int (GDM_KEY_POSITION_Y); - gdm_config_get_string (GDM_KEY_PRE_FETCH_PROGRAM); - gdm_config_get_bool (GDM_KEY_SET_POSITION); - - gdmcomm_comm_bulk_stop (); -} - -static gboolean -gdm_reread_config (int sig, gpointer data) -{ - gboolean resize = FALSE; - - /* Read config data in bulk */ - gdmcomm_comm_bulk_start (); - - if (gdm_config_reload_bool (GDM_KEY_DEBUG)) - gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG)); - - /* reparse config stuff here. At least the ones we care about */ - /* - * We don't want to reload GDM_KEY_POSITION_X, GDM_KEY_POSITION_Y - * GDM_KEY_LOCK_POSITION, and GDM_KEY_SET_POSITION since we don't - * want to move the window or lock its position just because the - * config default changed. It would be too confusing to have the - * window location move around. These changes can wait until the - * next time gdmlogin is launched. - */ - - /* FIXME: We should update these on the fly rather than just - * restarting */ - /* Also we may not need to check ALL those keys but just a few */ - - if (gdm_config_reload_string (GDM_KEY_BACKGROUND_PROGRAM) || - gdm_config_reload_string (GDM_KEY_CONFIGURATOR) || - gdm_config_reload_string (GDM_KEY_DEFAULT_FACE) || - gdm_config_reload_string (GDM_KEY_DEFAULT_SESSION) || - gdm_config_reload_string (GDM_KEY_EXCLUDE) || - gdm_config_reload_string (GDM_KEY_GTKRC) || - gdm_config_reload_string (GDM_KEY_GTK_THEME) || - gdm_config_reload_string (GDM_KEY_GTK_THEMES_TO_ALLOW) || - gdm_config_reload_string (GDM_KEY_HALT) || - gdm_config_reload_string (GDM_KEY_INCLUDE) || - gdm_config_reload_string (GDM_KEY_INFO_MSG_FILE) || - gdm_config_reload_string (GDM_KEY_INFO_MSG_FONT) || - gdm_config_reload_string (GDM_KEY_LOCALE_FILE) || - gdm_config_reload_string (GDM_KEY_REBOOT) || - gdm_config_reload_string (GDM_KEY_SESSION_DESKTOP_DIR) || - gdm_config_reload_string (GDM_KEY_SUSPEND) || - gdm_config_reload_string (GDM_KEY_TIMED_LOGIN) || - - gdm_config_reload_int (GDM_KEY_BACKGROUND_PROGRAM_INITIAL_DELAY) || - gdm_config_reload_int (GDM_KEY_BACKGROUND_PROGRAM_RESTART_DELAY) || - gdm_config_reload_int (GDM_KEY_MAX_ICON_WIDTH) || - gdm_config_reload_int (GDM_KEY_MAX_ICON_HEIGHT) || - gdm_config_reload_int (GDM_KEY_MINIMAL_UID) || - gdm_config_reload_int (GDM_KEY_TIMED_LOGIN_DELAY) || - gdm_config_reload_int (GDM_KEY_XINERAMA_SCREEN) || - - gdm_config_reload_bool (GDM_KEY_ALLOW_GTK_THEME_CHANGE) || - gdm_config_reload_bool (GDM_KEY_ALLOW_ROOT) || - gdm_config_reload_bool (GDM_KEY_ALLOW_REMOTE_ROOT) || - gdm_config_reload_bool (GDM_KEY_BROWSER) || - gdm_config_reload_bool (GDM_KEY_CHOOSER_BUTTON) || - gdm_config_reload_bool (GDM_KEY_CONFIG_AVAILABLE) || - gdm_config_reload_bool (GDM_KEY_ENTRY_CIRCLES) || - gdm_config_reload_bool (GDM_KEY_ENTRY_INVISIBLE) || - gdm_config_reload_bool (GDM_KEY_INCLUDE_ALL) || - gdm_config_reload_bool (GDM_KEY_QUIVER) || - gdm_config_reload_bool (GDM_KEY_RESTART_BACKGROUND_PROGRAM) || - gdm_config_reload_bool (GDM_KEY_RUN_BACKGROUND_PROGRAM_ALWAYS) || - gdm_config_reload_bool (GDM_KEY_SHOW_GNOME_FAILSAFE) || - gdm_config_reload_bool (GDM_KEY_SHOW_LAST_SESSION) || - gdm_config_reload_bool (GDM_KEY_SHOW_XTERM_FAILSAFE) || - gdm_config_reload_bool (GDM_KEY_SYSTEM_MENU) || - gdm_config_reload_bool (GDM_KEY_TIMED_LOGIN_ENABLE) || - gdm_config_reload_bool (GDM_KEY_TITLE_BAR)) { - - /* Set busy cursor */ - gdm_common_setup_cursor (GDK_WATCH); - - gdm_wm_save_wm_order (); - gdm_kill_thingies (); - gdmcomm_comm_bulk_stop (); - - _exit (DISPLAY_RESTARTGREETER); - return TRUE; - } - - if (gdm_config_reload_string (GDM_KEY_BACKGROUND_IMAGE) || - gdm_config_reload_string (GDM_KEY_BACKGROUND_COLOR) || - gdm_config_reload_int (GDM_KEY_BACKGROUND_TYPE) || - gdm_config_reload_bool (GDM_KEY_BACKGROUND_SCALE_TO_FIT) || - gdm_config_reload_bool (GDM_KEY_BACKGROUND_REMOTE_ONLY_COLOR)) { - - gdm_kill_thingies (); - setup_background (); - back_prog_launch_after_timeout (); - } - - gdm_config_reload_string (GDM_KEY_SOUND_PROGRAM); - gdm_config_reload_bool (GDM_KEY_SOUND_ON_LOGIN); - gdm_config_reload_string (GDM_KEY_SOUND_ON_LOGIN_FILE); - gdm_config_reload_string (GDM_KEY_USE_24_CLOCK); - update_clock (); - - if (gdm_config_reload_string (GDM_KEY_LOGO)) { - GdkPixbuf *pb; - gboolean have_logo = FALSE; - gchar *gdmlogo; - int lw, lh; - - gdmlogo = gdm_config_get_string (GDM_KEY_LOGO); - - if (gdmlogo != NULL) { - pb = gdk_pixbuf_new_from_file (gdmlogo, NULL); - } else { - pb = NULL; - } - - if (pb != NULL) { - have_logo = TRUE; - gtk_image_set_from_pixbuf (GTK_IMAGE (logo_image), pb); - lw = gdk_pixbuf_get_width (pb); - lh = gdk_pixbuf_get_height (pb); - g_object_unref (G_OBJECT (pb)); - } else { - lw = lh = 100; - } - - if (lw > gdm_wm_screen.width / 2) - lw = gdm_wm_screen.width / 2; - else - lw = -1; - if (lh > (2 * gdm_wm_screen.height) / 3) - lh = (2 * gdm_wm_screen.height) / 3; - else - lh = -1; - if (lw > -1 || lh > -1) - gtk_widget_set_size_request (logo_image, lw, lh); - - if (have_logo) { - gtk_table_set_col_spacings (GTK_TABLE (table), 10); - gtk_widget_show (logo_frame); - } else { - gtk_table_set_col_spacings (GTK_TABLE (table), 0); - gtk_widget_hide (logo_frame); - } - - resize = TRUE; - } - - if (gdm_config_reload_string (GDM_KEY_WELCOME) || - gdm_config_reload_bool (GDM_KEY_DEFAULT_WELCOME) || - gdm_config_reload_string (GDM_KEY_REMOTE_WELCOME) || - gdm_config_reload_bool (GDM_KEY_DEFAULT_REMOTE_WELCOME)) { - - gdm_set_welcomemsg (); - } - - if (resize) - login_window_resize (TRUE /* force */); - - gdmcomm_comm_bulk_stop (); - - return TRUE; -} - -int -main (int argc, char *argv[]) -{ - struct sigaction hup; - struct sigaction term; - sigset_t mask; - GIOChannel *ctrlch; - const char *gdm_version; - const char *gdm_protocol_version; - guint sid; - - if (g_getenv ("DOING_GDM_DEVELOPMENT") != NULL) - DOING_GDM_DEVELOPMENT = TRUE; - - gdm_common_openlog ("gdmlogin", LOG_PID, LOG_DAEMON); - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); - - gtk_init (&argc, &argv); - - if (ve_string_empty (g_getenv ("GDM_IS_LOCAL"))) - disable_sys_config_chooser_buttons = TRUE; - - /* Read all configuration at once, so the values get cached */ - gdm_read_config (); - - GdmLockPosition = gdm_config_get_bool (GDM_KEY_LOCK_POSITION); - GdmSetPosition = gdm_config_get_bool (GDM_KEY_SET_POSITION); - GdmPositionX = gdm_config_get_int (GDM_KEY_POSITION_X); - GdmPositionY = gdm_config_get_int (GDM_KEY_POSITION_Y); - setlocale (LC_ALL, ""); - - gdm_wm_screen_init (gdm_config_get_int (GDM_KEY_XINERAMA_SCREEN)); - - gdm_version = g_getenv ("GDM_VERSION"); - gdm_protocol_version = g_getenv ("GDM_GREETER_PROTOCOL_VERSION"); - - /* Load the background as early as possible so GDM does not leave */ - /* the background unfilled. The cursor should be a watch already */ - /* but just in case */ - setup_background (); - gdm_common_setup_cursor (GDK_WATCH); - - if ( ! DOING_GDM_DEVELOPMENT && - ((gdm_protocol_version != NULL && - strcmp (gdm_protocol_version, GDM_GREETER_PROTOCOL_VERSION) != 0) || - (gdm_protocol_version == NULL && - (gdm_version == NULL || - strcmp (gdm_version, VERSION) != 0))) && - ve_string_empty (g_getenv ("GDM_IS_LOCAL"))) { - GtkWidget *dialog; - gchar *msg; - - gdm_wm_init (0); - - gdm_wm_focus_new_windows (TRUE); - - msg = g_strdup_printf (_("The greeter version (%s) does not match the daemon " - "version. " - "You have probably just upgraded GDM. " - "Please restart the GDM daemon or the computer."), - VERSION); - - dialog = ve_hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Cannot start the greeter"), - msg); - g_free (msg); - - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_common_setup_cursor (GDK_LEFT_PTR); - - gtk_dialog_run (GTK_DIALOG (dialog)); - - return EXIT_SUCCESS; - } - - if ( ! DOING_GDM_DEVELOPMENT && - gdm_protocol_version == NULL && - gdm_version == NULL) { - GtkWidget *dialog; - gchar *msg; - - gdm_wm_init (0); - - gdm_wm_focus_new_windows (TRUE); - - msg = g_strdup_printf (_("The greeter version (%s) does not match the daemon " - "version. " - "You have probably just upgraded GDM. " - "Please restart the GDM daemon or the computer."), - VERSION); - - dialog = ve_hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_NONE, - _("Cannot start the greeter"), - msg); - g_free (msg); - - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - _("Restart"), - RESPONSE_REBOOT, - GTK_STOCK_CLOSE, - RESPONSE_CLOSE, - NULL); - - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_common_setup_cursor (GDK_LEFT_PTR); - - switch (gtk_dialog_run (GTK_DIALOG (dialog))) { - case RESPONSE_REBOOT: - gtk_widget_destroy (dialog); - return DISPLAY_REBOOT; - default: - gtk_widget_destroy (dialog); - return DISPLAY_ABORT; - } - } - - if ( ! DOING_GDM_DEVELOPMENT && - ((gdm_protocol_version != NULL && - strcmp (gdm_protocol_version, GDM_GREETER_PROTOCOL_VERSION) != 0) || - (gdm_protocol_version == NULL && - strcmp (gdm_version, VERSION) != 0))) { - GtkWidget *dialog; - gchar *msg; - - gdm_wm_init (0); - - gdm_wm_focus_new_windows (TRUE); - - msg = g_strdup_printf (_("The greeter version (%s) does not match the daemon " - "version (%s). " - "You have probably just upgraded GDM. " - "Please restart the GDM daemon or the computer."), - VERSION, gdm_version); - - dialog = ve_hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_NONE, - _("Cannot start the greeter"), - msg); - g_free (msg); - - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - _("Restart GDM"), - RESPONSE_RESTART, - _("Restart computer"), - RESPONSE_REBOOT, - GTK_STOCK_CLOSE, - RESPONSE_CLOSE, - NULL); - - - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gtk_dialog_set_default_response (GTK_DIALOG (dialog), RESPONSE_RESTART); - - gdm_common_setup_cursor (GDK_LEFT_PTR); - - switch (gtk_dialog_run (GTK_DIALOG (dialog))) { - case RESPONSE_RESTART: - gtk_widget_destroy (dialog); - return DISPLAY_RESTARTGDM; - case RESPONSE_REBOOT: - gtk_widget_destroy (dialog); - return DISPLAY_REBOOT; - default: - gtk_widget_destroy (dialog); - return DISPLAY_ABORT; - } - } - - if (browser_ok && gdm_config_get_bool (GDM_KEY_BROWSER)) { - defface = gdm_common_get_face (NULL, - gdm_config_get_string (GDM_KEY_DEFAULT_FACE), - gdm_config_get_int (GDM_KEY_MAX_ICON_WIDTH), - gdm_config_get_int (GDM_KEY_MAX_ICON_HEIGHT)); - - if (! defface) { - gdm_common_warning ("Could not open DefaultImage: %s. Suspending face browser!", - gdm_config_get_string (GDM_KEY_DEFAULT_FACE)); - browser_ok = FALSE; - } else { - gdm_users_init (&users, &users_string, NULL, defface, - &size_of_users, login_is_local, !DOING_GDM_DEVELOPMENT); - } - } - - gdm_login_gui_init (); - - if (browser_ok && gdm_config_get_bool (GDM_KEY_BROWSER)) - gdm_login_browser_populate (); - - ve_signal_add (SIGHUP, gdm_reread_config, NULL); - - hup.sa_handler = ve_signal_notify; - hup.sa_flags = 0; - sigemptyset (&hup.sa_mask); - sigaddset (&hup.sa_mask, SIGCHLD); - - if G_UNLIKELY (sigaction (SIGHUP, &hup, NULL) < 0) { - gdm_kill_thingies (); - gdm_common_fail_greeter (_("%s: Error setting up %s signal handler: %s"), "main", - "HUP", strerror (errno)); - } - - term.sa_handler = gdm_login_done; - term.sa_flags = 0; - sigemptyset (&term.sa_mask); - sigaddset (&term.sa_mask, SIGCHLD); - - if G_UNLIKELY (sigaction (SIGINT, &term, NULL) < 0) { - gdm_kill_thingies (); - gdm_common_fail_greeter (_("%s: Error setting up %s signal handler: %s"), "main", - "INT", strerror (errno)); - } - - if G_UNLIKELY (sigaction (SIGTERM, &term, NULL) < 0) { - gdm_kill_thingies (); - gdm_common_fail_greeter (_("%s: Error setting up %s signal handler: %s"), "main", - "TERM", strerror (errno)); - } - - sigemptyset (&mask); - sigaddset (&mask, SIGTERM); - sigaddset (&mask, SIGHUP); - sigaddset (&mask, SIGINT); - - if G_UNLIKELY (sigprocmask (SIG_UNBLOCK, &mask, NULL) == -1) { - gdm_kill_thingies (); - gdm_common_fail_greeter (_("Could not set signal mask!")); - } - - g_atexit (gdm_kill_thingies); - back_prog_launch_after_timeout (); - - if G_LIKELY ( ! DOING_GDM_DEVELOPMENT) { - ctrlch = g_io_channel_unix_new (STDIN_FILENO); - g_io_channel_set_encoding (ctrlch, NULL, NULL); - g_io_channel_set_buffered (ctrlch, FALSE); - g_io_add_watch (ctrlch, - G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL, - (GIOFunc) gdm_login_ctrl_handler, - NULL); - g_io_channel_unref (ctrlch); - } - - /* if in timed mode, delay timeout on keyboard or menu - * activity */ - if (gdm_config_get_bool (GDM_KEY_TIMED_LOGIN_ENABLE) && - ! ve_string_empty (gdm_config_get_string (GDM_KEY_TIMED_LOGIN))) { - sid = g_signal_lookup ("activate", - GTK_TYPE_MENU_ITEM); - g_signal_add_emission_hook (sid, - 0 /* detail */, - gdm_timer_up_delay, - NULL /* data */, - NULL /* destroy_notify */); - - sid = g_signal_lookup ("key_press_event", - GTK_TYPE_WIDGET); - g_signal_add_emission_hook (sid, - 0 /* detail */, - gdm_timer_up_delay, - NULL /* data */, - NULL /* destroy_notify */); - - sid = g_signal_lookup ("button_press_event", - GTK_TYPE_WIDGET); - g_signal_add_emission_hook (sid, - 0 /* detail */, - gdm_timer_up_delay, - NULL /* data */, - NULL /* destroy_notify */); - } - - /* if a flexiserver, reap self after some time */ - if (gdm_config_get_int (GDM_KEY_FLEXI_REAP_DELAY_MINUTES) > 0 && - ! ve_string_empty (g_getenv ("GDM_FLEXI_SERVER")) && - /* but don't reap Xnest flexis */ - ve_string_empty (g_getenv ("GDM_PARENT_DISPLAY"))) { - sid = g_signal_lookup ("activate", - GTK_TYPE_MENU_ITEM); - g_signal_add_emission_hook (sid, - 0 /* detail */, - delay_reaping, - NULL /* data */, - NULL /* destroy_notify */); - - sid = g_signal_lookup ("key_press_event", - GTK_TYPE_WIDGET); - g_signal_add_emission_hook (sid, - 0 /* detail */, - delay_reaping, - NULL /* data */, - NULL /* destroy_notify */); - - sid = g_signal_lookup ("button_press_event", - GTK_TYPE_WIDGET); - g_signal_add_emission_hook (sid, - 0 /* detail */, - delay_reaping, - NULL /* data */, - NULL /* destroy_notify */); - - last_reap_delay = time (NULL); - g_timeout_add (60*1000, reap_flexiserver, NULL); - } - - sid = g_signal_lookup ("event", - GTK_TYPE_WIDGET); - g_signal_add_emission_hook (sid, - 0 /* detail */, - gdm_event, - NULL /* data */, - NULL /* destroy_notify */); - - gtk_widget_queue_resize (login); - gtk_widget_show_now (login); - - if (GdmSetPosition) { - set_screen_pos (login, GdmPositionX, GdmPositionY); - } else { - gdm_wm_center_window (GTK_WINDOW (login)); - } - - /* can it ever happen that it'd be NULL here ??? */ - if G_UNLIKELY (login->window != NULL) { - gdm_wm_init (GDK_WINDOW_XWINDOW (login->window)); - - /* Run the focus, note that this will work no matter what - * since gdm_wm_init will set the display to the gdk one - * if it fails */ - gdm_wm_focus_window (GDK_WINDOW_XWINDOW (login->window)); - } - - if G_UNLIKELY (session_dir_whacked_out) { - GtkWidget *dialog; - - gdm_wm_focus_new_windows (TRUE); - - dialog = ve_hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Session directory is missing"), - _("Your session directory is missing or empty! " - "There are two available sessions you can use, but " - "you should log in and correct the GDM configuration.")); - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_common_setup_cursor (GDK_LEFT_PTR); - - gdm_wm_no_login_focus_push (); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - gdm_wm_no_login_focus_pop (); - } - - if G_UNLIKELY (g_getenv ("GDM_WHACKED_GREETER_CONFIG") != NULL) { - GtkWidget *dialog; - - gdm_wm_focus_new_windows (TRUE); - - dialog = ve_hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Configuration is not correct"), - _("The configuration file contains an invalid command " - "line for the login dialog, so running the " - "default command. Please fix your configuration.")); - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_common_setup_cursor (GDK_LEFT_PTR); - - gdm_wm_no_login_focus_push (); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - gdm_wm_no_login_focus_pop (); - } - - gdm_wm_restore_wm_order (); - - gdm_wm_show_info_msg_dialog (gdm_config_get_string (GDM_KEY_INFO_MSG_FILE), - gdm_config_get_string (GDM_KEY_INFO_MSG_FONT)); - - /* Only setup the cursor now since it will be a WATCH from before */ - gdm_common_setup_cursor (GDK_LEFT_PTR); - - gdm_common_pre_fetch_launch (); - gtk_main (); - - gdm_kill_thingies (); - - return EXIT_SUCCESS; -} - -/* EOF */ |