Esempio n. 1
0
int main (int argc, char **argv)
{
	int fd, rd, i, j, k;
	struct input_event ev[64];
	int version;
	unsigned short id[4];
	unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
	char name[256] = "Unknown";
	int abs[5];

	if (argc < 2) {
		printf("Usage: evtest /dev/input/eventX\n");
		printf("Where X = input device number\n");
		return 1;
	}

	if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
		perror("evtest");
		return 1;
	}

	if (ioctl(fd, EVIOCGVERSION, &version)) {
		perror("evtest: can't get version");
		return 1;
	}

	printf("Input driver version is %d.%d.%d\n",
		version >> 16, (version >> 8) & 0xff, version & 0xff);

	ioctl(fd, EVIOCGID, id);
	printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
		id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);

	ioctl(fd, EVIOCGNAME(sizeof(name)), name);
	printf("Input device name: \"%s\"\n", name);

	memset(bit, 0, sizeof(bit));
	ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
	printf("Supported events:\n");

	for (i = 0; i < EV_MAX; i++)
		if (test_bit(i, bit[0])) {
			printf("  Event type %d (%s)\n", i, events[i] ? events[i] : "?");
			if (!i) continue;
			ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
			for (j = 0; j < KEY_MAX; j++) 
				if (test_bit(j, bit[i])) {
					printf("    Event code %d (%s)\n", j, names[i] ? (names[i][j] ? names[i][j] : "?") : "?");
					if (i == EV_ABS) {
						ioctl(fd, EVIOCGABS(j), abs);
						for (k = 0; k < 5; k++)
							if ((k < 3) || abs[k])
								printf("      %s %6d\n", absval[k], abs[k]);
					}
				}
		}
		

	printf("Testing ... (interrupt to exit)\n");

	while (1) {
		rd = read(fd, ev, sizeof(struct input_event) * 64);

		if (rd < (int) sizeof(struct input_event)) {
			printf("yyy\n");
			perror("\nevtest: error reading");
			return 1;
		}

		for (i = 0; i < rd / sizeof(struct input_event); i++)

			if (ev[i].type == EV_SYN) {
				printf("Event: time %ld.%06ld, -------------- %s ------------\n",
					ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].code ? "Config Sync" : "Report Sync" );
			} else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW || ev[i].code == MSC_SCAN)) {
				printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %02x\n",
					ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
					events[ev[i].type] ? events[ev[i].type] : "?",
					ev[i].code,
					names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
					ev[i].value);
			} else {
				printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
					ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
					events[ev[i].type] ? events[ev[i].type] : "?",
					ev[i].code,
					names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
					ev[i].value);
			}	

	}
}
Esempio n. 2
0
void Gamepad_detectDevices() {
    unsigned int numPaths;
    char ** gamepadPaths;
    bool duplicate;
    unsigned int pathIndex, gamepadIndex;
    struct stat statBuf;
    struct Gamepad_device * deviceRecord;
    struct Gamepad_devicePrivate * deviceRecordPrivate;
    int fd;
    char name[128];
    char * description;
    int evKeyBits[(KEY_CNT - 1) / sizeof(int) * 8 + 1];
    int evAbsBits[(ABS_CNT - 1) / sizeof(int) * 8 + 1];
    int bit;
    struct input_id id;

    if (!inited) {
        return;
    }

    gamepadPaths = findGamepadPaths(&numPaths);

    pthread_mutex_lock(&devicesMutex);
    for (pathIndex = 0; pathIndex < numPaths; pathIndex++) {
        duplicate = false;
        for (gamepadIndex = 0; gamepadIndex < numDevices; gamepadIndex++) {
            if (!strcmp(((struct Gamepad_devicePrivate *) devices[gamepadIndex]->privateData)->path, gamepadPaths[pathIndex])) {
                duplicate = true;
                break;
            }
        }
        if (duplicate) {
            free(gamepadPaths[pathIndex]);
            continue;
        }

        if (!stat(gamepadPaths[pathIndex], &statBuf)) {
            deviceRecord = (Gamepad_device*)malloc(sizeof(struct Gamepad_device));
            deviceRecord->deviceID = nextDeviceID++;
            deviceRecord->eventDispatcher = EventDispatcher_create(deviceRecord);
            devices = (Gamepad_device**)realloc(devices, sizeof(struct Gamepad_device *) * (numDevices + 1));
            devices[numDevices++] = deviceRecord;

            fd = open(gamepadPaths[pathIndex], O_RDONLY, 0);

            deviceRecordPrivate = (Gamepad_devicePrivate*)malloc(sizeof(struct Gamepad_devicePrivate));
            deviceRecordPrivate->fd = fd;
            deviceRecordPrivate->path = gamepadPaths[pathIndex];
            memset(deviceRecordPrivate->buttonMap, 0xFF, sizeof(deviceRecordPrivate->buttonMap));
            memset(deviceRecordPrivate->axisMap, 0xFF, sizeof(deviceRecordPrivate->axisMap));
            deviceRecord->privateData = deviceRecordPrivate;

            if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) > 0) {
                description = (char*)malloc(strlen(name + 1));
                strcpy(description, name);
            } else {
                description = (char*)malloc(strlen(gamepadPaths[pathIndex] + 1));
                strcpy(description, gamepadPaths[pathIndex]);
            }
            deviceRecord->description = description;

            if (!ioctl(fd, EVIOCGID, &id)) {
                deviceRecord->vendorID = id.vendor;
                deviceRecord->productID = id.product;
            } else {
                deviceRecord->vendorID = deviceRecord->productID = 0;
            }

            memset(evKeyBits, 0, sizeof(evKeyBits));
            memset(evAbsBits, 0, sizeof(evAbsBits));
            ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(evKeyBits)), evKeyBits);
            ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(evAbsBits)), evAbsBits);

            deviceRecord->numAxes = 0;
            for (bit = 0; bit < ABS_CNT; bit++) {
                if (test_bit(bit, evAbsBits)) {
                    if (ioctl(fd, EVIOCGABS(bit), &deviceRecordPrivate->axisInfo[bit]) < 0 ||
                            deviceRecordPrivate->axisInfo[bit].minimum == deviceRecordPrivate->axisInfo[bit].maximum) {
                        continue;
                    }
                    deviceRecordPrivate->axisMap[bit] = deviceRecord->numAxes;
                    deviceRecord->numAxes++;
                }
            }
            deviceRecord->numButtons = 0;
            for (bit = BTN_MISC; bit < KEY_CNT; bit++) {
                if (test_bit(bit, evKeyBits)) {
                    deviceRecordPrivate->buttonMap[bit - BTN_MISC] = deviceRecord->numButtons;
                    deviceRecord->numButtons++;
                }
            }

            deviceRecord->axisStates = (float*)calloc(sizeof(float), deviceRecord->numAxes);
            deviceRecord->buttonStates = (bool*)calloc(sizeof(bool), deviceRecord->numButtons);

            Gamepad_eventDispatcher()->dispatchEvent(Gamepad_eventDispatcher(), GAMEPAD_EVENT_DEVICE_ATTACHED, deviceRecord);

            pthread_create(&deviceRecordPrivate->thread, NULL, deviceThread, deviceRecord);
        }
    }
    pthread_mutex_unlock(&devicesMutex);
}
Esempio n. 3
0
int evio_get_joystick_status(evio_handle v, float *abs_x1, float *abs_y1,
                             float *abs_x2, float *abs_y2, int *buttons) {
  struct input_absinfo absinfo;
  int xax2, yax2;
  evio *evp = (evio *) v;
  int rc=0;

  memset(&absinfo, 0, sizeof(absinfo));

  *abs_x1 = 0;
  *abs_y1 = 0;
  *abs_x2 = 0;
  *abs_y2 = 0;
  *buttons = 0;

  if (ioctl(evp->fd, EVIOCGABS(ABS_X), &absinfo) < 0) {
    return 0;
  } else {
    rc |= 1;
    *abs_x1 = evio_absinfo2float(&absinfo);
  }
  if (ioctl(evp->fd, EVIOCGABS(ABS_Y), &absinfo) < 0) {
    return 0;
  } else {
    rc |= 1;
    *abs_y1 = evio_absinfo2float(&absinfo);
  }
 
  switch (evp->devjoystick) {
    case EVENTIO_JOYSTICK_LOGIF310:
      xax2 = ABS_RX; 
      yax2 = ABS_RY; 
      break;

    case EVENTIO_JOYSTICK_NYKO:
      xax2 = ABS_Z; 
      yax2 = ABS_RZ; 
      break;

    default:
    case EVENTIO_JOYSTICK_STD:
      xax2 = 0; 
      yax2 = 0; 
      break;
  }

  if (xax2 && yax2) { 
    if (ioctl(evp->fd, EVIOCGABS(xax2), &absinfo) < 0) {
      return 0;
    } else {
      rc |= 1;
      *abs_x2 = evio_absinfo2float(&absinfo);
    }
    if (ioctl(evp->fd, EVIOCGABS(yax2), &absinfo) < 0) {
      return 0;
    } else {
      rc |= 1;
      *abs_y2 = evio_absinfo2float(&absinfo);
    }
  }


  if (ioctl(evp->fd, EVIOCGKEY(sizeof(evp->keystate)), evp->keystate) >= 0) {
#if 1
    int btmp=0;
    btmp |= evio_get_button_status(v, BTN_BACK, EVENTIO_BACK);
    btmp |= evio_get_button_status(v, BTN_TASK, EVENTIO_TASK);
    btmp |= evio_get_button_status(v, BTN_START, EVENTIO_START);

    btmp |= evio_get_button_status(v, BTN_A, EVENTIO_GAMEPAD_A);
    btmp |= evio_get_button_status(v, BTN_B, EVENTIO_GAMEPAD_B);
    btmp |= evio_get_button_status(v, BTN_X, EVENTIO_GAMEPAD_X);
    btmp |= evio_get_button_status(v, BTN_Y, EVENTIO_GAMEPAD_Y);

    btmp |= evio_get_button_status(v, BTN_TL, EVENTIO_TL);
    btmp |= evio_get_button_status(v, BTN_TR, EVENTIO_TR);
    btmp |= evio_get_button_status(v, BTN_THUMBL, EVENTIO_THUMBL);
    btmp |= evio_get_button_status(v, BTN_THUMBR, EVENTIO_THUMBR);
#else      
    int i, btmp=0;
    for (i=0; i<31; i++) {
      if (EVIO_TESTBIT(BTN_GAMEPAD+i, evp->keybit))
        btmp |= (1 << i);
    }
#endif

    *buttons = btmp;
  }

  return rc;
}
Esempio n. 4
0
static int
SDL_EVDEV_init_touchscreen(SDL_evdevlist_item* item)
{
    int ret, i;
    char name[64];
    struct input_absinfo abs_info;
    
    if (!item->is_touchscreen)
        return 0;
    
    item->touchscreen_data = SDL_calloc(1, sizeof(*item->touchscreen_data));
    if (item->touchscreen_data == NULL)
        return SDL_OutOfMemory();
    
    ret = ioctl(item->fd, EVIOCGNAME(sizeof(name)), name);
    if (ret < 0) {
        SDL_free(item->touchscreen_data);
        return SDL_SetError("Failed to get evdev touchscreen name");
    }
    
    item->touchscreen_data->name = SDL_strdup(name);
    if (item->touchscreen_data->name == NULL) {
        SDL_free(item->touchscreen_data);
        return SDL_OutOfMemory();
    }
    
    ret = ioctl(item->fd, EVIOCGABS(ABS_MT_POSITION_X), &abs_info);
    if (ret < 0) {
        SDL_free(item->touchscreen_data->name);
        SDL_free(item->touchscreen_data);
        return SDL_SetError("Failed to get evdev touchscreen limits");
    }
    item->touchscreen_data->min_x = abs_info.minimum;
    item->touchscreen_data->max_x = abs_info.maximum;
    item->touchscreen_data->range_x = abs_info.maximum - abs_info.minimum;
        
    ret = ioctl(item->fd, EVIOCGABS(ABS_MT_POSITION_Y), &abs_info);
    if (ret < 0) {
        SDL_free(item->touchscreen_data->name);
        SDL_free(item->touchscreen_data);
        return SDL_SetError("Failed to get evdev touchscreen limits");
    }
    item->touchscreen_data->min_y = abs_info.minimum;
    item->touchscreen_data->max_y = abs_info.maximum;
    item->touchscreen_data->range_y = abs_info.maximum - abs_info.minimum;
    
    ret = ioctl(item->fd, EVIOCGABS(ABS_MT_SLOT), &abs_info);
    if (ret < 0) {
        SDL_free(item->touchscreen_data->name);
        SDL_free(item->touchscreen_data);
        return SDL_SetError("Failed to get evdev touchscreen limits");
    }
    item->touchscreen_data->max_slots = abs_info.maximum + 1;
    
    item->touchscreen_data->slots = SDL_calloc(
        item->touchscreen_data->max_slots,
        sizeof(*item->touchscreen_data->slots));
    if (item->touchscreen_data->slots == NULL) {
        SDL_free(item->touchscreen_data->name);
        SDL_free(item->touchscreen_data);
        return SDL_OutOfMemory();
    }
    
    for(i = 0; i < item->touchscreen_data->max_slots; i++) {
        item->touchscreen_data->slots[i].tracking_id = -1;
    }
    
    ret = SDL_AddTouch(item->fd, /* I guess our fd is unique enough */
        item->touchscreen_data->name);
    if (ret < 0) {
        SDL_free(item->touchscreen_data->slots);
        SDL_free(item->touchscreen_data->name);
        SDL_free(item->touchscreen_data);
        return ret;
    }
    
    return 0;
}
Esempio n. 5
0
static int
touchpad_init(struct touchpad_dispatch *touchpad,
	      struct evdev_device *device)
{
	struct motion_filter *accel;

	unsigned long prop_bits[INPUT_PROP_MAX];
	struct input_absinfo absinfo;
	unsigned long abs_bits[NBITS(ABS_MAX)];

	bool has_buttonpad;

	double width;
	double height;
	double diagonal;

	touchpad->base.interface = &touchpad_interface;
	touchpad->device = device;

	/* Detect model */
	touchpad->model = get_touchpad_model(device);

	ioctl(device->fd, EVIOCGPROP(sizeof(prop_bits)), prop_bits);
	has_buttonpad = TEST_BIT(prop_bits, INPUT_PROP_BUTTONPAD);

	/* Configure pressure */
	ioctl(device->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits);
	if (TEST_BIT(abs_bits, ABS_PRESSURE)) {
		ioctl(device->fd, EVIOCGABS(ABS_PRESSURE), &absinfo);
		configure_touchpad_pressure(touchpad,
					    absinfo.minimum,
					    absinfo.maximum);
	}

	/* Configure acceleration factor */
	width = abs(device->abs.max_x - device->abs.min_x);
	height = abs(device->abs.max_y - device->abs.min_y);
	diagonal = sqrt(width*width + height*height);

	/* Set default parameters */
	touchpad->constant_accel_factor =
		DEFAULT_CONSTANT_ACCEL_NUMERATOR / diagonal;
	touchpad->min_accel_factor = DEFAULT_MIN_ACCEL_FACTOR;
	touchpad->max_accel_factor = DEFAULT_MAX_ACCEL_FACTOR;

	touchpad->hysteresis.margin_x =
		diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
	touchpad->hysteresis.margin_y =
		diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
	touchpad->hysteresis.center_x = 0;
	touchpad->hysteresis.center_y = 0;

	/* Configure acceleration profile */
	accel = create_pointer_accelator_filter(touchpad_profile);
	if (accel == NULL)
		return -1;
	touchpad->filter = accel;

	/* Setup initial state */
	touchpad->reset = 1;

	memset(touchpad->motion_history, 0, sizeof touchpad->motion_history);
	touchpad->motion_index = 0;
	touchpad->motion_count = 0;

	touchpad->state = TOUCHPAD_STATE_NONE;
	touchpad->last_finger_state = 0;
	touchpad->finger_state = 0;

	touchpad->fsm.events = NULL;
	touchpad->fsm.events_count = 0;
	touchpad->fsm.events_len = 0;
	touchpad->fsm.state = FSM_IDLE;

	touchpad->fsm.timer.fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
	touchpad->fsm.timer.source =
		libinput_add_fd(touchpad->device->base.seat->libinput,
				touchpad->fsm.timer.fd,
				fsm_timeout_handler,
				touchpad);

	if (touchpad->fsm.timer.source == NULL) {
		close(touchpad->fsm.timer.fd);
		accel->interface->destroy(accel);
		return -1;
	}

	/* Configure */
	touchpad->fsm.enable = !has_buttonpad;

	return 0;
}
Esempio n. 6
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 SDL_bool EV_ConfigJoystick(STJoystick::STJoystickData* joystick, int fd)
{
	int i, t;
	unsigned long keybit[40];
	unsigned long absbit[40];
	unsigned long relbit[40];

	/* See if this device uses the new unified event API */
	if ( (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
	     (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&
	     (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0) ) {
		joystick->hwdata->is_hid = SDL_TRUE;

		/* Get the number of buttons, axes, and other thingamajigs */
		for ( i=BTN_JOYSTICK; i < KEY_MAX; ++i ) {
			if ( test_bit(i, keybit) ) {
#ifdef DEBUG_INPUT_EVENTS
				printf("Joystick has button: 0x%x\n", i);
#endif
				joystick->hwdata->key_map[i-BTN_MISC] =
						joystick->nbuttons;
				++joystick->nbuttons;
			}
		}
		for ( i=BTN_MISC; i < BTN_JOYSTICK; ++i ) {
			if ( test_bit(i, keybit) ) {
#ifdef DEBUG_INPUT_EVENTS
				printf("Joystick has button: 0x%x\n", i);
#endif
				joystick->hwdata->key_map[i-BTN_MISC] =
						joystick->nbuttons;
				++joystick->nbuttons;
			}
		}
		for ( i=0; i<ABS_MAX; ++i ) {
			/* Skip hats */
			if ( i == ABS_HAT0X ) {
				i = ABS_HAT3Y;
				continue;
			}
			if ( test_bit(i, absbit) ) {
				int values[5];

				if ( ioctl(fd, EVIOCGABS(i), values) < 0 )
					continue;
#ifdef DEBUG_INPUT_EVENTS
				printf("Joystick has absolute axis: %x\n", i);
				printf("Values = { %d, %d, %d, %d, %d }\n",
					values[0], values[1],
					values[2], values[3], values[4]);
#endif /* DEBUG_INPUT_EVENTS */
				joystick->hwdata->abs_map[i] = joystick->naxes;
				if ( values[1] == values[2] ) {
				    joystick->hwdata->abs_correct[i].used = 0;
				} else {
				    joystick->hwdata->abs_correct[i].used = 1;
				    joystick->hwdata->abs_correct[i].coef[0] =
					(values[2] + values[1]) / 2 - values[4];
				    joystick->hwdata->abs_correct[i].coef[1] =
					(values[2] + values[1]) / 2 + values[4];
				    t = ((values[2] - values[1]) / 2 - 2 * values[4]);
				    if ( t != 0 ) {
					joystick->hwdata->abs_correct[i].coef[2] = (1 << 29) / t;
				    } else {
					joystick->hwdata->abs_correct[i].coef[2] = 0;
				    }
				}
				++joystick->naxes;
			}
		}
		for ( i=ABS_HAT0X; i <= ABS_HAT3Y; i += 2 ) {
			if ( test_bit(i, absbit) || test_bit(i+1, absbit) ) {
#ifdef DEBUG_INPUT_EVENTS
				printf("Joystick has hat %d\n",(i-ABS_HAT0X)/2);
#endif
				++joystick->nhats;
			}
		}
		if ( test_bit(REL_X, relbit) || test_bit(REL_Y, relbit) ) {
			++joystick->nballs;
		}

		/* Allocate data to keep track of these thingamajigs */
		if ( joystick->nhats > 0 ) {
			if ( allocate_hatdata(joystick) < 0 ) {
				joystick->nhats = 0;
			}
		}
		if ( joystick->nballs > 0 ) {
			if ( allocate_balldata(joystick) < 0 ) {
				joystick->nballs = 0;
			}
		}
	}
	return(joystick->hwdata->is_hid);
}
Esempio n. 8
0
void Gamepad_detectDevices() {
	struct input_id id;
	DIR * dev_input;
	struct dirent * entity;
	unsigned int charsConsumed;
	int num;
	int fd;
	int evCapBits[(EV_CNT - 1) / sizeof(int) * 8 + 1];
	int evKeyBits[(KEY_CNT - 1) / sizeof(int) * 8 + 1];
	int evAbsBits[(ABS_CNT - 1) / sizeof(int) * 8 + 1];
	char fileName[PATH_MAX];
	bool duplicate;
	unsigned int gamepadIndex;
	struct stat statBuf;
	struct Gamepad_device * deviceRecord;
	struct Gamepad_devicePrivate * deviceRecordPrivate;
	char name[128];
	char * description;
	int bit;
	time_t currentTime;
	static time_t lastInputStatTime;
	
	if (!inited) {
		return;
	}
	
	pthread_mutex_lock(&devicesMutex);
	
	dev_input = opendir("/dev/input");
	currentTime = time(NULL);
	if (dev_input != NULL) {
		while ((entity = readdir(dev_input)) != NULL) {
			charsConsumed = 0;
			if (sscanf(entity->d_name, "event%d%n", &num, &charsConsumed) && charsConsumed == strlen(entity->d_name)) {
				snprintf(fileName, PATH_MAX, "/dev/input/%s", entity->d_name);
				if (stat(fileName, &statBuf) || statBuf.st_mtime < lastInputStatTime) {
					continue;
				}
				
				duplicate = false;
				for (gamepadIndex = 0; gamepadIndex < numDevices; gamepadIndex++) {
					if (!strcmp(((struct Gamepad_devicePrivate *) devices[gamepadIndex]->privateData)->path, fileName)) {
						duplicate = true;
						break;
					}
				}
				if (duplicate) {
					continue;
				}
				
				fd = open(fileName, O_RDONLY, 0);
				memset(evCapBits, 0, sizeof(evCapBits));
				memset(evKeyBits, 0, sizeof(evKeyBits));
				memset(evAbsBits, 0, sizeof(evAbsBits));
				if (ioctl(fd, EVIOCGBIT(0, sizeof(evCapBits)), evCapBits) < 0 ||
				    ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(evKeyBits)), evKeyBits) < 0 ||
				    ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(evAbsBits)), evAbsBits) < 0) {
					close(fd);
					continue;
				}
				if (!test_bit(EV_KEY, evCapBits) || !test_bit(EV_ABS, evCapBits) ||
				    !test_bit(ABS_X, evAbsBits) || !test_bit(ABS_Y, evAbsBits) ||
				    (!test_bit(BTN_TRIGGER, evKeyBits) && !test_bit(BTN_A, evKeyBits) && !test_bit(BTN_1, evKeyBits))) {
					close(fd);
					continue;
				}
				
				deviceRecord = malloc(sizeof(struct Gamepad_device));
				deviceRecord->deviceID = nextDeviceID++;
				devices = realloc(devices, sizeof(struct Gamepad_device *) * (numDevices + 1));
				devices[numDevices++] = deviceRecord;
				
				deviceRecordPrivate = malloc(sizeof(struct Gamepad_devicePrivate));
				deviceRecordPrivate->fd = fd;
				deviceRecordPrivate->path = malloc(strlen(fileName) + 1);
				strcpy(deviceRecordPrivate->path, fileName);
				memset(deviceRecordPrivate->buttonMap, 0xFF, sizeof(deviceRecordPrivate->buttonMap));
				memset(deviceRecordPrivate->axisMap, 0xFF, sizeof(deviceRecordPrivate->axisMap));
				deviceRecord->privateData = deviceRecordPrivate;
				
				if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) > 0) {
					description = malloc(strlen(name) + 1);
					strcpy(description, name);
				} else {
					description = malloc(strlen(fileName) + 1);
					strcpy(description, fileName);
				}
				deviceRecord->description = description;
				
				if (!ioctl(fd, EVIOCGID, &id)) {
					deviceRecord->vendorID = id.vendor;
					deviceRecord->productID = id.product;
				} else {
					deviceRecord->vendorID = deviceRecord->productID = 0;
				}
				
				memset(evKeyBits, 0, sizeof(evKeyBits));
				memset(evAbsBits, 0, sizeof(evAbsBits));
				ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(evKeyBits)), evKeyBits);
				ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(evAbsBits)), evAbsBits);
				
				deviceRecord->numAxes = 0;
				for (bit = 0; bit < ABS_CNT; bit++) {
					if (test_bit(bit, evAbsBits)) {
						if (ioctl(fd, EVIOCGABS(bit), &deviceRecordPrivate->axisInfo[bit]) < 0 ||
							  deviceRecordPrivate->axisInfo[bit].minimum == deviceRecordPrivate->axisInfo[bit].maximum) {
							continue;
						}
						deviceRecordPrivate->axisMap[bit] = deviceRecord->numAxes;
						deviceRecord->numAxes++;
					}
				}
				deviceRecord->numButtons = 0;
				for (bit = BTN_MISC; bit < KEY_CNT; bit++) {
					if (test_bit(bit, evKeyBits)) {
						deviceRecordPrivate->buttonMap[bit - BTN_MISC] = deviceRecord->numButtons;
						deviceRecord->numButtons++;
					}
				}
				
				deviceRecord->axisStates = calloc(sizeof(float), deviceRecord->numAxes);
				deviceRecord->buttonStates = calloc(sizeof(bool), deviceRecord->numButtons);
				
				if (Gamepad_deviceAttachCallback != NULL) {
					Gamepad_deviceAttachCallback(deviceRecord, Gamepad_deviceAttachContext);
				}
				
				pthread_create(&deviceRecordPrivate->thread, NULL, deviceThread, deviceRecord);
			}
		}
		closedir(dev_input);
	}
	
	lastInputStatTime = currentTime;
	pthread_mutex_unlock(&devicesMutex);
}
static int vk_init(struct ev *e)
{
    char vk_path[PATH_MAX] = "/sys/board_properties/virtualkeys.";
    char vks[2048], *ts;
    ssize_t len;
    int vk_fd;
    int i;

    e->vk_count = 0;

    len = strlen(vk_path);
    len = ioctl(e->fd->fd, EVIOCGNAME(sizeof(vk_path) - len), vk_path + len);
    if (len <= 0)
        return -1;

    vk_fd = open(vk_path, O_RDONLY);
    if (vk_fd < 0)
        return -1;

    len = read(vk_fd, vks, sizeof(vks)-1);
    close(vk_fd);
    if (len <= 0)
        return -1;

    vks[len] = '\0';

    /* Parse a line like:
        keytype:keycode:centerx:centery:width:height:keytype2:keycode2:centerx2:...
    */
    for (ts = vks, e->vk_count = 1; *ts; ++ts) {
        if (*ts == ':')
            ++e->vk_count;
    }

    if (e->vk_count % 6) {
        LOGW("minui: %s is %d %% 6\n", vk_path, e->vk_count % 6);
    }
    e->vk_count /= 6;
    if (e->vk_count <= 0)
        return -1;

    e->sent = 0;
    e->mt_idx = 0;

    ioctl(e->fd->fd, EVIOCGABS(ABS_X), &e->p.xi);
    ioctl(e->fd->fd, EVIOCGABS(ABS_Y), &e->p.yi);
    e->p.pressed = 0;

    ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_X), &e->mt_p.xi);
    ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_Y), &e->mt_p.yi);
    e->mt_p.pressed = 0;

    e->vks = malloc(sizeof(*e->vks) * e->vk_count);

    for (i = 0; i < e->vk_count; ++i) {
        char *token[6];
        int j;

        for (j = 0; j < 6; ++j) {
            token[j] = vk_strtok_r((i||j)?NULL:vks, ":", &ts);
        }

        if (strcmp(token[0], "0x01") != 0) {
            /* Java does string compare, so we do too. */
            LOGW("minui: %s: ignoring unknown virtual key type %s\n", vk_path, token[0]);
            continue;
        }

        e->vks[i].scancode = strtol(token[1], NULL, 0);
        e->vks[i].centerx = strtol(token[2], NULL, 0);
        e->vks[i].centery = strtol(token[3], NULL, 0);
        e->vks[i].width = strtol(token[4], NULL, 0);
        e->vks[i].height = strtol(token[5], NULL, 0);
    }

    return 0;
}
Esempio n. 10
0
#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
};

static const char *const input_devs[] = {
	"input",
};

static void input_sanitise(const struct ioctl_group *grp, int childno)
Esempio n. 11
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;
	}
}
Esempio n. 12
0
/* Init Event Device Properties */
static byte aipInitEventDev(AIP_EVP e){
  /* Variables */
  char    vk_path[PATH_MAX] = "/sys/board_properties/virtualkeys.";
  char    vks[2048], *ts    = NULL;
  ssize_t len;
  int     vk_fd;
  int     i;

  e->vkn = 0;
  len = strlen(vk_path);
  len = ioctl(_aip->fds[e->fd_id].fd, EVIOCGNAME(sizeof(e->device_name)), e->device_name);
  if (len <= 0){
      return 0;
  }

  /* Blacklist these "input" devices */
  if (strcmp(e->device_name, "bma250") == 0){
      e->ignored = 1;
  }

  /* virtualkeys.{device_name} */
  strcat(vk_path, e->device_name);

  /* Some devices split the keys from the touchscreen */
  e->vkn = 0;
  vk_fd = open(vk_path, O_RDONLY);
  if (vk_fd >= 0){
    /* Read Contents */
    len = read(vk_fd, vks, sizeof(vks)-1);
    close(vk_fd);
    
    /* Return False on Failed */
    if (len<=0){
      return 0;
    }
    
    /* Add string break */
    vks[len] = '\0';
    
    /* Parse a line like:
        keytype:keycode:centerx:centery:width:height:keytype2:keycode2:centerx2:...
    */
    for (ts=vks, e->vkn=1; *ts; ++ts) {
      if (*ts == ':'){
        e->vkn++;
      }
    }
    
    e->vkn /= 6;
    if (e->vkn <= 0){
      return 0;
    }
    e->down = 0;
  }

  /* IOCTL ABS DEVICE */
  ioctl(_aip->fds[e->fd_id].fd, EVIOCGABS(AIP_ABS_X), &e->p.xi);
  ioctl(_aip->fds[e->fd_id].fd, EVIOCGABS(AIP_ABS_Y), &e->p.yi);
  ioctl(_aip->fds[e->fd_id].fd, EVIOCGABS(AIP_ABS_MT_POSITION_X), &e->mt_p.xi);
  ioctl(_aip->fds[e->fd_id].fd, EVIOCGABS(AIP_ABS_MT_POSITION_Y), &e->mt_p.yi);
  e->p.synced = 0;
  e->mt_p.synced = 0;
  
  /* LOGS */
  printf("\nDEVICE NAME: %s - %s\n", e->device_name, vk_path);
  printf("EV ST: minX: %d  maxX: %d  minY: %d  maxY: %d\n", e->p.xi.minimum, e->p.xi.maximum, e->p.yi.minimum, e->p.yi.maximum);
  printf("EV MT: minX: %d  maxX: %d  minY: %d  maxY: %d\n", e->mt_p.xi.minimum, e->mt_p.xi.maximum, e->mt_p.yi.minimum, e->mt_p.yi.maximum);


  /* Allocate Virtualkeys Count */
  e->vks = malloc(sizeof(AIP_VK) * e->vkn);
  for (i=0; i<e->vkn; ++i) {
    char * token[6];
    int j;

    for (j=0; j<6; ++j) {
      token[j] = aipStrTokR((i||j)?NULL:vks, ":", &ts);
    }

    if (strcmp(token[0],"0x01") != 0) {
      continue;
    }

    /* Dump It */
    e->vks[i].scan  = strtol(token[1], NULL, 0);
    e->vks[i].x     = strtol(token[2], NULL, 0);
    e->vks[i].y     = strtol(token[3], NULL, 0);
    e->vks[i].w     = strtol(token[4], NULL, 0);
    e->vks[i].h     = strtol(token[5], NULL, 0);
  }
  
  /* OK */
  return 1;
}
void lightgun_event_abs_init(void)
{
	int i;

	for (i = 0; i < GUN_MAX; i++) {
		char name[256] = "Unknown";
		uint8_t abs_bitmask[ABS_MAX/8 + 1];
		struct input_absinfo abs_features;

		if (!lg_devices[i].device)
			continue;

		if ((lg_devices[i].fd = open(lg_devices[i].device, O_RDONLY)) < 0) {
			fprintf(stderr_file, "Lightgun%d: %s[open]: %s",
				i + 1, lg_devices[i].device, strerror(errno));
			continue;
		}

		if (ioctl(lg_devices[i].fd, EVIOCGNAME(sizeof(name)), name) < 0) {
			fprintf(stderr_file, "Lightgun%d: %s[ioctl/EVIOCGNAME]: %s\n",
				i + 1, lg_devices[i].device, strerror(errno));
			lg_devices[i].device = NULL;
			continue;
		}

		memset(abs_bitmask, 0, sizeof(abs_bitmask));
		if (ioctl(lg_devices[i].fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) < 0) {
			fprintf(stderr_file, "Lightgun%d: %s[ioctl/EVIOCGNAME]: %s\n",
				i + 1, lg_devices[i].device, strerror(errno));
			lg_devices[i].device = NULL;
			continue;
		}

		/* Make sure we have an X and Y axis. Not much good
		 * without it. */
		if (!test_bit(ABS_X, abs_bitmask) || !test_bit(ABS_Y, abs_bitmask)) {
			fprintf(stderr_file, "Lightgun%d: %s: Does not contain both X and Y axis, "
				"ignoring\n", i + 1, lg_devices[i].device);
			lg_devices[i].device = NULL;
			continue;
		}

		if (ioctl(lg_devices[i].fd, EVIOCGABS(ABS_X), &abs_features)) {
			fprintf(stderr_file, "Lightgun%d: %s[ioctl/EVIOCGABS(ABX_X)]: %s\n",
				i + 1, lg_devices[i].device, strerror(errno));
			lg_devices[i].device = NULL;
			continue;
		}

		lg_devices[i].min[LG_X_AXIS] = abs_features.minimum;
		lg_devices[i].range[LG_X_AXIS] = abs_features.maximum - abs_features.minimum;

		if (ioctl(lg_devices[i].fd, EVIOCGABS(ABS_Y), &abs_features)) {
			fprintf(stderr_file, "Lightgun%d: %s[ioctl/EVIOCGABS(ABX_Y)]: %s\n",
				i + 1, lg_devices[i].device, strerror(errno));
			lg_devices[i].device = NULL;
			continue;
		}

		lg_devices[i].min[LG_Y_AXIS] = abs_features.minimum;
		lg_devices[i].range[LG_Y_AXIS] = abs_features.maximum - abs_features.minimum;

		fprintf(stderr_file, "Lightgun%d: %s\n", i + 1, name);
		fprintf(stderr_file, "           X axis:  min[%d]  range[%d]\n",
			lg_devices[i].min[LG_X_AXIS], lg_devices[i].range[LG_X_AXIS]);
		fprintf(stderr_file, "           Y axis:  min[%d]  range[%d]\n",
			lg_devices[i].min[LG_Y_AXIS], lg_devices[i].range[LG_Y_AXIS]);
	}
}
Esempio n. 14
0
static int
evdev_handle_device(struct evdev_device *device)
{
	struct input_absinfo absinfo;
	unsigned long ev_bits[NBITS(EV_MAX)];
	unsigned long abs_bits[NBITS(ABS_MAX)];
	unsigned long rel_bits[NBITS(REL_MAX)];
	unsigned long key_bits[NBITS(KEY_MAX)];
	int has_key, has_abs;
	unsigned int i;

	has_key = 0;
	has_abs = 0;
	device->caps = 0;

	ioctl(device->fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits);
	if (TEST_BIT(ev_bits, EV_ABS)) {
		has_abs = 1;

		ioctl(device->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)),
		      abs_bits);
		if (TEST_BIT(abs_bits, ABS_X)) {
			ioctl(device->fd, EVIOCGABS(ABS_X), &absinfo);
			device->abs.min_x = absinfo.minimum;
			device->abs.max_x = absinfo.maximum;
			device->caps |= EVDEV_MOTION_ABS;
		}
		if (TEST_BIT(abs_bits, ABS_Y)) {
			ioctl(device->fd, EVIOCGABS(ABS_Y), &absinfo);
			device->abs.min_y = absinfo.minimum;
			device->abs.max_y = absinfo.maximum;
			device->caps |= EVDEV_MOTION_ABS;
		}
		if (TEST_BIT(abs_bits, ABS_MT_SLOT)) {
			ioctl(device->fd, EVIOCGABS(ABS_MT_POSITION_X),
			      &absinfo);
			device->abs.min_x = absinfo.minimum;
			device->abs.max_x = absinfo.maximum;
			ioctl(device->fd, EVIOCGABS(ABS_MT_POSITION_Y),
			      &absinfo);
			device->abs.min_y = absinfo.minimum;
			device->abs.max_y = absinfo.maximum;
			device->is_mt = 1;
			device->mt.slot = 0;
			device->caps |= EVDEV_TOUCH;
		}
	}
	if (TEST_BIT(ev_bits, EV_REL)) {
		ioctl(device->fd, EVIOCGBIT(EV_REL, sizeof(rel_bits)),
		      rel_bits);
		if (TEST_BIT(rel_bits, REL_X) || TEST_BIT(rel_bits, REL_Y))
			device->caps |= EVDEV_MOTION_REL;
	}
	if (TEST_BIT(ev_bits, EV_KEY)) {
		has_key = 1;
		ioctl(device->fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)),
		      key_bits);
		if (TEST_BIT(key_bits, BTN_TOOL_FINGER) &&
		    !TEST_BIT(key_bits, BTN_TOOL_PEN) &&
		    has_abs)
			device->dispatch = evdev_touchpad_create(device);
		for (i = KEY_ESC; i < KEY_MAX; i++) {
			if (i >= BTN_MISC && i < KEY_OK)
				continue;
			if (TEST_BIT(key_bits, i)) {
				device->caps |= EVDEV_KEYBOARD;
				break;
			}
		}
		for (i = BTN_MISC; i < KEY_OK; i++) {
			if (TEST_BIT(key_bits, i)) {
				device->caps |= EVDEV_BUTTON;
				break;
			}
		}
	}
	if (TEST_BIT(ev_bits, EV_LED)) {
		device->caps |= EVDEV_KEYBOARD;
	}

	/* This rule tries to catch accelerometer devices and opt out. We may
	 * want to adjust the protocol later adding a proper event for dealing
	 * with accelerometers and implement here accordingly */
	if (has_abs && !has_key && !device->is_mt) {
		weston_log("input device %s, %s "
			   "ignored: unsupported device type\n",
			   device->devname, device->devnode);
		return 0;
	}

	return 1;
}
Esempio n. 15
0
HIDDevice::HIDDevice(VRDevice::Factory* sFactory,VRDeviceManager* sDeviceManager,Misc::ConfigurationFile& configFile)
	:VRDevice(sFactory,sDeviceManager,configFile),
	 deviceFd(-1),
	 keyMap(0),
	 absAxisMap(0),relAxisMap(0),axisConverters(0),
	 reportEvents(false),
	 buttonStates(0),valuatorStates(0)
	{
	/* First option: Open device by explicit event device file name: */
	if(deviceFd<0)
		{
		std::string deviceFileName=configFile.retrieveString("./deviceFileName","");
		if(deviceFileName!="")
			{
			#ifdef VERBOSE
			printf("HIDDevice: Opening device %s\n",deviceFileName.c_str());
			fflush(stdout);
			#endif
			deviceFd=open(deviceFileName.c_str(),O_RDONLY);
			if(deviceFd<0)
				Misc::throwStdErr("HIDDevice: Unable to open device file \"%s\"",deviceFileName.c_str());
			}
		}
	
	/* Second option: Open device by vendor ID / product ID: */
	if(deviceFd<0)
		{
		std::string deviceVendorProductId=configFile.retrieveString("./deviceVendorProductId","");
		if(deviceVendorProductId!="")
			{
			/* Split ID string into vendor ID / product ID: */
			char* colonPtr;
			int vendorId=strtol(deviceVendorProductId.c_str(),&colonPtr,16);
			char* endPtr;
			int productId=strtol(colonPtr+1,&endPtr,16);
			if(*colonPtr!=':'||*endPtr!='\0'||vendorId<0||productId<0)
				Misc::throwStdErr("HIDDevice: Malformed vendorId:productId string \"%s\"",deviceVendorProductId.c_str());
			#ifdef VERBOSE
			printf("HIDDevice: Searching device %04x:%04x\n",vendorId,productId);
			fflush(stdout);
			#endif
			deviceFd=findDevice(vendorId,productId);
			if(deviceFd<0)
				Misc::throwStdErr("HIDDevice: No device with vendorId:productId %04x:%04x found",vendorId,productId);
			}
		}
	
	/* Third option: Open device by device name: */
	if(deviceFd<0)
		{
		std::string deviceName=configFile.retrieveString("./deviceName","");
		if(deviceName!="")
			{
			#ifdef VERBOSE
			printf("HIDDevice: Searching device %s\n",deviceName.c_str());
			fflush(stdout);
			#endif
			deviceFd=findDevice(deviceName.c_str());
			if(deviceFd<0)
				Misc::throwStdErr("HIDDevice: No device with name \"%s\" found",deviceName.c_str());
			}
		}
	
	/* Bail out if no device was found: */
	if(deviceFd<0)
		Misc::throwStdErr("HIDDevice: No device specified");
	
	/* Set number of trackers on device: */
	setNumTrackers(0,configFile);
	
	/* Query all feature types of the device: */
	unsigned char featureTypeBits[EV_MAX/8+1];
	memset(featureTypeBits,0,EV_MAX/8+1);
	if(ioctl(deviceFd,EVIOCGBIT(0,sizeof(featureTypeBits)),featureTypeBits)<0)
		Misc::throwStdErr("HIDDevice: Unable to query device feature types");
	
	/* Query the number of keys on the device: */
	if(featureTypeBits[EV_KEY/8]&(1<<(EV_KEY%8)))
		{
		#ifdef VERBOSE
		printf("HIDDevice: Initializing buttons...\n");
		fflush(stdout);
		#endif
		
		/* Query key features: */
		unsigned char keyBits[KEY_MAX/8+1];
		memset(keyBits,0,KEY_MAX/8+1);
		if(ioctl(deviceFd,EVIOCGBIT(EV_KEY,sizeof(keyBits)),keyBits)<0)
			Misc::throwStdErr("HIDDevice: Unable to query device key features");
		
		/* Initialize the key translation array: */
		keyMap=new int[KEY_MAX+1];
		int numKeys=0;
		for(int i=0;i<=KEY_MAX;++i)
			{
			if(keyBits[i/8]&(1<<(i%8)))
				{
				keyMap[i]=numKeys;
				++numKeys;
				}
			else
				keyMap[i]=-1;
			}
		
		/* Set number of buttons on device: */
		#ifdef VERBOSE
		printf("HIDDevice: %d buttons found\n",numKeys);
		fflush(stdout);
		#endif
		setNumButtons(numKeys,configFile);
		}
	else
		setNumButtons(0,configFile);
	
	/* Count the number of absolute and relative axes: */
	int numAxes=0;
	
	/* Query the number of absolute axes on the device: */
	if(featureTypeBits[EV_ABS/8]&(1<<(EV_ABS%8)))
		{
		#ifdef VERBOSE
		printf("HIDDevice: Initializing absolute axes...\n");
		fflush(stdout);
		#endif
		
		/* Query absolute axis features: */
		unsigned char absAxisBits[ABS_MAX/8+1];
		memset(absAxisBits,0,ABS_MAX/8+1);
		if(ioctl(deviceFd,EVIOCGBIT(EV_ABS,sizeof(absAxisBits)),absAxisBits)<0)
			Misc::throwStdErr("HIDDevice: Unable to query device absolute axis features");
		
		/* Initialize the axis translation array: */
		absAxisMap=new int[ABS_MAX+1];
		int numAbsAxes=0;
		for(int i=0;i<=ABS_MAX;++i)
			{
			if(absAxisBits[i/8]&(1<<(i%8)))
				{
				absAxisMap[i]=numAxes;
				++numAxes;
				++numAbsAxes;
				}
			else
				absAxisMap[i]=-1;
			}
		
		#ifdef VERBOSE
		printf("HIDDevice: %d absolute axes found\n",numAbsAxes);
		fflush(stdout);
		#endif
		}
	
	/* Query the number of relative axes on the device: */
	if(featureTypeBits[EV_REL/8]&(1<<(EV_REL%8)))
		{
		#ifdef VERBOSE
		printf("HIDDevice: Initializing relative axes...\n");
		fflush(stdout);
		#endif
		
		/* Query relative axis features: */
		unsigned char relAxisBits[REL_MAX/8+1];
		memset(relAxisBits,0,REL_MAX/8+1);
		if(ioctl(deviceFd,EVIOCGBIT(EV_REL,sizeof(relAxisBits)),relAxisBits)<0)
			Misc::throwStdErr("HIDDevice: Unable to query device relative axis features");
		
		/* Initialize the axis translation array: */
		relAxisMap=new int[REL_MAX+1];
		int numRelAxes=0;
		for(int i=0;i<=REL_MAX;++i)
			{
			if(relAxisBits[i/8]&(1<<(i%8)))
				{
				relAxisMap[i]=numAxes;
				++numAxes;
				++numRelAxes;
				}
			else
				relAxisMap[i]=-1;
			}
		
		#ifdef VERBOSE
		printf("HIDDevice: %d relative axes found\n",numRelAxes);
		fflush(stdout);
		#endif
		}
	
	/* Set number of valuators on device: */
	setNumValuators(numAxes,configFile);
		
	/* Initialize axis converters: */
	axisConverters=new AxisConverter[numAxes];
	
	if(absAxisMap!=0)
		{
		/* Initialize absolute axis converters: */
		#ifdef VERBOSE
		printf("HIDDevice: Initializing absolute axis converters\n");
		fflush(stdout);
		#endif
		for(int i=0;i<=ABS_MAX;++i)
			if(absAxisMap[i]>=0)
				{
				/* Query configuration of this axis: */
				input_absinfo absAxisConf;
				if(ioctl(deviceFd,EVIOCGABS(i),&absAxisConf)<0)
					Misc::throwStdErr("HIDDevice: Unable to query device absolute axis configuration");
				
				#ifdef VERBOSE
				printf("Axis %2d: min %d, max %d, fuzz %d, flat %d\n",absAxisMap[i],absAxisConf.minimum,absAxisConf.maximum,absAxisConf.fuzz,absAxisConf.flat);
				fflush(stdout);
				#endif
				
				/* Initialize converter with queried values: */
				AxisConverter& converter=axisConverters[absAxisMap[i]];
				float mid=Math::mid(absAxisConf.minimum,absAxisConf.maximum);
				converter=AxisConverter(absAxisConf.minimum,mid-absAxisConf.flat,mid+absAxisConf.flat,absAxisConf.maximum);
				
				/* Override axis settings from configuration file: */
				char axisSettingsTag[20];
				snprintf(axisSettingsTag,sizeof(axisSettingsTag),"axis%dSettings",absAxisMap[i]);
				converter=configFile.retrieveValue<AxisConverter>(axisSettingsTag,converter);
				
				#ifdef VERBOSE
				printf("Axis %2d: %s\n",absAxisMap[i],Misc::ValueCoder<AxisConverter>::encode(converter).c_str());
				fflush(stdout);
				#endif
				}
		}
	
	if(relAxisMap!=0)
		{
		/* Initialize relative axis converters: */
		#ifdef VERBOSE
		printf("HIDDevice: Initializing relative axis converters\n");
		fflush(stdout);
		#endif
		for(int i=0;i<=REL_MAX;++i)
			if(relAxisMap[i]>=0)
				{
				/* Initialize converter with default values: */
				AxisConverter& converter=axisConverters[relAxisMap[i]];
				converter=AxisConverter(-1.0f,1.0f);
				
				/* Override axis settings from configuration file: */
				char axisSettingsTag[20];
				snprintf(axisSettingsTag,sizeof(axisSettingsTag),"axis%dSettings",relAxisMap[i]);
				converter=configFile.retrieveValue<AxisConverter>(axisSettingsTag,converter);
				
				#ifdef VERBOSE
				printf("Axis %2d: %s\n",relAxisMap[i],Misc::ValueCoder<AxisConverter>::encode(converter).c_str());
				fflush(stdout);
				#endif
				}
		}
	
	#if 0
	/* Initialize gain arrays: */
	valuatorGains=new float[getNumValuators()];
	for(int i=0;i<getNumValuators();++i)
		{
		char valuatorGainTag[40];
		snprintf(valuatorGainTag,sizeof(valuatorGainTag),"./valuatorGain%d",i);
		valuatorGains[i]=configFile.retrieveValue<float>(valuatorGainTag,1.0f);
		}
	#endif
	
	/* Initialize state arrays: */
	buttonStates=new bool[getNumButtons()];
	for(int i=0;i<getNumButtons();++i)
		buttonStates[i]=false;
	valuatorStates=new float[getNumValuators()];
	for(int i=0;i<getNumValuators();++i)
		valuatorStates[i]=0.0f;
	
	/* Start device thread (HID device cannot be disabled): */
	startDeviceThread();
	}
Esempio n. 16
0
int init_hid_device(char* device_name)
{
  int cnt;
  unsigned long buttons,axes;
  unsigned long key_bits[32],abs_bits[32],led_bits[32];
  //	unsigned long ff_bits[32];
  int valbuf[16];
  char name[MAX_NAME_LENGTH] = "Unknown";

  stick_button_count = 0;
  stick_axis_count = 0;

  /* Detect device mode, event interface or joystick */
  if (strstr( device_name, "event" ) == 0 ) {
    dbgprintf(stderr," Using Joystick interface\n");
    event_mode = STICK_MODE_JOYSTICK;
  } else {
    dbgprintf(stderr," Using Event interface\n");
    event_mode = STICK_MODE_EVENT;
  }

  /* Open event device read only (with write permission for ff) */
  stick_device_handle = open(device_name,O_RDONLY|O_NONBLOCK);
  if (stick_device_handle<0) {
    dbgprintf(stderr,"ERROR: can not open %s (%s) [%s:%d]\n",
        device_name,strerror(errno),__FILE__,__LINE__);
    return(1);
  }

  /* LED testing */

//  led_test( );


  /* Which buttons has the device? */
  memset(key_bits,0,32*sizeof(unsigned long));
  memset(led_bits,0,32*sizeof(unsigned long));
  if (event_mode == STICK_MODE_EVENT ) {
    if (ioctl(stick_device_handle,EVIOCGBIT(EV_KEY,32*sizeof(unsigned long)),key_bits)<0) {
      dbgprintf(stderr,"ERROR: can not get key bits (%s) [%s:%d]\n",
          strerror(errno),__FILE__,__LINE__);
      return(1);
    }
    //read LED count
    if (ioctl(stick_device_handle,EVIOCGLED(32*sizeof(led_bits)),led_bits)<0) {
      dbgprintf(stderr,"ERROR: can not get LED bits (%s) [%s:%d]\n",
          strerror(errno),__FILE__,__LINE__);
      return(1);
    }
    dbgprintf(stderr,"LEDs: %X",*led_bits);


  } else {
    if (ioctl(stick_device_handle,JSIOCGBUTTONS,&buttons)<0) {
      dbgprintf(stderr,"ERROR: can not get key bits (%s) [%s:%d]\n",
          strerror(errno),__FILE__,__LINE__);
      return(1);
    }
  }

  /* Store buttons */
  if (stick_init_param.button_count > 0) {
    for (cnt = 0; cnt < MIN(stick_init_param.button_count,BUTTON_COUNT); cnt++) {
      if (!TEST_BIT(stick_init_param.button_code[cnt], key_bits)) {
        dbgprintf(stderr,"ERROR: no suitable custom button %d found [%s:%d]\n",cnt,__FILE__,__LINE__);
        return 1;
      }
    }
    stick_button_count = stick_init_param.button_count;
    memcpy(button_code,stick_init_param.button_code,BUTTON_COUNT*sizeof(int));
  }
  else {
    if (event_mode == STICK_MODE_EVENT) {
      for (cnt = MIN_BUTTON_CODE; cnt < MAX_BUTTON_CODE; cnt++) {
        if (TEST_BIT(cnt, key_bits)) {
          button_code[stick_button_count++] = cnt;
          dbgprintf(stderr,"Available button: %d (0x%x)\n",cnt,cnt);
        }
        if (stick_button_count == BUTTON_COUNT) break;
      }
    } else {
      for (cnt = 0; cnt < buttons; cnt++) {
        button_code[stick_button_count++] = cnt;
        dbgprintf(stderr,"Available button: %d (0x%x)\n",cnt,cnt);
        if (stick_button_count == BUTTON_COUNT) break;
      }
    }

    if (stick_button_count == 0) {
      dbgprintf(stderr,"ERROR: no suitable buttons found [%s:%d]\n",__FILE__,__LINE__);
    }
  }

  /* Which axis has the device? */
  memset(abs_bits,0,32*sizeof(unsigned long));
  if (event_mode == STICK_MODE_EVENT ) {
    if (ioctl(stick_device_handle,EVIOCGBIT(EV_ABS,32*sizeof(unsigned long)),abs_bits)<0) {
      dbgprintf(stderr,"ERROR: can not get abs bits (%s) [%s:%d]\n",
          strerror(errno),__FILE__,__LINE__);
      return(1);
    }
  } else {
    if (ioctl(stick_device_handle,JSIOCGAXES,&axes)<0) {
      dbgprintf(stderr,"ERROR: can not get abs bits (%s) [%s:%d]\n",
          strerror(errno),__FILE__,__LINE__);
      return(1);
    }
  }

  /* Store axis */
  if (stick_init_param.axis_count > 0) {
    for (cnt = 0; cnt < MIN(stick_init_param.axis_count,AXIS_COUNT); cnt++) {
      if (!TEST_BIT(stick_init_param.axis_code[cnt], abs_bits)) {
        dbgprintf(stderr,"ERROR: no suitable custom axis %d found [%s:%d]\n",cnt,__FILE__,__LINE__);
        return 1;
      }
    }
    stick_axis_count = stick_init_param.axis_count;
    memcpy(axis_code,stick_init_param.axis_code,AXIS_COUNT*sizeof(int));
  }
  else {
    if(event_mode == STICK_MODE_EVENT) {
      for (cnt = MIN_ABS_CODE; cnt < MAX_ABS_CODE; cnt++) {
        if (TEST_BIT(cnt, abs_bits)) {
          axis_code[stick_axis_count++] = cnt;
          dbgprintf(stderr,"Available axis: %d (0x%x)\n",cnt,cnt);
        }
        if (stick_axis_count == AXIS_COUNT) break;
      }
    } else {
      for (cnt = 0; cnt < axes; cnt++) {
        axis_code[stick_axis_count++] = cnt;
        dbgprintf(stderr,"Available axis: %d (0x%x)\n",cnt,cnt);
        if (stick_axis_count == AXIS_COUNT) break;
      }
    }

    // at least 2 axis are needed in auto detection
    if (stick_axis_count < 2) {
      dbgprintf(stderr,"ERROR: no suitable axis found [%s:%d]\n",__FILE__,__LINE__);
      return(1);
    }
  }

  /* Axis param */
  for (cnt = 0; cnt < stick_axis_count; cnt++)
  {
    if (event_mode == STICK_MODE_EVENT ) {
      /* get axis value range */
      if (ioctl(stick_device_handle,EVIOCGABS(axis_code[cnt]),valbuf)<0) {
        dbgprintf(stderr,"ERROR: can not get axis %d value range (%s) [%s:%d]\n",
            cnt,strerror(errno),__FILE__,__LINE__);
        return(1);
      }
      axis_min[cnt]=valbuf[1];
      axis_max[cnt]=valbuf[2];
    } else {
      // with joystick interface, all axes are signed 16 bit with full range
      axis_min[cnt]=-32768;
      axis_max[cnt]=32768;
    }

    if (axis_min[cnt]>=axis_max[cnt]) {
      dbgprintf(stderr,"ERROR: bad axis %d value range (%d,%d) [%s:%d]\n",
          cnt,axis_min[cnt],axis_max[cnt],__FILE__,__LINE__);
      return(1);
    }
    dbgprintf(stderr,"Axis %d : parameters = [%d,%d]\n",
        cnt,axis_min[cnt],axis_max[cnt]);
  }

  //--------------------------------------------------
  // force feedback, TBD feature
  //--------------------------------------------------
#if 0
  /* Now get some information about force feedback */
  memset(ff_bits,0,32*sizeof(unsigned long));
  if (ioctl(device_handle,EVIOCGBIT(EV_FF ,32*sizeof(unsigned long)),ff_bits)<0) {
    dbgprintf(stderr,"ERROR: can not get ff bits (%s) [%s:%d]\n",
        strerror(errno),__FILE__,__LINE__);
    return(1);
  }

  /* force feedback supported? */
  if (!TEST_BIT(FF_CONSTANT,ff_bits)) {
    dbgprintf(stderr,"ERROR: device (or driver) has no force feedback support [%s:%d]\n",
        __FILE__,__LINE__);
    return(1);
  }

  /* Switch off auto centering */
  memset(&event,0,sizeof(event));
  event.type=EV_FF;
  event.code=FF_AUTOCENTER;
  event.value=0;
  if (write(device_handle,&event,sizeof(event))!=sizeof(event)) {
    dbgprintf(stderr,"ERROR: failed to disable auto centering (%s) [%s:%d]\n",
        strerror(errno),__FILE__,__LINE__);
    return(1);
  }

  /* Initialize constant force effect */
  memset(&effect,0,sizeof(effect));
  effect.type=FF_CONSTANT;
  effect.id=-1;
  effect.trigger.button=0;
  effect.trigger.interval=0;
  effect.replay.length=0xffff;
  effect.replay.delay=0;
  effect.u.constant.level=0;
  effect.direction=0xC000;
  effect.u.constant.envelope.attack_length=0;
  effect.u.constant.envelope.attack_level=0;
  effect.u.constant.envelope.fade_length=0;
  effect.u.constant.envelope.fade_level=0;

  /* Upload effect */
  if (ioctl(device_handle,EVIOCSFF,&effect)==-1) {
    dbgprintf(stderr,"ERROR: uploading effect failed (%s) [%s:%d]\n",
        strerror(errno),__FILE__,__LINE__);
    return(1);
  }

  /* Start effect */
  memset(&event,0,sizeof(event));
  event.type=EV_FF;
  event.code=effect.id;
  event.value=1;
  if (write(device_handle,&event,sizeof(event))!=sizeof(event)) {
    dbgprintf(stderr,"ERROR: starting effect failed (%s) [%s:%d]\n",
        strerror(errno),__FILE__,__LINE__);
    return(1);
  }
#endif

  if (event_mode == STICK_MODE_EVENT ) {
    ioctl(stick_device_handle, EVIOCGNAME(sizeof(name)), name);
  } else {
    ioctl(stick_device_handle, JSIOCGNAME(MAX_NAME_LENGTH), name);
  }
  printf("Input device name: \"%s\" on device \"%s\"\n", name, device_name);

  return(0);
}
Esempio n. 17
0
static struct orng_device_info *
read_devinfo(struct orng_device_info *devinfo, int with_scancodes, int fd)
{
  int i;
  char buf[1024];
  __u32 sc;
  __u16 j;
  int res = 0;
  __u32 nsc;

  memset(devinfo, 0, sizeof(*devinfo));

  /* device identifier */

  if (ioctl(fd, EVIOCGID, &devinfo->id) < 0) {
    fprintf(stderr, "ioctl(EVIOCGID): %s\n", strerror(errno));
    goto err_ioctl;
  }

  /* event bits */

  if (ioctl(fd, EVIOCGBIT(0, sizeof(devinfo->evbit)), devinfo->evbit) < 0) {
    fprintf(stderr, "ioctl(EVIOCGBIT(0)): %s\n", strerror(errno));
    goto err_ioctl;
  }

  /* keys */

  if (TEST_ARRAY_BIT(devinfo->evbit, EV_KEY)) {
    if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(devinfo->keybit)), devinfo->keybit) < 0) {
      fprintf(stderr, "ioctl(EVIOCGBIT(EV_KEY)): %s\n", strerror(errno));
      goto err_ioctl;
    }

    /* key state */

    if (TEST_ARRAY_BIT(devinfo->evbit, EV_KEY)) {
      if (ioctl(fd, EVIOCGKEY(sizeof(devinfo->key)), devinfo->key) < 0) {
        fprintf(stderr, "ioctl(EVIOCGKEY(%zu)): %s\n",
                sizeof(buf), strerror(errno));
        goto err_ioctl;
      }
    }

    /* read mapping between scan codes and key codes */

    if (with_scancodes) {
      nsc = 1ul<<((CHAR_BIT*sizeof(devinfo->keymap[0][0]))-1);

      for (sc = 0, j = 0; sc < nsc; ++sc) {

        int map[2] = {sc, 0};

        int res = ioctl(fd, EVIOCGKEYCODE, map);

        if (res < 0) {
          if (errno != EINVAL) {
            fprintf(stderr, "ioctl: %s\n", strerror(errno));
            goto err_ioctl;
          }
        } else {
          /* save mapping */

          devinfo->keymap[j][0] = map[0]; /* scan code */
          devinfo->keymap[j][1] = map[1]; /* key code */
          ++j;

          if (j >= sizeof(devinfo->keymap)/sizeof(devinfo->keymap[0])) {
            break;
          }
        }
      }
    }
  }

  /* relative positioning */

  if (TEST_ARRAY_BIT(devinfo->evbit, EV_REL)) {
    if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(devinfo->relbit)), devinfo->relbit) < 0) {
      fprintf(stderr, "ioctl(EVIOCGBIT(EV_REL)): %s\n", strerror(errno));
      goto err_ioctl;
    }
  }

  /* absolute positioning */

  if (TEST_ARRAY_BIT(devinfo->evbit, EV_ABS)) {
    if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(devinfo->absbit)), devinfo->absbit) < 0) {
      fprintf(stderr, "ioctl(EVIOCGBIT(EV_ABS)): %s\n", strerror(errno));
      goto err_ioctl;
    }

    /* limits */

    for (i = 0; i <= ABS_MAX; ++i) {
      if (TEST_ARRAY_BIT(devinfo->absbit, i)) {
        if (ioctl(fd, EVIOCGABS(i), devinfo->absinfo+i) < 0) {
          fprintf(stderr, "ioctl(EVIOCGABS(%d)): %s\n", i, strerror(errno));
          goto err_ioctl;
        }
      }
    }
  }

  /* misc */

  if (TEST_ARRAY_BIT(devinfo->evbit, EV_MSC)) {
    if (ioctl(fd, EVIOCGBIT(EV_MSC, sizeof(devinfo->mscbit)), devinfo->mscbit) < 0) {
      fprintf(stderr, "ioctl(EVIOCGBIT(EV_MSC)): %s\n", strerror(errno));
      goto err_ioctl;
    }
  }

  /* LEDs */

  if (TEST_ARRAY_BIT(devinfo->evbit, EV_LED)) {
    if (ioctl(fd, EVIOCGBIT(EV_LED, sizeof(devinfo->ledbit)), devinfo->ledbit) < 0) {
      fprintf(stderr, "ioctl(EVIOCGBIT(EV_LED)): %s\n", strerror(errno));
      goto err_ioctl;
    }

    /* LED state */

    if (TEST_ARRAY_BIT(devinfo->evbit, EV_LED)) {
      if (ioctl(fd, EVIOCGLED(sizeof(devinfo->led)), devinfo->led) < 0) {
        fprintf(stderr, "ioctl(EVIOCGLED(%zu)): %s\n",
                sizeof(buf), strerror(errno));
        goto err_ioctl;
      }
    }
  }

  /* sound */

  if (TEST_ARRAY_BIT(devinfo->evbit, EV_SND)) {
    if (ioctl(fd, EVIOCGBIT(EV_SND, sizeof(devinfo->sndbit)), devinfo->sndbit) < 0) {
      fprintf(stderr, "ioctl(EVIOCGBIT(EV_SND)): %s\n", strerror(errno));
      goto err_ioctl;
    }

    /* sound state */

    if (TEST_ARRAY_BIT(devinfo->evbit, EV_SW)) {
      if (ioctl(fd, EVIOCGSND(sizeof(devinfo->snd)), devinfo->snd) < 0) {
        fprintf(stderr, "ioctl(EVIOCGSND(%zu)): %s\n",
                sizeof(buf), strerror(errno));
        goto err_ioctl;
      }
    }
  }

  /* force feedback */

  if (TEST_ARRAY_BIT(devinfo->evbit, EV_FF)) {
    if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(devinfo->ffbit)), devinfo->ffbit) < 0) {
      fprintf(stderr, "ioctl(EVIOCGBIT(EV_FF)): %s\n", strerror(errno));
      goto err_ioctl;
    }
  }

  /* switches */

  if (TEST_ARRAY_BIT(devinfo->evbit, EV_SW)) {
    if (ioctl(fd, EVIOCGBIT(EV_SW, sizeof(devinfo->swbit)), devinfo->swbit) < 0) {
      fprintf(stderr, "ioctl(EVIOCGBIT(EV_SW)): %s\n", strerror(errno));
      goto err_ioctl;
    }

    /* switch state */

    if (TEST_ARRAY_BIT(devinfo->evbit, EV_SW)) {
      if (ioctl(fd, EVIOCGSW(sizeof(devinfo->sw)), devinfo->sw) < 0) {
        fprintf(stderr, "ioctl(EVIOCGSW(%zu)): %s\n",
                sizeof(buf), strerror(errno));
        goto err_ioctl;
      }
    }
  }

  /* auto repeat */

  if (TEST_ARRAY_BIT(devinfo->evbit, EV_REP)) {
    if (ioctl(fd, EVIOCGREP, devinfo->rep) < 0) {
      fprintf(stderr, "ioctl(EVIOCGREP): %s\n", strerror(errno));
      goto err_ioctl;
    }
  }

  /* name */

  memset(buf, 0, sizeof(buf));

  do {
    res = ioctl(fd, EVIOCGNAME(sizeof(buf)), buf);
  } while ((res < 0) && (errno == EINTR));

  if (res >= 0) {
    devinfo->name = strndup(buf, sizeof(buf)-1);

    if (!devinfo->name) {
      fprintf(stderr, "strdup: %s\n", strerror(errno));
      goto err_strdup_name;
    }
  } else if (errno != ENOENT) {
    fprintf(stderr, "ioctl(EVIOCGPHYS(%lu)): %s\n",
            (unsigned long)sizeof(buf), strerror(errno));
    goto err_ioctl;
  }

  /* physical location */

  memset(buf, 0, sizeof(buf));

  do {
    res = ioctl(fd, EVIOCGPHYS(sizeof(buf)), buf);
  } while ((res < 0) && (errno == EINTR));

  if (res >= 0) {
    devinfo->phys = strndup(buf, sizeof(buf)-1);

    if (!devinfo->phys) {
      fprintf(stderr, "strdup: %s\n", strerror(errno));
      goto err_strdup_phys;
    }
  } else if (errno != ENOENT) {
    fprintf(stderr, "ioctl(EVIOCGPHYS(%lu)): %s\n",
            (unsigned long)sizeof(buf), strerror(errno));
    goto err_ioctl;
  }

  /* unique identifier */

  memset(buf, 0, sizeof(buf));

  do {
    res = ioctl(fd, EVIOCGUNIQ(sizeof(buf)), buf);
  } while ((res < 0) && (errno == EINTR));

  if (res >= 0) {
    devinfo->uniq = strndup(buf, sizeof(buf)-1);

    if (!devinfo->uniq) {
      fprintf(stderr, "strdup: %s\n", strerror(errno));
      goto err_strdup_uniq;
    }
  } else if (errno != ENOENT) {
    fprintf(stderr, "ioctl(EVIOCGUNIQ(%lu)): %s\n",
            (unsigned long)sizeof(buf), strerror(errno));
    goto err_ioctl;
  }

  return devinfo;

err_strdup_uniq:
  free(devinfo->phys);
err_strdup_phys:
err_ioctl_gphys:
  free(devinfo->name);
err_strdup_name:
err_ioctl:
  return NULL;
}
Esempio n. 18
0
EvdevDevice::EvdevDevice(const std::string& filename)
  : device(filename)
{
  fd = open(device.c_str(), O_RDONLY | O_NONBLOCK);

  if (fd == -1)
    {
      throw std::runtime_error(filename + ": " + std::string(strerror(errno)));
    }

  if (ioctl(fd, EVIOCGVERSION, &version)) 
    {
      throw std::runtime_error("Error: EvdevDevice: Couldn't get version for " + filename);
    }

  if (1)
    { // FIXME: Some versions of linux don't have these structs, use arrays there
      struct input_id id;
      ioctl(fd, EVIOCGID, &id);
      printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
             id.bustype, id.vendor, id.product, id.vendor);
    }

  {  // Get the human readable name
    char c_name[256] = "unknown";
    ioctl(fd, EVIOCGNAME(sizeof(c_name)), c_name);
    name = c_name;
    std::cout << "Name: " << name << std::endl;
  }

  { // Read in how many buttons the device has
    unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
    memset(bit, 0, sizeof(bit));
    ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);

    for (int i = 0; i < EV_MAX; i++)
      {
        if (test_bit(i, bit[0])) 
          {
            //printf("  Event type %d (%s)\n", i, events[i] ? events[i] : "?");
				
            if (!i) continue;

            ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
            for (int j = 0; j < KEY_MAX; j++) 
              {
                if (test_bit(j, bit[i])) 
                  {
                    if (i == EV_KEY) 
                      { 
                        keys.push_back(Key(j));
                      } 
                    else if (i == EV_ABS)
                      { 
                        // FIXME: Some Linuxes don't have these struct
                        struct input_absinfo absinfo;
                        ioctl(fd, EVIOCGABS(j), &absinfo);
                        // FIXME: we are ignoring absinfo.fuzz and
                        // absinfo.flat = deadzone
                        // absinfo.fuzz = values in which range can be considered the same (jitter)
                        absolutes.push_back(Absolute(j, absinfo.minimum, absinfo.maximum, absinfo.value));
                      }
                    else if (i == EV_REL) 
                      {
                        relatives.push_back(Relative(j));
                      }
                  }
              }
          }
      }
  }
}
void swipe_handle_input(int fd, struct input_event *ev) {
    int abs_store[6] = {0};
    int k;

    ioctl(fd, EVIOCGABS(ABS_MT_POSITION_X), abs_store);
    int max_x_touch = abs_store[2];

    ioctl(fd, EVIOCGABS(ABS_MT_POSITION_Y), abs_store);
    int max_y_touch = abs_store[2];

    if(ev->type == EV_ABS && ev->code == ABS_MT_TRACKING_ID) {
        if(in_touch == 0) {
            in_touch = 1;
            reset_gestures();
        } else { // finger lifted
            ev->type = EV_KEY;
            int keywidth = gr_fb_width() / 4;
            if(slide_right == 1) {
                ev->code = KEY_POWER;
                slide_right = 0;
            } else if(slide_left == 1) {
                ev->code = KEY_BACK;
                slide_left = 0;
            }

            ev->value = 1;
            in_touch = 0;
            reset_gestures();
        }
    } else if(ev->type == EV_ABS && ev->code == ABS_MT_POSITION_X) {
        old_x = touch_x;
        float touch_x_rel = (float)ev->value / (float)max_x_touch;
        touch_x = touch_x_rel * gr_fb_width();

        if(old_x != 0) diff_x += touch_x - old_x;

        if(diff_x > 100) {
            slide_right = 1;
            reset_gestures();
        } else if(diff_x < -100) {
            slide_left = 1;
            reset_gestures();
        }
    } else if(ev->type == EV_ABS && ev->code == ABS_MT_POSITION_Y) {
        old_y = touch_y;
        float touch_y_rel = (float)ev->value / (float)max_y_touch;
        touch_y = touch_y_rel * gr_fb_height();

        if(old_y != 0) diff_y += touch_y - old_y;

        if(diff_y > 80) {
            ev->code = KEY_VOLUMEDOWN;
            ev->type = EV_KEY;
            reset_gestures();
        } else if(diff_y < -80) {
            ev->code = KEY_VOLUMEUP;
            ev->type = EV_KEY;
            reset_gestures();
        }
    }

    return;
}
Esempio n. 20
0
static bool enumerateAxesEvdev(int fd, axes_t *axes)
{
  //printf("Enumerating evdev axes\n");
  uint8_t bit[KEY_MAX / 8 + 1];
  memset(bit, 0, sizeof(bit));
  if(ioctl(fd, EVIOCGBIT(0, EV_MAX), bit) < 0){
    ltr_int_my_perror("EVIOCGBIT_1");
    return false;
  }
  int type;

  if(!(bit[0] & (1 << EV_ABS))){
    //printf("No absolute events available.\n");
    return false;
  }
  //printf("We have absolute events available!\n");
  //We have some absolute axes
  memset(bit, 0, sizeof(bit));
  if(ioctl(fd, EVIOCGBIT(EV_ABS, KEY_MAX), bit) < 0){
    ltr_int_my_perror("EVIOCGBIT_2");
    return false;
  }
  //Get axes number
  axes->axes = 0;
  for(type = 0; type < KEY_MAX; ++type){
    if(bit[type >> 3] & (1 << (type & 7))){
      ++axes->axes;
    }
  }
  if((axes->axesList = (uint8_t*)malloc(axes->axes * sizeof(uint8_t))) == NULL){
    ltr_int_my_perror("malloc");
    return false;
  }
  memset(axes->axesList, 0, axes->axes);
  if((axes->axisNames = (const char**)malloc(axes->axes * sizeof(char*))) == NULL){
    ltr_int_my_perror("malloc");
    return false;
  }
  if((axes->min = (int*)malloc(axes->axes * sizeof(int))) == NULL){
    ltr_int_my_perror("malloc");
    return false;
  }
  if((axes->max = (int*)malloc(axes->axes * sizeof(int))) == NULL){
    ltr_int_my_perror("malloc");
    return false;
  }
  size_t current = 0;
  for(type = 0; type < KEY_MAX; ++type){
    if(bit[type >> 3] & (1 << (type & 7))){
      axes->axesList[current] = type;
      axes->axisNames[current] = getAxisName(type);

      struct input_absinfo ai = {0};

      if(ioctl(fd, EVIOCGABS(type), &ai) < 0){
        ltr_int_my_perror("EVIOCGABS");
        free(axes->axesList);
        free(axes->min);
        free(axes->max);
        axes->axesList = NULL;
        axes->min = NULL;
        axes->max = NULL;
        axes->axes = 0;
        return false;
      }

      ltr_int_log_message("Axis: %d (%s)\n", type, getAxisName(type));
      ltr_int_log_message("  Val: %d\n", ai.value);
      ltr_int_log_message("  Minimum: %d\n", ai.minimum);
      ltr_int_log_message("  Maximum: %d\n", ai.maximum);
      ltr_int_log_message("  Fuzz: %d\n", ai.fuzz);
      ltr_int_log_message("  Flat: %d\n", ai.flat);
      ltr_int_log_message("  Resolution: %d\n", ai.resolution);

      axes->min[current] = ai.minimum;
      axes->max[current] = ai.maximum;
      ++current;
    }
  }
  return true;
}
AkmSensor::AkmSensor()
: SensorBase(NULL, NULL),
      mEnabled(0),
      mPendingMask(0),
      mInputReader(32)
{
    /* Open the library before opening the input device.  The library
     * creates a uinput device.
     */
    if (loadAKMLibrary() == 0) {
        data_name = "compass_sensor";
        data_fd = openInput("compass_sensor");
    }

    memset(mPendingEvents, 0, sizeof(mPendingEvents));

    mPendingEvents[Accelerometer].version = sizeof(sensors_event_t);
    mPendingEvents[Accelerometer].sensor = ID_A;
    mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER;
    mPendingEvents[Accelerometer].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;

    mPendingEvents[MagneticField].version = sizeof(sensors_event_t);
    mPendingEvents[MagneticField].sensor = ID_M;
    mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD;
    mPendingEvents[MagneticField].magnetic.status = SENSOR_STATUS_ACCURACY_HIGH;

    mPendingEvents[Orientation  ].version = sizeof(sensors_event_t);
    mPendingEvents[Orientation  ].sensor = ID_O;
    mPendingEvents[Orientation  ].type = SENSOR_TYPE_ORIENTATION;
    mPendingEvents[Orientation  ].orientation.status = SENSOR_STATUS_ACCURACY_HIGH;

    // read the actual value of all sensors if they're enabled already
    struct input_absinfo absinfo;
    short flags = 0;

    if (akm_is_sensor_enabled(SENSOR_TYPE_ACCELEROMETER))  {
        mEnabled |= 1<<Accelerometer;
        if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ACCEL_X), &absinfo)) {
            mPendingEvents[Accelerometer].acceleration.x = absinfo.value * CONVERT_A_X;
        }
        if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Y), &absinfo)) {
            mPendingEvents[Accelerometer].acceleration.y = absinfo.value * CONVERT_A_Y;
        }
        if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Z), &absinfo)) {
            mPendingEvents[Accelerometer].acceleration.z = absinfo.value * CONVERT_A_Z;
        }
    }
    if (akm_is_sensor_enabled(SENSOR_TYPE_MAGNETIC_FIELD))  {
        mEnabled |= 1<<MagneticField;
        if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_MAGV_X), &absinfo)) {
            mPendingEvents[MagneticField].magnetic.x = absinfo.value * CONVERT_M_X;
        }
        if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_MAGV_Y), &absinfo)) {
            mPendingEvents[MagneticField].magnetic.y = absinfo.value * CONVERT_M_Y;
        }
        if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_MAGV_Z), &absinfo)) {
            mPendingEvents[MagneticField].magnetic.z = absinfo.value * CONVERT_M_Z;
        }
    }
    if (akm_is_sensor_enabled(SENSOR_TYPE_ORIENTATION))  {
        mEnabled |= 1<<Orientation;
        if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_YAW), &absinfo)) {
            mPendingEvents[Orientation].orientation.azimuth = absinfo.value;
        }
        if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_PITCH), &absinfo)) {
            mPendingEvents[Orientation].orientation.pitch = absinfo.value;
        }
        if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ROLL), &absinfo)) {
            mPendingEvents[Orientation].orientation.roll = -absinfo.value;
        }
        if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ORIENT_STATUS), &absinfo)) {
            mPendingEvents[Orientation].orientation.status = uint8_t(absinfo.value & SENSOR_STATE_MASK);
        }
    }

    // disable temperature sensor, since it is not supported
    akm_disable_sensor(SENSOR_TYPE_TEMPERATURE);
}
Esempio n. 22
0
// Get the event types and event codes that the input device supports
static PyObject *
ioctl_capabilities(PyObject *self, PyObject *args)
{
    int fd, ev_type, ev_code;
    char ev_bits[EV_MAX/8 + 1], code_bits[KEY_MAX/8 + 1];
    struct input_absinfo absinfo;

    int ret = PyArg_ParseTuple(args, "i", &fd);
    if (!ret) return NULL;

    // @todo: figure out why fd gets zeroed on an ioctl after the
    // refactoring and get rid of this workaround
    const int _fd = fd;

    // Capabilities is a mapping of supported event types to lists of handled
    // events e.g: {1: [272, 273, 274, 275], 2: [0, 1, 6, 8]}
    PyObject* capabilities = PyDict_New();
    PyObject* eventcodes = NULL;
    PyObject* evlong = NULL;
    PyObject* capability = NULL;
    PyObject* py_absinfo = NULL;
    PyObject* absitem = NULL;

    memset(&ev_bits, 0, sizeof(ev_bits));

    if (ioctl(_fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) < 0)
        goto on_err;

    // Build a dictionary of the device's capabilities
    for (ev_type=0 ; ev_type<EV_MAX ; ev_type++) {
        if (test_bit(ev_bits, ev_type)) {

            capability = PyLong_FromLong(ev_type);
            eventcodes = PyList_New(0);

            memset(&code_bits, 0, sizeof(code_bits));
            ioctl(_fd, EVIOCGBIT(ev_type, sizeof(code_bits)), code_bits);

            for (ev_code = 0; ev_code < KEY_MAX; ev_code++) {
                if (test_bit(code_bits, ev_code)) {
                    // Get abs{min,max,fuzz,flat} values for ABS_* event codes
                    if (ev_type == EV_ABS) {
                        memset(&absinfo, 0, sizeof(absinfo));
                        ioctl(_fd, EVIOCGABS(ev_code), &absinfo);

                        py_absinfo = Py_BuildValue("(iiiiii)",
                                                   absinfo.value,
                                                   absinfo.minimum,
                                                   absinfo.maximum,
                                                   absinfo.fuzz,
                                                   absinfo.flat,
                                                   absinfo.resolution);

                        evlong = PyLong_FromLong(ev_code);
                        absitem = Py_BuildValue("(OO)", evlong, py_absinfo);

                        // absitem -> tuple(ABS_X, (0, 255, 0, 0))
                        PyList_Append(eventcodes, absitem);

                        Py_DECREF(absitem);
                        Py_DECREF(py_absinfo);
                    }
                    else {
                        evlong = PyLong_FromLong(ev_code);
                        PyList_Append(eventcodes, evlong);
                    }

                    Py_DECREF(evlong);
                }
            }
            // capabilities[EV_KEY] = [KEY_A, KEY_B, KEY_C, ...]
            // capabilities[EV_ABS] = [(ABS_X, (0, 255, 0, 0)), ...]
            PyDict_SetItem(capabilities, capability, eventcodes);

            Py_DECREF(capability);
            Py_DECREF(eventcodes);
        }
    }

    return capabilities;

    on_err:
        PyErr_SetFromErrno(PyExc_IOError);
        return NULL;
}
Esempio n. 23
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 */
}
Esempio n. 24
0
static void find_joydevs(void)
{
  int i;

  if (have_joydevs!=-1) {
    return;
  }

  have_joydevs = 0;

  for (i=0;i<MAX_JOYDEV;i++) {
    char	buf[MAX_PATH];
    struct JoyDev joydev = {0};
    int fd;
    int no_ff_check = 0;
    int j;

    snprintf(buf,MAX_PATH,EVDEVPREFIX"%d",i);
    buf[MAX_PATH-1] = 0;

    if ((fd=open(buf, O_RDWR))==-1) {
      fd = open(buf, O_RDONLY);
      no_ff_check = 1;
    }

    if (fd!=-1) {

      if ((-1==ioctl(fd,EVIOCGBIT(0,sizeof(joydev.evbits)),joydev.evbits))) {
        perror("EVIOCGBIT 0");
        close(fd);
        continue; 
      }
      if (-1==ioctl(fd,EVIOCGBIT(EV_ABS,sizeof(joydev.absbits)),joydev.absbits)) {
        perror("EVIOCGBIT EV_ABS");
        close(fd);
        continue;
      }
      if (-1==ioctl(fd,EVIOCGBIT(EV_KEY,sizeof(joydev.keybits)),joydev.keybits)) {
        perror("EVIOCGBIT EV_KEY");
        close(fd);
        continue;
      }
      /* A true joystick has at least axis X and Y, and at least 1
       * button. copied from linux/drivers/input/joydev.c */
      if (test_bit(joydev.absbits,ABS_X) && test_bit(joydev.absbits,ABS_Y) &&
          (   test_bit(joydev.keybits,BTN_TRIGGER)	||
              test_bit(joydev.keybits,BTN_A) 	||
              test_bit(joydev.keybits,BTN_1)
          )
         ) {

        joydev.device = strdup(buf);

        if (-1!=ioctl(fd, EVIOCGNAME(MAX_PATH-1), buf)) {
          buf[MAX_PATH-1] = 0;
          joydev.name = strdup(buf);
        } else {
          joydev.name = joydev.device;
        }

	joydev.guid = DInput_Wine_Joystick_Base_GUID;
	joydev.guid.Data3 += have_joydevs;

        TRACE("Found a joystick on %s: %s (%s)\n", 
            joydev.device, joydev.name, 
            debugstr_guid(&joydev.guid)
            );

#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
        if (!no_ff_check &&
            test_bit(joydev.evbits, EV_FF) &&
            ioctl(fd, EVIOCGBIT(EV_FF, sizeof(joydev.ffbits)), joydev.ffbits) != -1 &&
            ioctl(fd, EVIOCGEFFECTS, &joydev.num_effects) != -1 &&
            joydev.num_effects > 0)
        {
	    TRACE(" ... with force feedback\n");
	    joydev.has_ff = 1;
        }
#endif

	for (j=0;j<ABS_MAX;j++) {
	  if (test_bit(joydev.absbits,j)) {
	    if (-1!=ioctl(fd,EVIOCGABS(j),&(joydev.axes[j]))) {
	      TRACE(" ... with axis %d: cur=%d, min=%d, max=%d, fuzz=%d, flat=%d\n",
		  j,
		  joydev.axes[j].value,
		  joydev.axes[j].minimum,
		  joydev.axes[j].maximum,
		  joydev.axes[j].fuzz,
		  joydev.axes[j].flat
		  );
	    }
	  }
	}

	if (have_joydevs==0) {
	  joydevs = HeapAlloc(GetProcessHeap(), 0, sizeof(struct JoyDev));
	} else {
	  HeapReAlloc(GetProcessHeap(), 0, joydevs, (1+have_joydevs) * sizeof(struct JoyDev));
	}
	memcpy(joydevs+have_joydevs, &joydev, sizeof(struct JoyDev));
        have_joydevs++;
      }

      close(fd);
    }
  }
}
Esempio n. 25
0
AkmSensor::AkmSensor()
: SensorBase(AKM_DEVICE_NAME, "compass"),
      mEnabled(0),
      mPendingMask(0),
      mInputReader(32)
{
    memset(mPendingEvents, 0, sizeof(mPendingEvents));

    mPendingEvents[Accelerometer].version = sizeof(sensors_event_t);
    mPendingEvents[Accelerometer].sensor = ID_A;
    mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER;
    mPendingEvents[Accelerometer].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;

    mPendingEvents[MagneticField].version = sizeof(sensors_event_t);
    mPendingEvents[MagneticField].sensor = ID_M;
    mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD;
    mPendingEvents[MagneticField].magnetic.status = SENSOR_STATUS_ACCURACY_HIGH;

    mPendingEvents[Orientation  ].version = sizeof(sensors_event_t);
    mPendingEvents[Orientation  ].sensor = ID_O;
    mPendingEvents[Orientation  ].type = SENSOR_TYPE_ORIENTATION;
    mPendingEvents[Orientation  ].orientation.status = SENSOR_STATUS_ACCURACY_HIGH;

    for (int i=0 ; i<numSensors ; i++)
        mDelays[i] = 200000000; // 200 ms by default

    // read the actual value of all sensors if they're enabled already
    struct input_absinfo absinfo;
    short flags = 0;

    open_device();

    if (!ioctl(dev_fd, ECS_IOCTL_APP_GET_AFLAG, &flags)) {
        if (flags)  {
            mEnabled |= 1<<Accelerometer;
            if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ACCEL_X), &absinfo)) {
                mPendingEvents[Accelerometer].acceleration.x = absinfo.value * CONVERT_A_X;
            }
            if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Y), &absinfo)) {
                mPendingEvents[Accelerometer].acceleration.y = absinfo.value * CONVERT_A_Y;
            }
            if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Z), &absinfo)) {
                mPendingEvents[Accelerometer].acceleration.z = absinfo.value * CONVERT_A_Z;
            }
        }
    }
    if (!ioctl(dev_fd, ECS_IOCTL_APP_GET_MVFLAG, &flags)) {
        if (flags)  {
            mEnabled |= 1<<MagneticField;
            if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_MAGV_X), &absinfo)) {
                mPendingEvents[MagneticField].magnetic.x = absinfo.value * CONVERT_M_X;
            }
            if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_MAGV_Y), &absinfo)) {
                mPendingEvents[MagneticField].magnetic.y = absinfo.value * CONVERT_M_Y;
            }
            if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_MAGV_Z), &absinfo)) {
                mPendingEvents[MagneticField].magnetic.z = absinfo.value * CONVERT_M_Z;
            }
        }
    }
    if (!ioctl(dev_fd, ECS_IOCTL_APP_GET_MFLAG, &flags)) {
        if (flags)  {
            mEnabled |= 1<<Orientation;
            if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_YAW), &absinfo)) {
                mPendingEvents[Orientation].orientation.azimuth = absinfo.value;
            }
            if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_PITCH), &absinfo)) {
                mPendingEvents[Orientation].orientation.pitch = absinfo.value;
            }
            if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ROLL), &absinfo)) {
                mPendingEvents[Orientation].orientation.roll = -absinfo.value;
            }
            if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ORIENT_STATUS), &absinfo)) {
                mPendingEvents[Orientation].orientation.status = uint8_t(absinfo.value & SENSOR_STATE_MASK);
            }
        }
    }

    // disable temperature sensor, since it is not reported
    flags = 0;
    ioctl(dev_fd, ECS_IOCTL_APP_SET_TFLAG, &flags);

    if (!mEnabled) {
        close_device();
    }
}
Esempio n. 26
0
static void
ConfigJoystick(SDL_Joystick * joystick, int fd)
{
    int i, t;
    unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
    unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
    unsigned long relbit[NBITS(REL_MAX)] = { 0 };

    /* See if this device uses the new unified event API */
    if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
        (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&
        (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0)) {

        /* Get the number of buttons, axes, and other thingamajigs */
        for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
            if (test_bit(i, keybit)) {
#ifdef DEBUG_INPUT_EVENTS
                printf("Joystick has button: 0x%x\n", i);
#endif
                joystick->hwdata->key_map[i] = joystick->nbuttons;
                ++joystick->nbuttons;
            }
        }
        for (i = 0; i < BTN_JOYSTICK; ++i) {
            if (test_bit(i, keybit)) {
#ifdef DEBUG_INPUT_EVENTS
                printf("Joystick has button: 0x%x\n", i);
#endif
                joystick->hwdata->key_map[i] = joystick->nbuttons;
                ++joystick->nbuttons;
            }
        }
        for (i = 0; i < ABS_MAX; ++i) {
            /* Skip hats */
            if (i == ABS_HAT0X) {
                i = ABS_HAT3Y;
                continue;
            }
            if (test_bit(i, absbit)) {
                struct input_absinfo absinfo;

                if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0) {
                    continue;
                }
#ifdef DEBUG_INPUT_EVENTS
                printf("Joystick has absolute axis: 0x%.2x\n", i);
                printf("Values = { %d, %d, %d, %d, %d }\n",
                       absinfo.value, absinfo.minimum, absinfo.maximum,
                       absinfo.fuzz, absinfo.flat);
#endif /* DEBUG_INPUT_EVENTS */
                joystick->hwdata->abs_map[i] = joystick->naxes;
                if (absinfo.minimum == absinfo.maximum) {
                    joystick->hwdata->abs_correct[i].used = 0;
                } else {
                    joystick->hwdata->abs_correct[i].used = 1;
                    joystick->hwdata->abs_correct[i].coef[0] =
                        (absinfo.maximum + absinfo.minimum) - 2 * absinfo.flat;
                    joystick->hwdata->abs_correct[i].coef[1] =
                        (absinfo.maximum + absinfo.minimum) + 2 * absinfo.flat;
                    t = ((absinfo.maximum - absinfo.minimum) - 4 * absinfo.flat);
                    if (t != 0) {
                        joystick->hwdata->abs_correct[i].coef[2] =
                            (1 << 28) / t;
                    } else {
                        joystick->hwdata->abs_correct[i].coef[2] = 0;
                    }
                }
                ++joystick->naxes;
            }
        }
        for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) {
            if (test_bit(i, absbit) || test_bit(i + 1, absbit)) {
                struct input_absinfo absinfo;

                if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0) {
                    continue;
                }
#ifdef DEBUG_INPUT_EVENTS
                printf("Joystick has hat %d\n", (i - ABS_HAT0X) / 2);
                printf("Values = { %d, %d, %d, %d, %d }\n",
                       absinfo.value, absinfo.minimum, absinfo.maximum,
                       absinfo.fuzz, absinfo.flat);
#endif /* DEBUG_INPUT_EVENTS */
                ++joystick->nhats;
            }
        }
        if (test_bit(REL_X, relbit) || test_bit(REL_Y, relbit)) {
            ++joystick->nballs;
        }

        /* Allocate data to keep track of these thingamajigs */
        if (joystick->nhats > 0) {
            if (allocate_hatdata(joystick) < 0) {
                joystick->nhats = 0;
            }
        }
        if (joystick->nballs > 0) {
            if (allocate_balldata(joystick) < 0) {
                joystick->nballs = 0;
            }
        }
    }
}
static int vk_init(struct ev *e)
{
    char vk_path[PATH_MAX] = "/sys/board_properties/virtualkeys.";
    char vks[2048], *ts = NULL;
    ssize_t len;
    int vk_fd;
    int i;

    e->vk_count = 0;

    len = strlen(vk_path);
    len = ioctl(e->fd->fd, EVIOCGNAME(sizeof(e->deviceName)), e->deviceName);
    if (len <= 0)
    {
        printf("Unable to query event object.\n");
        return -1;
    }
#ifdef _EVENT_LOGGING
    printf("Event object: %s\n", e->deviceName);
#endif

    // Blacklist these "input" devices
    if (strcmp(e->deviceName, "bma250") == 0 || strcmp(e->deviceName, "bma150") == 0 || strcmp(e->deviceName, "accelerometer") == 0)
    {
        e->ignored = 1;
    }

    strcat(vk_path, e->deviceName);

    // Some devices split the keys from the touchscreen
    e->vk_count = 0;
    vk_fd = open(vk_path, O_RDONLY);
    if (vk_fd >= 0)
    {
        len = read(vk_fd, vks, sizeof(vks)-1);
        close(vk_fd);
        if (len <= 0)
            return -1;

        vks[len] = '\0';

        /* Parse a line like:
            keytype:keycode:centerx:centery:width:height:keytype2:keycode2:centerx2:...
        */
        for (ts = vks, e->vk_count = 1; *ts; ++ts) {
            if (*ts == ':')
                ++e->vk_count;
        }

        if (e->vk_count % 6) {
            printf("minui: %s is %d %% 6\n", vk_path, e->vk_count % 6);
        }
        e->vk_count /= 6;
        if (e->vk_count <= 0)
            return -1;

        e->down = DOWN_NOT;
    }

    ioctl(e->fd->fd, EVIOCGABS(ABS_X), &e->p.xi);
    ioctl(e->fd->fd, EVIOCGABS(ABS_Y), &e->p.yi);
    e->p.synced = 0;
#ifdef _EVENT_LOGGING
    printf("EV: ST minX: %d  maxX: %d  minY: %d  maxY: %d\n", e->p.xi.minimum, e->p.xi.maximum, e->p.yi.minimum, e->p.yi.maximum);
#endif

    ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_X), &e->mt_p.xi);
    ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_Y), &e->mt_p.yi);
    e->mt_p.synced = 0;
#ifdef _EVENT_LOGGING
    printf("EV: MT minX: %d  maxX: %d  minY: %d  maxY: %d\n", e->mt_p.xi.minimum, e->mt_p.xi.maximum, e->mt_p.yi.minimum, e->mt_p.yi.maximum);
#endif

    e->vks = malloc(sizeof(*e->vks) * e->vk_count);

    for (i = 0; i < e->vk_count; ++i) {
        char *token[6];
        int j;

        for (j = 0; j < 6; ++j) {
            token[j] = vk_strtok_r((i||j)?NULL:vks, ":", &ts);
        }

        if (strcmp(token[0], "0x01") != 0) {
            /* Java does string compare, so we do too. */
            printf("minui: %s: ignoring unknown virtual key type %s\n", vk_path, token[0]);
            continue;
        }

        e->vks[i].scancode = strtol(token[1], NULL, 0);
        e->vks[i].centerx = strtol(token[2], NULL, 0);
        e->vks[i].centery = strtol(token[3], NULL, 0);
        e->vks[i].width = strtol(token[4], NULL, 0);
        e->vks[i].height = strtol(token[5], NULL, 0);
    }

    return 0;
}
Esempio n. 28
0
static int print_possible_events(int fd, int print_flags)
{
    uint8_t *bits = NULL;
    ssize_t bits_size = 0;
    const char* label;
    int i, j, k;
    int res, res2;
    struct label* bit_labels;
    const char *bit_label;

    printf("  events:\n");
    for(i = EV_KEY; i <= EV_MAX; i++) { // skip EV_SYN since we cannot query its available codes
        int count = 0;
        while(1) {
            res = ioctl(fd, EVIOCGBIT(i, bits_size), bits);
            if(res < bits_size)
                break;
            bits_size = res + 16;
            bits = realloc(bits, bits_size * 2);
            if(bits == NULL)
                err(1, "failed to allocate buffer of size %d\n", (int)bits_size);
        }
        res2 = 0;
        switch(i) {
            case EV_KEY:
                res2 = ioctl(fd, EVIOCGKEY(res), bits + bits_size);
                label = "KEY";
                bit_labels = key_labels;
                break;
            case EV_REL:
                label = "REL";
                bit_labels = rel_labels;
                break;
            case EV_ABS:
                label = "ABS";
                bit_labels = abs_labels;
                break;
            case EV_MSC:
                label = "MSC";
                bit_labels = msc_labels;
                break;
            case EV_LED:
                res2 = ioctl(fd, EVIOCGLED(res), bits + bits_size);
                label = "LED";
                bit_labels = led_labels;
                break;
            case EV_SND:
                res2 = ioctl(fd, EVIOCGSND(res), bits + bits_size);
                label = "SND";
                bit_labels = snd_labels;
                break;
            case EV_SW:
                res2 = ioctl(fd, EVIOCGSW(bits_size), bits + bits_size);
                label = "SW ";
                bit_labels = sw_labels;
                break;
            case EV_REP:
                label = "REP";
                bit_labels = rep_labels;
                break;
            case EV_FF:
                label = "FF ";
                bit_labels = ff_labels;
                break;
            case EV_PWR:
                label = "PWR";
                bit_labels = NULL;
                break;
            case EV_FF_STATUS:
                label = "FFS";
                bit_labels = ff_status_labels;
                break;
            default:
                res2 = 0;
                label = "???";
                bit_labels = NULL;
        }
        for(j = 0; j < res; j++) {
            for(k = 0; k < 8; k++)
                if(bits[j] & 1 << k) {
                    char down;
                    if(j < res2 && (bits[j + bits_size] & 1 << k))
                        down = '*';
                    else
                        down = ' ';
                    if(count == 0)
                        printf("    %s (%04x):", label, i);
                    else if((count & (print_flags & PRINT_LABELS ? 0x3 : 0x7)) == 0 || i == EV_ABS)
                        printf("\n               ");
                    if(bit_labels && (print_flags & PRINT_LABELS)) {
                        bit_label = get_label(bit_labels, j * 8 + k);
                        if(bit_label)
                            printf(" %.20s%c%*s", bit_label, down, (int) (20 - strlen(bit_label)), "");
                        else
                            printf(" %04x%c                ", j * 8 + k, down);
                    } else {
                        printf(" %04x%c", j * 8 + k, down);
                    }
                    if(i == EV_ABS) {
                        struct input_absinfo abs;
                        if(ioctl(fd, EVIOCGABS(j * 8 + k), &abs) == 0) {
                            printf(" : value %d, min %d, max %d, fuzz %d, flat %d, resolution %d",
                                abs.value, abs.minimum, abs.maximum, abs.fuzz, abs.flat,
                                abs.resolution);
                        }
                    }
                    count++;
                }
        }
        if(count)
            printf("\n");
    }
    free(bits);
    return 0;
}
Esempio n. 29
0
int evio_get_spaceball_status(evio_handle v,
                              int *rel_x,
                              int *rel_y,
                              int *rel_z,
                              int *rel_rx,
                              int *rel_ry,
                              int *rel_rz,
                              int *buttons) {
  struct input_absinfo absinfo;
  evio *evp = (evio *) v;
  int rc=0;

  *rel_x = 0;
  *rel_y = 0;
  *rel_z = 0;
  *rel_rx = 0;
  *rel_ry = 0;
  *rel_rz = 0;
  *buttons = 0;

  memset(&absinfo, 0, sizeof(absinfo));

  if (ioctl(evp->fd, EVIOCGABS(REL_X), &absinfo) < 0) {
    return 0;
  } else {
    rc |= 1;
    *rel_x = absinfo.value;
  }
  if (ioctl(evp->fd, EVIOCGABS(REL_Y), &absinfo) < 0) {
    return 0;
  } else {
    rc |= 1;
    *rel_y = absinfo.value;
  }
  if (ioctl(evp->fd, EVIOCGABS(REL_Z), &absinfo) < 0) {
    return 0;
  } else {
    rc |= 1;
    *rel_z = absinfo.value;
  }

  if (ioctl(evp->fd, EVIOCGABS(REL_RX), &absinfo) < 0) {
    return 0;
  } else {
    rc |= 1;
    *rel_rx = absinfo.value;
  }
  if (ioctl(evp->fd, EVIOCGABS(REL_RY), &absinfo) < 0) {
    return 0;
  } else {
    rc |= 1;
    *rel_ry = absinfo.value;
  }
  if (ioctl(evp->fd, EVIOCGABS(REL_RZ), &absinfo) < 0) {
    return 0;
  } else {
    rc |= 1;
    *rel_rz = absinfo.value;
  }


  if (ioctl(evp->fd, EVIOCGBIT(EV_KEY, sizeof(evp->keybit)), evp->keybit) >= 0) {
    int i, btmp=0;
    for (i=0; i<31; i++) {
      if (EVIO_TESTBIT(BTN_MISC+i, evp->keybit))
        btmp |= (1 << i);
    }
    *buttons = btmp;
  }

  return rc; 
}
Esempio n. 30
0
int open_dev_usb(struct device *dev)
{
	int i;
	struct input_absinfo absinfo;
	unsigned char evtype_mask[(EV_MAX + 7) / 8];

	if((dev->fd = open(dev->path, O_RDWR)) == -1) {
		if((dev->fd = open(dev->path, O_RDONLY)) == -1) {
			perror("failed to open device");
			return -1;
		}
		fprintf(stderr, "opened device read-only, LEDs won't work\n");
	}

	if(ioctl(dev->fd, EVIOCGNAME(sizeof dev->name), dev->name) == -1) {
		perror("EVIOCGNAME ioctl failed");
		strcpy(dev->name, "unknown");
	}
	printf("device name: %s\n", dev->name);

	/* get number of axes */
	dev->num_axes = 6;	/* default to regular 6dof controller axis count */
	if(ioctl(dev->fd, EVIOCGBIT(EV_ABS, sizeof evtype_mask), evtype_mask) == 0) {
		dev->num_axes = 0;
		for(i=0; i<ABS_CNT; i++) {
			int idx = i / 8;
			int bit = i % 8;

			if(evtype_mask[idx] & (1 << bit)) {
				dev->num_axes++;
			} else {
				break;
			}
		}
	}
	if(verbose) {
		printf("  Number of axes: %d\n", dev->num_axes);
	}

	dev->minval = malloc(dev->num_axes * sizeof *dev->minval);
	dev->maxval = malloc(dev->num_axes * sizeof *dev->maxval);
	dev->fuzz = malloc(dev->num_axes * sizeof *dev->fuzz);

	if(!dev->minval || !dev->maxval || !dev->fuzz) {
		perror("failed to allocate memory");
		return -1;
	}

	/* if the device is an absolute device, find the minimum and maximum axis values */
	for(i=0; i<dev->num_axes; i++) {
		dev->minval[i] = DEF_MINVAL;
		dev->maxval[i] = DEF_MAXVAL;
		dev->fuzz[i] = 0;

		if(ioctl(dev->fd, EVIOCGABS(i), &absinfo) == 0) {
			dev->minval[i] = absinfo.minimum;
			dev->maxval[i] = absinfo.maximum;
			dev->fuzz[i] = absinfo.fuzz;

			if(verbose) {
				printf("  Axis %d value range: %d - %d (fuzz: %d)\n", i, dev->minval[i], dev->maxval[i], dev->fuzz[i]);
			}
		}
	}

	/*if(ioctl(dev->fd, EVIOCGBIT(0, sizeof(evtype_mask)), evtype_mask) == -1) {
		perror("EVIOCGBIT ioctl failed\n");
		close(dev->fd);
		return -1;
	}*/

	if(cfg.grab_device) {
		int grab = 1;
		/* try to grab the device */
		if(ioctl(dev->fd, EVIOCGRAB, &grab) == -1) {
			perror("failed to grab the device");
		}
	}

	/* set non-blocking */
	fcntl(dev->fd, F_SETFL, fcntl(dev->fd, F_GETFL) | O_NONBLOCK);

	if(cfg.led) {
		set_led_evdev(dev, 1);
	}

	/* fill the device function pointers */
	dev->close = close_evdev;
	dev->read = read_evdev;
	dev->set_led = set_led_evdev;

	return 0;
}