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