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