tools: add newline before function name
[platform/upstream/libinput.git] / tools / event-debug.c
1 /*
2  * Copyright © 2014 Red Hat, Inc.
3  *
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.
13  *
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.
21  */
22
23 #define _GNU_SOURCE
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <getopt.h>
27 #include <poll.h>
28 #include <stdio.h>
29 #include <signal.h>
30 #include <string.h>
31 #include <time.h>
32 #include <unistd.h>
33 #include <linux/input.h>
34 #include <sys/ioctl.h>
35 #include <sys/signalfd.h>
36
37 #include <libinput.h>
38
39 static enum {
40         MODE_UDEV,
41         MODE_DEVICE,
42 } mode = MODE_UDEV;
43 static const char *device;
44 static const char *seat = "seat0";
45 static struct udev *udev;
46 uint32_t start_time;
47 static const uint32_t screen_width = 100;
48 static const uint32_t screen_height = 100;
49 static int verbose = 0;
50
51 static void
52 usage(void)
53 {
54         printf("Usage: %s [--verbose] [--udev [<seat>]|--device /dev/input/event0]\n"
55                "--verbose ....... Print debugging output.\n"
56                "--udev <seat>.... Use udev device discovery (default).\n"
57                "                  Specifying a seat ID is optional.\n"
58                "--device /path/to/device .... open the given device only\n",
59                 program_invocation_short_name);
60 }
61
62 static int
63 parse_args(int argc, char **argv)
64 {
65         while (1) {
66                 int c;
67                 int option_index = 0;
68                 static struct option opts[] = {
69                         { "device", 1, 0, 'd' },
70                         { "udev", 0, 0, 'u' },
71                         { "help", 0, 0, 'h' },
72                         { "verbose", 0, 0, 'v'},
73                         { 0, 0, 0, 0}
74                 };
75
76                 c = getopt_long(argc, argv, "h", opts, &option_index);
77                 if (c == -1)
78                         break;
79
80                 switch(c) {
81                         case 'h': /* --help */
82                                 usage();
83                                 exit(0);
84                         case 'd': /* --device */
85                                 mode = MODE_DEVICE;
86                                 if (!optarg) {
87                                         usage();
88                                         return 1;
89                                 }
90                                 device = optarg;
91                                 break;
92                         case 'u': /* --udev */
93                                 mode = MODE_UDEV;
94                                 if (optarg)
95                                         seat = optarg;
96                                 break;
97                         case 'v': /* --verbose */
98                                 verbose = 1;
99                                 break;
100                         default:
101                                 usage();
102                                 return 1;
103                 }
104
105         }
106
107         if (optind < argc) {
108                 usage();
109                 return 1;
110         }
111
112         return 0;
113 }
114
115 static int
116 open_restricted(const char *path, int flags, void *user_data)
117 {
118         int fd = open(path, flags);
119         return fd < 0 ? -errno : fd;
120 }
121
122 static void
123 close_restricted(int fd, void *user_data)
124 {
125         close(fd);
126 }
127
128 const static struct libinput_interface interface = {
129         .open_restricted = open_restricted,
130         .close_restricted = close_restricted,
131 };
132
133 static int
134 open_udev(struct libinput **li)
135 {
136         udev = udev_new();
137         if (!udev) {
138                 fprintf(stderr, "Failed to initialize udev\n");
139                 return 1;
140         }
141
142         *li = libinput_udev_create_for_seat(&interface, NULL, udev, seat);
143         if (!*li) {
144                 fprintf(stderr, "Failed to initialize context from udev\n");
145                 return 1;
146         }
147
148         return 0;
149 }
150
151 static int
152 open_device(struct libinput **li, const char *path)
153 {
154         struct libinput_device *device;
155
156         *li = libinput_path_create_context(&interface, NULL);
157         if (!*li) {
158                 fprintf(stderr, "Failed to initialize context from %s\n", path);
159                 return 1;
160         }
161
162         device = libinput_path_add_device(*li, path);
163         if (!device) {
164                 fprintf(stderr, "Failed to initialized device %s\n", path);
165                 libinput_destroy(*li);
166                 return 1;
167         }
168
169         return 0;
170 }
171
172 static void
173 print_event_header(struct libinput_event *ev)
174 {
175         struct libinput_device *dev = libinput_event_get_device(ev);
176         const char *type;
177
178         switch(libinput_event_get_type(ev)) {
179         case LIBINPUT_EVENT_NONE:
180                 abort();
181         case LIBINPUT_EVENT_DEVICE_ADDED:
182                 type = "DEVICE_ADDED";
183                 break;
184         case LIBINPUT_EVENT_DEVICE_REMOVED:
185                 type = "DEVICE_REMOVED";
186                 break;
187         case LIBINPUT_EVENT_KEYBOARD_KEY:
188                 type = "KEYBOARD_KEY";
189                 break;
190         case LIBINPUT_EVENT_POINTER_MOTION:
191                 type = "POINTER_MOTION";
192                 break;
193         case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
194                 type = "POINTER_MOTION_ABSOLUTE";
195                 break;
196         case LIBINPUT_EVENT_POINTER_BUTTON:
197                 type = "POINTER_BUTTON";
198                 break;
199         case LIBINPUT_EVENT_POINTER_AXIS:
200                 type = "POINTER_AXIS";
201                 break;
202         case LIBINPUT_EVENT_TOUCH_DOWN:
203                 type = "TOUCH_DOWN";
204                 break;
205         case LIBINPUT_EVENT_TOUCH_MOTION:
206                 type = "TOUCH_MOTION";
207                 break;
208         case LIBINPUT_EVENT_TOUCH_UP:
209                 type = "TOUCH_UP";
210                 break;
211         case LIBINPUT_EVENT_TOUCH_CANCEL:
212                 type = "TOUCH_CANCEL";
213                 break;
214         case LIBINPUT_EVENT_TOUCH_FRAME:
215                 type = "TOUCH_FRAME";
216                 break;
217         }
218
219         printf("%-7s    %s      ", libinput_device_get_sysname(dev), type);
220 }
221
222 static void
223 print_event_time(uint32_t time)
224 {
225         printf("%+6.2fs ", (time - start_time) / 1000.0);
226 }
227
228 static void
229 print_device_notify(struct libinput_event *ev)
230 {
231         struct libinput_device *dev = libinput_event_get_device(ev);
232         struct libinput_seat *seat = libinput_device_get_seat(dev);
233
234         printf("%s      %s\n",
235                libinput_seat_get_physical_name(seat),
236                libinput_seat_get_logical_name(seat));
237 }
238
239 static void
240 print_key_event(struct libinput_event *ev)
241 {
242         struct libinput_event_keyboard *k = libinput_event_get_keyboard_event(ev);
243         enum libinput_keyboard_key_state state;
244
245         print_event_time(libinput_event_keyboard_get_time(k));
246         state = libinput_event_keyboard_get_key_state(k);
247         printf("%d %s\n",
248                libinput_event_keyboard_get_key(k),
249                state == LIBINPUT_KEYBOARD_KEY_STATE_PRESSED ? "pressed" : "released");
250 }
251
252 static void
253 print_motion_event(struct libinput_event *ev)
254 {
255         struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
256         li_fixed_t x =  libinput_event_pointer_get_dx(p),
257                    y = libinput_event_pointer_get_dy(p);
258
259         print_event_time(libinput_event_pointer_get_time(p));
260
261         printf("%6.2f/%6.2f\n",
262                li_fixed_to_double(x),
263                li_fixed_to_double(y));
264 }
265
266 static void
267 print_absmotion_event(struct libinput_event *ev)
268 {
269         struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
270         li_fixed_t x = libinput_event_pointer_get_absolute_x_transformed(
271                 p, screen_width);
272         li_fixed_t y = libinput_event_pointer_get_absolute_y_transformed(
273                 p, screen_height);
274
275         print_event_time(libinput_event_pointer_get_time(p));
276         printf("%6.2f/%6.2f\n",
277                li_fixed_to_double(x),
278                li_fixed_to_double(y));
279 }
280
281 static void
282 print_button_event(struct libinput_event *ev)
283 {
284         struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
285         enum libinput_pointer_button_state state;
286
287         print_event_time(libinput_event_pointer_get_time(p));
288
289         state = libinput_event_pointer_get_button_state(p);
290         printf("%3d %s, seat count: %u\n",
291                libinput_event_pointer_get_button(p),
292                state == LIBINPUT_POINTER_BUTTON_STATE_PRESSED ? "pressed" : "released",
293                libinput_event_pointer_get_seat_button_count(p));
294 }
295
296 static void
297 print_axis_event(struct libinput_event *ev)
298 {
299         struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
300         enum libinput_pointer_axis axis = libinput_event_pointer_get_axis(p);
301         const char *ax;
302         li_fixed_t val;
303
304         switch (axis) {
305         case LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL:
306                 ax = "vscroll";
307                 break;
308         case LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL:
309                 ax = "hscroll";
310                 break;
311         default:
312                 abort();
313         }
314
315         print_event_time(libinput_event_pointer_get_time(p));
316         val = libinput_event_pointer_get_axis_value(p);
317         printf("%s %.2f\n",
318                ax, li_fixed_to_double(val));
319 }
320
321 static void
322 print_touch_event_without_coords(struct libinput_event *ev)
323 {
324         struct libinput_event_touch *t = libinput_event_get_touch_event(ev);
325
326         print_event_time(libinput_event_touch_get_time(t));
327         printf("\n");
328 }
329
330 static void
331 print_touch_event_with_coords(struct libinput_event *ev)
332 {
333         struct libinput_event_touch *t = libinput_event_get_touch_event(ev);
334         li_fixed_t x = libinput_event_touch_get_x_transformed(t, screen_width),
335                    y = libinput_event_touch_get_y_transformed(t, screen_height);
336
337         print_event_time(libinput_event_touch_get_time(t));
338
339         printf("%d (%d) %5.2f/%5.2f\n",
340                libinput_event_touch_get_slot(t),
341                libinput_event_touch_get_seat_slot(t),
342                li_fixed_to_double(x),
343                li_fixed_to_double(y));
344 }
345
346 static int
347 handle_and_print_events(struct libinput *li)
348 {
349         int rc = -1;
350         struct libinput_event *ev;
351
352         libinput_dispatch(li);
353         while ((ev = libinput_get_event(li))) {
354                 print_event_header(ev);
355
356                 switch (libinput_event_get_type(ev)) {
357                 case LIBINPUT_EVENT_NONE:
358                         abort();
359                 case LIBINPUT_EVENT_DEVICE_ADDED:
360                 case LIBINPUT_EVENT_DEVICE_REMOVED:
361                         print_device_notify(ev);
362                         break;
363                 case LIBINPUT_EVENT_KEYBOARD_KEY:
364                         print_key_event(ev);
365                         break;
366                 case LIBINPUT_EVENT_POINTER_MOTION:
367                         print_motion_event(ev);
368                         break;
369                 case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
370                         print_absmotion_event(ev);
371                         break;
372                 case LIBINPUT_EVENT_POINTER_BUTTON:
373                         print_button_event(ev);
374                         break;
375                 case LIBINPUT_EVENT_POINTER_AXIS:
376                         print_axis_event(ev);
377                         break;
378                 case LIBINPUT_EVENT_TOUCH_DOWN:
379                         print_touch_event_with_coords(ev);
380                         break;
381                 case LIBINPUT_EVENT_TOUCH_MOTION:
382                         print_touch_event_with_coords(ev);
383                         break;
384                 case LIBINPUT_EVENT_TOUCH_UP:
385                         print_touch_event_without_coords(ev);
386                         break;
387                 case LIBINPUT_EVENT_TOUCH_CANCEL:
388                         print_touch_event_without_coords(ev);
389                         break;
390                 case LIBINPUT_EVENT_TOUCH_FRAME:
391                         print_touch_event_without_coords(ev);
392                         break;
393                 }
394
395                 libinput_event_destroy(ev);
396                 libinput_dispatch(li);
397                 rc = 0;
398         }
399         return rc;
400 }
401
402 void
403 mainloop(struct libinput *li)
404 {
405         struct pollfd fds[2];
406         sigset_t mask;
407
408         fds[0].fd = libinput_get_fd(li);
409         fds[0].events = POLLIN;
410         fds[0].revents = 0;
411
412         sigemptyset(&mask);
413         sigaddset(&mask, SIGINT);
414
415         fds[1].fd = signalfd(-1, &mask, SFD_NONBLOCK);
416         fds[1].events = POLLIN;
417         fds[1].revents = 0;
418
419         if (fds[1].fd == -1 ||
420             sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
421                 fprintf(stderr, "Failed to set up signal handling (%s)\n",
422                                 strerror(errno));
423         }
424
425         /* Handle already-pending device added events */
426         if (handle_and_print_events(li))
427                 fprintf(stderr, "Expected device added events on startup but got none. "
428                                 "Maybe you don't have the right permissions?\n");
429
430         while (poll(fds, 2, -1) > -1) {
431                 if (fds[1].revents)
432                         break;
433
434                 handle_and_print_events(li);
435         }
436
437         close(fds[1].fd);
438 }
439
440 static void
441 log_handler(enum libinput_log_priority priority,
442             void *user_data,
443             const char *format,
444             va_list args)
445 {
446         vprintf(format, args);
447 }
448
449 int
450 main(int argc, char **argv)
451 {
452         struct libinput *li;
453         struct timespec tp;
454
455         if (parse_args(argc, argv))
456                 return 1;
457
458         if (verbose) {
459                 libinput_log_set_handler(log_handler, NULL);
460                 libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_DEBUG);
461         }
462
463         if (mode == MODE_UDEV) {
464                 if (open_udev(&li))
465                         return 1;
466         } else if (mode == MODE_DEVICE) {
467                 if (open_device(&li, device))
468                         return 1;
469         } else
470                 abort();
471
472         clock_gettime(CLOCK_MONOTONIC, &tp);
473         start_time = tp.tv_sec * 1000 + tp.tv_nsec / 1000000;
474
475         mainloop(li);
476
477         if (udev)
478                 udev_unref(udev);
479
480         return 0;
481 }