]> granicus.if.org Git - strace/blob - evdev.c
Update NEWS
[strace] / evdev.c
1 /*
2  * Copyright (c) 2015 Etienne Gemsa <etienne.gemsa@lse.epita.fr>
3  * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "defs.h"
30
31 #ifdef HAVE_LINUX_INPUT_H
32
33 #include DEF_MPERS_TYPE(struct_ff_effect)
34
35 # include <linux/ioctl.h>
36 # include <linux/input.h>
37
38 typedef struct ff_effect struct_ff_effect;
39
40 #endif /* HAVE_LINUX_INPUT_H */
41
42 #include MPERS_DEFS
43
44 #ifdef HAVE_LINUX_INPUT_H
45
46 # include "xlat/evdev_autorepeat.h"
47 # include "xlat/evdev_ff_status.h"
48 # include "xlat/evdev_ff_types.h"
49 # include "xlat/evdev_keycode.h"
50 # include "xlat/evdev_leds.h"
51 # include "xlat/evdev_misc.h"
52 # include "xlat/evdev_mtslots.h"
53 # include "xlat/evdev_prop.h"
54 # include "xlat/evdev_relative_axes.h"
55 # include "xlat/evdev_snd.h"
56 # include "xlat/evdev_switch.h"
57 # include "xlat/evdev_sync.h"
58
59 # ifndef SYN_MAX
60 #  define SYN_MAX 0xf
61 # endif
62
63 static void
64 decode_envelope(void *const data)
65 {
66         const struct ff_envelope *const envelope = data;
67
68         tprintf(", envelope={attack_length=%" PRIu16
69                 ", attack_level=%" PRIu16
70                 ", fade_length=%" PRIu16
71                 ", fade_level=%#x}",
72                 envelope->attack_length,
73                 envelope->attack_level,
74                 envelope->fade_length,
75                 envelope->fade_level);
76 }
77
78 static int
79 ff_effect_ioctl(struct tcb *tcp, long arg)
80 {
81         tprints(", ");
82
83         struct_ff_effect ffe;
84
85         if (umove_or_printaddr(tcp, arg, &ffe))
86                 return 1;
87
88         tprints("{type=");
89         printxval(evdev_ff_types, ffe.type, "FF_???");
90         tprintf(", id=%" PRIu16
91                 ", direction=%" PRIu16 ", ",
92                 ffe.id,
93                 ffe.direction);
94
95         if (abbrev(tcp)) {
96                 tprints("...}");
97                 return 1;
98         }
99
100         tprintf("trigger={button=%" PRIu16
101                 ", interval=%" PRIu16 "}"
102                 ", replay={length=%" PRIu16
103                 ", delay=%" PRIu16 "}",
104                 ffe.trigger.button,
105                 ffe.trigger.interval,
106                 ffe.replay.length,
107                 ffe.replay.delay);
108
109         switch (ffe.type) {
110                 case FF_CONSTANT:
111                         tprintf(", constant={level=%" PRId16,
112                                 ffe.u.constant.level);
113                         decode_envelope(&ffe.u.constant.envelope);
114                         tprints("}");
115                         break;
116                 case FF_RAMP:
117                         tprintf(", ramp={start_level=%" PRId16
118                                 ", end_level=%" PRId16,
119                                 ffe.u.ramp.start_level,
120                                 ffe.u.ramp.end_level);
121                         decode_envelope(&ffe.u.ramp.envelope);
122                         tprints("}");
123                         break;
124                 case FF_PERIODIC:
125                         tprintf(", periodic={waveform=%" PRIu16
126                                 ", period=%" PRIu16
127                                 ", magnitude=%" PRId16
128                                 ", offset=%" PRId16
129                                 ", phase=%" PRIu16,
130                                 ffe.u.periodic.waveform,
131                                 ffe.u.periodic.period,
132                                 ffe.u.periodic.magnitude,
133                                 ffe.u.periodic.offset,
134                                 ffe.u.periodic.phase);
135                         decode_envelope(&ffe.u.periodic.envelope);
136                         tprintf(", custom_len=%u, custom_data=",
137                                 ffe.u.periodic.custom_len);
138                         printaddr((unsigned long) ffe.u.periodic.custom_data);
139                         tprints("}");
140                         break;
141                 case FF_RUMBLE:
142                         tprintf(", rumble={strong_magnitude=%" PRIu16
143                                 ", weak_magnitude=%" PRIu16 "}",
144                                 ffe.u.rumble.strong_magnitude,
145                                 ffe.u.rumble.weak_magnitude);
146                         break;
147                 default:
148                         break;
149         }
150
151         tprints("}");
152
153         return 1;
154 }
155
156 static int
157 abs_ioctl(struct tcb *tcp, long arg)
158 {
159         tprints(", ");
160
161         struct input_absinfo absinfo;
162
163         if (!umove_or_printaddr(tcp, arg, &absinfo)) {
164                 tprintf("{value=%u"
165                         ", minimum=%u, ",
166                         absinfo.value,
167                         absinfo.minimum);
168
169                 if (!abbrev(tcp)) {
170                         tprintf("maximum=%u"
171                                 ", fuzz=%u"
172                                 ", flat=%u",
173                                 absinfo.maximum,
174                                 absinfo.fuzz,
175                                 absinfo.flat);
176 # ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION
177                         tprintf(", resolution=%u",
178                                 absinfo.resolution);
179 # endif
180                 } else {
181                         tprints("...");
182                 }
183
184                 tprints("}");
185         }
186
187         return 1;
188 }
189
190 static int
191 keycode_ioctl(struct tcb *tcp, long arg)
192 {
193         tprints(", ");
194
195         unsigned int keycode[2];
196
197         if (!umove_or_printaddr(tcp, arg, &keycode)) {
198                 tprintf("[%u, ", keycode[0]);
199                 printxval(evdev_keycode, keycode[1], "KEY_???");
200                 tprints("]");
201         }
202
203         return 1;
204 }
205
206 # ifdef EVIOCGKEYCODE_V2
207 static int
208 keycode_V2_ioctl(struct tcb *tcp, long arg)
209 {
210         tprints(", ");
211
212         struct input_keymap_entry ike;
213
214         if (umove_or_printaddr(tcp, arg, &ike))
215                 return 1;
216
217         tprintf("{flags=%" PRIu8
218                 ", len=%" PRIu8 ", ",
219                 ike.flags,
220                 ike.len);
221
222         if (!abbrev(tcp)) {
223                 unsigned int i;
224
225                 tprintf("index=%" PRIu16 ", keycode=", ike.index);
226                 printxval(evdev_keycode, ike.keycode, "KEY_???");
227                 tprints(", scancode=[");
228                 for (i = 0; i < ARRAY_SIZE(ike.scancode); i++) {
229                         if (i > 0)
230                                 tprints(", ");
231                         tprintf("%" PRIx8, ike.scancode[i]);
232                 }
233                 tprints("]");
234         } else {
235                 tprints("...");
236         }
237
238         tprints("}");
239
240         return 1;
241 }
242 # endif /* EVIOCGKEYCODE_V2 */
243
244 static int
245 getid_ioctl(struct tcb *tcp, long arg)
246 {
247         tprints(", ");
248
249         struct input_id id;
250
251         if (!umove_or_printaddr(tcp, arg, &id))
252                 tprintf("{ID_BUS=%" PRIu16
253                         ", ID_VENDOR=%" PRIu16
254                         ", ID_PRODUCT=%" PRIu16
255                         ", ID_VERSION=%" PRIu16 "}",
256                         id.bustype,
257                         id.vendor,
258                         id.product,
259                         id.version);
260
261         return 1;
262 }
263
264 static int
265 decode_bitset(struct tcb *tcp, long arg, const struct xlat decode_nr[],
266               const unsigned int max_nr, const char *dflt)
267 {
268         tprints(", ");
269
270         unsigned int size;
271         if ((unsigned long) tcp->u_rval > max_nr)
272                 size = max_nr;
273         else
274                 size = tcp->u_rval;
275         char decoded_arg[size];
276
277         if (umove_or_printaddr(tcp, arg, &decoded_arg))
278                 return 1;
279
280         tprints("[");
281
282         int bit_displayed = 0;
283         int i = next_set_bit(decoded_arg, 0, size);
284         if (i < 0) {
285                 tprints(" 0 ");
286         } else {
287                 printxval(decode_nr, i, dflt);
288
289                 while ((i = next_set_bit(decoded_arg, i + 1, size)) > 0) {
290                         if (abbrev(tcp) && bit_displayed >= 3) {
291                                 tprints(", ...");
292                                 break;
293                         }
294                         tprints(", ");
295                         printxval(decode_nr, i, dflt);
296                         bit_displayed++;
297                 }
298         }
299
300         tprints("]");
301
302         return 1;
303 }
304
305 # ifdef EVIOCGMTSLOTS
306 static int
307 mtslots_ioctl(struct tcb *tcp, const unsigned int code, long arg)
308 {
309         tprints(", ");
310
311         const size_t size = _IOC_SIZE(code) / sizeof(int);
312         if (!size) {
313                 printaddr(arg);
314                 return 1;
315         }
316
317         int buffer[size];
318
319         if (umove_or_printaddr(tcp, arg, &buffer))
320                 return 1;
321
322         tprints("{code=");
323         printxval(evdev_mtslots, buffer[0], "ABS_MT_???");
324
325         tprints(", values=[");
326
327         unsigned int i;
328         for (i = 1; i < ARRAY_SIZE(buffer); i++)
329                 tprintf("%s%d", i > 1 ? ", " : "", buffer[i]);
330
331         tprints("]}");
332
333         return 1;
334 }
335 # endif /* EVIOCGMTSLOTS */
336
337 # if defined EVIOCGREP || defined EVIOCSREP
338 static int
339 repeat_ioctl(struct tcb *tcp, long arg)
340 {
341         tprints(", ");
342         printpair_int(tcp, arg, "%u");
343         return 1;
344 }
345 # endif /* EVIOCGREP || EVIOCSREP */
346
347 static int
348 bit_ioctl(struct tcb *tcp, const unsigned int ev_nr, const long arg)
349 {
350         switch (ev_nr) {
351                 case EV_SYN:
352                         return decode_bitset(tcp, arg, evdev_sync,
353                                              SYN_MAX, "SYN_???");
354                 case EV_KEY:
355                         return decode_bitset(tcp, arg, evdev_keycode,
356                                              KEY_MAX, "KEY_???");
357                 case EV_REL:
358                         return decode_bitset(tcp, arg, evdev_relative_axes,
359                                              REL_MAX, "REL_???");
360                 case EV_ABS:
361                         return decode_bitset(tcp, arg, evdev_abs,
362                                              ABS_MAX, "ABS_???");
363                 case EV_MSC:
364                         return decode_bitset(tcp, arg, evdev_misc,
365                                              MSC_MAX, "MSC_???");
366 # ifdef EV_SW
367                 case EV_SW:
368                         return decode_bitset(tcp, arg, evdev_switch,
369                                              SW_MAX, "SW_???");
370 # endif
371                 case EV_LED:
372                         return decode_bitset(tcp, arg, evdev_leds,
373                                              LED_MAX, "LED_???");
374                 case EV_SND:
375                         return decode_bitset(tcp, arg, evdev_snd,
376                                              SND_MAX, "SND_???");
377                 case EV_REP:
378                         return decode_bitset(tcp, arg, evdev_autorepeat,
379                                              REP_MAX, "REP_???");
380                 case EV_FF:
381                         return decode_bitset(tcp, arg, evdev_ff_types,
382                                              FF_MAX, "FF_???");
383                 case EV_PWR:
384                         tprints(", ");
385                         printnum_int(tcp, arg, "%d");
386                         return 1;
387                 case EV_FF_STATUS:
388                         return decode_bitset(tcp, arg, evdev_ff_status,
389                                              FF_STATUS_MAX, "FF_STATUS_???");
390                 default:
391                         tprints(", ");
392                         printaddr(arg);
393                         return 1;
394         }
395 }
396
397 static int
398 evdev_read_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
399 {
400         /* fixed-number fixed-length commands */
401         switch (code) {
402                 case EVIOCGVERSION:
403                         tprints(", ");
404                         printnum_int(tcp, arg, "%#x");
405                         return 1;
406                 case EVIOCGEFFECTS:
407                         tprints(", ");
408                         printnum_int(tcp, arg, "%u");
409                         return 1;
410                 case EVIOCGID:
411                         return getid_ioctl(tcp, arg);
412 # ifdef EVIOCGREP
413                 case EVIOCGREP:
414                         return repeat_ioctl(tcp, arg);
415 # endif
416                 case EVIOCGKEYCODE:
417                         return keycode_ioctl(tcp, arg);
418 # ifdef EVIOCGKEYCODE_V2
419                 case EVIOCGKEYCODE_V2:
420                         return keycode_V2_ioctl(tcp, arg);
421 # endif
422         }
423
424         /* fixed-number variable-length commands */
425         switch (_IOC_NR(code)) {
426 # ifdef EVIOCGMTSLOTS
427                 case _IOC_NR(EVIOCGMTSLOTS(0)):
428                         return mtslots_ioctl(tcp, code, arg);
429 # endif
430                 case _IOC_NR(EVIOCGNAME(0)):
431                 case _IOC_NR(EVIOCGPHYS(0)):
432                 case _IOC_NR(EVIOCGUNIQ(0)):
433                         tprints(", ");
434                         if (syserror(tcp))
435                                 printaddr(arg);
436                         else
437                                 printstr(tcp, arg, tcp->u_rval);
438                         return 1;
439 # ifdef EVIOCGPROP
440                 case _IOC_NR(EVIOCGPROP(0)):
441                         return decode_bitset(tcp, arg, evdev_prop,
442                                              INPUT_PROP_MAX, "PROP_???");
443 # endif
444                 case _IOC_NR(EVIOCGSND(0)):
445                         return decode_bitset(tcp, arg, evdev_snd,
446                                              SND_MAX, "SND_???");
447 # ifdef EVIOCGSW
448                 case _IOC_NR(EVIOCGSW(0)):
449                         return decode_bitset(tcp, arg, evdev_switch,
450                                              SW_MAX, "SW_???");
451 # endif
452                 case _IOC_NR(EVIOCGKEY(0)):
453                         return decode_bitset(tcp, arg, evdev_keycode,
454                                              KEY_MAX, "KEY_???");
455                 case _IOC_NR(EVIOCGLED(0)):
456                         return decode_bitset(tcp, arg, evdev_leds,
457                                              LED_MAX, "LED_???");
458         }
459
460         /* multi-number fixed-length commands */
461         if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0)))
462                 return abs_ioctl(tcp, arg);
463
464         /* multi-number variable-length commands */
465         if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
466                 return bit_ioctl(tcp, _IOC_NR(code) & EV_MAX, arg);
467
468         return 0;
469 }
470
471 static int
472 evdev_write_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
473 {
474         /* fixed-number fixed-length commands */
475         switch (code) {
476 # ifdef EVIOCSREP
477                 case EVIOCSREP:
478                         return repeat_ioctl(tcp, arg);
479 # endif
480                 case EVIOCSKEYCODE:
481                         return keycode_ioctl(tcp, arg);
482 # ifdef EVIOCSKEYCODE_V2
483                 case EVIOCSKEYCODE_V2:
484                         return keycode_V2_ioctl(tcp, arg);
485 # endif
486                 case EVIOCSFF:
487                         return ff_effect_ioctl(tcp, arg);
488                 case EVIOCRMFF:
489                         tprintf(", %d", (int) arg);
490                         return 1;
491                 case EVIOCGRAB:
492 # ifdef EVIOCREVOKE
493                 case EVIOCREVOKE:
494 # endif
495                         tprintf(", %lu", arg);
496                         return 1;
497 # ifdef EVIOCSCLOCKID
498                 case EVIOCSCLOCKID:
499                         tprints(", ");
500                         printnum_int(tcp, arg, "%u");
501                         return 1;
502 # endif
503         }
504
505         /* multi-number fixed-length commands */
506         if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0)))
507                 return abs_ioctl(tcp, arg);
508
509         return 0;
510 }
511
512 MPERS_PRINTER_DECL(int, evdev_ioctl, struct tcb *tcp,
513                    const unsigned int code, const long arg)
514 {
515         switch(_IOC_DIR(code)) {
516                 case _IOC_READ:
517                         if (entering(tcp))
518                                 return 0;
519                         return evdev_read_ioctl(tcp, code, arg);
520                 case _IOC_WRITE:
521                         return evdev_write_ioctl(tcp, code, arg) | RVAL_DECODED;
522                 default:
523                         return RVAL_DECODED;
524         }
525 }
526
527 #endif /* HAVE_LINUX_INPUT_H */