xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

xkbInit.c (24294B)


      1 /************************************************************
      2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
      3 
      4 Permission to use, copy, modify, and distribute this
      5 software and its documentation for any purpose and without
      6 fee is hereby granted, provided that the above copyright
      7 notice appear in all copies and that both that copyright
      8 notice and this permission notice appear in supporting
      9 documentation, and that the name of Silicon Graphics not be
     10 used in advertising or publicity pertaining to distribution
     11 of the software without specific prior written permission.
     12 Silicon Graphics makes no representation about the suitability
     13 of this software for any purpose. It is provided "as is"
     14 without any express or implied warranty.
     15 
     16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
     17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
     18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
     19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
     20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
     22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
     23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
     24 
     25 ********************************************************/
     26 
     27 #ifdef HAVE_DIX_CONFIG_H
     28 #include <dix-config.h>
     29 #endif
     30 
     31 #include <xkb-config.h>
     32 
     33 #include <stdio.h>
     34 #include <stdlib.h>
     35 #include <ctype.h>
     36 #include <unistd.h>
     37 #include <math.h>
     38 #include <X11/X.h>
     39 #include <X11/Xproto.h>
     40 #include <X11/keysym.h>
     41 #include <X11/Xatom.h>
     42 #include "misc.h"
     43 #include "inputstr.h"
     44 #include "opaque.h"
     45 #include "property.h"
     46 #include "scrnintstr.h"
     47 #define	XKBSRV_NEED_FILE_FUNCS
     48 #include <xkbsrv.h>
     49 #include "xkbgeom.h"
     50 #include <X11/extensions/XKMformat.h>
     51 #include "xkbfile.h"
     52 #include "xkb.h"
     53 
     54 #define	CREATE_ATOM(s)	MakeAtom(s,sizeof(s)-1,1)
     55 
     56 #if defined(__alpha) || defined(__alpha__)
     57 #define	LED_COMPOSE	2
     58 #define LED_CAPS	3
     59 #define	LED_SCROLL	4
     60 #define	LED_NUM		5
     61 #define	PHYS_LEDS	0x1f
     62 #else
     63 #ifdef __sun
     64 #define LED_NUM		1
     65 #define	LED_SCROLL	2
     66 #define	LED_COMPOSE	3
     67 #define LED_CAPS	4
     68 #define	PHYS_LEDS	0x0f
     69 #else
     70 #define	LED_CAPS	1
     71 #define	LED_NUM		2
     72 #define	LED_SCROLL	3
     73 #define	PHYS_LEDS	0x07
     74 #endif
     75 #endif
     76 
     77 #define	MAX_TOC	16
     78 typedef struct _SrvXkmInfo {
     79     DeviceIntPtr dev;
     80     FILE *file;
     81     XkbDescPtr xkb;
     82 } SrvXkmInfo;
     83 
     84 /***====================================================================***/
     85 
     86 #ifndef XKB_DFLT_RULES_PROP
     87 #define	XKB_DFLT_RULES_PROP	TRUE
     88 #endif
     89 
     90 const char *XkbBaseDirectory = XKB_BASE_DIRECTORY;
     91 const char *XkbBinDirectory = XKB_BIN_DIRECTORY;
     92 static int XkbWantAccessX = 0;
     93 
     94 static char *XkbRulesDflt = NULL;
     95 static char *XkbModelDflt = NULL;
     96 static char *XkbLayoutDflt = NULL;
     97 static char *XkbVariantDflt = NULL;
     98 static char *XkbOptionsDflt = NULL;
     99 
    100 static char *XkbRulesUsed = NULL;
    101 static char *XkbModelUsed = NULL;
    102 static char *XkbLayoutUsed = NULL;
    103 static char *XkbVariantUsed = NULL;
    104 static char *XkbOptionsUsed = NULL;
    105 
    106 static XkbDescPtr xkb_cached_map = NULL;
    107 
    108 static Bool XkbWantRulesProp = XKB_DFLT_RULES_PROP;
    109 
    110 /***====================================================================***/
    111 
    112 /**
    113  * Get the current default XKB rules.
    114  * Caller must free the data in rmlvo.
    115  */
    116 void
    117 XkbGetRulesDflts(XkbRMLVOSet * rmlvo)
    118 {
    119     rmlvo->rules = strdup(XkbRulesDflt ? XkbRulesDflt : XKB_DFLT_RULES);
    120     rmlvo->model = strdup(XkbModelDflt ? XkbModelDflt : XKB_DFLT_MODEL);
    121     rmlvo->layout = strdup(XkbLayoutDflt ? XkbLayoutDflt : XKB_DFLT_LAYOUT);
    122     rmlvo->variant = strdup(XkbVariantDflt ? XkbVariantDflt : XKB_DFLT_VARIANT);
    123     rmlvo->options = strdup(XkbOptionsDflt ? XkbOptionsDflt : XKB_DFLT_OPTIONS);
    124 }
    125 
    126 void
    127 XkbFreeRMLVOSet(XkbRMLVOSet * rmlvo, Bool freeRMLVO)
    128 {
    129     if (!rmlvo)
    130         return;
    131 
    132     free(rmlvo->rules);
    133     free(rmlvo->model);
    134     free(rmlvo->layout);
    135     free(rmlvo->variant);
    136     free(rmlvo->options);
    137 
    138     if (freeRMLVO)
    139         free(rmlvo);
    140     else
    141         memset(rmlvo, 0, sizeof(XkbRMLVOSet));
    142 }
    143 
    144 static Bool
    145 XkbWriteRulesProp(void)
    146 {
    147     int len, out;
    148     Atom name;
    149     char *pval;
    150 
    151     len = (XkbRulesUsed ? strlen(XkbRulesUsed) : 0);
    152     len += (XkbModelUsed ? strlen(XkbModelUsed) : 0);
    153     len += (XkbLayoutUsed ? strlen(XkbLayoutUsed) : 0);
    154     len += (XkbVariantUsed ? strlen(XkbVariantUsed) : 0);
    155     len += (XkbOptionsUsed ? strlen(XkbOptionsUsed) : 0);
    156     if (len < 1)
    157         return TRUE;
    158 
    159     len += 5;                   /* trailing NULs */
    160 
    161     name =
    162         MakeAtom(_XKB_RF_NAMES_PROP_ATOM, strlen(_XKB_RF_NAMES_PROP_ATOM), 1);
    163     if (name == None) {
    164         ErrorF("[xkb] Atom error: %s not created\n", _XKB_RF_NAMES_PROP_ATOM);
    165         return TRUE;
    166     }
    167     pval = (char *) malloc(len);
    168     if (!pval) {
    169         ErrorF("[xkb] Allocation error: %s proprerty not created\n",
    170                _XKB_RF_NAMES_PROP_ATOM);
    171         return TRUE;
    172     }
    173     out = 0;
    174     if (XkbRulesUsed) {
    175         strcpy(&pval[out], XkbRulesUsed);
    176         out += strlen(XkbRulesUsed);
    177     }
    178     pval[out++] = '\0';
    179     if (XkbModelUsed) {
    180         strcpy(&pval[out], XkbModelUsed);
    181         out += strlen(XkbModelUsed);
    182     }
    183     pval[out++] = '\0';
    184     if (XkbLayoutUsed) {
    185         strcpy(&pval[out], XkbLayoutUsed);
    186         out += strlen(XkbLayoutUsed);
    187     }
    188     pval[out++] = '\0';
    189     if (XkbVariantUsed) {
    190         strcpy(&pval[out], XkbVariantUsed);
    191         out += strlen(XkbVariantUsed);
    192     }
    193     pval[out++] = '\0';
    194     if (XkbOptionsUsed) {
    195         strcpy(&pval[out], XkbOptionsUsed);
    196         out += strlen(XkbOptionsUsed);
    197     }
    198     pval[out++] = '\0';
    199     if (out != len) {
    200         ErrorF("[xkb] Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n",
    201                out, len);
    202     }
    203     dixChangeWindowProperty(serverClient, screenInfo.screens[0]->root, name,
    204                             XA_STRING, 8, PropModeReplace, len, pval, TRUE);
    205     free(pval);
    206     return TRUE;
    207 }
    208 
    209 void
    210 XkbInitRules(XkbRMLVOSet *rmlvo,
    211              const char *rules,
    212              const char *model,
    213              const char *layout,
    214              const char *variant,
    215              const char *options)
    216 {
    217     rmlvo->rules = rules ? xnfstrdup(rules) : NULL;
    218     rmlvo->model = model ? xnfstrdup(model) : NULL;
    219     rmlvo->layout = layout ? xnfstrdup(layout) : NULL;
    220     rmlvo->variant = variant ? xnfstrdup(variant) : NULL;
    221     rmlvo->options = options ? xnfstrdup(options) : NULL;
    222 }
    223 
    224 static void
    225 XkbSetRulesUsed(XkbRMLVOSet * rmlvo)
    226 {
    227     free(XkbRulesUsed);
    228     XkbRulesUsed = (rmlvo->rules ? Xstrdup(rmlvo->rules) : NULL);
    229     free(XkbModelUsed);
    230     XkbModelUsed = (rmlvo->model ? Xstrdup(rmlvo->model) : NULL);
    231     free(XkbLayoutUsed);
    232     XkbLayoutUsed = (rmlvo->layout ? Xstrdup(rmlvo->layout) : NULL);
    233     free(XkbVariantUsed);
    234     XkbVariantUsed = (rmlvo->variant ? Xstrdup(rmlvo->variant) : NULL);
    235     free(XkbOptionsUsed);
    236     XkbOptionsUsed = (rmlvo->options ? Xstrdup(rmlvo->options) : NULL);
    237     if (XkbWantRulesProp)
    238         XkbWriteRulesProp();
    239     return;
    240 }
    241 
    242 void
    243 XkbSetRulesDflts(XkbRMLVOSet * rmlvo)
    244 {
    245     if (rmlvo->rules) {
    246         free(XkbRulesDflt);
    247         XkbRulesDflt = Xstrdup(rmlvo->rules);
    248     }
    249     if (rmlvo->model) {
    250         free(XkbModelDflt);
    251         XkbModelDflt = Xstrdup(rmlvo->model);
    252     }
    253     if (rmlvo->layout) {
    254         free(XkbLayoutDflt);
    255         XkbLayoutDflt = Xstrdup(rmlvo->layout);
    256     }
    257     if (rmlvo->variant) {
    258         free(XkbVariantDflt);
    259         XkbVariantDflt = Xstrdup(rmlvo->variant);
    260     }
    261     if (rmlvo->options) {
    262         free(XkbOptionsDflt);
    263         XkbOptionsDflt = Xstrdup(rmlvo->options);
    264     }
    265     return;
    266 }
    267 
    268 void
    269 XkbDeleteRulesUsed(void)
    270 {
    271     free(XkbRulesUsed);
    272     XkbRulesUsed = NULL;
    273     free(XkbModelUsed);
    274     XkbModelUsed = NULL;
    275     free(XkbLayoutUsed);
    276     XkbLayoutUsed = NULL;
    277     free(XkbVariantUsed);
    278     XkbVariantUsed = NULL;
    279     free(XkbOptionsUsed);
    280     XkbOptionsUsed = NULL;
    281 }
    282 
    283 void
    284 XkbDeleteRulesDflts(void)
    285 {
    286     free(XkbRulesDflt);
    287     XkbRulesDflt = NULL;
    288     free(XkbModelDflt);
    289     XkbModelDflt = NULL;
    290     free(XkbLayoutDflt);
    291     XkbLayoutDflt = NULL;
    292     free(XkbVariantDflt);
    293     XkbVariantDflt = NULL;
    294     free(XkbOptionsDflt);
    295     XkbOptionsDflt = NULL;
    296 
    297     XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
    298     xkb_cached_map = NULL;
    299 }
    300 
    301 #define DIFFERS(a, b) (strcmp((a) ? (a) : "", (b) ? (b) : "") != 0)
    302 
    303 static Bool
    304 XkbCompareUsedRMLVO(XkbRMLVOSet * rmlvo)
    305 {
    306     if (DIFFERS(rmlvo->rules, XkbRulesUsed) ||
    307         DIFFERS(rmlvo->model, XkbModelUsed) ||
    308         DIFFERS(rmlvo->layout, XkbLayoutUsed) ||
    309         DIFFERS(rmlvo->variant, XkbVariantUsed) ||
    310         DIFFERS(rmlvo->options, XkbOptionsUsed))
    311         return FALSE;
    312     return TRUE;
    313 }
    314 
    315 #undef DIFFERS
    316 
    317 /***====================================================================***/
    318 
    319 #include "xkbDflts.h"
    320 
    321 static Bool
    322 XkbInitKeyTypes(XkbDescPtr xkb)
    323 {
    324     if (xkb->defined & XkmTypesMask)
    325         return TRUE;
    326 
    327     initTypeNames(NULL);
    328     if (XkbAllocClientMap(xkb, XkbKeyTypesMask, num_dflt_types) != Success)
    329         return FALSE;
    330     if (XkbCopyKeyTypes(dflt_types, xkb->map->types, num_dflt_types) != Success) {
    331         return FALSE;
    332     }
    333     xkb->map->size_types = xkb->map->num_types = num_dflt_types;
    334     return TRUE;
    335 }
    336 
    337 static void
    338 XkbInitRadioGroups(XkbSrvInfoPtr xkbi)
    339 {
    340     xkbi->nRadioGroups = 0;
    341     xkbi->radioGroups = NULL;
    342     return;
    343 }
    344 
    345 static Status
    346 XkbInitCompatStructs(XkbDescPtr xkb)
    347 {
    348     register int i;
    349     XkbCompatMapPtr compat;
    350 
    351     if (xkb->defined & XkmCompatMapMask)
    352         return TRUE;
    353 
    354     if (XkbAllocCompatMap(xkb, XkbAllCompatMask, num_dfltSI) != Success)
    355         return BadAlloc;
    356     compat = xkb->compat;
    357     if (compat->sym_interpret) {
    358         compat->num_si = num_dfltSI;
    359         memcpy((char *) compat->sym_interpret, (char *) dfltSI, sizeof(dfltSI));
    360     }
    361     for (i = 0; i < XkbNumKbdGroups; i++) {
    362         compat->groups[i] = compatMap.groups[i];
    363         if (compat->groups[i].vmods != 0) {
    364             unsigned mask;
    365 
    366             mask = XkbMaskForVMask(xkb, compat->groups[i].vmods);
    367             compat->groups[i].mask = compat->groups[i].real_mods | mask;
    368         }
    369         else
    370             compat->groups[i].mask = compat->groups[i].real_mods;
    371     }
    372     return Success;
    373 }
    374 
    375 static void
    376 XkbInitSemantics(XkbDescPtr xkb)
    377 {
    378     XkbInitKeyTypes(xkb);
    379     XkbInitCompatStructs(xkb);
    380     return;
    381 }
    382 
    383 /***====================================================================***/
    384 
    385 static Status
    386 XkbInitNames(XkbSrvInfoPtr xkbi)
    387 {
    388     XkbDescPtr xkb;
    389     XkbNamesPtr names;
    390     Status rtrn;
    391     Atom unknown;
    392 
    393     xkb = xkbi->desc;
    394     if ((rtrn = XkbAllocNames(xkb, XkbAllNamesMask, 0, 0)) != Success)
    395         return rtrn;
    396     unknown = CREATE_ATOM("unknown");
    397     names = xkb->names;
    398     if (names->keycodes == None)
    399         names->keycodes = unknown;
    400     if (names->geometry == None)
    401         names->geometry = unknown;
    402     if (names->phys_symbols == None)
    403         names->phys_symbols = unknown;
    404     if (names->symbols == None)
    405         names->symbols = unknown;
    406     if (names->types == None)
    407         names->types = unknown;
    408     if (names->compat == None)
    409         names->compat = unknown;
    410     if (!(xkb->defined & XkmVirtualModsMask)) {
    411         if (names->vmods[vmod_NumLock] == None)
    412             names->vmods[vmod_NumLock] = CREATE_ATOM("NumLock");
    413         if (names->vmods[vmod_Alt] == None)
    414             names->vmods[vmod_Alt] = CREATE_ATOM("Alt");
    415         if (names->vmods[vmod_AltGr] == None)
    416             names->vmods[vmod_AltGr] = CREATE_ATOM("ModeSwitch");
    417     }
    418 
    419     if (!(xkb->defined & XkmIndicatorsMask) ||
    420         !(xkb->defined & XkmGeometryMask)) {
    421         initIndicatorNames(NULL, xkb);
    422         if (names->indicators[LED_CAPS - 1] == None)
    423             names->indicators[LED_CAPS - 1] = CREATE_ATOM("Caps Lock");
    424         if (names->indicators[LED_NUM - 1] == None)
    425             names->indicators[LED_NUM - 1] = CREATE_ATOM("Num Lock");
    426         if (names->indicators[LED_SCROLL - 1] == None)
    427             names->indicators[LED_SCROLL - 1] = CREATE_ATOM("Scroll Lock");
    428 #ifdef LED_COMPOSE
    429         if (names->indicators[LED_COMPOSE - 1] == None)
    430             names->indicators[LED_COMPOSE - 1] = CREATE_ATOM("Compose");
    431 #endif
    432     }
    433 
    434     if (xkb->geom != NULL)
    435         names->geometry = xkb->geom->name;
    436     else
    437         names->geometry = unknown;
    438 
    439     return Success;
    440 }
    441 
    442 static Status
    443 XkbInitIndicatorMap(XkbSrvInfoPtr xkbi)
    444 {
    445     XkbDescPtr xkb;
    446     XkbIndicatorPtr map;
    447     XkbSrvLedInfoPtr sli;
    448 
    449     xkb = xkbi->desc;
    450     if (XkbAllocIndicatorMaps(xkb) != Success)
    451         return BadAlloc;
    452 
    453     if (!(xkb->defined & XkmIndicatorsMask)) {
    454         map = xkb->indicators;
    455         map->phys_indicators = PHYS_LEDS;
    456         map->maps[LED_CAPS - 1].flags = XkbIM_NoExplicit;
    457         map->maps[LED_CAPS - 1].which_mods = XkbIM_UseLocked;
    458         map->maps[LED_CAPS - 1].mods.mask = LockMask;
    459         map->maps[LED_CAPS - 1].mods.real_mods = LockMask;
    460 
    461         map->maps[LED_NUM - 1].flags = XkbIM_NoExplicit;
    462         map->maps[LED_NUM - 1].which_mods = XkbIM_UseLocked;
    463         map->maps[LED_NUM - 1].mods.mask = 0;
    464         map->maps[LED_NUM - 1].mods.real_mods = 0;
    465         map->maps[LED_NUM - 1].mods.vmods = vmod_NumLockMask;
    466 
    467         map->maps[LED_SCROLL - 1].flags = XkbIM_NoExplicit;
    468         map->maps[LED_SCROLL - 1].which_mods = XkbIM_UseLocked;
    469         map->maps[LED_SCROLL - 1].mods.mask = Mod3Mask;
    470         map->maps[LED_SCROLL - 1].mods.real_mods = Mod3Mask;
    471     }
    472 
    473     sli = XkbFindSrvLedInfo(xkbi->device, XkbDfltXIClass, XkbDfltXIId, 0);
    474     if (sli)
    475         XkbCheckIndicatorMaps(xkbi->device, sli, XkbAllIndicatorsMask);
    476 
    477     return Success;
    478 }
    479 
    480 static Status
    481 XkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
    482 {
    483     XkbDescPtr xkb;
    484     XkbControlsPtr ctrls;
    485 
    486     xkb = xkbi->desc;
    487     /* 12/31/94 (ef) -- XXX! Should check if controls loaded from file */
    488     if (XkbAllocControls(xkb, XkbAllControlsMask) != Success)
    489         FatalError("Couldn't allocate keyboard controls\n");
    490     ctrls = xkb->ctrls;
    491     if (!(xkb->defined & XkmSymbolsMask))
    492         ctrls->num_groups = 1;
    493     ctrls->groups_wrap = XkbSetGroupInfo(1, XkbWrapIntoRange, 0);
    494     ctrls->internal.mask = 0;
    495     ctrls->internal.real_mods = 0;
    496     ctrls->internal.vmods = 0;
    497     ctrls->ignore_lock.mask = 0;
    498     ctrls->ignore_lock.real_mods = 0;
    499     ctrls->ignore_lock.vmods = 0;
    500     ctrls->enabled_ctrls = XkbAccessXTimeoutMask | XkbRepeatKeysMask |
    501         XkbMouseKeysAccelMask | XkbAudibleBellMask | XkbIgnoreGroupLockMask;
    502     if (XkbWantAccessX)
    503         ctrls->enabled_ctrls |= XkbAccessXKeysMask;
    504     AccessXInit(pXDev);
    505     return Success;
    506 }
    507 
    508 static Status
    509 XkbInitOverlayState(XkbSrvInfoPtr xkbi)
    510 {
    511     memset(xkbi->overlay_perkey_state, 0, sizeof(xkbi->overlay_perkey_state));
    512     return Success;
    513 }
    514 
    515 static Bool
    516 InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
    517                                  const char *keymap, int keymap_length,
    518                                  BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
    519 {
    520     int i;
    521     unsigned int check;
    522     XkbSrvInfoPtr xkbi;
    523     XkbDescPtr xkb;
    524     XkbSrvLedInfoPtr sli;
    525     XkbChangesRec changes;
    526     XkbEventCauseRec cause;
    527     XkbRMLVOSet rmlvo_dflts = { NULL };
    528 
    529     BUG_RETURN_VAL(dev == NULL, FALSE);
    530     BUG_RETURN_VAL(dev->key != NULL, FALSE);
    531     BUG_RETURN_VAL(dev->kbdfeed != NULL, FALSE);
    532     BUG_RETURN_VAL(rmlvo && keymap, FALSE);
    533 
    534     if (!rmlvo && !keymap) {
    535         rmlvo = &rmlvo_dflts;
    536         XkbGetRulesDflts(rmlvo);
    537     }
    538 
    539     memset(&changes, 0, sizeof(changes));
    540     XkbSetCauseUnknown(&cause);
    541 
    542     dev->key = calloc(1, sizeof(*dev->key));
    543     if (!dev->key) {
    544         ErrorF("XKB: Failed to allocate key class\n");
    545         return FALSE;
    546     }
    547     dev->key->sourceid = dev->id;
    548 
    549     dev->kbdfeed = calloc(1, sizeof(*dev->kbdfeed));
    550     if (!dev->kbdfeed) {
    551         ErrorF("XKB: Failed to allocate key feedback class\n");
    552         goto unwind_key;
    553     }
    554 
    555     xkbi = calloc(1, sizeof(*xkbi));
    556     if (!xkbi) {
    557         ErrorF("XKB: Failed to allocate XKB info\n");
    558         goto unwind_kbdfeed;
    559     }
    560     dev->key->xkbInfo = xkbi;
    561 
    562     if (xkb_cached_map && (keymap || (rmlvo && !XkbCompareUsedRMLVO(rmlvo)))) {
    563         XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
    564         xkb_cached_map = NULL;
    565     }
    566 
    567     if (xkb_cached_map)
    568         LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
    569     else {
    570         if (rmlvo)
    571             xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
    572         else
    573             xkb_cached_map = XkbCompileKeymapFromString(dev, keymap, keymap_length);
    574 
    575         if (!xkb_cached_map) {
    576             ErrorF("XKB: Failed to compile keymap\n");
    577             goto unwind_info;
    578         }
    579     }
    580 
    581     xkb = XkbAllocKeyboard();
    582     if (!xkb) {
    583         ErrorF("XKB: Failed to allocate keyboard description\n");
    584         goto unwind_info;
    585     }
    586 
    587     if (!XkbCopyKeymap(xkb, xkb_cached_map)) {
    588         ErrorF("XKB: Failed to copy keymap\n");
    589         goto unwind_desc;
    590     }
    591     xkb->defined = xkb_cached_map->defined;
    592     xkb->flags = xkb_cached_map->flags;
    593     xkb->device_spec = xkb_cached_map->device_spec;
    594     xkbi->desc = xkb;
    595 
    596     if (xkb->min_key_code == 0)
    597         xkb->min_key_code = 8;
    598     if (xkb->max_key_code == 0)
    599         xkb->max_key_code = 255;
    600 
    601     i = XkbNumKeys(xkb) / 3 + 1;
    602     if (XkbAllocClientMap(xkb, XkbAllClientInfoMask, 0) != Success)
    603         goto unwind_desc;
    604     if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, i) != Success)
    605         goto unwind_desc;
    606 
    607     xkbi->dfltPtrDelta = 1;
    608     xkbi->device = dev;
    609 
    610     XkbInitSemantics(xkb);
    611     XkbInitNames(xkbi);
    612     XkbInitRadioGroups(xkbi);
    613 
    614     XkbInitControls(dev, xkbi);
    615 
    616     XkbInitIndicatorMap(xkbi);
    617 
    618     XkbInitOverlayState(xkbi);
    619 
    620     XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes,
    621                      &check, &cause);
    622 
    623     if (!dev->focus)
    624         InitFocusClassDeviceStruct(dev);
    625 
    626     xkbi->kbdProc = ctrl_func;
    627     dev->kbdfeed->BellProc = bell_func;
    628     dev->kbdfeed->CtrlProc = XkbDDXKeybdCtrlProc;
    629 
    630     dev->kbdfeed->ctrl = defaultKeyboardControl;
    631     if (dev->kbdfeed->ctrl.autoRepeat)
    632         xkb->ctrls->enabled_ctrls |= XkbRepeatKeysMask;
    633 
    634     memcpy(dev->kbdfeed->ctrl.autoRepeats, xkb->ctrls->per_key_repeat,
    635            XkbPerKeyBitArraySize);
    636 
    637     sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
    638     if (sli)
    639         XkbCheckIndicatorMaps(dev, sli, XkbAllIndicatorsMask);
    640     else
    641         DebugF("XKB: No indicator feedback in XkbFinishInit!\n");
    642 
    643     dev->kbdfeed->CtrlProc(dev, &dev->kbdfeed->ctrl);
    644 
    645     if (rmlvo) {
    646         XkbSetRulesDflts(rmlvo);
    647         XkbSetRulesUsed(rmlvo);
    648     }
    649     XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
    650 
    651     return TRUE;
    652 
    653  unwind_desc:
    654     XkbFreeKeyboard(xkb, 0, TRUE);
    655  unwind_info:
    656     free(xkbi);
    657     dev->key->xkbInfo = NULL;
    658  unwind_kbdfeed:
    659     free(dev->kbdfeed);
    660     dev->kbdfeed = NULL;
    661  unwind_key:
    662     free(dev->key);
    663     dev->key = NULL;
    664     return FALSE;
    665 }
    666 
    667 _X_EXPORT Bool
    668 InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
    669                          BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
    670 {
    671     return InitKeyboardDeviceStructInternal(dev, rmlvo,
    672                                             NULL, 0, bell_func, ctrl_func);
    673 }
    674 
    675 _X_EXPORT Bool
    676 InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
    677                                    const char *keymap, int keymap_length,
    678                                    BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
    679 {
    680     return InitKeyboardDeviceStructInternal(dev, NULL,
    681                                             keymap, keymap_length,
    682                                             bell_func, ctrl_func);
    683 }
    684 
    685 /***====================================================================***/
    686 
    687         /*
    688          * Be very careful about what does and doesn't get freed by this
    689          * function.  To reduce fragmentation, XkbInitDevice allocates a
    690          * single huge block per device and divides it up into most of the
    691          * fixed-size structures for the device.   Don't free anything that
    692          * is part of this larger block.
    693          */
    694 void
    695 XkbFreeInfo(XkbSrvInfoPtr xkbi)
    696 {
    697     free(xkbi->radioGroups);
    698     xkbi->radioGroups = NULL;
    699     if (xkbi->mouseKeyTimer) {
    700         TimerFree(xkbi->mouseKeyTimer);
    701         xkbi->mouseKeyTimer = NULL;
    702     }
    703     if (xkbi->slowKeysTimer) {
    704         TimerFree(xkbi->slowKeysTimer);
    705         xkbi->slowKeysTimer = NULL;
    706     }
    707     if (xkbi->bounceKeysTimer) {
    708         TimerFree(xkbi->bounceKeysTimer);
    709         xkbi->bounceKeysTimer = NULL;
    710     }
    711     if (xkbi->repeatKeyTimer) {
    712         TimerFree(xkbi->repeatKeyTimer);
    713         xkbi->repeatKeyTimer = NULL;
    714     }
    715     if (xkbi->krgTimer) {
    716         TimerFree(xkbi->krgTimer);
    717         xkbi->krgTimer = NULL;
    718     }
    719     xkbi->beepType = _BEEP_NONE;
    720     if (xkbi->beepTimer) {
    721         TimerFree(xkbi->beepTimer);
    722         xkbi->beepTimer = NULL;
    723     }
    724     if (xkbi->desc) {
    725         XkbFreeKeyboard(xkbi->desc, XkbAllComponentsMask, TRUE);
    726         xkbi->desc = NULL;
    727     }
    728     free(xkbi);
    729     return;
    730 }
    731 
    732 /***====================================================================***/
    733 
    734 extern int XkbDfltRepeatDelay;
    735 extern int XkbDfltRepeatInterval;
    736 
    737 extern unsigned short XkbDfltAccessXTimeout;
    738 extern unsigned int XkbDfltAccessXTimeoutMask;
    739 extern unsigned int XkbDfltAccessXFeedback;
    740 extern unsigned short XkbDfltAccessXOptions;
    741 
    742 int
    743 XkbProcessArguments(int argc, char *argv[], int i)
    744 {
    745     if (strncmp(argv[i], "-xkbdir", 7) == 0) {
    746         if (++i < argc) {
    747 #if !defined(WIN32) && !defined(__CYGWIN__)
    748             if (getuid() != geteuid()) {
    749                 LogMessage(X_WARNING,
    750                            "-xkbdir is not available for setuid X servers\n");
    751                 return -1;
    752             }
    753             else
    754 #endif
    755             {
    756                 if (strlen(argv[i]) < PATH_MAX) {
    757                     XkbBaseDirectory = argv[i];
    758                     return 2;
    759                 }
    760                 else {
    761                     LogMessage(X_ERROR, "-xkbdir pathname too long\n");
    762                     return -1;
    763                 }
    764             }
    765         }
    766         else {
    767             return -1;
    768         }
    769     }
    770     else if ((strncmp(argv[i], "-accessx", 8) == 0) ||
    771              (strncmp(argv[i], "+accessx", 8) == 0)) {
    772         int j = 1;
    773 
    774         if (argv[i][0] == '-')
    775             XkbWantAccessX = 0;
    776         else {
    777             XkbWantAccessX = 1;
    778 
    779             if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) {
    780                 XkbDfltAccessXTimeout = atoi(argv[++i]);
    781                 j++;
    782 
    783                 if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) {
    784                     /*
    785                      * presumption that the reasonably useful range of
    786                      * values fits in 0..MAXINT since SunOS 4 doesn't
    787                      * have strtoul.
    788                      */
    789                     XkbDfltAccessXTimeoutMask = (unsigned int)
    790                         strtol(argv[++i], NULL, 16);
    791                     j++;
    792                 }
    793                 if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) {
    794                     if (argv[++i][0] == '1')
    795                         XkbDfltAccessXFeedback = XkbAccessXFeedbackMask;
    796                     else
    797                         XkbDfltAccessXFeedback = 0;
    798                     j++;
    799                 }
    800                 if (((i + 1) < argc) && (isdigit(argv[i + 1][0]))) {
    801                     XkbDfltAccessXOptions = (unsigned short)
    802                         strtol(argv[++i], NULL, 16);
    803                     j++;
    804                 }
    805             }
    806         }
    807         return j;
    808     }
    809     if ((strcmp(argv[i], "-ardelay") == 0) || (strcmp(argv[i], "-ar1") == 0)) { /* -ardelay int */
    810         if (++i >= argc)
    811             UseMsg();
    812         else
    813             XkbDfltRepeatDelay = (long) atoi(argv[i]);
    814         return 2;
    815     }
    816     if ((strcmp(argv[i], "-arinterval") == 0) || (strcmp(argv[i], "-ar2") == 0)) {      /* -arinterval int */
    817         if (++i >= argc)
    818             UseMsg();
    819         else
    820             XkbDfltRepeatInterval = (long) atoi(argv[i]);
    821         return 2;
    822     }
    823     return 0;
    824 }
    825 
    826 void
    827 XkbUseMsg(void)
    828 {
    829     ErrorF
    830         ("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n");
    831     ErrorF("                       enable/disable accessx key sequences\n");
    832     ErrorF("-ardelay               set XKB autorepeat delay\n");
    833     ErrorF("-arinterval            set XKB autorepeat interval\n");
    834 }