コード例 #1
0
int
tp_init_buttons(struct tp_dispatch *tp,
                struct evdev_device *device)
{
    struct libinput *libinput = tp_libinput_context(tp);
    struct tp_touch *t;
    const struct input_absinfo *absinfo_x, *absinfo_y;

    tp->buttons.is_clickpad = libevdev_has_property(device->evdev,
                              INPUT_PROP_BUTTONPAD);
    tp->buttons.has_topbuttons = libevdev_has_property(device->evdev,
                                 INPUT_PROP_TOPBUTTONPAD);

    if (libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE) ||
            libevdev_has_event_code(device->evdev, EV_KEY, BTN_RIGHT)) {
        if (tp->buttons.is_clickpad)
            log_bug_kernel(libinput,
                           "%s: clickpad advertising right button\n",
                           device->devname);
    } else if (libevdev_has_event_code(device->evdev, EV_KEY, BTN_LEFT) &&
               !tp->buttons.is_clickpad &&
               libevdev_get_id_vendor(device->evdev) != VENDOR_ID_APPLE) {
        log_bug_kernel(libinput,
                       "%s: non clickpad without right button?\n",
                       device->devname);
    }

    absinfo_x = device->abs.absinfo_x;
    absinfo_y = device->abs.absinfo_y;

    /* pinned-finger motion threshold, see tp_unpin_finger. */
    tp->buttons.motion_dist.x_scale_coeff = 1.0/absinfo_x->resolution;
    tp->buttons.motion_dist.y_scale_coeff = 1.0/absinfo_y->resolution;

    tp->buttons.config_method.get_methods = tp_button_config_click_get_methods;
    tp->buttons.config_method.set_method = tp_button_config_click_set_method;
    tp->buttons.config_method.get_method = tp_button_config_click_get_method;
    tp->buttons.config_method.get_default_method = tp_button_config_click_get_default_method;
    tp->device->base.config.click_method = &tp->buttons.config_method;

    tp->buttons.click_method = tp_click_get_default_method(tp);
    tp_switch_click_method(tp);

    tp_init_top_softbuttons(tp, device, 1.0);

    tp_init_middlebutton_emulation(tp, device);

    tp_for_each_touch(tp, t) {
        t->button.state = BUTTON_STATE_NONE;
        libinput_timer_init(&t->button.timer,
                            tp_libinput_context(tp),
                            tp_button_handle_timeout, t);
    }
コード例 #2
0
ファイル: test-uinput.c プロジェクト: AndrewSmart/libevdev
END_TEST

START_TEST(test_uinput_properties)
{
	struct libevdev *dev, *dev2;
	struct libevdev_uinput *uidev;
	int fd;
	int rc;
	const char *devnode;

	dev = libevdev_new();
	ck_assert(dev != NULL);
	libevdev_set_name(dev, TEST_DEVICE_NAME);
	libevdev_enable_event_type(dev, EV_SYN);
	libevdev_enable_event_type(dev, EV_REL);
	libevdev_enable_event_type(dev, EV_KEY);
	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
	libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
	libevdev_enable_property(dev, INPUT_PROP_BUTTONPAD);
	libevdev_enable_property(dev, INPUT_PROP_MAX);

	rc = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev);
	ck_assert_int_eq(rc, 0);
	ck_assert(uidev != NULL);

	devnode = libevdev_uinput_get_devnode(uidev);
	ck_assert(devnode != NULL);

	fd = open(devnode, O_RDONLY);
	ck_assert_int_gt(fd, -1);
	rc = libevdev_new_from_fd(fd, &dev2);
	ck_assert_int_eq(rc, 0);

	ck_assert(libevdev_has_property(dev2, INPUT_PROP_BUTTONPAD));
	ck_assert(libevdev_has_property(dev2, INPUT_PROP_MAX));

	libevdev_free(dev);
	libevdev_free(dev2);
	libevdev_uinput_destroy(uidev);
	close(fd);
}
コード例 #3
0
ファイル: minitouch.c プロジェクト: openstf/minitouch
static int consider_device(const char* devpath, internal_state_t* state)
{
  int fd = -1;
  struct libevdev* evdev = NULL;

  if (!is_character_device(devpath))
  {
    goto mismatch;
  }

  if ((fd = open(devpath, O_RDWR)) < 0)
  {
    perror("open");
    fprintf(stderr, "Unable to open device %s for inspection", devpath);
    goto mismatch;
  }

  if (libevdev_new_from_fd(fd, &evdev) < 0)
  {
    fprintf(stderr, "Note: device %s is not supported by libevdev\n", devpath);
    goto mismatch;
  }

  if (!is_multitouch_device(evdev))
  {
    goto mismatch;
  }

  int score = 10000;

  if (libevdev_has_event_code(evdev, EV_ABS, ABS_MT_TOOL_TYPE))
  {
    int tool_min = libevdev_get_abs_minimum(evdev, ABS_MT_TOOL_TYPE);
    int tool_max = libevdev_get_abs_maximum(evdev, ABS_MT_TOOL_TYPE);

    if (tool_min > MT_TOOL_FINGER || tool_max < MT_TOOL_FINGER)
    {
      fprintf(stderr, "Note: device %s is a touch device, but doesn't"
        " support fingers\n", devpath);
      goto mismatch;
    }

    score -= tool_max - MT_TOOL_FINGER;
  }

  if (libevdev_has_event_code(evdev, EV_ABS, ABS_MT_SLOT))
  {
    score += 1000;

    // Some devices, e.g. Blackberry PRIV (STV100) have more than one surface
    // you can touch. On the PRIV, the keypad also acts as a touch screen
    // that you can swipe and scroll with. The only differences between the
    // touch devices are that one is named "touch_display" and the other
    // "touch_keypad", the keypad only supports 3 contacts and the display
    // up to 9, and the keypad has a much lower resolution. Therefore
    // increasing the score by the number of contacts should be a relatively
    // safe bet, though we may also want to decrease the score by, say, 1,
    // if the device name contains "key" just in case they decide to start
    // supporting more contacts on both touch surfaces in the future.
    int num_slots = libevdev_get_abs_maximum(evdev, ABS_MT_SLOT);
    score += num_slots;
  }

  // For Blackberry devices, see above.
  const char* name = libevdev_get_name(evdev);
  if (strstr(name, "key") != NULL)
  {
    score -= 1;
  }

  // Alcatel OneTouch Idol 3 has an `input_mt_wrapper` device in addition
  // to direct input. It seems to be related to accessibility, as it shows
  // a touchpoint that you can move around, and then tap to activate whatever
  // is under the point. That wrapper device lacks the direct property.
  if (libevdev_has_property(evdev, INPUT_PROP_DIRECT))
  {
    score += 10000;
  }

  // Some devices may have an additional screen. For example, Meizu Pro7 Plus
  // has a small screen on the back side of the device called sub_touch, while
  // the boring screen in the front is called main_touch. The resolution on
  // the sub_touch device is much much lower. It seems like a safe bet
  // to always prefer the larger device, as long as the score adjustment is
  // likely to be lower than the adjustment we do for INPUT_PROP_DIRECT.
  if (libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_X))
  {
    int x = libevdev_get_abs_maximum(evdev, ABS_MT_POSITION_X);
    int y = libevdev_get_abs_maximum(evdev, ABS_MT_POSITION_Y);
    score += sqrt(x * y);
  }

  if (state->evdev != NULL)
  {
    if (state->score >= score)
    {
      fprintf(stderr, "Note: device %s was outscored by %s (%d >= %d)\n",
        devpath, state->path, state->score, score);
      goto mismatch;
    }
    else
    {
      fprintf(stderr, "Note: device %s was outscored by %s (%d >= %d)\n",
        state->path, devpath, score, state->score);
    }
  }

  libevdev_free(state->evdev);

  state->fd = fd;
  state->score = score;
  strncpy(state->path, devpath, sizeof(state->path));
  state->evdev = evdev;

  return 1;

mismatch:
  libevdev_free(evdev);

  if (fd >= 0)
  {
    close(fd);
  }

  return 0;
}