elput: Add APIs to support keyboard key remapping
authorChris Michael <cpmichael@osg.samsung.com>
Thu, 26 May 2016 16:36:51 +0000 (12:36 -0400)
committerChris Michael <cpmichael@osg.samsung.com>
Thu, 26 May 2016 16:49:24 +0000 (12:49 -0400)
This patch adds 2 new API functions which can enable keyboard key
remapping, and set which keys are to be remapped.

@feature

Signed-off-by: Chris Michael <cpmichael@osg.samsung.com>
src/lib/elput/Elput.h
src/lib/elput/elput_evdev.c
src/lib/elput/elput_input.c
src/lib/elput/elput_private.h

index 8d3d6f6..a7f0b7e 100644 (file)
@@ -351,6 +351,34 @@ EAPI void elput_input_pointer_max_set(Elput_Manager *manager, int maxw, int maxh
  */
 EAPI void elput_input_devices_calibrate(Elput_Manager *manager, int w, int h);
 
+/**
+ * Enable key remap functionality
+ *
+ * @param manager
+ * @param enable
+ *
+ * @return EINA_TRUE on success, EINA_FALSE otherwise
+ *
+ * @ingroup Elput_Input_Group
+ * @since 1.18
+ */
+EAPI Eina_Bool elput_input_key_remap_enable(Elput_Manager *manager, Eina_Bool enable);
+
+/**
+ * Set a given set of keys as remapped keys
+ *
+ * @param manager
+ * @param from_keys
+ * @param to_keys
+ * @param num
+ *
+ * @return EINA_TRUE on success, EINA_FALSE otherwise
+ *
+ * @ingroup Elput_Input_Group
+ * @since 1.18
+ */
+EAPI Eina_Bool elput_input_key_remap_set(Elput_Manager *manager, int *from_keys, int *to_keys, int num);
+
 # endif
 
 # undef EAPI
index 82768d6..c083a17 100644 (file)
@@ -384,6 +384,20 @@ _keyboard_keymap_update(Elput_Seat *seat)
 }
 
 static int
+_keyboard_remapped_key_get(Elput_Device *edev, int code)
+{
+   void *ret = NULL;
+
+   if (!edev) return code;
+   if (!edev->key_remap) return code;
+   if (!edev->key_remap_hash) return code;
+
+   ret = eina_hash_find(edev->key_remap_hash, &code);
+   if (ret) code = (int)(intptr_t)ret;
+   return code;
+}
+
+static int
 _keyboard_keysym_translate(xkb_keysym_t keysym, unsigned int modifiers, char *buffer, int bytes)
 {
    unsigned long hbytes = 0;
@@ -456,7 +470,9 @@ _keyboard_key(struct libinput_device *idevice, struct libinput_event_keyboard *e
        ((state == LIBINPUT_KEY_STATE_RELEASED) && (count != 0)))
      return;
 
-   code = libinput_event_keyboard_get_key(event) + 8;
+   code = libinput_event_keyboard_get_key(event);
+   code = _keyboard_remapped_key_get(dev, code) + 8;
+
    timestamp = libinput_event_keyboard_get_time(event);
 
    if (state == LIBINPUT_KEY_STATE_PRESSED)
@@ -1280,6 +1296,9 @@ _evdev_device_destroy(Elput_Device *edev)
 
    libinput_device_unref(edev->device);
    eina_stringshare_del(edev->output_name);
+
+   if (edev->key_remap_hash) eina_hash_free(edev->key_remap_hash);
+
    free(edev);
 }
 
index b427c38..e838c9b 100644 (file)
@@ -510,3 +510,69 @@ elput_input_devices_calibrate(Elput_Manager *manager, int w, int h)
           }
      }
 }
+
+EAPI Eina_Bool
+elput_input_key_remap_enable(Elput_Manager *manager, Eina_Bool enable)
+{
+   Elput_Seat *eseat;
+   Elput_Device *edev;
+   Eina_List *l, *ll;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(manager, EINA_FALSE);
+
+   EINA_LIST_FOREACH(manager->input.seats, l, eseat)
+     {
+        EINA_LIST_FOREACH(eseat->devices, ll, edev)
+          {
+             if (!(edev->caps & EVDEV_SEAT_KEYBOARD)) continue;
+
+             edev->key_remap = enable;
+             if ((!enable) && (edev->key_remap_hash))
+               {
+                  eina_hash_free(edev->key_remap_hash);
+                  edev->key_remap_hash = NULL;
+               }
+          }
+     }
+
+   return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+elput_input_key_remap_set(Elput_Manager *manager, int *from_keys, int *to_keys, int num)
+{
+   Elput_Seat *eseat;
+   Elput_Device *edev;
+   Eina_List *l, *ll;
+   int i = 0;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(manager, 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_LIST_FOREACH(manager->input.seats, l, eseat)
+     {
+        EINA_LIST_FOREACH(eseat->devices, ll, edev)
+          {
+             if (!(edev->caps & EVDEV_SEAT_KEYBOARD)) continue;
+
+             if (!edev->key_remap) continue;
+             if (!edev->key_remap_hash)
+               edev->key_remap_hash = eina_hash_int32_new(NULL);
+             if (!edev->key_remap_hash) continue;
+
+             for (i = 0; i < num; i++)
+               {
+                  if ((!from_keys[i]) || (!to_keys[i]))
+                    continue;
+               }
+
+             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;
+}
index dc34f24..2d9de14 100644 (file)
@@ -217,7 +217,10 @@ struct _Elput_Device
 
    Elput_Device_Capability caps;
 
+   Eina_Hash *key_remap_hash;
+
    Eina_Bool left_handed : 1;
+   Eina_Bool key_remap : 1;
 };
 
 struct _Elput_Manager