diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | docs/reference/ChangeLog | 4 | ||||
-rw-r--r-- | docs/reference/gdk/gdk-sections.txt | 1 | ||||
-rw-r--r-- | gdk/gdk.symbols | 1 | ||||
-rw-r--r-- | gdk/gdkkeys.h | 1 | ||||
-rw-r--r-- | gdk/x11/gdkkeys-x11.c | 179 |
6 files changed, 141 insertions, 54 deletions
@@ -1,5 +1,14 @@ 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): (_get_check): Enable SSL support. (#451070, Vince Busam) diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 6fbefce85b..51127fb1b4 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,5 +1,9 @@ 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 * gtk/Makefile.am: * gtk/gtk-docs.sgml: Integrate it diff --git a/docs/reference/gdk/gdk-sections.txt b/docs/reference/gdk/gdk-sections.txt index 0da3b962e4..69adf717ea 100644 --- a/docs/reference/gdk/gdk-sections.txt +++ b/docs/reference/gdk/gdk-sections.txt @@ -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 diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols index 8757324fcc..ef801d3e34 100644 --- a/gdk/gdk.symbols +++ b/gdk/gdk.symbols @@ -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 diff --git a/gdk/gdkkeys.h b/gdk/gdkkeys.h index 2c76bf5547..fda2997e53 100644 --- a/gdk/gdkkeys.h +++ b/gdk/gdkkeys.h @@ -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 */ diff --git a/gdk/x11/gdkkeys-x11.c b/gdk/x11/gdkkeys-x11.c index 779090f04e..f5ca8bc226 100644 --- a/gdk/x11/gdkkeys-x11.c +++ b/gdk/x11/gdkkeys-x11.c @@ -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 |