cout.c revision 87c518e6
1/************************************************************ 2 Copyright (c) 1994 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_CONFIG_H 28#include <config.h> 29#endif 30#include <stdio.h> 31#include <ctype.h> 32#include <stdlib.h> 33#include <X11/Xos.h> 34#include <X11/Xlib.h> 35#include <X11/XKBlib.h> 36#include <X11/extensions/XKBgeom.h> 37 38#include "XKMformat.h" 39#include "XKBfileInt.h" 40 41#define lowbit(x) ((x) & (-(x))) 42 43static Bool 44WriteCHdrVMods(FILE *file, Display *dpy, XkbDescPtr xkb) 45{ 46 register int i, nOut; 47 48 if ((!xkb) || (!xkb->names)) 49 return False; 50 for (i = nOut = 0; i < XkbNumVirtualMods; i++) { 51 if (xkb->names->vmods[i] != None) { 52 fprintf(file, "%s#define vmod_%s %d\n", 53 (nOut < 1 ? "\n" : ""), 54 XkbAtomText(dpy, xkb->names->vmods[i], XkbCFile), i); 55 nOut++; 56 } 57 } 58 for (i = nOut = 0; i < XkbNumVirtualMods; i++) { 59 if (xkb->names->vmods[i] != None) { 60 fprintf(file, "%s#define vmod_%sMask (1<<%d)\n", 61 (nOut < 1 ? "\n" : ""), 62 XkbAtomText(dpy, xkb->names->vmods[i], XkbCFile), i); 63 nOut++; 64 } 65 } 66 if (nOut > 0) 67 fprintf(file, "\n"); 68 return True; 69} 70 71static Bool 72WriteCHdrKeycodes(FILE * file, XkbDescPtr xkb) 73{ 74 Atom kcName; 75 register unsigned i; 76 char buf[8]; 77 78 if ((!xkb) || (!xkb->names) || (!xkb->names->keys)) { 79 _XkbLibError(_XkbErrMissingNames, "WriteCHdrKeycodes", 0); 80 return False; 81 } 82 kcName = xkb->names->keycodes; 83 buf[4] = '\0'; 84 if (xkb->names->keycodes != None) 85 fprintf(file, "/* keycodes name is \"%s\" */\n", 86 XkbAtomText(xkb->dpy, kcName, XkbMessage)); 87 fprintf(file, "static XkbKeyNameRec keyNames[NUM_KEYS]= {\n"); 88 for (i = 0; i <= xkb->max_key_code; i++) { 89 snprintf(buf, sizeof(buf), "\"%s\"", 90 XkbKeyNameText(xkb->names->keys[i].name, XkbCFile)); 91 if (i != xkb->max_key_code) { 92 fprintf(file, " { %6s },", buf); 93 if ((i & 3) == 3) 94 fprintf(file, "\n"); 95 } 96 else { 97 fprintf(file, " { %6s }\n", buf); 98 } 99 } 100 fprintf(file, "};\n"); 101 return True; 102} 103 104static void 105WriteTypePreserve(FILE * file, 106 Display * dpy, 107 char * prefix, 108 XkbDescPtr xkb, 109 XkbKeyTypePtr type) 110{ 111 register unsigned i; 112 XkbModsPtr pre; 113 114 fprintf(file, "static XkbModsRec preserve_%s[%d]= {\n", prefix, 115 type->map_count); 116 for (i = 0, pre = type->preserve; i < type->map_count; i++, pre++) { 117 if (i != 0) 118 fprintf(file, ",\n"); 119 fprintf(file, " { %15s, ", XkbModMaskText(pre->mask, XkbCFile)); 120 fprintf(file, "%15s, ", XkbModMaskText(pre->real_mods, XkbCFile)); 121 fprintf(file, "%15s }", 122 XkbVModMaskText(dpy, xkb, 0, pre->vmods, XkbCFile)); 123 } 124 fprintf(file, "\n};\n"); 125 return; 126} 127 128static void 129WriteTypeInitFunc(FILE *file, Display *dpy, XkbDescPtr xkb) 130{ 131 register unsigned i, n; 132 XkbKeyTypePtr type; 133 Atom * names; 134 char * prefix = NULL; 135 136 fprintf(file, "\n\nstatic void\n"); 137 fprintf(file, "initTypeNames(DPYTYPE dpy)\n"); 138 fprintf(file, "{\n"); 139 for (i = 0, type = xkb->map->types; i < xkb->map->num_types; i++, type++) { 140 if (!(prefix = strdup(XkbAtomText(dpy, type->name, XkbCFile)))) { 141 _XkbLibError(_XkbErrBadAlloc, "WriteTypeInitFunc", 0); 142 fprintf(file, "#error XkbErrBadAlloc WriteTypeInitFunc\n"); 143 break; 144 } 145 if (type->name != None) 146 fprintf(file, " dflt_types[%d].name= GET_ATOM(dpy,\"%s\");\n", 147 i, XkbAtomText(dpy, type->name, XkbCFile)); 148 names = type->level_names; 149 if (names != NULL) { 150 char *tmp; 151 152 for (n = 0; n < type->num_levels; n++) { 153 if (names[n] == None) 154 continue; 155 tmp = XkbAtomText(dpy, names[n], XkbCFile); 156 if (tmp == NULL) 157 continue; 158 fprintf(file, " lnames_%s[%d]= ", prefix, n); 159 fprintf(file, "GET_ATOM(dpy,\"%s\");\n", tmp); 160 } 161 } 162 free(prefix); 163 prefix = NULL; 164 } 165 fprintf(file, "}\n"); 166 return; 167} 168 169static Bool 170WriteCHdrKeyTypes(FILE *file, Display *dpy, XkbDescPtr xkb) 171{ 172 register unsigned i, n; 173 XkbClientMapPtr map; 174 XkbKeyTypePtr type; 175 char * prefix = NULL; 176 177 if ((!xkb) || (!xkb->map) || (!xkb->map->types)) { 178 _XkbLibError(_XkbErrMissingTypes, "WriteCHdrKeyTypes", 0); 179 return False; 180 } 181 if (xkb->map->num_types < XkbNumRequiredTypes) { 182 _XkbLibError(_XkbErrMissingReqTypes, "WriteCHdrKeyTypes", 0); 183 return 0; 184 } 185 map = xkb->map; 186 if ((xkb->names != NULL) && (xkb->names->types != None)) { 187 fprintf(file, "/* types name is \"%s\" */\n", 188 XkbAtomText(dpy, xkb->names->types, XkbCFile)); 189 } 190 for (i = 0, type = map->types; i < map->num_types; i++, type++) { 191 if (!(prefix = strdup(XkbAtomText(dpy, type->name, XkbCFile)))) { 192 _XkbLibError(_XkbErrBadAlloc, "WriteCHdrKeyTypes", 0); 193 return False; 194 } 195 196 if (type->map_count > 0) { 197 XkbKTMapEntryPtr entry; 198 199 entry = type->map; 200 fprintf(file, "static XkbKTMapEntryRec map_%s[%d]= {\n", prefix, 201 type->map_count); 202 for (n = 0; n < (unsigned) type->map_count; n++, entry++) { 203 if (n != 0) 204 fprintf(file, ",\n"); 205 fprintf(file, " { %d, %6d, { %15s, %15s, %15s } }", 206 entry->active, 207 entry->level, 208 XkbModMaskText(entry->mods.mask, XkbCFile), 209 XkbModMaskText(entry->mods.real_mods, XkbCFile), 210 XkbVModMaskText(dpy, xkb, 0, entry->mods.vmods, 211 XkbCFile)); 212 } 213 fprintf(file, "\n};\n"); 214 215 if (type->preserve) 216 WriteTypePreserve(file, dpy, prefix, xkb, type); 217 } 218 if (type->level_names != NULL) { 219 fprintf(file, "static Atom lnames_%s[%d];\n", prefix, 220 type->num_levels); 221 } 222 fprintf(file, "\n"); 223 free(prefix); 224 prefix = NULL; 225 } 226 fprintf(file, "static XkbKeyTypeRec dflt_types[]= {\n"); 227 for (i = 0, type = map->types; i < (unsigned) map->num_types; i++, type++) { 228 if (!(prefix = strdup(XkbAtomText(dpy, type->name, XkbCFile)))) { 229 _XkbLibError(_XkbErrBadAlloc, "WriteCHdrKeyTypes", 0); 230 return False; 231 } 232 if (i != 0) 233 fprintf(file, ",\n"); 234 fprintf(file, " {\n { %15s, %15s, %15s },\n", 235 XkbModMaskText(type->mods.mask, XkbCFile), 236 XkbModMaskText(type->mods.real_mods, XkbCFile), 237 XkbVModMaskText(dpy, xkb, 0, type->mods.vmods, XkbCFile)); 238 fprintf(file, " %d,\n", type->num_levels); 239 fprintf(file, " %d,", type->map_count); 240 if (type->map_count > 0) 241 fprintf(file, " map_%s,", prefix); 242 else 243 fprintf(file, " NULL,"); 244 if (type->preserve) 245 fprintf(file, " preserve_%s,\n", prefix); 246 else 247 fprintf(file, " NULL,\n"); 248 if (type->level_names != NULL) 249 fprintf(file, " None, lnames_%s\n }", prefix); 250 else 251 fprintf(file, " None, NULL\n }"); 252 free(prefix); 253 prefix = NULL; 254 } 255 fprintf(file, "\n};\n"); 256 fprintf(file, 257 "#define num_dflt_types (sizeof(dflt_types)/sizeof(XkbKeyTypeRec))\n"); 258 WriteTypeInitFunc(file, dpy, xkb); 259 return True; 260} 261 262static Bool 263WriteCHdrCompatMap(FILE *file, Display *dpy, XkbDescPtr xkb) 264{ 265 register unsigned i; 266 XkbCompatMapPtr compat; 267 XkbSymInterpretPtr interp; 268 269 if ((!xkb) || (!xkb->compat) || (!xkb->compat->sym_interpret)) { 270 _XkbLibError(_XkbErrMissingSymInterps, "WriteCHdrInterp", 0); 271 return False; 272 } 273 compat = xkb->compat; 274 if ((xkb->names != NULL) && (xkb->names->compat != None)) { 275 fprintf(file, "/* compat name is \"%s\" */\n", 276 XkbAtomText(dpy, xkb->names->compat, XkbCFile)); 277 } 278 fprintf(file, "static XkbSymInterpretRec dfltSI[%d]= {\n", compat->num_si); 279 interp = compat->sym_interpret; 280 for (i = 0; i < compat->num_si; i++, interp++) { 281 XkbAction *act; 282 283 act = (XkbAction *) &interp->act; 284 if (i != 0) 285 fprintf(file, ",\n"); 286 fprintf(file, " { %s, ", XkbKeysymText(interp->sym, XkbCFile)); 287 fprintf(file, "0x%04x,\n", interp->flags); 288 fprintf(file, " %s, ", XkbSIMatchText(interp->match, XkbCFile)); 289 fprintf(file, "%s,\n", XkbModMaskText(interp->mods, XkbCFile)); 290 fprintf(file, " %d,\n", interp->virtual_mod); 291 fprintf(file, " %s }", XkbActionText(dpy, xkb, act, XkbCFile)); 292 } 293 fprintf(file, "\n};\n"); 294 fprintf(file, 295 "#define num_dfltSI (sizeof(dfltSI)/sizeof(XkbSymInterpretRec))\n"); 296 fprintf(file, "\nstatic XkbCompatMapRec compatMap= {\n"); 297 fprintf(file, " dfltSI,\n"); 298 fprintf(file, " { /* group compatibility */\n "); 299 for (i = 0; i < XkbNumKbdGroups; i++) { 300 XkbModsPtr gc; 301 302 gc = &xkb->compat->groups[i]; 303 fprintf(file, "%s{ %12s, %12s, %12s }", 304 ((i == 0) ? "" : ",\n "), 305 XkbModMaskText(gc->mask, XkbCFile), 306 XkbModMaskText(gc->real_mods, XkbCFile), 307 XkbVModMaskText(xkb->dpy, xkb, 0, gc->vmods, XkbCFile)); 308 } 309 fprintf(file, "\n },\n"); 310 fprintf(file, " num_dfltSI, num_dfltSI\n"); 311 fprintf(file, "};\n\n"); 312 return True; 313} 314 315static Bool 316WriteCHdrSymbols(FILE *file, XkbDescPtr xkb) 317{ 318 register unsigned i; 319 320 if ((!xkb) || (!xkb->map) || (!xkb->map->syms) || (!xkb->map->key_sym_map)) { 321 _XkbLibError(_XkbErrMissingSymbols, "WriteCHdrSymbols", 0); 322 return False; 323 } 324 fprintf(file, "#define NUM_SYMBOLS %d\n", xkb->map->num_syms); 325 if (xkb->map->num_syms > 0) { 326 register KeySym *sym; 327 328 sym = xkb->map->syms; 329 fprintf(file, "static KeySym symCache[NUM_SYMBOLS]= {\n"); 330 for (i = 0; i < xkb->map->num_syms; i++, sym++) { 331 if (i == 0) 332 fprintf(file, " "); 333 else if (i % 4 == 0) 334 fprintf(file, ",\n "); 335 else 336 fprintf(file, ", "); 337 fprintf(file, "%15s", XkbKeysymText(*sym, XkbCFile)); 338 } 339 fprintf(file, "\n};\n"); 340 } 341 if (xkb->max_key_code > 0) { 342 register XkbSymMapPtr map; 343 344 map = xkb->map->key_sym_map; 345 fprintf(file, "static XkbSymMapRec symMap[NUM_KEYS]= {\n"); 346 for (i = 0; i <= xkb->max_key_code; i++, map++) { 347 if (i == 0) 348 fprintf(file, " "); 349 else if ((i & 3) == 0) 350 fprintf(file, ",\n "); 351 else 352 fprintf(file, ", "); 353 fprintf(file, "{ %2d, 0x%x, %3d }", 354 map->kt_index[0], map->group_info, map->offset); 355 } 356 fprintf(file, "\n};\n"); 357 } 358 return True; 359} 360 361static Bool 362WriteCHdrClientMap(FILE *file, Display *dpy, XkbDescPtr xkb) 363{ 364 if ((!xkb) || (!xkb->map) || (!xkb->map->syms) || (!xkb->map->key_sym_map)) { 365 _XkbLibError(_XkbErrMissingSymbols, "WriteCHdrClientMap", 0); 366 return False; 367 } 368 if (!WriteCHdrKeyTypes(file, dpy, xkb)) 369 return False; 370 if (!WriteCHdrSymbols(file, xkb)) 371 return False; 372 fprintf(file, "static XkbClientMapRec clientMap= {\n"); 373 fprintf(file, " NUM_TYPES, NUM_TYPES, types, \n"); 374 fprintf(file, " NUM_SYMBOLS, NUM_SYMBOLS, symCache, symMap\n"); 375 fprintf(file, "};\n\n"); 376 return True; 377} 378 379static Bool 380WriteCHdrServerMap(FILE *file, Display *dpy, XkbDescPtr xkb) 381{ 382 register unsigned i; 383 384 if ((!xkb) || (!xkb->map) || (!xkb->map->syms) || (!xkb->map->key_sym_map)) { 385 _XkbLibError(_XkbErrMissingSymbols, "WriteCHdrServerMap", 0); 386 return False; 387 } 388 if (xkb->server->num_acts > 0) { 389 register XkbAnyAction *act; 390 391 act = (XkbAnyAction *) xkb->server->acts; 392 fprintf(file, "#define NUM_ACTIONS %d\n", xkb->server->num_acts); 393 fprintf(file, "static XkbAnyAction actionCache[NUM_ACTIONS]= {\n"); 394 for (i = 0; i < xkb->server->num_acts; i++, act++) { 395 if (i == 0) 396 fprintf(file, " "); 397 else 398 fprintf(file, ",\n "); 399 fprintf(file, "%s", 400 XkbActionText(dpy, xkb, (XkbAction *) act, XkbCFile)); 401 } 402 fprintf(file, "\n};\n"); 403 } 404 fprintf(file, "static unsigned short keyActions[NUM_KEYS]= {\n"); 405 for (i = 0; i <= xkb->max_key_code; i++) { 406 if (i == 0) 407 fprintf(file, " "); 408 else if ((i & 0xf) == 0) 409 fprintf(file, ",\n "); 410 else 411 fprintf(file, ", "); 412 fprintf(file, "%2d", xkb->server->key_acts[i]); 413 } 414 fprintf(file, "\n};\n"); 415 fprintf(file, "static XkbBehavior behaviors[NUM_KEYS]= {\n"); 416 for (i = 0; i <= xkb->max_key_code; i++) { 417 if (i == 0) 418 fprintf(file, " "); 419 else if ((i & 0x3) == 0) 420 fprintf(file, ",\n "); 421 else 422 fprintf(file, ", "); 423 if (xkb->server->behaviors) { 424 fprintf(file, "%s", 425 XkbBehaviorText(xkb, &xkb->server->behaviors[i], XkbCFile)); 426 } 427 else 428 fprintf(file, "{ 0, 0 }"); 429 } 430 fprintf(file, "\n};\n"); 431 fprintf(file, "static unsigned char explicit_parts[NUM_KEYS]= {\n"); 432 for (i = 0; i <= xkb->max_key_code; i++) { 433 if (i == 0) 434 fprintf(file, " "); 435 else if ((i & 0x7) == 0) 436 fprintf(file, ",\n "); 437 else 438 fprintf(file, ", "); 439 if ((xkb->server->explicit == NULL) || (xkb->server->explicit[i] == 0)) 440 fprintf(file, " 0"); 441 else 442 fprintf(file, "0x%02x", xkb->server->explicit[i]); 443 } 444 fprintf(file, "\n};\n"); 445 fprintf(file, "static unsigned short vmodmap[NUM_KEYS]= {\n"); 446 for (i = 0; i < xkb->max_key_code; i++) { 447 if (i == 0) 448 fprintf(file, " "); 449 else if ((i & 0x7) == 0) 450 fprintf(file, ",\n "); 451 else 452 fprintf(file, ", "); 453 if ((xkb->server->vmodmap == NULL) || (xkb->server->vmodmap[i] == 0)) 454 fprintf(file, " 0"); 455 else 456 fprintf(file, "0x%04x", xkb->server->vmodmap[i]); 457 } 458 fprintf(file, "};\n"); 459 fprintf(file, "static XkbServerMapRec serverMap= {\n"); 460 fprintf(file, " %d, %d, (XkbAction *)actionCache,\n", 461 xkb->server->num_acts, xkb->server->num_acts); 462 fprintf(file, " behaviors, keyActions, explicit_parts,\n"); 463 for (i = 0; i < XkbNumVirtualMods; i++) { 464 if (i == 0) 465 fprintf(file, " { "); 466 else if (i == 8) 467 fprintf(file, ",\n "); 468 else 469 fprintf(file, ", "); 470 fprintf(file, "%3d", xkb->server->vmods[i]); 471 } 472 fprintf(file, " },\n"); 473 fprintf(file, " vmodmap\n"); 474 fprintf(file, "};\n\n"); 475 return True; 476} 477 478static Bool 479WriteCHdrIndicators(FILE *file, Display *dpy, XkbDescPtr xkb) 480{ 481 register int i, nNames; 482 XkbIndicatorMapPtr imap; 483 484 if (xkb->indicators == NULL) 485 return True; 486 fprintf(file, "static XkbIndicatorRec indicators= {\n"); 487 fprintf(file, " 0x%lx,\n {\n", 488 (long) xkb->indicators->phys_indicators); 489 for (imap = xkb->indicators->maps, i = nNames = 0; i < XkbNumIndicators; 490 i++, imap++) { 491 fprintf(file, "%s { 0x%02x, %s, 0x%02x, %s, { %s, ", 492 (i != 0 ? ",\n" : ""), imap->flags, 493 XkbIMWhichStateMaskText(imap->which_groups, XkbCFile), 494 imap->groups, XkbIMWhichStateMaskText(imap->which_mods, 495 XkbCFile), 496 XkbModMaskText(imap->mods.mask, XkbCFile)); 497 fprintf(file, " %s, %s }, %s }", 498 XkbModMaskText(imap->mods.real_mods, XkbCFile), 499 XkbVModMaskText(dpy, xkb, 0, imap->mods.vmods, XkbCFile), 500 XkbControlsMaskText(imap->ctrls, XkbCFile)); 501 if (xkb->names && (xkb->names->indicators[i] != None)) 502 nNames++; 503 } 504 fprintf(file, "\n }\n};\n"); 505 if (nNames > 0) { 506 fprintf(file, "static void\n"); 507 fprintf(file, "initIndicatorNames(DPYTYPE dpy,XkbDescPtr xkb)\n"); 508 fprintf(file, "{\n"); 509 for (i = 0; i < XkbNumIndicators; i++) { 510 Atom name; 511 512 if (xkb->names->indicators[i] == None) 513 continue; 514 name = xkb->names->indicators[i]; 515 fprintf(file, " xkb->names->indicators[%2d]= ", i); 516 fprintf(file, "GET_ATOM(dpy,\"%s\");\n", 517 XkbAtomText(dpy, name, XkbCFile)); 518 } 519 fprintf(file, "}\n"); 520 } 521 return True; 522} 523 524static Bool 525WriteCHdrGeomProps(FILE *file, XkbDescPtr xkb, XkbGeometryPtr geom) 526{ 527 if (geom->num_properties > 0) { 528 register int i; 529 530 fprintf(file, "\nstatic XkbPropertyRec g_props[%d]= {\n", 531 geom->num_properties); 532 for (i = 0; i < geom->num_properties; i++) { 533 fprintf(file, "%s { \"%s\", \"%s\" }", 534 (i == 0 ? "" : ",\n"), 535 XkbStringText(geom->properties[i].name, XkbCFile), 536 XkbStringText(geom->properties[i].value, XkbCFile)); 537 } 538 fprintf(file, "\n};\n"); 539 } 540 return True; 541} 542 543static Bool 544WriteCHdrGeomColors(FILE *file, XkbDescPtr xkb, XkbGeometryPtr geom) 545{ 546 if (geom->num_colors > 0) { 547 register int i; 548 549 fprintf(file, "\nstatic XkbColorRec g_colors[%d]= {\n", 550 geom->num_colors); 551 for (i = 0; i < geom->num_colors; i++) { 552 fprintf(file, "%s { %3d, \"%s\" }", 553 (i == 0 ? "" : ",\n"), geom->colors[i].pixel, 554 XkbStringText(geom->colors[i].spec, XkbCFile)); 555 } 556 fprintf(file, "\n};\n"); 557 } 558 return True; 559} 560 561static Bool 562WriteCHdrGeomOutlines(FILE *file, int nOL, XkbOutlinePtr ol, int shapeNdx) 563{ 564 register int o, p; 565 566 for (o = 0; o < nOL; o++) { 567 fprintf(file, "\nstatic XkbPointRec pts_sh%02do%02d[]= {\n", shapeNdx, 568 o); 569 for (p = 0; p < ol[o].num_points; p++) { 570 if (p == 0) 571 fprintf(file, " "); 572 else if ((p & 0x3) == 0) 573 fprintf(file, ",\n "); 574 else 575 fprintf(file, ", "); 576 fprintf(file, "{ %4d, %4d }", ol[o].points[p].x, ol[o].points[p].y); 577 } 578 fprintf(file, "\n};"); 579 } 580 fprintf(file, "\n\nstatic XkbOutlineRec ol_sh%02d[]= {\n", shapeNdx); 581 for (o = 0; o < nOL; o++) { 582 fprintf(file, "%s { %d, %d, %d, pts_sh%02do%02d }", 583 (o == 0 ? "" : ",\n"), 584 ol[o].num_points, ol[o].num_points, 585 ol[o].corner_radius, shapeNdx, o); 586 } 587 fprintf(file, "\n};\n"); 588 return True; 589} 590 591static Bool 592WriteCHdrGeomShapes(FILE *file, XkbDescPtr xkb, XkbGeometryPtr geom) 593{ 594 register int s; 595 register XkbShapePtr shape; 596 597 for (s = 0, shape = geom->shapes; s < geom->num_shapes; s++, shape++) { 598 WriteCHdrGeomOutlines(file, shape->num_outlines, shape->outlines, s); 599 } 600 fprintf(file, "\n\nstatic XkbShapeRec g_shapes[%d]= {\n", geom->num_shapes); 601 for (s = 0, shape = geom->shapes; s < geom->num_shapes; s++, shape++) { 602 fprintf(file, "%s { None, %3d, %3d, ol_sh%02d, ", 603 (s == 0 ? "" : ",\n"), shape->num_outlines, 604 shape->num_outlines, s); 605 if (shape->approx) { 606 fprintf(file, "&ol_sh%02d[%2d], ", s, 607 XkbOutlineIndex(shape, shape->approx)); 608 } 609 else 610 fprintf(file, " NULL, "); 611 if (shape->primary) { 612 fprintf(file, "&ol_sh%02d[%2d],\n", s, 613 XkbOutlineIndex(shape, shape->primary)); 614 } 615 else 616 fprintf(file, " NULL,\n"); 617 fprintf(file, 618 " { %4d, %4d, %4d, %4d } }", 619 shape->bounds.x1, shape->bounds.y1, 620 shape->bounds.x2, shape->bounds.y2); 621 } 622 fprintf(file, "\n};\n"); 623 return True; 624} 625 626static Bool 627WriteCHdrGeomDoodads(FILE * file, 628 XkbDescPtr xkb, 629 XkbGeometryPtr geom, 630 XkbSectionPtr section, 631 int section_num) 632{ 633 int nd, d; 634 XkbDoodadPtr doodad; 635 Display * dpy; 636 637 dpy = xkb->dpy; 638 if (section == NULL) { 639 if (geom->num_doodads > 0) { 640 fprintf(file, "static XkbDoodadRec g_doodads[%d];\n", 641 geom->num_doodads); 642 } 643 fprintf(file, "static void\n"); 644 fprintf(file, "_InitGeomDoodads(DPYTYPE dpy,XkbGeometryPtr geom)\n"); 645 fprintf(file, "{\n"); 646 fprintf(file, "register XkbDoodadPtr doodads;\n\n"); 647 fprintf(file, " doodads= geom->doodads;\n"); 648 nd = geom->num_doodads; 649 doodad = geom->doodads; 650 } 651 else { 652 if (section->num_doodads > 0) { 653 fprintf(file, "static XkbDoodadRec doodads_s%02d[%d];\n", 654 section_num, section->num_doodads); 655 } 656 fprintf(file, "static void\n"); 657 fprintf(file, "_InitS%02dDoodads(", section_num); 658 fprintf(file, " DPYTYPE dpy,\n"); 659 fprintf(file, " XkbGeometryPtr geom,\n"); 660 fprintf(file, " XkbSectionPtr section)\n"); 661 fprintf(file, "{\n"); 662 fprintf(file, "register XkbDoodadPtr doodads;\n\n"); 663 fprintf(file, " doodads= section->doodads;\n"); 664 nd = geom->num_doodads; 665 doodad = geom->doodads; 666 } 667 for (d = 0; d < nd; d++, doodad++) { 668 if (d != 0) 669 fprintf(file, "\n"); 670 fprintf(file, " doodads[%d].any.name= GET_ATOM(dpy,\"%s\");\n", 671 d, XkbAtomText(dpy, doodad->any.name, XkbCFile)); 672 fprintf(file, " doodads[%d].any.type= %s;\n", 673 d, XkbDoodadTypeText(doodad->any.type, XkbCFile)); 674 fprintf(file, " doodads[%d].any.priority= %d;\n", 675 d, doodad->any.priority); 676 fprintf(file, " doodads[%d].any.top= %d;\n", d, doodad->any.top); 677 fprintf(file, " doodads[%d].any.left= %d;\n", d, doodad->any.left); 678 fprintf(file, " doodads[%d].any.angle= %d;\n", d, doodad->any.angle); 679 switch (doodad->any.type) { 680 case XkbOutlineDoodad: 681 case XkbSolidDoodad: 682 fprintf(file, " doodads[%d].shape.color_ndx= %d;\n", 683 d, doodad->shape.color_ndx); 684 fprintf(file, " doodads[%d].shape.shape_ndx= %d;\n", 685 d, doodad->shape.shape_ndx); 686 break; 687 case XkbTextDoodad: 688 fprintf(file, " doodads[%d].text.width= %d;\n", 689 d, doodad->text.width); 690 fprintf(file, " doodads[%d].text.height= %d;\n", 691 d, doodad->text.height); 692 fprintf(file, " doodads[%d].text.color_ndx= %d;\n", 693 d, doodad->text.color_ndx); 694 fprintf(file, " doodads[%d].text.text= \"%s\";\n", 695 d, XkbStringText(doodad->text.text, XkbCFile)); 696 fprintf(file, " doodads[%d].text.font= \"%s\";\n", 697 d, XkbStringText(doodad->text.font, XkbCFile)); 698 break; 699 case XkbIndicatorDoodad: 700 fprintf(file, " doodads[%d].indicator.shape_ndx= %d;\n", 701 d, doodad->indicator.shape_ndx); 702 fprintf(file, " doodads[%d].indicator.on_color_ndx= %d;\n", 703 d, doodad->indicator.on_color_ndx); 704 fprintf(file, " doodads[%d].indicator.off_color_ndx= %d;\n", 705 d, doodad->indicator.off_color_ndx); 706 break; 707 case XkbLogoDoodad: 708 fprintf(file, " doodads[%d].logo.color_ndx= %d;\n", 709 d, doodad->logo.color_ndx); 710 fprintf(file, " doodads[%d].logo.shape_ndx= %d;\n", 711 d, doodad->logo.shape_ndx); 712 fprintf(file, " doodads[%d].logo.logo_name= \"%s\";\n", 713 d, XkbStringText(doodad->logo.logo_name, XkbCFile)); 714 break; 715 } 716 } 717 fprintf(file, "}\n"); 718 return True; 719} 720 721static Bool 722WriteCHdrGeomOverlays(FILE * file, 723 XkbDescPtr xkb, 724 XkbSectionPtr section, 725 int section_num) 726{ 727 register int o, r, k; 728 XkbOverlayPtr ol; 729 XkbOverlayRowPtr row; 730 XkbOverlayKeyPtr key; 731 732 if (section->num_overlays < 1) 733 return True; 734 for (o = 0, ol = section->overlays; o < section->num_overlays; o++, ol++) { 735 for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { 736 fprintf(file, "static XkbOverlayKeyRec olkeys_s%02dr%02d[%d]= {\n", 737 section_num, r, row->num_keys); 738 for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 739 fprintf(file, "%s { {\"%s\"}, {\"%s\"} }", 740 (k == 0 ? "" : ",\n"), 741 XkbKeyNameText(key->over.name, XkbCFile), 742 XkbKeyNameText(key->under.name, XkbCFile)); 743 } 744 fprintf(file, "\n};\n"); 745 } 746 fprintf(file, "static XkbOverlayRowRec olrows_s%02d[%d]= {\n", 747 section_num, section->num_rows); 748 for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { 749 fprintf(file, "%s { %4d, %4d, %4d, olkeys_s%02dr%02d }", 750 (r == 0 ? "" : ",\n"), 751 row->row_under, row->num_keys, row->num_keys, 752 section_num, r); 753 } 754 fprintf(file, "\n};\n"); 755 } 756 fprintf(file, "static XkbOverlayRec overlays_s%02d[%d]= {\n", section_num, 757 section->num_overlays); 758 for (o = 0, ol = section->overlays; o < section->num_overlays; o++, ol++) { 759 fprintf(file, "%s {\n", (o == 0 ? "" : ",\n")); 760 fprintf(file, " None, /* name */\n"); 761 fprintf(file, " NULL, /* section_under */\n"); 762 fprintf(file, " %4d, /* num_rows */\n", ol->num_rows); 763 fprintf(file, " %4d, /* sz_rows */\n", ol->num_rows); 764 fprintf(file, " olrows_s%02d,\n", section_num); 765 fprintf(file, " NULL /* bounds */\n"); 766 fprintf(file, " }"); 767 } 768 fprintf(file, "\n};\n"); 769 fprintf(file, "static void\n"); 770 fprintf(file, "_InitS%02dOverlay(", section_num); 771 fprintf(file, " DPYTYPE dpy,\n"); 772 fprintf(file, " XkbGeometryPtr geom,\n"); 773 fprintf(file, " XkbSectionPtr section)\n"); 774 fprintf(file, "{\n"); 775 fprintf(file, "XkbOverlayPtr ol;\n\n"); 776 fprintf(file, " ol= section->overlays;\n"); 777 for (o = 0, ol = section->overlays; o < section->num_overlays; o++, ol++) { 778 fprintf(file, " ol[%2d].name= GET_ATOM(dpy,\"%s\");\n", 779 o, XkbAtomText(xkb->dpy, ol->name, XkbCFile)); 780 fprintf(file, " ol[%2d].section_under= section;\n", o); 781 } 782 fprintf(file, "}\n"); 783 return True; 784} 785 786static Bool 787WriteCHdrGeomRows(FILE * file, 788 XkbDescPtr xkb, 789 XkbSectionPtr section, 790 int section_num) 791{ 792 register int k, r; 793 register XkbRowPtr row; 794 register XkbKeyPtr key; 795 796 for (r = 0, row = section->rows; r < section->num_rows; r++, row++) { 797 fprintf(file, "static XkbKeyRec keys_s%02dr%02d[]= {\n", 798 section_num, r); 799 for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 800 fprintf(file, "%s { { \"%s\" }, %4d, %4d, %4d }", 801 (k == 0 ? "" : ",\n"), 802 XkbKeyNameText(key->name.name, XkbCFile), 803 key->gap, key->shape_ndx, key->color_ndx); 804 } 805 fprintf(file, "\n};\n"); 806 } 807 fprintf(file, "static XkbRowRec rows_s%02d[]= {\n", section_num); 808 for (r = 0, row = section->rows; r < section->num_rows; r++, row++) { 809 fprintf(file, "%s { %4d, %4d, %2d, %2d, %1d, keys_s%02dr%02d, ", 810 (r == 0 ? "" : ",\n"), 811 row->top, row->left, row->num_keys, row->num_keys, 812 (row->vertical != 0), section_num, r); 813 fprintf(file, " { %4d, %4d, %4d, %4d } }", 814 row->bounds.x1, row->bounds.y1, row->bounds.x2, row->bounds.y2); 815 } 816 fprintf(file, "\n};\n"); 817 return True; 818} 819 820static Bool 821WriteCHdrGeomSections(FILE *file, XkbDescPtr xkb, XkbGeometryPtr geom) 822{ 823 register int s; 824 register XkbSectionPtr section; 825 826 for (s = 0, section = geom->sections; s < geom->num_sections; 827 s++, section++) { 828 WriteCHdrGeomRows(file, xkb, section, s); 829#ifdef NOTYET 830 if (section->num_doodads > 0) 831 WriteCHdrGeomDoodads(file, xkb, geom, section, s); 832#endif 833 if (section->num_overlays > 0) 834 WriteCHdrGeomOverlays(file, xkb, section, s); 835 } 836 fprintf(file, "\nstatic XkbSectionRec g_sections[%d]= {\n", 837 geom->num_sections); 838 for (s = 0, section = geom->sections; s < geom->num_sections; 839 s++, section++) { 840 if (s != 0) 841 fprintf(file, ",\n"); 842 fprintf(file, " {\n None, /* name */\n"); 843 fprintf(file, " %4d, /* priority */\n", section->priority); 844 fprintf(file, " %4d, /* top */\n", section->top); 845 fprintf(file, " %4d, /* left */\n", section->left); 846 fprintf(file, " %4d, /* width */\n", section->width); 847 fprintf(file, " %4d, /* height */\n", section->height); 848 fprintf(file, " %4d, /* angle */\n", section->angle); 849 fprintf(file, " %4d, /* num_rows */\n", section->num_rows); 850 fprintf(file, " %4d, /* num_doodads */\n", section->num_doodads); 851 fprintf(file, " %4d, /* num_overlays */\n", section->num_overlays); 852 fprintf(file, " %4d, /* sz_rows */\n", section->num_rows); 853 fprintf(file, " %4d, /* sz_doodads */\n", section->num_doodads); 854 fprintf(file, " %4d, /* sz_overlays */\n", section->num_overlays); 855 if (section->num_rows > 0) 856 fprintf(file, " rows_s%02d,\n", s); 857 else 858 fprintf(file, " NULL, /* rows */\n"); 859 if (section->num_doodads > 0) 860 fprintf(file, " doodads_s%02d,\n", s); 861 else 862 fprintf(file, " NULL, /* doodads */\n"); 863 fprintf(file, " { %4d, %4d, %4d, %4d }, /* bounds */\n", 864 section->bounds.x1, section->bounds.y1, 865 section->bounds.x2, section->bounds.y2); 866 if (section->num_overlays > 0) 867 fprintf(file, " overlays_s%02d\n", s); 868 else 869 fprintf(file, " NULL /* overlays */\n"); 870 fprintf(file, " }"); 871 } 872 fprintf(file, "\n};\n"); 873 fprintf(file, "\nstatic Bool\n"); 874 fprintf(file, "_InitSections(DPYTYPE dpy,XkbGeometryPtr geom)\n"); 875 fprintf(file, "{\nXkbSectionPtr sections;\n\n"); 876 fprintf(file, " sections= geom->sections;\n"); 877 for (s = 0, section = geom->sections; s < geom->num_sections; 878 s++, section++) { 879 if (section->num_doodads > 0) { 880 fprintf(file, " _InitS%02dDoodads(dpy,geom,§ions[%d]);\n", 881 s, s); 882 } 883 if (section->num_overlays > 0) { 884 fprintf(file, " _InitS%02dOverlays(dpy,geom,§ions[%d]);\n", 885 s, s); 886 } 887 } 888 fprintf(file, "}\n"); 889 return True; 890} 891 892static Bool 893WriteCHdrGeomAliases(FILE *file, XkbDescPtr xkb, XkbGeometryPtr geom) 894{ 895 if (geom->num_key_aliases > 0) { 896 register int i; 897 898 fprintf(file, "\nstatic XkbKeyAliasRec g_aliases[%d]= {\n", 899 geom->num_key_aliases); 900 for (i = 0; i < geom->num_key_aliases; i++) { 901 fprintf(file, "%s { \"%s\", \"%s\" }", 902 (i == 0 ? "" : ",\n"), 903 XkbKeyNameText(geom->key_aliases[i].real, XkbCFile), 904 XkbKeyNameText(geom->key_aliases[i].alias, XkbCFile)); 905 } 906 fprintf(file, "\n};\n"); 907 } 908 return True; 909} 910 911static Bool 912WriteCHdrGeometry(FILE *file, XkbDescPtr xkb) 913{ 914 XkbGeometryPtr geom; 915 register int i; 916 917 if ((!xkb) || (!xkb->geom)) { 918 _XkbLibError(_XkbErrMissingGeometry, "WriteCHdrGeometry", 0); 919 return False; 920 } 921 geom = xkb->geom; 922 WriteCHdrGeomProps(file, xkb, geom); 923 WriteCHdrGeomColors(file, xkb, geom); 924 WriteCHdrGeomShapes(file, xkb, geom); 925 WriteCHdrGeomSections(file, xkb, geom); 926 WriteCHdrGeomDoodads(file, xkb, geom, NULL, 0); 927 WriteCHdrGeomAliases(file, xkb, geom); 928 fprintf(file, "\nstatic XkbGeometryRec geom= {\n"); 929 fprintf(file, " None, /* name */\n"); 930 fprintf(file, " %d, %d, /* width, height */\n", 931 geom->width_mm, geom->height_mm); 932 if (geom->label_font) 933 fprintf(file, " \"%s\",/* label font */\n", 934 XkbStringText(geom->label_font, XkbCFile)); 935 else 936 fprintf(file, " NULL, /* label font */\n"); 937 if (geom->label_color) 938 fprintf(file, " &g_colors[%d], /* label color */\n", 939 XkbGeomColorIndex(geom, geom->label_color)); 940 else 941 fprintf(file, " NULL, /* label color */\n"); 942 if (geom->base_color) 943 fprintf(file, " &g_colors[%d], /* base color */\n", 944 XkbGeomColorIndex(geom, geom->base_color)); 945 else 946 fprintf(file, " NULL, /* base color */\n"); 947 fprintf(file, 948 " %d, %d, %d, /* sz: props, colors, shapes */\n", 949 geom->num_properties, geom->num_colors, geom->num_shapes); 950 fprintf(file, 951 " %d, %d, %d, /* sz: sections, doodads, aliases */\n", 952 geom->num_sections, geom->num_doodads, geom->num_key_aliases); 953 fprintf(file, 954 " %d, %d, %d, /* num: props, colors, shapes */\n", 955 geom->num_properties, geom->num_colors, geom->num_shapes); 956 fprintf(file, 957 " %d, %d, %d, /* num: sections, doodads, aliases */\n", 958 geom->num_sections, geom->num_doodads, geom->num_key_aliases); 959 fprintf(file, " %s, %s, %s,\n", 960 (geom->num_properties > 0 ? "g_props" : "NULL"), 961 (geom->num_colors > 0 ? "g_colors" : "NULL"), 962 (geom->num_shapes > 0 ? "g_shapes" : "NULL")); 963 fprintf(file, " %s, %s, %s\n", 964 (geom->num_sections > 0 ? "g_sections" : "NULL"), 965 (geom->num_doodads > 0 ? "g_doodads" : "NULL"), 966 (geom->num_key_aliases > 0 ? "g_aliases" : "NULL")); 967 fprintf(file, "};\n\n"); 968 fprintf(file, "static Bool\n"); 969 fprintf(file, "_InitHdrGeom(DPYTYPE dpy,XkbGeometryPtr geom)\n"); 970 fprintf(file, "{\n"); 971 if (geom->name != None) { 972 fprintf(file, " geom->name= GET_ATOM(dpy,\"%s\");\n", 973 XkbAtomText(xkb->dpy, geom->name, XkbCFile)); 974 } 975 for (i = 0; i < geom->num_shapes; i++) { 976 fprintf(file, " geom->shapes[%2d].name= GET_ATOM(dpy,\"%s\");\n", i, 977 XkbAtomText(xkb->dpy, geom->shapes[i].name, XkbCFile)); 978 } 979 if (geom->num_doodads > 0) 980 fprintf(file, " _InitGeomDoodads(dpy,geom);\n"); 981 fprintf(file, " _InitSections(dpy,geom);\n"); 982 fprintf(file, "}\n\n"); 983 return True; 984} 985 986static Bool 987WriteCHdrGeomFile(FILE *file, XkbFileInfo *result) 988{ 989 Bool ok; 990 991 ok = WriteCHdrGeometry(file, result->xkb); 992 return ok; 993} 994 995static Bool 996WriteCHdrLayout(FILE *file, XkbFileInfo *result) 997{ 998 Bool ok; 999 XkbDescPtr xkb; 1000 1001 xkb = result->xkb; 1002 ok = WriteCHdrVMods(file, xkb->dpy, xkb); 1003 ok = WriteCHdrKeycodes(file, xkb) && ok; 1004 ok = WriteCHdrSymbols(file, xkb) && ok; 1005 ok = WriteCHdrGeometry(file, xkb) && ok; 1006 return ok; 1007} 1008 1009static Bool 1010WriteCHdrSemantics(FILE *file, XkbFileInfo *result) 1011{ 1012 Bool ok; 1013 XkbDescPtr xkb; 1014 1015 xkb = result->xkb; 1016 ok = WriteCHdrVMods(file, xkb->dpy, xkb); 1017 ok = WriteCHdrKeyTypes(file, xkb->dpy, xkb) && ok; 1018 ok = WriteCHdrCompatMap(file, xkb->dpy, xkb) && ok; 1019 ok = WriteCHdrIndicators(file, xkb->dpy, xkb) && ok; 1020 return ok; 1021} 1022 1023static Bool 1024WriteCHdrKeymap(FILE *file, XkbFileInfo *result) 1025{ 1026 Bool ok; 1027 XkbDescPtr xkb; 1028 1029 xkb = result->xkb; 1030 ok = WriteCHdrVMods(file, xkb->dpy, xkb); 1031 ok = ok && WriteCHdrKeycodes(file, xkb); 1032 ok = ok && WriteCHdrClientMap(file, xkb->dpy, xkb); 1033 ok = ok && WriteCHdrServerMap(file, xkb->dpy, xkb); 1034 ok = ok && WriteCHdrCompatMap(file, xkb->dpy, xkb); 1035 ok = WriteCHdrIndicators(file, xkb->dpy, xkb) && ok; 1036 ok = ok && WriteCHdrGeometry(file, xkb); 1037 return ok; 1038} 1039 1040Bool 1041XkbWriteCFile(FILE *out, char *name, XkbFileInfo *result) 1042{ 1043 Bool ok; 1044 XkbDescPtr xkb; 1045 1046 Bool (*func) (FILE * /* file */, 1047 XkbFileInfo * /* result */ 1048 ); 1049 1050 switch (result->type) { 1051 case XkmSemanticsFile: 1052 func = WriteCHdrSemantics; 1053 break; 1054 case XkmLayoutFile: 1055 func = WriteCHdrLayout; 1056 break; 1057 case XkmKeymapFile: 1058 func = WriteCHdrKeymap; 1059 break; 1060 case XkmGeometryIndex: 1061 case XkmGeometryFile: 1062 func = WriteCHdrGeomFile; 1063 break; 1064 default: 1065 _XkbLibError(_XkbErrIllegalContents, "XkbWriteCFile", result->type); 1066 return False; 1067 } 1068 xkb = result->xkb; 1069 if (out == NULL) { 1070 _XkbLibError(_XkbErrFileCannotOpen, "XkbWriteCFile", 0); 1071 ok = False; 1072 } 1073 else { 1074 char *tmp, *hdrdef; 1075 1076 tmp = (char *) strrchr(name, '/'); 1077 if (tmp == NULL) 1078 tmp = name; 1079 else 1080 tmp++; 1081 hdrdef = (char *) _XkbCalloc(strlen(tmp) + 1, sizeof(char)); 1082 if (hdrdef) { 1083 strcpy(hdrdef, tmp); 1084 tmp = hdrdef; 1085 while (*tmp) { 1086 if (islower(*tmp)) 1087 *tmp = toupper(*tmp); 1088 else if (!isalnum(*tmp)) 1089 *tmp = '_'; 1090 tmp++; 1091 } 1092 fprintf(out, "/* This file generated automatically by xkbcomp */\n"); 1093 fprintf(out, "/* DO NOT EDIT */\n"); 1094 fprintf(out, "#ifndef %s\n", hdrdef); 1095 fprintf(out, "#define %s 1\n\n", hdrdef); 1096 } 1097 fprintf(out, "#ifndef XKB_IN_SERVER\n"); 1098 fprintf(out, "#define GET_ATOM(d,s) XInternAtom(d,s,0)\n"); 1099 fprintf(out, "#define DPYTYPE Display *\n"); 1100 fprintf(out, "#else\n"); 1101 fprintf(out, "#define GET_ATOM(d,s) MakeAtom(s,strlen(s),1)\n"); 1102 fprintf(out, "#define DPYTYPE char *\n"); 1103 fprintf(out, "#endif\n"); 1104 fprintf(out, "#define NUM_KEYS %d\n", xkb->max_key_code + 1); 1105 ok = (*func) (out, result); 1106 if (hdrdef) 1107 fprintf(out, "#endif /* %s */\n", hdrdef); 1108 } 1109 1110 if (!ok) { 1111 return False; 1112 } 1113 return True; 1114} 1115