Xnest: use xcb for retrieving keymap controls
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
parent
261d22a444
commit
e5eec08f33
|
@ -21,6 +21,7 @@ is" without express or implied warranty.
|
||||||
#include <X11/Xdefs.h>
|
#include <X11/Xdefs.h>
|
||||||
#include <X11/Xproto.h>
|
#include <X11/Xproto.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
|
#include <xcb/xkb.h>
|
||||||
|
|
||||||
#include "screenint.h"
|
#include "screenint.h"
|
||||||
#include "inputstr.h"
|
#include "inputstr.h"
|
||||||
|
@ -103,8 +104,6 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
|
||||||
CARD8 modmap[MAP_LENGTH];
|
CARD8 modmap[MAP_LENGTH];
|
||||||
int i, j;
|
int i, j;
|
||||||
XKeyboardState values;
|
XKeyboardState values;
|
||||||
XkbDescPtr xkb;
|
|
||||||
int op, event, error, major, minor;
|
|
||||||
|
|
||||||
switch (onoff) {
|
switch (onoff) {
|
||||||
case DEVICE_INIT:
|
case DEVICE_INIT:
|
||||||
|
@ -154,20 +153,6 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
|
||||||
keySyms.mapWidth = mapWidth;
|
keySyms.mapWidth = mapWidth;
|
||||||
keySyms.map = keymap;
|
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,
|
InitKeyboardDeviceStruct(pDev, NULL,
|
||||||
xnestBell, xnestChangeKeyboardControl);
|
xnestBell, xnestChangeKeyboardControl);
|
||||||
|
|
||||||
|
@ -175,8 +160,61 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
|
||||||
keySyms.maxKeyCode - keySyms.minKeyCode + 1,
|
keySyms.maxKeyCode - keySyms.minKeyCode + 1,
|
||||||
modmap, serverClient);
|
modmap, serverClient);
|
||||||
|
|
||||||
XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
|
xnest_xkb_init(xnestUpstreamInfo.conn);
|
||||||
XkbFreeKeyboard(xkb, 0, FALSE);
|
|
||||||
|
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);
|
free(keymap);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ xcb_dep = dependency('xcb', required: true)
|
||||||
xcb_aux_dep = dependency('xcb-aux', required: true)
|
xcb_aux_dep = dependency('xcb-aux', required: true)
|
||||||
xcb_shape_dep = dependency('xcb-shape', required: true)
|
xcb_shape_dep = dependency('xcb-shape', required: true)
|
||||||
xcb_icccm_dep = dependency('xcb-icccm', required: true)
|
xcb_icccm_dep = dependency('xcb-icccm', required: true)
|
||||||
|
xcb_xkb_dep = dependency('xcb-xkb', required: true)
|
||||||
|
|
||||||
executable(
|
executable(
|
||||||
'Xnest',
|
'Xnest',
|
||||||
|
@ -37,6 +38,7 @@ executable(
|
||||||
xcb_aux_dep,
|
xcb_aux_dep,
|
||||||
xcb_shape_dep,
|
xcb_shape_dep,
|
||||||
xcb_icccm_dep,
|
xcb_icccm_dep,
|
||||||
|
xcb_xkb_dep,
|
||||||
x11_xcb_dep,
|
x11_xcb_dep,
|
||||||
],
|
],
|
||||||
link_with: [
|
link_with: [
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
#include <X11/Xdefs.h>
|
#include <X11/Xdefs.h>
|
||||||
#include <X11/Xproto.h>
|
#include <X11/Xproto.h>
|
||||||
|
#include <xcb/xkb.h>
|
||||||
|
|
||||||
#include "include/gc.h"
|
#include "include/gc.h"
|
||||||
#include "include/servermd.h"
|
#include "include/servermd.h"
|
||||||
|
@ -180,3 +181,66 @@ void xnest_set_command(
|
||||||
nbytes,
|
nbytes,
|
||||||
buf);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -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_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 */
|
#endif /* __XNEST__XCB_H */
|
||||||
|
|
Loading…
Reference in New Issue