mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 05:01:09 +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>
|
2007-06-29 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* modules/printbackend/cups/gtkcupsutils.c (_post_check):
|
* 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>
|
2007-06-29 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* gtk/migrating-GtkBuilder.sgml: An empty shell
|
* 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_keyval
|
||||||
gdk_keymap_get_entries_for_keycode
|
gdk_keymap_get_entries_for_keycode
|
||||||
gdk_keymap_get_direction
|
gdk_keymap_get_direction
|
||||||
|
gdk_keymap_have_bidi_layouts
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
gdk_keyval_name
|
gdk_keyval_name
|
||||||
|
@ -819,6 +819,7 @@ gdk_keymap_get_direction
|
|||||||
gdk_keymap_get_entries_for_keycode
|
gdk_keymap_get_entries_for_keycode
|
||||||
gdk_keymap_get_entries_for_keyval
|
gdk_keymap_get_entries_for_keyval
|
||||||
gdk_keymap_get_for_display
|
gdk_keymap_get_for_display
|
||||||
|
gdk_keymap_have_bidi_layouts
|
||||||
gdk_keymap_lookup_key
|
gdk_keymap_lookup_key
|
||||||
gdk_keymap_translate_keyboard_state
|
gdk_keymap_translate_keyboard_state
|
||||||
gdk_keyval_convert_case
|
gdk_keyval_convert_case
|
||||||
|
@ -101,6 +101,7 @@ gboolean gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap,
|
|||||||
guint **keyvals,
|
guint **keyvals,
|
||||||
gint *n_entries);
|
gint *n_entries);
|
||||||
PangoDirection gdk_keymap_get_direction (GdkKeymap *keymap);
|
PangoDirection gdk_keymap_get_direction (GdkKeymap *keymap);
|
||||||
|
gboolean gdk_keymap_have_bidi_layouts (GdkKeymap *keymap);
|
||||||
|
|
||||||
/* Key values
|
/* Key values
|
||||||
*/
|
*/
|
||||||
|
@ -584,11 +584,83 @@ get_direction (XkbDescRec *xkb,
|
|||||||
return PANGO_DIRECTION_LTR;
|
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
|
static void
|
||||||
update_direction (GdkKeymapX11 *keymap_x11,
|
update_direction (GdkKeymapX11 *keymap_x11,
|
||||||
gint group)
|
gint group)
|
||||||
{
|
{
|
||||||
XkbDescRec *xkb = get_xkb (keymap_x11);
|
XkbDescPtr xkb = get_xkb (keymap_x11);
|
||||||
Atom group_atom;
|
Atom group_atom;
|
||||||
|
|
||||||
group_atom = xkb->names->groups[group];
|
group_atom = xkb->names->groups[group];
|
||||||
@ -596,61 +668,9 @@ update_direction (GdkKeymapX11 *keymap_x11,
|
|||||||
/* a group change? */
|
/* a group change? */
|
||||||
if (!keymap_x11->have_direction || keymap_x11->current_group_atom != group_atom)
|
if (!keymap_x11->have_direction || keymap_x11->current_group_atom != group_atom)
|
||||||
{
|
{
|
||||||
gboolean cache_hit = FALSE;
|
keymap_x11->current_direction = get_direction_from_cache (keymap_x11, xkb, group);
|
||||||
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_group_atom = group_atom;
|
keymap_x11->current_group_atom = group_atom;
|
||||||
|
|
||||||
keymap_x11->have_direction = TRUE;
|
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;
|
had_direction = keymap_x11->have_direction;
|
||||||
direction = keymap_x11->current_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)
|
if (!had_direction || direction != keymap_x11->current_direction)
|
||||||
g_signal_emit_by_name (keymap_x11, "direction_changed");
|
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);
|
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
|
PangoDirection
|
||||||
gdk_keymap_get_direction (GdkKeymap *keymap)
|
gdk_keymap_get_direction (GdkKeymap *keymap)
|
||||||
{
|
{
|
||||||
@ -710,7 +739,7 @@ gdk_keymap_get_direction (GdkKeymap *keymap)
|
|||||||
|
|
||||||
XkbGetState (GDK_DISPLAY_XDISPLAY (display), XkbUseCoreKbd,
|
XkbGetState (GDK_DISPLAY_XDISPLAY (display), XkbUseCoreKbd,
|
||||||
&state_rec);
|
&state_rec);
|
||||||
update_direction (keymap_x11, XkbGroupLock (&state_rec));
|
update_direction (keymap_x11, XkbStateGroup (&state_rec));
|
||||||
}
|
}
|
||||||
|
|
||||||
return keymap_x11->current_direction;
|
return keymap_x11->current_direction;
|
||||||
@ -720,6 +749,48 @@ gdk_keymap_get_direction (GdkKeymap *keymap)
|
|||||||
return PANGO_DIRECTION_NEUTRAL;
|
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:
|
* gdk_keymap_get_entries_for_keyval:
|
||||||
* @keymap: a #GdkKeymap, or %NULL to use the default keymap
|
* @keymap: a #GdkKeymap, or %NULL to use the default keymap
|
||||||
|
Loading…
Reference in New Issue
Block a user