1 /************************************************************
2 Copyright (c) 1993 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 #ifdef DEBUG
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <stdio.h>
32 #endif
33
34 #define NEED_MAP_READERS
35 #include "Xlibint.h"
36 #include "X11/extensions/XKBgeom.h"
37 #include <X11/extensions/XKBproto.h>
38 #include "XKBlibint.h"
39
40 #ifndef MINSHORT
41 #define MINSHORT -32768
42 #endif
43 #ifndef MAXSHORT
44 #define MAXSHORT 32767
45 #endif
46
47 /***====================================================================***/
48
49 static void
_XkbCheckBounds(XkbBoundsPtr bounds,int x,int y)50 _XkbCheckBounds(XkbBoundsPtr bounds, int x, int y)
51 {
52 if (x < bounds->x1)
53 bounds->x1 = x;
54 if (x > bounds->x2)
55 bounds->x2 = x;
56 if (y < bounds->y1)
57 bounds->y1 = y;
58 if (y > bounds->y2)
59 bounds->y2 = y;
60 return;
61 }
62
63 Bool
XkbComputeShapeBounds(XkbShapePtr shape)64 XkbComputeShapeBounds(XkbShapePtr shape)
65 {
66 register int o, p;
67 XkbOutlinePtr outline;
68 XkbPointPtr pt;
69
70 if ((!shape) || (shape->num_outlines < 1))
71 return False;
72 shape->bounds.x1 = shape->bounds.y1 = MAXSHORT;
73 shape->bounds.x2 = shape->bounds.y2 = MINSHORT;
74 for (outline = shape->outlines, o = 0; o < shape->num_outlines;
75 o++, outline++) {
76 for (pt = outline->points, p = 0; p < outline->num_points; p++, pt++) {
77 _XkbCheckBounds(&shape->bounds, pt->x, pt->y);
78 }
79 if (outline->num_points < 2) {
80 _XkbCheckBounds(&shape->bounds, 0, 0);
81 }
82 }
83 return True;
84 }
85
86 Bool
XkbComputeShapeTop(XkbShapePtr shape,XkbBoundsPtr bounds)87 XkbComputeShapeTop(XkbShapePtr shape, XkbBoundsPtr bounds)
88 {
89 register int p;
90 XkbOutlinePtr outline;
91 XkbPointPtr pt;
92
93 if ((!shape) || (shape->num_outlines < 1))
94 return False;
95 if (shape->approx)
96 outline = shape->approx;
97 else
98 outline = &shape->outlines[shape->num_outlines - 1];
99 if (outline->num_points < 2) {
100 bounds->x1 = bounds->y1 = 0;
101 bounds->x2 = bounds->y2 = 0;
102 }
103 else {
104 bounds->x1 = bounds->y1 = MAXSHORT;
105 bounds->x2 = bounds->y2 = MINSHORT;
106 }
107 for (pt = outline->points, p = 0; p < outline->num_points; p++, pt++) {
108 _XkbCheckBounds(bounds, pt->x, pt->y);
109 }
110 return True;
111 }
112
113 Bool
XkbComputeRowBounds(XkbGeometryPtr geom,XkbSectionPtr section,XkbRowPtr row)114 XkbComputeRowBounds(XkbGeometryPtr geom, XkbSectionPtr section, XkbRowPtr row)
115 {
116 register int k, pos;
117 XkbKeyPtr key;
118 XkbBoundsPtr bounds, sbounds;
119
120 if ((!geom) || (!section) || (!row))
121 return False;
122 bounds = &row->bounds;
123 bzero(bounds, sizeof(XkbBoundsRec));
124 for (key = row->keys, pos = k = 0; k < row->num_keys; k++, key++) {
125 sbounds = &XkbKeyShape(geom, key)->bounds;
126 _XkbCheckBounds(bounds, pos, 0);
127 if (!row->vertical) {
128 if (key->gap != 0) {
129 pos += key->gap;
130 _XkbCheckBounds(bounds, pos, 0);
131 }
132 _XkbCheckBounds(bounds, pos + sbounds->x1, sbounds->y1);
133 _XkbCheckBounds(bounds, pos + sbounds->x2, sbounds->y2);
134 pos += sbounds->x2;
135 }
136 else {
137 if (key->gap != 0) {
138 pos += key->gap;
139 _XkbCheckBounds(bounds, 0, pos);
140 }
141 _XkbCheckBounds(bounds, pos + sbounds->x1, sbounds->y1);
142 _XkbCheckBounds(bounds, pos + sbounds->x2, sbounds->y2);
143 pos += sbounds->y2;
144 }
145 }
146 return True;
147 }
148
149 Bool
XkbComputeSectionBounds(XkbGeometryPtr geom,XkbSectionPtr section)150 XkbComputeSectionBounds(XkbGeometryPtr geom, XkbSectionPtr section)
151 {
152 register int i;
153 XkbShapePtr shape;
154 XkbRowPtr row;
155 XkbDoodadPtr doodad;
156 XkbBoundsPtr bounds, rbounds;
157
158 if ((!geom) || (!section))
159 return False;
160 bounds = §ion->bounds;
161 bzero(bounds, sizeof(XkbBoundsRec));
162 for (i = 0, row = section->rows; i < section->num_rows; i++, row++) {
163 if (!XkbComputeRowBounds(geom, section, row))
164 return False;
165 rbounds = &row->bounds;
166 _XkbCheckBounds(bounds, row->left + rbounds->x1,
167 row->top + rbounds->y1);
168 _XkbCheckBounds(bounds, row->left + rbounds->x2,
169 row->top + rbounds->y2);
170 }
171 for (i = 0, doodad = section->doodads; i < section->num_doodads;
172 i++, doodad++) {
173 static XkbBoundsRec tbounds;
174
175 switch (doodad->any.type) {
176 case XkbOutlineDoodad:
177 case XkbSolidDoodad:
178 shape = XkbShapeDoodadShape(geom, &doodad->shape);
179 rbounds = &shape->bounds;
180 break;
181 case XkbTextDoodad:
182 tbounds.x1 = doodad->text.left;
183 tbounds.y1 = doodad->text.top;
184 tbounds.x2 = tbounds.x1 + doodad->text.width;
185 tbounds.y2 = tbounds.y1 + doodad->text.height;
186 rbounds = &tbounds;
187 break;
188 case XkbIndicatorDoodad:
189 shape = XkbIndicatorDoodadShape(geom, &doodad->indicator);
190 rbounds = &shape->bounds;
191 break;
192 case XkbLogoDoodad:
193 shape = XkbLogoDoodadShape(geom, &doodad->logo);
194 rbounds = &shape->bounds;
195 break;
196 default:
197 tbounds.x1 = tbounds.x2 = doodad->any.left;
198 tbounds.y1 = tbounds.y2 = doodad->any.top;
199 rbounds = &tbounds;
200 break;
201 }
202 _XkbCheckBounds(bounds, rbounds->x1, rbounds->y1);
203 _XkbCheckBounds(bounds, rbounds->x2, rbounds->y2);
204 }
205 return True;
206 }
207
208 /***====================================================================***/
209
210 char *
XkbFindOverlayForKey(XkbGeometryPtr geom,XkbSectionPtr wanted,char * under)211 XkbFindOverlayForKey(XkbGeometryPtr geom, XkbSectionPtr wanted, char *under)
212 {
213 int s;
214 XkbSectionPtr section;
215
216 if ((geom == NULL) || (under == NULL) || (geom->num_sections < 1))
217 return NULL;
218
219 if (wanted)
220 section = wanted;
221 else
222 section = geom->sections;
223
224 for (s = 0; s < geom->num_sections; s++, section++) {
225 XkbOverlayPtr ol;
226 int o;
227
228 if (section->num_overlays < 1)
229 continue;
230 for (o = 0, ol = section->overlays; o < section->num_overlays;
231 o++, ol++) {
232 XkbOverlayRowPtr row;
233 int r;
234
235 for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) {
236 XkbOverlayKeyPtr key;
237 int k;
238
239 for (k = 0, key = row->keys; k < row->num_keys; k++, key++) {
240 if (strncmp(under, key->under.name, XkbKeyNameLength) == 0)
241 return key->over.name;
242 }
243 }
244 }
245 if (wanted != NULL)
246 break;
247 }
248 return NULL;
249 }
250
251 /***====================================================================***/
252
253 static Status
_XkbReadGeomProperties(XkbReadBufferPtr buf,XkbGeometryPtr geom,xkbGetGeometryReply * rep)254 _XkbReadGeomProperties(XkbReadBufferPtr buf,
255 XkbGeometryPtr geom,
256 xkbGetGeometryReply *rep)
257 {
258 Status rtrn;
259
260 if (rep->nProperties < 1)
261 return Success;
262 if ((rtrn = XkbAllocGeomProps(geom, rep->nProperties)) == Success) {
263 register int i;
264 register Bool ok = True;
265
266 for (i = 0; (i < rep->nProperties) && ok; i++) {
267 char *name = NULL;
268 char *value = NULL;
269 ok = _XkbGetReadBufferCountedString(buf, &name) && ok;
270 ok = _XkbGetReadBufferCountedString(buf, &value) && ok;
271 ok = ok && (XkbAddGeomProperty(geom, name, value) != NULL);
272
273 _XkbFree(name);
274 _XkbFree(value);
275 }
276 if (ok)
277 rtrn = Success;
278 else
279 rtrn = BadLength;
280 }
281 return rtrn;
282 }
283
284 static Status
_XkbReadGeomKeyAliases(XkbReadBufferPtr buf,XkbGeometryPtr geom,xkbGetGeometryReply * rep)285 _XkbReadGeomKeyAliases(XkbReadBufferPtr buf,
286 XkbGeometryPtr geom,
287 xkbGetGeometryReply *rep)
288 {
289 Status rtrn;
290
291 if (rep->nKeyAliases < 1)
292 return Success;
293 if ((rtrn = XkbAllocGeomKeyAliases(geom, rep->nKeyAliases)) == Success) {
294 if (!_XkbCopyFromReadBuffer(buf, (char *) geom->key_aliases,
295 (rep->nKeyAliases * XkbKeyNameLength * 2)))
296 return BadLength;
297 geom->num_key_aliases = rep->nKeyAliases;
298 return Success;
299 }
300 else { /* alloc failed, just skip the aliases */
301 _XkbSkipReadBufferData(buf, (rep->nKeyAliases * XkbKeyNameLength * 2));
302 }
303 return rtrn;
304 }
305
306 static Status
_XkbReadGeomColors(XkbReadBufferPtr buf,XkbGeometryPtr geom,xkbGetGeometryReply * rep)307 _XkbReadGeomColors(XkbReadBufferPtr buf,
308 XkbGeometryPtr geom,
309 xkbGetGeometryReply *rep)
310 {
311 Status rtrn;
312
313 if (rep->nColors < 1)
314 return Success;
315 if ((rtrn = XkbAllocGeomColors(geom, rep->nColors)) == Success) {
316 register int i;
317
318 for (i = 0; i < rep->nColors; i++) {
319 char *spec = NULL;
320 if (!_XkbGetReadBufferCountedString(buf, &spec))
321 rtrn = BadLength;
322 else if (XkbAddGeomColor(geom, spec, geom->num_colors) == NULL)
323 rtrn = BadAlloc;
324
325 _XkbFree(spec);
326 if (rtrn != Success)
327 return rtrn;
328 }
329 return Success;
330 }
331 return rtrn;
332 }
333
334 static Status
_XkbReadGeomShapes(XkbReadBufferPtr buf,XkbGeometryPtr geom,xkbGetGeometryReply * rep)335 _XkbReadGeomShapes(XkbReadBufferPtr buf,
336 XkbGeometryPtr geom,
337 xkbGetGeometryReply *rep)
338 {
339 register int i;
340 Status rtrn;
341
342 if (rep->nShapes < 1)
343 return Success;
344 if ((rtrn = XkbAllocGeomShapes(geom, rep->nShapes)) != Success)
345 return rtrn;
346 for (i = 0; i < rep->nShapes; i++) {
347 xkbShapeWireDesc *shapeWire;
348 XkbShapePtr shape;
349 register int o;
350
351 shapeWire = (xkbShapeWireDesc *)
352 _XkbGetReadBufferPtr(buf, SIZEOF(xkbShapeWireDesc));
353 if (!shapeWire)
354 return BadLength;
355 shape = XkbAddGeomShape(geom, shapeWire->name, shapeWire->nOutlines);
356 if (!shape)
357 return BadAlloc;
358 for (o = 0; o < shapeWire->nOutlines; o++) {
359 xkbOutlineWireDesc *olWire;
360 XkbOutlinePtr ol;
361 register int p;
362 XkbPointPtr pt;
363
364 olWire = (xkbOutlineWireDesc *)
365 _XkbGetReadBufferPtr(buf, SIZEOF(xkbOutlineWireDesc));
366 if (!olWire)
367 return BadLength;
368 ol = XkbAddGeomOutline(shape, olWire->nPoints);
369 if (!ol)
370 return BadAlloc;
371 ol->corner_radius = olWire->cornerRadius;
372 for (p = 0, pt = ol->points; p < olWire->nPoints; p++, pt++) {
373 xkbPointWireDesc *ptWire;
374
375 ptWire = (xkbPointWireDesc *)
376 _XkbGetReadBufferPtr(buf, SIZEOF(xkbPointWireDesc));
377 if (!ptWire)
378 return BadLength;
379 pt->x = ptWire->x;
380 pt->y = ptWire->y;
381 }
382 ol->num_points = olWire->nPoints;
383 }
384 if ((shapeWire->primaryNdx != XkbNoShape) &&
385 (shapeWire->primaryNdx < shapeWire->nOutlines))
386 shape->primary = &shape->outlines[shapeWire->primaryNdx];
387 else
388 shape->primary = NULL;
389 if ((shapeWire->approxNdx != XkbNoShape) &&
390 (shapeWire->approxNdx < shapeWire->nOutlines))
391 shape->approx = &shape->outlines[shapeWire->approxNdx];
392 else
393 shape->approx = NULL;
394 XkbComputeShapeBounds(shape);
395 }
396 return Success;
397 }
398
399 static Status
_XkbReadGeomDoodad(XkbReadBufferPtr buf,XkbGeometryPtr geom,XkbSectionPtr section)400 _XkbReadGeomDoodad(XkbReadBufferPtr buf,
401 XkbGeometryPtr geom,
402 XkbSectionPtr section)
403 {
404 XkbDoodadPtr doodad;
405 xkbDoodadWireDesc *doodadWire;
406
407 doodadWire = (xkbDoodadWireDesc *)
408 _XkbGetReadBufferPtr(buf, SIZEOF(xkbDoodadWireDesc));
409 if (!doodadWire)
410 return BadLength;
411 doodad = XkbAddGeomDoodad(geom, section, doodadWire->any.name);
412 if (!doodad)
413 return BadAlloc;
414 doodad->any.type = doodadWire->any.type;
415 doodad->any.priority = doodadWire->any.priority;
416 doodad->any.top = doodadWire->any.top;
417 doodad->any.left = doodadWire->any.left;
418 doodad->any.angle = doodadWire->any.angle;
419 switch (doodad->any.type) {
420 case XkbOutlineDoodad:
421 case XkbSolidDoodad:
422 doodad->shape.color_ndx = doodadWire->shape.colorNdx;
423 doodad->shape.shape_ndx = doodadWire->shape.shapeNdx;
424 break;
425 case XkbTextDoodad:
426 doodad->text.width = doodadWire->text.width;
427 doodad->text.height = doodadWire->text.height;
428 doodad->text.color_ndx = doodadWire->text.colorNdx;
429 if (!_XkbGetReadBufferCountedString(buf, &doodad->text.text))
430 return BadLength;
431 if (!_XkbGetReadBufferCountedString(buf, &doodad->text.font))
432 return BadLength;
433 break;
434 case XkbIndicatorDoodad:
435 doodad->indicator.shape_ndx = doodadWire->indicator.shapeNdx;
436 doodad->indicator.on_color_ndx = doodadWire->indicator.onColorNdx;
437 doodad->indicator.off_color_ndx = doodadWire->indicator.offColorNdx;
438 break;
439 case XkbLogoDoodad:
440 doodad->logo.color_ndx = doodadWire->logo.colorNdx;
441 doodad->logo.shape_ndx = doodadWire->logo.shapeNdx;
442 if (!_XkbGetReadBufferCountedString(buf, &doodad->logo.logo_name))
443 return BadLength;
444 break;
445 default:
446 return BadValue;
447 }
448 return Success;
449 }
450
451 static Status
_XkbReadGeomOverlay(XkbReadBufferPtr buf,XkbGeometryPtr geom,XkbSectionPtr section)452 _XkbReadGeomOverlay(XkbReadBufferPtr buf,
453 XkbGeometryPtr geom,
454 XkbSectionPtr section)
455 {
456 XkbOverlayPtr ol;
457 xkbOverlayWireDesc *olWire;
458 register int r;
459
460 olWire = (xkbOverlayWireDesc *)
461 _XkbGetReadBufferPtr(buf, SIZEOF(xkbOverlayWireDesc));
462 if (olWire == NULL)
463 return BadLength;
464 ol = XkbAddGeomOverlay(section, olWire->name, olWire->nRows);
465 if (ol == NULL)
466 return BadLength;
467 for (r = 0; r < olWire->nRows; r++) {
468 register int k;
469 XkbOverlayRowPtr row;
470 xkbOverlayRowWireDesc *rowWire;
471 xkbOverlayKeyWireDesc *keyWire;
472
473 rowWire = (xkbOverlayRowWireDesc *)
474 _XkbGetReadBufferPtr(buf, SIZEOF(xkbOverlayRowWireDesc));
475 if (rowWire == NULL)
476 return BadLength;
477 row = XkbAddGeomOverlayRow(ol, rowWire->rowUnder, rowWire->nKeys);
478 if (!row)
479 return BadAlloc;
480 row->row_under = rowWire->rowUnder;
481 if (rowWire->nKeys < 1)
482 continue;
483 keyWire = (xkbOverlayKeyWireDesc *)
484 _XkbGetReadBufferPtr(buf,
485 SIZEOF(xkbOverlayKeyWireDesc) * rowWire->nKeys);
486 if (keyWire == NULL)
487 return BadLength;
488 for (k = 0; k < rowWire->nKeys; k++, keyWire++, row->num_keys++) {
489 memcpy(row->keys[row->num_keys].over.name, keyWire->over,
490 XkbKeyNameLength);
491 memcpy(row->keys[row->num_keys].under.name, keyWire->under,
492 XkbKeyNameLength);
493 }
494 }
495 return Success;
496 }
497
498 static Status
_XkbReadGeomSections(XkbReadBufferPtr buf,XkbGeometryPtr geom,xkbGetGeometryReply * rep)499 _XkbReadGeomSections(XkbReadBufferPtr buf,
500 XkbGeometryPtr geom,
501 xkbGetGeometryReply *rep)
502 {
503 register int s;
504 XkbSectionPtr section;
505 xkbSectionWireDesc *sectionWire;
506 Status rtrn;
507
508 if (rep->nSections < 1)
509 return Success;
510 if ((rtrn = XkbAllocGeomSections(geom, rep->nSections)) != Success)
511 return rtrn;
512 for (s = 0; s < rep->nSections; s++) {
513 sectionWire = (xkbSectionWireDesc *)
514 _XkbGetReadBufferPtr(buf, SIZEOF(xkbSectionWireDesc));
515 if (!sectionWire)
516 return BadLength;
517 section = XkbAddGeomSection(geom, sectionWire->name, sectionWire->nRows,
518 sectionWire->nDoodads,
519 sectionWire->nOverlays);
520 if (!section)
521 return BadAlloc;
522 section->top = sectionWire->top;
523 section->left = sectionWire->left;
524 section->width = sectionWire->width;
525 section->height = sectionWire->height;
526 section->angle = sectionWire->angle;
527 section->priority = sectionWire->priority;
528 if (sectionWire->nRows > 0) {
529 register int r;
530
531 for (r = 0; r < sectionWire->nRows; r++) {
532 XkbRowPtr row;
533 xkbRowWireDesc *rowWire;
534
535 rowWire = (xkbRowWireDesc *)
536 _XkbGetReadBufferPtr(buf, SIZEOF(xkbRowWireDesc));
537 if (!rowWire)
538 return BadLength;
539 row = XkbAddGeomRow(section, rowWire->nKeys);
540 if (!row)
541 return BadAlloc;
542 row->top = rowWire->top;
543 row->left = rowWire->left;
544 row->vertical = rowWire->vertical;
545 if (rowWire->nKeys > 0) {
546 register int k;
547
548 for (k = 0; k < rowWire->nKeys; k++) {
549 XkbKeyPtr key;
550 xkbKeyWireDesc *keyWire;
551
552 keyWire = (xkbKeyWireDesc *)
553 _XkbGetReadBufferPtr(buf, SIZEOF(xkbKeyWireDesc));
554 if (!keyWire)
555 return BadLength;
556 key = XkbAddGeomKey(row);
557 if (!key)
558 return BadAlloc;
559 memcpy(key->name.name, keyWire->name, XkbKeyNameLength);
560 key->gap = keyWire->gap;
561 key->shape_ndx = keyWire->shapeNdx;
562 key->color_ndx = keyWire->colorNdx;
563 }
564 }
565 }
566 }
567 if (sectionWire->nDoodads > 0) {
568 register int d;
569
570 for (d = 0; d < sectionWire->nDoodads; d++) {
571 if ((rtrn = _XkbReadGeomDoodad(buf, geom, section)) != Success)
572 return rtrn;
573 }
574 }
575 if (sectionWire->nOverlays > 0) {
576 register int o;
577
578 for (o = 0; o < sectionWire->nOverlays; o++) {
579 if ((rtrn = _XkbReadGeomOverlay(buf, geom, section)) != Success)
580 return rtrn;
581 }
582 }
583 }
584 return Success;
585 }
586
587 static Status
_XkbReadGeomDoodads(XkbReadBufferPtr buf,XkbGeometryPtr geom,xkbGetGeometryReply * rep)588 _XkbReadGeomDoodads(XkbReadBufferPtr buf,
589 XkbGeometryPtr geom,
590 xkbGetGeometryReply *rep)
591 {
592 register int d;
593 Status rtrn;
594
595 if (rep->nDoodads < 1)
596 return Success;
597 if ((rtrn = XkbAllocGeomDoodads(geom, rep->nDoodads)) != Success)
598 return rtrn;
599 for (d = 0; d < rep->nDoodads; d++) {
600 if ((rtrn = _XkbReadGeomDoodad(buf, geom, NULL)) != Success)
601 return rtrn;
602 }
603 return Success;
604 }
605
606 Status
_XkbReadGetGeometryReply(Display * dpy,xkbGetGeometryReply * rep,XkbDescPtr xkb,int * nread_rtrn)607 _XkbReadGetGeometryReply(Display *dpy,
608 xkbGetGeometryReply *rep,
609 XkbDescPtr xkb,
610 int *nread_rtrn)
611 {
612 XkbGeometryPtr geom;
613
614 geom = _XkbTypedCalloc(1, XkbGeometryRec);
615 if (!geom)
616 return BadAlloc;
617 if (xkb->geom)
618 XkbFreeGeometry(xkb->geom, XkbGeomAllMask, True);
619 xkb->geom = geom;
620
621 geom->name = rep->name;
622 geom->width_mm = rep->widthMM;
623 geom->height_mm = rep->heightMM;
624 if (rep->length) {
625 XkbReadBufferRec buf;
626 int left;
627
628 if (_XkbInitReadBuffer(dpy, &buf, (int) rep->length * 4)) {
629 Status status = Success;
630
631 if (nread_rtrn)
632 *nread_rtrn = (int) rep->length * 4;
633 if (!_XkbGetReadBufferCountedString(&buf, &geom->label_font))
634 status = BadLength;
635 if (status == Success)
636 status = _XkbReadGeomProperties(&buf, geom, rep);
637 if (status == Success)
638 status = _XkbReadGeomColors(&buf, geom, rep);
639 if (status == Success)
640 status = _XkbReadGeomShapes(&buf, geom, rep);
641 if (status == Success)
642 status = _XkbReadGeomSections(&buf, geom, rep);
643 if (status == Success)
644 status = _XkbReadGeomDoodads(&buf, geom, rep);
645 if (status == Success)
646 status = _XkbReadGeomKeyAliases(&buf, geom, rep);
647 left = _XkbFreeReadBuffer(&buf);
648 if ((rep->baseColorNdx > geom->num_colors) ||
649 (rep->labelColorNdx > geom->num_colors))
650 status = BadLength;
651 if ((status != Success) || left || buf.error) {
652 if (status == Success)
653 status = BadLength;
654 XkbFreeGeometry(geom, XkbGeomAllMask, True);
655 xkb->geom = NULL;
656 return status;
657 }
658 geom->base_color = &geom->colors[rep->baseColorNdx];
659 geom->label_color = &geom->colors[rep->labelColorNdx];
660 }
661 else {
662 XkbFreeGeometry(geom, XkbGeomAllMask, True);
663 xkb->geom = NULL;
664 return BadAlloc;
665 }
666 }
667 return Success;
668 }
669
670 Status
XkbGetGeometry(Display * dpy,XkbDescPtr xkb)671 XkbGetGeometry(Display *dpy, XkbDescPtr xkb)
672 {
673 xkbGetGeometryReq *req;
674 xkbGetGeometryReply rep;
675 Status status;
676
677 if ((!xkb) || (dpy->flags & XlibDisplayNoXkb) ||
678 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
679 return BadAccess;
680
681 LockDisplay(dpy);
682 GetReq(kbGetGeometry, req);
683 req->reqType = dpy->xkb_info->codes->major_opcode;
684 req->xkbReqType = X_kbGetGeometry;
685 req->deviceSpec = xkb->device_spec;
686 req->name = None;
687 if (!_XReply(dpy, (xReply *) &rep, 0, xFalse))
688 status = BadImplementation;
689 else if (!rep.found)
690 status = BadName;
691 else
692 status = _XkbReadGetGeometryReply(dpy, &rep, xkb, NULL);
693 UnlockDisplay(dpy);
694 SyncHandle();
695 return status;
696 }
697
698 Status
XkbGetNamedGeometry(Display * dpy,XkbDescPtr xkb,Atom name)699 XkbGetNamedGeometry(Display *dpy, XkbDescPtr xkb, Atom name)
700 {
701 xkbGetGeometryReq *req;
702 xkbGetGeometryReply rep;
703 Status status;
704
705 if ((name == None) || (dpy->flags & XlibDisplayNoXkb) ||
706 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
707 return BadAccess;
708
709 LockDisplay(dpy);
710 GetReq(kbGetGeometry, req);
711 req->reqType = dpy->xkb_info->codes->major_opcode;
712 req->xkbReqType = X_kbGetGeometry;
713 req->deviceSpec = xkb->device_spec;
714 req->name = (CARD32) name;
715 if ((!_XReply(dpy, (xReply *) &rep, 0, xFalse)) || (!rep.found))
716 status = BadImplementation;
717 else if (!rep.found)
718 status = BadName;
719 else
720 status = _XkbReadGetGeometryReply(dpy, &rep, xkb, NULL);
721 UnlockDisplay(dpy);
722 SyncHandle();
723 return status;
724 }
725