Ejemplo n.º 1
0
static void
SDL_EVDEV_sync_device(SDL_evdevlist_item *item) 
{
#ifdef EVIOCGMTSLOTS
    int i, ret;
    struct input_absinfo abs_info;
    /*
     * struct input_mt_request_layout {
     *     __u32 code;
     *     __s32 values[num_slots];
     * };
     *
     * this is the structure we're trying to emulate
     */
    __u32* mt_req_code;
    __s32* mt_req_values;
    size_t mt_req_size;
    
    /* TODO: sync devices other than touchscreen */
    if (!item->is_touchscreen)
        return;
    
    mt_req_size = sizeof(*mt_req_code) +
        sizeof(*mt_req_values) * item->touchscreen_data->max_slots;
    
    mt_req_code = SDL_calloc(1, mt_req_size);
    if (mt_req_code == NULL) {
        return;
    }
    
    mt_req_values = (__s32*)mt_req_code + 1;
    
    *mt_req_code = ABS_MT_TRACKING_ID;
    ret = ioctl(item->fd, EVIOCGMTSLOTS(mt_req_size), mt_req_code);
    if (ret < 0) {
        SDL_free(mt_req_code);
        return;
    }
    for(i = 0; i < item->touchscreen_data->max_slots; i++) {
        /*
         * This doesn't account for the very edge case of the user removing their
         * finger and replacing it on the screen during the time we're out of sync,
         * which'll mean that we're not going from down -> up or up -> down, we're
         * going from down -> down but with a different tracking id, meaning we'd
         * have to tell SDL of the two events, but since we wait till SYN_REPORT in
         * SDL_EVDEV_Poll to tell SDL, the current structure of this code doesn't
         * allow it. Lets just pray to God it doesn't happen.
         */
        if (item->touchscreen_data->slots[i].tracking_id < 0 &&
            mt_req_values[i] >= 0) {
            item->touchscreen_data->slots[i].tracking_id = mt_req_values[i];
            item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_DOWN;
        } else if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
            mt_req_values[i] < 0) {
            item->touchscreen_data->slots[i].tracking_id = -1;
            item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_UP;
        }
    }
    
    *mt_req_code = ABS_MT_POSITION_X;
    ret = ioctl(item->fd, EVIOCGMTSLOTS(mt_req_size), mt_req_code);
    if (ret < 0) {
        SDL_free(mt_req_code);
        return;
    }
    for(i = 0; i < item->touchscreen_data->max_slots; i++) {
        if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
            item->touchscreen_data->slots[i].x != mt_req_values[i]) {
            item->touchscreen_data->slots[i].x = mt_req_values[i];
            if (item->touchscreen_data->slots[i].delta ==
                EVDEV_TOUCH_SLOTDELTA_NONE) {
                item->touchscreen_data->slots[i].delta =
                    EVDEV_TOUCH_SLOTDELTA_MOVE;
            }
        }
    }
    
    *mt_req_code = ABS_MT_POSITION_Y;
    ret = ioctl(item->fd, EVIOCGMTSLOTS(mt_req_size), mt_req_code);
    if (ret < 0) {
        SDL_free(mt_req_code);
        return;
    }
    for(i = 0; i < item->touchscreen_data->max_slots; i++) {
        if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
            item->touchscreen_data->slots[i].y != mt_req_values[i]) {
            item->touchscreen_data->slots[i].y = mt_req_values[i];
            if (item->touchscreen_data->slots[i].delta ==
                EVDEV_TOUCH_SLOTDELTA_NONE) {
                item->touchscreen_data->slots[i].delta =
                    EVDEV_TOUCH_SLOTDELTA_MOVE;
            }
        }
    }
    
    ret = ioctl(item->fd, EVIOCGABS(ABS_MT_SLOT), &abs_info);
    if (ret < 0) {
        SDL_free(mt_req_code);
        return;
    }
    item->touchscreen_data->current_slot = abs_info.value;
    
    SDL_free(mt_req_code);

#endif /* EVIOCGMTSLOTS */
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
	}
}
Ejemplo n.º 4
0
	IOCTL(EVIOCGKEYCODE),
#ifdef EVIOCGKEYCODE_V2
	IOCTL(EVIOCGKEYCODE_V2),
#endif
	IOCTL(EVIOCSKEYCODE),
#ifdef EVIOCSKEYCODE_V2
	IOCTL(EVIOCSKEYCODE_V2),
#endif
	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
Ejemplo n.º 5
0
    I_SIMPLE_STRUCT_IN(EVIOCGEFFECTS, 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGABS(0), "EVIOCGABS", ABS_MAX, ioctl_insertion_parent_stateless),
    /* we define these with len==32, but they apply to any len */
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGBIT(0, 32), "EVIOCGBIT", EV_MAX, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGNAME(32), "EVIOCGNAME", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGPHYS(32), "EVIOCGPHYS", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGUNIQ(32), "EVIOCGUNIQ", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGPROP(32), "EVIOCGPROP", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGKEY(32), "EVIOCGKEY", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGLED(32), "EVIOCGLED", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGSND(32), "EVIOCGSND", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGSW(32), "EVIOCGSW", 0, ioctl_insertion_parent_stateless),

    /* this was introduced not too long ago */
#ifdef EVIOCGMTSLOTS
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGMTSLOTS(32), "EVIOCGMTSLOTS", 0, ioctl_insertion_parent_stateless),
#endif

    /* terminator */
    {0, 0, 0, "", NULL, NULL, NULL, NULL, NULL}
};

const ioctl_type *
ioctl_type_get_by_id(unsigned long id)
{
    ioctl_type *cur;
    for (cur = ioctl_db; cur->name[0] != '\0'; ++cur)
	if (id_matches_type(id, cur))
	    return cur;
    return NULL;
}
Ejemplo n.º 6
0
static int
evdev_read_ioctl(struct tcb *const tcp, const unsigned int code,
		 const kernel_ulong_t arg)
{
	/* fixed-number fixed-length commands */
	switch (code) {
		case EVIOCGVERSION:
			tprints(", ");
			printnum_int(tcp, arg, "%#x");
			return 1;
		case EVIOCGEFFECTS:
			tprints(", ");
			printnum_int(tcp, arg, "%u");
			return 1;
		case EVIOCGID:
			return getid_ioctl(tcp, arg);
# ifdef EVIOCGREP
		case EVIOCGREP:
			return repeat_ioctl(tcp, arg);
# endif
		case EVIOCGKEYCODE:
			return keycode_ioctl(tcp, arg);
# ifdef EVIOCGKEYCODE_V2
		case EVIOCGKEYCODE_V2:
			return keycode_V2_ioctl(tcp, arg);
# endif
	}

	/* fixed-number variable-length commands */
	switch (_IOC_NR(code)) {
# ifdef EVIOCGMTSLOTS
		case _IOC_NR(EVIOCGMTSLOTS(0)):
			return mtslots_ioctl(tcp, code, arg);
# endif
		case _IOC_NR(EVIOCGNAME(0)):
		case _IOC_NR(EVIOCGPHYS(0)):
		case _IOC_NR(EVIOCGUNIQ(0)):
			tprints(", ");
			if (syserror(tcp))
				printaddr(arg);
			else
				printstrn(tcp, arg, tcp->u_rval);
			return 1;
# ifdef EVIOCGPROP
		case _IOC_NR(EVIOCGPROP(0)):
			return decode_bitset(tcp, arg, evdev_prop,
					     INPUT_PROP_MAX, "PROP_???");
# endif
		case _IOC_NR(EVIOCGSND(0)):
			return decode_bitset(tcp, arg, evdev_snd,
					     SND_MAX, "SND_???");
# ifdef EVIOCGSW
		case _IOC_NR(EVIOCGSW(0)):
			return decode_bitset(tcp, arg, evdev_switch,
					     SW_MAX, "SW_???");
# endif
		case _IOC_NR(EVIOCGKEY(0)):
			return decode_bitset(tcp, arg, evdev_keycode,
					     KEY_MAX, "KEY_???");
		case _IOC_NR(EVIOCGLED(0)):
			return decode_bitset(tcp, arg, evdev_leds,
					     LED_MAX, "LED_???");
	}

	/* multi-number fixed-length commands */
	if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0)))
		return abs_ioctl(tcp, arg);

	/* multi-number variable-length commands */
	if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
		return bit_ioctl(tcp, _IOC_NR(code) & EV_MAX, arg);

	return 0;
}