2 * Copyright © 2014 Red Hat, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
34 #include "linux/input.h"
35 #include <sys/ioctl.h>
36 #include <sys/signalfd.h>
44 static const char *device;
45 static const char *seat = "seat0";
46 static struct udev *udev;
48 static const uint32_t screen_width = 100;
49 static const uint32_t screen_height = 100;
50 static int verbose = 0;
55 printf("Usage: %s [--verbose] [--udev [<seat>]|--device /dev/input/event0]\n"
56 "--verbose ....... Print debugging output.\n"
57 "--udev <seat>.... Use udev device discovery (default).\n"
58 " Specifying a seat ID is optional.\n"
59 "--device /path/to/device .... open the given device only\n",
60 program_invocation_short_name);
64 parse_args(int argc, char **argv)
69 static struct option opts[] = {
70 { "device", 1, 0, 'd' },
71 { "udev", 0, 0, 'u' },
72 { "help", 0, 0, 'h' },
73 { "verbose", 0, 0, 'v'},
77 c = getopt_long(argc, argv, "h", opts, &option_index);
82 case 'h': /* --help */
85 case 'd': /* --device */
93 case 'u': /* --udev */
98 case 'v': /* --verbose */
117 open_restricted(const char *path, int flags, void *user_data)
119 int fd = open(path, flags);
120 return fd < 0 ? -errno : fd;
124 close_restricted(int fd, void *user_data)
129 static const struct libinput_interface interface = {
130 .open_restricted = open_restricted,
131 .close_restricted = close_restricted,
135 log_handler(struct libinput *li,
136 enum libinput_log_priority priority,
140 vprintf(format, args);
144 open_udev(struct libinput **li)
148 fprintf(stderr, "Failed to initialize udev\n");
152 *li = libinput_udev_create_context(&interface, NULL, udev);
154 fprintf(stderr, "Failed to initialize context from udev\n");
159 libinput_log_set_handler(*li, log_handler);
160 libinput_log_set_priority(*li, LIBINPUT_LOG_PRIORITY_DEBUG);
163 if (libinput_udev_assign_seat(*li, seat)) {
164 fprintf(stderr, "Failed to set seat\n");
173 open_device(struct libinput **li, const char *path)
175 struct libinput_device *device;
177 *li = libinput_path_create_context(&interface, NULL);
179 fprintf(stderr, "Failed to initialize context from %s\n", path);
184 libinput_log_set_handler(*li, log_handler);
185 libinput_log_set_priority(*li, LIBINPUT_LOG_PRIORITY_DEBUG);
188 device = libinput_path_add_device(*li, path);
190 fprintf(stderr, "Failed to initialized device %s\n", path);
199 print_event_header(struct libinput_event *ev)
201 struct libinput_device *dev = libinput_event_get_device(ev);
204 switch(libinput_event_get_type(ev)) {
205 case LIBINPUT_EVENT_NONE:
207 case LIBINPUT_EVENT_DEVICE_ADDED:
208 type = "DEVICE_ADDED";
210 case LIBINPUT_EVENT_DEVICE_REMOVED:
211 type = "DEVICE_REMOVED";
213 case LIBINPUT_EVENT_KEYBOARD_KEY:
214 type = "KEYBOARD_KEY";
216 case LIBINPUT_EVENT_POINTER_MOTION:
217 type = "POINTER_MOTION";
219 case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
220 type = "POINTER_MOTION_ABSOLUTE";
222 case LIBINPUT_EVENT_POINTER_BUTTON:
223 type = "POINTER_BUTTON";
225 case LIBINPUT_EVENT_POINTER_AXIS:
226 type = "POINTER_AXIS";
228 case LIBINPUT_EVENT_TOUCH_DOWN:
231 case LIBINPUT_EVENT_TOUCH_MOTION:
232 type = "TOUCH_MOTION";
234 case LIBINPUT_EVENT_TOUCH_UP:
237 case LIBINPUT_EVENT_TOUCH_CANCEL:
238 type = "TOUCH_CANCEL";
240 case LIBINPUT_EVENT_TOUCH_FRAME:
241 type = "TOUCH_FRAME";
245 printf("%-7s %s ", libinput_device_get_sysname(dev), type);
249 print_event_time(uint32_t time)
251 printf("%+6.2fs ", (time - start_time) / 1000.0);
255 print_device_notify(struct libinput_event *ev)
257 struct libinput_device *dev = libinput_event_get_device(ev);
258 struct libinput_seat *seat = libinput_device_get_seat(dev);
262 libinput_seat_get_physical_name(seat),
263 libinput_seat_get_logical_name(seat));
265 if (libinput_device_get_size(dev, &w, &h) == 0)
266 printf("\tsize %.2f/%.2fmm", w, h);
272 print_key_event(struct libinput_event *ev)
274 struct libinput_event_keyboard *k = libinput_event_get_keyboard_event(ev);
275 enum libinput_key_state state;
277 print_event_time(libinput_event_keyboard_get_time(k));
278 state = libinput_event_keyboard_get_key_state(k);
280 libinput_event_keyboard_get_key(k),
281 state == LIBINPUT_KEY_STATE_PRESSED ? "pressed" : "released");
285 print_motion_event(struct libinput_event *ev)
287 struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
288 double x = libinput_event_pointer_get_dx(p);
289 double y = libinput_event_pointer_get_dy(p);
291 print_event_time(libinput_event_pointer_get_time(p));
293 printf("%6.2f/%6.2f\n", x, y);
297 print_absmotion_event(struct libinput_event *ev)
299 struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
300 double x = libinput_event_pointer_get_absolute_x_transformed(
302 double y = libinput_event_pointer_get_absolute_y_transformed(
305 print_event_time(libinput_event_pointer_get_time(p));
306 printf("%6.2f/%6.2f\n", x, y);
310 print_button_event(struct libinput_event *ev)
312 struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
313 enum libinput_button_state state;
315 print_event_time(libinput_event_pointer_get_time(p));
317 state = libinput_event_pointer_get_button_state(p);
318 printf("%3d %s, seat count: %u\n",
319 libinput_event_pointer_get_button(p),
320 state == LIBINPUT_BUTTON_STATE_PRESSED ? "pressed" : "released",
321 libinput_event_pointer_get_seat_button_count(p));
325 print_axis_event(struct libinput_event *ev)
327 struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
328 enum libinput_pointer_axis axis = libinput_event_pointer_get_axis(p);
333 case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
336 case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
343 print_event_time(libinput_event_pointer_get_time(p));
344 val = libinput_event_pointer_get_axis_value(p);
345 printf("%s %.2f\n", ax, val);
349 print_touch_event_without_coords(struct libinput_event *ev)
351 struct libinput_event_touch *t = libinput_event_get_touch_event(ev);
353 print_event_time(libinput_event_touch_get_time(t));
358 print_touch_event_with_coords(struct libinput_event *ev)
360 struct libinput_event_touch *t = libinput_event_get_touch_event(ev);
361 double x = libinput_event_touch_get_x_transformed(t, screen_width);
362 double y = libinput_event_touch_get_y_transformed(t, screen_height);
363 double xmm = libinput_event_touch_get_x(t);
364 double ymm = libinput_event_touch_get_y(t);
366 print_event_time(libinput_event_touch_get_time(t));
368 printf("%d (%d) %5.2f/%5.2f (%5.2f/%5.2fmm)\n",
369 libinput_event_touch_get_slot(t),
370 libinput_event_touch_get_seat_slot(t),
376 handle_and_print_events(struct libinput *li)
379 struct libinput_event *ev;
381 libinput_dispatch(li);
382 while ((ev = libinput_get_event(li))) {
383 print_event_header(ev);
385 switch (libinput_event_get_type(ev)) {
386 case LIBINPUT_EVENT_NONE:
388 case LIBINPUT_EVENT_DEVICE_ADDED:
389 case LIBINPUT_EVENT_DEVICE_REMOVED:
390 print_device_notify(ev);
392 case LIBINPUT_EVENT_KEYBOARD_KEY:
395 case LIBINPUT_EVENT_POINTER_MOTION:
396 print_motion_event(ev);
398 case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
399 print_absmotion_event(ev);
401 case LIBINPUT_EVENT_POINTER_BUTTON:
402 print_button_event(ev);
404 case LIBINPUT_EVENT_POINTER_AXIS:
405 print_axis_event(ev);
407 case LIBINPUT_EVENT_TOUCH_DOWN:
408 print_touch_event_with_coords(ev);
410 case LIBINPUT_EVENT_TOUCH_MOTION:
411 print_touch_event_with_coords(ev);
413 case LIBINPUT_EVENT_TOUCH_UP:
414 print_touch_event_without_coords(ev);
416 case LIBINPUT_EVENT_TOUCH_CANCEL:
417 print_touch_event_without_coords(ev);
419 case LIBINPUT_EVENT_TOUCH_FRAME:
420 print_touch_event_without_coords(ev);
424 libinput_event_destroy(ev);
425 libinput_dispatch(li);
432 mainloop(struct libinput *li)
434 struct pollfd fds[2];
437 fds[0].fd = libinput_get_fd(li);
438 fds[0].events = POLLIN;
442 sigaddset(&mask, SIGINT);
444 fds[1].fd = signalfd(-1, &mask, SFD_NONBLOCK);
445 fds[1].events = POLLIN;
448 if (fds[1].fd == -1 ||
449 sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
450 fprintf(stderr, "Failed to set up signal handling (%s)\n",
454 /* Handle already-pending device added events */
455 if (handle_and_print_events(li))
456 fprintf(stderr, "Expected device added events on startup but got none. "
457 "Maybe you don't have the right permissions?\n");
459 while (poll(fds, 2, -1) > -1) {
463 handle_and_print_events(li);
470 main(int argc, char **argv)
475 if (parse_args(argc, argv))
478 if (mode == MODE_UDEV) {
481 } else if (mode == MODE_DEVICE) {
482 if (open_device(&li, device))
487 clock_gettime(CLOCK_MONOTONIC, &tp);
488 start_time = tp.tv_sec * 1000 + tp.tv_nsec / 1000000;