summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/input.h6
-rw-r--r--include/xkbsrv.h4
-rw-r--r--xkb/ddxLoad.c72
-rw-r--r--xkb/xkbInit.c42
4 files changed, 116 insertions, 8 deletions
diff --git a/include/input.h b/include/input.h
index 93c45107d..36463f2d1 100644
--- a/include/input.h
+++ b/include/input.h
@@ -385,6 +385,12 @@ extern _X_EXPORT Bool InitKeyboardDeviceStruct(DeviceIntPtr /*device */ ,
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 */ ,
CARD8 * /* map */ ,
int /* len */ ,
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index c1c1561cb..a80e11970 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -876,4 +876,8 @@ extern _X_EXPORT XkbDescPtr XkbCompileKeymap(DeviceIntPtr /* dev */ ,
XkbRMLVOSet * /* rmlvo */
);
+extern _X_EXPORT XkbDescPtr XkbCompileKeymapFromString(DeviceIntPtr dev,
+ const char *keymap,
+ int keymap_length);
+
#endif /* _XKBSRV_H_ */
diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index 76bf09ca7..1dc0e4eee 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -68,6 +68,9 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define PATHSEPARATOR "/"
#endif
+static unsigned
+LoadXKM(unsigned want, unsigned need, const char *keymap, XkbDescPtr *xkbRtrn);
+
static void
OutputDirectory(char *outdir, size_t size)
{
@@ -255,6 +258,46 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
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 *
XkbDDXOpenConfigFile(const char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
{
@@ -486,3 +529,32 @@ XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
return KeymapOrDefaults(dev, xkb);
}
+
+XkbDescPtr
+XkbCompileKeymapFromString(DeviceIntPtr dev,
+ const char *keymap, int keymap_length)
+{
+ XkbDescPtr xkb;
+ unsigned int need, provided;
+
+ if (!dev || !keymap) {
+ LogMessage(X_ERROR, "XKB: No device or keymap specified\n");
+ return NULL;
+ }
+
+ /* 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);
+}
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index 33420b6b6..06ec46e81 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -505,9 +505,10 @@ XkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
return Success;
}
-_X_EXPORT Bool
-InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
- BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+static Bool
+InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
+ const char *keymap, int keymap_length,
+ BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
{
int i;
unsigned int check;
@@ -521,8 +522,9 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
BUG_RETURN_VAL(dev == NULL, FALSE);
BUG_RETURN_VAL(dev->key != NULL, FALSE);
BUG_RETURN_VAL(dev->kbdfeed != NULL, FALSE);
+ BUG_RETURN_VAL(rmlvo && keymap, FALSE);
- if (!rmlvo) {
+ if (!rmlvo && !keymap) {
rmlvo = &rmlvo_dflts;
XkbGetRulesDflts(rmlvo);
}
@@ -550,7 +552,7 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
}
dev->key->xkbInfo = xkbi;
- if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) {
+ if (xkb_cached_map && (keymap || (rmlvo && !XkbCompareUsedRMLVO(rmlvo)))) {
XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
xkb_cached_map = NULL;
}
@@ -558,7 +560,11 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
if (xkb_cached_map)
LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
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) {
ErrorF("XKB: Failed to compile keymap\n");
goto unwind_info;
@@ -627,8 +633,10 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
dev->kbdfeed->CtrlProc(dev, &dev->kbdfeed->ctrl);
- XkbSetRulesDflts(rmlvo);
- XkbSetRulesUsed(rmlvo);
+ if (rmlvo) {
+ XkbSetRulesDflts(rmlvo);
+ XkbSetRulesUsed(rmlvo);
+ }
XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
return TRUE;
@@ -647,6 +655,24 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
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);
+}
+
/***====================================================================***/
/*