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;
 | 
			
		||||
 | 
			
		||||
    if (!XkbCopyDeviceKeymap(master, device))
 | 
			
		||||
    if (!XkbDeviceApplyKeymap(master, device->key->xkbInfo->desc))
 | 
			
		||||
        FatalError("Couldn't pivot keymap from device to core!\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 */ ,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -824,8 +824,8 @@ extern _X_EXPORT void XkbSendNewKeyboardNotify(DeviceIntPtr /* kbd */ ,
 | 
			
		|||
extern Bool XkbCopyKeymap(XkbDescPtr /* dst */ ,
 | 
			
		||||
                          XkbDescPtr /* src */ );
 | 
			
		||||
 | 
			
		||||
extern _X_EXPORT Bool XkbCopyDeviceKeymap(DeviceIntPtr /* dst */ ,
 | 
			
		||||
                                          DeviceIntPtr /* src */ );
 | 
			
		||||
extern _X_EXPORT Bool XkbDeviceApplyKeymap(DeviceIntPtr /* dst */ ,
 | 
			
		||||
                                           XkbDescPtr /* src */ );
 | 
			
		||||
 | 
			
		||||
extern void XkbFilterEvents(ClientPtr /* pClient */ ,
 | 
			
		||||
                            int /* nEvents */ ,
 | 
			
		||||
| 
						 | 
				
			
			@ -841,6 +841,9 @@ extern void XkbFakeDeviceButton(DeviceIntPtr /* dev */ ,
 | 
			
		|||
                                int /* press */ ,
 | 
			
		||||
                                int /* button */ );
 | 
			
		||||
 | 
			
		||||
extern _X_EXPORT void XkbCopyControls(XkbDescPtr /* dst */ ,
 | 
			
		||||
                                      XkbDescPtr /* src */ );
 | 
			
		||||
 | 
			
		||||
#include "xkbfile.h"
 | 
			
		||||
#include "xkbrules.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -873,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_ */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										252
									
								
								xkb/ddxLoad.c
								
								
								
								
							
							
						
						
									
										252
									
								
								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)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -90,11 +93,17 @@ OutputDirectory(char *outdir, size_t size)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
 | 
			
		||||
                           XkbComponentNamesPtr names,
 | 
			
		||||
                           unsigned want,
 | 
			
		||||
                           unsigned need, char *nameRtrn, int nameRtrnLen)
 | 
			
		||||
/**
 | 
			
		||||
 * Callback invoked by XkbRunXkbComp. Write to out to talk to xkbcomp.
 | 
			
		||||
 */
 | 
			
		||||
typedef void (*xkbcomp_buffer_callback)(FILE *out, void *userdata);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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;
 | 
			
		||||
    char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX];
 | 
			
		||||
| 
						 | 
				
			
			@ -155,7 +164,7 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
 | 
			
		|||
    if (!buf) {
 | 
			
		||||
        LogMessage(X_ERROR,
 | 
			
		||||
                   "XKB: Could not invoke xkbcomp: not enough memory\n");
 | 
			
		||||
        return FALSE;
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
| 
						 | 
				
			
			@ -165,13 +174,9 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
    if (out != NULL) {
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
        if (xkbDebugFlags) {
 | 
			
		||||
            ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
 | 
			
		||||
            XkbWriteXKBKeymapForNames(stderr, names, xkb, want, need);
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        XkbWriteXKBKeymapForNames(out, names, xkb, want, need);
 | 
			
		||||
        /* Now write to xkbcomp */
 | 
			
		||||
        (*callback)(out, userdata);
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
        if (Pclose(out) == 0)
 | 
			
		||||
#else
 | 
			
		||||
| 
						 | 
				
			
			@ -180,14 +185,11 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
 | 
			
		|||
        {
 | 
			
		||||
            if (xkbDebugFlags)
 | 
			
		||||
                DebugF("[xkb] xkb executes: %s\n", buf);
 | 
			
		||||
            if (nameRtrn) {
 | 
			
		||||
                strlcpy(nameRtrn, keymap, nameRtrnLen);
 | 
			
		||||
            }
 | 
			
		||||
            free(buf);
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
            unlink(tmpname);
 | 
			
		||||
#endif
 | 
			
		||||
            return TRUE;
 | 
			
		||||
            return xnfstrdup(keymap);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            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);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
    if (nameRtrn)
 | 
			
		||||
        nameRtrn[0] = '\0';
 | 
			
		||||
    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 *
 | 
			
		||||
XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
 | 
			
		||||
XkbDDXOpenConfigFile(const char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
 | 
			
		||||
{
 | 
			
		||||
    char buf[PATH_MAX], xkm_output_dir[PATH_MAX];
 | 
			
		||||
    FILE *file;
 | 
			
		||||
| 
						 | 
				
			
			@ -245,37 +334,14 @@ XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
 | 
			
		|||
    return file;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned
 | 
			
		||||
XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
 | 
			
		||||
                        XkbComponentNamesPtr names,
 | 
			
		||||
                        unsigned want,
 | 
			
		||||
                        unsigned need,
 | 
			
		||||
                        XkbDescPtr *xkbRtrn, char *nameRtrn, int nameRtrnLen)
 | 
			
		||||
static unsigned
 | 
			
		||||
LoadXKM(unsigned want, unsigned need, const char *keymap, XkbDescPtr *xkbRtrn)
 | 
			
		||||
{
 | 
			
		||||
    XkbDescPtr xkb;
 | 
			
		||||
    FILE *file;
 | 
			
		||||
    char fileName[PATH_MAX];
 | 
			
		||||
    unsigned missing;
 | 
			
		||||
 | 
			
		||||
    *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;
 | 
			
		||||
    }
 | 
			
		||||
    file = XkbDDXOpenConfigFile(nameRtrn, fileName, PATH_MAX);
 | 
			
		||||
    file = XkbDDXOpenConfigFile(keymap, fileName, PATH_MAX);
 | 
			
		||||
    if (file == NULL) {
 | 
			
		||||
        LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
 | 
			
		||||
                   fileName);
 | 
			
		||||
| 
						 | 
				
			
			@ -297,6 +363,37 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
 | 
			
		|||
    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
 | 
			
		||||
XkbDDXNamesFromRules(DeviceIntPtr keybd,
 | 
			
		||||
                     const char *rules_name,
 | 
			
		||||
| 
						 | 
				
			
			@ -390,6 +487,29 @@ XkbCompileKeymapForDevice(DeviceIntPtr dev, XkbRMLVOSet * rmlvo, int need)
 | 
			
		|||
    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
 | 
			
		||||
XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -407,20 +527,34 @@ XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
 | 
			
		|||
 | 
			
		||||
    xkb = XkbCompileKeymapForDevice(dev, rmlvo, need);
 | 
			
		||||
 | 
			
		||||
    if (!xkb) {
 | 
			
		||||
        XkbRMLVOSet dflts;
 | 
			
		||||
    return KeymapOrDefaults(dev, 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");
 | 
			
		||||
XkbDescPtr
 | 
			
		||||
XkbCompileKeymapFromString(DeviceIntPtr dev,
 | 
			
		||||
                           const char *keymap, int keymap_length)
 | 
			
		||||
{
 | 
			
		||||
    XkbDescPtr xkb;
 | 
			
		||||
    unsigned int need, provided;
 | 
			
		||||
 | 
			
		||||
        XkbGetRulesDflts(&dflts);
 | 
			
		||||
 | 
			
		||||
        xkb = XkbCompileKeymapForDevice(dev, &dflts, 0);
 | 
			
		||||
 | 
			
		||||
        XkbFreeRMLVOSet(&dflts, FALSE);
 | 
			
		||||
    if (!dev || !keymap) {
 | 
			
		||||
        LogMessage(X_ERROR, "XKB: No device or keymap specified\n");
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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) {
 | 
			
		||||
        XkbDescPtr old_xkb;
 | 
			
		||||
        xkbNewKeyboardNotify nkn;
 | 
			
		||||
        int i, nG, nTG;
 | 
			
		||||
 | 
			
		||||
        old_xkb = xkb;
 | 
			
		||||
        xkb = new;
 | 
			
		||||
        dev->key->xkbInfo->desc = xkb;
 | 
			
		||||
        new = old_xkb;          /* so it'll get freed automatically */
 | 
			
		||||
 | 
			
		||||
        *xkb->ctrls = *old_xkb->ctrls;
 | 
			
		||||
        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;
 | 
			
		||||
        XkbCopyControls(xkb, old_xkb);
 | 
			
		||||
 | 
			
		||||
        nkn.deviceID = nkn.oldDeviceID = dev->id;
 | 
			
		||||
        nkn.minKeyCode = new->min_key_code;
 | 
			
		||||
| 
						 | 
				
			
			@ -5991,7 +5979,7 @@ ProcXkbGetKbdByName(ClientPtr client)
 | 
			
		|||
                continue;
 | 
			
		||||
 | 
			
		||||
            if (tmpd != dev)
 | 
			
		||||
                XkbCopyDeviceKeymap(tmpd, dev);
 | 
			
		||||
                XkbDeviceApplyKeymap(tmpd, xkb);
 | 
			
		||||
 | 
			
		||||
            if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
 | 
			
		||||
                old_sli = tmpd->kbdfeed->xkb_sli;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***====================================================================***/
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1999,28 +1999,28 @@ XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
Bool
 | 
			
		||||
XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
 | 
			
		||||
XkbDeviceApplyKeymap(DeviceIntPtr dst, XkbDescPtr desc)
 | 
			
		||||
{
 | 
			
		||||
    xkbNewKeyboardNotify nkn;
 | 
			
		||||
    Bool ret;
 | 
			
		||||
 | 
			
		||||
    if (!dst->key || !src->key)
 | 
			
		||||
    if (!dst->key || !desc)
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
 | 
			
		||||
    nkn.oldMinKeyCode = dst->key->xkbInfo->desc->min_key_code;
 | 
			
		||||
    nkn.oldMaxKeyCode = dst->key->xkbInfo->desc->max_key_code;
 | 
			
		||||
    nkn.deviceID = dst->id;
 | 
			
		||||
    nkn.oldDeviceID = dst->id;  /* maybe src->id? */
 | 
			
		||||
    nkn.minKeyCode = src->key->xkbInfo->desc->min_key_code;
 | 
			
		||||
    nkn.maxKeyCode = src->key->xkbInfo->desc->max_key_code;
 | 
			
		||||
    nkn.oldDeviceID = dst->id;
 | 
			
		||||
    nkn.minKeyCode = desc->min_key_code;
 | 
			
		||||
    nkn.maxKeyCode = desc->max_key_code;
 | 
			
		||||
    nkn.requestMajor = XkbReqCode;
 | 
			
		||||
    nkn.requestMinor = X_kbSetMap;      /* Near enough's good enough. */
 | 
			
		||||
    nkn.changed = XkbNKN_KeycodesMask;
 | 
			
		||||
    if (src->key->xkbInfo->desc->geom)
 | 
			
		||||
    if (desc->geom)
 | 
			
		||||
        nkn.changed |= XkbNKN_GeometryMask;
 | 
			
		||||
 | 
			
		||||
    ret = XkbCopyKeymap(dst->key->xkbInfo->desc, src->key->xkbInfo->desc);
 | 
			
		||||
    ret = XkbCopyKeymap(dst->key->xkbInfo->desc, desc);
 | 
			
		||||
    if (ret)
 | 
			
		||||
        XkbSendNewKeyboardNotify(dst, &nkn);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2090,3 +2090,26 @@ XkbMergeLockedPtrBtns(DeviceIntPtr master)
 | 
			
		|||
        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