summaryrefslogtreecommitdiff
path: root/src/gs-window-x11.c.orig
diff options
context:
space:
mode:
Diffstat (limited to 'src/gs-window-x11.c.orig')
-rw-r--r--src/gs-window-x11.c.orig2647
1 files changed, 0 insertions, 2647 deletions
diff --git a/src/gs-window-x11.c.orig b/src/gs-window-x11.c.orig
deleted file mode 100644
index f7c3c70..0000000
--- a/src/gs-window-x11.c.orig
+++ /dev/null
@@ -1,2647 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2004-2008 William Jon McCann <[email protected]>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Authors: William Jon McCann <[email protected]>
- *
- */
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include <string.h>
-
-#include <gdk/gdkx.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-
-#include "gs-window.h"
-#include "gs-marshal.h"
-#include "subprocs.h"
-#include "gs-debug.h"
-
-#ifdef HAVE_SHAPE_EXT
-#include <X11/extensions/shape.h>
-#endif
-
-static void gs_window_class_init (GSWindowClass *klass);
-static void gs_window_init (GSWindow *window);
-static void gs_window_finalize (GObject *object);
-
-static gboolean popup_dialog_idle (GSWindow *window);
-static void gs_window_dialog_finish (GSWindow *window);
-static void remove_command_watches (GSWindow *window);
-
-enum
-{
- DIALOG_RESPONSE_CANCEL,
- DIALOG_RESPONSE_OK
-};
-
-#define MAX_QUEUED_EVENTS 16
-#define INFO_BAR_SECONDS 30
-
-#define GS_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_WINDOW, GSWindowPrivate))
-
-struct GSWindowPrivate
-{
- int monitor;
-
- GdkRectangle geometry;
- guint obscured : 1;
- guint dialog_up : 1;
-
- guint lock_enabled : 1;
- guint user_switch_enabled : 1;
- guint logout_enabled : 1;
- guint keyboard_enabled : 1;
-
- guint64 logout_timeout;
- char *logout_command;
- char *keyboard_command;
- char *status_message;
-
- GtkWidget *vbox;
- GtkWidget *drawing_area;
- GtkWidget *lock_box;
- GtkWidget *lock_socket;
- GtkWidget *keyboard_socket;
- GtkWidget *info_bar;
- GtkWidget *info_content;
-
- GdkPixmap *background_pixmap;
-
- guint popup_dialog_idle_id;
-
- guint dialog_map_signal_id;
- guint dialog_unmap_signal_id;
- guint dialog_response_signal_id;
-
- guint watchdog_timer_id;
- guint info_bar_timer_id;
-
- gint lock_pid;
- gint lock_watch_id;
- gint dialog_response;
- gboolean dialog_quit_requested;
- gboolean dialog_shake_in_progress;
-
- gint keyboard_pid;
- gint keyboard_watch_id;
-
- GList *key_events;
-
- gdouble last_x;
- gdouble last_y;
-
- GTimer *timer;
-
-#ifdef HAVE_SHAPE_EXT
- int shape_event_base;
-#endif
-};
-
-enum
-{
- ACTIVITY,
- DEACTIVATED,
- LAST_SIGNAL
-};
-
-enum
-{
- PROP_0,
- PROP_OBSCURED,
- PROP_DIALOG_UP,
- PROP_LOCK_ENABLED,
- PROP_LOGOUT_ENABLED,
- PROP_KEYBOARD_ENABLED,
- PROP_KEYBOARD_COMMAND,
- PROP_LOGOUT_COMMAND,
- PROP_LOGOUT_TIMEOUT,
- PROP_MONITOR,
- PROP_STATUS_MESSAGE
-};
-
-static guint signals [LAST_SIGNAL] = { 0, };
-
-G_DEFINE_TYPE (GSWindow, gs_window, GTK_TYPE_WINDOW)
-
-static void
-set_invisible_cursor (GdkWindow *window,
- gboolean invisible)
-{
- GdkBitmap *empty_bitmap;
- GdkCursor *cursor = NULL;
- GdkColor useless;
- char invisible_cursor_bits [] = { 0x0 };
-
- if (invisible)
- {
- useless.red = useless.green = useless.blue = 0;
- useless.pixel = 0;
-
- empty_bitmap = gdk_bitmap_create_from_data (window,
- invisible_cursor_bits,
- 1, 1);
-
- cursor = gdk_cursor_new_from_pixmap (empty_bitmap,
- empty_bitmap,
- &useless,
- &useless, 0, 0);
-
- g_object_unref (empty_bitmap);
- }
-
- gdk_window_set_cursor (window, cursor);
-
- if (cursor)
- {
- gdk_cursor_unref (cursor);
- }
-}
-
-/* derived from tomboy */
-static void
-gs_window_override_user_time (GSWindow *window)
-{
- guint32 ev_time = gtk_get_current_event_time ();
-
- if (ev_time == 0)
- {
- gint ev_mask = gtk_widget_get_events (GTK_WIDGET (window));
- if (!(ev_mask & GDK_PROPERTY_CHANGE_MASK))
- {
- gtk_widget_add_events (GTK_WIDGET (window),
- GDK_PROPERTY_CHANGE_MASK);
- }
-
- /*
- * NOTE: Last resort for D-BUS or other non-interactive
- * openings. Causes roundtrip to server. Lame.
- */
- ev_time = gdk_x11_get_server_time (GTK_WIDGET (window)->window);
- }
-
- gdk_x11_window_set_user_time (GTK_WIDGET (window)->window, ev_time);
-}
-
-static void
-force_no_pixmap_background (GtkWidget *widget)
-{
- static gboolean first_time = TRUE;
-
- if (first_time)
- {
- gtk_rc_parse_string ("\n"
- " style \"gs-theme-engine-style\"\n"
- " {\n"
- " bg_pixmap[NORMAL] = \"<none>\"\n"
- " bg_pixmap[INSENSITIVE] = \"<none>\"\n"
- " bg_pixmap[ACTIVE] = \"<none>\"\n"
- " bg_pixmap[PRELIGHT] = \"<none>\"\n"
- " bg[NORMAL] = { 0.0, 0.0, 0.0 }\n"
- " bg[INSENSITIVE] = { 0.0, 0.0, 0.0 }\n"
- " bg[ACTIVE] = { 0.0, 0.0, 0.0 }\n"
- " bg[PRELIGHT] = { 0.0, 0.0, 0.0 }\n"
- " }\n"
- " widget \"gs-window-drawing-area*\" style : highest \"gs-theme-engine-style\"\n"
- "\n");
- first_time = FALSE;
- }
-
- gtk_widget_set_name (widget, "gs-window-drawing-area");
-}
-
-static void
-clear_children (Window window)
-{
- Window root;
- Window parent;
- Window *children;
- unsigned int n_children;
- int status;
-
- children = NULL;
- status = XQueryTree (GDK_DISPLAY (), window, &root, &parent, &children, &n_children);
-
- if (status == 0)
- {
- if (children)
- {
- XFree (children);
- }
- return;
- }
-
- if (children)
- {
- while (n_children)
- {
- Window child;
-
- child = children [--n_children];
-
- XClearWindow (GDK_DISPLAY (), child);
- clear_children (child);
- }
-
- XFree (children);
- }
-}
-
-static void
-widget_clear_all_children (GtkWidget *widget)
-{
- GdkWindow *w;
-
- gs_debug ("Clearing all child windows");
-
- gdk_error_trap_push ();
-
- w = widget->window;
-
- clear_children (GDK_WINDOW_XID (w));
-
- gdk_display_sync (gtk_widget_get_display (widget));
- gdk_error_trap_pop ();
-}
-
-void
-gs_window_set_background_pixmap (GSWindow *window,
- GdkPixmap *pixmap)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- if (window->priv->background_pixmap != NULL)
- {
- g_object_unref (window->priv->background_pixmap);
- }
-
- if (pixmap != NULL)
- {
- window->priv->background_pixmap = g_object_ref (pixmap);
- gdk_window_set_back_pixmap (GTK_WIDGET (window)->window,
- pixmap,
- FALSE);
- }
-}
-
-static void
-gs_window_clear_to_background_pixmap (GSWindow *window)
-{
- GtkStateType state;
- GtkStyle *style;
-
- g_return_if_fail (GS_IS_WINDOW (window));
-
- if (! GTK_WIDGET_VISIBLE (GTK_WIDGET (window)))
- {
- return;
- }
-
- if (window->priv->background_pixmap == NULL)
- {
- /* don't allow null pixmaps */
- return;
- }
-
- gs_debug ("Clearing window to background pixmap");
-
- style = gtk_style_copy (GTK_WIDGET (window)->style);
-
- state = (GtkStateType) 0;
- while (state < (GtkStateType) G_N_ELEMENTS (GTK_WIDGET (window)->style->bg_pixmap))
- {
-
- if (style->bg_pixmap[state] != NULL)
- {
- g_object_unref (style->bg_pixmap[state]);
- }
-
- style->bg_pixmap[state] = g_object_ref (window->priv->background_pixmap);
- state++;
- }
-
- gtk_widget_set_style (GTK_WIDGET (window), style);
- g_object_unref (style);
-
- if (window->priv->background_pixmap != NULL)
- {
- gdk_window_set_back_pixmap (GTK_WIDGET (window)->window,
- window->priv->background_pixmap,
- FALSE);
- }
-
- gdk_window_clear (GTK_WIDGET (window)->window);
-
- gdk_flush ();
-}
-
-static void
-clear_widget (GtkWidget *widget)
-{
- GdkColor color = { 0, 0x0000, 0x0000, 0x0000 };
- GdkColormap *colormap;
- GtkStateType state;
- GtkStyle *style;
-
- if (! GTK_WIDGET_VISIBLE (widget))
- {
- return;
- }
-
- gs_debug ("Clearing widget");
-
- state = (GtkStateType) 0;
- while (state < (GtkStateType) G_N_ELEMENTS (widget->style->bg))
- {
- gtk_widget_modify_bg (widget, state, &color);
- state++;
- }
-
- style = gtk_style_copy (widget->style);
-
- state = (GtkStateType) 0;
- while (state < (GtkStateType) G_N_ELEMENTS (widget->style->bg_pixmap))
- {
-
- if (style->bg_pixmap[state] != NULL)
- {
- g_object_unref (style->bg_pixmap[state]);
- }
-
- style->bg_pixmap[state] = NULL;
- state++;
- }
-
- colormap = gdk_drawable_get_colormap (widget->window);
- gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE);
- gdk_window_set_background (widget->window, &color);
-
- gtk_widget_set_style (widget, style);
- g_object_unref (style);
-
- gdk_window_clear (widget->window);
-
- /* If a screensaver theme adds child windows we need to clear them too */
- widget_clear_all_children (widget);
-
- gdk_flush ();
-}
-
-void
-gs_window_clear (GSWindow *window)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- clear_widget (GTK_WIDGET (window));
- clear_widget (window->priv->drawing_area);
-}
-
-static GdkRegion *
-get_outside_region (GSWindow *window)
-{
- int i;
- GdkRegion *region;
-
- region = gdk_region_new ();
- for (i = 0; i < window->priv->monitor; i++)
- {
- GdkRectangle geometry;
-
- gdk_screen_get_monitor_geometry (GTK_WINDOW (window)->screen,
- i, &geometry);
- gdk_region_union_with_rect (region, &geometry);
- }
-
- return region;
-}
-
-static void
-update_geometry (GSWindow *window)
-{
- GdkRectangle geometry;
- GdkRegion *outside_region;
- GdkRegion *monitor_region;
-
- outside_region = get_outside_region (window);
-
- gdk_screen_get_monitor_geometry (GTK_WINDOW (window)->screen,
- window->priv->monitor,
- &geometry);
- gs_debug ("got geometry for monitor %d: x=%d y=%d w=%d h=%d",
- window->priv->monitor,
- geometry.x,
- geometry.y,
- geometry.width,
- geometry.height);
- monitor_region = gdk_region_rectangle (&geometry);
- gdk_region_subtract (monitor_region, outside_region);
- gdk_region_destroy (outside_region);
-
- gdk_region_get_clipbox (monitor_region, &geometry);
- gdk_region_destroy (monitor_region);
-
- gs_debug ("using geometry for monitor %d: x=%d y=%d w=%d h=%d",
- window->priv->monitor,
- geometry.x,
- geometry.y,
- geometry.width,
- geometry.height);
-
- window->priv->geometry.x = geometry.x;
- window->priv->geometry.y = geometry.y;
- window->priv->geometry.width = geometry.width;
- window->priv->geometry.height = geometry.height;
-}
-
-static void
-screen_size_changed (GdkScreen *screen,
- GSWindow *window)
-{
- gs_debug ("Got screen size changed signal");
- gtk_widget_queue_resize (GTK_WIDGET (window));
-}
-
-/* copied from panel-toplevel.c */
-static void
-gs_window_move_resize_window (GSWindow *window,
- gboolean move,
- gboolean resize)
-{
- GtkWidget *widget;
-
- widget = GTK_WIDGET (window);
-
- g_assert (GTK_WIDGET_REALIZED (widget));
-
- gs_debug ("Move and/or resize window on monitor %d: x=%d y=%d w=%d h=%d",
- window->priv->monitor,
- window->priv->geometry.x,
- window->priv->geometry.y,
- window->priv->geometry.width,
- window->priv->geometry.height);
-
- if (move && resize)
- {
- gdk_window_move_resize (widget->window,
- window->priv->geometry.x,
- window->priv->geometry.y,
- window->priv->geometry.width,
- window->priv->geometry.height);
- }
- else if (move)
- {
- gdk_window_move (widget->window,
- window->priv->geometry.x,
- window->priv->geometry.y);
- }
- else if (resize)
- {
- gdk_window_resize (widget->window,
- window->priv->geometry.width,
- window->priv->geometry.height);
- }
-}
-
-static void
-gs_window_real_unrealize (GtkWidget *widget)
-{
- g_signal_handlers_disconnect_by_func (gtk_window_get_screen (GTK_WINDOW (widget)),
- screen_size_changed,
- widget);
-
- if (GTK_WIDGET_CLASS (gs_window_parent_class)->unrealize)
- {
- GTK_WIDGET_CLASS (gs_window_parent_class)->unrealize (widget);
- }
-}
-
-/* copied from gdk */
-extern char **environ;
-
-static gchar **
-spawn_make_environment_for_screen (GdkScreen *screen,
- gchar **envp)
-{
- gchar **retval = NULL;
- gchar *display_name;
- gint display_index = -1;
- gint i, env_len;
-
- g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
-
- if (envp == NULL)
- envp = environ;
-
- for (env_len = 0; envp[env_len]; env_len++)
- if (strncmp (envp[env_len], "DISPLAY", strlen ("DISPLAY")) == 0)
- display_index = env_len;
-
- retval = g_new (char *, env_len + 1);
- retval[env_len] = NULL;
-
- display_name = gdk_screen_make_display_name (screen);
-
- for (i = 0; i < env_len; i++)
- if (i == display_index)
- retval[i] = g_strconcat ("DISPLAY=", display_name, NULL);
- else
- retval[i] = g_strdup (envp[i]);
-
- g_assert (i == env_len);
-
- g_free (display_name);
-
- return retval;
-}
-
-static gboolean
-spawn_command_line_on_screen_sync (GdkScreen *screen,
- const gchar *command_line,
- char **standard_output,
- char **standard_error,
- int *exit_status,
- GError **error)
-{
- char **argv = NULL;
- char **envp = NULL;
- gboolean retval;
-
- g_return_val_if_fail (command_line != NULL, FALSE);
-
- if (! g_shell_parse_argv (command_line, NULL, &argv, error))
- {
- return FALSE;
- }
-
- envp = spawn_make_environment_for_screen (screen, NULL);
-
- retval = g_spawn_sync (NULL,
- argv,
- envp,
- G_SPAWN_SEARCH_PATH,
- NULL,
- NULL,
- standard_output,
- standard_error,
- exit_status,
- error);
-
- g_strfreev (argv);
- g_strfreev (envp);
-
- return retval;
-}
-
-static GdkVisual *
-get_best_visual_for_screen (GdkScreen *screen)
-{
- char *command;
- char *std_output;
- int exit_status;
- GError *error;
- unsigned long v;
- char c;
- GdkVisual *visual;
- gboolean res;
-
- visual = NULL;
-
- command = g_build_filename (LIBEXECDIR, "mate-screensaver-gl-helper", NULL);
-
- error = NULL;
- std_output = NULL;
- res = spawn_command_line_on_screen_sync (screen,
- command,
- &std_output,
- NULL,
- &exit_status,
- &error);
- if (! res)
- {
- gs_debug ("Could not run command '%s': %s", command, error->message);
- g_error_free (error);
- goto out;
- }
-
- if (1 == sscanf (std_output, "0x%lx %c", &v, &c))
- {
- if (v != 0)
- {
- VisualID visual_id;
-
- visual_id = (VisualID) v;
- visual = gdkx_visual_get (visual_id);
-
- gs_debug ("Found best GL visual for screen %d: 0x%x",
- gdk_screen_get_number (screen),
- (unsigned int) visual_id);
- }
- }
-out:
- g_free (std_output);
- g_free (command);
-
- return visual;
-}
-
-static GdkColormap *
-get_best_colormap_for_screen (GdkScreen *screen)
-{
- GdkColormap *colormap;
- GdkVisual *visual;
-
- g_return_val_if_fail (screen != NULL, NULL);
-
- visual = get_best_visual_for_screen (screen);
-
- colormap = NULL;
- if (visual != NULL)
- {
- colormap = gdk_colormap_new (visual, FALSE);
- }
-
- return colormap;
-}
-
-static void
-widget_set_best_colormap (GtkWidget *widget)
-{
- GdkColormap *colormap;
-
- g_return_if_fail (widget != NULL);
-
- colormap = get_best_colormap_for_screen (gtk_widget_get_screen (widget));
- if (colormap != NULL)
- {
- gtk_widget_set_colormap (widget, colormap);
- g_object_unref (colormap);
- }
-}
-
-static void
-gs_window_real_realize (GtkWidget *widget)
-{
- widget_set_best_colormap (widget);
-
- if (GTK_WIDGET_CLASS (gs_window_parent_class)->realize)
- {
- GTK_WIDGET_CLASS (gs_window_parent_class)->realize (widget);
- }
-
- gs_window_override_user_time (GS_WINDOW (widget));
-
- gs_window_move_resize_window (GS_WINDOW (widget), TRUE, TRUE);
-
- g_signal_connect (gtk_window_get_screen (GTK_WINDOW (widget)),
- "size_changed",
- G_CALLBACK (screen_size_changed),
- widget);
-}
-
-/* every so often we should raise the window in case
- another window has somehow gotten on top */
-static gboolean
-watchdog_timer (GSWindow *window)
-{
- GtkWidget *widget = GTK_WIDGET (window);
-
- gdk_window_focus (widget->window, GDK_CURRENT_TIME);
-
- return TRUE;
-}
-
-static void
-remove_watchdog_timer (GSWindow *window)
-{
- if (window->priv->watchdog_timer_id != 0)
- {
- g_source_remove (window->priv->watchdog_timer_id);
- window->priv->watchdog_timer_id = 0;
- }
-}
-
-static void
-add_watchdog_timer (GSWindow *window,
- glong timeout)
-{
- window->priv->watchdog_timer_id = g_timeout_add (timeout,
- (GSourceFunc)watchdog_timer,
- window);
-}
-
-static void
-remove_popup_dialog_idle (GSWindow *window)
-{
- if (window->priv->popup_dialog_idle_id != 0)
- {
- g_source_remove (window->priv->popup_dialog_idle_id);
- window->priv->popup_dialog_idle_id = 0;
- }
-}
-
-static void
-add_popup_dialog_idle (GSWindow *window)
-{
- window->priv->popup_dialog_idle_id = g_idle_add ((GSourceFunc)popup_dialog_idle, window);
-}
-
-static gboolean
-emit_deactivated_idle (GSWindow *window)
-{
- g_signal_emit (window, signals [DEACTIVATED], 0);
-
- return FALSE;
-}
-
-static void
-add_emit_deactivated_idle (GSWindow *window)
-{
- g_idle_add ((GSourceFunc)emit_deactivated_idle, window);
-}
-
-static void
-gs_window_raise (GSWindow *window)
-{
- GdkWindow *win;
-
- g_return_if_fail (GS_IS_WINDOW (window));
-
- gs_debug ("Raising screensaver window");
-
- win = GTK_WIDGET (window)->window;
-
- gdk_window_raise (win);
-}
-
-static gboolean
-x11_window_is_ours (Window window)
-{
- GdkWindow *gwindow;
- gboolean ret;
-
- ret = FALSE;
-
- gwindow = gdk_window_lookup (window);
- if (gwindow && (window != GDK_ROOT_WINDOW ()))
- {
- ret = TRUE;
- }
-
- return ret;
-}
-
-#ifdef HAVE_SHAPE_EXT
-static void
-unshape_window (GSWindow *window)
-{
- gdk_window_shape_combine_region (GTK_WIDGET (window)->window,
- NULL,
- 0,
- 0);
-}
-#endif
-
-static void
-gs_window_xevent (GSWindow *window,
- GdkXEvent *xevent)
-{
- XEvent *ev;
-
- ev = xevent;
-
- /* MapNotify is used to tell us when new windows are mapped.
- ConfigureNofify is used to tell us when windows are raised. */
- switch (ev->xany.type)
- {
- case MapNotify:
- {
- XMapEvent *xme = &ev->xmap;
-
- if (! x11_window_is_ours (xme->window))
- {
- gs_window_raise (window);
- }
- else
- {
- gs_debug ("not raising our windows");
- }
-
- break;
- }
- case ConfigureNotify:
- {
- XConfigureEvent *xce = &ev->xconfigure;
-
- if (! x11_window_is_ours (xce->window))
- {
- gs_window_raise (window);
- }
- else
- {
- gs_debug ("not raising our windows");
- }
-
- break;
- }
- default:
- /* extension events */
-#ifdef HAVE_SHAPE_EXT
- if (ev->xany.type == (window->priv->shape_event_base + ShapeNotify))
- {
- /*XShapeEvent *xse = (XShapeEvent *) ev;*/
- unshape_window (window);
- gs_debug ("Window was reshaped!");
- }
-#endif
-
- break;
- }
-
-}
-
-static GdkFilterReturn
-xevent_filter (GdkXEvent *xevent,
- GdkEvent *event,
- GSWindow *window)
-{
- gs_window_xevent (window, xevent);
-
- return GDK_FILTER_CONTINUE;
-}
-
-static void
-select_popup_events (void)
-{
- XWindowAttributes attr;
- unsigned long events;
-
- gdk_error_trap_push ();
-
- memset (&attr, 0, sizeof (attr));
- XGetWindowAttributes (GDK_DISPLAY (), GDK_ROOT_WINDOW (), &attr);
-
- events = SubstructureNotifyMask | attr.your_event_mask;
- XSelectInput (GDK_DISPLAY (), GDK_ROOT_WINDOW (), events);
-
- gdk_display_sync (gdk_display_get_default ());
- gdk_error_trap_pop ();
-}
-
-static void
-window_select_shape_events (GSWindow *window)
-{
-#ifdef HAVE_SHAPE_EXT
- unsigned long events;
- int shape_error_base;
-
- gdk_error_trap_push ();
-
- if (XShapeQueryExtension (GDK_DISPLAY (), &window->priv->shape_event_base, &shape_error_base))
- {
- events = ShapeNotifyMask;
- XShapeSelectInput (GDK_DISPLAY (), GDK_WINDOW_XID (GTK_WIDGET (window)->window), events);
- }
-
- gdk_display_sync (gdk_display_get_default ());
- gdk_error_trap_pop ();
-#endif
-}
-
-static void
-gs_window_real_show (GtkWidget *widget)
-{
- GSWindow *window;
-
- if (GTK_WIDGET_CLASS (gs_window_parent_class)->show)
- {
- GTK_WIDGET_CLASS (gs_window_parent_class)->show (widget);
- }
-
- gs_window_clear (GS_WINDOW (widget));
-
- set_invisible_cursor (widget->window, TRUE);
-
- window = GS_WINDOW (widget);
- if (window->priv->timer)
- {
- g_timer_destroy (window->priv->timer);
- }
- window->priv->timer = g_timer_new ();
-
- remove_watchdog_timer (window);
- add_watchdog_timer (window, 30000);
-
- select_popup_events ();
- window_select_shape_events (window);
- gdk_window_add_filter (NULL, (GdkFilterFunc)xevent_filter, window);
-}
-
-static void
-set_info_text_and_icon (GSWindow *window,
- const char *icon_stock_id,
- const char *primary_text,
- const char *secondary_text)
-{
- GtkWidget *content_area;
- GtkWidget *hbox_content;
- GtkWidget *image;
- GtkWidget *vbox;
- gchar *primary_markup;
- gchar *secondary_markup;
- GtkWidget *primary_label;
- GtkWidget *secondary_label;
-
- hbox_content = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox_content);
-
- image = gtk_image_new_from_stock (icon_stock_id, GTK_ICON_SIZE_DIALOG);
- gtk_widget_show (image);
- gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0);
- gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0);
-
- vbox = gtk_vbox_new (FALSE, 6);
- gtk_widget_show (vbox);
- gtk_box_pack_start (GTK_BOX (hbox_content), vbox, FALSE, FALSE, 0);
-
- primary_markup = g_strdup_printf ("<b>%s</b>", primary_text);
- primary_label = gtk_label_new (primary_markup);
- g_free (primary_markup);
- gtk_widget_show (primary_label);
- gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
- gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
- gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
- gtk_misc_set_alignment (GTK_MISC (primary_label), 0, 0.5);
-
- if (secondary_text != NULL)
- {
- secondary_markup = g_strdup_printf ("<small>%s</small>",
- secondary_text);
- secondary_label = gtk_label_new (secondary_markup);
- g_free (secondary_markup);
- gtk_widget_show (secondary_label);
- gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
- gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
- gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
- gtk_misc_set_alignment (GTK_MISC (secondary_label), 0, 0.5);
- }
-
- /* remove old content */
- content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (window->priv->info_bar));
- if (window->priv->info_content != NULL)
- {
- gtk_container_remove (GTK_CONTAINER (content_area), window->priv->info_content);
- }
- gtk_box_pack_start (GTK_BOX (content_area),
- hbox_content,
- TRUE, FALSE, 0);
- window->priv->info_content = hbox_content;
-}
-
-static gboolean
-info_bar_timeout (GSWindow *window)
-{
- window->priv->info_bar_timer_id = 0;
- gtk_widget_hide (window->priv->info_bar);
- return FALSE;
-}
-
-void
-gs_window_show_message (GSWindow *window,
- const char *summary,
- const char *body,
- const char *icon)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- set_info_text_and_icon (window,
- icon,
- summary,
- body);
- gtk_widget_show (window->priv->info_bar);
-
- if (window->priv->info_bar_timer_id > 0)
- {
- g_source_remove (window->priv->info_bar_timer_id);
- }
-
- window->priv->info_bar_timer_id = g_timeout_add_seconds (INFO_BAR_SECONDS,
- (GSourceFunc)info_bar_timeout,
- window);
-}
-
-void
-gs_window_show (GSWindow *window)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- gtk_widget_show (GTK_WIDGET (window));
-}
-
-static void
-gs_window_real_hide (GtkWidget *widget)
-{
- GSWindow *window;
-
- window = GS_WINDOW (widget);
-
- gdk_window_remove_filter (NULL, (GdkFilterFunc)xevent_filter, window);
-
- remove_watchdog_timer (window);
-
- if (GTK_WIDGET_CLASS (gs_window_parent_class)->hide)
- {
- GTK_WIDGET_CLASS (gs_window_parent_class)->hide (widget);
- }
-}
-
-void
-gs_window_destroy (GSWindow *window)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- gs_window_cancel_unlock_request (window);
-
- gtk_widget_destroy (GTK_WIDGET (window));
-}
-
-GdkWindow *
-gs_window_get_gdk_window (GSWindow *window)
-{
- g_return_val_if_fail (GS_IS_WINDOW (window), NULL);
-
- return GTK_WIDGET (window)->window;
-}
-
-GtkWidget *
-gs_window_get_drawing_area (GSWindow *window)
-{
- g_return_val_if_fail (GS_IS_WINDOW (window), NULL);
-
- return window->priv->drawing_area;
-}
-
-/* just for debugging */
-static gboolean
-error_watch (GIOChannel *source,
- GIOCondition condition,
- gpointer data)
-{
- gboolean finished = FALSE;
-
- if (condition & G_IO_IN)
- {
- GIOStatus status;
- GError *error = NULL;
- char *line;
-
- line = NULL;
- status = g_io_channel_read_line (source, &line, NULL, NULL, &error);
-
- switch (status)
- {
- case G_IO_STATUS_NORMAL:
- gs_debug ("command error output: %s", line);
- break;
- case G_IO_STATUS_EOF:
- finished = TRUE;
- break;
- case G_IO_STATUS_ERROR:
- finished = TRUE;
- gs_debug ("Error reading from child: %s\n", error->message);
- g_error_free (error);
- return FALSE;
- case G_IO_STATUS_AGAIN:
- default:
- break;
- }
- g_free (line);
- }
- else if (condition & G_IO_HUP)
- {
- finished = TRUE;
- }
-
- if (finished)
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-spawn_on_window (GSWindow *window,
- char *command,
- int *pid,
- GIOFunc watch_func,
- gpointer user_data,
- gint *watch_id)
-{
- int argc;
- char **argv;
- GError *error;
- gboolean result;
- GIOChannel *channel;
- int standard_output;
- int standard_error;
- int child_pid;
- int id;
-
- error = NULL;
- if (! g_shell_parse_argv (command, &argc, &argv, &error))
- {
- gs_debug ("Could not parse command: %s", error->message);
- g_error_free (error);
- return FALSE;
- }
-
- error = NULL;
- result = gdk_spawn_on_screen_with_pipes (GTK_WINDOW (window)->screen,
- NULL,
- argv,
- NULL,
- G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
- NULL,
- NULL,
- &child_pid,
- NULL,
- &standard_output,
- &standard_error,
- &error);
-
- if (! result)
- {
- gs_debug ("Could not start command '%s': %s", command, error->message);
- g_error_free (error);
- g_strfreev (argv);
- return FALSE;
- }
-
- if (pid != NULL)
- {
- *pid = child_pid;
- }
- else
- {
- g_spawn_close_pid (child_pid);
- }
-
- /* output channel */
- channel = g_io_channel_unix_new (standard_output);
- g_io_channel_set_close_on_unref (channel, TRUE);
- g_io_channel_set_flags (channel,
- g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK,
- NULL);
- id = g_io_add_watch (channel,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- watch_func,
- user_data);
- if (watch_id != NULL)
- {
- *watch_id = id;
- }
- g_io_channel_unref (channel);
-
- /* error channel */
- channel = g_io_channel_unix_new (standard_error);
- g_io_channel_set_close_on_unref (channel, TRUE);
- g_io_channel_set_flags (channel,
- g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK,
- NULL);
- id = g_io_add_watch (channel,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- error_watch,
- NULL);
- g_io_channel_unref (channel);
-
- g_strfreev (argv);
-
- return result;
-}
-
-static void
-lock_plug_added (GtkWidget *widget,
- GSWindow *window)
-{
- gtk_widget_show (widget);
-}
-
-static gboolean
-lock_plug_removed (GtkWidget *widget,
- GSWindow *window)
-{
- gtk_widget_hide (widget);
- gtk_container_remove (GTK_CONTAINER (window->priv->vbox), GTK_WIDGET (window->priv->lock_box));
- window->priv->lock_box = NULL;
-
- return TRUE;
-}
-
-static void
-keyboard_plug_added (GtkWidget *widget,
- GSWindow *window)
-{
- gtk_widget_show (widget);
-}
-
-static gboolean
-keyboard_plug_removed (GtkWidget *widget,
- GSWindow *window)
-{
- gtk_widget_hide (widget);
- gtk_container_remove (GTK_CONTAINER (window->priv->vbox), GTK_WIDGET (window->priv->keyboard_socket));
-
- return TRUE;
-}
-
-static void
-keyboard_socket_destroyed (GtkWidget *widget,
- GSWindow *window)
-{
- g_signal_handlers_disconnect_by_func (widget, keyboard_socket_destroyed, window);
- g_signal_handlers_disconnect_by_func (widget, keyboard_plug_added, window);
- g_signal_handlers_disconnect_by_func (widget, keyboard_plug_removed, window);
-
- window->priv->keyboard_socket = NULL;
-}
-
-static void
-forward_key_events (GSWindow *window)
-{
- window->priv->key_events = g_list_reverse (window->priv->key_events);
-
- while (window->priv->key_events != NULL)
- {
- GdkEventKey *event = window->priv->key_events->data;
-
- gtk_window_propagate_key_event (GTK_WINDOW (window), event);
-
- gdk_event_free ((GdkEvent *)event);
- window->priv->key_events = g_list_delete_link (window->priv->key_events,
- window->priv->key_events);
- }
-}
-
-static void
-remove_key_events (GSWindow *window)
-{
- window->priv->key_events = g_list_reverse (window->priv->key_events);
-
- while (window->priv->key_events)
- {
- GdkEventKey *event = window->priv->key_events->data;
-
- gdk_event_free ((GdkEvent *)event);
- window->priv->key_events = g_list_delete_link (window->priv->key_events,
- window->priv->key_events);
- }
-}
-
-static void
-lock_socket_show (GtkWidget *widget,
- GSWindow *window)
-{
- gtk_widget_child_focus (window->priv->lock_socket, GTK_DIR_TAB_FORWARD);
-
- /* send queued events to the dialog */
- forward_key_events (window);
-}
-
-static void
-lock_socket_destroyed (GtkWidget *widget,
- GSWindow *window)
-{
- g_signal_handlers_disconnect_by_func (widget, lock_socket_show, window);
- g_signal_handlers_disconnect_by_func (widget, lock_socket_destroyed, window);
- g_signal_handlers_disconnect_by_func (widget, lock_plug_added, window);
- g_signal_handlers_disconnect_by_func (widget, lock_plug_removed, window);
-
- window->priv->lock_socket = NULL;
-}
-
-static void
-create_keyboard_socket (GSWindow *window,
- guint32 id)
-{
- int height;
-
- height = (gdk_screen_get_height (gtk_widget_get_screen (GTK_WIDGET (window)))) / 4;
-
- window->priv->keyboard_socket = gtk_socket_new ();
- gtk_widget_set_size_request (window->priv->keyboard_socket, -1, height);
-
- g_signal_connect (window->priv->keyboard_socket, "destroy",
- G_CALLBACK (keyboard_socket_destroyed), window);
- g_signal_connect (window->priv->keyboard_socket, "plug_added",
- G_CALLBACK (keyboard_plug_added), window);
- g_signal_connect (window->priv->keyboard_socket, "plug_removed",
- G_CALLBACK (keyboard_plug_removed), window);
- gtk_box_pack_start (GTK_BOX (window->priv->vbox), window->priv->keyboard_socket, FALSE, FALSE, 0);
- gtk_socket_add_id (GTK_SOCKET (window->priv->keyboard_socket), id);
-}
-
-/* adapted from gspawn.c */
-static int
-wait_on_child (int pid)
-{
- int status;
-
-wait_again:
- if (waitpid (pid, &status, 0) < 0)
- {
- if (errno == EINTR)
- {
- goto wait_again;
- }
- else if (errno == ECHILD)
- {
- ; /* do nothing, child already reaped */
- }
- else
- {
- gs_debug ("waitpid () should not fail in 'GSWindow'");
- }
- }
-
- return status;
-}
-
-static void
-kill_keyboard_command (GSWindow *window)
-{
- if (window->priv->keyboard_pid > 0)
- {
- signal_pid (window->priv->keyboard_pid, SIGTERM);
- }
-}
-
-static void
-kill_dialog_command (GSWindow *window)
-{
- /* If a dialog is up we need to signal it
- and wait on it */
- if (window->priv->lock_pid > 0)
- {
- signal_pid (window->priv->lock_pid, SIGTERM);
- }
-}
-
-static void
-keyboard_command_finish (GSWindow *window)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- /* send a signal just in case */
- kill_keyboard_command (window);
-
- gs_debug ("Keyboard finished");
-
- if (window->priv->keyboard_pid > 0)
- {
- int exit_status;
-
- exit_status = wait_on_child (window->priv->keyboard_pid);
-
- g_spawn_close_pid (window->priv->keyboard_pid);
- window->priv->keyboard_pid = 0;
- }
-}
-
-static gboolean
-keyboard_command_watch (GIOChannel *source,
- GIOCondition condition,
- GSWindow *window)
-{
- gboolean finished = FALSE;
-
- g_return_val_if_fail (GS_IS_WINDOW (window), FALSE);
-
- if (condition & G_IO_IN)
- {
- GIOStatus status;
- GError *error = NULL;
- char *line;
-
- line = NULL;
- status = g_io_channel_read_line (source, &line, NULL, NULL, &error);
-
- switch (status)
- {
- case G_IO_STATUS_NORMAL:
- {
- guint32 id;
- char c;
- gs_debug ("keyboard command output: %s", line);
- if (1 == sscanf (line, " %" G_GUINT32_FORMAT " %c", &id, &c))
- {
- create_keyboard_socket (window, id);
- }
- }
- break;
- case G_IO_STATUS_EOF:
- finished = TRUE;
- break;
- case G_IO_STATUS_ERROR:
- finished = TRUE;
- gs_debug ("Error reading from child: %s\n", error->message);
- g_error_free (error);
- return FALSE;
- case G_IO_STATUS_AGAIN:
- default:
- break;
- }
-
- g_free (line);
- }
- else if (condition & G_IO_HUP)
- {
- finished = TRUE;
- }
-
- if (finished)
- {
- window->priv->keyboard_watch_id = 0;
- keyboard_command_finish (window);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-embed_keyboard (GSWindow *window)
-{
- gboolean res;
-
- if (! window->priv->keyboard_enabled
- || window->priv->keyboard_command == NULL)
- return;
-
- gs_debug ("Adding embedded keyboard widget");
-
- /* FIXME: verify command is safe */
-
- gs_debug ("Running command: %s", window->priv->keyboard_command);
-
- res = spawn_on_window (window,
- window->priv->keyboard_command,
- &window->priv->keyboard_pid,
- (GIOFunc)keyboard_command_watch,
- window,
- &window->priv->keyboard_watch_id);
- if (! res)
- {
- gs_debug ("Could not start command: %s", window->priv->keyboard_command);
- }
-}
-
-static void
-create_lock_socket (GSWindow *window,
- guint32 id)
-{
- window->priv->lock_socket = gtk_socket_new ();
- window->priv->lock_box = gtk_alignment_new (0.5, 0.5, 0, 0);
- gtk_widget_show (window->priv->lock_box);
- gtk_box_pack_start (GTK_BOX (window->priv->vbox), window->priv->lock_box, TRUE, TRUE, 0);
-
- gtk_container_add (GTK_CONTAINER (window->priv->lock_box), window->priv->lock_socket);
-
- g_signal_connect (window->priv->lock_socket, "show",
- G_CALLBACK (lock_socket_show), window);
- g_signal_connect (window->priv->lock_socket, "destroy",
- G_CALLBACK (lock_socket_destroyed), window);
- g_signal_connect (window->priv->lock_socket, "plug_added",
- G_CALLBACK (lock_plug_added), window);
- g_signal_connect (window->priv->lock_socket, "plug_removed",
- G_CALLBACK (lock_plug_removed), window);
-
- gtk_socket_add_id (GTK_SOCKET (window->priv->lock_socket), id);
-
- if (window->priv->keyboard_enabled)
- {
- embed_keyboard (window);
- }
-}
-
-static void
-gs_window_dialog_finish (GSWindow *window)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- gs_debug ("Dialog finished");
-
- /* make sure we finish the keyboard thing too */
- keyboard_command_finish (window);
-
- /* send a signal just in case */
- kill_dialog_command (window);
-
- if (window->priv->lock_pid > 0)
- {
- int exit_status;
-
- exit_status = wait_on_child (window->priv->lock_pid);
-
- g_spawn_close_pid (window->priv->lock_pid);
- window->priv->lock_pid = 0;
- }
-
- /* remove events for the case were we failed to show socket */
- remove_key_events (window);
-}
-
-static void
-maybe_kill_dialog (GSWindow *window)
-{
- if (!window->priv->dialog_shake_in_progress
- && window->priv->dialog_quit_requested
- && window->priv->lock_pid > 0)
- {
- kill (window->priv->lock_pid, SIGTERM);
- }
-}
-
-/* very rudimentary animation for indicating an auth failure */
-static void
-shake_dialog (GSWindow *window)
-{
- int i;
- guint left;
- guint right;
-
- window->priv->dialog_shake_in_progress = TRUE;
-
- for (i = 0; i < 9; i++)
- {
- if (i % 2 == 0)
- {
- left = 30;
- right = 0;
- }
- else
- {
- left = 0;
- right = 30;
- }
-
- if (! window->priv->lock_box)
- {
- break;
- }
-
- gtk_alignment_set_padding (GTK_ALIGNMENT (window->priv->lock_box),
- 0, 0,
- left,
- right);
-
- while (gtk_events_pending ())
- {
- gtk_main_iteration ();
- }
-
- g_usleep (10000);
- }
-
- window->priv->dialog_shake_in_progress = FALSE;
- maybe_kill_dialog (window);
-}
-
-static void
-window_set_dialog_up (GSWindow *window,
- gboolean dialog_up)
-{
- if (window->priv->dialog_up == dialog_up)
- {
- return;
- }
-
- window->priv->dialog_up = dialog_up;
- g_object_notify (G_OBJECT (window), "dialog-up");
-}
-
-static void
-popdown_dialog (GSWindow *window)
-{
- gs_window_dialog_finish (window);
-
- gtk_widget_show (window->priv->drawing_area);
-
- gs_window_clear (window);
- set_invisible_cursor (GTK_WIDGET (window)->window, TRUE);
-
- window_set_dialog_up (window, FALSE);
-
- /* reset the pointer positions */
- window->priv->last_x = -1;
- window->priv->last_y = -1;
-
- if (window->priv->lock_box != NULL)
- {
- gtk_container_remove (GTK_CONTAINER (window->priv->vbox), GTK_WIDGET (window->priv->lock_box));
- window->priv->lock_box = NULL;
- }
-
- remove_popup_dialog_idle (window);
- remove_command_watches (window);
-}
-
-static gboolean
-lock_command_watch (GIOChannel *source,
- GIOCondition condition,
- GSWindow *window)
-{
- gboolean finished = FALSE;
-
- g_return_val_if_fail (GS_IS_WINDOW (window), FALSE);
-
- if (condition & G_IO_IN)
- {
- GIOStatus status;
- GError *error = NULL;
- char *line;
-
- line = NULL;
- status = g_io_channel_read_line (source, &line, NULL, NULL, &error);
-
- switch (status)
- {
- case G_IO_STATUS_NORMAL:
- gs_debug ("command output: %s", line);
-
- if (strstr (line, "WINDOW ID=") != NULL)
- {
- guint32 id;
- char c;
- if (1 == sscanf (line, " WINDOW ID= %" G_GUINT32_FORMAT " %c", &id, &c))
- {
- create_lock_socket (window, id);
- }
- }
- else if (strstr (line, "NOTICE=") != NULL)
- {
- if (strstr (line, "NOTICE=AUTH FAILED") != NULL)
- {
- shake_dialog (window);
- }
- }
- else if (strstr (line, "RESPONSE=") != NULL)
- {
- if (strstr (line, "RESPONSE=OK") != NULL)
- {
- gs_debug ("Got OK response");
- window->priv->dialog_response = DIALOG_RESPONSE_OK;
- }
- else
- {
- gs_debug ("Got CANCEL response");
- window->priv->dialog_response = DIALOG_RESPONSE_CANCEL;
- }
- finished = TRUE;
- }
- else if (strstr (line, "REQUEST QUIT") != NULL)
- {
- gs_debug ("Got request for quit");
- window->priv->dialog_quit_requested = TRUE;
- maybe_kill_dialog (window);
- }
- break;
- case G_IO_STATUS_EOF:
- finished = TRUE;
- break;
- case G_IO_STATUS_ERROR:
- finished = TRUE;
- gs_debug ("Error reading from child: %s\n", error->message);
- g_error_free (error);
- return FALSE;
- case G_IO_STATUS_AGAIN:
- default:
- break;
- }
-
- g_free (line);
- }
- else if (condition & G_IO_HUP)
- {
- finished = TRUE;
- }
-
- if (finished)
- {
- popdown_dialog (window);
-
- if (window->priv->dialog_response == DIALOG_RESPONSE_OK)
- {
- add_emit_deactivated_idle (window);
- }
-
- window->priv->lock_watch_id = 0;
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-is_logout_enabled (GSWindow *window)
-{
- double elapsed;
-
- if (! window->priv->logout_enabled)
- {
- return FALSE;
- }
-
- if (! window->priv->logout_command)
- {
- return FALSE;
- }
-
- elapsed = g_timer_elapsed (window->priv->timer, NULL);
-
- if (window->priv->logout_timeout < (elapsed * 1000))
- {
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-is_user_switch_enabled (GSWindow *window)
-{
- return window->priv->user_switch_enabled;
-}
-
-static void
-popup_dialog (GSWindow *window)
-{
- gboolean result;
- char *tmp;
- GString *command;
-
- gs_debug ("Popping up dialog");
-
- tmp = g_build_filename (LIBEXECDIR, "mate-screensaver-dialog", NULL);
- command = g_string_new (tmp);
- g_free (tmp);
-
- if (is_logout_enabled (window))
- {
- command = g_string_append (command, " --enable-logout");
- g_string_append_printf (command, " --logout-command='%s'", window->priv->logout_command);
- }
-
- if (window->priv->status_message)
- {
- char *quoted;
-
- quoted = g_shell_quote (window->priv->status_message);
- g_string_append_printf (command, " --status-message=%s", quoted);
- g_free (quoted);
- }
-
- if (is_user_switch_enabled (window))
- {
- command = g_string_append (command, " --enable-switch");
- }
-
- if (gs_debug_enabled ())
- {
- command = g_string_append (command, " --verbose");
- }
-
- gtk_widget_hide (window->priv->drawing_area);
-
- gs_window_clear_to_background_pixmap (window);
-
- set_invisible_cursor (GTK_WIDGET (window)->window, FALSE);
-
- window->priv->dialog_quit_requested = FALSE;
- window->priv->dialog_shake_in_progress = FALSE;
-
- result = spawn_on_window (window,
- command->str,
- &window->priv->lock_pid,
- (GIOFunc)lock_command_watch,
- window,
- &window->priv->lock_watch_id);
- if (! result)
- {
- gs_debug ("Could not start command: %s", command->str);
- }
-
- g_string_free (command, TRUE);
-}
-
-static gboolean
-popup_dialog_idle (GSWindow *window)
-{
- popup_dialog (window);
-
- window->priv->popup_dialog_idle_id = 0;
-
- return FALSE;
-}
-
-void
-gs_window_request_unlock (GSWindow *window)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- gs_debug ("Requesting unlock");
-
- if (! GTK_WIDGET_VISIBLE (GTK_WIDGET (window)))
- {
- gs_debug ("Request unlock but window is not visible!");
- return;
- }
-
- if (window->priv->lock_watch_id > 0)
- {
- return;
- }
-
- if (! window->priv->lock_enabled)
- {
- add_emit_deactivated_idle (window);
-
- return;
- }
-
- if (window->priv->popup_dialog_idle_id == 0)
- {
- add_popup_dialog_idle (window);
- }
-
- window_set_dialog_up (window, TRUE);
-}
-
-void
-gs_window_cancel_unlock_request (GSWindow *window)
-{
- /* FIXME: This is a bit of a hammer approach...
- * Maybe we should send a delete-event to
- * the plug?
- */
- g_return_if_fail (GS_IS_WINDOW (window));
-
- popdown_dialog (window);
-}
-
-void
-gs_window_set_lock_enabled (GSWindow *window,
- gboolean lock_enabled)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- if (window->priv->lock_enabled == lock_enabled)
- {
- return;
- }
-
- window->priv->lock_enabled = lock_enabled;
- g_object_notify (G_OBJECT (window), "lock-enabled");
-}
-
-void
-gs_window_set_screen (GSWindow *window,
- GdkScreen *screen)
-{
-
- g_return_if_fail (GS_IS_WINDOW (window));
- g_return_if_fail (GDK_IS_SCREEN (screen));
-
- gtk_window_set_screen (GTK_WINDOW (window), screen);
-}
-
-GdkScreen *
-gs_window_get_screen (GSWindow *window)
-{
- g_return_val_if_fail (GS_IS_WINDOW (window), NULL);
-
- return GTK_WINDOW (window)->screen;
-}
-
-void
-gs_window_set_keyboard_enabled (GSWindow *window,
- gboolean enabled)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- window->priv->keyboard_enabled = enabled;
-}
-
-void
-gs_window_set_keyboard_command (GSWindow *window,
- const char *command)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- g_free (window->priv->keyboard_command);
-
- if (command != NULL)
- {
- window->priv->keyboard_command = g_strdup (command);
- }
- else
- {
- window->priv->keyboard_command = NULL;
- }
-}
-
-void
-gs_window_set_logout_enabled (GSWindow *window,
- gboolean logout_enabled)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- window->priv->logout_enabled = logout_enabled;
-}
-
-void
-gs_window_set_user_switch_enabled (GSWindow *window,
- gboolean user_switch_enabled)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- window->priv->user_switch_enabled = user_switch_enabled;
-}
-
-void
-gs_window_set_logout_timeout (GSWindow *window,
- glong logout_timeout)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- if (logout_timeout < 0)
- {
- window->priv->logout_timeout = 0;
- }
- else
- {
- window->priv->logout_timeout = logout_timeout;
- }
-}
-
-void
-gs_window_set_logout_command (GSWindow *window,
- const char *command)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- g_free (window->priv->logout_command);
-
- if (command)
- {
- window->priv->logout_command = g_strdup (command);
- }
- else
- {
- window->priv->logout_command = NULL;
- }
-}
-
-void
-gs_window_set_status_message (GSWindow *window,
- const char *status_message)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- g_free (window->priv->status_message);
- window->priv->status_message = g_strdup (status_message);
-}
-
-void
-gs_window_set_monitor (GSWindow *window,
- int monitor)
-{
- g_return_if_fail (GS_IS_WINDOW (window));
-
- if (window->priv->monitor == monitor)
- {
- return;
- }
-
- window->priv->monitor = monitor;
-
- gtk_widget_queue_resize (GTK_WIDGET (window));
-
- g_object_notify (G_OBJECT (window), "monitor");
-}
-
-int
-gs_window_get_monitor (GSWindow *window)
-{
- g_return_val_if_fail (GS_IS_WINDOW (window), -1);
-
- return window->priv->monitor;
-}
-
-static void
-gs_window_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GSWindow *self;
-
- self = GS_WINDOW (object);
-
- switch (prop_id)
- {
- case PROP_LOCK_ENABLED:
- gs_window_set_lock_enabled (self, g_value_get_boolean (value));
- break;
- case PROP_KEYBOARD_ENABLED:
- gs_window_set_keyboard_enabled (self, g_value_get_boolean (value));
- break;
- case PROP_KEYBOARD_COMMAND:
- gs_window_set_keyboard_command (self, g_value_get_string (value));
- break;
- case PROP_LOGOUT_ENABLED:
- gs_window_set_logout_enabled (self, g_value_get_boolean (value));
- break;
- case PROP_LOGOUT_COMMAND:
- gs_window_set_logout_command (self, g_value_get_string (value));
- break;
- case PROP_STATUS_MESSAGE:
- gs_window_set_status_message (self, g_value_get_string (value));
- break;
- case PROP_LOGOUT_TIMEOUT:
- gs_window_set_logout_timeout (self, g_value_get_long (value));
- break;
- case PROP_MONITOR:
- gs_window_set_monitor (self, g_value_get_int (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gs_window_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GSWindow *self;
-
- self = GS_WINDOW (object);
-
- switch (prop_id)
- {
- case PROP_LOCK_ENABLED:
- g_value_set_boolean (value, self->priv->lock_enabled);
- break;
- case PROP_KEYBOARD_ENABLED:
- g_value_set_boolean (value, self->priv->keyboard_enabled);
- break;
- case PROP_KEYBOARD_COMMAND:
- g_value_set_string (value, self->priv->keyboard_command);
- break;
- case PROP_LOGOUT_ENABLED:
- g_value_set_boolean (value, self->priv->logout_enabled);
- break;
- case PROP_LOGOUT_COMMAND:
- g_value_set_string (value, self->priv->logout_command);
- break;
- case PROP_STATUS_MESSAGE:
- g_value_set_string (value, self->priv->status_message);
- break;
- case PROP_LOGOUT_TIMEOUT:
- g_value_set_long (value, self->priv->logout_timeout);
- break;
- case PROP_MONITOR:
- g_value_set_int (value, self->priv->monitor);
- break;
- case PROP_OBSCURED:
- g_value_set_boolean (value, self->priv->obscured);
- break;
- case PROP_DIALOG_UP:
- g_value_set_boolean (value, self->priv->dialog_up);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-queue_key_event (GSWindow *window,
- GdkEventKey *event)
-{
- /* Eat the first return, enter, escape, or space */
- if (window->priv->key_events == NULL
- && (event->keyval == GDK_Return
- || event->keyval == GDK_KP_Enter
- || event->keyval == GDK_Escape
- || event->keyval == GDK_space))
- {
- return;
- }
-
- /* Only cache MAX_QUEUED_EVENTS key events. If there are any more than this then
- something is wrong */
- /* Don't queue keys that may cause focus navigation in the dialog */
- if (g_list_length (window->priv->key_events) < MAX_QUEUED_EVENTS
- && event->keyval != GDK_Tab
- && event->keyval != GDK_Up
- && event->keyval != GDK_Down)
- {
- window->priv->key_events = g_list_prepend (window->priv->key_events,
- gdk_event_copy ((GdkEvent *)event));
- }
-}
-
-static gboolean
-maybe_handle_activity (GSWindow *window)
-{
- gboolean handled;
-
- handled = FALSE;
-
- /* if we already have a socket then don't bother */
- if (! window->priv->lock_socket
- && GTK_WIDGET_IS_SENSITIVE (GTK_WIDGET (window)))
- {
- g_signal_emit (window, signals [ACTIVITY], 0, &handled);
- }
-
- return handled;
-}
-
-static gboolean
-gs_window_real_key_press_event (GtkWidget *widget,
- GdkEventKey *event)
-{
- /*g_message ("KEY PRESS state: %u keyval %u", event->state, event->keyval);*/
-
- /* Ignore brightness keys */
- if (event->hardware_keycode == 101 || event->hardware_keycode == 212)
- {
- gs_debug ("Ignoring brightness keys");
- return TRUE;
- }
-
- maybe_handle_activity (GS_WINDOW (widget));
-
- queue_key_event (GS_WINDOW (widget), event);
-
- if (GTK_WIDGET_CLASS (gs_window_parent_class)->key_press_event)
- {
- GTK_WIDGET_CLASS (gs_window_parent_class)->key_press_event (widget, event);
- }
-
- return TRUE;
-}
-
-static gboolean
-gs_window_real_motion_notify_event (GtkWidget *widget,
- GdkEventMotion *event)
-{
- GSWindow *window;
- gdouble distance;
- gdouble min_distance;
- gdouble min_percentage = 0.1;
- GdkScreen *screen;
-
- window = GS_WINDOW (widget);
-
- screen = gs_window_get_screen (window);
- min_distance = gdk_screen_get_width (screen) * min_percentage;
-
- /* if the last position was not set then don't detect motion */
- if (window->priv->last_x < 0 || window->priv->last_y < 0)
- {
- window->priv->last_x = event->x;
- window->priv->last_y = event->y;
-
- return FALSE;
- }
-
- /* just an approximate distance */
- distance = MAX (ABS (window->priv->last_x - event->x),
- ABS (window->priv->last_y - event->y));
-
- if (distance > min_distance)
- {
- maybe_handle_activity (window);
-
- window->priv->last_x = -1;
- window->priv->last_y = -1;
- }
-
- return FALSE;
-}
-
-static gboolean
-gs_window_real_button_press_event (GtkWidget *widget,
- GdkEventButton *event)
-{
- GSWindow *window;
-
- window = GS_WINDOW (widget);
- maybe_handle_activity (window);
-
- return FALSE;
-}
-
-static gboolean
-gs_window_real_scroll_event (GtkWidget *widget,
- GdkEventScroll *event)
-{
- GSWindow *window;
-
- window = GS_WINDOW (widget);
- maybe_handle_activity (window);
-
- return FALSE;
-}
-
-static void
-gs_window_real_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
-{
- GSWindow *window;
- GtkBin *bin;
- GdkRectangle old_geometry;
- int position_changed = FALSE;
- int size_changed = FALSE;
-
- window = GS_WINDOW (widget);
- bin = GTK_BIN (widget);
-
- if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
- {
- gtk_widget_size_request (bin->child, requisition);
- }
-
- old_geometry = window->priv->geometry;
-
- update_geometry (window);
-
- requisition->width = window->priv->geometry.width;
- requisition->height = window->priv->geometry.height;
-
- if (! GTK_WIDGET_REALIZED (widget))
- {
- return;
- }
-
- if (old_geometry.width != window->priv->geometry.width ||
- old_geometry.height != window->priv->geometry.height)
- {
- size_changed = TRUE;
- }
-
- if (old_geometry.x != window->priv->geometry.x ||
- old_geometry.y != window->priv->geometry.y)
- {
- position_changed = TRUE;
- }
-
- gs_window_move_resize_window (window, position_changed, size_changed);
-}
-
-static gboolean
-gs_window_real_grab_broken (GtkWidget *widget,
- GdkEventGrabBroken *event)
-{
- if (event->grab_window != NULL)
- {
- gs_debug ("Grab broken on window %X %s, new grab on window %X",
- (guint32) GDK_WINDOW_XID (event->window),
- event->keyboard ? "keyboard" : "pointer",
- (guint32) GDK_WINDOW_XID (event->grab_window));
- }
- else
- {
- gs_debug ("Grab broken on window %X %s, new grab is outside application",
- (guint32) GDK_WINDOW_XID (event->window),
- event->keyboard ? "keyboard" : "pointer");
- }
-
- return FALSE;
-}
-
-gboolean
-gs_window_is_obscured (GSWindow *window)
-{
- g_return_val_if_fail (GS_IS_WINDOW (window), FALSE);
-
- return window->priv->obscured;
-}
-
-gboolean
-gs_window_is_dialog_up (GSWindow *window)
-{
- g_return_val_if_fail (GS_IS_WINDOW (window), FALSE);
-
- return window->priv->dialog_up;
-}
-
-static void
-window_set_obscured (GSWindow *window,
- gboolean obscured)
-{
- if (window->priv->obscured == obscured)
- {
- return;
- }
-
- window->priv->obscured = obscured;
- g_object_notify (G_OBJECT (window), "obscured");
-}
-
-static gboolean
-gs_window_real_visibility_notify_event (GtkWidget *widget,
- GdkEventVisibility *event)
-{
- switch (event->state)
- {
- case GDK_VISIBILITY_FULLY_OBSCURED:
- window_set_obscured (GS_WINDOW (widget), TRUE);
- break;
- case GDK_VISIBILITY_PARTIAL:
- break;
- case GDK_VISIBILITY_UNOBSCURED:
- window_set_obscured (GS_WINDOW (widget), FALSE);
- break;
- default:
- break;
- }
-
- return FALSE;
-}
-
-static void
-gs_window_class_init (GSWindowClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- object_class->finalize = gs_window_finalize;
- object_class->get_property = gs_window_get_property;
- object_class->set_property = gs_window_set_property;
-
- widget_class->show = gs_window_real_show;
- widget_class->hide = gs_window_real_hide;
- widget_class->realize = gs_window_real_realize;
- widget_class->unrealize = gs_window_real_unrealize;
- widget_class->key_press_event = gs_window_real_key_press_event;
- widget_class->motion_notify_event = gs_window_real_motion_notify_event;
- widget_class->button_press_event = gs_window_real_button_press_event;
- widget_class->scroll_event = gs_window_real_scroll_event;
- widget_class->size_request = gs_window_real_size_request;
- widget_class->grab_broken_event = gs_window_real_grab_broken;
- widget_class->visibility_notify_event = gs_window_real_visibility_notify_event;
-
- g_type_class_add_private (klass, sizeof (GSWindowPrivate));
-
- signals [ACTIVITY] =
- g_signal_new ("activity",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GSWindowClass, activity),
- NULL,
- NULL,
- gs_marshal_BOOLEAN__VOID,
- G_TYPE_BOOLEAN,
- 0);
- signals [DEACTIVATED] =
- g_signal_new ("deactivated",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GSWindowClass, deactivated),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- g_object_class_install_property (object_class,
- PROP_OBSCURED,
- g_param_spec_boolean ("obscured",
- NULL,
- NULL,
- FALSE,
- G_PARAM_READABLE));
- g_object_class_install_property (object_class,
- PROP_DIALOG_UP,
- g_param_spec_boolean ("dialog-up",
- NULL,
- NULL,
- FALSE,
- G_PARAM_READABLE));
- g_object_class_install_property (object_class,
- PROP_LOCK_ENABLED,
- g_param_spec_boolean ("lock-enabled",
- NULL,
- NULL,
- FALSE,
- G_PARAM_READWRITE));
- g_object_class_install_property (object_class,
- PROP_LOGOUT_ENABLED,
- g_param_spec_boolean ("logout-enabled",
- NULL,
- NULL,
- FALSE,
- G_PARAM_READWRITE));
- g_object_class_install_property (object_class,
- PROP_LOGOUT_TIMEOUT,
- g_param_spec_long ("logout-timeout",
- NULL,
- NULL,
- -1,
- G_MAXLONG,
- 0,
- G_PARAM_READWRITE));
- g_object_class_install_property (object_class,
- PROP_LOGOUT_COMMAND,
- g_param_spec_string ("logout-command",
- NULL,
- NULL,
- NULL,
- G_PARAM_READWRITE));
- g_object_class_install_property (object_class,
- PROP_STATUS_MESSAGE,
- g_param_spec_string ("status-message",
- NULL,
- NULL,
- NULL,
- G_PARAM_READWRITE));
- g_object_class_install_property (object_class,
- PROP_KEYBOARD_ENABLED,
- g_param_spec_boolean ("keyboard-enabled",
- NULL,
- NULL,
- FALSE,
- G_PARAM_READWRITE));
- g_object_class_install_property (object_class,
- PROP_KEYBOARD_COMMAND,
- g_param_spec_string ("keyboard-command",
- NULL,
- NULL,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_MONITOR,
- g_param_spec_int ("monitor",
- "Xinerama monitor",
- "The monitor (in terms of Xinerama) which the window is on",
- 0,
- G_MAXINT,
- 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
-}
-
-static void
-create_info_bar (GSWindow *window)
-{
- window->priv->info_bar = gtk_info_bar_new ();
- gtk_widget_set_no_show_all (window->priv->info_bar, TRUE);
- gtk_box_pack_end (GTK_BOX (window->priv->vbox), window->priv->info_bar, FALSE, FALSE, 0);
-}
-
-static void
-gs_window_init (GSWindow *window)
-{
- window->priv = GS_WINDOW_GET_PRIVATE (window);
-
- window->priv->geometry.x = -1;
- window->priv->geometry.y = -1;
- window->priv->geometry.width = -1;
- window->priv->geometry.height = -1;
-
- window->priv->last_x = -1;
- window->priv->last_y = -1;
-
- gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
-
- gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);
- gtk_window_set_skip_pager_hint (GTK_WINDOW (window), TRUE);
-
- gtk_window_set_keep_above (GTK_WINDOW (window), TRUE);
-
- gtk_window_fullscreen (GTK_WINDOW (window));
-
- gtk_widget_set_events (GTK_WIDGET (window),
- gtk_widget_get_events (GTK_WIDGET (window))
- | GDK_POINTER_MOTION_MASK
- | GDK_BUTTON_PRESS_MASK
- | GDK_BUTTON_RELEASE_MASK
- | GDK_KEY_PRESS_MASK
- | GDK_KEY_RELEASE_MASK
- | GDK_EXPOSURE_MASK
- | GDK_VISIBILITY_NOTIFY_MASK
- | GDK_ENTER_NOTIFY_MASK
- | GDK_LEAVE_NOTIFY_MASK);
-
- window->priv->vbox = gtk_vbox_new (FALSE, 12);
- gtk_widget_show (window->priv->vbox);
- gtk_container_add (GTK_CONTAINER (window), window->priv->vbox);
-
- window->priv->drawing_area = gtk_drawing_area_new ();
- gtk_widget_show (window->priv->drawing_area);
- gtk_box_pack_start (GTK_BOX (window->priv->vbox), window->priv->drawing_area, TRUE, TRUE, 0);
- create_info_bar (window);
-
- force_no_pixmap_background (window->priv->drawing_area);
-}
-
-static void
-remove_command_watches (GSWindow *window)
-{
- if (window->priv->lock_watch_id != 0)
- {
- g_source_remove (window->priv->lock_watch_id);
- window->priv->lock_watch_id = 0;
- }
- if (window->priv->keyboard_watch_id != 0)
- {
- g_source_remove (window->priv->keyboard_watch_id);
- window->priv->keyboard_watch_id = 0;
- }
-}
-
-static void
-gs_window_finalize (GObject *object)
-{
- GSWindow *window;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (GS_IS_WINDOW (object));
-
- window = GS_WINDOW (object);
-
- g_return_if_fail (window->priv != NULL);
-
- g_free (window->priv->logout_command);
- g_free (window->priv->keyboard_command);
-
- if (window->priv->info_bar_timer_id > 0)
- {
- g_source_remove (window->priv->info_bar_timer_id);
- }
-
- remove_watchdog_timer (window);
- remove_popup_dialog_idle (window);
-
- if (window->priv->timer)
- {
- g_timer_destroy (window->priv->timer);
- }
-
- remove_key_events (window);
-
- remove_command_watches (window);
-
- gs_window_dialog_finish (window);
-
- if (window->priv->background_pixmap)
- {
- g_object_unref (window->priv->background_pixmap);
- }
-
- G_OBJECT_CLASS (gs_window_parent_class)->finalize (object);
-}
-
-GSWindow *
-gs_window_new (GdkScreen *screen,
- int monitor,
- gboolean lock_enabled)
-{
- GObject *result;
-
- result = g_object_new (GS_TYPE_WINDOW,
- "type", GTK_WINDOW_POPUP,
- "screen", screen,
- "monitor", monitor,
- "lock-enabled", lock_enabled,
- NULL);
-
- return GS_WINDOW (result);
-}