static void override_abs(int fd, const char *devnode, unsigned evcode, const char *value) { struct input_absinfo absinfo; int rc; char *next; rc = ioctl(fd, EVIOCGABS(evcode), &absinfo); if (rc < 0) { log_error_errno(errno, "Unable to EVIOCGABS device \"%s\"", devnode); return; } next = parse_token(value, &absinfo.minimum); next = parse_token(next, &absinfo.maximum); next = parse_token(next, &absinfo.resolution); next = parse_token(next, &absinfo.fuzz); next = parse_token(next, &absinfo.flat); if (!next) { log_error("Unable to parse EV_ABS override '%s' for '%s'", value, devnode); return; } log_debug("keyboard: %x overridden with %"PRIi32"/%"PRIi32"/%"PRIi32"/%"PRIi32"/%"PRIi32" for \"%s\"", evcode, absinfo.minimum, absinfo.maximum, absinfo.resolution, absinfo.fuzz, absinfo.flat, devnode); rc = ioctl(fd, EVIOCSABS(evcode), &absinfo); if (rc < 0) log_error_errno(errno, "Unable to EVIOCSABS device \"%s\"", devnode); }
static int evdev_write_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg) { /* fixed-number fixed-length commands */ switch (code) { # ifdef EVIOCSREP case EVIOCSREP: return repeat_ioctl(tcp, arg); # endif case EVIOCSKEYCODE: return keycode_ioctl(tcp, arg); # ifdef EVIOCSKEYCODE_V2 case EVIOCSKEYCODE_V2: return keycode_V2_ioctl(tcp, arg); # endif case EVIOCSFF: return ff_effect_ioctl(tcp, arg); case EVIOCRMFF: tprintf(", %d", (int) arg); return 1; case EVIOCGRAB: # ifdef EVIOCREVOKE case EVIOCREVOKE: # endif tprintf(", %" PRI_klu, arg); return 1; # ifdef EVIOCSCLOCKID case EVIOCSCLOCKID: tprints(", "); printnum_int(tcp, arg, "%u"); return 1; # endif } /* multi-number fixed-length commands */ if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) return abs_ioctl(tcp, arg); return 0; }
int main(void) { TEST_NULL_ARG(EVIOCGVERSION); TEST_NULL_ARG(EVIOCGEFFECTS); TEST_NULL_ARG(EVIOCGID); TEST_NULL_ARG(EVIOCGKEYCODE); TEST_NULL_ARG(EVIOCSKEYCODE); TEST_NULL_ARG(EVIOCSFF); # ifdef EVIOCGKEYCODE_V2 TEST_NULL_ARG(EVIOCGKEYCODE_V2); # endif # ifdef EVIOCSKEYCODE_V2 TEST_NULL_ARG(EVIOCSKEYCODE_V2); # endif # ifdef EVIOCGREP TEST_NULL_ARG(EVIOCGREP); # endif # ifdef EVIOCSREP TEST_NULL_ARG(EVIOCSREP); # endif # ifdef EVIOCSCLOCKID TEST_NULL_ARG(EVIOCSCLOCKID); # endif TEST_NULL_ARG(EVIOCGNAME(0)); TEST_NULL_ARG(EVIOCGPHYS(0)); TEST_NULL_ARG(EVIOCGUNIQ(0)); TEST_NULL_ARG(EVIOCGKEY(0)); TEST_NULL_ARG(EVIOCGLED(0)); # ifdef EVIOCGMTSLOTS TEST_NULL_ARG(EVIOCGMTSLOTS(0)); # endif # ifdef EVIOCGPROP TEST_NULL_ARG(EVIOCGPROP(0)); # endif TEST_NULL_ARG(EVIOCGSND(0)); # ifdef EVIOCGSW TEST_NULL_ARG(EVIOCGSW(0)); # endif TEST_NULL_ARG(EVIOCGABS(ABS_X)); TEST_NULL_ARG(EVIOCSABS(ABS_X)); TEST_NULL_ARG(EVIOCGBIT(EV_SYN, 0)); TEST_NULL_ARG(EVIOCGBIT(EV_KEY, 1)); TEST_NULL_ARG(EVIOCGBIT(EV_REL, 2)); TEST_NULL_ARG(EVIOCGBIT(EV_ABS, 3)); TEST_NULL_ARG(EVIOCGBIT(EV_MSC, 4)); # ifdef EV_SW TEST_NULL_ARG(EVIOCGBIT(EV_SW, 5)); # endif TEST_NULL_ARG(EVIOCGBIT(EV_LED, 6)); TEST_NULL_ARG(EVIOCGBIT(EV_SND, 7)); TEST_NULL_ARG(EVIOCGBIT(EV_REP, 8)); TEST_NULL_ARG(EVIOCGBIT(EV_FF, 9)); TEST_NULL_ARG(EVIOCGBIT(EV_PWR, 10)); TEST_NULL_ARG(EVIOCGBIT(EV_FF_STATUS, 11)); ioctl(-1, EVIOCGBIT(EV_MAX, 42), 0); printf("ioctl(-1, EVIOCGBIT(%#x /* EV_??? */, 42), NULL)" " = -1 EBADF (%m)\n", EV_MAX); ioctl(-1, EVIOCRMFF, lmagic); printf("ioctl(-1, EVIOCRMFF, %d) = -1 EBADF (%m)\n", (int) lmagic); ioctl(-1, EVIOCGRAB, lmagic); printf("ioctl(-1, EVIOCGRAB, %lu) = -1 EBADF (%m)\n", lmagic); # ifdef EVIOCREVOKE ioctl(-1, EVIOCREVOKE, lmagic); printf("ioctl(-1, EVIOCREVOKE, %lu) = -1 EBADF (%m)\n", lmagic); # endif const unsigned int size = get_page_size(); void *const page = tail_alloc(size); fill_memory(page, size); int *const val_int = tail_alloc(sizeof(*val_int)); *val_int = magic; # ifdef EVIOCSCLOCKID ioctl(-1, EVIOCSCLOCKID, val_int); printf("ioctl(-1, EVIOCSCLOCKID, [%u]) = -1 EBADF (%m)\n", *val_int); # endif int *pair_int = tail_alloc(sizeof(*pair_int) * 2); pair_int[0] = 0xdeadbeef; pair_int[1] = 0xbadc0ded; # ifdef EVIOSGREP ioctl(-1, EVIOCSREP, pair_int); printf("ioctl(-1, EVIOCSREP, [%u, %u]) = -1 EBADF (%m)\n", pair_int[0], pair_int[1]); # endif pair_int[1] = 1; ioctl(-1, EVIOCSKEYCODE, pair_int); printf("ioctl(-1, EVIOCSKEYCODE, [%u, %s]) = -1 EBADF (%m)\n", pair_int[0], "KEY_ESC"); # ifdef EVIOCSKEYCODE_V2 struct input_keymap_entry *const ike = tail_alloc(sizeof(*ike)); fill_memory(ike, sizeof(*ike)); ike->keycode = 2; ioctl(-1, EVIOCSKEYCODE_V2, ike); printf("ioctl(-1, EVIOCSKEYCODE_V2, {flags=%" PRIu8 ", len=%" PRIu8 ", ", ike->flags, ike->len); # if VERBOSE printf("index=%" PRIu16 ", keycode=%s, scancode=[", ike->index, "KEY_1"); unsigned int i; for (i = 0; i < ARRAY_SIZE(ike->scancode); ++i) { if (i > 0) printf(", "); printf("%" PRIx8, ike->scancode[i]); } printf("]"); # else printf("..."); # endif errno = EBADF; printf("}) = -1 EBADF (%m)\n"); # endif struct ff_effect *const ffe = tail_alloc(sizeof(*ffe)); fill_memory(ffe, sizeof(*ffe)); ffe->type = FF_CONSTANT; ioctl(-1, EVIOCSFF, ffe); print_ffe_common(ffe, "FF_CONSTANT"); # if VERBOSE printf(", constant={level=%hd", ffe->u.constant.level); print_envelope(&ffe->u.constant.envelope); printf("}"); # else printf("..."); # endif errno = EBADF; printf("}) = -1 EBADF (%m)\n"); # if VERBOSE ffe->type = FF_RAMP; ioctl(-1, EVIOCSFF, ffe); print_ffe_common(ffe, "FF_RAMP"); printf(", ramp={start_level=%hd, end_level=%hd", ffe->u.ramp.start_level, ffe->u.ramp.end_level); print_envelope(&ffe->u.ramp.envelope); errno = EBADF; printf("}}) = -1 EBADF (%m)\n"); ffe->type = FF_PERIODIC; ioctl(-1, EVIOCSFF, ffe); print_ffe_common(ffe, "FF_PERIODIC"); printf(", periodic={waveform=%hu, period=%hu, magnitude=%hd" ", offset=%hd, phase=%hu", ffe->u.periodic.waveform, ffe->u.periodic.period, ffe->u.periodic.magnitude, ffe->u.periodic.offset, ffe->u.periodic.phase); print_envelope(&ffe->u.periodic.envelope); printf(", custom_len=%u, custom_data=%p}", ffe->u.periodic.custom_len, ffe->u.periodic.custom_data); errno = EBADF; printf("}) = -1 EBADF (%m)\n"); ffe->type = FF_RUMBLE; ioctl(-1, EVIOCSFF, ffe); print_ffe_common(ffe, "FF_RUMBLE"); printf(", rumble={strong_magnitude=%hu, weak_magnitude=%hu}", ffe->u.rumble.strong_magnitude, ffe->u.rumble.weak_magnitude); errno = EBADF; printf("}) = -1 EBADF (%m)\n"); ffe->type = 0xff; ioctl(-1, EVIOCSFF, ffe); print_ffe_common(ffe, "0xff /* FF_??? */"); errno = EBADF; printf("}) = -1 EBADF (%m)\n"); # endif ioctl(-1, _IOC(_IOC_READ, 0x45, 0x1, 0xff), lmagic); printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n", "_IOC(_IOC_READ, 0x45, 0x1, 0xff)", lmagic); ioctl(-1, _IOC(_IOC_WRITE, 0x45, 0x1, 0xff), lmagic); printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n", "_IOC(_IOC_WRITE, 0x45, 0x1, 0xff)", lmagic); ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE, 0x45, 0xfe, 0xff), lmagic); printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n", "_IOC(_IOC_READ|_IOC_WRITE, 0x45, 0xfe, 0xff)", lmagic); ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE, 0x45, 0, 0), lmagic); printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n", "_IOC(_IOC_READ|_IOC_WRITE, 0x45, 0, 0)", lmagic); puts("+++ exited with 0 +++"); return 0; }
static void input_sanitise(const struct ioctl_group *grp, int childno) { unsigned int u, r; pick_random_ioctl(grp, childno); switch (shm->syscall[childno].a2) { case EVIOCGNAME(0): u = rand(); shm->syscall[childno].a2 = EVIOCGNAME(u); break; case EVIOCGPHYS(0): u = rand(); shm->syscall[childno].a2 = EVIOCGPHYS(u); break; case EVIOCGUNIQ(0): u = rand(); shm->syscall[childno].a2 = EVIOCGUNIQ(u); break; #ifdef EVIOCGPROP case EVIOCGPROP(0): u = rand(); shm->syscall[childno].a2 = EVIOCGPROP(u); break; #endif #ifdef EVIOCGMTSLOTS case EVIOCGMTSLOTS(0): u = rand(); shm->syscall[childno].a2 = EVIOCGMTSLOTS(u); break; #endif case EVIOCGKEY(0): u = rand(); shm->syscall[childno].a2 = EVIOCGKEY(u); break; case EVIOCGLED(0): u = rand(); shm->syscall[childno].a2 = EVIOCGLED(u); break; case EVIOCGSND(0): u = rand(); shm->syscall[childno].a2 = EVIOCGSND(u); break; case EVIOCGSW(0): u = rand(); shm->syscall[childno].a2 = EVIOCGSW(u); break; case EVIOCGBIT(0,0): u = rand(); r = rand(); if (u % 10) u %= EV_CNT; if (r % 10) r /= 4; shm->syscall[childno].a2 = EVIOCGBIT(u, r); break; case EVIOCGABS(0): u = rand(); if (u % 10) u %= ABS_CNT; shm->syscall[childno].a2 = EVIOCGABS(u); break; case EVIOCSABS(0): u = rand(); if (u % 10) u %= ABS_CNT; shm->syscall[childno].a2 = EVIOCSABS(u); break; default: break; } }
IOCTL(EVIOCGNAME(0)), IOCTL(EVIOCGPHYS(0)), IOCTL(EVIOCGUNIQ(0)), #ifdef EVIOCGPROP IOCTL(EVIOCGPROP(0)), #endif #ifdef EVIOCGMTSLOTS IOCTL(EVIOCGMTSLOTS(0)), #endif IOCTL(EVIOCGKEY(0)), IOCTL(EVIOCGLED(0)), IOCTL(EVIOCGSND(0)), IOCTL(EVIOCGSW(0)), IOCTL(EVIOCGBIT(0,0)), IOCTL(EVIOCGABS(0)), IOCTL(EVIOCSABS(0)), IOCTL(EVIOCSFF), IOCTL(EVIOCRMFF), IOCTL(EVIOCGEFFECTS), IOCTL(EVIOCGRAB), #ifdef EVIOCSCLOCKID IOCTL(EVIOCSCLOCKID), #endif }; static const char *const input_devs[] = { "input", }; static void input_sanitise(const struct ioctl_group *grp, int childno) {
static void do_calibration_da9052(int do_calib) { int i, x, y; int dx[3], dy[3]; int tx[3], ty[3]; int delta, delta_x[3], delta_y[3]; struct input_absinfo absX, absY; if (do_calib) { /* calculate the expected point */ x = info.xres / 4; y = info.yres / 4; dx[0] = x; dy[0] = info.yres / 2; dx[1] = info.xres / 2; dy[1] = y; dx[2] = info.xres - x; dy[2] = info.yres - y; for (i = 0; i < 3; i ++) { draw_cross(dx[i], dy[i], 0); get_input(&tx[i], &ty[i]); log_write("Received x,y -> Expected x,y\n"); log_write("%d,%d -> %d,%d\n", tx[i], ty[i], dx[i], dy[i]); draw_cross(dx[i], dy[i], 1); } /* check ok, calulate the result */ delta = (tx[0] - tx[2]) * (ty[1] - ty[2]) - (tx[1] - tx[2]) * (ty[0] - ty[2]); delta_x[0] = (dx[0] - dx[2]) * (ty[1] - ty[2]) - (dx[1] - dx[2]) * (ty[0] - ty[2]); delta_x[1] = (tx[0] - tx[2]) * (dx[1] - dx[2]) - (tx[1] - tx[2]) * (dx[0] - dx[2]); delta_x[2] = dx[0] * (tx[1] * ty[2] - tx[2] * ty[1]) - dx[1] * (tx[0] * ty[2] - tx[2] * ty[0]) + dx[2] * (tx[0] * ty[1] - tx[1] * ty[0]); delta_y[0] = (dy[0] - dy[2]) * (ty[1] - ty[2]) - (dy[1] - dy[2]) * (ty[0] - ty[2]); delta_y[1] = (tx[0] - tx[2]) * (dy[1] - dy[2]) - (tx[1] - tx[2]) * (dy[0] - dy[2]); delta_y[2] = dy[0] * (tx[1] * ty[2] - tx[2] * ty[1]) - dy[1] * (tx[0] * ty[2] - tx[2] * ty[0]) + dy[2] * (tx[0] * ty[1] - tx[1] * ty[0]); cal_val[0] = delta_x[0]; cal_val[1] = delta_x[1]; cal_val[2] = delta_x[2]; cal_val[3] = delta_y[0]; cal_val[4] = delta_y[1]; cal_val[5] = delta_y[2]; cal_val[6] = delta; save_conf(cal_val); write_conf(cal_val); } /* Android input framework expects values based on the absmax. Now that the touchscreen is calibrated set the input maximum according to screen resolution, not the touch sensor resolution */ if (ioctl(ts_fd, EVIOCGABS(ABS_X), &absX) == -1) { log_write("EVIOCGABS( failed\n"); } else { log_write("Modifying x.max:%i -> %i\n", absX.maximum, info.xres); absX.maximum = info.xres; if (ioctl(ts_fd, EVIOCSABS(ABS_X), &absX) == -1) log_write("EVIOCSABS( failed\n"); } if (ioctl(ts_fd, EVIOCGABS(ABS_Y), &absY) == -1) { log_write("EVIOCGABS( failed\n"); } else { log_write("Modifying y.max:%i -> %i\n", absY.maximum, info.yres); absY.maximum = info.yres; if (ioctl(ts_fd, EVIOCSABS(ABS_Y), &absY) == -1) log_write("EVIOCSABS( failed\n"); } }