|
|
1.1 ! root 1: /* ! 2: * tkConfig.c -- ! 3: * ! 4: * This file contains the Tk_ConfigureWidget procedure. ! 5: * ! 6: * Copyright 1990-1992 Regents of the University of California. ! 7: * Permission to use, copy, modify, and distribute this ! 8: * software and its documentation for any purpose and without ! 9: * fee is hereby granted, provided that the above copyright ! 10: * notice appear in all copies. The University of California ! 11: * makes no representations about the suitability of this ! 12: * software for any purpose. It is provided "as is" without ! 13: * express or implied warranty. ! 14: */ ! 15: ! 16: #ifndef lint ! 17: static char rcsid[] = "$Header: /user6/ouster/wish/RCS/tkConfig.c,v 1.28 92/07/25 15:52:26 ouster Exp $ SPRITE (Berkeley)"; ! 18: #endif ! 19: ! 20: #include "tkconfig.h" ! 21: #include "tk.h" ! 22: ! 23: /* ! 24: * Values for "flags" field of Tk_ConfigSpec structures. Be sure ! 25: * to coordinate these values with those defined in tk.h ! 26: * (TK_CONFIG_COLOR_ONLY, etc.). There must not be overlap! ! 27: * ! 28: * INIT - Non-zero means (char *) things have been ! 29: * converted to Tk_Uid's. ! 30: */ ! 31: ! 32: #define INIT 0x20 ! 33: ! 34: /* ! 35: * Forward declarations for procedures defined later in this file: ! 36: */ ! 37: ! 38: static int DoConfig _ANSI_ARGS_((Tcl_Interp *interp, ! 39: Tk_Window tkwin, Tk_ConfigSpec *specPtr, ! 40: Tk_Uid value, int valueIsUid, char *widgRec)); ! 41: static Tk_ConfigSpec * FindConfigSpec _ANSI_ARGS_ ((Tcl_Interp *interp, ! 42: Tk_ConfigSpec *specs, char *argvName, ! 43: int needFlags, int hateFlags)); ! 44: static char * FormatConfigInfo _ANSI_ARGS_ ((Tk_Window tkwin, ! 45: Tk_ConfigSpec *specPtr, char *widgRec)); ! 46: ! 47: /* ! 48: *-------------------------------------------------------------- ! 49: * ! 50: * Tk_ConfigureWidget -- ! 51: * ! 52: * Process command-line options and database options to ! 53: * fill in fields of a widget record with resources and ! 54: * other parameters. ! 55: * ! 56: * Results: ! 57: * A standard Tcl return value. In case of an error, ! 58: * interp->result will hold an error message. ! 59: * ! 60: * Side effects: ! 61: * The fields of widgRec get filled in with information ! 62: * from argc/argv and the option database. Old information ! 63: * in widgRec's fields gets recycled. ! 64: * ! 65: *-------------------------------------------------------------- ! 66: */ ! 67: ! 68: int ! 69: Tk_ConfigureWidget(interp, tkwin, specs, argc, argv, widgRec, flags) ! 70: Tcl_Interp *interp; /* Interpreter for error reporting. */ ! 71: Tk_Window tkwin; /* Window containing widget (needed to ! 72: * set up X resources). */ ! 73: Tk_ConfigSpec *specs; /* Describes legal options. */ ! 74: int argc; /* Number of elements in argv. */ ! 75: char **argv; /* Command-line options. */ ! 76: char *widgRec; /* Record whose fields are to be ! 77: * modified. Values must be properly ! 78: * initialized. */ ! 79: int flags; /* Used to specify additional flags ! 80: * that must be present in config specs ! 81: * for them to be considered. Also, ! 82: * may have TK_CONFIG_ARGV_ONLY set. */ ! 83: { ! 84: register Tk_ConfigSpec *specPtr; ! 85: Tk_Uid value; /* Value of option from database. */ ! 86: int needFlags; /* Specs must contain this set of flags ! 87: * or else they are not considered. */ ! 88: int hateFlags; /* If a spec contains any bits here, it's ! 89: * not considered. */ ! 90: ! 91: needFlags = flags & ~(TK_CONFIG_USER_BIT - 1); ! 92: if (Tk_DefaultDepth(Tk_Screen(tkwin)) == 1) { ! 93: hateFlags = TK_CONFIG_COLOR_ONLY; ! 94: } else { ! 95: hateFlags = TK_CONFIG_MONO_ONLY; ! 96: } ! 97: ! 98: /* ! 99: * Pass one: scan through all the option specs, replacing strings ! 100: * with Tk_Uids (if this hasn't been done already) and clearing ! 101: * the TK_CONFIG_OPTION_SPECIFIED flags. ! 102: */ ! 103: ! 104: for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { ! 105: if (!(specPtr->specFlags & INIT) && (specPtr->argvName != NULL)) { ! 106: if (specPtr->dbName != NULL) { ! 107: specPtr->dbName = Tk_GetUid(specPtr->dbName); ! 108: } ! 109: if (specPtr->dbClass != NULL) { ! 110: specPtr->dbClass = Tk_GetUid(specPtr->dbClass); ! 111: } ! 112: if (specPtr->defValue != NULL) { ! 113: specPtr->defValue = Tk_GetUid(specPtr->defValue); ! 114: } ! 115: } ! 116: specPtr->specFlags = (specPtr->specFlags & ~TK_CONFIG_OPTION_SPECIFIED) ! 117: | INIT; ! 118: } ! 119: ! 120: /* ! 121: * Pass two: scan through all of the arguments, processing those ! 122: * that match entries in the specs. ! 123: */ ! 124: ! 125: for ( ; argc > 0; argc -= 2, argv += 2) { ! 126: specPtr = FindConfigSpec(interp, specs, *argv, needFlags, hateFlags); ! 127: if (specPtr == NULL) { ! 128: return TCL_ERROR; ! 129: } ! 130: ! 131: /* ! 132: * Process the entry. ! 133: */ ! 134: ! 135: if (argc < 2) { ! 136: Tcl_AppendResult(interp, "value for \"", *argv, ! 137: "\" missing", (char *) NULL); ! 138: return TCL_ERROR; ! 139: } ! 140: if (DoConfig(interp, tkwin, specPtr, argv[1], 0, widgRec) != TCL_OK) { ! 141: char msg[100]; ! 142: ! 143: sprintf(msg, "\n (processing \"%.40s\" option)", ! 144: specPtr->argvName); ! 145: Tcl_AddErrorInfo(interp, msg); ! 146: return TCL_ERROR; ! 147: } ! 148: specPtr->specFlags |= TK_CONFIG_OPTION_SPECIFIED; ! 149: } ! 150: ! 151: /* ! 152: * Pass three: scan through all of the specs again; if no ! 153: * command-line argument matched a spec, then check for info ! 154: * in the option database. If there was nothing in the ! 155: * database, then use the default. ! 156: */ ! 157: ! 158: if (!(flags & TK_CONFIG_ARGV_ONLY)) { ! 159: for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { ! 160: if ((specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED) ! 161: || (specPtr->argvName == NULL) ! 162: || (specPtr->type == TK_CONFIG_SYNONYM)) { ! 163: continue; ! 164: } ! 165: if (((specPtr->specFlags & needFlags) != needFlags) ! 166: || (specPtr->specFlags & hateFlags)) { ! 167: continue; ! 168: } ! 169: value = NULL; ! 170: if (specPtr->dbName != NULL) { ! 171: value = Tk_GetOption(tkwin, specPtr->dbName, specPtr->dbClass); ! 172: } ! 173: if (value != NULL) { ! 174: if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) != ! 175: TCL_OK) { ! 176: char msg[200]; ! 177: ! 178: sprintf(msg, "\n (%s \"%.50s\" in widget \"%.50s\")", ! 179: "database entry for", ! 180: specPtr->dbName, Tk_PathName(tkwin)); ! 181: Tcl_AddErrorInfo(interp, msg); ! 182: return TCL_ERROR; ! 183: } ! 184: } else { ! 185: value = specPtr->defValue; ! 186: if ((value != NULL) && !(specPtr->specFlags ! 187: & TK_CONFIG_DONT_SET_DEFAULT)) { ! 188: if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) != ! 189: TCL_OK) { ! 190: char msg[200]; ! 191: ! 192: sprintf(msg, ! 193: "\n (%s \"%.50s\" in widget \"%.50s\")", ! 194: "default value for", ! 195: specPtr->dbName, Tk_PathName(tkwin)); ! 196: Tcl_AddErrorInfo(interp, msg); ! 197: return TCL_ERROR; ! 198: } ! 199: } ! 200: } ! 201: } ! 202: } ! 203: ! 204: return TCL_OK; ! 205: } ! 206: ! 207: /* ! 208: *-------------------------------------------------------------- ! 209: * ! 210: * FindConfigSpec -- ! 211: * ! 212: * Search through a table of configuration specs, looking for ! 213: * one that matches a given argvName. ! 214: * ! 215: * Results: ! 216: * The return value is a pointer to the matching entry, or NULL ! 217: * if nothing matched. In that case an error message is left ! 218: * in interp->result. ! 219: * ! 220: * Side effects: ! 221: * None. ! 222: * ! 223: *-------------------------------------------------------------- ! 224: */ ! 225: ! 226: static Tk_ConfigSpec * ! 227: FindConfigSpec(interp, specs, argvName, needFlags, hateFlags) ! 228: Tcl_Interp *interp; /* Used for reporting errors. */ ! 229: Tk_ConfigSpec *specs; /* Pointer to table of configuration ! 230: * specifications for a widget. */ ! 231: char *argvName; /* Name (suitable for use in a "config" ! 232: * command) identifying particular option. */ ! 233: int needFlags; /* Flags that must be present in matching ! 234: * entry. */ ! 235: int hateFlags; /* Flags that must NOT be present in ! 236: * matching entry. */ ! 237: { ! 238: register Tk_ConfigSpec *specPtr; ! 239: register char c; /* First character of current argument. */ ! 240: Tk_ConfigSpec *matchPtr; /* Matching spec, or NULL. */ ! 241: int length; ! 242: ! 243: c = argvName[1]; ! 244: length = strlen(argvName); ! 245: matchPtr = NULL; ! 246: for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { ! 247: if (specPtr->argvName == NULL) { ! 248: continue; ! 249: } ! 250: if ((specPtr->argvName[1] != c) ! 251: || (strncmp(specPtr->argvName, argvName, length) != 0)) { ! 252: continue; ! 253: } ! 254: if (((specPtr->specFlags & needFlags) != needFlags) ! 255: || (specPtr->specFlags & hateFlags)) { ! 256: continue; ! 257: } ! 258: if (specPtr->argvName[length] == 0) { ! 259: matchPtr = specPtr; ! 260: goto gotMatch; ! 261: } ! 262: if (matchPtr != NULL) { ! 263: Tcl_AppendResult(interp, "ambiguous option \"", argvName, ! 264: "\"", (char *) NULL); ! 265: return (Tk_ConfigSpec *) NULL; ! 266: } ! 267: matchPtr = specPtr; ! 268: } ! 269: ! 270: if (matchPtr == NULL) { ! 271: Tcl_AppendResult(interp, "unknown option \"", argvName, ! 272: "\"", (char *) NULL); ! 273: return (Tk_ConfigSpec *) NULL; ! 274: } ! 275: ! 276: /* ! 277: * Found a matching entry. If it's a synonym, then find the ! 278: * entry that it's a synonym for. ! 279: */ ! 280: ! 281: gotMatch: ! 282: specPtr = matchPtr; ! 283: if (specPtr->type == TK_CONFIG_SYNONYM) { ! 284: for (specPtr = specs; ; specPtr++) { ! 285: if (specPtr->type == TK_CONFIG_END) { ! 286: Tcl_AppendResult(interp, ! 287: "couldn't find synonym for option \"", ! 288: argvName, "\"", (char *) NULL); ! 289: return (Tk_ConfigSpec *) NULL; ! 290: } ! 291: if ((specPtr->dbName == matchPtr->dbName) ! 292: && (specPtr->type != TK_CONFIG_SYNONYM) ! 293: && ((specPtr->specFlags & needFlags) == needFlags) ! 294: && !(specPtr->specFlags & hateFlags)) { ! 295: break; ! 296: } ! 297: } ! 298: } ! 299: return specPtr; ! 300: } ! 301: ! 302: /* ! 303: *-------------------------------------------------------------- ! 304: * ! 305: * DoConfig -- ! 306: * ! 307: * This procedure applies a single configuration option ! 308: * to a widget record. ! 309: * ! 310: * Results: ! 311: * A standard Tcl return value. ! 312: * ! 313: * Side effects: ! 314: * WidgRec is modified as indicated by specPtr and value. ! 315: * The old value is recycled, if that is appropriate for ! 316: * the value type. ! 317: * ! 318: *-------------------------------------------------------------- ! 319: */ ! 320: ! 321: static int ! 322: DoConfig(interp, tkwin, specPtr, value, valueIsUid, widgRec) ! 323: Tcl_Interp *interp; /* Interpreter for error reporting. */ ! 324: Tk_Window tkwin; /* Window containing widget (needed to ! 325: * set up X resources). */ ! 326: Tk_ConfigSpec *specPtr; /* Specifier to apply. */ ! 327: char *value; /* Value to use to fill in widgRec. */ ! 328: int valueIsUid; /* Non-zero means value is a Tk_Uid; ! 329: * zero means it's an ordinary string. */ ! 330: char *widgRec; /* Record whose fields are to be ! 331: * modified. Values must be properly ! 332: * initialized. */ ! 333: { ! 334: char *ptr; ! 335: Tk_Uid uid; ! 336: int nullValue; ! 337: ! 338: nullValue = 0; ! 339: if ((*value == 0) && (specPtr->specFlags & TK_CONFIG_NULL_OK)) { ! 340: nullValue = 1; ! 341: } ! 342: ! 343: do { ! 344: ptr = widgRec + specPtr->offset; ! 345: switch (specPtr->type) { ! 346: case TK_CONFIG_BOOLEAN: ! 347: if (Tcl_GetBoolean(interp, value, (int *) ptr) != TCL_OK) { ! 348: return TCL_ERROR; ! 349: } ! 350: break; ! 351: case TK_CONFIG_INT: ! 352: if (Tcl_GetInt(interp, value, (int *) ptr) != TCL_OK) { ! 353: return TCL_ERROR; ! 354: } ! 355: break; ! 356: case TK_CONFIG_DOUBLE: ! 357: if (Tcl_GetDouble(interp, value, (double *) ptr) != TCL_OK) { ! 358: return TCL_ERROR; ! 359: } ! 360: break; ! 361: case TK_CONFIG_STRING: { ! 362: char *old, *new; ! 363: ! 364: if (nullValue) { ! 365: new = NULL; ! 366: } else { ! 367: new = (char *) ckalloc((unsigned) (strlen(value) + 1)); ! 368: strcpy(new, value); ! 369: } ! 370: old = *((char **) ptr); ! 371: if (old != NULL) { ! 372: ckfree(old); ! 373: } ! 374: *((char **) ptr) = new; ! 375: break; ! 376: } ! 377: case TK_CONFIG_UID: ! 378: if (nullValue) { ! 379: *((Tk_Uid *) ptr) = NULL; ! 380: } else { ! 381: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); ! 382: *((Tk_Uid *) ptr) = uid; ! 383: } ! 384: break; ! 385: case TK_CONFIG_COLOR: { ! 386: XColor *newPtr, *oldPtr; ! 387: ! 388: if (nullValue) { ! 389: newPtr = NULL; ! 390: } else { ! 391: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); ! 392: newPtr = Tk_GetColor(interp, tkwin, (Colormap) None, uid); ! 393: if (newPtr == NULL) { ! 394: return TCL_ERROR; ! 395: } ! 396: } ! 397: oldPtr = *((XColor **) ptr); ! 398: if (oldPtr != NULL) { ! 399: Tk_FreeColor(oldPtr); ! 400: } ! 401: *((XColor **) ptr) = newPtr; ! 402: break; ! 403: } ! 404: case TK_CONFIG_FONT: { ! 405: XFontStruct *newPtr, *oldPtr; ! 406: ! 407: if (nullValue) { ! 408: newPtr = NULL; ! 409: } else { ! 410: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); ! 411: newPtr = Tk_GetFontStruct(interp, tkwin, uid); ! 412: if (newPtr == NULL) { ! 413: return TCL_ERROR; ! 414: } ! 415: } ! 416: oldPtr = *((XFontStruct **) ptr); ! 417: if (oldPtr != NULL) { ! 418: Tk_FreeFontStruct(oldPtr); ! 419: } ! 420: *((XFontStruct **) ptr) = newPtr; ! 421: break; ! 422: } ! 423: case TK_CONFIG_BITMAP: { ! 424: Pixmap new, old; ! 425: ! 426: if (nullValue) { ! 427: new = None; ! 428: } else { ! 429: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); ! 430: new = Tk_GetBitmap(interp, tkwin, uid); ! 431: if (new == None) { ! 432: return TCL_ERROR; ! 433: } ! 434: } ! 435: old = *((Pixmap *) ptr); ! 436: if (old != None) { ! 437: Tk_FreeBitmap(old); ! 438: } ! 439: *((Pixmap *) ptr) = new; ! 440: break; ! 441: } ! 442: #if defined(USE_XPM3) ! 443: case TK_CONFIG_PIXMAP: { ! 444: Pixmap new, old; ! 445: ! 446: if (nullValue) { ! 447: new = None; ! 448: } else { ! 449: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); ! 450: new = Tk_GetPixmap(interp, tkwin, uid); ! 451: if (new == None) { ! 452: return TCL_ERROR; ! 453: } ! 454: } ! 455: old = *((Pixmap *) ptr); ! 456: if (old != None) { ! 457: Tk_FreePixmap(old); ! 458: } ! 459: *((Pixmap *) ptr) = new; ! 460: break; ! 461: } ! 462: #endif ! 463: case TK_CONFIG_BORDER: { ! 464: Tk_3DBorder new, old; ! 465: ! 466: if (nullValue) { ! 467: new = NULL; ! 468: } else { ! 469: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); ! 470: new = Tk_Get3DBorder(interp, tkwin, (Colormap) None, uid); ! 471: if (new == NULL) { ! 472: return TCL_ERROR; ! 473: } ! 474: } ! 475: old = *((Tk_3DBorder *) ptr); ! 476: if (old != NULL) { ! 477: Tk_Free3DBorder(old); ! 478: } ! 479: *((Tk_3DBorder *) ptr) = new; ! 480: break; ! 481: } ! 482: case TK_CONFIG_RELIEF: ! 483: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); ! 484: if (Tk_GetRelief(interp, uid, (int *) ptr) != TCL_OK) { ! 485: return TCL_ERROR; ! 486: } ! 487: break; ! 488: case TK_CONFIG_CURSOR: ! 489: case TK_CONFIG_ACTIVE_CURSOR: { ! 490: Cursor new, old; ! 491: ! 492: if (nullValue) { ! 493: new = None; ! 494: } else { ! 495: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); ! 496: new = Tk_GetCursor(interp, tkwin, uid); ! 497: if (new == None) { ! 498: return TCL_ERROR; ! 499: } ! 500: } ! 501: old = *((Cursor *) ptr); ! 502: if (old != None) { ! 503: Tk_FreeCursor(old); ! 504: } ! 505: *((Cursor *) ptr) = new; ! 506: if (specPtr->type == TK_CONFIG_ACTIVE_CURSOR) { ! 507: Tk_DefineCursor(tkwin, new); ! 508: } ! 509: break; ! 510: } ! 511: case TK_CONFIG_JUSTIFY: ! 512: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); ! 513: if (Tk_GetJustify(interp, uid, (Tk_Justify *) ptr) != TCL_OK) { ! 514: return TCL_ERROR; ! 515: } ! 516: break; ! 517: case TK_CONFIG_ANCHOR: ! 518: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); ! 519: if (Tk_GetAnchor(interp, uid, (Tk_Anchor *) ptr) != TCL_OK) { ! 520: return TCL_ERROR; ! 521: } ! 522: break; ! 523: case TK_CONFIG_CAP_STYLE: ! 524: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); ! 525: if (Tk_GetCapStyle(interp, uid, (int *) ptr) != TCL_OK) { ! 526: return TCL_ERROR; ! 527: } ! 528: break; ! 529: case TK_CONFIG_JOIN_STYLE: ! 530: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); ! 531: if (Tk_GetJoinStyle(interp, uid, (int *) ptr) != TCL_OK) { ! 532: return TCL_ERROR; ! 533: } ! 534: break; ! 535: case TK_CONFIG_PIXELS: ! 536: if (Tk_GetPixels(interp, tkwin, value, (int *) ptr) ! 537: != TCL_OK) { ! 538: return TCL_ERROR; ! 539: } ! 540: break; ! 541: case TK_CONFIG_MM: ! 542: if (Tk_GetScreenMM(interp, tkwin, value, (double *) ptr) ! 543: != TCL_OK) { ! 544: return TCL_ERROR; ! 545: } ! 546: break; ! 547: case TK_CONFIG_WINDOW: { ! 548: Tk_Window tkwin2; ! 549: ! 550: if (nullValue) { ! 551: tkwin2 = NULL; ! 552: } else { ! 553: tkwin2 = Tk_NameToWindow(interp, value, tkwin); ! 554: if (tkwin2 == NULL) { ! 555: return TCL_ERROR; ! 556: } ! 557: } ! 558: *((Tk_Window *) ptr) = tkwin2; ! 559: break; ! 560: } ! 561: case TK_CONFIG_CUSTOM: ! 562: if ((*specPtr->customPtr->parseProc)( ! 563: specPtr->customPtr->clientData, interp, tkwin, ! 564: value, widgRec, specPtr->offset) != TCL_OK) { ! 565: return TCL_ERROR; ! 566: } ! 567: break; ! 568: default: { ! 569: sprintf(interp->result, "bad config table: unknown type %d", ! 570: specPtr->type); ! 571: return TCL_ERROR; ! 572: } ! 573: } ! 574: specPtr++; ! 575: } while ((specPtr->argvName == NULL) && (specPtr->type != TK_CONFIG_END)); ! 576: return TCL_OK; ! 577: } ! 578: ! 579: /* ! 580: *-------------------------------------------------------------- ! 581: * ! 582: * Tk_ConfigureInfo -- ! 583: * ! 584: * Return information about the configuration options ! 585: * for a window, and their current values. ! 586: * ! 587: * Results: ! 588: * Always returns TCL_OK. Interp->result will be modified ! 589: * hold a description of either a single configuration option ! 590: * available for "widgRec" via "specs", or all the configuration ! 591: * options available. In the "all" case, the result will ! 592: * available for "widgRec" via "specs". The result will ! 593: * be a list, each of whose entries describes one option. ! 594: * Each entry will itself be a list containing the option's ! 595: * name for use on command lines, database name, database ! 596: * class, default value, and current value (empty string ! 597: * if none). For options that are synonyms, the list will ! 598: * contain only two values: name and synonym name. If the ! 599: * "name" argument is non-NULL, then the only information ! 600: * returned is that for the named argument (i.e. the corresponding ! 601: * entry in the overall list is returned). ! 602: * ! 603: * Side effects: ! 604: * None. ! 605: * ! 606: *-------------------------------------------------------------- ! 607: */ ! 608: ! 609: int ! 610: Tk_ConfigureInfo(interp, tkwin, specs, widgRec, argvName, flags) ! 611: Tcl_Interp *interp; /* Interpreter for error reporting. */ ! 612: Tk_Window tkwin; /* Window corresponding to widgRec. */ ! 613: Tk_ConfigSpec *specs; /* Describes legal options. */ ! 614: char *widgRec; /* Record whose fields contain current ! 615: * values for options. */ ! 616: char *argvName; /* If non-NULL, indicates a single option ! 617: * whose info is to be returned. Otherwise ! 618: * info is returned for all options. */ ! 619: int flags; /* Used to specify additional flags ! 620: * that must be present in config specs ! 621: * for them to be considered. */ ! 622: { ! 623: register Tk_ConfigSpec *specPtr; ! 624: int needFlags, hateFlags; ! 625: char *list; ! 626: char *leader = "{"; ! 627: ! 628: needFlags = flags & ~(TK_CONFIG_USER_BIT - 1); ! 629: if (Tk_DefaultDepth(Tk_Screen(tkwin)) == 1) { ! 630: hateFlags = TK_CONFIG_COLOR_ONLY; ! 631: } else { ! 632: hateFlags = TK_CONFIG_MONO_ONLY; ! 633: } ! 634: ! 635: /* ! 636: * If information is only wanted for a single configuration ! 637: * spec, then handle that one spec specially. ! 638: */ ! 639: ! 640: Tcl_SetResult(interp, (char *) NULL, TCL_STATIC); ! 641: if (argvName != NULL) { ! 642: specPtr = FindConfigSpec(interp, specs, argvName, needFlags, ! 643: hateFlags); ! 644: if (specPtr == NULL) { ! 645: return TCL_ERROR; ! 646: } ! 647: interp->result = FormatConfigInfo(tkwin, specPtr, widgRec); ! 648: interp->freeProc = TCL_DYNAMIC; ! 649: return TCL_OK; ! 650: } ! 651: ! 652: /* ! 653: * Loop through all the specs, creating a big list with all ! 654: * their information. ! 655: */ ! 656: ! 657: for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { ! 658: if ((argvName != NULL) && (specPtr->argvName != argvName)) { ! 659: continue; ! 660: } ! 661: if (((specPtr->specFlags & needFlags) != needFlags) ! 662: || (specPtr->specFlags & hateFlags)) { ! 663: continue; ! 664: } ! 665: if (specPtr->argvName == NULL) { ! 666: continue; ! 667: } ! 668: list = FormatConfigInfo(tkwin, specPtr, widgRec); ! 669: Tcl_AppendResult(interp, leader, list, "}", (char *) NULL); ! 670: ckfree(list); ! 671: leader = " {"; ! 672: } ! 673: return TCL_OK; ! 674: } ! 675: ! 676: /* ! 677: *-------------------------------------------------------------- ! 678: * ! 679: * FormatConfigInfo -- ! 680: * ! 681: * Create a valid Tcl list holding the configuration information ! 682: * for a single configuration option. ! 683: * ! 684: * Results: ! 685: * A Tcl list, dynamically allocated. The caller is expected to ! 686: * arrange for this list to be freed eventually. ! 687: * ! 688: * Side effects: ! 689: * Memory is allocated. ! 690: * ! 691: *-------------------------------------------------------------- ! 692: */ ! 693: ! 694: static char * ! 695: FormatConfigInfo(tkwin, specPtr, widgRec) ! 696: Tk_Window tkwin; /* Window corresponding to widget. */ ! 697: register Tk_ConfigSpec *specPtr; /* Pointer to information describing ! 698: * option. */ ! 699: char *widgRec; /* Pointer to record holding current ! 700: * values of info for widget. */ ! 701: { ! 702: char *argv[6], *ptr, *result; ! 703: char buffer[200]; ! 704: Tcl_FreeProc *freeProc = (Tcl_FreeProc *) NULL; ! 705: ! 706: argv[0] = specPtr->argvName; ! 707: argv[1] = specPtr->dbName; ! 708: argv[2] = specPtr->dbClass; ! 709: argv[3] = specPtr->defValue; ! 710: if (specPtr->type == TK_CONFIG_SYNONYM) { ! 711: return Tcl_Merge(2, argv); ! 712: } ! 713: ptr = widgRec + specPtr->offset; ! 714: argv[4] = ""; ! 715: switch (specPtr->type) { ! 716: case TK_CONFIG_BOOLEAN: ! 717: if (*((int *) ptr) == 0) { ! 718: argv[4] = "false"; ! 719: } else { ! 720: argv[4] = "true"; ! 721: } ! 722: break; ! 723: case TK_CONFIG_INT: ! 724: sprintf(buffer, "%d", *((int *) ptr)); ! 725: argv[4] = buffer; ! 726: break; ! 727: case TK_CONFIG_DOUBLE: ! 728: sprintf(buffer, "%g", *((double *) ptr)); ! 729: argv[4] = buffer; ! 730: break; ! 731: case TK_CONFIG_STRING: ! 732: argv[4] = (*(char **) ptr); ! 733: break; ! 734: case TK_CONFIG_UID: { ! 735: Tk_Uid uid = *((Tk_Uid *) ptr); ! 736: if (uid != NULL) { ! 737: argv[4] = uid; ! 738: } ! 739: break; ! 740: } ! 741: case TK_CONFIG_COLOR: { ! 742: XColor *colorPtr = *((XColor **) ptr); ! 743: if (colorPtr != NULL) { ! 744: argv[4] = Tk_NameOfColor(colorPtr); ! 745: } ! 746: break; ! 747: } ! 748: case TK_CONFIG_FONT: { ! 749: XFontStruct *fontStructPtr = *((XFontStruct **) ptr); ! 750: if (fontStructPtr != NULL) { ! 751: argv[4] = Tk_NameOfFontStruct(fontStructPtr); ! 752: } ! 753: break; ! 754: } ! 755: case TK_CONFIG_BITMAP: { ! 756: Pixmap pixmap = *((Pixmap *) ptr); ! 757: if (pixmap != None) { ! 758: argv[4] = Tk_NameOfBitmap(pixmap); ! 759: } ! 760: break; ! 761: } ! 762: #if defined(USE_XPM3) ! 763: case TK_CONFIG_PIXMAP: { ! 764: Pixmap pixmap = *((Pixmap *) ptr); ! 765: if (pixmap != None) { ! 766: argv[4] = Tk_NameOfPixmap(pixmap); ! 767: } ! 768: break; ! 769: } ! 770: #endif ! 771: case TK_CONFIG_BORDER: { ! 772: Tk_3DBorder border = *((Tk_3DBorder *) ptr); ! 773: if (border != NULL) { ! 774: argv[4] = Tk_NameOf3DBorder(border); ! 775: } ! 776: break; ! 777: } ! 778: case TK_CONFIG_RELIEF: ! 779: argv[4] = Tk_NameOfRelief(*((int *) ptr)); ! 780: break; ! 781: case TK_CONFIG_CURSOR: ! 782: case TK_CONFIG_ACTIVE_CURSOR: { ! 783: Cursor cursor = *((Cursor *) ptr); ! 784: if (cursor != None) { ! 785: argv[4] = Tk_NameOfCursor(cursor); ! 786: } ! 787: break; ! 788: } ! 789: case TK_CONFIG_JUSTIFY: ! 790: argv[4] = Tk_NameOfJustify(*((Tk_Justify *) ptr)); ! 791: break; ! 792: case TK_CONFIG_ANCHOR: ! 793: argv[4] = Tk_NameOfAnchor(*((Tk_Anchor *) ptr)); ! 794: break; ! 795: case TK_CONFIG_CAP_STYLE: ! 796: argv[4] = Tk_NameOfCapStyle(*((int *) ptr)); ! 797: break; ! 798: case TK_CONFIG_JOIN_STYLE: ! 799: argv[4] = Tk_NameOfJoinStyle(*((int *) ptr)); ! 800: break; ! 801: case TK_CONFIG_PIXELS: ! 802: sprintf(buffer, "%d", *((int *) ptr)); ! 803: argv[4] = buffer; ! 804: break; ! 805: case TK_CONFIG_MM: ! 806: sprintf(buffer, "%gm", *((int *) ptr)); ! 807: argv[4] = buffer; ! 808: break; ! 809: case TK_CONFIG_WINDOW: { ! 810: Tk_Window tkwin; ! 811: ! 812: tkwin = *((Tk_Window *) ptr); ! 813: if (tkwin != NULL) { ! 814: argv[4] = Tk_PathName(tkwin); ! 815: } ! 816: break; ! 817: } ! 818: case TK_CONFIG_CUSTOM: ! 819: argv[4] = (*specPtr->customPtr->printProc)( ! 820: specPtr->customPtr->clientData, tkwin, widgRec, ! 821: specPtr->offset, &freeProc); ! 822: break; ! 823: default: ! 824: argv[4] = "?? unknown type ??"; ! 825: } ! 826: if (argv[1] == NULL) { ! 827: argv[1] = ""; ! 828: } ! 829: if (argv[2] == NULL) { ! 830: argv[2] = ""; ! 831: } ! 832: if (argv[3] == NULL) { ! 833: argv[3] = ""; ! 834: } ! 835: if (argv[4] == NULL) { ! 836: argv[4] = ""; ! 837: } ! 838: result = Tcl_Merge(5, argv); ! 839: if (freeProc != NULL) { ! 840: if (freeProc == (Tcl_FreeProc *) free) { ! 841: ckfree(argv[4]); ! 842: } else { ! 843: (*freeProc)(argv[4]); ! 844: } ! 845: } ! 846: return result; ! 847: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.