From 40c1e796fe003dd7d364ef0ab496fcf063f64a4b Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 20 Jan 2016 12:38:22 -0500 Subject: [PATCH] add function for wayland compositors to generate (fake) keyboard events in automated testing scenarios, being able to generate input events is useful for detecting regressions related to keyboard actions this depends on an xkbcommon function which is expected to be in the 0.6.0 release, so dlsym here in order to make that a runtime dependency for now since this is not going to be a widely-used feature #SamsungFeatures --- src/bin/e_comp_wl_input.c | 66 +++++++++++++++++++++++++++++++++++++++ src/bin/e_comp_wl_input.h | 1 + 2 files changed, 67 insertions(+) diff --git a/src/bin/e_comp_wl_input.c b/src/bin/e_comp_wl_input.c index e430a3bbe..19338b493 100644 --- a/src/bin/e_comp_wl_input.c +++ b/src/bin/e_comp_wl_input.c @@ -7,6 +7,7 @@ #endif E_API int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = -1; +static xkb_keycode_t (*_xkb_keymap_key_by_name)(void *, const char *); static void _e_comp_wl_input_update_seat_caps(void) @@ -437,6 +438,8 @@ e_comp_wl_input_init(void) E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new(); + _xkb_keymap_key_by_name = dlsym(NULL, "xkb_keymap_key_by_name"); + return EINA_TRUE; } @@ -678,3 +681,66 @@ e_comp_wl_input_keyboard_modifers_clear(void) e_comp_wl_input_keyboard_modifiers_serialize(); } + +static void +_event_generate(const char *key, const char *keyname, int mods, Eina_Bool up) +{ + Ecore_Event_Key *ev; + int keycode; + + /* "key" here is the platform-specific key name; + * /usr/share/X11/xkb/keycodes/evdev is probably what your system is using + */ + keycode = _xkb_keymap_key_by_name(e_comp_wl->xkb.keymap, keyname ?: key); + if (!keycode) + { + ERR("no keycode found for key '%s'", key); + return; + } + ev = calloc(1, sizeof(Ecore_Event_Key) + (2 * (strlen(key) + 1))); + + ev->keyname = (char *)(ev + 1); + ev->key = ev->keyname + strlen(key) + 1; + + strcpy((char *)ev->keyname, key); + strcpy((char *)ev->key, key); + + ev->window = e_comp->ee_win; + ev->event_window = e_comp->ee_win; + ev->timestamp = 0; + ev->modifiers = mods; + ev->keycode = keycode; + ecore_event_add(up ? ECORE_EVENT_KEY_UP : ECORE_EVENT_KEY_DOWN, ev, NULL, NULL); +} + +static void +_event_generate_mods(int mods, Eina_Bool up) +{ + if (!mods) return; + if (mods & ECORE_EVENT_MODIFIER_SHIFT) + _event_generate("Shift", "LFSH", mods, up); + if (mods & ECORE_EVENT_MODIFIER_CTRL) + _event_generate("Control_L", "LCTL", mods, up); + if (mods & ECORE_EVENT_MODIFIER_ALT) + _event_generate("Alt_L", "LALT", mods, up); + if (mods & ECORE_EVENT_MODIFIER_WIN) + _event_generate("Super_L", "LWIN", mods, up); + if (mods & ECORE_EVENT_MODIFIER_ALTGR) + _event_generate("Mode_switch", "ALGR", mods, up); +} + +E_API void +e_comp_wl_input_keyboard_event_generate(const char *key, int mods, Eina_Bool up) +{ + if (!_xkb_keymap_key_by_name) + { + ERR("xkbcommon >= 0.6.0 required for keyboard event generation!"); + return; + } + + if (!up) + _event_generate_mods(mods, up); + _event_generate(key, NULL, mods, up); + if (up) + _event_generate_mods(mods, up); +} diff --git a/src/bin/e_comp_wl_input.h b/src/bin/e_comp_wl_input.h index f13d0a151..9691b97be 100644 --- a/src/bin/e_comp_wl_input.h +++ b/src/bin/e_comp_wl_input.h @@ -32,5 +32,6 @@ E_API void e_comp_wl_input_touch_enabled_set(Eina_Bool enabled); E_API void e_comp_wl_input_keymap_set(const char *rules, const char *model, const char *layout, struct xkb_context *dflt_ctx, struct xkb_keymap *dflt_map); +E_API void e_comp_wl_input_keyboard_event_generate(const char *key, int mods, Eina_Bool up); # endif #endif