OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [tk/] [generic/] [tkConfig.c] - Blame information for rev 579

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tkConfig.c --
3
 *
4
 *      This file contains the Tk_ConfigureWidget procedure.
5
 *
6
 * Copyright (c) 1990-1994 The Regents of the University of California.
7
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
8
 *
9
 * See the file "license.terms" for information on usage and redistribution
10
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11
 *
12
 * RCS: @(#) $Id: tkConfig.c,v 1.1.1.1 2002-01-16 10:25:51 markom Exp $
13
 */
14
 
15
#include "tkPort.h"
16
#include "tk.h"
17
 
18
/*
19
 * Values for "flags" field of Tk_ConfigSpec structures.  Be sure
20
 * to coordinate these values with those defined in tk.h
21
 * (TK_CONFIG_COLOR_ONLY, etc.).  There must not be overlap!
22
 *
23
 * INIT -               Non-zero means (char *) things have been
24
 *                      converted to Tk_Uid's.
25
 */
26
 
27
#define INIT            0x20
28
 
29
/*
30
 * Forward declarations for procedures defined later in this file:
31
 */
32
 
33
static int              DoConfig _ANSI_ARGS_((Tcl_Interp *interp,
34
                            Tk_Window tkwin, Tk_ConfigSpec *specPtr,
35
                            Tk_Uid value, int valueIsUid, char *widgRec));
36
static Tk_ConfigSpec *  FindConfigSpec _ANSI_ARGS_((Tcl_Interp *interp,
37
                            Tk_ConfigSpec *specs, char *argvName,
38
                            int needFlags, int hateFlags));
39
static char *           FormatConfigInfo _ANSI_ARGS_((Tcl_Interp *interp,
40
                            Tk_Window tkwin, Tk_ConfigSpec *specPtr,
41
                            char *widgRec));
42
static char *           FormatConfigValue _ANSI_ARGS_((Tcl_Interp *interp,
43
                            Tk_Window tkwin, Tk_ConfigSpec *specPtr,
44
                            char *widgRec, char *buffer,
45
                            Tcl_FreeProc **freeProcPtr));
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_Depth(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
    size_t 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, 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
                Tk_Font new;
406
 
407
                if (nullValue) {
408
                    new = NULL;
409
                } else {
410
                    new = Tk_GetFont(interp, tkwin, value);
411
                    if (new == NULL) {
412
                        return TCL_ERROR;
413
                    }
414
                }
415
                Tk_FreeFont(*((Tk_Font *) ptr));
416
                *((Tk_Font *) ptr) = new;
417
                break;
418
            }
419
            case TK_CONFIG_BITMAP: {
420
                Pixmap new, old;
421
 
422
                if (nullValue) {
423
                    new = None;
424
                } else {
425
                    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
426
                    new = Tk_GetBitmap(interp, tkwin, uid);
427
                    if (new == None) {
428
                        return TCL_ERROR;
429
                    }
430
                }
431
                old = *((Pixmap *) ptr);
432
                if (old != None) {
433
                    Tk_FreeBitmap(Tk_Display(tkwin), old);
434
                }
435
                *((Pixmap *) ptr) = new;
436
                break;
437
            }
438
            case TK_CONFIG_BORDER: {
439
                Tk_3DBorder new, old;
440
 
441
                if (nullValue) {
442
                    new = NULL;
443
                } else {
444
                    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
445
                    new = Tk_Get3DBorder(interp, tkwin, uid);
446
                    if (new == NULL) {
447
                        return TCL_ERROR;
448
                    }
449
                }
450
                old = *((Tk_3DBorder *) ptr);
451
                if (old != NULL) {
452
                    Tk_Free3DBorder(old);
453
                }
454
                *((Tk_3DBorder *) ptr) = new;
455
                break;
456
            }
457
            case TK_CONFIG_RELIEF:
458
                uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
459
                if (Tk_GetRelief(interp, uid, (int *) ptr) != TCL_OK) {
460
                    return TCL_ERROR;
461
                }
462
                break;
463
            case TK_CONFIG_CURSOR:
464
            case TK_CONFIG_ACTIVE_CURSOR: {
465
                Tk_Cursor new, old;
466
 
467
                if (nullValue) {
468
                    new = None;
469
                } else {
470
                    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
471
                    new = Tk_GetCursor(interp, tkwin, uid);
472
                    if (new == None) {
473
                        return TCL_ERROR;
474
                    }
475
                }
476
                old = *((Tk_Cursor *) ptr);
477
                if (old != None) {
478
                    Tk_FreeCursor(Tk_Display(tkwin), old);
479
                }
480
                *((Tk_Cursor *) ptr) = new;
481
                if (specPtr->type == TK_CONFIG_ACTIVE_CURSOR) {
482
                    Tk_DefineCursor(tkwin, new);
483
                }
484
                break;
485
            }
486
            case TK_CONFIG_JUSTIFY:
487
                uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
488
                if (Tk_GetJustify(interp, uid, (Tk_Justify *) ptr) != TCL_OK) {
489
                    return TCL_ERROR;
490
                }
491
                break;
492
            case TK_CONFIG_ANCHOR:
493
                uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
494
                if (Tk_GetAnchor(interp, uid, (Tk_Anchor *) ptr) != TCL_OK) {
495
                    return TCL_ERROR;
496
                }
497
                break;
498
            case TK_CONFIG_CAP_STYLE:
499
                uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
500
                if (Tk_GetCapStyle(interp, uid, (int *) ptr) != TCL_OK) {
501
                    return TCL_ERROR;
502
                }
503
                break;
504
            case TK_CONFIG_JOIN_STYLE:
505
                uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
506
                if (Tk_GetJoinStyle(interp, uid, (int *) ptr) != TCL_OK) {
507
                    return TCL_ERROR;
508
                }
509
                break;
510
            case TK_CONFIG_PIXELS:
511
                if (Tk_GetPixels(interp, tkwin, value, (int *) ptr)
512
                        != TCL_OK) {
513
                    return TCL_ERROR;
514
                }
515
                break;
516
            case TK_CONFIG_MM:
517
                if (Tk_GetScreenMM(interp, tkwin, value, (double *) ptr)
518
                        != TCL_OK) {
519
                    return TCL_ERROR;
520
                }
521
                break;
522
            case TK_CONFIG_WINDOW: {
523
                Tk_Window tkwin2;
524
 
525
                if (nullValue) {
526
                    tkwin2 = NULL;
527
                } else {
528
                    tkwin2 = Tk_NameToWindow(interp, value, tkwin);
529
                    if (tkwin2 == NULL) {
530
                        return TCL_ERROR;
531
                    }
532
                }
533
                *((Tk_Window *) ptr) = tkwin2;
534
                break;
535
            }
536
            case TK_CONFIG_CUSTOM:
537
                if ((*specPtr->customPtr->parseProc)(
538
                        specPtr->customPtr->clientData, interp, tkwin,
539
                        value, widgRec, specPtr->offset) != TCL_OK) {
540
                    return TCL_ERROR;
541
                }
542
                break;
543
            default: {
544
                sprintf(interp->result, "bad config table: unknown type %d",
545
                        specPtr->type);
546
                return TCL_ERROR;
547
            }
548
        }
549
        specPtr++;
550
    } while ((specPtr->argvName == NULL) && (specPtr->type != TK_CONFIG_END));
551
    return TCL_OK;
552
}
553
 
554
/*
555
 *--------------------------------------------------------------
556
 *
557
 * Tk_ConfigureInfo --
558
 *
559
 *      Return information about the configuration options
560
 *      for a window, and their current values.
561
 *
562
 * Results:
563
 *      Always returns TCL_OK.  Interp->result will be modified
564
 *      hold a description of either a single configuration option
565
 *      available for "widgRec" via "specs", or all the configuration
566
 *      options available.  In the "all" case, the result will
567
 *      available for "widgRec" via "specs".  The result will
568
 *      be a list, each of whose entries describes one option.
569
 *      Each entry will itself be a list containing the option's
570
 *      name for use on command lines, database name, database
571
 *      class, default value, and current value (empty string
572
 *      if none).  For options that are synonyms, the list will
573
 *      contain only two values:  name and synonym name.  If the
574
 *      "name" argument is non-NULL, then the only information
575
 *      returned is that for the named argument (i.e. the corresponding
576
 *      entry in the overall list is returned).
577
 *
578
 * Side effects:
579
 *      None.
580
 *
581
 *--------------------------------------------------------------
582
 */
583
 
584
int
585
Tk_ConfigureInfo(interp, tkwin, specs, widgRec, argvName, flags)
586
    Tcl_Interp *interp;         /* Interpreter for error reporting. */
587
    Tk_Window tkwin;            /* Window corresponding to widgRec. */
588
    Tk_ConfigSpec *specs;       /* Describes legal options. */
589
    char *widgRec;              /* Record whose fields contain current
590
                                 * values for options. */
591
    char *argvName;             /* If non-NULL, indicates a single option
592
                                 * whose info is to be returned.  Otherwise
593
                                 * info is returned for all options. */
594
    int flags;                  /* Used to specify additional flags
595
                                 * that must be present in config specs
596
                                 * for them to be considered. */
597
{
598
    register Tk_ConfigSpec *specPtr;
599
    int needFlags, hateFlags;
600
    char *list;
601
    char *leader = "{";
602
 
603
    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
604
    if (Tk_Depth(tkwin) <= 1) {
605
        hateFlags = TK_CONFIG_COLOR_ONLY;
606
    } else {
607
        hateFlags = TK_CONFIG_MONO_ONLY;
608
    }
609
 
610
    /*
611
     * If information is only wanted for a single configuration
612
     * spec, then handle that one spec specially.
613
     */
614
 
615
    Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
616
    if (argvName != NULL) {
617
        specPtr = FindConfigSpec(interp, specs, argvName, needFlags,
618
                hateFlags);
619
        if (specPtr == NULL) {
620
            return TCL_ERROR;
621
        }
622
        interp->result = FormatConfigInfo(interp, tkwin, specPtr, widgRec);
623
        interp->freeProc = TCL_DYNAMIC;
624
        return TCL_OK;
625
    }
626
 
627
    /*
628
     * Loop through all the specs, creating a big list with all
629
     * their information.
630
     */
631
 
632
    for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
633
        if ((argvName != NULL) && (specPtr->argvName != argvName)) {
634
            continue;
635
        }
636
        if (((specPtr->specFlags & needFlags) != needFlags)
637
                || (specPtr->specFlags & hateFlags)) {
638
            continue;
639
        }
640
        if (specPtr->argvName == NULL) {
641
            continue;
642
        }
643
        list = FormatConfigInfo(interp, tkwin, specPtr, widgRec);
644
        Tcl_AppendResult(interp, leader, list, "}", (char *) NULL);
645
        ckfree(list);
646
        leader = " {";
647
    }
648
    return TCL_OK;
649
}
650
 
651
/*
652
 *--------------------------------------------------------------
653
 *
654
 * FormatConfigInfo --
655
 *
656
 *      Create a valid Tcl list holding the configuration information
657
 *      for a single configuration option.
658
 *
659
 * Results:
660
 *      A Tcl list, dynamically allocated.  The caller is expected to
661
 *      arrange for this list to be freed eventually.
662
 *
663
 * Side effects:
664
 *      Memory is allocated.
665
 *
666
 *--------------------------------------------------------------
667
 */
668
 
669
static char *
670
FormatConfigInfo(interp, tkwin, specPtr, widgRec)
671
    Tcl_Interp *interp;                 /* Interpreter to use for things
672
                                         * like floating-point precision. */
673
    Tk_Window tkwin;                    /* Window corresponding to widget. */
674
    register Tk_ConfigSpec *specPtr;    /* Pointer to information describing
675
                                         * option. */
676
    char *widgRec;                      /* Pointer to record holding current
677
                                         * values of info for widget. */
678
{
679
    char *argv[6], *result;
680
    char buffer[200];
681
    Tcl_FreeProc *freeProc = (Tcl_FreeProc *) NULL;
682
 
683
    argv[0] = specPtr->argvName;
684
    argv[1] = specPtr->dbName;
685
    argv[2] = specPtr->dbClass;
686
    argv[3] = specPtr->defValue;
687
    if (specPtr->type == TK_CONFIG_SYNONYM) {
688
        return Tcl_Merge(2, argv);
689
    }
690
    argv[4] = FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer,
691
            &freeProc);
692
    if (argv[1] == NULL) {
693
        argv[1] = "";
694
    }
695
    if (argv[2] == NULL) {
696
        argv[2] = "";
697
    }
698
    if (argv[3] == NULL) {
699
        argv[3] = "";
700
    }
701
    if (argv[4] == NULL) {
702
        argv[4] = "";
703
    }
704
    result = Tcl_Merge(5, argv);
705
    if (freeProc != NULL) {
706
        if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) {
707
            ckfree(argv[4]);
708
        } else {
709
            (*freeProc)(argv[4]);
710
        }
711
    }
712
    return result;
713
}
714
 
715
/*
716
 *----------------------------------------------------------------------
717
 *
718
 * FormatConfigValue --
719
 *
720
 *      This procedure formats the current value of a configuration
721
 *      option.
722
 *
723
 * Results:
724
 *      The return value is the formatted value of the option given
725
 *      by specPtr and widgRec.  If the value is static, so that it
726
 *      need not be freed, *freeProcPtr will be set to NULL;  otherwise
727
 *      *freeProcPtr will be set to the address of a procedure to
728
 *      free the result, and the caller must invoke this procedure
729
 *      when it is finished with the result.
730
 *
731
 * Side effects:
732
 *      None.
733
 *
734
 *----------------------------------------------------------------------
735
 */
736
 
737
static char *
738
FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer, freeProcPtr)
739
    Tcl_Interp *interp;         /* Interpreter for use in real conversions. */
740
    Tk_Window tkwin;            /* Window corresponding to widget. */
741
    Tk_ConfigSpec *specPtr;     /* Pointer to information describing option.
742
                                 * Must not point to a synonym option. */
743
    char *widgRec;              /* Pointer to record holding current
744
                                 * values of info for widget. */
745
    char *buffer;               /* Static buffer to use for small values.
746
                                 * Must have at least 200 bytes of storage. */
747
    Tcl_FreeProc **freeProcPtr; /* Pointer to word to fill in with address
748
                                 * of procedure to free the result, or NULL
749
                                 * if result is static. */
750
{
751
    char *ptr, *result;
752
 
753
    *freeProcPtr = NULL;
754
    ptr = widgRec + specPtr->offset;
755
    result = "";
756
    switch (specPtr->type) {
757
        case TK_CONFIG_BOOLEAN:
758
            if (*((int *) ptr) == 0) {
759
                result = "0";
760
            } else {
761
                result = "1";
762
            }
763
            break;
764
        case TK_CONFIG_INT:
765
            sprintf(buffer, "%d", *((int *) ptr));
766
            result = buffer;
767
            break;
768
        case TK_CONFIG_DOUBLE:
769
            Tcl_PrintDouble(interp, *((double *) ptr), buffer);
770
            result = buffer;
771
            break;
772
        case TK_CONFIG_STRING:
773
            result = (*(char **) ptr);
774
            if (result == NULL) {
775
                result = "";
776
            }
777
            break;
778
        case TK_CONFIG_UID: {
779
            Tk_Uid uid = *((Tk_Uid *) ptr);
780
            if (uid != NULL) {
781
                result = uid;
782
            }
783
            break;
784
        }
785
        case TK_CONFIG_COLOR: {
786
            XColor *colorPtr = *((XColor **) ptr);
787
            if (colorPtr != NULL) {
788
                result = Tk_NameOfColor(colorPtr);
789
            }
790
            break;
791
        }
792
        case TK_CONFIG_FONT: {
793
            Tk_Font tkfont = *((Tk_Font *) ptr);
794
            if (tkfont != NULL) {
795
                result = Tk_NameOfFont(tkfont);
796
            }
797
            break;
798
        }
799
        case TK_CONFIG_BITMAP: {
800
            Pixmap pixmap = *((Pixmap *) ptr);
801
            if (pixmap != None) {
802
                result = Tk_NameOfBitmap(Tk_Display(tkwin), pixmap);
803
            }
804
            break;
805
        }
806
        case TK_CONFIG_BORDER: {
807
            Tk_3DBorder border = *((Tk_3DBorder *) ptr);
808
            if (border != NULL) {
809
                result = Tk_NameOf3DBorder(border);
810
            }
811
            break;
812
        }
813
        case TK_CONFIG_RELIEF:
814
            result = Tk_NameOfRelief(*((int *) ptr));
815
            break;
816
        case TK_CONFIG_CURSOR:
817
        case TK_CONFIG_ACTIVE_CURSOR: {
818
            Tk_Cursor cursor = *((Tk_Cursor *) ptr);
819
            if (cursor != None) {
820
                result = Tk_NameOfCursor(Tk_Display(tkwin), cursor);
821
            }
822
            break;
823
        }
824
        case TK_CONFIG_JUSTIFY:
825
            result = Tk_NameOfJustify(*((Tk_Justify *) ptr));
826
            break;
827
        case TK_CONFIG_ANCHOR:
828
            result = Tk_NameOfAnchor(*((Tk_Anchor *) ptr));
829
            break;
830
        case TK_CONFIG_CAP_STYLE:
831
            result = Tk_NameOfCapStyle(*((int *) ptr));
832
            break;
833
        case TK_CONFIG_JOIN_STYLE:
834
            result = Tk_NameOfJoinStyle(*((int *) ptr));
835
            break;
836
        case TK_CONFIG_PIXELS:
837
            sprintf(buffer, "%d", *((int *) ptr));
838
            result = buffer;
839
            break;
840
        case TK_CONFIG_MM:
841
            Tcl_PrintDouble(interp, *((double *) ptr), buffer);
842
            result = buffer;
843
            break;
844
        case TK_CONFIG_WINDOW: {
845
            Tk_Window tkwin;
846
 
847
            tkwin = *((Tk_Window *) ptr);
848
            if (tkwin != NULL) {
849
                result = Tk_PathName(tkwin);
850
            }
851
            break;
852
        }
853
        case TK_CONFIG_CUSTOM:
854
            result = (*specPtr->customPtr->printProc)(
855
                    specPtr->customPtr->clientData, tkwin, widgRec,
856
                    specPtr->offset, freeProcPtr);
857
            break;
858
        default:
859
            result = "?? unknown type ??";
860
    }
861
    return result;
862
}
863
 
864
/*
865
 *----------------------------------------------------------------------
866
 *
867
 * Tk_ConfigureValue --
868
 *
869
 *      This procedure returns the current value of a configuration
870
 *      option for a widget.
871
 *
872
 * Results:
873
 *      The return value is a standard Tcl completion code (TCL_OK or
874
 *      TCL_ERROR).  Interp->result will be set to hold either the value
875
 *      of the option given by argvName (if TCL_OK is returned) or
876
 *      an error message (if TCL_ERROR is returned).
877
 *
878
 * Side effects:
879
 *      None.
880
 *
881
 *----------------------------------------------------------------------
882
 */
883
 
884
int
885
Tk_ConfigureValue(interp, tkwin, specs, widgRec, argvName, flags)
886
    Tcl_Interp *interp;         /* Interpreter for error reporting. */
887
    Tk_Window tkwin;            /* Window corresponding to widgRec. */
888
    Tk_ConfigSpec *specs;       /* Describes legal options. */
889
    char *widgRec;              /* Record whose fields contain current
890
                                 * values for options. */
891
    char *argvName;             /* Gives the command-line name for the
892
                                 * option whose value is to be returned. */
893
    int flags;                  /* Used to specify additional flags
894
                                 * that must be present in config specs
895
                                 * for them to be considered. */
896
{
897
    Tk_ConfigSpec *specPtr;
898
    int needFlags, hateFlags;
899
 
900
    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
901
    if (Tk_Depth(tkwin) <= 1) {
902
        hateFlags = TK_CONFIG_COLOR_ONLY;
903
    } else {
904
        hateFlags = TK_CONFIG_MONO_ONLY;
905
    }
906
    specPtr = FindConfigSpec(interp, specs, argvName, needFlags, hateFlags);
907
    if (specPtr == NULL) {
908
        return TCL_ERROR;
909
    }
910
    interp->result = FormatConfigValue(interp, tkwin, specPtr, widgRec,
911
            interp->result, &interp->freeProc);
912
    return TCL_OK;
913
}
914
 
915
/*
916
 *----------------------------------------------------------------------
917
 *
918
 * Tk_FreeOptions --
919
 *
920
 *      Free up all resources associated with configuration options.
921
 *
922
 * Results:
923
 *      None.
924
 *
925
 * Side effects:
926
 *      Any resource in widgRec that is controlled by a configuration
927
 *      option (e.g. a Tk_3DBorder or XColor) is freed in the appropriate
928
 *      fashion.
929
 *
930
 *----------------------------------------------------------------------
931
 */
932
 
933
        /* ARGSUSED */
934
void
935
Tk_FreeOptions(specs, widgRec, display, needFlags)
936
    Tk_ConfigSpec *specs;       /* Describes legal options. */
937
    char *widgRec;              /* Record whose fields contain current
938
                                 * values for options. */
939
    Display *display;           /* X display; needed for freeing some
940
                                 * resources. */
941
    int needFlags;              /* Used to specify additional flags
942
                                 * that must be present in config specs
943
                                 * for them to be considered. */
944
{
945
    register Tk_ConfigSpec *specPtr;
946
    char *ptr;
947
 
948
    for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
949
        if ((specPtr->specFlags & needFlags) != needFlags) {
950
            continue;
951
        }
952
        ptr = widgRec + specPtr->offset;
953
        switch (specPtr->type) {
954
            case TK_CONFIG_STRING:
955
                if (*((char **) ptr) != NULL) {
956
                    ckfree(*((char **) ptr));
957
                    *((char **) ptr) = NULL;
958
                }
959
                break;
960
            case TK_CONFIG_COLOR:
961
                if (*((XColor **) ptr) != NULL) {
962
                    Tk_FreeColor(*((XColor **) ptr));
963
                    *((XColor **) ptr) = NULL;
964
                }
965
                break;
966
            case TK_CONFIG_FONT:
967
                Tk_FreeFont(*((Tk_Font *) ptr));
968
                *((Tk_Font *) ptr) = NULL;
969
                break;
970
            case TK_CONFIG_BITMAP:
971
                if (*((Pixmap *) ptr) != None) {
972
                    Tk_FreeBitmap(display, *((Pixmap *) ptr));
973
                    *((Pixmap *) ptr) = None;
974
                }
975
                break;
976
            case TK_CONFIG_BORDER:
977
                if (*((Tk_3DBorder *) ptr) != NULL) {
978
                    Tk_Free3DBorder(*((Tk_3DBorder *) ptr));
979
                    *((Tk_3DBorder *) ptr) = NULL;
980
                }
981
                break;
982
            case TK_CONFIG_CURSOR:
983
            case TK_CONFIG_ACTIVE_CURSOR:
984
                if (*((Tk_Cursor *) ptr) != None) {
985
                    Tk_FreeCursor(display, *((Tk_Cursor *) ptr));
986
                    *((Tk_Cursor *) ptr) = None;
987
                }
988
        }
989
    }
990
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.