Ejemplo n.º 1
0
XkbDescPtr
XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
{
    XkbDescPtr xkb;
    unsigned int need;

    if (!dev || !rmlvo) {
        LogMessage(X_ERROR, "XKB: No device or RMLVO specified\n");
        return NULL;
    }

    /* These are the components we really really need */
    need = XkmSymbolsMask | XkmCompatMapMask | XkmTypesMask |
        XkmKeyNamesMask | XkmVirtualModsMask;

    xkb = XkbCompileKeymapForDevice(dev, rmlvo, need);

    if (!xkb) {
        XkbRMLVOSet dflts;

        /* 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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
/* Set the keyboard configuration */
Bool
winConfigKeyboard(DeviceIntPtr pDevice)
{
    char layoutName[KL_NAMELENGTH];
    unsigned char layoutFriendlyName[256];
    unsigned int layoutNum = 0;
    unsigned int deviceIdentifier = 0;
    int keyboardType;

#ifdef XWIN_XF86CONFIG
    XF86ConfInputPtr kbd = NULL;
    XF86ConfInputPtr input_list = NULL;
    MessageType kbdfrom = X_CONFIG;
#endif
    MessageType from = X_DEFAULT;
    char *s = NULL;

    /* Setup defaults */
    XkbGetRulesDflts(&g_winInfo.xkb);

    /*
     * Query the windows autorepeat settings and change the xserver defaults.
     */
    {
        int kbd_delay;
        DWORD kbd_speed;

        if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &kbd_delay, 0) &&
            SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &kbd_speed, 0)) {
            switch (kbd_delay) {
            case 0:
                g_winInfo.keyboard.delay = 250;
                break;
            case 1:
                g_winInfo.keyboard.delay = 500;
                break;
            case 2:
                g_winInfo.keyboard.delay = 750;
                break;
            default:
            case 3:
                g_winInfo.keyboard.delay = 1000;
                break;
            }
            g_winInfo.keyboard.rate = (kbd_speed > 0) ? kbd_speed : 1;
            winDebug("Setting autorepeat to delay=%ld, rate=%ld\n",
                   g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);

        }
    }

    keyboardType = GetKeyboardType(0);
    if (keyboardType > 0 && GetKeyboardLayoutName(layoutName)) {
        WinKBLayoutPtr pLayout;
        Bool bfound = FALSE;
        int pass;

        layoutNum = strtoul(layoutName, (char **) NULL, 16);
        if ((layoutNum & 0xffff) == 0x411) {
            if (keyboardType == 7) {
                /* Japanese layouts have problems with key event messages
                   such as the lack of WM_KEYUP for Caps Lock key.
                   Loading US layout fixes this problem. */
                if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL)
                    winDebug("Loading US keyboard layout.\n");
                else
                    ErrorF ("LoadKeyboardLayout failed.\n");
            }
        }

        /* Discover the friendly name of the current layout */
        {
            HKEY regkey = NULL;
            const char regtempl[] =
                "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
            char *regpath;
            DWORD namesize = sizeof(layoutFriendlyName);

            regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1);
            strcpy(regpath, regtempl);
            strcat(regpath, layoutName);

            if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, &regkey))
                RegQueryValueEx(regkey, "Layout Text", 0, NULL,
                                layoutFriendlyName, &namesize);

            /* Close registry key */
            if (regkey)
                RegCloseKey(regkey);
            free(regpath);
        }

        winDebug ("Windows keyboard layout: \"%s\" (%08x) \"%s\", type %d\n",
                  layoutName, layoutNum, layoutFriendlyName, keyboardType);

        deviceIdentifier = layoutNum >> 16;
        for (pass = 0; pass < 2; pass++) {
            /* If we didn't find an exact match for the input locale identifer,
               try to find an match on the language identifier part only  */
            if (pass == 1)
                layoutNum = (layoutNum & 0xffff);

            for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++) {
                if (pLayout->winlayout != layoutNum)
                    continue;
                if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType)
                    continue;

                bfound = TRUE;
                winDebug (
                       "Found matching XKB configuration \"%s\"\n",
                       pLayout->layoutname);

                winDebug(
                       "Model = \"%s\" Layout = \"%s\""
                       " Variant = \"%s\" Options = \"%s\"\n",
                       pLayout->xkbmodel ? pLayout->xkbmodel : "none",
                       pLayout->xkblayout ? pLayout->xkblayout : "none",
                       pLayout->xkbvariant ? pLayout->xkbvariant : "none",
                       pLayout->xkboptions ? pLayout->xkboptions : "none");

                g_winInfo.xkb.model = (char *)pLayout->xkbmodel;
                g_winInfo.xkb.layout = (char *)pLayout->xkblayout;
                g_winInfo.xkb.variant = (char *)pLayout->xkbvariant;
                g_winInfo.xkb.options = (char *)pLayout->xkboptions;

                if (deviceIdentifier == 0xa000) {
                    winDebug("Windows keyboard layout device identifier indicates Macintosh, setting Model = \"macintosh\"");
                    g_winInfo.xkb.model = "macintosh";
                }

                break;
            }

            if (bfound)
                break;
        }

        if (!bfound) {
            ErrorF ("Keyboardlayout \"%s\" (%s) is unknown, using X server default layout\n",
                   layoutFriendlyName, layoutName);
        }
    }
Ejemplo n.º 4
0
_X_EXPORT Bool
InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet *rmlvo,
                         BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
{
    int	i;
    unsigned int check;
    XkbSrvInfoPtr xkbi;
    XkbDescPtr xkb;
    XkbSrvLedInfoPtr sli;
    XkbChangesRec changes;
    XkbEventCauseRec cause;
    XkbRMLVOSet rmlvo_dflts = { NULL };

    if (dev->key || dev->kbdfeed)
	return FALSE;

    if (!rmlvo)
    {
        rmlvo = &rmlvo_dflts;
        XkbGetRulesDflts(rmlvo);
    }


    memset(&changes, 0, sizeof(changes));
    XkbSetCauseUnknown(&cause);

    dev->key = calloc(1, sizeof(*dev->key));
    if (!dev->key) {
        ErrorF("XKB: Failed to allocate key class\n");
        return FALSE;
    }
    dev->key->sourceid = dev->id;

    dev->kbdfeed = calloc(1, sizeof(*dev->kbdfeed));
    if (!dev->kbdfeed) {
        ErrorF("XKB: Failed to allocate key feedback class\n");
        goto unwind_key;
    }

    xkbi = calloc(1, sizeof(*xkbi));
    if (!xkbi) {
        ErrorF("XKB: Failed to allocate XKB info\n");
        goto unwind_kbdfeed;
    }
    dev->key->xkbInfo = xkbi;

    if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) {
        XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
        xkb_cached_map = NULL;
    }

    if (xkb_cached_map)
        LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
    else {
        xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
        if (!xkb_cached_map) {
            ErrorF("XKB: Failed to compile keymap\n");
            goto unwind_info;
        }
    }

    xkb = XkbAllocKeyboard();
    if (!xkb) {
        ErrorF("XKB: Failed to allocate keyboard description\n");
        goto unwind_info;
    }

    if (!XkbCopyKeymap(xkb, xkb_cached_map)) {
        ErrorF("XKB: Failed to copy keymap\n");
        goto unwind_desc;
    }
    xkb->defined = xkb_cached_map->defined;
    xkb->flags = xkb_cached_map->flags;
    xkb->device_spec = xkb_cached_map->device_spec;
    xkbi->desc = xkb;

    if (xkb->min_key_code == 0)
        xkb->min_key_code = 8;
    if (xkb->max_key_code == 0)
        xkb->max_key_code = 255;

    i = XkbNumKeys(xkb) / 3 + 1;
    if (XkbAllocClientMap(xkb, XkbAllClientInfoMask, 0) != Success)
        goto unwind_desc;
    if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, i) != Success)
        goto unwind_desc;

    xkbi->dfltPtrDelta = 1;
    xkbi->device = dev;

    XkbInitSemantics(xkb);
    XkbInitNames(xkbi);
    XkbInitRadioGroups(xkbi);

    XkbInitControls(dev, xkbi);

    XkbInitIndicatorMap(xkbi);

    XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes,
                     &check, &cause);

    InitFocusClassDeviceStruct(dev);

    xkbi->kbdProc = ctrl_func;
    dev->kbdfeed->BellProc = bell_func;
    dev->kbdfeed->CtrlProc = XkbDDXKeybdCtrlProc;

    dev->kbdfeed->ctrl = defaultKeyboardControl;
    if (dev->kbdfeed->ctrl.autoRepeat)
        xkb->ctrls->enabled_ctrls |= XkbRepeatKeysMask;

    memcpy(dev->kbdfeed->ctrl.autoRepeats, xkb->ctrls->per_key_repeat,
           XkbPerKeyBitArraySize);

    sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
    if (sli)
	XkbCheckIndicatorMaps(dev, sli, XkbAllIndicatorsMask);
    else
        DebugF("XKB: No indicator feedback in XkbFinishInit!\n");

    dev->kbdfeed->CtrlProc(dev,&dev->kbdfeed->ctrl);

    XkbSetRulesDflts(rmlvo);
    XkbSetRulesUsed(rmlvo);
    XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);

    return TRUE;

unwind_desc:
    XkbFreeKeyboard(xkb, 0, TRUE);
unwind_info:
    free(xkbi);
    dev->key->xkbInfo = NULL;
unwind_kbdfeed:
    free(dev->kbdfeed);
    dev->kbdfeed = NULL;
unwind_key:
    free(dev->key);
    dev->key = NULL;
    return FALSE;
}
Ejemplo n.º 5
0
Bool
XkbInitKeyboardDeviceStruct(
    DeviceIntPtr		dev,
    XkbComponentNamesPtr	names,
    KeySymsPtr                  pSymsIn,
    CARD8                       pModsIn[],
    void                        (*bellProc)(
        int /*percent*/,
        DeviceIntPtr /*device*/,
        pointer /*ctrl*/,
        int),
    void                        (*ctrlProc)(
        DeviceIntPtr /*device*/,
        KeybdCtrl * /*ctrl*/))
{
XkbFileInfo		finfo;
KeySymsRec		tmpSyms,*pSyms;
CARD8			tmpMods[XkbMaxLegalKeyCode+1],*pMods;
char			name[PATH_MAX],*rules;
Bool			ok=False;
XPointer		config;
XkbComponentNamesRec	cfgNames;
XkbRF_VarDefsRec	defs;

    if ((dev->key!=NULL)||(dev->kbdfeed!=NULL))
	return False;
    pSyms= pSymsIn;
    pMods= pModsIn;
    bzero(&defs,sizeof(XkbRF_VarDefsRec));
    bzero(&cfgNames,sizeof(XkbComponentNamesRec));
    rules= XkbGetRulesDflts(&defs);
    config= XkbDDXPreloadConfig(&rules,&defs,&cfgNames,dev);

    /*
     * The strings are duplicated because it is not guaranteed that
     * they are allocated, or that they are allocated for every server
     * generation. Eventually they will be freed at the end of this
     * function.
     */
    if (names->keymap) names->keymap = _XkbDupString(names->keymap);
    if (names->keycodes) names->keycodes = _XkbDupString(names->keycodes);
    if (names->types) names->types = _XkbDupString(names->types);
    if (names->compat) names->compat = _XkbDupString(names->compat);
    if (names->geometry) names->geometry = _XkbDupString(names->geometry);
    if (names->symbols) names->symbols = _XkbDupString(names->symbols);

    if (defs.model && defs.layout && rules) {
	XkbComponentNamesRec	rNames;
	bzero(&rNames,sizeof(XkbComponentNamesRec));
	if (XkbDDXNamesFromRules(dev,rules,&defs,&rNames)) {
	    if (rNames.keymap) {
		if (!names->keymap)
		    names->keymap = rNames.keymap;
		else _XkbFree(rNames.keymap);
	    }
	    if (rNames.keycodes) {
		if (!names->keycodes)
		    names->keycodes =  rNames.keycodes;
		else
		    _XkbFree(rNames.keycodes);
	    }
	    if (rNames.types) {
		if (!names->types)
		    names->types = rNames.types;
		else  _XkbFree(rNames.types);
	    }
	    if (rNames.compat) {
		if (!names->compat) 
		    names->compat =  rNames.compat;
		else  _XkbFree(rNames.compat);
	    }
	    if (rNames.symbols) {
		if (!names->symbols)
		    names->symbols =  rNames.symbols;
		else _XkbFree(rNames.symbols);
	    }
	    if (rNames.geometry) {
		if (!names->geometry)
		    names->geometry = rNames.geometry;
		else _XkbFree(rNames.geometry);
	    }
	    XkbSetRulesUsed(&defs);
	}
    }
    if (cfgNames.keymap){
	if (names->keymap) _XkbFree(names->keymap);
	names->keymap= cfgNames.keymap;
    }
    if (cfgNames.keycodes){
	if (names->keycodes) _XkbFree(names->keycodes);	
	names->keycodes= cfgNames.keycodes;
    }
    if (cfgNames.types) {
	if (names->types) _XkbFree(names->types);	
	names->types= cfgNames.types;
    }
    if (cfgNames.compat) {
	if (names->compat) _XkbFree(names->compat);	
	names->compat= cfgNames.compat;
    }
    if (cfgNames.symbols){
	if (names->symbols) _XkbFree(names->symbols);	
	names->symbols= cfgNames.symbols;
    }
    if (cfgNames.geometry) {
	if (names->geometry) _XkbFree(names->geometry);
	names->geometry= cfgNames.geometry;
    }

    if (names->keymap) {
        XkbComponentNamesRec	tmpNames;
	bzero(&tmpNames,sizeof(XkbComponentNamesRec));
	tmpNames.keymap = names->keymap;
        ok = (Bool) XkbDDXLoadKeymapByNames(dev,&tmpNames,XkmAllIndicesMask,0,
					    &finfo,name,PATH_MAX);
    }
    if (!(ok && (finfo.xkb!=NULL)))
        ok = (Bool) XkbDDXLoadKeymapByNames(dev,names,XkmAllIndicesMask,0,
					    &finfo,name,PATH_MAX);

    if (ok && (finfo.xkb!=NULL)) {
	XkbDescPtr	xkb;
	KeyCode		minKC,maxKC;

	xkb= finfo.xkb;
	minKC= xkb->min_key_code;
	maxKC= xkb->max_key_code;
	if (XkbIsLegalKeycode(minKC)&&XkbIsLegalKeycode(maxKC)&&(minKC<=maxKC)&&
	    ((minKC!=pSyms->minKeyCode)||(maxKC!=pSyms->maxKeyCode))) {
	    if (xkb->map!=NULL) {
		KeySym	*inSym,*outSym;
		int	width= pSymsIn->mapWidth;

		tmpSyms.minKeyCode= minKC;
		tmpSyms.maxKeyCode= maxKC;

		if (minKC<pSymsIn->minKeyCode)
		    minKC= pSymsIn->minKeyCode;
		if (maxKC>pSymsIn->maxKeyCode)
		    maxKC= pSymsIn->maxKeyCode;

		tmpSyms.mapWidth= width;
		tmpSyms.map= _XkbTypedCalloc(width*XkbNumKeys(xkb),KeySym);
		inSym= &pSymsIn->map[(minKC-pSymsIn->minKeyCode)*width];
		outSym= &tmpSyms.map[(minKC-tmpSyms.minKeyCode)*width];
		memcpy(outSym,inSym,((maxKC-minKC+1)*width)*sizeof(KeySym));
		pSyms= &tmpSyms;
	    }
	    if ((xkb->map!=NULL)&&(xkb->map->modmap!=NULL)) {
		bzero(tmpMods,XkbMaxKeyCount);
		memcpy(tmpMods,xkb->map->modmap,maxKC+1);
		pMods= tmpMods;
	    }
	}
	_XkbInitFileInfo= &finfo;
    }
    else {
	LogMessage(X_WARNING, "Couldn't load XKB keymap, falling back to pre-XKB keymap\n");
    }
    ok= InitKeyboardDeviceStruct((DevicePtr)dev,pSyms,pMods,bellProc,ctrlProc);
    if ((config!=NULL)&&(dev && dev->key && dev->key->xkbInfo))
	XkbDDXApplyConfig(config,dev->key->xkbInfo);
    _XkbInitFileInfo= NULL;
    if ((pSyms==&tmpSyms)&&(pSyms->map!=NULL)) {
	_XkbFree(pSyms->map);
	pSyms->map= NULL;
    }

    if (names->keymap) _XkbFree(names->keymap);
    names->keymap = NULL;
    if (names->keycodes) _XkbFree(names->keycodes);
    names->keycodes = NULL;
    if (names->types) _XkbFree(names->types);
    names->types = NULL;
    if (names->compat) _XkbFree(names->compat);
    names->compat = NULL;
    if (names->geometry) _XkbFree(names->geometry);
    names->geometry = NULL;
    if (names->symbols) _XkbFree(names->symbols);
    names->symbols = NULL;

    return ok;
}