• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016 Red Hat, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include "config.h"
25 #include "evdev-tablet-pad.h"
26 #include "util-input-event.h"
27 
28 #include <assert.h>
29 #include <stdbool.h>
30 #include <string.h>
31 
32 #if HAVE_LIBWACOM
33 #include <libwacom/libwacom.h>
34 #endif
35 
36 #define pad_set_status(pad_,s_) (pad_)->status |= (s_)
37 #define pad_unset_status(pad_,s_) (pad_)->status &= ~(s_)
38 #define pad_has_status(pad_,s_) (!!((pad_)->status & (s_)))
39 
40 static void
pad_get_buttons_pressed(struct pad_dispatch * pad,struct button_state * buttons)41 pad_get_buttons_pressed(struct pad_dispatch *pad,
42 			struct button_state *buttons)
43 {
44 	struct button_state *state = &pad->button_state;
45 	struct button_state *prev_state = &pad->prev_button_state;
46 	unsigned int i;
47 
48 	for (i = 0; i < sizeof(buttons->bits); i++)
49 		buttons->bits[i] = state->bits[i] & ~(prev_state->bits[i]);
50 }
51 
52 static void
pad_get_buttons_released(struct pad_dispatch * pad,struct button_state * buttons)53 pad_get_buttons_released(struct pad_dispatch *pad,
54 			 struct button_state *buttons)
55 {
56 	struct button_state *state = &pad->button_state;
57 	struct button_state *prev_state = &pad->prev_button_state;
58 	unsigned int i;
59 
60 	for (i = 0; i < sizeof(buttons->bits); i++)
61 		buttons->bits[i] = prev_state->bits[i] & ~(state->bits[i]);
62 }
63 
64 static inline bool
pad_button_is_down(const struct pad_dispatch * pad,uint32_t button)65 pad_button_is_down(const struct pad_dispatch *pad,
66 		   uint32_t button)
67 {
68 	return bit_is_set(pad->button_state.bits, button);
69 }
70 
71 static inline bool
pad_any_button_down(const struct pad_dispatch * pad)72 pad_any_button_down(const struct pad_dispatch *pad)
73 {
74 	const struct button_state *state = &pad->button_state;
75 	unsigned int i;
76 
77 	for (i = 0; i < sizeof(state->bits); i++)
78 		if (state->bits[i] != 0)
79 			return true;
80 
81 	return false;
82 }
83 
84 static inline void
pad_button_set_down(struct pad_dispatch * pad,uint32_t button,bool is_down)85 pad_button_set_down(struct pad_dispatch *pad,
86 		    uint32_t button,
87 		    bool is_down)
88 {
89 	struct button_state *state = &pad->button_state;
90 
91 	if (is_down) {
92 		set_bit(state->bits, button);
93 		pad_set_status(pad, PAD_BUTTONS_PRESSED);
94 	} else {
95 		clear_bit(state->bits, button);
96 		pad_set_status(pad, PAD_BUTTONS_RELEASED);
97 	}
98 }
99 
100 static void
pad_process_absolute(struct pad_dispatch * pad,struct evdev_device * device,struct input_event * e,uint64_t time)101 pad_process_absolute(struct pad_dispatch *pad,
102 		     struct evdev_device *device,
103 		     struct input_event *e,
104 		     uint64_t time)
105 {
106 	switch (e->code) {
107 	case ABS_WHEEL:
108 		pad->changed_axes |= PAD_AXIS_RING1;
109 		pad_set_status(pad, PAD_AXES_UPDATED);
110 		break;
111 	case ABS_THROTTLE:
112 		pad->changed_axes |= PAD_AXIS_RING2;
113 		pad_set_status(pad, PAD_AXES_UPDATED);
114 		break;
115 	case ABS_RX:
116 		pad->changed_axes |= PAD_AXIS_STRIP1;
117 		pad_set_status(pad, PAD_AXES_UPDATED);
118 		break;
119 	case ABS_RY:
120 		pad->changed_axes |= PAD_AXIS_STRIP2;
121 		pad_set_status(pad, PAD_AXES_UPDATED);
122 		break;
123 	case ABS_MISC:
124 		/* The wacom driver always sends a 0 axis event on finger
125 		   up, but we also get an ABS_MISC 15 on touch down and
126 		   ABS_MISC 0 on touch up, on top of the actual event. This
127 		   is kernel behavior for xf86-input-wacom backwards
128 		   compatibility after the 3.17 wacom HID move.
129 
130 		   We use that event to tell when we truly went a full
131 		   rotation around the wheel vs. a finger release.
132 
133 		   FIXME: On the Intuos5 and later the kernel merges all
134 		   states into that event, so if any finger is down on any
135 		   button, the wheel release won't trigger the ABS_MISC 0
136 		   but still send a 0 event. We can't currently detect this.
137 		 */
138 		pad->have_abs_misc_terminator = true;
139 		break;
140 	default:
141 		evdev_log_info(device,
142 			       "Unhandled EV_ABS event code %#x\n",
143 			       e->code);
144 		break;
145 	}
146 }
147 
148 static inline double
normalize_ring(const struct input_absinfo * absinfo)149 normalize_ring(const struct input_absinfo *absinfo)
150 {
151 	/* libinput has 0 as the ring's northernmost point in the device's
152 	   current logical rotation, increasing clockwise to 1. Wacom has
153 	   0 on the left-most wheel position.
154 	 */
155 	double range = absinfo_range(absinfo);
156 	double value = (absinfo->value - absinfo->minimum) / range - 0.25;
157 
158 	if (value < 0.0)
159 		value += 1.0;
160 
161 	return value;
162 }
163 
164 static inline double
normalize_strip(const struct input_absinfo * absinfo)165 normalize_strip(const struct input_absinfo *absinfo)
166 {
167 	/* strip axes don't use a proper value, they just shift the bit left
168 	 * for each position. 0 isn't a real value either, it's only sent on
169 	 * finger release */
170 	double min = 0,
171 	       max = log2(absinfo->maximum);
172 	double range = max - min;
173 	double value = (log2(absinfo->value) - min) / range;
174 
175 	return value;
176 }
177 
178 static inline double
pad_handle_ring(struct pad_dispatch * pad,struct evdev_device * device,unsigned int code)179 pad_handle_ring(struct pad_dispatch *pad,
180 		struct evdev_device *device,
181 		unsigned int code)
182 {
183 	const struct input_absinfo *absinfo;
184 	double degrees;
185 
186 	absinfo = libevdev_get_abs_info(device->evdev, code);
187 	assert(absinfo);
188 
189 	degrees = normalize_ring(absinfo) * 360;
190 
191 	if (device->left_handed.enabled)
192 		degrees = fmod(degrees + 180, 360);
193 
194 	return degrees;
195 }
196 
197 static inline double
pad_handle_strip(struct pad_dispatch * pad,struct evdev_device * device,unsigned int code)198 pad_handle_strip(struct pad_dispatch *pad,
199 		 struct evdev_device *device,
200 		 unsigned int code)
201 {
202 	const struct input_absinfo *absinfo;
203 	double pos;
204 
205 	absinfo = libevdev_get_abs_info(device->evdev, code);
206 	assert(absinfo);
207 
208 	if (absinfo->value == 0)
209 		return 0.0;
210 
211 	pos = normalize_strip(absinfo);
212 
213 	if (device->left_handed.enabled)
214 		pos = 1.0 - pos;
215 
216 	return pos;
217 }
218 
219 static inline struct libinput_tablet_pad_mode_group *
pad_ring_get_mode_group(struct pad_dispatch * pad,unsigned int ring)220 pad_ring_get_mode_group(struct pad_dispatch *pad,
221 			unsigned int ring)
222 {
223 	struct libinput_tablet_pad_mode_group *group;
224 
225 	list_for_each(group, &pad->modes.mode_group_list, link) {
226 		if (libinput_tablet_pad_mode_group_has_ring(group, ring))
227 			return group;
228 	}
229 
230 	assert(!"Unable to find ring mode group");
231 
232 	return NULL;
233 }
234 
235 static inline struct libinput_tablet_pad_mode_group *
pad_strip_get_mode_group(struct pad_dispatch * pad,unsigned int strip)236 pad_strip_get_mode_group(struct pad_dispatch *pad,
237 			unsigned int strip)
238 {
239 	struct libinput_tablet_pad_mode_group *group;
240 
241 	list_for_each(group, &pad->modes.mode_group_list, link) {
242 		if (libinput_tablet_pad_mode_group_has_strip(group, strip))
243 			return group;
244 	}
245 
246 	assert(!"Unable to find strip mode group");
247 
248 	return NULL;
249 }
250 
251 static void
pad_check_notify_axes(struct pad_dispatch * pad,struct evdev_device * device,uint64_t time)252 pad_check_notify_axes(struct pad_dispatch *pad,
253 		      struct evdev_device *device,
254 		      uint64_t time)
255 {
256 	struct libinput_device *base = &device->base;
257 	struct libinput_tablet_pad_mode_group *group;
258 	double value;
259 	bool send_finger_up = false;
260 
261 	/* Suppress the reset to 0 on finger up. See the
262 	   comment in pad_process_absolute */
263 	if (pad->have_abs_misc_terminator &&
264 	    libevdev_get_event_value(device->evdev, EV_ABS, ABS_MISC) == 0)
265 		send_finger_up = true;
266 
267 	if (pad->changed_axes & PAD_AXIS_RING1) {
268 		value = pad_handle_ring(pad, device, ABS_WHEEL);
269 		if (send_finger_up)
270 			value = -1.0;
271 
272 		group = pad_ring_get_mode_group(pad, 0);
273 		tablet_pad_notify_ring(base,
274 				       time,
275 				       0,
276 				       value,
277 				       LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER,
278 				       group);
279 	}
280 
281 	if (pad->changed_axes & PAD_AXIS_RING2) {
282 		value = pad_handle_ring(pad, device, ABS_THROTTLE);
283 		if (send_finger_up)
284 			value = -1.0;
285 
286 		group = pad_ring_get_mode_group(pad, 1);
287 		tablet_pad_notify_ring(base,
288 				       time,
289 				       1,
290 				       value,
291 				       LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER,
292 				       group);
293 	}
294 
295 	if (pad->changed_axes & PAD_AXIS_STRIP1) {
296 		value = pad_handle_strip(pad, device, ABS_RX);
297 		if (send_finger_up)
298 			value = -1.0;
299 
300 		group = pad_strip_get_mode_group(pad, 0);
301 		tablet_pad_notify_strip(base,
302 					time,
303 					0,
304 					value,
305 					LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER,
306 					group);
307 	}
308 
309 	if (pad->changed_axes & PAD_AXIS_STRIP2) {
310 		value = pad_handle_strip(pad, device, ABS_RY);
311 		if (send_finger_up)
312 			value = -1.0;
313 
314 		group = pad_strip_get_mode_group(pad, 1);
315 		tablet_pad_notify_strip(base,
316 					time,
317 					1,
318 					value,
319 					LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER,
320 					group);
321 	}
322 
323 	pad->changed_axes = PAD_AXIS_NONE;
324 	pad->have_abs_misc_terminator = false;
325 }
326 
327 static void
pad_process_key(struct pad_dispatch * pad,struct evdev_device * device,struct input_event * e,uint64_t time)328 pad_process_key(struct pad_dispatch *pad,
329 		struct evdev_device *device,
330 		struct input_event *e,
331 		uint64_t time)
332 {
333 	uint32_t button = e->code;
334 	uint32_t is_press = e->value != 0;
335 
336 	/* ignore kernel key repeat */
337 	if (e->value == 2)
338 		return;
339 
340 	pad_button_set_down(pad, button, is_press);
341 }
342 
343 static inline struct libinput_tablet_pad_mode_group *
pad_button_get_mode_group(struct pad_dispatch * pad,unsigned int button)344 pad_button_get_mode_group(struct pad_dispatch *pad,
345 			  unsigned int button)
346 {
347 	struct libinput_tablet_pad_mode_group *group;
348 
349 	list_for_each(group, &pad->modes.mode_group_list, link) {
350 		if (libinput_tablet_pad_mode_group_has_button(group, button))
351 			return group;
352 	}
353 
354 	assert(!"Unable to find button mode group\n");
355 
356 	return NULL;
357 }
358 
359 static void
pad_notify_button_mask(struct pad_dispatch * pad,struct evdev_device * device,uint64_t time,const struct button_state * buttons,enum libinput_button_state state)360 pad_notify_button_mask(struct pad_dispatch *pad,
361 		       struct evdev_device *device,
362 		       uint64_t time,
363 		       const struct button_state *buttons,
364 		       enum libinput_button_state state)
365 {
366 	struct libinput_device *base = &device->base;
367 	struct libinput_tablet_pad_mode_group *group;
368 	int32_t code;
369 	unsigned int i;
370 
371 	for (i = 0; i < sizeof(buttons->bits); i++) {
372 		unsigned char buttons_slice = buttons->bits[i];
373 
374 		code = i * 8;
375 		while (buttons_slice) {
376 			int enabled;
377 			key_or_button_map_t map;
378 
379 			code++;
380 			enabled = (buttons_slice & 1);
381 			buttons_slice >>= 1;
382 
383 			if (!enabled)
384 				continue;
385 
386 			map = pad->button_map[code - 1];
387 			if (map_is_unmapped(map))
388 				continue;
389 
390 			if (map_is_button(map)) {
391 				int32_t button = map_value(map);
392 
393 				group = pad_button_get_mode_group(pad, button);
394 				pad_button_update_mode(group, button, state);
395 				tablet_pad_notify_button(base,
396 							 time,
397 							 button,
398 							 state,
399 							 group);
400 			} else if (map_is_key(map)) {
401 				uint32_t key = map_value(map);
402 
403 				tablet_pad_notify_key(base,
404 						      time,
405 						      key,
406 						      (enum libinput_key_state)state);
407 			} else {
408 				abort();
409 			}
410 		}
411 	}
412 }
413 
414 static void
pad_notify_buttons(struct pad_dispatch * pad,struct evdev_device * device,uint64_t time,enum libinput_button_state state)415 pad_notify_buttons(struct pad_dispatch *pad,
416 		   struct evdev_device *device,
417 		   uint64_t time,
418 		   enum libinput_button_state state)
419 {
420 	struct button_state buttons;
421 
422 	if (state == LIBINPUT_BUTTON_STATE_PRESSED)
423 		pad_get_buttons_pressed(pad, &buttons);
424 	else
425 		pad_get_buttons_released(pad, &buttons);
426 
427 	pad_notify_button_mask(pad, device, time, &buttons, state);
428 }
429 
430 static void
pad_change_to_left_handed(struct evdev_device * device)431 pad_change_to_left_handed(struct evdev_device *device)
432 {
433 	struct pad_dispatch *pad = (struct pad_dispatch*)device->dispatch;
434 
435 	if (device->left_handed.enabled == device->left_handed.want_enabled)
436 		return;
437 
438 	if (pad_any_button_down(pad))
439 		return;
440 
441 	device->left_handed.enabled = device->left_handed.want_enabled;
442 }
443 
444 static void
pad_flush(struct pad_dispatch * pad,struct evdev_device * device,uint64_t time)445 pad_flush(struct pad_dispatch *pad,
446 	  struct evdev_device *device,
447 	  uint64_t time)
448 {
449 	if (pad_has_status(pad, PAD_AXES_UPDATED)) {
450 		pad_check_notify_axes(pad, device, time);
451 		pad_unset_status(pad, PAD_AXES_UPDATED);
452 	}
453 
454 	if (pad_has_status(pad, PAD_BUTTONS_RELEASED)) {
455 		pad_notify_buttons(pad,
456 				   device,
457 				   time,
458 				   LIBINPUT_BUTTON_STATE_RELEASED);
459 		pad_unset_status(pad, PAD_BUTTONS_RELEASED);
460 
461 		pad_change_to_left_handed(device);
462 	}
463 
464 	if (pad_has_status(pad, PAD_BUTTONS_PRESSED)) {
465 		pad_notify_buttons(pad,
466 				   device,
467 				   time,
468 				   LIBINPUT_BUTTON_STATE_PRESSED);
469 		pad_unset_status(pad, PAD_BUTTONS_PRESSED);
470 	}
471 
472 	/* Update state */
473 	memcpy(&pad->prev_button_state,
474 	       &pad->button_state,
475 	       sizeof(pad->button_state));
476 }
477 
478 static void
pad_process(struct evdev_dispatch * dispatch,struct evdev_device * device,struct input_event * e,uint64_t time)479 pad_process(struct evdev_dispatch *dispatch,
480 	    struct evdev_device *device,
481 	    struct input_event *e,
482 	    uint64_t time)
483 {
484 	struct pad_dispatch *pad = pad_dispatch(dispatch);
485 
486 	switch (e->type) {
487 	case EV_ABS:
488 		pad_process_absolute(pad, device, e, time);
489 		break;
490 	case EV_KEY:
491 		pad_process_key(pad, device, e, time);
492 		break;
493 	case EV_SYN:
494 		pad_flush(pad, device, time);
495 		break;
496 	case EV_MSC:
497 		/* The EKR sends the serial as MSC_SERIAL, ignore this for
498 		 * now */
499 		break;
500 	default:
501 		evdev_log_error(device,
502 				"Unexpected event type %s (%#x)\n",
503 				libevdev_event_type_get_name(e->type),
504 				e->type);
505 		break;
506 	}
507 }
508 
509 static void
pad_suspend(struct evdev_dispatch * dispatch,struct evdev_device * device)510 pad_suspend(struct evdev_dispatch *dispatch,
511 	    struct evdev_device *device)
512 {
513 	struct pad_dispatch *pad = pad_dispatch(dispatch);
514 	struct libinput *libinput = pad_libinput_context(pad);
515 	unsigned int code;
516 
517 	for (code = KEY_ESC; code < KEY_CNT; code++) {
518 		if (pad_button_is_down(pad, code))
519 			pad_button_set_down(pad, code, false);
520 	}
521 
522 	pad_flush(pad, device, libinput_now(libinput));
523 }
524 
525 static void
pad_destroy(struct evdev_dispatch * dispatch)526 pad_destroy(struct evdev_dispatch *dispatch)
527 {
528 	struct pad_dispatch *pad = pad_dispatch(dispatch);
529 
530 	pad_destroy_leds(pad);
531 	free(pad);
532 }
533 
534 static struct evdev_dispatch_interface pad_interface = {
535 	.process = pad_process,
536 	.suspend = pad_suspend,
537 	.remove = NULL,
538 	.destroy = pad_destroy,
539 	.device_added = NULL,
540 	.device_removed = NULL,
541 	.device_suspended = NULL,
542 	.device_resumed = NULL,
543 	.post_added = NULL,
544 	.touch_arbitration_toggle = NULL,
545 	.touch_arbitration_update_rect = NULL,
546 	.get_switch_state = NULL,
547 };
548 
549 static bool
pad_init_buttons_from_libwacom(struct pad_dispatch * pad,struct evdev_device * device)550 pad_init_buttons_from_libwacom(struct pad_dispatch *pad,
551 			       struct evdev_device *device)
552 {
553 	bool rc = false;
554 #if HAVE_LIBWACOM
555 	struct libinput *li = pad_libinput_context(pad);
556 	WacomDeviceDatabase *db = NULL;
557 	WacomDevice *tablet = NULL;
558 	int num_buttons;
559 	int map = 0;
560 	char event_path[64];
561 
562 	db = libinput_libwacom_ref(li);
563 	if (!db)
564 		goto out;
565 
566 	snprintf(event_path,
567 		 sizeof(event_path),
568 		 "/dev/input/%s",
569 		 evdev_device_get_sysname(device));
570 	tablet = libwacom_new_from_path(db,
571 					event_path,
572 					WFALLBACK_NONE,
573 					NULL);
574 	if (!tablet) {
575 		tablet = libwacom_new_from_usbid(db,
576 						 evdev_device_get_id_vendor(device),
577 						 evdev_device_get_id_product(device),
578 						 NULL);
579 	}
580 
581 	if (!tablet)
582 		goto out;
583 
584 	num_buttons = libwacom_get_num_buttons(tablet);
585 	for (int i = 0; i < num_buttons; i++) {
586 		unsigned int code;
587 
588 		code = libwacom_get_button_evdev_code(tablet, 'A' + i);
589 		if (code == 0)
590 			continue;
591 
592 		map_set_button_map(pad->button_map[code], map++);
593 	}
594 
595 	pad->nbuttons = map;
596 
597 	rc = true;
598 out:
599 	if (tablet)
600 		libwacom_destroy(tablet);
601 	if (db)
602 		libinput_libwacom_unref(li);
603 #endif
604 	return rc;
605 }
606 
607 static void
pad_init_buttons_from_kernel(struct pad_dispatch * pad,struct evdev_device * device)608 pad_init_buttons_from_kernel(struct pad_dispatch *pad,
609 			       struct evdev_device *device)
610 {
611 	unsigned int code;
612 	int map = 0;
613 
614 	/* we match wacom_report_numbered_buttons() from the kernel */
615 	for (code = BTN_0; code < BTN_0 + 10; code++) {
616 		if (libevdev_has_event_code(device->evdev, EV_KEY, code))
617 			map_set_button_map(pad->button_map[code], map++);
618 	}
619 
620 	for (code = BTN_BASE; code < BTN_BASE + 2; code++) {
621 		if (libevdev_has_event_code(device->evdev, EV_KEY, code))
622 			map_set_button_map(pad->button_map[code], map++);
623 	}
624 
625 	for (code = BTN_A; code < BTN_A + 6; code++) {
626 		if (libevdev_has_event_code(device->evdev, EV_KEY, code))
627 			map_set_button_map(pad->button_map[code], map++);
628 	}
629 
630 	for (code = BTN_LEFT; code < BTN_LEFT + 7; code++) {
631 		if (libevdev_has_event_code(device->evdev, EV_KEY, code))
632 			map_set_button_map(pad->button_map[code], map++);
633 	}
634 
635 	pad->nbuttons = map;
636 }
637 
638 static void
pad_init_keys(struct pad_dispatch * pad,struct evdev_device * device)639 pad_init_keys(struct pad_dispatch *pad, struct evdev_device *device)
640 {
641 	unsigned int codes[] = {
642 		KEY_BUTTONCONFIG,
643 		KEY_ONSCREEN_KEYBOARD,
644 		KEY_CONTROLPANEL,
645 	};
646 
647 	/* Wacom's keys are the only ones we know anything about */
648 	if (libevdev_get_id_vendor(device->evdev) != VENDOR_ID_WACOM)
649 		return;
650 
651 	ARRAY_FOR_EACH(codes, code) {
652 		if (libevdev_has_event_code(device->evdev, EV_KEY, *code))
653 			map_set_key_map(pad->button_map[*code], *code);
654 	}
655 }
656 
657 static void
pad_init_buttons(struct pad_dispatch * pad,struct evdev_device * device)658 pad_init_buttons(struct pad_dispatch *pad,
659 		 struct evdev_device *device)
660 {
661 	size_t i;
662 
663 	for (i = 0; i < ARRAY_LENGTH(pad->button_map); i++)
664 		map_init(pad->button_map[i]);
665 
666 	if (!pad_init_buttons_from_libwacom(pad, device))
667 		pad_init_buttons_from_kernel(pad, device);
668 
669 	pad_init_keys(pad, device);
670 }
671 
672 static void
pad_init_left_handed(struct evdev_device * device)673 pad_init_left_handed(struct evdev_device *device)
674 {
675 	if (evdev_tablet_has_left_handed(device))
676 		evdev_init_left_handed(device,
677 				       pad_change_to_left_handed);
678 }
679 
680 static int
pad_init(struct pad_dispatch * pad,struct evdev_device * device)681 pad_init(struct pad_dispatch *pad, struct evdev_device *device)
682 {
683 	pad->base.dispatch_type = DISPATCH_TABLET_PAD;
684 	pad->base.interface = &pad_interface;
685 	pad->device = device;
686 	pad->status = PAD_NONE;
687 	pad->changed_axes = PAD_AXIS_NONE;
688 
689 	pad_init_buttons(pad, device);
690 	pad_init_left_handed(device);
691 	if (pad_init_leds(pad, device) != 0)
692 		return 1;
693 
694 	return 0;
695 }
696 
697 static uint32_t
pad_sendevents_get_modes(struct libinput_device * device)698 pad_sendevents_get_modes(struct libinput_device *device)
699 {
700 	return LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
701 }
702 
703 static enum libinput_config_status
pad_sendevents_set_mode(struct libinput_device * device,enum libinput_config_send_events_mode mode)704 pad_sendevents_set_mode(struct libinput_device *device,
705 			enum libinput_config_send_events_mode mode)
706 {
707 	struct evdev_device *evdev = evdev_device(device);
708 	struct pad_dispatch *pad = (struct pad_dispatch*)evdev->dispatch;
709 
710 	if (mode == pad->sendevents.current_mode)
711 		return LIBINPUT_CONFIG_STATUS_SUCCESS;
712 
713 	switch(mode) {
714 	case LIBINPUT_CONFIG_SEND_EVENTS_ENABLED:
715 		break;
716 	case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED:
717 		pad_suspend(evdev->dispatch, evdev);
718 		break;
719 	default:
720 		return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
721 	}
722 
723 	pad->sendevents.current_mode = mode;
724 
725 	return LIBINPUT_CONFIG_STATUS_SUCCESS;
726 }
727 
728 static enum libinput_config_send_events_mode
pad_sendevents_get_mode(struct libinput_device * device)729 pad_sendevents_get_mode(struct libinput_device *device)
730 {
731 	struct evdev_device *evdev = evdev_device(device);
732 	struct pad_dispatch *dispatch = (struct pad_dispatch*)evdev->dispatch;
733 
734 	return dispatch->sendevents.current_mode;
735 }
736 
737 static enum libinput_config_send_events_mode
pad_sendevents_get_default_mode(struct libinput_device * device)738 pad_sendevents_get_default_mode(struct libinput_device *device)
739 {
740 	return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
741 }
742 
743 struct evdev_dispatch *
evdev_tablet_pad_create(struct evdev_device * device)744 evdev_tablet_pad_create(struct evdev_device *device)
745 {
746 	struct pad_dispatch *pad;
747 
748 	pad = zalloc(sizeof *pad);
749 
750 	if (pad_init(pad, device) != 0) {
751 		pad_destroy(&pad->base);
752 		return NULL;
753 	}
754 
755 	device->base.config.sendevents = &pad->sendevents.config;
756 	pad->sendevents.current_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
757 	pad->sendevents.config.get_modes = pad_sendevents_get_modes;
758 	pad->sendevents.config.set_mode = pad_sendevents_set_mode;
759 	pad->sendevents.config.get_mode = pad_sendevents_get_mode;
760 	pad->sendevents.config.get_default_mode = pad_sendevents_get_default_mode;
761 
762 	return &pad->base;
763 }
764 
765 int
evdev_device_tablet_pad_has_key(struct evdev_device * device,uint32_t code)766 evdev_device_tablet_pad_has_key(struct evdev_device *device, uint32_t code)
767 {
768 	if (!(device->seat_caps & EVDEV_DEVICE_TABLET_PAD))
769 		return -1;
770 
771 	return libevdev_has_event_code(device->evdev, EV_KEY, code);
772 }
773 
774 int
evdev_device_tablet_pad_get_num_buttons(struct evdev_device * device)775 evdev_device_tablet_pad_get_num_buttons(struct evdev_device *device)
776 {
777 	struct pad_dispatch *pad = (struct pad_dispatch*)device->dispatch;
778 
779 	if (!(device->seat_caps & EVDEV_DEVICE_TABLET_PAD))
780 		return -1;
781 
782 	return pad->nbuttons;
783 }
784 
785 int
evdev_device_tablet_pad_get_num_rings(struct evdev_device * device)786 evdev_device_tablet_pad_get_num_rings(struct evdev_device *device)
787 {
788 	int nrings = 0;
789 
790 	if (!(device->seat_caps & EVDEV_DEVICE_TABLET_PAD))
791 		return -1;
792 
793 	if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_WHEEL)) {
794 		nrings++;
795 		if (libevdev_has_event_code(device->evdev,
796 					    EV_ABS,
797 					    ABS_THROTTLE))
798 			nrings++;
799 	}
800 
801 	return nrings;
802 }
803 
804 int
evdev_device_tablet_pad_get_num_strips(struct evdev_device * device)805 evdev_device_tablet_pad_get_num_strips(struct evdev_device *device)
806 {
807 	int nstrips = 0;
808 
809 	if (!(device->seat_caps & EVDEV_DEVICE_TABLET_PAD))
810 		return -1;
811 
812 	if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_RX)) {
813 		nstrips++;
814 		if (libevdev_has_event_code(device->evdev,
815 					    EV_ABS,
816 					    ABS_RY))
817 			nstrips++;
818 	}
819 
820 	return nstrips;
821 }
822