1 /*
2 * Copyright © 2013-2017 Red Hat, Inc.
3 * Copyright © 2020 Povilas Kanapickas <povilas@radix.lt>
4 *
5 * Permission to use, copy, modify, distribute, and sell this software
6 * and its documentation for any purpose is hereby granted without
7 * fee, provided that the above copyright notice appear in all copies
8 * and that both that copyright notice and this permission notice
9 * appear in supporting documentation, and that the name of Red Hat
10 * not be used in advertising or publicity pertaining to distribution
11 * of the software without specific, written prior permission. Red
12 * Hat makes no representations about the suitability of this software
13 * for any purpose. It is provided "as is" without express or implied
14 * warranty.
15 *
16 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
18 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
20 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
21 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 */
24
25 #ifdef HAVE_XORG_CONFIG_H
26 #include <xorg-config.h>
27 #endif
28
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <exevents.h>
33 #include <input.h>
34 #include <xkbsrv.h>
35 #include <xf86.h>
36 #include <xf86Xinput.h>
37 #include "xorgVersion.h"
38 #include <xserver-properties.h>
39 #include <os.h>
40 #include <X11/Xatom.h>
41
42 #include <sys/socket.h>
43 #include <sys/stat.h>
44 #include <sys/un.h>
45 #include <stdbool.h>
46
47 #include "xf86-input-inputtest-protocol.h"
48
49 #define MAX_POINTER_NUM_AXES 5 /* x, y, hscroll, vscroll, [pressure] */
50 #define MAX_TOUCH_NUM_AXES 5 /* x, y, hscroll, vscroll, pressure */
51 #define TOUCH_MAX_SLOTS 15
52
53 #define TOUCH_AXIS_MAX 0xffff
54 #define TABLET_PRESSURE_AXIS_MAX 2047
55
56 #define EVENT_BUFFER_SIZE 4096
57
58 enum xf86ITDeviceType {
59 DEVICE_KEYBOARD = 1,
60 DEVICE_POINTER,
61 DEVICE_POINTER_GESTURE,
62 DEVICE_POINTER_ABS,
63 DEVICE_POINTER_ABS_PROXIMITY,
64 DEVICE_TOUCH,
65 };
66
67 enum xf86ITClientState {
68 CLIENT_STATE_NOT_CONNECTED = 0,
69
70 /* connection_fd is valid */
71 CLIENT_STATE_NEW,
72
73 /* connection_fd is valid and client_protocol.{major,minor} are set */
74 CLIENT_STATE_READY,
75 };
76
77 typedef struct {
78 InputInfoPtr pInfo;
79
80 int socket_fd; /* for accepting new clients */
81 int connection_fd; /* current client connection */
82
83 char *socket_path;
84
85 enum xf86ITClientState client_state;
86 struct {
87 int major, minor;
88 } client_protocol;
89
90 struct {
91 char data[EVENT_BUFFER_SIZE];
92 int valid_length;
93 } buffer;
94
95 uint32_t device_type;
96
97 /* last_processed_event_num == last_event_num and waiting_for_drain != 0 must never be true
98 both at the same time. This would mean that we are waiting for the input queue to be
99 processed, yet all events have already been processed, i.e. a deadlock.
100
101 waiting_for_drain_mutex protects concurrent access to waiting_for_drain variable which
102 may be modified from multiple threads.
103 */
104 pthread_mutex_t waiting_for_drain_mutex;
105 bool waiting_for_drain;
106 int last_processed_event_num;
107 int last_event_num;
108
109 ValuatorMask *valuators;
110 ValuatorMask *valuators_unaccelerated;
111 } xf86ITDevice, *xf86ITDevicePtr;
112
113 static void
114 read_input_from_connection(InputInfoPtr pInfo);
115
116 static Bool
notify_sync_finished(ClientPtr ptr,void * closure)117 notify_sync_finished(ClientPtr ptr, void *closure)
118 {
119 int fd = (int)(intptr_t) closure;
120 xf86ITResponseSyncFinished response;
121 response.header.length = sizeof(response);
122 response.header.type = XF86IT_RESPONSE_SYNC_FINISHED;
123
124 input_lock();
125 /* we don't really care whether the write succeeds. It may fail if the device is
126 already shut down and the descriptor is closed.
127 */
128 if (write(fd, &response, response.header.length) != response.header.length) {
129 LogMessageVerbSigSafe(X_ERROR, 0,
130 "inputtest: Failed to write sync response: %s\n",
131 strerror(errno));
132 }
133 input_unlock();
134 return TRUE;
135 }
136
137 static void
input_drain_callback(CallbackListPtr * callback,void * data,void * call_data)138 input_drain_callback(CallbackListPtr *callback, void *data, void *call_data)
139 {
140 void *drain_write_closure;
141 InputInfoPtr pInfo = data;
142 xf86ITDevicePtr driver_data = pInfo->private;
143 bool notify_synchronization = false;
144
145 pthread_mutex_lock(&driver_data->waiting_for_drain_mutex);
146 driver_data->last_processed_event_num = driver_data->last_event_num;
147 if (driver_data->waiting_for_drain) {
148 driver_data->waiting_for_drain = false;
149 notify_synchronization = true;
150 }
151 pthread_mutex_unlock(&driver_data->waiting_for_drain_mutex);
152
153 if (notify_synchronization) {
154 drain_write_closure = (void*)(intptr_t) driver_data->connection_fd;
155 /* One input event may result in additional sets of events being submitted to the
156 input queue from the input processing code itself. This results in
157 input_drain_callback being called multiple times.
158
159 We therefore schedule a WorkProc (to be run when the server is no longer busy)
160 to notify the client when all current events have been processed.
161 */
162 xf86IDrvMsg(pInfo, X_DEBUG, "Synchronization finished\n");
163 QueueWorkProc(notify_sync_finished, NULL, drain_write_closure);
164 }
165 }
166
167 static void
read_events(int fd,int ready,void * data)168 read_events(int fd, int ready, void *data)
169 {
170 DeviceIntPtr dev = (DeviceIntPtr) data;
171 InputInfoPtr pInfo = dev->public.devicePrivate;
172 read_input_from_connection(pInfo);
173 }
174
175 static void
try_accept_connection(int fd,int ready,void * data)176 try_accept_connection(int fd, int ready, void *data)
177 {
178 DeviceIntPtr dev = (DeviceIntPtr) data;
179 InputInfoPtr pInfo = dev->public.devicePrivate;
180 xf86ITDevicePtr driver_data = pInfo->private;
181 int connection_fd;
182 int flags;
183
184 if (driver_data->connection_fd >= 0)
185 return;
186
187 connection_fd = accept(driver_data->socket_fd, NULL, NULL);
188 if (connection_fd < 0) {
189 if (errno == EAGAIN || errno == EWOULDBLOCK)
190 return;
191 xf86IDrvMsg(pInfo, X_ERROR, "Failed to accept a connection\n");
192 return;
193 }
194
195 xf86IDrvMsg(pInfo, X_DEBUG, "Accepted input control connection\n");
196
197 flags = fcntl(connection_fd, F_GETFL, 0);
198 fcntl(connection_fd, F_SETFL, flags | O_NONBLOCK);
199
200 driver_data->connection_fd = connection_fd;
201 xf86AddInputEventDrainCallback(input_drain_callback, pInfo);
202 SetNotifyFd(driver_data->connection_fd, read_events, X_NOTIFY_READ, dev);
203
204 driver_data->client_state = CLIENT_STATE_NEW;
205 }
206
207 static int
device_on(DeviceIntPtr dev)208 device_on(DeviceIntPtr dev)
209 {
210 InputInfoPtr pInfo = dev->public.devicePrivate;
211 xf86ITDevicePtr driver_data = pInfo->private;
212
213 xf86IDrvMsg(pInfo, X_DEBUG, "Device turned on\n");
214
215 xf86AddEnabledDevice(pInfo);
216 dev->public.on = TRUE;
217 driver_data->buffer.valid_length = 0;
218
219 try_accept_connection(-1, 0, dev);
220 if (driver_data->connection_fd < 0)
221 SetNotifyFd(driver_data->socket_fd, try_accept_connection, X_NOTIFY_READ, dev);
222
223 return Success;
224 }
225
226 static void
teardown_client_connection(InputInfoPtr pInfo)227 teardown_client_connection(InputInfoPtr pInfo)
228 {
229 xf86ITDevicePtr driver_data = pInfo->private;
230 if (driver_data->client_state != CLIENT_STATE_NOT_CONNECTED) {
231 RemoveNotifyFd(driver_data->connection_fd);
232 xf86RemoveInputEventDrainCallback(input_drain_callback, pInfo);
233
234 close(driver_data->connection_fd);
235 driver_data->connection_fd = -1;
236 }
237 RemoveNotifyFd(driver_data->socket_fd);
238 driver_data->client_state = CLIENT_STATE_NOT_CONNECTED;
239 }
240
241 static int
device_off(DeviceIntPtr dev)242 device_off(DeviceIntPtr dev)
243 {
244 InputInfoPtr pInfo = dev->public.devicePrivate;
245
246 xf86IDrvMsg(pInfo, X_DEBUG, "Device turned off\n");
247
248 if (dev->public.on) {
249 teardown_client_connection(pInfo);
250 xf86RemoveEnabledDevice(pInfo);
251 }
252 dev->public.on = FALSE;
253 return Success;
254 }
255
256 static void
ptr_ctl(DeviceIntPtr dev,PtrCtrl * ctl)257 ptr_ctl(DeviceIntPtr dev, PtrCtrl *ctl)
258 {
259 }
260
261 static void
init_button_map(unsigned char * btnmap,size_t size)262 init_button_map(unsigned char *btnmap, size_t size)
263 {
264 int i;
265
266 memset(btnmap, 0, size);
267 for (i = 0; i < size; i++)
268 btnmap[i] = i;
269 }
270
271 static void
init_button_labels(Atom * labels,size_t size)272 init_button_labels(Atom *labels, size_t size)
273 {
274 assert(size > 10);
275
276 memset(labels, 0, size * sizeof(Atom));
277 labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
278 labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
279 labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
280 labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
281 labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
282 labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
283 labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
284 labels[7] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_SIDE);
285 labels[8] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_EXTRA);
286 labels[9] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_FORWARD);
287 labels[10] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_BACK);
288 }
289
290 static void
init_pointer(InputInfoPtr pInfo)291 init_pointer(InputInfoPtr pInfo)
292 {
293 DeviceIntPtr dev= pInfo->dev;
294 int min, max, res;
295 int nbuttons = 7;
296 bool has_pressure = false;
297 int num_axes = 0;
298
299 unsigned char btnmap[MAX_BUTTONS + 1];
300 Atom btnlabels[MAX_BUTTONS];
301 Atom axislabels[MAX_POINTER_NUM_AXES];
302
303 nbuttons = xf86SetIntOption(pInfo->options, "PointerButtonCount", 7);
304 has_pressure = xf86SetBoolOption(pInfo->options, "PointerHasPressure",
305 false);
306
307 init_button_map(btnmap, ARRAY_SIZE(btnmap));
308 init_button_labels(btnlabels, ARRAY_SIZE(btnlabels));
309
310 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
311 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
312 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL);
313 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL);
314 if (has_pressure)
315 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
316
317 InitPointerDeviceStruct((DevicePtr)dev,
318 btnmap,
319 nbuttons,
320 btnlabels,
321 ptr_ctl,
322 GetMotionHistorySize(),
323 num_axes,
324 axislabels);
325 min = -1;
326 max = -1;
327 res = 0;
328
329 xf86InitValuatorAxisStruct(dev, 0, XIGetKnownProperty(AXIS_LABEL_PROP_REL_X),
330 min, max, res * 1000, 0, res * 1000, Relative);
331 xf86InitValuatorAxisStruct(dev, 1, XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y),
332 min, max, res * 1000, 0, res * 1000, Relative);
333
334 SetScrollValuator(dev, 2, SCROLL_TYPE_HORIZONTAL, 120, 0);
335 SetScrollValuator(dev, 3, SCROLL_TYPE_VERTICAL, 120, 0);
336
337 if (has_pressure) {
338 xf86InitValuatorAxisStruct(dev, 4,
339 XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE),
340 0, 1000, 1, 1, 1, Absolute);
341 }
342 }
343
344 static void
init_pointer_absolute(InputInfoPtr pInfo)345 init_pointer_absolute(InputInfoPtr pInfo)
346 {
347 DeviceIntPtr dev = pInfo->dev;
348 int min, max, res;
349 int nbuttons = 7;
350 bool has_pressure = false;
351 int num_axes = 0;
352
353 unsigned char btnmap[MAX_BUTTONS + 1];
354 Atom btnlabels[MAX_BUTTONS];
355 Atom axislabels[MAX_POINTER_NUM_AXES];
356
357 nbuttons = xf86SetIntOption(pInfo->options, "PointerButtonCount", 7);
358 has_pressure = xf86SetBoolOption(pInfo->options, "PointerHasPressure",
359 false);
360
361 init_button_map(btnmap, ARRAY_SIZE(btnmap));
362 init_button_labels(btnlabels, ARRAY_SIZE(btnlabels));
363
364 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
365 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
366 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL);
367 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL);
368 if (has_pressure)
369 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
370
371 InitPointerDeviceStruct((DevicePtr)dev,
372 btnmap,
373 nbuttons,
374 btnlabels,
375 ptr_ctl,
376 GetMotionHistorySize(),
377 num_axes ,
378 axislabels);
379 min = 0;
380 max = TOUCH_AXIS_MAX;
381 res = 0;
382
383 xf86InitValuatorAxisStruct(dev, 0, XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X),
384 min, max, res * 1000, 0, res * 1000, Absolute);
385 xf86InitValuatorAxisStruct(dev, 1, XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y),
386 min, max, res * 1000, 0, res * 1000, Absolute);
387
388 SetScrollValuator(dev, 2, SCROLL_TYPE_HORIZONTAL, 120, 0);
389 SetScrollValuator(dev, 3, SCROLL_TYPE_VERTICAL, 120, 0);
390
391 if (has_pressure) {
392 xf86InitValuatorAxisStruct(dev, 4,
393 XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE),
394 0, 1000, 1, 1, 1, Absolute);
395 }
396 }
397
398 static void
init_proximity(InputInfoPtr pInfo)399 init_proximity(InputInfoPtr pInfo)
400 {
401 DeviceIntPtr dev = pInfo->dev;
402 InitProximityClassDeviceStruct(dev);
403 }
404
405 static void
init_keyboard(InputInfoPtr pInfo)406 init_keyboard(InputInfoPtr pInfo)
407 {
408 DeviceIntPtr dev= pInfo->dev;
409 XkbRMLVOSet rmlvo = {0};
410 XkbRMLVOSet defaults = {0};
411
412 XkbGetRulesDflts(&defaults);
413
414 rmlvo.rules = xf86SetStrOption(pInfo->options, "xkb_rules", defaults.rules);
415 rmlvo.model = xf86SetStrOption(pInfo->options, "xkb_model", defaults.model);
416 rmlvo.layout = xf86SetStrOption(pInfo->options, "xkb_layout", defaults.layout);
417 rmlvo.variant = xf86SetStrOption(pInfo->options, "xkb_variant", defaults.variant);
418 rmlvo.options = xf86SetStrOption(pInfo->options, "xkb_options", defaults.options);
419
420 InitKeyboardDeviceStruct(dev, &rmlvo, NULL, NULL);
421 XkbFreeRMLVOSet(&rmlvo, FALSE);
422 XkbFreeRMLVOSet(&defaults, FALSE);
423 }
424
425 static void
init_touch(InputInfoPtr pInfo)426 init_touch(InputInfoPtr pInfo)
427 {
428 DeviceIntPtr dev = pInfo->dev;
429 int min, max, res;
430 unsigned char btnmap[MAX_BUTTONS + 1];
431 Atom btnlabels[MAX_BUTTONS];
432 Atom axislabels[MAX_TOUCH_NUM_AXES];
433 int num_axes = 0;
434 int nbuttons = 7;
435 int ntouches = TOUCH_MAX_SLOTS;
436
437 init_button_map(btnmap, ARRAY_SIZE(btnmap));
438 init_button_labels(btnlabels, ARRAY_SIZE(btnlabels));
439
440 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_X);
441 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_Y);
442 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL);
443 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL);
444 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_PRESSURE);
445
446 InitPointerDeviceStruct((DevicePtr)dev,
447 btnmap,
448 nbuttons,
449 btnlabels,
450 ptr_ctl,
451 GetMotionHistorySize(),
452 num_axes,
453 axislabels);
454 min = 0;
455 max = TOUCH_AXIS_MAX;
456 res = 0;
457
458 xf86InitValuatorAxisStruct(dev, 0,
459 XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_X),
460 min, max, res * 1000, 0, res * 1000, Absolute);
461 xf86InitValuatorAxisStruct(dev, 1,
462 XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_Y),
463 min, max, res * 1000, 0, res * 1000, Absolute);
464
465 SetScrollValuator(dev, 2, SCROLL_TYPE_HORIZONTAL, 120, 0);
466 SetScrollValuator(dev, 3, SCROLL_TYPE_VERTICAL, 120, 0);
467
468 xf86InitValuatorAxisStruct(dev, 4,
469 XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_PRESSURE),
470 min, TABLET_PRESSURE_AXIS_MAX, res * 1000, 0, res * 1000, Absolute);
471
472 ntouches = xf86SetIntOption(pInfo->options, "TouchCount", TOUCH_MAX_SLOTS);
473 if (ntouches == 0) /* unknown */
474 ntouches = TOUCH_MAX_SLOTS;
475 InitTouchClassDeviceStruct(dev, ntouches, XIDirectTouch, 2);
476 }
477
478 static void
init_gesture(InputInfoPtr pInfo)479 init_gesture(InputInfoPtr pInfo)
480 {
481 DeviceIntPtr dev = pInfo->dev;
482 int ntouches = TOUCH_MAX_SLOTS;
483 InitGestureClassDeviceStruct(dev, ntouches);
484 }
485
486 static void
device_init(DeviceIntPtr dev)487 device_init(DeviceIntPtr dev)
488 {
489 InputInfoPtr pInfo = dev->public.devicePrivate;
490 xf86ITDevicePtr driver_data = pInfo->private;
491
492 dev->public.on = FALSE;
493
494 switch (driver_data->device_type) {
495 case DEVICE_KEYBOARD:
496 init_keyboard(pInfo);
497 break;
498 case DEVICE_POINTER:
499 init_pointer(pInfo);
500 break;
501 case DEVICE_POINTER_GESTURE:
502 init_pointer(pInfo);
503 init_gesture(pInfo);
504 break;
505 case DEVICE_POINTER_ABS:
506 init_pointer_absolute(pInfo);
507 break;
508 case DEVICE_POINTER_ABS_PROXIMITY:
509 init_pointer_absolute(pInfo);
510 init_proximity(pInfo);
511 break;
512 case DEVICE_TOUCH:
513 init_touch(pInfo);
514 break;
515 }
516 }
517
518 static void
device_destroy(DeviceIntPtr dev)519 device_destroy(DeviceIntPtr dev)
520 {
521 InputInfoPtr pInfo = dev->public.devicePrivate;
522 xf86IDrvMsg(pInfo, X_INFO, "Close\n");
523 }
524
525 static int
device_control(DeviceIntPtr dev,int mode)526 device_control(DeviceIntPtr dev, int mode)
527 {
528 switch (mode) {
529 case DEVICE_INIT:
530 device_init(dev);
531 break;
532 case DEVICE_ON:
533 device_on(dev);
534 break;
535 case DEVICE_OFF:
536 device_off(dev);
537 break;
538 case DEVICE_CLOSE:
539 device_destroy(dev);
540 break;
541 }
542
543 return Success;
544 }
545
546 static void
convert_to_valuator_mask(xf86ITValuatorData * event,ValuatorMask * mask)547 convert_to_valuator_mask(xf86ITValuatorData *event, ValuatorMask *mask)
548 {
549 valuator_mask_zero(mask);
550 for (int i = 0; i < min(XF86IT_MAX_VALUATORS, MAX_VALUATORS); ++i) {
551 if (BitIsOn(event->mask, i)) {
552 if (event->has_unaccelerated) {
553 valuator_mask_set_unaccelerated(mask, i, event->valuators[i],
554 event->unaccelerated[i]);
555 } else {
556 valuator_mask_set_double(mask, i, event->valuators[i]);
557 }
558 }
559 }
560 }
561
562 static void
handle_client_version(InputInfoPtr pInfo,xf86ITEventClientVersion * event)563 handle_client_version(InputInfoPtr pInfo, xf86ITEventClientVersion *event)
564 {
565 xf86ITDevicePtr driver_data = pInfo->private;
566 xf86ITResponseServerVersion response;
567
568 response.header.length = sizeof(response);
569 response.header.type = XF86IT_RESPONSE_SERVER_VERSION;
570 response.major = XF86IT_PROTOCOL_VERSION_MAJOR;
571 response.minor = XF86IT_PROTOCOL_VERSION_MINOR;
572
573 if (write(driver_data->connection_fd, &response, response.header.length) != response.header.length) {
574 xf86IDrvMsg(pInfo, X_ERROR, "Error writing driver version: %s\n", strerror(errno));
575 teardown_client_connection(pInfo);
576 return;
577 }
578
579 if (event->major != XF86IT_PROTOCOL_VERSION_MAJOR ||
580 event->minor > XF86IT_PROTOCOL_VERSION_MINOR)
581 {
582 xf86IDrvMsg(pInfo, X_ERROR, "Unsupported protocol version: %d.%d (current %d.%d)\n",
583 event->major, event->minor,
584 XF86IT_PROTOCOL_VERSION_MAJOR,
585 XF86IT_PROTOCOL_VERSION_MINOR);
586 teardown_client_connection(pInfo);
587 return;
588 }
589
590 driver_data->client_protocol.major = event->major;
591 driver_data->client_protocol.minor = event->minor;
592
593 driver_data->client_state = CLIENT_STATE_READY;
594 }
595
596 static void
handle_wait_for_sync(InputInfoPtr pInfo)597 handle_wait_for_sync(InputInfoPtr pInfo)
598 {
599 xf86ITDevicePtr driver_data = pInfo->private;
600 bool notify_synchronization = false;
601 void *drain_write_closure;
602
603 xf86IDrvMsg(pInfo, X_DEBUG, "Handling sync event\n");
604
605 pthread_mutex_lock(&driver_data->waiting_for_drain_mutex);
606 if (driver_data->last_processed_event_num == driver_data->last_event_num) {
607 notify_synchronization = true;
608 } else {
609 driver_data->waiting_for_drain = true;
610 }
611 pthread_mutex_unlock(&driver_data->waiting_for_drain_mutex);
612
613 if (notify_synchronization) {
614 drain_write_closure = (void*)(intptr_t) driver_data->connection_fd;
615 xf86IDrvMsg(pInfo, X_DEBUG, "Synchronization finished\n");
616 notify_sync_finished(NULL, drain_write_closure);
617 }
618 }
619
620 static void
handle_motion(InputInfoPtr pInfo,xf86ITEventMotion * event)621 handle_motion(InputInfoPtr pInfo, xf86ITEventMotion *event)
622 {
623 DeviceIntPtr dev = pInfo->dev;
624 xf86ITDevicePtr driver_data = pInfo->private;
625 ValuatorMask *mask = driver_data->valuators;
626
627 xf86IDrvMsg(pInfo, X_DEBUG, "Handling motion event\n");
628
629 driver_data->last_event_num++;
630
631 convert_to_valuator_mask(&event->valuators, mask);
632 xf86PostMotionEventM(dev, event->is_absolute ? Absolute : Relative, mask);
633 }
634
635 static void
handle_proximity(InputInfoPtr pInfo,xf86ITEventProximity * event)636 handle_proximity(InputInfoPtr pInfo, xf86ITEventProximity *event)
637 {
638 DeviceIntPtr dev = pInfo->dev;
639 xf86ITDevicePtr driver_data = pInfo->private;
640 ValuatorMask *mask = driver_data->valuators;
641
642 xf86IDrvMsg(pInfo, X_DEBUG, "Handling proximity event\n");
643
644 driver_data->last_event_num++;
645
646 convert_to_valuator_mask(&event->valuators, mask);
647 xf86PostProximityEventM(dev, event->is_prox_in, mask);
648 }
649
650 static void
handle_button(InputInfoPtr pInfo,xf86ITEventButton * event)651 handle_button(InputInfoPtr pInfo, xf86ITEventButton *event)
652 {
653 DeviceIntPtr dev = pInfo->dev;
654 xf86ITDevicePtr driver_data = pInfo->private;
655 ValuatorMask *mask = driver_data->valuators;
656
657 xf86IDrvMsg(pInfo, X_DEBUG, "Handling button event\n");
658
659 driver_data->last_event_num++;
660
661 convert_to_valuator_mask(&event->valuators, mask);
662 xf86PostButtonEventM(dev, event->is_absolute ? Absolute : Relative, event->button,
663 event->is_press, mask);
664 }
665
666 static void
handle_key(InputInfoPtr pInfo,xf86ITEventKey * event)667 handle_key(InputInfoPtr pInfo, xf86ITEventKey *event)
668 {
669 DeviceIntPtr dev = pInfo->dev;
670 xf86ITDevicePtr driver_data = pInfo->private;
671
672 xf86IDrvMsg(pInfo, X_DEBUG, "Handling key event\n");
673
674 driver_data->last_event_num++;
675
676 xf86PostKeyboardEvent(dev, event->key_code, event->is_press);
677 }
678
679 static void
handle_touch(InputInfoPtr pInfo,xf86ITEventTouch * event)680 handle_touch(InputInfoPtr pInfo, xf86ITEventTouch *event)
681 {
682 DeviceIntPtr dev = pInfo->dev;
683 xf86ITDevicePtr driver_data = pInfo->private;
684 ValuatorMask *mask = driver_data->valuators;
685
686 xf86IDrvMsg(pInfo, X_DEBUG, "Handling touch event\n");
687
688 driver_data->last_event_num++;
689
690 convert_to_valuator_mask(&event->valuators, mask);
691 xf86PostTouchEvent(dev, event->touchid, event->touch_type, 0, mask);
692 }
693
694 static void
handle_gesture_swipe(InputInfoPtr pInfo,xf86ITEventGestureSwipe * event)695 handle_gesture_swipe(InputInfoPtr pInfo, xf86ITEventGestureSwipe *event)
696 {
697 DeviceIntPtr dev = pInfo->dev;
698 xf86ITDevicePtr driver_data = pInfo->private;
699
700 xf86IDrvMsg(pInfo, X_DEBUG, "Handling gesture swipe event\n");
701
702 driver_data->last_event_num++;
703
704 xf86PostGestureSwipeEvent(dev, event->gesture_type, event->num_touches, event->flags,
705 event->delta_x, event->delta_y,
706 event->delta_unaccel_x, event->delta_unaccel_y);
707 }
708
709 static void
handle_gesture_pinch(InputInfoPtr pInfo,xf86ITEventGesturePinch * event)710 handle_gesture_pinch(InputInfoPtr pInfo, xf86ITEventGesturePinch *event)
711 {
712 DeviceIntPtr dev = pInfo->dev;
713 xf86ITDevicePtr driver_data = pInfo->private;
714
715 xf86IDrvMsg(pInfo, X_DEBUG, "Handling gesture pinch event\n");
716
717 driver_data->last_event_num++;
718
719 xf86PostGesturePinchEvent(dev, event->gesture_type, event->num_touches, event->flags,
720 event->delta_x, event->delta_y,
721 event->delta_unaccel_x, event->delta_unaccel_y,
722 event->scale, event->delta_angle);
723 }
724
725 static void
client_new_handle_event(InputInfoPtr pInfo,xf86ITEventAny * event)726 client_new_handle_event(InputInfoPtr pInfo, xf86ITEventAny *event)
727 {
728 switch (event->header.type) {
729 case XF86IT_EVENT_CLIENT_VERSION:
730 handle_client_version(pInfo, &event->version);
731 break;
732 default:
733 xf86IDrvMsg(pInfo, X_ERROR, "Event before client is ready: event type %d\n",
734 event->header.type);
735 teardown_client_connection(pInfo);
736 break;
737 }
738 }
739
740 static void
client_ready_handle_event(InputInfoPtr pInfo,xf86ITEventAny * event)741 client_ready_handle_event(InputInfoPtr pInfo, xf86ITEventAny *event)
742 {
743 switch (event->header.type) {
744 case XF86IT_EVENT_WAIT_FOR_SYNC:
745 handle_wait_for_sync(pInfo);
746 break;
747 case XF86IT_EVENT_MOTION:
748 handle_motion(pInfo, &event->motion);
749 break;
750 case XF86IT_EVENT_PROXIMITY:
751 handle_proximity(pInfo, &event->proximity);
752 break;
753 case XF86IT_EVENT_BUTTON:
754 handle_button(pInfo, &event->button);
755 break;
756 case XF86IT_EVENT_KEY:
757 handle_key(pInfo, &event->key);
758 break;
759 case XF86IT_EVENT_TOUCH:
760 handle_touch(pInfo, &event->touch);
761 break;
762 case XF86IT_EVENT_GESTURE_PINCH:
763 handle_gesture_pinch(pInfo, &(event->pinch));
764 break;
765 case XF86IT_EVENT_GESTURE_SWIPE:
766 handle_gesture_swipe(pInfo, &(event->swipe));
767 break;
768 case XF86IT_EVENT_CLIENT_VERSION:
769 xf86IDrvMsg(pInfo, X_ERROR, "Only single ClientVersion event is allowed\n");
770 teardown_client_connection(pInfo);
771 break;
772 default:
773 xf86IDrvMsg(pInfo, X_ERROR, "Invalid event when client is ready %d\n",
774 event->header.type);
775 teardown_client_connection(pInfo);
776 break;
777 }
778 }
779
780 static void
handle_event(InputInfoPtr pInfo,xf86ITEventAny * event)781 handle_event(InputInfoPtr pInfo, xf86ITEventAny *event)
782 {
783 xf86ITDevicePtr driver_data = pInfo->private;
784
785 if (!pInfo->dev->public.on)
786 return;
787
788 switch (driver_data->client_state) {
789 case CLIENT_STATE_NOT_CONNECTED:
790 xf86IDrvMsg(pInfo, X_ERROR, "Got event when client is not connected\n");
791 break;
792 case CLIENT_STATE_NEW:
793 client_new_handle_event(pInfo, event);
794 break;
795 case CLIENT_STATE_READY:
796 client_ready_handle_event(pInfo, event);
797 break;
798 }
799 }
800
801 static bool
is_supported_event(enum xf86ITEventType type)802 is_supported_event(enum xf86ITEventType type)
803 {
804 switch (type) {
805 case XF86IT_EVENT_CLIENT_VERSION:
806 case XF86IT_EVENT_WAIT_FOR_SYNC:
807 case XF86IT_EVENT_MOTION:
808 case XF86IT_EVENT_PROXIMITY:
809 case XF86IT_EVENT_BUTTON:
810 case XF86IT_EVENT_KEY:
811 case XF86IT_EVENT_TOUCH:
812 case XF86IT_EVENT_GESTURE_PINCH:
813 case XF86IT_EVENT_GESTURE_SWIPE:
814 return true;
815 }
816 return false;
817 }
818
819 static int
get_event_size(enum xf86ITEventType type)820 get_event_size(enum xf86ITEventType type)
821 {
822 switch (type) {
823 case XF86IT_EVENT_CLIENT_VERSION: return sizeof(xf86ITEventClientVersion);
824 case XF86IT_EVENT_WAIT_FOR_SYNC: return sizeof(xf86ITEventWaitForSync);
825 case XF86IT_EVENT_MOTION: return sizeof(xf86ITEventMotion);
826 case XF86IT_EVENT_PROXIMITY: return sizeof(xf86ITEventProximity);
827 case XF86IT_EVENT_BUTTON: return sizeof(xf86ITEventButton);
828 case XF86IT_EVENT_KEY: return sizeof(xf86ITEventKey);
829 case XF86IT_EVENT_TOUCH: return sizeof(xf86ITEventTouch);
830 case XF86IT_EVENT_GESTURE_PINCH: return sizeof(xf86ITEventGesturePinch);
831 case XF86IT_EVENT_GESTURE_SWIPE: return sizeof(xf86ITEventGestureSwipe);
832 }
833 abort();
834 }
835
836 static void
read_input_from_connection(InputInfoPtr pInfo)837 read_input_from_connection(InputInfoPtr pInfo)
838 {
839 xf86ITDevicePtr driver_data = pInfo->private;
840
841 while (1) {
842 int processed_size = 0;
843 int read_size = read(driver_data->connection_fd,
844 driver_data->buffer.data + driver_data->buffer.valid_length,
845 EVENT_BUFFER_SIZE - driver_data->buffer.valid_length);
846
847 if (read_size < 0) {
848 if (errno == EAGAIN || errno == EWOULDBLOCK)
849 return;
850
851 xf86IDrvMsg(pInfo, X_ERROR, "Error reading events: %s\n", strerror(errno));
852 teardown_client_connection(pInfo);
853 return;
854 }
855
856 driver_data->buffer.valid_length += read_size;
857
858 while (1) {
859 xf86ITEventHeader event_header;
860 char *event_begin = driver_data->buffer.data + processed_size;
861
862 if (driver_data->buffer.valid_length - processed_size < sizeof(xf86ITEventHeader))
863 break;
864
865 /* Note that event_begin pointer is not aligned, accessing it directly is
866 undefined behavior. We must use memcpy to copy the data to aligned data
867 area. Most compilers will optimize out this call out and use whatever
868 is most efficient to access unaligned data on a particular platform */
869 memcpy(&event_header, event_begin, sizeof(xf86ITEventHeader));
870
871 if (event_header.length >= EVENT_BUFFER_SIZE) {
872 xf86IDrvMsg(pInfo, X_ERROR, "Received event with too long length: %d\n",
873 event_header.length);
874 teardown_client_connection(pInfo);
875 return;
876 }
877
878 if (driver_data->buffer.valid_length - processed_size < event_header.length)
879 break;
880
881 if (is_supported_event(event_header.type)) {
882 int expected_event_size = get_event_size(event_header.type);
883
884 if (event_header.length != expected_event_size) {
885 xf86IDrvMsg(pInfo, X_ERROR, "Unexpected event length: was %d bytes, "
886 "expected %d (event type: %d)\n",
887 event_header.length, expected_event_size,
888 (int) event_header.type);
889 teardown_client_connection(pInfo);
890 return;
891 }
892
893 /* We could use event_begin pointer directly, but we want to ensure correct
894 data alignment (if only so that address sanitizer does not complain) */
895 xf86ITEventAny event_data;
896 memset(&event_data, 0, sizeof(event_data));
897 memcpy(&event_data, event_begin, event_header.length);
898 handle_event(pInfo, &event_data);
899 }
900 processed_size += event_header.length;
901 }
902
903 if (processed_size > 0) {
904 memmove(driver_data->buffer.data,
905 driver_data->buffer.data + processed_size,
906 driver_data->buffer.valid_length - processed_size);
907 driver_data->buffer.valid_length -= processed_size;
908 }
909
910 if (read_size == 0)
911 break;
912 }
913 }
914
915 static void
read_input(InputInfoPtr pInfo)916 read_input(InputInfoPtr pInfo)
917 {
918 /* The test input driver does not set up the pInfo->fd and use the regular
919 read_input callback because we want to only accept the connection to
920 the controlling socket after the device is turned on.
921 */
922 }
923
924 static const char*
get_type_name(InputInfoPtr pInfo,xf86ITDevicePtr driver_data)925 get_type_name(InputInfoPtr pInfo, xf86ITDevicePtr driver_data)
926 {
927 switch (driver_data->device_type) {
928 case DEVICE_TOUCH: return XI_TOUCHSCREEN;
929 case DEVICE_POINTER: return XI_MOUSE;
930 case DEVICE_POINTER_GESTURE: return XI_TOUCHPAD;
931 case DEVICE_POINTER_ABS: return XI_MOUSE;
932 case DEVICE_POINTER_ABS_PROXIMITY: return XI_TABLET;
933 case DEVICE_KEYBOARD: return XI_KEYBOARD;
934 }
935 xf86IDrvMsg(pInfo, X_ERROR, "Unexpected device type %d\n",
936 driver_data->device_type);
937 return XI_KEYBOARD;
938 }
939
940 static xf86ITDevicePtr
device_alloc(void)941 device_alloc(void)
942 {
943 xf86ITDevicePtr driver_data = calloc(sizeof(xf86ITDevice), 1);
944
945 if (!driver_data)
946 return NULL;
947
948 driver_data->socket_fd = -1;
949 driver_data->connection_fd = -1;
950
951 return driver_data;
952 }
953
954 static void
free_driver_data(xf86ITDevicePtr driver_data)955 free_driver_data(xf86ITDevicePtr driver_data)
956 {
957 if (driver_data) {
958 close(driver_data->connection_fd);
959 close(driver_data->socket_fd);
960 if (driver_data->socket_path)
961 unlink(driver_data->socket_path);
962 free(driver_data->socket_path);
963 pthread_mutex_destroy(&driver_data->waiting_for_drain_mutex);
964
965 if (driver_data->valuators)
966 valuator_mask_free(&driver_data->valuators);
967 if (driver_data->valuators_unaccelerated)
968 valuator_mask_free(&driver_data->valuators_unaccelerated);
969 }
970 free(driver_data);
971 }
972
973 static int
pre_init(InputDriverPtr drv,InputInfoPtr pInfo,int flags)974 pre_init(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
975 {
976 xf86ITDevicePtr driver_data = NULL;
977 char *device_type_option;
978 struct sockaddr_un addr;
979
980 pInfo->type_name = 0;
981 pInfo->device_control = device_control;
982 pInfo->read_input = read_input;
983 pInfo->control_proc = NULL;
984 pInfo->switch_mode = NULL;
985
986 driver_data = device_alloc();
987 if (!driver_data)
988 goto fail;
989
990 driver_data->client_state = CLIENT_STATE_NOT_CONNECTED;
991 driver_data->last_event_num = 1;
992 driver_data->last_processed_event_num = 0;
993 driver_data->waiting_for_drain = false;
994 pthread_mutex_init(&driver_data->waiting_for_drain_mutex, NULL);
995
996 driver_data->valuators = valuator_mask_new(6);
997 if (!driver_data->valuators)
998 goto fail;
999
1000 driver_data->valuators_unaccelerated = valuator_mask_new(2);
1001 if (!driver_data->valuators_unaccelerated)
1002 goto fail;
1003
1004 driver_data->socket_path = xf86SetStrOption(pInfo->options, "SocketPath", NULL);
1005 if (!driver_data->socket_path){
1006 xf86IDrvMsg(pInfo, X_ERROR, "SocketPath must be specified\n");
1007 goto fail;
1008 }
1009
1010 if (strlen(driver_data->socket_path) >= sizeof(addr.sun_path)) {
1011 xf86IDrvMsg(pInfo, X_ERROR, "SocketPath is too long\n");
1012 goto fail;
1013 }
1014
1015 unlink(driver_data->socket_path);
1016
1017 driver_data->socket_fd = socket(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
1018 if (driver_data->socket_fd < 0) {
1019 xf86IDrvMsg(pInfo, X_ERROR, "Failed to create a socket for communication: %s\n",
1020 strerror(errno));
1021 goto fail;
1022 }
1023
1024 memset(&addr, 0, sizeof(addr));
1025 addr.sun_family = AF_UNIX;
1026 strncpy(addr.sun_path, driver_data->socket_path, sizeof(addr.sun_path) - 1);
1027
1028 if (bind(driver_data->socket_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) {
1029 xf86IDrvMsg(pInfo, X_ERROR, "Failed to assign address to the socket\n");
1030 goto fail;
1031 }
1032
1033 if (chmod(driver_data->socket_path, 0777) != 0) {
1034 xf86IDrvMsg(pInfo, X_ERROR, "Failed to chmod the socket path\n");
1035 goto fail;
1036 }
1037
1038 if (listen(driver_data->socket_fd, 1) != 0) {
1039 xf86IDrvMsg(pInfo, X_ERROR, "Failed to listen on the socket\n");
1040 goto fail;
1041 }
1042
1043 device_type_option = xf86SetStrOption(pInfo->options, "DeviceType", NULL);
1044 if (device_type_option == NULL) {
1045 xf86IDrvMsg(pInfo, X_ERROR, "DeviceType option must be specified\n");
1046 goto fail;
1047 }
1048
1049 if (strcmp(device_type_option, "Keyboard") == 0) {
1050 driver_data->device_type = DEVICE_KEYBOARD;
1051 } else if (strcmp(device_type_option, "Pointer") == 0) {
1052 driver_data->device_type = DEVICE_POINTER;
1053 } else if (strcmp(device_type_option, "PointerGesture") == 0) {
1054 driver_data->device_type = DEVICE_POINTER_GESTURE;
1055 } else if (strcmp(device_type_option, "PointerAbsolute") == 0) {
1056 driver_data->device_type = DEVICE_POINTER_ABS;
1057 } else if (strcmp(device_type_option, "PointerAbsoluteProximity") == 0) {
1058 driver_data->device_type = DEVICE_POINTER_ABS_PROXIMITY;
1059 } else if (strcmp(device_type_option, "Touch") == 0) {
1060 driver_data->device_type = DEVICE_TOUCH;
1061 } else {
1062 xf86IDrvMsg(pInfo, X_ERROR, "Unsupported DeviceType option.\n");
1063 goto fail;
1064 }
1065 free(device_type_option);
1066
1067 pInfo->private = driver_data;
1068 driver_data->pInfo = pInfo;
1069
1070 pInfo->type_name = get_type_name(pInfo, driver_data);
1071
1072 return Success;
1073 fail:
1074 free_driver_data(driver_data);
1075 return BadValue;
1076 }
1077
1078 static void
uninit(InputDriverPtr drv,InputInfoPtr pInfo,int flags)1079 uninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
1080 {
1081 xf86ITDevicePtr driver_data = pInfo->private;
1082 free_driver_data(driver_data);
1083 pInfo->private = NULL;
1084 xf86DeleteInput(pInfo, flags);
1085 }
1086
1087 InputDriverRec driver = {
1088 .driverVersion = 1,
1089 .driverName = "inputtest",
1090 .PreInit = pre_init,
1091 .UnInit = uninit,
1092 .module = NULL,
1093 .default_options = NULL,
1094 .capabilities = 0
1095 };
1096
1097 static XF86ModuleVersionInfo version_info = {
1098 "inputtest",
1099 MODULEVENDORSTRING,
1100 MODINFOSTRING1,
1101 MODINFOSTRING2,
1102 XORG_VERSION_CURRENT,
1103 XORG_VERSION_MAJOR,
1104 XORG_VERSION_MINOR,
1105 XORG_VERSION_PATCH,
1106 ABI_CLASS_XINPUT,
1107 ABI_XINPUT_VERSION,
1108 MOD_CLASS_XINPUT,
1109 {0, 0, 0, 0}
1110 };
1111
1112 static void*
setup_proc(void * module,void * options,int * errmaj,int * errmin)1113 setup_proc(void *module, void *options, int *errmaj, int *errmin)
1114 {
1115 xf86AddInputDriver(&driver, module, 0);
1116 return module;
1117 }
1118
1119 _X_EXPORT XF86ModuleData inputtestModuleData = {
1120 .vers = &version_info,
1121 .setup = &setup_proc,
1122 .teardown = NULL
1123 };
1124