1 /*
2 * Copyright © 2015 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
26 #include <errno.h>
27 #include <stdbool.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <libudev.h>
32
33 #include <libinput.h>
34 #include <libinput-version.h>
35 #include "util-strings.h"
36
37 #include "shared.h"
38
39 static const char *
tap_default(struct libinput_device * device)40 tap_default(struct libinput_device *device)
41 {
42 if (!libinput_device_config_tap_get_finger_count(device))
43 return "n/a";
44
45 if (libinput_device_config_tap_get_default_enabled(device))
46 return "enabled";
47 else
48 return "disabled";
49 }
50
51 static const char *
drag_default(struct libinput_device * device)52 drag_default(struct libinput_device *device)
53 {
54 if (!libinput_device_config_tap_get_finger_count(device))
55 return "n/a";
56
57 if (libinput_device_config_tap_get_default_drag_enabled(device))
58 return "enabled";
59 else
60 return "disabled";
61 }
62
63 static const char *
draglock_default(struct libinput_device * device)64 draglock_default(struct libinput_device *device)
65 {
66 if (!libinput_device_config_tap_get_finger_count(device))
67 return "n/a";
68
69 if (libinput_device_config_tap_get_default_drag_lock_enabled(device))
70 return "enabled";
71 else
72 return "disabled";
73 }
74
75 static const char*
left_handed_default(struct libinput_device * device)76 left_handed_default(struct libinput_device *device)
77 {
78 if (!libinput_device_config_left_handed_is_available(device))
79 return "n/a";
80
81 if (libinput_device_config_left_handed_get_default(device))
82 return "enabled";
83 else
84 return "disabled";
85 }
86
87 static const char *
nat_scroll_default(struct libinput_device * device)88 nat_scroll_default(struct libinput_device *device)
89 {
90 if (!libinput_device_config_scroll_has_natural_scroll(device))
91 return "n/a";
92
93 if (libinput_device_config_scroll_get_default_natural_scroll_enabled(device))
94 return "enabled";
95 else
96 return "disabled";
97 }
98
99 static const char *
middle_emulation_default(struct libinput_device * device)100 middle_emulation_default(struct libinput_device *device)
101 {
102 if (!libinput_device_config_middle_emulation_is_available(device))
103 return "n/a";
104
105 if (libinput_device_config_middle_emulation_get_default_enabled(device))
106 return "enabled";
107 else
108 return "disabled";
109 }
110
111 static char *
calibration_default(struct libinput_device * device)112 calibration_default(struct libinput_device *device)
113 {
114 char *str;
115 float calibration[6];
116
117 if (!libinput_device_config_calibration_has_matrix(device)) {
118 xasprintf(&str, "n/a");
119 return str;
120 }
121
122 if (libinput_device_config_calibration_get_default_matrix(device,
123 calibration) == 0) {
124 xasprintf(&str, "identity matrix");
125 return str;
126 }
127
128 xasprintf(&str,
129 "%.2f %.2f %.2f %.2f %.2f %.2f",
130 calibration[0],
131 calibration[1],
132 calibration[2],
133 calibration[3],
134 calibration[4],
135 calibration[5]);
136 return str;
137 }
138
139 static char *
scroll_defaults(struct libinput_device * device)140 scroll_defaults(struct libinput_device *device)
141 {
142 uint32_t scroll_methods;
143 char *str;
144 enum libinput_config_scroll_method method;
145
146 scroll_methods = libinput_device_config_scroll_get_methods(device);
147 if (scroll_methods == LIBINPUT_CONFIG_SCROLL_NO_SCROLL) {
148 xasprintf(&str, "none");
149 return str;
150 }
151
152 method = libinput_device_config_scroll_get_default_method(device);
153
154 xasprintf(&str,
155 "%s%s%s%s%s%s",
156 (method == LIBINPUT_CONFIG_SCROLL_2FG) ? "*" : "",
157 (scroll_methods & LIBINPUT_CONFIG_SCROLL_2FG) ? "two-finger " : "",
158 (method == LIBINPUT_CONFIG_SCROLL_EDGE) ? "*" : "",
159 (scroll_methods & LIBINPUT_CONFIG_SCROLL_EDGE) ? "edge " : "",
160 (method == LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) ? "*" : "",
161 (scroll_methods & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) ? "button" : "");
162 return str;
163 }
164
165 static char*
click_defaults(struct libinput_device * device)166 click_defaults(struct libinput_device *device)
167 {
168 uint32_t click_methods;
169 char *str;
170 enum libinput_config_click_method method;
171
172 click_methods = libinput_device_config_click_get_methods(device);
173 if (click_methods == LIBINPUT_CONFIG_CLICK_METHOD_NONE) {
174 xasprintf(&str, "none");
175 return str;
176 }
177
178 method = libinput_device_config_click_get_default_method(device);
179 xasprintf(&str,
180 "%s%s%s%s",
181 (method == LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) ? "*" : "",
182 (click_methods & LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) ? "button-areas " : "",
183 (method == LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) ? "*" : "",
184 (click_methods & LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) ? "clickfinger " : "");
185 return str;
186 }
187
188 static char*
accel_profiles(struct libinput_device * device)189 accel_profiles(struct libinput_device *device)
190 {
191 uint32_t profiles;
192 char *str;
193 enum libinput_config_accel_profile profile;
194
195 if (!libinput_device_config_accel_is_available(device)) {
196 xasprintf(&str, "n/a");
197 return str;
198 }
199
200 profiles = libinput_device_config_accel_get_profiles(device);
201 if (profiles == LIBINPUT_CONFIG_ACCEL_PROFILE_NONE) {
202 xasprintf(&str, "none");
203 return str;
204 }
205
206 profile = libinput_device_config_accel_get_default_profile(device);
207 xasprintf(&str,
208 "%s%s %s%s",
209 (profile == LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT) ? "*" : "",
210 (profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT) ? "flat" : "",
211 (profile == LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE) ? "*" : "",
212 (profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE) ? "adaptive" : "");
213
214 return str;
215 }
216
217 static const char *
dwt_default(struct libinput_device * device)218 dwt_default(struct libinput_device *device)
219 {
220 if (!libinput_device_config_dwt_is_available(device))
221 return "n/a";
222
223 if (libinput_device_config_dwt_get_default_enabled(device))
224 return "enabled";
225 else
226 return "disabled";
227 }
228
229 static char *
rotation_default(struct libinput_device * device)230 rotation_default(struct libinput_device *device)
231 {
232 char *str;
233 double angle;
234
235 if (!libinput_device_config_rotation_is_available(device)) {
236 xasprintf(&str, "n/a");
237 return str;
238 }
239
240 angle = libinput_device_config_rotation_get_angle(device);
241 xasprintf(&str, "%.1f", angle);
242 return str;
243 }
244
245 static void
print_pad_info(struct libinput_device * device)246 print_pad_info(struct libinput_device *device)
247 {
248 int nbuttons, nrings, nstrips, ngroups, nmodes;
249 struct libinput_tablet_pad_mode_group *group;
250
251 nbuttons = libinput_device_tablet_pad_get_num_buttons(device);
252 nrings = libinput_device_tablet_pad_get_num_rings(device);
253 nstrips = libinput_device_tablet_pad_get_num_strips(device);
254 ngroups = libinput_device_tablet_pad_get_num_mode_groups(device);
255
256 group = libinput_device_tablet_pad_get_mode_group(device, 0);
257 nmodes = libinput_tablet_pad_mode_group_get_num_modes(group);
258
259 printf("Pad:\n");
260 printf(" Rings: %d\n", nrings);
261 printf(" Strips: %d\n", nstrips);
262 printf(" Buttons: %d\n", nbuttons);
263 printf(" Mode groups: %d (%d modes)\n", ngroups, nmodes);
264
265 }
266
267 static void
print_device_notify(struct libinput_event * ev)268 print_device_notify(struct libinput_event *ev)
269 {
270 struct libinput_device *dev = libinput_event_get_device(ev);
271 struct libinput_seat *seat = libinput_device_get_seat(dev);
272 struct libinput_device_group *group;
273 struct udev_device *udev_device;
274 double w, h;
275 static int next_group_id = 0;
276 intptr_t group_id;
277 const char *devnode;
278 char *str;
279
280 group = libinput_device_get_device_group(dev);
281 group_id = (intptr_t)libinput_device_group_get_user_data(group);
282 if (!group_id) {
283 group_id = ++next_group_id;
284 libinput_device_group_set_user_data(group, (void*)group_id);
285 }
286
287 udev_device = libinput_device_get_udev_device(dev);
288 devnode = udev_device_get_devnode(udev_device);
289
290 printf("Device: %s\n"
291 "Kernel: %s\n"
292 "Group: %d\n"
293 "Seat: %s, %s\n",
294 libinput_device_get_name(dev),
295 devnode,
296 (int)group_id,
297 libinput_seat_get_physical_name(seat),
298 libinput_seat_get_logical_name(seat));
299
300 udev_device_unref(udev_device);
301
302 if (libinput_device_get_size(dev, &w, &h) == 0)
303 printf("Size: %.fx%.fmm\n", w, h);
304 printf("Capabilities: ");
305 if (libinput_device_has_capability(dev,
306 LIBINPUT_DEVICE_CAP_KEYBOARD))
307 printf("keyboard ");
308 if (libinput_device_has_capability(dev,
309 LIBINPUT_DEVICE_CAP_POINTER))
310 printf("pointer ");
311 if (libinput_device_has_capability(dev,
312 LIBINPUT_DEVICE_CAP_TOUCH))
313 printf("touch ");
314 if (libinput_device_has_capability(dev,
315 LIBINPUT_DEVICE_CAP_TABLET_TOOL))
316 printf("tablet ");
317 if (libinput_device_has_capability(dev,
318 LIBINPUT_DEVICE_CAP_TABLET_PAD))
319 printf("tablet-pad");
320 if (libinput_device_has_capability(dev,
321 LIBINPUT_DEVICE_CAP_GESTURE))
322 printf("gesture");
323 if (libinput_device_has_capability(dev,
324 LIBINPUT_DEVICE_CAP_SWITCH))
325 printf("switch");
326 printf("\n");
327
328 printf("Tap-to-click: %s\n", tap_default(dev));
329 printf("Tap-and-drag: %s\n", drag_default(dev));
330 printf("Tap drag lock: %s\n", draglock_default(dev));
331 printf("Left-handed: %s\n", left_handed_default(dev));
332 printf("Nat.scrolling: %s\n", nat_scroll_default(dev));
333 printf("Middle emulation: %s\n", middle_emulation_default(dev));
334 str = calibration_default(dev);
335 printf("Calibration: %s\n", str);
336 free(str);
337
338 str = scroll_defaults(dev);
339 printf("Scroll methods: %s\n", str);
340 free(str);
341
342 str = click_defaults(dev);
343 printf("Click methods: %s\n", str);
344 free(str);
345
346 printf("Disable-w-typing: %s\n", dwt_default(dev));
347
348 str = accel_profiles(dev);
349 printf("Accel profiles: %s\n", str);
350 free(str);
351
352 str = rotation_default(dev);
353 printf("Rotation: %s\n", str);
354 free(str);
355
356 if (libinput_device_has_capability(dev,
357 LIBINPUT_DEVICE_CAP_TABLET_PAD))
358 print_pad_info(dev);
359
360 printf("\n");
361 }
362
363 static inline void
usage(void)364 usage(void)
365 {
366 printf("Usage: libinput list-devices [--help|--version]\n");
367 printf("\n"
368 "--help ...... show this help and exit\n"
369 "--version ... show version information and exit\n"
370 "\n");
371 }
372
373 int
main(int argc,char ** argv)374 main(int argc, char **argv)
375 {
376 struct libinput *li;
377 struct libinput_event *ev;
378 bool grab = false;
379 const char *seat[2] = {"seat0", NULL};
380
381 /* This is kept for backwards-compatibility with the old
382 libinput-list-devices */
383 if (argc > 1) {
384 if (streq(argv[1], "--help")) {
385 usage();
386 return 0;
387 } else if (streq(argv[1], "--version")) {
388 printf("%s\n", LIBINPUT_VERSION);
389 return 0;
390 } else {
391 usage();
392 return EXIT_INVALID_USAGE;
393 }
394 }
395
396 li = tools_open_backend(BACKEND_UDEV, seat, false, &grab);
397 if (!li)
398 return 1;
399
400 libinput_dispatch(li);
401 while ((ev = libinput_get_event(li))) {
402
403 if (libinput_event_get_type(ev) == LIBINPUT_EVENT_DEVICE_ADDED)
404 print_device_notify(ev);
405
406 libinput_event_destroy(ev);
407 libinput_dispatch(li);
408 }
409
410 libinput_unref(li);
411
412 return EXIT_SUCCESS;
413 }
414