xserver

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

xkbfmisc.c (15698B)


      1 /************************************************************
      2  Copyright (c) 1995 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 <stdio.h>
     32 #include <ctype.h>
     33 #include <stdlib.h>
     34 
     35 #include <X11/Xos.h>
     36 #include <X11/Xfuncs.h>
     37 #include <X11/extensions/XKMformat.h>
     38 
     39 #include <X11/X.h>
     40 #include <X11/keysym.h>
     41 #include <X11/Xproto.h>
     42 #include "misc.h"
     43 #include "inputstr.h"
     44 #include "dix.h"
     45 #include "xkbstr.h"
     46 #define XKBSRV_NEED_FILE_FUNCS	1
     47 #include <xkbsrv.h>
     48 #include "xkbgeom.h"
     49 #include "xkb.h"
     50 
     51 unsigned
     52 _XkbKSCheckCase(KeySym ks)
     53 {
     54     unsigned set, rtrn;
     55 
     56     set = (ks & (~0xff)) >> 8;
     57     rtrn = 0;
     58     switch (set) {
     59     case 0:                    /* latin 1 */
     60         if (((ks >= XK_A) && (ks <= XK_Z)) ||
     61             ((ks >= XK_Agrave) && (ks <= XK_THORN) && (ks != XK_multiply))) {
     62             rtrn |= _XkbKSUpper;
     63         }
     64         if (((ks >= XK_a) && (ks <= XK_z)) ||
     65             ((ks >= XK_ssharp) && (ks <= XK_ydiaeresis) &&
     66              (ks != XK_division))) {
     67             rtrn |= _XkbKSLower;
     68         }
     69         break;
     70     case 1:                    /* latin 2 */
     71         if (((ks >= XK_Aogonek) && (ks <= XK_Zabovedot) && (ks != XK_breve)) ||
     72             ((ks >= XK_Racute) && (ks <= XK_Tcedilla))) {
     73             rtrn |= _XkbKSUpper;
     74         }
     75         if (((ks >= XK_aogonek) && (ks <= XK_zabovedot) && (ks != XK_ogonek) &&
     76              (ks != XK_caron) && (ks != XK_doubleacute)) || ((ks >= XK_racute)
     77                                                              && (ks <=
     78                                                                  XK_tcedilla)))
     79         {
     80             rtrn |= _XkbKSLower;
     81         }
     82         break;
     83     case 2:                    /* latin 3 */
     84         if (((ks >= XK_Hstroke) && (ks <= XK_Jcircumflex)) ||
     85             ((ks >= XK_Cabovedot) && (ks <= XK_Scircumflex))) {
     86             rtrn |= _XkbKSUpper;
     87         }
     88         if (((ks >= XK_hstroke) && (ks <= XK_jcircumflex)) ||
     89             ((ks >= XK_cabovedot) && (ks <= XK_scircumflex))) {
     90             rtrn |= _XkbKSLower;
     91         }
     92         break;
     93     case 3:                    /* latin 4 */
     94         if (((ks >= XK_Rcedilla) && (ks <= XK_Tslash)) ||
     95             (ks == XK_ENG) || ((ks >= XK_Amacron) && (ks <= XK_Umacron))) {
     96             rtrn |= _XkbKSUpper;
     97         }
     98         if ((ks == XK_kra) ||
     99             ((ks >= XK_rcedilla) && (ks <= XK_tslash)) ||
    100             (ks == XK_eng) || ((ks >= XK_amacron) && (ks <= XK_umacron))) {
    101             rtrn |= _XkbKSLower;
    102         }
    103         break;
    104     case 18:                   /* latin 8 */
    105         if ((ks == XK_Wcircumflex) ||
    106             (ks == XK_Ycircumflex) ||
    107             (ks == XK_Babovedot) ||
    108             (ks == XK_Dabovedot) ||
    109             (ks == XK_Fabovedot) ||
    110             (ks == XK_Mabovedot) ||
    111             (ks == XK_Pabovedot) ||
    112             (ks == XK_Sabovedot) ||
    113             (ks == XK_Tabovedot) ||
    114             (ks == XK_Wgrave) ||
    115             (ks == XK_Wacute) || (ks == XK_Wdiaeresis) || (ks == XK_Ygrave)) {
    116             rtrn |= _XkbKSUpper;
    117         }
    118         if ((ks == XK_wcircumflex) ||
    119             (ks == XK_ycircumflex) ||
    120             (ks == XK_babovedot) ||
    121             (ks == XK_dabovedot) ||
    122             (ks == XK_fabovedot) ||
    123             (ks == XK_mabovedot) ||
    124             (ks == XK_pabovedot) ||
    125             (ks == XK_sabovedot) ||
    126             (ks == XK_tabovedot) ||
    127             (ks == XK_wgrave) ||
    128             (ks == XK_wacute) || (ks == XK_wdiaeresis) || (ks == XK_ygrave)) {
    129             rtrn |= _XkbKSLower;
    130         }
    131         break;
    132     case 19:                   /* latin 9 */
    133         if ((ks == XK_OE) || (ks == XK_Ydiaeresis)) {
    134             rtrn |= _XkbKSUpper;
    135         }
    136         if (ks == XK_oe) {
    137             rtrn |= _XkbKSLower;
    138         }
    139         break;
    140     }
    141     return rtrn;
    142 }
    143 
    144 /***===================================================================***/
    145 
    146 static Bool
    147 XkbWriteSectionFromName(FILE * file, const char *sectionName, const char *name)
    148 {
    149     fprintf(file, "    xkb_%-20s { include \"%s\" };\n", sectionName, name);
    150     return TRUE;
    151 }
    152 
    153 #define	NEED_DESC(n) ((!n)||((n)[0]=='+')||((n)[0]=='|')||(strchr((n),'%')))
    154 #define	COMPLETE(n)  ((n)&&(!NEED_DESC(n)))
    155 
    156 /* ARGSUSED */
    157 static void
    158 _AddIncl(FILE * file,
    159          XkbDescPtr xkb,
    160          Bool topLevel, Bool showImplicit, int index, void *priv)
    161 {
    162     if ((priv) && (strcmp((char *) priv, "%") != 0))
    163         fprintf(file, "    include \"%s\"\n", (char *) priv);
    164     return;
    165 }
    166 
    167 Bool
    168 XkbWriteXKBKeymapForNames(FILE * file,
    169                           XkbComponentNamesPtr names,
    170                           XkbDescPtr xkb, unsigned want, unsigned need)
    171 {
    172     const char *tmp;
    173     unsigned complete;
    174     XkbNamesPtr old_names;
    175     int multi_section;
    176     unsigned wantNames, wantConfig, wantDflts;
    177 
    178     complete = 0;
    179     if (COMPLETE(names->keycodes))
    180         complete |= XkmKeyNamesMask;
    181     if (COMPLETE(names->types))
    182         complete |= XkmTypesMask;
    183     if (COMPLETE(names->compat))
    184         complete |= XkmCompatMapMask;
    185     if (COMPLETE(names->symbols))
    186         complete |= XkmSymbolsMask;
    187     if (COMPLETE(names->geometry))
    188         complete |= XkmGeometryMask;
    189     want |= (complete | need);
    190     if (want & XkmSymbolsMask)
    191         want |= XkmKeyNamesMask | XkmTypesMask;
    192 
    193     if (want == 0)
    194         return FALSE;
    195 
    196     if (xkb) {
    197         old_names = xkb->names;
    198 
    199         xkb->defined = 0;
    200         /* Wow would it ever be neat if we didn't need this noise. */
    201         if (xkb->names && xkb->names->keys)
    202             xkb->defined |= XkmKeyNamesMask;
    203         if (xkb->map && xkb->map->types)
    204             xkb->defined |= XkmTypesMask;
    205         if (xkb->compat)
    206             xkb->defined |= XkmCompatMapMask;
    207         if (xkb->map && xkb->map->num_syms)
    208             xkb->defined |= XkmSymbolsMask;
    209         if (xkb->indicators)
    210             xkb->defined |= XkmIndicatorsMask;
    211         if (xkb->geom)
    212             xkb->defined |= XkmGeometryMask;
    213     }
    214     else {
    215         old_names = NULL;
    216     }
    217 
    218     wantConfig = want & (~complete);
    219     if (xkb != NULL) {
    220         if (wantConfig & XkmTypesMask) {
    221             if ((!xkb->map) || (xkb->map->num_types < XkbNumRequiredTypes))
    222                 wantConfig &= ~XkmTypesMask;
    223         }
    224         if (wantConfig & XkmCompatMapMask) {
    225             if ((!xkb->compat) || (xkb->compat->num_si < 1))
    226                 wantConfig &= ~XkmCompatMapMask;
    227         }
    228         if (wantConfig & XkmSymbolsMask) {
    229             if ((!xkb->map) || (!xkb->map->key_sym_map))
    230                 wantConfig &= ~XkmSymbolsMask;
    231         }
    232         if (wantConfig & XkmIndicatorsMask) {
    233             if (!xkb->indicators)
    234                 wantConfig &= ~XkmIndicatorsMask;
    235         }
    236         if (wantConfig & XkmKeyNamesMask) {
    237             if ((!xkb->names) || (!xkb->names->keys))
    238                 wantConfig &= ~XkmKeyNamesMask;
    239         }
    240         if ((wantConfig & XkmGeometryMask) && (!xkb->geom))
    241             wantConfig &= ~XkmGeometryMask;
    242     }
    243     else {
    244         wantConfig = 0;
    245     }
    246     complete |= wantConfig;
    247 
    248     wantDflts = 0;
    249     wantNames = want & (~complete);
    250     if ((xkb != NULL) && (old_names != NULL)) {
    251         if (wantNames & XkmTypesMask) {
    252             if (old_names->types != None) {
    253                 tmp = NameForAtom(old_names->types);
    254                 names->types = Xstrdup(tmp);
    255             }
    256             else {
    257                 wantDflts |= XkmTypesMask;
    258             }
    259             complete |= XkmTypesMask;
    260         }
    261         if (wantNames & XkmCompatMapMask) {
    262             if (old_names->compat != None) {
    263                 tmp = NameForAtom(old_names->compat);
    264                 names->compat = Xstrdup(tmp);
    265             }
    266             else
    267                 wantDflts |= XkmCompatMapMask;
    268             complete |= XkmCompatMapMask;
    269         }
    270         if (wantNames & XkmSymbolsMask) {
    271             if (old_names->symbols == None)
    272                 return FALSE;
    273             tmp = NameForAtom(old_names->symbols);
    274             names->symbols = Xstrdup(tmp);
    275             complete |= XkmSymbolsMask;
    276         }
    277         if (wantNames & XkmKeyNamesMask) {
    278             if (old_names->keycodes != None) {
    279                 tmp = NameForAtom(old_names->keycodes);
    280                 names->keycodes = Xstrdup(tmp);
    281             }
    282             else
    283                 wantDflts |= XkmKeyNamesMask;
    284             complete |= XkmKeyNamesMask;
    285         }
    286         if (wantNames & XkmGeometryMask) {
    287             if (old_names->geometry == None)
    288                 return FALSE;
    289             tmp = NameForAtom(old_names->geometry);
    290             names->geometry = Xstrdup(tmp);
    291             complete |= XkmGeometryMask;
    292             wantNames &= ~XkmGeometryMask;
    293         }
    294     }
    295     if (complete & XkmCompatMapMask)
    296         complete |= XkmIndicatorsMask | XkmVirtualModsMask;
    297     else if (complete & (XkmSymbolsMask | XkmTypesMask))
    298         complete |= XkmVirtualModsMask;
    299     if (need & (~complete))
    300         return FALSE;
    301     if ((complete & XkmSymbolsMask) &&
    302         ((XkmKeyNamesMask | XkmTypesMask) & (~complete)))
    303         return FALSE;
    304 
    305     multi_section = 1;
    306     if (((complete & XkmKeymapRequired) == XkmKeymapRequired) &&
    307         ((complete & (~XkmKeymapLegal)) == 0)) {
    308         fprintf(file, "xkb_keymap \"default\" {\n");
    309     }
    310     else if (((complete & XkmSemanticsRequired) == XkmSemanticsRequired) &&
    311              ((complete & (~XkmSemanticsLegal)) == 0)) {
    312         fprintf(file, "xkb_semantics \"default\" {\n");
    313     }
    314     else if (((complete & XkmLayoutRequired) == XkmLayoutRequired) &&
    315              ((complete & (~XkmLayoutLegal)) == 0)) {
    316         fprintf(file, "xkb_layout \"default\" {\n");
    317     }
    318     else if (XkmSingleSection(complete & (~XkmVirtualModsMask))) {
    319         multi_section = 0;
    320     }
    321     else {
    322         return FALSE;
    323     }
    324 
    325     wantNames = complete & (~(wantConfig | wantDflts));
    326     if (wantConfig & XkmKeyNamesMask)
    327         XkbWriteXKBKeycodes(file, xkb, FALSE, FALSE, _AddIncl, names->keycodes);
    328     else if (wantDflts & XkmKeyNamesMask)
    329         fprintf(stderr, "Default symbols not implemented yet!\n");
    330     else if (wantNames & XkmKeyNamesMask)
    331         XkbWriteSectionFromName(file, "keycodes", names->keycodes);
    332 
    333     if (wantConfig & XkmTypesMask)
    334         XkbWriteXKBKeyTypes(file, xkb, FALSE, FALSE, _AddIncl, names->types);
    335     else if (wantDflts & XkmTypesMask)
    336         fprintf(stderr, "Default types not implemented yet!\n");
    337     else if (wantNames & XkmTypesMask)
    338         XkbWriteSectionFromName(file, "types", names->types);
    339 
    340     if (wantConfig & XkmCompatMapMask)
    341         XkbWriteXKBCompatMap(file, xkb, FALSE, FALSE, _AddIncl, names->compat);
    342     else if (wantDflts & XkmCompatMapMask)
    343         fprintf(stderr, "Default interps not implemented yet!\n");
    344     else if (wantNames & XkmCompatMapMask)
    345         XkbWriteSectionFromName(file, "compatibility", names->compat);
    346 
    347     if (wantConfig & XkmSymbolsMask)
    348         XkbWriteXKBSymbols(file, xkb, FALSE, FALSE, _AddIncl, names->symbols);
    349     else if (wantNames & XkmSymbolsMask)
    350         XkbWriteSectionFromName(file, "symbols", names->symbols);
    351 
    352     if (wantConfig & XkmGeometryMask)
    353         XkbWriteXKBGeometry(file, xkb, FALSE, FALSE, _AddIncl, names->geometry);
    354     else if (wantNames & XkmGeometryMask)
    355         XkbWriteSectionFromName(file, "geometry", names->geometry);
    356 
    357     if (multi_section)
    358         fprintf(file, "};\n");
    359     return TRUE;
    360 }
    361 
    362 /***====================================================================***/
    363 
    364 int
    365 XkbFindKeycodeByName(XkbDescPtr xkb, char *name, Bool use_aliases)
    366 {
    367     register int i;
    368 
    369     if ((!xkb) || (!xkb->names) || (!xkb->names->keys))
    370         return 0;
    371     for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
    372         if (strncmp(xkb->names->keys[i].name, name, XkbKeyNameLength) == 0)
    373             return i;
    374     }
    375     if (!use_aliases)
    376         return 0;
    377     if (xkb->geom && xkb->geom->key_aliases) {
    378         XkbKeyAliasPtr a;
    379 
    380         a = xkb->geom->key_aliases;
    381         for (i = 0; i < xkb->geom->num_key_aliases; i++, a++) {
    382             if (strncmp(name, a->alias, XkbKeyNameLength) == 0)
    383                 return XkbFindKeycodeByName(xkb, a->real, FALSE);
    384         }
    385     }
    386     if (xkb->names && xkb->names->key_aliases) {
    387         XkbKeyAliasPtr a;
    388 
    389         a = xkb->names->key_aliases;
    390         for (i = 0; i < xkb->names->num_key_aliases; i++, a++) {
    391             if (strncmp(name, a->alias, XkbKeyNameLength) == 0)
    392                 return XkbFindKeycodeByName(xkb, a->real, FALSE);
    393         }
    394     }
    395     return 0;
    396 }
    397 
    398 unsigned
    399 XkbConvertGetByNameComponents(Bool toXkm, unsigned orig)
    400 {
    401     unsigned rtrn;
    402 
    403     rtrn = 0;
    404     if (toXkm) {
    405         if (orig & XkbGBN_TypesMask)
    406             rtrn |= XkmTypesMask;
    407         if (orig & XkbGBN_CompatMapMask)
    408             rtrn |= XkmCompatMapMask;
    409         if (orig & XkbGBN_SymbolsMask)
    410             rtrn |= XkmSymbolsMask;
    411         if (orig & XkbGBN_IndicatorMapMask)
    412             rtrn |= XkmIndicatorsMask;
    413         if (orig & XkbGBN_KeyNamesMask)
    414             rtrn |= XkmKeyNamesMask;
    415         if (orig & XkbGBN_GeometryMask)
    416             rtrn |= XkmGeometryMask;
    417     }
    418     else {
    419         if (orig & XkmTypesMask)
    420             rtrn |= XkbGBN_TypesMask;
    421         if (orig & XkmCompatMapMask)
    422             rtrn |= XkbGBN_CompatMapMask;
    423         if (orig & XkmSymbolsMask)
    424             rtrn |= XkbGBN_SymbolsMask;
    425         if (orig & XkmIndicatorsMask)
    426             rtrn |= XkbGBN_IndicatorMapMask;
    427         if (orig & XkmKeyNamesMask)
    428             rtrn |= XkbGBN_KeyNamesMask;
    429         if (orig & XkmGeometryMask)
    430             rtrn |= XkbGBN_GeometryMask;
    431         if (orig != 0)
    432             rtrn |= XkbGBN_OtherNamesMask;
    433     }
    434     return rtrn;
    435 }
    436 
    437 /***====================================================================***/
    438 
    439 #define	UNMATCHABLE(c)	(((c)=='(')||((c)==')')||((c)=='/'))
    440 
    441 Bool
    442 XkbNameMatchesPattern(char *name, char *ptrn)
    443 {
    444     while (ptrn[0] != '\0') {
    445         if (name[0] == '\0') {
    446             if (ptrn[0] == '*') {
    447                 ptrn++;
    448                 continue;
    449             }
    450             return FALSE;
    451         }
    452         if (ptrn[0] == '?') {
    453             if (UNMATCHABLE(name[0]))
    454                 return FALSE;
    455         }
    456         else if (ptrn[0] == '*') {
    457             if ((!UNMATCHABLE(name[0])) &&
    458                 XkbNameMatchesPattern(name + 1, ptrn))
    459                 return TRUE;
    460             return XkbNameMatchesPattern(name, ptrn + 1);
    461         }
    462         else if (ptrn[0] != name[0])
    463             return FALSE;
    464         name++;
    465         ptrn++;
    466     }
    467     /* if we get here, the pattern is exhausted (-:just like me:-) */
    468     return name[0] == '\0';
    469 }