Add a new API for keymap cache 00/54600/6
authorJengHyun Kang <jhyuni.kang@samsung.com>
Thu, 24 Dec 2015 05:40:06 +0000 (14:40 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Tue, 5 Jan 2016 07:38:07 +0000 (23:38 -0800)
Change-Id: I36ab0d665e6a43d55eb3c741c0c5889a4c4d9801

src/lib/ecore_drm/Ecore_Drm.h
src/lib/ecore_drm/ecore_drm_device.c
src/lib/ecore_drm/ecore_drm_evdev.c
src/lib/ecore_drm/ecore_drm_private.h

index 7ed2aad..7f10565 100644 (file)
@@ -6,6 +6,7 @@
 # include <drm_fourcc.h>
 # include <Ecore.h>
 # include <Eeze.h>
+# include <xkbcommon/xkbcommon.h>
 
 # ifdef EAPI
 #  undef EAPI
@@ -405,6 +406,32 @@ EAPI Eina_Bool ecore_drm_device_software_setup(Ecore_Drm_Device *dev);
 EAPI Eina_Bool ecore_drm_device_pointer_left_handed_set(Ecore_Drm_Device *dev, Eina_Bool left_handed);
 
 /**
+ * Setup a cached context to use same context for each devices
+ *
+ * This function will setup a cached context to use same context for each devices
+ * This function will be called before initialize Ecore_Drm.
+ *
+ * @param ctx struct xkb_context used in libxkbcommon
+ *
+ * @ingroup Ecore_Drm_Device_Group
+ * @since 1.17
+ */
+EAPI void ecore_drm_device_keyboard_cached_context_set(struct xkb_context *ctx);
+
+/**
+ * Setup a cached keymap to use same keymap for each devices
+ *
+ * This function will setup a cached keymap to use same keymap for each devices
+ * This function will be called before initialize Ecore_Drm.
+ *
+ * @param map struct xkb_keymap used in libxkbcommon
+ *
+ * @ingroup Ecore_Drm_Device_Group
+ * @since 1.17
+ */
+EAPI void ecore_drm_device_keyboard_cached_keymap_set(struct xkb_keymap *map);
+
+/**
  * Find an Ecore_Drm_Output at the given coordinates
  *
  * This function will loop all the existing outputs in Ecore_Drm_Device and 
index 46a2355..38b680f 100644 (file)
@@ -119,6 +119,58 @@ _ecore_drm_device_cb_output_event(const char *device EINA_UNUSED, Eeze_Udev_Even
    _ecore_drm_outputs_update(dev);
 }
 
+struct xkb_context *
+_ecore_drm_device_cached_context_get(enum xkb_context_flags flags)
+{
+   if (!cached_context)
+     return xkb_context_new(flags);
+   else
+     return xkb_context_ref(cached_context);
+}
+
+struct xkb_keymap *
+_ecore_drm_device_cached_keymap_get(struct xkb_context *ctx,
+                       const struct xkb_rule_names *names,
+                       enum xkb_keymap_compile_flags flags)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
+
+   if (!cached_keymap)
+     return xkb_map_new_from_names(ctx, names, flags);
+   else
+     return xkb_map_ref(cached_keymap);
+}
+
+void
+_ecore_drm_device_cached_context_update(struct xkb_context *ctx)
+{
+   Eina_List *l;
+   Ecore_Drm_Device *dev;
+
+   EINA_LIST_FOREACH(drm_devices, l, dev)
+     {
+        xkb_context_unref(dev->xkb_ctx);
+        dev->xkb_ctx = xkb_context_ref(ctx);
+     }
+}
+
+void
+_ecore_drm_device_cached_keymap_update(struct xkb_keymap *map)
+{
+   Eina_List *l, *l2, *l3;
+   Ecore_Drm_Device *dev;
+   Ecore_Drm_Seat *seat;
+   Ecore_Drm_Evdev *edev;
+
+   EINA_LIST_FOREACH(drm_devices, l, dev)
+     EINA_LIST_FOREACH(dev->seats, l2, seat)
+       EINA_LIST_FOREACH(ecore_drm_seat_evdev_list_get(seat), l3, edev)
+         {
+            xkb_keymap_unref(edev->xkb.keymap);
+            edev->xkb.keymap = xkb_keymap_ref(map);
+         }
+}
+
 /**
  * @defgroup Ecore_Drm_Device_Group Device manipulation functions
  * 
@@ -377,7 +429,7 @@ ecore_drm_device_open(Ecore_Drm_Device *dev)
      }
 
    /* try to create xkb context */
-   if (!(dev->xkb_ctx = xkb_context_new(0)))
+   if (!(dev->xkb_ctx = _ecore_drm_device_cached_context_get(0)))
      {
         ERR("Failed to create xkb context: %m");
         return EINA_FALSE;
@@ -684,3 +736,29 @@ ecore_drm_device_pointer_left_handed_set(Ecore_Drm_Device *dev, Eina_Bool left_h
      }
    return EINA_TRUE;
 }
+
+EAPI void
+ecore_drm_device_keyboard_cached_context_set(struct xkb_context *ctx)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ctx);
+
+   if (cached_context == ctx) return;
+
+   if (cached_context)
+     _ecore_drm_device_cached_context_update(ctx);
+
+   cached_context = ctx;
+}
+
+EAPI void
+ecore_drm_device_keyboard_cached_keymap_set(struct xkb_keymap *map)
+{
+   EINA_SAFETY_ON_NULL_RETURN(map);
+
+   if (cached_keymap == map) return;
+
+   if (cached_keymap)
+      _ecore_drm_device_cached_keymap_update(map);
+
+   cached_keymap = map;
+}
index d36035b..94d3711 100644 (file)
@@ -116,7 +116,7 @@ _device_keyboard_setup(Ecore_Drm_Evdev *edev)
    if (!input->dev->xkb_ctx) return;
 
    /* create keymap from xkb context */
-   edev->xkb.keymap = xkb_map_new_from_names(input->dev->xkb_ctx, NULL, 0);
+   edev->xkb.keymap = _ecore_drm_device_cached_keymap_get(input->dev->xkb_ctx, NULL, 0);
    if (!edev->xkb.keymap)
      {
         ERR("Failed to create keymap: %m");
index b457b47..f95cca1 100644 (file)
@@ -24,7 +24,6 @@
 # include <linux/major.h>
 # include <linux/input.h>
 # include <libinput.h>
-# include <xkbcommon/xkbcommon.h>
 
 # ifdef HAVE_SYSTEMD
 #  include <systemd/sd-login.h>
@@ -69,6 +68,8 @@
 # endif
 
 extern int _ecore_drm_log_dom;
+struct xkb_keymap *cached_keymap;
+struct xkb_context *cached_context;
 
 # define EVDEV_MAX_SLOTS 32
 
@@ -308,4 +309,9 @@ void _ecore_drm_device_info_send(unsigned int window, Ecore_Drm_Evdev *edev, Ein
 
 void _ecore_drm_inputs_init(void);
 void _ecore_drm_inputs_shutdown(void);
+
+struct xkb_context *_ecore_drm_device_cached_context_get(enum xkb_context_flags flags);
+struct xkb_keymap *_ecore_drm_device_cached_keymap_get(struct xkb_context *ctx,
+                       const struct xkb_rule_names *names,
+                       enum xkb_keymap_compile_flags flags);
 #endif