XKBSetGeom.c revision e9fcaa8a
1/************************************************************
2Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
4Permission to use, copy, modify, and distribute this
5software and its documentation for any purpose and without
6fee is hereby granted, provided that the above copyright
7notice appear in all copies and that both that copyright
8notice and this permission notice appear in supporting
9documentation, and that the name of Silicon Graphics not be
10used in advertising or publicity pertaining to distribution
11of the software without specific prior written permission.
12Silicon Graphics makes no representation about the suitability
13of this software for any purpose. It is provided "as is"
14without any express or implied warranty.
15
16SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23THE 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
50static char *
51_WriteCountedString(char *wire,char *str)
52{
53CARD16	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
64static int
65_SizeGeomProperties(XkbGeometryPtr geom)
66{
67register int 	i,size;
68XkbPropertyPtr	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
77static int
78_SizeGeomColors(XkbGeometryPtr geom)
79{
80register int 		i,size;
81register 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
89static int
90_SizeGeomShapes(XkbGeometryPtr geom)
91{
92register int		i,size;
93register 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
107static int
108_SizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad)
109{
110register 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
125static int
126_SizeGeomSections(XkbGeometryPtr geom)
127{
128register int 	i,size;
129XkbSectionPtr	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
160static int
161_SizeGeomKeyAliases(XkbGeometryPtr geom)
162{
163    return geom->num_key_aliases*(2*XkbKeyNameLength);
164}
165
166/***====================================================================***/
167
168static char *
169_WriteGeomProperties(char *wire,XkbGeometryPtr geom)
170{
171register int 	i;
172register 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
181static char *
182_WriteGeomColors(char *wire,XkbGeometryPtr geom)
183{
184register int		i;
185register 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
193static char *
194_WriteGeomShapes(char *wire,XkbGeometryPtr geom)
195{
196int			i;
197XkbShapePtr		shape;
198xkbShapeWireDesc *	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
233static char *
234_WriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad)
235{
236register int		i;
237xkbDoodadWireDesc *	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
280static char *
281_WriteGeomOverlay(char *wire,XkbOverlayPtr ol)
282{
283register int		r;
284XkbOverlayRowPtr	row;
285xkbOverlayWireDesc *	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
310static char *
311_WriteGeomSections(char *wire,XkbGeometryPtr geom)
312{
313register int		i;
314XkbSectionPtr		section;
315xkbSectionWireDesc *	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
372static char *
373_WriteGeomKeyAliases(char *wire,XkbGeometryPtr geom)
374{
375register 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
387static Status
388_SendSetGeometry(Display *dpy,XkbGeometryPtr geom,xkbSetGeometryReq *req)
389{
390int			sz;
391char *			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
434Status
435XkbSetGeometry(Display *dpy,unsigned deviceSpec,XkbGeometryPtr geom)
436{
437xkbSetGeometryReq	*req;
438Status 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
467