[134] | 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 | } |
---|