Bug Summary

File:geometry.c
Location:line 2583, column 9
Description:Access to field 'sectionRow' results in a dereference of a null pointer (loaded from variable 'key')

Annotated Source Code

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 "tokens.h"
29#include "expr.h"
30#include "vmod.h"
31#include "misc.h"
32#include "indicators.h"
33#include "action.h"
34#include "keycodes.h"
35#include "alias.h"
36
37#include "X11/extensions/XKBgeom.h"
38
39#define DFLT_FONT"helvetica" "helvetica"
40#define DFLT_SLANT"r" "r"
41#define DFLT_WEIGHT"medium" "medium"
42#define DFLT_SET_WIDTH"normal" "normal"
43#define DFLT_VARIANT"" ""
44#define DFLT_ENCODING"iso8859-1" "iso8859-1"
45#define DFLT_SIZE120 120
46
47typedef struct _PropertyInfo
48{
49 CommonInfo defs;
50 char *name;
51 char *value;
52} PropertyInfo;
53
54#define _GSh_Outlines(1<<1) (1<<1)
55#define _GSh_Approx(1<<2) (1<<2)
56#define _GSh_Primary(1<<3) (1<<3)
57typedef struct _ShapeInfo
58{
59 CommonInfo defs;
60 Atom name;
61 short index;
62 unsigned short nOutlines;
63 unsigned short szOutlines;
64 XkbOutlinePtr outlines;
65 XkbOutlinePtr approx;
66 XkbOutlinePtr primary;
67 int dfltCornerRadius;
68} ShapeInfo;
69
70#define shText(d,s)((s)?XkbAtomText((d),(s)->name,3):"default shape") \
71 ((s)?XkbAtomText((d),(s)->name,XkbMessage3):"default shape")
72
73#define _GD_Priority(1<<0) (1<<0)
74#define _GD_Top(1<<1) (1<<1)
75#define _GD_Left(1<<2) (1<<2)
76#define _GD_Angle(1<<3) (1<<3)
77#define _GD_Shape(1<<4) (1<<4)
78#define _GD_FontVariant(1<<4) (1<<4) /* CHEATING */
79#define _GD_Corner(1<<5) (1<<5)
80#define _GD_Width(1<<5) (1<<5) /* CHEATING */
81#define _GD_Color(1<<6) (1<<6)
82#define _GD_OffColor(1<<7) (1<<7)
83#define _GD_Height(1<<7) (1<<7) /* CHEATING */
84#define _GD_Text(1<<8) (1<<8)
85#define _GD_Font(1<<9) (1<<9)
86#define _GD_FontSlant(1<<10) (1<<10)
87#define _GD_FontWeight(1<<11) (1<<11)
88#define _GD_FontSetWidth(1<<12) (1<<12)
89#define _GD_FontSize(1<<13) (1<<13)
90#define _GD_FontEncoding(1<<14) (1<<14)
91#define _GD_FontSpec(1<<15) (1<<15)
92
93
94#define _GD_FontParts((1<<9)|(1<<10)|(1<<11)|(1<<12)|(1<<
13)|(1<<14)|(1<<4))
(_GD_Font(1<<9)|_GD_FontSlant(1<<10)|_GD_FontWeight(1<<11)|_GD_FontSetWidth(1<<12)|_GD_FontSize(1<<13)|_GD_FontEncoding(1<<14)|_GD_FontVariant(1<<4))
95
96typedef struct _DoodadInfo
97{
98 CommonInfo defs;
99 Atom name;
100 unsigned char type;
101 unsigned char priority;
102 short top;
103 short left;
104 short angle;
105 unsigned short corner;
106 unsigned short width;
107 unsigned short height;
108 Atom shape;
109 Atom color;
110 Atom offColor;
111 Atom text;
112 Atom font;
113 Atom fontSlant;
114 Atom fontWeight;
115 Atom fontSetWidth;
116 Atom fontVariant;
117 unsigned short fontSize;
118 Atom fontEncoding;
119 Atom fontSpec;
120 char *logoName;
121 struct _SectionInfo *section;
122} DoodadInfo;
123
124#define Yes1 1
125#define No0 0
126#define Undefined-1 -1
127
128#define _GK_Default(1<<0) (1<<0)
129#define _GK_Name(1<<1) (1<<1)
130#define _GK_Gap(1<<2) (1<<2)
131#define _GK_Shape(1<<3) (1<<3)
132#define _GK_Color(1<<4) (1<<4)
133typedef struct _KeyInfo
134{
135 CommonInfo defs;
136 char name[8];
137 short gap;
138 short index;
139 Atom shape;
140 Atom color;
141 struct _RowInfo *row;
142} KeyInfo;
143#define keyText(k)((k)&&(k)->name[0]?(k)->name:"default") ((k)&&(k)->name[0]?(k)->name:"default")
144
145#define _GR_Default(1<<0) (1<<0)
146#define _GR_Vertical(1<<1) (1<<1)
147#define _GR_Top(1<<2) (1<<2)
148#define _GR_Left(1<<3) (1<<3)
149typedef struct _RowInfo
150{
151 CommonInfo defs;
152 unsigned short top;
153 unsigned short left;
154 short index;
155 Boolint vertical;
156 unsigned short nKeys;
157 KeyInfo *keys;
158 KeyInfo dfltKey;
159 struct _SectionInfo *section;
160} RowInfo;
161#define rowText(d,r)((r)?XkbAtomText((d),(r)->section->name,3):"default") \
162 ((r)?XkbAtomText((d),(r)->section->name,XkbMessage3):"default")
163
164#define _GOK_UnknownRow-1 -1
165typedef struct _OverlayKeyInfo
166{
167 CommonInfo defs;
168 short sectionRow;
169 short overlayRow;
170 char over[XkbKeyNameLength4 + 1];
171 char under[XkbKeyNameLength4 + 1];
172} OverlayKeyInfo;
173
174typedef struct _OverlayInfo
175{
176 CommonInfo defs;
177 Atom name;
178 unsigned short nRows;
179 unsigned short nKeys;
180 OverlayKeyInfo *keys;
181} OverlayInfo;
182
183
184#define _GS_Default(1<<0) (1<<0)
185#define _GS_Name(1<<1) (1<<1)
186#define _GS_Top(1<<2) (1<<2)
187#define _GS_Left(1<<3) (1<<3)
188#define _GS_Width(1<<4) (1<<4)
189#define _GS_Height(1<<5) (1<<5)
190#define _GS_Angle(1<<6) (1<<6)
191#define _GS_Priority(1<<7) (1<<7)
192typedef struct _SectionInfo
193{
194 CommonInfo defs;
195 Atom name;
196 unsigned short top;
197 unsigned short left;
198 unsigned short width;
199 unsigned short height;
200 unsigned short angle;
201 unsigned short nRows;
202 unsigned short nDoodads;
203 unsigned short nOverlays;
204 unsigned char priority;
205 unsigned char nextDoodadPriority;
206 RowInfo *rows;
207 DoodadInfo *doodads;
208 RowInfo dfltRow;
209 DoodadInfo *dfltDoodads;
210 OverlayInfo *overlays;
211 struct _GeometryInfo *geometry;
212} SectionInfo;
213#define scText(d,s)((s)?XkbAtomText((d),(s)->name,3):"default") ((s)?XkbAtomText((d),(s)->name,XkbMessage3):"default")
214
215typedef struct _GeometryInfo
216{
217 char *name;
218 Display *dpy;
219 unsigned fileID;
220 unsigned merge;
221 int errorCount;
222 unsigned nextPriority;
223 int nProps;
224 int nShapes;
225 int nSections;
226 int nDoodads;
227 PropertyInfo *props;
228 ShapeInfo *shapes;
229 SectionInfo *sections;
230 DoodadInfo *doodads;
231 int widthMM;
232 int heightMM;
233 Atom font;
234 Atom fontSlant;
235 Atom fontWeight;
236 Atom fontSetWidth;
237 Atom fontVariant;
238 unsigned fontSize;
239 Atom fontEncoding;
240 Atom fontSpec;
241 Atom baseColor;
242 Atom labelColor;
243 int dfltCornerRadius;
244 SectionInfo dfltSection;
245 DoodadInfo *dfltDoodads;
246 AliasInfo *aliases;
247} GeometryInfo;
248
249static char *
250ddText(Display * dpy, DoodadInfo * di)
251{
252 static char buf[64];
253
254 if (di == NULL((void*)0))
255 {
256 strcpy(buf, "default");
257 return buf;
258 }
259 if (di->section)
260 {
261 sprintf(buf, "%s in section %s",
262 XkbAtomText(dpy, di->name, XkbMessage3), scText(dpy,((di->section)?XkbAtomText((dpy),(di->section)->name
,3):"default")
263 di->section)((di->section)?XkbAtomText((dpy),(di->section)->name
,3):"default")
);
264 return buf;
265 }
266 return XkbAtomText(dpy, di->name, XkbMessage3);
267}
268
269/***====================================================================***/
270
271static void
272InitPropertyInfo(PropertyInfo * pi, GeometryInfo * info)
273{
274 pi->defs.defined = 0;
275 pi->defs.fileID = info->fileID;
276 pi->defs.merge = info->merge;
277 pi->name = pi->value = NULL((void*)0);
278 return;
279}
280
281static void
282FreeProperties(PropertyInfo * pi, GeometryInfo * info)
283{
284 PropertyInfo *tmp;
285 PropertyInfo *next;
286
287 if (info->props == pi)
288 {
289 info->props = NULL((void*)0);
290 info->nProps = 0;
291 }
292 for (tmp = pi; tmp != NULL((void*)0); tmp = next)
293 {
294 if (tmp->name)
295 uFree(tmp->name);
296 if (tmp->value)
297 uFree(tmp->value);
298 tmp->name = tmp->value = NULL((void*)0);
299 next = (PropertyInfo *) tmp->defs.next;
300 uFree(tmp);
301 }
302 return;
303}
304
305static void
306InitKeyInfo(KeyInfo * key, RowInfo * row, GeometryInfo * info)
307{
308
309 if (key != &row->dfltKey)
310 {
311 *key = row->dfltKey;
312 strcpy(key->name, "unknown");
313 key->defs.defined &= ~_GK_Default(1<<0);
314 }
315 else
316 {
317 bzero(key, sizeof(KeyInfo))memset(key,0,sizeof(KeyInfo));
318 strcpy(key->name, "default");
319 key->defs.defined = _GK_Default(1<<0);
320 key->defs.fileID = info->fileID;
321 key->defs.merge = info->merge;
322 key->defs.next = NULL((void*)0);
323 key->row = row;
324 }
325 return;
326}
327
328static void
329ClearKeyInfo(KeyInfo * key)
330{
331 key->defs.defined &= ~_GK_Default(1<<0);
332 strcpy(key->name, "default");
333 key->gap = 0;
334 key->shape = None0L;
335 key->color = None0L;
336 return;
337}
338
339static void
340FreeKeys(KeyInfo * key, RowInfo * row, GeometryInfo * info)
341{
342 KeyInfo *tmp;
343 KeyInfo *next;
344
345 if (row->keys == key)
346 {
347 row->nKeys = 0;
348 row->keys = NULL((void*)0);
349 }
350 for (tmp = key; tmp != NULL((void*)0); tmp = next)
351 {
352 ClearKeyInfo(tmp);
353 next = (KeyInfo *) tmp->defs.next;
354 uFree(tmp);
355 }
356 return;
357}
358
359static void
360InitRowInfo(RowInfo * row, SectionInfo * section, GeometryInfo * info)
361{
362 if (row != &section->dfltRow)
363 {
364 *row = section->dfltRow;
365 row->defs.defined &= ~_GR_Default(1<<0);
366 }
367 else
368 {
369 bzero(row, sizeof(*row))memset(row,0,sizeof(*row));
370 row->defs.defined = _GR_Default(1<<0);
371 row->defs.fileID = info->fileID;
372 row->defs.merge = info->merge;
373 row->defs.next = NULL((void*)0);
374 row->section = section;
375 row->nKeys = 0;
376 row->keys = NULL((void*)0);
377 InitKeyInfo(&row->dfltKey, row, info);
378 }
379 return;
380}
381
382static void
383ClearRowInfo(RowInfo * row, GeometryInfo * info)
384{
385 row->defs.defined &= ~_GR_Default(1<<0);
386 row->top = row->left = 0;
387 row->vertical = False0;
388 row->nKeys = 0;
389 if (row->keys)
390 FreeKeys(row->keys, row, info);
391 ClearKeyInfo(&row->dfltKey);
392 row->dfltKey.defs.defined |= _GK_Default(1<<0);
393 return;
394}
395
396static void
397FreeRows(RowInfo * row, SectionInfo * section, GeometryInfo * info)
398{
399 RowInfo *next;
400 RowInfo *tmp;
401
402 if (row == section->rows)
403 {
404 section->nRows = 0;
405 section->rows = NULL((void*)0);
406 }
407 for (tmp = row; tmp != NULL((void*)0); tmp = next)
408 {
409 ClearRowInfo(tmp, info);
410 next = (RowInfo *) tmp->defs.next;
411 uFree(tmp);
412 }
413 return;
414}
415
416static DoodadInfo *
417FindDoodadByType(DoodadInfo * di, unsigned type)
418{
419 while (di)
420 {
421 if (di->type == type)
422 return di;
423 di = (DoodadInfo *) di->defs.next;
424 }
425 return NULL((void*)0);
426}
427
428static DoodadInfo *
429FindDoodadByName(DoodadInfo * di, Atom name)
430{
431 while (di)
432 {
433 if (di->name == name)
434 return di;
435 di = (DoodadInfo *) di->defs.next;
436 }
437 return NULL((void*)0);
438}
439
440static void
441InitDoodadInfo(DoodadInfo * di, unsigned type, SectionInfo * si,
442 GeometryInfo * info)
443{
444 DoodadInfo *dflt;
445
446 dflt = NULL((void*)0);
447 if (si && si->dfltDoodads)
448 dflt = FindDoodadByType(si->dfltDoodads, type);
449 if ((dflt == NULL((void*)0)) && (info->dfltDoodads))
450 dflt = FindDoodadByType(info->dfltDoodads, type);
451 if (dflt != NULL((void*)0))
452 {
453 *di = *dflt;
454 di->defs.next = NULL((void*)0);
455 }
456 else
457 {
458 bzero(di, sizeof(DoodadInfo))memset(di,0,sizeof(DoodadInfo));
459 di->defs.fileID = info->fileID;
460 di->type = type;
461 }
462 di->section = si;
463 if (si != NULL((void*)0))
464 {
465 di->priority = si->nextDoodadPriority++;
466#if XkbGeomMaxPriority255 < 255
467 if (si->nextDoodadPriority > XkbGeomMaxPriority255)
468 si->nextDoodadPriority = XkbGeomMaxPriority255;
469#endif
470 }
471 else
472 {
473 di->priority = info->nextPriority++;
474 if (info->nextPriority > XkbGeomMaxPriority255)
475 info->nextPriority = XkbGeomMaxPriority255;
476 }
477 return;
478}
479
480static void
481ClearDoodadInfo(DoodadInfo * di)
482{
483 CommonInfo defs;
484
485 defs = di->defs;
486 bzero(di, sizeof(DoodadInfo))memset(di,0,sizeof(DoodadInfo));
487 di->defs = defs;
488 di->defs.defined = 0;
489 return;
490}
491
492static void
493ClearOverlayInfo(OverlayInfo * ol)
494{
495 if (ol && ol->keys)
496 {
497 ol->keys = (OverlayKeyInfo *) ClearCommonInfo(&ol->keys->defs);
498 ol->nKeys = 0;
499 }
500 return;
501}
502
503static void
504FreeDoodads(DoodadInfo * di, SectionInfo * si, GeometryInfo * info)
505{
506 DoodadInfo *tmp;
507 DoodadInfo *next;
508
509 if (si)
510 {
511 if (si->doodads == di)
512 {
513 si->doodads = NULL((void*)0);
514 si->nDoodads = 0;
515 }
516 if (si->dfltDoodads == di)
517 si->dfltDoodads = NULL((void*)0);
518 }
519 if (info->doodads == di)
520 {
521 info->doodads = NULL((void*)0);
522 info->nDoodads = 0;
523 }
524 if (info->dfltDoodads == di)
525 info->dfltDoodads = NULL((void*)0);
526 for (tmp = di; tmp != NULL((void*)0); tmp = next)
527 {
528 next = (DoodadInfo *) tmp->defs.next;
529 ClearDoodadInfo(tmp);
530 uFree(tmp);
531 }
532 return;
533}
534
535static void
536InitSectionInfo(SectionInfo * si, GeometryInfo * info)
537{
538 if (si != &info->dfltSection)
539 {
540 *si = info->dfltSection;
541 si->defs.defined &= ~_GS_Default(1<<0);
542 si->name = XkbInternAtom(info->dpy, "unknown", False0);
543 si->priority = info->nextPriority++;
544 if (info->nextPriority > XkbGeomMaxPriority255)
545 info->nextPriority = XkbGeomMaxPriority255;
546 }
547 else
548 {
549 bzero(si, sizeof(SectionInfo))memset(si,0,sizeof(SectionInfo));
550 si->defs.fileID = info->fileID;
551 si->defs.merge = info->merge;
552 si->defs.next = NULL((void*)0);
553 si->geometry = info;
554 si->name = XkbInternAtom(info->dpy, "default", False0);
555 InitRowInfo(&si->dfltRow, si, info);
556 }
557 return;
558}
559
560static void
561DupSectionInfo(SectionInfo * into, SectionInfo * from, GeometryInfo * info)
562{
563 CommonInfo defs;
564
565 defs = into->defs;
566 *into = *from;
567 into->defs.fileID = defs.fileID;
568 into->defs.merge = defs.merge;
569 into->defs.next = NULL((void*)0);
570 into->dfltRow.defs.fileID = defs.fileID;
571 into->dfltRow.defs.merge = defs.merge;
572 into->dfltRow.defs.next = NULL((void*)0);
573 into->dfltRow.section = into;
574 into->dfltRow.dfltKey.defs.fileID = defs.fileID;
575 into->dfltRow.dfltKey.defs.merge = defs.merge;
576 into->dfltRow.dfltKey.defs.next = NULL((void*)0);
577 into->dfltRow.dfltKey.row = &into->dfltRow;
578 return;
579}
580
581static void
582ClearSectionInfo(SectionInfo * si, GeometryInfo * info)
583{
584
585 si->defs.defined &= ~_GS_Default(1<<0);
586 si->name = XkbInternAtom(info->dpy, "default", False0);
587 si->top = si->left = 0;
588 si->width = si->height = 0;
589 si->angle = 0;
590 if (si->rows)
591 {
592 FreeRows(si->rows, si, info);
593 si->rows = NULL((void*)0);
594 }
595 ClearRowInfo(&si->dfltRow, info);
596 if (si->doodads)
597 {
598 FreeDoodads(si->doodads, si, info);
599 si->doodads = NULL((void*)0);
600 }
601 si->dfltRow.defs.defined = _GR_Default(1<<0);
602 return;
603}
604
605static void
606FreeSections(SectionInfo * si, GeometryInfo * info)
607{
608 SectionInfo *tmp;
609 SectionInfo *next;
610
611 if (si == info->sections)
612 {
613 info->nSections = 0;
614 info->sections = NULL((void*)0);
615 }
616 for (tmp = si; tmp != NULL((void*)0); tmp = next)
617 {
618 ClearSectionInfo(tmp, info);
619 next = (SectionInfo *) tmp->defs.next;
620 uFree(tmp);
621 }
622 return;
623}
624
625static void
626FreeShapes(ShapeInfo * si, GeometryInfo * info)
627{
628 ShapeInfo *tmp;
629 ShapeInfo *next;
630
631 if (si == info->shapes)
632 {
633 info->nShapes = 0;
634 info->shapes = NULL((void*)0);
635 }
636 for (tmp = si; tmp != NULL((void*)0); tmp = next)
637 {
638 if (tmp->outlines)
639 {
640 register int i;
641 for (i = 0; i < tmp->nOutlines; i++)
642 {
643 if (tmp->outlines[i].points != NULL((void*)0))
644 {
645 uFree(tmp->outlines[i].points);
646 tmp->outlines[i].num_points = 0;
647 tmp->outlines[i].points = NULL((void*)0);
648 }
649 }
650 uFree(tmp->outlines);
651 tmp->szOutlines = 0;
652 tmp->nOutlines = 0;
653 tmp->outlines = NULL((void*)0);
654 tmp->primary = tmp->approx = NULL((void*)0);
655 }
656 next = (ShapeInfo *) tmp->defs.next;
657 uFree(tmp);
658 }
659 return;
660}
661
662/***====================================================================***/
663
664static void
665InitGeometryInfo(GeometryInfo * info, unsigned fileID, unsigned merge)
666{
667 bzero(info, sizeof(GeometryInfo))memset(info,0,sizeof(GeometryInfo));
668 info->fileID = fileID;
669 info->merge = merge;
670 InitSectionInfo(&info->dfltSection, info);
671 info->dfltSection.defs.defined = _GS_Default(1<<0);
672 return;
673}
674
675static void
676ClearGeometryInfo(GeometryInfo * info)
677{
678 if (info->name)
679 uFree(info->name);
680 info->name = NULL((void*)0);
681 if (info->props)
682 FreeProperties(info->props, info);
683 if (info->shapes)
684 FreeShapes(info->shapes, info);
685 if (info->sections)
686 FreeSections(info->sections, info);
687 info->widthMM = 0;
688 info->heightMM = 0;
689 info->dfltCornerRadius = 0;
690 ClearSectionInfo(&info->dfltSection, info);
691 info->dfltSection.defs.defined = _GS_Default(1<<0);
692 if (info->aliases)
693 ClearAliases(&info->aliases);
694 return;
695}
696
697/***====================================================================***/
698
699static PropertyInfo *
700NextProperty(GeometryInfo * info)
701{
702 PropertyInfo *pi;
703
704 pi = uTypedAlloc(PropertyInfo)((PropertyInfo *)uAlloc((unsigned)sizeof(PropertyInfo)));
705 if (pi)
706 {
707 bzero((char *) pi, sizeof(PropertyInfo))memset((char *) pi,0,sizeof(PropertyInfo));
708 info->props = (PropertyInfo *) AddCommonInfo(&info->props->defs,
709 (CommonInfo *) pi);
710 info->nProps++;
711 }
712 return pi;
713}
714
715static PropertyInfo *
716FindProperty(GeometryInfo * info, char *name)
717{
718 PropertyInfo *old;
719
720 if (!name)
721 return NULL((void*)0);
722 for (old = info->props; old != NULL((void*)0);
723 old = (PropertyInfo *) old->defs.next)
724 {
725 if ((old->name) && (uStringEqual(name, old->name)((((name)==((char *)((void*)0))||(old->name)==((char *)((void
*)0)))? (name)!=(old->name):strcmp(name,old->name))==((
Comparison)0))
))
726 return old;
727 }
728 return NULL((void*)0);
729}
730
731static Boolint
732AddProperty(GeometryInfo * info, PropertyInfo * new)
733{
734 PropertyInfo *old;
735
736 if ((!new) || (!new->value) || (!new->name))
737 return False0;
738 old = FindProperty(info, new->name);
739 if (old != NULL((void*)0))
740 {
741 if ((new->defs.merge == MergeReplace3)
742 || (new->defs.merge == MergeOverride2))
743 {
744 if (((old->defs.fileID == new->defs.fileID)
745 && (warningLevel > 0)) || (warningLevel > 9))
746 {
747 WARN1uWarning("Multiple definitions for the \"%s\" property\n",
748 new->name);
749 ACTION2uAction("Ignoring \"%s\", using \"%s\"\n", old->value,
750 new->value);
751 }
752 if (old->value)
753 uFree(old->value);
754 old->value = uStringDup(new->value)((new->value) ? strdup(new->value) : ((void*)0));
755 return True1;
756 }
757 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
758 || (warningLevel > 9))
759 {
760 WARN1uWarning("Multiple definitions for \"%s\" property\n", new->name);
761 ACTION2uAction("Using \"%s\", ignoring \"%s\" \n", old->value,
762 new->value);
763 }
764 return True1;
765 }
766 old = new;
767 if ((new = NextProperty(info)) == NULL((void*)0))
768 return False0;
769 new->defs.next = NULL((void*)0);
770 new->name = uStringDup(old->name)((old->name) ? strdup(old->name) : ((void*)0));
771 new->value = uStringDup(old->value)((old->value) ? strdup(old->value) : ((void*)0));
772 return True1;
773}
774
775/***====================================================================***/
776
777static ShapeInfo *
778NextShape(GeometryInfo * info)
779{
780 ShapeInfo *si;
781
782 si = uTypedAlloc(ShapeInfo)((ShapeInfo *)uAlloc((unsigned)sizeof(ShapeInfo)));
783 if (si)
784 {
785 bzero((char *) si, sizeof(ShapeInfo))memset((char *) si,0,sizeof(ShapeInfo));
786 info->shapes = (ShapeInfo *) AddCommonInfo(&info->shapes->defs,
787 (CommonInfo *) si);
788 info->nShapes++;
789 si->dfltCornerRadius = info->dfltCornerRadius;
790 }
791 return si;
792}
793
794static ShapeInfo *
795FindShape(GeometryInfo * info, Atom name, const char *type, const char *which)
796{
797 ShapeInfo *old;
798
799 for (old = info->shapes; old != NULL((void*)0); old = (ShapeInfo *) old->defs.next)
800 {
801 if (name == old->name)
802 return old;
803 }
804 if (type != NULL((void*)0))
805 {
806 old = info->shapes;
807 WARN3uWarning("Unknown shape \"%s\" for %s %s\n",
808 XkbAtomText(info->dpy, name, XkbMessage3), type, which);
809 if (old)
810 {
811 ACTION1uAction("Using default shape %s instead\n",
812 shText(info->dpy, old)((old)?XkbAtomText((info->dpy),(old)->name,3):"default shape"
)
);
813 return old;
814 }
815 ACTIONuAction("No default shape; definition ignored\n");
816 return NULL((void*)0);
817 }
818 return NULL((void*)0);
819}
820
821static Boolint
822AddShape(GeometryInfo * info, ShapeInfo * new)
823{
824 ShapeInfo *old;
825
826 old = FindShape(info, new->name, NULL((void*)0), NULL((void*)0));
827 if (old != NULL((void*)0))
828 {
829 if ((new->defs.merge == MergeReplace3)
830 || (new->defs.merge == MergeOverride2))
831 {
832 ShapeInfo *next = (ShapeInfo *) old->defs.next;
833 if (((old->defs.fileID == new->defs.fileID)
834 && (warningLevel > 0)) || (warningLevel > 9))
835 {
836 WARN1uWarning("Duplicate shape name \"%s\"\n",
837 shText(info->dpy, old)((old)?XkbAtomText((info->dpy),(old)->name,3):"default shape"
)
);
838 ACTIONuAction("Using last definition\n");
839 }
840 *old = *new;
841 old->defs.next = &next->defs;
842 return True1;
843 }
844 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
845 || (warningLevel > 9))
846 {
847 WARN1uWarning("Multiple shapes named \"%s\"\n", shText(info->dpy, old)((old)?XkbAtomText((info->dpy),(old)->name,3):"default shape"
)
);
848 ACTIONuAction("Using first definition\n");
849 }
850 return True1;
851 }
852 old = new;
853 if ((new = NextShape(info)) == NULL((void*)0))
854 return False0;
855 *new = *old;
856 new->defs.next = NULL((void*)0);
857 old->szOutlines = old->nOutlines = 0;
858 old->outlines = NULL((void*)0);
859 old->approx = NULL((void*)0);
860 old->primary = NULL((void*)0);
861 return True1;
862}
863
864/***====================================================================***/
865
866static void
867ReplaceDoodad(DoodadInfo * into, DoodadInfo * from)
868{
869 CommonInfo *next;
870
871 next = into->defs.next;
872 ClearDoodadInfo(into);
873 *into = *from;
874 into->defs.next = next;
875 next = from->defs.next;
876 ClearDoodadInfo(from);
877 from->defs.next = next;
878 return;
879}
880
881static DoodadInfo *
882NextDfltDoodad(SectionInfo * si, GeometryInfo * info)
883{
884 DoodadInfo *di;
885
886 di = uTypedCalloc(1, DoodadInfo)((DoodadInfo *)uCalloc((unsigned)1,(unsigned)sizeof(DoodadInfo
)))
;
887 if (!di)
888 return NULL((void*)0);
889 if (si)
890 {
891 si->dfltDoodads =
892 (DoodadInfo *) AddCommonInfo(&si->dfltDoodads->defs,
893 (CommonInfo *) di);
894 }
895 else
896 {
897 info->dfltDoodads =
898 (DoodadInfo *) AddCommonInfo(&info->dfltDoodads->defs,
899 (CommonInfo *) di);
900 }
901 return di;
902}
903
904static DoodadInfo *
905NextDoodad(SectionInfo * si, GeometryInfo * info)
906{
907 DoodadInfo *di;
908
909 di = uTypedCalloc(1, DoodadInfo)((DoodadInfo *)uCalloc((unsigned)1,(unsigned)sizeof(DoodadInfo
)))
;
910 if (di)
911 {
912 if (si)
913 {
914 si->doodads = (DoodadInfo *) AddCommonInfo(&si->doodads->defs,
915 (CommonInfo *) di);
916 si->nDoodads++;
917 }
918 else
919 {
920 info->doodads =
921 (DoodadInfo *) AddCommonInfo(&info->doodads->defs,
922 (CommonInfo *) di);
923 info->nDoodads++;
924 }
925 }
926 return di;
927}
928
929static Boolint
930AddDoodad(SectionInfo * si, GeometryInfo * info, DoodadInfo * new)
931{
932 DoodadInfo *old;
933
934 old = FindDoodadByName((si ? si->doodads : info->doodads), new->name);
935 if (old != NULL((void*)0))
936 {
937 if ((new->defs.merge == MergeReplace3)
938 || (new->defs.merge == MergeOverride2))
939 {
940 if (((old->defs.fileID == new->defs.fileID)
941 && (warningLevel > 0)) || (warningLevel > 9))
942 {
943 WARN1uWarning("Multiple doodads named \"%s\"\n",
944 XkbAtomText(info->dpy, old->name, XkbMessage3));
945 ACTIONuAction("Using last definition\n");
946 }
947 ReplaceDoodad(old, new);
948 old->section = si;
949 return True1;
950 }
951 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
952 || (warningLevel > 9))
953 {
954 WARN1uWarning("Multiple doodads named \"%s\"\n",
955 XkbAtomText(info->dpy, old->name, XkbMessage3));
956 ACTIONuAction("Using first definition\n");
957 }
958 return True1;
959 }
960 old = new;
961 if ((new = NextDoodad(si, info)) == NULL((void*)0))
962 return False0;
963 ReplaceDoodad(new, old);
964 new->section = si;
965 new->defs.next = NULL((void*)0);
966 return True1;
967}
968
969static DoodadInfo *
970FindDfltDoodadByTypeName(char *name, SectionInfo * si, GeometryInfo * info)
971{
972 DoodadInfo *dflt;
973 unsigned type;
974
975 if (uStrCaseCmp(name, "outline")(strcasecmp(name,"outline")) == 0)
976 type = XkbOutlineDoodad1;
977 else if (uStrCaseCmp(name, "solid")(strcasecmp(name,"solid")) == 0)
978 type = XkbSolidDoodad2;
979 else if (uStrCaseCmp(name, "text")(strcasecmp(name,"text")) == 0)
980 type = XkbTextDoodad3;
981 else if (uStrCaseCmp(name, "indicator")(strcasecmp(name,"indicator")) == 0)
982 type = XkbIndicatorDoodad4;
983 else if (uStrCaseCmp(name, "logo")(strcasecmp(name,"logo")) == 0)
984 type = XkbLogoDoodad5;
985 else
986 return NULL((void*)0);
987 if ((si) && (si->dfltDoodads))
988 dflt = FindDoodadByType(si->dfltDoodads, type);
989 else
990 dflt = NULL((void*)0);
991 if ((!dflt) && (info->dfltDoodads))
992 dflt = FindDoodadByType(info->dfltDoodads, type);
993 if (dflt == NULL((void*)0))
994 {
995 dflt = NextDfltDoodad(si, info);
996 if (dflt != NULL((void*)0))
997 {
998 dflt->name = None0L;
999 dflt->type = type;
1000 }
1001 }
1002 return dflt;
1003}
1004
1005/***====================================================================***/
1006
1007static Boolint
1008AddOverlay(SectionInfo * si, GeometryInfo * info, OverlayInfo * new)
1009{
1010 OverlayInfo *old;
1011
1012 for (old = si->overlays; old != NULL((void*)0);
1013 old = (OverlayInfo *) old->defs.next)
1014 {
1015 if (old->name == new->name)
1016 break;
1017 }
1018 if (old != NULL((void*)0))
1019 {
1020 if ((new->defs.merge == MergeReplace3)
1021 || (new->defs.merge == MergeOverride2))
1022 {
1023 if (((old->defs.fileID == new->defs.fileID)
1024 && (warningLevel > 0)) || (warningLevel > 9))
1025 {
1026 WARN2uWarning
1027 ("Multiple overlays named \"%s\" for section \"%s\"\n",
1028 XkbAtomText(info->dpy, old->name, XkbMessage3),
1029 XkbAtomText(info->dpy, si->name, XkbMessage3));
1030 ACTIONuAction("Using last definition\n");
1031 }
1032 ClearOverlayInfo(old);
1033 old->nKeys = new->nKeys;
1034 old->keys = new->keys;
1035 new->nKeys = 0;
1036 new->keys = NULL((void*)0);
1037 return True1;
1038 }
1039 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
1040 || (warningLevel > 9))
1041 {
1042 WARN2uWarning("Multiple doodads named \"%s\" in section \"%s\"\n",
1043 XkbAtomText(info->dpy, old->name, XkbMessage3),
1044 XkbAtomText(info->dpy, si->name, XkbMessage3));
1045 ACTIONuAction("Using first definition\n");
1046 }
1047 return True1;
1048 }
1049 old = new;
1050 new = uTypedCalloc(1, OverlayInfo)((OverlayInfo *)uCalloc((unsigned)1,(unsigned)sizeof(OverlayInfo
)))
;
1051 if (!new)
1052 {
1053 if (warningLevel > 0)
1054 {
1055 WSGOuInternalError("Couldn't allocate a new OverlayInfo\n");
1056 ACTION2uAction
1057 ("Overlay \"%s\" in section \"%s\" will be incomplete\n",
1058 XkbAtomText(info->dpy, old->name, XkbMessage3),
1059 XkbAtomText(info->dpy, si->name, XkbMessage3));
1060 }
1061 return False0;
1062 }
1063 *new = *old;
1064 old->nKeys = 0;
1065 old->keys = NULL((void*)0);
1066 si->overlays = (OverlayInfo *) AddCommonInfo(&si->overlays->defs,
1067 (CommonInfo *) new);
1068 si->nOverlays++;
1069 return True1;
1070}
1071
1072/***====================================================================***/
1073
1074static SectionInfo *
1075NextSection(GeometryInfo * info)
1076{
1077 SectionInfo *si;
1078
1079 si = uTypedAlloc(SectionInfo)((SectionInfo *)uAlloc((unsigned)sizeof(SectionInfo)));
1080 if (si)
1081 {
1082 *si = info->dfltSection;
1083 si->defs.defined &= ~_GS_Default(1<<0);
1084 si->defs.next = NULL((void*)0);
1085 si->nRows = 0;
1086 si->rows = NULL((void*)0);
1087 info->sections =
1088 (SectionInfo *) AddCommonInfo(&info->sections->defs,
1089 (CommonInfo *) si);
1090 info->nSections++;
1091 }
1092 return si;
1093}
1094
1095static SectionInfo *
1096FindMatchingSection(GeometryInfo * info, SectionInfo * new)
1097{
1098 SectionInfo *old;
1099
1100 for (old = info->sections; old != NULL((void*)0);
1101 old = (SectionInfo *) old->defs.next)
1102 {
1103 if (new->name == old->name)
1104 return old;
1105 }
1106 return NULL((void*)0);
1107}
1108
1109static Boolint
1110AddSection(GeometryInfo * info, SectionInfo * new)
1111{
1112 SectionInfo *old;
1113
1114 old = FindMatchingSection(info, new);
1115 if (old != NULL((void*)0))
1116 {
1117#ifdef NOTDEF
1118 if ((new->defs.merge == MergeReplace3)
1119 || (new->defs.merge == MergeOverride2))
1120 {
1121 SectionInfo *next = (SectionInfo *) old->defs.next;
1122 if (((old->defs.fileID == new->defs.fileID)
1123 && (warningLevel > 0)) || (warningLevel > 9))
1124 {
1125 WARN1uWarning("Duplicate shape name \"%s\"\n",
1126 shText(info->dpy, old)((old)?XkbAtomText((info->dpy),(old)->name,3):"default shape"
)
);
1127 ACTIONuAction("Using last definition\n");
1128 }
1129 *old = *new;
1130 old->defs.next = &next->defs;
1131 return True1;
1132 }
1133 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
1134 || (warningLevel > 9))
1135 {
1136 WARN1uWarning("Multiple shapes named \"%s\"\n", shText(info->dpy, old)((old)?XkbAtomText((info->dpy),(old)->name,3):"default shape"
)
);
1137 ACTIONuAction("Using first definition\n");
1138 }
1139 return True1;
1140#else
1141 WARNuWarning("Don't know how to merge sections yet\n");
1142#endif
1143 }
1144 old = new;
1145 if ((new = NextSection(info)) == NULL((void*)0))
1146 return False0;
1147 *new = *old;
1148 new->defs.next = NULL((void*)0);
1149 old->nRows = old->nDoodads = old->nOverlays = 0;
1150 old->rows = NULL((void*)0);
1151 old->doodads = NULL((void*)0);
1152 old->overlays = NULL((void*)0);
1153 if (new->doodads)
1154 {
1155 DoodadInfo *di;
1156 for (di = new->doodads; di; di = (DoodadInfo *) di->defs.next)
1157 {
1158 di->section = new;
1159 }
1160 }
1161 return True1;
1162}
1163
1164/***====================================================================***/
1165
1166static RowInfo *
1167NextRow(SectionInfo * si)
1168{
1169 RowInfo *row;
1170
1171 row = uTypedAlloc(RowInfo)((RowInfo *)uAlloc((unsigned)sizeof(RowInfo)));
1172 if (row)
1173 {
1174 *row = si->dfltRow;
1175 row->defs.defined &= ~_GR_Default(1<<0);
1176 row->defs.next = NULL((void*)0);
1177 row->nKeys = 0;
1178 row->keys = NULL((void*)0);
1179 si->rows =
1180 (RowInfo *) AddCommonInfo(&si->rows->defs, (CommonInfo *) row);
1181 row->index = si->nRows++;
1182 }
1183 return row;
1184}
1185
1186static Boolint
1187AddRow(SectionInfo * si, RowInfo * new)
1188{
1189 RowInfo *old;
1190
1191 old = new;
1192 if ((new = NextRow(si)) == NULL((void*)0))
1193 return False0;
1194 *new = *old;
1195 new->defs.next = NULL((void*)0);
1196 old->nKeys = 0;
1197 old->keys = NULL((void*)0);
1198 return True1;
1199}
1200
1201/***====================================================================***/
1202
1203static KeyInfo *
1204NextKey(RowInfo * row)
1205{
1206 KeyInfo *key;
1207
1208 key = uTypedAlloc(KeyInfo)((KeyInfo *)uAlloc((unsigned)sizeof(KeyInfo)));
1209 if (key)
1210 {
1211 *key = row->dfltKey;
1212 key->defs.defined &= ~_GK_Default(1<<0);
1213 key->defs.next = NULL((void*)0);
1214 key->index = row->nKeys++;
1215 }
1216 return key;
1217}
1218
1219static Boolint
1220AddKey(RowInfo * row, KeyInfo * new)
1221{
1222 KeyInfo *old;
1223
1224 old = new;
1225 if ((new = NextKey(row)) == NULL((void*)0))
1226 return False0;
1227 *new = *old;
1228 new->defs.next = NULL((void*)0);
1229 row->keys =
1230 (KeyInfo *) AddCommonInfo(&row->keys->defs, (CommonInfo *) new);
1231 return True1;
1232}
1233
1234/***====================================================================***/
1235
1236static void
1237MergeIncludedGeometry(GeometryInfo * into, GeometryInfo * from,
1238 unsigned merge)
1239{
1240 Boolint clobber;
1241
1242 if (from->errorCount > 0)
1243 {
1244 into->errorCount += from->errorCount;
1245 return;
1246 }
1247 clobber = (merge == MergeOverride2) || (merge == MergeReplace3);
1248 if (into->name == NULL((void*)0))
1249 {
1250 into->name = from->name;
1251 from->name = NULL((void*)0);
1252 }
1253 if ((into->widthMM == 0) || ((from->widthMM != 0) && clobber))
1254 into->widthMM = from->widthMM;
1255 if ((into->heightMM == 0) || ((from->heightMM != 0) && clobber))
1256 into->heightMM = from->heightMM;
1257 if ((into->font == None0L) || ((from->font != None0L) && clobber))
1258 into->font = from->font;
1259 if ((into->fontSlant == None0L) || ((from->fontSlant != None0L) && clobber))
1260 into->fontSlant = from->fontSlant;
1261 if ((into->fontWeight == None0L) || ((from->fontWeight != None0L) && clobber))
1262 into->fontWeight = from->fontWeight;
1263 if ((into->fontSetWidth == None0L)
1264 || ((from->fontSetWidth != None0L) && clobber))
1265 into->fontSetWidth = from->fontSetWidth;
1266 if ((into->fontVariant == None0L)
1267 || ((from->fontVariant != None0L) && clobber))
1268 into->fontVariant = from->fontVariant;
1269 if ((into->fontSize == 0) || ((from->fontSize != 0) && clobber))
1270 into->fontSize = from->fontSize;
1271 if ((into->fontEncoding == None0L)
1272 || ((from->fontEncoding != None0L) && clobber))
1273 into->fontEncoding = from->fontEncoding;
1274 if ((into->fontSpec == None0L) || ((from->fontSpec != None0L) && clobber))
1275 into->fontSpec = from->fontSpec;
1276 if ((into->baseColor == None0L) || ((from->baseColor != None0L) && clobber))
1277 into->baseColor = from->baseColor;
1278 if ((into->labelColor == None0L) || ((from->labelColor != None0L) && clobber))
1279 into->labelColor = from->labelColor;
1280 into->nextPriority = from->nextPriority;
1281 if (from->props != NULL((void*)0))
1282 {
1283 PropertyInfo *pi;
1284 for (pi = from->props; pi; pi = (PropertyInfo *) pi->defs.next)
1285 {
1286 if (!AddProperty(into, pi))
1287 into->errorCount++;
1288 }
1289 }
1290 if (from->shapes != NULL((void*)0))
1291 {
1292 ShapeInfo *si;
1293
1294 for (si = from->shapes; si; si = (ShapeInfo *) si->defs.next)
1295 {
1296 if (!AddShape(into, si))
1297 into->errorCount++;
1298 }
1299 }
1300 if (from->sections != NULL((void*)0))
1301 {
1302 SectionInfo *si;
1303
1304 for (si = from->sections; si; si = (SectionInfo *) si->defs.next)
1305 {
1306 if (!AddSection(into, si))
1307 into->errorCount++;
1308 }
1309 }
1310 if (from->doodads != NULL((void*)0))
1311 {
1312 DoodadInfo *di;
1313
1314 for (di = from->doodads; di; di = (DoodadInfo *) di->defs.next)
1315 {
1316 if (!AddDoodad(NULL((void*)0), into, di))
1317 into->errorCount++;
1318 }
1319 }
1320 if (!MergeAliases(&into->aliases, &from->aliases, merge))
1321 into->errorCount++;
1322 return;
1323}
1324
1325typedef void (*FileHandler) (XkbFile * /* file */ ,
1326 XkbDescPtr /* xkb */ ,
1327 unsigned /* merge */ ,
1328 GeometryInfo * /* info */
1329 );
1330
1331static Boolint
1332HandleIncludeGeometry(IncludeStmt * stmt, XkbDescPtr xkb, GeometryInfo * info,
1333 FileHandler hndlr)
1334{
1335 unsigned newMerge;
1336 XkbFile *rtrn;
1337 GeometryInfo included;
1338 Boolint haveSelf;
1339
1340 haveSelf = False0;
1341 if ((stmt->file == NULL((void*)0)) && (stmt->map == NULL((void*)0)))
1342 {
1343 haveSelf = True1;
1344 included = *info;
1345 bzero(info, sizeof(GeometryInfo))memset(info,0,sizeof(GeometryInfo));
1346 }
1347 else if (ProcessIncludeFile(stmt, XkmGeometryIndex5, &rtrn, &newMerge))
1348 {
1349 InitGeometryInfo(&included, rtrn->id, newMerge);
1350 included.nextPriority = info->nextPriority;
1351 included.dfltCornerRadius = info->dfltCornerRadius;
1352 DupSectionInfo(&included.dfltSection, &info->dfltSection, info);
1353 (*hndlr) (rtrn, xkb, MergeOverride2, &included);
1354 if (stmt->stmt != NULL((void*)0))
1355 {
1356 if (included.name != NULL((void*)0))
1357 uFree(included.name);
1358 included.name = stmt->stmt;
1359 stmt->stmt = NULL((void*)0);
1360 }
1361 }
1362 else
1363 {
1364 info->errorCount += 10;
1365 return False0;
1366 }
1367 if ((stmt->next != NULL((void*)0)) && (included.errorCount < 1))
1368 {
1369 IncludeStmt *next;
1370 unsigned op;
1371 GeometryInfo next_incl;
1372
1373 for (next = stmt->next; next != NULL((void*)0); next = next->next)
1374 {
1375 if ((next->file == NULL((void*)0)) && (next->map == NULL((void*)0)))
1376 {
1377 haveSelf = True1;
1378 MergeIncludedGeometry(&included, info, next->merge);
1379 ClearGeometryInfo(info);
1380 }
1381 else if (ProcessIncludeFile(next, XkmGeometryIndex5, &rtrn, &op))
1382 {
1383 InitGeometryInfo(&next_incl, rtrn->id, op);
1384 next_incl.nextPriority = included.nextPriority;
1385 next_incl.dfltCornerRadius = included.dfltCornerRadius;
1386 DupSectionInfo(&next_incl.dfltSection,
1387 &included.dfltSection, &included);
1388 (*hndlr) (rtrn, xkb, MergeOverride2, &next_incl);
1389 MergeIncludedGeometry(&included, &next_incl, op);
1390 ClearGeometryInfo(&next_incl);
1391 }
1392 else
1393 {
1394 info->errorCount += 10;
1395 return False0;
1396 }
1397 }
1398 }
1399 if (haveSelf)
1400 *info = included;
1401 else
1402 {
1403 MergeIncludedGeometry(info, &included, newMerge);
1404 ClearGeometryInfo(&included);
1405 }
1406 return (info->errorCount == 0);
1407}
1408
1409static int
1410SetShapeField(ShapeInfo * si,
1411 char *field,
1412 ExprDef * arrayNdx, ExprDef * value, GeometryInfo * info)
1413{
1414 ExprResult tmp;
1415
1416 if ((uStrCaseCmp(field, "radius")(strcasecmp(field,"radius")) == 0)
1417 || (uStrCaseCmp(field, "corner")(strcasecmp(field,"corner")) == 0)
1418 || (uStrCaseCmp(field, "cornerradius")(strcasecmp(field,"cornerradius")) == 0))
1419 {
1420 if (arrayNdx != NULL((void*)0))
1421 {
1422 info->errorCount++;
1423 return ReportNotArray("key shape", field, shText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default shape"
)
);
1424 }
1425 if (!ExprResolveFloat(value, &tmp, NULL((void*)0), NULL((void*)0)))
1426 {
1427 info->errorCount++;
1428 return ReportBadType("key shape", field,
1429 shText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default shape"
)
, "number");
1430 }
1431 if (si)
1432 si->dfltCornerRadius = tmp.ival;
1433 else
1434 info->dfltCornerRadius = tmp.ival;
1435 return True1;
1436 }
1437 info->errorCount++;
1438 return ReportBadField("key shape", field, shText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default shape"
)
);
1439}
1440
1441static int
1442SetShapeDoodadField(DoodadInfo * di,
1443 char *field,
1444 ExprDef * arrayNdx,
1445 ExprDef * value, SectionInfo * si, GeometryInfo * info)
1446{
1447 ExprResult tmp;
1448 const char *typeName;
1449
1450 typeName =
1451 (di->type == XkbSolidDoodad2 ? "solid doodad" : "outline doodad");
1452 if ((!uStrCaseCmp(field, "corner")(strcasecmp(field,"corner")))
1453 || (!uStrCaseCmp(field, "cornerradius")(strcasecmp(field,"cornerradius"))))
1454 {
1455 if (arrayNdx != NULL((void*)0))
1456 {
1457 info->errorCount++;
1458 return ReportNotArray(typeName, field, ddText(info->dpy, di));
1459 }
1460 if (!ExprResolveFloat(value, &tmp, NULL((void*)0), NULL((void*)0)))
1461 {
1462 info->errorCount++;
1463 return ReportBadType(typeName, field, ddText(info->dpy, di),
1464 "number");
1465 }
1466 di->defs.defined |= _GD_Corner(1<<5);
1467 di->corner = tmp.ival;
1468 return True1;
1469 }
1470 else if (uStrCaseCmp(field, "angle")(strcasecmp(field,"angle")) == 0)
1471 {
1472 if (arrayNdx != NULL((void*)0))
1473 {
1474 info->errorCount++;
1475 return ReportNotArray(typeName, field, ddText(info->dpy, di));
1476 }
1477 if (!ExprResolveFloat(value, &tmp, NULL((void*)0), NULL((void*)0)))
1478 {
1479 info->errorCount++;
1480 return ReportBadType(typeName, field, ddText(info->dpy, di),
1481 "number");
1482 }
1483 di->defs.defined |= _GD_Angle(1<<3);
1484 di->angle = tmp.ival;
1485 return True1;
1486 }
1487 else if (uStrCaseCmp(field, "shape")(strcasecmp(field,"shape")) == 0)
1488 {
1489 if (arrayNdx != NULL((void*)0))
1490 {
1491 info->errorCount++;
1492 return ReportNotArray(typeName, field, ddText(info->dpy, di));
1493 }
1494 if (!ExprResolveString(value, &tmp, NULL((void*)0), NULL((void*)0)))
1495 {
1496 info->errorCount++;
1497 return ReportBadType(typeName, field, ddText(info->dpy, di),
1498 "string");
1499 }
1500 di->shape = XkbInternAtom(info->dpy, tmp.str, False0);
1501 di->defs.defined |= _GD_Shape(1<<4);
1502 return True1;
1503 }
1504 return ReportBadField(typeName, field, ddText(info->dpy, di));
1505}
1506
1507#define FIELD_STRING0 0
1508#define FIELD_SHORT1 1
1509#define FIELD_USHORT2 2
1510
1511static int
1512SetTextDoodadField(DoodadInfo * di,
1513 char *field,
1514 ExprDef * arrayNdx,
1515 ExprDef * value, SectionInfo * si, GeometryInfo * info)
1516{
1517 ExprResult tmp;
1518 unsigned def;
1519 unsigned type;
1520 char *typeName = "text doodad";
1521 union
1522 {
1523 Atom *str;
1524 short *ival;
1525 unsigned short *uval;
1526 } pField;
1527
1528 if (uStrCaseCmp(field, "angle")(strcasecmp(field,"angle")) == 0)
1529 {
1530 if (arrayNdx != NULL((void*)0))
1531 {
1532 info->errorCount++;
1533 return ReportNotArray(typeName, field, ddText(info->dpy, di));
1534 }
1535 if (!ExprResolveFloat(value, &tmp, NULL((void*)0), NULL((void*)0)))
1536 {
1537 info->errorCount++;
1538 return ReportBadType(typeName, field, ddText(info->dpy, di),
1539 "number");
1540 }
1541 di->defs.defined |= _GD_Angle(1<<3);
1542 di->angle = tmp.ival;
1543 return True1;
1544 }
1545 if (uStrCaseCmp(field, "width")(strcasecmp(field,"width")) == 0)
1546 {
1547 type = FIELD_USHORT2;
1548 pField.uval = &di->width;
1549 def = _GD_Width(1<<5);
1550 }
1551 else if (uStrCaseCmp(field, "height")(strcasecmp(field,"height")) == 0)
1552 {
1553 type = FIELD_USHORT2;
1554 pField.uval = &di->height;
1555 def = _GD_Height(1<<7);
1556 }
1557 else if (uStrCaseCmp(field, "text")(strcasecmp(field,"text")) == 0)
1558 {
1559 type = FIELD_STRING0;
1560 pField.str = &di->text;
1561 def = _GD_Text(1<<8);
1562 }
1563 else if (uStrCaseCmp(field, "font")(strcasecmp(field,"font")) == 0)
1564 {
1565 type = FIELD_STRING0;
1566 pField.str = &di->font;
1567 def = _GD_Font(1<<9);
1568 }
1569 else if ((uStrCaseCmp(field, "fontslant")(strcasecmp(field,"fontslant")) == 0) ||
1570 (uStrCaseCmp(field, "slant")(strcasecmp(field,"slant")) == 0))
1571 {
1572 type = FIELD_STRING0;
1573 pField.str = &di->fontSlant;
1574 def = _GD_FontSlant(1<<10);
1575 }
1576 else if ((uStrCaseCmp(field, "fontweight")(strcasecmp(field,"fontweight")) == 0) ||
1577 (uStrCaseCmp(field, "weight")(strcasecmp(field,"weight")) == 0))
1578 {
1579 type = FIELD_STRING0;
1580 pField.str = &di->fontWeight;
1581 def = _GD_FontWeight(1<<11);
1582 }
1583 else if ((uStrCaseCmp(field, "fontwidth")(strcasecmp(field,"fontwidth")) == 0) ||
1584 (uStrCaseCmp(field, "setwidth")(strcasecmp(field,"setwidth")) == 0))
1585 {
1586 type = FIELD_STRING0;
1587 pField.str = &di->fontSetWidth;
1588 def = _GD_FontSetWidth(1<<12);
1589 }
1590 else if ((uStrCaseCmp(field, "fontvariant")(strcasecmp(field,"fontvariant")) == 0) ||
1591 (uStrCaseCmp(field, "variant")(strcasecmp(field,"variant")) == 0))
1592 {
1593 type = FIELD_STRING0;
1594 pField.str = &di->fontVariant;
1595 def = _GD_FontVariant(1<<4);
1596 }
1597 else if ((uStrCaseCmp(field, "fontencoding")(strcasecmp(field,"fontencoding")) == 0) ||
1598 (uStrCaseCmp(field, "encoding")(strcasecmp(field,"encoding")) == 0))
1599 {
1600 type = FIELD_STRING0;
1601 pField.str = &di->fontEncoding;
1602 def = _GD_FontEncoding(1<<14);
1603 }
1604 else if ((uStrCaseCmp(field, "xfont")(strcasecmp(field,"xfont")) == 0) ||
1605 (uStrCaseCmp(field, "xfontname")(strcasecmp(field,"xfontname")) == 0))
1606 {
1607 type = FIELD_STRING0;
1608 pField.str = &di->fontSpec;
1609 def = _GD_FontSpec(1<<15);
1610 }
1611 else if (uStrCaseCmp(field, "fontsize")(strcasecmp(field,"fontsize")) == 0)
1612 {
1613 type = FIELD_USHORT2;
1614 pField.uval = &di->fontSize;
1615 def = _GD_FontSize(1<<13);
1616 }
1617 else
1618 {
1619 return ReportBadField(typeName, field, ddText(info->dpy, di));
1620 }
1621 if (arrayNdx != NULL((void*)0))
1622 {
1623 info->errorCount++;
1624 return ReportNotArray(typeName, field, ddText(info->dpy, di));
1625 }
1626 if (type == FIELD_STRING0)
1627 {
1628 if (!ExprResolveString(value, &tmp, NULL((void*)0), NULL((void*)0)))
1629 {
1630 info->errorCount++;
1631 return ReportBadType(typeName, field, ddText(info->dpy, di),
1632 "string");
1633 }
1634 di->defs.defined |= def;
1635 *pField.str = XkbInternAtom(NULL((void*)0), tmp.str, False0);
1636 }
1637 else
1638 {
1639 if (!ExprResolveFloat(value, &tmp, NULL((void*)0), NULL((void*)0)))
1640 {
1641 info->errorCount++;
1642 return ReportBadType(typeName, field, ddText(info->dpy, di),
1643 "number");
1644 }
1645 if ((type == FIELD_USHORT2) && (tmp.ival < 0))
1646 {
1647 info->errorCount++;
1648 return
1649 ReportBadType(typeName, field, ddText(info->dpy, di),
1650 "unsigned");
1651 }
1652 di->defs.defined |= def;
1653 if (type == FIELD_USHORT2)
1654 *pField.uval = tmp.uval;
1655 else
1656 *pField.ival = tmp.ival;
1657 }
1658 return True1;
1659}
1660
1661static int
1662SetIndicatorDoodadField(DoodadInfo * di,
1663 char *field,
1664 ExprDef * arrayNdx,
1665 ExprDef * value,
1666 SectionInfo * si, GeometryInfo * info)
1667{
1668 ExprResult tmp;
1669
1670 if ((uStrCaseCmp(field, "oncolor")(strcasecmp(field,"oncolor")) == 0)
1671 || (uStrCaseCmp(field, "offcolor")(strcasecmp(field,"offcolor")) == 0)
1672 || (uStrCaseCmp(field, "shape")(strcasecmp(field,"shape")) == 0))
1673 {
1674 if (arrayNdx != NULL((void*)0))
1675 {
1676 info->errorCount++;
1677 return ReportNotArray("indicator doodad", field,
1678 ddText(info->dpy, di));
1679 }
1680 if (!ExprResolveString(value, &tmp, NULL((void*)0), NULL((void*)0)))
1681 {
1682 info->errorCount++;
1683 return ReportBadType("indicator doodad", field,
1684 ddText(info->dpy, di), "string");
1685 }
1686 if (uStrCaseCmp(field, "oncolor")(strcasecmp(field,"oncolor")) == 0)
1687 {
1688 di->defs.defined |= _GD_Color(1<<6);
1689 di->color = XkbInternAtom(NULL((void*)0), tmp.str, False0);
1690 }
1691 else if (uStrCaseCmp(field, "offcolor")(strcasecmp(field,"offcolor")) == 0)
1692 {
1693 di->defs.defined |= _GD_OffColor(1<<7);
1694 di->offColor = XkbInternAtom(NULL((void*)0), tmp.str, False0);
1695 }
1696 else if (uStrCaseCmp(field, "shape")(strcasecmp(field,"shape")) == 0)
1697 {
1698 di->defs.defined |= _GD_Shape(1<<4);
1699 di->shape = XkbInternAtom(info->dpy, tmp.str, False0);
1700 }
1701 return True1;
1702 }
1703 return ReportBadField("indicator doodad", field, ddText(info->dpy, di));
1704}
1705
1706static int
1707SetLogoDoodadField(DoodadInfo * di,
1708 char *field,
1709 ExprDef * arrayNdx,
1710 ExprDef * value, SectionInfo * si, GeometryInfo * info)
1711{
1712 ExprResult tmp;
1713 char *typeName = "logo doodad";
1714
1715 if ((!uStrCaseCmp(field, "corner")(strcasecmp(field,"corner")))
1716 || (!uStrCaseCmp(field, "cornerradius")(strcasecmp(field,"cornerradius"))))
1717 {
1718 if (arrayNdx != NULL((void*)0))
1719 {
1720 info->errorCount++;
1721 return ReportNotArray(typeName, field, ddText(info->dpy, di));
1722 }
1723 if (!ExprResolveFloat(value, &tmp, NULL((void*)0), NULL((void*)0)))
1724 {
1725 info->errorCount++;
1726 return ReportBadType(typeName, field, ddText(info->dpy, di),
1727 "number");
1728 }
1729 di->defs.defined |= _GD_Corner(1<<5);
1730 di->corner = tmp.ival;
1731 return True1;
1732 }
1733 else if (uStrCaseCmp(field, "angle")(strcasecmp(field,"angle")) == 0)
1734 {
1735 if (arrayNdx != NULL((void*)0))
1736 {
1737 info->errorCount++;
1738 return ReportNotArray(typeName, field, ddText(info->dpy, di));
1739 }
1740 if (!ExprResolveFloat(value, &tmp, NULL((void*)0), NULL((void*)0)))
1741 {
1742 info->errorCount++;
1743 return ReportBadType(typeName, field, ddText(info->dpy, di),
1744 "number");
1745 }
1746 di->defs.defined |= _GD_Angle(1<<3);
1747 di->angle = tmp.ival;
1748 return True1;
1749 }
1750 else if (uStrCaseCmp(field, "shape")(strcasecmp(field,"shape")) == 0)
1751 {
1752 if (arrayNdx != NULL((void*)0))
1753 {
1754 info->errorCount++;
1755 return ReportNotArray(typeName, field, ddText(info->dpy, di));
1756 }
1757 if (!ExprResolveString(value, &tmp, NULL((void*)0), NULL((void*)0)))
1758 {
1759 info->errorCount++;
1760 return ReportBadType(typeName, field, ddText(info->dpy, di),
1761 "string");
1762 }
1763 di->shape = XkbInternAtom(info->dpy, tmp.str, False0);
1764 di->defs.defined |= _GD_Shape(1<<4);
1765 return True1;
1766 }
1767 else if ((!uStrCaseCmp(field, "logoname")(strcasecmp(field,"logoname")))
1768 || (!uStrCaseCmp(field, "name")(strcasecmp(field,"name"))))
1769 {
1770 if (arrayNdx != NULL((void*)0))
1771 {
1772 info->errorCount++;
1773 return ReportNotArray(typeName, field, ddText(info->dpy, di));
1774 }
1775 if (!ExprResolveString(value, &tmp, NULL((void*)0), NULL((void*)0)))
1776 {
1777 info->errorCount++;
1778 return ReportBadType(typeName, field, ddText(info->dpy, di),
1779 "string");
1780 }
1781 di->logoName = uStringDup(tmp.str)((tmp.str) ? strdup(tmp.str) : ((void*)0));
1782 return True1;
1783 }
1784 return ReportBadField(typeName, field, ddText(info->dpy, di));
1785}
1786
1787static int
1788SetDoodadField(DoodadInfo * di,
1789 char *field,
1790 ExprDef * arrayNdx,
1791 ExprDef * value, SectionInfo * si, GeometryInfo * info)
1792{
1793 ExprResult tmp;
1794
1795 if (uStrCaseCmp(field, "priority")(strcasecmp(field,"priority")) == 0)
1796 {
1797 if (arrayNdx != NULL((void*)0))
1798 {
1799 info->errorCount++;
1800 return ReportNotArray("doodad", field, ddText(info->dpy, di));
1801 }
1802 if (!ExprResolveInteger(value, &tmp, NULL((void*)0), NULL((void*)0)))
1803 {
1804 info->errorCount++;
1805 return ReportBadType("doodad", field, ddText(info->dpy, di),
1806 "integer");
1807 }
1808 if ((tmp.ival < 0) || (tmp.ival > XkbGeomMaxPriority255))
1809 {
1810 info->errorCount++;
1811 ERROR2uError("Doodad priority %d out of range (must be 0..%d)\n",
1812 tmp.ival, XkbGeomMaxPriority255);
1813 ACTION1uAction("Priority for doodad %s not changed",
1814 ddText(info->dpy, di));
1815 return False0;
1816 }
1817 di->defs.defined |= _GD_Priority(1<<0);
1818 di->priority = tmp.ival;
1819 return True1;
1820 }
1821 else if (uStrCaseCmp(field, "left")(strcasecmp(field,"left")) == 0)
1822 {
1823 if (arrayNdx != NULL((void*)0))
1824 {
1825 info->errorCount++;
1826 return ReportNotArray("doodad", field, ddText(info->dpy, di));
1827 }
1828 if (!ExprResolveFloat(value, &tmp, NULL((void*)0), NULL((void*)0)))
1829 {
1830 info->errorCount++;
1831 return ReportBadType("doodad", field, ddText(info->dpy, di),
1832 "number");
1833 }
1834 di->defs.defined |= _GD_Left(1<<2);
1835 di->left = tmp.ival;
1836 return True1;
1837 }
1838 else if (uStrCaseCmp(field, "top")(strcasecmp(field,"top")) == 0)
1839 {
1840 if (arrayNdx != NULL((void*)0))
1841 {
1842 info->errorCount++;
1843 return ReportNotArray("doodad", field, ddText(info->dpy, di));
1844 }
1845 if (!ExprResolveFloat(value, &tmp, NULL((void*)0), NULL((void*)0)))
1846 {
1847 info->errorCount++;
1848 return ReportBadType("doodad", field, ddText(info->dpy, di),
1849 "number");
1850 }
1851 di->defs.defined |= _GD_Top(1<<1);
1852 di->top = tmp.ival;
1853 return True1;
1854 }
1855 else if (uStrCaseCmp(field, "color")(strcasecmp(field,"color")) == 0)
1856 {
1857 if (arrayNdx != NULL((void*)0))
1858 {
1859 info->errorCount++;
1860 return ReportNotArray("doodad", field, ddText(info->dpy, di));
1861 }
1862 if (!ExprResolveString(value, &tmp, NULL((void*)0), NULL((void*)0)))
1863 {
1864 info->errorCount++;
1865 return ReportBadType("doodad", field, ddText(info->dpy, di),
1866 "string");
1867 }
1868 di->defs.defined |= _GD_Color(1<<6);
1869 di->color = XkbInternAtom(NULL((void*)0), tmp.str, False0);
1870 return True1;
1871 }
1872 switch (di->type)
1873 {
1874 case XkbOutlineDoodad1:
1875 case XkbSolidDoodad2:
1876 return SetShapeDoodadField(di, field, arrayNdx, value, si, info);
1877 case XkbTextDoodad3:
1878 return SetTextDoodadField(di, field, arrayNdx, value, si, info);
1879 case XkbIndicatorDoodad4:
1880 return SetIndicatorDoodadField(di, field, arrayNdx, value, si, info);
1881 case XkbLogoDoodad5:
1882 return SetLogoDoodadField(di, field, arrayNdx, value, si, info);
1883 }
1884 WSGO1uInternalError("Unknown doodad type %d in SetDoodadField\n",
1885 (unsigned int) di->type);
1886 ACTION2uAction("Definition of %s in %s ignored\n", field, ddText(info->dpy, di));
1887 return False0;
1888}
1889
1890static int
1891SetSectionField(SectionInfo * si,
1892 char *field,
1893 ExprDef * arrayNdx, ExprDef * value, GeometryInfo * info)
1894{
1895 unsigned short *pField;
1896 unsigned def;
1897 ExprResult tmp;
1898
1899 pField = NULL((void*)0);
1900 def = 0;
1901 if (uStrCaseCmp(field, "priority")(strcasecmp(field,"priority")) == 0)
1902 {
1903 if (arrayNdx != NULL((void*)0))
1904 {
1905 info->errorCount++;
1906 return ReportNotArray("keyboard section", field,
1907 scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"));
1908 }
1909 if (!ExprResolveInteger(value, &tmp, NULL((void*)0), NULL((void*)0)))
1910 {
1911 info->errorCount++;
1912 ReportBadType("keyboard section", field,
1913 scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"), "integer");
1914 return False0;
1915 }
1916 if ((tmp.ival < 0) || (tmp.ival > XkbGeomMaxPriority255))
1917 {
1918 info->errorCount++;
1919 ERROR2uError("Section priority %d out of range (must be 0..%d)\n",
1920 tmp.ival, XkbGeomMaxPriority255);
1921 ACTION1uAction("Priority for section %s not changed",
1922 scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"));
1923 return False0;
1924 }
1925 si->priority = tmp.ival;
1926 si->defs.defined |= _GS_Priority(1<<7);
1927 return True1;
1928 }
1929 else if (uStrCaseCmp(field, "top")(strcasecmp(field,"top")) == 0)
1930 {
1931 pField = &si->top;
1932 def = _GS_Top(1<<2);
1933 }
1934 else if (uStrCaseCmp(field, "left")(strcasecmp(field,"left")) == 0)
1935 {
1936 pField = &si->left;
1937 def = _GS_Left(1<<3);
1938 }
1939 else if (uStrCaseCmp(field, "width")(strcasecmp(field,"width")) == 0)
1940 {
1941 pField = &si->width;
1942 def = _GS_Width(1<<4);
1943 }
1944 else if (uStrCaseCmp(field, "height")(strcasecmp(field,"height")) == 0)
1945 {
1946 pField = &si->height;
1947 def = _GS_Height(1<<5);
1948 }
1949 else if (uStrCaseCmp(field, "angle")(strcasecmp(field,"angle")) == 0)
1950 {
1951 pField = &si->angle;
1952 def = _GS_Angle(1<<6);
1953 }
1954 else
1955 {
1956 info->errorCount++;
1957 return ReportBadField("keyboard section", field,
1958 scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"));
1959 }
1960 if (arrayNdx != NULL((void*)0))
1961 {
1962 info->errorCount++;
1963 return ReportNotArray("keyboard section", field,
1964 scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"));
1965 }
1966 if (!ExprResolveFloat(value, &tmp, NULL((void*)0), NULL((void*)0)))
1967 {
1968 info->errorCount++;
1969 ReportBadType("keyboard section", field, scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"),
1970 "number");
1971 return False0;
1972 }
1973 si->defs.defined |= def;
1974 *pField = tmp.uval;
1975 return True1;
1976}
1977
1978static int
1979SetRowField(RowInfo * row,
1980 char *field,
1981 ExprDef * arrayNdx, ExprDef * value, GeometryInfo * info)
1982{
1983 ExprResult tmp;
1984
1985 if (uStrCaseCmp(field, "top")(strcasecmp(field,"top")) == 0)
1986 {
1987 if (arrayNdx != NULL((void*)0))
1988 {
1989 info->errorCount++;
1990 return ReportNotArray("keyboard row", field,
1991 rowText(info->dpy, row)((row)?XkbAtomText((info->dpy),(row)->section->name,
3):"default")
);
1992 }
1993 if (!ExprResolveFloat(value, &tmp, NULL((void*)0), NULL((void*)0)))
1994 {
1995 info->errorCount++;
1996 return ReportBadType("keyboard row", field,
1997 rowText(info->dpy, row)((row)?XkbAtomText((info->dpy),(row)->section->name,
3):"default")
, "number");
1998 }
1999 row->defs.defined |= _GR_Top(1<<2);
2000 row->top = tmp.uval;
2001 }
2002 else if (uStrCaseCmp(field, "left")(strcasecmp(field,"left")) == 0)
2003 {
2004 if (arrayNdx != NULL((void*)0))
2005 {
2006 info->errorCount++;
2007 return ReportNotArray("keyboard row", field,
2008 rowText(info->dpy, row)((row)?XkbAtomText((info->dpy),(row)->section->name,
3):"default")
);
2009 }
2010 if (!ExprResolveFloat(value, &tmp, NULL((void*)0), NULL((void*)0)))
2011 {
2012 info->errorCount++;
2013 return ReportBadType("keyboard row", field,
2014 rowText(info->dpy, row)((row)?XkbAtomText((info->dpy),(row)->section->name,
3):"default")
, "number");
2015 }
2016 row->defs.defined |= _GR_Left(1<<3);
2017 row->left = tmp.uval;
2018 }
2019 else if (uStrCaseCmp(field, "vertical")(strcasecmp(field,"vertical")) == 0)
2020 {
2021 if (arrayNdx != NULL((void*)0))
2022 {
2023 info->errorCount++;
2024 return ReportNotArray("keyboard row", field,
2025 rowText(info->dpy, row)((row)?XkbAtomText((info->dpy),(row)->section->name,
3):"default")
);
2026 }
2027 if (!ExprResolveBoolean(value, &tmp, NULL((void*)0), NULL((void*)0)))
2028 {
2029 info->errorCount++;
2030 return ReportBadType("keyboard row", field,
2031 rowText(info->dpy, row)((row)?XkbAtomText((info->dpy),(row)->section->name,
3):"default")
, "boolean");
2032 }
2033 row->defs.defined |= _GR_Vertical(1<<1);
2034 row->vertical = tmp.uval;
2035 }
2036 else
2037 {
2038 info->errorCount++;
2039 return ReportBadField("keyboard row", field, rowText(info->dpy, row)((row)?XkbAtomText((info->dpy),(row)->section->name,
3):"default")
);
2040 }
2041 return True1;
2042}
2043
2044static int
2045SetKeyField(KeyInfo * key,
2046 const char *field,
2047 ExprDef * arrayNdx, ExprDef * value, GeometryInfo * info)
2048{
2049 ExprResult tmp;
2050
2051 if (uStrCaseCmp(field, "gap")(strcasecmp(field,"gap")) == 0)
2052 {
2053 if (arrayNdx != NULL((void*)0))
2054 {
2055 info->errorCount++;
2056 return ReportNotArray("key", field, keyText(key)((key)&&(key)->name[0]?(key)->name:"default"));
2057 }
2058 if (!ExprResolveFloat(value, &tmp, NULL((void*)0), NULL((void*)0)))
2059 {
2060 info->errorCount++;
2061 return ReportBadType("key", field, keyText(key)((key)&&(key)->name[0]?(key)->name:"default"), "number");
2062 }
2063 key->defs.defined |= _GK_Gap(1<<2);
2064 key->gap = tmp.ival;
2065 }
2066 else if (uStrCaseCmp(field, "shape")(strcasecmp(field,"shape")) == 0)
2067 {
2068 if (arrayNdx != NULL((void*)0))
2069 {
2070 info->errorCount++;
2071 return ReportNotArray("key", field, keyText(key)((key)&&(key)->name[0]?(key)->name:"default"));
2072 }
2073 if (!ExprResolveString(value, &tmp, NULL((void*)0), NULL((void*)0)))
2074 {
2075 info->errorCount++;
2076 return ReportBadType("key", field, keyText(key)((key)&&(key)->name[0]?(key)->name:"default"), "string");
2077 }
2078 key->defs.defined |= _GK_Shape(1<<3);
2079 key->shape = XkbInternAtom(info->dpy, tmp.str, False0);
2080 }
2081 else if ((uStrCaseCmp(field, "color")(strcasecmp(field,"color")) == 0) ||
2082 (uStrCaseCmp(field, "keycolor")(strcasecmp(field,"keycolor")) == 0))
2083 {
2084 if (arrayNdx != NULL((void*)0))
2085 {
2086 info->errorCount++;
2087 return ReportNotArray("key", field, keyText(key)((key)&&(key)->name[0]?(key)->name:"default"));
2088 }
2089 if (!ExprResolveString(value, &tmp, NULL((void*)0), NULL((void*)0)))
2090 {
2091 info->errorCount++;
2092 return ReportBadType("key", field, keyText(key)((key)&&(key)->name[0]?(key)->name:"default"), "string");
2093 }
2094 key->defs.defined |= _GK_Color(1<<4);
2095 key->color = XkbInternAtom(NULL((void*)0), tmp.str, False0);
2096 }
2097 else if ((uStrCaseCmp(field, "name")(strcasecmp(field,"name")) == 0)
2098 || (uStrCaseCmp(field, "keyname")(strcasecmp(field,"keyname")) == 0))
2099 {
2100 if (arrayNdx != NULL((void*)0))
2101 {
2102 info->errorCount++;
2103 return ReportNotArray("key", field, keyText(key)((key)&&(key)->name[0]?(key)->name:"default"));
2104 }
2105 if (!ExprResolveKeyName(value, &tmp, NULL((void*)0), NULL((void*)0)))
2106 {
2107 info->errorCount++;
2108 return ReportBadType("key", field, keyText(key)((key)&&(key)->name[0]?(key)->name:"default"), "key name");
2109 }
2110 key->defs.defined |= _GK_Name(1<<1);
2111 bzero(key->name, XkbKeyNameLength + 1)memset(key->name,0,4 + 1);
2112 strncpy(key->name, tmp.keyName.name, XkbKeyNameLength4);
2113 }
2114 else
2115 {
2116 info->errorCount++;
2117 return ReportBadField("key", field, keyText(key)((key)&&(key)->name[0]?(key)->name:"default"));
2118 }
2119 return True1;
2120}
2121
2122static int
2123SetGeometryProperty(GeometryInfo * info, char *property, ExprDef * value)
2124{
2125 PropertyInfo pi;
2126 ExprResult result;
2127
2128 InitPropertyInfo(&pi, info);
2129 pi.name = property;
2130 if (!ExprResolveString(value, &result, NULL((void*)0), NULL((void*)0)))
2131 {
2132 info->errorCount++;
2133 ERRORuError("Property values must be type string\n");
2134 ACTION1uAction("Ignoring illegal definition of \"%s\" property\n", property);
2135 return False0;
2136 }
2137 pi.value = result.str;
2138 return AddProperty(info, &pi);
2139}
2140
2141static int
2142HandleGeometryVar(VarDef * stmt, XkbDescPtr xkb, GeometryInfo * info)
2143{
2144 ExprResult elem, field, tmp;
2145 ExprDef *ndx;
2146 DoodadInfo *di;
2147 Atom *pField;
2148
2149 if (ExprResolveLhs(stmt->name, &elem, &field, &ndx) == 0)
2150 return 0; /* internal error, already reported */
2151 if (elem.str && (uStrCaseCmp(elem.str, "shape")(strcasecmp(elem.str,"shape")) == 0))
2152 return SetShapeField(NULL((void*)0), field.str, ndx, stmt->value, info);
2153 if (elem.str && (uStrCaseCmp(elem.str, "key")(strcasecmp(elem.str,"key")) == 0))
2154 return SetKeyField(&info->dfltSection.dfltRow.dfltKey,
2155 field.str, ndx, stmt->value, info);
2156 if (elem.str && (uStrCaseCmp(elem.str, "row")(strcasecmp(elem.str,"row")) == 0))
2157 return SetRowField(&info->dfltSection.dfltRow, field.str, ndx,
2158 stmt->value, info);
2159 if (elem.str && (uStrCaseCmp(elem.str, "section")(strcasecmp(elem.str,"section")) == 0))
2160 {
2161 return SetSectionField(&info->dfltSection, field.str, ndx,
2162 stmt->value, info);
2163 }
2164 if (elem.str && (uStrCaseCmp(elem.str, "property")(strcasecmp(elem.str,"property")) == 0))
2165 {
2166 if (ndx != NULL((void*)0))
2167 {
2168 info->errorCount++;
2169 ERROR1uError("The %s geometry property is not an array\n", field.str);
2170 ACTIONuAction("Ignoring illegal property definition\n");
2171 return False0;
2172 }
2173 return SetGeometryProperty(info, field.str, stmt->value);
2174 }
2175 if (elem.str
2176 && ((di = FindDfltDoodadByTypeName(elem.str, NULL((void*)0), info)) != NULL((void*)0)))
2177 {
2178 return SetDoodadField(di, field.str, ndx, stmt->value, NULL((void*)0), info);
2179 }
2180 if (elem.str && (uStrCaseCmp(elem.str, "solid")(strcasecmp(elem.str,"solid")) == 0))
2181 {
2182 DoodadInfo *dflt;
2183 dflt = FindDoodadByType(info->dfltDoodads, XkbSolidDoodad2);
2184 if (dflt == NULL((void*)0))
2185 dflt = NextDfltDoodad(NULL((void*)0), info);
2186 return SetDoodadField(dflt, field.str, ndx, stmt->value, NULL((void*)0), info);
2187 }
2188 if (elem.str && (uStrCaseCmp(elem.str, "outline")(strcasecmp(elem.str,"outline")) == 0))
2189 {
2190 DoodadInfo *dflt;
2191 dflt = FindDoodadByType(info->dfltDoodads, XkbOutlineDoodad1);
2192 if (dflt == NULL((void*)0))
2193 dflt = NextDfltDoodad(NULL((void*)0), info);
2194 return SetDoodadField(dflt, field.str, ndx, stmt->value, NULL((void*)0), info);
2195 }
2196 if (elem.str && (uStrCaseCmp(elem.str, "text")(strcasecmp(elem.str,"text")) == 0))
2197 {
2198 DoodadInfo *dflt;
2199 dflt = FindDoodadByType(info->dfltDoodads, XkbTextDoodad3);
2200 if (dflt == NULL((void*)0))
2201 dflt = NextDfltDoodad(NULL((void*)0), info);
2202 return SetDoodadField(dflt, field.str, ndx, stmt->value, NULL((void*)0), info);
2203 }
2204 if (elem.str && (uStrCaseCmp(elem.str, "indicator")(strcasecmp(elem.str,"indicator")) == 0))
2205 {
2206 DoodadInfo *dflt;
2207 dflt = FindDoodadByType(info->dfltDoodads, XkbIndicatorDoodad4);
2208 if (dflt == NULL((void*)0))
2209 dflt = NextDfltDoodad(NULL((void*)0), info);
2210 return SetDoodadField(dflt, field.str, ndx, stmt->value, NULL((void*)0), info);
2211 }
2212 if (elem.str && (uStrCaseCmp(elem.str, "logo")(strcasecmp(elem.str,"logo")) == 0))
2213 {
2214 DoodadInfo *dflt;
2215 dflt = FindDoodadByType(info->dfltDoodads, XkbLogoDoodad5);
2216 if (dflt == NULL((void*)0))
2217 dflt = NextDfltDoodad(NULL((void*)0), info);
2218 return SetDoodadField(dflt, field.str, ndx, stmt->value, NULL((void*)0), info);
2219 }
2220 if (elem.str)
2221 {
2222 WARNuWarning("Assignment to field of unknown element\n");
2223 ACTION2uAction("No value assigned to %s.%s\n", elem.str, field.str);
2224 return False0;
2225 }
2226
2227 if ((uStrCaseCmp(field.str, "width")(strcasecmp(field.str,"width")) == 0) ||
2228 (uStrCaseCmp(field.str, "widthmm")(strcasecmp(field.str,"widthmm")) == 0))
2229 {
2230 if (ndx != NULL((void*)0))
2231 {
2232 info->errorCount++;
2233 return ReportNotArray("keyboard", field.str, "geometry");
2234 }
2235 if (!ExprResolveFloat(stmt->value, &tmp, NULL((void*)0), NULL((void*)0)))
2236 {
2237 info->errorCount++;
2238 return ReportBadType("keyboard", field.str, "geometry", "number");
2239 }
2240 if (tmp.ival < 1)
2241 {
2242 WARNuWarning("Keyboard width must be positive\n");
2243 ACTION1uAction("Ignoring illegal keyboard width %s\n",
2244 XkbGeomFPText(tmp.ival, XkbMessage3));
2245 return True1;
2246 }
2247 if (info->widthMM != 0)
2248 {
2249 WARNuWarning("Keyboard width multiply defined\n");
2250 ACTION1uAction("Using last definition (%s),",
2251 XkbGeomFPText(tmp.ival, XkbMessage3));
2252 INFO1uInformation(" ignoring first (%s)\n",
2253 XkbGeomFPText(info->widthMM, XkbMessage3));
2254 }
2255 info->widthMM = tmp.ival;
2256 return True1;
2257 }
2258 else if ((uStrCaseCmp(field.str, "height")(strcasecmp(field.str,"height")) == 0) ||
2259 (uStrCaseCmp(field.str, "heightmm")(strcasecmp(field.str,"heightmm")) == 0))
2260 {
2261 if (ndx != NULL((void*)0))
2262 {
2263 info->errorCount++;
2264 return ReportNotArray("keyboard", field.str, "geometry");
2265 }
2266 if (!ExprResolveFloat(stmt->value, &tmp, NULL((void*)0), NULL((void*)0)))
2267 {
2268 info->errorCount++;
2269 return ReportBadType("keyboard", field.str, "geometry", "number");
2270 }
2271 if (tmp.ival < 1)
2272 {
2273 WARNuWarning("Keyboard height must be positive\n");
2274 ACTION1uAction("Ignoring illegal keyboard height %s\n",
2275 XkbGeomFPText(tmp.ival, XkbMessage3));
2276 return True1;
2277 }
2278 if (info->heightMM != 0)
2279 {
2280 WARNuWarning("Keyboard height multiply defined\n");
2281 ACTION1uAction("Using last definition (%s),",
2282 XkbGeomFPText(tmp.ival, XkbMessage3));
2283 INFO1uInformation(" ignoring first (%s)\n",
2284 XkbGeomFPText(info->heightMM, XkbMessage3));
2285 }
2286 info->heightMM = tmp.ival;
2287 return True1;
2288 }
2289 else if (uStrCaseCmp(field.str, "font")(strcasecmp(field.str,"font")) == 0)
2290 {
2291 pField = &info->font;
2292 }
2293 else if ((uStrCaseCmp(field.str, "fontslant")(strcasecmp(field.str,"fontslant")) == 0) ||
2294 (uStrCaseCmp(field.str, "slant")(strcasecmp(field.str,"slant")) == 0))
2295 {
2296 pField = &info->fontSlant;
2297 }
2298 else if ((uStrCaseCmp(field.str, "fontweight")(strcasecmp(field.str,"fontweight")) == 0) ||
2299 (uStrCaseCmp(field.str, "weight")(strcasecmp(field.str,"weight")) == 0))
2300 {
2301 pField = &info->fontWeight;
2302 }
2303 else if ((uStrCaseCmp(field.str, "fontwidth")(strcasecmp(field.str,"fontwidth")) == 0) ||
2304 (uStrCaseCmp(field.str, "setwidth")(strcasecmp(field.str,"setwidth")) == 0))
2305 {
2306 pField = &info->fontWeight;
2307 }
2308 else if ((uStrCaseCmp(field.str, "fontencoding")(strcasecmp(field.str,"fontencoding")) == 0) ||
2309 (uStrCaseCmp(field.str, "encoding")(strcasecmp(field.str,"encoding")) == 0))
2310 {
2311 pField = &info->fontEncoding;
2312 }
2313 else if ((uStrCaseCmp(field.str, "xfont")(strcasecmp(field.str,"xfont")) == 0) ||
2314 (uStrCaseCmp(field.str, "xfontname")(strcasecmp(field.str,"xfontname")) == 0))
2315 {
2316 pField = &info->fontSpec;
2317 }
2318 else if (uStrCaseCmp(field.str, "fontsize")(strcasecmp(field.str,"fontsize")) == 0)
2319 {
2320 if (ndx != NULL((void*)0))
2321 {
2322 info->errorCount++;
2323 return ReportNotArray("keyboard", field.str, "geometry");
2324 }
2325 if (!ExprResolveFloat(stmt->value, &tmp, NULL((void*)0), NULL((void*)0)))
2326 {
2327 info->errorCount++;
2328 return ReportBadType("keyboard", field.str, "geometry", "number");
2329 }
2330 if ((tmp.ival < 40) || (tmp.ival > 2550))
2331 {
2332 info->errorCount++;
2333 ERROR1uError("Illegal font size %d (must be 4..255)\n", tmp.ival);
2334 ACTIONuAction("Ignoring font size in keyboard geometry\n");
2335 return False0;
2336 }
2337 info->fontSize = tmp.ival;
2338 return True1;
2339 }
2340 else if ((uStrCaseCmp(field.str, "color")(strcasecmp(field.str,"color")) == 0) ||
2341 (uStrCaseCmp(field.str, "basecolor")(strcasecmp(field.str,"basecolor")) == 0))
2342 {
2343 if (ndx != NULL((void*)0))
2344 {
2345 info->errorCount++;
2346 return ReportNotArray("keyboard", field.str, "geometry");
2347 }
2348 if (!ExprResolveString(stmt->value, &tmp, NULL((void*)0), NULL((void*)0)))
2349 {
2350 info->errorCount++;
2351 return ReportBadType("keyboard", field.str, "geometry", "string");
2352 }
2353 info->baseColor = XkbInternAtom(NULL((void*)0), tmp.str, False0);
2354 return True1;
2355 }
2356 else if (uStrCaseCmp(field.str, "labelcolor")(strcasecmp(field.str,"labelcolor")) == 0)
2357 {
2358 if (ndx != NULL((void*)0))
2359 {
2360 info->errorCount++;
2361 return ReportNotArray("keyboard", field.str, "geometry");
2362 }
2363 if (!ExprResolveString(stmt->value, &tmp, NULL((void*)0), NULL((void*)0)))
2364 {
2365 info->errorCount++;
2366 return ReportBadType("keyboard", field.str, "geometry", "string");
2367 }
2368 info->labelColor = XkbInternAtom(NULL((void*)0), tmp.str, False0);
2369 return True1;
2370 }
2371 else
2372 {
2373 return SetGeometryProperty(info, field.str, stmt->value);
2374 }
2375
2376 if (ndx != NULL((void*)0))
2377 {
2378 info->errorCount++;
2379 return ReportNotArray("keyboard", field.str, "geometry");
2380 }
2381 if (!ExprResolveString(stmt->value, &tmp, NULL((void*)0), NULL((void*)0)))
2382 {
2383 info->errorCount++;
2384 return ReportBadType("keyboard", field.str, "geometry", "string");
2385 }
2386 *pField = XkbInternAtom(NULL((void*)0), tmp.str, False0);
2387 return True1;
2388}
2389
2390/***====================================================================***/
2391
2392static Boolint
2393HandleShapeBody(ShapeDef * def, ShapeInfo * si, unsigned merge,
2394 GeometryInfo * info)
2395{
2396 OutlineDef *ol;
2397 int nOut, nPt;
2398 XkbOutlinePtr outline;
2399 ExprDef *pt;
2400
2401 if (def->nOutlines < 1)
2402 {
2403 WARN1uWarning("Shape \"%s\" has no outlines\n", shText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default shape"
)
);
2404 ACTIONuAction("Definition ignored\n");
2405 return True1;
2406 }
2407 si->nOutlines = def->nOutlines;
2408 si->outlines = uTypedCalloc(def->nOutlines, XkbOutlineRec)((XkbOutlineRec *)uCalloc((unsigned)def->nOutlines,(unsigned
)sizeof(XkbOutlineRec)))
;
2409 if (!si->outlines)
2410 {
2411 ERROR1uError("Couldn't allocate outlines for \"%s\"\n",
2412 shText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default shape"
)
);
2413 ACTIONuAction("Definition ignored\n");
2414 info->errorCount++;
2415 return False0;
2416 }
2417 for (nOut = 0, ol = def->outlines; ol != NULL((void*)0);
2418 ol = (OutlineDef *) ol->common.next)
2419 {
2420 if (ol->nPoints < 1)
2421 {
2422 SetShapeField(si, XkbAtomGetString(NULL((void*)0), ol->field), NULL((void*)0),
2423 ol->points, info);
2424 continue;
2425 }
2426 outline = NULL((void*)0);
2427 outline = &si->outlines[nOut++];
2428 outline->num_points = ol->nPoints;
2429 outline->corner_radius = si->dfltCornerRadius;
2430 outline->points = uTypedCalloc(ol->nPoints, XkbPointRec)((XkbPointRec *)uCalloc((unsigned)ol->nPoints,(unsigned)sizeof
(XkbPointRec)))
;
2431 if (!outline->points)
2432 {
2433 ERROR1uError("Can't allocate points for \"%s\"\n",
2434 shText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default shape"
)
);
2435 ACTIONuAction("Definition ignored\n");
2436 info->errorCount++;
2437 return False0;
2438 }
2439 for (nPt = 0, pt = ol->points; pt != NULL((void*)0);
2440 pt = (ExprDef *) pt->common.next)
2441 {
2442 outline->points[nPt].x = pt->value.coord.x;
2443 outline->points[nPt].y = pt->value.coord.y;
2444 nPt++;
2445 }
2446 if (ol->field != None0L)
2447 {
2448 char *str = XkbAtomText(NULL((void*)0), ol->field, XkbMessage3);
2449 if ((uStrCaseCmp(str, "approximation")(strcasecmp(str,"approximation")) == 0) ||
2450 (uStrCaseCmp(str, "approx")(strcasecmp(str,"approx")) == 0))
2451 {
2452 if (si->approx == NULL((void*)0))
2453 si->approx = outline;
2454 else
2455 {
2456 WARN1uWarning("Multiple approximations for \"%s\"\n",
2457 shText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default shape"
)
);
2458 ACTIONuAction("Treating all but the first as normal outlines\n");
2459 }
2460 }
2461 else if (uStrCaseCmp(str, "primary")(strcasecmp(str,"primary")) == 0)
2462 {
2463 if (si->primary == NULL((void*)0))
2464 si->primary = outline;
2465 else
2466 {
2467 WARN1uWarning("Multiple primary outlines for \"%s\"\n",
2468 shText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default shape"
)
);
2469 ACTIONuAction("Treating all but the first as normal outlines\n");
2470 }
2471 }
2472 else
2473 {
2474 WARN2uWarning("Unknown outline type %s for \"%s\"\n", str,
2475 shText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default shape"
)
);
2476 ACTIONuAction("Treated as a normal outline\n");
2477 }
2478 }
2479 }
2480 if (nOut != si->nOutlines)
2481 {
2482 WSGO2uInternalError("Expected %d outlines, got %d\n",
2483 (unsigned int) si->nOutlines, nOut);
2484 si->nOutlines = nOut;
2485 }
2486 return True1;
2487}
2488
2489static int
2490HandleShapeDef(ShapeDef * def, XkbDescPtr xkb, unsigned merge,
2491 GeometryInfo * info)
2492{
2493 ShapeInfo si;
2494
2495 if (def->merge != MergeDefault0)
2496 merge = def->merge;
2497
2498 bzero(&si, sizeof(ShapeInfo))memset(&si,0,sizeof(ShapeInfo));
2499 si.defs.merge = merge;
2500 si.name =
2501 XkbInternAtom(info->dpy, XkbAtomGetString(NULL((void*)0), def->name), False0);
2502 si.dfltCornerRadius = info->dfltCornerRadius;
2503 if (!HandleShapeBody(def, &si, merge, info))
2504 return False0;
2505 if (!AddShape(info, &si))
2506 return False0;
2507 return True1;
2508}
2509
2510/***====================================================================***/
2511
2512static int
2513HandleDoodadDef(DoodadDef * def,
2514 unsigned merge, SectionInfo * si, GeometryInfo * info)
2515{
2516 ExprResult elem, field;
2517 ExprDef *ndx;
2518 DoodadInfo new;
2519 VarDef *var;
2520
2521 if (def->common.stmtType == StmtIndicatorMapDef12)
2522 {
2523 def->common.stmtType = StmtDoodadDef21;
2524 def->type = XkbIndicatorDoodad4;
2525 }
2526 InitDoodadInfo(&new, def->type, si, info);
2527 new.name =
2528 XkbInternAtom(info->dpy, XkbAtomGetString(NULL((void*)0), def->name), False0);
2529 for (var = def->body; var != NULL((void*)0); var = (VarDef *) var->common.next)
2530 {
2531 if (ExprResolveLhs(var->name, &elem, &field, &ndx) == 0)
2532 return 0; /* internal error, already reported */
2533 if (elem.str != NULL((void*)0))
2534 {
2535 WARN1uWarning("Assignment to field of unknown element in doodad %s\n",
2536 ddText(info->dpy, &new));
2537 ACTION2uAction("No value assigned to %s.%s\n", elem.str, field.str);
2538 }
2539 else if (!SetDoodadField(&new, field.str, ndx, var->value, si, info))
2540 return False0;
2541 }
2542 if (!AddDoodad(si, info, &new))
2543 return False0;
2544 ClearDoodadInfo(&new);
2545 return True1;
2546}
2547
2548/***====================================================================***/
2549
2550static int
2551HandleOverlayDef(OverlayDef * def,
2552 unsigned merge, SectionInfo * si, GeometryInfo * info)
2553{
2554 OverlayKeyDef *keyDef;
2555 OverlayKeyInfo *key;
2556 OverlayInfo ol;
2557
2558 if ((def->nKeys < 1) && (warningLevel > 3))
1
Taking false branch
2559 {
2560 WARN2uWarning("Overlay \"%s\" in section \"%s\" has no keys\n",
2561 XkbAtomText(NULL((void*)0), def->name, XkbMessage3), scText(info->dpy,((si)?XkbAtomText((info->dpy),(si)->name,3):"default")
2562 si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"));
2563 ACTIONuAction("Overlay ignored\n");
2564 return True1;
2565 }
2566 bzero(&ol, sizeof(OverlayInfo))memset(&ol,0,sizeof(OverlayInfo));
2567 ol.name =
2568 XkbInternAtom(info->dpy, XkbAtomGetString(NULL((void*)0), def->name), False0);
2569 for (keyDef = def->keys; keyDef;
2
Loop condition is true. Entering loop body
2570 keyDef = (OverlayKeyDef *) keyDef->common.next)
2571 {
2572 key = uTypedCalloc(1, OverlayKeyInfo)((OverlayKeyInfo *)uCalloc((unsigned)1,(unsigned)sizeof(OverlayKeyInfo
)))
;
2573 if ((!key) && warningLevel > 0)
3
Assuming 'key' is null
4
Assuming 'warningLevel' is <= 0
5
Taking false branch
2574 {
2575 WSGOuInternalError("Couldn't allocate OverlayKeyInfo\n");
2576 ACTION2uAction("Overlay %s for section %s will be incomplete\n",
2577 XkbAtomText(info->dpy, ol.name, XkbMessage3),
2578 scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"));
2579 return False0;
2580 }
2581 strncpy(key->over, keyDef->over, XkbKeyNameLength4);
2582 strncpy(key->under, keyDef->under, XkbKeyNameLength4);
2583 key->sectionRow = _GOK_UnknownRow-1;
6
Access to field 'sectionRow' results in a dereference of a null pointer (loaded from variable 'key')
2584 key->overlayRow = _GOK_UnknownRow-1;
2585 ol.keys = (OverlayKeyInfo *) AddCommonInfo(&ol.keys->defs,
2586 (CommonInfo *) key);
2587 ol.nKeys++;
2588 }
2589 if (!AddOverlay(si, info, &ol))
2590 return False0;
2591 ClearOverlayInfo(&ol);
2592 return True1;
2593}
2594
2595/***====================================================================***/
2596
2597static Boolint
2598HandleComplexKey(KeyDef * def, KeyInfo * key, GeometryInfo * info)
2599{
2600 RowInfo *row;
2601 ExprDef *expr;
2602
2603 row = key->row;
2604 for (expr = def->expr; expr != NULL((void*)0); expr = (ExprDef *) expr->common.next)
2605 {
2606 if (expr->op == OpAssign24)
2607 {
2608 ExprResult elem, f;
2609 ExprDef *ndx;
2610 if (ExprResolveLhs(expr->value.binary.left, &elem, &f, &ndx) == 0)
2611 return False0; /* internal error, already reported */
2612 if ((elem.str == NULL((void*)0)) || (uStrCaseCmp(elem.str, "key")(strcasecmp(elem.str,"key")) == 0))
2613 {
2614 if (!SetKeyField
2615 (key, f.str, ndx, expr->value.binary.right, info))
2616 return False0;
2617 }
2618 else
2619 {
2620 ERRORuError("Illegal element used in a key definition\n");
2621 ACTION2uAction("Assignment to %s.%s ignored\n", elem.str, f.str);
2622 return False0;
2623 }
2624 }
2625 else
2626 {
2627 switch (expr->type)
2628 {
2629 case TypeInt2:
2630 case TypeFloat3:
2631 if (!SetKeyField(key, "gap", NULL((void*)0), expr, info))
2632 return False0;
2633 break;
2634 case TypeString4:
2635 if (!SetKeyField(key, "shape", NULL((void*)0), expr, info))
2636 return False0;
2637 break;
2638 case TypeKeyName6:
2639 if (!SetKeyField(key, "name", NULL((void*)0), expr, info))
2640 return False0;
2641 break;
2642 default:
2643 ERRORuError("Cannot determine field for unnamed expression\n");
2644 ACTION3uAction("Ignoring key %d in row %d of section %s\n",
2645 row->nKeys + 1, row->section->nRows + 1,
2646 rowText(info->dpy, row)((row)?XkbAtomText((info->dpy),(row)->section->name,
3):"default")
);
2647 return False0;
2648 }
2649 }
2650 }
2651 return True1;
2652}
2653
2654static Boolint
2655HandleRowBody(RowDef * def, RowInfo * row, unsigned merge,
2656 GeometryInfo * info)
2657{
2658 KeyDef *keyDef;
2659
2660 if ((def->nKeys < 1) && (warningLevel > 3))
2661 {
2662 ERROR1uError("Row in section %s has no keys\n", rowText(info->dpy, row)((row)?XkbAtomText((info->dpy),(row)->section->name,
3):"default")
);
2663 ACTIONuAction("Section ignored\n");
2664 return True1;
2665 }
2666 for (keyDef = def->keys; keyDef != NULL((void*)0);
2667 keyDef = (KeyDef *) keyDef->common.next)
2668 {
2669 if (keyDef->common.stmtType == StmtVarDef5)
2670 {
2671 VarDef *var = (VarDef *) keyDef;
2672 ExprResult elem, field;
2673 ExprDef *ndx;
2674 if (ExprResolveLhs(var->name, &elem, &field, &ndx) == 0)
2675 return 0; /* internal error, already reported */
2676 if ((elem.str == NULL((void*)0)) || (uStrCaseCmp(elem.str, "row")(strcasecmp(elem.str,"row")) == 0))
2677 {
2678 if (!SetRowField(row, field.str, ndx, var->value, info))
2679 return False0;
2680 }
2681 else if (uStrCaseCmp(elem.str, "key")(strcasecmp(elem.str,"key")) == 0)
2682 {
2683 if (!SetKeyField
2684 (&row->dfltKey, field.str, ndx, var->value, info))
2685 return False0;
2686 }
2687 else
2688 {
2689 WARNuWarning("Assignment to field of unknown element in row\n");
2690 ACTION2uAction("No value assigned to %s.%s\n", elem.str, field.str);
2691 }
2692 }
2693 else if (keyDef->common.stmtType == StmtKeyDef16)
2694 {
2695 KeyInfo key;
2696 InitKeyInfo(&key, row, info);
2697 if (keyDef->name != NULL((void*)0))
2698 {
2699 int len = strlen(keyDef->name);
2700 if ((len < 1) || (len > XkbKeyNameLength4))
2701 {
2702 ERROR2uError("Illegal name %s for key in section %s\n",
2703 keyDef->name, rowText(info->dpy, row)((row)?XkbAtomText((info->dpy),(row)->section->name,
3):"default")
);
2704 ACTIONuAction("Section not compiled\n");
2705 return False0;
2706 }
2707 bzero(key.name, XkbKeyNameLength + 1)memset(key.name,0,4 + 1);
2708 strncpy(key.name, keyDef->name, XkbKeyNameLength4);
2709 key.defs.defined |= _GK_Name(1<<1);
2710 }
2711 else if (!HandleComplexKey(keyDef, &key, info))
2712 return False0;
2713 if (!AddKey(row, &key))
2714 return False0;
2715 }
2716 else
2717 {
2718 WSGO1uInternalError("Unexpected statement (type %d) in row body\n",
2719 keyDef->common.stmtType);
2720 return False0;
2721 }
2722 }
2723 return True1;
2724}
2725
2726static Boolint
2727HandleSectionBody(SectionDef * def,
2728 SectionInfo * si, unsigned merge, GeometryInfo * info)
2729{
2730 RowDef *rowDef;
2731 DoodadInfo *di;
2732
2733 for (rowDef = def->rows; rowDef != NULL((void*)0);
2734 rowDef = (RowDef *) rowDef->common.next)
2735 {
2736 if (rowDef->common.stmtType == StmtVarDef5)
2737 {
2738 VarDef *var = (VarDef *) rowDef;
2739 ExprResult elem, field;
2740 ExprDef *ndx;
2741 if (ExprResolveLhs(var->name, &elem, &field, &ndx) == 0)
2742 return 0; /* internal error, already reported */
2743 if ((elem.str == NULL((void*)0)) || (uStrCaseCmp(elem.str, "section")(strcasecmp(elem.str,"section")) == 0))
2744 {
2745 if (!SetSectionField(si, field.str, ndx, var->value, info))
2746 return False0;
2747 }
2748 else if (uStrCaseCmp(elem.str, "row")(strcasecmp(elem.str,"row")) == 0)
2749 {
2750 if (!SetRowField
2751 (&si->dfltRow, field.str, ndx, var->value, info))
2752 return False0;
2753 }
2754 else if (uStrCaseCmp(elem.str, "key")(strcasecmp(elem.str,"key")) == 0)
2755 {
2756 if (!SetKeyField(&si->dfltRow.dfltKey, field.str, ndx,
2757 var->value, info))
2758 return False0;
2759 }
2760 else if ((di =
2761 FindDfltDoodadByTypeName(elem.str, si, info)) != NULL((void*)0))
2762 {
2763 if (!SetDoodadField(di, field.str, ndx, var->value, si, info))
2764 return False0;
2765 }
2766 else
2767 {
2768 WARNuWarning("Assignment to field of unknown element in section\n");
2769 ACTION2uAction("No value assigned to %s.%s\n", elem.str, field.str);
2770 }
2771 }
2772 else if (rowDef->common.stmtType == StmtRowDef17)
2773 {
2774 RowInfo row;
2775 InitRowInfo(&row, si, info);
2776 if (!HandleRowBody(rowDef, &row, merge, info))
2777 return False0;
2778 if (!AddRow(si, &row))
2779 return False0;
2780/* ClearRowInfo(&row,info);*/
2781 }
2782 else if ((rowDef->common.stmtType == StmtDoodadDef21) ||
2783 (rowDef->common.stmtType == StmtIndicatorMapDef12))
2784 {
2785 if (!HandleDoodadDef((DoodadDef *) rowDef, merge, si, info))
2786 return False0;
2787 }
2788 else if (rowDef->common.stmtType == StmtOverlayDef20)
2789 {
2790 if (!HandleOverlayDef((OverlayDef *) rowDef, merge, si, info))
2791 return False0;
2792 }
2793 else
2794 {
2795 WSGO1uInternalError("Unexpected statement (type %d) in section body\n",
2796 rowDef->common.stmtType);
2797 return False0;
2798 }
2799 }
2800 if (si->nRows != def->nRows)
2801 {
2802 WSGO2uInternalError("Expected %d rows, found %d\n", (unsigned int) def->nRows,
2803 (unsigned int) si->nRows);
2804 ACTION1uAction("Definition of section %s might be incorrect\n",
2805 scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"));
2806 }
2807 return True1;
2808}
2809
2810static int
2811HandleSectionDef(SectionDef * def,
2812 XkbDescPtr xkb, unsigned merge, GeometryInfo * info)
2813{
2814 SectionInfo si;
2815 char *str;
2816
2817 if (def->merge != MergeDefault0)
2818 merge = def->merge;
2819 InitSectionInfo(&si, info);
2820 si.defs.merge = merge;
2821 str = XkbAtomGetString(NULL((void*)0), def->name);
2822 if ((str == NULL((void*)0)) || (strlen(str) < 1))
2823 {
2824 ERRORuError("Section defined without a name\n");
2825 ACTIONuAction("Definition ignored\n");
2826 return False0;
2827 }
2828 si.name =
2829 XkbInternAtom(info->dpy, XkbAtomGetString(NULL((void*)0), def->name), False0);
2830 if (!HandleSectionBody(def, &si, merge, info))
2831 return False0;
2832 if (!AddSection(info, &si))
2833 return False0;
2834 return True1;
2835}
2836
2837/***====================================================================***/
2838
2839static void
2840HandleGeometryFile(XkbFile * file,
2841 XkbDescPtr xkb, unsigned merge, GeometryInfo * info)
2842{
2843 ParseCommon *stmt;
2844 char *failWhat;
2845
2846 if (merge == MergeDefault0)
2847 merge = MergeAugment1;
2848 info->name = uStringDup(file->name)((file->name) ? strdup(file->name) : ((void*)0));
2849 stmt = file->defs;
2850 while (stmt)
2851 {
2852 failWhat = NULL((void*)0);
2853 switch (stmt->stmtType)
2854 {
2855 case StmtInclude1:
2856 if (!HandleIncludeGeometry((IncludeStmt *) stmt, xkb, info,
2857 HandleGeometryFile))
2858 info->errorCount++;
2859 break;
2860 case StmtKeyAliasDef3:
2861 if (!HandleAliasDef((KeyAliasDef *) stmt,
2862 merge, info->fileID, &info->aliases))
2863 {
2864 info->errorCount++;
2865 }
2866 break;
2867 case StmtVarDef5:
2868 if (!HandleGeometryVar((VarDef *) stmt, xkb, info))
2869 info->errorCount++;
2870 break;
2871 case StmtShapeDef15:
2872 if (!HandleShapeDef((ShapeDef *) stmt, xkb, merge, info))
2873 info->errorCount++;
2874 break;
2875 case StmtSectionDef18:
2876 if (!HandleSectionDef((SectionDef *) stmt, xkb, merge, info))
2877 info->errorCount++;
2878 break;
2879 case StmtIndicatorMapDef12:
2880 case StmtDoodadDef21:
2881 if (!HandleDoodadDef((DoodadDef *) stmt, merge, NULL((void*)0), info))
2882 info->errorCount++;
2883 break;
2884 case StmtVModDef8:
2885 if (!failWhat)
2886 failWhat = "virtual modfier";
2887 case StmtInterpDef7:
2888 if (!failWhat)
2889 failWhat = "symbol interpretation";
2890 case StmtGroupCompatDef11:
2891 if (!failWhat)
2892 failWhat = "group compatibility map";
2893 case StmtKeycodeDef2:
2894 if (!failWhat)
2895 failWhat = "key name";
2896 ERRORuError("Interpretation files may not include other types\n");
2897 ACTION1uAction("Ignoring %s definition.\n", failWhat);
2898 info->errorCount++;
2899 break;
2900 default:
2901 WSGO1uInternalError("Unexpected statement type %d in HandleGeometryFile\n",
2902 stmt->stmtType);
2903 break;
2904 }
2905 stmt = stmt->next;
2906 if (info->errorCount > 10)
2907 {
2908#ifdef NOISY
2909 ERRORuError("Too many errors\n");
2910#endif
2911 ACTION1uAction("Abandoning geometry file \"%s\"\n", file->topName);
2912 break;
2913 }
2914 }
2915 return;
2916}
2917
2918/***====================================================================***/
2919
2920static Boolint
2921CopyShapeDef(Display * dpy, XkbGeometryPtr geom, ShapeInfo * si)
2922{
2923 register int i, n;
2924 XkbShapePtr shape;
2925 XkbOutlinePtr old_outline, outline;
2926 Atom name;
2927
2928 si->index = geom->num_shapes;
2929 name = XkbInternAtom(dpy, XkbAtomGetString(NULL((void*)0), si->name), False0);
2930 shape = XkbAddGeomShape(geom, name, si->nOutlines);
2931 if (!shape)
2932 {
2933 WSGOuInternalError("Couldn't allocate shape in geometry\n");
2934 ACTION1uAction("Shape %s not compiled\n", shText(dpy, si)((si)?XkbAtomText((dpy),(si)->name,3):"default shape"));
2935 return False0;
2936 }
2937 old_outline = si->outlines;
2938 for (i = 0; i < si->nOutlines; i++, old_outline++)
2939 {
2940 outline = XkbAddGeomOutline(shape, old_outline->num_points);
2941 if (!outline)
2942 {
2943 WSGOuInternalError("Couldn't allocate outline in shape\n");
2944 ACTION1uAction("Shape %s is incomplete\n", shText(dpy, si)((si)?XkbAtomText((dpy),(si)->name,3):"default shape"));
2945 return False0;
2946 }
2947 n = old_outline->num_points;
2948 memcpy(outline->points, old_outline->points, n * sizeof(XkbPointRec));
2949 outline->num_points = old_outline->num_points;
2950 outline->corner_radius = old_outline->corner_radius;
2951 }
2952 if (si->approx)
2953 {
2954 n = (si->approx - si->outlines);
2955 shape->approx = &shape->outlines[n];
2956 }
2957 if (si->primary)
2958 {
2959 n = (si->primary - si->outlines);
2960 shape->primary = &shape->outlines[n];
2961 }
2962 XkbComputeShapeBounds(shape);
2963 return True1;
2964}
2965
2966static Boolint
2967VerifyDoodadInfo(DoodadInfo * di, GeometryInfo * info)
2968{
2969 if ((di->defs.defined & (_GD_Top(1<<1) | _GD_Left(1<<2))) != (_GD_Top(1<<1) | _GD_Left(1<<2)))
2970 {
2971 if (warningLevel < 9)
2972 {
2973 ERROR1uError("No position defined for doodad %s\n",
2974 ddText(info->dpy, di));
2975 ACTIONuAction("Illegal doodad ignored\n");
2976 return False0;
2977 }
2978 }
2979 if ((di->defs.defined & _GD_Priority(1<<0)) == 0)
2980 {
2981 /* calculate priority -- should be just above previous doodad/row */
2982 }
2983 switch (di->type)
2984 {
2985 case XkbOutlineDoodad1:
2986 case XkbSolidDoodad2:
2987 if ((di->defs.defined & _GD_Shape(1<<4)) == 0)
2988 {
2989 ERROR2uError("No shape defined for %s doodad %s\n",
2990 (di->type == XkbOutlineDoodad1 ? "outline" : "filled"),
2991 ddText(info->dpy, di));
2992 ACTIONuAction("Incomplete definition ignored\n");
2993 return False0;
2994 }
2995 else
2996 {
2997 ShapeInfo *si;
2998 si = FindShape(info, di->shape,
2999 (di->type ==
3000 XkbOutlineDoodad1 ? "outline doodad" :
3001 "solid doodad"), ddText(info->dpy, di));
3002 if (si)
3003 di->shape = si->name;
3004 else
3005 {
3006 ERROR1uError("No legal shape for %s\n", ddText(info->dpy, di));
3007 ACTIONuAction("Incomplete definition ignored\n");
3008 return False0;
3009 }
3010 }
3011 if ((di->defs.defined & _GD_Color(1<<6)) == 0)
3012 {
3013 if (warningLevel > 5)
3014 {
3015 WARN1uWarning("No color for doodad %s\n", ddText(info->dpy, di));
3016 ACTIONuAction("Using black\n");
3017 }
3018 di->color = XkbInternAtom(NULL((void*)0), "black", False0);
3019 }
3020 break;
3021 case XkbTextDoodad3:
3022 if ((di->defs.defined & _GD_Text(1<<8)) == 0)
3023 {
3024 ERROR1uError("No text specified for text doodad %s\n",
3025 ddText(info->dpy, di));
3026 ACTIONuAction("Illegal doodad definition ignored\n");
3027 return False0;
3028 }
3029 if ((di->defs.defined & _GD_Angle(1<<3)) == 0)
3030 di->angle = 0;
3031 if ((di->defs.defined & _GD_Color(1<<6)) == 0)
3032 {
3033 if (warningLevel > 5)
3034 {
3035 WARN1uWarning("No color specified for doodad %s\n",
3036 ddText(info->dpy, di));
3037 ACTIONuAction("Using black\n");
3038 }
3039 di->color = XkbInternAtom(NULL((void*)0), "black", False0);
3040 }
3041 if ((di->defs.defined & _GD_FontSpec(1<<15)) != 0)
3042 {
3043 if ((di->defs.defined & _GD_FontParts((1<<9)|(1<<10)|(1<<11)|(1<<12)|(1<<
13)|(1<<14)|(1<<4))
) == 0)
3044 return True1;
3045 if (warningLevel < 9)
3046 {
3047 WARN1uWarning
3048 ("Text doodad %s has full and partial font definition\n",
3049 ddText(info->dpy, di));
3050 ACTIONuAction("Full specification ignored\n");
3051 }
3052 di->defs.defined &= ~_GD_FontSpec(1<<15);
3053 di->fontSpec = None0L;
3054 }
3055 if ((di->defs.defined & _GD_Font(1<<9)) == 0)
3056 {
3057 if (warningLevel > 5)
3058 {
3059 WARN1uWarning("No font specified for doodad %s\n",
3060 ddText(info->dpy, di));
3061 ACTION1uAction("Using \"%s\"\n", DFLT_FONT"helvetica");
3062 }
3063 di->font = XkbInternAtom(NULL((void*)0), DFLT_FONT"helvetica", False0);
3064 }
3065 if ((di->defs.defined & _GD_FontSlant(1<<10)) == 0)
3066 {
3067 if (warningLevel > 7)
3068 {
3069 WARN1uWarning("No font slant for text doodad %s\n",
3070 ddText(info->dpy, di));
3071 ACTION1uAction("Using \"%s\"\n", DFLT_SLANT"r");
3072 }
3073 di->fontSlant = XkbInternAtom(NULL((void*)0), DFLT_SLANT"r", False0);
3074 }
3075 if ((di->defs.defined & _GD_FontWeight(1<<11)) == 0)
3076 {
3077 if (warningLevel > 7)
3078 {
3079 WARN1uWarning("No font weight for text doodad %s\n",
3080 ddText(info->dpy, di));
3081 ACTION1uAction("Using \"%s\"\n", DFLT_WEIGHT"medium");
3082 }
3083 di->fontWeight = XkbInternAtom(NULL((void*)0), DFLT_WEIGHT"medium", False0);
3084 }
3085 if ((di->defs.defined & _GD_FontSetWidth(1<<12)) == 0)
3086 {
3087 if (warningLevel > 9)
3088 {
3089 WARN1uWarning("No font set width for text doodad %s\n",
3090 ddText(info->dpy, di));
3091 ACTION1uAction("Using \"%s\"\n", DFLT_SET_WIDTH"normal");
3092 }
3093 di->fontSetWidth = XkbInternAtom(NULL((void*)0), DFLT_SET_WIDTH"normal", False0);
3094 }
3095 if ((di->defs.defined & _GD_FontVariant(1<<4)) == 0)
3096 {
3097 if (warningLevel > 9)
3098 {
3099 WARN1uWarning("No font variant for text doodad %s\n",
3100 ddText(info->dpy, di));
3101 ACTION1uAction("Using \"%s\"\n", DFLT_VARIANT"");
3102 }
3103 di->fontVariant = XkbInternAtom(NULL((void*)0), DFLT_VARIANT"", False0);
3104 }
3105 if ((di->defs.defined & _GD_FontEncoding(1<<14)) == 0)
3106 {
3107 if (warningLevel > 7)
3108 {
3109 WARN1uWarning("No font encoding for doodad %s\n",
3110 ddText(info->dpy, di));
3111 ACTION1uAction("Using \"%s\"\n", DFLT_ENCODING"iso8859-1");
3112 }
3113 di->fontEncoding = XkbInternAtom(NULL((void*)0), DFLT_ENCODING"iso8859-1", False0);
3114 }
3115 if ((di->defs.defined & _GD_FontSize(1<<13)) == 0)
3116 {
3117 if (warningLevel > 7)
3118 {
3119 WARN1uWarning("No font size for text doodad %s\n",
3120 ddText(info->dpy, di));
3121 ACTION1uAction("Using %s point text\n",
3122 XkbGeomFPText(DFLT_SIZE120, XkbMessage3));
3123 }
3124 di->fontSize = DFLT_SIZE120;
3125 }
3126 if ((di->defs.defined & _GD_Height(1<<7)) == 0)
3127 {
3128 unsigned size, nLines;
3129 char *tmp;
3130 size = (di->fontSize * 120) / 100;
3131 size = (size * 254) / 720; /* convert to mm/10 */
3132 for (nLines = 1, tmp = XkbAtomGetString(NULL((void*)0), di->text); *tmp;
3133 tmp++)
3134 {
3135 if (*tmp == '\n')
3136 nLines++;
3137 }
3138 size *= nLines;
3139 if (warningLevel > 5)
3140 {
3141 WARN1uWarning("No height for text doodad %s\n",
3142 ddText(info->dpy, di));
3143 ACTION1uAction("Using calculated height %s millimeters\n",
3144 XkbGeomFPText(size, XkbMessage3));
3145 }
3146 di->height = size;
3147 }
3148 if ((di->defs.defined & _GD_Width(1<<5)) == 0)
3149 {
3150 unsigned width, tmp;
3151 char *str;
3152 width = tmp = 0;
3153 for (str = XkbAtomGetString(NULL((void*)0), di->text); *str; str++)
3154 {
3155 if (*str != '\n')
3156 tmp++;
3157 else
3158 {
3159 if (tmp > width)
3160 width = tmp;
3161 tmp = 1;
3162 }
3163 }
3164 if (width == 0)
3165 width = tmp;
3166 width *= (di->height * 2) / 3;
3167 if (warningLevel > 5)
3168 {
3169 WARN1uWarning("No width for text doodad %s\n", ddText(info->dpy, di));
3170 ACTION1uAction("Using calculated width %s millimeters\n",
3171 XkbGeomFPText(width, XkbMessage3));
3172 }
3173 di->width = width;
3174 }
3175 break;
3176 case XkbIndicatorDoodad4:
3177 if ((di->defs.defined & _GD_Shape(1<<4)) == 0)
3178 {
3179 ERROR1uError("No shape defined for indicator doodad %s\n",
3180 ddText(info->dpy, di));
3181 ACTIONuAction("Incomplete definition ignored\n");
3182 return False0;
3183 }
3184 else
3185 {
3186 ShapeInfo *si;
3187 si = FindShape(info, di->shape, "indicator doodad",
3188 ddText(info->dpy, di));
3189 if (si)
3190 di->shape = si->name;
3191 else
3192 {
3193 ERROR1uError("No legal shape for doodad %s\n",
3194 ddText(info->dpy, di));
3195 ACTIONuAction("Incomplete definition ignored\n");
3196 return False0;
3197 }
3198 }
3199 if ((di->defs.defined & _GD_Color(1<<6)) == 0)
3200 {
3201 if (warningLevel > 5)
3202 {
3203 WARN1uWarning("No \"on\" color for indicator doodad %s\n",
3204 ddText(info->dpy, di));
3205 ACTIONuAction("Using green\n");
3206 }
3207 di->color = XkbInternAtom(NULL((void*)0), "green", False0);
3208 }
3209 if ((di->defs.defined & _GD_OffColor(1<<7)) == 0)
3210 {
3211 if (warningLevel > 5)
3212 {
3213 WARN1uWarning("No \"off\" color for indicator doodad %s\n",
3214 ddText(info->dpy, di));
3215 ACTIONuAction("Using black\n");
3216 }
3217 di->offColor = XkbInternAtom(NULL((void*)0), "black", False0);
3218 }
3219 break;
3220 case XkbLogoDoodad5:
3221 if (di->logoName == NULL((void*)0))
3222 {
3223 ERROR1uError("No logo name defined for logo doodad %s\n",
3224 ddText(info->dpy, di));
3225 ACTIONuAction("Incomplete definition ignored\n");
3226 return False0;
3227 }
3228 if ((di->defs.defined & _GD_Shape(1<<4)) == 0)
3229 {
3230 ERROR1uError("No shape defined for logo doodad %s\n",
3231 ddText(info->dpy, di));
3232 ACTIONuAction("Incomplete definition ignored\n");
3233 return False0;
3234 }
3235 else
3236 {
3237 ShapeInfo *si;
3238 si = FindShape(info, di->shape, "logo doodad",
3239 ddText(info->dpy, di));
3240 if (si)
3241 di->shape = si->name;
3242 else
3243 {
3244 ERROR1uError("No legal shape for %s\n", ddText(info->dpy, di));
3245 ACTIONuAction("Incomplete definition ignored\n");
3246 return False0;
3247 }
3248 }
3249 if ((di->defs.defined & _GD_Color(1<<6)) == 0)
3250 {
3251 if (warningLevel > 5)
3252 {
3253 WARN1uWarning("No color for doodad %s\n", ddText(info->dpy, di));
3254 ACTIONuAction("Using black\n");
3255 }
3256 di->color = XkbInternAtom(NULL((void*)0), "black", False0);
3257 }
3258 break;
3259 default:
3260 WSGO1uInternalError("Uknown doodad type %d in VerifyDoodad\n",
3261 (unsigned int) di->type);
3262 return False0;
3263 }
3264 return True1;
3265}
3266
3267#define FONT_TEMPLATE"-*-%s-%s-%s-%s-%s-*-%d-*-*-*-*-%s" "-*-%s-%s-%s-%s-%s-*-%d-*-*-*-*-%s"
3268
3269static char *
3270FontFromParts(Atom fontTok,
3271 Atom weightTok,
3272 Atom slantTok,
3273 Atom setWidthTok, Atom varTok, int size, Atom encodingTok)
3274{
3275 int totalSize;
3276 char *font, *weight, *slant, *setWidth, *variant, *encoding;
3277 char *rtrn;
3278
3279 font = (fontTok != None0L ? XkbAtomGetString(NULL((void*)0), fontTok) : DFLT_FONT"helvetica");
3280 weight =
3281 (weightTok != None0L ? XkbAtomGetString(NULL((void*)0), weightTok) : DFLT_WEIGHT"medium");
3282 slant =
3283 (slantTok != None0L ? XkbAtomGetString(NULL((void*)0), slantTok) : DFLT_SLANT"r");
3284 setWidth =
3285 (setWidthTok !=
3286 None0L ? XkbAtomGetString(NULL((void*)0), setWidthTok) : DFLT_SET_WIDTH"normal");
3287 variant =
3288 (varTok != None0L ? XkbAtomGetString(NULL((void*)0), varTok) : DFLT_VARIANT"");
3289 encoding =
3290 (encodingTok !=
3291 None0L ? XkbAtomGetString(NULL((void*)0), encodingTok) : DFLT_ENCODING"iso8859-1");
3292 if (size == 0)
3293 size = DFLT_SIZE120;
3294 totalSize =
3295 strlen(FONT_TEMPLATE"-*-%s-%s-%s-%s-%s-*-%d-*-*-*-*-%s") + strlen(font) + strlen(weight) + strlen(slant);
3296 totalSize += strlen(setWidth) + strlen(variant) + strlen(encoding);
3297 rtrn = uCalloc(totalSize, 1);
3298 if (rtrn)
3299 {
3300 sprintf(rtrn, FONT_TEMPLATE"-*-%s-%s-%s-%s-%s-*-%d-*-*-*-*-%s", font, weight, slant, setWidth, variant,
3301 size, encoding);
3302 }
3303 return rtrn;
3304}
3305
3306static Boolint
3307CopyDoodadDef(XkbGeometryPtr geom,
3308 XkbSectionPtr section, DoodadInfo * di, GeometryInfo * info)
3309{
3310 Atom name;
3311 XkbDoodadPtr doodad;
3312 XkbColorPtr color;
3313 XkbShapePtr shape;
3314 ShapeInfo *si;
3315
3316 if (!VerifyDoodadInfo(di, info))
3317 return False0;
3318 name = XkbInternAtom(NULL((void*)0), XkbAtomGetString(NULL((void*)0), di->name), False0);
3319 doodad = XkbAddGeomDoodad(geom, section, name);
3320 if (!doodad)
3321 {
3322 WSGO1uInternalError("Couldn't allocate doodad in %s\n",
3323 (section ? "section" : "geometry"));
3324 ACTION1uAction("Cannot copy doodad %s\n", ddText(info->dpy, di));
3325 return False0;
3326 }
3327 doodad->any.type = di->type;
3328 doodad->any.priority = di->priority;
3329 doodad->any.top = di->top;
3330 doodad->any.left = di->left;
3331 switch (di->type)
3332 {
3333 case XkbOutlineDoodad1:
3334 case XkbSolidDoodad2:
3335 si = FindShape(info, di->shape, NULL((void*)0), NULL((void*)0));
3336 if (!si)
3337 return False0;
3338 doodad->shape.angle = di->angle;
3339 color =
3340 XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), di->color),
3341 geom->num_colors);
3342 shape = &geom->shapes[si->index];
3343 XkbSetShapeDoodadColor(geom, &doodad->shape, color)((&doodad->shape)->color_ndx= (color)-&(geom)->
colors[0])
;
3344 XkbSetShapeDoodadShape(geom, &doodad->shape, shape)((&doodad->shape)->shape_ndx= (shape)-&(geom)->
shapes[0])
;
3345 break;
3346 case XkbTextDoodad3:
3347 doodad->text.angle = di->angle;
3348 doodad->text.width = di->width;
3349 doodad->text.height = di->height;
3350 if (di->fontSpec == None0L)
3351 doodad->text.font = FontFromParts(di->font, di->fontWeight,
3352 di->fontSlant,
3353 di->fontSetWidth,
3354 di->fontVariant, di->fontSize,
3355 di->fontEncoding);
3356 else
3357 doodad->text.font = XkbAtomGetString(NULL((void*)0), di->fontSpec);
3358 doodad->text.text = XkbAtomGetString(NULL((void*)0), di->text);
3359 color =
3360 XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), di->color),
3361 geom->num_colors);
3362 XkbSetTextDoodadColor(geom, &doodad->text, color)((&doodad->text)->color_ndx= (color)-&(geom)->
colors[0])
;
3363 break;
3364 case XkbIndicatorDoodad4:
3365 si = FindShape(info, di->shape, NULL((void*)0), NULL((void*)0));
3366 if (!si)
3367 return False0;
3368 shape = &geom->shapes[si->index];
3369 color =
3370 XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), di->color),
3371 geom->num_colors);
3372 XkbSetIndicatorDoodadShape(geom, &doodad->indicator, shape)((&doodad->indicator)->shape_ndx= (shape)-&(geom
)->shapes[0])
;
3373 XkbSetIndicatorDoodadOnColor(geom, &doodad->indicator, color)((&doodad->indicator)->on_color_ndx= (color)-&(
geom)->colors[0])
;
3374 color =
3375 XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), di->offColor),
3376 geom->num_colors);
3377 XkbSetIndicatorDoodadOffColor(geom, &doodad->indicator, color)((&doodad->indicator)->off_color_ndx= (color)-&
(geom)->colors[0])
;
3378 break;
3379 case XkbLogoDoodad5:
3380 si = FindShape(info, di->shape, NULL((void*)0), NULL((void*)0));
3381 if (!si)
3382 return False0;
3383 doodad->logo.angle = di->angle;
3384 color =
3385 XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), di->color),
3386 geom->num_colors);
3387 shape = &geom->shapes[si->index];
3388 XkbSetLogoDoodadColor(geom, &doodad->logo, color)((&doodad->logo)->color_ndx= (color)-&(geom)->
colors[0])
;
3389 XkbSetLogoDoodadShape(geom, &doodad->logo, shape)((&doodad->logo)->shape_ndx= (shape)-&(geom)->
shapes[0])
;
3390 doodad->logo.logo_name = di->logoName;
3391 di->logoName = NULL((void*)0);
3392 break;
3393 }
3394 return True1;
3395}
3396
3397/***====================================================================***/
3398
3399static Boolint
3400VerifyOverlayInfo(XkbGeometryPtr geom,
3401 XkbSectionPtr section,
3402 OverlayInfo * oi,
3403 GeometryInfo * info, short rowMap[256], short rowSize[256])
3404{
3405 register OverlayKeyInfo *ki, *next;
3406 unsigned long oKey, uKey, sKey;
3407 XkbRowPtr row;
3408 XkbKeyPtr key;
3409 int r, k;
3410
3411 /* find out which row each key is in */
3412 for (ki = oi->keys; ki != NULL((void*)0); ki = (OverlayKeyInfo *) ki->defs.next)
3413 {
3414 oKey = KeyNameToLong(ki->over)((((unsigned long)ki->over[0])<<24)|(((unsigned long
)ki->over[1])<<16)|(((unsigned long)ki->over[2])<<
8)|ki->over[3])
;
3415 uKey = KeyNameToLong(ki->under)((((unsigned long)ki->under[0])<<24)|(((unsigned long
)ki->under[1])<<16)|(((unsigned long)ki->under[2]
)<<8)|ki->under[3])
;
3416 for (r = 0, row = section->rows; (r < section->num_rows) && oKey;
3417 r++, row++)
3418 {
3419 for (k = 0, key = row->keys; (k < row->num_keys) && oKey;
3420 k++, key++)
3421 {
3422 sKey = KeyNameToLong(key->name.name)((((unsigned long)key->name.name[0])<<24)|(((unsigned
long)key->name.name[1])<<16)|(((unsigned long)key->
name.name[2])<<8)|key->name.name[3])
;
3423 if (sKey == oKey)
3424 {
3425 if (warningLevel > 0)
3426 {
3427 WARN3uWarning
3428 ("Key %s in section \"%s\" and overlay \"%s\"\n",
3429 XkbKeyNameText(key->name.name,
3430 XkbMessage3),
3431 XkbAtomText(info->dpy, section->name,
3432 XkbMessage3),
3433 XkbAtomText(info->dpy, oi->name, XkbMessage3));
3434 ACTIONuAction("Overlay definition ignored\n");
3435 }
3436 oKey = 0;
3437 }
3438 else if (sKey == uKey)
3439 {
3440 ki->sectionRow = r;
3441 oKey = 0;
3442 }
3443 }
3444 }
3445 if ((ki->sectionRow == _GOK_UnknownRow-1) && (warningLevel > 0))
3446 {
3447 WARN3uWarning
3448 ("Key %s not in \"%s\", but has an overlay key in \"%s\"\n",
3449 XkbKeyNameText(ki->under, XkbMessage3),
3450 XkbAtomText(info->dpy, section->name, XkbMessage3),
3451 XkbAtomText(info->dpy, oi->name, XkbMessage3));
3452 ACTIONuAction("Definition ignored\n");
3453 }
3454 }
3455 /* now prune out keys that aren't in the section */
3456 while ((oi->keys != NULL((void*)0)) && (oi->keys->sectionRow == _GOK_UnknownRow-1))
3457 {
3458 next = (OverlayKeyInfo *) oi->keys->defs.next;
3459 uFree(oi->keys);
3460 oi->keys = next;
3461 oi->nKeys--;
3462 }
3463 for (ki = oi->keys; (ki != NULL((void*)0)) && (ki->defs.next != NULL((void*)0)); ki = next)
3464 {
3465 next = (OverlayKeyInfo *) ki->defs.next;
3466 if (next->sectionRow == _GOK_UnknownRow-1)
3467 {
3468 ki->defs.next = next->defs.next;
3469 oi->nKeys--;
3470 uFree(next);
3471 next = (OverlayKeyInfo *) ki->defs.next;
3472 }
3473 }
3474 if (oi->nKeys < 1)
3475 {
3476 ERROR2uError("Overlay \"%s\" for section \"%s\" has no legal keys\n",
3477 XkbAtomText(info->dpy, oi->name, XkbMessage3),
3478 XkbAtomText(info->dpy, section->name, XkbMessage3));
3479 ACTIONuAction("Overlay definition ignored\n");
3480 return False0;
3481 }
3482 /* now figure out how many rows are defined for the overlay */
3483 bzero(rowSize, sizeof(short) * 256)memset(rowSize,0,sizeof(short) * 256);
3484 for (k = 0; k < 256; k++)
3485 {
3486 rowMap[k] = -1;
3487 }
3488 oi->nRows = 0;
3489 for (ki = oi->keys; ki != NULL((void*)0); ki = (OverlayKeyInfo *) ki->defs.next)
3490 {
3491 if (rowMap[ki->sectionRow] == -1)
3492 rowMap[ki->sectionRow] = oi->nRows++;
3493 ki->overlayRow = rowMap[ki->sectionRow];
3494 rowSize[ki->overlayRow]++;
3495 }
3496 return True1;
3497}
3498
3499static Boolint
3500CopyOverlayDef(XkbGeometryPtr geom,
3501 XkbSectionPtr section, OverlayInfo * oi, GeometryInfo * info)
3502{
3503 Atom name;
3504 XkbOverlayPtr ol;
3505 XkbOverlayRowPtr row;
3506 XkbOverlayKeyPtr key;
3507 OverlayKeyInfo *ki;
3508 short rowMap[256], rowSize[256];
3509 int i;
3510
3511 if (!VerifyOverlayInfo(geom, section, oi, info, rowMap, rowSize))
3512 return False0;
3513 name = XkbInternAtom(NULL((void*)0), XkbAtomGetString(NULL((void*)0), oi->name), False0);
3514 ol = XkbAddGeomOverlay(section, name, oi->nRows);
3515 if (!ol)
3516 {
3517 WSGO2uInternalError("Couldn't add overlay \"%s\" to section \"%s\"\n",
3518 XkbAtomText(info->dpy, name, XkbMessage3),
3519 XkbAtomText(info->dpy, section->name, XkbMessage3));
3520 return False0;
3521 }
3522 for (i = 0; i < oi->nRows; i++)
3523 {
3524 int tmp, row_under;
3525 for (tmp = 0, row_under = -1;
3526 (tmp < section->num_rows) && (row_under < 0); tmp++)
3527 {
3528 if (rowMap[tmp] == i)
3529 row_under = tmp;
3530 }
3531 if (!XkbAddGeomOverlayRow(ol, row_under, rowSize[i]))
3532 {
3533 WSGO3uInternalError
3534 ("Can't add row %d to overlay \"%s\" of section \"%s\"\n",
3535 i, XkbAtomText(info->dpy, name, XkbMessage3),
3536 XkbAtomText(info->dpy, section->name, XkbMessage3));
3537 return False0;
3538 }
3539 }
3540 for (ki = oi->keys; ki != NULL((void*)0); ki = (OverlayKeyInfo *) ki->defs.next)
3541 {
3542 row = &ol->rows[ki->overlayRow];
3543 key = &row->keys[row->num_keys++];
3544 bzero(key, sizeof(XkbOverlayKeyRec))memset(key,0,sizeof(XkbOverlayKeyRec));
3545 strncpy(key->over.name, ki->over, XkbKeyNameLength4);
3546 strncpy(key->under.name, ki->under, XkbKeyNameLength4);
3547 }
3548 return True1;
3549}
3550
3551/***====================================================================***/
3552
3553static Boolint
3554CopySectionDef(XkbGeometryPtr geom, SectionInfo * si, GeometryInfo * info)
3555{
3556 XkbSectionPtr section;
3557 XkbRowPtr row;
3558 XkbKeyPtr key;
3559 KeyInfo *ki;
3560 RowInfo *ri;
3561 Atom name;
3562
3563 name = XkbInternAtom(NULL((void*)0), XkbAtomGetString(NULL((void*)0), si->name), False0);
3564 section =
3565 XkbAddGeomSection(geom, name, si->nRows, si->nDoodads, si->nOverlays);
3566 if (section == NULL((void*)0))
3567 {
3568 WSGOuInternalError("Couldn't allocate section in geometry\n");
3569 ACTION1uAction("Section %s not compiled\n", scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"));
3570 return False0;
3571 }
3572 section->top = si->top;
3573 section->left = si->left;
3574 section->width = si->width;
3575 section->height = si->height;
3576 section->angle = si->angle;
3577 section->priority = si->priority;
3578 for (ri = si->rows; ri != NULL((void*)0); ri = (RowInfo *) ri->defs.next)
3579 {
3580 row = XkbAddGeomRow(section, ri->nKeys);
3581 if (row == NULL((void*)0))
3582 {
3583 WSGOuInternalError("Couldn't allocate row in section\n");
3584 ACTION1uAction("Section %s is incomplete\n", scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"));
3585 return False0;
3586 }
3587 row->top = ri->top;
3588 row->left = ri->left;
3589 row->vertical = ri->vertical;
3590 for (ki = ri->keys; ki != NULL((void*)0); ki = (KeyInfo *) ki->defs.next)
3591 {
3592 XkbColorPtr color;
3593 if ((ki->defs.defined & _GK_Name(1<<1)) == 0)
3594 {
3595 ERROR3uError("Key %d of row %d in section %s has no name\n",
3596 (int) ki->index, (int) ri->index,
3597 scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"));
3598 ACTION1uAction("Section %s ignored\n", scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"));
3599 return False0;
3600 }
3601 key = XkbAddGeomKey(row);
3602 if (key == NULL((void*)0))
3603 {
3604 WSGOuInternalError("Couldn't allocate key in row\n");
3605 ACTION1uAction("Section %s is incomplete\n", scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default"));
3606 return False0;
3607 }
3608 memcpy(key->name.name, ki->name, XkbKeyNameLength4);
3609 key->gap = ki->gap;
3610 if (ki->shape == None0L)
3611 key->shape_ndx = 0;
3612 else
3613 {
3614 ShapeInfo *sinfo;
3615 sinfo = FindShape(info, ki->shape, "key", keyText(ki)((ki)&&(ki)->name[0]?(ki)->name:"default"));
3616 if (!sinfo)
3617 return False0;
3618 key->shape_ndx = sinfo->index;
3619 }
3620 if (ki->color != None0L)
3621 color =
3622 XkbAddGeomColor(geom,
3623 XkbAtomGetString(NULL((void*)0), ki->color),
3624 geom->num_colors);
3625 else
3626 color = XkbAddGeomColor(geom, "white", geom->num_colors);
3627 XkbSetKeyColor(geom, key, color)((key)->color_ndx= (color)-&(geom)->colors[0]);
3628 }
3629 }
3630 if (si->doodads != NULL((void*)0))
3631 {
3632 DoodadInfo *di;
3633 for (di = si->doodads; di != NULL((void*)0); di = (DoodadInfo *) di->defs.next)
3634 {
3635 CopyDoodadDef(geom, section, di, info);
3636 }
3637 }
3638 if (si->overlays != NULL((void*)0))
3639 {
3640 OverlayInfo *oi;
3641 for (oi = si->overlays; oi != NULL((void*)0);
3642 oi = (OverlayInfo *) oi->defs.next)
3643 {
3644 CopyOverlayDef(geom, section, oi, info);
3645 }
3646 }
3647 if (XkbComputeSectionBounds(geom, section))
3648 {
3649 /* 7/6/94 (ef) -- check for negative origin and translate */
3650 if ((si->defs.defined & _GS_Width(1<<4)) == 0)
3651 section->width = section->bounds.x2;
3652 if ((si->defs.defined & _GS_Height(1<<5)) == 0)
3653 section->height = section->bounds.y2;
3654 }
3655 return True1;
3656}
3657
3658/***====================================================================***/
3659
3660Boolint
3661CompileGeometry(XkbFile * file, XkbFileInfo * result, unsigned merge)
3662{
3663 GeometryInfo info;
3664 XkbDescPtr xkb;
3665
3666 xkb = result->xkb;
3667 InitGeometryInfo(&info, file->id, merge);
3668 info.dpy = xkb->dpy;
3669 HandleGeometryFile(file, xkb, merge, &info);
3670
3671 if (info.errorCount == 0)
3672 {
3673 XkbGeometryPtr geom;
3674 XkbGeometrySizesRec sizes;
3675 bzero(&sizes, sizeof(sizes))memset(&sizes,0,sizeof(sizes));
3676 sizes.which = XkbGeomAllMask(0x3f);
3677 sizes.num_properties = info.nProps;
3678 sizes.num_colors = 8;
3679 sizes.num_shapes = info.nShapes;
3680 sizes.num_sections = info.nSections;
3681 sizes.num_doodads = info.nDoodads;
3682 if (XkbAllocGeometry(xkb, &sizes) != Success0)
3683 {
3684 WSGOuInternalError("Couldn't allocate GeometryRec\n");
3685 ACTIONuAction("Geometry not compiled\n");
3686 return False0;
3687 }
3688 geom = xkb->geom;
3689
3690 geom->width_mm = info.widthMM;
3691 geom->height_mm = info.heightMM;
3692 if (info.name != NULL((void*)0))
3693 {
3694 geom->name = XkbInternAtom(xkb->dpy, info.name, False0);
3695 if (XkbAllocNames(xkb, XkbGeometryNameMask(1<<1), 0, 0) == Success0)
3696 xkb->names->geometry = geom->name;
3697 }
3698 if (info.fontSpec != None0L)
3699 geom->label_font =
3700 uStringDup(XkbAtomGetString(NULL, info.fontSpec))((XkbAtomGetString(((void*)0), info.fontSpec)) ? strdup(XkbAtomGetString
(((void*)0), info.fontSpec)) : ((void*)0))
;
3701 else
3702 geom->label_font = FontFromParts(info.font, info.fontWeight,
3703 info.fontSlant,
3704 info.fontSetWidth,
3705 info.fontVariant,
3706 info.fontSize,
3707 info.fontEncoding);
3708 XkbAddGeomColor(geom, "black", geom->num_colors);
3709 XkbAddGeomColor(geom, "white", geom->num_colors);
3710
3711 if (info.baseColor == None0L)
3712 info.baseColor = XkbInternAtom(NULL((void*)0), "white", False0);
3713 if (info.labelColor == None0L)
3714 info.labelColor = XkbInternAtom(NULL((void*)0), "black", False0);
3715 geom->base_color =
3716 XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), info.baseColor),
3717 geom->num_colors);
3718 geom->label_color =
3719 XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), info.labelColor),
3720 geom->num_colors);
3721
3722 if (info.props)
3723 {
3724 PropertyInfo *pi;
3725 for (pi = info.props; pi != NULL((void*)0);
3726 pi = (PropertyInfo *) pi->defs.next)
3727 {
3728 if (!XkbAddGeomProperty(geom, pi->name, pi->value))
3729 return False0;
3730 }
3731 }
3732 if (info.shapes)
3733 {
3734 ShapeInfo *si;
3735 for (si = info.shapes; si != NULL((void*)0);
3736 si = (ShapeInfo *) si->defs.next)
3737 {
3738 if (!CopyShapeDef(xkb->dpy, geom, si))
3739 return False0;
3740 }
3741 }
3742 if (info.sections)
3743 {
3744 SectionInfo *si;
3745 for (si = info.sections; si != NULL((void*)0);
3746 si = (SectionInfo *) si->defs.next)
3747 {
3748 if (!CopySectionDef(geom, si, &info))
3749 return False0;
3750 }
3751 }
3752 if (info.doodads)
3753 {
3754 DoodadInfo *di;
3755 for (di = info.doodads; di != NULL((void*)0);
3756 di = (DoodadInfo *) di->defs.next)
3757 {
3758 if (!CopyDoodadDef(geom, NULL((void*)0), di, &info))
3759 return False0;
3760 }
3761 }
3762 if (info.aliases)
3763 ApplyAliases(xkb, True1, &info.aliases);
3764 ClearGeometryInfo(&info);
3765 return True1;
3766 }
3767 return False0;
3768}