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