Merge remote-tracking branch 'whot/for-keith'
This commit is contained in:
commit
4fb31e4824
|
@ -230,7 +230,7 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
|
||||||
|
|
||||||
mk->sourceid = device->id;
|
mk->sourceid = device->id;
|
||||||
|
|
||||||
if (!XkbCopyDeviceKeymap(master, device))
|
if (!XkbDeviceApplyKeymap(master, device->key->xkbInfo->desc))
|
||||||
FatalError("Couldn't pivot keymap from device to core!\n");
|
FatalError("Couldn't pivot keymap from device to core!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -385,6 +385,12 @@ extern _X_EXPORT Bool InitKeyboardDeviceStruct(DeviceIntPtr /*device */ ,
|
||||||
KbdCtrlProcPtr /*controlProc */
|
KbdCtrlProcPtr /*controlProc */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
extern _X_EXPORT Bool InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
|
||||||
|
const char *keymap,
|
||||||
|
int keymap_length,
|
||||||
|
BellProcPtr bell_func,
|
||||||
|
KbdCtrlProcPtr ctrl_func);
|
||||||
|
|
||||||
extern int ApplyPointerMapping(DeviceIntPtr /* pDev */ ,
|
extern int ApplyPointerMapping(DeviceIntPtr /* pDev */ ,
|
||||||
CARD8 * /* map */ ,
|
CARD8 * /* map */ ,
|
||||||
int /* len */ ,
|
int /* len */ ,
|
||||||
|
|
|
@ -824,8 +824,8 @@ extern _X_EXPORT void XkbSendNewKeyboardNotify(DeviceIntPtr /* kbd */ ,
|
||||||
extern Bool XkbCopyKeymap(XkbDescPtr /* dst */ ,
|
extern Bool XkbCopyKeymap(XkbDescPtr /* dst */ ,
|
||||||
XkbDescPtr /* src */ );
|
XkbDescPtr /* src */ );
|
||||||
|
|
||||||
extern _X_EXPORT Bool XkbCopyDeviceKeymap(DeviceIntPtr /* dst */ ,
|
extern _X_EXPORT Bool XkbDeviceApplyKeymap(DeviceIntPtr /* dst */ ,
|
||||||
DeviceIntPtr /* src */ );
|
XkbDescPtr /* src */ );
|
||||||
|
|
||||||
extern void XkbFilterEvents(ClientPtr /* pClient */ ,
|
extern void XkbFilterEvents(ClientPtr /* pClient */ ,
|
||||||
int /* nEvents */ ,
|
int /* nEvents */ ,
|
||||||
|
@ -841,6 +841,9 @@ extern void XkbFakeDeviceButton(DeviceIntPtr /* dev */ ,
|
||||||
int /* press */ ,
|
int /* press */ ,
|
||||||
int /* button */ );
|
int /* button */ );
|
||||||
|
|
||||||
|
extern _X_EXPORT void XkbCopyControls(XkbDescPtr /* dst */ ,
|
||||||
|
XkbDescPtr /* src */ );
|
||||||
|
|
||||||
#include "xkbfile.h"
|
#include "xkbfile.h"
|
||||||
#include "xkbrules.h"
|
#include "xkbrules.h"
|
||||||
|
|
||||||
|
@ -873,4 +876,8 @@ extern _X_EXPORT XkbDescPtr XkbCompileKeymap(DeviceIntPtr /* dev */ ,
|
||||||
XkbRMLVOSet * /* rmlvo */
|
XkbRMLVOSet * /* rmlvo */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
extern _X_EXPORT XkbDescPtr XkbCompileKeymapFromString(DeviceIntPtr dev,
|
||||||
|
const char *keymap,
|
||||||
|
int keymap_length);
|
||||||
|
|
||||||
#endif /* _XKBSRV_H_ */
|
#endif /* _XKBSRV_H_ */
|
||||||
|
|
252
xkb/ddxLoad.c
252
xkb/ddxLoad.c
|
@ -68,6 +68,9 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#define PATHSEPARATOR "/"
|
#define PATHSEPARATOR "/"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
LoadXKM(unsigned want, unsigned need, const char *keymap, XkbDescPtr *xkbRtrn);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
OutputDirectory(char *outdir, size_t size)
|
OutputDirectory(char *outdir, size_t size)
|
||||||
{
|
{
|
||||||
|
@ -90,11 +93,17 @@ OutputDirectory(char *outdir, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
/**
|
||||||
XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
|
* Callback invoked by XkbRunXkbComp. Write to out to talk to xkbcomp.
|
||||||
XkbComponentNamesPtr names,
|
*/
|
||||||
unsigned want,
|
typedef void (*xkbcomp_buffer_callback)(FILE *out, void *userdata);
|
||||||
unsigned need, char *nameRtrn, int nameRtrnLen)
|
|
||||||
|
/**
|
||||||
|
* Start xkbcomp, let the callback write into xkbcomp's stdin. When done,
|
||||||
|
* return a strdup'd copy of the file name we've written to.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
RunXkbComp(xkbcomp_buffer_callback callback, void *userdata)
|
||||||
{
|
{
|
||||||
FILE *out;
|
FILE *out;
|
||||||
char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX];
|
char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX];
|
||||||
|
@ -155,7 +164,7 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
LogMessage(X_ERROR,
|
LogMessage(X_ERROR,
|
||||||
"XKB: Could not invoke xkbcomp: not enough memory\n");
|
"XKB: Could not invoke xkbcomp: not enough memory\n");
|
||||||
return FALSE;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
@ -165,13 +174,9 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (out != NULL) {
|
if (out != NULL) {
|
||||||
#ifdef DEBUG
|
/* Now write to xkbcomp */
|
||||||
if (xkbDebugFlags) {
|
(*callback)(out, userdata);
|
||||||
ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
|
|
||||||
XkbWriteXKBKeymapForNames(stderr, names, xkb, want, need);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
XkbWriteXKBKeymapForNames(out, names, xkb, want, need);
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
if (Pclose(out) == 0)
|
if (Pclose(out) == 0)
|
||||||
#else
|
#else
|
||||||
|
@ -180,14 +185,11 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
|
||||||
{
|
{
|
||||||
if (xkbDebugFlags)
|
if (xkbDebugFlags)
|
||||||
DebugF("[xkb] xkb executes: %s\n", buf);
|
DebugF("[xkb] xkb executes: %s\n", buf);
|
||||||
if (nameRtrn) {
|
|
||||||
strlcpy(nameRtrn, keymap, nameRtrnLen);
|
|
||||||
}
|
|
||||||
free(buf);
|
free(buf);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
unlink(tmpname);
|
unlink(tmpname);
|
||||||
#endif
|
#endif
|
||||||
return TRUE;
|
return xnfstrdup(keymap);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap);
|
LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap);
|
||||||
|
@ -203,14 +205,101 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
|
||||||
LogMessage(X_ERROR, "Could not open file %s\n", tmpname);
|
LogMessage(X_ERROR, "Could not open file %s\n", tmpname);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (nameRtrn)
|
|
||||||
nameRtrn[0] = '\0';
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return FALSE;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
XkbDescPtr xkb;
|
||||||
|
XkbComponentNamesPtr names;
|
||||||
|
unsigned int want;
|
||||||
|
unsigned int need;
|
||||||
|
} XkbKeymapNamesCtx;
|
||||||
|
|
||||||
|
static void
|
||||||
|
xkb_write_keymap_for_names_cb(FILE *out, void *userdata)
|
||||||
|
{
|
||||||
|
XkbKeymapNamesCtx *ctx = userdata;
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (xkbDebugFlags) {
|
||||||
|
ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
|
||||||
|
XkbWriteXKBKeymapForNames(stderr, ctx->names, ctx->xkb, ctx->want, ctx->need);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
XkbWriteXKBKeymapForNames(out, ctx->names, ctx->xkb, ctx->want, ctx->need);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
|
||||||
|
XkbComponentNamesPtr names,
|
||||||
|
unsigned want,
|
||||||
|
unsigned need, char *nameRtrn, int nameRtrnLen)
|
||||||
|
{
|
||||||
|
char *keymap;
|
||||||
|
Bool rc = FALSE;
|
||||||
|
XkbKeymapNamesCtx ctx = {
|
||||||
|
.xkb = xkb,
|
||||||
|
.names = names,
|
||||||
|
.want = want,
|
||||||
|
.need = need
|
||||||
|
};
|
||||||
|
|
||||||
|
keymap = RunXkbComp(xkb_write_keymap_for_names_cb, &ctx);
|
||||||
|
|
||||||
|
if (keymap) {
|
||||||
|
if(nameRtrn)
|
||||||
|
strlcpy(nameRtrn, keymap, nameRtrnLen);
|
||||||
|
|
||||||
|
free(keymap);
|
||||||
|
rc = TRUE;
|
||||||
|
} else if (nameRtrn)
|
||||||
|
*nameRtrn = '\0';
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *keymap;
|
||||||
|
size_t len;
|
||||||
|
} XkbKeymapString;
|
||||||
|
|
||||||
|
static void
|
||||||
|
xkb_write_keymap_string_cb(FILE *out, void *userdata)
|
||||||
|
{
|
||||||
|
XkbKeymapString *s = userdata;
|
||||||
|
fwrite(s->keymap, s->len, 1, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
XkbDDXLoadKeymapFromString(DeviceIntPtr keybd,
|
||||||
|
const char *keymap, int keymap_length,
|
||||||
|
unsigned int want,
|
||||||
|
unsigned int need,
|
||||||
|
XkbDescPtr *xkbRtrn)
|
||||||
|
{
|
||||||
|
unsigned int have;
|
||||||
|
char *map_name;
|
||||||
|
XkbKeymapString map = {
|
||||||
|
.keymap = keymap,
|
||||||
|
.len = keymap_length
|
||||||
|
};
|
||||||
|
|
||||||
|
*xkbRtrn = NULL;
|
||||||
|
|
||||||
|
map_name = RunXkbComp(xkb_write_keymap_string_cb, &map);
|
||||||
|
if (!map_name) {
|
||||||
|
LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
have = LoadXKM(want, need, map_name, xkbRtrn);
|
||||||
|
free(map_name);
|
||||||
|
|
||||||
|
return have;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE *
|
static FILE *
|
||||||
XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
|
XkbDDXOpenConfigFile(const char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
|
||||||
{
|
{
|
||||||
char buf[PATH_MAX], xkm_output_dir[PATH_MAX];
|
char buf[PATH_MAX], xkm_output_dir[PATH_MAX];
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
@ -245,37 +334,14 @@ XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
static unsigned
|
||||||
XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
|
LoadXKM(unsigned want, unsigned need, const char *keymap, XkbDescPtr *xkbRtrn)
|
||||||
XkbComponentNamesPtr names,
|
|
||||||
unsigned want,
|
|
||||||
unsigned need,
|
|
||||||
XkbDescPtr *xkbRtrn, char *nameRtrn, int nameRtrnLen)
|
|
||||||
{
|
{
|
||||||
XkbDescPtr xkb;
|
|
||||||
FILE *file;
|
FILE *file;
|
||||||
char fileName[PATH_MAX];
|
char fileName[PATH_MAX];
|
||||||
unsigned missing;
|
unsigned missing;
|
||||||
|
|
||||||
*xkbRtrn = NULL;
|
file = XkbDDXOpenConfigFile(keymap, fileName, PATH_MAX);
|
||||||
if ((keybd == NULL) || (keybd->key == NULL) ||
|
|
||||||
(keybd->key->xkbInfo == NULL))
|
|
||||||
xkb = NULL;
|
|
||||||
else
|
|
||||||
xkb = keybd->key->xkbInfo->desc;
|
|
||||||
if ((names->keycodes == NULL) && (names->types == NULL) &&
|
|
||||||
(names->compat == NULL) && (names->symbols == NULL) &&
|
|
||||||
(names->geometry == NULL)) {
|
|
||||||
LogMessage(X_ERROR, "XKB: No components provided for device %s\n",
|
|
||||||
keybd->name ? keybd->name : "(unnamed keyboard)");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (!XkbDDXCompileKeymapByNames(xkb, names, want, need,
|
|
||||||
nameRtrn, nameRtrnLen)) {
|
|
||||||
LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
file = XkbDDXOpenConfigFile(nameRtrn, fileName, PATH_MAX);
|
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
|
LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
|
||||||
fileName);
|
fileName);
|
||||||
|
@ -297,6 +363,37 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
|
||||||
return (need | want) & (~missing);
|
return (need | want) & (~missing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
|
||||||
|
XkbComponentNamesPtr names,
|
||||||
|
unsigned want,
|
||||||
|
unsigned need,
|
||||||
|
XkbDescPtr *xkbRtrn, char *nameRtrn, int nameRtrnLen)
|
||||||
|
{
|
||||||
|
XkbDescPtr xkb;
|
||||||
|
|
||||||
|
*xkbRtrn = NULL;
|
||||||
|
if ((keybd == NULL) || (keybd->key == NULL) ||
|
||||||
|
(keybd->key->xkbInfo == NULL))
|
||||||
|
xkb = NULL;
|
||||||
|
else
|
||||||
|
xkb = keybd->key->xkbInfo->desc;
|
||||||
|
if ((names->keycodes == NULL) && (names->types == NULL) &&
|
||||||
|
(names->compat == NULL) && (names->symbols == NULL) &&
|
||||||
|
(names->geometry == NULL)) {
|
||||||
|
LogMessage(X_ERROR, "XKB: No components provided for device %s\n",
|
||||||
|
keybd->name ? keybd->name : "(unnamed keyboard)");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (!XkbDDXCompileKeymapByNames(xkb, names, want, need,
|
||||||
|
nameRtrn, nameRtrnLen)) {
|
||||||
|
LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LoadXKM(want, need, nameRtrn, xkbRtrn);
|
||||||
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
XkbDDXNamesFromRules(DeviceIntPtr keybd,
|
XkbDDXNamesFromRules(DeviceIntPtr keybd,
|
||||||
const char *rules_name,
|
const char *rules_name,
|
||||||
|
@ -390,6 +487,29 @@ XkbCompileKeymapForDevice(DeviceIntPtr dev, XkbRMLVOSet * rmlvo, int need)
|
||||||
return xkb;
|
return xkb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static XkbDescPtr
|
||||||
|
KeymapOrDefaults(DeviceIntPtr dev, XkbDescPtr xkb)
|
||||||
|
{
|
||||||
|
XkbRMLVOSet dflts;
|
||||||
|
|
||||||
|
if (xkb)
|
||||||
|
return xkb;
|
||||||
|
|
||||||
|
/* we didn't get what we really needed. And that will likely leave
|
||||||
|
* us with a keyboard that doesn't work. Use the defaults instead */
|
||||||
|
LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default "
|
||||||
|
"keymap instead.\n");
|
||||||
|
|
||||||
|
XkbGetRulesDflts(&dflts);
|
||||||
|
|
||||||
|
xkb = XkbCompileKeymapForDevice(dev, &dflts, 0);
|
||||||
|
|
||||||
|
XkbFreeRMLVOSet(&dflts, FALSE);
|
||||||
|
|
||||||
|
return xkb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
XkbDescPtr
|
XkbDescPtr
|
||||||
XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
|
XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
|
||||||
{
|
{
|
||||||
|
@ -407,20 +527,34 @@ XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
|
||||||
|
|
||||||
xkb = XkbCompileKeymapForDevice(dev, rmlvo, need);
|
xkb = XkbCompileKeymapForDevice(dev, rmlvo, need);
|
||||||
|
|
||||||
if (!xkb) {
|
return KeymapOrDefaults(dev, xkb);
|
||||||
XkbRMLVOSet dflts;
|
}
|
||||||
|
|
||||||
/* we didn't get what we really needed. And that will likely leave
|
XkbDescPtr
|
||||||
* us with a keyboard that doesn't work. Use the defaults instead */
|
XkbCompileKeymapFromString(DeviceIntPtr dev,
|
||||||
LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default "
|
const char *keymap, int keymap_length)
|
||||||
"keymap instead.\n");
|
{
|
||||||
|
XkbDescPtr xkb;
|
||||||
|
unsigned int need, provided;
|
||||||
|
|
||||||
XkbGetRulesDflts(&dflts);
|
if (!dev || !keymap) {
|
||||||
|
LogMessage(X_ERROR, "XKB: No device or keymap specified\n");
|
||||||
xkb = XkbCompileKeymapForDevice(dev, &dflts, 0);
|
return NULL;
|
||||||
|
|
||||||
XkbFreeRMLVOSet(&dflts, FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return xkb;
|
/* These are the components we really really need */
|
||||||
|
need = XkmSymbolsMask | XkmCompatMapMask | XkmTypesMask |
|
||||||
|
XkmKeyNamesMask | XkmVirtualModsMask;
|
||||||
|
|
||||||
|
provided =
|
||||||
|
XkbDDXLoadKeymapFromString(dev, keymap, keymap_length,
|
||||||
|
XkmAllIndicesMask, need, &xkb);
|
||||||
|
if ((need & provided) != need) {
|
||||||
|
if (xkb) {
|
||||||
|
XkbFreeKeyboard(xkb, 0, TRUE);
|
||||||
|
xkb = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return KeymapOrDefaults(dev, xkb);
|
||||||
}
|
}
|
||||||
|
|
16
xkb/xkb.c
16
xkb/xkb.c
|
@ -5950,25 +5950,13 @@ ProcXkbGetKbdByName(ClientPtr client)
|
||||||
if (rep.loaded) {
|
if (rep.loaded) {
|
||||||
XkbDescPtr old_xkb;
|
XkbDescPtr old_xkb;
|
||||||
xkbNewKeyboardNotify nkn;
|
xkbNewKeyboardNotify nkn;
|
||||||
int i, nG, nTG;
|
|
||||||
|
|
||||||
old_xkb = xkb;
|
old_xkb = xkb;
|
||||||
xkb = new;
|
xkb = new;
|
||||||
dev->key->xkbInfo->desc = xkb;
|
dev->key->xkbInfo->desc = xkb;
|
||||||
new = old_xkb; /* so it'll get freed automatically */
|
new = old_xkb; /* so it'll get freed automatically */
|
||||||
|
|
||||||
*xkb->ctrls = *old_xkb->ctrls;
|
XkbCopyControls(xkb, old_xkb);
|
||||||
for (nG = nTG = 0, i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
|
|
||||||
nG = XkbKeyNumGroups(xkb, i);
|
|
||||||
if (nG >= XkbNumKbdGroups) {
|
|
||||||
nTG = XkbNumKbdGroups;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (nG > nTG) {
|
|
||||||
nTG = nG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xkb->ctrls->num_groups = nTG;
|
|
||||||
|
|
||||||
nkn.deviceID = nkn.oldDeviceID = dev->id;
|
nkn.deviceID = nkn.oldDeviceID = dev->id;
|
||||||
nkn.minKeyCode = new->min_key_code;
|
nkn.minKeyCode = new->min_key_code;
|
||||||
|
@ -5991,7 +5979,7 @@ ProcXkbGetKbdByName(ClientPtr client)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (tmpd != dev)
|
if (tmpd != dev)
|
||||||
XkbCopyDeviceKeymap(tmpd, dev);
|
XkbDeviceApplyKeymap(tmpd, xkb);
|
||||||
|
|
||||||
if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
|
if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
|
||||||
old_sli = tmpd->kbdfeed->xkb_sli;
|
old_sli = tmpd->kbdfeed->xkb_sli;
|
||||||
|
|
|
@ -505,9 +505,10 @@ XkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
_X_EXPORT Bool
|
static Bool
|
||||||
InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
||||||
BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
|
const char *keymap, int keymap_length,
|
||||||
|
BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned int check;
|
unsigned int check;
|
||||||
|
@ -521,8 +522,9 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
||||||
BUG_RETURN_VAL(dev == NULL, FALSE);
|
BUG_RETURN_VAL(dev == NULL, FALSE);
|
||||||
BUG_RETURN_VAL(dev->key != NULL, FALSE);
|
BUG_RETURN_VAL(dev->key != NULL, FALSE);
|
||||||
BUG_RETURN_VAL(dev->kbdfeed != NULL, FALSE);
|
BUG_RETURN_VAL(dev->kbdfeed != NULL, FALSE);
|
||||||
|
BUG_RETURN_VAL(rmlvo && keymap, FALSE);
|
||||||
|
|
||||||
if (!rmlvo) {
|
if (!rmlvo && !keymap) {
|
||||||
rmlvo = &rmlvo_dflts;
|
rmlvo = &rmlvo_dflts;
|
||||||
XkbGetRulesDflts(rmlvo);
|
XkbGetRulesDflts(rmlvo);
|
||||||
}
|
}
|
||||||
|
@ -550,7 +552,7 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
||||||
}
|
}
|
||||||
dev->key->xkbInfo = xkbi;
|
dev->key->xkbInfo = xkbi;
|
||||||
|
|
||||||
if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) {
|
if (xkb_cached_map && (keymap || (rmlvo && !XkbCompareUsedRMLVO(rmlvo)))) {
|
||||||
XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
|
XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
|
||||||
xkb_cached_map = NULL;
|
xkb_cached_map = NULL;
|
||||||
}
|
}
|
||||||
|
@ -558,7 +560,11 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
||||||
if (xkb_cached_map)
|
if (xkb_cached_map)
|
||||||
LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
|
LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
|
||||||
else {
|
else {
|
||||||
xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
|
if (rmlvo)
|
||||||
|
xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
|
||||||
|
else
|
||||||
|
xkb_cached_map = XkbCompileKeymapFromString(dev, keymap, keymap_length);
|
||||||
|
|
||||||
if (!xkb_cached_map) {
|
if (!xkb_cached_map) {
|
||||||
ErrorF("XKB: Failed to compile keymap\n");
|
ErrorF("XKB: Failed to compile keymap\n");
|
||||||
goto unwind_info;
|
goto unwind_info;
|
||||||
|
@ -627,8 +633,10 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
||||||
|
|
||||||
dev->kbdfeed->CtrlProc(dev, &dev->kbdfeed->ctrl);
|
dev->kbdfeed->CtrlProc(dev, &dev->kbdfeed->ctrl);
|
||||||
|
|
||||||
XkbSetRulesDflts(rmlvo);
|
if (rmlvo) {
|
||||||
XkbSetRulesUsed(rmlvo);
|
XkbSetRulesDflts(rmlvo);
|
||||||
|
XkbSetRulesUsed(rmlvo);
|
||||||
|
}
|
||||||
XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
|
XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -647,6 +655,24 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_X_EXPORT Bool
|
||||||
|
InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
||||||
|
BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
|
||||||
|
{
|
||||||
|
return InitKeyboardDeviceStructInternal(dev, rmlvo,
|
||||||
|
NULL, 0, bell_func, ctrl_func);
|
||||||
|
}
|
||||||
|
|
||||||
|
_X_EXPORT Bool
|
||||||
|
InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
|
||||||
|
const char *keymap, int keymap_length,
|
||||||
|
BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
|
||||||
|
{
|
||||||
|
return InitKeyboardDeviceStructInternal(dev, NULL,
|
||||||
|
keymap, keymap_length,
|
||||||
|
bell_func, ctrl_func);
|
||||||
|
}
|
||||||
|
|
||||||
/***====================================================================***/
|
/***====================================================================***/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1999,28 +1999,28 @@ XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src)
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
|
XkbDeviceApplyKeymap(DeviceIntPtr dst, XkbDescPtr desc)
|
||||||
{
|
{
|
||||||
xkbNewKeyboardNotify nkn;
|
xkbNewKeyboardNotify nkn;
|
||||||
Bool ret;
|
Bool ret;
|
||||||
|
|
||||||
if (!dst->key || !src->key)
|
if (!dst->key || !desc)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
|
memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
|
||||||
nkn.oldMinKeyCode = dst->key->xkbInfo->desc->min_key_code;
|
nkn.oldMinKeyCode = dst->key->xkbInfo->desc->min_key_code;
|
||||||
nkn.oldMaxKeyCode = dst->key->xkbInfo->desc->max_key_code;
|
nkn.oldMaxKeyCode = dst->key->xkbInfo->desc->max_key_code;
|
||||||
nkn.deviceID = dst->id;
|
nkn.deviceID = dst->id;
|
||||||
nkn.oldDeviceID = dst->id; /* maybe src->id? */
|
nkn.oldDeviceID = dst->id;
|
||||||
nkn.minKeyCode = src->key->xkbInfo->desc->min_key_code;
|
nkn.minKeyCode = desc->min_key_code;
|
||||||
nkn.maxKeyCode = src->key->xkbInfo->desc->max_key_code;
|
nkn.maxKeyCode = desc->max_key_code;
|
||||||
nkn.requestMajor = XkbReqCode;
|
nkn.requestMajor = XkbReqCode;
|
||||||
nkn.requestMinor = X_kbSetMap; /* Near enough's good enough. */
|
nkn.requestMinor = X_kbSetMap; /* Near enough's good enough. */
|
||||||
nkn.changed = XkbNKN_KeycodesMask;
|
nkn.changed = XkbNKN_KeycodesMask;
|
||||||
if (src->key->xkbInfo->desc->geom)
|
if (desc->geom)
|
||||||
nkn.changed |= XkbNKN_GeometryMask;
|
nkn.changed |= XkbNKN_GeometryMask;
|
||||||
|
|
||||||
ret = XkbCopyKeymap(dst->key->xkbInfo->desc, src->key->xkbInfo->desc);
|
ret = XkbCopyKeymap(dst->key->xkbInfo->desc, desc);
|
||||||
if (ret)
|
if (ret)
|
||||||
XkbSendNewKeyboardNotify(dst, &nkn);
|
XkbSendNewKeyboardNotify(dst, &nkn);
|
||||||
|
|
||||||
|
@ -2090,3 +2090,26 @@ XkbMergeLockedPtrBtns(DeviceIntPtr master)
|
||||||
xkbi->lockedPtrButtons |= d->key->xkbInfo->lockedPtrButtons;
|
xkbi->lockedPtrButtons |= d->key->xkbInfo->lockedPtrButtons;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
XkbCopyControls(XkbDescPtr dst, XkbDescPtr src)
|
||||||
|
{
|
||||||
|
int i, nG, nTG;
|
||||||
|
|
||||||
|
if (!dst || !src)
|
||||||
|
return;
|
||||||
|
|
||||||
|
*dst->ctrls = *src->ctrls;
|
||||||
|
|
||||||
|
for (nG = nTG = 0, i = dst->min_key_code; i <= dst->max_key_code; i++) {
|
||||||
|
nG = XkbKeyNumGroups(dst, i);
|
||||||
|
if (nG >= XkbNumKbdGroups) {
|
||||||
|
nTG = XkbNumKbdGroups;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nG > nTG) {
|
||||||
|
nTG = nG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst->ctrls->num_groups = nTG;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user