1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- |
---|
2 | * |
---|
3 | * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu> |
---|
4 | * Copyright (C) 2008 Red Hat, Inc. |
---|
5 | * |
---|
6 | * This program is free software; you can redistribute it and/or modify |
---|
7 | * it under the terms of the GNU General Public License as published by |
---|
8 | * the Free Software Foundation; either version 2 of the License, or |
---|
9 | * (at your option) any later version. |
---|
10 | * |
---|
11 | * This program is distributed in the hope that it will be useful, |
---|
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | * GNU General Public License for more details. |
---|
15 | * |
---|
16 | * You should have received a copy of the GNU General Public License |
---|
17 | * along with this program; if not, write to the Free Software |
---|
18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
---|
19 | * |
---|
20 | */ |
---|
21 | |
---|
22 | #include "config.h" |
---|
23 | |
---|
24 | #include <stdlib.h> |
---|
25 | #include <stdio.h> |
---|
26 | #include <fcntl.h> |
---|
27 | #include <unistd.h> |
---|
28 | #include <string.h> |
---|
29 | #include <signal.h> |
---|
30 | #include <sys/stat.h> |
---|
31 | #include <sys/types.h> |
---|
32 | #include <sys/socket.h> |
---|
33 | #include <sys/time.h> |
---|
34 | #include <errno.h> |
---|
35 | #include <pwd.h> |
---|
36 | |
---|
37 | #ifdef ENABLE_RBAC_SHUTDOWN |
---|
38 | #include <auth_attr.h> |
---|
39 | #include <secdb.h> |
---|
40 | #endif |
---|
41 | |
---|
42 | #include <glib.h> |
---|
43 | #include <glib/gi18n.h> |
---|
44 | #include <glib/gstdio.h> |
---|
45 | #include <glib-object.h> |
---|
46 | |
---|
47 | #include <gdk/gdkkeysyms.h> |
---|
48 | #include <gdk/gdkx.h> |
---|
49 | #include <X11/XKBlib.h> |
---|
50 | |
---|
51 | #include <gst/gst.h> |
---|
52 | #include <gtk/gtk.h> |
---|
53 | #include <gst/interfaces/xoverlay.h> |
---|
54 | |
---|
55 | #include <glade/glade-xml.h> |
---|
56 | #include <gconf/gconf-client.h> |
---|
57 | |
---|
58 | #include <dbus/dbus-glib.h> |
---|
59 | #include <dbus/dbus-glib-lowlevel.h> |
---|
60 | |
---|
61 | #ifdef HAVE_DEVICEKIT_POWER |
---|
62 | #include <devkit-power-gobject/devicekit-power.h> |
---|
63 | #endif |
---|
64 | |
---|
65 | #include "gdm-settings-client.h" |
---|
66 | #include "gdm-settings-keys.h" |
---|
67 | #include "gdm-profile.h" |
---|
68 | |
---|
69 | #include "gdm-greeter-login-window.h" |
---|
70 | #include "gdm-user-chooser-widget.h" |
---|
71 | |
---|
72 | #ifdef HAVE_PAM |
---|
73 | #include <security/pam_appl.h> |
---|
74 | #define PW_ENTRY_SIZE PAM_MAX_RESP_SIZE |
---|
75 | #else |
---|
76 | #define PW_ENTRY_SIZE GDM_MAX_PASS |
---|
77 | #endif |
---|
78 | |
---|
79 | #define CK_NAME "org.freedesktop.ConsoleKit" |
---|
80 | #define CK_PATH "/org/freedesktop/ConsoleKit" |
---|
81 | #define CK_INTERFACE "org.freedesktop.ConsoleKit" |
---|
82 | |
---|
83 | #define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" |
---|
84 | #define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" |
---|
85 | #define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat" |
---|
86 | #define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" |
---|
87 | |
---|
88 | #define GLADE_XML_FILE "gdm-greeter-login-window.glade" |
---|
89 | |
---|
90 | #define KEY_GREETER_DIR "/apps/gdm/simple-greeter" |
---|
91 | #define KEY_BANNER_MESSAGE_ENABLED KEY_GREETER_DIR "/banner_message_enable" |
---|
92 | #define KEY_BANNER_MESSAGE_TEXT KEY_GREETER_DIR "/banner_message_text" |
---|
93 | #define KEY_BANNER_MESSAGE_TEXT_NOCHOOSER KEY_GREETER_DIR "/banner_message_text_nochooser" |
---|
94 | #define KEY_LOGO KEY_GREETER_DIR "/logo_icon_name" |
---|
95 | #define KEY_DISABLE_RESTART_BUTTONS KEY_GREETER_DIR "/disable_restart_buttons" |
---|
96 | #define GDM_GREETER_LOGIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_LOGIN_WINDOW, GdmGreeterLoginWindowPrivate)) |
---|
97 | |
---|
98 | enum { |
---|
99 | MODE_SELECTION = 0, |
---|
100 | MODE_AUTHENTICATION |
---|
101 | }; |
---|
102 | |
---|
103 | enum { |
---|
104 | LOGIN_BUTTON_HIDDEN = 0, |
---|
105 | LOGIN_BUTTON_START_OTHER, |
---|
106 | LOGIN_BUTTON_ANSWER_QUERY, |
---|
107 | LOGIN_BUTTON_TIMED_LOGIN |
---|
108 | }; |
---|
109 | |
---|
110 | struct GdmGreeterLoginWindowPrivate |
---|
111 | { |
---|
112 | GladeXML *xml; |
---|
113 | GtkWidget *user_chooser; |
---|
114 | GtkWidget *auth_banner_label; |
---|
115 | guint display_is_local : 1; |
---|
116 | guint is_interactive : 1; |
---|
117 | guint user_chooser_loaded : 1; |
---|
118 | GConfClient *client; |
---|
119 | |
---|
120 | gboolean banner_message_enabled; |
---|
121 | guint gconf_cnxn; |
---|
122 | |
---|
123 | guint dialog_mode; |
---|
124 | |
---|
125 | gboolean timed_login_enabled; |
---|
126 | guint timed_login_delay; |
---|
127 | char *timed_login_username; |
---|
128 | guint timed_login_timeout_id; |
---|
129 | |
---|
130 | guint sensitize_power_buttons_timeout_id; |
---|
131 | |
---|
132 | guint login_button_handler_id; |
---|
133 | guint start_session_handler_id; |
---|
134 | }; |
---|
135 | |
---|
136 | enum { |
---|
137 | PROP_0, |
---|
138 | PROP_DISPLAY_IS_LOCAL, |
---|
139 | PROP_IS_INTERACTIVE, |
---|
140 | }; |
---|
141 | |
---|
142 | enum { |
---|
143 | BEGIN_AUTO_LOGIN, |
---|
144 | BEGIN_VERIFICATION, |
---|
145 | BEGIN_VERIFICATION_FOR_USER, |
---|
146 | QUERY_ANSWER, |
---|
147 | START_SESSION, |
---|
148 | USER_SELECTED, |
---|
149 | DISCONNECTED, |
---|
150 | CANCELLED, |
---|
151 | LAST_SIGNAL |
---|
152 | }; |
---|
153 | |
---|
154 | static guint signals [LAST_SIGNAL] = { 0, }; |
---|
155 | static GstElement * pipeline; |
---|
156 | |
---|
157 | static void gdm_greeter_login_window_class_init (GdmGreeterLoginWindowClass *klass); |
---|
158 | static void gdm_greeter_login_window_init (GdmGreeterLoginWindow *greeter_login_window); |
---|
159 | static void gdm_greeter_login_window_finalize (GObject *object); |
---|
160 | |
---|
161 | static void restart_timed_login_timeout (GdmGreeterLoginWindow *login_window); |
---|
162 | static void on_user_unchosen (GdmUserChooserWidget *user_chooser, |
---|
163 | GdmGreeterLoginWindow *login_window); |
---|
164 | |
---|
165 | static void switch_mode (GdmGreeterLoginWindow *login_window, |
---|
166 | int number); |
---|
167 | static void update_banner_message (GdmGreeterLoginWindow *login_window); |
---|
168 | |
---|
169 | G_DEFINE_TYPE (GdmGreeterLoginWindow, gdm_greeter_login_window, GTK_TYPE_WINDOW) |
---|
170 | |
---|
171 | static void |
---|
172 | set_busy (GdmGreeterLoginWindow *login_window) |
---|
173 | { |
---|
174 | GdkCursor *cursor; |
---|
175 | |
---|
176 | cursor = gdk_cursor_new (GDK_WATCH); |
---|
177 | gdk_window_set_cursor (GTK_WIDGET (login_window)->window, cursor); |
---|
178 | gdk_cursor_unref (cursor); |
---|
179 | } |
---|
180 | |
---|
181 | static void |
---|
182 | set_ready (GdmGreeterLoginWindow *login_window) |
---|
183 | { |
---|
184 | gdk_window_set_cursor (GTK_WIDGET (login_window)->window, NULL); |
---|
185 | } |
---|
186 | |
---|
187 | static void |
---|
188 | set_sensitive (GdmGreeterLoginWindow *login_window, |
---|
189 | gboolean sensitive) |
---|
190 | { |
---|
191 | GtkWidget *box; |
---|
192 | |
---|
193 | box = glade_xml_get_widget (login_window->priv->xml, "auth-input-box"); |
---|
194 | gtk_widget_set_sensitive (box, sensitive); |
---|
195 | |
---|
196 | box = glade_xml_get_widget (login_window->priv->xml, "buttonbox"); |
---|
197 | gtk_widget_set_sensitive (box, sensitive); |
---|
198 | |
---|
199 | gtk_widget_set_sensitive (login_window->priv->user_chooser, sensitive); |
---|
200 | } |
---|
201 | |
---|
202 | static void |
---|
203 | set_focus (GdmGreeterLoginWindow *login_window) |
---|
204 | { |
---|
205 | GtkWidget *entry; |
---|
206 | |
---|
207 | entry = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-entry"); |
---|
208 | |
---|
209 | gdk_window_focus (GTK_WIDGET (login_window)->window, GDK_CURRENT_TIME); |
---|
210 | |
---|
211 | if (GTK_WIDGET_REALIZED (entry) && ! GTK_WIDGET_HAS_FOCUS (entry)) { |
---|
212 | gtk_widget_grab_focus (entry); |
---|
213 | } else if (GTK_WIDGET_REALIZED (login_window->priv->user_chooser) && ! GTK_WIDGET_HAS_FOCUS (login_window->priv->user_chooser)) { |
---|
214 | gtk_widget_grab_focus (login_window->priv->user_chooser); |
---|
215 | } |
---|
216 | } |
---|
217 | |
---|
218 | static void |
---|
219 | set_message (GdmGreeterLoginWindow *login_window, |
---|
220 | const char *text) |
---|
221 | { |
---|
222 | GtkWidget *label; |
---|
223 | |
---|
224 | label = glade_xml_get_widget (login_window->priv->xml, "auth-message-label"); |
---|
225 | gtk_label_set_text (GTK_LABEL (label), text); |
---|
226 | } |
---|
227 | |
---|
228 | static void |
---|
229 | on_user_interaction (GdmGreeterLoginWindow *login_window) |
---|
230 | { |
---|
231 | g_debug ("GdmGreeterLoginWindow: user is interacting with session!\n"); |
---|
232 | restart_timed_login_timeout (login_window); |
---|
233 | } |
---|
234 | |
---|
235 | static GdkFilterReturn |
---|
236 | on_xevent (XEvent *xevent, |
---|
237 | GdkEvent *event, |
---|
238 | GdmGreeterLoginWindow *login_window) |
---|
239 | { |
---|
240 | switch (xevent->xany.type) { |
---|
241 | case KeyPress: |
---|
242 | case KeyRelease: |
---|
243 | case ButtonPress: |
---|
244 | case ButtonRelease: |
---|
245 | on_user_interaction (login_window); |
---|
246 | break; |
---|
247 | case PropertyNotify: |
---|
248 | if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name ("_NET_WM_USER_TIME")) { |
---|
249 | on_user_interaction (login_window); |
---|
250 | } |
---|
251 | break; |
---|
252 | |
---|
253 | default: |
---|
254 | break; |
---|
255 | } |
---|
256 | |
---|
257 | return GDK_FILTER_CONTINUE; |
---|
258 | } |
---|
259 | |
---|
260 | static void |
---|
261 | stop_watching_for_user_interaction (GdmGreeterLoginWindow *login_window) |
---|
262 | { |
---|
263 | gdk_window_remove_filter (NULL, |
---|
264 | (GdkFilterFunc) on_xevent, |
---|
265 | login_window); |
---|
266 | } |
---|
267 | |
---|
268 | static void |
---|
269 | remove_timed_login_timeout (GdmGreeterLoginWindow *login_window) |
---|
270 | { |
---|
271 | if (login_window->priv->timed_login_timeout_id > 0) { |
---|
272 | g_debug ("GdmGreeterLoginWindow: removing timed login timer"); |
---|
273 | g_source_remove (login_window->priv->timed_login_timeout_id); |
---|
274 | login_window->priv->timed_login_timeout_id = 0; |
---|
275 | } |
---|
276 | |
---|
277 | stop_watching_for_user_interaction (login_window); |
---|
278 | } |
---|
279 | |
---|
280 | static void |
---|
281 | _gdm_greeter_login_window_set_interactive (GdmGreeterLoginWindow *login_window, |
---|
282 | gboolean is_interactive) |
---|
283 | { |
---|
284 | if (login_window->priv->is_interactive != is_interactive) { |
---|
285 | login_window->priv->is_interactive = is_interactive; |
---|
286 | g_object_notify (G_OBJECT (login_window), "is-interactive"); |
---|
287 | } |
---|
288 | } |
---|
289 | |
---|
290 | static gboolean |
---|
291 | timed_login_timer (GdmGreeterLoginWindow *login_window) |
---|
292 | { |
---|
293 | set_sensitive (login_window, FALSE); |
---|
294 | set_message (login_window, _("Automatically logging in...")); |
---|
295 | |
---|
296 | g_debug ("GdmGreeterLoginWindow: timer expired"); |
---|
297 | _gdm_greeter_login_window_set_interactive (login_window, TRUE); |
---|
298 | login_window->priv->timed_login_timeout_id = 0; |
---|
299 | |
---|
300 | return FALSE; |
---|
301 | } |
---|
302 | |
---|
303 | static void |
---|
304 | watch_for_user_interaction (GdmGreeterLoginWindow *login_window) |
---|
305 | { |
---|
306 | gdk_window_add_filter (NULL, |
---|
307 | (GdkFilterFunc) on_xevent, |
---|
308 | login_window); |
---|
309 | } |
---|
310 | |
---|
311 | static void |
---|
312 | restart_timed_login_timeout (GdmGreeterLoginWindow *login_window) |
---|
313 | { |
---|
314 | remove_timed_login_timeout (login_window); |
---|
315 | |
---|
316 | if (login_window->priv->timed_login_enabled) { |
---|
317 | g_debug ("GdmGreeterLoginWindow: adding timed login timer"); |
---|
318 | watch_for_user_interaction (login_window); |
---|
319 | login_window->priv->timed_login_timeout_id = g_timeout_add_seconds (login_window->priv->timed_login_delay, |
---|
320 | (GSourceFunc)timed_login_timer, |
---|
321 | login_window); |
---|
322 | |
---|
323 | gdm_chooser_widget_set_item_timer (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser), |
---|
324 | GDM_USER_CHOOSER_USER_AUTO, |
---|
325 | login_window->priv->timed_login_delay * 1000); |
---|
326 | } |
---|
327 | } |
---|
328 | |
---|
329 | static void |
---|
330 | show_widget (GdmGreeterLoginWindow *login_window, |
---|
331 | const char *name, |
---|
332 | gboolean visible) |
---|
333 | { |
---|
334 | GtkWidget *widget; |
---|
335 | |
---|
336 | widget = glade_xml_get_widget (login_window->priv->xml, name); |
---|
337 | if (widget != NULL) { |
---|
338 | if (visible) { |
---|
339 | gtk_widget_show (widget); |
---|
340 | } else { |
---|
341 | gtk_widget_hide (widget); |
---|
342 | } |
---|
343 | } |
---|
344 | } |
---|
345 | |
---|
346 | static void |
---|
347 | sensitize_widget (GdmGreeterLoginWindow *login_window, |
---|
348 | const char *name, |
---|
349 | gboolean sense) |
---|
350 | { |
---|
351 | GtkWidget *widget; |
---|
352 | |
---|
353 | widget = glade_xml_get_widget (login_window->priv->xml, name); |
---|
354 | if (widget != NULL) { |
---|
355 | gtk_widget_set_sensitive (widget, sense); |
---|
356 | } |
---|
357 | } |
---|
358 | |
---|
359 | static gboolean |
---|
360 | get_show_restart_buttons (GdmGreeterLoginWindow *login_window) |
---|
361 | { |
---|
362 | gboolean show; |
---|
363 | GError *error; |
---|
364 | |
---|
365 | error = NULL; |
---|
366 | show = ! gconf_client_get_bool (login_window->priv->client, KEY_DISABLE_RESTART_BUTTONS, &error); |
---|
367 | if (error != NULL) { |
---|
368 | g_debug ("GdmGreeterLoginWindow: unable to get disable-restart-buttons configuration: %s", error->message); |
---|
369 | g_error_free (error); |
---|
370 | } |
---|
371 | |
---|
372 | #ifdef ENABLE_RBAC_SHUTDOWN |
---|
373 | { |
---|
374 | char *username; |
---|
375 | |
---|
376 | username = g_get_user_name (); |
---|
377 | if (username == NULL || !chkauthattr (RBAC_SHUTDOWN_KEY, username)) { |
---|
378 | show = FALSE; |
---|
379 | g_debug ("GdmGreeterLoginWindow: Not showing stop/restart buttons for user %s due to RBAC key %s", |
---|
380 | username, RBAC_SHUTDOWN_KEY); |
---|
381 | } else { |
---|
382 | g_debug ("GdmGreeterLoginWindow: Showing stop/restart buttons for user %s due to RBAC key %s", |
---|
383 | username, RBAC_SHUTDOWN_KEY); |
---|
384 | } |
---|
385 | } |
---|
386 | #endif |
---|
387 | return show; |
---|
388 | } |
---|
389 | |
---|
390 | static void |
---|
391 | on_login_button_clicked_answer_query (GtkButton *button, |
---|
392 | GdmGreeterLoginWindow *login_window) |
---|
393 | { |
---|
394 | GtkWidget *entry; |
---|
395 | const char *text; |
---|
396 | |
---|
397 | set_busy (login_window); |
---|
398 | set_sensitive (login_window, FALSE); |
---|
399 | |
---|
400 | entry = glade_xml_get_widget (login_window->priv->xml, "auth-prompt-entry"); |
---|
401 | text = gtk_entry_get_text (GTK_ENTRY (entry)); |
---|
402 | |
---|
403 | _gdm_greeter_login_window_set_interactive (login_window, TRUE); |
---|
404 | g_signal_emit (login_window, signals[QUERY_ANSWER], 0, text); |
---|
405 | } |
---|
406 | |
---|
407 | static void |
---|
408 | on_login_button_clicked_timed_login (GtkButton *button, |
---|
409 | GdmGreeterLoginWindow *login_window) |
---|
410 | { |
---|
411 | set_busy (login_window); |
---|
412 | set_sensitive (login_window, FALSE); |
---|
413 | |
---|
414 | _gdm_greeter_login_window_set_interactive (login_window, TRUE); |
---|
415 | } |
---|
416 | static void |
---|
417 | on_login_button_clicked_start_other (GtkButton *button, |
---|
418 | GdmGreeterLoginWindow *login_window) |
---|
419 | { |
---|
420 | g_debug ("GdmGreeterLoginWindow: starting OTHER login"); |
---|
421 | |
---|
422 | g_signal_emit (G_OBJECT (login_window), signals[USER_SELECTED], |
---|
423 | 0, GDM_USER_CHOOSER_USER_OTHER); |
---|
424 | g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0); |
---|
425 | switch_mode (login_window, MODE_AUTHENTICATION); |
---|
426 | } |
---|
427 | |
---|
428 | static void |
---|
429 | set_log_in_button_mode (GdmGreeterLoginWindow *login_window, |
---|
430 | int mode) |
---|
431 | { |
---|
432 | GtkWidget *button; |
---|
433 | |
---|
434 | button = glade_xml_get_widget (login_window->priv->xml, "log-in-button"); |
---|
435 | gtk_widget_grab_default (button); |
---|
436 | |
---|
437 | /* disconnect any signals */ |
---|
438 | if (login_window->priv->login_button_handler_id > 0) { |
---|
439 | g_signal_handler_disconnect (button, login_window->priv->login_button_handler_id); |
---|
440 | login_window->priv->login_button_handler_id = 0; |
---|
441 | } |
---|
442 | |
---|
443 | switch (mode) { |
---|
444 | case LOGIN_BUTTON_HIDDEN: |
---|
445 | gtk_widget_hide (button); |
---|
446 | break; |
---|
447 | case LOGIN_BUTTON_START_OTHER: |
---|
448 | login_window->priv->login_button_handler_id = g_signal_connect (button, "clicked", G_CALLBACK (on_login_button_clicked_start_other), login_window); |
---|
449 | gtk_widget_show (button); |
---|
450 | break; |
---|
451 | case LOGIN_BUTTON_ANSWER_QUERY: |
---|
452 | login_window->priv->login_button_handler_id = g_signal_connect (button, "clicked", G_CALLBACK (on_login_button_clicked_answer_query), login_window); |
---|
453 | gtk_widget_show (button); |
---|
454 | break; |
---|
455 | case LOGIN_BUTTON_TIMED_LOGIN: |
---|
456 | login_window->priv->login_button_handler_id = g_signal_connect (button, "clicked", G_CALLBACK (on_login_button_clicked_timed_login), login_window); |
---|
457 | gtk_widget_show (button); |
---|
458 | break; |
---|
459 | default: |
---|
460 | g_assert_not_reached (); |
---|
461 | break; |
---|
462 | } |
---|
463 | } |
---|
464 | |
---|
465 | static void |
---|
466 | adjust_other_login_visibility(GdmGreeterLoginWindow *login_window) |
---|
467 | { |
---|
468 | if (! login_window->priv->user_chooser_loaded) { |
---|
469 | return; |
---|
470 | } |
---|
471 | |
---|
472 | if (login_window->priv->dialog_mode != MODE_SELECTION) { |
---|
473 | return; |
---|
474 | } |
---|
475 | |
---|
476 | if (gdm_chooser_widget_get_number_of_items (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser)) == 0) { |
---|
477 | set_log_in_button_mode (login_window, LOGIN_BUTTON_START_OTHER); |
---|
478 | } else { |
---|
479 | set_log_in_button_mode (login_window, LOGIN_BUTTON_HIDDEN); |
---|
480 | } |
---|
481 | } |
---|
482 | |
---|
483 | #ifdef HAVE_DEVICEKIT_POWER |
---|
484 | static gboolean |
---|
485 | can_suspend (GdmGreeterLoginWindow *login_window) |
---|
486 | { |
---|
487 | gboolean ret; |
---|
488 | DkpClient *dkp_client; |
---|
489 | |
---|
490 | /* use DeviceKit-power to get data */ |
---|
491 | dkp_client = dkp_client_new (); |
---|
492 | g_object_get (dkp_client, |
---|
493 | "can-suspend", &ret, |
---|
494 | NULL); |
---|
495 | g_object_unref (dkp_client); |
---|
496 | return ret; |
---|
497 | } |
---|
498 | #endif |
---|
499 | |
---|
500 | static void |
---|
501 | remove_sensitize_power_buttons_timeout (GdmGreeterLoginWindow *login_window) |
---|
502 | { |
---|
503 | if (login_window->priv->sensitize_power_buttons_timeout_id > 0) { |
---|
504 | g_source_remove (login_window->priv->sensitize_power_buttons_timeout_id); |
---|
505 | login_window->priv->sensitize_power_buttons_timeout_id = 0; |
---|
506 | } |
---|
507 | } |
---|
508 | |
---|
509 | static gboolean |
---|
510 | sensitize_power_buttons_timeout (GdmGreeterLoginWindow *login_window) |
---|
511 | { |
---|
512 | switch (login_window->priv->dialog_mode) { |
---|
513 | case MODE_SELECTION: |
---|
514 | sensitize_widget (login_window, "shutdown-button", TRUE); |
---|
515 | sensitize_widget (login_window, "restart-button", TRUE); |
---|
516 | sensitize_widget (login_window, "suspend-button", TRUE); |
---|
517 | sensitize_widget (login_window, "disconnect-button", TRUE); |
---|
518 | break; |
---|
519 | case MODE_AUTHENTICATION: |
---|
520 | break; |
---|
521 | default: |
---|
522 | g_assert_not_reached (); |
---|
523 | } |
---|
524 | |
---|
525 | login_window->priv->sensitize_power_buttons_timeout_id = 0; |
---|
526 | return FALSE; |
---|
527 | } |
---|
528 | |
---|
529 | static void |
---|
530 | add_sensitize_power_buttons_timeout (GdmGreeterLoginWindow *login_window) |
---|
531 | { |
---|
532 | remove_sensitize_power_buttons_timeout (login_window); |
---|
533 | login_window->priv->sensitize_power_buttons_timeout_id = g_timeout_add_seconds (1, |
---|
534 | (GSourceFunc)sensitize_power_buttons_timeout, |
---|
535 | login_window); |
---|
536 | } |
---|
537 | |
---|
538 | static void |
---|
539 | switch_mode (GdmGreeterLoginWindow *login_window, |
---|
540 | int number) |
---|
541 | { |
---|
542 | const char *default_name; |
---|
543 | GtkWidget *user_chooser; |
---|
544 | GtkWidget *box; |
---|
545 | gboolean show_restart_buttons; |
---|
546 | gboolean show_suspend_button; |
---|
547 | |
---|
548 | show_restart_buttons = get_show_restart_buttons (login_window); |
---|
549 | |
---|
550 | #ifdef HAVE_DEVICEKIT_POWER |
---|
551 | show_suspend_button = can_suspend (login_window); |
---|
552 | #else |
---|
553 | show_suspend_button = FALSE; |
---|
554 | #endif |
---|
555 | |
---|
556 | /* we want to run this even if we're supposed to |
---|
557 | be in the mode already so that we reset everything |
---|
558 | to a known state */ |
---|
559 | login_window->priv->dialog_mode = number; |
---|
560 | |
---|
561 | default_name = NULL; |
---|
562 | |
---|
563 | remove_sensitize_power_buttons_timeout (login_window); |
---|
564 | |
---|
565 | switch (number) { |
---|
566 | case MODE_SELECTION: |
---|
567 | set_log_in_button_mode (login_window, LOGIN_BUTTON_HIDDEN); |
---|
568 | |
---|
569 | show_widget (login_window, "cancel-button", FALSE); |
---|
570 | |
---|
571 | show_widget (login_window, "shutdown-button", |
---|
572 | login_window->priv->display_is_local && show_restart_buttons); |
---|
573 | show_widget (login_window, "restart-button", |
---|
574 | login_window->priv->display_is_local && show_restart_buttons); |
---|
575 | show_widget (login_window, "suspend-button", |
---|
576 | login_window->priv->display_is_local && show_restart_buttons && show_suspend_button); |
---|
577 | show_widget (login_window, "disconnect-button", |
---|
578 | ! login_window->priv->display_is_local); |
---|
579 | |
---|
580 | show_widget (login_window, "auth-input-box", FALSE); |
---|
581 | |
---|
582 | add_sensitize_power_buttons_timeout (login_window); |
---|
583 | sensitize_widget (login_window, "shutdown-button", FALSE); |
---|
584 | sensitize_widget (login_window, "restart-button", FALSE); |
---|
585 | sensitize_widget (login_window, "suspend-button", FALSE); |
---|
586 | sensitize_widget (login_window, "disconnect-button", FALSE); |
---|
587 | |
---|
588 | default_name = NULL; |
---|
589 | break; |
---|
590 | case MODE_AUTHENTICATION: |
---|
591 | show_widget (login_window, "cancel-button", TRUE); |
---|
592 | show_widget (login_window, "shutdown-button", FALSE); |
---|
593 | show_widget (login_window, "restart-button", FALSE); |
---|
594 | show_widget (login_window, "suspend-button", FALSE); |
---|
595 | show_widget (login_window, "disconnect-button", FALSE); |
---|
596 | default_name = "log-in-button"; |
---|
597 | break; |
---|
598 | default: |
---|
599 | g_assert_not_reached (); |
---|
600 | } |
---|
601 | |
---|
602 | box = glade_xml_get_widget (login_window->priv->xml, "buttonbox"); |
---|
603 | gtk_button_box_set_layout (GTK_BUTTON_BOX (box), |
---|
604 | (number == MODE_SELECTION) ? GTK_BUTTONBOX_SPREAD : GTK_BUTTONBOX_END ); |
---|
605 | |
---|
606 | user_chooser = glade_xml_get_widget (login_window->priv->xml, "user-chooser"); |
---|
607 | box = gtk_widget_get_parent (user_chooser); |
---|
608 | if (GTK_IS_BOX (box)) { |
---|
609 | guint padding; |
---|
610 | GtkPackType pack_type; |
---|
611 | |
---|
612 | gtk_box_query_child_packing (GTK_BOX (box), |
---|
613 | user_chooser, |
---|
614 | NULL, |
---|
615 | NULL, |
---|
616 | &padding, |
---|
617 | &pack_type); |
---|
618 | gtk_box_set_child_packing (GTK_BOX (box), |
---|
619 | user_chooser, |
---|
620 | number == MODE_SELECTION, |
---|
621 | number == MODE_SELECTION, |
---|
622 | padding, |
---|
623 | pack_type); |
---|
624 | } |
---|
625 | |
---|
626 | if (default_name != NULL) { |
---|
627 | GtkWidget *widget; |
---|
628 | |
---|
629 | widget = glade_xml_get_widget (login_window->priv->xml, default_name); |
---|
630 | gtk_widget_grab_default (widget); |
---|
631 | } |
---|
632 | } |
---|
633 | |
---|
634 | static void |
---|
635 | do_disconnect (GdmGreeterLoginWindow *login_window) |
---|
636 | { |
---|
637 | gtk_main_quit (); |
---|
638 | } |
---|
639 | |
---|
640 | #ifdef HAVE_DEVICEKIT_POWER |
---|
641 | static void |
---|
642 | do_suspend (GdmGreeterLoginWindow *login_window) |
---|
643 | { |
---|
644 | gboolean ret; |
---|
645 | DkpClient *dkp_client; |
---|
646 | GError *error = NULL; |
---|
647 | |
---|
648 | /* use DeviceKit-power to get data */ |
---|
649 | dkp_client = dkp_client_new (); |
---|
650 | ret = dkp_client_suspend (dkp_client, &error); |
---|
651 | if (!ret) { |
---|
652 | g_warning ("Couldn't suspend: %s", error->message); |
---|
653 | g_error_free (error); |
---|
654 | return; |
---|
655 | } |
---|
656 | g_object_unref (dkp_client); |
---|
657 | } |
---|
658 | #endif |
---|
659 | |
---|
660 | static void |
---|
661 | delete_entry_text (GtkWidget *entry) |
---|
662 | { |
---|
663 | const char *typed_text; |
---|
664 | char *null_text; |
---|
665 | |
---|
666 | /* try to scrub out any secret info */ |
---|
667 | typed_text = gtk_entry_get_text (GTK_ENTRY (entry)); |
---|
668 | null_text = g_strnfill (strlen (typed_text) + 1, '\b'); |
---|
669 | gtk_entry_set_text (GTK_ENTRY (entry), null_text); |
---|
670 | gtk_entry_set_text (GTK_ENTRY (entry), ""); |
---|
671 | } |
---|
672 | |
---|
673 | static void |
---|
674 | reset_dialog (GdmGreeterLoginWindow *login_window) |
---|
675 | { |
---|
676 | GtkWidget *entry; |
---|
677 | GtkWidget *label; |
---|
678 | |
---|
679 | g_debug ("GdmGreeterLoginWindow: Resetting dialog"); |
---|
680 | set_busy (login_window); |
---|
681 | set_sensitive (login_window, FALSE); |
---|
682 | |
---|
683 | if (login_window->priv->timed_login_enabled) { |
---|
684 | gdm_chooser_widget_set_item_timer (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser), |
---|
685 | GDM_USER_CHOOSER_USER_AUTO, 0); |
---|
686 | remove_timed_login_timeout (login_window); |
---|
687 | login_window->priv->timed_login_enabled = FALSE; |
---|
688 | } |
---|
689 | _gdm_greeter_login_window_set_interactive (login_window, FALSE); |
---|
690 | |
---|
691 | g_signal_handlers_block_by_func (G_OBJECT (login_window->priv->user_chooser), |
---|
692 | G_CALLBACK (on_user_unchosen), login_window); |
---|
693 | gdm_user_chooser_widget_set_chosen_user_name (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser), NULL); |
---|
694 | g_signal_handlers_unblock_by_func (G_OBJECT (login_window->priv->user_chooser), |
---|
695 | G_CALLBACK (on_user_unchosen), login_window); |
---|
696 | |
---|
697 | if (login_window->priv->start_session_handler_id > 0) { |
---|
698 | g_signal_handler_disconnect (login_window, login_window->priv->start_session_handler_id); |
---|
699 | login_window->priv->start_session_handler_id = 0; |
---|
700 | } |
---|
701 | |
---|
702 | entry = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-entry"); |
---|
703 | |
---|
704 | delete_entry_text (entry); |
---|
705 | |
---|
706 | gtk_entry_set_visibility (GTK_ENTRY (entry), TRUE); |
---|
707 | set_message (login_window, ""); |
---|
708 | |
---|
709 | label = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-label"); |
---|
710 | gtk_label_set_text (GTK_LABEL (label), ""); |
---|
711 | |
---|
712 | switch_mode (login_window, MODE_SELECTION); |
---|
713 | |
---|
714 | set_sensitive (login_window, TRUE); |
---|
715 | set_ready (login_window); |
---|
716 | set_focus (GDM_GREETER_LOGIN_WINDOW (login_window)); |
---|
717 | update_banner_message (login_window); |
---|
718 | adjust_other_login_visibility (login_window); |
---|
719 | if (gdm_chooser_widget_get_number_of_items (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser)) >= 1) { |
---|
720 | gdm_chooser_widget_propagate_pending_key_events (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser)); |
---|
721 | } |
---|
722 | } |
---|
723 | |
---|
724 | static void |
---|
725 | do_cancel (GdmGreeterLoginWindow *login_window) |
---|
726 | { |
---|
727 | /* need to wait for response from backend */ |
---|
728 | set_message (login_window, _("Cancelling...")); |
---|
729 | set_busy (login_window); |
---|
730 | set_sensitive (login_window, FALSE); |
---|
731 | g_signal_emit (login_window, signals[CANCELLED], 0); |
---|
732 | } |
---|
733 | |
---|
734 | gboolean |
---|
735 | gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window) |
---|
736 | { |
---|
737 | g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE); |
---|
738 | |
---|
739 | reset_dialog (login_window); |
---|
740 | |
---|
741 | set_sensitive (GDM_GREETER_LOGIN_WINDOW (login_window), TRUE); |
---|
742 | set_ready (GDM_GREETER_LOGIN_WINDOW (login_window)); |
---|
743 | set_focus (GDM_GREETER_LOGIN_WINDOW (login_window)); |
---|
744 | |
---|
745 | return TRUE; |
---|
746 | } |
---|
747 | |
---|
748 | gboolean |
---|
749 | gdm_greeter_login_window_reset (GdmGreeterLoginWindow *login_window) |
---|
750 | { |
---|
751 | g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE); |
---|
752 | |
---|
753 | reset_dialog (GDM_GREETER_LOGIN_WINDOW (login_window)); |
---|
754 | |
---|
755 | return TRUE; |
---|
756 | } |
---|
757 | |
---|
758 | gboolean |
---|
759 | gdm_greeter_login_window_info (GdmGreeterLoginWindow *login_window, |
---|
760 | const char *text) |
---|
761 | { |
---|
762 | g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE); |
---|
763 | |
---|
764 | g_debug ("GdmGreeterLoginWindow: info: %s", text); |
---|
765 | |
---|
766 | set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text); |
---|
767 | |
---|
768 | return TRUE; |
---|
769 | } |
---|
770 | |
---|
771 | gboolean |
---|
772 | gdm_greeter_login_window_problem (GdmGreeterLoginWindow *login_window, |
---|
773 | const char *text) |
---|
774 | { |
---|
775 | g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE); |
---|
776 | |
---|
777 | g_debug ("GdmGreeterLoginWindow: problem: %s", text); |
---|
778 | |
---|
779 | set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text); |
---|
780 | gdk_window_beep (GTK_WIDGET (login_window)->window); |
---|
781 | |
---|
782 | return TRUE; |
---|
783 | } |
---|
784 | |
---|
785 | void |
---|
786 | gdm_greeter_login_window_request_timed_login (GdmGreeterLoginWindow *login_window, |
---|
787 | const char *username, |
---|
788 | int delay) |
---|
789 | { |
---|
790 | static gboolean timed_login_already_enabled; |
---|
791 | |
---|
792 | g_return_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window)); |
---|
793 | |
---|
794 | g_debug ("GdmGreeterLoginWindow: requested automatic login for user '%s' in %d seconds", username, delay); |
---|
795 | |
---|
796 | if (login_window->priv->timed_login_username != NULL) { |
---|
797 | timed_login_already_enabled = TRUE; |
---|
798 | g_free (login_window->priv->timed_login_username); |
---|
799 | } else { |
---|
800 | timed_login_already_enabled = FALSE; |
---|
801 | } |
---|
802 | login_window->priv->timed_login_username = g_strdup (username); |
---|
803 | login_window->priv->timed_login_delay = delay; |
---|
804 | |
---|
805 | if (login_window->priv->dialog_mode != MODE_SELECTION) { |
---|
806 | reset_dialog (login_window); |
---|
807 | } |
---|
808 | gdm_user_chooser_widget_set_show_user_auto (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser), TRUE); |
---|
809 | |
---|
810 | if (!timed_login_already_enabled) { |
---|
811 | gdm_user_chooser_widget_set_chosen_user_name (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser), |
---|
812 | GDM_USER_CHOOSER_USER_AUTO); |
---|
813 | } |
---|
814 | } |
---|
815 | |
---|
816 | static void |
---|
817 | gdm_greeter_login_window_start_session_when_ready (GdmGreeterLoginWindow *login_window) |
---|
818 | { |
---|
819 | if (login_window->priv->is_interactive) { |
---|
820 | g_debug ("GdmGreeterLoginWindow: starting session"); |
---|
821 | g_signal_emit (login_window, signals[START_SESSION], 0); |
---|
822 | } else { |
---|
823 | g_debug ("GdmGreeterLoginWindow: not starting session since " |
---|
824 | "user hasn't had an opportunity to pick language " |
---|
825 | "and session yet."); |
---|
826 | |
---|
827 | /* Call back when we're ready to go |
---|
828 | */ |
---|
829 | login_window->priv->start_session_handler_id = |
---|
830 | g_signal_connect (login_window, "notify::is-interactive", |
---|
831 | G_CALLBACK (gdm_greeter_login_window_start_session_when_ready), |
---|
832 | NULL); |
---|
833 | |
---|
834 | /* FIXME: If the user wasn't asked any questions by pam but |
---|
835 | * pam still authorized them (passwd -d, or the questions got |
---|
836 | * asked on an external device) then we need to let them log in. |
---|
837 | * Right now we just log them in right away, but we really should |
---|
838 | * set a timer up like timed login (but shorter, say ~5 seconds), |
---|
839 | * so they can pick language/session. Will need to refactor things |
---|
840 | * a bit so we can share code with timed login. |
---|
841 | */ |
---|
842 | if (!login_window->priv->timed_login_enabled) { |
---|
843 | |
---|
844 | g_debug ("GdmGreeterLoginWindow: Okay, we'll start the session anyway," |
---|
845 | "because the user isn't ever going to get an opportunity to" |
---|
846 | "interact with session"); |
---|
847 | _gdm_greeter_login_window_set_interactive (login_window, TRUE); |
---|
848 | } |
---|
849 | |
---|
850 | } |
---|
851 | } |
---|
852 | |
---|
853 | gboolean |
---|
854 | gdm_greeter_login_window_info_query (GdmGreeterLoginWindow *login_window, |
---|
855 | const char *text) |
---|
856 | { |
---|
857 | GtkWidget *entry; |
---|
858 | GtkWidget *label; |
---|
859 | |
---|
860 | g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE); |
---|
861 | |
---|
862 | g_debug ("GdmGreeterLoginWindow: info query: %s", text); |
---|
863 | |
---|
864 | entry = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-entry"); |
---|
865 | delete_entry_text (entry); |
---|
866 | gtk_entry_set_visibility (GTK_ENTRY (entry), TRUE); |
---|
867 | set_log_in_button_mode (login_window, LOGIN_BUTTON_ANSWER_QUERY); |
---|
868 | |
---|
869 | label = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-label"); |
---|
870 | gtk_label_set_text (GTK_LABEL (label), text); |
---|
871 | |
---|
872 | show_widget (login_window, "auth-input-box", TRUE); |
---|
873 | set_sensitive (GDM_GREETER_LOGIN_WINDOW (login_window), TRUE); |
---|
874 | set_ready (GDM_GREETER_LOGIN_WINDOW (login_window)); |
---|
875 | set_focus (GDM_GREETER_LOGIN_WINDOW (login_window)); |
---|
876 | |
---|
877 | gdm_chooser_widget_propagate_pending_key_events (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser)); |
---|
878 | |
---|
879 | return TRUE; |
---|
880 | } |
---|
881 | |
---|
882 | gboolean |
---|
883 | gdm_greeter_login_window_secret_info_query (GdmGreeterLoginWindow *login_window, |
---|
884 | const char *text) |
---|
885 | { |
---|
886 | GtkWidget *entry; |
---|
887 | GtkWidget *label; |
---|
888 | |
---|
889 | g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE); |
---|
890 | |
---|
891 | entry = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-entry"); |
---|
892 | delete_entry_text (entry); |
---|
893 | gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE); |
---|
894 | set_log_in_button_mode (login_window, LOGIN_BUTTON_ANSWER_QUERY); |
---|
895 | |
---|
896 | label = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-label"); |
---|
897 | gtk_label_set_text (GTK_LABEL (label), text); |
---|
898 | |
---|
899 | show_widget (login_window, "auth-input-box", TRUE); |
---|
900 | set_sensitive (GDM_GREETER_LOGIN_WINDOW (login_window), TRUE); |
---|
901 | set_ready (GDM_GREETER_LOGIN_WINDOW (login_window)); |
---|
902 | set_focus (GDM_GREETER_LOGIN_WINDOW (login_window)); |
---|
903 | |
---|
904 | gdm_chooser_widget_propagate_pending_key_events (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser)); |
---|
905 | |
---|
906 | return TRUE; |
---|
907 | } |
---|
908 | |
---|
909 | void |
---|
910 | gdm_greeter_login_window_user_authorized (GdmGreeterLoginWindow *login_window) |
---|
911 | { |
---|
912 | g_return_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window)); |
---|
913 | |
---|
914 | g_debug ("GdmGreeterLoginWindow: user now authorized"); |
---|
915 | |
---|
916 | gdm_greeter_login_window_start_session_when_ready (login_window); |
---|
917 | } |
---|
918 | |
---|
919 | static void |
---|
920 | _gdm_greeter_login_window_set_display_is_local (GdmGreeterLoginWindow *login_window, |
---|
921 | gboolean is) |
---|
922 | { |
---|
923 | login_window->priv->display_is_local = is; |
---|
924 | } |
---|
925 | |
---|
926 | static void |
---|
927 | gdm_greeter_login_window_set_property (GObject *object, |
---|
928 | guint prop_id, |
---|
929 | const GValue *value, |
---|
930 | GParamSpec *pspec) |
---|
931 | { |
---|
932 | GdmGreeterLoginWindow *self; |
---|
933 | |
---|
934 | self = GDM_GREETER_LOGIN_WINDOW (object); |
---|
935 | |
---|
936 | switch (prop_id) { |
---|
937 | case PROP_DISPLAY_IS_LOCAL: |
---|
938 | _gdm_greeter_login_window_set_display_is_local (self, g_value_get_boolean (value)); |
---|
939 | break; |
---|
940 | case PROP_IS_INTERACTIVE: |
---|
941 | _gdm_greeter_login_window_set_interactive (self, g_value_get_boolean (value)); |
---|
942 | break; |
---|
943 | default: |
---|
944 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
---|
945 | break; |
---|
946 | } |
---|
947 | } |
---|
948 | |
---|
949 | static void |
---|
950 | gdm_greeter_login_window_get_property (GObject *object, |
---|
951 | guint prop_id, |
---|
952 | GValue *value, |
---|
953 | GParamSpec *pspec) |
---|
954 | { |
---|
955 | GdmGreeterLoginWindow *self; |
---|
956 | |
---|
957 | self = GDM_GREETER_LOGIN_WINDOW (object); |
---|
958 | |
---|
959 | switch (prop_id) { |
---|
960 | case PROP_DISPLAY_IS_LOCAL: |
---|
961 | g_value_set_boolean (value, self->priv->display_is_local); |
---|
962 | break; |
---|
963 | case PROP_IS_INTERACTIVE: |
---|
964 | g_value_set_boolean (value, self->priv->is_interactive); |
---|
965 | break; |
---|
966 | |
---|
967 | default: |
---|
968 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
---|
969 | break; |
---|
970 | } |
---|
971 | } |
---|
972 | |
---|
973 | static void |
---|
974 | suspend_button_clicked (GtkButton *button, |
---|
975 | GdmGreeterLoginWindow *login_window) |
---|
976 | { |
---|
977 | #ifdef HAVE_DEVICEKIT_POWER |
---|
978 | do_suspend (login_window); |
---|
979 | #endif |
---|
980 | } |
---|
981 | |
---|
982 | |
---|
983 | static void |
---|
984 | cancel_button_clicked (GtkButton *button, |
---|
985 | GdmGreeterLoginWindow *login_window) |
---|
986 | { |
---|
987 | do_cancel (login_window); |
---|
988 | } |
---|
989 | |
---|
990 | static void |
---|
991 | disconnect_button_clicked (GtkButton *button, |
---|
992 | GdmGreeterLoginWindow *login_window) |
---|
993 | { |
---|
994 | do_disconnect (login_window); |
---|
995 | } |
---|
996 | |
---|
997 | static gboolean |
---|
998 | try_system_stop (DBusGConnection *connection, |
---|
999 | GError **error) |
---|
1000 | { |
---|
1001 | DBusGProxy *proxy; |
---|
1002 | gboolean res; |
---|
1003 | |
---|
1004 | g_debug ("GdmGreeterLoginWindow: trying to stop system"); |
---|
1005 | |
---|
1006 | proxy = dbus_g_proxy_new_for_name (connection, |
---|
1007 | CK_NAME, |
---|
1008 | CK_MANAGER_PATH, |
---|
1009 | CK_MANAGER_INTERFACE); |
---|
1010 | res = dbus_g_proxy_call_with_timeout (proxy, |
---|
1011 | "Stop", |
---|
1012 | INT_MAX, |
---|
1013 | error, |
---|
1014 | /* parameters: */ |
---|
1015 | G_TYPE_INVALID, |
---|
1016 | /* return values: */ |
---|
1017 | G_TYPE_INVALID); |
---|
1018 | return res; |
---|
1019 | } |
---|
1020 | |
---|
1021 | static gboolean |
---|
1022 | try_system_restart (DBusGConnection *connection, |
---|
1023 | GError **error) |
---|
1024 | { |
---|
1025 | DBusGProxy *proxy; |
---|
1026 | gboolean res; |
---|
1027 | |
---|
1028 | g_debug ("GdmGreeterLoginWindow: trying to restart system"); |
---|
1029 | |
---|
1030 | proxy = dbus_g_proxy_new_for_name (connection, |
---|
1031 | CK_NAME, |
---|
1032 | CK_MANAGER_PATH, |
---|
1033 | CK_MANAGER_INTERFACE); |
---|
1034 | res = dbus_g_proxy_call_with_timeout (proxy, |
---|
1035 | "Restart", |
---|
1036 | INT_MAX, |
---|
1037 | error, |
---|
1038 | /* parameters: */ |
---|
1039 | G_TYPE_INVALID, |
---|
1040 | /* return values: */ |
---|
1041 | G_TYPE_INVALID); |
---|
1042 | return res; |
---|
1043 | } |
---|
1044 | |
---|
1045 | static void |
---|
1046 | do_system_restart (GdmGreeterLoginWindow *login_window) |
---|
1047 | { |
---|
1048 | gboolean res; |
---|
1049 | GError *error; |
---|
1050 | DBusGConnection *connection; |
---|
1051 | |
---|
1052 | error = NULL; |
---|
1053 | connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); |
---|
1054 | if (connection == NULL) { |
---|
1055 | g_warning ("Unable to get system bus connection: %s", error->message); |
---|
1056 | g_error_free (error); |
---|
1057 | return; |
---|
1058 | } |
---|
1059 | |
---|
1060 | res = try_system_restart (connection, &error); |
---|
1061 | if (!res) { |
---|
1062 | g_debug ("GdmGreeterLoginWindow: unable to restart system: %s: %s", |
---|
1063 | dbus_g_error_get_name (error), |
---|
1064 | error->message); |
---|
1065 | g_error_free (error); |
---|
1066 | } |
---|
1067 | } |
---|
1068 | |
---|
1069 | static void |
---|
1070 | do_system_stop (GdmGreeterLoginWindow *login_window) |
---|
1071 | { |
---|
1072 | gboolean res; |
---|
1073 | GError *error; |
---|
1074 | DBusGConnection *connection; |
---|
1075 | |
---|
1076 | error = NULL; |
---|
1077 | connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); |
---|
1078 | if (connection == NULL) { |
---|
1079 | g_warning ("Unable to get system bus connection: %s", error->message); |
---|
1080 | g_error_free (error); |
---|
1081 | return; |
---|
1082 | } |
---|
1083 | |
---|
1084 | res = try_system_stop (connection, &error); |
---|
1085 | if (!res) { |
---|
1086 | g_debug ("GdmGreeterLoginWindow: unable to stop system: %s: %s", |
---|
1087 | dbus_g_error_get_name (error), |
---|
1088 | error->message); |
---|
1089 | g_error_free (error); |
---|
1090 | } |
---|
1091 | } |
---|
1092 | |
---|
1093 | static void |
---|
1094 | restart_button_clicked (GtkButton *button, |
---|
1095 | GdmGreeterLoginWindow *login_window) |
---|
1096 | { |
---|
1097 | g_debug ("GdmGreeterLoginWindow: restart button clicked"); |
---|
1098 | do_system_restart (login_window); |
---|
1099 | } |
---|
1100 | |
---|
1101 | static void |
---|
1102 | shutdown_button_clicked (GtkButton *button, |
---|
1103 | GdmGreeterLoginWindow *login_window) |
---|
1104 | { |
---|
1105 | g_debug ("GdmGreeterLoginWindow: stop button clicked"); |
---|
1106 | do_system_stop (login_window); |
---|
1107 | } |
---|
1108 | |
---|
1109 | static void |
---|
1110 | on_user_chooser_visibility_changed (GdmGreeterLoginWindow *login_window) |
---|
1111 | { |
---|
1112 | update_banner_message (login_window); |
---|
1113 | adjust_other_login_visibility (login_window); |
---|
1114 | } |
---|
1115 | |
---|
1116 | static void |
---|
1117 | on_users_loaded (GdmUserChooserWidget *user_chooser, |
---|
1118 | GdmGreeterLoginWindow *login_window) |
---|
1119 | { |
---|
1120 | g_debug ("GdmGreeterLoginWindow: users loaded"); |
---|
1121 | login_window->priv->user_chooser_loaded = TRUE; |
---|
1122 | update_banner_message (login_window); |
---|
1123 | adjust_other_login_visibility (login_window); |
---|
1124 | |
---|
1125 | gdm_chooser_widget_activate_if_one_item (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser)); |
---|
1126 | } |
---|
1127 | |
---|
1128 | static void |
---|
1129 | on_user_chosen (GdmUserChooserWidget *user_chooser, |
---|
1130 | GdmGreeterLoginWindow *login_window) |
---|
1131 | { |
---|
1132 | char *user_name; |
---|
1133 | |
---|
1134 | user_name = gdm_user_chooser_widget_get_chosen_user_name (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser)); |
---|
1135 | g_debug ("GdmGreeterLoginWindow: user chosen '%s'", user_name); |
---|
1136 | |
---|
1137 | if (user_name == NULL) { |
---|
1138 | return; |
---|
1139 | } |
---|
1140 | |
---|
1141 | g_signal_emit (G_OBJECT (login_window), signals[USER_SELECTED], |
---|
1142 | 0, user_name); |
---|
1143 | |
---|
1144 | if (strcmp (user_name, GDM_USER_CHOOSER_USER_OTHER) == 0) { |
---|
1145 | g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0); |
---|
1146 | } else if (strcmp (user_name, GDM_USER_CHOOSER_USER_GUEST) == 0) { |
---|
1147 | /* FIXME: handle guest account stuff */ |
---|
1148 | } else if (strcmp (user_name, GDM_USER_CHOOSER_USER_AUTO) == 0) { |
---|
1149 | g_signal_emit (login_window, signals[BEGIN_AUTO_LOGIN], 0, |
---|
1150 | login_window->priv->timed_login_username); |
---|
1151 | |
---|
1152 | login_window->priv->timed_login_enabled = TRUE; |
---|
1153 | restart_timed_login_timeout (login_window); |
---|
1154 | |
---|
1155 | /* just wait for the user to select language and stuff */ |
---|
1156 | set_log_in_button_mode (login_window, LOGIN_BUTTON_TIMED_LOGIN); |
---|
1157 | set_message (login_window, _("Select language and click Log In")); |
---|
1158 | } else { |
---|
1159 | g_signal_emit (login_window, signals[BEGIN_VERIFICATION_FOR_USER], 0, user_name); |
---|
1160 | } |
---|
1161 | |
---|
1162 | switch_mode (login_window, MODE_AUTHENTICATION); |
---|
1163 | |
---|
1164 | g_free (user_name); |
---|
1165 | } |
---|
1166 | |
---|
1167 | static void |
---|
1168 | on_user_unchosen (GdmUserChooserWidget *user_chooser, |
---|
1169 | GdmGreeterLoginWindow *login_window) |
---|
1170 | { |
---|
1171 | do_cancel (login_window); |
---|
1172 | } |
---|
1173 | |
---|
1174 | static gboolean |
---|
1175 | on_computer_info_label_button_press (GtkWidget *widget, |
---|
1176 | GdkEventButton *event, |
---|
1177 | GdmGreeterLoginWindow *login_window) |
---|
1178 | { |
---|
1179 | GtkWidget *notebook; |
---|
1180 | int current_page; |
---|
1181 | int n_pages; |
---|
1182 | |
---|
1183 | /* switch page */ |
---|
1184 | notebook = glade_xml_get_widget (login_window->priv->xml, "computer-info-notebook"); |
---|
1185 | current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); |
---|
1186 | n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)); |
---|
1187 | |
---|
1188 | if (current_page + 1 < n_pages) { |
---|
1189 | gtk_notebook_next_page (GTK_NOTEBOOK (notebook)); |
---|
1190 | } else { |
---|
1191 | gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 0); |
---|
1192 | } |
---|
1193 | |
---|
1194 | return FALSE; |
---|
1195 | } |
---|
1196 | |
---|
1197 | static char * |
---|
1198 | file_read_one_line (const char *filename) |
---|
1199 | { |
---|
1200 | FILE *f; |
---|
1201 | char *line; |
---|
1202 | char buf[4096]; |
---|
1203 | |
---|
1204 | line = NULL; |
---|
1205 | |
---|
1206 | f = fopen (filename, "r"); |
---|
1207 | if (f == NULL) { |
---|
1208 | g_warning ("Unable to open file %s: %s", filename, g_strerror (errno)); |
---|
1209 | goto out; |
---|
1210 | } |
---|
1211 | |
---|
1212 | if (fgets (buf, sizeof (buf), f) == NULL) { |
---|
1213 | g_warning ("Unable to read from file %s", filename); |
---|
1214 | } |
---|
1215 | |
---|
1216 | line = g_strdup (buf); |
---|
1217 | g_strchomp (line); |
---|
1218 | |
---|
1219 | out: |
---|
1220 | fclose (f); |
---|
1221 | |
---|
1222 | return line; |
---|
1223 | } |
---|
1224 | |
---|
1225 | static const char *known_etc_info_files [] = { |
---|
1226 | "redhat-release", |
---|
1227 | "SuSE-release", |
---|
1228 | "gentoo-release", |
---|
1229 | "arch-release", |
---|
1230 | "debian_version", |
---|
1231 | "mandriva-release", |
---|
1232 | "slackware-version", |
---|
1233 | NULL |
---|
1234 | }; |
---|
1235 | |
---|
1236 | |
---|
1237 | static char * |
---|
1238 | get_system_version (void) |
---|
1239 | { |
---|
1240 | char *version; |
---|
1241 | int i; |
---|
1242 | |
---|
1243 | version = NULL; |
---|
1244 | |
---|
1245 | for (i = 0; known_etc_info_files [i]; i++) { |
---|
1246 | char *path1; |
---|
1247 | char *path2; |
---|
1248 | |
---|
1249 | path1 = g_build_filename (SYSCONFDIR, known_etc_info_files [i], NULL); |
---|
1250 | path2 = g_build_filename ("/etc", known_etc_info_files [i], NULL); |
---|
1251 | if (g_access (path1, R_OK) == 0) { |
---|
1252 | version = file_read_one_line (path1); |
---|
1253 | } else if (g_access (path2, R_OK) == 0) { |
---|
1254 | version = file_read_one_line (path2); |
---|
1255 | } |
---|
1256 | g_free (path2); |
---|
1257 | g_free (path1); |
---|
1258 | if (version != NULL) { |
---|
1259 | break; |
---|
1260 | } |
---|
1261 | } |
---|
1262 | |
---|
1263 | if (version == NULL) { |
---|
1264 | char *output; |
---|
1265 | output = NULL; |
---|
1266 | if (g_spawn_command_line_sync ("uname -sr", &output, NULL, NULL, NULL)) { |
---|
1267 | version = g_strchomp (output); |
---|
1268 | } |
---|
1269 | } |
---|
1270 | |
---|
1271 | return version; |
---|
1272 | } |
---|
1273 | |
---|
1274 | static void |
---|
1275 | create_computer_info (GdmGreeterLoginWindow *login_window) |
---|
1276 | { |
---|
1277 | GtkWidget *label; |
---|
1278 | |
---|
1279 | gdm_profile_start (NULL); |
---|
1280 | |
---|
1281 | label = glade_xml_get_widget (login_window->priv->xml, "computer-info-name-label"); |
---|
1282 | if (label != NULL) { |
---|
1283 | gtk_label_set_text (GTK_LABEL (label), "ana are mere");//g_get_host_name ()); |
---|
1284 | } |
---|
1285 | |
---|
1286 | label = glade_xml_get_widget (login_window->priv->xml, "computer-info-version-label"); |
---|
1287 | if (label != NULL) { |
---|
1288 | char *version; |
---|
1289 | version = get_system_version (); |
---|
1290 | gtk_label_set_text (GTK_LABEL (label), version); |
---|
1291 | g_free (version); |
---|
1292 | } |
---|
1293 | |
---|
1294 | gdm_profile_end (NULL); |
---|
1295 | } |
---|
1296 | |
---|
1297 | #define INVISIBLE_CHAR_DEFAULT '*' |
---|
1298 | #define INVISIBLE_CHAR_BLACK_CIRCLE 0x25cf |
---|
1299 | #define INVISIBLE_CHAR_WHITE_BULLET 0x25e6 |
---|
1300 | #define INVISIBLE_CHAR_BULLET 0x2022 |
---|
1301 | #define INVISIBLE_CHAR_NONE 0 |
---|
1302 | |
---|
1303 | static GtkWidget * |
---|
1304 | custom_widget_constructor (GladeXML *xml, |
---|
1305 | char *func_name, |
---|
1306 | char *name, |
---|
1307 | char *string1, |
---|
1308 | char *string2, |
---|
1309 | int int1, |
---|
1310 | int int2, |
---|
1311 | GdmGreeterLoginWindow *login_window) |
---|
1312 | { |
---|
1313 | GtkWidget *widget; |
---|
1314 | |
---|
1315 | g_assert (GLADE_IS_XML (xml)); |
---|
1316 | g_assert (name != NULL); |
---|
1317 | g_assert (GDM_IS_GREETER_LOGIN_WINDOW (login_window)); |
---|
1318 | |
---|
1319 | gdm_profile_start (NULL); |
---|
1320 | |
---|
1321 | widget = NULL; |
---|
1322 | |
---|
1323 | if (strcmp (name, "user-chooser") == 0) { |
---|
1324 | widget = gdm_user_chooser_widget_new (); |
---|
1325 | } |
---|
1326 | |
---|
1327 | gdm_profile_end (NULL); |
---|
1328 | |
---|
1329 | return widget; |
---|
1330 | } |
---|
1331 | |
---|
1332 | static void |
---|
1333 | load_theme (GdmGreeterLoginWindow *login_window) |
---|
1334 | { |
---|
1335 | GtkWidget *entry; |
---|
1336 | GtkWidget *button; |
---|
1337 | GtkWidget *box; |
---|
1338 | GtkWidget *image; |
---|
1339 | |
---|
1340 | gdm_profile_start (NULL); |
---|
1341 | |
---|
1342 | glade_set_custom_handler ((GladeXMLCustomWidgetHandler) custom_widget_constructor, |
---|
1343 | login_window); |
---|
1344 | login_window->priv->xml = glade_xml_new (GLADEDIR "/" GLADE_XML_FILE, |
---|
1345 | "window-frame", |
---|
1346 | PACKAGE); |
---|
1347 | |
---|
1348 | g_assert (login_window->priv->xml != NULL); |
---|
1349 | |
---|
1350 | image = glade_xml_get_widget (login_window->priv->xml, "logo-image"); |
---|
1351 | if (image != NULL) { |
---|
1352 | char *icon_name; |
---|
1353 | GError *error; |
---|
1354 | |
---|
1355 | error = NULL; |
---|
1356 | icon_name = gconf_client_get_string (login_window->priv->client, KEY_LOGO, &error); |
---|
1357 | if (error != NULL) { |
---|
1358 | g_debug ("GdmGreeterLoginWindow: unable to get logo icon name: %s", error->message); |
---|
1359 | g_error_free (error); |
---|
1360 | } |
---|
1361 | |
---|
1362 | g_debug ("GdmGreeterLoginWindow: Got greeter logo '%s'", |
---|
1363 | icon_name ? icon_name : "(null)"); |
---|
1364 | if (icon_name != NULL) { |
---|
1365 | gtk_image_set_from_icon_name (GTK_IMAGE (image), |
---|
1366 | icon_name, |
---|
1367 | GTK_ICON_SIZE_DIALOG); |
---|
1368 | g_free (icon_name); |
---|
1369 | } |
---|
1370 | } |
---|
1371 | |
---|
1372 | box = glade_xml_get_widget (login_window->priv->xml, "window-frame"); |
---|
1373 | gtk_container_add (GTK_CONTAINER (login_window), box); |
---|
1374 | |
---|
1375 | login_window->priv->user_chooser = glade_xml_get_widget (login_window->priv->xml, |
---|
1376 | "user-chooser"); |
---|
1377 | if (login_window->priv->user_chooser == NULL) { |
---|
1378 | g_critical ("Userlist box not found"); |
---|
1379 | } |
---|
1380 | |
---|
1381 | gdm_user_chooser_widget_set_show_only_chosen (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser), TRUE); |
---|
1382 | |
---|
1383 | g_signal_connect (login_window->priv->user_chooser, |
---|
1384 | "loaded", |
---|
1385 | G_CALLBACK (on_users_loaded), |
---|
1386 | login_window); |
---|
1387 | g_signal_connect (login_window->priv->user_chooser, |
---|
1388 | "activated", |
---|
1389 | G_CALLBACK (on_user_chosen), |
---|
1390 | login_window); |
---|
1391 | g_signal_connect (login_window->priv->user_chooser, |
---|
1392 | "deactivated", |
---|
1393 | G_CALLBACK (on_user_unchosen), |
---|
1394 | login_window); |
---|
1395 | |
---|
1396 | g_signal_connect_swapped (login_window->priv->user_chooser, |
---|
1397 | "notify::list-visible", |
---|
1398 | G_CALLBACK (on_user_chooser_visibility_changed), |
---|
1399 | login_window); |
---|
1400 | |
---|
1401 | gtk_widget_show (login_window->priv->user_chooser); |
---|
1402 | |
---|
1403 | login_window->priv->auth_banner_label = glade_xml_get_widget (login_window->priv->xml, "auth-banner-label"); |
---|
1404 | /*make_label_small_italic (login_window->priv->auth_banner_label);*/ |
---|
1405 | |
---|
1406 | button = glade_xml_get_widget (login_window->priv->xml, "suspend-button"); |
---|
1407 | g_signal_connect (button, "clicked", G_CALLBACK (suspend_button_clicked), login_window); |
---|
1408 | |
---|
1409 | button = glade_xml_get_widget (login_window->priv->xml, "cancel-button"); |
---|
1410 | g_signal_connect (button, "clicked", G_CALLBACK (cancel_button_clicked), login_window); |
---|
1411 | |
---|
1412 | button = glade_xml_get_widget (login_window->priv->xml, "disconnect-button"); |
---|
1413 | g_signal_connect (button, "clicked", G_CALLBACK (disconnect_button_clicked), login_window); |
---|
1414 | |
---|
1415 | button = glade_xml_get_widget (login_window->priv->xml, "restart-button"); |
---|
1416 | g_signal_connect (button, "clicked", G_CALLBACK (restart_button_clicked), login_window); |
---|
1417 | button = glade_xml_get_widget (login_window->priv->xml, "shutdown-button"); |
---|
1418 | g_signal_connect (button, "clicked", G_CALLBACK (shutdown_button_clicked), login_window); |
---|
1419 | |
---|
1420 | entry = glade_xml_get_widget (login_window->priv->xml, "auth-prompt-entry"); |
---|
1421 | /* Only change the invisible character if it '*' otherwise assume it is OK */ |
---|
1422 | if ('*' == gtk_entry_get_invisible_char (GTK_ENTRY (entry))) { |
---|
1423 | gunichar invisible_char; |
---|
1424 | invisible_char = INVISIBLE_CHAR_BLACK_CIRCLE; |
---|
1425 | gtk_entry_set_invisible_char (GTK_ENTRY (entry), invisible_char); |
---|
1426 | } |
---|
1427 | |
---|
1428 | create_computer_info (login_window); |
---|
1429 | |
---|
1430 | box = glade_xml_get_widget (login_window->priv->xml, "computer-info-event-box"); |
---|
1431 | g_signal_connect (box, "button-press-event", G_CALLBACK (on_computer_info_label_button_press), login_window); |
---|
1432 | |
---|
1433 | switch_mode (login_window, MODE_SELECTION); |
---|
1434 | |
---|
1435 | gdm_profile_end (NULL); |
---|
1436 | } |
---|
1437 | |
---|
1438 | static gboolean |
---|
1439 | gdm_greeter_login_window_key_press_event (GtkWidget *widget, |
---|
1440 | GdkEventKey *event) |
---|
1441 | { |
---|
1442 | GdmGreeterLoginWindow *login_window; |
---|
1443 | |
---|
1444 | login_window = GDM_GREETER_LOGIN_WINDOW (widget); |
---|
1445 | |
---|
1446 | if (event->keyval == GDK_Escape) { |
---|
1447 | if (login_window->priv->dialog_mode == MODE_AUTHENTICATION) { |
---|
1448 | do_cancel (GDM_GREETER_LOGIN_WINDOW (widget)); |
---|
1449 | } |
---|
1450 | } |
---|
1451 | |
---|
1452 | return GTK_WIDGET_CLASS (gdm_greeter_login_window_parent_class)->key_press_event (widget, event); |
---|
1453 | } |
---|
1454 | |
---|
1455 | static void |
---|
1456 | gdm_greeter_login_window_size_request (GtkWidget *widget, |
---|
1457 | GtkRequisition *requisition) |
---|
1458 | { |
---|
1459 | int monitor; |
---|
1460 | GdkScreen *screen; |
---|
1461 | GtkRequisition child_requisition; |
---|
1462 | GdkRectangle area; |
---|
1463 | |
---|
1464 | if (GTK_WIDGET_CLASS (gdm_greeter_login_window_parent_class)->size_request) { |
---|
1465 | GTK_WIDGET_CLASS (gdm_greeter_login_window_parent_class)->size_request (widget, requisition); |
---|
1466 | } |
---|
1467 | |
---|
1468 | if (!GTK_WIDGET_REALIZED (widget)) { |
---|
1469 | return; |
---|
1470 | } |
---|
1471 | |
---|
1472 | screen = gtk_widget_get_screen (widget); |
---|
1473 | monitor = gdk_screen_get_monitor_at_window (screen, widget->window); |
---|
1474 | gdk_screen_get_monitor_geometry (screen, monitor, &area); |
---|
1475 | |
---|
1476 | gtk_widget_get_child_requisition (GTK_BIN (widget)->child, &child_requisition); |
---|
1477 | *requisition = child_requisition; |
---|
1478 | |
---|
1479 | requisition->width += 2 * GTK_CONTAINER (widget)->border_width; |
---|
1480 | requisition->height += 2 * GTK_CONTAINER (widget)->border_width; |
---|
1481 | |
---|
1482 | /* Make width be at least 33% screen width |
---|
1483 | * and height be at most 80% of screen height |
---|
1484 | */ |
---|
1485 | requisition->width = MAX (requisition->width, .33 * area.width); |
---|
1486 | requisition->height = MIN (requisition->height, .80 * area.height); |
---|
1487 | |
---|
1488 | /* Don't ever shrink window width |
---|
1489 | */ |
---|
1490 | requisition->width = MAX (requisition->width, widget->allocation.width); |
---|
1491 | } |
---|
1492 | |
---|
1493 | static void |
---|
1494 | update_banner_message (GdmGreeterLoginWindow *login_window) |
---|
1495 | { |
---|
1496 | GError *error; |
---|
1497 | gboolean enabled; |
---|
1498 | |
---|
1499 | if (login_window->priv->auth_banner_label == NULL) { |
---|
1500 | /* if the theme doesn't have a banner message */ |
---|
1501 | g_debug ("GdmGreeterLoginWindow: theme doesn't support a banner message"); |
---|
1502 | return; |
---|
1503 | } |
---|
1504 | |
---|
1505 | error = NULL; |
---|
1506 | enabled = gconf_client_get_bool (login_window->priv->client, KEY_BANNER_MESSAGE_ENABLED, &error); |
---|
1507 | if (error != NULL) { |
---|
1508 | g_debug ("GdmGreeterLoginWindow: unable to get configuration: %s", error->message); |
---|
1509 | g_error_free (error); |
---|
1510 | } |
---|
1511 | |
---|
1512 | login_window->priv->banner_message_enabled = enabled; |
---|
1513 | |
---|
1514 | if (! enabled) { |
---|
1515 | g_debug ("GdmGreeterLoginWindow: banner message disabled"); |
---|
1516 | gtk_widget_hide (login_window->priv->auth_banner_label); |
---|
1517 | } else { |
---|
1518 | char *message = NULL; |
---|
1519 | error = NULL; |
---|
1520 | if (login_window->priv->user_chooser_loaded && gdm_chooser_widget_get_number_of_items (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser)) == 0) { |
---|
1521 | message = gconf_client_get_string (login_window->priv->client, KEY_BANNER_MESSAGE_TEXT_NOCHOOSER, &error); |
---|
1522 | if (error != NULL) { |
---|
1523 | g_debug("GdmGreeterLoginWindow: unable to get nochooser banner text: %s", error->message); |
---|
1524 | g_error_free(error); |
---|
1525 | } |
---|
1526 | } |
---|
1527 | error = NULL; |
---|
1528 | if (message == NULL) { |
---|
1529 | message = gconf_client_get_string (login_window->priv->client, KEY_BANNER_MESSAGE_TEXT, &error); |
---|
1530 | if (error != NULL) { |
---|
1531 | g_debug("GdmGreeterLoginWindow: unable to get banner text: %s", error->message); |
---|
1532 | g_error_free(error); |
---|
1533 | } |
---|
1534 | } |
---|
1535 | if (message != NULL) { |
---|
1536 | char *markup; |
---|
1537 | markup = g_markup_printf_escaped ("<small><i>%s</i></small>", message); |
---|
1538 | gtk_label_set_markup (GTK_LABEL (login_window->priv->auth_banner_label), |
---|
1539 | markup); |
---|
1540 | g_free (markup); |
---|
1541 | } |
---|
1542 | g_debug ("GdmGreeterLoginWindow: banner message: %s", message); |
---|
1543 | |
---|
1544 | gtk_widget_show (login_window->priv->auth_banner_label); |
---|
1545 | } |
---|
1546 | } |
---|
1547 | |
---|
1548 | gboolean handleBusMsg(GstMessage * message, GtkWidget *window) |
---|
1549 | { |
---|
1550 | // ignore anything but 'prepare-xwindow-id' element messages |
---|
1551 | if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_ELEMENT) |
---|
1552 | return FALSE; |
---|
1553 | |
---|
1554 | if (!gst_structure_has_name(message->structure, "prepare-xwindow-id")) |
---|
1555 | return FALSE; |
---|
1556 | |
---|
1557 | g_assert(!GTK_WIDGET_NO_WINDOW(window)); |
---|
1558 | g_print("Got prepare-xwindow-id msg\n"); |
---|
1559 | // FIXME: see https://bugzilla.gnome.org/show_bug.cgi?id=599885 |
---|
1560 | //gdk_window_resize(window->window, 100, 100); |
---|
1561 | gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC(message)), GDK_WINDOW_XWINDOW(gtk_widget_get_window(window))); |
---|
1562 | g_debug("pe nas%s\n",gtk_widget_get_name(window)); |
---|
1563 | |
---|
1564 | return TRUE; |
---|
1565 | } |
---|
1566 | |
---|
1567 | gboolean bus_call(GstBus * bus, GstMessage *msg, gpointer data) |
---|
1568 | { |
---|
1569 | GtkWidget *window = (GtkWidget*) data; |
---|
1570 | switch(GST_MESSAGE_TYPE(msg)) |
---|
1571 | { |
---|
1572 | case GST_MESSAGE_ELEMENT: |
---|
1573 | { |
---|
1574 | handleBusMsg(msg, window); |
---|
1575 | break; |
---|
1576 | } |
---|
1577 | |
---|
1578 | default: |
---|
1579 | break; |
---|
1580 | } |
---|
1581 | |
---|
1582 | return TRUE; |
---|
1583 | } |
---|
1584 | |
---|
1585 | static void makeWindowBlack(GtkWidget * window) |
---|
1586 | { |
---|
1587 | GdkColor color; |
---|
1588 | gdk_color_parse ("black", &color); |
---|
1589 | gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &color); // needed to ensure black background |
---|
1590 | } |
---|
1591 | |
---|
1592 | |
---|
1593 | static GObject * |
---|
1594 | gdm_greeter_login_window_constructor (GType type, |
---|
1595 | guint n_construct_properties, |
---|
1596 | GObjectConstructParam *construct_properties) |
---|
1597 | { |
---|
1598 | GdmGreeterLoginWindow *login_window; |
---|
1599 | GstElement *src, *sink; |
---|
1600 | GstStateChangeReturn ret; |
---|
1601 | GtkWidget * logo; |
---|
1602 | |
---|
1603 | gdm_profile_start (NULL); |
---|
1604 | |
---|
1605 | login_window = GDM_GREETER_LOGIN_WINDOW (G_OBJECT_CLASS (gdm_greeter_login_window_parent_class)->constructor (type, |
---|
1606 | n_construct_properties, |
---|
1607 | construct_properties)); |
---|
1608 | |
---|
1609 | |
---|
1610 | load_theme (login_window); |
---|
1611 | update_banner_message (login_window); |
---|
1612 | |
---|
1613 | |
---|
1614 | gst_init(NULL,NULL); |
---|
1615 | |
---|
1616 | |
---|
1617 | |
---|
1618 | g_assert(login_window!=NULL); |
---|
1619 | g_assert(login_window->priv!=NULL); |
---|
1620 | g_assert(login_window->priv->xml!=NULL); |
---|
1621 | logo = glade_xml_get_widget (login_window->priv->xml, "webcam"); |
---|
1622 | g_assert(logo!=NULL); |
---|
1623 | /* create elements */ |
---|
1624 | pipeline = gst_pipeline_new ("my_pipeline"); |
---|
1625 | gst_bus_add_watch(gst_pipeline_get_bus(GST_PIPELINE(pipeline)), |
---|
1626 | (GstBusFunc)bus_call, logo); |
---|
1627 | |
---|
1628 | src = gst_element_factory_make ("v4l2src", NULL); |
---|
1629 | |
---|
1630 | sink = gst_element_factory_make("autovideosink", "videosink"); |
---|
1631 | g_object_set(G_OBJECT(sink), "sync", FALSE, NULL); |
---|
1632 | |
---|
1633 | if (!sink) |
---|
1634 | g_print ("output could not be found - check your install\n"); |
---|
1635 | |
---|
1636 | gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL); |
---|
1637 | g_object_set(G_OBJECT(sink), "force-aspect-ratio", TRUE, NULL); |
---|
1638 | |
---|
1639 | /* link everything together */ |
---|
1640 | if (!gst_element_link(src, sink)) { |
---|
1641 | g_print ("Failed to link one or more elements!\n"); |
---|
1642 | return -1; |
---|
1643 | } |
---|
1644 | |
---|
1645 | |
---|
1646 | /* run */ |
---|
1647 | makeWindowBlack(logo); |
---|
1648 | gtk_widget_show_all(logo); |
---|
1649 | |
---|
1650 | ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); |
---|
1651 | |
---|
1652 | if (ret == GST_STATE_CHANGE_FAILURE) |
---|
1653 | { |
---|
1654 | g_print ("Failed to start up pipeline!\n"); |
---|
1655 | return 1; |
---|
1656 | } |
---|
1657 | |
---|
1658 | |
---|
1659 | gdm_profile_end (NULL); |
---|
1660 | |
---|
1661 | return G_OBJECT (login_window); |
---|
1662 | } |
---|
1663 | |
---|
1664 | static void |
---|
1665 | gdm_greeter_login_window_class_init (GdmGreeterLoginWindowClass *klass) |
---|
1666 | { |
---|
1667 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |
---|
1668 | GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); |
---|
1669 | |
---|
1670 | object_class->get_property = gdm_greeter_login_window_get_property; |
---|
1671 | object_class->set_property = gdm_greeter_login_window_set_property; |
---|
1672 | object_class->constructor = gdm_greeter_login_window_constructor; |
---|
1673 | object_class->finalize = gdm_greeter_login_window_finalize; |
---|
1674 | |
---|
1675 | widget_class->key_press_event = gdm_greeter_login_window_key_press_event; |
---|
1676 | widget_class->size_request = gdm_greeter_login_window_size_request; |
---|
1677 | |
---|
1678 | signals [BEGIN_AUTO_LOGIN] = |
---|
1679 | g_signal_new ("begin-auto-login", |
---|
1680 | G_TYPE_FROM_CLASS (object_class), |
---|
1681 | G_SIGNAL_RUN_LAST, |
---|
1682 | G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, begin_auto_login), |
---|
1683 | NULL, |
---|
1684 | NULL, |
---|
1685 | g_cclosure_marshal_VOID__STRING, |
---|
1686 | G_TYPE_NONE, 1, G_TYPE_STRING); |
---|
1687 | signals [BEGIN_VERIFICATION] = |
---|
1688 | g_signal_new ("begin-verification", |
---|
1689 | G_TYPE_FROM_CLASS (object_class), |
---|
1690 | G_SIGNAL_RUN_LAST, |
---|
1691 | G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, begin_verification), |
---|
1692 | NULL, |
---|
1693 | NULL, |
---|
1694 | g_cclosure_marshal_VOID__VOID, |
---|
1695 | G_TYPE_NONE, |
---|
1696 | 0); |
---|
1697 | signals [BEGIN_VERIFICATION_FOR_USER] = |
---|
1698 | g_signal_new ("begin-verification-for-user", |
---|
1699 | G_TYPE_FROM_CLASS (object_class), |
---|
1700 | G_SIGNAL_RUN_LAST, |
---|
1701 | G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, begin_verification_for_user), |
---|
1702 | NULL, |
---|
1703 | NULL, |
---|
1704 | g_cclosure_marshal_VOID__STRING, |
---|
1705 | G_TYPE_NONE, |
---|
1706 | 1, G_TYPE_STRING); |
---|
1707 | signals [QUERY_ANSWER] = |
---|
1708 | g_signal_new ("query-answer", |
---|
1709 | G_TYPE_FROM_CLASS (object_class), |
---|
1710 | G_SIGNAL_RUN_LAST, |
---|
1711 | G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, query_answer), |
---|
1712 | NULL, |
---|
1713 | NULL, |
---|
1714 | g_cclosure_marshal_VOID__STRING, |
---|
1715 | G_TYPE_NONE, |
---|
1716 | 1, G_TYPE_STRING); |
---|
1717 | signals [USER_SELECTED] = |
---|
1718 | g_signal_new ("user-selected", |
---|
1719 | G_TYPE_FROM_CLASS (object_class), |
---|
1720 | G_SIGNAL_RUN_LAST, |
---|
1721 | G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, user_selected), |
---|
1722 | NULL, |
---|
1723 | NULL, |
---|
1724 | g_cclosure_marshal_VOID__STRING, |
---|
1725 | G_TYPE_NONE, |
---|
1726 | 1, G_TYPE_STRING); |
---|
1727 | signals [CANCELLED] = |
---|
1728 | g_signal_new ("cancelled", |
---|
1729 | G_TYPE_FROM_CLASS (object_class), |
---|
1730 | G_SIGNAL_RUN_LAST, |
---|
1731 | G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, cancelled), |
---|
1732 | NULL, |
---|
1733 | NULL, |
---|
1734 | g_cclosure_marshal_VOID__VOID, |
---|
1735 | G_TYPE_NONE, |
---|
1736 | 0); |
---|
1737 | signals [DISCONNECTED] = |
---|
1738 | g_signal_new ("disconnected", |
---|
1739 | G_TYPE_FROM_CLASS (object_class), |
---|
1740 | G_SIGNAL_RUN_LAST, |
---|
1741 | G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, disconnected), |
---|
1742 | NULL, |
---|
1743 | NULL, |
---|
1744 | g_cclosure_marshal_VOID__VOID, |
---|
1745 | G_TYPE_NONE, |
---|
1746 | 0); |
---|
1747 | signals [START_SESSION] = |
---|
1748 | g_signal_new ("start-session", |
---|
1749 | G_TYPE_FROM_CLASS (object_class), |
---|
1750 | G_SIGNAL_RUN_LAST, |
---|
1751 | G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, start_session), |
---|
1752 | NULL, |
---|
1753 | NULL, |
---|
1754 | g_cclosure_marshal_VOID__VOID, |
---|
1755 | G_TYPE_NONE, |
---|
1756 | 0); |
---|
1757 | |
---|
1758 | g_object_class_install_property (object_class, |
---|
1759 | PROP_DISPLAY_IS_LOCAL, |
---|
1760 | g_param_spec_boolean ("display-is-local", |
---|
1761 | "display is local", |
---|
1762 | "display is local", |
---|
1763 | FALSE, |
---|
1764 | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); |
---|
1765 | g_object_class_install_property (object_class, |
---|
1766 | PROP_IS_INTERACTIVE, |
---|
1767 | g_param_spec_boolean ("is-interactive", |
---|
1768 | "Is Interactive", |
---|
1769 | "Use has had an oppurtunity to interact with window", |
---|
1770 | FALSE, |
---|
1771 | G_PARAM_READABLE)); |
---|
1772 | |
---|
1773 | g_type_class_add_private (klass, sizeof (GdmGreeterLoginWindowPrivate)); |
---|
1774 | } |
---|
1775 | |
---|
1776 | static void |
---|
1777 | on_gconf_key_changed (GConfClient *client, |
---|
1778 | guint cnxn_id, |
---|
1779 | GConfEntry *entry, |
---|
1780 | GdmGreeterLoginWindow *login_window) |
---|
1781 | { |
---|
1782 | const char *key; |
---|
1783 | GConfValue *value; |
---|
1784 | |
---|
1785 | key = gconf_entry_get_key (entry); |
---|
1786 | value = gconf_entry_get_value (entry); |
---|
1787 | |
---|
1788 | if (strcmp (key, KEY_BANNER_MESSAGE_ENABLED) == 0) { |
---|
1789 | if (value->type == GCONF_VALUE_BOOL) { |
---|
1790 | gboolean enabled; |
---|
1791 | |
---|
1792 | enabled = gconf_value_get_bool (value); |
---|
1793 | g_debug ("setting key %s = %d", key, enabled); |
---|
1794 | login_window->priv->banner_message_enabled = enabled; |
---|
1795 | update_banner_message (login_window); |
---|
1796 | } else { |
---|
1797 | g_warning ("Error retrieving configuration key '%s': Invalid type", |
---|
1798 | key); |
---|
1799 | } |
---|
1800 | } else if (strcmp (key, KEY_BANNER_MESSAGE_TEXT) == 0 || strcmp (key, KEY_BANNER_MESSAGE_TEXT_NOCHOOSER) == 0) { |
---|
1801 | if (login_window->priv->banner_message_enabled) { |
---|
1802 | update_banner_message (login_window); |
---|
1803 | } |
---|
1804 | } else { |
---|
1805 | g_debug ("GdmGreeterLoginWindow: Config key not handled: %s", key); |
---|
1806 | } |
---|
1807 | } |
---|
1808 | |
---|
1809 | static gboolean |
---|
1810 | on_window_state_event (GtkWidget *widget, |
---|
1811 | GdkEventWindowState *event, |
---|
1812 | gpointer data) |
---|
1813 | { |
---|
1814 | if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) { |
---|
1815 | g_debug ("GdmGreeterLoginWindow: window iconified"); |
---|
1816 | gtk_window_deiconify (GTK_WINDOW (widget)); |
---|
1817 | } |
---|
1818 | |
---|
1819 | return FALSE; |
---|
1820 | } |
---|
1821 | |
---|
1822 | static void |
---|
1823 | gdm_greeter_login_window_init (GdmGreeterLoginWindow *login_window) |
---|
1824 | { |
---|
1825 | |
---|
1826 | |
---|
1827 | gdm_profile_start (NULL); |
---|
1828 | |
---|
1829 | login_window->priv = GDM_GREETER_LOGIN_WINDOW_GET_PRIVATE (login_window); |
---|
1830 | |
---|
1831 | login_window->priv->timed_login_enabled = FALSE; |
---|
1832 | |
---|
1833 | login_window->priv->dialog_mode = MODE_SELECTION; |
---|
1834 | |
---|
1835 | gtk_window_set_title (GTK_WINDOW (login_window), _("Login Window")); |
---|
1836 | /*gtk_window_set_opacity (GTK_WINDOW (login_window), 0.85);*/ |
---|
1837 | gtk_window_set_position (GTK_WINDOW (login_window), GTK_WIN_POS_CENTER_ALWAYS); |
---|
1838 | gtk_window_set_deletable (GTK_WINDOW (login_window), FALSE); |
---|
1839 | gtk_window_set_decorated (GTK_WINDOW (login_window), FALSE); |
---|
1840 | gtk_window_set_keep_below (GTK_WINDOW (login_window), TRUE); |
---|
1841 | gtk_window_set_skip_taskbar_hint (GTK_WINDOW (login_window), TRUE); |
---|
1842 | gtk_window_set_skip_pager_hint (GTK_WINDOW (login_window), TRUE); |
---|
1843 | gtk_window_stick (GTK_WINDOW (login_window)); |
---|
1844 | gtk_window_set_type_hint (GTK_WINDOW (login_window), GDK_WINDOW_TYPE_HINT_DOCK); |
---|
1845 | gtk_container_set_border_width (GTK_CONTAINER (login_window), 0); |
---|
1846 | |
---|
1847 | g_signal_connect (login_window, |
---|
1848 | "window-state-event", |
---|
1849 | G_CALLBACK (on_window_state_event), |
---|
1850 | NULL); |
---|
1851 | |
---|
1852 | login_window->priv->client = gconf_client_get_default (); |
---|
1853 | gconf_client_add_dir (login_window->priv->client, |
---|
1854 | KEY_GREETER_DIR, |
---|
1855 | GCONF_CLIENT_PRELOAD_ONELEVEL, |
---|
1856 | NULL); |
---|
1857 | login_window->priv->gconf_cnxn = gconf_client_notify_add (login_window->priv->client, |
---|
1858 | KEY_GREETER_DIR, |
---|
1859 | (GConfClientNotifyFunc)on_gconf_key_changed, |
---|
1860 | login_window, |
---|
1861 | NULL, |
---|
1862 | NULL); |
---|
1863 | |
---|
1864 | |
---|
1865 | |
---|
1866 | gdm_profile_end (NULL); |
---|
1867 | } |
---|
1868 | |
---|
1869 | static void |
---|
1870 | gdm_greeter_login_window_finalize (GObject *object) |
---|
1871 | { |
---|
1872 | GdmGreeterLoginWindow *login_window; |
---|
1873 | |
---|
1874 | g_return_if_fail (object != NULL); |
---|
1875 | g_return_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (object)); |
---|
1876 | |
---|
1877 | login_window = GDM_GREETER_LOGIN_WINDOW (object); |
---|
1878 | |
---|
1879 | g_return_if_fail (login_window->priv != NULL); |
---|
1880 | |
---|
1881 | if (login_window->priv->client != NULL) { |
---|
1882 | g_object_unref (login_window->priv->client); |
---|
1883 | } |
---|
1884 | |
---|
1885 | remove_sensitize_power_buttons_timeout (login_window); |
---|
1886 | /* clean up */ |
---|
1887 | gst_element_set_state (pipeline, GST_STATE_NULL); |
---|
1888 | gst_object_unref (pipeline); |
---|
1889 | |
---|
1890 | G_OBJECT_CLASS (gdm_greeter_login_window_parent_class)->finalize (object); |
---|
1891 | } |
---|
1892 | |
---|
1893 | GtkWidget * |
---|
1894 | gdm_greeter_login_window_new (gboolean is_local) |
---|
1895 | { |
---|
1896 | GObject *object; |
---|
1897 | |
---|
1898 | object = g_object_new (GDM_TYPE_GREETER_LOGIN_WINDOW, |
---|
1899 | "display-is-local", is_local, |
---|
1900 | "resizable", FALSE, |
---|
1901 | NULL); |
---|
1902 | |
---|
1903 | return GTK_WIDGET (object); |
---|
1904 | } |
---|