XKBSetGeom.c revision 61b2299d
1/* $Xorg: XKBSetGeom.c,v 1.3 2000/08/17 19:45:03 cpqbld Exp $ */
2/* $XdotOrg: lib/X11/src/xkb/XKBSetGeom.c,v 1.5 2005-07-03 07:00:55 daniels Exp $ */
3/************************************************************
4Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
5
6Permission to use, copy, modify, and distribute this
7software and its documentation for any purpose and without
8fee is hereby granted, provided that the above copyright
9notice appear in all copies and that both that copyright
10notice and this permission notice appear in supporting
11documentation, and that the name of Silicon Graphics not be
12used in advertising or publicity pertaining to distribution
13of the software without specific prior written permission.
14Silicon Graphics makes no representation about the suitability
15of this software for any purpose. It is provided "as is"
16without any express or implied warranty.
17
18SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
19SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
20AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
21GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
22DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
23DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
24OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
25THE USE OR PERFORMANCE OF THIS SOFTWARE.
26
27********************************************************/
28/* $XFree86: xc/lib/X11/XKBSetGeom.c,v 3.5 2003/05/27 22:26:25 tsi Exp $ */
29
30#ifdef DEBUG
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34#include <stdio.h>
35#endif
36
37#define NEED_EVENTS
38#define NEED_REPLIES
39#include "Xlibint.h"
40#include "XKBlibint.h"
41#include <X11/extensions/XKBgeom.h>
42#include <X11/extensions/XKBproto.h>
43
44#ifndef MINSHORT
45#define	MINSHORT	-32768
46#endif
47#ifndef MAXSHORT
48#define	MAXSHORT	32767
49#endif
50
51/***====================================================================***/
52
53#define	_SizeCountedString(s)  ((s)?XkbPaddedSize(2+strlen(s)):4)
54
55static char *
56_WriteCountedString(char *wire,char *str)
57{
58CARD16	len,*pLen;
59
60    len= (str?strlen(str):0);
61    pLen= (CARD16 *)wire;
62    *pLen= len;
63    if (len && str)
64	memcpy(&wire[2],str,len);
65    wire+= XkbPaddedSize(len+2);
66    return wire;
67}
68
69static int
70_SizeGeomProperties(XkbGeometryPtr geom)
71{
72register int 	i,size;
73XkbPropertyPtr	prop;
74
75    for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
76	size+= _SizeCountedString(prop->name);
77	size+= _SizeCountedString(prop->value);
78    }
79    return size;
80}
81
82static int
83_SizeGeomColors(XkbGeometryPtr geom)
84{
85register int 		i,size;
86register XkbColorPtr	color;
87
88    for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) {
89	size+= _SizeCountedString(color->spec);
90    }
91    return size;
92}
93
94static int
95_SizeGeomShapes(XkbGeometryPtr geom)
96{
97register int		i,size;
98register XkbShapePtr	shape;
99
100    for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
101	register int		n;
102	register XkbOutlinePtr	ol;
103	size+= SIZEOF(xkbShapeWireDesc);
104	for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
105	    size+= SIZEOF(xkbOutlineWireDesc);
106	    size+= ol->num_points*SIZEOF(xkbPointWireDesc);
107	}
108    }
109    return size;
110}
111
112static int
113_SizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad)
114{
115register int	i,size;
116
117    for (i=size=0;i<num_doodads;i++,doodad++) {
118	size+= SIZEOF(xkbAnyDoodadWireDesc);
119	if (doodad->any.type==XkbTextDoodad) {
120	    size+= _SizeCountedString(doodad->text.text);
121	    size+= _SizeCountedString(doodad->text.font);
122	}
123	else if (doodad->any.type==XkbLogoDoodad) {
124	    size+= _SizeCountedString(doodad->logo.logo_name);
125	}
126    }
127    return size;
128}
129
130static int
131_SizeGeomSections(XkbGeometryPtr geom)
132{
133register int 	i,size;
134XkbSectionPtr	section;
135
136    for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) {
137	size+= SIZEOF(xkbSectionWireDesc);
138	if (section->rows) {
139	    int		r;
140	    XkbRowPtr	row;
141	    for (r=0,row=section->rows;r<section->num_rows;row++,r++) {
142		size+= SIZEOF(xkbRowWireDesc);
143		size+= row->num_keys*SIZEOF(xkbKeyWireDesc);
144	    }
145	}
146	if (section->doodads)
147	    size+= _SizeGeomDoodads(section->num_doodads,section->doodads);
148	if (section->overlays) {
149	    int			o;
150	    XkbOverlayPtr	ol;
151	    for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
152		int			r;
153		XkbOverlayRowPtr	row;
154		size+= SIZEOF(xkbOverlayWireDesc);
155		for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
156		   size+= SIZEOF(xkbOverlayRowWireDesc);
157		   size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc);
158		}
159	    }
160	}
161    }
162    return size;
163}
164
165static int
166_SizeGeomKeyAliases(XkbGeometryPtr geom)
167{
168    return geom->num_key_aliases*(2*XkbKeyNameLength);
169}
170
171/***====================================================================***/
172
173static char *
174_WriteGeomProperties(char *wire,XkbGeometryPtr geom)
175{
176register int 	i;
177register XkbPropertyPtr	prop;
178
179    for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
180	wire= _WriteCountedString(wire,prop->name);
181	wire= _WriteCountedString(wire,prop->value);
182    }
183    return wire;
184}
185
186static char *
187_WriteGeomColors(char *wire,XkbGeometryPtr geom)
188{
189register int		i;
190register XkbColorPtr	color;
191
192    for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
193	wire= _WriteCountedString(wire,color->spec);
194    }
195    return wire;
196}
197
198static char *
199_WriteGeomShapes(char *wire,XkbGeometryPtr geom)
200{
201int			i;
202XkbShapePtr		shape;
203xkbShapeWireDesc *	shapeWire;
204
205    for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
206	register int 		o;
207	XkbOutlinePtr		ol;
208	xkbOutlineWireDesc *	olWire;
209	shapeWire= (xkbShapeWireDesc *)wire;
210	shapeWire->name= shape->name;
211	shapeWire->nOutlines= shape->num_outlines;
212	if (shape->primary!=NULL)
213	     shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary);
214	else shapeWire->primaryNdx= XkbNoShape;
215	if (shape->approx!=NULL)
216	     shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx);
217	else shapeWire->approxNdx= XkbNoShape;
218	wire= (char *)&shapeWire[1];
219	for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) {
220	    register int	p;
221	    XkbPointPtr		pt;
222	    xkbPointWireDesc *	ptWire;
223	    olWire= (xkbOutlineWireDesc *)wire;
224	    olWire->nPoints= ol->num_points;
225	    olWire->cornerRadius= ol->corner_radius;
226	    wire= (char *)&olWire[1];
227	    ptWire= (xkbPointWireDesc *)wire;
228	    for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) {
229		ptWire[p].x= pt->x;
230		ptWire[p].y= pt->y;
231	    }
232	    wire= (char *)&ptWire[ol->num_points];
233	}
234    }
235    return wire;
236}
237
238static char *
239_WriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad)
240{
241register int		i;
242xkbDoodadWireDesc *	doodadWire;
243
244    for (i=0;i<num_doodads;i++,doodad++) {
245	doodadWire= (xkbDoodadWireDesc *)wire;
246	wire= (char *)&doodadWire[1];
247	bzero(doodadWire,SIZEOF(xkbDoodadWireDesc));
248	doodadWire->any.name= doodad->any.name;
249	doodadWire->any.type= doodad->any.type;
250	doodadWire->any.priority= doodad->any.priority;
251	doodadWire->any.top= doodad->any.top;
252	doodadWire->any.left= doodad->any.left;
253	doodadWire->any.angle= doodad->any.angle;
254	switch (doodad->any.type) {
255	    case XkbOutlineDoodad:
256	    case XkbSolidDoodad:
257		doodadWire->shape.colorNdx= doodad->shape.color_ndx;
258		doodadWire->shape.shapeNdx= doodad->shape.shape_ndx;
259		break;
260	    case XkbTextDoodad:
261		doodadWire->text.width= doodad->text.width;
262		doodadWire->text.height= doodad->text.height;
263		doodadWire->text.colorNdx= doodad->text.color_ndx;
264		wire= _WriteCountedString(wire,doodad->text.text);
265		wire= _WriteCountedString(wire,doodad->text.font);
266		break;
267	    case XkbIndicatorDoodad:
268		doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx;
269		doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx;
270		doodadWire->indicator.offColorNdx=
271						doodad->indicator.off_color_ndx;
272		break;
273	    case XkbLogoDoodad:
274		doodadWire->logo.colorNdx= doodad->logo.color_ndx;
275		doodadWire->logo.shapeNdx= doodad->logo.shape_ndx;
276		wire= _WriteCountedString(wire,doodad->logo.logo_name);
277		break;
278	    default:
279		break;
280	}
281    }
282    return wire;
283}
284
285static char *
286_WriteGeomOverlay(char *wire,XkbOverlayPtr ol)
287{
288register int		r;
289XkbOverlayRowPtr	row;
290xkbOverlayWireDesc *	olWire;
291
292   olWire= (xkbOverlayWireDesc *)wire;
293   olWire->name= ol->name;
294   olWire->nRows= ol->num_rows;
295   wire= (char *)&olWire[1];
296   for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
297   	unsigned int		k;
298	XkbOverlayKeyPtr	key;
299	xkbOverlayRowWireDesc *	rowWire;
300	rowWire= (xkbOverlayRowWireDesc *)wire;
301	rowWire->rowUnder= row->row_under;
302	rowWire->nKeys= row->num_keys;
303	wire= (char *)&rowWire[1];
304	for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
305	    xkbOverlayKeyWireDesc *	keyWire;
306	    keyWire= (xkbOverlayKeyWireDesc *)wire;
307	    memcpy(keyWire->over,key->over.name,XkbKeyNameLength);
308	    memcpy(keyWire->under,key->under.name,XkbKeyNameLength);
309	    wire= (char *)&keyWire[1];
310	}
311   }
312   return wire;
313}
314
315static char *
316_WriteGeomSections(char *wire,XkbGeometryPtr geom)
317{
318register int		i;
319XkbSectionPtr		section;
320xkbSectionWireDesc *	sectionWire;
321
322    for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
323	sectionWire= (xkbSectionWireDesc *)wire;
324	sectionWire->name= section->name;
325	sectionWire->top= section->top;
326	sectionWire->left= section->left;
327	sectionWire->width= section->width;
328	sectionWire->height= section->height;
329	sectionWire->angle= section->angle;
330	sectionWire->priority= section->priority;
331	sectionWire->nRows= section->num_rows;
332	sectionWire->nDoodads= section->num_doodads;
333	sectionWire->nOverlays= section->num_overlays;
334	sectionWire->pad= 0;
335	wire= (char *)&sectionWire[1];
336	if (section->rows) {
337	    int			r;
338	    XkbRowPtr		row;
339	    xkbRowWireDesc *	rowWire;
340	    for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
341		rowWire= (xkbRowWireDesc *)wire;
342		rowWire->top= row->top;
343		rowWire->left= row->left;
344		rowWire->nKeys= row->num_keys;
345		rowWire->vertical= row->vertical;
346		rowWire->pad= 0;
347		wire= (char *)&rowWire[1];
348		if (row->keys) {
349		    int			k;
350		    XkbKeyPtr		key;
351		    xkbKeyWireDesc *	keyWire;
352		    keyWire= (xkbKeyWireDesc *)wire;
353		    for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
354			memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength);
355			keyWire[k].gap= key->gap;
356			keyWire[k].shapeNdx= key->shape_ndx;
357			keyWire[k].colorNdx= key->color_ndx;
358		    }
359		    wire= (char *)&keyWire[row->num_keys];
360		}
361	    }
362	}
363	if (section->doodads) {
364	    wire= _WriteGeomDoodads(wire,
365	    			      section->num_doodads,section->doodads);
366	}
367	if (section->overlays) {
368	    register int o;
369	    for (o=0;o<section->num_overlays;o++) {
370		wire= _WriteGeomOverlay(wire,&section->overlays[o]);
371	    }
372	}
373    }
374    return wire;
375}
376
377static char *
378_WriteGeomKeyAliases(char *wire,XkbGeometryPtr geom)
379{
380register int sz;
381
382    sz= geom->num_key_aliases*(XkbKeyNameLength*2);
383    if (sz>0) {
384	memcpy(wire,(char *)geom->key_aliases,sz);
385	wire+= sz;
386    }
387    return wire;
388}
389
390/***====================================================================***/
391
392static Status
393_SendSetGeometry(Display *dpy,XkbGeometryPtr geom,xkbSetGeometryReq *req)
394{
395int			sz;
396char *			wire,*tbuf;
397
398    sz= 0;
399    sz+= _SizeCountedString(geom->label_font);
400    sz+= _SizeGeomProperties(geom);
401    sz+= _SizeGeomColors(geom);
402    sz+= _SizeGeomShapes(geom);
403    sz+= _SizeGeomSections(geom);
404    sz+= _SizeGeomDoodads(geom->num_doodads,geom->doodads);
405    sz+= _SizeGeomKeyAliases(geom);
406    req->length+= (sz/4);
407    if (sz < (dpy->bufmax - dpy->buffer)) {
408	BufAlloc(char *,wire,sz);
409	tbuf= NULL;
410    }
411    else {
412	tbuf= _XAllocTemp(dpy,sz);
413	if (!tbuf)
414	    return BadAlloc;
415	wire= tbuf;
416    }
417    wire= _WriteCountedString(wire,geom->label_font);
418    if (geom->num_properties>0)
419	wire= _WriteGeomProperties(wire,geom);
420    if (geom->num_colors>0)
421	wire= _WriteGeomColors(wire,geom);
422    if (geom->num_shapes>0)
423	wire= _WriteGeomShapes(wire,geom);
424    if (geom->num_sections>0)
425	wire= _WriteGeomSections(wire,geom);
426    if (geom->num_doodads>0)
427	wire= _WriteGeomDoodads(wire,geom->num_doodads,geom->doodads);
428    if (geom->num_key_aliases>0)
429	wire= _WriteGeomKeyAliases(wire,geom);
430    if (tbuf!=NULL) {
431	Data(dpy,tbuf,sz);
432	_XFreeTemp(dpy,tbuf,sz);
433    }
434    return Success;
435}
436
437/***====================================================================***/
438
439Status
440XkbSetGeometry(Display *dpy,unsigned deviceSpec,XkbGeometryPtr geom)
441{
442xkbSetGeometryReq	*req;
443Status ret;
444
445    if ( (!geom) || (dpy->flags & XlibDisplayNoXkb) ||
446	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
447	return BadAccess;
448
449    LockDisplay(dpy);
450    GetReq(kbSetGeometry, req);
451    req->reqType = dpy->xkb_info->codes->major_opcode;
452    req->xkbReqType = X_kbSetGeometry;
453    req->deviceSpec = deviceSpec;
454    req->nShapes= geom->num_shapes;
455    req->nSections= geom->num_sections;
456    req->name= geom->name;
457    req->widthMM= geom->width_mm;
458    req->heightMM= geom->height_mm;
459    req->nProperties= geom->num_properties;
460    req->nColors= geom->num_colors;
461    req->nDoodads= geom->num_doodads;
462    req->nKeyAliases= geom->num_key_aliases;
463    req->baseColorNdx= (geom->base_color-geom->colors);
464    req->labelColorNdx= (geom->label_color-geom->colors);
465
466    ret = _SendSetGeometry(dpy,geom,req);
467    UnlockDisplay(dpy);
468    SyncHandle();
469    return ret;
470}
471
472