misc.c revision 34345a63
1f46a6179Smrg/************************************************************ 2f46a6179Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 3f46a6179Smrg 4f46a6179Smrg Permission to use, copy, modify, and distribute this 5f46a6179Smrg software and its documentation for any purpose and without 6f46a6179Smrg fee is hereby granted, provided that the above copyright 7f46a6179Smrg notice appear in all copies and that both that copyright 8f46a6179Smrg notice and this permission notice appear in supporting 9f46a6179Smrg documentation, and that the name of Silicon Graphics not be 10f46a6179Smrg used in advertising or publicity pertaining to distribution 11f46a6179Smrg of the software without specific prior written permission. 12f46a6179Smrg Silicon Graphics makes no representation about the suitability 13f46a6179Smrg of this software for any purpose. It is provided "as is" 14f46a6179Smrg without any express or implied warranty. 15f46a6179Smrg 16f46a6179Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17f46a6179Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18f46a6179Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19f46a6179Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20f46a6179Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21f46a6179Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22f46a6179Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23f46a6179Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 24f46a6179Smrg 25f46a6179Smrg ********************************************************/ 26f46a6179Smrg 27f46a6179Smrg#include "xkbcomp.h" 28f46a6179Smrg#include "xkbpath.h" 29f46a6179Smrg#include "tokens.h" 30f46a6179Smrg#include "keycodes.h" 31f46a6179Smrg#include "misc.h" 32f46a6179Smrg#include <X11/keysym.h> 33f46a6179Smrg#include "parseutils.h" 34f46a6179Smrg 35f46a6179Smrg#include <X11/extensions/XKBgeom.h> 36f46a6179Smrg 37f46a6179Smrg/***====================================================================***/ 38f46a6179Smrg 3934345a63Smrg/** 4034345a63Smrg * Open the file given in the include statement and parse it's content. 4134345a63Smrg * If the statement defines a specific map to use, this map is returned in 4234345a63Smrg * file_rtrn. Otherwise, the default map is returned. 4334345a63Smrg * 4434345a63Smrg * @param stmt The include statement, specifying the file name to look for. 4534345a63Smrg * @param file_type Type of file (XkmKeyNamesIdx, etc.) 4634345a63Smrg * @param file_rtrn Returns the key map to be used. 4734345a63Smrg * @param merge_rtrn Always returns stmt->merge. 4834345a63Smrg * 4934345a63Smrg * @return True on success or False otherwise. 5034345a63Smrg */ 51f46a6179SmrgBool 5234345a63SmrgProcessIncludeFile(IncludeStmt * stmt, 5334345a63Smrg unsigned file_type, 5434345a63Smrg XkbFile ** file_rtrn, unsigned *merge_rtrn) 55f46a6179Smrg{ 5634345a63Smrg FILE *file; 5734345a63Smrg XkbFile *rtrn, *mapToUse; 5834345a63Smrg char oldFile[1024] = {0}; 5934345a63Smrg int oldLine = lineNum; 6034345a63Smrg 6134345a63Smrg rtrn = XkbFindFileInCache(stmt->file, file_type, &stmt->path); 6234345a63Smrg if (rtrn == NULL) 6334345a63Smrg { 6434345a63Smrg /* file not in cache, open it, parse it and store it in cache for next 6534345a63Smrg time. */ 6634345a63Smrg file = XkbFindFileInPath(stmt->file, file_type, &stmt->path); 6734345a63Smrg if (file == NULL) 6834345a63Smrg { 6934345a63Smrg ERROR2("Can't find file \"%s\" for %s include\n", stmt->file, 7034345a63Smrg XkbDirectoryForInclude(file_type)); 7134345a63Smrg ACTION("Exiting\n"); 7234345a63Smrg return False; 7334345a63Smrg } 7434345a63Smrg strcpy(oldFile, scanFile); 7534345a63Smrg oldLine = lineNum; 7634345a63Smrg setScanState(stmt->file, 1); 7734345a63Smrg if (debugFlags & 2) 7834345a63Smrg INFO1("About to parse include file %s\n", stmt->file); 7934345a63Smrg /* parse the file */ 8034345a63Smrg if ((XKBParseFile(file, &rtrn) == 0) || (rtrn == NULL)) 8134345a63Smrg { 8234345a63Smrg setScanState(oldFile, oldLine); 8334345a63Smrg ERROR1("Error interpreting include file \"%s\"\n", stmt->file); 8434345a63Smrg ACTION("Exiting\n"); 8534345a63Smrg fclose(file); 8634345a63Smrg return False; 8734345a63Smrg } 8834345a63Smrg fclose(file); 8934345a63Smrg XkbAddFileToCache(stmt->file, file_type, stmt->path, rtrn); 90f46a6179Smrg } 9134345a63Smrg mapToUse = rtrn; 9234345a63Smrg if (stmt->map != NULL) 9334345a63Smrg { 9434345a63Smrg while ((mapToUse) && ((!uStringEqual(mapToUse->name, stmt->map)) || 9534345a63Smrg (mapToUse->type != file_type))) 9634345a63Smrg { 9734345a63Smrg mapToUse = (XkbFile *) mapToUse->common.next; 9834345a63Smrg } 9934345a63Smrg if (!mapToUse) 10034345a63Smrg { 10134345a63Smrg ERROR3("No %s named \"%s\" in the include file \"%s\"\n", 10234345a63Smrg XkbConfigText(file_type, XkbMessage), stmt->map, 10334345a63Smrg stmt->file); 10434345a63Smrg ACTION("Exiting\n"); 10534345a63Smrg return False; 10634345a63Smrg } 107f46a6179Smrg } 10834345a63Smrg else if ((rtrn->common.next != NULL) && (warningLevel > 5)) 10934345a63Smrg { 11034345a63Smrg WARN1("No map in include statement, but \"%s\" contains several\n", 11134345a63Smrg stmt->file); 11234345a63Smrg ACTION1("Using first defined map, \"%s\"\n", rtrn->name); 113f46a6179Smrg } 11434345a63Smrg setScanState(oldFile, oldLine); 11534345a63Smrg if (mapToUse->type != file_type) 11634345a63Smrg { 11734345a63Smrg ERROR2("Include file wrong type (expected %s, got %s)\n", 11834345a63Smrg XkbConfigText(file_type, XkbMessage), 11934345a63Smrg XkbConfigText(mapToUse->type, XkbMessage)); 12034345a63Smrg ACTION1("Include file \"%s\" ignored\n", stmt->file); 12134345a63Smrg return False; 122f46a6179Smrg } 123f46a6179Smrg /* FIXME: we have to check recursive includes here (or somewhere) */ 124f46a6179Smrg 12534345a63Smrg mapToUse->compiled = True; 12634345a63Smrg *file_rtrn = mapToUse; 12734345a63Smrg *merge_rtrn = stmt->merge; 128f46a6179Smrg return True; 129f46a6179Smrg} 130f46a6179Smrg 131f46a6179Smrg/***====================================================================***/ 132f46a6179Smrg 133f46a6179Smrgint 134f46a6179SmrgReportNotArray(const char *type, const char *field, const char *name) 135f46a6179Smrg{ 13634345a63Smrg ERROR2("The %s %s field is not an array\n", type, field); 13734345a63Smrg ACTION1("Ignoring illegal assignment in %s\n", name); 138f46a6179Smrg return False; 139f46a6179Smrg} 140f46a6179Smrg 141f46a6179Smrgint 142f46a6179SmrgReportShouldBeArray(const char *type, const char *field, char *name) 143f46a6179Smrg{ 14434345a63Smrg ERROR2("Missing subscript for %s %s\n", type, field); 14534345a63Smrg ACTION1("Ignoring illegal assignment in %s\n", name); 146f46a6179Smrg return False; 147f46a6179Smrg} 148f46a6179Smrg 149f46a6179Smrgint 150f46a6179SmrgReportBadType(const char *type, const char *field, 151f46a6179Smrg const char *name, const char *wanted) 152f46a6179Smrg{ 15334345a63Smrg ERROR3("The %s %s field must be a %s\n", type, field, wanted); 15434345a63Smrg ACTION1("Ignoring illegal assignment in %s\n", name); 155f46a6179Smrg return False; 156f46a6179Smrg} 157f46a6179Smrg 158f46a6179Smrgint 15934345a63SmrgReportBadIndexType(char *type, char *field, char *name, char *wanted) 160f46a6179Smrg{ 16134345a63Smrg ERROR3("Index for the %s %s field must be a %s\n", type, field, wanted); 16234345a63Smrg ACTION1("Ignoring assignment to illegal field in %s\n", name); 163f46a6179Smrg return False; 164f46a6179Smrg} 165f46a6179Smrg 166f46a6179Smrgint 167f46a6179SmrgReportBadField(const char *type, const char *field, const char *name) 168f46a6179Smrg{ 16934345a63Smrg ERROR3("Unknown %s field %s in %s\n", type, field, name); 17034345a63Smrg ACTION1("Ignoring assignment to unknown field in %s\n", name); 171f46a6179Smrg return False; 172f46a6179Smrg} 173f46a6179Smrg 174f46a6179Smrgint 17534345a63SmrgReportMultipleDefs(char *type, char *field, char *name) 176f46a6179Smrg{ 17734345a63Smrg WARN3("Multiple definitions of %s in %s \"%s\"\n", field, type, name); 178f46a6179Smrg ACTION("Using last definition\n"); 179f46a6179Smrg return False; 180f46a6179Smrg} 181f46a6179Smrg 182f46a6179Smrg/***====================================================================***/ 183f46a6179Smrg 18434345a63SmrgBool 18534345a63SmrgUseNewField(unsigned field, 18634345a63Smrg CommonInfo * oldDefs, CommonInfo * newDefs, unsigned *pCollide) 187f46a6179Smrg{ 18834345a63Smrg Bool useNew; 18934345a63Smrg 19034345a63Smrg useNew = False; 19134345a63Smrg if (oldDefs->defined & field) 19234345a63Smrg { 19334345a63Smrg if (newDefs->defined & field) 19434345a63Smrg { 19534345a63Smrg if (((oldDefs->fileID == newDefs->fileID) 19634345a63Smrg && (warningLevel > 0)) || (warningLevel > 9)) 19734345a63Smrg { 19834345a63Smrg *pCollide |= field; 19934345a63Smrg } 20034345a63Smrg if (newDefs->merge != MergeAugment) 20134345a63Smrg useNew = True; 20234345a63Smrg } 203f46a6179Smrg } 20434345a63Smrg else if (newDefs->defined & field) 20534345a63Smrg useNew = True; 206f46a6179Smrg return useNew; 207f46a6179Smrg} 208f46a6179Smrg 20934345a63SmrgBool 21034345a63SmrgMergeNewField(unsigned field, 21134345a63Smrg CommonInfo * oldDefs, CommonInfo * newDefs, unsigned *pCollide) 212f46a6179Smrg{ 21334345a63Smrg if ((oldDefs->defined & field) && (newDefs->defined & field)) 21434345a63Smrg { 21534345a63Smrg if (((oldDefs->fileID == newDefs->fileID) && (warningLevel > 0)) || 21634345a63Smrg (warningLevel > 9)) 21734345a63Smrg { 21834345a63Smrg *pCollide |= field; 21934345a63Smrg } 22034345a63Smrg if (newDefs->merge == MergeAugment) 22134345a63Smrg return True; 222f46a6179Smrg } 223f46a6179Smrg return False; 224f46a6179Smrg} 225f46a6179Smrg 226f46a6179SmrgXPointer 22734345a63SmrgClearCommonInfo(CommonInfo * cmn) 228f46a6179Smrg{ 22934345a63Smrg if (cmn != NULL) 23034345a63Smrg { 23134345a63Smrg CommonInfo *this, *next; 23234345a63Smrg for (this = cmn; this != NULL; this = next) 23334345a63Smrg { 23434345a63Smrg next = this->next; 23534345a63Smrg uFree(this); 23634345a63Smrg } 237f46a6179Smrg } 238f46a6179Smrg return NULL; 239f46a6179Smrg} 240f46a6179Smrg 241f46a6179SmrgXPointer 24234345a63SmrgAddCommonInfo(CommonInfo * old, CommonInfo * new) 243f46a6179Smrg{ 24434345a63Smrg CommonInfo *first; 245f46a6179Smrg 24634345a63Smrg first = old; 24734345a63Smrg while (old && old->next) 24834345a63Smrg { 24934345a63Smrg old = old->next; 250f46a6179Smrg } 25134345a63Smrg new->next = NULL; 25234345a63Smrg if (old) 25334345a63Smrg { 25434345a63Smrg old->next = new; 25534345a63Smrg return (XPointer) first; 256f46a6179Smrg } 25734345a63Smrg return (XPointer) new; 258f46a6179Smrg} 259f46a6179Smrg 260f46a6179Smrg/***====================================================================***/ 261f46a6179Smrg 26234345a63Smrgtypedef struct _KeyNameDesc 26334345a63Smrg{ 26434345a63Smrg KeySym level1; 26534345a63Smrg KeySym level2; 26634345a63Smrg char name[5]; 26734345a63Smrg Bool used; 268f46a6179Smrg} KeyNameDesc; 269f46a6179Smrg 27034345a63Smrgstatic KeyNameDesc dfltKeys[] = { 27134345a63Smrg {XK_Escape, NoSymbol, "ESC\0"}, 27234345a63Smrg {XK_quoteleft, XK_asciitilde, "TLDE"}, 27334345a63Smrg {XK_1, XK_exclam, "AE01"}, 27434345a63Smrg {XK_2, XK_at, "AE02"}, 27534345a63Smrg {XK_3, XK_numbersign, "AE03"}, 27634345a63Smrg {XK_4, XK_dollar, "AE04"}, 27734345a63Smrg {XK_5, XK_percent, "AE05"}, 27834345a63Smrg {XK_6, XK_asciicircum, "AE06"}, 27934345a63Smrg {XK_7, XK_ampersand, "AE07"}, 28034345a63Smrg {XK_8, XK_asterisk, "AE08"}, 28134345a63Smrg {XK_9, XK_parenleft, "AE09"}, 28234345a63Smrg {XK_0, XK_parenright, "AE10"}, 28334345a63Smrg {XK_minus, XK_underscore, "AE11"}, 28434345a63Smrg {XK_equal, XK_plus, "AE12"}, 28534345a63Smrg {XK_BackSpace, NoSymbol, "BKSP"}, 28634345a63Smrg {XK_Tab, NoSymbol, "TAB\0"}, 28734345a63Smrg {XK_q, XK_Q, "AD01"}, 28834345a63Smrg {XK_w, XK_W, "AD02"}, 28934345a63Smrg {XK_e, XK_E, "AD03"}, 29034345a63Smrg {XK_r, XK_R, "AD04"}, 29134345a63Smrg {XK_t, XK_T, "AD05"}, 29234345a63Smrg {XK_y, XK_Y, "AD06"}, 29334345a63Smrg {XK_u, XK_U, "AD07"}, 29434345a63Smrg {XK_i, XK_I, "AD08"}, 29534345a63Smrg {XK_o, XK_O, "AD09"}, 29634345a63Smrg {XK_p, XK_P, "AD10"}, 29734345a63Smrg {XK_bracketleft, XK_braceleft, "AD11"}, 29834345a63Smrg {XK_bracketright, XK_braceright, "AD12"}, 29934345a63Smrg {XK_Return, NoSymbol, "RTRN"}, 30034345a63Smrg {XK_Caps_Lock, NoSymbol, "CAPS"}, 30134345a63Smrg {XK_a, XK_A, "AC01"}, 30234345a63Smrg {XK_s, XK_S, "AC02"}, 30334345a63Smrg {XK_d, XK_D, "AC03"}, 30434345a63Smrg {XK_f, XK_F, "AC04"}, 30534345a63Smrg {XK_g, XK_G, "AC05"}, 30634345a63Smrg {XK_h, XK_H, "AC06"}, 30734345a63Smrg {XK_j, XK_J, "AC07"}, 30834345a63Smrg {XK_k, XK_K, "AC08"}, 30934345a63Smrg {XK_l, XK_L, "AC09"}, 31034345a63Smrg {XK_semicolon, XK_colon, "AC10"}, 31134345a63Smrg {XK_quoteright, XK_quotedbl, "AC11"}, 31234345a63Smrg {XK_Shift_L, NoSymbol, "LFSH"}, 31334345a63Smrg {XK_z, XK_Z, "AB01"}, 31434345a63Smrg {XK_x, XK_X, "AB02"}, 31534345a63Smrg {XK_c, XK_C, "AB03"}, 31634345a63Smrg {XK_v, XK_V, "AB04"}, 31734345a63Smrg {XK_b, XK_B, "AB05"}, 31834345a63Smrg {XK_n, XK_N, "AB06"}, 31934345a63Smrg {XK_m, XK_M, "AB07"}, 32034345a63Smrg {XK_comma, XK_less, "AB08"}, 32134345a63Smrg {XK_period, XK_greater, "AB09"}, 32234345a63Smrg {XK_slash, XK_question, "AB10"}, 32334345a63Smrg {XK_backslash, XK_bar, "BKSL"}, 32434345a63Smrg {XK_Control_L, NoSymbol, "LCTL"}, 32534345a63Smrg {XK_space, NoSymbol, "SPCE"}, 32634345a63Smrg {XK_Shift_R, NoSymbol, "RTSH"}, 32734345a63Smrg {XK_Alt_L, NoSymbol, "LALT"}, 32834345a63Smrg {XK_space, NoSymbol, "SPCE"}, 32934345a63Smrg {XK_Control_R, NoSymbol, "RCTL"}, 33034345a63Smrg {XK_Alt_R, NoSymbol, "RALT"}, 33134345a63Smrg {XK_F1, NoSymbol, "FK01"}, 33234345a63Smrg {XK_F2, NoSymbol, "FK02"}, 33334345a63Smrg {XK_F3, NoSymbol, "FK03"}, 33434345a63Smrg {XK_F4, NoSymbol, "FK04"}, 33534345a63Smrg {XK_F5, NoSymbol, "FK05"}, 33634345a63Smrg {XK_F6, NoSymbol, "FK06"}, 33734345a63Smrg {XK_F7, NoSymbol, "FK07"}, 33834345a63Smrg {XK_F8, NoSymbol, "FK08"}, 33934345a63Smrg {XK_F9, NoSymbol, "FK09"}, 34034345a63Smrg {XK_F10, NoSymbol, "FK10"}, 34134345a63Smrg {XK_F11, NoSymbol, "FK11"}, 34234345a63Smrg {XK_F12, NoSymbol, "FK12"}, 34334345a63Smrg {XK_Print, NoSymbol, "PRSC"}, 34434345a63Smrg {XK_Scroll_Lock, NoSymbol, "SCLK"}, 34534345a63Smrg {XK_Pause, NoSymbol, "PAUS"}, 34634345a63Smrg {XK_Insert, NoSymbol, "INS\0"}, 34734345a63Smrg {XK_Home, NoSymbol, "HOME"}, 34834345a63Smrg {XK_Prior, NoSymbol, "PGUP"}, 34934345a63Smrg {XK_Delete, NoSymbol, "DELE"}, 35034345a63Smrg {XK_End, NoSymbol, "END"}, 35134345a63Smrg {XK_Next, NoSymbol, "PGDN"}, 35234345a63Smrg {XK_Up, NoSymbol, "UP\0\0"}, 35334345a63Smrg {XK_Left, NoSymbol, "LEFT"}, 35434345a63Smrg {XK_Down, NoSymbol, "DOWN"}, 35534345a63Smrg {XK_Right, NoSymbol, "RGHT"}, 35634345a63Smrg {XK_Num_Lock, NoSymbol, "NMLK"}, 35734345a63Smrg {XK_KP_Divide, NoSymbol, "KPDV"}, 35834345a63Smrg {XK_KP_Multiply, NoSymbol, "KPMU"}, 35934345a63Smrg {XK_KP_Subtract, NoSymbol, "KPSU"}, 36034345a63Smrg {NoSymbol, XK_KP_7, "KP7\0"}, 36134345a63Smrg {NoSymbol, XK_KP_8, "KP8\0"}, 36234345a63Smrg {NoSymbol, XK_KP_9, "KP9\0"}, 36334345a63Smrg {XK_KP_Add, NoSymbol, "KPAD"}, 36434345a63Smrg {NoSymbol, XK_KP_4, "KP4\0"}, 36534345a63Smrg {NoSymbol, XK_KP_5, "KP5\0"}, 36634345a63Smrg {NoSymbol, XK_KP_6, "KP6\0"}, 36734345a63Smrg {NoSymbol, XK_KP_1, "KP1\0"}, 36834345a63Smrg {NoSymbol, XK_KP_2, "KP2\0"}, 36934345a63Smrg {NoSymbol, XK_KP_3, "KP3\0"}, 37034345a63Smrg {XK_KP_Enter, NoSymbol, "KPEN"}, 37134345a63Smrg {NoSymbol, XK_KP_0, "KP0\0"}, 37234345a63Smrg {XK_KP_Delete, NoSymbol, "KPDL"}, 37334345a63Smrg {XK_less, XK_greater, "LSGT"}, 37434345a63Smrg {XK_KP_Separator, NoSymbol, "KPCO"}, 37534345a63Smrg {XK_Find, NoSymbol, "FIND"}, 37634345a63Smrg {NoSymbol, NoSymbol, "\0\0\0\0"} 377f46a6179Smrg}; 378f46a6179Smrg 379f46a6179SmrgStatus 380f46a6179SmrgComputeKbdDefaults(XkbDescPtr xkb) 381f46a6179Smrg{ 38234345a63Smrg Status rtrn; 38334345a63Smrg register int i, tmp, nUnknown; 38434345a63Smrg KeyNameDesc *name; 38534345a63Smrg KeySym *syms; 38634345a63Smrg char tmpname[XkbKeyNameLength + 1]; 38734345a63Smrg 38834345a63Smrg if ((xkb->names == NULL) || (xkb->names->keys == NULL)) 38934345a63Smrg { 39034345a63Smrg if ((rtrn = XkbAllocNames(xkb, XkbKeyNamesMask, 0, 0)) != Success) 39134345a63Smrg return rtrn; 392f46a6179Smrg } 39334345a63Smrg for (name = dfltKeys; (name->name[0] != '\0'); name++) 39434345a63Smrg { 39534345a63Smrg name->used = False; 396f46a6179Smrg } 39734345a63Smrg nUnknown = 0; 39834345a63Smrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) 39934345a63Smrg { 40034345a63Smrg tmp = XkbKeyNumSyms(xkb, i); 40134345a63Smrg if ((xkb->names->keys[i].name[0] == '\0') && (tmp > 0)) 40234345a63Smrg { 40334345a63Smrg tmp = XkbKeyGroupsWidth(xkb, i); 40434345a63Smrg syms = XkbKeySymsPtr(xkb, i); 40534345a63Smrg for (name = dfltKeys; (name->name[0] != '\0'); name++) 40634345a63Smrg { 40734345a63Smrg Bool match = True; 40834345a63Smrg if (((name->level1 != syms[0]) 40934345a63Smrg && (name->level1 != NoSymbol)) 41034345a63Smrg || ((name->level2 != NoSymbol) && (tmp < 2)) 41134345a63Smrg || ((name->level2 != syms[1]) 41234345a63Smrg && (name->level2 != NoSymbol))) 41334345a63Smrg { 41434345a63Smrg match = False; 41534345a63Smrg } 41634345a63Smrg if (match) 41734345a63Smrg { 41834345a63Smrg if (!name->used) 41934345a63Smrg { 42034345a63Smrg memcpy(xkb->names->keys[i].name, name->name, 42134345a63Smrg XkbKeyNameLength); 42234345a63Smrg name->used = True; 42334345a63Smrg } 42434345a63Smrg else 42534345a63Smrg { 42634345a63Smrg if (warningLevel > 2) 42734345a63Smrg { 42834345a63Smrg WARN1 42934345a63Smrg ("Several keys match pattern for %s\n", 43034345a63Smrg XkbKeyNameText(name->name, XkbMessage)); 43134345a63Smrg ACTION2("Using <U%03d> for key %d\n", 43234345a63Smrg nUnknown, i); 43334345a63Smrg } 43434345a63Smrg snprintf(tmpname, sizeof(tmpname), "U%03d", 43534345a63Smrg nUnknown++); 43634345a63Smrg memcpy(xkb->names->keys[i].name, tmpname, 43734345a63Smrg XkbKeyNameLength); 43834345a63Smrg } 43934345a63Smrg break; 44034345a63Smrg } 44134345a63Smrg } 44234345a63Smrg if (xkb->names->keys[i].name[0] == '\0') 44334345a63Smrg { 44434345a63Smrg if (warningLevel > 2) 44534345a63Smrg { 44634345a63Smrg WARN1("Key %d does not match any defaults\n", i); 44734345a63Smrg ACTION1("Using name <U%03d>\n", nUnknown); 44834345a63Smrg snprintf(tmpname, sizeof(tmpname), "U%03d", nUnknown++); 44934345a63Smrg memcpy(xkb->names->keys[i].name, tmpname, 45034345a63Smrg XkbKeyNameLength); 45134345a63Smrg } 45234345a63Smrg } 45334345a63Smrg } 454f46a6179Smrg } 455f46a6179Smrg return Success; 456f46a6179Smrg} 457f46a6179Smrg 45834345a63Smrg/** 45934345a63Smrg * Find the key with the given name and return its keycode in kc_rtrn. 46034345a63Smrg * 46134345a63Smrg * @param name The 4-letter name of the key as a long. 46234345a63Smrg * @param kc_rtrn Set to the keycode if the key was found, otherwise 0. 46334345a63Smrg * @param use_aliases True if the key aliases should be searched too. 46434345a63Smrg * @param create If True and the key is not found, it is added to the 46534345a63Smrg * xkb->names at the first free keycode. 46634345a63Smrg * @param start_from Keycode to start searching from. 46734345a63Smrg * 46834345a63Smrg * @return True if found, False otherwise. 46934345a63Smrg */ 470f46a6179SmrgBool 47134345a63SmrgFindNamedKey(XkbDescPtr xkb, 47234345a63Smrg unsigned long name, 47334345a63Smrg unsigned int *kc_rtrn, 47434345a63Smrg Bool use_aliases, Bool create, int start_from) 475f46a6179Smrg{ 47634345a63Smrg register unsigned n; 477f46a6179Smrg 47834345a63Smrg if (start_from < xkb->min_key_code) 47934345a63Smrg { 48034345a63Smrg start_from = xkb->min_key_code; 481f46a6179Smrg } 48234345a63Smrg else if (start_from > xkb->max_key_code) 48334345a63Smrg { 48434345a63Smrg return False; 485f46a6179Smrg } 486f46a6179Smrg 48734345a63Smrg *kc_rtrn = 0; /* some callers rely on this */ 48834345a63Smrg if (xkb && xkb->names && xkb->names->keys) 48934345a63Smrg { 49034345a63Smrg for (n = start_from; n <= xkb->max_key_code; n++) 49134345a63Smrg { 49234345a63Smrg unsigned long tmp; 49334345a63Smrg tmp = KeyNameToLong(xkb->names->keys[n].name); 49434345a63Smrg if (tmp == name) 49534345a63Smrg { 49634345a63Smrg *kc_rtrn = n; 49734345a63Smrg return True; 49834345a63Smrg } 49934345a63Smrg } 50034345a63Smrg if (use_aliases) 50134345a63Smrg { 50234345a63Smrg unsigned long new_name; 50334345a63Smrg if (FindKeyNameForAlias(xkb, name, &new_name)) 50434345a63Smrg return FindNamedKey(xkb, new_name, kc_rtrn, False, create, 0); 50534345a63Smrg } 506f46a6179Smrg } 50734345a63Smrg if (create) 50834345a63Smrg { 50934345a63Smrg if ((!xkb->names) || (!xkb->names->keys)) 51034345a63Smrg { 51134345a63Smrg if (xkb->min_key_code < XkbMinLegalKeyCode) 51234345a63Smrg { 51334345a63Smrg xkb->min_key_code = XkbMinLegalKeyCode; 51434345a63Smrg xkb->max_key_code = XkbMaxLegalKeyCode; 51534345a63Smrg } 51634345a63Smrg if (XkbAllocNames(xkb, XkbKeyNamesMask, 0, 0) != Success) 51734345a63Smrg { 51834345a63Smrg if (warningLevel > 0) 51934345a63Smrg { 52034345a63Smrg WARN("Couldn't allocate key names in FindNamedKey\n"); 52134345a63Smrg ACTION1("Key \"%s\" not automatically created\n", 52234345a63Smrg longText(name, XkbMessage)); 52334345a63Smrg } 52434345a63Smrg return False; 52534345a63Smrg } 52634345a63Smrg } 52734345a63Smrg /* Find first unused keycode and store our key here */ 52834345a63Smrg for (n = xkb->min_key_code; n <= xkb->max_key_code; n++) 52934345a63Smrg { 53034345a63Smrg if (xkb->names->keys[n].name[0] == '\0') 53134345a63Smrg { 53234345a63Smrg char buf[XkbKeyNameLength + 1]; 53334345a63Smrg LongToKeyName(name, buf); 53434345a63Smrg memcpy(xkb->names->keys[n].name, buf, XkbKeyNameLength); 53534345a63Smrg *kc_rtrn = n; 53634345a63Smrg return True; 53734345a63Smrg } 53834345a63Smrg } 539f46a6179Smrg } 540f46a6179Smrg return False; 541f46a6179Smrg} 542f46a6179Smrg 543f46a6179SmrgBool 54434345a63SmrgFindKeyNameForAlias(XkbDescPtr xkb, unsigned long lname, 54534345a63Smrg unsigned long *real_name) 546f46a6179Smrg{ 54734345a63Smrg register int i; 54834345a63Smrg char name[XkbKeyNameLength + 1]; 54934345a63Smrg 55034345a63Smrg if (xkb && xkb->geom && xkb->geom->key_aliases) 55134345a63Smrg { 55234345a63Smrg XkbKeyAliasPtr a; 55334345a63Smrg a = xkb->geom->key_aliases; 55434345a63Smrg LongToKeyName(lname, name); 55534345a63Smrg name[XkbKeyNameLength] = '\0'; 55634345a63Smrg for (i = 0; i < xkb->geom->num_key_aliases; i++, a++) 55734345a63Smrg { 55834345a63Smrg if (strncmp(name, a->alias, XkbKeyNameLength) == 0) 55934345a63Smrg { 56034345a63Smrg *real_name = KeyNameToLong(a->real); 56134345a63Smrg return True; 56234345a63Smrg } 56334345a63Smrg } 564f46a6179Smrg } 56534345a63Smrg if (xkb && xkb->names && xkb->names->key_aliases) 56634345a63Smrg { 56734345a63Smrg XkbKeyAliasPtr a; 56834345a63Smrg a = xkb->names->key_aliases; 56934345a63Smrg LongToKeyName(lname, name); 57034345a63Smrg name[XkbKeyNameLength] = '\0'; 57134345a63Smrg for (i = 0; i < xkb->names->num_key_aliases; i++, a++) 57234345a63Smrg { 57334345a63Smrg if (strncmp(name, a->alias, XkbKeyNameLength) == 0) 57434345a63Smrg { 57534345a63Smrg *real_name = KeyNameToLong(a->real); 57634345a63Smrg return True; 57734345a63Smrg } 57834345a63Smrg } 579f46a6179Smrg } 580f46a6179Smrg return False; 581f46a6179Smrg} 582