static int receive_xkb_events(xcb_connection_t *c) { xcb_xkb_use_extension_cookie_t xkb_cookie; xcb_xkb_use_extension_reply_t *xkb_reply; xcb_generic_error_t *error; xcb_void_cookie_t cookie; unsigned int events, map; xkb_cookie = xcb_xkb_use_extension(c, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION); xkb_reply = xcb_xkb_use_extension_reply(c, xkb_cookie, NULL); if (!xkb_reply) { ERR("couldn't initialize XKB\n"); return -1; } else if (!xkb_reply->supported) { ERR("couldn't initialize XKB: unsupported version" "(server is %d.%d, we're %d.%d)\n", xkb_reply->serverMajor, xkb_reply->serverMinor, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION); free(xkb_reply); return -1; } free(xkb_reply); map = XCB_XKB_MAP_PART_KEY_SYMS | XCB_XKB_MAP_PART_MODIFIER_MAP; events = XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | XCB_XKB_EVENT_TYPE_STATE_NOTIFY; cookie = xcb_xkb_select_events_checked(c, XCB_XKB_ID_USE_CORE_KBD, events, 0, events, map, map, 0); error = xcb_request_check(c, cookie); if (error) { ERR("error requesting XKB events\n"); free(error); return -1; } return 0; }
void X11Backend::xkbSetup() { const xcb_query_extension_reply_t *ext; if(!(ext = xcb_get_extension_data(xConnection_, &xcb_xkb_id))) { ny::sendWarning("xkb setup fail"); return; } xkbEventBase_ = ext->first_event; xcb_void_cookie_t select = xcb_xkb_select_events_checked(xConnection_, XCB_XKB_ID_USE_CORE_KBD, XCB_XKB_EVENT_TYPE_STATE_NOTIFY, 0, XCB_XKB_EVENT_TYPE_STATE_NOTIFY, 0, 0, nullptr); xcb_generic_error_t *error; if((error = xcb_request_check(xConnection_, select))) { ny::sendWarning("xkb setup fail"); free(error); return; } xcb_xkb_use_extension_reply_t *use_ext_reply; xcb_xkb_use_extension_cookie_t use_ext = xcb_xkb_use_extension(xConnection_, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION); if(!(use_ext_reply = xcb_xkb_use_extension_reply(xConnection_, use_ext, nullptr))) { ny::sendWarning("xkb setup fail"); free(error); } const bool supported = use_ext_reply->supported; free(use_ext_reply); if(!supported) { ny::sendWarning("xkb setup fail"); free(error); } xcb_xkb_per_client_flags_cookie_t pcf = xcb_xkb_per_client_flags(xConnection_, XCB_XKB_ID_USE_CORE_KBD, XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT, XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT, 0, 0, 0); xcb_xkb_per_client_flags_reply_t *pcf_reply; if(!(pcf_reply = xcb_xkb_per_client_flags_reply(xConnection_, pcf, NULL))) { ny::sendWarning("xkb setup fail"); free(error); } const bool hasRepeat = (pcf_reply->value & XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT); free(pcf_reply); if(!hasRepeat) { ny::sendWarning("xkb setup fail"); free(error); } }