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.
33 #include <linux/input.h>
34 #include <sys/ioctl.h>
35 #include <sys/signalfd.h>
43 static const char *device;
44 static const char *seat = "seat0";
45 static struct udev *udev;
47 static const uint32_t screen_width = 100;
48 static const uint32_t screen_height = 100;
53 printf("Usage: %s [--udev [<seat>]|--device /dev/input/event0]\n"
54 "--udev <seat>.... Use udev device discovery (default).\n"
55 " Specifying a seat ID is optional.\n"
56 "--device /path/to/device .... open the given device only\n",
57 program_invocation_short_name);
61 parse_args(int argc, char **argv)
66 static struct option opts[] = {
67 { "device", 1, 0, 'd' },
68 { "udev", 0, 0, 'u' },
69 { "help", 0, 0, 'h' },
73 c = getopt_long(argc, argv, "h", opts, &option_index);
78 case 'h': /* --help */
81 case 'd': /* --device */
89 case 'u': /* --udev */
110 open_restricted(const char *path, int flags, void *user_data)
112 int fd = open(path, flags);
113 return fd < 0 ? -errno : fd;
117 close_restricted(int fd, void *user_data)
122 const static struct libinput_interface interface = {
123 .open_restricted = open_restricted,
124 .close_restricted = close_restricted,
128 open_udev(struct libinput **li)
132 fprintf(stderr, "Failed to initialize udev\n");
136 *li = libinput_udev_create_for_seat(&interface, NULL, udev, seat);
138 fprintf(stderr, "Failed to initialize context from udev\n");
146 open_device(struct libinput **li, const char *path)
148 struct libinput_device *device;
150 *li = libinput_path_create_context(&interface, NULL);
152 fprintf(stderr, "Failed to initialize context from %s\n", path);
156 device = libinput_path_add_device(*li, path);
158 fprintf(stderr, "Failed to initialized device %s\n", path);
159 libinput_destroy(*li);
167 print_event_header(struct libinput_event *ev)
169 struct libinput_device *dev = libinput_event_get_device(ev);
172 switch(libinput_event_get_type(ev)) {
173 case LIBINPUT_EVENT_NONE:
175 case LIBINPUT_EVENT_DEVICE_ADDED:
176 type = "DEVICE_ADDED";
178 case LIBINPUT_EVENT_DEVICE_REMOVED:
179 type = "DEVICE_REMOVED";
181 case LIBINPUT_EVENT_KEYBOARD_KEY:
182 type = "KEYBOARD_KEY";
184 case LIBINPUT_EVENT_POINTER_MOTION:
185 type = "POINTER_MOTION";
187 case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
188 type = "POINTER_MOTION_ABSOLUTE";
190 case LIBINPUT_EVENT_POINTER_BUTTON:
191 type = "POINTER_BUTTON";
193 case LIBINPUT_EVENT_POINTER_AXIS:
194 type = "POINTER_AXIS";
196 case LIBINPUT_EVENT_TOUCH_DOWN:
199 case LIBINPUT_EVENT_TOUCH_MOTION:
200 type = "TOUCH_MOTION";
202 case LIBINPUT_EVENT_TOUCH_UP:
205 case LIBINPUT_EVENT_TOUCH_CANCEL:
206 type = "TOUCH_CANCEL";
208 case LIBINPUT_EVENT_TOUCH_FRAME:
209 type = "TOUCH_FRAME";
213 printf("%-7s %s ", libinput_device_get_sysname(dev), type);
217 print_event_time(uint32_t time)
219 printf("%+6.2fs ", (time - start_time) / 1000.0);
223 print_device_notify(struct libinput_event *ev)
225 struct libinput_device *dev = libinput_event_get_device(ev);
226 struct libinput_seat *seat = libinput_device_get_seat(dev);
229 libinput_seat_get_physical_name(seat),
230 libinput_seat_get_logical_name(seat));
234 print_key_event(struct libinput_event *ev)
236 struct libinput_event_keyboard *k = libinput_event_get_keyboard_event(ev);
237 enum libinput_keyboard_key_state state;
239 print_event_time(libinput_event_keyboard_get_time(k));
240 state = libinput_event_keyboard_get_key_state(k);
242 libinput_event_keyboard_get_key(k),
243 state == LIBINPUT_KEYBOARD_KEY_STATE_PRESSED ? "pressed" : "released");
247 print_motion_event(struct libinput_event *ev)
249 struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
250 li_fixed_t x = libinput_event_pointer_get_dx(p),
251 y = libinput_event_pointer_get_dy(p);
253 print_event_time(libinput_event_pointer_get_time(p));
255 printf("%6.2f/%6.2f\n",
256 li_fixed_to_double(x),
257 li_fixed_to_double(y));
261 print_absmotion_event(struct libinput_event *ev)
263 struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
264 li_fixed_t x = libinput_event_pointer_get_absolute_x_transformed(
266 li_fixed_t y = libinput_event_pointer_get_absolute_y_transformed(
269 print_event_time(libinput_event_pointer_get_time(p));
270 printf("%6.2f/%6.2f\n",
271 li_fixed_to_double(x),
272 li_fixed_to_double(y));
276 print_button_event(struct libinput_event *ev)
278 struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
279 enum libinput_pointer_button_state state;
281 print_event_time(libinput_event_pointer_get_time(p));
283 state = libinput_event_pointer_get_button_state(p);
285 libinput_event_pointer_get_button(p),
286 state == LIBINPUT_POINTER_BUTTON_STATE_PRESSED ? "pressed" : "released");
290 print_axis_event(struct libinput_event *ev)
292 struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
293 enum libinput_pointer_axis axis = libinput_event_pointer_get_axis(p);
298 case LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL:
301 case LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL:
308 print_event_time(libinput_event_pointer_get_time(p));
309 val = libinput_event_pointer_get_axis_value(p);
311 ax, li_fixed_to_double(val));
315 print_touch_event_without_coords(struct libinput_event *ev)
317 struct libinput_event_touch *t = libinput_event_get_touch_event(ev);
319 print_event_time(libinput_event_touch_get_time(t));
324 print_touch_event_with_coords(struct libinput_event *ev)
326 struct libinput_event_touch *t = libinput_event_get_touch_event(ev);
327 li_fixed_t x = libinput_event_touch_get_x_transformed(t, screen_width),
328 y = libinput_event_touch_get_y_transformed(t, screen_height);
330 print_event_time(libinput_event_touch_get_time(t));
332 printf("%d (%d) %5.2f/%5.2f\n",
333 libinput_event_touch_get_slot(t),
334 libinput_event_touch_get_seat_slot(t),
335 li_fixed_to_double(x),
336 li_fixed_to_double(y));
340 handle_and_print_events(struct libinput *li)
343 struct libinput_event *ev;
345 libinput_dispatch(li);
346 while ((ev = libinput_get_event(li))) {
347 print_event_header(ev);
349 switch (libinput_event_get_type(ev)) {
350 case LIBINPUT_EVENT_NONE:
352 case LIBINPUT_EVENT_DEVICE_ADDED:
353 case LIBINPUT_EVENT_DEVICE_REMOVED:
354 print_device_notify(ev);
356 case LIBINPUT_EVENT_KEYBOARD_KEY:
359 case LIBINPUT_EVENT_POINTER_MOTION:
360 print_motion_event(ev);
362 case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
363 print_absmotion_event(ev);
365 case LIBINPUT_EVENT_POINTER_BUTTON:
366 print_button_event(ev);
368 case LIBINPUT_EVENT_POINTER_AXIS:
369 print_axis_event(ev);
371 case LIBINPUT_EVENT_TOUCH_DOWN:
372 print_touch_event_with_coords(ev);
374 case LIBINPUT_EVENT_TOUCH_MOTION:
375 print_touch_event_with_coords(ev);
377 case LIBINPUT_EVENT_TOUCH_UP:
378 print_touch_event_without_coords(ev);
380 case LIBINPUT_EVENT_TOUCH_CANCEL:
381 print_touch_event_without_coords(ev);
383 case LIBINPUT_EVENT_TOUCH_FRAME:
384 print_touch_event_without_coords(ev);
388 libinput_event_destroy(ev);
389 libinput_dispatch(li);
396 mainloop(struct libinput *li)
398 struct pollfd fds[2];
401 fds[0].fd = libinput_get_fd(li);
402 fds[0].events = POLLIN;
406 sigaddset(&mask, SIGINT);
408 fds[1].fd = signalfd(-1, &mask, SFD_NONBLOCK);
409 fds[1].events = POLLIN;
412 if (fds[1].fd == -1 ||
413 sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
414 fprintf(stderr, "Failed to set up signal handling (%s)\n",
418 /* Handle already-pending device added events */
419 if (handle_and_print_events(li))
420 fprintf(stderr, "Expected device added events on startup but got none. "
421 "Maybe you don't have the right permissions?\n");
423 while (poll(fds, 2, -1) > -1) {
427 handle_and_print_events(li);
434 main(int argc, char **argv)
439 if (parse_args(argc, argv))
442 if (mode == MODE_UDEV) {
445 } else if (mode == MODE_DEVICE) {
446 if (open_device(&li, device))
451 clock_gettime(CLOCK_MONOTONIC, &tp);
452 start_time = tp.tv_sec * 1000 + tp.tv_nsec / 1000000;