Improved virtual keyboard demo to use a relocatable GtkWindow.
authorbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Mon, 12 Nov 2001 20:02:21 +0000 (20:02 +0000)
committerbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Mon, 12 Nov 2001 20:02:21 +0000 (20:02 +0000)
git-svn-id: http://svn.gnome.org/svn/at-spi/trunk@85 e2bd861d-eb25-0410-b326-f6ed22b6b98c

ChangeLog
test/keysynth-demo.c

index 19db2dd..96b7cd6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2001-11-12  Bill Haneman <bill.haneman@sun.com>
+
+        * test/keysynth-demo.c:
+        Use a 'realize' signal-handler to set the WM properties for
+        the virtual keyboard, rather than making it a "POPUP" type
+        override-redirect window (thanks to anders carlsson for that
+        tip!)
+
 2001-11-11  Bill Haneman <bill.haneman@sun.com>
 
        * test/Makefile.am:
index 9bf7130..c112275 100644 (file)
 #define LABELMAXLEN 20
 #define MIN_KEYCODE 9
 #define CAPSLOCK_KEYCODE 66
+#define SHIFT_L_KEYCODE 50
+#define SHIFT_R_KEYCODE 62
 
 /* these can be increased to access more keys */
 #define MAX_ROWS 5
 #define MAX_COLUMNS 14
 
 static KeystrokeListener *key_listener;
+static KeystrokeListener *switch_listener;
 
 static boolean shift_latched = False;
 static boolean caps_lock = False;
 static GtkButton **buttons[MAX_ROWS];
 
 static void
-label_buttons()
+label_buttons(boolean shifted)
 {
   int i, j;
   KeySym keysym;
@@ -48,13 +51,11 @@ label_buttons()
   char label[LABELMAXLEN] = " ";
   char *button_label;
   char *keysymstring;
-  boolean shifted;
   
   for (i=0; i<MAX_ROWS; ++i)
     {
       for (j=0; j<MAX_COLUMNS; ++j, ++keycode)
         {
-         shifted = caps_lock || shift_latched;
          keysym = (KeySym) XKeycodeToKeysym (GDK_DISPLAY(), keycode, shifted ? 1 : 0);
           /* Note: these routines are not i18n-savvy,  we need to use XIM, other methods here */
          if (keysym && g_ascii_isprint((int)keysym))
@@ -81,6 +82,12 @@ label_buttons()
 }
 
 static void
+show_shift (GtkButton *button, boolean *is_shifted)
+{
+ label_buttons (*is_shifted ^ caps_lock);      
+}
+
+static void
 do_shift (GtkButton *button)
 {
   static KeyCode shift_keycode = 0;
@@ -88,7 +95,7 @@ do_shift (GtkButton *button)
   /* Note: in a real onscreen keyboard shift keycode should not be hard-coded! */
   shift_latched = !shift_latched;
   generateKeyEvent (shift_keycode, shift_latched ? KEY_PRESS : KEY_RELEASE);
-  if (buttons) label_buttons (buttons);
+  if (buttons) label_buttons (caps_lock || shift_latched);
 }
 
 static void
@@ -96,10 +103,34 @@ keysynth_exit()
 {
   if (shift_latched) do_shift (NULL);
   deregisterKeystrokeListener (key_listener, KEYMASK_ALT );
+  deregisterKeystrokeListener (switch_listener, KEYMASK_UNMODIFIED );
   SPI_exit ();
 }
 
 static void
+keysynth_realize (GtkWidget *widget)
+{
+  XWMHints wm_hints;
+  Atom wm_window_protocols[2];
+  static gboolean initialized = FALSE;
+  
+  if (!initialized)
+    {
+      wm_window_protocols[0] = gdk_x11_get_xatom_by_name ("WM_DELETE_WINDOW");
+      wm_window_protocols[1] = gdk_x11_get_xatom_by_name ("_NET_WM_PING");
+    }
+  
+  wm_hints.flags = InputHint;
+  wm_hints.input = False;
+  
+  XSetWMHints (GDK_WINDOW_XDISPLAY (widget->window),
+              GDK_WINDOW_XWINDOW (widget->window), &wm_hints);
+  
+  XSetWMProtocols (GDK_WINDOW_XDISPLAY (widget->window),
+                  GDK_WINDOW_XWINDOW (widget->window), wm_window_protocols, 2);
+}
+
+static void
 button_exit(GtkButton *notused, void *alsonotused)
 {
   keysynth_exit();
@@ -118,16 +149,25 @@ is_command_key (void *p)
     }
 }
 
+static boolean
+switch_callback (void *p)
+{
+  return FALSE;
+}
+
 static void
 synth_keycode (GtkButton *button, KeyCode *keycode)
 {
-  if (*keycode)  generateKeyEvent ((long) *keycode, KEY_PRESSRELEASE);
   if (shift_latched) do_shift (button);
-  if (*keycode == CAPSLOCK_KEYCODE)
+  if (*keycode)
     {
-      caps_lock = !caps_lock;      
-      label_buttons ();
-    }
+      if (*keycode == CAPSLOCK_KEYCODE)
+        {
+          caps_lock = !caps_lock;           
+          label_buttons (caps_lock || shift_latched);
+        }
+      generateKeyEvent ((long) *keycode, KEY_PRESSRELEASE);
+    }      
 }
 
 static void
@@ -136,17 +176,20 @@ create_vkbd()
   GtkWidget *window, *button, *container, *hbox;
   int i, j;
   KeyCode *keycodeptr, keycode = MIN_KEYCODE;
+  static boolean true_val = True;
+  static boolean false_val = False;
 
   window = g_object_connect (gtk_widget_new (gtk_window_get_type (),
                                             "user_data", NULL,
                                             "can_focus", FALSE,
-                                            "type", GTK_WINDOW_POPUP,
+                                            "type", GTK_WINDOW_TOPLEVEL,
                                             "window-position", GTK_WIN_POS_CENTER,
                                             "title", "test",
                                             "allow_grow", FALSE,
                                             "allow_shrink", FALSE,
                                             "border_width", 10,
                                             NULL),
+                            "signal::realize", keysynth_realize, NULL,
                             "signal::destroy", keysynth_exit, NULL,
                             NULL);
   
@@ -165,7 +208,6 @@ create_vkbd()
        {
          keycodeptr = (KeyCode *) g_new0 (KeyCode, 1);
          *keycodeptr = keycode;
-         ++keycode;
          buttons[i][j] = g_object_connect (gtk_widget_new (gtk_button_get_type (),
                                                     "GtkWidget::parent", hbox,
                                                     "GtkWidget::visible", TRUE,
@@ -173,6 +215,14 @@ create_vkbd()
                                     "signal::clicked",
                                     synth_keycode, keycodeptr,
                                     NULL);
+         if (keycode == SHIFT_L_KEYCODE || keycode == SHIFT_R_KEYCODE)
+           {
+             g_object_connect (buttons[i][j], "signal::pressed", show_shift,
+                               &true_val, NULL);  
+             g_object_connect (buttons[i][j], "signal::released", show_shift,
+                               &false_val, NULL);  
+           }
+         ++keycode;
        }
     } 
   hbox = gtk_widget_new (gtk_hbox_get_type(),
@@ -195,14 +245,15 @@ create_vkbd()
                             "signal::clicked",
                             do_shift, NULL,
                             NULL);
-  label_buttons ();
+  label_buttons (caps_lock || shift_latched);
   gtk_widget_show (window);
-
 }
 
 int
 main(int argc, char **argv)
 {
+  KeySet spacebar_set;
+  
   if ((argc > 1) && (!strncmp(argv[1],"-h",2)))
   {
     printf ("Usage: keysynth-demo\n");
@@ -219,8 +270,22 @@ main(int argc, char **argv)
                            (KeySet *) ALL_KEYS,
                            KEYMASK_ALT,
                            (unsigned long) ( KeyPress | KeyRelease),
-                           KEYLISTENER_CANCONSUME);
+                           KEYLISTENER_CANCONSUME | KEYLISTENER_ALLWINDOWS);
   create_vkbd();  
 
+  /* register a listener on the spacebar, to serve as a 'single switch' */
+  spacebar_set.keysyms = g_new0 (unsigned long, 1);
+  spacebar_set.keycodes = g_new0 (unsigned short, 1);
+  spacebar_set.len = 1;
+  spacebar_set.keysyms[0] = (unsigned long) ' ';
+  spacebar_set.keycodes[0] = (unsigned short) 0;
+  switch_listener = createKeystrokeListener(switch_callback);
+  /* registerKeystrokeListener(switch_listener,
+                           &spacebar_set,
+                           KEYMASK_UNMODIFIED,
+                           (unsigned long) ( KeyPress | KeyRelease),
+                           KEYLISTENER_CANCONSUME);
+  */
+  
   SPI_event_main(TRUE);
 }