mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-24 12:41:16 +00:00
New function to determine if keyboard layouts for both LTR and LTR
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
This commit is contained in:
parent
5c31ca5c85
commit
436a34e318
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -584,11 +584,83 @@ get_direction (XkbDescRec *xkb,
|
||||
return PANGO_DIRECTION_LTR;
|
||||
}
|
||||
|
||||
static PangoDirection
|
||||
get_direction_from_cache (GdkKeymapX11 *keymap_x11,
|
||||
XkbDescPtr xkb,
|
||||
gint group)
|
||||
{
|
||||
Atom group_atom = xkb->names->groups[group];
|
||||
|
||||
gboolean cache_hit = FALSE;
|
||||
DirectionCacheEntry *cache = keymap_x11->group_direction_cache;
|
||||
|
||||
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 (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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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++;
|
||||
}
|
||||
|
||||
/* insert in cache */
|
||||
if (!cache_hit)
|
||||
{
|
||||
gint oldest = 0;
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
XkbDescRec *xkb = get_xkb (keymap_x11);
|
||||
XkbDescPtr xkb = get_xkb (keymap_x11);
|
||||
Atom group_atom;
|
||||
|
||||
group_atom = xkb->names->groups[group];
|
||||
@ -596,61 +668,9 @@ update_direction (GdkKeymapX11 *keymap_x11,
|
||||
/* 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;
|
||||
|
||||
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 (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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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++;
|
||||
}
|
||||
|
||||
/* insert in cache */
|
||||
if (!cache_hit)
|
||||
{
|
||||
gint oldest = 0;
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user