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 HAVE_DIX_CONFIG_H 28#include <dix-config.h> 29#endif 30 31 32#include <stdio.h> 33#include <X11/X.h> 34#include <X11/Xproto.h> 35#include "misc.h" 36#include "inputstr.h" 37#include <xkbsrv.h> 38#include "xkbgeom.h" 39 40/***====================================================================***/ 41 42static void 43_XkbFreeGeomLeafElems( Bool freeAll, 44 int first, 45 int count, 46 unsigned short * num_inout, 47 unsigned short * sz_inout, 48 char ** elems, 49 unsigned int elem_sz) 50{ 51 if ((freeAll)||(*elems==NULL)) { 52 *num_inout= *sz_inout= 0; 53 free(*elems); 54 *elems = NULL; 55 return; 56 } 57 58 if ((first>=(*num_inout))||(first<0)||(count<1)) 59 return; 60 61 if (first+count>=(*num_inout)) { 62 /* truncating the array is easy */ 63 (*num_inout)= first; 64 } 65 else { 66 char * ptr; 67 int extra; 68 ptr= *elems; 69 extra= ((*num_inout)-(first+count))*elem_sz; 70 if (extra>0) 71 memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra); 72 (*num_inout)-= count; 73 } 74 return; 75} 76 77typedef void (*ContentsClearFunc)( 78 char * /* priv */ 79); 80 81static void 82_XkbFreeGeomNonLeafElems( Bool freeAll, 83 int first, 84 int count, 85 unsigned short * num_inout, 86 unsigned short * sz_inout, 87 char ** elems, 88 unsigned int elem_sz, 89 ContentsClearFunc freeFunc) 90{ 91register int i; 92register char *ptr; 93 94 if (freeAll) { 95 first= 0; 96 count= (*num_inout); 97 } 98 else if ((first>=(*num_inout))||(first<0)||(count<1)) 99 return; 100 else if (first+count>(*num_inout)) 101 count= (*num_inout)-first; 102 if (*elems==NULL) 103 return; 104 105 if (freeFunc) { 106 ptr= *elems; 107 ptr+= first*elem_sz; 108 for (i=0;i<count;i++) { 109 (*freeFunc)(ptr); 110 ptr+= elem_sz; 111 } 112 } 113 if (freeAll) { 114 (*num_inout)= (*sz_inout)= 0; 115 free(*elems); 116 *elems = NULL; 117 } 118 else if (first+count>=(*num_inout)) 119 *num_inout= first; 120 else { 121 i= ((*num_inout)-(first+count))*elem_sz; 122 ptr= *elems; 123 memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i); 124 (*num_inout)-= count; 125 } 126 return; 127} 128 129/***====================================================================***/ 130 131static void 132_XkbClearProperty(char *prop_in) 133{ 134XkbPropertyPtr prop= (XkbPropertyPtr)prop_in; 135 136 free(prop->name); 137 prop->name = NULL; 138 free(prop->value); 139 prop->value = NULL; 140 return; 141} 142 143void 144XkbFreeGeomProperties( XkbGeometryPtr geom, 145 int first, 146 int count, 147 Bool freeAll) 148{ 149 _XkbFreeGeomNonLeafElems(freeAll,first,count, 150 &geom->num_properties,&geom->sz_properties, 151 (char **)&geom->properties, 152 sizeof(XkbPropertyRec),_XkbClearProperty); 153 return; 154} 155 156/***====================================================================***/ 157 158void 159XkbFreeGeomKeyAliases( XkbGeometryPtr geom, 160 int first, 161 int count, 162 Bool freeAll) 163{ 164 _XkbFreeGeomLeafElems(freeAll,first,count, 165 &geom->num_key_aliases,&geom->sz_key_aliases, 166 (char **)&geom->key_aliases, 167 sizeof(XkbKeyAliasRec)); 168 return; 169} 170 171/***====================================================================***/ 172 173static void 174_XkbClearColor(char *color_in) 175{ 176XkbColorPtr color= (XkbColorPtr)color_in; 177 178 free(color->spec); 179 return; 180} 181 182void 183XkbFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll) 184{ 185 _XkbFreeGeomNonLeafElems(freeAll,first,count, 186 &geom->num_colors,&geom->sz_colors, 187 (char **)&geom->colors, 188 sizeof(XkbColorRec),_XkbClearColor); 189 return; 190} 191 192/***====================================================================***/ 193 194void 195XkbFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll) 196{ 197 _XkbFreeGeomLeafElems(freeAll,first,count, 198 &outline->num_points,&outline->sz_points, 199 (char **)&outline->points, 200 sizeof(XkbPointRec)); 201 return; 202} 203 204/***====================================================================***/ 205 206static void 207_XkbClearOutline(char *outline_in) 208{ 209XkbOutlinePtr outline= (XkbOutlinePtr)outline_in; 210 211 if (outline->points!=NULL) 212 XkbFreeGeomPoints(outline,0,outline->num_points,TRUE); 213 return; 214} 215 216void 217XkbFreeGeomOutlines(XkbShapePtr shape,int first,int count,Bool freeAll) 218{ 219 _XkbFreeGeomNonLeafElems(freeAll,first,count, 220 &shape->num_outlines,&shape->sz_outlines, 221 (char **)&shape->outlines, 222 sizeof(XkbOutlineRec),_XkbClearOutline); 223 224 return; 225} 226 227/***====================================================================***/ 228 229static void 230_XkbClearShape(char *shape_in) 231{ 232XkbShapePtr shape= (XkbShapePtr)shape_in; 233 234 if (shape->outlines) 235 XkbFreeGeomOutlines(shape,0,shape->num_outlines,TRUE); 236 return; 237} 238 239void 240XkbFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll) 241{ 242 _XkbFreeGeomNonLeafElems(freeAll,first,count, 243 &geom->num_shapes,&geom->sz_shapes, 244 (char **)&geom->shapes, 245 sizeof(XkbShapeRec),_XkbClearShape); 246 return; 247} 248 249/***====================================================================***/ 250 251void 252XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll) 253{ 254 _XkbFreeGeomLeafElems(freeAll,first,count, 255 &row->num_keys,&row->sz_keys, 256 (char **)&row->keys, 257 sizeof(XkbOverlayKeyRec)); 258 return; 259} 260 261/***====================================================================***/ 262 263static void 264_XkbClearOverlayRow(char *row_in) 265{ 266XkbOverlayRowPtr row= (XkbOverlayRowPtr)row_in; 267 268 if (row->keys!=NULL) 269 XkbFreeGeomOverlayKeys(row,0,row->num_keys,TRUE); 270 return; 271} 272 273void 274XkbFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll) 275{ 276 _XkbFreeGeomNonLeafElems(freeAll,first,count, 277 &overlay->num_rows,&overlay->sz_rows, 278 (char **)&overlay->rows, 279 sizeof(XkbOverlayRowRec),_XkbClearOverlayRow); 280 return; 281} 282 283/***====================================================================***/ 284 285static void 286_XkbClearOverlay(char *overlay_in) 287{ 288XkbOverlayPtr overlay= (XkbOverlayPtr)overlay_in; 289 290 if (overlay->rows!=NULL) 291 XkbFreeGeomOverlayRows(overlay,0,overlay->num_rows,TRUE); 292 return; 293} 294 295void 296XkbFreeGeomOverlays(XkbSectionPtr section,int first,int count,Bool freeAll) 297{ 298 _XkbFreeGeomNonLeafElems(freeAll,first,count, 299 §ion->num_overlays,§ion->sz_overlays, 300 (char **)§ion->overlays, 301 sizeof(XkbOverlayRec),_XkbClearOverlay); 302 return; 303} 304 305/***====================================================================***/ 306 307void 308XkbFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll) 309{ 310 _XkbFreeGeomLeafElems(freeAll,first,count, 311 &row->num_keys,&row->sz_keys, 312 (char **)&row->keys, 313 sizeof(XkbKeyRec)); 314 return; 315} 316 317/***====================================================================***/ 318 319static void 320_XkbClearRow(char *row_in) 321{ 322XkbRowPtr row= (XkbRowPtr)row_in; 323 324 if (row->keys!=NULL) 325 XkbFreeGeomKeys(row,0,row->num_keys,TRUE); 326 return; 327} 328 329void 330XkbFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll) 331{ 332 _XkbFreeGeomNonLeafElems(freeAll,first,count, 333 §ion->num_rows,§ion->sz_rows, 334 (char **)§ion->rows, 335 sizeof(XkbRowRec),_XkbClearRow); 336} 337 338/***====================================================================***/ 339 340static void 341_XkbClearSection(char *section_in) 342{ 343XkbSectionPtr section= (XkbSectionPtr)section_in; 344 345 if (section->rows!=NULL) 346 XkbFreeGeomRows(section,0,section->num_rows,TRUE); 347 if (section->doodads!=NULL) { 348 XkbFreeGeomDoodads(section->doodads,section->num_doodads,TRUE); 349 section->doodads= NULL; 350 } 351 return; 352} 353 354void 355XkbFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll) 356{ 357 _XkbFreeGeomNonLeafElems(freeAll,first,count, 358 &geom->num_sections,&geom->sz_sections, 359 (char **)&geom->sections, 360 sizeof(XkbSectionRec),_XkbClearSection); 361 return; 362} 363 364/***====================================================================***/ 365 366static void 367_XkbClearDoodad(char *doodad_in) 368{ 369XkbDoodadPtr doodad= (XkbDoodadPtr)doodad_in; 370 371 switch (doodad->any.type) { 372 case XkbTextDoodad: 373 { 374 free(doodad->text.text); 375 doodad->text.text = NULL; 376 free(doodad->text.font); 377 doodad->text.font = NULL; 378 } 379 break; 380 case XkbLogoDoodad: 381 { 382 free(doodad->logo.logo_name); 383 doodad->logo.logo_name = NULL; 384 } 385 break; 386 } 387 return; 388} 389 390void 391XkbFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll) 392{ 393register int i; 394register XkbDoodadPtr doodad; 395 396 if (doodads) { 397 for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) { 398 _XkbClearDoodad((char *)doodad); 399 } 400 if (freeAll) 401 free(doodads); 402 } 403 return; 404} 405 406void 407XkbFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap) 408{ 409 if (geom==NULL) 410 return; 411 if (freeMap) 412 which= XkbGeomAllMask; 413 if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL)) 414 XkbFreeGeomProperties(geom,0,geom->num_properties,TRUE); 415 if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL)) 416 XkbFreeGeomColors(geom,0,geom->num_colors,TRUE); 417 if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL)) 418 XkbFreeGeomShapes(geom,0,geom->num_shapes,TRUE); 419 if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL)) 420 XkbFreeGeomSections(geom,0,geom->num_sections,TRUE); 421 if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) { 422 XkbFreeGeomDoodads(geom->doodads,geom->num_doodads,TRUE); 423 geom->doodads= NULL; 424 geom->num_doodads= geom->sz_doodads= 0; 425 } 426 if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL)) 427 XkbFreeGeomKeyAliases(geom,0,geom->num_key_aliases,TRUE); 428 if (freeMap) { 429 free(geom->label_font); 430 geom->label_font = NULL; 431 free(geom); 432 } 433 return; 434} 435 436/***====================================================================***/ 437 438static Status 439_XkbGeomAlloc( void ** old, 440 unsigned short * num, 441 unsigned short * total, 442 int num_new, 443 size_t sz_elem) 444{ 445 if (num_new<1) 446 return Success; 447 if ((*old)==NULL) 448 *num= *total= 0; 449 450 if ((*num)+num_new<=(*total)) 451 return Success; 452 453 *total= (*num)+num_new; 454 if ((*old)!=NULL) 455 (*old)= realloc((*old),(*total)*sz_elem); 456 else (*old)= calloc((*total),sz_elem); 457 if ((*old)==NULL) { 458 *total= *num= 0; 459 return BadAlloc; 460 } 461 462 if (*num>0) { 463 char *tmp= (char *)(*old); 464 memset(&tmp[sz_elem*(*num)], 0, (num_new*sz_elem)); 465 } 466 return Success; 467} 468 469#define _XkbAllocProps(g,n) _XkbGeomAlloc((void *)&(g)->properties,\ 470 &(g)->num_properties,&(g)->sz_properties,\ 471 (n),sizeof(XkbPropertyRec)) 472#define _XkbAllocColors(g,n) _XkbGeomAlloc((void *)&(g)->colors,\ 473 &(g)->num_colors,&(g)->sz_colors,\ 474 (n),sizeof(XkbColorRec)) 475#define _XkbAllocShapes(g,n) _XkbGeomAlloc((void *)&(g)->shapes,\ 476 &(g)->num_shapes,&(g)->sz_shapes,\ 477 (n),sizeof(XkbShapeRec)) 478#define _XkbAllocSections(g,n) _XkbGeomAlloc((void *)&(g)->sections,\ 479 &(g)->num_sections,&(g)->sz_sections,\ 480 (n),sizeof(XkbSectionRec)) 481#define _XkbAllocDoodads(g,n) _XkbGeomAlloc((void *)&(g)->doodads,\ 482 &(g)->num_doodads,&(g)->sz_doodads,\ 483 (n),sizeof(XkbDoodadRec)) 484#define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((void *)&(g)->key_aliases,\ 485 &(g)->num_key_aliases,&(g)->sz_key_aliases,\ 486 (n),sizeof(XkbKeyAliasRec)) 487 488#define _XkbAllocOutlines(s,n) _XkbGeomAlloc((void *)&(s)->outlines,\ 489 &(s)->num_outlines,&(s)->sz_outlines,\ 490 (n),sizeof(XkbOutlineRec)) 491#define _XkbAllocRows(s,n) _XkbGeomAlloc((void *)&(s)->rows,\ 492 &(s)->num_rows,&(s)->sz_rows,\ 493 (n),sizeof(XkbRowRec)) 494#define _XkbAllocPoints(o,n) _XkbGeomAlloc((void *)&(o)->points,\ 495 &(o)->num_points,&(o)->sz_points,\ 496 (n),sizeof(XkbPointRec)) 497#define _XkbAllocKeys(r,n) _XkbGeomAlloc((void *)&(r)->keys,\ 498 &(r)->num_keys,&(r)->sz_keys,\ 499 (n),sizeof(XkbKeyRec)) 500#define _XkbAllocOverlays(s,n) _XkbGeomAlloc((void *)&(s)->overlays,\ 501 &(s)->num_overlays,&(s)->sz_overlays,\ 502 (n),sizeof(XkbOverlayRec)) 503#define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((void *)&(o)->rows,\ 504 &(o)->num_rows,&(o)->sz_rows,\ 505 (n),sizeof(XkbOverlayRowRec)) 506#define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((void *)&(r)->keys,\ 507 &(r)->num_keys,&(r)->sz_keys,\ 508 (n),sizeof(XkbOverlayKeyRec)) 509 510Status 511XkbAllocGeomProps(XkbGeometryPtr geom,int nProps) 512{ 513 return _XkbAllocProps(geom,nProps); 514} 515 516Status 517XkbAllocGeomColors(XkbGeometryPtr geom,int nColors) 518{ 519 return _XkbAllocColors(geom,nColors); 520} 521 522Status 523XkbAllocGeomKeyAliases(XkbGeometryPtr geom,int nKeyAliases) 524{ 525 return _XkbAllocKeyAliases(geom,nKeyAliases); 526} 527 528Status 529XkbAllocGeomShapes(XkbGeometryPtr geom,int nShapes) 530{ 531 return _XkbAllocShapes(geom,nShapes); 532} 533 534Status 535XkbAllocGeomSections(XkbGeometryPtr geom,int nSections) 536{ 537 return _XkbAllocSections(geom,nSections); 538} 539 540Status 541XkbAllocGeomOverlays(XkbSectionPtr section,int nOverlays) 542{ 543 return _XkbAllocOverlays(section,nOverlays); 544} 545 546Status 547XkbAllocGeomOverlayRows(XkbOverlayPtr overlay,int nRows) 548{ 549 return _XkbAllocOverlayRows(overlay,nRows); 550} 551 552Status 553XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row,int nKeys) 554{ 555 return _XkbAllocOverlayKeys(row,nKeys); 556} 557 558Status 559XkbAllocGeomDoodads(XkbGeometryPtr geom,int nDoodads) 560{ 561 return _XkbAllocDoodads(geom,nDoodads); 562} 563 564Status 565XkbAllocGeomSectionDoodads(XkbSectionPtr section,int nDoodads) 566{ 567 return _XkbAllocDoodads(section,nDoodads); 568} 569 570Status 571XkbAllocGeomOutlines(XkbShapePtr shape,int nOL) 572{ 573 return _XkbAllocOutlines(shape,nOL); 574} 575 576Status 577XkbAllocGeomRows(XkbSectionPtr section,int nRows) 578{ 579 return _XkbAllocRows(section,nRows); 580} 581 582Status 583XkbAllocGeomPoints(XkbOutlinePtr ol,int nPts) 584{ 585 return _XkbAllocPoints(ol,nPts); 586} 587 588Status 589XkbAllocGeomKeys(XkbRowPtr row,int nKeys) 590{ 591 return _XkbAllocKeys(row,nKeys); 592} 593 594Status 595XkbAllocGeometry(XkbDescPtr xkb,XkbGeometrySizesPtr sizes) 596{ 597XkbGeometryPtr geom; 598Status rtrn; 599 600 if (xkb->geom==NULL) { 601 xkb->geom= calloc(1, sizeof(XkbGeometryRec)); 602 if (!xkb->geom) 603 return BadAlloc; 604 } 605 geom= xkb->geom; 606 if ((sizes->which&XkbGeomPropertiesMask)&& 607 ((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) { 608 goto BAIL; 609 } 610 if ((sizes->which&XkbGeomColorsMask)&& 611 ((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) { 612 goto BAIL; 613 } 614 if ((sizes->which&XkbGeomShapesMask)&& 615 ((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) { 616 goto BAIL; 617 } 618 if ((sizes->which&XkbGeomSectionsMask)&& 619 ((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) { 620 goto BAIL; 621 } 622 if ((sizes->which&XkbGeomDoodadsMask)&& 623 ((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) { 624 goto BAIL; 625 } 626 if ((sizes->which&XkbGeomKeyAliasesMask)&& 627 ((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) { 628 goto BAIL; 629 } 630 return Success; 631BAIL: 632 XkbFreeGeometry(geom,XkbGeomAllMask,TRUE); 633 xkb->geom= NULL; 634 return rtrn; 635} 636 637/***====================================================================***/ 638 639XkbPropertyPtr 640XkbAddGeomProperty(XkbGeometryPtr geom,char *name,char *value) 641{ 642register int i; 643register XkbPropertyPtr prop; 644 645 if ((!geom)||(!name)||(!value)) 646 return NULL; 647 for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { 648 if ((prop->name)&&(strcmp(name,prop->name)==0)) { 649 free(prop->value); 650 prop->value= malloc(strlen(value)+1); 651 if (prop->value) 652 strcpy(prop->value,value); 653 return prop; 654 } 655 } 656 if ((geom->num_properties>=geom->sz_properties)&& 657 (_XkbAllocProps(geom,1)!=Success)) { 658 return NULL; 659 } 660 prop= &geom->properties[geom->num_properties]; 661 prop->name= malloc(strlen(name)+1); 662 if (!prop->name) 663 return NULL; 664 strcpy(prop->name,name); 665 prop->value= malloc(strlen(value)+1); 666 if (!prop->value) { 667 free(prop->name); 668 prop->name= NULL; 669 return NULL; 670 } 671 strcpy(prop->value,value); 672 geom->num_properties++; 673 return prop; 674} 675 676XkbKeyAliasPtr 677XkbAddGeomKeyAlias(XkbGeometryPtr geom,char *aliasStr,char *realStr) 678{ 679register int i; 680register XkbKeyAliasPtr alias; 681 682 if ((!geom)||(!aliasStr)||(!realStr)||(!aliasStr[0])||(!realStr[0])) 683 return NULL; 684 for (i=0,alias=geom->key_aliases;i<geom->num_key_aliases;i++,alias++) { 685 if (strncmp(alias->alias,aliasStr,XkbKeyNameLength)==0) { 686 memset(alias->real, 0, XkbKeyNameLength); 687 strncpy(alias->real,realStr,XkbKeyNameLength); 688 return alias; 689 } 690 } 691 if ((geom->num_key_aliases>=geom->sz_key_aliases)&& 692 (_XkbAllocKeyAliases(geom,1)!=Success)) { 693 return NULL; 694 } 695 alias= &geom->key_aliases[geom->num_key_aliases]; 696 memset(alias, 0, sizeof(XkbKeyAliasRec)); 697 strncpy(alias->alias,aliasStr,XkbKeyNameLength); 698 strncpy(alias->real,realStr,XkbKeyNameLength); 699 geom->num_key_aliases++; 700 return alias; 701} 702 703XkbColorPtr 704XkbAddGeomColor(XkbGeometryPtr geom,char *spec,unsigned int pixel) 705{ 706register int i; 707register XkbColorPtr color; 708 709 if ((!geom)||(!spec)) 710 return NULL; 711 for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { 712 if ((color->spec)&&(strcmp(color->spec,spec)==0)) { 713 color->pixel= pixel; 714 return color; 715 } 716 } 717 if ((geom->num_colors>=geom->sz_colors)&& 718 (_XkbAllocColors(geom,1)!=Success)) { 719 return NULL; 720 } 721 color= &geom->colors[geom->num_colors]; 722 color->pixel= pixel; 723 color->spec= malloc(strlen(spec)+1); 724 if (!color->spec) 725 return NULL; 726 strcpy(color->spec,spec); 727 geom->num_colors++; 728 return color; 729} 730 731XkbOutlinePtr 732XkbAddGeomOutline(XkbShapePtr shape,int sz_points) 733{ 734XkbOutlinePtr outline; 735 736 if ((!shape)||(sz_points<0)) 737 return NULL; 738 if ((shape->num_outlines>=shape->sz_outlines)&& 739 (_XkbAllocOutlines(shape,1)!=Success)) { 740 return NULL; 741 } 742 outline= &shape->outlines[shape->num_outlines]; 743 memset(outline, 0, sizeof(XkbOutlineRec)); 744 if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success)) 745 return NULL; 746 shape->num_outlines++; 747 return outline; 748} 749 750XkbShapePtr 751XkbAddGeomShape(XkbGeometryPtr geom,Atom name,int sz_outlines) 752{ 753XkbShapePtr shape; 754register int i; 755 756 if ((!geom)||(!name)||(sz_outlines<0)) 757 return NULL; 758 if (geom->num_shapes>0) { 759 for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) { 760 if (name==shape->name) 761 return shape; 762 } 763 } 764 if ((geom->num_shapes>=geom->sz_shapes)&& 765 (_XkbAllocShapes(geom,1)!=Success)) 766 return NULL; 767 shape= &geom->shapes[geom->num_shapes]; 768 memset(shape, 0, sizeof(XkbShapeRec)); 769 if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success)) 770 return NULL; 771 shape->name= name; 772 shape->primary= shape->approx= NULL; 773 geom->num_shapes++; 774 return shape; 775} 776 777XkbKeyPtr 778XkbAddGeomKey(XkbRowPtr row) 779{ 780XkbKeyPtr key; 781 if (!row) 782 return NULL; 783 if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success)) 784 return NULL; 785 key= &row->keys[row->num_keys++]; 786 memset(key, 0, sizeof(XkbKeyRec)); 787 return key; 788} 789 790XkbRowPtr 791XkbAddGeomRow(XkbSectionPtr section,int sz_keys) 792{ 793XkbRowPtr row; 794 795 if ((!section)||(sz_keys<0)) 796 return NULL; 797 if ((section->num_rows>=section->sz_rows)&& 798 (_XkbAllocRows(section,1)!=Success)) 799 return NULL; 800 row= §ion->rows[section->num_rows]; 801 memset(row, 0, sizeof(XkbRowRec)); 802 if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success)) 803 return NULL; 804 section->num_rows++; 805 return row; 806} 807 808XkbSectionPtr 809XkbAddGeomSection( XkbGeometryPtr geom, 810 Atom name, 811 int sz_rows, 812 int sz_doodads, 813 int sz_over) 814{ 815register int i; 816XkbSectionPtr section; 817 818 if ((!geom)||(name==None)||(sz_rows<0)) 819 return NULL; 820 for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { 821 if (section->name!=name) 822 continue; 823 if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))|| 824 ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))|| 825 ((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success))) 826 return NULL; 827 return section; 828 } 829 if ((geom->num_sections>=geom->sz_sections)&& 830 (_XkbAllocSections(geom,1)!=Success)) 831 return NULL; 832 section= &geom->sections[geom->num_sections]; 833 if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success)) 834 return NULL; 835 if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) { 836 if (section->rows) { 837 free(section->rows); 838 section->rows= NULL; 839 section->sz_rows= section->num_rows= 0; 840 } 841 return NULL; 842 } 843 section->name= name; 844 geom->num_sections++; 845 return section; 846} 847 848XkbDoodadPtr 849XkbAddGeomDoodad(XkbGeometryPtr geom,XkbSectionPtr section,Atom name) 850{ 851XkbDoodadPtr old,doodad; 852register int i,nDoodads; 853 854 if ((!geom)||(name==None)) 855 return NULL; 856 if ((section!=NULL)&&(section->num_doodads>0)) { 857 old= section->doodads; 858 nDoodads= section->num_doodads; 859 } 860 else { 861 old= geom->doodads; 862 nDoodads= geom->num_doodads; 863 } 864 for (i=0,doodad=old;i<nDoodads;i++,doodad++) { 865 if (doodad->any.name==name) 866 return doodad; 867 } 868 if (section) { 869 if ((section->num_doodads>=geom->sz_doodads)&& 870 (_XkbAllocDoodads(section,1)!=Success)) { 871 return NULL; 872 } 873 doodad= §ion->doodads[section->num_doodads++]; 874 } 875 else { 876 if ((geom->num_doodads>=geom->sz_doodads)&& 877 (_XkbAllocDoodads(geom,1)!=Success)) 878 return NULL; 879 doodad= &geom->doodads[geom->num_doodads++]; 880 } 881 memset(doodad, 0, sizeof(XkbDoodadRec)); 882 doodad->any.name= name; 883 return doodad; 884} 885 886XkbOverlayKeyPtr 887XkbAddGeomOverlayKey( XkbOverlayPtr overlay, 888 XkbOverlayRowPtr row, 889 char * over, 890 char * under) 891{ 892register int i; 893XkbOverlayKeyPtr key; 894XkbSectionPtr section; 895XkbRowPtr row_under; 896Bool found; 897 898 if ((!overlay)||(!row)||(!over)||(!under)) 899 return NULL; 900 section= overlay->section_under; 901 if (row->row_under>=section->num_rows) 902 return NULL; 903 row_under= §ion->rows[row->row_under]; 904 for (i=0,found=FALSE;i<row_under->num_keys;i++) { 905 if (strncmp(under,row_under->keys[i].name.name,XkbKeyNameLength)==0) { 906 found= TRUE; 907 break; 908 } 909 } 910 if (!found) 911 return NULL; 912 if ((row->num_keys>=row->sz_keys)&&(_XkbAllocOverlayKeys(row,1)!=Success)) 913 return NULL; 914 key= &row->keys[row->num_keys]; 915 strncpy(key->under.name,under,XkbKeyNameLength); 916 strncpy(key->over.name,over,XkbKeyNameLength); 917 row->num_keys++; 918 return key; 919} 920 921XkbOverlayRowPtr 922XkbAddGeomOverlayRow(XkbOverlayPtr overlay,int row_under,int sz_keys) 923{ 924register int i; 925XkbOverlayRowPtr row; 926 927 if ((!overlay)||(sz_keys<0)) 928 return NULL; 929 if (row_under>=overlay->section_under->num_rows) 930 return NULL; 931 for (i=0;i<overlay->num_rows;i++) { 932 if (overlay->rows[i].row_under==row_under) { 933 row= &overlay->rows[i]; 934 if ((row->sz_keys<sz_keys)&& 935 (_XkbAllocOverlayKeys(row,sz_keys)!=Success)) { 936 return NULL; 937 } 938 return &overlay->rows[i]; 939 } 940 } 941 if ((overlay->num_rows>=overlay->sz_rows)&& 942 (_XkbAllocOverlayRows(overlay,1)!=Success)) 943 return NULL; 944 row= &overlay->rows[overlay->num_rows]; 945 memset(row, 0, sizeof(XkbOverlayRowRec)); 946 if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success)) 947 return NULL; 948 row->row_under= row_under; 949 overlay->num_rows++; 950 return row; 951} 952 953XkbOverlayPtr 954XkbAddGeomOverlay(XkbSectionPtr section,Atom name,int sz_rows) 955{ 956register int i; 957XkbOverlayPtr overlay; 958 959 if ((!section)||(name==None)||(sz_rows==0)) 960 return NULL; 961 962 for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) { 963 if (overlay->name==name) { 964 if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success)) 965 return NULL; 966 return overlay; 967 } 968 } 969 if ((section->num_overlays>=section->sz_overlays)&& 970 (_XkbAllocOverlays(section,1)!=Success)) 971 return NULL; 972 overlay= §ion->overlays[section->num_overlays]; 973 if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success)) 974 return NULL; 975 overlay->name= name; 976 overlay->section_under= section; 977 section->num_overlays++; 978 return overlay; 979} 980