handling of keyboard under darwin (quartz)



Hello,

The current code in gdk/quartz/gdkkeys-quartz.c uses a deprecated (since 10.5)
API to handle keyboard layout on darwin, which is not available to x86-64
applications.

Here is a possible patch that uses the new TIS API.

Let me know if I should open a bugzilla PR for this patch, or if this patch
is a good start for inclusion in the quartz back-end.

Thanks in advance for your input,

Arno

--- gdk/quartz/gdkkeys-quartz.c.old	2008-10-30 14:31:20.000000000 +0100
+++ gdk/quartz/gdkkeys-quartz.c	2008-10-30 15:31:09.000000000 +0100
@@ -61,7 +61,7 @@
 
 static GdkKeymap *default_keymap = NULL;
 
-static KeyboardLayoutRef current_layout = NULL;
+static TISInputSourceRef current_layout = NULL;
 
 /* This is a table of all keyvals. Each keycode gets KEYVALS_PER_KEYCODE entries.
  * TThere is 1 keyval per modifier (Nothing, Shift, Alt, Shift+Alt);
@@ -179,114 +179,32 @@ const static struct {
 static void
 maybe_update_keymap (void)
 {
-  KeyboardLayoutRef new_layout;
+  TISInputSourceRef new_layout;
 
-  KLGetCurrentKeyboardLayout (&new_layout);
+  new_layout = TISCopyCurrentKeyboardLayoutInputSource ();
 
   if (new_layout != current_layout)
     {
       guint *p;
       int i;
 
-      KeyboardLayoutKind layout_kind;
-      
       g_free (keyval_array);
       keyval_array = g_new0 (guint, NUM_KEYCODES * KEYVALS_PER_KEYCODE);
-
-      /* Get the layout kind */
-      KLGetKeyboardLayoutProperty (new_layout, kKLKind, (const void **)&layout_kind);
-
-      /* 8-bit-only keyabord layout */
-      if (layout_kind == kKLKCHRKind)
+      
 	{ 
-	  const void *chr_data;
+	  const void *chr_data = NULL;
 	  
 	  /* Get chr data */
-	  KLGetKeyboardLayoutProperty (new_layout, kKLKCHRData, (const void **)&chr_data);
+	  CFDataRef currentKeyLayoutDataRef = (CFDataRef) TISGetInputSourceProperty (new_layout, kTISPropertyUnicodeKeyLayoutData);
+	  if (currentKeyLayoutDataRef)
+	    chr_data = CFDataGetBytePtr (currentKeyLayoutDataRef);
 	  
-	  for (i = 0; i < NUM_KEYCODES; i++) 
+	  if (chr_data == NULL)
 	    {
-	      int j;
-	      UInt32 modifiers[] = {0, shiftKey, optionKey, shiftKey | optionKey};
-
-	      p = keyval_array + i * KEYVALS_PER_KEYCODE;
-	      
-	      for (j = 0; j < KEYVALS_PER_KEYCODE; j++)
-		{
-		  UInt32 c, state = 0;
-		  UInt16 key_code;
-		  UniChar uc;
-		  
-		  key_code = modifiers[j] | i;
-		  c = KeyTranslate (chr_data, key_code, &state);
-
-		  if (state != 0)
-		    {
-		      UInt32 state2 = 0;
-		      c = KeyTranslate (chr_data, key_code | 128, &state2);
-		    }
-
-		  if (c != 0 && c != 0x10)
-		    {
-		      int k;
-		      gboolean found = FALSE;
-
-		      /* FIXME: some keyboard layouts (e.g. Russian) use
-                       * a different 8-bit character set. We should
-                       * check for this. Not a serious problem, because
-		       * most (all?) of these layouts also have a
-		       * uchr version. 
-		       */
-		      uc = macroman2ucs (c);
-
-		      for (k = 0; k < G_N_ELEMENTS (special_ucs_table); k++) 
-			{
-			  if (special_ucs_table[k].ucs_value == uc)
-			    {
-			      p[j] = special_ucs_table[k].keyval;
-			      found = TRUE;
-			      break;
-			    }
-			}
-		      
-		      /* Special-case shift-tab since GTK+ expects
-		       * GDK_ISO_Left_Tab for that. 
-		       */
-		      if (found && p[j] == GDK_Tab && modifiers[j] == shiftKey) 
-			p[j] = GDK_ISO_Left_Tab;
-
-		      if (!found)
-                        {
-                          guint tmp;
-                          
-                          tmp = gdk_unicode_to_keyval (uc);
-                          if (tmp != (uc | 0x01000000))
-                            p[j] = tmp;
-                          else
-                            p[j] = 0;
-                        }
-		    }
-		}
-	      
-	      if (p[3] == p[2])
-		p[3] = 0;
-	      if (p[2] == p[1])
-		p[2] = 0;
-	      if (p[1] == p[0])
-		p[1] = 0;
-	      if (p[0] == p[2] && 
-		  p[1] == p[3])
-		p[2] = p[3] = 0;
+	      g_error ("cannot get keyboard layout data");
+	      return;
 	    }
-	}
-      /* unicode keyboard layout */
-      else if (layout_kind == kKLKCHRuchrKind || layout_kind == kKLuchrKind)
-	{ 
-	  const void *chr_data;
-	  
-	  /* Get chr data */
-	  KLGetKeyboardLayoutProperty (new_layout, kKLuchrData, (const void **)&chr_data);
-	  
+
 	  for (i = 0; i < NUM_KEYCODES; i++) 
 	    {
 	      int j;
@@ -362,11 +280,6 @@ maybe_update_keymap (void)
 		p[2] = p[3] = 0;
 	    }
 	}
-      else
-	{
-	  g_error ("unknown type of keyboard layout (neither KCHR nor uchr)"
-	           " - not supported right now");
-	}
 
       for (i = 0; i < G_N_ELEMENTS (known_keys); i++)
 	{


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]