diff --git a/hw/xnest/Keyboard.c b/hw/xnest/Keyboard.c index 3ac7f779b..2f9ad7e5a 100644 --- a/hw/xnest/Keyboard.c +++ b/hw/xnest/Keyboard.c @@ -24,6 +24,7 @@ is" without express or implied warranty. #include #include #include +#include #include "screenint.h" #include "inputstr.h" @@ -43,25 +44,6 @@ is" without express or implied warranty. #include #include "xkbsrv.h" -extern Bool - XkbQueryExtension(Display * /* dpy */ , - int * /* opcodeReturn */ , - int * /* eventBaseReturn */ , - int * /* errorBaseReturn */ , - int * /* majorRtrn */ , - int * /* minorRtrn */ - ); - -extern XkbDescPtr XkbGetKeyboard(Display * /* dpy */ , - unsigned int /* which */ , - unsigned int /* deviceSpec */ - ); - -extern Status XkbGetControls(Display * /* dpy */ , - unsigned long /* which */ , - XkbDescPtr /* desc */ - ); - DeviceIntPtr xnestKeyboardDevice = NULL; void @@ -122,8 +104,6 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff) CARD8 modmap[MAP_LENGTH]; int i, j; XKeyboardState values; - XkbDescPtr xkb; - int op, event, error, major, minor; switch (onoff) { case DEVICE_INIT: @@ -172,20 +152,6 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff) keySyms.mapWidth = mapWidth; keySyms.map = keymap; - if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) - == 0) { - ErrorF("Unable to initialize XKEYBOARD extension.\n"); - goto XkbError; - } - xkb = - XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, - XkbUseCoreKbd); - if (xkb == NULL || xkb->geom == NULL) { - ErrorF("Couldn't get keyboard.\n"); - goto XkbError; - } - XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb); - InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl); @@ -193,8 +159,61 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff) keySyms.maxKeyCode - keySyms.minKeyCode + 1, modmap, serverClient); - XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); - XkbFreeKeyboard(xkb, 0, FALSE); + xnest_xkb_init(xnestUpstreamInfo.conn); + + int device_id = xnest_xkb_device_id(xnestUpstreamInfo.conn); + + xcb_generic_error_t *err = NULL; + xcb_xkb_get_controls_reply_t *reply = xcb_xkb_get_controls_reply( + xnestUpstreamInfo.conn, + xcb_xkb_get_controls(xnestUpstreamInfo.conn, device_id), + &err); + + if (err) { + ErrorF("Couldn't get keyboard controls for %d: error %d\n", device_id, err->error_code); + free(err); + goto XkbError; + } + + if (!reply) { + ErrorF("Couldn't get keyboard controls for %d: no reply", device_id); + goto XkbError; + } + + XkbControlsRec ctrls = { + .mk_dflt_btn = reply->mouseKeysDfltBtn, + .num_groups = reply->numGroups, + .groups_wrap = reply->groupsWrap, + .internal = (XkbModsRec) { + .mask = reply->internalModsMask, + .real_mods = reply->internalModsRealMods, + .vmods = reply->internalModsVmods, + }, + .ignore_lock = (XkbModsRec) { + .mask = reply->ignoreLockModsMask, + .real_mods = reply->ignoreLockModsRealMods, + .vmods = reply->ignoreLockModsVmods, + }, + .enabled_ctrls = reply->enabledControls, + .repeat_delay = reply->repeatDelay, + .repeat_interval = reply->repeatInterval, + .slow_keys_delay = reply->slowKeysDelay, + .debounce_delay = reply->debounceDelay, + .mk_delay = reply->mouseKeysDelay, + .mk_interval = reply->mouseKeysInterval, + .mk_time_to_max = reply->mouseKeysTimeToMax, + .mk_max_speed = reply->mouseKeysMaxSpeed, + .mk_curve = reply->mouseKeysCurve, + .ax_options = reply->accessXOption, + .ax_timeout = reply->accessXTimeout, + .axt_opts_mask = reply->accessXTimeoutOptionsMask, + .axt_opts_values = reply->accessXTimeoutOptionsValues, + .axt_ctrls_mask = reply->accessXTimeoutMask, + .axt_ctrls_values = reply->accessXTimeoutValues, + }; + memcpy(&ctrls.per_key_repeat, reply->perKeyRepeat, sizeof(ctrls.per_key_repeat)); + + XkbDDXChangeControls(pDev, &ctrls, &ctrls); free(keymap); break; } diff --git a/hw/xnest/meson.build b/hw/xnest/meson.build index e2a978b83..87875a3b8 100644 --- a/hw/xnest/meson.build +++ b/hw/xnest/meson.build @@ -25,6 +25,7 @@ xcb_dep = dependency('xcb', required: true) xcb_aux_dep = dependency('xcb-aux', required: true) xcb_shape_dep = dependency('xcb-shape', required: true) xcb_icccm_dep = dependency('xcb-icccm', required: true) +xcb_xkb_dep = dependency('xcb-xkb', required: true) executable( 'Xnest', @@ -37,6 +38,7 @@ executable( xcb_aux_dep, xcb_shape_dep, xcb_icccm_dep, + xcb_xkb_dep, x11_xcb_dep, ], link_with: [ diff --git a/hw/xnest/xcb.c b/hw/xnest/xcb.c index a6046108f..c2170b5d3 100644 --- a/hw/xnest/xcb.c +++ b/hw/xnest/xcb.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "include/gc.h" #include "include/servermd.h" @@ -180,3 +181,66 @@ void xnest_set_command( nbytes, buf); } + +void xnest_xkb_init(xcb_connection_t *conn) +{ + xcb_generic_error_t *err = NULL; + xcb_xkb_use_extension_reply_t *reply = xcb_xkb_use_extension_reply( + xnestUpstreamInfo.conn, + xcb_xkb_use_extension( + xnestUpstreamInfo.conn, + XCB_XKB_MAJOR_VERSION, + XCB_XKB_MINOR_VERSION), + &err); + + if (err) { + ErrorF("failed query xkb extension: %d\n", err->error_code); + free(err); + } else { + free(reply); + } +} + +#define XkbGBN_AllComponentsMask_2 ( \ + XCB_XKB_GBN_DETAIL_TYPES | \ + XCB_XKB_GBN_DETAIL_COMPAT_MAP | \ + XCB_XKB_GBN_DETAIL_CLIENT_SYMBOLS | \ + XCB_XKB_GBN_DETAIL_SERVER_SYMBOLS | \ + XCB_XKB_GBN_DETAIL_INDICATOR_MAPS | \ + XCB_XKB_GBN_DETAIL_KEY_NAMES | \ + XCB_XKB_GBN_DETAIL_GEOMETRY | \ + XCB_XKB_GBN_DETAIL_OTHER_NAMES) + +int xnest_xkb_device_id(xcb_connection_t *conn) +{ + int device_id = -1; + uint8_t xlen[6] = { 0 }; + xcb_generic_error_t *err = NULL; + + xcb_xkb_get_kbd_by_name_reply_t *reply = xcb_xkb_get_kbd_by_name_reply( + xnestUpstreamInfo.conn, + xcb_xkb_get_kbd_by_name( + xnestUpstreamInfo.conn, + XCB_XKB_ID_USE_CORE_KBD, + XkbGBN_AllComponentsMask_2, + XkbGBN_AllComponentsMask_2, + 0, + sizeof(xlen), + xlen), + &err); + + if (err) { + ErrorF("failed retrieving core keyboard: %d\n", err->error_code); + free(err); + return -1; + } + + if (!reply) { + ErrorF("failed retrieving core keyboard: no reply"); + return -1; + } + + device_id = reply->deviceID; + free(reply); + return device_id; +} diff --git a/hw/xnest/xnest-xcb.h b/hw/xnest/xnest-xcb.h index 60d9912e7..301aca981 100644 --- a/hw/xnest/xnest-xcb.h +++ b/hw/xnest/xnest-xcb.h @@ -34,4 +34,7 @@ uint32_t xnest_create_pixmap_from_bitmap_data(xcb_connection_t *conn, uint32_t d void xnest_set_command(xcb_connection_t *conn, xcb_window_t window, char ** argv, int argc); +void xnest_xkb_init(xcb_connection_t *conn); +int xnest_xkb_device_id(xcb_connection_t *conn); + #endif /* __XNEST__XCB_H */