xkbcomp: Remove duplicated macros
[platform/upstream/libxkbcommon.git] / src / xkbcomp / misc.c
1 /************************************************************
2  Copyright (c) 1994 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 #include "xkbcomp.h"
28 #include "xkbpath.h"
29 #include "tokens.h"
30 #include "keycodes.h"
31 #include "misc.h"
32 #include <X11/keysym.h>
33 #include "parseutils.h"
34
35 #include <X11/extensions/XKBgeomcommon.h>
36
37 /***====================================================================***/
38
39 /**
40  * Open the file given in the include statement and parse it's content.
41  * If the statement defines a specific map to use, this map is returned in
42  * file_rtrn. Otherwise, the default map is returned.
43  *
44  * @param stmt The include statement, specifying the file name to look for.
45  * @param file_type Type of file (XkmKeyNamesIdx, etc.)
46  * @param file_rtrn Returns the key map to be used.
47  * @param merge_rtrn Always returns stmt->merge.
48  *
49  * @return True on success or False otherwise.
50  */
51 Bool
52 ProcessIncludeFile(IncludeStmt * stmt,
53                    unsigned file_type,
54                    XkbFile ** file_rtrn, unsigned *merge_rtrn)
55 {
56     FILE *file;
57     XkbFile *rtrn, *mapToUse;
58     char oldFile[1024] = {0};
59     int oldLine = lineNum;
60
61     rtrn = XkbFindFileInCache(stmt->file, file_type, &stmt->path);
62     if (rtrn == NULL)
63     {
64         /* file not in cache, open it, parse it and store it in cache for next
65            time. */
66         file = XkbFindFileInPath(stmt->file, file_type, &stmt->path);
67         if (file == NULL)
68         {
69             ERROR("Can't find file \"%s\" for %s include\n", stmt->file,
70                    XkbDirectoryForInclude(file_type));
71             ACTION("Exiting\n");
72             return False;
73         }
74         strcpy(oldFile, scanFile);
75         oldLine = lineNum;
76         setScanState(stmt->file, 1);
77         if (debugFlags & 2)
78             INFO("About to parse include file %s\n", stmt->file);
79         /* parse the file */
80         if ((XKBParseFile(file, &rtrn) == 0) || (rtrn == NULL))
81         {
82             setScanState(oldFile, oldLine);
83             ERROR("Error interpreting include file \"%s\"\n", stmt->file);
84             ACTION("Exiting\n");
85             fclose(file);
86             return False;
87         }
88         fclose(file);
89         XkbAddFileToCache(stmt->file, file_type, stmt->path, rtrn);
90     }
91     mapToUse = rtrn;
92     if (stmt->map != NULL)
93     {
94         while ((mapToUse) && ((!uStringEqual(mapToUse->name, stmt->map)) ||
95                               (mapToUse->type != file_type)))
96         {
97             mapToUse = (XkbFile *) mapToUse->common.next;
98         }
99         if (!mapToUse)
100         {
101             ERROR("No %s named \"%s\" in the include file \"%s\"\n",
102                    XkbcConfigText(file_type), stmt->map, stmt->file);
103             ACTION("Exiting\n");
104             return False;
105         }
106     }
107     else if ((rtrn->common.next != NULL) && (warningLevel > 5))
108     {
109         WARN("No map in include statement, but \"%s\" contains several\n",
110               stmt->file);
111         ACTION("Using first defined map, \"%s\"\n", rtrn->name);
112     }
113     setScanState(oldFile, oldLine);
114     if (mapToUse->type != file_type)
115     {
116         ERROR("Include file wrong type (expected %s, got %s)\n",
117                XkbcConfigText(file_type), XkbcConfigText(mapToUse->type));
118         ACTION("Include file \"%s\" ignored\n", stmt->file);
119         return False;
120     }
121     /* FIXME: we have to check recursive includes here (or somewhere) */
122
123     mapToUse->compiled = True;
124     *file_rtrn = mapToUse;
125     *merge_rtrn = stmt->merge;
126     return True;
127 }
128
129 /***====================================================================***/
130
131 int
132 ReportNotArray(const char *type, const char *field, const char *name)
133 {
134     ERROR("The %s %s field is not an array\n", type, field);
135     ACTION("Ignoring illegal assignment in %s\n", name);
136     return False;
137 }
138
139 int
140 ReportShouldBeArray(const char *type, const char *field, char *name)
141 {
142     ERROR("Missing subscript for %s %s\n", type, field);
143     ACTION("Ignoring illegal assignment in %s\n", name);
144     return False;
145 }
146
147 int
148 ReportBadType(const char *type, const char *field,
149               const char *name, const char *wanted)
150 {
151     ERROR("The %s %s field must be a %s\n", type, field, wanted);
152     ACTION("Ignoring illegal assignment in %s\n", name);
153     return False;
154 }
155
156 int
157 ReportBadIndexType(char *type, char *field, char *name, char *wanted)
158 {
159     ERROR("Index for the %s %s field must be a %s\n", type, field, wanted);
160     ACTION("Ignoring assignment to illegal field in %s\n", name);
161     return False;
162 }
163
164 int
165 ReportBadField(const char *type, const char *field, const char *name)
166 {
167     ERROR("Unknown %s field %s in %s\n", type, field, name);
168     ACTION("Ignoring assignment to unknown field in %s\n", name);
169     return False;
170 }
171
172 int
173 ReportMultipleDefs(char *type, char *field, char *name)
174 {
175     WARN("Multiple definitions of %s in %s \"%s\"\n", field, type, name);
176     ACTION("Using last definition\n");
177     return False;
178 }
179
180 /***====================================================================***/
181
182 Bool
183 UseNewField(unsigned field,
184             CommonInfo * oldDefs, CommonInfo * newDefs, unsigned *pCollide)
185 {
186     Bool useNew;
187
188     useNew = False;
189     if (oldDefs->defined & field)
190     {
191         if (newDefs->defined & field)
192         {
193             if (((oldDefs->fileID == newDefs->fileID)
194                  && (warningLevel > 0)) || (warningLevel > 9))
195             {
196                 *pCollide |= field;
197             }
198             if (newDefs->merge != MergeAugment)
199                 useNew = True;
200         }
201     }
202     else if (newDefs->defined & field)
203         useNew = True;
204     return useNew;
205 }
206
207 Bool
208 MergeNewField(unsigned field,
209               CommonInfo * oldDefs, CommonInfo * newDefs, unsigned *pCollide)
210 {
211     if ((oldDefs->defined & field) && (newDefs->defined & field))
212     {
213         if (((oldDefs->fileID == newDefs->fileID) && (warningLevel > 0)) ||
214             (warningLevel > 9))
215         {
216             *pCollide |= field;
217         }
218         if (newDefs->merge == MergeAugment)
219             return True;
220     }
221     return False;
222 }
223
224 char *
225 ClearCommonInfo(CommonInfo * cmn)
226 {
227     if (cmn != NULL)
228     {
229         CommonInfo *this, *next;
230         for (this = cmn; this != NULL; this = next)
231         {
232             next = this->next;
233             uFree(this);
234         }
235     }
236     return NULL;
237 }
238
239 char *
240 AddCommonInfo(CommonInfo * old, CommonInfo * new)
241 {
242     CommonInfo *first;
243
244     first = old;
245     while (old && old->next)
246     {
247         old = old->next;
248     }
249     new->next = NULL;
250     if (old)
251     {
252         old->next = new;
253         return (char *) first;
254     }
255     return (char *) new;
256 }
257
258 /***====================================================================***/
259
260 typedef struct _KeyNameDesc
261 {
262     KeySym level1;
263     KeySym level2;
264     char name[5];
265     Bool used;
266 } KeyNameDesc;
267
268 static KeyNameDesc dfltKeys[] = {
269     {XK_Escape, NoSymbol, "ESC\0"},
270     {XK_quoteleft, XK_asciitilde, "TLDE"},
271     {XK_1, XK_exclam, "AE01"},
272     {XK_2, XK_at, "AE02"},
273     {XK_3, XK_numbersign, "AE03"},
274     {XK_4, XK_dollar, "AE04"},
275     {XK_5, XK_percent, "AE05"},
276     {XK_6, XK_asciicircum, "AE06"},
277     {XK_7, XK_ampersand, "AE07"},
278     {XK_8, XK_asterisk, "AE08"},
279     {XK_9, XK_parenleft, "AE09"},
280     {XK_0, XK_parenright, "AE10"},
281     {XK_minus, XK_underscore, "AE11"},
282     {XK_equal, XK_plus, "AE12"},
283     {XK_BackSpace, NoSymbol, "BKSP"},
284     {XK_Tab, NoSymbol, "TAB\0"},
285     {XK_q, XK_Q, "AD01"},
286     {XK_w, XK_W, "AD02"},
287     {XK_e, XK_E, "AD03"},
288     {XK_r, XK_R, "AD04"},
289     {XK_t, XK_T, "AD05"},
290     {XK_y, XK_Y, "AD06"},
291     {XK_u, XK_U, "AD07"},
292     {XK_i, XK_I, "AD08"},
293     {XK_o, XK_O, "AD09"},
294     {XK_p, XK_P, "AD10"},
295     {XK_bracketleft, XK_braceleft, "AD11"},
296     {XK_bracketright, XK_braceright, "AD12"},
297     {XK_Return, NoSymbol, "RTRN"},
298     {XK_Caps_Lock, NoSymbol, "CAPS"},
299     {XK_a, XK_A, "AC01"},
300     {XK_s, XK_S, "AC02"},
301     {XK_d, XK_D, "AC03"},
302     {XK_f, XK_F, "AC04"},
303     {XK_g, XK_G, "AC05"},
304     {XK_h, XK_H, "AC06"},
305     {XK_j, XK_J, "AC07"},
306     {XK_k, XK_K, "AC08"},
307     {XK_l, XK_L, "AC09"},
308     {XK_semicolon, XK_colon, "AC10"},
309     {XK_quoteright, XK_quotedbl, "AC11"},
310     {XK_Shift_L, NoSymbol, "LFSH"},
311     {XK_z, XK_Z, "AB01"},
312     {XK_x, XK_X, "AB02"},
313     {XK_c, XK_C, "AB03"},
314     {XK_v, XK_V, "AB04"},
315     {XK_b, XK_B, "AB05"},
316     {XK_n, XK_N, "AB06"},
317     {XK_m, XK_M, "AB07"},
318     {XK_comma, XK_less, "AB08"},
319     {XK_period, XK_greater, "AB09"},
320     {XK_slash, XK_question, "AB10"},
321     {XK_backslash, XK_bar, "BKSL"},
322     {XK_Control_L, NoSymbol, "LCTL"},
323     {XK_space, NoSymbol, "SPCE"},
324     {XK_Shift_R, NoSymbol, "RTSH"},
325     {XK_Alt_L, NoSymbol, "LALT"},
326     {XK_space, NoSymbol, "SPCE"},
327     {XK_Control_R, NoSymbol, "RCTL"},
328     {XK_Alt_R, NoSymbol, "RALT"},
329     {XK_F1, NoSymbol, "FK01"},
330     {XK_F2, NoSymbol, "FK02"},
331     {XK_F3, NoSymbol, "FK03"},
332     {XK_F4, NoSymbol, "FK04"},
333     {XK_F5, NoSymbol, "FK05"},
334     {XK_F6, NoSymbol, "FK06"},
335     {XK_F7, NoSymbol, "FK07"},
336     {XK_F8, NoSymbol, "FK08"},
337     {XK_F9, NoSymbol, "FK09"},
338     {XK_F10, NoSymbol, "FK10"},
339     {XK_F11, NoSymbol, "FK11"},
340     {XK_F12, NoSymbol, "FK12"},
341     {XK_Print, NoSymbol, "PRSC"},
342     {XK_Scroll_Lock, NoSymbol, "SCLK"},
343     {XK_Pause, NoSymbol, "PAUS"},
344     {XK_Insert, NoSymbol, "INS\0"},
345     {XK_Home, NoSymbol, "HOME"},
346     {XK_Prior, NoSymbol, "PGUP"},
347     {XK_Delete, NoSymbol, "DELE"},
348     {XK_End, NoSymbol, "END"},
349     {XK_Next, NoSymbol, "PGDN"},
350     {XK_Up, NoSymbol, "UP\0\0"},
351     {XK_Left, NoSymbol, "LEFT"},
352     {XK_Down, NoSymbol, "DOWN"},
353     {XK_Right, NoSymbol, "RGHT"},
354     {XK_Num_Lock, NoSymbol, "NMLK"},
355     {XK_KP_Divide, NoSymbol, "KPDV"},
356     {XK_KP_Multiply, NoSymbol, "KPMU"},
357     {XK_KP_Subtract, NoSymbol, "KPSU"},
358     {NoSymbol, XK_KP_7, "KP7\0"},
359     {NoSymbol, XK_KP_8, "KP8\0"},
360     {NoSymbol, XK_KP_9, "KP9\0"},
361     {XK_KP_Add, NoSymbol, "KPAD"},
362     {NoSymbol, XK_KP_4, "KP4\0"},
363     {NoSymbol, XK_KP_5, "KP5\0"},
364     {NoSymbol, XK_KP_6, "KP6\0"},
365     {NoSymbol, XK_KP_1, "KP1\0"},
366     {NoSymbol, XK_KP_2, "KP2\0"},
367     {NoSymbol, XK_KP_3, "KP3\0"},
368     {XK_KP_Enter, NoSymbol, "KPEN"},
369     {NoSymbol, XK_KP_0, "KP0\0"},
370     {XK_KP_Delete, NoSymbol, "KPDL"},
371     {XK_less, XK_greater, "LSGT"},
372     {XK_KP_Separator, NoSymbol, "KPCO"},
373     {XK_Find, NoSymbol, "FIND"},
374     {NoSymbol, NoSymbol, "\0\0\0\0"}
375 };
376
377 int
378 ComputeKbdDefaults(XkbcDescPtr xkb)
379 {
380     int rtrn;
381     register int i, tmp, nUnknown;
382     KeyNameDesc *name;
383     KeySym *syms;
384
385     if ((xkb->names == NULL) || (xkb->names->keys == NULL))
386     {
387         if ((rtrn = XkbcAllocNames(xkb, XkbKeyNamesMask, 0, 0)) != Success)
388             return rtrn;
389     }
390     for (name = dfltKeys; (name->name[0] != '\0'); name++)
391     {
392         name->used = False;
393     }
394     nUnknown = 0;
395     for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
396     {
397         tmp = XkbKeyNumSyms(xkb, i);
398         if ((xkb->names->keys[i].name[0] == '\0') && (tmp > 0))
399         {
400             tmp = XkbKeyGroupsWidth(xkb, i);
401             syms = XkbKeySymsPtr(xkb, i);
402             for (name = dfltKeys; (name->name[0] != '\0'); name++)
403             {
404                 Bool match = True;
405                 if (((name->level1 != syms[0])
406                      && (name->level1 != NoSymbol))
407                     || ((name->level2 != NoSymbol) && (tmp < 2))
408                     || ((name->level2 != syms[1])
409                         && (name->level2 != NoSymbol)))
410                 {
411                     match = False;
412                 }
413                 if (match)
414                 {
415                     if (!name->used)
416                     {
417                         memcpy(xkb->names->keys[i].name, name->name,
418                                XkbKeyNameLength);
419                         name->used = True;
420                     }
421                     else
422                     {
423                         if (warningLevel > 2)
424                         {
425                             WARN
426                                 ("Several keys match pattern for %s\n",
427                                  XkbcKeyNameText(name->name));
428                             ACTION("Using <U%03d> for key %d\n",
429                                     nUnknown, i);
430                         }
431                         sprintf(xkb->names->keys[i].name, "U%03d",
432                                 nUnknown++);
433                     }
434                     break;
435                 }
436             }
437             if (xkb->names->keys[i].name[0] == '\0')
438             {
439                 if (warningLevel > 2)
440                 {
441                     WARN("Key %d does not match any defaults\n", i);
442                     ACTION("Using name <U%03d>\n", nUnknown);
443                     sprintf(xkb->names->keys[i].name, "U%03d", nUnknown++);
444                 }
445             }
446         }
447     }
448     return Success;
449 }
450
451 /**
452  * Find the key with the given name and return its keycode in kc_rtrn.
453  *
454  * @param name The 4-letter name of the key as a long.
455  * @param kc_rtrn Set to the keycode if the key was found, otherwise 0.
456  * @param use_aliases True if the key aliases should be searched too.
457  * @param create If True and the key is not found, it is added to the
458  *        xkb->names at the first free keycode.
459  * @param start_from Keycode to start searching from.
460  *
461  * @return True if found, False otherwise.
462  */
463 Bool
464 FindNamedKey(XkbcDescPtr xkb,
465              unsigned long name,
466              unsigned int *kc_rtrn,
467              Bool use_aliases, Bool create, int start_from)
468 {
469     register unsigned n;
470
471     if (start_from < xkb->min_key_code)
472     {
473         start_from = xkb->min_key_code;
474     }
475     else if (start_from > xkb->max_key_code)
476     {
477         return False;
478     }
479
480     *kc_rtrn = 0;               /* some callers rely on this */
481     if (xkb && xkb->names && xkb->names->keys)
482     {
483         for (n = start_from; n <= xkb->max_key_code; n++)
484         {
485             unsigned long tmp;
486             tmp = KeyNameToLong(xkb->names->keys[n].name);
487             if (tmp == name)
488             {
489                 *kc_rtrn = n;
490                 return True;
491             }
492         }
493         if (use_aliases)
494         {
495             unsigned long new_name;
496             if (FindKeyNameForAlias(xkb, name, &new_name))
497                 return FindNamedKey(xkb, new_name, kc_rtrn, False, create, 0);
498         }
499     }
500     if (create)
501     {
502         if ((!xkb->names) || (!xkb->names->keys))
503         {
504             if (xkb->min_key_code < XkbMinLegalKeyCode)
505             {
506                 xkb->min_key_code = XkbMinLegalKeyCode;
507                 xkb->max_key_code = XkbMaxLegalKeyCode;
508             }
509             if (XkbcAllocNames(xkb, XkbKeyNamesMask, 0, 0) != Success)
510             {
511                 if (warningLevel > 0)
512                 {
513                     WARN("Couldn't allocate key names in FindNamedKey\n");
514                     ACTION("Key \"%s\" not automatically created\n",
515                             longText(name));
516                 }
517                 return False;
518             }
519         }
520         /* Find first unused keycode and store our key here */
521         for (n = xkb->min_key_code; n <= xkb->max_key_code; n++)
522         {
523             if (xkb->names->keys[n].name[0] == '\0')
524             {
525                 char buf[XkbKeyNameLength + 1];
526                 LongToKeyName(name, buf);
527                 memcpy(xkb->names->keys[n].name, buf, XkbKeyNameLength);
528                 *kc_rtrn = n;
529                 return True;
530             }
531         }
532     }
533     return False;
534 }
535
536 Bool
537 FindKeyNameForAlias(XkbcDescPtr xkb, unsigned long lname,
538                     unsigned long *real_name)
539 {
540     register int i;
541     char name[XkbKeyNameLength + 1];
542
543     if (xkb && xkb->geom && xkb->geom->key_aliases)
544     {
545         XkbKeyAliasPtr a;
546         a = xkb->geom->key_aliases;
547         LongToKeyName(lname, name);
548         name[XkbKeyNameLength] = '\0';
549         for (i = 0; i < xkb->geom->num_key_aliases; i++, a++)
550         {
551             if (strncmp(name, a->alias, XkbKeyNameLength) == 0)
552             {
553                 *real_name = KeyNameToLong(a->real);
554                 return True;
555             }
556         }
557     }
558     if (xkb && xkb->names && xkb->names->key_aliases)
559     {
560         XkbKeyAliasPtr a;
561         a = xkb->names->key_aliases;
562         LongToKeyName(lname, name);
563         name[XkbKeyNameLength] = '\0';
564         for (i = 0; i < xkb->names->num_key_aliases; i++, a++)
565         {
566             if (strncmp(name, a->alias, XkbKeyNameLength) == 0)
567             {
568                 *real_name = KeyNameToLong(a->real);
569                 return True;
570             }
571         }
572     }
573     return False;
574 }