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
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
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
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
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
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
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 %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 (profile == LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM) ? "*" : "",
214 (profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM) ? "custom" : "");
215
216 return str;
217 }
218
219 static const char *
dwt_default(struct libinput_device *device)220 dwt_default(struct libinput_device *device)
221 {
222 if (!libinput_device_config_dwt_is_available(device))
223 return "n/a";
224
225 if (libinput_device_config_dwt_get_default_enabled(device))
226 return "enabled";
227
228 return "disabled";
229 }
230
231 static const char *
dwtp_default(struct libinput_device *device)232 dwtp_default(struct libinput_device *device)
233 {
234 if (!libinput_device_config_dwtp_is_available(device))
235 return "n/a";
236
237 if (libinput_device_config_dwtp_get_default_enabled(device))
238 return "enabled";
239
240 return "disabled";
241 }
242
243 static char *
rotation_default(struct libinput_device *device)244 rotation_default(struct libinput_device *device)
245 {
246 char *str;
247 double angle;
248
249 if (!libinput_device_config_rotation_is_available(device)) {
250 xasprintf(&str, "n/a");
251 return str;
252 }
253
254 angle = libinput_device_config_rotation_get_angle(device);
255 xasprintf(&str, "%.1f", angle);
256 return str;
257 }
258
259 static void
print_pad_info(struct libinput_device *device)260 print_pad_info(struct libinput_device *device)
261 {
262 int nbuttons, nrings, nstrips, ngroups, nmodes;
263 struct libinput_tablet_pad_mode_group *group;
264
265 nbuttons = libinput_device_tablet_pad_get_num_buttons(device);
266 nrings = libinput_device_tablet_pad_get_num_rings(device);
267 nstrips = libinput_device_tablet_pad_get_num_strips(device);
268 ngroups = libinput_device_tablet_pad_get_num_mode_groups(device);
269
270 group = libinput_device_tablet_pad_get_mode_group(device, 0);
271 nmodes = libinput_tablet_pad_mode_group_get_num_modes(group);
272
273 printf("Pad:\n");
274 printf(" Rings: %d\n", nrings);
275 printf(" Strips: %d\n", nstrips);
276 printf(" Buttons: %d\n", nbuttons);
277 printf(" Mode groups: %d (%d modes)\n", ngroups, nmodes);
278
279 }
280
281 static void
print_device_notify(struct libinput_event *ev)282 print_device_notify(struct libinput_event *ev)
283 {
284 struct libinput_device *dev = libinput_event_get_device(ev);
285 struct libinput_seat *seat = libinput_device_get_seat(dev);
286 struct libinput_device_group *group;
287 struct udev_device *udev_device;
288 double w, h;
289 static int next_group_id = 0;
290 intptr_t group_id;
291 const char *devnode;
292 char *str;
293
294 group = libinput_device_get_device_group(dev);
295 group_id = (intptr_t)libinput_device_group_get_user_data(group);
296 if (!group_id) {
297 group_id = ++next_group_id;
298 libinput_device_group_set_user_data(group, (void*)group_id);
299 }
300
301 udev_device = libinput_device_get_udev_device(dev);
302 devnode = udev_device_get_devnode(udev_device);
303
304 printf("Device: %s\n"
305 "Kernel: %s\n"
306 "Group: %d\n"
307 "Seat: %s, %s\n",
308 libinput_device_get_name(dev),
309 devnode,
310 (int)group_id,
311 libinput_seat_get_physical_name(seat),
312 libinput_seat_get_logical_name(seat));
313
314 udev_device_unref(udev_device);
315
316 if (libinput_device_get_size(dev, &w, &h) == 0)
317 printf("Size: %.fx%.fmm\n", w, h);
318 printf("Capabilities: ");
319 if (libinput_device_has_capability(dev,
320 LIBINPUT_DEVICE_CAP_KEYBOARD))
321 printf("keyboard ");
322 if (libinput_device_has_capability(dev,
323 LIBINPUT_DEVICE_CAP_POINTER))
324 printf("pointer ");
325 if (libinput_device_has_capability(dev,
326 LIBINPUT_DEVICE_CAP_TOUCH))
327 printf("touch ");
328 if (libinput_device_has_capability(dev,
329 LIBINPUT_DEVICE_CAP_TABLET_TOOL))
330 printf("tablet ");
331 if (libinput_device_has_capability(dev,
332 LIBINPUT_DEVICE_CAP_TABLET_PAD))
333 printf("tablet-pad");
334 if (libinput_device_has_capability(dev,
335 LIBINPUT_DEVICE_CAP_GESTURE))
336 printf("gesture");
337 if (libinput_device_has_capability(dev,
338 LIBINPUT_DEVICE_CAP_SWITCH))
339 printf("switch");
340 printf("\n");
341
342 printf("Tap-to-click: %s\n", tap_default(dev));
343 printf("Tap-and-drag: %s\n", drag_default(dev));
344 printf("Tap drag lock: %s\n", draglock_default(dev));
345 printf("Left-handed: %s\n", left_handed_default(dev));
346 printf("Nat.scrolling: %s\n", nat_scroll_default(dev));
347 printf("Middle emulation: %s\n", middle_emulation_default(dev));
348 str = calibration_default(dev);
349 printf("Calibration: %s\n", str);
350 free(str);
351
352 str = scroll_defaults(dev);
353 printf("Scroll methods: %s\n", str);
354 free(str);
355
356 str = click_defaults(dev);
357 printf("Click methods: %s\n", str);
358 free(str);
359
360 printf("Disable-w-typing: %s\n", dwt_default(dev));
361 printf("Disable-w-trackpointing: %s\n", dwtp_default(dev));
362
363 str = accel_profiles(dev);
364 printf("Accel profiles: %s\n", str);
365 free(str);
366
367 str = rotation_default(dev);
368 printf("Rotation: %s\n", str);
369 free(str);
370
371 if (libinput_device_has_capability(dev,
372 LIBINPUT_DEVICE_CAP_TABLET_PAD))
373 print_pad_info(dev);
374
375 printf("\n");
376 }
377
378 static inline void
usage(void)379 usage(void)
380 {
381 printf("Usage: libinput list-devices [--help|--version]\n");
382 printf("\n"
383 "--help ...... show this help and exit\n"
384 "--version ... show version information and exit\n"
385 "\n");
386 }
387
388 int
main(int argc, char **argv)389 main(int argc, char **argv)
390 {
391 struct libinput *li;
392 struct libinput_event *ev;
393 bool grab = false;
394 const char *seat[2] = {"seat0", NULL};
395
396 /* This is kept for backwards-compatibility with the old
397 libinput-list-devices */
398 if (argc > 1) {
399 if (streq(argv[1], "--help")) {
400 usage();
401 return 0;
402 }
403
404 if (streq(argv[1], "--version")) {
405 printf("%s\n", LIBINPUT_VERSION);
406 return 0;
407 }
408
409 usage();
410 return EXIT_INVALID_USAGE;
411 }
412
413 li = tools_open_backend(BACKEND_UDEV, seat, false, &grab);
414 if (!li)
415 return 1;
416
417 libinput_dispatch(li);
418 while ((ev = libinput_get_event(li))) {
419
420 if (libinput_event_get_type(ev) == LIBINPUT_EVENT_DEVICE_ADDED)
421 print_device_notify(ev);
422
423 libinput_event_destroy(ev);
424 libinput_dispatch(li);
425 }
426
427 libinput_unref(li);
428
429 return EXIT_SUCCESS;
430 }
431