diff options
Diffstat (limited to 'src/gs-grab-x11.c.orig')
-rw-r--r-- | src/gs-grab-x11.c.orig | 672 |
1 files changed, 0 insertions, 672 deletions
diff --git a/src/gs-grab-x11.c.orig b/src/gs-grab-x11.c.orig deleted file mode 100644 index e6e7f22..0000000 --- a/src/gs-grab-x11.c.orig +++ /dev/null @@ -1,672 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2004-2006 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 <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <gdk/gdk.h> -#include <gdk/gdkx.h> -#include <gtk/gtk.h> - -#ifdef HAVE_XF86MISCSETGRABKEYSSTATE -# include <X11/extensions/xf86misc.h> -#endif /* HAVE_XF86MISCSETGRABKEYSSTATE */ - -#include "gs-window.h" -#include "gs-grab.h" -#include "gs-debug.h" - -static void gs_grab_class_init (GSGrabClass *klass); -static void gs_grab_init (GSGrab *grab); -static void gs_grab_finalize (GObject *object); - -#define GS_GRAB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_GRAB, GSGrabPrivate)) - -G_DEFINE_TYPE (GSGrab, gs_grab, G_TYPE_OBJECT) - -static gpointer grab_object = NULL; - -struct GSGrabPrivate -{ - guint mouse_hide_cursor : 1; - GdkWindow *mouse_grab_window; - GdkWindow *keyboard_grab_window; - GdkScreen *mouse_grab_screen; - GdkScreen *keyboard_grab_screen; - - GtkWidget *invisible; -}; - -static GdkCursor * -get_cursor (void) -{ - GdkBitmap *empty_bitmap; - GdkCursor *cursor; - GdkColor useless; - char invisible_cursor_bits [] = { 0x0 }; - - useless.red = useless.green = useless.blue = 0; - useless.pixel = 0; - - empty_bitmap = gdk_bitmap_create_from_data (NULL, - invisible_cursor_bits, - 1, 1); - - cursor = gdk_cursor_new_from_pixmap (empty_bitmap, - empty_bitmap, - &useless, - &useless, 0, 0); - - g_object_unref (empty_bitmap); - - return cursor; -} - -static const char * -grab_string (int status) -{ - switch (status) - { - case GDK_GRAB_SUCCESS: - return "GrabSuccess"; - case GDK_GRAB_ALREADY_GRABBED: - return "AlreadyGrabbed"; - case GDK_GRAB_INVALID_TIME: - return "GrabInvalidTime"; - case GDK_GRAB_NOT_VIEWABLE: - return "GrabNotViewable"; - case GDK_GRAB_FROZEN: - return "GrabFrozen"; - default: - { - static char foo [255]; - sprintf (foo, "unknown status: %d", status); - return foo; - } - } -} - -#ifdef HAVE_XF86MISCSETGRABKEYSSTATE -/* This function enables and disables the Ctrl-Alt-KP_star and - Ctrl-Alt-KP_slash hot-keys, which (in XFree86 4.2) break any - grabs and/or kill the grabbing client. That would effectively - unlock the screen, so we don't like that. - - The Ctrl-Alt-KP_star and Ctrl-Alt-KP_slash hot-keys only exist - if AllowDeactivateGrabs and/or AllowClosedownGrabs are turned on - in XF86Config. I believe they are disabled by default. - - This does not affect any other keys (specifically Ctrl-Alt-BS or - Ctrl-Alt-F1) but I wish it did. Maybe it will someday. - */ -static void -xorg_lock_smasher_set_active (GSGrab *grab, - gboolean active) -{ - int status, event, error; - - if (!XF86MiscQueryExtension (GDK_DISPLAY (), &event, &error)) - { - gs_debug ("No XFree86-Misc extension present"); - return; - } - - if (active) - { - gs_debug ("Enabling the x.org grab smasher"); - } - else - { - gs_debug ("Disabling the x.org grab smasher"); - } - - gdk_error_trap_push (); - - status = XF86MiscSetGrabKeysState (GDK_DISPLAY (), active); - - gdk_display_sync (gdk_display_get_default ()); - gdk_error_trap_pop (); - - if (active && status == MiscExtGrabStateAlready) - { - /* shut up, consider this success */ - status = MiscExtGrabStateSuccess; - } - - gs_debug ("XF86MiscSetGrabKeysState(%s) returned %s\n", - active ? "on" : "off", - (status == MiscExtGrabStateSuccess ? "MiscExtGrabStateSuccess" : - status == MiscExtGrabStateLocked ? "MiscExtGrabStateLocked" : - status == MiscExtGrabStateAlready ? "MiscExtGrabStateAlready" : - "unknown value")); -} -#else -static void -xorg_lock_smasher_set_active (GSGrab *grab, - gboolean active) -{ -} -#endif /* HAVE_XF86MISCSETGRABKEYSSTATE */ - -static int -gs_grab_get_keyboard (GSGrab *grab, - GdkWindow *window, - GdkScreen *screen) -{ - GdkGrabStatus status; - - g_return_val_if_fail (window != NULL, FALSE); - g_return_val_if_fail (screen != NULL, FALSE); - - gs_debug ("Grabbing keyboard widget=%X", (guint32) GDK_WINDOW_XID (window)); - status = gdk_keyboard_grab (window, FALSE, GDK_CURRENT_TIME); - - if (status == GDK_GRAB_SUCCESS) - { - if (grab->priv->keyboard_grab_window != NULL) - { - g_object_remove_weak_pointer (G_OBJECT (grab->priv->keyboard_grab_window), - (gpointer *) &grab->priv->keyboard_grab_window); - } - grab->priv->keyboard_grab_window = window; - - g_object_add_weak_pointer (G_OBJECT (grab->priv->keyboard_grab_window), - (gpointer *) &grab->priv->keyboard_grab_window); - - grab->priv->keyboard_grab_screen = screen; - } - else - { - gs_debug ("Couldn't grab keyboard! (%s)", grab_string (status)); - } - - return status; -} - -static int -gs_grab_get_mouse (GSGrab *grab, - GdkWindow *window, - GdkScreen *screen, - gboolean hide_cursor) -{ - GdkGrabStatus status; - GdkCursor *cursor; - - g_return_val_if_fail (window != NULL, FALSE); - g_return_val_if_fail (screen != NULL, FALSE); - - cursor = get_cursor (); - - gs_debug ("Grabbing mouse widget=%X", (guint32) GDK_WINDOW_XID (window)); - status = gdk_pointer_grab (window, TRUE, 0, NULL, - (hide_cursor ? cursor : NULL), - GDK_CURRENT_TIME); - - if (status == GDK_GRAB_SUCCESS) - { - if (grab->priv->mouse_grab_window != NULL) - { - g_object_remove_weak_pointer (G_OBJECT (grab->priv->mouse_grab_window), - (gpointer *) &grab->priv->mouse_grab_window); - } - grab->priv->mouse_grab_window = window; - - g_object_add_weak_pointer (G_OBJECT (grab->priv->mouse_grab_window), - (gpointer *) &grab->priv->mouse_grab_window); - - grab->priv->mouse_grab_screen = screen; - grab->priv->mouse_hide_cursor = hide_cursor; - } - - gdk_cursor_unref (cursor); - - return status; -} - -void -gs_grab_keyboard_reset (GSGrab *grab) -{ - if (grab->priv->keyboard_grab_window != NULL) - { - g_object_remove_weak_pointer (G_OBJECT (grab->priv->keyboard_grab_window), - (gpointer *) &grab->priv->keyboard_grab_window); - } - grab->priv->keyboard_grab_window = NULL; - grab->priv->keyboard_grab_screen = NULL; -} - -static gboolean -gs_grab_release_keyboard (GSGrab *grab) -{ - gs_debug ("Ungrabbing keyboard"); - gdk_keyboard_ungrab (GDK_CURRENT_TIME); - - gs_grab_keyboard_reset (grab); - - return TRUE; -} - -void -gs_grab_mouse_reset (GSGrab *grab) -{ - if (grab->priv->mouse_grab_window != NULL) - { - g_object_remove_weak_pointer (G_OBJECT (grab->priv->mouse_grab_window), - (gpointer *) &grab->priv->mouse_grab_window); - } - - grab->priv->mouse_grab_window = NULL; - grab->priv->mouse_grab_screen = NULL; -} - -gboolean -gs_grab_release_mouse (GSGrab *grab) -{ - gs_debug ("Ungrabbing pointer"); - gdk_pointer_ungrab (GDK_CURRENT_TIME); - - gs_grab_mouse_reset (grab); - - return TRUE; -} - -static gboolean -gs_grab_move_mouse (GSGrab *grab, - GdkWindow *window, - GdkScreen *screen, - gboolean hide_cursor) -{ - gboolean result; - GdkWindow *old_window; - GdkScreen *old_screen; - gboolean old_hide_cursor; - - /* if the pointer is not grabbed and we have a - mouse_grab_window defined then we lost the grab */ - if (! gdk_pointer_is_grabbed ()) - { - gs_grab_mouse_reset (grab); - } - - if (grab->priv->mouse_grab_window == window) - { - gs_debug ("Window %X is already grabbed, skipping", - (guint32) GDK_WINDOW_XID (grab->priv->mouse_grab_window)); - return TRUE; - } - -#if 0 - gs_debug ("Intentionally skipping move pointer grabs"); - /* FIXME: GTK doesn't like having the pointer grabbed */ - return TRUE; -#else - if (grab->priv->mouse_grab_window) - { - gs_debug ("Moving pointer grab from %X to %X", - (guint32) GDK_WINDOW_XID (grab->priv->mouse_grab_window), - (guint32) GDK_WINDOW_XID (window)); - } - else - { - gs_debug ("Getting pointer grab on %X", - (guint32) GDK_WINDOW_XID (window)); - } -#endif - - gs_debug ("*** doing X server grab"); - gdk_x11_grab_server (); - - old_window = grab->priv->mouse_grab_window; - old_screen = grab->priv->mouse_grab_screen; - old_hide_cursor = grab->priv->mouse_hide_cursor; - - if (old_window) - { - gs_grab_release_mouse (grab); - } - - result = gs_grab_get_mouse (grab, window, screen, hide_cursor); - - if (result != GDK_GRAB_SUCCESS) - { - sleep (1); - result = gs_grab_get_mouse (grab, window, screen, hide_cursor); - } - - if ((result != GDK_GRAB_SUCCESS) && old_window) - { - gs_debug ("Could not grab mouse for new window. Resuming previous grab."); - gs_grab_get_mouse (grab, old_window, old_screen, old_hide_cursor); - } - - gs_debug ("*** releasing X server grab"); - gdk_x11_ungrab_server (); - gdk_flush (); - - return (result == GDK_GRAB_SUCCESS); -} - -static gboolean -gs_grab_move_keyboard (GSGrab *grab, - GdkWindow *window, - GdkScreen *screen) -{ - gboolean result; - GdkWindow *old_window; - GdkScreen *old_screen; - - if (grab->priv->keyboard_grab_window == window) - { - gs_debug ("Window %X is already grabbed, skipping", - (guint32) GDK_WINDOW_XID (grab->priv->keyboard_grab_window)); - return TRUE; - } - - if (grab->priv->keyboard_grab_window != NULL) - { - gs_debug ("Moving keyboard grab from %X to %X", - (guint32) GDK_WINDOW_XID (grab->priv->keyboard_grab_window), - (guint32) GDK_WINDOW_XID (window)); - } - else - { - gs_debug ("Getting keyboard grab on %X", - (guint32) GDK_WINDOW_XID (window)); - - } - - gs_debug ("*** doing X server grab"); - gdk_x11_grab_server (); - - old_window = grab->priv->keyboard_grab_window; - old_screen = grab->priv->keyboard_grab_screen; - - if (old_window) - { - gs_grab_release_keyboard (grab); - } - - result = gs_grab_get_keyboard (grab, window, screen); - - if (result != GDK_GRAB_SUCCESS) - { - sleep (1); - result = gs_grab_get_keyboard (grab, window, screen); - } - - if ((result != GDK_GRAB_SUCCESS) && old_window) - { - gs_debug ("Could not grab keyboard for new window. Resuming previous grab."); - gs_grab_get_keyboard (grab, old_window, old_screen); - } - - gs_debug ("*** releasing X server grab"); - gdk_x11_ungrab_server (); - gdk_flush (); - - return (result == GDK_GRAB_SUCCESS); -} - -static void -gs_grab_nuke_focus (void) -{ - Window focus = 0; - int rev = 0; - - gs_debug ("Nuking focus"); - - gdk_error_trap_push (); - - XGetInputFocus (GDK_DISPLAY (), &focus, &rev); - - XSetInputFocus (GDK_DISPLAY (), None, RevertToNone, CurrentTime); - - gdk_display_sync (gdk_display_get_default ()); - gdk_error_trap_pop (); -} - -void -gs_grab_release (GSGrab *grab) -{ - gs_debug ("Releasing all grabs"); - - gs_grab_release_mouse (grab); - gs_grab_release_keyboard (grab); - - /* FIXME: is it right to enable this ? */ - xorg_lock_smasher_set_active (grab, TRUE); - - gdk_display_sync (gdk_display_get_default ()); - gdk_flush (); -} - -gboolean -gs_grab_grab_window (GSGrab *grab, - GdkWindow *window, - GdkScreen *screen, - gboolean hide_cursor) -{ - gboolean mstatus = FALSE; - gboolean kstatus = FALSE; - int i; - int retries = 4; - gboolean focus_fuckus = FALSE; - -AGAIN: - - for (i = 0; i < retries; i++) - { - kstatus = gs_grab_get_keyboard (grab, window, screen); - if (kstatus == GDK_GRAB_SUCCESS) - { - break; - } - - /* else, wait a second and try to grab again. */ - sleep (1); - } - - if (kstatus != GDK_GRAB_SUCCESS) - { - if (!focus_fuckus) - { - focus_fuckus = TRUE; - gs_grab_nuke_focus (); - goto AGAIN; - } - } - - for (i = 0; i < retries; i++) - { - mstatus = gs_grab_get_mouse (grab, window, screen, hide_cursor); - if (mstatus == GDK_GRAB_SUCCESS) - { - break; - } - - /* else, wait a second and try to grab again. */ - sleep (1); - } - - if (mstatus != GDK_GRAB_SUCCESS) - { - gs_debug ("Couldn't grab pointer! (%s)", - grab_string (mstatus)); - } - -#if 0 - /* FIXME: release the pointer grab so GTK will work */ - gs_grab_release_mouse (grab); -#endif - - /* When should we allow blanking to proceed? The current theory - is that both a keyboard grab and a mouse grab are mandatory - - - If we don't have a keyboard grab, then we won't be able to - read a password to unlock, so the kbd grab is manditory. - - - If we don't have a mouse grab, then we might not see mouse - clicks as a signal to unblank, on-screen widgets won't work ideally, - and gs_grab_move_to_window() will spin forever when it gets called. - */ - - if (kstatus != GDK_GRAB_SUCCESS || mstatus != GDK_GRAB_SUCCESS) - { - /* Do not blank without a keyboard and mouse grabs. */ - - /* Release keyboard or mouse which was grabbed. */ - if (kstatus == GDK_GRAB_SUCCESS) - { - gs_grab_release_keyboard (grab); - } - if (mstatus == GDK_GRAB_SUCCESS) - { - gs_grab_release_mouse (grab); - } - - return FALSE; - } - - /* Grab is good, go ahead and blank. */ - return TRUE; -} - -/* this is used to grab the keyboard and mouse to the root */ -gboolean -gs_grab_grab_root (GSGrab *grab, - gboolean hide_cursor) -{ - GdkDisplay *display; - GdkWindow *root; - GdkScreen *screen; - gboolean res; - - gs_debug ("Grabbing the root window"); - - display = gdk_display_get_default (); - gdk_display_get_pointer (display, &screen, NULL, NULL, NULL); - root = gdk_screen_get_root_window (screen); - - res = gs_grab_grab_window (grab, root, screen, hide_cursor); - - return res; -} - -/* this is used to grab the keyboard and mouse to an offscreen window */ -gboolean -gs_grab_grab_offscreen (GSGrab *grab, - gboolean hide_cursor) -{ - GdkScreen *screen; - gboolean res; - - gs_debug ("Grabbing an offscreen window"); - - screen = gtk_invisible_get_screen (GTK_INVISIBLE (grab->priv->invisible)); - res = gs_grab_grab_window (grab, grab->priv->invisible->window, screen, hide_cursor); - - return res; -} - -/* This is similar to gs_grab_grab_window but doesn't fail */ -void -gs_grab_move_to_window (GSGrab *grab, - GdkWindow *window, - GdkScreen *screen, - gboolean hide_cursor) -{ - gboolean result = FALSE; - - g_return_if_fail (GS_IS_GRAB (grab)); - - xorg_lock_smasher_set_active (grab, FALSE); - - do - { - result = gs_grab_move_keyboard (grab, window, screen); - gdk_flush (); - } - while (!result); - - do - { - result = gs_grab_move_mouse (grab, window, screen, hide_cursor); - gdk_flush (); - } - while (!result); -} - -static void -gs_grab_class_init (GSGrabClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = gs_grab_finalize; - - g_type_class_add_private (klass, sizeof (GSGrabPrivate)); -} - -static void -gs_grab_init (GSGrab *grab) -{ - grab->priv = GS_GRAB_GET_PRIVATE (grab); - - grab->priv->mouse_hide_cursor = FALSE; - grab->priv->invisible = gtk_invisible_new (); - gtk_widget_show (grab->priv->invisible); -} - -static void -gs_grab_finalize (GObject *object) -{ - GSGrab *grab; - - g_return_if_fail (object != NULL); - g_return_if_fail (GS_IS_GRAB (object)); - - grab = GS_GRAB (object); - - g_return_if_fail (grab->priv != NULL); - - gtk_widget_destroy (grab->priv->invisible); - - G_OBJECT_CLASS (gs_grab_parent_class)->finalize (object); -} - -GSGrab * -gs_grab_new (void) -{ - if (grab_object) - { - g_object_ref (grab_object); - } - else - { - grab_object = g_object_new (GS_TYPE_GRAB, NULL); - g_object_add_weak_pointer (grab_object, - (gpointer *) &grab_object); - } - - return GS_GRAB (grab_object); -} |