11ab64890Smrg/************************************************************
21ab64890SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
31ab64890Smrg
41ab64890SmrgPermission to use, copy, modify, and distribute this
51ab64890Smrgsoftware and its documentation for any purpose and without
61ab64890Smrgfee is hereby granted, provided that the above copyright
71ab64890Smrgnotice appear in all copies and that both that copyright
81ab64890Smrgnotice and this permission notice appear in supporting
961b2299dSmrgdocumentation, and that the name of Silicon Graphics not be
1061b2299dSmrgused in advertising or publicity pertaining to distribution
111ab64890Smrgof the software without specific prior written permission.
1261b2299dSmrgSilicon Graphics makes no representation about the suitability
131ab64890Smrgof this software for any purpose. It is provided "as is"
141ab64890Smrgwithout any express or implied warranty.
151ab64890Smrg
1661b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
1761b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
181ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
1961b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
2061b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2161b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
221ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
231ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE.
241ab64890Smrg
251ab64890Smrg********************************************************/
261ab64890Smrg
271ab64890Smrg#ifdef DEBUG
281ab64890Smrg#ifdef HAVE_CONFIG_H
291ab64890Smrg#include <config.h>
301ab64890Smrg#endif
311ab64890Smrg#include <stdio.h>
321ab64890Smrg#endif
331ab64890Smrg
341ab64890Smrg#include "Xlibint.h"
351ab64890Smrg#include "XKBlibint.h"
365afda2e6Smrg#include "X11/extensions/XKBgeom.h"
371ab64890Smrg#include <X11/extensions/XKBproto.h>
381ab64890Smrg
391ab64890Smrg#ifndef MINSHORT
401ab64890Smrg#define	MINSHORT	-32768
411ab64890Smrg#endif
421ab64890Smrg#ifndef MAXSHORT
431ab64890Smrg#define	MAXSHORT	32767
441ab64890Smrg#endif
451ab64890Smrg
461ab64890Smrg/***====================================================================***/
471ab64890Smrg
481ab64890Smrg#define	_SizeCountedString(s)  ((s)?XkbPaddedSize(2+strlen(s)):4)
491ab64890Smrg
501ab64890Smrgstatic char *
51818534a1Smrg_WriteCountedString(char *wire, char *str)
521ab64890Smrg{
53818534a1Smrg    CARD16 len, *pLen;
541ab64890Smrg
559c019ec5Smaya    len = (CARD16) (str ? strlen(str) : 0);
56818534a1Smrg    pLen = (CARD16 *) wire;
57818534a1Smrg    *pLen = len;
581ab64890Smrg    if (len && str)
59818534a1Smrg        memcpy(&wire[2], str, len);
60818534a1Smrg    wire += XkbPaddedSize(len + 2);
611ab64890Smrg    return wire;
621ab64890Smrg}
631ab64890Smrg
641ab64890Smrgstatic int
651ab64890Smrg_SizeGeomProperties(XkbGeometryPtr geom)
661ab64890Smrg{
67818534a1Smrg    register int i, size;
68818534a1Smrg    XkbPropertyPtr prop;
6961b2299dSmrg
70818534a1Smrg    for (size = i = 0, prop = geom->properties; i < geom->num_properties;
71818534a1Smrg         i++, prop++) {
729c019ec5Smaya        size = (int) ((unsigned) size + _SizeCountedString(prop->name));
739c019ec5Smaya        size = (int) ((unsigned) size + _SizeCountedString(prop->value));
741ab64890Smrg    }
751ab64890Smrg    return size;
761ab64890Smrg}
771ab64890Smrg
781ab64890Smrgstatic int
791ab64890Smrg_SizeGeomColors(XkbGeometryPtr geom)
801ab64890Smrg{
81818534a1Smrg    register int i, size;
82818534a1Smrg    register XkbColorPtr color;
831ab64890Smrg
84818534a1Smrg    for (i = size = 0, color = geom->colors; i < geom->num_colors; i++, color++) {
859c019ec5Smaya        size = (int) ((unsigned) size + _SizeCountedString(color->spec));
861ab64890Smrg    }
871ab64890Smrg    return size;
881ab64890Smrg}
891ab64890Smrg
901ab64890Smrgstatic int
911ab64890Smrg_SizeGeomShapes(XkbGeometryPtr geom)
921ab64890Smrg{
93818534a1Smrg    register int i, size;
94818534a1Smrg    register XkbShapePtr shape;
95818534a1Smrg
96818534a1Smrg    for (i = size = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) {
97818534a1Smrg        register int n;
98818534a1Smrg        register XkbOutlinePtr ol;
99818534a1Smrg
100818534a1Smrg        size += SIZEOF(xkbShapeWireDesc);
101818534a1Smrg        for (n = 0, ol = shape->outlines; n < shape->num_outlines; n++, ol++) {
102818534a1Smrg            size += SIZEOF(xkbOutlineWireDesc);
103818534a1Smrg            size += ol->num_points * SIZEOF(xkbPointWireDesc);
104818534a1Smrg        }
1051ab64890Smrg    }
1061ab64890Smrg    return size;
1071ab64890Smrg}
1081ab64890Smrg
1091ab64890Smrgstatic int
110818534a1Smrg_SizeGeomDoodads(int num_doodads, XkbDoodadPtr doodad)
1111ab64890Smrg{
112818534a1Smrg    register int i, size;
113818534a1Smrg
114818534a1Smrg    for (i = size = 0; i < num_doodads; i++, doodad++) {
115818534a1Smrg        size += SIZEOF(xkbAnyDoodadWireDesc);
116818534a1Smrg        if (doodad->any.type == XkbTextDoodad) {
1179c019ec5Smaya            size = (int) ((unsigned) size + _SizeCountedString(doodad->text.text));
1189c019ec5Smaya            size = (int) ((unsigned) size + _SizeCountedString(doodad->text.font));
119818534a1Smrg        }
120818534a1Smrg        else if (doodad->any.type == XkbLogoDoodad) {
1219c019ec5Smaya            size = (int) ((unsigned) size + _SizeCountedString(doodad->logo.logo_name));
122818534a1Smrg        }
1231ab64890Smrg    }
1241ab64890Smrg    return size;
1251ab64890Smrg}
1261ab64890Smrg
1271ab64890Smrgstatic int
1281ab64890Smrg_SizeGeomSections(XkbGeometryPtr geom)
1291ab64890Smrg{
130818534a1Smrg    register int i, size;
131818534a1Smrg    XkbSectionPtr section;
132818534a1Smrg
133818534a1Smrg    for (i = size = 0, section = geom->sections; i < geom->num_sections;
134818534a1Smrg         i++, section++) {
135818534a1Smrg        size += SIZEOF(xkbSectionWireDesc);
136818534a1Smrg        if (section->rows) {
137818534a1Smrg            int r;
138818534a1Smrg            XkbRowPtr row;
139818534a1Smrg
140818534a1Smrg            for (r = 0, row = section->rows; r < section->num_rows; row++, r++) {
141818534a1Smrg                size += SIZEOF(xkbRowWireDesc);
142818534a1Smrg                size += row->num_keys * SIZEOF(xkbKeyWireDesc);
143818534a1Smrg            }
144818534a1Smrg        }
145818534a1Smrg        if (section->doodads)
146818534a1Smrg            size += _SizeGeomDoodads(section->num_doodads, section->doodads);
147818534a1Smrg        if (section->overlays) {
148818534a1Smrg            int o;
149818534a1Smrg            XkbOverlayPtr ol;
150818534a1Smrg
151818534a1Smrg            for (o = 0, ol = section->overlays; o < section->num_overlays;
152818534a1Smrg                 o++, ol++) {
153818534a1Smrg                int r;
154818534a1Smrg                XkbOverlayRowPtr row;
155818534a1Smrg
156818534a1Smrg                size += SIZEOF(xkbOverlayWireDesc);
157818534a1Smrg                for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) {
158818534a1Smrg                    size += SIZEOF(xkbOverlayRowWireDesc);
159818534a1Smrg                    size += row->num_keys * SIZEOF(xkbOverlayKeyWireDesc);
160818534a1Smrg                }
161818534a1Smrg            }
162818534a1Smrg        }
1631ab64890Smrg    }
1641ab64890Smrg    return size;
1651ab64890Smrg}
1661ab64890Smrg
1671ab64890Smrgstatic int
1681ab64890Smrg_SizeGeomKeyAliases(XkbGeometryPtr geom)
1691ab64890Smrg{
170818534a1Smrg    return geom->num_key_aliases * (2 * XkbKeyNameLength);
1711ab64890Smrg}
1721ab64890Smrg
1731ab64890Smrg/***====================================================================***/
1741ab64890Smrg
1751ab64890Smrgstatic char *
176818534a1Smrg_WriteGeomProperties(char *wire, XkbGeometryPtr geom)
1771ab64890Smrg{
178818534a1Smrg    register int i;
179818534a1Smrg    register XkbPropertyPtr prop;
18061b2299dSmrg
181818534a1Smrg    for (i = 0, prop = geom->properties; i < geom->num_properties; i++, prop++) {
182818534a1Smrg        wire = _WriteCountedString(wire, prop->name);
183818534a1Smrg        wire = _WriteCountedString(wire, prop->value);
1841ab64890Smrg    }
1851ab64890Smrg    return wire;
1861ab64890Smrg}
1871ab64890Smrg
1881ab64890Smrgstatic char *
189818534a1Smrg_WriteGeomColors(char *wire, XkbGeometryPtr geom)
1901ab64890Smrg{
191818534a1Smrg    register int i;
192818534a1Smrg    register XkbColorPtr color;
1931ab64890Smrg
194818534a1Smrg    for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) {
195818534a1Smrg        wire = _WriteCountedString(wire, color->spec);
1961ab64890Smrg    }
1971ab64890Smrg    return wire;
1981ab64890Smrg}
1991ab64890Smrg
2001ab64890Smrgstatic char *
201818534a1Smrg_WriteGeomShapes(char *wire, XkbGeometryPtr geom)
2021ab64890Smrg{
203818534a1Smrg    int i;
204818534a1Smrg    XkbShapePtr shape;
205818534a1Smrg    xkbShapeWireDesc *shapeWire;
206818534a1Smrg
207818534a1Smrg    for (i = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) {
208818534a1Smrg        register int o;
209818534a1Smrg        XkbOutlinePtr ol;
210818534a1Smrg        xkbOutlineWireDesc *olWire;
211818534a1Smrg
212818534a1Smrg        shapeWire = (xkbShapeWireDesc *) wire;
213818534a1Smrg        shapeWire->name = shape->name;
214818534a1Smrg        shapeWire->nOutlines = shape->num_outlines;
215818534a1Smrg        if (shape->primary != NULL)
216818534a1Smrg            shapeWire->primaryNdx = XkbOutlineIndex(shape, shape->primary);
217818534a1Smrg        else
218818534a1Smrg            shapeWire->primaryNdx = XkbNoShape;
219818534a1Smrg        if (shape->approx != NULL)
220818534a1Smrg            shapeWire->approxNdx = XkbOutlineIndex(shape, shape->approx);
221818534a1Smrg        else
222818534a1Smrg            shapeWire->approxNdx = XkbNoShape;
223818534a1Smrg        wire = (char *) &shapeWire[1];
224818534a1Smrg        for (o = 0, ol = shape->outlines; o < shape->num_outlines; o++, ol++) {
225818534a1Smrg            register int p;
226818534a1Smrg            XkbPointPtr pt;
227818534a1Smrg            xkbPointWireDesc *ptWire;
228818534a1Smrg
229818534a1Smrg            olWire = (xkbOutlineWireDesc *) wire;
230818534a1Smrg            olWire->nPoints = ol->num_points;
231818534a1Smrg            olWire->cornerRadius = ol->corner_radius;
232818534a1Smrg            wire = (char *) &olWire[1];
233818534a1Smrg            ptWire = (xkbPointWireDesc *) wire;
234818534a1Smrg            for (p = 0, pt = ol->points; p < ol->num_points; p++, pt++) {
235818534a1Smrg                ptWire[p].x = pt->x;
236818534a1Smrg                ptWire[p].y = pt->y;
237818534a1Smrg            }
238818534a1Smrg            wire = (char *) &ptWire[ol->num_points];
239818534a1Smrg        }
2401ab64890Smrg    }
2411ab64890Smrg    return wire;
2421ab64890Smrg}
2431ab64890Smrg
2441ab64890Smrgstatic char *
245818534a1Smrg_WriteGeomDoodads(char *wire, int num_doodads, XkbDoodadPtr doodad)
2461ab64890Smrg{
247818534a1Smrg    register int i;
248818534a1Smrg
249818534a1Smrg    for (i = 0; i < num_doodads; i++, doodad++) {
250818534a1Smrg        xkbDoodadWireDesc *doodadWire = (xkbDoodadWireDesc *) wire;
251818534a1Smrg
252818534a1Smrg        wire = (char *) &doodadWire[1];
253818534a1Smrg        bzero(doodadWire, SIZEOF(xkbDoodadWireDesc));
254818534a1Smrg        doodadWire->any.name = doodad->any.name;
255818534a1Smrg        doodadWire->any.type = doodad->any.type;
256818534a1Smrg        doodadWire->any.priority = doodad->any.priority;
257818534a1Smrg        doodadWire->any.top = doodad->any.top;
258818534a1Smrg        doodadWire->any.left = doodad->any.left;
259818534a1Smrg        doodadWire->any.angle = doodad->any.angle;
260818534a1Smrg        switch (doodad->any.type) {
261818534a1Smrg        case XkbOutlineDoodad:
262818534a1Smrg        case XkbSolidDoodad:
263818534a1Smrg            doodadWire->shape.colorNdx = doodad->shape.color_ndx;
264818534a1Smrg            doodadWire->shape.shapeNdx = doodad->shape.shape_ndx;
265818534a1Smrg            break;
266818534a1Smrg        case XkbTextDoodad:
267818534a1Smrg            doodadWire->text.width = doodad->text.width;
268818534a1Smrg            doodadWire->text.height = doodad->text.height;
269818534a1Smrg            doodadWire->text.colorNdx = doodad->text.color_ndx;
270818534a1Smrg            wire = _WriteCountedString(wire, doodad->text.text);
271818534a1Smrg            wire = _WriteCountedString(wire, doodad->text.font);
272818534a1Smrg            break;
273818534a1Smrg        case XkbIndicatorDoodad:
274818534a1Smrg            doodadWire->indicator.shapeNdx = doodad->indicator.shape_ndx;
275818534a1Smrg            doodadWire->indicator.onColorNdx = doodad->indicator.on_color_ndx;
276818534a1Smrg            doodadWire->indicator.offColorNdx = doodad->indicator.off_color_ndx;
277818534a1Smrg            break;
278818534a1Smrg        case XkbLogoDoodad:
279818534a1Smrg            doodadWire->logo.colorNdx = doodad->logo.color_ndx;
280818534a1Smrg            doodadWire->logo.shapeNdx = doodad->logo.shape_ndx;
281818534a1Smrg            wire = _WriteCountedString(wire, doodad->logo.logo_name);
282818534a1Smrg            break;
283818534a1Smrg        default:
284818534a1Smrg            break;
285818534a1Smrg        }
2861ab64890Smrg    }
2871ab64890Smrg    return wire;
2881ab64890Smrg}
2891ab64890Smrg
2901ab64890Smrgstatic char *
291818534a1Smrg_WriteGeomOverlay(char *wire, XkbOverlayPtr ol)
2921ab64890Smrg{
293818534a1Smrg    register int r;
294818534a1Smrg    XkbOverlayRowPtr row;
295818534a1Smrg    xkbOverlayWireDesc *olWire = (xkbOverlayWireDesc *) wire;
296818534a1Smrg
297818534a1Smrg    olWire->name = ol->name;
298818534a1Smrg    olWire->nRows = ol->num_rows;
299818534a1Smrg    wire = (char *) &olWire[1];
300818534a1Smrg    for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) {
301818534a1Smrg        unsigned int k;
302818534a1Smrg        XkbOverlayKeyPtr key;
303818534a1Smrg        xkbOverlayRowWireDesc *rowWire = (xkbOverlayRowWireDesc *) wire;
304818534a1Smrg
305818534a1Smrg        rowWire->rowUnder = row->row_under;
306818534a1Smrg        rowWire->nKeys = row->num_keys;
307818534a1Smrg        wire = (char *) &rowWire[1];
308818534a1Smrg        for (k = 0, key = row->keys; k < row->num_keys; k++, key++) {
309818534a1Smrg            xkbOverlayKeyWireDesc *keyWire = (xkbOverlayKeyWireDesc *) wire;
310818534a1Smrg
311818534a1Smrg            memcpy(keyWire->over, key->over.name, XkbKeyNameLength);
312818534a1Smrg            memcpy(keyWire->under, key->under.name, XkbKeyNameLength);
313818534a1Smrg            wire = (char *) &keyWire[1];
314818534a1Smrg        }
315818534a1Smrg    }
316818534a1Smrg    return wire;
3171ab64890Smrg}
3181ab64890Smrg
3191ab64890Smrgstatic char *
320818534a1Smrg_WriteGeomSections(char *wire, XkbGeometryPtr geom)
3211ab64890Smrg{
322818534a1Smrg    register int i;
323818534a1Smrg    XkbSectionPtr section;
324818534a1Smrg
325818534a1Smrg    for (i = 0, section = geom->sections; i < geom->num_sections;
326818534a1Smrg         i++, section++) {
327818534a1Smrg        xkbSectionWireDesc *sectionWire = (xkbSectionWireDesc *) wire;
328818534a1Smrg
329818534a1Smrg        sectionWire->name = section->name;
330818534a1Smrg        sectionWire->top = section->top;
331818534a1Smrg        sectionWire->left = section->left;
332818534a1Smrg        sectionWire->width = section->width;
333818534a1Smrg        sectionWire->height = section->height;
334818534a1Smrg        sectionWire->angle = section->angle;
335818534a1Smrg        sectionWire->priority = section->priority;
336818534a1Smrg        sectionWire->nRows = section->num_rows;
337818534a1Smrg        sectionWire->nDoodads = section->num_doodads;
338818534a1Smrg        sectionWire->nOverlays = section->num_overlays;
339818534a1Smrg        sectionWire->pad = 0;
340818534a1Smrg        wire = (char *) &sectionWire[1];
341818534a1Smrg        if (section->rows) {
342818534a1Smrg            int r;
343818534a1Smrg            XkbRowPtr row;
344818534a1Smrg
345818534a1Smrg            for (r = 0, row = section->rows; r < section->num_rows; r++, row++) {
346818534a1Smrg                xkbRowWireDesc *rowWire = (xkbRowWireDesc *) wire;
347818534a1Smrg
348818534a1Smrg                rowWire->top = row->top;
349818534a1Smrg                rowWire->left = row->left;
350818534a1Smrg                rowWire->nKeys = row->num_keys;
351818534a1Smrg                rowWire->vertical = row->vertical;
352818534a1Smrg                rowWire->pad = 0;
353818534a1Smrg                wire = (char *) &rowWire[1];
354818534a1Smrg                if (row->keys) {
355818534a1Smrg                    int k;
356818534a1Smrg                    XkbKeyPtr key;
357818534a1Smrg                    xkbKeyWireDesc *keyWire = (xkbKeyWireDesc *) wire;
358818534a1Smrg
359818534a1Smrg                    for (k = 0, key = row->keys; k < row->num_keys; k++, key++) {
360818534a1Smrg                        memcpy(keyWire[k].name, key->name.name,
361818534a1Smrg                               XkbKeyNameLength);
362818534a1Smrg                        keyWire[k].gap = key->gap;
363818534a1Smrg                        keyWire[k].shapeNdx = key->shape_ndx;
364818534a1Smrg                        keyWire[k].colorNdx = key->color_ndx;
365818534a1Smrg                    }
366818534a1Smrg                    wire = (char *) &keyWire[row->num_keys];
367818534a1Smrg                }
368818534a1Smrg            }
369818534a1Smrg        }
370818534a1Smrg        if (section->doodads) {
371818534a1Smrg            wire = _WriteGeomDoodads(wire,
372818534a1Smrg                                     section->num_doodads, section->doodads);
373818534a1Smrg        }
374818534a1Smrg        if (section->overlays) {
375818534a1Smrg            register int o;
376818534a1Smrg
377818534a1Smrg            for (o = 0; o < section->num_overlays; o++) {
378818534a1Smrg                wire = _WriteGeomOverlay(wire, &section->overlays[o]);
379818534a1Smrg            }
380818534a1Smrg        }
3811ab64890Smrg    }
3821ab64890Smrg    return wire;
3831ab64890Smrg}
3841ab64890Smrg
3851ab64890Smrgstatic char *
386818534a1Smrg_WriteGeomKeyAliases(char *wire, XkbGeometryPtr geom)
3871ab64890Smrg{
388818534a1Smrg    register int sz;
38961b2299dSmrg
390818534a1Smrg    sz = geom->num_key_aliases * (XkbKeyNameLength * 2);
391818534a1Smrg    if (sz > 0) {
3929c019ec5Smaya        memcpy(wire, (char *) geom->key_aliases, (size_t)sz);
393818534a1Smrg        wire += sz;
3941ab64890Smrg    }
3951ab64890Smrg    return wire;
3961ab64890Smrg}
3971ab64890Smrg
3981ab64890Smrg/***====================================================================***/
3991ab64890Smrg
4001ab64890Smrgstatic Status
401818534a1Smrg_SendSetGeometry(Display *dpy, XkbGeometryPtr geom, xkbSetGeometryReq *req)
4021ab64890Smrg{
403818534a1Smrg    int sz;
404818534a1Smrg    char *wire, *tbuf;
405818534a1Smrg
406818534a1Smrg    sz = 0;
4079c019ec5Smaya    sz = (int) ((unsigned) (sz + _SizeCountedString(geom->label_font)));
408818534a1Smrg    sz += _SizeGeomProperties(geom);
409818534a1Smrg    sz += _SizeGeomColors(geom);
410818534a1Smrg    sz += _SizeGeomShapes(geom);
411818534a1Smrg    sz += _SizeGeomSections(geom);
412818534a1Smrg    sz += _SizeGeomDoodads(geom->num_doodads, geom->doodads);
413818534a1Smrg    sz += _SizeGeomKeyAliases(geom);
414818534a1Smrg    req->length += (sz / 4);
4151ab64890Smrg    if (sz < (dpy->bufmax - dpy->buffer)) {
416818534a1Smrg        BufAlloc(char *, wire, sz);
417818534a1Smrg        tbuf = NULL;
4181ab64890Smrg    }
4191ab64890Smrg    else {
420818534a1Smrg        tbuf = _XAllocTemp(dpy, sz);
421818534a1Smrg        if (!tbuf)
422818534a1Smrg            return BadAlloc;
423818534a1Smrg        wire = tbuf;
4241ab64890Smrg    }
425818534a1Smrg    wire = _WriteCountedString(wire, geom->label_font);
426818534a1Smrg    if (geom->num_properties > 0)
427818534a1Smrg        wire = _WriteGeomProperties(wire, geom);
428818534a1Smrg    if (geom->num_colors > 0)
429818534a1Smrg        wire = _WriteGeomColors(wire, geom);
430818534a1Smrg    if (geom->num_shapes > 0)
431818534a1Smrg        wire = _WriteGeomShapes(wire, geom);
432818534a1Smrg    if (geom->num_sections > 0)
433818534a1Smrg        wire = _WriteGeomSections(wire, geom);
434818534a1Smrg    if (geom->num_doodads > 0)
435818534a1Smrg        wire = _WriteGeomDoodads(wire, geom->num_doodads, geom->doodads);
436818534a1Smrg    if (geom->num_key_aliases > 0)
437818534a1Smrg        wire = _WriteGeomKeyAliases(wire, geom);
438818534a1Smrg    if (tbuf != NULL) {
439818534a1Smrg        Data(dpy, tbuf, sz);
440818534a1Smrg        _XFreeTemp(dpy, tbuf, sz);
4411ab64890Smrg    }
4421ab64890Smrg    return Success;
4431ab64890Smrg}
4441ab64890Smrg
4451ab64890Smrg/***====================================================================***/
4461ab64890Smrg
4471ab64890SmrgStatus
448818534a1SmrgXkbSetGeometry(Display *dpy, unsigned deviceSpec, XkbGeometryPtr geom)
4491ab64890Smrg{
450818534a1Smrg    xkbSetGeometryReq *req;
451818534a1Smrg    Status ret;
4521ab64890Smrg
453818534a1Smrg    if ((!geom) || (dpy->flags & XlibDisplayNoXkb) ||
454818534a1Smrg        (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
455818534a1Smrg        return BadAccess;
45661b2299dSmrg
4571ab64890Smrg    LockDisplay(dpy);
4581ab64890Smrg    GetReq(kbSetGeometry, req);
4591ab64890Smrg    req->reqType = dpy->xkb_info->codes->major_opcode;
4601ab64890Smrg    req->xkbReqType = X_kbSetGeometry;
4611ab64890Smrg    req->deviceSpec = deviceSpec;
462818534a1Smrg    req->nShapes = geom->num_shapes;
463818534a1Smrg    req->nSections = geom->num_sections;
464818534a1Smrg    req->name = geom->name;
465818534a1Smrg    req->widthMM = geom->width_mm;
466818534a1Smrg    req->heightMM = geom->height_mm;
467818534a1Smrg    req->nProperties = geom->num_properties;
468818534a1Smrg    req->nColors = geom->num_colors;
469818534a1Smrg    req->nDoodads = geom->num_doodads;
470818534a1Smrg    req->nKeyAliases = geom->num_key_aliases;
471818534a1Smrg    req->baseColorNdx = (geom->base_color - geom->colors);
472818534a1Smrg    req->labelColorNdx = (geom->label_color - geom->colors);
473818534a1Smrg
474818534a1Smrg    ret = _SendSetGeometry(dpy, geom, req);
4751ab64890Smrg    UnlockDisplay(dpy);
4761ab64890Smrg    SyncHandle();
4771ab64890Smrg    return ret;
4781ab64890Smrg}
479