commit b96f614
Michael Forney
·
2014-01-22 22:18:53 +0000 UTC
parent 0df9b8d
seat: Add option input hotplugging support through libudev
4 files changed,
+134,
-6
+3,
-0
1@@ -19,6 +19,9 @@ Dependencies
2 * [wld](http://github.com/michaelforney/wld)
3 * linux\[>=3.12\] (for EVIOCREVOKE)
4
5+For input hotplugging support, the following is also required:
6+* libudev
7+
8 For XWayland support, the following are also required:
9 * libxcb
10 * xcb-util-wm
+5,
-4
1@@ -12,9 +12,10 @@ CFLAGS = -pipe
2 PKG_CONFIG ?= pkg-config
3 WAYLAND_SCANNER ?= wayland-scanner
4
5-ENABLE_DEBUG = 1
6+ENABLE_DEBUG = 1
7
8-ENABLE_STATIC = 1
9-ENABLE_SHARED = 1
10-ENABLE_XWAYLAND = 1
11+ENABLE_STATIC = 1
12+ENABLE_SHARED = 1
13+ENABLE_HOTPLUGGING = 1
14+ENABLE_XWAYLAND = 1
15
+5,
-0
1@@ -63,6 +63,11 @@ SWC_SOURCES += \
2 libswc/bindings.c \
3 libswc/screen.c
4
5+ifeq ($(ENABLE_HOTPLUGGING),1)
6+$(dir)_CFLAGS += -DENABLE_HOTPLUGGING
7+$(dir)_PACKAGES += libudev
8+endif
9+
10 ifeq ($(ENABLE_XWAYLAND),1)
11 $(dir)_CFLAGS += -DENABLE_XWAYLAND
12 $(dir)_PACKAGES += \
+121,
-2
1@@ -35,13 +35,21 @@
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5-#include <libudev.h>
6+#ifdef ENABLE_HOTPLUGGING
7+# include <libudev.h>
8+#endif
9
10 static struct
11 {
12 char * name;
13 uint32_t capabilities;
14
15+#ifdef ENABLE_HOTPLUGGING
16+ struct udev * udev;
17+ struct udev_monitor * monitor;
18+ struct wl_event_source * monitor_source;
19+#endif
20+
21 struct swc_keyboard keyboard;
22 struct swc_pointer pointer;
23 struct swc_data_device data_device;
24@@ -249,6 +257,105 @@ static bool add_devices()
25 return true;
26 }
27
28+#ifdef ENABLE_HOTPLUGGING
29+static int handle_monitor_data(int fd, uint32_t mask, void * data)
30+{
31+ struct udev_device * udev_device;
32+ const char * path, * action, * sysname;
33+ unsigned num;
34+
35+ if (!(udev_device = udev_monitor_receive_device(seat.monitor)))
36+ return 0;
37+
38+ if (!(action = udev_device_get_action(udev_device)))
39+ goto done;
40+
41+ sysname = udev_device_get_sysname(udev_device);
42+
43+ if (sscanf(sysname, "event%u", &num) != 1)
44+ goto done;
45+
46+ path = udev_device_get_devnode(udev_device);
47+
48+ if (strcmp(action, "add") == 0)
49+ add_device(path);
50+ else if (strcmp(action, "remove") == 0)
51+ {
52+ struct swc_evdev_device * device, * next;
53+
54+ wl_list_for_each_safe(device, next, &seat.devices, link)
55+ {
56+ if (strcmp(device->path, path) == 0)
57+ {
58+ wl_list_remove(&device->link);
59+ swc_evdev_device_destroy(device);
60+ break;
61+ }
62+ }
63+ }
64+
65+ done:
66+ udev_device_unref(udev_device);
67+ return 0;
68+}
69+
70+bool initialize_monitor()
71+{
72+ int fd;
73+
74+ if (!(seat.udev = udev_new()))
75+ {
76+ ERROR("Could not create udev context\n");
77+ goto error0;
78+ }
79+
80+ if (!(seat.monitor = udev_monitor_new_from_netlink(seat.udev, "udev")))
81+ {
82+ ERROR("Could not create udev monitor\n");
83+ goto error1;
84+ }
85+
86+ if (udev_monitor_filter_add_match_subsystem_devtype(seat.monitor,
87+ "input", NULL) != 0)
88+ {
89+ ERROR("Could not set up udev monitor filter\n");
90+ goto error2;
91+ }
92+
93+ if (udev_monitor_enable_receiving(seat.monitor) != 0)
94+ {
95+ ERROR("Could not enable receiving for udev monitor\n");
96+ goto error2;
97+ }
98+
99+ fd = udev_monitor_get_fd(seat.monitor);
100+ seat.monitor_source = wl_event_loop_add_fd
101+ (swc.event_loop, fd, WL_EVENT_READABLE, &handle_monitor_data, NULL);
102+
103+ if (!seat.monitor_source)
104+ {
105+ ERROR("Could not create event source for udev monitor\n");
106+ goto error2;
107+ }
108+
109+ return true;
110+
111+ error2:
112+ udev_monitor_unref(seat.monitor);
113+ error1:
114+ udev_unref(seat.udev);
115+ error0:
116+ return false;
117+}
118+
119+void finalize_monitor()
120+{
121+ wl_event_source_remove(seat.monitor_source);
122+ udev_monitor_unref(seat.monitor);
123+ udev_unref(seat.udev);
124+}
125+#endif
126+
127 bool swc_seat_initialize(const char * seat_name)
128 {
129 if (!(seat.name = strdup(seat_name)))
130@@ -290,12 +397,21 @@ bool swc_seat_initialize(const char * seat_name)
131 goto error4;
132 }
133
134- if (!add_devices())
135+#ifdef ENABLE_HOTPLUGGING
136+ if (!initialize_monitor())
137 goto error5;
138+#endif
139+
140+ if (!add_devices())
141+ goto error6;
142
143 return true;
144
145+ error6:
146+#ifdef ENABLE_HOTPLUGGING
147+ finalize_monitor();
148 error5:
149+#endif
150 swc_pointer_finalize(&seat.pointer);
151 error4:
152 swc_keyboard_finalize(&seat.keyboard);
153@@ -313,6 +429,9 @@ void swc_seat_finalize()
154 {
155 struct swc_evdev_device * device, * tmp;
156
157+#ifdef ENABLE_HOTPLUGGING
158+ finalize_monitor();
159+#endif
160 swc_pointer_finalize(&seat.pointer);
161 swc_keyboard_finalize(&seat.keyboard);
162