Git init
[framework/uifw/xorg/lib/libx11.git] / src / xkb / XKBSetGeom.c
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 #include "Xlibint.h"
35 #include "XKBlibint.h"
36 #include <X11/extensions/XKBgeom.h>
37 #include <X11/extensions/XKBproto.h>
38
39 #ifndef MINSHORT
40 #define MINSHORT        -32768
41 #endif
42 #ifndef MAXSHORT
43 #define MAXSHORT        32767
44 #endif
45
46 /***====================================================================***/
47
48 #define _SizeCountedString(s)  ((s)?XkbPaddedSize(2+strlen(s)):4)
49
50 static char *
51 _WriteCountedString(char *wire,char *str)
52 {
53 CARD16  len,*pLen;
54
55     len= (str?strlen(str):0);
56     pLen= (CARD16 *)wire;
57     *pLen= len;
58     if (len && str)
59         memcpy(&wire[2],str,len);
60     wire+= XkbPaddedSize(len+2);
61     return wire;
62 }
63
64 static int
65 _SizeGeomProperties(XkbGeometryPtr geom)
66 {
67 register int    i,size;
68 XkbPropertyPtr  prop;
69
70     for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
71         size+= _SizeCountedString(prop->name);
72         size+= _SizeCountedString(prop->value);
73     }
74     return size;
75 }
76
77 static int
78 _SizeGeomColors(XkbGeometryPtr geom)
79 {
80 register int            i,size;
81 register XkbColorPtr    color;
82
83     for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) {
84         size+= _SizeCountedString(color->spec);
85     }
86     return size;
87 }
88
89 static int
90 _SizeGeomShapes(XkbGeometryPtr geom)
91 {
92 register int            i,size;
93 register XkbShapePtr    shape;
94
95     for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
96         register int            n;
97         register XkbOutlinePtr  ol;
98         size+= SIZEOF(xkbShapeWireDesc);
99         for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
100             size+= SIZEOF(xkbOutlineWireDesc);
101             size+= ol->num_points*SIZEOF(xkbPointWireDesc);
102         }
103     }
104     return size;
105 }
106
107 static int
108 _SizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad)
109 {
110 register int    i,size;
111
112     for (i=size=0;i<num_doodads;i++,doodad++) {
113         size+= SIZEOF(xkbAnyDoodadWireDesc);
114         if (doodad->any.type==XkbTextDoodad) {
115             size+= _SizeCountedString(doodad->text.text);
116             size+= _SizeCountedString(doodad->text.font);
117         }
118         else if (doodad->any.type==XkbLogoDoodad) {
119             size+= _SizeCountedString(doodad->logo.logo_name);
120         }
121     }
122     return size;
123 }
124
125 static int
126 _SizeGeomSections(XkbGeometryPtr geom)
127 {
128 register int    i,size;
129 XkbSectionPtr   section;
130
131     for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) {
132         size+= SIZEOF(xkbSectionWireDesc);
133         if (section->rows) {
134             int         r;
135             XkbRowPtr   row;
136             for (r=0,row=section->rows;r<section->num_rows;row++,r++) {
137                 size+= SIZEOF(xkbRowWireDesc);
138                 size+= row->num_keys*SIZEOF(xkbKeyWireDesc);
139             }
140         }
141         if (section->doodads)
142             size+= _SizeGeomDoodads(section->num_doodads,section->doodads);
143         if (section->overlays) {
144             int                 o;
145             XkbOverlayPtr       ol;
146             for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
147                 int                     r;
148                 XkbOverlayRowPtr        row;
149                 size+= SIZEOF(xkbOverlayWireDesc);
150                 for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
151                    size+= SIZEOF(xkbOverlayRowWireDesc);
152                    size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc);
153                 }
154             }
155         }
156     }
157     return size;
158 }
159
160 static int
161 _SizeGeomKeyAliases(XkbGeometryPtr geom)
162 {
163     return geom->num_key_aliases*(2*XkbKeyNameLength);
164 }
165
166 /***====================================================================***/
167
168 static char *
169 _WriteGeomProperties(char *wire,XkbGeometryPtr geom)
170 {
171 register int    i;
172 register XkbPropertyPtr prop;
173
174     for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
175         wire= _WriteCountedString(wire,prop->name);
176         wire= _WriteCountedString(wire,prop->value);
177     }
178     return wire;
179 }
180
181 static char *
182 _WriteGeomColors(char *wire,XkbGeometryPtr geom)
183 {
184 register int            i;
185 register XkbColorPtr    color;
186
187     for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
188         wire= _WriteCountedString(wire,color->spec);
189     }
190     return wire;
191 }
192
193 static char *
194 _WriteGeomShapes(char *wire,XkbGeometryPtr geom)
195 {
196 int                     i;
197 XkbShapePtr             shape;
198 xkbShapeWireDesc *      shapeWire;
199
200     for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
201         register int            o;
202         XkbOutlinePtr           ol;
203         xkbOutlineWireDesc *    olWire;
204         shapeWire= (xkbShapeWireDesc *)wire;
205         shapeWire->name= shape->name;
206         shapeWire->nOutlines= shape->num_outlines;
207         if (shape->primary!=NULL)
208              shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary);
209         else shapeWire->primaryNdx= XkbNoShape;
210         if (shape->approx!=NULL)
211              shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx);
212         else shapeWire->approxNdx= XkbNoShape;
213         wire= (char *)&shapeWire[1];
214         for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) {
215             register int        p;
216             XkbPointPtr         pt;
217             xkbPointWireDesc *  ptWire;
218             olWire= (xkbOutlineWireDesc *)wire;
219             olWire->nPoints= ol->num_points;
220             olWire->cornerRadius= ol->corner_radius;
221             wire= (char *)&olWire[1];
222             ptWire= (xkbPointWireDesc *)wire;
223             for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) {
224                 ptWire[p].x= pt->x;
225                 ptWire[p].y= pt->y;
226             }
227             wire= (char *)&ptWire[ol->num_points];
228         }
229     }
230     return wire;
231 }
232
233 static char *
234 _WriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad)
235 {
236 register int            i;
237 xkbDoodadWireDesc *     doodadWire;
238
239     for (i=0;i<num_doodads;i++,doodad++) {
240         doodadWire= (xkbDoodadWireDesc *)wire;
241         wire= (char *)&doodadWire[1];
242         bzero(doodadWire,SIZEOF(xkbDoodadWireDesc));
243         doodadWire->any.name= doodad->any.name;
244         doodadWire->any.type= doodad->any.type;
245         doodadWire->any.priority= doodad->any.priority;
246         doodadWire->any.top= doodad->any.top;
247         doodadWire->any.left= doodad->any.left;
248         doodadWire->any.angle= doodad->any.angle;
249         switch (doodad->any.type) {
250             case XkbOutlineDoodad:
251             case XkbSolidDoodad:
252                 doodadWire->shape.colorNdx= doodad->shape.color_ndx;
253                 doodadWire->shape.shapeNdx= doodad->shape.shape_ndx;
254                 break;
255             case XkbTextDoodad:
256                 doodadWire->text.width= doodad->text.width;
257                 doodadWire->text.height= doodad->text.height;
258                 doodadWire->text.colorNdx= doodad->text.color_ndx;
259                 wire= _WriteCountedString(wire,doodad->text.text);
260                 wire= _WriteCountedString(wire,doodad->text.font);
261                 break;
262             case XkbIndicatorDoodad:
263                 doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx;
264                 doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx;
265                 doodadWire->indicator.offColorNdx=
266                                                 doodad->indicator.off_color_ndx;
267                 break;
268             case XkbLogoDoodad:
269                 doodadWire->logo.colorNdx= doodad->logo.color_ndx;
270                 doodadWire->logo.shapeNdx= doodad->logo.shape_ndx;
271                 wire= _WriteCountedString(wire,doodad->logo.logo_name);
272                 break;
273             default:
274                 break;
275         }
276     }
277     return wire;
278 }
279
280 static char *
281 _WriteGeomOverlay(char *wire,XkbOverlayPtr ol)
282 {
283 register int            r;
284 XkbOverlayRowPtr        row;
285 xkbOverlayWireDesc *    olWire;
286
287    olWire= (xkbOverlayWireDesc *)wire;
288    olWire->name= ol->name;
289    olWire->nRows= ol->num_rows;
290    wire= (char *)&olWire[1];
291    for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
292         unsigned int            k;
293         XkbOverlayKeyPtr        key;
294         xkbOverlayRowWireDesc * rowWire;
295         rowWire= (xkbOverlayRowWireDesc *)wire;
296         rowWire->rowUnder= row->row_under;
297         rowWire->nKeys= row->num_keys;
298         wire= (char *)&rowWire[1];
299         for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
300             xkbOverlayKeyWireDesc *     keyWire;
301             keyWire= (xkbOverlayKeyWireDesc *)wire;
302             memcpy(keyWire->over,key->over.name,XkbKeyNameLength);
303             memcpy(keyWire->under,key->under.name,XkbKeyNameLength);
304             wire= (char *)&keyWire[1];
305         }
306    }
307    return wire;
308 }
309
310 static char *
311 _WriteGeomSections(char *wire,XkbGeometryPtr geom)
312 {
313 register int            i;
314 XkbSectionPtr           section;
315 xkbSectionWireDesc *    sectionWire;
316
317     for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
318         sectionWire= (xkbSectionWireDesc *)wire;
319         sectionWire->name= section->name;
320         sectionWire->top= section->top;
321         sectionWire->left= section->left;
322         sectionWire->width= section->width;
323         sectionWire->height= section->height;
324         sectionWire->angle= section->angle;
325         sectionWire->priority= section->priority;
326         sectionWire->nRows= section->num_rows;
327         sectionWire->nDoodads= section->num_doodads;
328         sectionWire->nOverlays= section->num_overlays;
329         sectionWire->pad= 0;
330         wire= (char *)&sectionWire[1];
331         if (section->rows) {
332             int                 r;
333             XkbRowPtr           row;
334             xkbRowWireDesc *    rowWire;
335             for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
336                 rowWire= (xkbRowWireDesc *)wire;
337                 rowWire->top= row->top;
338                 rowWire->left= row->left;
339                 rowWire->nKeys= row->num_keys;
340                 rowWire->vertical= row->vertical;
341                 rowWire->pad= 0;
342                 wire= (char *)&rowWire[1];
343                 if (row->keys) {
344                     int                 k;
345                     XkbKeyPtr           key;
346                     xkbKeyWireDesc *    keyWire;
347                     keyWire= (xkbKeyWireDesc *)wire;
348                     for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
349                         memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength);
350                         keyWire[k].gap= key->gap;
351                         keyWire[k].shapeNdx= key->shape_ndx;
352                         keyWire[k].colorNdx= key->color_ndx;
353                     }
354                     wire= (char *)&keyWire[row->num_keys];
355                 }
356             }
357         }
358         if (section->doodads) {
359             wire= _WriteGeomDoodads(wire,
360                                       section->num_doodads,section->doodads);
361         }
362         if (section->overlays) {
363             register int o;
364             for (o=0;o<section->num_overlays;o++) {
365                 wire= _WriteGeomOverlay(wire,&section->overlays[o]);
366             }
367         }
368     }
369     return wire;
370 }
371
372 static char *
373 _WriteGeomKeyAliases(char *wire,XkbGeometryPtr geom)
374 {
375 register int sz;
376
377     sz= geom->num_key_aliases*(XkbKeyNameLength*2);
378     if (sz>0) {
379         memcpy(wire,(char *)geom->key_aliases,sz);
380         wire+= sz;
381     }
382     return wire;
383 }
384
385 /***====================================================================***/
386
387 static Status
388 _SendSetGeometry(Display *dpy,XkbGeometryPtr geom,xkbSetGeometryReq *req)
389 {
390 int                     sz;
391 char *                  wire,*tbuf;
392
393     sz= 0;
394     sz+= _SizeCountedString(geom->label_font);
395     sz+= _SizeGeomProperties(geom);
396     sz+= _SizeGeomColors(geom);
397     sz+= _SizeGeomShapes(geom);
398     sz+= _SizeGeomSections(geom);
399     sz+= _SizeGeomDoodads(geom->num_doodads,geom->doodads);
400     sz+= _SizeGeomKeyAliases(geom);
401     req->length+= (sz/4);
402     if (sz < (dpy->bufmax - dpy->buffer)) {
403         BufAlloc(char *,wire,sz);
404         tbuf= NULL;
405     }
406     else {
407         tbuf= _XAllocTemp(dpy,sz);
408         if (!tbuf)
409             return BadAlloc;
410         wire= tbuf;
411     }
412     wire= _WriteCountedString(wire,geom->label_font);
413     if (geom->num_properties>0)
414         wire= _WriteGeomProperties(wire,geom);
415     if (geom->num_colors>0)
416         wire= _WriteGeomColors(wire,geom);
417     if (geom->num_shapes>0)
418         wire= _WriteGeomShapes(wire,geom);
419     if (geom->num_sections>0)
420         wire= _WriteGeomSections(wire,geom);
421     if (geom->num_doodads>0)
422         wire= _WriteGeomDoodads(wire,geom->num_doodads,geom->doodads);
423     if (geom->num_key_aliases>0)
424         wire= _WriteGeomKeyAliases(wire,geom);
425     if (tbuf!=NULL) {
426         Data(dpy,tbuf,sz);
427         _XFreeTemp(dpy,tbuf,sz);
428     }
429     return Success;
430 }
431
432 /***====================================================================***/
433
434 Status
435 XkbSetGeometry(Display *dpy,unsigned deviceSpec,XkbGeometryPtr geom)
436 {
437 xkbSetGeometryReq       *req;
438 Status ret;
439
440     if ( (!geom) || (dpy->flags & XlibDisplayNoXkb) ||
441         (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
442         return BadAccess;
443
444     LockDisplay(dpy);
445     GetReq(kbSetGeometry, req);
446     req->reqType = dpy->xkb_info->codes->major_opcode;
447     req->xkbReqType = X_kbSetGeometry;
448     req->deviceSpec = deviceSpec;
449     req->nShapes= geom->num_shapes;
450     req->nSections= geom->num_sections;
451     req->name= geom->name;
452     req->widthMM= geom->width_mm;
453     req->heightMM= geom->height_mm;
454     req->nProperties= geom->num_properties;
455     req->nColors= geom->num_colors;
456     req->nDoodads= geom->num_doodads;
457     req->nKeyAliases= geom->num_key_aliases;
458     req->baseColorNdx= (geom->base_color-geom->colors);
459     req->labelColorNdx= (geom->label_color-geom->colors);
460
461     ret = _SendSetGeometry(dpy,geom,req);
462     UnlockDisplay(dpy);
463     SyncHandle();
464     return ret;
465 }
466