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 | * |
---|
5 | * This program is free software; you can redistribute it and/or modify |
---|
6 | * it under the terms of the GNU General Public License as published by |
---|
7 | * the Free Software Foundation; either version 2 of the License, or |
---|
8 | * (at your option) any later version. |
---|
9 | * |
---|
10 | * This program is distributed in the hope that it will be useful, |
---|
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
13 | * GNU General Public License for more details. |
---|
14 | * |
---|
15 | * You should have received a copy of the GNU General Public License |
---|
16 | * along with this program; if not, write to the Free Software |
---|
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
---|
18 | * |
---|
19 | */ |
---|
20 | |
---|
21 | #include "config.h" |
---|
22 | |
---|
23 | #include <math.h> |
---|
24 | #include <stdlib.h> |
---|
25 | #include <stdio.h> |
---|
26 | #include <sys/time.h> |
---|
27 | #include <unistd.h> |
---|
28 | #include <string.h> |
---|
29 | |
---|
30 | #include <glib.h> |
---|
31 | #include <glib/gi18n.h> |
---|
32 | #include <glib-object.h> |
---|
33 | #include <gtk/gtk.h> |
---|
34 | |
---|
35 | #include <gconf/gconf-client.h> |
---|
36 | |
---|
37 | #include "gdm-languages.h" |
---|
38 | #include "gdm-layouts.h" |
---|
39 | #include "gdm-greeter-panel.h" |
---|
40 | #include "gdm-clock-widget.h" |
---|
41 | #include "gdm-language-option-widget.h" |
---|
42 | #include "gdm-layout-option-widget.h" |
---|
43 | #include "gdm-session-option-widget.h" |
---|
44 | #include "gdm-timer.h" |
---|
45 | #include "gdm-profile.h" |
---|
46 | |
---|
47 | #include "na-tray.h" |
---|
48 | |
---|
49 | #define GDM_GREETER_PANEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_PANEL, GdmGreeterPanelPrivate)) |
---|
50 | |
---|
51 | struct GdmGreeterPanelPrivate |
---|
52 | { |
---|
53 | int monitor; |
---|
54 | GdkRectangle geometry; |
---|
55 | GtkWidget *hbox; |
---|
56 | GtkWidget *alignment; |
---|
57 | GtkWidget *option_hbox; |
---|
58 | GtkWidget *hostname_label; |
---|
59 | GtkWidget *clock; |
---|
60 | GtkWidget *language_option_widget; |
---|
61 | GtkWidget *layout_option_widget; |
---|
62 | GtkWidget *session_option_widget; |
---|
63 | |
---|
64 | GdmTimer *animation_timer; |
---|
65 | double progress; |
---|
66 | |
---|
67 | char *default_session_name; |
---|
68 | char *default_language_name; |
---|
69 | }; |
---|
70 | |
---|
71 | enum { |
---|
72 | PROP_0, |
---|
73 | PROP_MONITOR |
---|
74 | }; |
---|
75 | |
---|
76 | enum { |
---|
77 | LANGUAGE_SELECTED, |
---|
78 | LAYOUT_SELECTED, |
---|
79 | SESSION_SELECTED, |
---|
80 | DIALOG_HIDDEN, |
---|
81 | NUMBER_OF_SIGNALS |
---|
82 | }; |
---|
83 | |
---|
84 | static guint signals [NUMBER_OF_SIGNALS] = { 0, }; |
---|
85 | |
---|
86 | static void gdm_greeter_panel_class_init (GdmGreeterPanelClass *klass); |
---|
87 | static void gdm_greeter_panel_init (GdmGreeterPanel *greeter_panel); |
---|
88 | static void gdm_greeter_panel_finalize (GObject *object); |
---|
89 | |
---|
90 | G_DEFINE_TYPE (GdmGreeterPanel, gdm_greeter_panel, GTK_TYPE_WINDOW) |
---|
91 | |
---|
92 | static void |
---|
93 | gdm_greeter_panel_set_monitor (GdmGreeterPanel *panel, |
---|
94 | int monitor) |
---|
95 | { |
---|
96 | g_return_if_fail (GDM_IS_GREETER_PANEL (panel)); |
---|
97 | |
---|
98 | if (panel->priv->monitor == monitor) { |
---|
99 | return; |
---|
100 | } |
---|
101 | |
---|
102 | panel->priv->monitor = monitor; |
---|
103 | |
---|
104 | gtk_widget_queue_resize (GTK_WIDGET (panel)); |
---|
105 | |
---|
106 | g_object_notify (G_OBJECT (panel), "monitor"); |
---|
107 | } |
---|
108 | |
---|
109 | static void |
---|
110 | gdm_greeter_panel_set_property (GObject *object, |
---|
111 | guint prop_id, |
---|
112 | const GValue *value, |
---|
113 | GParamSpec *pspec) |
---|
114 | { |
---|
115 | GdmGreeterPanel *self; |
---|
116 | |
---|
117 | self = GDM_GREETER_PANEL (object); |
---|
118 | |
---|
119 | switch (prop_id) { |
---|
120 | case PROP_MONITOR: |
---|
121 | gdm_greeter_panel_set_monitor (self, g_value_get_int (value)); |
---|
122 | break; |
---|
123 | default: |
---|
124 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
---|
125 | break; |
---|
126 | } |
---|
127 | } |
---|
128 | |
---|
129 | static void |
---|
130 | gdm_greeter_panel_get_property (GObject *object, |
---|
131 | guint prop_id, |
---|
132 | GValue *value, |
---|
133 | GParamSpec *pspec) |
---|
134 | { |
---|
135 | GdmGreeterPanel *self; |
---|
136 | |
---|
137 | self = GDM_GREETER_PANEL (object); |
---|
138 | |
---|
139 | switch (prop_id) { |
---|
140 | case PROP_MONITOR: |
---|
141 | g_value_set_int (value, self->priv->monitor); |
---|
142 | break; |
---|
143 | default: |
---|
144 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
---|
145 | break; |
---|
146 | } |
---|
147 | } |
---|
148 | |
---|
149 | static GObject * |
---|
150 | gdm_greeter_panel_constructor (GType type, |
---|
151 | guint n_construct_properties, |
---|
152 | GObjectConstructParam *construct_properties) |
---|
153 | { |
---|
154 | GdmGreeterPanel *greeter_panel; |
---|
155 | |
---|
156 | gdm_profile_start (NULL); |
---|
157 | |
---|
158 | greeter_panel = GDM_GREETER_PANEL (G_OBJECT_CLASS (gdm_greeter_panel_parent_class)->constructor (type, |
---|
159 | n_construct_properties, |
---|
160 | construct_properties)); |
---|
161 | |
---|
162 | gdm_profile_end (NULL); |
---|
163 | |
---|
164 | return G_OBJECT (greeter_panel); |
---|
165 | } |
---|
166 | |
---|
167 | static void |
---|
168 | gdm_greeter_panel_dispose (GObject *object) |
---|
169 | { |
---|
170 | G_OBJECT_CLASS (gdm_greeter_panel_parent_class)->dispose (object); |
---|
171 | } |
---|
172 | |
---|
173 | /* copied from panel-toplevel.c */ |
---|
174 | static void |
---|
175 | gdm_greeter_panel_move_resize_window (GdmGreeterPanel *panel, |
---|
176 | gboolean move, |
---|
177 | gboolean resize) |
---|
178 | { |
---|
179 | GtkWidget *widget; |
---|
180 | |
---|
181 | widget = GTK_WIDGET (panel); |
---|
182 | |
---|
183 | g_assert (GTK_WIDGET_REALIZED (widget)); |
---|
184 | |
---|
185 | if (move && resize) { |
---|
186 | gdk_window_move_resize (widget->window, |
---|
187 | panel->priv->geometry.x, |
---|
188 | panel->priv->geometry.y, |
---|
189 | panel->priv->geometry.width, |
---|
190 | panel->priv->geometry.height); |
---|
191 | } else if (move) { |
---|
192 | gdk_window_move (widget->window, |
---|
193 | panel->priv->geometry.x, |
---|
194 | panel->priv->geometry.y); |
---|
195 | } else if (resize) { |
---|
196 | gdk_window_resize (widget->window, |
---|
197 | panel->priv->geometry.width, |
---|
198 | panel->priv->geometry.height); |
---|
199 | } |
---|
200 | } |
---|
201 | |
---|
202 | static void |
---|
203 | on_screen_size_changed (GdkScreen *screen, |
---|
204 | GdmGreeterPanel *panel) |
---|
205 | { |
---|
206 | gtk_widget_queue_resize (GTK_WIDGET (panel)); |
---|
207 | } |
---|
208 | |
---|
209 | static void |
---|
210 | gdm_greeter_panel_real_realize (GtkWidget *widget) |
---|
211 | { |
---|
212 | if (GTK_WIDGET_CLASS (gdm_greeter_panel_parent_class)->realize) { |
---|
213 | GTK_WIDGET_CLASS (gdm_greeter_panel_parent_class)->realize (widget); |
---|
214 | } |
---|
215 | |
---|
216 | gdm_greeter_panel_move_resize_window (GDM_GREETER_PANEL (widget), TRUE, TRUE); |
---|
217 | |
---|
218 | g_signal_connect (gtk_window_get_screen (GTK_WINDOW (widget)), |
---|
219 | "size_changed", |
---|
220 | G_CALLBACK (on_screen_size_changed), |
---|
221 | widget); |
---|
222 | } |
---|
223 | |
---|
224 | static void |
---|
225 | gdm_greeter_panel_real_unrealize (GtkWidget *widget) |
---|
226 | { |
---|
227 | g_signal_handlers_disconnect_by_func (gtk_window_get_screen (GTK_WINDOW (widget)), |
---|
228 | on_screen_size_changed, |
---|
229 | widget); |
---|
230 | |
---|
231 | if (GTK_WIDGET_CLASS (gdm_greeter_panel_parent_class)->unrealize) { |
---|
232 | GTK_WIDGET_CLASS (gdm_greeter_panel_parent_class)->unrealize (widget); |
---|
233 | } |
---|
234 | } |
---|
235 | |
---|
236 | static void |
---|
237 | set_struts (GdmGreeterPanel *panel, |
---|
238 | int x, |
---|
239 | int y, |
---|
240 | int width, |
---|
241 | int height) |
---|
242 | { |
---|
243 | gulong data[12] = { 0, }; |
---|
244 | int screen_height; |
---|
245 | |
---|
246 | /* _NET_WM_STRUT_PARTIAL: CARDINAL[12]/32 |
---|
247 | * |
---|
248 | * 0: left 1: right 2: top 3: bottom |
---|
249 | * 4: left_start_y 5: left_end_y 6: right_start_y 7: right_end_y |
---|
250 | * 8: top_start_x 9: top_end_x 10: bottom_start_x 11: bottom_end_x |
---|
251 | * |
---|
252 | * Note: In xinerama use struts relative to combined screen dimensions, |
---|
253 | * not just the current monitor. |
---|
254 | */ |
---|
255 | |
---|
256 | /* for bottom panel */ |
---|
257 | screen_height = gdk_screen_get_height (gtk_window_get_screen (GTK_WINDOW (panel))); |
---|
258 | |
---|
259 | /* bottom */ |
---|
260 | data[3] = screen_height - panel->priv->geometry.y - panel->priv->geometry.height + height; |
---|
261 | /* bottom_start_x */ |
---|
262 | data[10] = x; |
---|
263 | /* bottom_end_x */ |
---|
264 | data[11] = x + width; |
---|
265 | |
---|
266 | #if 0 |
---|
267 | g_debug ("Setting strut: bottom=%lu bottom_start_x=%lu bottom_end_x=%lu", data[3], data[10], data[11]); |
---|
268 | #endif |
---|
269 | |
---|
270 | gdk_error_trap_push (); |
---|
271 | |
---|
272 | gdk_property_change (GTK_WIDGET (panel)->window, |
---|
273 | gdk_atom_intern ("_NET_WM_STRUT_PARTIAL", FALSE), |
---|
274 | gdk_atom_intern ("CARDINAL", FALSE), |
---|
275 | 32, |
---|
276 | GDK_PROP_MODE_REPLACE, |
---|
277 | (guchar *) &data, |
---|
278 | 12); |
---|
279 | |
---|
280 | gdk_property_change (GTK_WIDGET (panel)->window, |
---|
281 | gdk_atom_intern ("_NET_WM_STRUT", FALSE), |
---|
282 | gdk_atom_intern ("CARDINAL", FALSE), |
---|
283 | 32, |
---|
284 | GDK_PROP_MODE_REPLACE, |
---|
285 | (guchar *) &data, |
---|
286 | 4); |
---|
287 | |
---|
288 | gdk_error_trap_pop (); |
---|
289 | } |
---|
290 | |
---|
291 | static void |
---|
292 | update_struts (GdmGreeterPanel *panel) |
---|
293 | { |
---|
294 | GdkRectangle geometry; |
---|
295 | |
---|
296 | gdk_screen_get_monitor_geometry (GTK_WINDOW (panel)->screen, |
---|
297 | panel->priv->monitor, |
---|
298 | &geometry); |
---|
299 | |
---|
300 | /* FIXME: assumes only one panel */ |
---|
301 | set_struts (panel, |
---|
302 | panel->priv->geometry.x, |
---|
303 | panel->priv->geometry.y, |
---|
304 | panel->priv->geometry.width, |
---|
305 | panel->priv->geometry.height); |
---|
306 | } |
---|
307 | |
---|
308 | static void |
---|
309 | update_geometry (GdmGreeterPanel *panel, |
---|
310 | GtkRequisition *requisition) |
---|
311 | { |
---|
312 | GdkRectangle geometry; |
---|
313 | |
---|
314 | gdk_screen_get_monitor_geometry (GTK_WINDOW (panel)->screen, |
---|
315 | panel->priv->monitor, |
---|
316 | &geometry); |
---|
317 | |
---|
318 | panel->priv->geometry.width = geometry.width; |
---|
319 | panel->priv->geometry.height = requisition->height + 2 * GTK_CONTAINER (panel)->border_width; |
---|
320 | |
---|
321 | panel->priv->geometry.x = geometry.x; |
---|
322 | panel->priv->geometry.y = geometry.y + geometry.height - panel->priv->geometry.height + (1.0 - panel->priv->progress) * panel->priv->geometry.height; |
---|
323 | |
---|
324 | #if 0 |
---|
325 | g_debug ("Setting geometry x:%d y:%d w:%d h:%d", |
---|
326 | panel->priv->geometry.x, |
---|
327 | panel->priv->geometry.y, |
---|
328 | panel->priv->geometry.width, |
---|
329 | panel->priv->geometry.height); |
---|
330 | #endif |
---|
331 | |
---|
332 | update_struts (panel); |
---|
333 | } |
---|
334 | |
---|
335 | static void |
---|
336 | gdm_greeter_panel_real_size_request (GtkWidget *widget, |
---|
337 | GtkRequisition *requisition) |
---|
338 | { |
---|
339 | GdmGreeterPanel *panel; |
---|
340 | GtkBin *bin; |
---|
341 | GdkRectangle old_geometry; |
---|
342 | int position_changed = FALSE; |
---|
343 | int size_changed = FALSE; |
---|
344 | |
---|
345 | panel = GDM_GREETER_PANEL (widget); |
---|
346 | bin = GTK_BIN (widget); |
---|
347 | |
---|
348 | if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) { |
---|
349 | gtk_widget_size_request (bin->child, requisition); |
---|
350 | } |
---|
351 | |
---|
352 | old_geometry = panel->priv->geometry; |
---|
353 | |
---|
354 | update_geometry (panel, requisition); |
---|
355 | |
---|
356 | requisition->width = panel->priv->geometry.width; |
---|
357 | requisition->height = panel->priv->geometry.height; |
---|
358 | |
---|
359 | if (! GTK_WIDGET_REALIZED (widget)) { |
---|
360 | return; |
---|
361 | } |
---|
362 | |
---|
363 | if (old_geometry.width != panel->priv->geometry.width || |
---|
364 | old_geometry.height != panel->priv->geometry.height) { |
---|
365 | size_changed = TRUE; |
---|
366 | } |
---|
367 | |
---|
368 | if (old_geometry.x != panel->priv->geometry.x || |
---|
369 | old_geometry.y != panel->priv->geometry.y) { |
---|
370 | position_changed = TRUE; |
---|
371 | } |
---|
372 | |
---|
373 | gdm_greeter_panel_move_resize_window (panel, position_changed, size_changed); |
---|
374 | } |
---|
375 | static void |
---|
376 | gdm_greeter_panel_real_show (GtkWidget *widget) |
---|
377 | { |
---|
378 | GdmGreeterPanel *panel; |
---|
379 | GtkSettings *settings; |
---|
380 | gboolean animations_are_enabled; |
---|
381 | |
---|
382 | settings = gtk_settings_get_for_screen (gtk_widget_get_screen (widget)); |
---|
383 | g_object_get (settings, "gtk-enable-animations", &animations_are_enabled, NULL); |
---|
384 | |
---|
385 | panel = GDM_GREETER_PANEL (widget); |
---|
386 | |
---|
387 | if (animations_are_enabled) { |
---|
388 | gdm_timer_start (panel->priv->animation_timer, 1.0); |
---|
389 | } else { |
---|
390 | panel->priv->progress = 1.0; |
---|
391 | } |
---|
392 | |
---|
393 | GTK_WIDGET_CLASS (gdm_greeter_panel_parent_class)->show (widget); |
---|
394 | } |
---|
395 | |
---|
396 | static void |
---|
397 | gdm_greeter_panel_real_hide (GtkWidget *widget) |
---|
398 | { |
---|
399 | GdmGreeterPanel *panel; |
---|
400 | |
---|
401 | panel = GDM_GREETER_PANEL (widget); |
---|
402 | |
---|
403 | gdm_timer_stop (panel->priv->animation_timer); |
---|
404 | panel->priv->progress = 0.0; |
---|
405 | |
---|
406 | GTK_WIDGET_CLASS (gdm_greeter_panel_parent_class)->hide (widget); |
---|
407 | } |
---|
408 | |
---|
409 | static void |
---|
410 | gdm_greeter_panel_class_init (GdmGreeterPanelClass *klass) |
---|
411 | { |
---|
412 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |
---|
413 | GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); |
---|
414 | |
---|
415 | object_class->get_property = gdm_greeter_panel_get_property; |
---|
416 | object_class->set_property = gdm_greeter_panel_set_property; |
---|
417 | object_class->constructor = gdm_greeter_panel_constructor; |
---|
418 | object_class->dispose = gdm_greeter_panel_dispose; |
---|
419 | object_class->finalize = gdm_greeter_panel_finalize; |
---|
420 | |
---|
421 | widget_class->realize = gdm_greeter_panel_real_realize; |
---|
422 | widget_class->unrealize = gdm_greeter_panel_real_unrealize; |
---|
423 | widget_class->size_request = gdm_greeter_panel_real_size_request; |
---|
424 | widget_class->show = gdm_greeter_panel_real_show; |
---|
425 | widget_class->hide = gdm_greeter_panel_real_hide; |
---|
426 | |
---|
427 | signals[LANGUAGE_SELECTED] = |
---|
428 | g_signal_new ("language-selected", |
---|
429 | G_TYPE_FROM_CLASS (object_class), |
---|
430 | G_SIGNAL_RUN_LAST, |
---|
431 | G_STRUCT_OFFSET (GdmGreeterPanelClass, language_selected), |
---|
432 | NULL, |
---|
433 | NULL, |
---|
434 | g_cclosure_marshal_VOID__STRING, |
---|
435 | G_TYPE_NONE, |
---|
436 | 1, G_TYPE_STRING); |
---|
437 | |
---|
438 | signals[LAYOUT_SELECTED] = |
---|
439 | g_signal_new ("layout-selected", |
---|
440 | G_TYPE_FROM_CLASS (object_class), |
---|
441 | G_SIGNAL_RUN_LAST, |
---|
442 | G_STRUCT_OFFSET (GdmGreeterPanelClass, layout_selected), |
---|
443 | NULL, |
---|
444 | NULL, |
---|
445 | g_cclosure_marshal_VOID__STRING, |
---|
446 | G_TYPE_NONE, |
---|
447 | 1, G_TYPE_STRING); |
---|
448 | |
---|
449 | signals[SESSION_SELECTED] = |
---|
450 | g_signal_new ("session-selected", |
---|
451 | G_TYPE_FROM_CLASS (object_class), |
---|
452 | G_SIGNAL_RUN_LAST, |
---|
453 | G_STRUCT_OFFSET (GdmGreeterPanelClass, session_selected), |
---|
454 | NULL, |
---|
455 | NULL, |
---|
456 | g_cclosure_marshal_VOID__STRING, |
---|
457 | G_TYPE_NONE, |
---|
458 | 1, G_TYPE_STRING); |
---|
459 | |
---|
460 | signals[DIALOG_HIDDEN] = |
---|
461 | g_signal_new ("dialog-hidden", |
---|
462 | G_TYPE_FROM_CLASS (object_class), |
---|
463 | G_SIGNAL_RUN_LAST, |
---|
464 | G_STRUCT_OFFSET (GdmGreeterPanelClass, dialog_hidden), |
---|
465 | NULL, |
---|
466 | NULL, |
---|
467 | g_cclosure_marshal_VOID__VOID, |
---|
468 | G_TYPE_NONE, |
---|
469 | 0); |
---|
470 | |
---|
471 | g_object_class_install_property (object_class, |
---|
472 | PROP_MONITOR, |
---|
473 | g_param_spec_int ("monitor", |
---|
474 | "Xinerama monitor", |
---|
475 | "The monitor (in terms of Xinerama) which the window is on", |
---|
476 | 0, |
---|
477 | G_MAXINT, |
---|
478 | 0, |
---|
479 | G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); |
---|
480 | |
---|
481 | g_type_class_add_private (klass, sizeof (GdmGreeterPanelPrivate)); |
---|
482 | } |
---|
483 | |
---|
484 | static void |
---|
485 | on_language_activated (GdmLanguageOptionWidget *widget, |
---|
486 | GdmGreeterPanel *panel) |
---|
487 | { |
---|
488 | |
---|
489 | char *language; |
---|
490 | |
---|
491 | language = gdm_language_option_widget_get_current_language_name (GDM_LANGUAGE_OPTION_WIDGET (panel->priv->language_option_widget)); |
---|
492 | |
---|
493 | if (language == NULL) { |
---|
494 | return; |
---|
495 | } |
---|
496 | |
---|
497 | g_signal_emit (panel, signals[LANGUAGE_SELECTED], 0, language); |
---|
498 | |
---|
499 | g_free (language); |
---|
500 | } |
---|
501 | |
---|
502 | static void |
---|
503 | on_language_dialog_hidden(GdmLanguageOptionWidget *widget, |
---|
504 | GdmGreeterPanel *panel) |
---|
505 | { |
---|
506 | |
---|
507 | g_signal_emit (panel, signals[DIALOG_HIDDEN], 0); |
---|
508 | } |
---|
509 | |
---|
510 | static void |
---|
511 | on_layout_activated (GdmLayoutOptionWidget *widget, |
---|
512 | GdmGreeterPanel *panel) |
---|
513 | { |
---|
514 | |
---|
515 | char *layout; |
---|
516 | |
---|
517 | layout = gdm_layout_option_widget_get_current_layout_name (GDM_LAYOUT_OPTION_WIDGET (panel->priv->layout_option_widget)); |
---|
518 | |
---|
519 | if (layout == NULL) { |
---|
520 | return; |
---|
521 | } |
---|
522 | |
---|
523 | g_debug ("GdmGreeterPanel: activating selected layout %s", layout); |
---|
524 | gdm_layout_activate (layout); |
---|
525 | |
---|
526 | g_signal_emit (panel, signals[LAYOUT_SELECTED], 0, layout); |
---|
527 | |
---|
528 | g_free (layout); |
---|
529 | } |
---|
530 | |
---|
531 | static void |
---|
532 | on_layout_dialog_hidden (GdmLayoutOptionWidget *widget, |
---|
533 | GdmGreeterPanel *panel) |
---|
534 | { |
---|
535 | |
---|
536 | g_signal_emit (panel, signals[DIALOG_HIDDEN], 0); |
---|
537 | } |
---|
538 | |
---|
539 | static void |
---|
540 | on_session_activated (GdmSessionOptionWidget *widget, |
---|
541 | GdmGreeterPanel *panel) |
---|
542 | { |
---|
543 | |
---|
544 | char *session; |
---|
545 | |
---|
546 | session = gdm_session_option_widget_get_current_session (GDM_SESSION_OPTION_WIDGET (panel->priv->session_option_widget)); |
---|
547 | |
---|
548 | if (session == NULL) { |
---|
549 | return; |
---|
550 | } |
---|
551 | |
---|
552 | g_signal_emit (panel, signals[SESSION_SELECTED], 0, session); |
---|
553 | |
---|
554 | g_free (session); |
---|
555 | } |
---|
556 | |
---|
557 | static void |
---|
558 | on_animation_tick (GdmGreeterPanel *panel, |
---|
559 | double progress) |
---|
560 | { |
---|
561 | panel->priv->progress = progress * log ((G_E - 1.0) * progress + 1.0); |
---|
562 | |
---|
563 | gtk_widget_queue_resize (GTK_WIDGET (panel)); |
---|
564 | } |
---|
565 | |
---|
566 | static void |
---|
567 | gdm_greeter_panel_init (GdmGreeterPanel *panel) |
---|
568 | { |
---|
569 | NaTray *tray; |
---|
570 | GtkWidget *spacer; |
---|
571 | |
---|
572 | gdm_profile_start (NULL); |
---|
573 | |
---|
574 | panel->priv = GDM_GREETER_PANEL_GET_PRIVATE (panel); |
---|
575 | |
---|
576 | GTK_WIDGET_SET_FLAGS (GTK_WIDGET (panel), GTK_CAN_FOCUS); |
---|
577 | |
---|
578 | panel->priv->geometry.x = -1; |
---|
579 | panel->priv->geometry.y = -1; |
---|
580 | panel->priv->geometry.width = -1; |
---|
581 | panel->priv->geometry.height = -1; |
---|
582 | |
---|
583 | gtk_window_set_title (GTK_WINDOW (panel), _("Panel")); |
---|
584 | gtk_window_set_decorated (GTK_WINDOW (panel), FALSE); |
---|
585 | |
---|
586 | gtk_window_set_keep_above (GTK_WINDOW (panel), TRUE); |
---|
587 | gtk_window_set_type_hint (GTK_WINDOW (panel), GDK_WINDOW_TYPE_HINT_DOCK); |
---|
588 | gtk_window_set_opacity (GTK_WINDOW (panel), 0.85); |
---|
589 | |
---|
590 | panel->priv->hbox = gtk_hbox_new (FALSE, 12); |
---|
591 | gtk_container_set_border_width (GTK_CONTAINER (panel->priv->hbox), 0); |
---|
592 | gtk_widget_show (panel->priv->hbox); |
---|
593 | gtk_container_add (GTK_CONTAINER (panel), panel->priv->hbox); |
---|
594 | |
---|
595 | panel->priv->alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0); |
---|
596 | gtk_box_pack_start (GTK_BOX (panel->priv->hbox), panel->priv->alignment, TRUE, TRUE, 0); |
---|
597 | gtk_widget_show (panel->priv->alignment); |
---|
598 | |
---|
599 | panel->priv->option_hbox = gtk_hbox_new (FALSE, 12); |
---|
600 | gtk_widget_show (panel->priv->option_hbox); |
---|
601 | gtk_container_add (GTK_CONTAINER (panel->priv->alignment), panel->priv->option_hbox); |
---|
602 | |
---|
603 | spacer = gtk_label_new (""); |
---|
604 | gtk_box_pack_start (GTK_BOX (panel->priv->option_hbox), spacer, TRUE, TRUE, 6); |
---|
605 | gtk_widget_show (spacer); |
---|
606 | |
---|
607 | gdm_profile_start ("creating option widget"); |
---|
608 | panel->priv->language_option_widget = gdm_language_option_widget_new (); |
---|
609 | g_signal_connect (G_OBJECT (panel->priv->language_option_widget), |
---|
610 | "language-activated", |
---|
611 | G_CALLBACK (on_language_activated), panel); |
---|
612 | g_signal_connect (G_OBJECT (panel->priv->language_option_widget), |
---|
613 | "dialog-hidden", |
---|
614 | G_CALLBACK (on_language_dialog_hidden), panel); |
---|
615 | gtk_box_pack_start (GTK_BOX (panel->priv->option_hbox), panel->priv->language_option_widget, FALSE, FALSE, 6); |
---|
616 | gdm_profile_end ("creating option widget"); |
---|
617 | |
---|
618 | panel->priv->layout_option_widget = gdm_layout_option_widget_new (); |
---|
619 | g_signal_connect (G_OBJECT (panel->priv->layout_option_widget), |
---|
620 | "layout-activated", |
---|
621 | G_CALLBACK (on_layout_activated), panel); |
---|
622 | g_signal_connect (G_OBJECT (panel->priv->layout_option_widget), |
---|
623 | "dialog-hidden", |
---|
624 | G_CALLBACK (on_layout_dialog_hidden), panel); |
---|
625 | gtk_box_pack_start (GTK_BOX (panel->priv->option_hbox), panel->priv->layout_option_widget, FALSE, FALSE, 6); |
---|
626 | |
---|
627 | panel->priv->session_option_widget = gdm_session_option_widget_new (); |
---|
628 | g_signal_connect (G_OBJECT (panel->priv->session_option_widget), |
---|
629 | "session-activated", |
---|
630 | G_CALLBACK (on_session_activated), panel); |
---|
631 | gtk_box_pack_start (GTK_BOX (panel->priv->option_hbox), panel->priv->session_option_widget, FALSE, FALSE, 6); |
---|
632 | |
---|
633 | spacer = gtk_label_new (""); |
---|
634 | gtk_box_pack_start (GTK_BOX (panel->priv->option_hbox), spacer, TRUE, TRUE, 6); |
---|
635 | gtk_widget_show (spacer); |
---|
636 | |
---|
637 | /* FIXME: we should only show hostname on panel when connected |
---|
638 | to a remote host */ |
---|
639 | if (0) { |
---|
640 | panel->priv->hostname_label = gtk_label_new (g_get_host_name ()); |
---|
641 | gtk_box_pack_start (GTK_BOX (panel->priv->hbox), panel->priv->hostname_label, FALSE, FALSE, 6); |
---|
642 | gtk_widget_show (panel->priv->hostname_label); |
---|
643 | } |
---|
644 | |
---|
645 | panel->priv->clock = gdm_clock_widget_new (); |
---|
646 | gtk_box_pack_end (GTK_BOX (panel->priv->hbox), |
---|
647 | GTK_WIDGET (panel->priv->clock), FALSE, FALSE, 6); |
---|
648 | gtk_widget_show (panel->priv->clock); |
---|
649 | |
---|
650 | tray = na_tray_new_for_screen (gtk_window_get_screen (GTK_WINDOW (panel)), |
---|
651 | GTK_ORIENTATION_HORIZONTAL); |
---|
652 | gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (tray), FALSE, FALSE, 6); |
---|
653 | gtk_widget_show (GTK_WIDGET (tray)); |
---|
654 | |
---|
655 | gdm_greeter_panel_hide_user_options (panel); |
---|
656 | |
---|
657 | panel->priv->progress = 0.0; |
---|
658 | panel->priv->animation_timer = gdm_timer_new (); |
---|
659 | g_signal_connect_swapped (panel->priv->animation_timer, |
---|
660 | "tick", |
---|
661 | G_CALLBACK (on_animation_tick), |
---|
662 | panel); |
---|
663 | |
---|
664 | gdm_profile_end (NULL); |
---|
665 | } |
---|
666 | |
---|
667 | static void |
---|
668 | gdm_greeter_panel_finalize (GObject *object) |
---|
669 | { |
---|
670 | GdmGreeterPanel *greeter_panel; |
---|
671 | |
---|
672 | g_return_if_fail (object != NULL); |
---|
673 | g_return_if_fail (GDM_IS_GREETER_PANEL (object)); |
---|
674 | |
---|
675 | greeter_panel = GDM_GREETER_PANEL (object); |
---|
676 | |
---|
677 | g_return_if_fail (greeter_panel->priv != NULL); |
---|
678 | |
---|
679 | g_signal_handlers_disconnect_by_func (object, on_animation_tick, greeter_panel); |
---|
680 | g_object_unref (greeter_panel->priv->animation_timer); |
---|
681 | |
---|
682 | G_OBJECT_CLASS (gdm_greeter_panel_parent_class)->finalize (object); |
---|
683 | } |
---|
684 | |
---|
685 | GtkWidget * |
---|
686 | gdm_greeter_panel_new (GdkScreen *screen, |
---|
687 | int monitor) |
---|
688 | { |
---|
689 | GObject *object; |
---|
690 | |
---|
691 | object = g_object_new (GDM_TYPE_GREETER_PANEL, |
---|
692 | "screen", screen, |
---|
693 | "monitor", monitor, |
---|
694 | NULL); |
---|
695 | |
---|
696 | return GTK_WIDGET (object); |
---|
697 | } |
---|
698 | |
---|
699 | void |
---|
700 | gdm_greeter_panel_show_user_options (GdmGreeterPanel *panel) |
---|
701 | { |
---|
702 | gtk_widget_show (panel->priv->session_option_widget); |
---|
703 | gtk_widget_show (panel->priv->language_option_widget); |
---|
704 | gtk_widget_show (panel->priv->layout_option_widget); |
---|
705 | } |
---|
706 | |
---|
707 | void |
---|
708 | gdm_greeter_panel_hide_user_options (GdmGreeterPanel *panel) |
---|
709 | { |
---|
710 | gtk_widget_hide (panel->priv->session_option_widget); |
---|
711 | gtk_widget_hide (panel->priv->language_option_widget); |
---|
712 | gtk_widget_hide (panel->priv->layout_option_widget); |
---|
713 | |
---|
714 | g_debug ("GdmGreeterPanel: activating default layout"); |
---|
715 | gdm_layout_activate (NULL); |
---|
716 | } |
---|
717 | |
---|
718 | void |
---|
719 | gdm_greeter_panel_reset (GdmGreeterPanel *panel) |
---|
720 | { |
---|
721 | gdm_greeter_panel_set_default_language_name (panel, NULL); |
---|
722 | gdm_greeter_panel_set_default_layout_name (panel, NULL); |
---|
723 | gdm_greeter_panel_set_default_session_name (panel, NULL); |
---|
724 | gdm_greeter_panel_hide_user_options (panel); |
---|
725 | } |
---|
726 | |
---|
727 | void |
---|
728 | gdm_greeter_panel_set_default_language_name (GdmGreeterPanel *panel, |
---|
729 | const char *language_name) |
---|
730 | { |
---|
731 | char *normalized_language_name; |
---|
732 | |
---|
733 | g_return_if_fail (GDM_IS_GREETER_PANEL (panel)); |
---|
734 | |
---|
735 | if (language_name != NULL) { |
---|
736 | normalized_language_name = gdm_normalize_language_name (language_name); |
---|
737 | } else { |
---|
738 | normalized_language_name = NULL; |
---|
739 | } |
---|
740 | |
---|
741 | if (normalized_language_name != NULL && |
---|
742 | !gdm_option_widget_lookup_item (GDM_OPTION_WIDGET (panel->priv->language_option_widget), |
---|
743 | normalized_language_name, NULL, NULL, NULL)) { |
---|
744 | gdm_recent_option_widget_add_item (GDM_RECENT_OPTION_WIDGET (panel->priv->language_option_widget), |
---|
745 | normalized_language_name); |
---|
746 | } |
---|
747 | |
---|
748 | gdm_option_widget_set_default_item (GDM_OPTION_WIDGET (panel->priv->language_option_widget), |
---|
749 | normalized_language_name); |
---|
750 | |
---|
751 | g_free (normalized_language_name); |
---|
752 | } |
---|
753 | |
---|
754 | void |
---|
755 | gdm_greeter_panel_set_default_layout_name (GdmGreeterPanel *panel, |
---|
756 | const char *layout_name) |
---|
757 | { |
---|
758 | #ifdef HAVE_LIBXKLAVIER |
---|
759 | g_return_if_fail (GDM_IS_GREETER_PANEL (panel)); |
---|
760 | |
---|
761 | if (layout_name != NULL && |
---|
762 | !gdm_layout_is_valid (layout_name)) { |
---|
763 | const char *default_layout; |
---|
764 | |
---|
765 | default_layout = gdm_layout_get_default_layout (); |
---|
766 | |
---|
767 | g_debug ("GdmGreeterPanel: default layout %s is invalid, resetting to: %s", |
---|
768 | layout_name, default_layout ? default_layout : "null"); |
---|
769 | |
---|
770 | g_signal_emit (panel, signals[LAYOUT_SELECTED], 0, default_layout); |
---|
771 | |
---|
772 | layout_name = default_layout; |
---|
773 | } |
---|
774 | |
---|
775 | if (layout_name != NULL && |
---|
776 | !gdm_option_widget_lookup_item (GDM_OPTION_WIDGET (panel->priv->layout_option_widget), |
---|
777 | layout_name, NULL, NULL, NULL)) { |
---|
778 | gdm_recent_option_widget_add_item (GDM_RECENT_OPTION_WIDGET (panel->priv->layout_option_widget), |
---|
779 | layout_name); |
---|
780 | } |
---|
781 | |
---|
782 | gdm_option_widget_set_default_item (GDM_OPTION_WIDGET (panel->priv->layout_option_widget), |
---|
783 | layout_name); |
---|
784 | |
---|
785 | g_debug ("GdmGreeterPanel: activating layout: %s", layout_name); |
---|
786 | gdm_layout_activate (layout_name); |
---|
787 | #endif |
---|
788 | } |
---|
789 | |
---|
790 | void |
---|
791 | gdm_greeter_panel_set_default_session_name (GdmGreeterPanel *panel, |
---|
792 | const char *session_name) |
---|
793 | { |
---|
794 | g_return_if_fail (GDM_IS_GREETER_PANEL (panel)); |
---|
795 | |
---|
796 | if (session_name != NULL && |
---|
797 | !gdm_option_widget_lookup_item (GDM_OPTION_WIDGET (panel->priv->session_option_widget), |
---|
798 | session_name, NULL, NULL, NULL)) { |
---|
799 | g_warning ("Default session is not available"); |
---|
800 | return; |
---|
801 | } |
---|
802 | |
---|
803 | gdm_option_widget_set_default_item (GDM_OPTION_WIDGET (panel->priv->session_option_widget), |
---|
804 | session_name); |
---|
805 | } |
---|