|
|
70130e |
From ae806ffa6b94bf75b9cb1b2db3e717fcaf13c8d0 Mon Sep 17 00:00:00 2001
|
|
|
70130e |
From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= <krh@bitplanet.net>
|
|
|
70130e |
Date: Tue, 9 Apr 2013 17:45:08 -0400
|
|
|
70130e |
Subject: [PATCH 04/39] xkb: Add XkbCompileKeymapFromString()
|
|
|
70130e |
|
|
|
70130e |
This new function compiles a keymap from an in-memory string. We use it
|
|
|
70130e |
to add a new keyooard device init function,
|
|
|
70130e |
InitKeyboardDeviceStructFromString(), which inits a keyboard device with
|
|
|
70130e |
a keymap specified as a string instead of a rmlvo set.
|
|
|
70130e |
|
|
|
70130e |
Reviewed-by: Daniel Stone <daniel@fooishbar.org>
|
|
|
70130e |
---
|
|
|
70130e |
include/input.h | 6 +++
|
|
|
70130e |
include/xkbsrv.h | 4 ++
|
|
|
70130e |
xkb/ddxLoad.c | 129 ++++++++++++++++++++++++++++++++++++++++++-------------
|
|
|
70130e |
xkb/xkbInit.c | 44 +++++++++++++++----
|
|
|
70130e |
4 files changed, 144 insertions(+), 39 deletions(-)
|
|
|
70130e |
|
|
|
70130e |
diff --git a/include/input.h b/include/input.h
|
|
|
70130e |
index 350daba..6573a3a 100644
|
|
|
70130e |
--- a/include/input.h
|
|
|
70130e |
+++ b/include/input.h
|
|
|
70130e |
@@ -385,6 +385,12 @@ extern _X_EXPORT Bool InitKeyboardDeviceStruct(DeviceIntPtr /*device */ ,
|
|
|
70130e |
KbdCtrlProcPtr /*controlProc */
|
|
|
70130e |
);
|
|
|
70130e |
|
|
|
70130e |
+extern _X_EXPORT Bool InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
|
|
|
70130e |
+ const char *keymap,
|
|
|
70130e |
+ int keymap_length,
|
|
|
70130e |
+ BellProcPtr bell_func,
|
|
|
70130e |
+ KbdCtrlProcPtr ctrl_func);
|
|
|
70130e |
+
|
|
|
70130e |
extern int ApplyPointerMapping(DeviceIntPtr /* pDev */ ,
|
|
|
70130e |
CARD8 * /* map */ ,
|
|
|
70130e |
int /* len */ ,
|
|
|
70130e |
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
|
|
|
70130e |
index 346ebcc..bef98ef 100644
|
|
|
70130e |
--- a/include/xkbsrv.h
|
|
|
70130e |
+++ b/include/xkbsrv.h
|
|
|
70130e |
@@ -861,4 +861,8 @@ extern _X_EXPORT XkbDescPtr XkbCompileKeymap(DeviceIntPtr /* dev */ ,
|
|
|
70130e |
XkbRMLVOSet * /* rmlvo */
|
|
|
70130e |
);
|
|
|
70130e |
|
|
|
70130e |
+extern _X_EXPORT XkbDescPtr XkbCompileKeymapFromString(DeviceIntPtr dev,
|
|
|
70130e |
+ const char *keymap,
|
|
|
70130e |
+ int keymap_length);
|
|
|
70130e |
+
|
|
|
70130e |
#endif /* _XKBSRV_H_ */
|
|
|
70130e |
diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
|
|
|
70130e |
index 001ff46..7a7cf1e 100644
|
|
|
70130e |
--- a/xkb/ddxLoad.c
|
|
|
70130e |
+++ b/xkb/ddxLoad.c
|
|
|
70130e |
@@ -262,6 +262,35 @@ XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
|
|
|
70130e |
return file;
|
|
|
70130e |
}
|
|
|
70130e |
|
|
|
70130e |
+static unsigned
|
|
|
70130e |
+LoadXKM(unsigned want, unsigned need, XkbCompContextPtr ctx, XkbDescPtr *xkbRtrn)
|
|
|
70130e |
+{
|
|
|
70130e |
+ FILE *file;
|
|
|
70130e |
+ char fileName[PATH_MAX];
|
|
|
70130e |
+ unsigned missing;
|
|
|
70130e |
+
|
|
|
70130e |
+ file = XkbDDXOpenConfigFile(ctx->keymap, fileName, PATH_MAX);
|
|
|
70130e |
+ if (file == NULL) {
|
|
|
70130e |
+ LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
|
|
|
70130e |
+ fileName);
|
|
|
70130e |
+ return 0;
|
|
|
70130e |
+ }
|
|
|
70130e |
+ missing = XkmReadFile(file, need, want, xkbRtrn);
|
|
|
70130e |
+ if (*xkbRtrn == NULL) {
|
|
|
70130e |
+ LogMessage(X_ERROR, "Error loading keymap %s\n", fileName);
|
|
|
70130e |
+ fclose(file);
|
|
|
70130e |
+ (void) unlink(fileName);
|
|
|
70130e |
+ return 0;
|
|
|
70130e |
+ }
|
|
|
70130e |
+ else {
|
|
|
70130e |
+ DebugF("Loaded XKB keymap %s, defined=0x%x\n", fileName,
|
|
|
70130e |
+ (*xkbRtrn)->defined);
|
|
|
70130e |
+ }
|
|
|
70130e |
+ fclose(file);
|
|
|
70130e |
+ (void) unlink(fileName);
|
|
|
70130e |
+ return (need | want) & (~missing);
|
|
|
70130e |
+}
|
|
|
70130e |
+
|
|
|
70130e |
unsigned
|
|
|
70130e |
XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
|
|
|
70130e |
XkbComponentNamesPtr names,
|
|
|
70130e |
@@ -270,9 +299,6 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
|
|
|
70130e |
XkbDescPtr *xkbRtrn, char *nameRtrn, int nameRtrnLen)
|
|
|
70130e |
{
|
|
|
70130e |
XkbDescPtr xkb;
|
|
|
70130e |
- FILE *file;
|
|
|
70130e |
- char fileName[PATH_MAX];
|
|
|
70130e |
- unsigned missing;
|
|
|
70130e |
XkbCompContextRec ctx;
|
|
|
70130e |
|
|
|
70130e |
*xkbRtrn = NULL;
|
|
|
70130e |
@@ -292,26 +318,30 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
|
|
|
70130e |
LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
|
|
|
70130e |
return 0;
|
|
|
70130e |
}
|
|
|
70130e |
- file = XkbDDXOpenConfigFile(ctx.keymap, fileName, PATH_MAX);
|
|
|
70130e |
- if (file == NULL) {
|
|
|
70130e |
- LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
|
|
|
70130e |
- fileName);
|
|
|
70130e |
- return 0;
|
|
|
70130e |
- }
|
|
|
70130e |
- missing = XkmReadFile(file, need, want, xkbRtrn);
|
|
|
70130e |
- if (*xkbRtrn == NULL) {
|
|
|
70130e |
- LogMessage(X_ERROR, "Error loading keymap %s\n", fileName);
|
|
|
70130e |
- fclose(file);
|
|
|
70130e |
- (void) unlink(fileName);
|
|
|
70130e |
+
|
|
|
70130e |
+ return LoadXKM(want, need, &ctx, xkbRtrn);
|
|
|
70130e |
+}
|
|
|
70130e |
+
|
|
|
70130e |
+static unsigned
|
|
|
70130e |
+XkbDDXLoadKeymapFromString(DeviceIntPtr keybd,
|
|
|
70130e |
+ const char *keymap, int keymap_length,
|
|
|
70130e |
+ unsigned want,
|
|
|
70130e |
+ unsigned need,
|
|
|
70130e |
+ XkbDescPtr *xkbRtrn)
|
|
|
70130e |
+{
|
|
|
70130e |
+ XkbCompContextRec ctx;
|
|
|
70130e |
+
|
|
|
70130e |
+ *xkbRtrn = NULL;
|
|
|
70130e |
+
|
|
|
70130e |
+ if (StartXkbComp(&ctx))
|
|
|
70130e |
+ fwrite(keymap, keymap_length, 1, ctx.out);
|
|
|
70130e |
+
|
|
|
70130e |
+ if (!FinishXkbComp(&ctx)) {
|
|
|
70130e |
+ LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
|
|
|
70130e |
return 0;
|
|
|
70130e |
}
|
|
|
70130e |
- else {
|
|
|
70130e |
- DebugF("Loaded XKB keymap %s, defined=0x%x\n", fileName,
|
|
|
70130e |
- (*xkbRtrn)->defined);
|
|
|
70130e |
- }
|
|
|
70130e |
- fclose(file);
|
|
|
70130e |
- (void) unlink(fileName);
|
|
|
70130e |
- return (need | want) & (~missing);
|
|
|
70130e |
+
|
|
|
70130e |
+ return LoadXKM(want, need, &ctx, xkbRtrn);
|
|
|
70130e |
}
|
|
|
70130e |
|
|
|
70130e |
Bool
|
|
|
70130e |
@@ -407,6 +437,29 @@ XkbCompileKeymapForDevice(DeviceIntPtr dev, XkbRMLVOSet * rmlvo, int need)
|
|
|
70130e |
return xkb;
|
|
|
70130e |
}
|
|
|
70130e |
|
|
|
70130e |
+static XkbDescPtr
|
|
|
70130e |
+KeymapOrDefaults(DeviceIntPtr dev, XkbDescPtr xkb)
|
|
|
70130e |
+{
|
|
|
70130e |
+ XkbRMLVOSet dflts;
|
|
|
70130e |
+
|
|
|
70130e |
+ if (xkb)
|
|
|
70130e |
+ return xkb;
|
|
|
70130e |
+
|
|
|
70130e |
+ /* we didn't get what we really needed. And that will likely leave
|
|
|
70130e |
+ * us with a keyboard that doesn't work. Use the defaults instead */
|
|
|
70130e |
+ LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default "
|
|
|
70130e |
+ "keymap instead.\n");
|
|
|
70130e |
+
|
|
|
70130e |
+ XkbGetRulesDflts(&dflts);
|
|
|
70130e |
+
|
|
|
70130e |
+ xkb = XkbCompileKeymapForDevice(dev, &dflts, 0);
|
|
|
70130e |
+
|
|
|
70130e |
+ XkbFreeRMLVOSet(&dflts, FALSE);
|
|
|
70130e |
+
|
|
|
70130e |
+ return xkb;
|
|
|
70130e |
+}
|
|
|
70130e |
+
|
|
|
70130e |
+
|
|
|
70130e |
XkbDescPtr
|
|
|
70130e |
XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
|
|
|
70130e |
{
|
|
|
70130e |
@@ -424,20 +477,34 @@ XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
|
|
|
70130e |
|
|
|
70130e |
xkb = XkbCompileKeymapForDevice(dev, rmlvo, need);
|
|
|
70130e |
|
|
|
70130e |
- if (!xkb) {
|
|
|
70130e |
- XkbRMLVOSet dflts;
|
|
|
70130e |
+ return KeymapOrDefaults(dev, xkb);
|
|
|
70130e |
+}
|
|
|
70130e |
|
|
|
70130e |
- /* we didn't get what we really needed. And that will likely leave
|
|
|
70130e |
- * us with a keyboard that doesn't work. Use the defaults instead */
|
|
|
70130e |
- LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default "
|
|
|
70130e |
- "keymap instead.\n");
|
|
|
70130e |
+XkbDescPtr
|
|
|
70130e |
+XkbCompileKeymapFromString(DeviceIntPtr dev,
|
|
|
70130e |
+ const char *keymap, int keymap_length)
|
|
|
70130e |
+{
|
|
|
70130e |
+ XkbDescPtr xkb;
|
|
|
70130e |
+ unsigned int need, provided;
|
|
|
70130e |
|
|
|
70130e |
- XkbGetRulesDflts(&dflts);
|
|
|
70130e |
+ if (!dev || !keymap) {
|
|
|
70130e |
+ LogMessage(X_ERROR, "XKB: No device or keymap specified\n");
|
|
|
70130e |
+ return NULL;
|
|
|
70130e |
+ }
|
|
|
70130e |
|
|
|
70130e |
- xkb = XkbCompileKeymapForDevice(dev, &dflts, 0);
|
|
|
70130e |
+ /* These are the components we really really need */
|
|
|
70130e |
+ need = XkmSymbolsMask | XkmCompatMapMask | XkmTypesMask |
|
|
|
70130e |
+ XkmKeyNamesMask | XkmVirtualModsMask;
|
|
|
70130e |
|
|
|
70130e |
- XkbFreeRMLVOSet(&dflts, FALSE);
|
|
|
70130e |
+ provided =
|
|
|
70130e |
+ XkbDDXLoadKeymapFromString(dev, keymap, keymap_length,
|
|
|
70130e |
+ XkmAllIndicesMask, need, &xkb);
|
|
|
70130e |
+ if ((need & provided) != need) {
|
|
|
70130e |
+ if (xkb) {
|
|
|
70130e |
+ XkbFreeKeyboard(xkb, 0, TRUE);
|
|
|
70130e |
+ xkb = NULL;
|
|
|
70130e |
+ }
|
|
|
70130e |
}
|
|
|
70130e |
|
|
|
70130e |
- return xkb;
|
|
|
70130e |
+ return KeymapOrDefaults(dev, xkb);
|
|
|
70130e |
}
|
|
|
70130e |
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
|
|
|
70130e |
index f72655f..f3f0d8f 100644
|
|
|
70130e |
--- a/xkb/xkbInit.c
|
|
|
70130e |
+++ b/xkb/xkbInit.c
|
|
|
70130e |
@@ -490,9 +490,10 @@ XkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
|
|
|
70130e |
return Success;
|
|
|
70130e |
}
|
|
|
70130e |
|
|
|
70130e |
-_X_EXPORT Bool
|
|
|
70130e |
-InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
|
|
70130e |
- BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
|
|
|
70130e |
+static Bool
|
|
|
70130e |
+InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
|
|
70130e |
+ const char *keymap, int keymap_length,
|
|
|
70130e |
+ BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
|
|
|
70130e |
{
|
|
|
70130e |
int i;
|
|
|
70130e |
unsigned int check;
|
|
|
70130e |
@@ -507,7 +508,7 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
|
|
70130e |
BUG_RETURN_VAL(dev->key != NULL, FALSE);
|
|
|
70130e |
BUG_RETURN_VAL(dev->kbdfeed != NULL, FALSE);
|
|
|
70130e |
|
|
|
70130e |
- if (!rmlvo) {
|
|
|
70130e |
+ if (!rmlvo && !keymap) {
|
|
|
70130e |
rmlvo = &rmlvo_dflts;
|
|
|
70130e |
XkbGetRulesDflts(rmlvo);
|
|
|
70130e |
}
|
|
|
70130e |
@@ -535,19 +536,26 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
|
|
70130e |
}
|
|
|
70130e |
dev->key->xkbInfo = xkbi;
|
|
|
70130e |
|
|
|
70130e |
- if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) {
|
|
|
70130e |
+ if (xkb_cached_map && (keymap || (rmlvo && !XkbCompareUsedRMLVO(rmlvo)))) {
|
|
|
70130e |
XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
|
|
|
70130e |
xkb_cached_map = NULL;
|
|
|
70130e |
}
|
|
|
70130e |
|
|
|
70130e |
if (xkb_cached_map)
|
|
|
70130e |
LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
|
|
|
70130e |
- else {
|
|
|
70130e |
+ else if (rmlvo) {
|
|
|
70130e |
xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
|
|
|
70130e |
if (!xkb_cached_map) {
|
|
|
70130e |
ErrorF("XKB: Failed to compile keymap\n");
|
|
|
70130e |
goto unwind_info;
|
|
|
70130e |
}
|
|
|
70130e |
+ } else {
|
|
|
70130e |
+ xkb_cached_map = XkbCompileKeymapFromString(dev,
|
|
|
70130e |
+ keymap, keymap_length);
|
|
|
70130e |
+ if (!xkb_cached_map) {
|
|
|
70130e |
+ ErrorF("XKB: Failed to compile keymap from string\n");
|
|
|
70130e |
+ goto unwind_info;
|
|
|
70130e |
+ }
|
|
|
70130e |
}
|
|
|
70130e |
|
|
|
70130e |
xkb = XkbAllocKeyboard();
|
|
|
70130e |
@@ -612,8 +620,10 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
|
|
70130e |
|
|
|
70130e |
dev->kbdfeed->CtrlProc(dev, &dev->kbdfeed->ctrl);
|
|
|
70130e |
|
|
|
70130e |
- XkbSetRulesDflts(rmlvo);
|
|
|
70130e |
- XkbSetRulesUsed(rmlvo);
|
|
|
70130e |
+ if (rmlvo) {
|
|
|
70130e |
+ XkbSetRulesDflts(rmlvo);
|
|
|
70130e |
+ XkbSetRulesUsed(rmlvo);
|
|
|
70130e |
+ }
|
|
|
70130e |
XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
|
|
|
70130e |
|
|
|
70130e |
return TRUE;
|
|
|
70130e |
@@ -632,6 +642,24 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
|
|
70130e |
return FALSE;
|
|
|
70130e |
}
|
|
|
70130e |
|
|
|
70130e |
+_X_EXPORT Bool
|
|
|
70130e |
+InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
|
|
70130e |
+ BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
|
|
|
70130e |
+{
|
|
|
70130e |
+ return InitKeyboardDeviceStructInternal(dev, rmlvo,
|
|
|
70130e |
+ NULL, 0, bell_func, ctrl_func);
|
|
|
70130e |
+}
|
|
|
70130e |
+
|
|
|
70130e |
+_X_EXPORT Bool
|
|
|
70130e |
+InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
|
|
|
70130e |
+ const char *keymap, int keymap_length,
|
|
|
70130e |
+ BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
|
|
|
70130e |
+{
|
|
|
70130e |
+ return InitKeyboardDeviceStructInternal(dev, NULL,
|
|
|
70130e |
+ keymap, keymap_length,
|
|
|
70130e |
+ bell_func, ctrl_func);
|
|
|
70130e |
+}
|
|
|
70130e |
+
|
|
|
70130e |
/***====================================================================***/
|
|
|
70130e |
|
|
|
70130e |
/*
|
|
|
70130e |
--
|
|
|
70130e |
1.8.3.1
|
|
|
70130e |
|