pad: add LIBINPUT_EVENT_TABLET_PAD_KEY for pad keys
authorPeter Hutterer <peter.hutterer@who-t.net>
Thu, 17 Jan 2019 01:08:27 +0000 (11:08 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Wed, 4 Dec 2019 05:38:39 +0000 (15:38 +1000)
The Wacom Cintiq 24HD and later tablets send specific key events for
hardware/soft buttons. KEY_PROG1..KEY_PROG3 on earlier tablets,
KEY_CONTROLPANEL, KEY_ONSCREEN_DISPLAY, and KEY_BUTTONCONFIG on later tablets.
We ignore KEY_PROG1-3 because starting with kernel 5.4 older tablets will too
use the better-named #defines.

These differ from pad buttons as the key code in itself carries semantic
information, so we should pass them on as-is instead of mapping them to
meaningless 0-indexed buttons like we do on the other buttons.

So let's add a new event, LIBINPUT_EVENT_TABLET_PAD_KEY and the associated
functions to handle that case.

Pad keys have a fixed hw-defined semantic meaning and are thus not part of
a tablet mode group.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
src/evdev-tablet-pad.c
src/evdev.h
src/libinput-private.h
src/libinput.c
src/libinput.h
src/libinput.sym
test/litest.c
test/litest.h
test/test-pad.c
tools/libinput-debug-events.c
tools/libinput-debug-gui.c

index 431972ae190d3840b524e2a7908344ea80817a21..97fc97179d80231745dede49aeb80bffbbb02415 100644 (file)
@@ -392,6 +392,10 @@ pad_notify_button_mask(struct pad_dispatch *pad,
                                                         button,
                                                         state,
                                                         group);
+                       } else if (map_is_key(map)) {
+                               uint32_t key = map_value(map);
+
+                               tablet_pad_notify_key(base, time, key, state);
                        } else {
                                abort();
                        }
@@ -611,6 +615,26 @@ pad_init_buttons_from_kernel(struct pad_dispatch *pad,
        pad->nbuttons = map;
 }
 
+static void
+pad_init_keys(struct pad_dispatch *pad, struct evdev_device *device)
+{
+       unsigned int codes[] = {
+               KEY_BUTTONCONFIG,
+               KEY_ONSCREEN_KEYBOARD,
+               KEY_CONTROLPANEL,
+       };
+       unsigned int *code;
+
+       /* Wacom's keys are the only ones we know anything about */
+       if (libevdev_get_id_vendor(device->evdev) != VENDOR_ID_WACOM)
+               return;
+
+       ARRAY_FOR_EACH(codes, code) {
+               if (libevdev_has_event_code(device->evdev, EV_KEY, *code))
+                       map_set_key_map(pad->button_map[*code], *code);
+       }
+}
+
 static void
 pad_init_buttons(struct pad_dispatch *pad,
                 struct evdev_device *device)
@@ -623,6 +647,7 @@ pad_init_buttons(struct pad_dispatch *pad,
        if (!pad_init_buttons_from_libwacom(pad, device))
                pad_init_buttons_from_kernel(pad, device);
 
+       pad_init_keys(pad, device);
 }
 
 static void
@@ -718,6 +743,15 @@ evdev_tablet_pad_create(struct evdev_device *device)
        return &pad->base;
 }
 
+int
+evdev_device_tablet_pad_has_key(struct evdev_device *device, uint32_t code)
+{
+       if (!(device->seat_caps & EVDEV_DEVICE_TABLET_PAD))
+               return -1;
+
+       return libevdev_has_event_code(device->evdev, EV_KEY, code);
+}
+
 int
 evdev_device_tablet_pad_get_num_buttons(struct evdev_device *device)
 {
index 0af0ba36b61dd844877095cfc13a459e92e37f44..e95f7e60f1dedeab919311e0ac80042bd7896bbb 100644 (file)
@@ -510,6 +510,10 @@ int
 evdev_device_has_switch(struct evdev_device *device,
                        enum libinput_switch sw);
 
+int
+evdev_device_tablet_pad_has_key(struct evdev_device *device,
+                               uint32_t code);
+
 int
 evdev_device_tablet_pad_get_num_buttons(struct evdev_device *device);
 
index 1a7900fd1c6a7de99d8381c4dbad074c193cccbf..cb3a4017d79575716259893b0dd088b8ae006b8c 100644 (file)
@@ -683,6 +683,11 @@ tablet_pad_notify_strip(struct libinput_device *device,
                        enum libinput_tablet_pad_strip_axis_source source,
                        struct libinput_tablet_pad_mode_group *group);
 void
+tablet_pad_notify_key(struct libinput_device *device,
+                     uint64_t time,
+                     int32_t key,
+                     enum libinput_key_state state);
+void
 switch_notify_toggle(struct libinput_device *device,
                     uint64_t time,
                     enum libinput_switch sw,
index 9570dc684899e199ea862360d4e3392f1c714eb6..e764375bdc4fc65c6b78b4121499a28146fa9a9d 100644 (file)
@@ -130,6 +130,7 @@ event_type_to_str(enum libinput_event_type type)
        CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_BUTTON);
        CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_RING);
        CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_STRIP);
+       CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_KEY);
        CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN);
        CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE);
        CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_END);
@@ -218,6 +219,10 @@ struct libinput_event_tablet_pad {
                uint32_t number;
                enum libinput_button_state state;
        } button;
+       struct {
+               uint32_t code;
+               enum libinput_key_state state;
+       } key;
        struct {
                enum libinput_tablet_pad_ring_axis_source source;
                double position;
@@ -425,7 +430,8 @@ libinput_event_get_tablet_pad_event(struct libinput_event *event)
                           NULL,
                           LIBINPUT_EVENT_TABLET_PAD_RING,
                           LIBINPUT_EVENT_TABLET_PAD_STRIP,
-                          LIBINPUT_EVENT_TABLET_PAD_BUTTON);
+                          LIBINPUT_EVENT_TABLET_PAD_BUTTON,
+                          LIBINPUT_EVENT_TABLET_PAD_KEY);
 
        return (struct libinput_event_tablet_pad *) event;
 }
@@ -1914,7 +1920,8 @@ libinput_event_tablet_tool_destroy(struct libinput_event_tablet_tool *event)
 static void
 libinput_event_tablet_pad_destroy(struct libinput_event_tablet_pad *event)
 {
-       libinput_tablet_pad_mode_group_unref(event->mode_group);
+       if (event->base.type != LIBINPUT_EVENT_TABLET_PAD_KEY)
+               libinput_tablet_pad_mode_group_unref(event->mode_group);
 }
 
 LIBINPUT_EXPORT void
@@ -1934,6 +1941,7 @@ libinput_event_destroy(struct libinput_event *event)
        case LIBINPUT_EVENT_TABLET_PAD_RING:
        case LIBINPUT_EVENT_TABLET_PAD_STRIP:
        case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
+       case LIBINPUT_EVENT_TABLET_PAD_KEY:
                libinput_event_tablet_pad_destroy(
                   libinput_event_get_tablet_pad_event(event));
                break;
@@ -2767,6 +2775,28 @@ tablet_pad_notify_strip(struct libinput_device *device,
                          &strip_event->base);
 }
 
+void
+tablet_pad_notify_key(struct libinput_device *device,
+                     uint64_t time,
+                     int32_t key,
+                     enum libinput_key_state state)
+{
+       struct libinput_event_tablet_pad *key_event;
+
+       key_event = zalloc(sizeof *key_event);
+
+       *key_event = (struct libinput_event_tablet_pad) {
+               .time = time,
+               .key.code = key,
+               .key.state = state,
+       };
+
+       post_device_event(device,
+                         time,
+                         LIBINPUT_EVENT_TABLET_PAD_KEY,
+                         &key_event->base);
+}
+
 static void
 gesture_notify(struct libinput_device *device,
               uint64_t time,
@@ -3115,6 +3145,13 @@ libinput_device_switch_has_switch(struct libinput_device *device,
        return evdev_device_has_switch((struct evdev_device *)device, sw);
 }
 
+LIBINPUT_EXPORT int
+libinput_device_tablet_pad_has_key(struct libinput_device *device, uint32_t code)
+{
+       return evdev_device_tablet_pad_has_key((struct evdev_device *)device,
+                                              code);
+}
+
 LIBINPUT_EXPORT int
 libinput_device_tablet_pad_get_num_buttons(struct libinput_device *device)
 {
@@ -3418,6 +3455,28 @@ libinput_event_tablet_pad_get_button_state(struct libinput_event_tablet_pad *eve
        return event->button.state;
 }
 
+LIBINPUT_EXPORT uint32_t
+libinput_event_tablet_pad_get_key(struct libinput_event_tablet_pad *event)
+{
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TABLET_PAD_KEY);
+
+       return event->key.code;
+}
+
+LIBINPUT_EXPORT enum libinput_key_state
+libinput_event_tablet_pad_get_key_state(struct libinput_event_tablet_pad *event)
+{
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          LIBINPUT_KEY_STATE_RELEASED,
+                          LIBINPUT_EVENT_TABLET_PAD_KEY);
+
+       return event->key.state;
+}
+
 LIBINPUT_EXPORT unsigned int
 libinput_event_tablet_pad_get_mode(struct libinput_event_tablet_pad *event)
 {
@@ -3452,7 +3511,8 @@ libinput_event_tablet_pad_get_time(struct libinput_event_tablet_pad *event)
                           0,
                           LIBINPUT_EVENT_TABLET_PAD_RING,
                           LIBINPUT_EVENT_TABLET_PAD_STRIP,
-                          LIBINPUT_EVENT_TABLET_PAD_BUTTON);
+                          LIBINPUT_EVENT_TABLET_PAD_BUTTON,
+                          LIBINPUT_EVENT_TABLET_PAD_KEY);
 
        return us2ms(event->time);
 }
@@ -3465,7 +3525,8 @@ libinput_event_tablet_pad_get_time_usec(struct libinput_event_tablet_pad *event)
                           0,
                           LIBINPUT_EVENT_TABLET_PAD_RING,
                           LIBINPUT_EVENT_TABLET_PAD_STRIP,
-                          LIBINPUT_EVENT_TABLET_PAD_BUTTON);
+                          LIBINPUT_EVENT_TABLET_PAD_BUTTON,
+                          LIBINPUT_EVENT_TABLET_PAD_KEY);
 
        return event->time;
 }
@@ -3478,7 +3539,8 @@ libinput_event_tablet_pad_get_base_event(struct libinput_event_tablet_pad *event
                           NULL,
                           LIBINPUT_EVENT_TABLET_PAD_RING,
                           LIBINPUT_EVENT_TABLET_PAD_STRIP,
-                          LIBINPUT_EVENT_TABLET_PAD_BUTTON);
+                          LIBINPUT_EVENT_TABLET_PAD_BUTTON,
+                          LIBINPUT_EVENT_TABLET_PAD_KEY);
 
        return &event->base;
 }
index 54d40de641d166a5c0ee83bbdbbe6a43abb46a97..5a19f79d19ac4c30a94d017265327191a9f6d809 100644 (file)
@@ -845,6 +845,12 @@ enum libinput_event_type {
         * A button pressed on a device with the @ref
         * LIBINPUT_DEVICE_CAP_TABLET_PAD capability.
         *
+        * A button differs from @ref LIBINPUT_EVENT_TABLET_PAD_KEY in that
+        * buttons are sequentially indexed from 0 and do not carry any
+        * other information.  Keys have a specific functionality assigned
+        * to them. The key code thus carries a semantic meaning, a button
+        * number does not.
+        *
         * This event is not to be confused with the button events emitted
         * by tools on a tablet (@ref LIBINPUT_EVENT_TABLET_TOOL_BUTTON).
         *
@@ -867,6 +873,19 @@ enum libinput_event_type {
         */
        LIBINPUT_EVENT_TABLET_PAD_STRIP,
 
+       /**
+        * A key pressed on a device with the @ref
+        * LIBINPUT_DEVICE_CAP_TABLET_PAD capability.
+        *
+        * A key differs from @ref LIBINPUT_EVENT_TABLET_PAD_BUTTON in that
+        * keys have a specific functionality assigned to them (buttons are
+        * sequentially ordered). The key code thus carries a semantic
+        * meaning, a button number does not.
+        *
+        * @since 1.15
+        */
+       LIBINPUT_EVENT_TABLET_PAD_KEY,
+
        LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN = 800,
        LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
        LIBINPUT_EVENT_GESTURE_SWIPE_END,
@@ -3062,6 +3081,44 @@ libinput_event_tablet_pad_get_button_number(struct libinput_event_tablet_pad *ev
 enum libinput_button_state
 libinput_event_tablet_pad_get_button_state(struct libinput_event_tablet_pad *event);
 
+/**
+ * @ingroup event_tablet_pad
+ *
+ * Return the key code that triggered this event, e.g. KEY_CONTROLPANEL. The
+ * list of key codes is defined in linux/input-event-codes.h.
+ *
+ * For events that are not of type @ref LIBINPUT_EVENT_TABLET_PAD_KEY,
+ * this function returns 0.
+ *
+ * @note It is an application bug to call this function for events other than
+ * @ref LIBINPUT_EVENT_TABLET_PAD_KEY. For other events, this function
+ * returns 0.
+ *
+ * @param event The libinput tablet pad event
+ * @return the key code triggering this event
+ *
+ * @since 1.15
+ */
+uint32_t
+libinput_event_tablet_pad_get_key(struct libinput_event_tablet_pad *event);
+
+/**
+ * @ingroup event_tablet_pad
+ *
+ * Return the key state of the event.
+ *
+ * @note It is an application bug to call this function for events other than
+ * @ref LIBINPUT_EVENT_TABLET_PAD_KEY. For other events, this function
+ * returns 0.
+ *
+ * @param event The libinput tablet pad event
+ * @return the key state triggering this event
+ *
+ * @since 1.15
+ */
+enum libinput_key_state
+libinput_event_tablet_pad_get_key_state(struct libinput_event_tablet_pad *event);
+
 /**
  * @ingroup event_tablet_pad
  *
@@ -3072,6 +3129,9 @@ libinput_event_tablet_pad_get_button_state(struct libinput_event_tablet_pad *eve
  * visual feedback like LEDs on the pad. Mode indices start at 0, a device
  * that does not support modes always returns 0.
  *
+ * @note Pad keys are not part of a mode group. It is an application bug to
+ * call this function for @ref LIBINPUT_EVENT_TABLET_PAD_KEY.
+ *
  * Mode switching is controlled by libinput and more than one mode may exist
  * on the tablet. This function returns the mode that this event's button,
  * ring or strip is logically in. If the button is a mode toggle button
@@ -3102,6 +3162,9 @@ libinput_event_tablet_pad_get_mode(struct libinput_event_tablet_pad *event);
  * functionality, usually based on some visual feedback like LEDs on the
  * pad.
  *
+ * @note Pad keys are not part of a mode group. It is an application bug to
+ * call this function for @ref LIBINPUT_EVENT_TABLET_PAD_KEY.
+ *
  * The returned mode group is not refcounted and may become invalid after
  * the next call to libinput. Use libinput_tablet_pad_mode_group_ref() and
  * libinput_tablet_pad_mode_group_unref() to continue using the handle
@@ -4153,6 +4216,24 @@ libinput_device_tablet_pad_get_num_rings(struct libinput_device *device);
 int
 libinput_device_tablet_pad_get_num_strips(struct libinput_device *device);
 
+/**
+ * @ingroup device
+ *
+ * Check if a @ref LIBINPUT_DEVICE_CAP_TABLET_PAD device has a key with the
+ * given code (see linux/input-event-codes.h).
+ *
+ * @param device A current input device
+ * @param code Key code to check for, e.g. <i>KEY_ESC</i>
+ *
+ * @return 1 if the device supports this key code, 0 if it does not, -1
+ * on error.
+ *
+ * @since 1.15
+ */
+int
+libinput_device_tablet_pad_has_key(struct libinput_device *device,
+                                  uint32_t code);
+
 /**
  * @ingroup device
  *
index 1698a066d90aa71d490e89e18d18b8eb6e719724..b45838e0b12936543cceb51d9f19c66ae1efa238 100644 (file)
@@ -310,4 +310,7 @@ LIBINPUT_1.15 {
        libinput_device_config_scroll_set_button_lock;
        libinput_device_config_scroll_get_button_lock;
        libinput_device_config_scroll_get_default_button_lock;
+       libinput_device_tablet_pad_has_key;
+       libinput_event_tablet_pad_get_key;
+       libinput_event_tablet_pad_get_key_state;
 } LIBINPUT_1.14;
index 8c4e52ee9293624a07ae13bc58ae13adde2c6359..5325720a3e422609dccca0c6720839d3caa5b106 100644 (file)
@@ -2975,6 +2975,9 @@ litest_event_type_str(enum libinput_event_type type)
        case LIBINPUT_EVENT_TABLET_PAD_STRIP:
                str = "TABLET PAD STRIP";
                break;
+       case LIBINPUT_EVENT_TABLET_PAD_KEY:
+               str = "TABLET PAD KEY";
+               break;
        case LIBINPUT_EVENT_SWITCH_TOGGLE:
                str = "SWITCH TOGGLE";
                break;
@@ -3600,6 +3603,27 @@ litest_is_pad_strip_event(struct libinput_event *event,
        return p;
 }
 
+struct libinput_event_tablet_pad *
+litest_is_pad_key_event(struct libinput_event *event,
+                       unsigned int key,
+                       enum libinput_key_state state)
+{
+       struct libinput_event_tablet_pad *p;
+       enum libinput_event_type type = LIBINPUT_EVENT_TABLET_PAD_KEY;
+
+       litest_assert(event != NULL);
+       litest_assert_event_type(event, type);
+
+       p = libinput_event_get_tablet_pad_event(event);
+       litest_assert(p != NULL);
+
+       litest_assert_int_eq(libinput_event_tablet_pad_get_key(p), key);
+       litest_assert_int_eq(libinput_event_tablet_pad_get_key_state(p),
+                            state);
+
+       return p;
+}
+
 struct libinput_event_switch *
 litest_is_switch_event(struct libinput_event *event,
                       enum libinput_switch sw,
@@ -3634,6 +3658,21 @@ litest_assert_pad_button_event(struct libinput *li,
        libinput_event_destroy(libinput_event_tablet_pad_get_base_event(pev));
 }
 
+void
+litest_assert_pad_key_event(struct libinput *li,
+                           unsigned int key,
+                           enum libinput_key_state state)
+{
+       struct libinput_event *event;
+       struct libinput_event_tablet_pad *pev;
+
+       litest_wait_for_event(li);
+       event = libinput_get_event(li);
+
+       pev = litest_is_pad_key_event(event, key, state);
+       libinput_event_destroy(libinput_event_tablet_pad_get_base_event(pev));
+}
+
 void
 litest_assert_scroll(struct libinput *li,
                     enum libinput_pointer_axis axis,
index 06072c10e9a2398f3b5b0d93429c2281ef5e737f..5d0114e8adf155c533a31679035580fe8ab9f5f9 100644 (file)
@@ -751,6 +751,10 @@ struct libinput_event_tablet_pad *
 litest_is_pad_strip_event(struct libinput_event *event,
                          unsigned int number,
                          enum libinput_tablet_pad_strip_axis_source source);
+struct libinput_event_tablet_pad *
+litest_is_pad_key_event(struct libinput_event *event,
+                       unsigned int key,
+                       enum libinput_key_state state);
 
 struct libinput_event_switch *
 litest_is_switch_event(struct libinput_event *event,
@@ -796,6 +800,10 @@ void
 litest_assert_pad_button_event(struct libinput *li,
                                    unsigned int button,
                                    enum libinput_button_state state);
+void
+litest_assert_pad_key_event(struct libinput *li,
+                           unsigned int key,
+                           enum libinput_key_state state);
 struct libevdev_uinput *
 litest_create_uinput_device(const char *name,
                            struct input_id *id,
index 6ba8925cf0a8fd6c732a9d7511d656e5da66a91c..9eba7182f4796570168bad4c59f1ac66bc20ffee 100644 (file)
@@ -916,6 +916,72 @@ START_TEST(pad_mode_group_has_no_toggle)
 }
 END_TEST
 
+static bool
+pad_has_keys(struct litest_device *dev)
+{
+       struct libevdev *evdev = dev->evdev;
+
+       return (libevdev_has_event_code(evdev, EV_KEY, KEY_BUTTONCONFIG) ||
+               libevdev_has_event_code(evdev, EV_KEY, KEY_ONSCREEN_KEYBOARD) ||
+               libevdev_has_event_code(evdev, EV_KEY, KEY_CONTROLPANEL));
+}
+
+static void
+pad_key_down(struct litest_device *dev, unsigned int which)
+{
+       litest_event(dev, EV_ABS, ABS_MISC, 15);
+       litest_event(dev, EV_KEY, which, 1);
+       litest_event(dev, EV_SYN, SYN_REPORT, 0);
+}
+
+static void
+pad_key_up(struct litest_device *dev, unsigned int which)
+{
+       litest_event(dev, EV_ABS, ABS_MISC, 0);
+       litest_event(dev, EV_KEY, which, 0);
+       litest_event(dev, EV_SYN, SYN_REPORT, 0);
+}
+
+START_TEST(pad_keys)
+{
+       struct litest_device *dev = litest_current_device();
+       struct libinput *li = dev->libinput;
+       unsigned int key;
+
+       if (!pad_has_keys(dev))
+               return;
+
+       litest_drain_events(li);
+
+       key = KEY_BUTTONCONFIG;
+       pad_key_down(dev, key);
+       libinput_dispatch(li);
+       litest_assert_pad_key_event(li, key, LIBINPUT_KEY_STATE_PRESSED);
+
+       pad_key_up(dev, key);
+       libinput_dispatch(li);
+       litest_assert_pad_key_event(li, key, LIBINPUT_KEY_STATE_RELEASED);
+
+       key = KEY_ONSCREEN_KEYBOARD;
+       pad_key_down(dev, key);
+       libinput_dispatch(li);
+       litest_assert_pad_key_event(li, key, LIBINPUT_KEY_STATE_PRESSED);
+
+       pad_key_up(dev, key);
+       libinput_dispatch(li);
+       litest_assert_pad_key_event(li, key, LIBINPUT_KEY_STATE_RELEASED);
+
+       key = KEY_CONTROLPANEL;
+       pad_key_down(dev, key);
+       libinput_dispatch(li);
+       litest_assert_pad_key_event(li, key, LIBINPUT_KEY_STATE_PRESSED);
+
+       pad_key_up(dev, key);
+       libinput_dispatch(li);
+       litest_assert_pad_key_event(li, key, LIBINPUT_KEY_STATE_RELEASED);
+}
+END_TEST
+
 TEST_COLLECTION(tablet_pad)
 {
        litest_add("pad:cap", pad_cap, LITEST_TABLET_PAD, LITEST_ANY);
@@ -950,4 +1016,6 @@ TEST_COLLECTION(tablet_pad)
        litest_add("pad:modes", pad_mode_group_has, LITEST_TABLET_PAD, LITEST_ANY);
        litest_add("pad:modes", pad_mode_group_has_invalid, LITEST_TABLET_PAD, LITEST_ANY);
        litest_add("pad:modes", pad_mode_group_has_no_toggle, LITEST_TABLET_PAD, LITEST_ANY);
+
+       litest_add("pad:keys", pad_keys, LITEST_TABLET_PAD, LITEST_ANY);
 }
index 079aa7c839153af2b578a2a938bc78042f06a47e..48704ee116d66335bd383f75624186465be8bf67 100644 (file)
@@ -140,6 +140,9 @@ print_event_header(struct libinput_event *ev)
        case LIBINPUT_EVENT_TABLET_PAD_STRIP:
                type = "TABLET_PAD_STRIP";
                break;
+       case LIBINPUT_EVENT_TABLET_PAD_KEY:
+               type = "TABLET_PAD_KEY";
+               break;
        case LIBINPUT_EVENT_SWITCH_TOGGLE:
                type = "SWITCH_TOGGLE";
                break;
@@ -764,6 +767,32 @@ print_tablet_pad_strip_event(struct libinput_event *ev)
               mode);
 }
 
+static void
+print_tablet_pad_key_event(struct libinput_event *ev)
+{
+       struct libinput_event_tablet_pad *p = libinput_event_get_tablet_pad_event(ev);
+       enum libinput_key_state state;
+       uint32_t key;
+       const char *keyname;
+
+       print_event_time(libinput_event_tablet_pad_get_time(p));
+
+       key = libinput_event_tablet_pad_get_key(p);
+       if (!show_keycodes && (key >= KEY_ESC && key < KEY_ZENKAKUHANKAKU)) {
+               keyname = "***";
+               key = -1;
+       } else {
+               keyname = libevdev_event_code_get_name(EV_KEY, key);
+               keyname = keyname ? keyname : "???";
+       }
+       state = libinput_event_tablet_pad_get_key_state(p);
+       printq("%s (%d) %s\n",
+              keyname,
+              key,
+              state == LIBINPUT_KEY_STATE_PRESSED ? "pressed" : "released");
+}
+
+
 static void
 print_switch_event(struct libinput_event *ev)
 {
@@ -879,6 +908,9 @@ handle_and_print_events(struct libinput *li)
                case LIBINPUT_EVENT_TABLET_PAD_STRIP:
                        print_tablet_pad_strip_event(ev);
                        break;
+               case LIBINPUT_EVENT_TABLET_PAD_KEY:
+                       print_tablet_pad_key_event(ev);
+                       break;
                case LIBINPUT_EVENT_SWITCH_TOGGLE:
                        print_switch_event(ev);
                        break;
index 72fef04b6476d1dd38311d88880b35da0775df3d..d68f1ea147ca7910a95ee767323e97e67db92b8f 100644 (file)
@@ -1478,6 +1478,8 @@ handle_event_libinput(GIOChannel *source, GIOCondition condition, gpointer data)
                case LIBINPUT_EVENT_TABLET_PAD_STRIP:
                        handle_event_tablet_pad(ev, w);
                        break;
+               case LIBINPUT_EVENT_TABLET_PAD_KEY:
+                       break;
                case LIBINPUT_EVENT_SWITCH_TOGGLE:
                        break;
                }