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