18c9fbc29Smrg/************************************************************ 28c9fbc29Smrg Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 38c9fbc29Smrg 48c9fbc29Smrg Permission to use, copy, modify, and distribute this 58c9fbc29Smrg software and its documentation for any purpose and without 68c9fbc29Smrg fee is hereby granted, provided that the above copyright 78c9fbc29Smrg notice appear in all copies and that both that copyright 88c9fbc29Smrg notice and this permission notice appear in supporting 94cd6a3aeSmrg documentation, and that the name of Silicon Graphics not be 104cd6a3aeSmrg used in advertising or publicity pertaining to distribution 118c9fbc29Smrg of the software without specific prior written permission. 124cd6a3aeSmrg Silicon Graphics makes no representation about the suitability 138c9fbc29Smrg of this software for any purpose. It is provided "as is" 148c9fbc29Smrg without any express or implied warranty. 154cd6a3aeSmrg 164cd6a3aeSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 174cd6a3aeSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 188c9fbc29Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 194cd6a3aeSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 204cd6a3aeSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 214cd6a3aeSmrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 228c9fbc29Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 238c9fbc29Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 248c9fbc29Smrg 258c9fbc29Smrg ********************************************************/ 268c9fbc29Smrg 278c9fbc29Smrg#ifdef HAVE_DIX_CONFIG_H 288c9fbc29Smrg#include <dix-config.h> 298c9fbc29Smrg#elif defined(HAVE_CONFIG_H) 308c9fbc29Smrg#include <config.h> 318c9fbc29Smrg#endif 328c9fbc29Smrg 338c9fbc29Smrg#include <stdio.h> 348c9fbc29Smrg#include <ctype.h> 358c9fbc29Smrg#include <stdlib.h> 368c9fbc29Smrg 378c9fbc29Smrg#include <X11/Xos.h> 388c9fbc29Smrg#include <X11/Xfuncs.h> 398c9fbc29Smrg 408c9fbc29Smrg 418c9fbc29Smrg#include <X11/Xlib.h> 428c9fbc29Smrg#include <X11/keysym.h> 438c9fbc29Smrg#include <X11/XKBlib.h> 448c9fbc29Smrg#include <X11/extensions/XKBgeom.h> 458c9fbc29Smrg#include "XKMformat.h" 468c9fbc29Smrg#include "XKBfileInt.h" 478c9fbc29Smrg 488c9fbc29Smrg 498c9fbc29Smrgunsigned 508c9fbc29Smrg_XkbKSCheckCase(KeySym ks) 518c9fbc29Smrg{ 5270728a38Smrg unsigned set, rtrn; 538c9fbc29Smrg 5470728a38Smrg set = (ks & (~0xff)) >> 8; 5570728a38Smrg rtrn = 0; 568c9fbc29Smrg switch (set) { 5770728a38Smrg case 0: /* latin 1 */ 5870728a38Smrg if (((ks >= XK_A) && (ks <= XK_Z)) || 5970728a38Smrg ((ks >= XK_Agrave) && (ks <= XK_THORN) && (ks != XK_multiply))) { 6070728a38Smrg rtrn |= _XkbKSUpper; 6170728a38Smrg } 6270728a38Smrg if (((ks >= XK_a) && (ks <= XK_z)) || 6370728a38Smrg ((ks >= XK_agrave) && (ks <= XK_ydiaeresis))) { 6470728a38Smrg rtrn |= _XkbKSLower; 6570728a38Smrg } 6670728a38Smrg break; 6770728a38Smrg case 1: /* latin 2 */ 6870728a38Smrg if (((ks >= XK_Aogonek) && (ks <= XK_Zabovedot) && (ks != XK_breve)) || 6970728a38Smrg ((ks >= XK_Racute) && (ks <= XK_Tcedilla))) { 7070728a38Smrg rtrn |= _XkbKSUpper; 7170728a38Smrg } 7270728a38Smrg if (((ks >= XK_aogonek) && (ks <= XK_zabovedot) && (ks != XK_caron)) || 7370728a38Smrg ((ks >= XK_racute) && (ks <= XK_tcedilla))) { 7470728a38Smrg rtrn |= _XkbKSLower; 7570728a38Smrg } 7670728a38Smrg break; 7770728a38Smrg case 2: /* latin 3 */ 7870728a38Smrg if (((ks >= XK_Hstroke) && (ks <= XK_Jcircumflex)) || 7970728a38Smrg ((ks >= XK_Cabovedot) && (ks <= XK_Scircumflex))) { 8070728a38Smrg rtrn |= _XkbKSUpper; 8170728a38Smrg } 8270728a38Smrg if (((ks >= XK_hstroke) && (ks <= XK_jcircumflex)) || 8370728a38Smrg ((ks >= XK_cabovedot) && (ks <= XK_scircumflex))) { 8470728a38Smrg rtrn |= _XkbKSLower; 8570728a38Smrg } 8670728a38Smrg break; 8770728a38Smrg case 3: /* latin 4 */ 8870728a38Smrg if (((ks >= XK_Rcedilla) && (ks <= XK_Tslash)) || 8970728a38Smrg (ks == XK_ENG) || ((ks >= XK_Amacron) && (ks <= XK_Umacron))) { 9070728a38Smrg rtrn |= _XkbKSUpper; 9170728a38Smrg } 9270728a38Smrg if (((ks >= XK_rcedilla) && (ks <= XK_tslash)) || 9370728a38Smrg (ks == XK_eng) || ((ks >= XK_amacron) && (ks <= XK_umacron))) { 9470728a38Smrg rtrn |= _XkbKSLower; 9570728a38Smrg } 9670728a38Smrg break; 9770728a38Smrg case 18: /* latin 8 */ 9870728a38Smrg if ((ks == XK_Babovedot) || 9970728a38Smrg ((ks >= XK_Dabovedot) && (ks <= XK_Wacute)) || 10070728a38Smrg ((ks >= XK_Ygrave) && (ks <= XK_Fabovedot)) || 10170728a38Smrg (ks == XK_Mabovedot) || 10270728a38Smrg (ks == XK_Pabovedot) || 10370728a38Smrg (ks == XK_Sabovedot) || 10470728a38Smrg (ks == XK_Wdiaeresis) || 10570728a38Smrg ((ks >= XK_Wcircumflex) && (ks <= XK_Ycircumflex))) { 10670728a38Smrg rtrn |= _XkbKSUpper; 10770728a38Smrg } 10870728a38Smrg if ((ks == XK_babovedot) || 10970728a38Smrg (ks == XK_dabovedot) || 11070728a38Smrg (ks == XK_fabovedot) || 11170728a38Smrg (ks == XK_mabovedot) || 11270728a38Smrg ((ks >= XK_wgrave) && (ks <= XK_wacute)) || 11370728a38Smrg (ks == XK_ygrave) || 11470728a38Smrg ((ks >= XK_wdiaeresis) && (ks <= XK_ycircumflex))) { 11570728a38Smrg rtrn |= _XkbKSLower; 11670728a38Smrg } 11770728a38Smrg break; 11870728a38Smrg case 19: /* latin 9 */ 11970728a38Smrg if ((ks == XK_OE) || (ks == XK_Ydiaeresis)) { 12070728a38Smrg rtrn |= _XkbKSUpper; 12170728a38Smrg } 12270728a38Smrg if (ks == XK_oe) { 12370728a38Smrg rtrn |= _XkbKSLower; 12470728a38Smrg } 12570728a38Smrg break; 1268c9fbc29Smrg } 1278c9fbc29Smrg return rtrn; 1288c9fbc29Smrg} 1298c9fbc29Smrg 1308c9fbc29Smrg/***===================================================================***/ 1318c9fbc29Smrg 1328c9fbc29SmrgBool 13370728a38SmrgXkbLookupGroupAndLevel(XkbDescPtr xkb, 13470728a38Smrg int key, 13570728a38Smrg int * mods_inout, 13670728a38Smrg int * grp_inout, 13770728a38Smrg int * lvl_rtrn) 1388c9fbc29Smrg{ 13970728a38Smrg int nG, eG; 1408c9fbc29Smrg 14170728a38Smrg if ((!xkb) || (!XkbKeycodeInRange(xkb, key)) || (!grp_inout)) 14270728a38Smrg return False; 1438c9fbc29Smrg 14470728a38Smrg nG = XkbKeyNumGroups(xkb, key); 14570728a38Smrg eG = *grp_inout; 1468c9fbc29Smrg 14770728a38Smrg if (nG == 0) { 14870728a38Smrg *grp_inout = 0; 14970728a38Smrg if (lvl_rtrn != NULL) 15070728a38Smrg *lvl_rtrn = 0; 15170728a38Smrg return False; 1528c9fbc29Smrg } 15370728a38Smrg else if (nG == 1) { 15470728a38Smrg eG = 0; 1558c9fbc29Smrg } 15670728a38Smrg else if (eG >= nG) { 15770728a38Smrg unsigned gI = XkbKeyGroupInfo(xkb, key); 15870728a38Smrg 15970728a38Smrg switch (XkbOutOfRangeGroupAction(gI)) { 16070728a38Smrg default: 16170728a38Smrg eG %= nG; 16270728a38Smrg break; 16370728a38Smrg case XkbClampIntoRange: 16470728a38Smrg eG = nG - 1; 16570728a38Smrg break; 16670728a38Smrg case XkbRedirectIntoRange: 16770728a38Smrg eG = XkbOutOfRangeGroupNumber(gI); 16870728a38Smrg if (eG >= nG) 16970728a38Smrg eG = 0; 17070728a38Smrg break; 17170728a38Smrg } 1728c9fbc29Smrg } 17370728a38Smrg *grp_inout = eG; 17470728a38Smrg if (mods_inout != NULL) { 17570728a38Smrg XkbKeyTypePtr type; 17670728a38Smrg int preserve; 17770728a38Smrg 17870728a38Smrg type = XkbKeyKeyType(xkb, key, eG); 17970728a38Smrg if (lvl_rtrn != NULL) 18070728a38Smrg *lvl_rtrn = 0; 18170728a38Smrg preserve = 0; 18270728a38Smrg if (type->map) { /* find the shift level */ 18370728a38Smrg register int i; 18470728a38Smrg register XkbKTMapEntryPtr entry; 18570728a38Smrg 18670728a38Smrg for (i = 0, entry = type->map; i < type->map_count; i++, entry++) { 18770728a38Smrg if ((entry->active) && 18870728a38Smrg (((*mods_inout) & type->mods.mask) == entry->mods.mask)) { 18970728a38Smrg if (lvl_rtrn != NULL) 19070728a38Smrg *lvl_rtrn = entry->level; 19170728a38Smrg if (type->preserve) 19270728a38Smrg preserve = type->preserve[i].mask; 19370728a38Smrg break; 19470728a38Smrg } 19570728a38Smrg } 19670728a38Smrg } 19770728a38Smrg (*mods_inout) &= ~(type->mods.mask & (~preserve)); 1988c9fbc29Smrg } 1998c9fbc29Smrg return True; 2008c9fbc29Smrg} 2018c9fbc29Smrg 2028c9fbc29Smrg/***===================================================================***/ 2038c9fbc29Smrg 2048c9fbc29Smrgstatic Bool 2054cd6a3aeSmrgXkbWriteSectionFromName(FILE *file, const char *sectionName, const char *name) 2068c9fbc29Smrg{ 20770728a38Smrg fprintf(file, " xkb_%-20s { include \"%s\" };\n", sectionName, name); 2088c9fbc29Smrg return True; 2098c9fbc29Smrg} 2108c9fbc29Smrg 2118c9fbc29Smrg#define NEED_DESC(n) ((!n)||((n)[0]=='+')||((n)[0]=='|')||(strchr((n),'%'))) 2128c9fbc29Smrg#define COMPLETE(n) ((n)&&(!NEED_DESC(n))) 2138c9fbc29Smrg 2148c9fbc29Smrg/* ARGSUSED */ 2158c9fbc29Smrgstatic void 21670728a38Smrg_AddIncl(FILE * file, 21770728a38Smrg XkbFileInfo * result, 21870728a38Smrg Bool topLevel, 21970728a38Smrg Bool showImplicit, 22070728a38Smrg int index, 22170728a38Smrg void * priv) 2228c9fbc29Smrg{ 22370728a38Smrg if ((priv) && (strcmp((char *) priv, "%") != 0)) 22470728a38Smrg fprintf(file, " include \"%s\"\n", (char *) priv); 2258c9fbc29Smrg return; 2268c9fbc29Smrg} 2278c9fbc29Smrg 2288c9fbc29SmrgBool 22970728a38SmrgXkbWriteXKBKeymapForNames(FILE * file, 23070728a38Smrg XkbComponentNamesPtr names, 23170728a38Smrg Display * dpy, 23270728a38Smrg XkbDescPtr xkb, 23370728a38Smrg unsigned want, 23470728a38Smrg unsigned need) 2358c9fbc29Smrg{ 23670728a38Smrg char *name, *tmp; 23770728a38Smrg unsigned complete; 23870728a38Smrg XkbNamesPtr old_names; 23970728a38Smrg int multi_section; 24070728a38Smrg unsigned wantNames, wantConfig, wantDflts; 24170728a38Smrg XkbFileInfo finfo; 24270728a38Smrg 24370728a38Smrg bzero(&finfo, sizeof(XkbFileInfo)); 24470728a38Smrg 24570728a38Smrg complete = 0; 24670728a38Smrg if ((name = names->keymap) == NULL) 24770728a38Smrg name = "default"; 24870728a38Smrg if (COMPLETE(names->keycodes)) 24970728a38Smrg complete |= XkmKeyNamesMask; 25070728a38Smrg if (COMPLETE(names->types)) 25170728a38Smrg complete |= XkmTypesMask; 25270728a38Smrg if (COMPLETE(names->compat)) 25370728a38Smrg complete |= XkmCompatMapMask; 25470728a38Smrg if (COMPLETE(names->symbols)) 25570728a38Smrg complete |= XkmSymbolsMask; 25670728a38Smrg if (COMPLETE(names->geometry)) 25770728a38Smrg complete |= XkmGeometryMask; 25870728a38Smrg want |= (complete | need); 25970728a38Smrg if (want & XkmSymbolsMask) 26070728a38Smrg want |= XkmKeyNamesMask | XkmTypesMask; 26170728a38Smrg 26270728a38Smrg if (want == 0) 26370728a38Smrg return False; 26470728a38Smrg 26570728a38Smrg if (xkb != NULL) { 26670728a38Smrg old_names = xkb->names; 26770728a38Smrg finfo.type = 0; 26870728a38Smrg finfo.defined = 0; 26970728a38Smrg finfo.xkb = xkb; 27070728a38Smrg if (!XkbDetermineFileType(&finfo, XkbXKBFile, NULL)) 27170728a38Smrg return False; 2728c9fbc29Smrg } 27370728a38Smrg else 27470728a38Smrg old_names = NULL; 27570728a38Smrg 27670728a38Smrg wantConfig = want & (~complete); 27770728a38Smrg if (xkb != NULL) { 27870728a38Smrg if (wantConfig & XkmTypesMask) { 27970728a38Smrg if ((!xkb->map) || (xkb->map->num_types < XkbNumRequiredTypes)) 28070728a38Smrg wantConfig &= ~XkmTypesMask; 28170728a38Smrg } 28270728a38Smrg if (wantConfig & XkmCompatMapMask) { 28370728a38Smrg if ((!xkb->compat) || (xkb->compat->num_si < 1)) 28470728a38Smrg wantConfig &= ~XkmCompatMapMask; 28570728a38Smrg } 28670728a38Smrg if (wantConfig & XkmSymbolsMask) { 28770728a38Smrg if ((!xkb->map) || (!xkb->map->key_sym_map)) 28870728a38Smrg wantConfig &= ~XkmSymbolsMask; 28970728a38Smrg } 29070728a38Smrg if (wantConfig & XkmIndicatorsMask) { 29170728a38Smrg if (!xkb->indicators) 29270728a38Smrg wantConfig &= ~XkmIndicatorsMask; 29370728a38Smrg } 29470728a38Smrg if (wantConfig & XkmKeyNamesMask) { 29570728a38Smrg if ((!xkb->names) || (!xkb->names->keys)) 29670728a38Smrg wantConfig &= ~XkmKeyNamesMask; 29770728a38Smrg } 29870728a38Smrg if ((wantConfig & XkmGeometryMask) && (!xkb->geom)) 29970728a38Smrg wantConfig &= ~XkmGeometryMask; 3008c9fbc29Smrg } 3018c9fbc29Smrg else { 30270728a38Smrg wantConfig = 0; 3038c9fbc29Smrg } 30470728a38Smrg complete |= wantConfig; 30570728a38Smrg 30670728a38Smrg wantDflts = 0; 30770728a38Smrg wantNames = want & (~complete); 30870728a38Smrg if ((xkb != NULL) && (old_names != NULL)) { 30970728a38Smrg if (wantNames & XkmTypesMask) { 31070728a38Smrg if (old_names->types != None) { 31170728a38Smrg tmp = XkbAtomGetString(dpy, old_names->types); 31270728a38Smrg names->types = tmp; 31370728a38Smrg } 31470728a38Smrg else { 31570728a38Smrg wantDflts |= XkmTypesMask; 31670728a38Smrg } 31770728a38Smrg complete |= XkmTypesMask; 31870728a38Smrg } 31970728a38Smrg if (wantNames & XkmCompatMapMask) { 32070728a38Smrg if (old_names->compat != None) { 32170728a38Smrg tmp = XkbAtomGetString(dpy, old_names->compat); 32270728a38Smrg names->compat = tmp; 32370728a38Smrg } 32470728a38Smrg else 32570728a38Smrg wantDflts |= XkmCompatMapMask; 32670728a38Smrg complete |= XkmCompatMapMask; 32770728a38Smrg } 32870728a38Smrg if (wantNames & XkmSymbolsMask) { 32970728a38Smrg if (old_names->symbols == None) 33070728a38Smrg return False; 33170728a38Smrg tmp = XkbAtomGetString(dpy, old_names->symbols); 33270728a38Smrg names->symbols = tmp; 33370728a38Smrg complete |= XkmSymbolsMask; 33470728a38Smrg } 33570728a38Smrg if (wantNames & XkmKeyNamesMask) { 33670728a38Smrg if (old_names->keycodes != None) { 33770728a38Smrg tmp = XkbAtomGetString(dpy, old_names->keycodes); 33870728a38Smrg names->keycodes = tmp; 33970728a38Smrg } 34070728a38Smrg else 34170728a38Smrg wantDflts |= XkmKeyNamesMask; 34270728a38Smrg complete |= XkmKeyNamesMask; 34370728a38Smrg } 34470728a38Smrg if (wantNames & XkmGeometryMask) { 34570728a38Smrg if (old_names->geometry == None) 34670728a38Smrg return False; 34770728a38Smrg tmp = XkbAtomGetString(dpy, old_names->geometry); 34870728a38Smrg names->geometry = tmp; 34970728a38Smrg complete |= XkmGeometryMask; 35070728a38Smrg wantNames &= ~XkmGeometryMask; 35170728a38Smrg } 3528c9fbc29Smrg } 35370728a38Smrg if (complete & XkmCompatMapMask) 35470728a38Smrg complete |= XkmIndicatorsMask | XkmVirtualModsMask; 35570728a38Smrg else if (complete & (XkmSymbolsMask | XkmTypesMask)) 35670728a38Smrg complete |= XkmVirtualModsMask; 3578c9fbc29Smrg if (need & (~complete)) 35870728a38Smrg return False; 35970728a38Smrg if ((complete & XkmSymbolsMask) && 36070728a38Smrg ((XkmKeyNamesMask | XkmTypesMask) & (~complete))) 36170728a38Smrg return False; 36270728a38Smrg 36370728a38Smrg multi_section = 1; 36470728a38Smrg if (((complete & XkmKeymapRequired) == XkmKeymapRequired) && 36570728a38Smrg ((complete & (~XkmKeymapLegal)) == 0)) { 36670728a38Smrg fprintf(file, "xkb_keymap \"%s\" {\n", name); 3678c9fbc29Smrg } 36870728a38Smrg else if (((complete & XkmSemanticsRequired) == XkmSemanticsRequired) && 36970728a38Smrg ((complete & (~XkmSemanticsLegal)) == 0)) { 37070728a38Smrg fprintf(file, "xkb_semantics \"%s\" {\n", name); 3718c9fbc29Smrg } 37270728a38Smrg else if (((complete & XkmLayoutRequired) == XkmLayoutRequired) && 37370728a38Smrg ((complete & (~XkmLayoutLegal)) == 0)) { 37470728a38Smrg fprintf(file, "xkb_layout \"%s\" {\n", name); 3758c9fbc29Smrg } 37670728a38Smrg else if (XkmSingleSection(complete & (~XkmVirtualModsMask))) { 37770728a38Smrg multi_section = 0; 3788c9fbc29Smrg } 3798c9fbc29Smrg else { 38070728a38Smrg return False; 3818c9fbc29Smrg } 3828c9fbc29Smrg 38370728a38Smrg wantNames = complete & (~(wantConfig | wantDflts)); 38470728a38Smrg name = names->keycodes; 38570728a38Smrg if (wantConfig & XkmKeyNamesMask) 38670728a38Smrg XkbWriteXKBKeycodes(file, &finfo, False, False, _AddIncl, name); 38770728a38Smrg else if (wantDflts & XkmKeyNamesMask) 38870728a38Smrg fprintf(stderr, "Default symbols not implemented yet!\n"); 38970728a38Smrg else if (wantNames & XkmKeyNamesMask) 39070728a38Smrg XkbWriteSectionFromName(file, "keycodes", name); 39170728a38Smrg 39270728a38Smrg name = names->types; 39370728a38Smrg if (wantConfig & XkmTypesMask) 39470728a38Smrg XkbWriteXKBKeyTypes(file, &finfo, False, False, _AddIncl, name); 39570728a38Smrg else if (wantDflts & XkmTypesMask) 39670728a38Smrg fprintf(stderr, "Default types not implemented yet!\n"); 39770728a38Smrg else if (wantNames & XkmTypesMask) 39870728a38Smrg XkbWriteSectionFromName(file, "types", name); 39970728a38Smrg 40070728a38Smrg name = names->compat; 40170728a38Smrg if (wantConfig & XkmCompatMapMask) 40270728a38Smrg XkbWriteXKBCompatMap(file, &finfo, False, False, _AddIncl, name); 40370728a38Smrg else if (wantDflts & XkmCompatMapMask) 40470728a38Smrg fprintf(stderr, "Default interps not implemented yet!\n"); 40570728a38Smrg else if (wantNames & XkmCompatMapMask) 40670728a38Smrg XkbWriteSectionFromName(file, "compatibility", name); 40770728a38Smrg 40870728a38Smrg name = names->symbols; 40970728a38Smrg if (wantConfig & XkmSymbolsMask) 41070728a38Smrg XkbWriteXKBSymbols(file, &finfo, False, False, _AddIncl, name); 41170728a38Smrg else if (wantNames & XkmSymbolsMask) 41270728a38Smrg XkbWriteSectionFromName(file, "symbols", name); 41370728a38Smrg 41470728a38Smrg name = names->geometry; 41570728a38Smrg if (wantConfig & XkmGeometryMask) 41670728a38Smrg XkbWriteXKBGeometry(file, &finfo, False, False, _AddIncl, name); 41770728a38Smrg else if (wantNames & XkmGeometryMask) 41870728a38Smrg XkbWriteSectionFromName(file, "geometry", name); 4198c9fbc29Smrg 4208c9fbc29Smrg if (multi_section) 42170728a38Smrg fprintf(file, "};\n"); 4228c9fbc29Smrg return True; 4238c9fbc29Smrg} 4248c9fbc29Smrg 4258c9fbc29Smrg/***====================================================================***/ 4268c9fbc29Smrg 4278c9fbc29Smrg/*ARGSUSED*/ 4288c9fbc29SmrgStatus 42970728a38SmrgXkbMergeFile(XkbDescPtr xkb, XkbFileInfo finfo) 4308c9fbc29Smrg{ 4318c9fbc29Smrg return BadImplementation; 4328c9fbc29Smrg} 4338c9fbc29Smrg 4348c9fbc29Smrg/***====================================================================***/ 4358c9fbc29Smrg 4368c9fbc29Smrgint 43770728a38SmrgXkbFindKeycodeByName(XkbDescPtr xkb, char *name, Bool use_aliases) 4388c9fbc29Smrg{ 43970728a38Smrg register int i; 4408c9fbc29Smrg 44170728a38Smrg if ((!xkb) || (!xkb->names) || (!xkb->names->keys)) 44270728a38Smrg return 0; 44370728a38Smrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 44470728a38Smrg if (strncmp(xkb->names->keys[i].name, name, XkbKeyNameLength) == 0) 44570728a38Smrg return i; 4468c9fbc29Smrg } 4478c9fbc29Smrg if (!use_aliases) 44870728a38Smrg return 0; 4498c9fbc29Smrg if (xkb->geom && xkb->geom->key_aliases) { 45070728a38Smrg XkbKeyAliasPtr a; 45170728a38Smrg 45270728a38Smrg a = xkb->geom->key_aliases; 45370728a38Smrg for (i = 0; i < xkb->geom->num_key_aliases; i++, a++) { 45470728a38Smrg if (strncmp(name, a->alias, XkbKeyNameLength) == 0) 45570728a38Smrg return XkbFindKeycodeByName(xkb, a->real, False); 45670728a38Smrg } 4578c9fbc29Smrg } 4588c9fbc29Smrg if (xkb->names && xkb->names->key_aliases) { 45970728a38Smrg XkbKeyAliasPtr a; 46070728a38Smrg 46170728a38Smrg a = xkb->names->key_aliases; 46270728a38Smrg for (i = 0; i < xkb->names->num_key_aliases; i++, a++) { 46370728a38Smrg if (strncmp(name, a->alias, XkbKeyNameLength) == 0) 46470728a38Smrg return XkbFindKeycodeByName(xkb, a->real, False); 46570728a38Smrg } 4668c9fbc29Smrg } 4678c9fbc29Smrg return 0; 4688c9fbc29Smrg} 4698c9fbc29Smrg 4708c9fbc29Smrgunsigned 47170728a38SmrgXkbConvertGetByNameComponents(Bool toXkm, unsigned orig) 4728c9fbc29Smrg{ 47370728a38Smrg unsigned rtrn; 4748c9fbc29Smrg 47570728a38Smrg rtrn = 0; 4768c9fbc29Smrg if (toXkm) { 47770728a38Smrg if (orig & XkbGBN_TypesMask) 47870728a38Smrg rtrn |= XkmTypesMask; 47970728a38Smrg if (orig & XkbGBN_CompatMapMask) 48070728a38Smrg rtrn |= XkmCompatMapMask; 48170728a38Smrg if (orig & XkbGBN_SymbolsMask) 48270728a38Smrg rtrn |= XkmSymbolsMask; 48370728a38Smrg if (orig & XkbGBN_IndicatorMapMask) 48470728a38Smrg rtrn |= XkmIndicatorsMask; 48570728a38Smrg if (orig & XkbGBN_KeyNamesMask) 48670728a38Smrg rtrn |= XkmKeyNamesMask; 48770728a38Smrg if (orig & XkbGBN_GeometryMask) 48870728a38Smrg rtrn |= XkmGeometryMask; 4898c9fbc29Smrg } 4908c9fbc29Smrg else { 49170728a38Smrg if (orig & XkmTypesMask) 49270728a38Smrg rtrn |= XkbGBN_TypesMask; 49370728a38Smrg if (orig & XkmCompatMapMask) 49470728a38Smrg rtrn |= XkbGBN_CompatMapMask; 49570728a38Smrg if (orig & XkmSymbolsMask) 49670728a38Smrg rtrn |= XkbGBN_SymbolsMask; 49770728a38Smrg if (orig & XkmIndicatorsMask) 49870728a38Smrg rtrn |= XkbGBN_IndicatorMapMask; 49970728a38Smrg if (orig & XkmKeyNamesMask) 50070728a38Smrg rtrn |= XkbGBN_KeyNamesMask; 50170728a38Smrg if (orig & XkmGeometryMask) 50270728a38Smrg rtrn |= XkbGBN_GeometryMask; 50370728a38Smrg if (orig != 0) 50470728a38Smrg rtrn |= XkbGBN_OtherNamesMask; 5058c9fbc29Smrg } 5068c9fbc29Smrg return rtrn; 5078c9fbc29Smrg} 5088c9fbc29Smrg 5098c9fbc29Smrgunsigned 51070728a38SmrgXkbConvertXkbComponents(Bool toXkm, unsigned orig) 5118c9fbc29Smrg{ 51270728a38Smrg unsigned rtrn; 5138c9fbc29Smrg 51470728a38Smrg rtrn = 0; 5158c9fbc29Smrg if (toXkm) { 51670728a38Smrg if (orig & XkbClientMapMask) 51770728a38Smrg rtrn |= XkmTypesMask | XkmSymbolsMask; 51870728a38Smrg if (orig & XkbServerMapMask) 51970728a38Smrg rtrn |= XkmTypesMask | XkmSymbolsMask; 52070728a38Smrg if (orig & XkbCompatMapMask) 52170728a38Smrg rtrn |= XkmCompatMapMask; 52270728a38Smrg if (orig & XkbIndicatorMapMask) 52370728a38Smrg rtrn |= XkmIndicatorsMask; 52470728a38Smrg if (orig & XkbNamesMask) 52570728a38Smrg rtrn |= XkmKeyNamesMask; 52670728a38Smrg if (orig & XkbGeometryMask) 52770728a38Smrg rtrn |= XkmGeometryMask; 5288c9fbc29Smrg } 5298c9fbc29Smrg else { 53070728a38Smrg if (orig != 0) 53170728a38Smrg rtrn |= XkbNamesMask; 53270728a38Smrg if (orig & XkmTypesMask) 53370728a38Smrg rtrn |= XkbClientMapMask; 53470728a38Smrg if (orig & XkmCompatMapMask) 53570728a38Smrg rtrn |= XkbCompatMapMask | XkbIndicatorMapMask; 53670728a38Smrg if (orig & XkmSymbolsMask) 53770728a38Smrg rtrn |= XkbClientMapMask | XkbServerMapMask; 53870728a38Smrg if (orig & XkmIndicatorsMask) 53970728a38Smrg rtrn |= XkbIndicatorMapMask; 54070728a38Smrg if (orig & XkmKeyNamesMask) 54170728a38Smrg rtrn |= XkbNamesMask | XkbIndicatorMapMask; 54270728a38Smrg if (orig & XkmGeometryMask) 54370728a38Smrg rtrn |= XkbGeometryMask; 5448c9fbc29Smrg } 5458c9fbc29Smrg return rtrn; 5468c9fbc29Smrg} 5478c9fbc29Smrg 5488c9fbc29SmrgBool 54970728a38SmrgXkbDetermineFileType(XkbFileInfoPtr finfo, int format, int *opts_missing) 5508c9fbc29Smrg{ 55170728a38Smrg unsigned present; 55270728a38Smrg XkbDescPtr xkb; 5538c9fbc29Smrg 55470728a38Smrg if ((!finfo) || (!finfo->xkb)) 55570728a38Smrg return False; 5568c9fbc29Smrg if (opts_missing) 55770728a38Smrg *opts_missing = 0; 55870728a38Smrg xkb = finfo->xkb; 55970728a38Smrg present = 0; 56070728a38Smrg if ((xkb->names) && (xkb->names->keys)) 56170728a38Smrg present |= XkmKeyNamesMask; 56270728a38Smrg if ((xkb->map) && (xkb->map->types)) 56370728a38Smrg present |= XkmTypesMask; 56470728a38Smrg if (xkb->compat) 56570728a38Smrg present |= XkmCompatMapMask; 56670728a38Smrg if ((xkb->map) && (xkb->map->num_syms > 1)) 56770728a38Smrg present |= XkmSymbolsMask; 56870728a38Smrg if (xkb->indicators) 56970728a38Smrg present |= XkmIndicatorsMask; 57070728a38Smrg if (xkb->geom) 57170728a38Smrg present |= XkmGeometryMask; 5728c9fbc29Smrg if (!present) 57370728a38Smrg return False; 57470728a38Smrg else 57570728a38Smrg switch (present) { 57670728a38Smrg case XkmKeyNamesMask: 57770728a38Smrg finfo->type = XkmKeyNamesIndex; 57870728a38Smrg finfo->defined = present; 57970728a38Smrg return True; 58070728a38Smrg case XkmTypesMask: 58170728a38Smrg finfo->type = XkmTypesIndex; 58270728a38Smrg finfo->defined = present; 58370728a38Smrg return True; 58470728a38Smrg case XkmCompatMapMask: 58570728a38Smrg finfo->type = XkmCompatMapIndex; 58670728a38Smrg finfo->defined = present; 58770728a38Smrg return True; 58870728a38Smrg case XkmSymbolsMask: 58970728a38Smrg if (format != XkbXKMFile) { 59070728a38Smrg finfo->type = XkmSymbolsIndex; 59170728a38Smrg finfo->defined = present; 59270728a38Smrg return True; 59370728a38Smrg } 59470728a38Smrg break; 59570728a38Smrg case XkmGeometryMask: 59670728a38Smrg finfo->type = XkmGeometryIndex; 59770728a38Smrg finfo->defined = present; 59870728a38Smrg return True; 59970728a38Smrg } 60070728a38Smrg if ((present & (~XkmSemanticsLegal)) == 0) { 60170728a38Smrg if ((XkmSemanticsRequired & present) == XkmSemanticsRequired) { 60270728a38Smrg if (opts_missing) 60370728a38Smrg *opts_missing = XkmSemanticsOptional & (~present); 60470728a38Smrg finfo->type = XkmSemanticsFile; 60570728a38Smrg finfo->defined = present; 60670728a38Smrg return True; 60770728a38Smrg } 6088c9fbc29Smrg } 60970728a38Smrg else if ((present & (~XkmLayoutLegal)) == 0) { 61070728a38Smrg if ((XkmLayoutRequired & present) == XkmLayoutRequired) { 61170728a38Smrg if (opts_missing) 61270728a38Smrg *opts_missing = XkmLayoutOptional & (~present); 61370728a38Smrg finfo->type = XkmLayoutFile; 61470728a38Smrg finfo->defined = present; 61570728a38Smrg return True; 61670728a38Smrg } 6178c9fbc29Smrg } 61870728a38Smrg else if ((present & (~XkmKeymapLegal)) == 0) { 61970728a38Smrg if ((XkmKeymapRequired & present) == XkmKeymapRequired) { 62070728a38Smrg if (opts_missing) 62170728a38Smrg *opts_missing = XkmKeymapOptional & (~present); 62270728a38Smrg finfo->type = XkmKeymapFile; 62370728a38Smrg finfo->defined = present; 62470728a38Smrg return True; 62570728a38Smrg } 6268c9fbc29Smrg } 6278c9fbc29Smrg return False; 6288c9fbc29Smrg} 6298c9fbc29Smrg 6308c9fbc29Smrg/* all latin-1 alphanumerics, plus parens, slash, minus, underscore and */ 6318c9fbc29Smrg/* wildcards */ 6328c9fbc29Smrg 6338c9fbc29Smrgstatic unsigned char componentSpecLegal[] = { 63470728a38Smrg 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83, 63570728a38Smrg 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, 63670728a38Smrg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63770728a38Smrg 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 6388c9fbc29Smrg}; 6398c9fbc29Smrg 6408c9fbc29Smrgvoid 6418c9fbc29SmrgXkbEnsureSafeMapName(char *name) 6428c9fbc29Smrg{ 64370728a38Smrg if (name == NULL) 6448c9fbc29Smrg return; 64570728a38Smrg while (*name != '\0') { 64670728a38Smrg if ((componentSpecLegal[(*name) / 8] & (1 << ((*name) % 8))) == 0) 64770728a38Smrg *name = '_'; 6488c9fbc29Smrg name++; 6498c9fbc29Smrg } 6508c9fbc29Smrg return; 6518c9fbc29Smrg} 6528c9fbc29Smrg 6538c9fbc29Smrg/***====================================================================***/ 6548c9fbc29Smrg 6558c9fbc29Smrg#define UNMATCHABLE(c) (((c)=='(')||((c)==')')||((c)=='/')) 6568c9fbc29Smrg 6578c9fbc29SmrgBool 65870728a38SmrgXkbNameMatchesPattern(char *name, char *ptrn) 6598c9fbc29Smrg{ 66070728a38Smrg while (ptrn[0] != '\0') { 66170728a38Smrg if (name[0] == '\0') { 66270728a38Smrg if (ptrn[0] == '*') { 66370728a38Smrg ptrn++; 66470728a38Smrg continue; 66570728a38Smrg } 66670728a38Smrg return False; 66770728a38Smrg } 66870728a38Smrg if (ptrn[0] == '?') { 66970728a38Smrg if (UNMATCHABLE(name[0])) 67070728a38Smrg return False; 67170728a38Smrg } 67270728a38Smrg else if (ptrn[0] == '*') { 67370728a38Smrg if ((!UNMATCHABLE(name[0])) && 67470728a38Smrg XkbNameMatchesPattern(name + 1, ptrn)) 67570728a38Smrg return True; 67670728a38Smrg return XkbNameMatchesPattern(name, ptrn + 1); 67770728a38Smrg } 67870728a38Smrg else if (ptrn[0] != name[0]) 67970728a38Smrg return False; 68070728a38Smrg name++; 68170728a38Smrg ptrn++; 6828c9fbc29Smrg } 6838c9fbc29Smrg /* if we get here, the pattern is exhausted (-:just like me:-) */ 68470728a38Smrg return (name[0] == '\0'); 6858c9fbc29Smrg} 6868c9fbc29Smrg 68754cef2ddSmrg#ifndef HAVE_STRCASECMP 6888c9fbc29Smrg_X_HIDDEN int 68970728a38Smrg_XkbStrCaseCmp(char *str1, char *str2) 6908c9fbc29Smrg{ 69170728a38Smrg const u_char *us1 = (const u_char *) str1, *us2 = (const u_char *) str2; 6924cd6a3aeSmrg 6938c9fbc29Smrg while (tolower(*us1) == tolower(*us2)) { 6948c9fbc29Smrg if (*us1++ == '\0') 6958c9fbc29Smrg return (0); 6968c9fbc29Smrg us2++; 6978c9fbc29Smrg } 6988c9fbc29Smrg 6998c9fbc29Smrg return (tolower(*us1) - tolower(*us2)); 7008c9fbc29Smrg} 7018c9fbc29Smrg#endif 702