Annotation of micropolis/src/tk/tkconfig.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.