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