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