[gtk+] wayland: Process the keymap that is sent over from the compositor



commit 1d080a01c19b06b6bf62c62c633ea3d18e2dcafd
Author: Rob Bradford <rob linux intel com>
Date:   Mon Jul 16 12:33:35 2012 +0100

    wayland: Process the keymap that is sent over from the compositor
    
    Load the keymap from the file descriptor that the compositor has sent us and
    then save that into our internal object for future use.

 gdk/wayland/gdkdevice-wayland.c  |   32 ++++++++++++++++++++++++++++++++
 gdk/wayland/gdkdisplay-wayland.c |    2 ++
 gdk/wayland/gdkdisplay-wayland.h |    2 ++
 gdk/wayland/gdkkeys-wayland.c    |   31 +++++++++++++++++++++++++++++++
 gdk/wayland/gdkprivate-wayland.h |    4 ++++
 5 files changed, 71 insertions(+), 0 deletions(-)
---
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index 6e15fa8..c45eb21 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -36,6 +36,7 @@
 #include <X11/keysym.h>
 
 #include <sys/time.h>
+#include <sys/mman.h>
 
 #define GDK_TYPE_DEVICE_CORE         (gdk_device_core_get_type ())
 #define GDK_DEVICE_CORE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCore))
@@ -1126,6 +1127,37 @@ keyboard_handle_keymap (void               *data,
                        int                 fd,
                        uint32_t            size)
 {
+  GdkWaylandDevice *device = data;
+  GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
+  GdkKeymap *gdk_keymap;
+  gchar *keymap_data;
+  struct xkb_keymap *keymap;
+
+  if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
+    {
+      g_critical (G_STRLOC ": Unknown keymap format");
+      close (fd);
+      return;
+    }
+
+  keymap_data = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+  if (keymap_data == MAP_FAILED)
+    {
+      g_critical (G_STRLOC ": Unable to map fd for keymap %s", g_strerror (errno));
+      close (fd);
+      return;
+    }
+
+  keymap = xkb_map_new_from_string (display->xkb_context,
+                                    keymap_data,
+                                    format,
+                                    0);
+
+  munmap (keymap_data, size);
+  close (fd);
+
+  gdk_keymap = _gdk_wayland_display_get_keymap (device->display);
+  _gdk_wayland_keymap_update_keymap (gdk_keymap, keymap);
 }
 
 static void
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index 13cfb0c..84660a1 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -619,6 +619,8 @@ _gdk_wayland_display_init (GdkWaylandDisplay *display)
 {
   _gdk_wayland_display_manager_add_display (gdk_display_manager_get (),
 					    GDK_DISPLAY (display));
+
+  display->xkb_context = xkb_context_new (0);
 }
 
 static void
diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h
index 8b6dd5c..c31a82b 100644
--- a/gdk/wayland/gdkdisplay-wayland.h
+++ b/gdk/wayland/gdkdisplay-wayland.h
@@ -87,6 +87,8 @@ struct _GdkWaylandDisplay
 
   GSource *event_source;
 
+  struct xkb_context *xkb_context;
+
 #ifdef GDK_WAYLAND_USE_EGL
   EGLDisplay egl_display;
   EGLContext egl_context;
diff --git a/gdk/wayland/gdkkeys-wayland.c b/gdk/wayland/gdkkeys-wayland.c
index 0a13b93..b4b205b 100644
--- a/gdk/wayland/gdkkeys-wayland.c
+++ b/gdk/wayland/gdkkeys-wayland.c
@@ -49,6 +49,11 @@ struct _GdkWaylandKeymap
   GdkKeymap parent_instance;
   GdkModifierType modmap[8];
   struct xkb_desc *xkb;
+  struct xkb_keymap *keymap;
+  struct xkb_state *state;
+  xkb_mod_mask_t control_mask;
+  xkb_mod_mask_t alt_mask;
+  xkb_mod_mask_t shift_mask;
 };
 
 struct _GdkWaylandKeymapClass
@@ -661,6 +666,32 @@ _gdk_wayland_keymap_new (GdkDisplay *display)
   return GDK_KEYMAP (keymap);
 }
 
+void
+_gdk_wayland_keymap_update_keymap (GdkKeymap  *gdk_keymap,
+                                   struct xkb_keymap *xkb_keymap)
+{
+  GdkWaylandKeymap *keymap;
+
+  keymap = GDK_WAYLAND_KEYMAP (gdk_keymap);
+
+  if (keymap->keymap)
+    xkb_map_unref (keymap->keymap);
+
+  keymap->keymap = xkb_keymap;
+
+  if (keymap->state)
+    xkb_state_unref (keymap->state);
+
+  keymap->state = xkb_state_new (keymap->keymap);
+
+  keymap->control_mask =
+    1 << xkb_map_mod_get_index(keymap->keymap, "Control");
+  keymap->alt_mask =
+    1 << xkb_map_mod_get_index(keymap->keymap, "Mod1");
+  keymap->shift_mask =
+    1 << xkb_map_mod_get_index(keymap->keymap, "Shift");
+}
+
 struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap)
 {
   return GDK_WAYLAND_KEYMAP (keymap)->xkb;
diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h
index 6b4d3b8..607e99a 100644
--- a/gdk/wayland/gdkprivate-wayland.h
+++ b/gdk/wayland/gdkprivate-wayland.h
@@ -33,6 +33,8 @@
 #include <gdk/gdkprivate.h>
 #include <gdk/wayland/gdkdisplay-wayland.h>
 
+#include <xkbcommon/xkbcommon.h>
+
 #include "gdkinternals.h"
 
 #include "config.h"
@@ -89,6 +91,8 @@ void _gdk_wayland_display_create_window_impl (GdkDisplay    *display,
 					      gint           attributes_mask);
 
 GdkKeymap *_gdk_wayland_display_get_keymap (GdkDisplay *display);
+void       _gdk_wayland_keymap_update_keymap (GdkKeymap  *gdk_keymap,
+                                              struct xkb_keymap *xkb_keymap);
 
 GdkWindow *_gdk_wayland_display_get_selection_owner (GdkDisplay *display,
 						 GdkAtom     selection);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]