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 *)§ionWire[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,§ion->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