From f08f80dcf2e5c3e3db39fde0099dd7a23e6245eb Mon Sep 17 00:00:00 2001 From: JengHyun Kang Date: Thu, 24 Dec 2015 14:40:06 +0900 Subject: [PATCH] Add a new API for keymap cache Change-Id: I36ab0d665e6a43d55eb3c741c0c5889a4c4d9801 --- src/lib/ecore_drm/Ecore_Drm.h | 27 ++++++++++++ src/lib/ecore_drm/ecore_drm_device.c | 80 ++++++++++++++++++++++++++++++++++- src/lib/ecore_drm/ecore_drm_evdev.c | 2 +- src/lib/ecore_drm/ecore_drm_private.h | 8 +++- 4 files changed, 114 insertions(+), 3 deletions(-) diff --git a/src/lib/ecore_drm/Ecore_Drm.h b/src/lib/ecore_drm/Ecore_Drm.h index 7ed2aad..7f10565 100644 --- a/src/lib/ecore_drm/Ecore_Drm.h +++ b/src/lib/ecore_drm/Ecore_Drm.h @@ -6,6 +6,7 @@ # include # include # include +# include # 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 diff --git a/src/lib/ecore_drm/ecore_drm_device.c b/src/lib/ecore_drm/ecore_drm_device.c index 46a2355..38b680f 100644 --- a/src/lib/ecore_drm/ecore_drm_device.c +++ b/src/lib/ecore_drm/ecore_drm_device.c @@ -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; +} diff --git a/src/lib/ecore_drm/ecore_drm_evdev.c b/src/lib/ecore_drm/ecore_drm_evdev.c index d36035b..94d3711 100644 --- a/src/lib/ecore_drm/ecore_drm_evdev.c +++ b/src/lib/ecore_drm/ecore_drm_evdev.c @@ -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"); diff --git a/src/lib/ecore_drm/ecore_drm_private.h b/src/lib/ecore_drm/ecore_drm_private.h index b457b47..f95cca1 100644 --- a/src/lib/ecore_drm/ecore_drm_private.h +++ b/src/lib/ecore_drm/ecore_drm_private.h @@ -24,7 +24,6 @@ # include # include # include -# include # ifdef HAVE_SYSTEMD # include @@ -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 -- 2.7.4