int main(int argc, char *argv[]) { struct input_event ev; m_dpy = XOpenDisplay(NULL); if (!m_dpy) printf("fail top open x display\n"); m_fd = open(argv[1] ? argv[1] : DEVICE, O_RDONLY); if (m_fd == -1) { printf("fail to open device\n"); return -1; } if (m_dev = mtdev_new_open(m_fd)) { unlink(SAMPLE_FILE); m_sample_file.open(SAMPLE_FILE); CHECK(m_dev, ABS_MT_SLOT); CHECK(m_dev, ABS_MT_TOUCH_MAJOR); CHECK(m_dev, ABS_MT_TOUCH_MINOR); CHECK(m_dev, ABS_MT_WIDTH_MAJOR); CHECK(m_dev, ABS_MT_WIDTH_MINOR); CHECK(m_dev, ABS_MT_ORIENTATION); CHECK(m_dev, ABS_MT_POSITION_X); CHECK(m_dev, ABS_MT_POSITION_Y); CHECK(m_dev, ABS_MT_TOOL_TYPE); CHECK(m_dev, ABS_MT_BLOB_ID); CHECK(m_dev, ABS_MT_TRACKING_ID); CHECK(m_dev, ABS_MT_PRESSURE); CHECK(m_dev, ABS_MT_DISTANCE); CHECK(m_dev, ABS_MT_TOOL_X); CHECK(m_dev, ABS_MT_TOOL_Y); printf("ctrl+c to quit\n"); signal(SIGINT, m_signal_callback_handler); while (mtdev_get(m_dev, m_fd, &ev, 1) * sizeof(struct input_event)) m_process_event(&ev); } return 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_WHEEL) || TEST_BIT(abs_bits, ABS_GAS) || TEST_BIT(abs_bits, ABS_BRAKE) || TEST_BIT(abs_bits, ABS_HAT0X)) { /* Device %s is a joystick, ignoring. */ return 0; } 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; } /* We only handle the slotted Protocol B in weston. Devices with ABS_MT_POSITION_* but not ABS_MT_SLOT require mtdev for conversion. */ if (TEST_BIT(abs_bits, ABS_MT_POSITION_X) && TEST_BIT(abs_bits, ABS_MT_POSITION_Y)) { 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->caps |= EVDEV_TOUCH; if (!TEST_BIT(abs_bits, ABS_MT_SLOT)) { device->mtdev = mtdev_new_open(device->fd); if (!device->mtdev) { /* mtdev required but failed to open. */ return 0; } device->mt.slot = device->mtdev->caps.slot.value; } else { ioctl(device->fd, EVIOCGABS(ABS_MT_SLOT), &absinfo); device->mt.slot = absinfo.value; } } } 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; } } if (TEST_BIT(key_bits, BTN_TOUCH)) { device->caps |= EVDEV_TOUCH; } for (i = BTN_MISC; i < BTN_JOYSTICK; i++) { if (TEST_BIT(key_bits, i)) { device->caps |= EVDEV_BUTTON; device->caps &= ~EVDEV_TOUCH; 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) { return 0; } return 1; }
struct evdev_device * evdev_device_create(struct weston_seat *seat, const char *path, int device_fd) { struct evdev_device *device; struct weston_compositor *ec; char devname[256] = "unknown"; device = malloc(sizeof *device); if (device == NULL) return NULL; memset(device, 0, sizeof *device); ec = seat->compositor; device->output = container_of(ec->output_list.next, struct weston_output, link); device->seat = seat; device->is_mt = 0; device->mtdev = NULL; device->devnode = strdup(path); device->mt.slot = -1; device->rel.dx = 0; device->rel.dy = 0; device->dispatch = NULL; device->fd = device_fd; ioctl(device->fd, EVIOCGNAME(sizeof(devname)), devname); device->devname = strdup(devname); if (!evdev_handle_device(device)) { free(device->devnode); free(device->devname); free(device); return EVDEV_UNHANDLED_DEVICE; } if (evdev_configure_device(device) == -1) goto err1; /* If the dispatch was not set up use the fallback. */ if (device->dispatch == NULL) device->dispatch = fallback_dispatch_create(); if (device->dispatch == NULL) goto err1; if (device->is_mt) { device->mtdev = mtdev_new_open(device->fd); if (!device->mtdev) weston_log("mtdev failed to open for %s\n", path); } device->source = wl_event_loop_add_fd(ec->input_loop, device->fd, WL_EVENT_READABLE, evdev_device_data, device); if (device->source == NULL) goto err2; return device; err2: device->dispatch->interface->destroy(device->dispatch); err1: free(device->devname); free(device->devnode); free(device); return NULL; }