json_object *ipc_json_describe_input(struct libinput_device *device) { char* identifier = libinput_dev_unique_id(device); int vendor = libinput_device_get_id_vendor(device); int product = libinput_device_get_id_product(device); const char *name = libinput_device_get_name(device); double width = -1, height = -1; int has_size = libinput_device_get_size(device, &width, &height); json_object *device_object = json_object_new_object(); json_object_object_add(device_object,"identifier", identifier ? json_object_new_string(identifier) : NULL); json_object_object_add(device_object, "vendor", json_object_new_int(vendor)); json_object_object_add(device_object, "product", json_object_new_int(product)); json_object_object_add(device_object, "name", json_object_new_string(name)); if (has_size == 0) { json_object *size_object = json_object_new_object(); json_object_object_add(size_object, "width", json_object_new_double(width)); json_object_object_add(size_object, "height", json_object_new_double(height)); } else { json_object_object_add(device_object, "size", NULL); } struct { enum libinput_device_capability cap; const char *name; // If anyone feels like implementing device-specific IPC output, // be my guest json_object *(*describe)(struct libinput_device *); } caps[] = { { LIBINPUT_DEVICE_CAP_KEYBOARD, "keyboard", NULL }, { LIBINPUT_DEVICE_CAP_POINTER, "pointer", NULL }, { LIBINPUT_DEVICE_CAP_TOUCH, "touch", NULL }, { LIBINPUT_DEVICE_CAP_TABLET_TOOL, "tablet_tool", NULL }, { LIBINPUT_DEVICE_CAP_TABLET_PAD, "tablet_pad", NULL }, { LIBINPUT_DEVICE_CAP_GESTURE, "gesture", NULL }, #ifdef LIBINPUT_DEVICE_CAP_SWITCH // libinput 1.7.0+ { LIBINPUT_DEVICE_CAP_SWITCH, "switch", NULL }, #endif }; json_object *_caps = json_object_new_array(); for (size_t i = 0; i < sizeof(caps) / sizeof(caps[0]); ++i) { if (libinput_device_has_capability(device, caps[i].cap)) { json_object_array_add(_caps, json_object_new_string(caps[i].name)); if (caps[i].describe) { json_object *desc = caps[i].describe(device); json_object_object_add(device_object, caps[i].name, desc); } } } json_object_object_add(device_object, "capabilities", _caps); free(identifier); return device_object; }
char *libinput_dev_unique_id(struct libinput_device *device) { int vendor = libinput_device_get_id_vendor(device); int product = libinput_device_get_id_product(device); char *name = strdup(libinput_device_get_name(device)); char *p = name; for (; *p; ++p) { if (*p == ' ') { *p = '_'; } } sway_log(L_DEBUG, "rewritten name %s", name); int len = strlen(name) + sizeof(char) * 6; char *identifier = malloc(len); if (!identifier) { sway_log(L_ERROR, "Unable to allocate unique input device name"); return NULL; } const char *fmt = "%d:%d:%s"; snprintf(identifier, len, fmt, vendor, product, name); free(name); return identifier; }
/* * _clutter_input_device_evdev_new: * @manager: the device manager * @seat: the seat the device will belong to * @libinput_device: the libinput device * * Create a new ClutterInputDevice given a libinput device and associate * it with the provided seat. */ ClutterInputDevice * _clutter_input_device_evdev_new (ClutterDeviceManager *manager, ClutterSeatEvdev *seat, struct libinput_device *libinput_device) { ClutterInputDeviceEvdev *device; ClutterInputDeviceType type; ClutterDeviceManagerEvdev *manager_evdev; gchar *vendor, *product; gint device_id, n_rings = 0, n_strips = 0, n_groups = 1; gchar *node_path; gdouble width, height; type = _clutter_input_device_evdev_determine_type (libinput_device); vendor = g_strdup_printf ("%.4x", libinput_device_get_id_vendor (libinput_device)); product = g_strdup_printf ("%.4x", libinput_device_get_id_product (libinput_device)); manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager); device_id = _clutter_device_manager_evdev_acquire_device_id (manager_evdev); node_path = g_strdup_printf ("/dev/input/%s", libinput_device_get_sysname (libinput_device)); if (libinput_device_has_capability (libinput_device, LIBINPUT_DEVICE_CAP_TABLET_PAD)) { n_rings = libinput_device_tablet_pad_get_num_rings (libinput_device); n_strips = libinput_device_tablet_pad_get_num_strips (libinput_device); n_groups = libinput_device_tablet_pad_get_num_mode_groups (libinput_device); } device = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_EVDEV, "id", device_id, "name", libinput_device_get_name (libinput_device), "device-manager", manager, "device-type", type, "device-mode", CLUTTER_INPUT_MODE_SLAVE, "enabled", TRUE, "vendor-id", vendor, "product-id", product, "n-rings", n_rings, "n-strips", n_strips, "n-mode-groups", n_groups, "device-node", node_path, NULL); device->seat = seat; device->libinput_device = libinput_device; libinput_device_set_user_data (libinput_device, device); libinput_device_ref (libinput_device); g_free (vendor); g_free (product); g_free (node_path); if (libinput_device_get_size (libinput_device, &width, &height) == 0) device->device_aspect_ratio = width / height; return CLUTTER_INPUT_DEVICE (device); }
END_TEST START_TEST(device_ids) { struct litest_device *dev = litest_current_device(); const char *name; unsigned int pid, vid; name = libevdev_get_name(dev->evdev); pid = libevdev_get_id_product(dev->evdev); vid = libevdev_get_id_vendor(dev->evdev); ck_assert_str_eq(name, libinput_device_get_name(dev->libinput_device)); ck_assert_int_eq(pid, libinput_device_get_id_product(dev->libinput_device)); ck_assert_int_eq(vid, libinput_device_get_id_vendor(dev->libinput_device)); }
END_TEST START_TEST(device_udev_tag_alps) { struct litest_device *dev = litest_current_device(); struct libinput_device *device = dev->libinput_device; struct udev_device *d; const char *prop; d = libinput_device_get_udev_device(device); prop = udev_device_get_property_value(d, "LIBINPUT_MODEL_ALPS_TOUCHPAD"); if (strstr(libinput_device_get_name(device), "ALPS")) ck_assert_notnull(prop); else ck_assert(prop == NULL); udev_device_unref(d); }
static void print_device_notify(struct libinput_event *ev) { struct libinput_device *dev = libinput_event_get_device(ev); struct libinput_seat *seat = libinput_device_get_seat(dev); struct libinput_device_group *group; double w, h; static int next_group_id = 0; intptr_t group_id; const char *devnode; char *str; group = libinput_device_get_device_group(dev); group_id = (intptr_t)libinput_device_group_get_user_data(group); if (!group_id) { group_id = ++next_group_id; libinput_device_group_set_user_data(group, (void*)group_id); } devnode = udev_device_get_devnode( libinput_device_get_udev_device(dev)); printf("Device: %s\n" "Kernel: %s\n" "Group: %d\n" "Seat: %s, %s\n", libinput_device_get_name(dev), devnode, (int)group_id, libinput_seat_get_physical_name(seat), libinput_seat_get_logical_name(seat)); if (libinput_device_get_size(dev, &w, &h) == 0) printf("Size: %.2fx%.2fmm\n", w, h); printf("Capabilities: "); if (libinput_device_has_capability(dev, LIBINPUT_DEVICE_CAP_KEYBOARD)) printf("keyboard "); if (libinput_device_has_capability(dev, LIBINPUT_DEVICE_CAP_POINTER)) printf("pointer "); if (libinput_device_has_capability(dev, LIBINPUT_DEVICE_CAP_TOUCH)) printf("touch"); printf("\n"); printf("Tap-to-click: %s\n", tap_default(dev)); printf("Left-handed: %s\n", left_handed_default(dev)); printf("Nat.scrolling: %s\n", nat_scroll_default(dev)); str = calibration_default(dev); printf("Calibration: %s\n", str); free(str); str = scroll_defaults(dev); printf("Scroll methods: %s\n", str); free(str); str = click_defaults(dev); printf("Click methods: %s\n", str); free(str); printf("\n"); }