File gnome-screensaver-xvkbd-on-lock.patch of Package gnome-screensaver

Index: gnome-screensaver-2.91.2/src/gnome-screensaver-dialog.c
===================================================================
--- gnome-screensaver-2.91.2.orig/src/gnome-screensaver-dialog.c
+++ gnome-screensaver-2.91.2/src/gnome-screensaver-dialog.c
@@ -119,10 +119,19 @@ response_ok (void)
         fflush (stdout);
 }
 
+static GPid    xvkbd_pid;
+static gboolean xvkbd_running = FALSE;
+
 static gboolean
 quit_response_ok (void)
 {
         response_ok ();
+
+        if (xvkbd_running) {
+                xvkbd_running = FALSE;
+                kill (xvkbd_pid, 9);
+        }
+
         gtk_main_quit ();
         return FALSE;
 }
@@ -131,6 +140,12 @@ static gboolean
 quit_response_cancel (void)
 {
         response_cancel ();
+
+        if (xvkbd_running) {
+                xvkbd_running = FALSE;
+                kill (xvkbd_pid, 9);
+        }
+
         gtk_main_quit ();
         return FALSE;
 }
@@ -422,6 +437,14 @@ popup_dialog_idle (void)
         return FALSE;
 }
 
+static void
+handle_sigterm (int sig)
+{
+        if (xvkbd_running)
+                kill (xvkbd_pid, 9);
+
+        exit (0);
+}
 
 /*
  * Copyright (c) 1991-2004 Jamie Zawinski <jwz@jwz.org>
@@ -582,6 +605,8 @@ main (int    argc,
                 exit (1);
         }
 
+        signal (SIGTERM, handle_sigterm);
+
         if (show_version) {
                 g_print ("%s %s\n", argv [0], VERSION);
                 exit (1);
@@ -598,10 +623,27 @@ main (int    argc,
 
         gs_debug_init (verbose, FALSE);
 
+        int status = system ("hal-find-by-property --key system.formfactor.subtype --string tabletpc");
+        if (WIFEXITED (status) && WEXITSTATUS (status) == 0) {
+                gchar **arguments[] = { "/usr/bin/xvkbd", "-always-on-top", "-compact", "-geometry", "-0-0", NULL };
+                error = NULL;
+
+                if (g_spawn_async (g_get_home_dir (), arguments, NULL, 0, NULL, NULL,
+                                    &xvkbd_pid, &error))
+                        xvkbd_running = TRUE;
+                else {
+                        g_warning ("Could not spawn xvkbd: %s\n", error->message);
+                        g_error_free (error);
+
+                }
+	 }
         g_idle_add ((GSourceFunc)popup_dialog_idle, NULL);
 
         gtk_main ();
 
+        if (xvkbd_running)
+                kill (xvkbd_pid, 9);
+
         gs_profile_end (NULL);
         gs_debug_shutdown ();
 
Index: gnome-screensaver-2.91.2/src/gs-window-x11.c
===================================================================
--- gnome-screensaver-2.91.2.orig/src/gs-window-x11.c
+++ gnome-screensaver-2.91.2/src/gs-window-x11.c
@@ -633,6 +633,49 @@ x11_window_is_ours (Window window)
         return ret;
 }
 
+#define GET_DISPLAY gdk_x11_display_get_xdisplay (gdk_display_get_default ())
+
+GdkWindow *xvkbd_window = NULL;
+
+static gboolean
+is_xvkbd_window (Window window)
+{
+        gboolean ret = FALSE;
+        XClassHint class_hint = { NULL, NULL };
+
+	gdk_error_trap_push ();
+        if (XGetClassHint (GET_DISPLAY, window, &class_hint)) {
+                if (g_strstr_len (class_hint.res_name,
+                                  strlen (class_hint.res_name),
+                                  "xvkbd"))
+                        ret = TRUE;
+        }
+
+	if (G_UNLIKELY (gdk_error_trap_pop () == BadWindow)) ;
+
+        return ret;
+}
+
+static void
+setup_xvkbd_window (GSWindow *gswindow, Window window)
+{
+	gs_debug ("Setting up xvkbd_window from window %d", (int) window);
+
+	xvkbd_window = gdk_x11_window_foreign_new_for_display (gtk_widget_get_display (widget), window);
+        gdk_window_hide (xvkbd_window);
+        gdk_window_set_override_redirect (xvkbd_window, TRUE);
+        gdk_window_set_events (xvkbd_window, gdk_window_get_events (xvkbd_window) | GDK_STRUCTURE_MASK);
+       
+        int display_width, display_height, width, height;
+        GdkWindow *root = gdk_screen_get_root_window (gdk_window_get_screen (xvkbd_window));
+       
+        gdk_window_get_geometry (xvkbd_window, NULL, NULL, &width, &height);
+        gdk_window_get_geometry (root, NULL, NULL, &display_width, &display_height);
+        gdk_window_reparent (xvkbd_window, NULL, display_width - width, display_height - height);
+        gdk_window_set_transient_for (xvkbd_window, gtk_widget_get_window (GTK_WIDGET (gswindow)));
+        gdk_window_show (xvkbd_window);
+}
+
 #ifdef HAVE_SHAPE_EXT
 static void
 unshape_window (GSWindow *window)
@@ -655,6 +698,16 @@ gs_window_xevent (GSWindow  *window,
         /* 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 CreateNotify :
+                {
+                        XCreateWindowEvent *create_event;
+
+                        create_event = &ev->xcreatewindow;
+                        if (!x11_window_is_ours (create_event->window) && is_xvkbd_window (create_event->window))
+                                setup_xvkbd_window (window, create_event->window);
+
+                        break;
+                }
         case MapNotify:
                 {
                         XMapEvent *xme = &ev->xmap;
@@ -672,7 +725,7 @@ gs_window_xevent (GSWindow  *window,
                         XConfigureEvent *xce = &ev->xconfigure;
 
                         if (! x11_window_is_ours (xce->window)) {
-                                gs_window_raise (window);
+				gs_window_raise (window);
                         } else {
                                 gs_debug ("not raising our windows");
                         }