XKBGAlloc.c (26651B)
1 /************************************************************ 2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 3 4 Permission to use, copy, modify, and distribute this 5 software and its documentation for any purpose and without 6 fee is hereby granted, provided that the above copyright 7 notice appear in all copies and that both that copyright 8 notice and this permission notice appear in supporting 9 documentation, and that the name of Silicon Graphics not be 10 used in advertising or publicity pertaining to distribution 11 of the software without specific prior written permission. 12 Silicon Graphics makes no representation about the suitability 13 of this software for any purpose. It is provided "as is" 14 without any express or implied warranty. 15 16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23 THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 25 ********************************************************/ 26 27 #ifdef HAVE_DIX_CONFIG_H 28 #include <dix-config.h> 29 #endif 30 31 #include <stdio.h> 32 #include <X11/X.h> 33 #include <X11/Xproto.h> 34 #include "misc.h" 35 #include "inputstr.h" 36 #include <xkbsrv.h> 37 #include "xkbgeom.h" 38 39 /***====================================================================***/ 40 41 static void 42 _XkbFreeGeomLeafElems(Bool freeAll, 43 int first, 44 int count, 45 unsigned short *num_inout, 46 unsigned short *sz_inout, 47 char **elems, unsigned int elem_sz) 48 { 49 if ((freeAll) || (*elems == NULL)) { 50 *num_inout = *sz_inout = 0; 51 free(*elems); 52 *elems = NULL; 53 return; 54 } 55 56 if ((first >= (*num_inout)) || (first < 0) || (count < 1)) 57 return; 58 59 if (first + count >= (*num_inout)) { 60 /* truncating the array is easy */ 61 (*num_inout) = first; 62 } 63 else { 64 char *ptr; 65 int extra; 66 67 ptr = *elems; 68 extra = ((*num_inout) - (first + count)) * elem_sz; 69 if (extra > 0) 70 memmove(&ptr[first * elem_sz], &ptr[(first + count) * elem_sz], 71 extra); 72 (*num_inout) -= count; 73 } 74 return; 75 } 76 77 typedef void (*ContentsClearFunc) (char * /* priv */ 78 ); 79 80 static void 81 _XkbFreeGeomNonLeafElems(Bool freeAll, 82 int first, 83 int count, 84 unsigned short *num_inout, 85 unsigned short *sz_inout, 86 char **elems, 87 unsigned int elem_sz, ContentsClearFunc freeFunc) 88 { 89 register int i; 90 register char *ptr; 91 92 if (freeAll) { 93 first = 0; 94 count = (*num_inout); 95 } 96 else if ((first >= (*num_inout)) || (first < 0) || (count < 1)) 97 return; 98 else if (first + count > (*num_inout)) 99 count = (*num_inout) - first; 100 if (*elems == NULL) 101 return; 102 103 if (freeFunc) { 104 ptr = *elems; 105 ptr += first * elem_sz; 106 for (i = 0; i < count; i++) { 107 (*freeFunc) (ptr); 108 ptr += elem_sz; 109 } 110 } 111 if (freeAll) { 112 (*num_inout) = (*sz_inout) = 0; 113 free(*elems); 114 *elems = NULL; 115 } 116 else if (first + count >= (*num_inout)) 117 *num_inout = first; 118 else { 119 i = ((*num_inout) - (first + count)) * elem_sz; 120 ptr = *elems; 121 memmove(&ptr[first * elem_sz], &ptr[(first + count) * elem_sz], i); 122 (*num_inout) -= count; 123 } 124 return; 125 } 126 127 /***====================================================================***/ 128 129 static void 130 _XkbClearProperty(char *prop_in) 131 { 132 XkbPropertyPtr prop = (XkbPropertyPtr) prop_in; 133 134 free(prop->name); 135 prop->name = NULL; 136 free(prop->value); 137 prop->value = NULL; 138 return; 139 } 140 141 void 142 XkbFreeGeomProperties(XkbGeometryPtr geom, int first, int count, Bool freeAll) 143 { 144 _XkbFreeGeomNonLeafElems(freeAll, first, count, 145 &geom->num_properties, &geom->sz_properties, 146 (char **) &geom->properties, 147 sizeof(XkbPropertyRec), _XkbClearProperty); 148 return; 149 } 150 151 /***====================================================================***/ 152 153 void 154 XkbFreeGeomKeyAliases(XkbGeometryPtr geom, int first, int count, Bool freeAll) 155 { 156 _XkbFreeGeomLeafElems(freeAll, first, count, 157 &geom->num_key_aliases, &geom->sz_key_aliases, 158 (char **) &geom->key_aliases, sizeof(XkbKeyAliasRec)); 159 return; 160 } 161 162 /***====================================================================***/ 163 164 static void 165 _XkbClearColor(char *color_in) 166 { 167 XkbColorPtr color = (XkbColorPtr) color_in; 168 169 free(color->spec); 170 return; 171 } 172 173 void 174 XkbFreeGeomColors(XkbGeometryPtr geom, int first, int count, Bool freeAll) 175 { 176 _XkbFreeGeomNonLeafElems(freeAll, first, count, 177 &geom->num_colors, &geom->sz_colors, 178 (char **) &geom->colors, 179 sizeof(XkbColorRec), _XkbClearColor); 180 return; 181 } 182 183 /***====================================================================***/ 184 185 void 186 XkbFreeGeomPoints(XkbOutlinePtr outline, int first, int count, Bool freeAll) 187 { 188 _XkbFreeGeomLeafElems(freeAll, first, count, 189 &outline->num_points, &outline->sz_points, 190 (char **) &outline->points, sizeof(XkbPointRec)); 191 return; 192 } 193 194 /***====================================================================***/ 195 196 static void 197 _XkbClearOutline(char *outline_in) 198 { 199 XkbOutlinePtr outline = (XkbOutlinePtr) outline_in; 200 201 if (outline->points != NULL) 202 XkbFreeGeomPoints(outline, 0, outline->num_points, TRUE); 203 return; 204 } 205 206 void 207 XkbFreeGeomOutlines(XkbShapePtr shape, int first, int count, Bool freeAll) 208 { 209 _XkbFreeGeomNonLeafElems(freeAll, first, count, 210 &shape->num_outlines, &shape->sz_outlines, 211 (char **) &shape->outlines, 212 sizeof(XkbOutlineRec), _XkbClearOutline); 213 214 return; 215 } 216 217 /***====================================================================***/ 218 219 static void 220 _XkbClearShape(char *shape_in) 221 { 222 XkbShapePtr shape = (XkbShapePtr) shape_in; 223 224 if (shape->outlines) 225 XkbFreeGeomOutlines(shape, 0, shape->num_outlines, TRUE); 226 return; 227 } 228 229 void 230 XkbFreeGeomShapes(XkbGeometryPtr geom, int first, int count, Bool freeAll) 231 { 232 _XkbFreeGeomNonLeafElems(freeAll, first, count, 233 &geom->num_shapes, &geom->sz_shapes, 234 (char **) &geom->shapes, 235 sizeof(XkbShapeRec), _XkbClearShape); 236 return; 237 } 238 239 /***====================================================================***/ 240 241 void 242 XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row, int first, int count, Bool freeAll) 243 { 244 _XkbFreeGeomLeafElems(freeAll, first, count, 245 &row->num_keys, &row->sz_keys, 246 (char **) &row->keys, sizeof(XkbOverlayKeyRec)); 247 return; 248 } 249 250 /***====================================================================***/ 251 252 void 253 XkbFreeGeomKeys(XkbRowPtr row, int first, int count, Bool freeAll) 254 { 255 _XkbFreeGeomLeafElems(freeAll, first, count, 256 &row->num_keys, &row->sz_keys, 257 (char **) &row->keys, sizeof(XkbKeyRec)); 258 return; 259 } 260 261 /***====================================================================***/ 262 263 static void 264 _XkbClearRow(char *row_in) 265 { 266 XkbRowPtr row = (XkbRowPtr) row_in; 267 268 if (row->keys != NULL) 269 XkbFreeGeomKeys(row, 0, row->num_keys, TRUE); 270 return; 271 } 272 273 void 274 XkbFreeGeomRows(XkbSectionPtr section, int first, int count, Bool freeAll) 275 { 276 _XkbFreeGeomNonLeafElems(freeAll, first, count, 277 §ion->num_rows, §ion->sz_rows, 278 (char **) §ion->rows, 279 sizeof(XkbRowRec), _XkbClearRow); 280 } 281 282 /***====================================================================***/ 283 284 static void 285 _XkbClearSection(char *section_in) 286 { 287 XkbSectionPtr section = (XkbSectionPtr) section_in; 288 289 if (section->rows != NULL) 290 XkbFreeGeomRows(section, 0, section->num_rows, TRUE); 291 if (section->doodads != NULL) { 292 XkbFreeGeomDoodads(section->doodads, section->num_doodads, TRUE); 293 section->doodads = NULL; 294 } 295 return; 296 } 297 298 void 299 XkbFreeGeomSections(XkbGeometryPtr geom, int first, int count, Bool freeAll) 300 { 301 _XkbFreeGeomNonLeafElems(freeAll, first, count, 302 &geom->num_sections, &geom->sz_sections, 303 (char **) &geom->sections, 304 sizeof(XkbSectionRec), _XkbClearSection); 305 return; 306 } 307 308 /***====================================================================***/ 309 310 static void 311 _XkbClearDoodad(char *doodad_in) 312 { 313 XkbDoodadPtr doodad = (XkbDoodadPtr) doodad_in; 314 315 switch (doodad->any.type) { 316 case XkbTextDoodad: 317 { 318 free(doodad->text.text); 319 doodad->text.text = NULL; 320 free(doodad->text.font); 321 doodad->text.font = NULL; 322 } 323 break; 324 case XkbLogoDoodad: 325 { 326 free(doodad->logo.logo_name); 327 doodad->logo.logo_name = NULL; 328 } 329 break; 330 } 331 return; 332 } 333 334 void 335 XkbFreeGeomDoodads(XkbDoodadPtr doodads, int nDoodads, Bool freeAll) 336 { 337 register int i; 338 register XkbDoodadPtr doodad; 339 340 if (doodads) { 341 for (i = 0, doodad = doodads; i < nDoodads; i++, doodad++) { 342 _XkbClearDoodad((char *) doodad); 343 } 344 if (freeAll) 345 free(doodads); 346 } 347 return; 348 } 349 350 void 351 XkbFreeGeometry(XkbGeometryPtr geom, unsigned which, Bool freeMap) 352 { 353 if (geom == NULL) 354 return; 355 if (freeMap) 356 which = XkbGeomAllMask; 357 if ((which & XkbGeomPropertiesMask) && (geom->properties != NULL)) 358 XkbFreeGeomProperties(geom, 0, geom->num_properties, TRUE); 359 if ((which & XkbGeomColorsMask) && (geom->colors != NULL)) 360 XkbFreeGeomColors(geom, 0, geom->num_colors, TRUE); 361 if ((which & XkbGeomShapesMask) && (geom->shapes != NULL)) 362 XkbFreeGeomShapes(geom, 0, geom->num_shapes, TRUE); 363 if ((which & XkbGeomSectionsMask) && (geom->sections != NULL)) 364 XkbFreeGeomSections(geom, 0, geom->num_sections, TRUE); 365 if ((which & XkbGeomDoodadsMask) && (geom->doodads != NULL)) { 366 XkbFreeGeomDoodads(geom->doodads, geom->num_doodads, TRUE); 367 geom->doodads = NULL; 368 geom->num_doodads = geom->sz_doodads = 0; 369 } 370 if ((which & XkbGeomKeyAliasesMask) && (geom->key_aliases != NULL)) 371 XkbFreeGeomKeyAliases(geom, 0, geom->num_key_aliases, TRUE); 372 if (freeMap) { 373 free(geom->label_font); 374 geom->label_font = NULL; 375 free(geom); 376 } 377 return; 378 } 379 380 /***====================================================================***/ 381 382 /** 383 * Resize and clear an XKB geometry item array. The array size may 384 * grow or shrink unlike in _XkbGeomAlloc. 385 * 386 * @param buffer[in,out] buffer to reallocate and clear 387 * @param szItems[in] currently allocated item count for "buffer" 388 * @param nrItems[in] required item count for "buffer" 389 * @param itemSize[in] size of a single item in "buffer" 390 * @param clearance[in] items to clear after reallocation 391 * 392 * @see _XkbGeomAlloc 393 * 394 * @return TRUE if reallocation succeeded. Otherwise FALSE is returned 395 * and contents of "buffer" aren't touched. 396 */ 397 Bool 398 XkbGeomRealloc(void **buffer, int szItems, int nrItems, 399 int itemSize, XkbGeomClearance clearance) 400 { 401 void *items; 402 int clearBegin; 403 404 /* Check validity of arguments. */ 405 if (!buffer) 406 return FALSE; 407 items = *buffer; 408 if (!((items && (szItems > 0)) || (!items && !szItems))) 409 return FALSE; 410 /* Check if there is need to resize. */ 411 if (nrItems != szItems) 412 if (!(items = reallocarray(items, nrItems, itemSize))) 413 return FALSE; 414 /* Clear specified items to zero. */ 415 switch (clearance) { 416 case XKB_GEOM_CLEAR_EXCESS: 417 clearBegin = szItems; 418 break; 419 case XKB_GEOM_CLEAR_ALL: 420 clearBegin = 0; 421 break; 422 case XKB_GEOM_CLEAR_NONE: 423 default: 424 clearBegin = nrItems; 425 break; 426 } 427 if (items && (clearBegin < nrItems)) 428 memset((char *) items + (clearBegin * itemSize), 0, 429 (nrItems - clearBegin) * itemSize); 430 *buffer = items; 431 return TRUE; 432 } 433 434 static Status 435 _XkbGeomAlloc(void **old, 436 unsigned short *num, 437 unsigned short *total, int num_new, size_t sz_elem) 438 { 439 if (num_new < 1) 440 return Success; 441 if ((*old) == NULL) 442 *num = *total = 0; 443 444 if ((*num) + num_new <= (*total)) 445 return Success; 446 447 *total = (*num) + num_new; 448 449 if (!XkbGeomRealloc(old, *num, *total, sz_elem, XKB_GEOM_CLEAR_EXCESS)) { 450 free(*old); 451 (*old) = NULL; 452 *total = *num = 0; 453 return BadAlloc; 454 } 455 456 return Success; 457 } 458 459 #define _XkbAllocProps(g,n) _XkbGeomAlloc((void *)&(g)->properties,\ 460 &(g)->num_properties,&(g)->sz_properties,\ 461 (n),sizeof(XkbPropertyRec)) 462 #define _XkbAllocColors(g,n) _XkbGeomAlloc((void *)&(g)->colors,\ 463 &(g)->num_colors,&(g)->sz_colors,\ 464 (n),sizeof(XkbColorRec)) 465 #define _XkbAllocShapes(g,n) _XkbGeomAlloc((void *)&(g)->shapes,\ 466 &(g)->num_shapes,&(g)->sz_shapes,\ 467 (n),sizeof(XkbShapeRec)) 468 #define _XkbAllocSections(g,n) _XkbGeomAlloc((void *)&(g)->sections,\ 469 &(g)->num_sections,&(g)->sz_sections,\ 470 (n),sizeof(XkbSectionRec)) 471 #define _XkbAllocDoodads(g,n) _XkbGeomAlloc((void *)&(g)->doodads,\ 472 &(g)->num_doodads,&(g)->sz_doodads,\ 473 (n),sizeof(XkbDoodadRec)) 474 #define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((void *)&(g)->key_aliases,\ 475 &(g)->num_key_aliases,&(g)->sz_key_aliases,\ 476 (n),sizeof(XkbKeyAliasRec)) 477 478 #define _XkbAllocOutlines(s,n) _XkbGeomAlloc((void *)&(s)->outlines,\ 479 &(s)->num_outlines,&(s)->sz_outlines,\ 480 (n),sizeof(XkbOutlineRec)) 481 #define _XkbAllocRows(s,n) _XkbGeomAlloc((void *)&(s)->rows,\ 482 &(s)->num_rows,&(s)->sz_rows,\ 483 (n),sizeof(XkbRowRec)) 484 #define _XkbAllocPoints(o,n) _XkbGeomAlloc((void *)&(o)->points,\ 485 &(o)->num_points,&(o)->sz_points,\ 486 (n),sizeof(XkbPointRec)) 487 #define _XkbAllocKeys(r,n) _XkbGeomAlloc((void *)&(r)->keys,\ 488 &(r)->num_keys,&(r)->sz_keys,\ 489 (n),sizeof(XkbKeyRec)) 490 #define _XkbAllocOverlays(s,n) _XkbGeomAlloc((void *)&(s)->overlays,\ 491 &(s)->num_overlays,&(s)->sz_overlays,\ 492 (n),sizeof(XkbOverlayRec)) 493 #define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((void *)&(o)->rows,\ 494 &(o)->num_rows,&(o)->sz_rows,\ 495 (n),sizeof(XkbOverlayRowRec)) 496 #define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((void *)&(r)->keys,\ 497 &(r)->num_keys,&(r)->sz_keys,\ 498 (n),sizeof(XkbOverlayKeyRec)) 499 500 Status 501 XkbAllocGeometry(XkbDescPtr xkb, XkbGeometrySizesPtr sizes) 502 { 503 XkbGeometryPtr geom; 504 Status rtrn; 505 506 if (xkb->geom == NULL) { 507 xkb->geom = calloc(1, sizeof(XkbGeometryRec)); 508 if (!xkb->geom) 509 return BadAlloc; 510 } 511 geom = xkb->geom; 512 if ((sizes->which & XkbGeomPropertiesMask) && 513 ((rtrn = _XkbAllocProps(geom, sizes->num_properties)) != Success)) { 514 goto BAIL; 515 } 516 if ((sizes->which & XkbGeomColorsMask) && 517 ((rtrn = _XkbAllocColors(geom, sizes->num_colors)) != Success)) { 518 goto BAIL; 519 } 520 if ((sizes->which & XkbGeomShapesMask) && 521 ((rtrn = _XkbAllocShapes(geom, sizes->num_shapes)) != Success)) { 522 goto BAIL; 523 } 524 if ((sizes->which & XkbGeomSectionsMask) && 525 ((rtrn = _XkbAllocSections(geom, sizes->num_sections)) != Success)) { 526 goto BAIL; 527 } 528 if ((sizes->which & XkbGeomDoodadsMask) && 529 ((rtrn = _XkbAllocDoodads(geom, sizes->num_doodads)) != Success)) { 530 goto BAIL; 531 } 532 if ((sizes->which & XkbGeomKeyAliasesMask) && 533 ((rtrn = 534 _XkbAllocKeyAliases(geom, sizes->num_key_aliases)) != Success)) { 535 goto BAIL; 536 } 537 return Success; 538 BAIL: 539 XkbFreeGeometry(geom, XkbGeomAllMask, TRUE); 540 xkb->geom = NULL; 541 return rtrn; 542 } 543 544 /***====================================================================***/ 545 546 XkbPropertyPtr 547 XkbAddGeomProperty(XkbGeometryPtr geom, char *name, char *value) 548 { 549 register int i; 550 register XkbPropertyPtr prop; 551 552 if ((!geom) || (!name) || (!value)) 553 return NULL; 554 for (i = 0, prop = geom->properties; i < geom->num_properties; i++, prop++) { 555 if ((prop->name) && (strcmp(name, prop->name) == 0)) { 556 free(prop->value); 557 prop->value = strdup(value); 558 return prop; 559 } 560 } 561 if ((geom->num_properties >= geom->sz_properties) && 562 (_XkbAllocProps(geom, 1) != Success)) { 563 return NULL; 564 } 565 prop = &geom->properties[geom->num_properties]; 566 prop->name = strdup(name); 567 if (!prop->name) 568 return NULL; 569 prop->value = strdup(value); 570 if (!prop->value) { 571 free(prop->name); 572 prop->name = NULL; 573 return NULL; 574 } 575 geom->num_properties++; 576 return prop; 577 } 578 579 XkbKeyAliasPtr 580 XkbAddGeomKeyAlias(XkbGeometryPtr geom, char *aliasStr, char *realStr) 581 { 582 register int i; 583 register XkbKeyAliasPtr alias; 584 585 if ((!geom) || (!aliasStr) || (!realStr) || (!aliasStr[0]) || (!realStr[0])) 586 return NULL; 587 for (i = 0, alias = geom->key_aliases; i < geom->num_key_aliases; 588 i++, alias++) { 589 if (strncmp(alias->alias, aliasStr, XkbKeyNameLength) == 0) { 590 memset(alias->real, 0, XkbKeyNameLength); 591 memcpy(alias->real, realStr, strnlen(realStr, XkbKeyNameLength)); 592 return alias; 593 } 594 } 595 if ((geom->num_key_aliases >= geom->sz_key_aliases) && 596 (_XkbAllocKeyAliases(geom, 1) != Success)) { 597 return NULL; 598 } 599 alias = &geom->key_aliases[geom->num_key_aliases]; 600 memset(alias, 0, sizeof(XkbKeyAliasRec)); 601 memcpy(alias->alias, aliasStr, strnlen(aliasStr, XkbKeyNameLength)); 602 memcpy(alias->real, realStr, strnlen(realStr, XkbKeyNameLength)); 603 geom->num_key_aliases++; 604 return alias; 605 } 606 607 XkbColorPtr 608 XkbAddGeomColor(XkbGeometryPtr geom, char *spec, unsigned int pixel) 609 { 610 register int i; 611 register XkbColorPtr color; 612 613 if ((!geom) || (!spec)) 614 return NULL; 615 for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) { 616 if ((color->spec) && (strcmp(color->spec, spec) == 0)) { 617 color->pixel = pixel; 618 return color; 619 } 620 } 621 if ((geom->num_colors >= geom->sz_colors) && 622 (_XkbAllocColors(geom, 1) != Success)) { 623 return NULL; 624 } 625 color = &geom->colors[geom->num_colors]; 626 color->pixel = pixel; 627 color->spec = strdup(spec); 628 if (!color->spec) 629 return NULL; 630 geom->num_colors++; 631 return color; 632 } 633 634 XkbOutlinePtr 635 XkbAddGeomOutline(XkbShapePtr shape, int sz_points) 636 { 637 XkbOutlinePtr outline; 638 639 if ((!shape) || (sz_points < 0)) 640 return NULL; 641 if ((shape->num_outlines >= shape->sz_outlines) && 642 (_XkbAllocOutlines(shape, 1) != Success)) { 643 return NULL; 644 } 645 outline = &shape->outlines[shape->num_outlines]; 646 memset(outline, 0, sizeof(XkbOutlineRec)); 647 if ((sz_points > 0) && (_XkbAllocPoints(outline, sz_points) != Success)) 648 return NULL; 649 shape->num_outlines++; 650 return outline; 651 } 652 653 XkbShapePtr 654 XkbAddGeomShape(XkbGeometryPtr geom, Atom name, int sz_outlines) 655 { 656 XkbShapePtr shape; 657 register int i; 658 659 if ((!geom) || (!name) || (sz_outlines < 0)) 660 return NULL; 661 if (geom->num_shapes > 0) { 662 for (shape = geom->shapes, i = 0; i < geom->num_shapes; i++, shape++) { 663 if (name == shape->name) 664 return shape; 665 } 666 } 667 if ((geom->num_shapes >= geom->sz_shapes) && 668 (_XkbAllocShapes(geom, 1) != Success)) 669 return NULL; 670 shape = &geom->shapes[geom->num_shapes]; 671 memset(shape, 0, sizeof(XkbShapeRec)); 672 if ((sz_outlines > 0) && (_XkbAllocOutlines(shape, sz_outlines) != Success)) 673 return NULL; 674 shape->name = name; 675 shape->primary = shape->approx = NULL; 676 geom->num_shapes++; 677 return shape; 678 } 679 680 XkbKeyPtr 681 XkbAddGeomKey(XkbRowPtr row) 682 { 683 XkbKeyPtr key; 684 685 if (!row) 686 return NULL; 687 if ((row->num_keys >= row->sz_keys) && (_XkbAllocKeys(row, 1) != Success)) 688 return NULL; 689 key = &row->keys[row->num_keys++]; 690 memset(key, 0, sizeof(XkbKeyRec)); 691 return key; 692 } 693 694 XkbRowPtr 695 XkbAddGeomRow(XkbSectionPtr section, int sz_keys) 696 { 697 XkbRowPtr row; 698 699 if ((!section) || (sz_keys < 0)) 700 return NULL; 701 if ((section->num_rows >= section->sz_rows) && 702 (_XkbAllocRows(section, 1) != Success)) 703 return NULL; 704 row = §ion->rows[section->num_rows]; 705 memset(row, 0, sizeof(XkbRowRec)); 706 if ((sz_keys > 0) && (_XkbAllocKeys(row, sz_keys) != Success)) 707 return NULL; 708 section->num_rows++; 709 return row; 710 } 711 712 XkbSectionPtr 713 XkbAddGeomSection(XkbGeometryPtr geom, 714 Atom name, int sz_rows, int sz_doodads, int sz_over) 715 { 716 register int i; 717 XkbSectionPtr section; 718 719 if ((!geom) || (name == None) || (sz_rows < 0)) 720 return NULL; 721 for (i = 0, section = geom->sections; i < geom->num_sections; 722 i++, section++) { 723 if (section->name != name) 724 continue; 725 if (((sz_rows > 0) && (_XkbAllocRows(section, sz_rows) != Success)) || 726 ((sz_doodads > 0) && 727 (_XkbAllocDoodads(section, sz_doodads) != Success)) || 728 ((sz_over > 0) && (_XkbAllocOverlays(section, sz_over) != Success))) 729 return NULL; 730 return section; 731 } 732 if ((geom->num_sections >= geom->sz_sections) && 733 (_XkbAllocSections(geom, 1) != Success)) 734 return NULL; 735 section = &geom->sections[geom->num_sections]; 736 if ((sz_rows > 0) && (_XkbAllocRows(section, sz_rows) != Success)) 737 return NULL; 738 if ((sz_doodads > 0) && (_XkbAllocDoodads(section, sz_doodads) != Success)) { 739 if (section->rows) { 740 free(section->rows); 741 section->rows = NULL; 742 section->sz_rows = section->num_rows = 0; 743 } 744 return NULL; 745 } 746 section->name = name; 747 geom->num_sections++; 748 return section; 749 } 750 751 XkbDoodadPtr 752 XkbAddGeomDoodad(XkbGeometryPtr geom, XkbSectionPtr section, Atom name) 753 { 754 XkbDoodadPtr old, doodad; 755 register int i, nDoodads; 756 757 if ((!geom) || (name == None)) 758 return NULL; 759 if ((section != NULL) && (section->num_doodads > 0)) { 760 old = section->doodads; 761 nDoodads = section->num_doodads; 762 } 763 else { 764 old = geom->doodads; 765 nDoodads = geom->num_doodads; 766 } 767 for (i = 0, doodad = old; i < nDoodads; i++, doodad++) { 768 if (doodad->any.name == name) 769 return doodad; 770 } 771 if (section) { 772 if ((section->num_doodads >= geom->sz_doodads) && 773 (_XkbAllocDoodads(section, 1) != Success)) { 774 return NULL; 775 } 776 doodad = §ion->doodads[section->num_doodads++]; 777 } 778 else { 779 if ((geom->num_doodads >= geom->sz_doodads) && 780 (_XkbAllocDoodads(geom, 1) != Success)) 781 return NULL; 782 doodad = &geom->doodads[geom->num_doodads++]; 783 } 784 memset(doodad, 0, sizeof(XkbDoodadRec)); 785 doodad->any.name = name; 786 return doodad; 787 } 788 789 XkbOverlayKeyPtr 790 XkbAddGeomOverlayKey(XkbOverlayPtr overlay, 791 XkbOverlayRowPtr row, char *over, char *under) 792 { 793 register int i; 794 XkbOverlayKeyPtr key; 795 XkbSectionPtr section; 796 XkbRowPtr row_under; 797 Bool found; 798 799 if ((!overlay) || (!row) || (!over) || (!under)) 800 return NULL; 801 section = overlay->section_under; 802 if (row->row_under >= section->num_rows) 803 return NULL; 804 row_under = §ion->rows[row->row_under]; 805 for (i = 0, found = FALSE; i < row_under->num_keys; i++) { 806 if (strncmp(under, row_under->keys[i].name.name, XkbKeyNameLength) == 0) { 807 found = TRUE; 808 break; 809 } 810 } 811 if (!found) 812 return NULL; 813 if ((row->num_keys >= row->sz_keys) && 814 (_XkbAllocOverlayKeys(row, 1) != Success)) 815 return NULL; 816 key = &row->keys[row->num_keys]; 817 memcpy(key->under.name, under, strnlen(under, XkbKeyNameLength)); 818 memcpy(key->over.name, over, strnlen(over, XkbKeyNameLength)); 819 row->num_keys++; 820 return key; 821 } 822 823 XkbOverlayRowPtr 824 XkbAddGeomOverlayRow(XkbOverlayPtr overlay, int row_under, int sz_keys) 825 { 826 register int i; 827 XkbOverlayRowPtr row; 828 829 if ((!overlay) || (sz_keys < 0)) 830 return NULL; 831 if (row_under >= overlay->section_under->num_rows) 832 return NULL; 833 for (i = 0; i < overlay->num_rows; i++) { 834 if (overlay->rows[i].row_under == row_under) { 835 row = &overlay->rows[i]; 836 if ((row->sz_keys < sz_keys) && 837 (_XkbAllocOverlayKeys(row, sz_keys) != Success)) { 838 return NULL; 839 } 840 return &overlay->rows[i]; 841 } 842 } 843 if ((overlay->num_rows >= overlay->sz_rows) && 844 (_XkbAllocOverlayRows(overlay, 1) != Success)) 845 return NULL; 846 row = &overlay->rows[overlay->num_rows]; 847 memset(row, 0, sizeof(XkbOverlayRowRec)); 848 if ((sz_keys > 0) && (_XkbAllocOverlayKeys(row, sz_keys) != Success)) 849 return NULL; 850 row->row_under = row_under; 851 overlay->num_rows++; 852 return row; 853 } 854 855 XkbOverlayPtr 856 XkbAddGeomOverlay(XkbSectionPtr section, Atom name, int sz_rows) 857 { 858 register int i; 859 XkbOverlayPtr overlay; 860 861 if ((!section) || (name == None) || (sz_rows == 0)) 862 return NULL; 863 864 for (i = 0, overlay = section->overlays; i < section->num_overlays; 865 i++, overlay++) { 866 if (overlay->name == name) { 867 if ((sz_rows > 0) && 868 (_XkbAllocOverlayRows(overlay, sz_rows) != Success)) 869 return NULL; 870 return overlay; 871 } 872 } 873 if ((section->num_overlays >= section->sz_overlays) && 874 (_XkbAllocOverlays(section, 1) != Success)) 875 return NULL; 876 overlay = §ion->overlays[section->num_overlays]; 877 if ((sz_rows > 0) && (_XkbAllocOverlayRows(overlay, sz_rows) != Success)) 878 return NULL; 879 overlay->name = name; 880 overlay->section_under = section; 881 section->num_overlays++; 882 return overlay; 883 }