xkb: add XkbLoadKeymapFromString

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
This commit is contained in:
Kristian Høgsberg 2014-03-12 16:31:25 +10:00 committed by Peter Hutterer
parent 8b6c79e19c
commit 0e531fbb97
4 changed files with 116 additions and 8 deletions

View File

@ -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 */ ,

View File

@ -876,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_ */

View File

@ -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)
{ {
@ -255,6 +258,46 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
return rc; 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(const char *mapName, char *fileNameRtrn, int fileNameRtrnLen) XkbDDXOpenConfigFile(const char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
{ {
@ -486,3 +529,32 @@ XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
return KeymapOrDefaults(dev, xkb); 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);
}

View File

@ -505,8 +505,9 @@ XkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
return Success; return Success;
} }
_X_EXPORT Bool static Bool
InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo, InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
const char *keymap, int keymap_length,
BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func) BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
{ {
int i; int i;
@ -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 {
if (rmlvo)
xkb_cached_map = XkbCompileKeymap(dev, 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);
if (rmlvo) {
XkbSetRulesDflts(rmlvo); XkbSetRulesDflts(rmlvo);
XkbSetRulesUsed(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);
}
/***====================================================================***/ /***====================================================================***/
/* /*