Analogous to Xnest implementation at 83fef4235db86343477b4ec9858c6ba35e1aa7d9.
Signed-off-by: Laércio de Sousa <laercioso...@sme-mogidascruzes.sp.gov.br> --- configure.ac | 2 +- hw/kdrive/ephyr/ephyr.c | 19 +++++++--- hw/kdrive/ephyr/hostx.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++--- hw/kdrive/ephyr/hostx.h | 9 +---- hw/kdrive/src/kdrive.h | 4 ++ hw/kdrive/src/kinput.c | 11 ++++++ 6 files changed, 123 insertions(+), 20 deletions(-) diff --git a/configure.ac b/configure.ac index 2e38efa..933addc 100644 --- a/configure.ac +++ b/configure.ac @@ -2391,7 +2391,7 @@ if test "$KDRIVE" = yes; then AC_DEFINE(KDRIVE_MOUSE, 1, [Enable KDrive mouse driver]) fi - XEPHYR_REQUIRED_LIBS="xau xdmcp xcb xcb-shape xcb-render xcb-renderutil xcb-aux xcb-image xcb-icccm xcb-shm xcb-keysyms xcb-randr" + XEPHYR_REQUIRED_LIBS="xau xdmcp xcb xcb-shape xcb-render xcb-renderutil xcb-aux xcb-image xcb-icccm xcb-shm xcb-keysyms xcb-randr xcb-xkb" if test "x$XV" = xyes; then XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xcb-xv" fi diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index 896bac5..a949f26 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -54,7 +54,6 @@ extern Bool ephyr_glamor; KdKeyboardInfo *ephyrKbd; KdPointerInfo *ephyrMouse; -EphyrKeySyms ephyrKeySyms; Bool ephyrNoDRI = FALSE; Bool ephyrNoXV = FALSE; @@ -1367,16 +1366,24 @@ KdPointerDriver EphyrMouseDriver = { static Status EphyrKeyboardInit(KdKeyboardInfo * ki) { + int i; + ki->driverPrivate = (EphyrKbdPrivate *) calloc(sizeof(EphyrKbdPrivate), 1); - hostx_load_keymap(); - if (!ephyrKeySyms.minKeyCode) { + ki->keymapLoaded = hostx_load_keymap(&ki->keySyms, ki->modmap, &ki->controls); + + if (!ki->keySyms.minKeyCode) { ErrorF("Couldn't load keymap from host\n"); return BadAlloc; } - ki->minScanCode = ephyrKeySyms.minKeyCode; - ki->maxScanCode = ephyrKeySyms.maxKeyCode; - free(ki->name); + + ki->minScanCode = ki->keySyms.minKeyCode; + ki->maxScanCode = ki->keySyms.maxKeyCode; + + if (ki->name != NULL) { + free(ki->name); + } + ki->name = strdup("Xephyr virtual keyboard"); ephyrKbd = ki; return Success; diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index 49516bb..249b210 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -52,6 +52,7 @@ #include <xcb/shape.h> #include <xcb/xcb_keysyms.h> #include <xcb/randr.h> +#include <xcb/xkb.h> #ifdef XF86DRI #include <xcb/xf86dri.h> #include <xcb/glx.h> @@ -90,8 +91,6 @@ static EphyrHostXVars HostX; static int HostXWantDamageDebug = 0; -extern EphyrKeySyms ephyrKeySyms; - extern Bool EphyrWantResize; char *ephyrResName = NULL; @@ -1086,18 +1085,105 @@ hostx_paint_debug_rect(KdScreenInfo *screen, nanosleep(&tspec, NULL); } -void -hostx_load_keymap(void) +Bool +hostx_load_keymap(KeySymsPtr keySyms, CARD8 *modmap, XkbControlsPtr controls) { int min_keycode, max_keycode; + int map_width; + size_t i, j; + int keymap_len; + xcb_keysym_t *keymap; + xcb_keycode_t *modifier_map; + xcb_get_keyboard_mapping_cookie_t mapping_c; + xcb_get_keyboard_mapping_reply_t *mapping_r; + xcb_get_modifier_mapping_cookie_t modifier_c; + xcb_get_modifier_mapping_reply_t *modifier_r; + xcb_xkb_use_extension_cookie_t use_c; + xcb_xkb_use_extension_reply_t *use_r; + xcb_xkb_get_controls_cookie_t controls_c; + xcb_xkb_get_controls_reply_t *controls_r; min_keycode = xcb_get_setup(HostX.conn)->min_keycode; max_keycode = xcb_get_setup(HostX.conn)->max_keycode; EPHYR_DBG("min: %d, max: %d", min_keycode, max_keycode); - ephyrKeySyms.minKeyCode = min_keycode; - ephyrKeySyms.maxKeyCode = max_keycode; + keySyms->minKeyCode = min_keycode; + keySyms->maxKeyCode = max_keycode; + + use_c = xcb_xkb_use_extension(HostX.conn, + XCB_XKB_MAJOR_VERSION, + XCB_XKB_MINOR_VERSION); + use_r = xcb_xkb_use_extension_reply(HostX.conn, use_c, NULL); + + if (!use_r) { + EPHYR_LOG_ERROR("Couldn't use XKB extension."); + return FALSE; + } else if (!use_r->supported) { + EPHYR_LOG_ERROR("XKB extension is not supported in X server."); + free(use_r); + return FALSE; + } + + free(use_r); + + controls_c = xcb_xkb_get_controls(HostX.conn, + XCB_XKB_ID_USE_CORE_KBD); + controls_r = xcb_xkb_get_controls_reply(HostX.conn, + controls_c, + NULL); + + if (!controls_r) { + EPHYR_LOG_ERROR("Couldn't get XKB keyboard controls."); + return FALSE; + } + + mapping_c = xcb_get_keyboard_mapping(HostX.conn, + min_keycode, + max_keycode - min_keycode + 1); + mapping_r = xcb_get_keyboard_mapping_reply(HostX.conn, + mapping_c, + NULL); + map_width = mapping_r->keysyms_per_keycode; + keymap = xcb_get_keyboard_mapping_keysyms(mapping_r); + keymap_len = xcb_get_keyboard_mapping_keysyms_length(mapping_r); + + modifier_c = xcb_get_modifier_mapping(HostX.conn); + modifier_r = xcb_get_modifier_mapping_reply(HostX.conn, + modifier_c, + NULL); + modifier_map = xcb_get_modifier_mapping_keycodes(modifier_r); + memset(modmap, 0, sizeof(CARD8) * MAP_LENGTH); + + for (j = 0; j < 8; j++) { + for (i = 0; i < modifier_r->keycodes_per_modifier; i++) { + CARD8 keycode; + + if ((keycode = modifier_map[j * modifier_r->keycodes_per_modifier + i])) { + modmap[keycode] |= 1 << j; + } + } + } + + free(modifier_r); + + keySyms->mapWidth = map_width; + keySyms->map = calloc(keymap_len, sizeof(KeySym)); + + for (i = 0; i < keymap_len; i++) { + keySyms->map[i] = keymap[i]; + } + + free(mapping_r); + + controls->enabled_ctrls = controls_r->enabledControls; + + for (i = 0; i < XkbPerKeyBitArraySize; i++) { + controls->per_key_repeat[i] = controls_r->perKeyRepeat[i]; + } + + free(controls_r); + return TRUE; } xcb_connection_t * diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h index d416dae..c907274 100644 --- a/hw/kdrive/ephyr/hostx.h +++ b/hw/kdrive/ephyr/hostx.h @@ -44,11 +44,6 @@ typedef struct EphyrHostXVars EphyrHostXVars; typedef struct { - int minKeyCode; - int maxKeyCode; -} EphyrKeySyms; - -typedef struct { VisualID visualid; int screen; int depth; @@ -153,8 +148,8 @@ void hostx_paint_rect(KdScreenInfo *screen, int sx, int sy, int dx, int dy, int width, int height); -void - hostx_load_keymap(void); +Bool +hostx_load_keymap(KeySymsPtr keySyms, CARD8 *modmap, XkbControlsPtr controls); xcb_connection_t * hostx_get_xcbconn(void); diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h index e1d2b59..1537d13 100644 --- a/hw/kdrive/src/kdrive.h +++ b/hw/kdrive/src/kdrive.h @@ -272,6 +272,10 @@ struct _KdKeyboardInfo { int minScanCode; int maxScanCode; + KeySymsRec keySyms; + CARD8 modmap[MAP_LENGTH]; + XkbControlsRec controls; + Bool keymapLoaded; int leds; int bellPitch; diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index 1fdaa52..7151d75 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -742,6 +742,8 @@ KdKeyboardProc(DeviceIntPtr pDevice, int onoff) return BadImplementation; } + ki->keymapLoaded = FALSE; + if ((*ki->driver->Init) (ki) != Success) { return !Success; } @@ -758,6 +760,15 @@ KdKeyboardProc(DeviceIntPtr pDevice, int onoff) return BadImplementation; } + if (ki->keymapLoaded) { + XkbApplyMappingChange(ki->dixdev, &ki->keySyms, + ki->keySyms.minKeyCode, + ki->keySyms.maxKeyCode - ki->keySyms.minKeyCode + 1, + ki->modmap, serverClient); + XkbDDXChangeControls(ki->dixdev, &ki->controls, &ki->controls); + free(ki->keySyms.map); + } + xiclass = AtomFromName(XI_KEYBOARD); AssignTypeAndName(pDevice, xiclass, ki->name ? ki->name : "Generic KDrive Keyboard"); -- 2.1.4 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel