devilhorns pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=936350d37fd7d2ba695584db079cfc98eb13faed

commit 936350d37fd7d2ba695584db079cfc98eb13faed
Author: Sung-Jin Park <input.hac...@gmail.com>
Date:   Mon Dec 28 09:18:05 2015 -0500

    ecore-drm: Add APIs to support key remap functionality
    
    Summary:
    This adds two new APIs to enable/set key remap functionality and
    a number of keys to be remapped to the other keys. As of now there is no
    api to do this therefore we need to remap using linux utility such as
    'setkeycodes'. By adding/calling these apis, each Ecore_Drm_Evdev device
    will have its specific key remap hash and we can apply each remapping keys
    for each key/keyboard device.
    
    Test Plan:
    (1) Enable key remap and set remapping of a key on a specific keyboard 
device
    (2) Plug in the keyboard device and check the key is being remapped or not
    (3) Check the other keys are coming normally
    (4) Check the the remapping key on a specific keyboard doesn't affect to 
any other devices
    
    Signed-off-by: Sung-Jin Park <input.hac...@gmail.com>
    
    Reviewers: raster, zmike, gwanglim, ManMower, devilhorns
    
    Subscribers: JHyun, ohduna, cedric, jpeg
    
    Differential Revision: https://phab.enlightenment.org/D3463
---
 src/lib/ecore_drm/Ecore_Drm.h         |  35 +++++++++++
 src/lib/ecore_drm/ecore_drm_evdev.c   | 109 +++++++++++++++++++++++++++++++++-
 src/lib/ecore_drm/ecore_drm_private.h |   3 +
 3 files changed, 144 insertions(+), 3 deletions(-)

diff --git a/src/lib/ecore_drm/Ecore_Drm.h b/src/lib/ecore_drm/Ecore_Drm.h
index 47c6004..b7dccce 100644
--- a/src/lib/ecore_drm/Ecore_Drm.h
+++ b/src/lib/ecore_drm/Ecore_Drm.h
@@ -940,6 +940,41 @@ EAPI Eina_Bool 
ecore_drm_output_possible_crtc_get(Ecore_Drm_Output *output, unsi
  */
 EAPI Eina_Bool ecore_drm_output_mode_set(Ecore_Drm_Output *output, 
Ecore_Drm_Output_Mode *mode, int x, int y);
 
+/**
+ * Enable key remap functionality on a Ecore_Drm_Evdev
+ *
+ * This function will enable the key remap functionality to the given 
Ecore_Drm_Evdev
+ *
+ * @param edev The Ecore_Drm_Evdev to enable the key remap on
+ * @param enable A valid Eina_Bool to enable or disable the key remap on the 
device
+ *
+ * @return EINA_FALSE is returned if the Ecore_Drm_Evdev is not valid, or if 
no libinput device has been
+ * assigned to it yet. EINA_TRUE will be returned if enabling key remap for 
this device succeeded.
+ *
+ * @ingroup Ecore_Drm_Input_Group
+ * @since 1.17
+ */
+EAPI Eina_Bool ecore_drm_evdev_key_remap_enable(Ecore_Drm_Evdev *edev, 
Eina_Bool enable);
+
+/**
+ * Set a given set of keys as remapped keys on a Ecore_Drm_Evdev
+ *
+ * This function will create a hash table of remapping keys as a member of the 
given Ecore_Drm_Evdev
+ *
+ * @param edev The Ecore_Drm_Evdev to set the remapping keys on
+ * @param from_keys A set of keycodes which contains the original keycode
+ * @param to_keys A set of keycodes which contains the keycode to be remapped
+ * @param num The number of keys to be applied
+ *
+ * @return EINA_FALSE is returned if the Ecore_Drm_Evdev is not valid, if no 
libinput device has been
+ * assigned to it yet, if key remap is not enabled yet, or the some of the 
given parameters such as
+ * from_keys, to_keys, num are not valid. EINA_TRUE will be returned if 
setting key remap for this device succeeded.
+ *
+ * @ingroup Ecore_Drm_Input_Group
+ * @since 1.17
+ */
+EAPI Eina_Bool ecore_drm_evdev_key_remap_set(Ecore_Drm_Evdev *edev, int 
*from_keys, int *to_keys, int num);
+
 # ifdef __cplusplus
 }
 # endif
diff --git a/src/lib/ecore_drm/ecore_drm_evdev.c 
b/src/lib/ecore_drm/ecore_drm_evdev.c
index 824fb09..1052f98 100644
--- a/src/lib/ecore_drm/ecore_drm_evdev.c
+++ b/src/lib/ecore_drm/ecore_drm_evdev.c
@@ -247,13 +247,29 @@ _device_modifiers_update(Ecore_Drm_Evdev *edev)
 
 }
 
+static int
+_device_remapped_key_get(Ecore_Drm_Evdev *edev, int code)
+{
+   void *ret = NULL;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(edev, code);
+   if (!edev->key_remap_enabled) return code;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(edev->key_remap_hash, code);
+
+   ret = eina_hash_find(edev->key_remap_hash, &code);
+
+   if (ret) code = (int)(intptr_t)ret;
+
+   return code;
+}
+
 static void
 _device_handle_key(struct libinput_device *device, struct 
libinput_event_keyboard *event)
 {
    Ecore_Drm_Evdev *edev;
    Ecore_Drm_Input *input;
-   uint32_t timestamp;
-   uint32_t code, nsyms;
+   uint32_t timestamp, nsyms;
+   uint32_t code = 0;
    const xkb_keysym_t *syms;
    enum libinput_key_state state;
    int key_count;
@@ -267,7 +283,12 @@ _device_handle_key(struct libinput_device *device, struct 
libinput_event_keyboar
    if (!(input = edev->seat->input)) return;
 
    timestamp = libinput_event_keyboard_get_time(event);
-   code = libinput_event_keyboard_get_key(event) + 8;
+   code = libinput_event_keyboard_get_key(event);
+
+   if (!code) return;
+
+   code = _device_remapped_key_get(edev, code) + 8;
+
    state = libinput_event_keyboard_get_key_state(event);
    key_count = libinput_event_keyboard_get_seat_key_count(event);
 
@@ -835,6 +856,7 @@ _ecore_drm_evdev_device_destroy(Ecore_Drm_Evdev *edev)
 
    if (edev->path) eina_stringshare_del(edev->path);
    if (edev->device) libinput_device_unref(edev->device);
+   if (edev->key_remap_hash) eina_hash_free(edev->key_remap_hash);
 
    free(edev);
 }
@@ -942,3 +964,84 @@ cont:
         continue;
      }
 }
+
+/**
+ * @brief Enable key remap functionality on the given device
+ *
+ * @param edev The Ecore_Drm_Evdev to enable the key remap on.
+ * @param enable An Eina_Bool value to enable or disable the key remap on the 
device.
+ * @return EINA_FALSE is returned if the Ecore_Drm_Evdev is not valid, or if 
no libinput device has been
+ * assigned to it yet. EINA_TRUE will be returned if enabling key remap for 
this device succeeded.
+ *
+ * This function enables/disables key remap functionality with the given 
enable value.
+ * If the given enable value is EINA_FALSE, the key remap functionality wil be 
disable and
+ * the existing hash table for remapping keys will be freed.
+ */
+EAPI Eina_Bool
+ecore_drm_evdev_key_remap_enable(Ecore_Drm_Evdev *edev, Eina_Bool enable)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(edev, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(edev->device, EINA_FALSE);
+
+   edev->key_remap_enabled = enable;
+
+   if (enable == EINA_FALSE && edev->key_remap_hash)
+     {
+        eina_hash_free(edev->key_remap_hash);
+        edev->key_remap_hash = NULL;
+     }
+
+   return EINA_TRUE;
+}
+
+/**
+ * @brief Set a set of keys as remapping keys on the given device.
+ *
+ * @param edev The Ecore_Drm_Evdev to set the remapping keys on
+ * @param from_keys A set of keys which contains the original keycodes
+ * @param to_keys A set of keys which contains the keycodes to be remapped
+ * @param num The number of keys to be applied
+ * @return EINA_FALSE is returned if the Ecore_Drm_Evdev is not valid, if no 
libinput device has been
+ * assigned to it yet, if key remap is not enabled yet, or the some of the 
given parameters such as
+ * from_keys, to_keys, num are not valid. EINA_TRUE will be returned if 
setting key remap for this device succeeded.
+ *
+ * This function will create a hash table of remapping keys as a member of the 
given device.
+ * This hash table will be used in _device_remapped_key_get() later on.
+ * Whenever a key event is coming from the the backend of ecore drm layer
+ * the keycode of it can be replaced with the key found in the hash table.
+ * If there is no key found, the coming keycode will be used.
+ */
+EAPI Eina_Bool
+ecore_drm_evdev_key_remap_set(Ecore_Drm_Evdev *edev, int *from_keys, int 
*to_keys, int num)
+{
+   int i;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(edev, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(edev->device, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(from_keys, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(to_keys, EINA_FALSE);
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(num <= 0, EINA_FALSE);
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(!edev->key_remap_enabled, EINA_FALSE);
+
+   if (!edev->key_remap_hash) edev->key_remap_hash = eina_hash_int32_new(NULL);
+
+   if (!edev->key_remap_hash)
+     {
+        ERR("Failed to set remap key information : creating a hash is 
failed.");
+        return EINA_FALSE;
+     }
+
+   for (i = 0; i < num ; i++)
+     {
+        if ((!from_keys[i]) || (!to_keys[i]))
+          {
+             ERR("Failed to set remap key information : given arguments are 
invalid.");
+             return EINA_FALSE;
+          }
+     }
+
+   for (i = 0; i < num ; i++)
+     eina_hash_add(edev->key_remap_hash, &from_keys[i], (void 
*)(intptr_t)to_keys[i]);
+
+   return EINA_TRUE;
+}
diff --git a/src/lib/ecore_drm/ecore_drm_private.h 
b/src/lib/ecore_drm/ecore_drm_private.h
index fbc6bda..6d30dee 100644
--- a/src/lib/ecore_drm/ecore_drm_private.h
+++ b/src/lib/ecore_drm/ecore_drm_private.h
@@ -225,6 +225,9 @@ struct _Ecore_Drm_Evdev
         unsigned int depressed, latched, locked, group;
      } xkb;
 
+   Eina_Hash *key_remap_hash;
+   Eina_Bool key_remap_enabled : 1;
+
    /* Ecore_Drm_Evdev_Capabilities caps; */
    Ecore_Drm_Seat_Capabilities seat_caps;
 };

-- 


Reply via email to