File: | geometry.c |
Location: | line 2645, column 41 |
Description: | Access to field 'section' results in a dereference of a null pointer (loaded from variable 'row') |
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 | |||||
47 | typedef 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) | ||||
57 | typedef 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 | |||||
96 | typedef 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) | ||||
133 | typedef 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) | ||||
149 | typedef 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 | ||||
165 | typedef 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 | |||||
174 | typedef 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) | ||||
192 | typedef 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 | |||||
215 | typedef 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 | |||||
249 | static char * | ||||
250 | ddText(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 | |||||
271 | static void | ||||
272 | InitPropertyInfo(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 | |||||
281 | static void | ||||
282 | FreeProperties(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 | |||||
305 | static void | ||||
306 | InitKeyInfo(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 | |||||
328 | static void | ||||
329 | ClearKeyInfo(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 | |||||
339 | static void | ||||
340 | FreeKeys(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 | |||||
359 | static void | ||||
360 | InitRowInfo(RowInfo * row, SectionInfo * section, GeometryInfo * info) | ||||
361 | { | ||||
362 | if (row != §ion->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 | |||||
382 | static void | ||||
383 | ClearRowInfo(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 | |||||
396 | static void | ||||
397 | FreeRows(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 | |||||
416 | static DoodadInfo * | ||||
417 | FindDoodadByType(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 | |||||
428 | static DoodadInfo * | ||||
429 | FindDoodadByName(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 | |||||
440 | static void | ||||
441 | InitDoodadInfo(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 | |||||
480 | static void | ||||
481 | ClearDoodadInfo(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 | |||||
492 | static void | ||||
493 | ClearOverlayInfo(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 | |||||
503 | static void | ||||
504 | FreeDoodads(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 | |||||
535 | static void | ||||
536 | InitSectionInfo(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 | |||||
560 | static void | ||||
561 | DupSectionInfo(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 | |||||
581 | static void | ||||
582 | ClearSectionInfo(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 | |||||
605 | static void | ||||
606 | FreeSections(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 | |||||
625 | static void | ||||
626 | FreeShapes(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 | |||||
664 | static void | ||||
665 | InitGeometryInfo(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 | |||||
675 | static void | ||||
676 | ClearGeometryInfo(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 | |||||
699 | static PropertyInfo * | ||||
700 | NextProperty(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 | |||||
715 | static PropertyInfo * | ||||
716 | FindProperty(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 | |||||
731 | static Boolint | ||||
732 | AddProperty(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 | |||||
777 | static ShapeInfo * | ||||
778 | NextShape(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 | |||||
794 | static ShapeInfo * | ||||
795 | FindShape(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 | |||||
821 | static Boolint | ||||
822 | AddShape(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 | |||||
866 | static void | ||||
867 | ReplaceDoodad(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 | |||||
881 | static DoodadInfo * | ||||
882 | NextDfltDoodad(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 | |||||
904 | static DoodadInfo * | ||||
905 | NextDoodad(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 | |||||
929 | static Boolint | ||||
930 | AddDoodad(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 | |||||
969 | static DoodadInfo * | ||||
970 | FindDfltDoodadByTypeName(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 | |||||
1007 | static Boolint | ||||
1008 | AddOverlay(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 | |||||
1074 | static SectionInfo * | ||||
1075 | NextSection(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 | |||||
1095 | static SectionInfo * | ||||
1096 | FindMatchingSection(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 | |||||
1109 | static Boolint | ||||
1110 | AddSection(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 | |||||
1166 | static RowInfo * | ||||
1167 | NextRow(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 | |||||
1186 | static Boolint | ||||
1187 | AddRow(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 | |||||
1203 | static KeyInfo * | ||||
1204 | NextKey(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 | |||||
1219 | static Boolint | ||||
1220 | AddKey(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 | |||||
1236 | static void | ||||
1237 | MergeIncludedGeometry(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 | |||||
1325 | typedef void (*FileHandler) (XkbFile * /* file */ , | ||||
1326 | XkbDescPtr /* xkb */ , | ||||
1327 | unsigned /* merge */ , | ||||
1328 | GeometryInfo * /* info */ | ||||
1329 | ); | ||||
1330 | |||||
1331 | static Boolint | ||||
1332 | HandleIncludeGeometry(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 | |||||
1409 | static int | ||||
1410 | SetShapeField(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 | |||||
1441 | static int | ||||
1442 | SetShapeDoodadField(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 | |||||
1511 | static int | ||||
1512 | SetTextDoodadField(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 | |||||
1661 | static int | ||||
1662 | SetIndicatorDoodadField(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 | |||||
1706 | static int | ||||
1707 | SetLogoDoodadField(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 | |||||
1787 | static int | ||||
1788 | SetDoodadField(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 | |||||
1890 | static int | ||||
1891 | SetSectionField(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 | |||||
1978 | static int | ||||
1979 | SetRowField(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 | |||||
2044 | static int | ||||
2045 | SetKeyField(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 | |||||
2122 | static int | ||||
2123 | SetGeometryProperty(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 | |||||
2141 | static int | ||||
2142 | HandleGeometryVar(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 | |||||
2392 | static Boolint | ||||
2393 | HandleShapeBody(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 | |||||
2489 | static int | ||||
2490 | HandleShapeDef(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 | |||||
2512 | static int | ||||
2513 | HandleDoodadDef(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 | |||||
2550 | static int | ||||
2551 | HandleOverlayDef(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)) | ||||
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; | ||||
2570 | keyDef = (OverlayKeyDef *) keyDef->common.next) | ||||
2571 | { | ||||
2572 | key = uTypedCalloc(1, OverlayKeyInfo)((OverlayKeyInfo *)uCalloc((unsigned)1,(unsigned)sizeof(OverlayKeyInfo ))); | ||||
2573 | if ((!key) && warningLevel > 0) | ||||
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; | ||||
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 | |||||
2597 | static Boolint | ||||
2598 | HandleComplexKey(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 | |||||
2654 | static Boolint | ||||
2655 | HandleRowBody(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 | |||||
2726 | static Boolint | ||||
2727 | HandleSectionBody(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 | |||||
2810 | static int | ||||
2811 | HandleSectionDef(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 | |||||
2839 | static void | ||||
2840 | HandleGeometryFile(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 | |||||
2920 | static Boolint | ||||
2921 | CopyShapeDef(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 | |||||
2966 | static Boolint | ||||
2967 | VerifyDoodadInfo(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 | |||||
3269 | static char * | ||||
3270 | FontFromParts(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 | |||||
3306 | static Boolint | ||||
3307 | CopyDoodadDef(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 | |||||
3399 | static Boolint | ||||
3400 | VerifyOverlayInfo(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 | |||||
3499 | static Boolint | ||||
3500 | CopyOverlayDef(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 | |||||
3553 | static Boolint | ||||
3554 | CopySectionDef(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 | |||||
3660 | Boolint | ||||
3661 | CompileGeometry(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 | } |