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