[PATCH libinput 02/14] Add evdev_dispatch interface for lid switch
Peter Hutterer
peter.hutterer at who-t.net
Wed Jan 25 23:44:12 UTC 2017
From: James Ye <jye836 at gmail.com>
Create a lid_switch_interface to handle lid switch events, so the touchpad can
be disabled when lid is closed.
Signed-off-by: James Ye <jye836 at gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
src/evdev.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
src/evdev.h | 8 +++++
2 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/src/evdev.c b/src/evdev.c
index d086c18..245d878 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -68,6 +68,7 @@ enum evdev_device_udev_tags {
EVDEV_UDEV_TAG_TABLET_PAD = (1 << 8),
EVDEV_UDEV_TAG_POINTINGSTICK = (1 << 9),
EVDEV_UDEV_TAG_TRACKBALL = (1 << 10),
+ EVDEV_UDEV_TAG_SWITCH = (1 << 11),
};
struct evdev_udev_tag_match {
@@ -88,6 +89,7 @@ static const struct evdev_udev_tag_match evdev_udev_tag_matches[] = {
{"ID_INPUT_ACCELEROMETER", EVDEV_UDEV_TAG_ACCELEROMETER},
{"ID_INPUT_POINTINGSTICK", EVDEV_UDEV_TAG_POINTINGSTICK},
{"ID_INPUT_TRACKBALL", EVDEV_UDEV_TAG_TRACKBALL},
+ {"ID_INPUT_SWITCH", EVDEV_UDEV_TAG_SWITCH},
/* sentinel value */
{ 0 },
@@ -1028,6 +1030,24 @@ fallback_process_absolute(struct fallback_dispatch *dispatch,
}
}
+static void
+lid_switch_process_switch(struct lid_switch_dispatch *dispatch,
+ struct evdev_device *device,
+ struct input_event *e,
+ uint64_t time)
+{
+ switch (e->code) {
+ case SW_LID:
+ dispatch->lid_is_closed = !!e->value;
+
+ switch_notify_toggle(&device->base,
+ time,
+ LIBINPUT_SWITCH_LID,
+ dispatch->lid_is_closed);
+ break;
+ }
+}
+
static inline bool
fallback_any_button_down(struct fallback_dispatch *dispatch,
struct evdev_device *device)
@@ -1083,6 +1103,13 @@ evdev_tag_keyboard(struct evdev_device *device,
}
static void
+evdev_tag_lid_switch(struct evdev_device *device,
+ struct udev_device *udev_device)
+{
+ device->tags |= EVDEV_TAG_LID_SWITCH;
+}
+
+static void
fallback_process(struct evdev_dispatch *evdev_dispatch,
struct evdev_device *device,
struct input_event *event,
@@ -1124,6 +1151,27 @@ fallback_process(struct evdev_dispatch *evdev_dispatch,
}
static void
+lid_switch_process(struct evdev_dispatch *evdev_dispatch,
+ struct evdev_device *device,
+ struct input_event *event,
+ uint64_t time)
+{
+ struct lid_switch_dispatch *dispatch =
+ (struct lid_switch_dispatch*)evdev_dispatch;
+
+ switch (event->type) {
+ case EV_SW:
+ lid_switch_process_switch(dispatch, device, event, time);
+ break;
+ case EV_SYN:
+ break;
+ default:
+ assert(0 && "Unknown event type");
+ break;
+ }
+}
+
+static void
release_touches(struct fallback_dispatch *dispatch,
struct evdev_device *device,
uint64_t time)
@@ -1248,6 +1296,15 @@ fallback_destroy(struct evdev_dispatch *evdev_dispatch)
free(dispatch);
}
+static void
+lid_switch_destroy(struct evdev_dispatch *evdev_dispatch)
+{
+ struct lid_switch_dispatch *dispatch =
+ (struct lid_switch_dispatch*)evdev_dispatch;
+
+ free(dispatch);
+}
+
static int
evdev_calibration_has_matrix(struct libinput_device *libinput_device)
{
@@ -1302,6 +1359,19 @@ struct evdev_dispatch_interface fallback_interface = {
fallback_toggle_touch, /* toggle_touch */
};
+struct evdev_dispatch_interface lid_switch_interface = {
+ lid_switch_process,
+ NULL, /* suspend */
+ NULL, /* remove */
+ lid_switch_destroy,
+ NULL, /* device_added */
+ NULL, /* device_removed */
+ NULL, /* device_suspended */
+ NULL, /* device_resumed */
+ NULL, /* post_added */
+ NULL, /* toggle_touch */
+};
+
static uint32_t
evdev_sendevents_get_modes(struct libinput_device *device)
{
@@ -1811,6 +1881,24 @@ fallback_dispatch_create(struct libinput_device *device)
return &dispatch->base;
}
+static struct evdev_dispatch *
+lid_switch_dispatch_create(struct libinput_device *device)
+{
+ struct lid_switch_dispatch *dispatch = zalloc(sizeof *dispatch);
+ struct evdev_device *lid_device = (struct evdev_device *)device;
+
+ if (dispatch == NULL)
+ return NULL;
+
+ dispatch->base.interface = &lid_switch_interface;
+
+ evdev_init_sendevents(lid_device, &dispatch->base);
+
+ dispatch->lid_is_closed = false;
+
+ return &dispatch->base;
+}
+
static inline void
evdev_process_event(struct evdev_device *device, struct input_event *e)
{
@@ -2534,7 +2622,7 @@ evdev_configure_device(struct evdev_device *device)
}
log_info(libinput,
- "input device '%s', %s is tagged by udev as:%s%s%s%s%s%s%s%s%s%s\n",
+ "input device '%s', %s is tagged by udev as:%s%s%s%s%s%s%s%s%s%s%s\n",
device->devname, devnode,
udev_tags & EVDEV_UDEV_TAG_KEYBOARD ? " Keyboard" : "",
udev_tags & EVDEV_UDEV_TAG_MOUSE ? " Mouse" : "",
@@ -2545,7 +2633,8 @@ evdev_configure_device(struct evdev_device *device)
udev_tags & EVDEV_UDEV_TAG_JOYSTICK ? " Joystick" : "",
udev_tags & EVDEV_UDEV_TAG_ACCELEROMETER ? " Accelerometer" : "",
udev_tags & EVDEV_UDEV_TAG_TABLET_PAD ? " TabletPad" : "",
- udev_tags & EVDEV_UDEV_TAG_TRACKBALL ? " Trackball" : "");
+ udev_tags & EVDEV_UDEV_TAG_TRACKBALL ? " Trackball" : "",
+ udev_tags & EVDEV_UDEV_TAG_SWITCH ? " Switch" : "");
if (udev_tags & EVDEV_UDEV_TAG_ACCELEROMETER) {
log_info(libinput,
@@ -2657,6 +2746,17 @@ evdev_configure_device(struct evdev_device *device)
device->devname, devnode);
}
+ if (udev_tags & EVDEV_UDEV_TAG_SWITCH &&
+ libevdev_has_event_code(evdev, EV_SW, SW_LID)) {
+ dispatch = lid_switch_dispatch_create(&device->base);
+ device->seat_caps |= EVDEV_DEVICE_SWITCH;
+ evdev_tag_lid_switch(device, device->udev_device);
+ log_info(libinput,
+ "input device '%s', %s is a switch device\n",
+ device->devname, devnode);
+ return dispatch;
+ }
+
if (device->seat_caps & EVDEV_DEVICE_POINTER &&
libevdev_has_event_code(evdev, EV_REL, REL_X) &&
libevdev_has_event_code(evdev, EV_REL, REL_Y) &&
@@ -3089,6 +3189,8 @@ evdev_device_has_capability(struct evdev_device *device,
return !!(device->seat_caps & EVDEV_DEVICE_TABLET);
case LIBINPUT_DEVICE_CAP_TABLET_PAD:
return !!(device->seat_caps & EVDEV_DEVICE_TABLET_PAD);
+ case LIBINPUT_DEVICE_CAP_SWITCH:
+ return !!(device->seat_caps & EVDEV_DEVICE_SWITCH);
default:
return false;
}
diff --git a/src/evdev.h b/src/evdev.h
index 95cde8b..32d854f 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -63,6 +63,7 @@ enum evdev_device_seat_capability {
EVDEV_DEVICE_TABLET = (1 << 3),
EVDEV_DEVICE_TABLET_PAD = (1 << 4),
EVDEV_DEVICE_GESTURE = (1 << 5),
+ EVDEV_DEVICE_SWITCH = (1 << 6),
};
enum evdev_device_tags {
@@ -71,6 +72,7 @@ enum evdev_device_tags {
EVDEV_TAG_EXTERNAL_TOUCHPAD = (1 << 2),
EVDEV_TAG_TRACKPOINT = (1 << 3),
EVDEV_TAG_KEYBOARD = (1 << 4),
+ EVDEV_TAG_LID_SWITCH = (1 << 5),
};
enum evdev_middlebutton_state {
@@ -334,6 +336,12 @@ struct fallback_dispatch {
bool ignore_events;
};
+struct lid_switch_dispatch {
+ struct evdev_dispatch base;
+
+ bool lid_is_closed;
+};
+
struct evdev_device *
evdev_device_create(struct libinput_seat *seat,
struct udev_device *device);
--
2.9.3
More information about the wayland-devel
mailing list