File: | geometry.c |
Location: | line 2531, column 20 |
Description: | Potential leak of memory pointed to by 'new.logoName' |
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")__builtin___strcpy_chk (buf, "default", __builtin_object_size (buf, 2 > 1 ? 1 : 0)); | |||
257 | return buf; | |||
258 | } | |||
259 | if (di->section) | |||
260 | { | |||
261 | snprintf(buf, sizeof(buf), "%s in section %s",__builtin___snprintf_chk (buf, sizeof(buf), 0, __builtin_object_size (buf, 2 > 1 ? 1 : 0), "%s in section %s", XkbAtomText(dpy , di->name, 3), ((di->section)?XkbAtomText((dpy),(di-> section)->name,3):"default")) | |||
262 | XkbAtomText(dpy, di->name, XkbMessage),__builtin___snprintf_chk (buf, sizeof(buf), 0, __builtin_object_size (buf, 2 > 1 ? 1 : 0), "%s in section %s", XkbAtomText(dpy , di->name, 3), ((di->section)?XkbAtomText((dpy),(di-> section)->name,3):"default")) | |||
263 | scText(dpy, di->section))__builtin___snprintf_chk (buf, sizeof(buf), 0, __builtin_object_size (buf, 2 > 1 ? 1 : 0), "%s in section %s", XkbAtomText(dpy , di->name, 3), ((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")__builtin___strcpy_chk (key->name, "unknown", __builtin_object_size (key->name, 2 > 1 ? 1 : 0)); | |||
313 | key->defs.defined &= ~_GK_Default(1<<0); | |||
314 | } | |||
315 | else | |||
316 | { | |||
317 | bzero(key, sizeof(KeyInfo))__builtin___memset_chk (key, 0, sizeof(KeyInfo), __builtin_object_size (key, 0)); | |||
318 | strcpy(key->name, "default")__builtin___strcpy_chk (key->name, "default", __builtin_object_size (key->name, 2 > 1 ? 1 : 0)); | |||
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")__builtin___strcpy_chk (key->name, "default", __builtin_object_size (key->name, 2 > 1 ? 1 : 0)); | |||
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))__builtin___memset_chk (row, 0, sizeof(*row), __builtin_object_size (row, 0)); | |||
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))__builtin___memset_chk (di, 0, sizeof(DoodadInfo), __builtin_object_size (di, 0)); | |||
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))__builtin___memset_chk (di, 0, sizeof(DoodadInfo), __builtin_object_size (di, 0)); | |||
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))__builtin___memset_chk (si, 0, sizeof(SectionInfo), __builtin_object_size (si, 0)); | |||
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))__builtin___memset_chk (info, 0, sizeof(GeometryInfo), __builtin_object_size (info, 0)); | |||
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))__builtin___memset_chk ((char *) pi, 0, sizeof(PropertyInfo), __builtin_object_size ((char *) pi, 0)); | |||
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))__builtin___memset_chk ((char *) si, 0, sizeof(ShapeInfo), __builtin_object_size ((char *) si, 0)); | |||
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(const 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))__builtin___memset_chk (info, 0, sizeof(GeometryInfo), __builtin_object_size (info, 0)); | |||
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 | const 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 | const 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 | const char *field, | |||
1514 | ExprDef * arrayNdx, | |||
1515 | ExprDef * value, SectionInfo * si, GeometryInfo * info) | |||
1516 | { | |||
1517 | ExprResult tmp; | |||
1518 | unsigned def; | |||
1519 | unsigned type; | |||
1520 | const 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 | const 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 | const char *field, | |||
1709 | ExprDef * arrayNdx, | |||
1710 | ExprDef * value, SectionInfo * si, GeometryInfo * info) | |||
1711 | { | |||
1712 | ExprResult tmp; | |||
1713 | const 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 | const 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 | const 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 | const 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)__builtin___memset_chk (key->name, 0, 4 + 1, __builtin_object_size (key->name, 0)); | |||
2112 | strncpy(key->name, tmp.keyName.name, XkbKeyNameLength)__builtin___strncpy_chk (key->name, tmp.keyName.name, 4, __builtin_object_size (key->name, 2 > 1 ? 1 : 0)); | |||
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 = &si->outlines[nOut++]; | |||
2427 | outline->num_points = ol->nPoints; | |||
2428 | outline->corner_radius = si->dfltCornerRadius; | |||
2429 | outline->points = uTypedCalloc(ol->nPoints, XkbPointRec)((XkbPointRec *)uCalloc((unsigned)ol->nPoints,(unsigned)sizeof (XkbPointRec))); | |||
2430 | if (!outline->points) | |||
2431 | { | |||
2432 | ERROR1uError("Can't allocate points for \"%s\"\n", | |||
2433 | shText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default shape" )); | |||
2434 | ACTIONuAction("Definition ignored\n"); | |||
2435 | info->errorCount++; | |||
2436 | return False0; | |||
2437 | } | |||
2438 | for (nPt = 0, pt = ol->points; pt != NULL((void*)0); | |||
2439 | pt = (ExprDef *) pt->common.next) | |||
2440 | { | |||
2441 | outline->points[nPt].x = pt->value.coord.x; | |||
2442 | outline->points[nPt].y = pt->value.coord.y; | |||
2443 | nPt++; | |||
2444 | } | |||
2445 | if (ol->field != None0L) | |||
2446 | { | |||
2447 | char *str = XkbAtomText(NULL((void*)0), ol->field, XkbMessage3); | |||
2448 | if ((uStrCaseCmp(str, "approximation")(strcasecmp(str,"approximation")) == 0) || | |||
2449 | (uStrCaseCmp(str, "approx")(strcasecmp(str,"approx")) == 0)) | |||
2450 | { | |||
2451 | if (si->approx == NULL((void*)0)) | |||
2452 | si->approx = outline; | |||
2453 | else | |||
2454 | { | |||
2455 | WARN1uWarning("Multiple approximations for \"%s\"\n", | |||
2456 | shText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default shape" )); | |||
2457 | ACTIONuAction("Treating all but the first as normal outlines\n"); | |||
2458 | } | |||
2459 | } | |||
2460 | else if (uStrCaseCmp(str, "primary")(strcasecmp(str,"primary")) == 0) | |||
2461 | { | |||
2462 | if (si->primary == NULL((void*)0)) | |||
2463 | si->primary = outline; | |||
2464 | else | |||
2465 | { | |||
2466 | WARN1uWarning("Multiple primary outlines for \"%s\"\n", | |||
2467 | shText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default shape" )); | |||
2468 | ACTIONuAction("Treating all but the first as normal outlines\n"); | |||
2469 | } | |||
2470 | } | |||
2471 | else | |||
2472 | { | |||
2473 | WARN2uWarning("Unknown outline type %s for \"%s\"\n", str, | |||
2474 | shText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default shape" )); | |||
2475 | ACTIONuAction("Treated as a normal outline\n"); | |||
2476 | } | |||
2477 | } | |||
2478 | } | |||
2479 | if (nOut != si->nOutlines) | |||
2480 | { | |||
2481 | WSGO2uInternalError("Expected %d outlines, got %d\n", | |||
2482 | (unsigned int) si->nOutlines, nOut); | |||
2483 | si->nOutlines = nOut; | |||
2484 | } | |||
2485 | return True1; | |||
2486 | } | |||
2487 | ||||
2488 | static int | |||
2489 | HandleShapeDef(ShapeDef * def, XkbDescPtr xkb, unsigned merge, | |||
2490 | GeometryInfo * info) | |||
2491 | { | |||
2492 | ShapeInfo si; | |||
2493 | ||||
2494 | if (def->merge != MergeDefault0) | |||
2495 | merge = def->merge; | |||
2496 | ||||
2497 | bzero(&si, sizeof(ShapeInfo))__builtin___memset_chk (&si, 0, sizeof(ShapeInfo), __builtin_object_size (&si, 0)); | |||
2498 | si.defs.merge = merge; | |||
2499 | si.name = | |||
2500 | XkbInternAtom(info->dpy, XkbAtomGetString(NULL((void*)0), def->name), False0); | |||
2501 | si.dfltCornerRadius = info->dfltCornerRadius; | |||
2502 | if (!HandleShapeBody(def, &si, merge, info)) | |||
2503 | return False0; | |||
2504 | if (!AddShape(info, &si)) | |||
2505 | return False0; | |||
2506 | return True1; | |||
2507 | } | |||
2508 | ||||
2509 | /***====================================================================***/ | |||
2510 | ||||
2511 | static int | |||
2512 | HandleDoodadDef(DoodadDef * def, | |||
2513 | unsigned merge, SectionInfo * si, GeometryInfo * info) | |||
2514 | { | |||
2515 | ExprResult elem, field; | |||
2516 | ExprDef *ndx; | |||
2517 | DoodadInfo new; | |||
2518 | VarDef *var; | |||
2519 | ||||
2520 | if (def->common.stmtType == StmtIndicatorMapDef12) | |||
2521 | { | |||
2522 | def->common.stmtType = StmtDoodadDef21; | |||
2523 | def->type = XkbIndicatorDoodad4; | |||
2524 | } | |||
2525 | InitDoodadInfo(&new, def->type, si, info); | |||
2526 | new.name = | |||
2527 | XkbInternAtom(info->dpy, XkbAtomGetString(NULL((void*)0), def->name), False0); | |||
2528 | for (var = def->body; var != NULL((void*)0); var = (VarDef *) var->common.next) | |||
2529 | { | |||
2530 | if (ExprResolveLhs(var->name, &elem, &field, &ndx) == 0) | |||
2531 | return 0; /* internal error, already reported */ | |||
| ||||
2532 | if (elem.str != NULL((void*)0)) | |||
2533 | { | |||
2534 | WARN1uWarning("Assignment to field of unknown element in doodad %s\n", | |||
2535 | ddText(info->dpy, &new)); | |||
2536 | ACTION2uAction("No value assigned to %s.%s\n", elem.str, field.str); | |||
2537 | } | |||
2538 | else if (!SetDoodadField(&new, field.str, ndx, var->value, si, info)) | |||
2539 | return False0; | |||
2540 | } | |||
2541 | if (!AddDoodad(si, info, &new)) | |||
2542 | return False0; | |||
2543 | ClearDoodadInfo(&new); | |||
2544 | return True1; | |||
2545 | } | |||
2546 | ||||
2547 | /***====================================================================***/ | |||
2548 | ||||
2549 | static int | |||
2550 | HandleOverlayDef(OverlayDef * def, | |||
2551 | unsigned merge, SectionInfo * si, GeometryInfo * info) | |||
2552 | { | |||
2553 | OverlayKeyDef *keyDef; | |||
2554 | OverlayKeyInfo *key; | |||
2555 | OverlayInfo ol; | |||
2556 | ||||
2557 | if ((def->nKeys < 1) && (warningLevel > 3)) | |||
2558 | { | |||
2559 | WARN2uWarning("Overlay \"%s\" in section \"%s\" has no keys\n", | |||
2560 | XkbAtomText(NULL((void*)0), def->name, XkbMessage3), scText(info->dpy,((si)?XkbAtomText((info->dpy),(si)->name,3):"default") | |||
2561 | si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default")); | |||
2562 | ACTIONuAction("Overlay ignored\n"); | |||
2563 | return True1; | |||
2564 | } | |||
2565 | bzero(&ol, sizeof(OverlayInfo))__builtin___memset_chk (&ol, 0, sizeof(OverlayInfo), __builtin_object_size (&ol, 0)); | |||
2566 | ol.name = | |||
2567 | XkbInternAtom(info->dpy, XkbAtomGetString(NULL((void*)0), def->name), False0); | |||
2568 | for (keyDef = def->keys; keyDef; | |||
2569 | keyDef = (OverlayKeyDef *) keyDef->common.next) | |||
2570 | { | |||
2571 | key = uTypedCalloc(1, OverlayKeyInfo)((OverlayKeyInfo *)uCalloc((unsigned)1,(unsigned)sizeof(OverlayKeyInfo ))); | |||
2572 | if ((!key) && warningLevel > 0) | |||
2573 | { | |||
2574 | WSGOuInternalError("Couldn't allocate OverlayKeyInfo\n"); | |||
2575 | ACTION2uAction("Overlay %s for section %s will be incomplete\n", | |||
2576 | XkbAtomText(info->dpy, ol.name, XkbMessage3), | |||
2577 | scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default")); | |||
2578 | return False0; | |||
2579 | } | |||
2580 | strncpy(key->over, keyDef->over, XkbKeyNameLength)__builtin___strncpy_chk (key->over, keyDef->over, 4, __builtin_object_size (key->over, 2 > 1 ? 1 : 0)); | |||
2581 | strncpy(key->under, keyDef->under, XkbKeyNameLength)__builtin___strncpy_chk (key->under, keyDef->under, 4, __builtin_object_size (key->under, 2 > 1 ? 1 : 0)); | |||
2582 | key->sectionRow = _GOK_UnknownRow-1; | |||
2583 | key->overlayRow = _GOK_UnknownRow-1; | |||
2584 | ol.keys = (OverlayKeyInfo *) AddCommonInfo(&ol.keys->defs, | |||
2585 | (CommonInfo *) key); | |||
2586 | ol.nKeys++; | |||
2587 | } | |||
2588 | if (!AddOverlay(si, info, &ol)) | |||
2589 | return False0; | |||
2590 | ClearOverlayInfo(&ol); | |||
2591 | return True1; | |||
2592 | } | |||
2593 | ||||
2594 | /***====================================================================***/ | |||
2595 | ||||
2596 | static Boolint | |||
2597 | HandleComplexKey(KeyDef * def, KeyInfo * key, GeometryInfo * info) | |||
2598 | { | |||
2599 | RowInfo *row; | |||
2600 | ExprDef *expr; | |||
2601 | ||||
2602 | row = key->row; | |||
2603 | for (expr = def->expr; expr != NULL((void*)0); expr = (ExprDef *) expr->common.next) | |||
2604 | { | |||
2605 | if (expr->op == OpAssign24) | |||
2606 | { | |||
2607 | ExprResult elem, f; | |||
2608 | ExprDef *ndx; | |||
2609 | if (ExprResolveLhs(expr->value.binary.left, &elem, &f, &ndx) == 0) | |||
2610 | return False0; /* internal error, already reported */ | |||
2611 | if ((elem.str == NULL((void*)0)) || (uStrCaseCmp(elem.str, "key")(strcasecmp(elem.str,"key")) == 0)) | |||
2612 | { | |||
2613 | if (!SetKeyField | |||
2614 | (key, f.str, ndx, expr->value.binary.right, info)) | |||
2615 | return False0; | |||
2616 | } | |||
2617 | else | |||
2618 | { | |||
2619 | ERRORuError("Illegal element used in a key definition\n"); | |||
2620 | ACTION2uAction("Assignment to %s.%s ignored\n", elem.str, f.str); | |||
2621 | return False0; | |||
2622 | } | |||
2623 | } | |||
2624 | else | |||
2625 | { | |||
2626 | switch (expr->type) | |||
2627 | { | |||
2628 | case TypeInt2: | |||
2629 | case TypeFloat3: | |||
2630 | if (!SetKeyField(key, "gap", NULL((void*)0), expr, info)) | |||
2631 | return False0; | |||
2632 | break; | |||
2633 | case TypeString4: | |||
2634 | if (!SetKeyField(key, "shape", NULL((void*)0), expr, info)) | |||
2635 | return False0; | |||
2636 | break; | |||
2637 | case TypeKeyName6: | |||
2638 | if (!SetKeyField(key, "name", NULL((void*)0), expr, info)) | |||
2639 | return False0; | |||
2640 | break; | |||
2641 | default: | |||
2642 | ERRORuError("Cannot determine field for unnamed expression\n"); | |||
2643 | ACTION3uAction("Ignoring key %d in row %d of section %s\n", | |||
2644 | row->nKeys + 1, row->section->nRows + 1, | |||
2645 | rowText(info->dpy, row)((row)?XkbAtomText((info->dpy),(row)->section->name, 3):"default")); | |||
2646 | return False0; | |||
2647 | } | |||
2648 | } | |||
2649 | } | |||
2650 | return True1; | |||
2651 | } | |||
2652 | ||||
2653 | static Boolint | |||
2654 | HandleRowBody(RowDef * def, RowInfo * row, unsigned merge, | |||
2655 | GeometryInfo * info) | |||
2656 | { | |||
2657 | KeyDef *keyDef; | |||
2658 | ||||
2659 | if ((def->nKeys < 1) && (warningLevel > 3)) | |||
2660 | { | |||
2661 | ERROR1uError("Row in section %s has no keys\n", rowText(info->dpy, row)((row)?XkbAtomText((info->dpy),(row)->section->name, 3):"default")); | |||
2662 | ACTIONuAction("Section ignored\n"); | |||
2663 | return True1; | |||
2664 | } | |||
2665 | for (keyDef = def->keys; keyDef != NULL((void*)0); | |||
2666 | keyDef = (KeyDef *) keyDef->common.next) | |||
2667 | { | |||
2668 | if (keyDef->common.stmtType == StmtVarDef5) | |||
2669 | { | |||
2670 | VarDef *var = (VarDef *) keyDef; | |||
2671 | ExprResult elem, field; | |||
2672 | ExprDef *ndx; | |||
2673 | if (ExprResolveLhs(var->name, &elem, &field, &ndx) == 0) | |||
2674 | return 0; /* internal error, already reported */ | |||
2675 | if ((elem.str == NULL((void*)0)) || (uStrCaseCmp(elem.str, "row")(strcasecmp(elem.str,"row")) == 0)) | |||
2676 | { | |||
2677 | if (!SetRowField(row, field.str, ndx, var->value, info)) | |||
2678 | return False0; | |||
2679 | } | |||
2680 | else if (uStrCaseCmp(elem.str, "key")(strcasecmp(elem.str,"key")) == 0) | |||
2681 | { | |||
2682 | if (!SetKeyField | |||
2683 | (&row->dfltKey, field.str, ndx, var->value, info)) | |||
2684 | return False0; | |||
2685 | } | |||
2686 | else | |||
2687 | { | |||
2688 | WARNuWarning("Assignment to field of unknown element in row\n"); | |||
2689 | ACTION2uAction("No value assigned to %s.%s\n", elem.str, field.str); | |||
2690 | } | |||
2691 | } | |||
2692 | else if (keyDef->common.stmtType == StmtKeyDef16) | |||
2693 | { | |||
2694 | KeyInfo key; | |||
2695 | InitKeyInfo(&key, row, info); | |||
2696 | if (keyDef->name != NULL((void*)0)) | |||
2697 | { | |||
2698 | int len = strlen(keyDef->name); | |||
2699 | if ((len < 1) || (len > XkbKeyNameLength4)) | |||
2700 | { | |||
2701 | ERROR2uError("Illegal name %s for key in section %s\n", | |||
2702 | keyDef->name, rowText(info->dpy, row)((row)?XkbAtomText((info->dpy),(row)->section->name, 3):"default")); | |||
2703 | ACTIONuAction("Section not compiled\n"); | |||
2704 | return False0; | |||
2705 | } | |||
2706 | bzero(key.name, XkbKeyNameLength + 1)__builtin___memset_chk (key.name, 0, 4 + 1, __builtin_object_size (key.name, 0)); | |||
2707 | strncpy(key.name, keyDef->name, XkbKeyNameLength)__builtin___strncpy_chk (key.name, keyDef->name, 4, __builtin_object_size (key.name, 2 > 1 ? 1 : 0)); | |||
2708 | key.defs.defined |= _GK_Name(1<<1); | |||
2709 | } | |||
2710 | else if (!HandleComplexKey(keyDef, &key, info)) | |||
2711 | return False0; | |||
2712 | if (!AddKey(row, &key)) | |||
2713 | return False0; | |||
2714 | } | |||
2715 | else | |||
2716 | { | |||
2717 | WSGO1uInternalError("Unexpected statement (type %d) in row body\n", | |||
2718 | keyDef->common.stmtType); | |||
2719 | return False0; | |||
2720 | } | |||
2721 | } | |||
2722 | return True1; | |||
2723 | } | |||
2724 | ||||
2725 | static Boolint | |||
2726 | HandleSectionBody(SectionDef * def, | |||
2727 | SectionInfo * si, unsigned merge, GeometryInfo * info) | |||
2728 | { | |||
2729 | RowDef *rowDef; | |||
2730 | DoodadInfo *di; | |||
2731 | ||||
2732 | for (rowDef = def->rows; rowDef != NULL((void*)0); | |||
2733 | rowDef = (RowDef *) rowDef->common.next) | |||
2734 | { | |||
2735 | if (rowDef->common.stmtType == StmtVarDef5) | |||
2736 | { | |||
2737 | VarDef *var = (VarDef *) rowDef; | |||
2738 | ExprResult elem, field; | |||
2739 | ExprDef *ndx; | |||
2740 | if (ExprResolveLhs(var->name, &elem, &field, &ndx) == 0) | |||
2741 | return 0; /* internal error, already reported */ | |||
2742 | if ((elem.str == NULL((void*)0)) || (uStrCaseCmp(elem.str, "section")(strcasecmp(elem.str,"section")) == 0)) | |||
2743 | { | |||
2744 | if (!SetSectionField(si, field.str, ndx, var->value, info)) | |||
2745 | return False0; | |||
2746 | } | |||
2747 | else if (uStrCaseCmp(elem.str, "row")(strcasecmp(elem.str,"row")) == 0) | |||
2748 | { | |||
2749 | if (!SetRowField | |||
2750 | (&si->dfltRow, field.str, ndx, var->value, info)) | |||
2751 | return False0; | |||
2752 | } | |||
2753 | else if (uStrCaseCmp(elem.str, "key")(strcasecmp(elem.str,"key")) == 0) | |||
2754 | { | |||
2755 | if (!SetKeyField(&si->dfltRow.dfltKey, field.str, ndx, | |||
2756 | var->value, info)) | |||
2757 | return False0; | |||
2758 | } | |||
2759 | else if ((di = | |||
2760 | FindDfltDoodadByTypeName(elem.str, si, info)) != NULL((void*)0)) | |||
2761 | { | |||
2762 | if (!SetDoodadField(di, field.str, ndx, var->value, si, info)) | |||
2763 | return False0; | |||
2764 | } | |||
2765 | else | |||
2766 | { | |||
2767 | WARNuWarning("Assignment to field of unknown element in section\n"); | |||
2768 | ACTION2uAction("No value assigned to %s.%s\n", elem.str, field.str); | |||
2769 | } | |||
2770 | } | |||
2771 | else if (rowDef->common.stmtType == StmtRowDef17) | |||
2772 | { | |||
2773 | RowInfo row; | |||
2774 | InitRowInfo(&row, si, info); | |||
2775 | if (!HandleRowBody(rowDef, &row, merge, info)) | |||
2776 | return False0; | |||
2777 | if (!AddRow(si, &row)) | |||
2778 | return False0; | |||
2779 | /* ClearRowInfo(&row,info);*/ | |||
2780 | } | |||
2781 | else if ((rowDef->common.stmtType == StmtDoodadDef21) || | |||
2782 | (rowDef->common.stmtType == StmtIndicatorMapDef12)) | |||
2783 | { | |||
2784 | if (!HandleDoodadDef((DoodadDef *) rowDef, merge, si, info)) | |||
2785 | return False0; | |||
2786 | } | |||
2787 | else if (rowDef->common.stmtType == StmtOverlayDef20) | |||
2788 | { | |||
2789 | if (!HandleOverlayDef((OverlayDef *) rowDef, merge, si, info)) | |||
2790 | return False0; | |||
2791 | } | |||
2792 | else | |||
2793 | { | |||
2794 | WSGO1uInternalError("Unexpected statement (type %d) in section body\n", | |||
2795 | rowDef->common.stmtType); | |||
2796 | return False0; | |||
2797 | } | |||
2798 | } | |||
2799 | if (si->nRows != def->nRows) | |||
2800 | { | |||
2801 | WSGO2uInternalError("Expected %d rows, found %d\n", (unsigned int) def->nRows, | |||
2802 | (unsigned int) si->nRows); | |||
2803 | ACTION1uAction("Definition of section %s might be incorrect\n", | |||
2804 | scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default")); | |||
2805 | } | |||
2806 | return True1; | |||
2807 | } | |||
2808 | ||||
2809 | static int | |||
2810 | HandleSectionDef(SectionDef * def, | |||
2811 | XkbDescPtr xkb, unsigned merge, GeometryInfo * info) | |||
2812 | { | |||
2813 | SectionInfo si; | |||
2814 | char *str; | |||
2815 | ||||
2816 | if (def->merge != MergeDefault0) | |||
| ||||
2817 | merge = def->merge; | |||
2818 | InitSectionInfo(&si, info); | |||
2819 | si.defs.merge = merge; | |||
2820 | str = XkbAtomGetString(NULL((void*)0), def->name); | |||
2821 | if ((str == NULL((void*)0)) || (strlen(str) < 1)) | |||
2822 | { | |||
2823 | ERRORuError("Section defined without a name\n"); | |||
2824 | ACTIONuAction("Definition ignored\n"); | |||
2825 | return False0; | |||
2826 | } | |||
2827 | si.name = | |||
2828 | XkbInternAtom(info->dpy, XkbAtomGetString(NULL((void*)0), def->name), False0); | |||
2829 | if (!HandleSectionBody(def, &si, merge, info)) | |||
2830 | return False0; | |||
2831 | if (!AddSection(info, &si)) | |||
2832 | return False0; | |||
2833 | return True1; | |||
2834 | } | |||
2835 | ||||
2836 | /***====================================================================***/ | |||
2837 | ||||
2838 | static void | |||
2839 | HandleGeometryFile(XkbFile * file, | |||
2840 | XkbDescPtr xkb, unsigned merge, GeometryInfo * info) | |||
2841 | { | |||
2842 | ParseCommon *stmt; | |||
2843 | const char *failWhat; | |||
2844 | ||||
2845 | if (merge == MergeDefault0) | |||
2846 | merge = MergeAugment1; | |||
2847 | info->name = uStringDup(file->name)((file->name) ? strdup(file->name) : ((void*)0)); | |||
2848 | stmt = file->defs; | |||
2849 | while (stmt) | |||
2850 | { | |||
2851 | failWhat = NULL((void*)0); | |||
2852 | switch (stmt->stmtType) | |||
2853 | { | |||
2854 | case StmtInclude1: | |||
2855 | if (!HandleIncludeGeometry((IncludeStmt *) stmt, xkb, info, | |||
2856 | HandleGeometryFile)) | |||
2857 | info->errorCount++; | |||
2858 | break; | |||
2859 | case StmtKeyAliasDef3: | |||
2860 | if (!HandleAliasDef((KeyAliasDef *) stmt, | |||
2861 | merge, info->fileID, &info->aliases)) | |||
2862 | { | |||
2863 | info->errorCount++; | |||
2864 | } | |||
2865 | break; | |||
2866 | case StmtVarDef5: | |||
2867 | if (!HandleGeometryVar((VarDef *) stmt, xkb, info)) | |||
2868 | info->errorCount++; | |||
2869 | break; | |||
2870 | case StmtShapeDef15: | |||
2871 | if (!HandleShapeDef((ShapeDef *) stmt, xkb, merge, info)) | |||
2872 | info->errorCount++; | |||
2873 | break; | |||
2874 | case StmtSectionDef18: | |||
2875 | if (!HandleSectionDef((SectionDef *) stmt, xkb, merge, info)) | |||
2876 | info->errorCount++; | |||
2877 | break; | |||
2878 | case StmtIndicatorMapDef12: | |||
2879 | case StmtDoodadDef21: | |||
2880 | if (!HandleDoodadDef((DoodadDef *) stmt, merge, NULL((void*)0), info)) | |||
2881 | info->errorCount++; | |||
2882 | break; | |||
2883 | case StmtVModDef8: | |||
2884 | if (!failWhat) | |||
2885 | failWhat = "virtual modfier"; | |||
2886 | case StmtInterpDef7: | |||
2887 | if (!failWhat) | |||
2888 | failWhat = "symbol interpretation"; | |||
2889 | case StmtGroupCompatDef11: | |||
2890 | if (!failWhat) | |||
2891 | failWhat = "group compatibility map"; | |||
2892 | case StmtKeycodeDef2: | |||
2893 | if (!failWhat) | |||
2894 | failWhat = "key name"; | |||
2895 | ERRORuError("Interpretation files may not include other types\n"); | |||
2896 | ACTION1uAction("Ignoring %s definition.\n", failWhat); | |||
2897 | info->errorCount++; | |||
2898 | break; | |||
2899 | default: | |||
2900 | WSGO1uInternalError("Unexpected statement type %d in HandleGeometryFile\n", | |||
2901 | stmt->stmtType); | |||
2902 | break; | |||
2903 | } | |||
2904 | stmt = stmt->next; | |||
2905 | if (info->errorCount > 10) | |||
2906 | { | |||
2907 | #ifdef NOISY | |||
2908 | ERRORuError("Too many errors\n"); | |||
2909 | #endif | |||
2910 | ACTION1uAction("Abandoning geometry file \"%s\"\n", file->topName); | |||
2911 | break; | |||
2912 | } | |||
2913 | } | |||
2914 | return; | |||
2915 | } | |||
2916 | ||||
2917 | /***====================================================================***/ | |||
2918 | ||||
2919 | static Boolint | |||
2920 | CopyShapeDef(Display * dpy, XkbGeometryPtr geom, ShapeInfo * si) | |||
2921 | { | |||
2922 | register int i, n; | |||
2923 | XkbShapePtr shape; | |||
2924 | XkbOutlinePtr old_outline, outline; | |||
2925 | Atom name; | |||
2926 | ||||
2927 | si->index = geom->num_shapes; | |||
2928 | name = XkbInternAtom(dpy, XkbAtomGetString(NULL((void*)0), si->name), False0); | |||
2929 | shape = XkbAddGeomShape(geom, name, si->nOutlines); | |||
2930 | if (!shape) | |||
2931 | { | |||
2932 | WSGOuInternalError("Couldn't allocate shape in geometry\n"); | |||
2933 | ACTION1uAction("Shape %s not compiled\n", shText(dpy, si)((si)?XkbAtomText((dpy),(si)->name,3):"default shape")); | |||
2934 | return False0; | |||
2935 | } | |||
2936 | old_outline = si->outlines; | |||
2937 | for (i = 0; i < si->nOutlines; i++, old_outline++) | |||
2938 | { | |||
2939 | outline = XkbAddGeomOutline(shape, old_outline->num_points); | |||
2940 | if (!outline) | |||
2941 | { | |||
2942 | WSGOuInternalError("Couldn't allocate outline in shape\n"); | |||
2943 | ACTION1uAction("Shape %s is incomplete\n", shText(dpy, si)((si)?XkbAtomText((dpy),(si)->name,3):"default shape")); | |||
2944 | return False0; | |||
2945 | } | |||
2946 | n = old_outline->num_points; | |||
2947 | memcpy(outline->points, old_outline->points, n * sizeof(XkbPointRec))__builtin___memcpy_chk (outline->points, old_outline->points , n * sizeof(XkbPointRec), __builtin_object_size (outline-> points, 0)); | |||
2948 | outline->num_points = old_outline->num_points; | |||
2949 | outline->corner_radius = old_outline->corner_radius; | |||
2950 | } | |||
2951 | if (si->approx) | |||
2952 | { | |||
2953 | n = (si->approx - si->outlines); | |||
2954 | shape->approx = &shape->outlines[n]; | |||
2955 | } | |||
2956 | if (si->primary) | |||
2957 | { | |||
2958 | n = (si->primary - si->outlines); | |||
2959 | shape->primary = &shape->outlines[n]; | |||
2960 | } | |||
2961 | XkbComputeShapeBounds(shape); | |||
2962 | return True1; | |||
2963 | } | |||
2964 | ||||
2965 | static Boolint | |||
2966 | VerifyDoodadInfo(DoodadInfo * di, GeometryInfo * info) | |||
2967 | { | |||
2968 | if ((di->defs.defined & (_GD_Top(1<<1) | _GD_Left(1<<2))) != (_GD_Top(1<<1) | _GD_Left(1<<2))) | |||
2969 | { | |||
2970 | if (warningLevel < 9) | |||
2971 | { | |||
2972 | ERROR1uError("No position defined for doodad %s\n", | |||
2973 | ddText(info->dpy, di)); | |||
2974 | ACTIONuAction("Illegal doodad ignored\n"); | |||
2975 | return False0; | |||
2976 | } | |||
2977 | } | |||
2978 | if ((di->defs.defined & _GD_Priority(1<<0)) == 0) | |||
2979 | { | |||
2980 | /* calculate priority -- should be just above previous doodad/row */ | |||
2981 | } | |||
2982 | switch (di->type) | |||
2983 | { | |||
2984 | case XkbOutlineDoodad1: | |||
2985 | case XkbSolidDoodad2: | |||
2986 | if ((di->defs.defined & _GD_Shape(1<<4)) == 0) | |||
2987 | { | |||
2988 | ERROR2uError("No shape defined for %s doodad %s\n", | |||
2989 | (di->type == XkbOutlineDoodad1 ? "outline" : "filled"), | |||
2990 | ddText(info->dpy, di)); | |||
2991 | ACTIONuAction("Incomplete definition ignored\n"); | |||
2992 | return False0; | |||
2993 | } | |||
2994 | else | |||
2995 | { | |||
2996 | ShapeInfo *si; | |||
2997 | si = FindShape(info, di->shape, | |||
2998 | (di->type == | |||
2999 | XkbOutlineDoodad1 ? "outline doodad" : | |||
3000 | "solid doodad"), ddText(info->dpy, di)); | |||
3001 | if (si) | |||
3002 | di->shape = si->name; | |||
3003 | else | |||
3004 | { | |||
3005 | ERROR1uError("No legal shape for %s\n", ddText(info->dpy, di)); | |||
3006 | ACTIONuAction("Incomplete definition ignored\n"); | |||
3007 | return False0; | |||
3008 | } | |||
3009 | } | |||
3010 | if ((di->defs.defined & _GD_Color(1<<6)) == 0) | |||
3011 | { | |||
3012 | if (warningLevel > 5) | |||
3013 | { | |||
3014 | WARN1uWarning("No color for doodad %s\n", ddText(info->dpy, di)); | |||
3015 | ACTIONuAction("Using black\n"); | |||
3016 | } | |||
3017 | di->color = XkbInternAtom(NULL((void*)0), "black", False0); | |||
3018 | } | |||
3019 | break; | |||
3020 | case XkbTextDoodad3: | |||
3021 | if ((di->defs.defined & _GD_Text(1<<8)) == 0) | |||
3022 | { | |||
3023 | ERROR1uError("No text specified for text doodad %s\n", | |||
3024 | ddText(info->dpy, di)); | |||
3025 | ACTIONuAction("Illegal doodad definition ignored\n"); | |||
3026 | return False0; | |||
3027 | } | |||
3028 | if ((di->defs.defined & _GD_Angle(1<<3)) == 0) | |||
3029 | di->angle = 0; | |||
3030 | if ((di->defs.defined & _GD_Color(1<<6)) == 0) | |||
3031 | { | |||
3032 | if (warningLevel > 5) | |||
3033 | { | |||
3034 | WARN1uWarning("No color specified for doodad %s\n", | |||
3035 | ddText(info->dpy, di)); | |||
3036 | ACTIONuAction("Using black\n"); | |||
3037 | } | |||
3038 | di->color = XkbInternAtom(NULL((void*)0), "black", False0); | |||
3039 | } | |||
3040 | if ((di->defs.defined & _GD_FontSpec(1<<15)) != 0) | |||
3041 | { | |||
3042 | if ((di->defs.defined & _GD_FontParts((1<<9)|(1<<10)|(1<<11)|(1<<12)|(1<< 13)|(1<<14)|(1<<4))) == 0) | |||
3043 | return True1; | |||
3044 | if (warningLevel < 9) | |||
3045 | { | |||
3046 | WARN1uWarning | |||
3047 | ("Text doodad %s has full and partial font definition\n", | |||
3048 | ddText(info->dpy, di)); | |||
3049 | ACTIONuAction("Full specification ignored\n"); | |||
3050 | } | |||
3051 | di->defs.defined &= ~_GD_FontSpec(1<<15); | |||
3052 | di->fontSpec = None0L; | |||
3053 | } | |||
3054 | if ((di->defs.defined & _GD_Font(1<<9)) == 0) | |||
3055 | { | |||
3056 | if (warningLevel > 5) | |||
3057 | { | |||
3058 | WARN1uWarning("No font specified for doodad %s\n", | |||
3059 | ddText(info->dpy, di)); | |||
3060 | ACTION1uAction("Using \"%s\"\n", DFLT_FONT"helvetica"); | |||
3061 | } | |||
3062 | di->font = XkbInternAtom(NULL((void*)0), DFLT_FONT"helvetica", False0); | |||
3063 | } | |||
3064 | if ((di->defs.defined & _GD_FontSlant(1<<10)) == 0) | |||
3065 | { | |||
3066 | if (warningLevel > 7) | |||
3067 | { | |||
3068 | WARN1uWarning("No font slant for text doodad %s\n", | |||
3069 | ddText(info->dpy, di)); | |||
3070 | ACTION1uAction("Using \"%s\"\n", DFLT_SLANT"r"); | |||
3071 | } | |||
3072 | di->fontSlant = XkbInternAtom(NULL((void*)0), DFLT_SLANT"r", False0); | |||
3073 | } | |||
3074 | if ((di->defs.defined & _GD_FontWeight(1<<11)) == 0) | |||
3075 | { | |||
3076 | if (warningLevel > 7) | |||
3077 | { | |||
3078 | WARN1uWarning("No font weight for text doodad %s\n", | |||
3079 | ddText(info->dpy, di)); | |||
3080 | ACTION1uAction("Using \"%s\"\n", DFLT_WEIGHT"medium"); | |||
3081 | } | |||
3082 | di->fontWeight = XkbInternAtom(NULL((void*)0), DFLT_WEIGHT"medium", False0); | |||
3083 | } | |||
3084 | if ((di->defs.defined & _GD_FontSetWidth(1<<12)) == 0) | |||
3085 | { | |||
3086 | if (warningLevel > 9) | |||
3087 | { | |||
3088 | WARN1uWarning("No font set width for text doodad %s\n", | |||
3089 | ddText(info->dpy, di)); | |||
3090 | ACTION1uAction("Using \"%s\"\n", DFLT_SET_WIDTH"normal"); | |||
3091 | } | |||
3092 | di->fontSetWidth = XkbInternAtom(NULL((void*)0), DFLT_SET_WIDTH"normal", False0); | |||
3093 | } | |||
3094 | if ((di->defs.defined & _GD_FontVariant(1<<4)) == 0) | |||
3095 | { | |||
3096 | if (warningLevel > 9) | |||
3097 | { | |||
3098 | WARN1uWarning("No font variant for text doodad %s\n", | |||
3099 | ddText(info->dpy, di)); | |||
3100 | ACTION1uAction("Using \"%s\"\n", DFLT_VARIANT""); | |||
3101 | } | |||
3102 | di->fontVariant = XkbInternAtom(NULL((void*)0), DFLT_VARIANT"", False0); | |||
3103 | } | |||
3104 | if ((di->defs.defined & _GD_FontEncoding(1<<14)) == 0) | |||
3105 | { | |||
3106 | if (warningLevel > 7) | |||
3107 | { | |||
3108 | WARN1uWarning("No font encoding for doodad %s\n", | |||
3109 | ddText(info->dpy, di)); | |||
3110 | ACTION1uAction("Using \"%s\"\n", DFLT_ENCODING"iso8859-1"); | |||
3111 | } | |||
3112 | di->fontEncoding = XkbInternAtom(NULL((void*)0), DFLT_ENCODING"iso8859-1", False0); | |||
3113 | } | |||
3114 | if ((di->defs.defined & _GD_FontSize(1<<13)) == 0) | |||
3115 | { | |||
3116 | if (warningLevel > 7) | |||
3117 | { | |||
3118 | WARN1uWarning("No font size for text doodad %s\n", | |||
3119 | ddText(info->dpy, di)); | |||
3120 | ACTION1uAction("Using %s point text\n", | |||
3121 | XkbGeomFPText(DFLT_SIZE120, XkbMessage3)); | |||
3122 | } | |||
3123 | di->fontSize = DFLT_SIZE120; | |||
3124 | } | |||
3125 | if ((di->defs.defined & _GD_Height(1<<7)) == 0) | |||
3126 | { | |||
3127 | unsigned size, nLines; | |||
3128 | char *tmp; | |||
3129 | size = (di->fontSize * 120) / 100; | |||
3130 | size = (size * 254) / 720; /* convert to mm/10 */ | |||
3131 | for (nLines = 1, tmp = XkbAtomGetString(NULL((void*)0), di->text); *tmp; | |||
3132 | tmp++) | |||
3133 | { | |||
3134 | if (*tmp == '\n') | |||
3135 | nLines++; | |||
3136 | } | |||
3137 | size *= nLines; | |||
3138 | if (warningLevel > 5) | |||
3139 | { | |||
3140 | WARN1uWarning("No height for text doodad %s\n", | |||
3141 | ddText(info->dpy, di)); | |||
3142 | ACTION1uAction("Using calculated height %s millimeters\n", | |||
3143 | XkbGeomFPText(size, XkbMessage3)); | |||
3144 | } | |||
3145 | di->height = size; | |||
3146 | } | |||
3147 | if ((di->defs.defined & _GD_Width(1<<5)) == 0) | |||
3148 | { | |||
3149 | unsigned width, tmp; | |||
3150 | char *str; | |||
3151 | width = tmp = 0; | |||
3152 | for (str = XkbAtomGetString(NULL((void*)0), di->text); *str; str++) | |||
3153 | { | |||
3154 | if (*str != '\n') | |||
3155 | tmp++; | |||
3156 | else | |||
3157 | { | |||
3158 | if (tmp > width) | |||
3159 | width = tmp; | |||
3160 | tmp = 1; | |||
3161 | } | |||
3162 | } | |||
3163 | if (width == 0) | |||
3164 | width = tmp; | |||
3165 | width *= (di->height * 2) / 3; | |||
3166 | if (warningLevel > 5) | |||
3167 | { | |||
3168 | WARN1uWarning("No width for text doodad %s\n", ddText(info->dpy, di)); | |||
3169 | ACTION1uAction("Using calculated width %s millimeters\n", | |||
3170 | XkbGeomFPText(width, XkbMessage3)); | |||
3171 | } | |||
3172 | di->width = width; | |||
3173 | } | |||
3174 | break; | |||
3175 | case XkbIndicatorDoodad4: | |||
3176 | if ((di->defs.defined & _GD_Shape(1<<4)) == 0) | |||
3177 | { | |||
3178 | ERROR1uError("No shape defined for indicator doodad %s\n", | |||
3179 | ddText(info->dpy, di)); | |||
3180 | ACTIONuAction("Incomplete definition ignored\n"); | |||
3181 | return False0; | |||
3182 | } | |||
3183 | else | |||
3184 | { | |||
3185 | ShapeInfo *si; | |||
3186 | si = FindShape(info, di->shape, "indicator doodad", | |||
3187 | ddText(info->dpy, di)); | |||
3188 | if (si) | |||
3189 | di->shape = si->name; | |||
3190 | else | |||
3191 | { | |||
3192 | ERROR1uError("No legal shape for doodad %s\n", | |||
3193 | ddText(info->dpy, di)); | |||
3194 | ACTIONuAction("Incomplete definition ignored\n"); | |||
3195 | return False0; | |||
3196 | } | |||
3197 | } | |||
3198 | if ((di->defs.defined & _GD_Color(1<<6)) == 0) | |||
3199 | { | |||
3200 | if (warningLevel > 5) | |||
3201 | { | |||
3202 | WARN1uWarning("No \"on\" color for indicator doodad %s\n", | |||
3203 | ddText(info->dpy, di)); | |||
3204 | ACTIONuAction("Using green\n"); | |||
3205 | } | |||
3206 | di->color = XkbInternAtom(NULL((void*)0), "green", False0); | |||
3207 | } | |||
3208 | if ((di->defs.defined & _GD_OffColor(1<<7)) == 0) | |||
3209 | { | |||
3210 | if (warningLevel > 5) | |||
3211 | { | |||
3212 | WARN1uWarning("No \"off\" color for indicator doodad %s\n", | |||
3213 | ddText(info->dpy, di)); | |||
3214 | ACTIONuAction("Using black\n"); | |||
3215 | } | |||
3216 | di->offColor = XkbInternAtom(NULL((void*)0), "black", False0); | |||
3217 | } | |||
3218 | break; | |||
3219 | case XkbLogoDoodad5: | |||
3220 | if (di->logoName == NULL((void*)0)) | |||
3221 | { | |||
3222 | ERROR1uError("No logo name defined for logo doodad %s\n", | |||
3223 | ddText(info->dpy, di)); | |||
3224 | ACTIONuAction("Incomplete definition ignored\n"); | |||
3225 | return False0; | |||
3226 | } | |||
3227 | if ((di->defs.defined & _GD_Shape(1<<4)) == 0) | |||
3228 | { | |||
3229 | ERROR1uError("No shape defined for logo doodad %s\n", | |||
3230 | ddText(info->dpy, di)); | |||
3231 | ACTIONuAction("Incomplete definition ignored\n"); | |||
3232 | return False0; | |||
3233 | } | |||
3234 | else | |||
3235 | { | |||
3236 | ShapeInfo *si; | |||
3237 | si = FindShape(info, di->shape, "logo doodad", | |||
3238 | ddText(info->dpy, di)); | |||
3239 | if (si) | |||
3240 | di->shape = si->name; | |||
3241 | else | |||
3242 | { | |||
3243 | ERROR1uError("No legal shape for %s\n", ddText(info->dpy, di)); | |||
3244 | ACTIONuAction("Incomplete definition ignored\n"); | |||
3245 | return False0; | |||
3246 | } | |||
3247 | } | |||
3248 | if ((di->defs.defined & _GD_Color(1<<6)) == 0) | |||
3249 | { | |||
3250 | if (warningLevel > 5) | |||
3251 | { | |||
3252 | WARN1uWarning("No color for doodad %s\n", ddText(info->dpy, di)); | |||
3253 | ACTIONuAction("Using black\n"); | |||
3254 | } | |||
3255 | di->color = XkbInternAtom(NULL((void*)0), "black", False0); | |||
3256 | } | |||
3257 | break; | |||
3258 | default: | |||
3259 | WSGO1uInternalError("Uknown doodad type %d in VerifyDoodad\n", | |||
3260 | (unsigned int) di->type); | |||
3261 | return False0; | |||
3262 | } | |||
3263 | return True1; | |||
3264 | } | |||
3265 | ||||
3266 | #define FONT_TEMPLATE"-*-%s-%s-%s-%s-%s-*-%d-*-*-*-*-%s" "-*-%s-%s-%s-%s-%s-*-%d-*-*-*-*-%s" | |||
3267 | ||||
3268 | static char * | |||
3269 | FontFromParts(Atom fontTok, | |||
3270 | Atom weightTok, | |||
3271 | Atom slantTok, | |||
3272 | Atom setWidthTok, Atom varTok, int size, Atom encodingTok) | |||
3273 | { | |||
3274 | int totalSize; | |||
3275 | const char *font, *weight, *slant, *setWidth, *variant, *encoding; | |||
3276 | char *rtrn; | |||
3277 | ||||
3278 | font = (fontTok != None0L ? XkbAtomGetString(NULL((void*)0), fontTok) : DFLT_FONT"helvetica"); | |||
3279 | weight = | |||
3280 | (weightTok != None0L ? XkbAtomGetString(NULL((void*)0), weightTok) : DFLT_WEIGHT"medium"); | |||
3281 | slant = | |||
3282 | (slantTok != None0L ? XkbAtomGetString(NULL((void*)0), slantTok) : DFLT_SLANT"r"); | |||
3283 | setWidth = | |||
3284 | (setWidthTok != | |||
3285 | None0L ? XkbAtomGetString(NULL((void*)0), setWidthTok) : DFLT_SET_WIDTH"normal"); | |||
3286 | variant = | |||
3287 | (varTok != None0L ? XkbAtomGetString(NULL((void*)0), varTok) : DFLT_VARIANT""); | |||
3288 | encoding = | |||
3289 | (encodingTok != | |||
3290 | None0L ? XkbAtomGetString(NULL((void*)0), encodingTok) : DFLT_ENCODING"iso8859-1"); | |||
3291 | if (size == 0) | |||
3292 | size = DFLT_SIZE120; | |||
3293 | totalSize = | |||
3294 | strlen(FONT_TEMPLATE"-*-%s-%s-%s-%s-%s-*-%d-*-*-*-*-%s") + strlen(font) + strlen(weight) + strlen(slant); | |||
3295 | totalSize += strlen(setWidth) + strlen(variant) + strlen(encoding); | |||
3296 | rtrn = uCalloc(totalSize, 1); | |||
3297 | if (rtrn) | |||
3298 | { | |||
3299 | snprintf(rtrn, totalSize, FONT_TEMPLATE, font, weight, slant,__builtin___snprintf_chk (rtrn, totalSize, 0, __builtin_object_size (rtrn, 2 > 1 ? 1 : 0), "-*-%s-%s-%s-%s-%s-*-%d-*-*-*-*-%s" , font, weight, slant, setWidth, variant, size, encoding) | |||
3300 | setWidth, variant, size, encoding)__builtin___snprintf_chk (rtrn, totalSize, 0, __builtin_object_size (rtrn, 2 > 1 ? 1 : 0), "-*-%s-%s-%s-%s-%s-*-%d-*-*-*-*-%s" , font, weight, slant, setWidth, variant, size, encoding); | |||
3301 | } | |||
3302 | return rtrn; | |||
3303 | } | |||
3304 | ||||
3305 | static Boolint | |||
3306 | CopyDoodadDef(XkbGeometryPtr geom, | |||
3307 | XkbSectionPtr section, DoodadInfo * di, GeometryInfo * info) | |||
3308 | { | |||
3309 | Atom name; | |||
3310 | XkbDoodadPtr doodad; | |||
3311 | XkbColorPtr color; | |||
3312 | XkbShapePtr shape; | |||
3313 | ShapeInfo *si; | |||
3314 | ||||
3315 | if (!VerifyDoodadInfo(di, info)) | |||
3316 | return False0; | |||
3317 | name = XkbInternAtom(NULL((void*)0), XkbAtomGetString(NULL((void*)0), di->name), False0); | |||
3318 | doodad = XkbAddGeomDoodad(geom, section, name); | |||
3319 | if (!doodad) | |||
3320 | { | |||
3321 | WSGO1uInternalError("Couldn't allocate doodad in %s\n", | |||
3322 | (section ? "section" : "geometry")); | |||
3323 | ACTION1uAction("Cannot copy doodad %s\n", ddText(info->dpy, di)); | |||
3324 | return False0; | |||
3325 | } | |||
3326 | doodad->any.type = di->type; | |||
3327 | doodad->any.priority = di->priority; | |||
3328 | doodad->any.top = di->top; | |||
3329 | doodad->any.left = di->left; | |||
3330 | switch (di->type) | |||
3331 | { | |||
3332 | case XkbOutlineDoodad1: | |||
3333 | case XkbSolidDoodad2: | |||
3334 | si = FindShape(info, di->shape, NULL((void*)0), NULL((void*)0)); | |||
3335 | if (!si) | |||
3336 | return False0; | |||
3337 | doodad->shape.angle = di->angle; | |||
3338 | color = | |||
3339 | XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), di->color), | |||
3340 | geom->num_colors); | |||
3341 | shape = &geom->shapes[si->index]; | |||
3342 | XkbSetShapeDoodadColor(geom, &doodad->shape, color)((&doodad->shape)->color_ndx= (color)-&(geom)-> colors[0]); | |||
3343 | XkbSetShapeDoodadShape(geom, &doodad->shape, shape)((&doodad->shape)->shape_ndx= (shape)-&(geom)-> shapes[0]); | |||
3344 | break; | |||
3345 | case XkbTextDoodad3: | |||
3346 | doodad->text.angle = di->angle; | |||
3347 | doodad->text.width = di->width; | |||
3348 | doodad->text.height = di->height; | |||
3349 | if (di->fontSpec == None0L) | |||
3350 | doodad->text.font = FontFromParts(di->font, di->fontWeight, | |||
3351 | di->fontSlant, | |||
3352 | di->fontSetWidth, | |||
3353 | di->fontVariant, di->fontSize, | |||
3354 | di->fontEncoding); | |||
3355 | else | |||
3356 | doodad->text.font = XkbAtomGetString(NULL((void*)0), di->fontSpec); | |||
3357 | doodad->text.text = XkbAtomGetString(NULL((void*)0), di->text); | |||
3358 | color = | |||
3359 | XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), di->color), | |||
3360 | geom->num_colors); | |||
3361 | XkbSetTextDoodadColor(geom, &doodad->text, color)((&doodad->text)->color_ndx= (color)-&(geom)-> colors[0]); | |||
3362 | break; | |||
3363 | case XkbIndicatorDoodad4: | |||
3364 | si = FindShape(info, di->shape, NULL((void*)0), NULL((void*)0)); | |||
3365 | if (!si) | |||
3366 | return False0; | |||
3367 | shape = &geom->shapes[si->index]; | |||
3368 | color = | |||
3369 | XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), di->color), | |||
3370 | geom->num_colors); | |||
3371 | XkbSetIndicatorDoodadShape(geom, &doodad->indicator, shape)((&doodad->indicator)->shape_ndx= (shape)-&(geom )->shapes[0]); | |||
3372 | XkbSetIndicatorDoodadOnColor(geom, &doodad->indicator, color)((&doodad->indicator)->on_color_ndx= (color)-&( geom)->colors[0]); | |||
3373 | color = | |||
3374 | XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), di->offColor), | |||
3375 | geom->num_colors); | |||
3376 | XkbSetIndicatorDoodadOffColor(geom, &doodad->indicator, color)((&doodad->indicator)->off_color_ndx= (color)-& (geom)->colors[0]); | |||
3377 | break; | |||
3378 | case XkbLogoDoodad5: | |||
3379 | si = FindShape(info, di->shape, NULL((void*)0), NULL((void*)0)); | |||
3380 | if (!si) | |||
3381 | return False0; | |||
3382 | doodad->logo.angle = di->angle; | |||
3383 | color = | |||
3384 | XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), di->color), | |||
3385 | geom->num_colors); | |||
3386 | shape = &geom->shapes[si->index]; | |||
3387 | XkbSetLogoDoodadColor(geom, &doodad->logo, color)((&doodad->logo)->color_ndx= (color)-&(geom)-> colors[0]); | |||
3388 | XkbSetLogoDoodadShape(geom, &doodad->logo, shape)((&doodad->logo)->shape_ndx= (shape)-&(geom)-> shapes[0]); | |||
3389 | doodad->logo.logo_name = di->logoName; | |||
3390 | di->logoName = NULL((void*)0); | |||
3391 | break; | |||
3392 | } | |||
3393 | return True1; | |||
3394 | } | |||
3395 | ||||
3396 | /***====================================================================***/ | |||
3397 | ||||
3398 | static Boolint | |||
3399 | VerifyOverlayInfo(XkbGeometryPtr geom, | |||
3400 | XkbSectionPtr section, | |||
3401 | OverlayInfo * oi, | |||
3402 | GeometryInfo * info, short rowMap[256], short rowSize[256]) | |||
3403 | { | |||
3404 | register OverlayKeyInfo *ki, *next; | |||
3405 | unsigned long oKey, uKey, sKey; | |||
3406 | XkbRowPtr row; | |||
3407 | XkbKeyPtr key; | |||
3408 | int r, k; | |||
3409 | ||||
3410 | /* find out which row each key is in */ | |||
3411 | for (ki = oi->keys; ki != NULL((void*)0); ki = (OverlayKeyInfo *) ki->defs.next) | |||
3412 | { | |||
3413 | 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]); | |||
3414 | 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]); | |||
3415 | for (r = 0, row = section->rows; (r < section->num_rows) && oKey; | |||
3416 | r++, row++) | |||
3417 | { | |||
3418 | for (k = 0, key = row->keys; (k < row->num_keys) && oKey; | |||
3419 | k++, key++) | |||
3420 | { | |||
3421 | 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]); | |||
3422 | if (sKey == oKey) | |||
3423 | { | |||
3424 | if (warningLevel > 0) | |||
3425 | { | |||
3426 | WARN3uWarning | |||
3427 | ("Key %s in section \"%s\" and overlay \"%s\"\n", | |||
3428 | XkbKeyNameText(key->name.name, | |||
3429 | XkbMessage3), | |||
3430 | XkbAtomText(info->dpy, section->name, | |||
3431 | XkbMessage3), | |||
3432 | XkbAtomText(info->dpy, oi->name, XkbMessage3)); | |||
3433 | ACTIONuAction("Overlay definition ignored\n"); | |||
3434 | } | |||
3435 | oKey = 0; | |||
3436 | } | |||
3437 | else if (sKey == uKey) | |||
3438 | { | |||
3439 | ki->sectionRow = r; | |||
3440 | oKey = 0; | |||
3441 | } | |||
3442 | } | |||
3443 | } | |||
3444 | if ((ki->sectionRow == _GOK_UnknownRow-1) && (warningLevel > 0)) | |||
3445 | { | |||
3446 | WARN3uWarning | |||
3447 | ("Key %s not in \"%s\", but has an overlay key in \"%s\"\n", | |||
3448 | XkbKeyNameText(ki->under, XkbMessage3), | |||
3449 | XkbAtomText(info->dpy, section->name, XkbMessage3), | |||
3450 | XkbAtomText(info->dpy, oi->name, XkbMessage3)); | |||
3451 | ACTIONuAction("Definition ignored\n"); | |||
3452 | } | |||
3453 | } | |||
3454 | /* now prune out keys that aren't in the section */ | |||
3455 | while ((oi->keys != NULL((void*)0)) && (oi->keys->sectionRow == _GOK_UnknownRow-1)) | |||
3456 | { | |||
3457 | next = (OverlayKeyInfo *) oi->keys->defs.next; | |||
3458 | uFree(oi->keys); | |||
3459 | oi->keys = next; | |||
3460 | oi->nKeys--; | |||
3461 | } | |||
3462 | for (ki = oi->keys; (ki != NULL((void*)0)) && (ki->defs.next != NULL((void*)0)); ki = next) | |||
3463 | { | |||
3464 | next = (OverlayKeyInfo *) ki->defs.next; | |||
3465 | if (next->sectionRow == _GOK_UnknownRow-1) | |||
3466 | { | |||
3467 | ki->defs.next = next->defs.next; | |||
3468 | oi->nKeys--; | |||
3469 | uFree(next); | |||
3470 | next = (OverlayKeyInfo *) ki->defs.next; | |||
3471 | } | |||
3472 | } | |||
3473 | if (oi->nKeys < 1) | |||
3474 | { | |||
3475 | ERROR2uError("Overlay \"%s\" for section \"%s\" has no legal keys\n", | |||
3476 | XkbAtomText(info->dpy, oi->name, XkbMessage3), | |||
3477 | XkbAtomText(info->dpy, section->name, XkbMessage3)); | |||
3478 | ACTIONuAction("Overlay definition ignored\n"); | |||
3479 | return False0; | |||
3480 | } | |||
3481 | /* now figure out how many rows are defined for the overlay */ | |||
3482 | bzero(rowSize, sizeof(short) * 256)__builtin___memset_chk (rowSize, 0, sizeof(short) * 256, __builtin_object_size (rowSize, 0)); | |||
3483 | for (k = 0; k < 256; k++) | |||
3484 | { | |||
3485 | rowMap[k] = -1; | |||
3486 | } | |||
3487 | oi->nRows = 0; | |||
3488 | for (ki = oi->keys; ki != NULL((void*)0); ki = (OverlayKeyInfo *) ki->defs.next) | |||
3489 | { | |||
3490 | if (rowMap[ki->sectionRow] == -1) | |||
3491 | rowMap[ki->sectionRow] = oi->nRows++; | |||
3492 | ki->overlayRow = rowMap[ki->sectionRow]; | |||
3493 | rowSize[ki->overlayRow]++; | |||
3494 | } | |||
3495 | return True1; | |||
3496 | } | |||
3497 | ||||
3498 | static Boolint | |||
3499 | CopyOverlayDef(XkbGeometryPtr geom, | |||
3500 | XkbSectionPtr section, OverlayInfo * oi, GeometryInfo * info) | |||
3501 | { | |||
3502 | Atom name; | |||
3503 | XkbOverlayPtr ol; | |||
3504 | XkbOverlayRowPtr row; | |||
3505 | XkbOverlayKeyPtr key; | |||
3506 | OverlayKeyInfo *ki; | |||
3507 | short rowMap[256], rowSize[256]; | |||
3508 | int i; | |||
3509 | ||||
3510 | if (!VerifyOverlayInfo(geom, section, oi, info, rowMap, rowSize)) | |||
3511 | return False0; | |||
3512 | name = XkbInternAtom(NULL((void*)0), XkbAtomGetString(NULL((void*)0), oi->name), False0); | |||
3513 | ol = XkbAddGeomOverlay(section, name, oi->nRows); | |||
3514 | if (!ol) | |||
3515 | { | |||
3516 | WSGO2uInternalError("Couldn't add overlay \"%s\" to section \"%s\"\n", | |||
3517 | XkbAtomText(info->dpy, name, XkbMessage3), | |||
3518 | XkbAtomText(info->dpy, section->name, XkbMessage3)); | |||
3519 | return False0; | |||
3520 | } | |||
3521 | for (i = 0; i < oi->nRows; i++) | |||
3522 | { | |||
3523 | int tmp, row_under; | |||
3524 | for (tmp = 0, row_under = -1; | |||
3525 | (tmp < section->num_rows) && (row_under < 0); tmp++) | |||
3526 | { | |||
3527 | if (rowMap[tmp] == i) | |||
3528 | row_under = tmp; | |||
3529 | } | |||
3530 | if (!XkbAddGeomOverlayRow(ol, row_under, rowSize[i])) | |||
3531 | { | |||
3532 | WSGO3uInternalError | |||
3533 | ("Can't add row %d to overlay \"%s\" of section \"%s\"\n", | |||
3534 | i, XkbAtomText(info->dpy, name, XkbMessage3), | |||
3535 | XkbAtomText(info->dpy, section->name, XkbMessage3)); | |||
3536 | return False0; | |||
3537 | } | |||
3538 | } | |||
3539 | for (ki = oi->keys; ki != NULL((void*)0); ki = (OverlayKeyInfo *) ki->defs.next) | |||
3540 | { | |||
3541 | row = &ol->rows[ki->overlayRow]; | |||
3542 | key = &row->keys[row->num_keys++]; | |||
3543 | bzero(key, sizeof(XkbOverlayKeyRec))__builtin___memset_chk (key, 0, sizeof(XkbOverlayKeyRec), __builtin_object_size (key, 0)); | |||
3544 | strncpy(key->over.name, ki->over, XkbKeyNameLength)__builtin___strncpy_chk (key->over.name, ki->over, 4, __builtin_object_size (key->over.name, 2 > 1 ? 1 : 0)); | |||
3545 | strncpy(key->under.name, ki->under, XkbKeyNameLength)__builtin___strncpy_chk (key->under.name, ki->under, 4, __builtin_object_size (key->under.name, 2 > 1 ? 1 : 0) ); | |||
3546 | } | |||
3547 | return True1; | |||
3548 | } | |||
3549 | ||||
3550 | /***====================================================================***/ | |||
3551 | ||||
3552 | static Boolint | |||
3553 | CopySectionDef(XkbGeometryPtr geom, SectionInfo * si, GeometryInfo * info) | |||
3554 | { | |||
3555 | XkbSectionPtr section; | |||
3556 | XkbRowPtr row; | |||
3557 | XkbKeyPtr key; | |||
3558 | KeyInfo *ki; | |||
3559 | RowInfo *ri; | |||
3560 | Atom name; | |||
3561 | ||||
3562 | name = XkbInternAtom(NULL((void*)0), XkbAtomGetString(NULL((void*)0), si->name), False0); | |||
3563 | section = | |||
3564 | XkbAddGeomSection(geom, name, si->nRows, si->nDoodads, si->nOverlays); | |||
3565 | if (section == NULL((void*)0)) | |||
3566 | { | |||
3567 | WSGOuInternalError("Couldn't allocate section in geometry\n"); | |||
3568 | ACTION1uAction("Section %s not compiled\n", scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default")); | |||
3569 | return False0; | |||
3570 | } | |||
3571 | section->top = si->top; | |||
3572 | section->left = si->left; | |||
3573 | section->width = si->width; | |||
3574 | section->height = si->height; | |||
3575 | section->angle = si->angle; | |||
3576 | section->priority = si->priority; | |||
3577 | for (ri = si->rows; ri != NULL((void*)0); ri = (RowInfo *) ri->defs.next) | |||
3578 | { | |||
3579 | row = XkbAddGeomRow(section, ri->nKeys); | |||
3580 | if (row == NULL((void*)0)) | |||
3581 | { | |||
3582 | WSGOuInternalError("Couldn't allocate row in section\n"); | |||
3583 | ACTION1uAction("Section %s is incomplete\n", scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default")); | |||
3584 | return False0; | |||
3585 | } | |||
3586 | row->top = ri->top; | |||
3587 | row->left = ri->left; | |||
3588 | row->vertical = ri->vertical; | |||
3589 | for (ki = ri->keys; ki != NULL((void*)0); ki = (KeyInfo *) ki->defs.next) | |||
3590 | { | |||
3591 | XkbColorPtr color; | |||
3592 | if ((ki->defs.defined & _GK_Name(1<<1)) == 0) | |||
3593 | { | |||
3594 | ERROR3uError("Key %d of row %d in section %s has no name\n", | |||
3595 | (int) ki->index, (int) ri->index, | |||
3596 | scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default")); | |||
3597 | ACTION1uAction("Section %s ignored\n", scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default")); | |||
3598 | return False0; | |||
3599 | } | |||
3600 | key = XkbAddGeomKey(row); | |||
3601 | if (key == NULL((void*)0)) | |||
3602 | { | |||
3603 | WSGOuInternalError("Couldn't allocate key in row\n"); | |||
3604 | ACTION1uAction("Section %s is incomplete\n", scText(info->dpy, si)((si)?XkbAtomText((info->dpy),(si)->name,3):"default")); | |||
3605 | return False0; | |||
3606 | } | |||
3607 | memcpy(key->name.name, ki->name, XkbKeyNameLength)__builtin___memcpy_chk (key->name.name, ki->name, 4, __builtin_object_size (key->name.name, 0)); | |||
3608 | key->gap = ki->gap; | |||
3609 | if (ki->shape == None0L) | |||
3610 | key->shape_ndx = 0; | |||
3611 | else | |||
3612 | { | |||
3613 | ShapeInfo *sinfo; | |||
3614 | sinfo = FindShape(info, ki->shape, "key", keyText(ki)((ki)&&(ki)->name[0]?(ki)->name:"default")); | |||
3615 | if (!sinfo) | |||
3616 | return False0; | |||
3617 | key->shape_ndx = sinfo->index; | |||
3618 | } | |||
3619 | if (ki->color != None0L) | |||
3620 | color = | |||
3621 | XkbAddGeomColor(geom, | |||
3622 | XkbAtomGetString(NULL((void*)0), ki->color), | |||
3623 | geom->num_colors); | |||
3624 | else | |||
3625 | color = XkbAddGeomColor(geom, "white", geom->num_colors); | |||
3626 | XkbSetKeyColor(geom, key, color)((key)->color_ndx= (color)-&(geom)->colors[0]); | |||
3627 | } | |||
3628 | } | |||
3629 | if (si->doodads != NULL((void*)0)) | |||
3630 | { | |||
3631 | DoodadInfo *di; | |||
3632 | for (di = si->doodads; di != NULL((void*)0); di = (DoodadInfo *) di->defs.next) | |||
3633 | { | |||
3634 | CopyDoodadDef(geom, section, di, info); | |||
3635 | } | |||
3636 | } | |||
3637 | if (si->overlays != NULL((void*)0)) | |||
3638 | { | |||
3639 | OverlayInfo *oi; | |||
3640 | for (oi = si->overlays; oi != NULL((void*)0); | |||
3641 | oi = (OverlayInfo *) oi->defs.next) | |||
3642 | { | |||
3643 | CopyOverlayDef(geom, section, oi, info); | |||
3644 | } | |||
3645 | } | |||
3646 | if (XkbComputeSectionBounds(geom, section)) | |||
3647 | { | |||
3648 | /* 7/6/94 (ef) -- check for negative origin and translate */ | |||
3649 | if ((si->defs.defined & _GS_Width(1<<4)) == 0) | |||
3650 | section->width = section->bounds.x2; | |||
3651 | if ((si->defs.defined & _GS_Height(1<<5)) == 0) | |||
3652 | section->height = section->bounds.y2; | |||
3653 | } | |||
3654 | return True1; | |||
3655 | } | |||
3656 | ||||
3657 | /***====================================================================***/ | |||
3658 | ||||
3659 | Boolint | |||
3660 | CompileGeometry(XkbFile * file, XkbFileInfo * result, unsigned merge) | |||
3661 | { | |||
3662 | GeometryInfo info; | |||
3663 | XkbDescPtr xkb; | |||
3664 | ||||
3665 | xkb = result->xkb; | |||
3666 | InitGeometryInfo(&info, file->id, merge); | |||
3667 | info.dpy = xkb->dpy; | |||
3668 | HandleGeometryFile(file, xkb, merge, &info); | |||
3669 | ||||
3670 | if (info.errorCount == 0) | |||
3671 | { | |||
3672 | XkbGeometryPtr geom; | |||
3673 | XkbGeometrySizesRec sizes; | |||
3674 | bzero(&sizes, sizeof(sizes))__builtin___memset_chk (&sizes, 0, sizeof(sizes), __builtin_object_size (&sizes, 0)); | |||
3675 | sizes.which = XkbGeomAllMask(0x3f); | |||
3676 | sizes.num_properties = info.nProps; | |||
3677 | sizes.num_colors = 8; | |||
3678 | sizes.num_shapes = info.nShapes; | |||
3679 | sizes.num_sections = info.nSections; | |||
3680 | sizes.num_doodads = info.nDoodads; | |||
3681 | if (XkbAllocGeometry(xkb, &sizes) != Success0) | |||
3682 | { | |||
3683 | WSGOuInternalError("Couldn't allocate GeometryRec\n"); | |||
3684 | ACTIONuAction("Geometry not compiled\n"); | |||
3685 | return False0; | |||
3686 | } | |||
3687 | geom = xkb->geom; | |||
3688 | ||||
3689 | geom->width_mm = info.widthMM; | |||
3690 | geom->height_mm = info.heightMM; | |||
3691 | if (info.name != NULL((void*)0)) | |||
3692 | { | |||
3693 | geom->name = XkbInternAtom(xkb->dpy, info.name, False0); | |||
3694 | if (XkbAllocNames(xkb, XkbGeometryNameMask(1<<1), 0, 0) == Success0) | |||
3695 | xkb->names->geometry = geom->name; | |||
3696 | } | |||
3697 | if (info.fontSpec != None0L) | |||
3698 | geom->label_font = | |||
3699 | uStringDup(XkbAtomGetString(NULL, info.fontSpec))((XkbAtomGetString(((void*)0), info.fontSpec)) ? strdup(XkbAtomGetString (((void*)0), info.fontSpec)) : ((void*)0)); | |||
3700 | else | |||
3701 | geom->label_font = FontFromParts(info.font, info.fontWeight, | |||
3702 | info.fontSlant, | |||
3703 | info.fontSetWidth, | |||
3704 | info.fontVariant, | |||
3705 | info.fontSize, | |||
3706 | info.fontEncoding); | |||
3707 | XkbAddGeomColor(geom, "black", geom->num_colors); | |||
3708 | XkbAddGeomColor(geom, "white", geom->num_colors); | |||
3709 | ||||
3710 | if (info.baseColor == None0L) | |||
3711 | info.baseColor = XkbInternAtom(NULL((void*)0), "white", False0); | |||
3712 | if (info.labelColor == None0L) | |||
3713 | info.labelColor = XkbInternAtom(NULL((void*)0), "black", False0); | |||
3714 | geom->base_color = | |||
3715 | XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), info.baseColor), | |||
3716 | geom->num_colors); | |||
3717 | geom->label_color = | |||
3718 | XkbAddGeomColor(geom, XkbAtomGetString(NULL((void*)0), info.labelColor), | |||
3719 | geom->num_colors); | |||
3720 | ||||
3721 | if (info.props) | |||
3722 | { | |||
3723 | PropertyInfo *pi; | |||
3724 | for (pi = info.props; pi != NULL((void*)0); | |||
3725 | pi = (PropertyInfo *) pi->defs.next) | |||
3726 | { | |||
3727 | if (!XkbAddGeomProperty(geom, pi->name, pi->value)) | |||
3728 | return False0; | |||
3729 | } | |||
3730 | } | |||
3731 | if (info.shapes) | |||
3732 | { | |||
3733 | ShapeInfo *si; | |||
3734 | for (si = info.shapes; si != NULL((void*)0); | |||
3735 | si = (ShapeInfo *) si->defs.next) | |||
3736 | { | |||
3737 | if (!CopyShapeDef(xkb->dpy, geom, si)) | |||
3738 | return False0; | |||
3739 | } | |||
3740 | } | |||
3741 | if (info.sections) | |||
3742 | { | |||
3743 | SectionInfo *si; | |||
3744 | for (si = info.sections; si != NULL((void*)0); | |||
3745 | si = (SectionInfo *) si->defs.next) | |||
3746 | { | |||
3747 | if (!CopySectionDef(geom, si, &info)) | |||
3748 | return False0; | |||
3749 | } | |||
3750 | } | |||
3751 | if (info.doodads) | |||
3752 | { | |||
3753 | DoodadInfo *di; | |||
3754 | for (di = info.doodads; di != NULL((void*)0); | |||
3755 | di = (DoodadInfo *) di->defs.next) | |||
3756 | { | |||
3757 | if (!CopyDoodadDef(geom, NULL((void*)0), di, &info)) | |||
3758 | return False0; | |||
3759 | } | |||
3760 | } | |||
3761 | if (info.aliases) | |||
3762 | ApplyAliases(xkb, True1, &info.aliases); | |||
3763 | ClearGeometryInfo(&info); | |||
3764 | return True1; | |||
3765 | } | |||
3766 | return False0; | |||
3767 | } |