evdev.c revision 14a810e6d87d03852b45bacf5d4444320d413b69
1/* 2 * Copyright (c) 2015 Etienne Gemsa <etienne.gemsa@lse.epita.fr> 3 * Copyright (c) 2015 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 <linux/ioctl.h> 34# include <linux/input.h> 35# include "xlat/evdev_abs.h" 36# include "xlat/evdev_autorepeat.h" 37# include "xlat/evdev_ff_status.h" 38# include "xlat/evdev_ff_types.h" 39# include "xlat/evdev_keycode.h" 40# include "xlat/evdev_leds.h" 41# include "xlat/evdev_misc.h" 42# include "xlat/evdev_mtslots.h" 43# include "xlat/evdev_prop.h" 44# include "xlat/evdev_relative_axes.h" 45# include "xlat/evdev_snd.h" 46# include "xlat/evdev_switch.h" 47# include "xlat/evdev_sync.h" 48 49# ifndef SYN_MAX 50# define SYN_MAX 0xf 51# endif 52 53static void 54decode_envelope(const struct ff_envelope *envelope) 55{ 56 tprintf(", envelope={attack_length=%" PRIu16 57 ", attack_level=%" PRIu16 58 ", fade_length=%" PRIu16 59 ", fade_level=%#x}", 60 envelope->attack_length, 61 envelope->attack_level, 62 envelope->fade_length, 63 envelope->fade_level); 64} 65 66static int 67ff_effect_ioctl(struct tcb *tcp, long arg) 68{ 69 tprints(", "); 70 71 struct ff_effect ffe; 72 73 if (umove_or_printaddr(tcp, arg, &ffe)) 74 return 1; 75 76 tprints("{type="); 77 printxval(evdev_ff_types, ffe.type, "FF_???"); 78 tprintf(", id=%" PRIu16 79 ", direction=%" PRIu16 ", ", 80 ffe.id, 81 ffe.direction); 82 83 if (abbrev(tcp)) { 84 tprints("...}"); 85 return 1; 86 } 87 88 tprintf("trigger={button=%" PRIu16 89 ", interval=%" PRIu16 "}" 90 ", replay={length=%" PRIu16 91 ", delay=%" PRIu16 "}", 92 ffe.trigger.button, 93 ffe.trigger.interval, 94 ffe.replay.length, 95 ffe.replay.delay); 96 97 switch (ffe.type) { 98 case FF_CONSTANT: 99 tprintf(", constant={level=%" PRId16, 100 ffe.u.constant.level); 101 decode_envelope(&ffe.u.constant.envelope); 102 tprints("}"); 103 break; 104 case FF_RAMP: 105 tprintf(", ramp={start_level=%" PRId16 106 ", end_level=%" PRId16, 107 ffe.u.ramp.start_level, 108 ffe.u.ramp.end_level); 109 decode_envelope(&ffe.u.ramp.envelope); 110 tprints("}"); 111 break; 112 case FF_PERIODIC: 113 tprintf(", periodic={waveform=%" PRIu16 114 ", period=%" PRIu16 115 ", magnitude=%" PRId16 116 ", offset=%" PRId16 117 ", phase=%" PRIu16, 118 ffe.u.periodic.waveform, 119 ffe.u.periodic.period, 120 ffe.u.periodic.magnitude, 121 ffe.u.periodic.offset, 122 ffe.u.periodic.phase); 123 decode_envelope(&ffe.u.periodic.envelope); 124 tprintf(", custom_len=%u" 125 ", custom_data=%#lx}", 126 ffe.u.periodic.custom_len, 127 (unsigned long) ffe.u.periodic.custom_data); 128 break; 129 case FF_RUMBLE: 130 tprintf(", rumble={strong_magnitude=%" PRIu16 131 ", weak_magnitude=%" PRIu16 "}", 132 ffe.u.rumble.strong_magnitude, 133 ffe.u.rumble.weak_magnitude); 134 break; 135 default: 136 break; 137 } 138 139 tprints("}"); 140 141 return 1; 142} 143 144static int 145abs_ioctl(struct tcb *tcp, long arg) 146{ 147 tprints(", "); 148 149 struct input_absinfo absinfo; 150 151 if (!umove_or_printaddr(tcp, arg, &absinfo)) { 152 tprintf("{value=%u" 153 ", minimum=%u, ", 154 absinfo.value, 155 absinfo.minimum); 156 157 if (!abbrev(tcp)) { 158 tprintf("maximum=%u" 159 ", fuzz=%u" 160 ", flat=%u", 161 absinfo.maximum, 162 absinfo.fuzz, 163 absinfo.flat); 164# ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION 165 tprintf(", resolution=%u", 166 absinfo.resolution); 167# endif 168 } else { 169 tprints("..."); 170 } 171 172 tprints("}"); 173 } 174 175 return 1; 176} 177 178static int 179keycode_ioctl(struct tcb *tcp, long arg) 180{ 181 tprints(", "); 182 183 unsigned int keycode[2]; 184 185 if (!umove_or_printaddr(tcp, arg, &keycode)) { 186 tprintf("[%u, ", keycode[0]); 187 printxval(evdev_keycode, keycode[1], "KEY_???"); 188 tprints("]"); 189 } 190 191 return 1; 192} 193 194# ifdef EVIOCGKEYCODE_V2 195static int 196keycode_V2_ioctl(struct tcb *tcp, long arg) 197{ 198 tprints(", "); 199 200 struct input_keymap_entry ike; 201 202 if (umove_or_printaddr(tcp, arg, &ike)) 203 return 1; 204 205 tprintf("{flags=%" PRIu8 206 ", len=%" PRIu8 ", ", 207 ike.flags, 208 ike.len); 209 210 if (!abbrev(tcp)) { 211 unsigned int i; 212 213 tprintf("index=%" PRIu16 ", keycode=", ike.index); 214 printxval(evdev_keycode, ike.keycode, "KEY_???"); 215 tprints(", scancode=["); 216 for (i = 0; i < ARRAY_SIZE(ike.scancode); i++) { 217 if (i > 0) 218 tprints(", "); 219 tprintf("%" PRIx8, ike.scancode[i]); 220 } 221 tprints("]"); 222 } else { 223 tprints("..."); 224 } 225 226 tprints("}"); 227 228 return 1; 229} 230# endif /* EVIOCGKEYCODE_V2 */ 231 232static int 233getid_ioctl(struct tcb *tcp, long arg) 234{ 235 tprints(", "); 236 237 struct input_id id; 238 239 if (!umove_or_printaddr(tcp, arg, &id)) 240 tprintf("{ID_BUS=%" PRIu16 241 ", ID_VENDOR=%" PRIu16 242 ", ID_PRODUCT=%" PRIu16 243 ", ID_VERSION=%" PRIu16 "}", 244 id.bustype, 245 id.vendor, 246 id.product, 247 id.version); 248 249 return 1; 250} 251 252static int 253decode_bitset(struct tcb *tcp, long arg, const struct xlat decode_nr[], 254 const unsigned int max_nr, const char *dflt) 255{ 256 tprints(", "); 257 258 unsigned int size; 259 if ((unsigned long) tcp->u_rval > max_nr) 260 size = max_nr; 261 else 262 size = tcp->u_rval; 263 char decoded_arg[size]; 264 265 if (umove_or_printaddr(tcp, arg, &decoded_arg)) 266 return 1; 267 268 tprints("["); 269 270 int bit_displayed = 0; 271 int i = next_set_bit(decoded_arg, 0, size); 272 if (i < 0) { 273 tprints(" 0 "); 274 } else { 275 printxval(decode_nr, i, dflt); 276 277 while ((i = next_set_bit(decoded_arg, i + 1, size)) > 0) { 278 if (abbrev(tcp) && bit_displayed >= 3) { 279 tprints(", ..."); 280 break; 281 } 282 tprints(", "); 283 printxval(decode_nr, i, dflt); 284 bit_displayed++; 285 } 286 } 287 288 tprints("]"); 289 290 return 1; 291} 292 293# ifdef EVIOCGMTSLOTS 294static int 295mtslots_ioctl(struct tcb *tcp, const unsigned int code, long arg) 296{ 297 const size_t size = _IOC_SIZE(code) / sizeof(int32_t); 298 if (!size) 299 return 0; 300 301 int32_t buffer[size]; 302 303 if (!verbose(tcp) || umove(tcp, arg, &buffer) < 0) 304 return 0; 305 306 tprints(", {code="); 307 printxval(evdev_mtslots, buffer[0], "ABS_MT_???"); 308 309 unsigned int i; 310 tprints(", values=["); 311 312 for (i = 1; i < ARRAY_SIZE(buffer); i++) 313 tprintf("%s%d", i > 1 ? ", " : "", buffer[i]); 314 315 tprints("]}"); 316 return 1; 317} 318# endif /* EVIOCGMTSLOTS */ 319 320# if defined EVIOCGREP || defined EVIOCSREP 321static int 322repeat_ioctl(struct tcb *tcp, long arg) 323{ 324 tprints(", "); 325 printpair_int(tcp, arg, "%u"); 326 return 1; 327} 328# endif /* EVIOCGREP || EVIOCSREP */ 329 330static int 331bit_ioctl(struct tcb *tcp, const unsigned int ev_nr, const long arg) 332{ 333 switch (ev_nr) { 334 case EV_SYN: 335 return decode_bitset(tcp, arg, evdev_sync, 336 SYN_MAX, "SYN_???"); 337 case EV_KEY: 338 return decode_bitset(tcp, arg, evdev_keycode, 339 KEY_MAX, "KEY_???"); 340 case EV_REL: 341 return decode_bitset(tcp, arg, evdev_relative_axes, 342 REL_MAX, "REL_???"); 343 case EV_ABS: 344 return decode_bitset(tcp, arg, 345 evdev_abs, ABS_MAX, "ABS_???"); 346 case EV_MSC: 347 return decode_bitset(tcp, arg, 348 evdev_misc, MSC_MAX, "MSC_???"); 349# ifdef EV_SW 350 case EV_SW: 351 return decode_bitset(tcp, arg, 352 evdev_switch, SW_MAX, "SW_???"); 353# endif 354 case EV_LED: 355 return decode_bitset(tcp, arg, 356 evdev_leds, LED_MAX, "LED_???"); 357 case EV_SND: 358 return decode_bitset(tcp, arg, 359 evdev_snd, SND_MAX, "SND_???"); 360 case EV_REP: 361 return decode_bitset(tcp, arg, evdev_autorepeat, 362 REP_MAX, "REP_???"); 363 case EV_FF: 364 return decode_bitset(tcp, arg, evdev_ff_types, 365 FF_MAX, "FF_???"); 366 case EV_PWR: 367 printnum_int(tcp, arg, "%d"); 368 return 1; 369 case EV_FF_STATUS: 370 return decode_bitset(tcp, arg, evdev_ff_status, 371 FF_STATUS_MAX, "FF_STATUS_???"); 372 default: 373 return 0; 374 } 375} 376 377static int 378evdev_read_ioctl(struct tcb *tcp, const unsigned int code, const long arg) 379{ 380 if (syserror(tcp)) 381 return 0; 382 383 /* fixed-number fixed-length commands */ 384 switch (code) { 385 case EVIOCGVERSION: 386 tprints(", "); 387 printnum_int(tcp, arg, "%" PRIx32); 388 return 1; 389 case EVIOCGEFFECTS: 390 tprints(", "); 391 printnum_int(tcp, arg, "%" PRIu32); 392 return 1; 393 case EVIOCGID: 394 return getid_ioctl(tcp, arg); 395# ifdef EVIOCGREP 396 case EVIOCGREP: 397 return repeat_ioctl(tcp, arg);; 398# endif 399 case EVIOCGKEYCODE: 400 return keycode_ioctl(tcp, arg); 401# ifdef EVIOCGKEYCODE_V2 402 case EVIOCGKEYCODE_V2: 403 return keycode_V2_ioctl(tcp, arg); 404# endif 405 } 406 407 /* fixed-number variable-length commands */ 408 switch (_IOC_NR(code)) { 409# ifdef EVIOCGMTSLOTS 410 case _IOC_NR(EVIOCGMTSLOTS(0)): 411 return mtslots_ioctl(tcp, code, arg); 412# endif 413 case _IOC_NR(EVIOCGNAME(0)): 414 case _IOC_NR(EVIOCGPHYS(0)): 415 case _IOC_NR(EVIOCGUNIQ(0)): 416 tprints(", "); 417 printstr(tcp, arg, tcp->u_rval - 1); 418 return 1; 419# ifdef EVIOCGPROP 420 case _IOC_NR(EVIOCGPROP(0)): 421 return decode_bitset(tcp, arg, 422 evdev_prop, INPUT_PROP_MAX, "PROP_???"); 423# endif 424 case _IOC_NR(EVIOCGSND(0)): 425 return decode_bitset(tcp, arg, 426 evdev_snd, SND_MAX, "SND_???"); 427# ifdef EVIOCGSW 428 case _IOC_NR(EVIOCGSW(0)): 429 return decode_bitset(tcp, arg, 430 evdev_switch, SW_MAX, "SW_???"); 431# endif 432 case _IOC_NR(EVIOCGKEY(0)): 433 return decode_bitset(tcp, arg, 434 evdev_keycode, KEY_MAX, "KEY_???"); 435 case _IOC_NR(EVIOCGLED(0)): 436 return decode_bitset(tcp, arg, 437 evdev_leds, LED_MAX, "LED_???"); 438 } 439 440 /* multi-number fixed-length commands */ 441 if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) 442 return abs_ioctl(tcp, arg); 443 444 /* multi-number variable-length commands */ 445 if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) 446 return bit_ioctl(tcp, _IOC_NR(code) & EV_MAX, arg); 447 448 return 0; 449} 450 451static int 452evdev_write_ioctl(struct tcb *tcp, const unsigned int code, const long arg) 453{ 454 /* fixed-number fixed-length commands */ 455 switch (code) { 456# ifdef EVIOCSREP 457 case EVIOCSREP: 458 return repeat_ioctl(tcp, arg); 459# endif 460 case EVIOCSKEYCODE: 461 return keycode_ioctl(tcp, arg); 462# ifdef EVIOCSKEYCODE_V2 463 case EVIOCSKEYCODE_V2: 464 return keycode_V2_ioctl(tcp, arg); 465# endif 466 case EVIOCSFF: 467 return ff_effect_ioctl(tcp, arg); 468 case EVIOCRMFF: 469 tprintf(", %d", (int) arg); 470 return 1; 471 case EVIOCGRAB: 472# ifdef EVIOCREVOKE 473 case EVIOCREVOKE: 474# endif 475 tprintf(", %lu", arg); 476 return 1; 477# ifdef EVIOCSCLOCKID 478 case EVIOCSCLOCKID: 479 tprints(", "); 480 printnum_int(tcp, arg, "%u"); 481 return 1; 482# endif 483 } 484 485 /* multi-number fixed-length commands */ 486 if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) 487 return abs_ioctl(tcp, arg); 488 489 return 0; 490} 491 492int 493evdev_ioctl(struct tcb *tcp, const unsigned int code, long arg) 494{ 495 switch(_IOC_DIR(code)) { 496 case _IOC_READ: 497 if (entering(tcp)) 498 return 0; 499 return evdev_read_ioctl(tcp, code, arg); 500 case _IOC_WRITE: 501 return evdev_write_ioctl(tcp, code, arg) | RVAL_DECODED; 502 default: 503 return RVAL_DECODED; 504 } 505} 506 507#endif /* HAVE_LINUX_INPUT_H */ 508