summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2013-04-03 23:45:54 -0400
committerMatthias Clasen <mclasen@redhat.com>2013-04-03 23:45:54 -0400
commit2f8f1ef485e4d0a48dd7acad00cdbd6e6b5d25b8 (patch)
tree46e49fb86a2b339abaf42460922a131badb7dd60 /gdk
parent5d9c07a0615930670f4eb6faf49d3f127e2be580 (diff)
downloadgtk+-2f8f1ef485e4d0a48dd7acad00cdbd6e6b5d25b8.tar.gz
wayland: Implement keymap direction
This is very similar to the X11 implementation.
Diffstat (limited to 'gdk')
-rw-r--r--gdk/wayland/gdkkeys-wayland.c90
1 files changed, 88 insertions, 2 deletions
diff --git a/gdk/wayland/gdkkeys-wayland.c b/gdk/wayland/gdkkeys-wayland.c
index c2d07eb2a5..83d94e9be5 100644
--- a/gdk/wayland/gdkkeys-wayland.c
+++ b/gdk/wayland/gdkkeys-wayland.c
@@ -50,6 +50,9 @@ struct _GdkWaylandKeymap
struct xkb_keymap *xkb_keymap;
struct xkb_state *xkb_state;
+
+ PangoDirection *direction;
+ gboolean bidi;
};
struct _GdkWaylandKeymapClass
@@ -70,6 +73,7 @@ gdk_wayland_keymap_finalize (GObject *object)
xkb_keymap_unref (keymap->xkb_keymap);
xkb_state_unref (keymap->xkb_state);
+ g_free (keymap->direction);
G_OBJECT_CLASS (_gdk_wayland_keymap_parent_class)->finalize (object);
}
@@ -77,13 +81,24 @@ gdk_wayland_keymap_finalize (GObject *object)
static PangoDirection
gdk_wayland_keymap_get_direction (GdkKeymap *keymap)
{
- return PANGO_DIRECTION_NEUTRAL;
+ GdkWaylandKeymap *keymap_wayland = GDK_WAYLAND_KEYMAP (keymap);
+ gint i;
+
+ for (i = 0; i < xkb_keymap_num_layouts (keymap_wayland->xkb_keymap); i++)
+ {
+ if (xkb_state_layout_index_is_active (keymap_wayland->xkb_state, i, XKB_STATE_LAYOUT_EFFECTIVE))
+ return keymap_wayland->direction[i];
+ }
+
+ return PANGO_DIRECTION_NEUTRAL;
}
static gboolean
gdk_wayland_keymap_have_bidi_layouts (GdkKeymap *keymap)
{
- return FALSE;
+ GdkWaylandKeymap *keymap_wayland = GDK_WAYLAND_KEYMAP (keymap);
+
+ return keymap_wayland->bidi;
}
static gboolean
@@ -233,6 +248,75 @@ _gdk_wayland_keymap_new ()
return GDK_KEYMAP (keymap);
}
+static void
+update_direction (GdkWaylandKeymap *keymap)
+{
+ gint num_layouts;
+ gint *rtl;
+ gint key;
+ gboolean have_rtl, have_ltr;
+ gint i;
+
+ num_layouts = xkb_keymap_num_layouts (keymap->xkb_keymap);
+
+ g_free (keymap->direction);
+ keymap->direction = g_new0 (PangoDirection, num_layouts);
+
+ rtl = g_new0 (gint, num_layouts);
+
+ for (key = 8; key < 255; key++) /* FIXME: min/max keycode */
+ {
+ gint layouts;
+ gint layout;
+
+ layouts = xkb_keymap_num_layouts_for_key (keymap->xkb_keymap, key);
+ for (layout = 0; layout < layouts; layout++)
+ {
+ const xkb_keysym_t *syms;
+ gint num_syms;
+ gint sym;
+
+ num_syms = xkb_keymap_key_get_syms_by_level (keymap->xkb_keymap, key, layout, 0, &syms);
+ for (sym = 0; sym < num_syms; sym++)
+ {
+ PangoDirection dir;
+ dir = pango_unichar_direction (xkb_keysym_to_utf32 (syms[sym]));
+ switch (dir)
+ {
+ case PANGO_DIRECTION_RTL:
+ rtl[layout]++;
+ break;
+ case PANGO_DIRECTION_LTR:
+ rtl[layout]--;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ have_rtl = have_ltr = FALSE;
+ for (i = 0; i < num_layouts; i++)
+ {
+ if (rtl[i] > 0)
+ {
+ keymap->direction[i] = PANGO_DIRECTION_RTL;
+ have_rtl = TRUE;
+ }
+ else
+ {
+ keymap->direction[i] = PANGO_DIRECTION_LTR;
+ have_ltr = TRUE;
+ }
+ }
+
+ if (have_rtl && have_ltr)
+ keymap->bidi = TRUE;
+
+ g_free (rtl);
+}
+
void
_gdk_wayland_keymap_update_from_fd (GdkKeymap *keymap,
uint32_t format,
@@ -261,6 +345,8 @@ _gdk_wayland_keymap_update_from_fd (GdkKeymap *keymap,
keymap_wayland->xkb_state = xkb_state_new (keymap_wayland->xkb_keymap);
xkb_context_unref (context);
+
+ update_direction (keymap_wayland);
}
struct xkb_keymap *_gdk_wayland_keymap_get_xkb_keymap (GdkKeymap *keymap)