Input: sparse-keymap - switch to using new keycode interface
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Fri, 10 Sep 2010 04:54:22 +0000 (21:54 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Fri, 10 Sep 2010 05:01:07 +0000 (22:01 -0700)
Switch sparse keymap library to use new style of getkeycode and
setkeycode methods to allow retrieving and setting keycodes not
only by their scancodes but also by index.

Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
drivers/input/sparse-keymap.c

index 014248344763775b49285db0a480e794f5c76c2e..a29a7812bd46cea26613b813a3091eed476077aa 100644 (file)
@@ -22,6 +22,37 @@ MODULE_DESCRIPTION("Generic support for sparse keymaps");
 MODULE_LICENSE("GPL v2");
 MODULE_VERSION("0.1");
 
+static unsigned int sparse_keymap_get_key_index(struct input_dev *dev,
+                                               const struct key_entry *k)
+{
+       struct key_entry *key;
+       unsigned int idx = 0;
+
+       for (key = dev->keycode; key->type != KE_END; key++) {
+               if (key->type == KE_KEY) {
+                       if (key == k)
+                               break;
+                       idx++;
+               }
+       }
+
+       return idx;
+}
+
+static struct key_entry *sparse_keymap_entry_by_index(struct input_dev *dev,
+                                                     unsigned int index)
+{
+       struct key_entry *key;
+       unsigned int key_cnt = 0;
+
+       for (key = dev->keycode; key->type != KE_END; key++)
+               if (key->type == KE_KEY)
+                       if (key_cnt++ == index)
+                               return key;
+
+       return NULL;
+}
+
 /**
  * sparse_keymap_entry_from_scancode - perform sparse keymap lookup
  * @dev: Input device using sparse keymap
@@ -64,16 +95,36 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
 }
 EXPORT_SYMBOL(sparse_keymap_entry_from_keycode);
 
+static struct key_entry *sparse_keymap_locate(struct input_dev *dev,
+                                       const struct input_keymap_entry *ke)
+{
+       struct key_entry *key;
+       unsigned int scancode;
+
+       if (ke->flags & INPUT_KEYMAP_BY_INDEX)
+               key = sparse_keymap_entry_by_index(dev, ke->index);
+       else if (input_scancode_to_scalar(ke, &scancode) == 0)
+               key = sparse_keymap_entry_from_scancode(dev, scancode);
+       else
+               key = NULL;
+
+       return key;
+}
+
 static int sparse_keymap_getkeycode(struct input_dev *dev,
-                                   unsigned int scancode,
-                                   unsigned int *keycode)
+                                   struct input_keymap_entry *ke)
 {
        const struct key_entry *key;
 
        if (dev->keycode) {
-               key = sparse_keymap_entry_from_scancode(dev, scancode);
+               key = sparse_keymap_locate(dev, ke);
                if (key && key->type == KE_KEY) {
-                       *keycode = key->keycode;
+                       ke->keycode = key->keycode;
+                       if (!(ke->flags & INPUT_KEYMAP_BY_INDEX))
+                               ke->index =
+                                       sparse_keymap_get_key_index(dev, key);
+                       ke->len = sizeof(key->code);
+                       memcpy(ke->scancode, &key->code, sizeof(key->code));
                        return 0;
                }
        }
@@ -82,20 +133,19 @@ static int sparse_keymap_getkeycode(struct input_dev *dev,
 }
 
 static int sparse_keymap_setkeycode(struct input_dev *dev,
-                                   unsigned int scancode,
-                                   unsigned int keycode)
+                                   const struct input_keymap_entry *ke,
+                                   unsigned int *old_keycode)
 {
        struct key_entry *key;
-       int old_keycode;
 
        if (dev->keycode) {
-               key = sparse_keymap_entry_from_scancode(dev, scancode);
+               key = sparse_keymap_locate(dev, ke);
                if (key && key->type == KE_KEY) {
-                       old_keycode = key->keycode;
-                       key->keycode = keycode;
-                       set_bit(keycode, dev->keybit);
-                       if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
-                               clear_bit(old_keycode, dev->keybit);
+                       *old_keycode = key->keycode;
+                       key->keycode = ke->keycode;
+                       set_bit(ke->keycode, dev->keybit);
+                       if (!sparse_keymap_entry_from_keycode(dev, *old_keycode))
+                               clear_bit(*old_keycode, dev->keybit);
                        return 0;
                }
        }
@@ -159,15 +209,14 @@ int sparse_keymap_setup(struct input_dev *dev,
 
        dev->keycode = map;
        dev->keycodemax = map_size;
-       dev->getkeycode = sparse_keymap_getkeycode;
-       dev->setkeycode = sparse_keymap_setkeycode;
+       dev->getkeycode_new = sparse_keymap_getkeycode;
+       dev->setkeycode_new = sparse_keymap_setkeycode;
 
        return 0;
 
  err_out:
        kfree(map);
        return error;
-
 }
 EXPORT_SYMBOL(sparse_keymap_setup);