[gtk+/gtk-3-8] quartz: remove check for keymap changes from update_keymap()



commit f04fe99deb92e425acf1da95a0d8a3455bdc14b4
Author: Michael Natterer <mitch gimp org>
Date:   Thu Jun 20 17:21:25 2013 +0200

    quartz: remove check for keymap changes from update_keymap()
    
    The function is now only called when the keymap has actually
    changed. bug #698183.
    (cherry picked from commit e5e17cf3612191c0497882a6a6b3206dc0ca96cd)

 gdk/quartz/gdkkeys-quartz.c |  427 +++++++++++++++++++++----------------------
 1 files changed, 208 insertions(+), 219 deletions(-)
---
diff --git a/gdk/quartz/gdkkeys-quartz.c b/gdk/quartz/gdkkeys-quartz.c
index 0094102..8ecf79e 100644
--- a/gdk/quartz/gdkkeys-quartz.c
+++ b/gdk/quartz/gdkkeys-quartz.c
@@ -82,17 +82,6 @@ _gdk_quartz_display_get_keymap (GdkDisplay *display)
   return default_keymap;
 }
 
-/* Note: we could check only if building against the 10.5 SDK instead, but
- * that would make non-xml layouts not work in 32-bit which would be a quite
- * bad regression. This way, old unsupported layouts will just not work in
- * 64-bit.
- */
-#ifdef __LP64__
-static TISInputSourceRef current_layout = NULL;
-#else
-static KeyboardLayoutRef current_layout = NULL;
-#endif
-
 /* 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);
  */
@@ -270,7 +259,14 @@ static void
 update_keymap (void)
 {
   const void *chr_data = NULL;
+  guint *p;
+  int i;
 
+  /* Note: we could check only if building against the 10.5 SDK instead, but
+   * that would make non-xml layouts not work in 32-bit which would be a quite
+   * bad regression. This way, old unsupported layouts will just not work in
+   * 64-bit.
+   */
 #ifdef __LP64__
   TISInputSourceRef new_layout = TISCopyCurrentKeyboardLayoutInputSource ();
   CFDataRef layout_data_ref;
@@ -282,228 +278,221 @@ update_keymap (void)
   KLGetCurrentKeyboardLayout (&new_layout);
 #endif
 
-  if (new_layout != current_layout)
-    {
-      guint *p;
-      int i;
-
-      g_free (keyval_array);
-      keyval_array = g_new0 (guint, NUM_KEYCODES * KEYVALS_PER_KEYCODE);
+  g_free (keyval_array);
+  keyval_array = g_new0 (guint, NUM_KEYCODES * KEYVALS_PER_KEYCODE);
 
 #ifdef __LP64__
-      layout_data_ref = (CFDataRef) TISGetInputSourceProperty
-       (new_layout, kTISPropertyUnicodeKeyLayoutData);
+  layout_data_ref = (CFDataRef) TISGetInputSourceProperty
+    (new_layout, kTISPropertyUnicodeKeyLayoutData);
 
-      if (layout_data_ref)
-       chr_data = CFDataGetBytePtr (layout_data_ref);
+  if (layout_data_ref)
+    chr_data = CFDataGetBytePtr (layout_data_ref);
 
-      if (chr_data == NULL)
-       {
-         g_error ("cannot get keyboard layout data");
-         return;
-       }
+  if (chr_data == NULL)
+    {
+      g_error ("cannot get keyboard layout data");
+      return;
+    }
 #else
-      /* Get the layout kind */
-      KLGetKeyboardLayoutProperty (new_layout, kKLKind, (const void **)&layout_kind);
-
-      /* 8-bit-only keyabord layout */
-      if (layout_kind == kKLKCHRKind)
-       { 
-         /* Get chr data */
-         KLGetKeyboardLayoutProperty (new_layout, kKLKCHRData, (const void **)&chr_data);
-         
-         for (i = 0; i < NUM_KEYCODES; i++) 
-           {
-             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_KEY_ISO_Left_Tab for that.
-                      */
-                     if (found && p[j] == GDK_KEY_Tab && modifiers[j] == shiftKey)
-                       p[j] = GDK_KEY_ISO_Left_Tab;
-
-                     if (!found)
-                        p[j] = gdk_unicode_to_keyval (uc);
-                   }
-               }
-
-             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;
-           }
-       }
-      /* unicode keyboard layout */
-      else if (layout_kind == kKLKCHRuchrKind || layout_kind == kKLuchrKind)
-       { 
-         /* Get chr data */
-         KLGetKeyboardLayoutProperty (new_layout, kKLuchrData, (const void **)&chr_data);
+
+  /* Get the layout kind */
+  KLGetKeyboardLayoutProperty (new_layout, kKLKind, (const void **)&layout_kind);
+
+  /* 8-bit-only keyabord layout */
+  if (layout_kind == kKLKCHRKind)
+    {
+      /* Get chr data */
+      KLGetKeyboardLayoutProperty (new_layout, kKLKCHRData, (const void **)&chr_data);
+
+      for (i = 0; i < NUM_KEYCODES; i++)
+        {
+          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_KEY_ISO_Left_Tab for that.
+                   */
+                  if (found && p[j] == GDK_KEY_Tab && modifiers[j] == shiftKey)
+                    p[j] = GDK_KEY_ISO_Left_Tab;
+
+                  if (!found)
+                    p[j] = gdk_unicode_to_keyval (uc);
+                }
+            }
+
+          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;
+        }
+    }
+  /* unicode keyboard layout */
+  else if (layout_kind == kKLKCHRuchrKind || layout_kind == kKLuchrKind)
+    {
+      /* Get chr data */
+      KLGetKeyboardLayoutProperty (new_layout, kKLuchrData, (const void **)&chr_data);
 #endif
-         
-         for (i = 0; i < NUM_KEYCODES; i++) 
-           {
-             int j;
-             UInt32 modifiers[] = {0, shiftKey, optionKey, shiftKey | optionKey};
-              UniChar chars[4];
-              UniCharCount nChars;
-
-             p = keyval_array + i * KEYVALS_PER_KEYCODE;
-
-             for (j = 0; j < KEYVALS_PER_KEYCODE; j++)
-               {
-                 UInt32 state = 0;
-                 OSStatus err;
-                 UInt16 key_code;
-                 UniChar uc;
-                 
-                 key_code = modifiers[j] | i;
-                 err = UCKeyTranslate (chr_data, i, kUCKeyActionDisplay,
-                                       (modifiers[j] >> 8) & 0xFF,
-                                       LMGetKbdType(),
-                                       0,
-                                       &state, 4, &nChars, chars);
-
-                  /* FIXME: Theoretically, we can get multiple UTF-16 values;
-                  * we should convert them to proper unicode and figure
-                  * out whether there are really keyboard layouts that
-                  * give us more than one character for one keypress. */
-                 if (err == noErr && nChars == 1)
-                   {
-                     int k;
-                     gboolean found = FALSE;
-
-                     /* A few <Shift><Option>keys return two
-                      * characters, the first of which is U+00a0,
-                      * which isn't interesting; so we return the
-                      * second. More sophisticated handling is the
-                      * job of a GtkIMContext.
-                      *
-                      * If state isn't zero, it means that it's a
-                      * dead key of some sort. Some of those are
-                      * enumerated in the special_ucs_table with the
-                      * high nibble set to f to push it into the
-                      * private use range. Here we do the same.
-                      */
-                     if (state != 0)
-                       chars[nChars - 1] |= 0xf000;
-                     uc = chars[nChars - 1];
-
-                     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_KEY_ISO_Left_Tab for that.
-                      */
-                     if (found && p[j] == GDK_KEY_Tab && modifiers[j] == shiftKey)
-                       p[j] = GDK_KEY_ISO_Left_Tab;
-
-                     if (!found)
-                        p[j] = gdk_unicode_to_keyval (uc);
-                   }
-               }
-
-             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;
-           }
+
+      for (i = 0; i < NUM_KEYCODES; i++)
+        {
+          int j;
+          UInt32 modifiers[] = {0, shiftKey, optionKey, shiftKey | optionKey};
+          UniChar chars[4];
+          UniCharCount nChars;
+
+          p = keyval_array + i * KEYVALS_PER_KEYCODE;
+
+          for (j = 0; j < KEYVALS_PER_KEYCODE; j++)
+            {
+              UInt32 state = 0;
+              OSStatus err;
+              UInt16 key_code;
+              UniChar uc;
+
+              key_code = modifiers[j] | i;
+              err = UCKeyTranslate (chr_data, i, kUCKeyActionDisplay,
+                                    (modifiers[j] >> 8) & 0xFF,
+                                    LMGetKbdType(),
+                                    0,
+                                    &state, 4, &nChars, chars);
+
+              /* FIXME: Theoretically, we can get multiple UTF-16
+               * values; we should convert them to proper unicode and
+               * figure out whether there are really keyboard layouts
+               * that give us more than one character for one
+               * keypress.
+               */
+              if (err == noErr && nChars == 1)
+                {
+                  int k;
+                  gboolean found = FALSE;
+
+                  /* A few <Shift><Option>keys return two characters,
+                   * the first of which is U+00a0, which isn't
+                   * interesting; so we return the second. More
+                   * sophisticated handling is the job of a
+                   * GtkIMContext.
+                   *
+                   * If state isn't zero, it means that it's a dead
+                   * key of some sort. Some of those are enumerated in
+                   * the special_ucs_table with the high nibble set to
+                   * f to push it into the private use range. Here we
+                   * do the same.
+                   */
+                  if (state != 0)
+                    chars[nChars - 1] |= 0xf000;
+                  uc = chars[nChars - 1];
+
+                  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_KEY_ISO_Left_Tab for that.
+                   */
+                  if (found && p[j] == GDK_KEY_Tab && modifiers[j] == shiftKey)
+                    p[j] = GDK_KEY_ISO_Left_Tab;
+
+                  if (!found)
+                    p[j] = gdk_unicode_to_keyval (uc);
+                }
+            }
+
+          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;
+        }
 #ifndef __LP64__
-       }
-      else
-       {
-         g_error ("unknown type of keyboard layout (neither KCHR nor uchr)"
-                  " - not supported right now");
-       }
+    }
+  else
+    {
+      g_error ("unknown type of keyboard layout (neither KCHR nor uchr)"
+               " - not supported right now");
+    }
 #endif
 
-      for (i = 0; i < G_N_ELEMENTS (modifier_keys); i++)
-       {
-         p = keyval_array + modifier_keys[i].keycode * KEYVALS_PER_KEYCODE;
-
-         if (p[0] == 0 && p[1] == 0 && 
-             p[2] == 0 && p[3] == 0)
-           p[0] = modifier_keys[i].keyval;
-       }
+  for (i = 0; i < G_N_ELEMENTS (modifier_keys); i++)
+    {
+      p = keyval_array + modifier_keys[i].keycode * KEYVALS_PER_KEYCODE;
 
-      for (i = 0; i < G_N_ELEMENTS (function_keys); i++)
-       {
-         p = keyval_array + function_keys[i].keycode * KEYVALS_PER_KEYCODE;
+      if (p[0] == 0 && p[1] == 0 &&
+          p[2] == 0 && p[3] == 0)
+        p[0] = modifier_keys[i].keyval;
+    }
 
-          p[0] = function_keys[i].keyval;
-          p[1] = p[2] = p[3] = 0;
-       }
+  for (i = 0; i < G_N_ELEMENTS (function_keys); i++)
+    {
+      p = keyval_array + function_keys[i].keycode * KEYVALS_PER_KEYCODE;
 
-      for (i = 0; i < G_N_ELEMENTS (known_numeric_keys); i++)
-       {
-         p = keyval_array + known_numeric_keys[i].keycode * KEYVALS_PER_KEYCODE;
+      p[0] = function_keys[i].keyval;
+      p[1] = p[2] = p[3] = 0;
+    }
 
-         if (p[0] == known_numeric_keys[i].normal_keyval)
-            p[0] = known_numeric_keys[i].keypad_keyval;
-       }
-      
-      if (current_layout)
-       g_signal_emit_by_name (default_keymap, "keys_changed");
+  for (i = 0; i < G_N_ELEMENTS (known_numeric_keys); i++)
+    {
+      p = keyval_array + known_numeric_keys[i].keycode * KEYVALS_PER_KEYCODE;
 
-      current_layout = new_layout;
+      if (p[0] == known_numeric_keys[i].normal_keyval)
+        p[0] = known_numeric_keys[i].keypad_keyval;
     }
+
+  g_signal_emit_by_name (default_keymap, "keys-changed");
 }
 
 static PangoDirection


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