]> Pileus Git - ~andy/gtk/commitdiff
New function to determine if keyboard layouts for both LTR and LTR
authorMatthias Clasen <mclasen@redhat.com>
Sat, 30 Jun 2007 01:43:04 +0000 (01:43 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Sat, 30 Jun 2007 01:43:04 +0000 (01:43 +0000)
2007-06-29  Matthias Clasen  <mclasen@redhat.com>

        * gdk/gdk.symbols:
        * gdk/gdkkeys.h:
        * gdk/x11/gdkkeys-x11.c (gdk_keymap_have_bidi_layouts): New
        function to determine if keyboard layouts for both LTR and LTR
        languages are in use. Refactor the direction caching code to
        make this information available.  (#451575, Behnam Esfahbod)

svn path=/trunk/; revision=18301

ChangeLog
docs/reference/ChangeLog
docs/reference/gdk/gdk-sections.txt
gdk/gdk.symbols
gdk/gdkkeys.h
gdk/x11/gdkkeys-x11.c

index ac28a7a45ad4f19f12a31015d18656dfe2f765f0..9cd14351154623841624b1cc12a1dc041c98b3e9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-06-29  Matthias Clasen  <mclasen@redhat.com>
+
+       * gdk/gdk.symbols:
+       * gdk/gdkkeys.h:
+       * gdk/x11/gdkkeys-x11.c (gdk_keymap_have_bidi_layouts): New
+       function to determine if keyboard layouts for both LTR and LTR 
+       languages are in use. Refactor the direction caching code to
+       make this information available.  (#451575, Behnam Esfahbod)
+
 2007-06-29  Matthias Clasen  <mclasen@redhat.com>
 
        * modules/printbackend/cups/gtkcupsutils.c (_post_check):
index 6fbefce85b57d97dac73643386c8efc1191f07a2..51127fb1b4417c91f2dbcd833e3c5a9f6e09c107 100644 (file)
@@ -1,3 +1,7 @@
+2007-06-29  Matthias Clasen  <mclasen@redhat.com>
+
+       * gdk/gdk-sections.txt: Add gdk_keymap_have_bidi_layouts
+
 2007-06-29  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/migrating-GtkBuilder.sgml: An empty shell
index 0da3b962e46c906ba7708e83be5c8e225399f114..69adf717eaa0aa245aef3f59b664854b8937858e 100644 (file)
@@ -980,6 +980,7 @@ gdk_keymap_translate_keyboard_state
 gdk_keymap_get_entries_for_keyval
 gdk_keymap_get_entries_for_keycode
 gdk_keymap_get_direction
+gdk_keymap_have_bidi_layouts
 
 <SUBSECTION>
 gdk_keyval_name
index 8757324fcc7e6c53a62499c3461acc2751e84940..ef801d3e34debf8e82bbd4f877fc05842b469643 100644 (file)
@@ -819,6 +819,7 @@ gdk_keymap_get_direction
 gdk_keymap_get_entries_for_keycode
 gdk_keymap_get_entries_for_keyval
 gdk_keymap_get_for_display
+gdk_keymap_have_bidi_layouts
 gdk_keymap_lookup_key
 gdk_keymap_translate_keyboard_state
 gdk_keyval_convert_case
index 2c76bf5547bbf90768d5b9bbb5d04d0982b98be7..fda2997e53b265d2da56c55c929f78392b206a86 100644 (file)
@@ -101,6 +101,7 @@ gboolean       gdk_keymap_get_entries_for_keycode  (GdkKeymap           *keymap,
                                                    guint              **keyvals,
                                                    gint                *n_entries);
 PangoDirection gdk_keymap_get_direction            (GdkKeymap           *keymap);
+gboolean       gdk_keymap_have_bidi_layouts        (GdkKeymap           *keymap);
 
 /* Key values
  */
index 779090f04eaf0a66789436da20995f9e0f155078..f5ca8bc226b80cb55ae48c62bb33a17736376885 100644 (file)
@@ -584,73 +584,93 @@ get_direction (XkbDescRec *xkb,
     return PANGO_DIRECTION_LTR;
 }
 
-static void
-update_direction (GdkKeymapX11 *keymap_x11,
-                 gint          group)
+static PangoDirection
+get_direction_from_cache (GdkKeymapX11 *keymap_x11,
+                         XkbDescPtr xkb,
+                         gint group)
 {
-  XkbDescRec *xkb = get_xkb (keymap_x11);
-  Atom group_atom;
+  Atom group_atom = xkb->names->groups[group];
 
-  group_atom = xkb->names->groups[group];
-
-  /* a group change? */
-  if (!keymap_x11->have_direction || keymap_x11->current_group_atom != group_atom)
-    {
-      gboolean cache_hit = FALSE;
-      DirectionCacheEntry *cache = keymap_x11->group_direction_cache;
+  gboolean cache_hit = FALSE;
+  DirectionCacheEntry *cache = keymap_x11->group_direction_cache;
 
-      PangoDirection direction = PANGO_DIRECTION_NEUTRAL;
-      gint i;
+  PangoDirection direction = PANGO_DIRECTION_NEUTRAL;
+  gint i;
 
-      if (keymap_x11->have_direction)
-       {
-          /* lookup in cache */
-         for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++)
+  if (keymap_x11->have_direction)
+    {
+      /* lookup in cache */
+      for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++)
+      {
+       if (cache[i].group_atom == group_atom)
          {
-           if (cache[i].group_atom == group_atom)
-             {
-               cache_hit = TRUE;
-               cache[i].serial = keymap_x11->current_cache_serial++; /* freshen */
-               direction = cache[i].direction;
-               group_atom = cache[i].group_atom;
-               break;
-             }
+           cache_hit = TRUE;
+           cache[i].serial = keymap_x11->current_cache_serial++; /* freshen */
+           direction = cache[i].direction;
+           group_atom = cache[i].group_atom;
+           break;
          }
-       }
-      else
+      }
+    }
+  else
+    {
+      /* initialize cache */
+      for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++)
        {
-          /* initialize cache */
-         for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++)
-           {
-             cache[i].group_atom = 0;
-             cache[i].serial = keymap_x11->current_cache_serial;
-           }
-         keymap_x11->current_cache_serial++;
+         cache[i].group_atom = 0;
+         cache[i].serial = keymap_x11->current_cache_serial;
        }
+      keymap_x11->current_cache_serial++;
+    }
 
-      /* insert in cache */
-      if (!cache_hit)
-       {
-         gint oldest = 0;
+  /* insert in cache */
+  if (!cache_hit)
+    {
+      gint oldest = 0;
 
-         direction = get_direction (xkb, group);
+      direction = get_direction (xkb, group);
 
-         /* remove the oldest entry */
-         for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++)
-           {
-             if (cache[i].serial < cache[oldest].serial)
-               oldest = i;
-           }
-         
-         cache[oldest].group_atom = group_atom;
-         cache[oldest].direction = direction;
-         cache[oldest].serial = keymap_x11->current_cache_serial++;
+      /* remove the oldest entry */
+      for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++)
+       {
+         if (cache[i].serial < cache[oldest].serial)
+           oldest = i;
        }
+      
+      cache[oldest].group_atom = group_atom;
+      cache[oldest].direction = direction;
+      cache[oldest].serial = keymap_x11->current_cache_serial++;
+    }
 
-      keymap_x11->current_group_atom = group_atom;
+  return direction;
+}
+
+static int
+get_num_groups (GdkKeymap *keymap,
+               XkbDescPtr xkb)
+{
+      Display *display = KEYMAP_XDISPLAY (keymap);
+      XkbGetControls(display, XkbSlowKeysMask, xkb);
+      XkbGetUpdatedMap (display, XkbKeySymsMask | XkbKeyTypesMask |
+                       XkbModifierMapMask | XkbVirtualModsMask, xkb);
+      return xkb->ctrls->num_groups;
+}
+
+static void
+update_direction (GdkKeymapX11 *keymap_x11,
+                 gint          group)
+{
+  XkbDescPtr xkb = get_xkb (keymap_x11);
+  Atom group_atom;
 
+  group_atom = xkb->names->groups[group];
+
+  /* a group change? */
+  if (!keymap_x11->have_direction || keymap_x11->current_group_atom != group_atom)
+    {
+      keymap_x11->current_direction = get_direction_from_cache (keymap_x11, xkb, group);
+      keymap_x11->current_group_atom = group_atom;
       keymap_x11->have_direction = TRUE;
-      keymap_x11->current_direction = direction;
     }
 }
 
@@ -673,7 +693,7 @@ _gdk_keymap_state_changed (GdkDisplay *display,
       had_direction = keymap_x11->have_direction;
       direction = keymap_x11->current_direction;
       
-      update_direction (keymap_x11, xkb_event->state.locked_group);
+      update_direction (keymap_x11, XkbStateGroup (&xkb_event->state));
       
       if (!had_direction || direction != keymap_x11->current_direction)
        g_signal_emit_by_name (keymap_x11, "direction_changed");      
@@ -693,6 +713,15 @@ _gdk_keymap_keys_changed (GdkDisplay *display)
     g_signal_emit_by_name (display_x11->keymap, "keys_changed", 0);
 }
 
+/** 
+ * gdk_keymap_get_direction:
+ * @keymap: a #GdkKeymap or %NULL to use the default keymap
+ *
+ * Returns the direction of effective layout of the keymap.
+ *
+ * @Returns: %PANGO_DIRECTION_LTR or %PANGO_DIRECTION_RTL if determines the
+ * direction.  %PANGO_DIRECTION_NEUTRAL otherwise.
+ **/
 PangoDirection
 gdk_keymap_get_direction (GdkKeymap *keymap)
 {
@@ -710,7 +739,7 @@ gdk_keymap_get_direction (GdkKeymap *keymap)
 
          XkbGetState (GDK_DISPLAY_XDISPLAY (display), XkbUseCoreKbd, 
                       &state_rec);
-         update_direction (keymap_x11, XkbGroupLock (&state_rec));
+         update_direction (keymap_x11, XkbStateGroup (&state_rec));
        }
   
       return keymap_x11->current_direction;
@@ -720,6 +749,48 @@ gdk_keymap_get_direction (GdkKeymap *keymap)
     return PANGO_DIRECTION_NEUTRAL;
 }
 
+/** 
+ * gdk_keymap_have_bidi_layouts:
+ * @keymap: a #GdkKeymap or %NULL to use the default keymap
+ *
+ * Determines if keyboard layouts for both right-to-left and left-to-right
+ * languages are in use.
+ *
+ * @Returns: %TRUE if there are layouts in both directions, %FALSE otherwise
+ *
+ * Since: 2.12
+ **/
+gboolean
+gdk_keymap_have_bidi_layouts (GdkKeymap *keymap)
+{
+  keymap = GET_EFFECTIVE_KEYMAP (keymap);
+
+#if HAVE_XKB
+  if (KEYMAP_USE_XKB (keymap))
+    {
+      GdkKeymapX11 *keymap_x11 = GDK_KEYMAP_X11 (keymap);
+      XkbDescPtr xkb = get_xkb (keymap_x11);
+      int num_groups = get_num_groups (keymap, xkb);
+
+      int i;
+      gboolean have_ltr_keyboard = FALSE;
+      gboolean have_rtl_keyboard = FALSE;
+
+      for (i = 0; i < num_groups; i++)
+      {
+       if (get_direction_from_cache (keymap_x11, xkb, i) == PANGO_DIRECTION_RTL)
+         have_rtl_keyboard = TRUE;
+       else
+         have_ltr_keyboard = TRUE;
+      }
+
+      return have_ltr_keyboard && have_rtl_keyboard;
+    }
+  else
+#endif /* HAVE_XKB */
+    return FALSE;
+}
+
 /**
  * gdk_keymap_get_entries_for_keyval:
  * @keymap: a #GdkKeymap, or %NULL to use the default keymap