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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [insight/] [tix/] [generic/] [tixDiStyle.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tixDiStyle.c --
3
 *
4
 *      This file implements the "Display Item Styles" in the Tix library.
5
 *
6
 * Copyright (c) 1996, Expert Interface Technologies
7
 *
8
 * See the file "license.terms" for information on usage and redistribution
9
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10
 *
11
 *
12
 */
13
 
14
#include <tixPort.h>
15
#include <tixInt.h>
16
 
17
typedef struct StyleLink {
18
    Tix_DItemInfo * diTypePtr;
19
    Tix_DItemStyle* stylePtr;
20
    struct StyleLink * next;
21
} StyleLink;
22
 
23
typedef struct StyleInfo {
24
    Tix_StyleTemplate * tmplPtr;
25
    Tix_StyleTemplate tmpl;
26
    StyleLink * linkHead;
27
} StyleInfo;
28
 
29
 
30
static int              DItemStyleParseProc _ANSI_ARGS_((ClientData clientData,
31
                            Tcl_Interp *interp, Tk_Window tkwin,
32
                            char *value,char *widRec, int offset));
33
static char *           DItemStylePrintProc _ANSI_ARGS_((
34
                            ClientData clientData, Tk_Window tkwin,
35
                            char *widRec, int offset,
36
                            Tcl_FreeProc **freeProcPtr));
37
static Tix_DItemStyle*  FindDefaultStyle _ANSI_ARGS_((
38
                            Tix_DItemInfo * diTypePtr, Tk_Window tkwin));
39
static Tix_DItemStyle*  FindStyle _ANSI_ARGS_((
40
                            char *styleName));
41
static Tix_DItemStyle*  GetDItemStyle  _ANSI_ARGS_((
42
                            Tix_DispData * ddPtr, Tix_DItemInfo * diTypePtr,
43
                            char * styleName, int *isNew_ret));
44
static void             InitHashTables _ANSI_ARGS_((void));
45
static void             ListAdd _ANSI_ARGS_((Tix_DItemStyle * stylePtr,
46
                            Tix_DItem *iPtr));
47
static void             ListDelete _ANSI_ARGS_((Tix_DItemStyle * stylePtr,
48
                            Tix_DItem *iPtr));
49
static void             ListDeleteAll _ANSI_ARGS_((Tix_DItemStyle * stylePtr));
50
static void             StyleCmdDeletedProc _ANSI_ARGS_((
51
                            ClientData clientData));
52
static int              StyleCmd _ANSI_ARGS_((ClientData clientData,
53
                            Tcl_Interp *interp, int argc, char **argv));
54
static int              StyleConfigure _ANSI_ARGS_((Tcl_Interp *interp,
55
                            Tix_DItemStyle* stylePtr, int argc,
56
                            char **argv, int flags));
57
static void             StyleDestroy _ANSI_ARGS_((ClientData clientData));
58
static void             DeleteStyle _ANSI_ARGS_((Tix_DItemStyle * stylePtr));
59
static void             DefWindowStructureProc _ANSI_ARGS_((
60
                            ClientData clientData, XEvent *eventPtr));
61
static void             RefWindowStructureProc _ANSI_ARGS_((
62
                            ClientData clientData, XEvent *eventPtr));
63
static void             SetDefaultStyle _ANSI_ARGS_((Tix_DItemInfo *diTypePtr,
64
                            Tk_Window tkwin, Tix_DItemStyle * stylePtr));
65
 
66
static TIX_DECLARE_SUBCMD(StyleConfigCmd);
67
static TIX_DECLARE_SUBCMD(StyleCGetCmd);
68
static TIX_DECLARE_SUBCMD(StyleDeleteCmd);
69
 
70
static Tcl_HashTable styleTable;
71
static Tcl_HashTable defaultTable;
72
static int tableInited = 0;
73
 
74
 
75
/*
76
 *--------------------------------------------------------------
77
 *
78
 * TixDItemStyleFree --
79
 *
80
 *      When an item does not need a style anymore (when the item
81
 *      is destroyed, e.g.), it must call this procedute to free the
82
 *      style).
83
 *
84
 * Results:
85
 *      Nothing
86
 *
87
 * Side effects:
88
 *      The item is freed from the list of attached items in the style.
89
 *      Also, the style will be freed if it was already destroyed and
90
 *      it has no more items attached to it.
91
 *
92
 *--------------------------------------------------------------
93
 */
94
void TixDItemStyleFree(iPtr, stylePtr)
95
    Tix_DItem *iPtr;
96
    Tix_DItemStyle * stylePtr;
97
{
98
    ListDelete(stylePtr, iPtr);
99
}
100
 
101
/*
102
 *--------------------------------------------------------------
103
 *
104
 * Tix_ItemStyleCmd --
105
 *
106
 *      This procedure is invoked to process the "tixItemStyle" Tcl
107
 *      command.
108
 *
109
 * Results:
110
 *      A standard Tcl result.
111
 *
112
 * Side effects:
113
 *      A new widget is created and configured.
114
 *
115
 *--------------------------------------------------------------
116
 */
117
int
118
Tix_ItemStyleCmd(clientData, interp, argc, argv)
119
    ClientData clientData;
120
    Tcl_Interp *interp;         /* Current interpreter. */
121
    int argc;                   /* Number of arguments. */
122
    char **argv;                /* Argument strings. */
123
{
124
    Tix_DItemInfo * diTypePtr;
125
    Tk_Window tkwin = (Tk_Window)clientData;
126
    char * styleName = NULL;
127
    Tix_DispData dispData;
128
    char buff[100];
129
    int i, n;
130
    static int counter = 0;
131
    Tix_DItemStyle * stylePtr;
132
 
133
    if (tableInited == 0) {
134
        InitHashTables();
135
    }
136
 
137
    if (argc < 2) {
138
        return Tix_ArgcError(interp, argc, argv, 1,
139
            "itemtype ?option value ...");
140
    }
141
 
142
    if ((diTypePtr=Tix_GetDItemType(interp, argv[1])) == NULL) {
143
        return TCL_ERROR;
144
    }
145
 
146
    /*
147
     * Parse the -refwindow option: this tells the style to use this
148
     * window to query the default values for background, foreground
149
     * etc. Usually, you should set the -refwindow to the window that
150
     * holds the display items which are controlled by this style.
151
     */
152
    if (argc > 2) {
153
        size_t len;
154
        if (argc %2 != 0) {
155
            Tcl_AppendResult(interp, "value for \"", argv[argc-1],
156
                "\" missing", NULL);
157
            return TCL_ERROR;
158
        }
159
        for (n=i=2; i<argc; i+=2) {
160
            len = strlen(argv[i]);
161
            if (strncmp(argv[i], "-refwindow", len) == 0) {
162
                if ((tkwin=Tk_NameToWindow(interp,argv[i+1],tkwin)) == NULL) {
163
                    return TCL_ERROR;
164
                }
165
                continue;
166
            }
167
            if (strncmp(argv[i], "-stylename", len) == 0) {
168
                styleName = argv[i+1];
169
                if (FindStyle(styleName) != NULL) {
170
                    Tcl_AppendResult(interp, "style \"", argv[i+1],
171
                        "\" already exist", NULL);
172
                    return TCL_ERROR;
173
                }
174
                continue;
175
            }
176
 
177
            if (n!=i) {
178
                argv[n]   = argv[i];
179
                argv[n+1] = argv[i+1];
180
            }
181
            n+=2;
182
        }
183
        argc = n;
184
    }
185
 
186
    if (styleName == NULL) {
187
        /*
188
         * No name is given, we'll make a unique name by default
189
         * (ToDo: check if the name has already been used)
190
         */
191
        sprintf(buff, "tixStyle%d", counter++);
192
        styleName = buff;
193
    }
194
 
195
    dispData.interp  = interp;
196
    dispData.display = Tk_Display(tkwin);
197
    dispData.tkwin   = tkwin;
198
 
199
    if ((stylePtr = GetDItemStyle(&dispData, diTypePtr,
200
         styleName, NULL)) == NULL) {
201
        return TCL_ERROR;
202
    }
203
    if (StyleConfigure(interp, stylePtr, argc-2, argv+2, 0) != TCL_OK) {
204
        DeleteStyle(stylePtr);
205
        return TCL_ERROR;
206
    }
207
    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
208
            RefWindowStructureProc, (ClientData)stylePtr);
209
 
210
    Tcl_ResetResult(interp);
211
    Tcl_AppendResult(interp, styleName, NULL);
212
    return TCL_OK;
213
}
214
 
215
static int
216
StyleCmd(clientData, interp, argc, argv)
217
    ClientData clientData;
218
    Tcl_Interp *interp;
219
    int argc;
220
    char **argv;
221
{
222
    int code;
223
 
224
    static Tix_SubCmdInfo subCmdInfo[] = {
225
        {TIX_DEFAULT_LEN, "cget", 1, 1, StyleCGetCmd,
226
           "option"},
227
        {TIX_DEFAULT_LEN, "configure", 0, TIX_VAR_ARGS, StyleConfigCmd,
228
           "?option? ?value? ?option value ... ?"},
229
        {TIX_DEFAULT_LEN, "delete", 0, 0, StyleDeleteCmd,
230
           ""},
231
    };
232
 
233
    static Tix_CmdInfo cmdInfo = {
234
        Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? arg ?arg ...?",
235
    };
236
 
237
    Tk_Preserve(clientData);
238
    code = Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
239
        interp, argc, argv);
240
    Tk_Release(clientData);
241
 
242
    return code;
243
}
244
 
245
/*----------------------------------------------------------------------
246
 * "cget" sub command
247
 *----------------------------------------------------------------------
248
 */
249
static int
250
StyleCGetCmd(clientData, interp, argc, argv)
251
    ClientData clientData;
252
    Tcl_Interp *interp;         /* Current interpreter. */
253
    int argc;                   /* Number of arguments. */
254
    char **argv;                /* Argument strings. */
255
{
256
    Tix_DItemStyle* stylePtr= (Tix_DItemStyle*) clientData;
257
 
258
    return Tk_ConfigureValue(interp, stylePtr->base.tkwin,
259
        stylePtr->base.diTypePtr->styleConfigSpecs,
260
        (char *)stylePtr, argv[0], 0);
261
}
262
 
263
/*----------------------------------------------------------------------
264
 * "configure" sub command
265
 *----------------------------------------------------------------------
266
 */
267
static int
268
StyleConfigCmd(clientData, interp, argc, argv)
269
    ClientData clientData;
270
    Tcl_Interp *interp;         /* Current interpreter. */
271
    int argc;                   /* Number of arguments. */
272
    char **argv;                /* Argument strings. */
273
{
274
    Tix_DItemStyle* stylePtr= (Tix_DItemStyle*) clientData;
275
 
276
    if (argc == 0) {
277
        return Tk_ConfigureInfo(interp, stylePtr->base.tkwin,
278
            stylePtr->base.diTypePtr->styleConfigSpecs,
279
            (char *)stylePtr, (char *) NULL, 0);
280
    } else if (argc == 1) {
281
        return Tk_ConfigureInfo(interp, stylePtr->base.tkwin,
282
            stylePtr->base.diTypePtr->styleConfigSpecs,
283
            (char *)stylePtr, argv[0], 0);
284
    } else {
285
        return StyleConfigure(interp, stylePtr, argc, argv,
286
            TK_CONFIG_ARGV_ONLY);
287
    }
288
}
289
 
290
/*----------------------------------------------------------------------
291
 * "delete" sub command
292
 *----------------------------------------------------------------------
293
 */
294
static int
295
StyleDeleteCmd(clientData, interp, argc, argv)
296
    ClientData clientData;
297
    Tcl_Interp *interp;         /* Current interpreter. */
298
    int argc;                   /* Number of arguments. */
299
    char **argv;                /* Argument strings. */
300
{
301
    Tix_DItemStyle* stylePtr= (Tix_DItemStyle*) clientData;
302
 
303
    if (stylePtr->base.flags & TIX_STYLE_DEFAULT) {
304
        Tcl_AppendResult(interp, "Cannot delete default item style",
305
            NULL);
306
        return TCL_ERROR;
307
    }
308
 
309
    DeleteStyle(stylePtr);
310
    return TCL_OK;
311
}
312
 
313
static int
314
StyleConfigure(interp, stylePtr, argc, argv, flags)
315
    Tcl_Interp *interp;         /* Used for error reporting. */
316
    Tix_DItemStyle* stylePtr;   /* Information about the style;  may or may
317
                                 * not already have values for some fields. */
318
    int argc;                   /* Number of valid entries in argv. */
319
    char **argv;                /* Arguments. */
320
    int flags;                  /* Flags to pass to Tk_ConfigureWidget. */
321
{
322
    Tix_DItemInfo * diTypePtr = stylePtr->base.diTypePtr;
323
 
324
    if (diTypePtr->styleConfigureProc(stylePtr, argc, argv, flags) != TCL_OK) {
325
        return TCL_ERROR;
326
    }
327
    return TCL_OK;
328
}
329
 
330
/*----------------------------------------------------------------------
331
 * StyleDestroy --
332
 *
333
 *      Destroy a display style.
334
 *----------------------------------------------------------------------
335
 */
336
static void
337
StyleDestroy(clientData)
338
    ClientData clientData;
339
{
340
    Tix_DItemStyle* stylePtr= (Tix_DItemStyle*) clientData;
341
 
342
    if ((stylePtr->base.flags & TIX_STYLE_DEFAULT)) {
343
        /*
344
         * If this is the default style for the display items, we
345
         * can't tell the display items that it has lost its style,
346
         * otherwise the ditem will just attempt to create the default
347
         * style again, and we will go into an infinite loop
348
         */
349
        if (stylePtr->base.refCount != 0) {
350
            /*
351
             * If the refcount is not zero, this style will NOT be
352
             * destroyed.  The real destroy will be triggered if all
353
             * DItems associated with this style is destroyed (in the
354
             * ListDelete() function).
355
             *
356
             * If a widget is destroyed, it is the responsibility of the
357
             * widget writer to delete all DItems associated with this
358
             * widget. We can discover memory leak if the widget is
359
             * destroyed but some default styles associated with it still
360
             * exist
361
             */
362
            return;
363
        }
364
    } else {
365
        stylePtr->base.refCount = 0;
366
    }
367
 
368
    Tcl_DeleteHashTable(&stylePtr->base.items);
369
    ckfree((char*)stylePtr->base.name);
370
    stylePtr->base.diTypePtr->styleFreeProc(stylePtr);
371
}
372
 
373
static void
374
StyleCmdDeletedProc(clientData)
375
    ClientData clientData;
376
{
377
    Tix_DItemStyle * stylePtr = (Tix_DItemStyle *)clientData;
378
 
379
    stylePtr->base.styleCmd = NULL;
380
    if (stylePtr->base.flags & TIX_STYLE_DEFAULT) {
381
        /*
382
         * Don't do anything
383
         * ToDo: maybe should give a background warning:
384
         */
385
    } else {
386
        DeleteStyle(stylePtr);
387
    }
388
}
389
 
390
static void
391
DeleteStyle(stylePtr)
392
    Tix_DItemStyle * stylePtr;
393
{
394
    Tcl_HashEntry * hashPtr;
395
 
396
    if (!(stylePtr->base.flags & TIX_STYLE_DELETED)) {
397
        stylePtr->base.flags |= TIX_STYLE_DELETED;
398
 
399
        if (stylePtr->base.styleCmd != NULL) {
400
            Tcl_DeleteCommand(stylePtr->base.interp,
401
                Tcl_GetCommandName(stylePtr->base.interp,
402
                stylePtr->base.styleCmd));
403
        }
404
        hashPtr=Tcl_FindHashEntry(&styleTable, stylePtr->base.name);
405
        if (hashPtr != NULL) {
406
            Tcl_DeleteHashEntry(hashPtr);
407
        }
408
        ListDeleteAll(stylePtr);
409
 
410
        Tk_EventuallyFree((ClientData)stylePtr, (Tix_FreeProc *)StyleDestroy);
411
    }
412
}
413
 
414
/*
415
 *----------------------------------------------------------------------
416
 * FindDefaultStyle --
417
 *
418
 *      Return the default style of the given type of ditem for the
419
 *      given tkwin, if such a default style exists.
420
 *
421
 * Results:
422
 *      Pointer to the default style or NULL.
423
 *
424
 * Side effects:
425
 *      None.
426
 *----------------------------------------------------------------------
427
 */
428
 
429
static Tix_DItemStyle*
430
FindDefaultStyle(diTypePtr, tkwin)
431
    Tix_DItemInfo * diTypePtr;
432
    Tk_Window tkwin;
433
{
434
    Tcl_HashEntry *hashPtr;
435
    StyleInfo * infoPtr;
436
    StyleLink * linkPtr;
437
 
438
    if (tableInited == 0) {
439
        InitHashTables();
440
    }
441
    if ((hashPtr=Tcl_FindHashEntry(&defaultTable, (char*)tkwin)) == NULL) {
442
        return NULL;
443
    }
444
    infoPtr = (StyleInfo *)Tcl_GetHashValue(hashPtr);
445
    for (linkPtr = infoPtr->linkHead; linkPtr; linkPtr=linkPtr->next) {
446
        if (linkPtr->diTypePtr == diTypePtr) {
447
            return linkPtr->stylePtr;
448
        }
449
    }
450
    return NULL;
451
}
452
 
453
static void SetDefaultStyle(diTypePtr, tkwin, stylePtr)
454
    Tix_DItemInfo * diTypePtr;
455
    Tk_Window tkwin;
456
    Tix_DItemStyle * stylePtr;
457
{
458
    Tcl_HashEntry *hashPtr;
459
    StyleInfo * infoPtr;
460
    StyleLink * newPtr;
461
    int isNew;
462
 
463
    if (tableInited == 0) {
464
        InitHashTables();
465
    }
466
 
467
    newPtr = (StyleLink *)ckalloc(sizeof(StyleLink));
468
    newPtr->diTypePtr = diTypePtr;
469
    newPtr->stylePtr  = stylePtr;
470
 
471
    hashPtr = Tcl_CreateHashEntry(&defaultTable, (char*)tkwin, &isNew);
472
 
473
    if (!isNew) {
474
        infoPtr = (StyleInfo *)Tcl_GetHashValue(hashPtr);
475
        if (infoPtr->tmplPtr) {
476
            if (diTypePtr->styleSetTemplateProc != NULL) {
477
                diTypePtr->styleSetTemplateProc(stylePtr,
478
                    infoPtr->tmplPtr);
479
            }
480
        }
481
    } else {
482
        infoPtr = (StyleInfo *)ckalloc(sizeof(StyleInfo));
483
        infoPtr->linkHead = NULL;
484
        infoPtr->tmplPtr  = NULL;
485
 
486
        Tk_CreateEventHandler(tkwin, StructureNotifyMask,
487
            DefWindowStructureProc, (ClientData)tkwin);
488
        Tcl_SetHashValue(hashPtr, (char*)infoPtr);
489
    }
490
    newPtr->next = infoPtr->linkHead;
491
    infoPtr->linkHead = newPtr;
492
}
493
 
494
/*
495
 *----------------------------------------------------------------------
496
 * TixGetDefaultDItemStyle --
497
 *
498
 *      Gets the default style for an item if the application doesn't
499
 *      explicitly give it an style with the -style switch.
500
 *
501
 * Results:
502
 *      The default style.
503
 *
504
 * Side effects:
505
 *
506
 *----------------------------------------------------------------------
507
 */
508
 
509
Tix_DItemStyle*
510
TixGetDefaultDItemStyle(ddPtr, diTypePtr, iPtr, oldStylePtr)
511
    Tix_DispData * ddPtr;               /* Info about the display. */
512
    Tix_DItemInfo * diTypePtr;          /* Info about the DItem type. */
513
    Tix_DItem *iPtr;                    /* Get default style for this DItem. */
514
    Tix_DItemStyle* oldStylePtr;        /* ?? */
515
{
516
    Tcl_DString dString;
517
    Tix_DItemStyle* stylePtr;
518
    int isNew;
519
 
520
    if (tableInited  == 0) {
521
        InitHashTables();
522
    }
523
 
524
    stylePtr = FindDefaultStyle(diTypePtr, ddPtr->tkwin);
525
    if (stylePtr == NULL) {
526
        /*
527
         * Format default name for this style+window
528
         */
529
        Tcl_DStringInit(&dString);
530
        Tcl_DStringAppend(&dString, "style", 5);
531
        Tcl_DStringAppend(&dString, Tk_PathName(ddPtr->tkwin),
532
            strlen(Tk_PathName(ddPtr->tkwin)));
533
        Tcl_DStringAppend(&dString, ":", 1);
534
        Tcl_DStringAppend(&dString, diTypePtr->name, strlen(diTypePtr->name));
535
 
536
        /*
537
         * Create the new style
538
         */
539
        stylePtr = GetDItemStyle(ddPtr, diTypePtr, dString.string, &isNew);
540
        if (isNew) {
541
            diTypePtr->styleConfigureProc(stylePtr, 0, NULL, 0);
542
            stylePtr->base.flags |= TIX_STYLE_DEFAULT;
543
        }
544
 
545
        SetDefaultStyle(diTypePtr, ddPtr->tkwin, stylePtr);
546
        Tcl_DStringFree(&dString);
547
    }
548
 
549
    if (oldStylePtr) {
550
        ListDelete(oldStylePtr, iPtr);
551
    }
552
    ListAdd(stylePtr, iPtr);
553
 
554
    return stylePtr;
555
}
556
 
557
void Tix_SetDefaultStyleTemplate(tkwin, tmplPtr)
558
    Tk_Window tkwin;
559
    Tix_StyleTemplate * tmplPtr;
560
{
561
    Tcl_HashEntry * hashPtr;
562
    StyleInfo * infoPtr;
563
    StyleLink * linkPtr;
564
    int isNew;
565
 
566
    if (tableInited == 0) {
567
        InitHashTables();
568
    }
569
 
570
    hashPtr=Tcl_CreateHashEntry(&defaultTable, (char*)tkwin, &isNew);
571
    if (!isNew) {
572
        infoPtr = (StyleInfo *)Tcl_GetHashValue(hashPtr);
573
        infoPtr->tmplPtr = &infoPtr->tmpl;
574
        infoPtr->tmpl = *tmplPtr;
575
 
576
        for (linkPtr = infoPtr->linkHead; linkPtr; linkPtr=linkPtr->next) {
577
            if (linkPtr->diTypePtr->styleSetTemplateProc != NULL) {
578
                linkPtr->diTypePtr->styleSetTemplateProc(linkPtr->stylePtr,
579
                    tmplPtr);
580
            }
581
        }
582
    } else {
583
        infoPtr = (StyleInfo *)ckalloc(sizeof(StyleInfo));
584
        infoPtr->linkHead = NULL;
585
        infoPtr->tmplPtr = &infoPtr->tmpl;
586
        infoPtr->tmpl = *tmplPtr;
587
 
588
        Tk_CreateEventHandler(tkwin, StructureNotifyMask,
589
            DefWindowStructureProc, (ClientData)tkwin);
590
        Tcl_SetHashValue(hashPtr, (char*)infoPtr);
591
    }
592
}
593
 
594
/*
595
 *----------------------------------------------------------------------
596
 * GetDItemStyle --
597
 *
598
 *      Returns an ItemStyle with the given name.
599
 *
600
 * Results:
601
 *      Pointer to the given Tix_DItsmStyle.
602
 *
603
 * Side effects:
604
 *      If the style doesn't already exist, it is allocated.
605
 *----------------------------------------------------------------------
606
 */
607
 
608
static Tix_DItemStyle*
609
GetDItemStyle(ddPtr, diTypePtr, styleName, isNew_ret)
610
    Tix_DispData * ddPtr;
611
    Tix_DItemInfo * diTypePtr;
612
    char * styleName;
613
    int * isNew_ret;
614
{
615
    Tcl_HashEntry *hashPtr;
616
    int isNew;
617
    Tix_DItemStyle * stylePtr;
618
 
619
    if (tableInited == 0) {
620
        InitHashTables();
621
    }
622
 
623
    hashPtr = Tcl_CreateHashEntry(&styleTable, styleName, &isNew);
624
    if (!isNew) {
625
        stylePtr = (Tix_DItemStyle *)Tcl_GetHashValue(hashPtr);
626
    }
627
    else {
628
        stylePtr = diTypePtr->styleCreateProc(ddPtr->interp,
629
            ddPtr->tkwin, diTypePtr, styleName);
630
        stylePtr->base.styleCmd = Tcl_CreateCommand(ddPtr->interp,
631
            styleName, StyleCmd, (ClientData)stylePtr, StyleCmdDeletedProc);
632
        stylePtr->base.interp    = ddPtr->interp;
633
        stylePtr->base.tkwin     = ddPtr->tkwin;
634
        stylePtr->base.diTypePtr = diTypePtr;
635
        stylePtr->base.name      = (char*)tixStrDup(styleName);
636
        stylePtr->base.pad[0]     = 0;
637
        stylePtr->base.pad[1]    = 0;
638
        stylePtr->base.anchor    = TK_ANCHOR_CENTER;
639
        stylePtr->base.refCount  = 0;
640
        stylePtr->base.flags     = 0;
641
        Tcl_InitHashTable(&stylePtr->base.items, TCL_ONE_WORD_KEYS);
642
 
643
        Tcl_SetHashValue(hashPtr, (char*)stylePtr);
644
    }
645
 
646
    if (isNew_ret != NULL) {
647
        * isNew_ret = isNew;
648
    }
649
    return stylePtr;
650
}
651
 
652
static Tix_DItemStyle* FindStyle(styleName)
653
    char *styleName;
654
{
655
    Tcl_HashEntry *hashPtr;
656
 
657
    if (tableInited == 0) {
658
        InitHashTables();
659
    }
660
    if ((hashPtr=Tcl_FindHashEntry(&styleTable, styleName)) == NULL) {
661
        return NULL;
662
    }
663
 
664
    return (Tix_DItemStyle *)Tcl_GetHashValue(hashPtr);
665
}
666
 
667
/*----------------------------------------------------------------------
668
 * TixDItemStyleChanged --
669
 *
670
 *      Tell each Ditem that are affected by this style that the style
671
 *      has changed. The Ditems will respond by updating their
672
 *      attributes according to the new values of the style.
673
 *----------------------------------------------------------------------
674
 */
675
 
676
void TixDItemStyleChanged(diTypePtr, stylePtr)
677
    Tix_DItemInfo * diTypePtr;
678
    Tix_DItemStyle * stylePtr;
679
{
680
    Tcl_HashSearch hashSearch;
681
    Tcl_HashEntry *hashPtr;
682
    Tix_DItem * iPtr;
683
 
684
    for (hashPtr = Tcl_FirstHashEntry(&stylePtr->base.items, &hashSearch);
685
         hashPtr;
686
         hashPtr = Tcl_NextHashEntry(&hashSearch)) {
687
 
688
        iPtr = (Tix_DItem *)Tcl_GetHashValue(hashPtr);
689
        diTypePtr->styleChangedProc(iPtr);
690
    }
691
}
692
 
693
/*----------------------------------------------------------------------
694
 * ListAdd --
695
 *
696
 *      Add an item to the list of items affected by a style.
697
 *----------------------------------------------------------------------
698
 */
699
 
700
static void
701
ListAdd(stylePtr, iPtr)
702
    Tix_DItemStyle * stylePtr;
703
    Tix_DItem *iPtr;
704
{
705
    Tcl_HashEntry *hashPtr;
706
    int isNew;
707
 
708
    hashPtr = Tcl_CreateHashEntry(&stylePtr->base.items, (char*)iPtr, &isNew);
709
    if (!isNew) {
710
        panic("DItem is already associated with style");
711
    } else {
712
        Tcl_SetHashValue(hashPtr, (char*)iPtr);
713
    }
714
    ++ stylePtr->base.refCount;
715
}
716
 
717
static void
718
ListDelete(stylePtr, iPtr)
719
    Tix_DItemStyle * stylePtr;
720
    Tix_DItem *iPtr;
721
{
722
    Tcl_HashEntry *hashPtr;
723
 
724
    hashPtr = Tcl_FindHashEntry(&stylePtr->base.items, (char*)iPtr);
725
    if (hashPtr == NULL) {
726
        panic("DItem is not associated with style");
727
    }
728
    Tcl_DeleteHashEntry(hashPtr);
729
    stylePtr->base.refCount--;
730
 
731
    if ((stylePtr->base.refCount == 0) &&
732
            (stylePtr->base.flags & TIX_STYLE_DELETED) &&
733
            (stylePtr->base.flags & TIX_STYLE_DEFAULT)) {
734
        Tk_EventuallyFree((ClientData)stylePtr, (Tix_FreeProc *)StyleDestroy);
735
    }
736
}
737
 
738
static void
739
ListDeleteAll(stylePtr)
740
    Tix_DItemStyle * stylePtr;
741
{
742
    Tcl_HashSearch hashSearch;
743
    Tcl_HashEntry *hashPtr;
744
    Tix_DItem * iPtr;
745
 
746
    for (hashPtr = Tcl_FirstHashEntry(&stylePtr->base.items, &hashSearch);
747
         hashPtr;
748
         hashPtr = Tcl_NextHashEntry(&hashSearch)) {
749
 
750
        iPtr = (Tix_DItem *)Tcl_GetHashValue(hashPtr);
751
        if (stylePtr->base.diTypePtr->lostStyleProc != NULL) {
752
            stylePtr->base.diTypePtr->lostStyleProc(iPtr);
753
        }
754
        Tcl_DeleteHashEntry(hashPtr);
755
    }
756
}
757
 
758
static void
759
InitHashTables()
760
{
761
    if (tableInited == 0) {
762
        Tcl_InitHashTable(&styleTable, TCL_STRING_KEYS);
763
        Tcl_InitHashTable(&defaultTable, TCL_ONE_WORD_KEYS);
764
        tableInited = 1;
765
    }
766
}
767
 
768
/*
769
 *--------------------------------------------------------------
770
 *
771
 * DefWindowStructureProc --
772
 *
773
 *      This procedure is invoked whenever StructureNotify events
774
 *      occur for a window that has some default style(s) associated with it
775
 *
776
 * Results:
777
 *      None.
778
 *
779
 * Side effects:
780
 *      The style(s) associated with this window will all be deleted.
781
 *
782
 *--------------------------------------------------------------
783
 */
784
 
785
static void
786
DefWindowStructureProc(clientData, eventPtr)
787
    ClientData clientData;      /* Pointer to record describing window item. */
788
    XEvent *eventPtr;           /* Describes what just happened. */
789
{
790
    Tk_Window tkwin = (Tk_Window)clientData;
791
    Tcl_HashEntry *hashPtr;
792
    StyleInfo * infoPtr;
793
    StyleLink * linkPtr, *toFree;
794
 
795
    if (eventPtr->type != DestroyNotify) {
796
        return;
797
    }
798
    if (tableInited == 0) {
799
        InitHashTables();
800
    }
801
    if ((hashPtr=Tcl_FindHashEntry(&defaultTable, (char*)tkwin)) == NULL) {
802
        return;
803
    }
804
    infoPtr = (StyleInfo *)Tcl_GetHashValue(hashPtr);
805
    for (linkPtr = infoPtr->linkHead; linkPtr; ) {
806
        toFree = linkPtr;
807
        linkPtr=linkPtr->next;
808
 
809
        DeleteStyle(toFree->stylePtr);
810
        ckfree((char*)toFree);
811
    }
812
 
813
    ckfree((char*)infoPtr);
814
    Tcl_DeleteHashEntry(hashPtr);
815
}
816
 
817
/*
818
 *--------------------------------------------------------------
819
 *
820
 * RefWindowStructureProc --
821
 *
822
 *      This procedure is invoked when the refwindow of a non-default
823
 *      style is deleted.
824
 *
825
 * Results:
826
 *      None.
827
 *
828
 * Side effects:
829
 *      The style is deleted.
830
 *
831
 *--------------------------------------------------------------
832
 */
833
 
834
static void
835
RefWindowStructureProc(clientData, eventPtr)
836
    ClientData clientData;      /* Pointer to record describing window item. */
837
    XEvent *eventPtr;           /* Describes what just happened. */
838
{
839
    Tix_DItemStyle * stylePtr = (Tix_DItemStyle *)clientData;
840
 
841
    if (eventPtr->type == DestroyNotify) {
842
        /*
843
         * If some DItems are still associated with this window, they
844
         * will receive a "LostStyle" notification.
845
         */
846
        DeleteStyle(stylePtr);
847
    }
848
}
849
 
850
/*----------------------------------------------------------------------
851
 *
852
 *               The Tix Customed Config Options
853
 *
854
 *----------------------------------------------------------------------
855
 */
856
 
857
/*
858
 * The global data structures to use in widget configSpecs arrays
859
 *
860
 * These are declared in <tix.h>
861
 */
862
 
863
Tk_CustomOption tixConfigItemStyle = {
864
    DItemStyleParseProc, DItemStylePrintProc, 0,
865
};
866
 
867
/*----------------------------------------------------------------------
868
 *  DItemStyleParseProc --
869
 *
870
 *      Parse the text string and store the Tix_DItemStyleType information
871
 *      inside the widget record.
872
 *----------------------------------------------------------------------
873
 */
874
static int DItemStyleParseProc(clientData, interp, tkwin, value, widRec,offset)
875
    ClientData clientData;
876
    Tcl_Interp *interp;
877
    Tk_Window tkwin;
878
    char *value;
879
    char *widRec;               /* Must point to a valid Tix_DItem struct */
880
    int offset;
881
{
882
    Tix_DItem       * iPtr = (Tix_DItem *)widRec;
883
    Tix_DItemStyle ** ptr = (Tix_DItemStyle **)(widRec + offset);
884
    Tix_DItemStyle  * oldPtr = *ptr;
885
    Tix_DItemStyle  * newPtr;
886
 
887
    if (tableInited  == 0) {
888
        InitHashTables();
889
    }
890
 
891
    if (value == NULL || strlen(value) == 0) {
892
        /*
893
         * User gives a NULL string -- meaning he wants the default
894
         * style
895
         */
896
        if (oldPtr && oldPtr->base.flags & TIX_STYLE_DEFAULT) {
897
            /*
898
             * This ditem is already associated with a default style. Let's
899
             * keep it.
900
             */
901
            newPtr = oldPtr;
902
        } else {
903
            if (oldPtr) {
904
                ListDelete(oldPtr, iPtr);
905
            }
906
            newPtr = NULL;
907
        }
908
    } else {
909
        if ((newPtr = FindStyle(value)) == NULL) {
910
            goto not_found;
911
        }
912
        if (newPtr->base.flags & TIX_STYLE_DELETED) {
913
            goto not_found;
914
        }
915
        if (newPtr->base.diTypePtr != iPtr->base.diTypePtr) {
916
            Tcl_AppendResult(interp, "Style type mismatch ",
917
                "Needed ", iPtr->base.diTypePtr->name, " style but got ",
918
                newPtr->base.diTypePtr->name, " style", NULL);
919
            return TCL_ERROR;
920
        }
921
        if (oldPtr != newPtr) {
922
            if (oldPtr != NULL) {
923
                ListDelete(oldPtr, iPtr);
924
            }
925
            ListAdd(newPtr, iPtr);
926
        }
927
    }
928
 
929
    *ptr = newPtr;
930
    return TCL_OK;
931
 
932
not_found:
933
    Tcl_AppendResult(interp, "Display style \"", value,
934
        "\" not found", NULL);
935
    return TCL_ERROR;
936
}
937
 
938
static char *DItemStylePrintProc(clientData, tkwin, widRec,offset, freeProcPtr)
939
    ClientData clientData;
940
    Tk_Window tkwin;
941
    char *widRec;
942
    int offset;
943
    Tcl_FreeProc **freeProcPtr;
944
{
945
    Tix_DItemStyle *stylePtr = *((Tix_DItemStyle**)(widRec+offset));
946
 
947
    if (stylePtr != NULL) {
948
        return stylePtr->base.name;
949
    } else {
950
        return 0;
951
    }
952
}

powered by: WebSVN 2.1.0

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