// gcc -std=gnu99 `pkg-config --cflags --libs xcb xcb-xinput` list.c -o list #include #include #include #include #include #include xcb_connection_t *conn; static void setup_xinput2(void) { { const xcb_query_extension_reply_t *reply = xcb_get_extension_data(conn, &xcb_input_id); assert(reply); assert(reply->present); } { xcb_input_xi_query_version_cookie_t cookie = xcb_input_xi_query_version(conn, XCB_INPUT_MAJOR_VERSION, XCB_INPUT_MINOR_VERSION); xcb_input_xi_query_version_reply_t *reply = xcb_input_xi_query_version_reply(conn, cookie, NULL); assert(reply); assert(reply->major_version >= XCB_INPUT_MAJOR_VERSION); assert(reply->minor_version >= XCB_INPUT_MINOR_VERSION); free(reply); } } static const char * device_type_string(xcb_input_device_type_t type) { switch (type) { case XCB_INPUT_DEVICE_TYPE_MASTER_POINTER: return "master-pointer"; case XCB_INPUT_DEVICE_TYPE_MASTER_KEYBOARD: return "master-keyboard"; case XCB_INPUT_DEVICE_TYPE_SLAVE_POINTER: return "slave-pointer"; case XCB_INPUT_DEVICE_TYPE_SLAVE_KEYBOARD: return "slave-keyboard"; case XCB_INPUT_DEVICE_TYPE_FLOATING_SLAVE: return "floating-slave"; } assert(false); return ""; } static const char * device_class_type_string(xcb_input_device_class_type_t type) { switch (type) { case XCB_INPUT_DEVICE_CLASS_TYPE_KEY: return "key-class"; case XCB_INPUT_DEVICE_CLASS_TYPE_BUTTON: return "button-class"; case XCB_INPUT_DEVICE_CLASS_TYPE_VALUATOR: return "valuator-class"; case XCB_INPUT_DEVICE_CLASS_TYPE_SCROLL: return "scroll-class"; case XCB_INPUT_DEVICE_CLASS_TYPE_TOUCH: return "touch-class"; } assert(false); return ""; } static void list_devices(void) { xcb_input_xi_query_device_cookie_t cookie = xcb_input_xi_query_device(conn, XCB_INPUT_DEVICE_ALL); xcb_input_xi_query_device_reply_t *reply = xcb_input_xi_query_device_reply(conn, cookie, NULL); assert(reply); int devices_length = xcb_input_xi_query_device_infos_length(reply); xcb_input_xi_device_info_iterator_t devices_iter = xcb_input_xi_query_device_infos_iterator(reply); for (int i = 0; i < devices_length; i++) { xcb_input_xi_device_info_t *device = devices_iter.data; printf("Device %u:\n", device->deviceid); printf("\ttype: %s\n", device_type_string(device->type)); printf("\tattachment: %u\n", device->attachment); printf("\tnum_classes: %u\n", device->num_classes); printf("\tname_len: %u\n", device->name_len); printf("\tenabled: %u\n", device->enabled); printf("\tname: %.*s\n", xcb_input_xi_device_info_name_length(device), xcb_input_xi_device_info_name(device)); int classes_length = xcb_input_xi_device_info_classes_length(device); xcb_input_device_class_iterator_t classes_iter = xcb_input_xi_device_info_classes_iterator(device); for (int j = 0; j < classes_length; j++) { xcb_input_device_class_t *class = classes_iter.data; printf("\tClass %d\n", j); printf("\t\ttype: %s\n", device_class_type_string(class->type)); printf("\t\tsourceid: %u\n", class->sourceid); xcb_input_device_class_next(&classes_iter); } xcb_input_xi_device_info_next(&devices_iter); } free(reply); } int main(void) { conn = xcb_connect(NULL, NULL); assert(conn); setup_xinput2(); list_devices(); return 0; }