Implement remap for support keys which had keycode bigger than 255 72/34972/1 accepted/tizen_common accepted/tizen_mobile accepted/tizen_tv accepted/tizen_wearable tizen tizen_3.0.2015.q2_common accepted/tizen/common/20150210.133013 accepted/tizen/mobile/20150210.155521 accepted/tizen/tv/20150210.141306 accepted/tizen/wearable/20150210.155102 submit/tizen/20150210.105318
authorJeong-Hyun Kang <jhyuni.kang@samsung.com>
Thu, 5 Feb 2015 06:17:11 +0000 (15:17 +0900)
committerJeong-Hyun Kang <jhyuni.kang@samsung.com>
Thu, 5 Feb 2015 06:17:43 +0000 (15:17 +0900)
Change-Id: Ib534968886004851df605a1314de4b4a2f899cc0

packaging/xf86-input-evdev.spec
src/evdev.c
src/evdev.h

index 3becc13..dd11dfa 100644 (file)
@@ -44,6 +44,7 @@ including most mice, keyboards, tablets and touchscreens.
 cp %{SOURCE1001} .
 
 %build
+CFLAGS="$CFLAGS -D_F_REMAP_KEYS_ "
 %configure
 make %{?_smp_mflags}
 
index 54772c7..facfa32 100644 (file)
@@ -140,6 +140,48 @@ static Atom prop_virtual;
  * cannot be used by evdev, leaving us with a space of 2 at the end. */
 static EvdevPtr evdev_devices[MAXDEVICES] = {NULL};
 
+#ifdef _F_REMAP_KEYS_
+static uint16_t
+remapKey(EvdevPtr ev, uint16_t code)
+{
+    uint8_t slice=code/256;
+    uint8_t offs=code%256;
+
+    if (!ev->keyremap) return code;
+    if (!(ev->keyremap->sl[slice])) return code;
+    if (!(ev->keyremap->sl[slice]->cd[offs])) return code;
+    return ev->keyremap->sl[slice]->cd[offs];
+}
+
+static void
+addRemap(EvdevPtr ev,uint16_t code,uint8_t value)
+{
+    uint8_t slice=code/256;
+    uint8_t offs=code%256;
+
+    if (!ev->keyremap) {
+        ev->keyremap=(EvdevKeyRemapPtr)calloc(sizeof(EvdevKeyRemap),1);
+    }
+    if (!ev->keyremap->sl[slice]) {
+        ev->keyremap->sl[slice]=(EvdevKeyRemapSlice*)calloc(sizeof(EvdevKeyRemapSlice),1);
+     }
+     ev->keyremap->sl[slice]->cd[offs]=value;
+}
+
+static void
+freeRemap(EvdevPtr ev)
+{
+    uint16_t slice;
+    if (!ev->keyremap) return;
+    for (slice=0;slice<256;++slice) {
+        if (!ev->keyremap->sl[slice]) continue;
+        free(ev->keyremap->sl[slice]);
+    }
+    free(ev->keyremap);
+    ev->keyremap=0;
+}
+#endif //_F_REMAP_KEYS_
+
 static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode)
 {
     InputInfoPtr pInfo;
@@ -332,6 +374,44 @@ static int wheel_left_button = 6;
 static int wheel_right_button = 7;
 #endif
 
+#ifdef _F_REMAP_KEYS_
+static void
+SetRemapOption(InputInfoPtr pInfo,const char* name)
+{
+    char *s,*c;
+    unsigned long int code,value;
+    int consumed;
+    EvdevPtr ev = pInfo->private;
+
+    s = xf86SetStrOption(pInfo->options, name, NULL);
+    if (!s) return;
+    if (!s[0]) {
+        free(s);
+        return;
+    }
+
+    c=s;
+    while (sscanf(c," %li = %li %n",&code,&value,&consumed) > 1) {
+        c+=consumed;
+        if (code < 0 || code > 65535L) {
+            xf86Msg(X_ERROR,"%s: input code %ld out of range for option \"event_key_remap\", ignoring.\n",pInfo->name,code);
+            continue;
+        }
+        if (value < MIN_KEYCODE || value > 255) {
+            xf86Msg(X_ERROR,"%s: output value %ld out of range for option \"event_key_remap\", ignoring.\n",pInfo->name,value);
+            continue;
+        }
+        xf86Msg(X_INFO,"%s: remapping %ld into %ld.\n",pInfo->name,code,value);
+        addRemap(ev,code,value-MIN_KEYCODE);
+    }
+
+    if (*c!='\0') {
+        xf86Msg(X_ERROR, "%s: invalid input for option \"event_key_remap\" starting at '%s', ignoring.\n",
+                pInfo->name, c);
+    }
+}
+#endif //_F_REMAP_KEYS_
+
 static EventQueuePtr
 EvdevNextInQueue(InputInfoPtr pInfo)
 {
@@ -350,7 +430,11 @@ EvdevNextInQueue(InputInfoPtr pInfo)
 void
 EvdevQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
 {
+#ifdef _F_REMAP_KEYS_
+    int code = remapKey((EvdevPtr)(pInfo->private),ev->code) + MIN_KEYCODE;
+#else //_F_REMAP_KEYS_
     int code = ev->code + MIN_KEYCODE;
+#endif //_F_REMAP_KEYS_
     EventQueuePtr pQueue;
 
     /* Filter all repeated events from device.
@@ -1191,6 +1275,10 @@ EvdevAddKeyClass(DeviceIntPtr device)
     if (!InitKeyboardDeviceStruct(device, &pEvdev->rmlvo, NULL, EvdevKbdCtrl))
         return !Success;
 
+#ifdef _F_REMAP_KEYS_
+    SetRemapOption(pInfo,"event_key_remap");
+#endif //_F_REMAP_KEYS_
+
     return Success;
 }
 
@@ -1878,6 +1966,9 @@ EvdevProc(DeviceIntPtr device, int what)
         EvdevCloseDevice(pInfo);
         EvdevFreeMasks(pEvdev);
         EvdevRemoveDevice(pInfo);
+#ifdef _F_REMAP_KEYS_
+        freeRemap(pEvdev);
+#endif //_F_REMAP_KEYS_
         pEvdev->min_maj = 0;
        break;
 
index c2f9246..44bb42b 100644 (file)
@@ -145,6 +145,15 @@ typedef struct {
 #endif
 } EventQueueRec, *EventQueuePtr;
 
+#ifdef _F_REMAP_KEYS_
+typedef struct {
+    uint8_t cd[256];
+} EvdevKeyRemapSlice;
+typedef struct {
+    EvdevKeyRemapSlice* sl[256];
+} EvdevKeyRemap, *EvdevKeyRemapPtr;
+#endif //_F_REMAP_KEYS_
+
 typedef struct {
     unsigned short id_vendor;
     unsigned short id_product;
@@ -228,6 +237,10 @@ typedef struct {
 
     unsigned char btnmap[32];           /* config-file specified button mapping */
 
+#ifdef _F_REMAP_KEYS_
+    EvdevKeyRemapPtr keyremap;
+#endif //_F_REMAP_KEYS_
+
     int reopen_attempts; /* max attempts to re-open after read failure */
     int reopen_left;     /* number of attempts left to re-open the device */
     OsTimerPtr reopen_timer;