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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tix/] [generic/] [tixImgCmp.c] - Blame information for rev 1778

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

Line No. Rev Author Line
1 578 markom
/*
2
 * tkImgCmp.c --
3
 *
4
 *      This procedure implements images of type "compound" for Tix.
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
#include <tixPort.h>
14
#include <tixInt.h>
15
#include <tixDef.h>
16
 
17
/*
18
 * ToDo:
19
 *      - lineconfig and itemconfig command
20
 */
21
 
22
/*
23
 * The following data structure represents the master for a bitmap
24
 * image:
25
 */
26
typedef struct CmpMaster {
27
    Tk_ImageMaster tkMaster;    /* Tk's token for image master.  NULL means
28
                                 * the image is being deleted. */
29
    Tcl_Interp *interp;         /* Interpreter for application that is
30
                                 * using image. */
31
    Tcl_Command imageCmd;       /* Token for image command (used to delete
32
                                 * it when the image goes away).  NULL means
33
                                 * the image command has already been
34
                                 * deleted. */
35
    Display * display;          /* Display of the the window associated with
36
                                 * this image. We need to keep it
37
                                 * because Tk_Display(CmpMaster.tkwin) may
38
                                 * be invalid. */
39
    Tk_Window tkwin;            /* default options are taken from this window.
40
                                 * If undefined, will use the main window
41
                                 * of this application */
42
    int width, height;          /* Dimensions of image. */
43
    int padX, padY;
44
    struct CmpLine * lineHead;
45
    struct CmpLine * lineTail;
46
 
47
    /* Thde default options, etc */
48
    int borderWidth;            /* Width of 3-D borders. */
49
    Tk_3DBorder background;     /* Used for drawing background. */
50
    int relief;                 /* Indicates whether window as a whole is
51
                                 * raised, sunken, or flat. */
52
 
53
    TixFont font;               /* Information about text font.*/
54
    XColor *foreground;         /* Color for drawing text and bitmaps */
55
    GC gc;                      /* default GC for drawing text. */
56
 
57
    int showBackground;         /* whether the background should be drawn */
58
    unsigned int changing;      /* is this image going to call Tk_ImageChanged
59
                                 * in an idle event? */
60
    unsigned int isDeleted;
61
} CmpMaster;
62
 
63
#define TYPE_TEXT       0
64
#define TYPE_SPACE      1
65
#define TYPE_IMAGE      2
66
#define TYPE_BITMAP     3
67
#define TYPE_WIDGET     4
68
 
69
typedef struct CmpLine {
70
    struct CmpMaster *masterPtr;
71
    struct CmpLine * next;
72
    struct CmpItem * itemHead;
73
    struct CmpItem * itemTail;
74
    int padX, padY;
75
    Tk_Anchor anchor;
76
    int width, height;          /* Dimensions of this line. */
77
 
78
} CmpLine;
79
 
80
/* abstract type */
81
 
82
#define COMMON_MEMBERS \
83
    struct CmpLine * line; \
84
    struct CmpItem * next; \
85
    Tk_Anchor anchor; \
86
    char type; \
87
    int width; \
88
    int height; \
89
    int padX, padY
90
 
91
typedef struct CmpItem {
92
    COMMON_MEMBERS;
93
} CmpItem;
94
 
95
typedef struct CmpBitmapItem {
96
    COMMON_MEMBERS;
97
 
98
    Pixmap bitmap;
99
    XColor *foreground;
100
    XColor *background;
101
    GC gc;                      /* GC for drawing the bitmap. */
102
} CmpBitmapItem;
103
 
104
typedef struct CmpImageItem {
105
    COMMON_MEMBERS;
106
 
107
    Tk_Image image;
108
    char * imageString;
109
} CmpImageItem;
110
 
111
typedef struct CmpSpaceItem {
112
    COMMON_MEMBERS;
113
 
114
} CmpSpaceItem;
115
 
116
typedef struct CmpTextItem {
117
    COMMON_MEMBERS;
118
 
119
    char * text;
120
    int numChars;
121
    Tk_Justify justify;         /* Justification to use for multi-line text. */
122
    int wrapLength;
123
    int underline;              /* Index of character to underline.  < 0 means
124
                                 * don't underline anything. */
125
    XColor *foreground;
126
    TixFont font;               /* Information about text font, or NULL. */
127
    GC gc;                      /* GC for drawing the bitmap. */
128
} CmpTextItem;
129
 
130
typedef union CmpItemPtr {
131
    CmpItem       * item;
132
    CmpBitmapItem * bitmap;
133
    CmpImageItem  * image;
134
    CmpSpaceItem  * space;
135
    CmpTextItem  * text;
136
} CmpItemPtr;
137
 
138
/*
139
 * The type record for bitmap images:
140
 */
141
static int              ImgCmpCreate _ANSI_ARGS_((Tcl_Interp *interp,
142
                            char *name, int objc, Tcl_Obj *CONST *objv,
143
                            Tk_ImageType *typePtr, Tk_ImageMaster master,
144
                            ClientData *clientDataPtr));
145
static ClientData       ImgCmpGet _ANSI_ARGS_((Tk_Window tkwin,
146
                            ClientData clientData));
147
static void             ImgCmpDisplay _ANSI_ARGS_((ClientData clientData,
148
                            Display *display, Drawable drawable,
149
                            int imageX, int imageY, int width, int height,
150
                            int drawableX, int drawableY));
151
static void             ImgCmpFree _ANSI_ARGS_((ClientData clientData,
152
                            Display *display));
153
static void             ImgCmpDelete _ANSI_ARGS_((ClientData clientData));
154
 
155
Tk_ImageType tixCompoundImageType = {
156
    "compound",                 /* name */
157
    ImgCmpCreate,               /* createProc */
158
    ImgCmpGet,                  /* getProc */
159
    ImgCmpDisplay,              /* displayProc */
160
    ImgCmpFree,                 /* freeProc */
161
    ImgCmpDelete,               /* deleteProc */
162
    (Tk_ImageType *) NULL       /* nextPtr */
163
};
164
 
165
static Tk_ConfigSpec configSpecs[] = {
166
    {TK_CONFIG_BORDER, "-background", "background", "Background",
167
       DEF_CMPIMAGE_BG_COLOR, Tk_Offset(CmpMaster, background),
168
       TK_CONFIG_COLOR_ONLY},
169
 
170
    {TK_CONFIG_BORDER, "-background", "background", "Background",
171
       DEF_CMPIMAGE_BG_MONO, Tk_Offset(CmpMaster, background),
172
       TK_CONFIG_MONO_ONLY},
173
 
174
    {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
175
       (char *) NULL, 0, 0},
176
 
177
    {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
178
       (char *) NULL, 0, 0},
179
 
180
    {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", (char *) NULL,
181
       "0", Tk_Offset(CmpMaster, borderWidth), 0},
182
 
183
    {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL,
184
       (char *) NULL, 0, 0},
185
 
186
    {TK_CONFIG_FONT, "-font", "font", "Font",
187
       DEF_CMPIMAGE_FONT, Tk_Offset(CmpMaster, font), 0},
188
 
189
    {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
190
       DEF_CMPIMAGE_FG_COLOR, Tk_Offset(CmpMaster, foreground),
191
       TK_CONFIG_COLOR_ONLY},
192
 
193
    {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
194
       DEF_CMPIMAGE_FG_MONO, Tk_Offset(CmpMaster, foreground),
195
       TK_CONFIG_MONO_ONLY},
196
 
197
    {TK_CONFIG_PIXELS, "-padx", (char *) NULL, (char *) NULL,
198
        "0", Tk_Offset(CmpMaster, padX), 0},
199
 
200
    {TK_CONFIG_PIXELS, "-pady", (char *) NULL, (char *) NULL,
201
        "0", Tk_Offset(CmpMaster, padY), 0},
202
 
203
    {TK_CONFIG_RELIEF, "-relief", (char *) NULL, (char *) NULL,
204
        "flat", Tk_Offset(CmpMaster, relief), 0},
205
 
206
    {TK_CONFIG_BOOLEAN, "-showbackground", (char *) NULL, (char *) NULL,
207
        "0", Tk_Offset(CmpMaster, showBackground), 0},
208
 
209
    {TK_CONFIG_WINDOW, "-window", (char *) NULL, (char *) NULL,
210
        (char *) NULL, Tk_Offset(CmpMaster, tkwin), TK_CONFIG_NULL_OK},
211
 
212
    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
213
        (char *) NULL, 0, 0}
214
};
215
 
216
static Tk_ConfigSpec lineConfigSpecs[] = {
217
    {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
218
       "c", Tk_Offset(CmpLine, anchor), 0},
219
    {TK_CONFIG_PIXELS, "-padx", (char *) NULL, (char *) NULL,
220
       "0", Tk_Offset(CmpLine, padX), 0},
221
    {TK_CONFIG_PIXELS, "-pady", (char *) NULL, (char *) NULL,
222
       "0", Tk_Offset(CmpLine, padY), 0},
223
    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
224
        (char *) NULL, 0, 0}
225
};
226
 
227
static Tk_ConfigSpec bitmapConfigSpecs[] = {
228
    {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
229
       "c", Tk_Offset(CmpBitmapItem, anchor), 0},
230
 
231
    {TK_CONFIG_COLOR, "-background", "background", "Background",
232
       "", Tk_Offset(CmpBitmapItem, background),
233
       TK_CONFIG_NULL_OK},
234
 
235
    {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
236
       (char *) NULL, 0, 0},
237
 
238
    {TK_CONFIG_BITMAP, "-bitmap", (char *) NULL, (char *) NULL,
239
       "",  Tk_Offset(CmpBitmapItem, bitmap), TK_CONFIG_NULL_OK},
240
 
241
    {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL,
242
       (char *) NULL, 0, 0},
243
 
244
    {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
245
       "", Tk_Offset(CmpBitmapItem, foreground),
246
       TK_CONFIG_NULL_OK},
247
 
248
    {TK_CONFIG_PIXELS, "-padx", (char *) NULL, (char *) NULL,
249
       "0", Tk_Offset(CmpBitmapItem, padX), 0},
250
 
251
    {TK_CONFIG_PIXELS, "-pady", (char *) NULL, (char *) NULL,
252
       "0", Tk_Offset(CmpBitmapItem, padY), 0},
253
 
254
    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
255
        (char *) NULL, 0, 0}
256
};
257
 
258
static Tk_ConfigSpec imageConfigSpecs[] = {
259
    {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
260
       "c", Tk_Offset(CmpImageItem, anchor), 0},
261
    {TK_CONFIG_STRING, "-image", (char *) NULL, (char *) NULL,
262
       (char *) NULL, Tk_Offset(CmpImageItem, imageString), TK_CONFIG_NULL_OK},
263
    {TK_CONFIG_PIXELS, "-padx", (char *) NULL, (char *) NULL,
264
       "0", Tk_Offset(CmpImageItem, padX), 0},
265
    {TK_CONFIG_PIXELS, "-pady", (char *) NULL, (char *) NULL,
266
       "0", Tk_Offset(CmpImageItem, padY), 0},
267
    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
268
        (char *) NULL, 0, 0}
269
};
270
 
271
static Tk_ConfigSpec spaceConfigSpecs[] = {
272
    {TK_CONFIG_PIXELS, "-height", (char *) NULL, (char *) NULL,
273
       "0", Tk_Offset(CmpSpaceItem, height), 0},
274
    {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL,
275
       "0", Tk_Offset(CmpSpaceItem, width), 0},
276
    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
277
        (char *) NULL, 0, 0}
278
};
279
 
280
static Tk_ConfigSpec textConfigSpecs[] = {
281
    {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
282
       "c", Tk_Offset(CmpTextItem, anchor), 0},
283
 
284
    {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL,
285
       (char *) NULL, 0, 0},
286
 
287
    {TK_CONFIG_FONT, "-font", (char *) NULL, (char *) NULL,
288
       "", Tk_Offset(CmpTextItem, font), TK_CONFIG_NULL_OK},
289
 
290
    {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
291
       "", Tk_Offset(CmpTextItem, foreground),
292
       TK_CONFIG_NULL_OK},
293
 
294
    {TK_CONFIG_JUSTIFY, "-justify", (char *) NULL, (char *) NULL,
295
       "left", Tk_Offset(CmpTextItem, justify), 0},
296
 
297
    {TK_CONFIG_PIXELS, "-padx", (char *) NULL, (char *) NULL,
298
       "0", Tk_Offset(CmpTextItem, padX), 0},
299
 
300
    {TK_CONFIG_PIXELS, "-pady", (char *) NULL, (char *) NULL,
301
       "0", Tk_Offset(CmpTextItem, padY), 0},
302
 
303
    {TK_CONFIG_STRING, "-text", (char *) NULL, (char *) NULL,
304
       "",  Tk_Offset(CmpTextItem, text), TK_CONFIG_NULL_OK},
305
 
306
    {TK_CONFIG_INT, "-underline", (char *) NULL, (char *) NULL,
307
       "-1", Tk_Offset(CmpTextItem, underline), 0},
308
 
309
    {TK_CONFIG_PIXELS, "-wraplength", (char *) NULL, (char *) NULL,
310
       "0", Tk_Offset(CmpTextItem, wrapLength), 0},
311
 
312
    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
313
        (char *) NULL, 0, 0}
314
};
315
 
316
/*
317
 * Prototypes for procedures used only locally in this file:
318
 */
319
 
320
static int              ImgCmpCmd _ANSI_ARGS_((ClientData clientData,
321
                            Tcl_Interp *interp, int argc, char **argv));
322
static void             ImgCmpCmdDeletedProc _ANSI_ARGS_((
323
                            ClientData clientData));
324
static int              ImgCmpConfigureMaster _ANSI_ARGS_((
325
                            CmpMaster *masterPtr, int argc, char **argv,
326
                            int flags));
327
CmpBitmapItem *         AddNewBitmap _ANSI_ARGS_((CmpMaster *masterPtr,
328
                            CmpLine *line,
329
                            int argc, char **argv));
330
CmpImageItem *          AddNewImage _ANSI_ARGS_((CmpMaster *masterPtr,
331
                            CmpLine *line,
332
                            int argc, char **argv));
333
CmpSpaceItem *          AddNewSpace _ANSI_ARGS_((CmpMaster *masterPtr,
334
                            CmpLine *line,
335
                            int argc, char **argv));
336
CmpTextItem *           AddNewText _ANSI_ARGS_((CmpMaster *masterPtr,
337
                            CmpLine *line,
338
                            int argc, char **argv));
339
CmpLine*                AddNewLine _ANSI_ARGS_((CmpMaster *masterPtr,
340
                            int argc, char **argv));
341
static void             CalculateMasterSize _ANSI_ARGS_((
342
                            ClientData clientData));
343
static void             ChangeImageWhenIdle _ANSI_ARGS_((
344
                            CmpMaster *masterPtr));
345
static void             ImageProc _ANSI_ARGS_((ClientData clientData,
346
                            int x, int y, int width, int height,
347
                            int imgWidth, int imgHeight));
348
static void             FreeLine _ANSI_ARGS_((CmpLine * lPtr));
349
static void             FreeItem _ANSI_ARGS_((CmpItemPtr p));
350
static void             CmpEventProc _ANSI_ARGS_((ClientData clientData,
351
                            XEvent *eventPtr));
352
 
353
/*
354
 *----------------------------------------------------------------------
355
 *
356
 * ImgCmpCreate --
357
 *
358
 *      This procedure is called by the Tk image code to create "test"
359
 *      images.
360
 *
361
 * Results:
362
 *      A standard Tcl result.
363
 *
364
 * Side effects:
365
 *      The data structure for a new image is allocated.
366
 *
367
 *----------------------------------------------------------------------
368
 */
369
 
370
        /* ARGSUSED */
371
static int
372
ImgCmpCreate(interp, name, objc, objv, typePtr, master, clientDataPtr)
373
    Tcl_Interp *interp;         /* Interpreter for application containing
374
                                 * image. */
375
    char *name;                 /* Name to use for image. */
376
    int objc;                   /* Number of arguments. */
377
    Tcl_Obj *CONST *objv;       /* Arguments for options (doesn't
378
                                 * include image name or type). */
379
    Tk_ImageType *typePtr;      /* Pointer to our type record (not used). */
380
    Tk_ImageMaster master;      /* Token for image, to be used by us in
381
                                 * later callbacks. */
382
    ClientData *clientDataPtr;  /* Store manager's token for image here;
383
                                 * it will be returned in later callbacks. */
384
{
385
    CmpMaster *masterPtr;
386
    char **argv;
387
    int i, length;
388
 
389
    argv = (char **) Tcl_Alloc((objc + 1) * sizeof(char *));
390
    for (i = 0; i < objc; i++) {
391
        argv[i] = Tcl_GetStringFromObj(objv[i], &length);
392
    }
393
    argv[objc] = NULL;
394
 
395
    masterPtr = (CmpMaster *) ckalloc(sizeof(CmpMaster));
396
    masterPtr->tkMaster = master;
397
    masterPtr->interp = interp;
398
    masterPtr->imageCmd = Tcl_CreateCommand(interp, name, ImgCmpCmd,
399
        (ClientData)masterPtr, ImgCmpCmdDeletedProc);
400
    masterPtr->tkwin = NULL;
401
    masterPtr->display = NULL;
402
    masterPtr->width = 0;
403
    masterPtr->height = 0;
404
    masterPtr->padX = 0;
405
    masterPtr->padY = 0;
406
    masterPtr->lineHead = NULL;
407
    masterPtr->lineTail = NULL;
408
    masterPtr->borderWidth = 0;
409
    masterPtr->background = NULL;
410
    masterPtr->relief = 0;
411
    masterPtr->font = NULL;
412
    masterPtr->foreground = NULL;
413
    masterPtr->gc = None;
414
    masterPtr->showBackground = 0;
415
    masterPtr->changing = 0;
416
    masterPtr->isDeleted = 0;
417
 
418
    if (ImgCmpConfigureMaster(masterPtr, objc, argv, 0) != TCL_OK) {
419
        ImgCmpDelete((ClientData) masterPtr);
420
        Tcl_Free((char *) argv);
421
        return TCL_ERROR;
422
    }
423
    *clientDataPtr = (ClientData) masterPtr;
424
    Tcl_Free((char *) argv);
425
    return TCL_OK;
426
}
427
 
428
/*
429
 *----------------------------------------------------------------------
430
 *
431
 * ImgCmpConfigureMaster --
432
 *
433
 *      This procedure is called when a bitmap image is created or
434
 *      reconfigured.  It process configuration options and resets
435
 *      any instances of the image.
436
 *
437
 * Results:
438
 *      A standard Tcl return value.  If TCL_ERROR is returned then
439
 *      an error message is left in masterPtr->interp->result.
440
 *
441
 * Side effects:
442
 *      Existing instances of the image will be redisplayed to match
443
 *      the new configuration options.
444
 *
445
 *----------------------------------------------------------------------
446
 */
447
static int
448
ImgCmpConfigureMaster(masterPtr, argc, argv, flags)
449
    CmpMaster *masterPtr;       /* Pointer to data structure describing
450
                                 * overall bitmap image to (reconfigure). */
451
    int argc;                   /* Number of entries in argv. */
452
    char **argv;                /* Pairs of configuration options for image. */
453
    int flags;                  /* Flags to pass to Tk_ConfigureWidget,
454
                                 * such as TK_CONFIG_ARGV_ONLY. */
455
{
456
    XGCValues gcValues;
457
    GC newGC;
458
    int i;
459
 
460
    if (argc %2) {
461
        Tcl_AppendResult(masterPtr->interp, "value missing for option \"",
462
            argv[argc-1], "\"", NULL);
463
        return TCL_ERROR;
464
    }
465
    for (i=0; i<argc; i+=2) {
466
        size_t length = strlen(argv[i]);
467
        if (strncmp(argv[i], "-window", length) == 0) {
468
            masterPtr->tkwin = Tk_NameToWindow(masterPtr->interp, argv[i+1],
469
                Tk_MainWindow(masterPtr->interp));
470
            if (masterPtr->tkwin == NULL) {
471
                return TCL_ERROR;
472
            }
473
        }
474
    }
475
    if (masterPtr->tkwin == NULL) {
476
        Tcl_AppendResult(masterPtr->interp,
477
            "no value given for -window option.", NULL);
478
        return TCL_ERROR;
479
    }
480
    masterPtr->display = Tk_Display(masterPtr->tkwin);
481
 
482
    if (Tk_ConfigureWidget(masterPtr->interp, masterPtr->tkwin,
483
            configSpecs, argc, argv, (char *) masterPtr, flags) != TCL_OK) {
484
        return TCL_ERROR;
485
    }
486
 
487
    Tk_CreateEventHandler(masterPtr->tkwin,
488
        StructureNotifyMask, CmpEventProc, (ClientData)masterPtr);
489
    /*
490
     * Get the default GC for text and bitmaps
491
     */
492
    gcValues.foreground = masterPtr->foreground->pixel;
493
    gcValues.background = Tk_3DBorderColor(masterPtr->background)->pixel;
494
    gcValues.font = TixFontId(masterPtr->font);
495
    gcValues.graphics_exposures = False;
496
    newGC = Tk_GetGC(masterPtr->tkwin,
497
         GCBackground|GCForeground|GCFont|GCGraphicsExposures,
498
         &gcValues);
499
    if (masterPtr->gc != None) {
500
        Tk_FreeGC(Tk_Display(masterPtr->tkwin), masterPtr->gc);
501
    }
502
    masterPtr->gc = newGC;
503
 
504
    ChangeImageWhenIdle(masterPtr);
505
    return TCL_OK;
506
}
507
 
508
/*
509
 *--------------------------------------------------------------
510
 *
511
 * ImgCmpCmd --
512
 *
513
 *      This procedure is invoked to process the Tcl command
514
 *      that corresponds to an image managed by this module.
515
 *      See the user documentation for details on what it does.
516
 *
517
 * Results:
518
 *      A standard Tcl result.
519
 *
520
 * Side effects:
521
 *      See the user documentation.
522
 *
523
 *--------------------------------------------------------------
524
 */
525
static int
526
ImgCmpCmd(clientData, interp, argc, argv)
527
    ClientData clientData;      /* Information about button widget. */
528
    Tcl_Interp *interp;         /* Current interpreter. */
529
    int argc;                   /* Number of arguments. */
530
    char **argv;                /* Argument strings. */
531
{
532
    CmpMaster *masterPtr = (CmpMaster *) clientData;
533
    int c, code;
534
    size_t length;
535
 
536
    if (argc < 2) {
537
        sprintf(interp->result,
538
            "wrong # args: should be \"%.50s option ?arg arg ...?\"",
539
            argv[0]);
540
        return TCL_ERROR;
541
    }
542
    c = argv[1][0];
543
    length = strlen(argv[1]);
544
    if ((c == 'a') && (strncmp(argv[1], "add", length) == 0)) {
545
        if (argc < 3) {
546
            return Tix_ArgcError(interp, argc, argv, 2,
547
                "type ?option value? ...");
548
        }
549
        c = argv[2][0];
550
        length = strlen(argv[2]);
551
 
552
        if ((c == 'l') && (strncmp(argv[2], "line", length) == 0)) {
553
            CmpLine * newLine;
554
 
555
            newLine = AddNewLine(masterPtr, argc-3, argv+3);
556
            if (newLine == NULL) {
557
                return TCL_ERROR;
558
            }
559
        }
560
        else {
561
            CmpItemPtr p;
562
 
563
            if (masterPtr->lineTail == 0) {
564
                if (AddNewLine(masterPtr, 0, 0) == NULL) {
565
                    return TCL_ERROR;
566
                }
567
            }
568
            if ((c == 'b') && (strncmp(argv[2], "bitmap", length) == 0)) {
569
                p.bitmap = AddNewBitmap(masterPtr, masterPtr->lineTail,
570
                    argc-3, argv+3);
571
                if (p.bitmap == NULL) {
572
                    return TCL_ERROR;
573
                }
574
            }
575
            else if ((c == 'i') && (strncmp(argv[2], "image", length) == 0)) {
576
                p.image = AddNewImage(masterPtr, masterPtr->lineTail,
577
                    argc-3, argv+3);
578
                if (p.image == NULL) {
579
                    return TCL_ERROR;
580
                }
581
            }
582
            else if ((c == 's') && (strncmp(argv[2], "space", length) == 0)) {
583
                p.space = AddNewSpace(masterPtr, masterPtr->lineTail,
584
                    argc-3, argv+3);
585
                if (p.space == NULL) {
586
                    return TCL_ERROR;
587
                }
588
            }
589
            else if ((c == 't') && (strncmp(argv[2], "text", length) == 0)) {
590
                p.text = AddNewText(masterPtr, masterPtr->lineTail,
591
                    argc-3, argv+3);
592
                if (p.text == NULL) {
593
                    return TCL_ERROR;
594
                }
595
            }
596
            else {
597
                Tcl_AppendResult(interp, "unknown option \"",
598
                    argv[2], "\", must be bitmap, image, line, ",
599
                    "space, text or widget", NULL);
600
                return TCL_ERROR;
601
            }
602
 
603
            /* append to the end of the line */
604
            if (masterPtr->lineTail->itemHead == NULL) {
605
                masterPtr->lineTail->itemHead =  p.item;
606
                masterPtr->lineTail->itemTail = p.item;
607
            } else {
608
                masterPtr->lineTail->itemTail->next = p.item;
609
                masterPtr->lineTail->itemTail = p.item;
610
            }
611
        }
612
        ChangeImageWhenIdle(masterPtr);
613
        return TCL_OK;
614
    } else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0)
615
            && (length >= 2)) {
616
        if (argc != 3) {
617
            Tcl_AppendResult(interp, "wrong # args: should be \"",
618
                    argv[0], " cget option\"",
619
                    (char *) NULL);
620
            return TCL_ERROR;
621
        }
622
        return Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs,
623
                (char *) masterPtr, argv[2], 0);
624
    } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)
625
            && (length >= 2)) {
626
        if (argc == 2) {
627
            code = Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
628
                configSpecs, (char *) masterPtr, (char *) NULL, 0);
629
        } else if (argc == 3) {
630
            code = Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
631
                configSpecs, (char *) masterPtr, argv[2], 0);
632
        } else {
633
            int i;
634
            for (i=2; i<argc-2; i++) {
635
                length = strlen(argv[i]);
636
                if (strncmp(argv[i], "-window", length) == 0) {
637
                    Tcl_AppendResult(interp, "The -window option cannot ",
638
                        "be changed.", (char *) NULL);
639
                    return TCL_ERROR;
640
                }
641
            }
642
            code = ImgCmpConfigureMaster(masterPtr, argc-2, argv+2,
643
                TK_CONFIG_ARGV_ONLY);
644
        }
645
        return code;
646
    } else if ((c == 'i') && (strncmp(argv[1], "itemconfigure", length)== 0)) {
647
        Tcl_AppendResult(interp, "unimplemented", NULL);
648
        return TCL_ERROR;
649
    } else if ((c == 'l') && (strncmp(argv[1], "lineconfigure", length)== 0)) {
650
        Tcl_AppendResult(interp, "unimplemented", NULL);
651
        return TCL_ERROR;
652
    } else {
653
        Tcl_AppendResult(interp, "bad option \"", argv[1],
654
            "\": must be cget or configure", (char *) NULL);
655
        return TCL_ERROR;
656
    }
657
    return TCL_OK;
658
}
659
 
660
/*----------------------------------------------------------------------
661
 *
662
 *
663
 *----------------------------------------------------------------------
664
 */
665
CmpLine *
666
AddNewLine(masterPtr, argc, argv)
667
    CmpMaster *masterPtr;
668
    int argc;                   /* Number of arguments. */
669
    char **argv;                /* Argument strings. */
670
{
671
    CmpLine * lPtr = (CmpLine *)ckalloc(sizeof(CmpLine));
672
 
673
    lPtr->masterPtr = masterPtr;
674
    lPtr->next = NULL;
675
    lPtr->itemHead = NULL;
676
    lPtr->itemTail = NULL;
677
    lPtr->padX   = 0;
678
    lPtr->padY   = 0;
679
    lPtr->width  = 1;
680
    lPtr->height = 1;
681
 
682
    lPtr->anchor = TK_ANCHOR_CENTER;
683
 
684
    if (Tk_ConfigureWidget(masterPtr->interp, masterPtr->tkwin,
685
            lineConfigSpecs, argc, argv, (char *) lPtr,
686
            TK_CONFIG_ARGV_ONLY) != TCL_OK) {
687
        FreeLine(lPtr);
688
        return NULL;
689
    }
690
 
691
    /*
692
     * Append to the end of the master's lines
693
     */
694
    if (masterPtr->lineHead == NULL) {
695
        masterPtr->lineHead = masterPtr->lineTail = lPtr;
696
    } else {
697
        masterPtr->lineTail->next = lPtr;
698
        masterPtr->lineTail = lPtr;
699
    }
700
 
701
    return lPtr;
702
}
703
 
704
/*----------------------------------------------------------------------
705
 *
706
 *
707
 *----------------------------------------------------------------------
708
 */
709
CmpBitmapItem *
710
AddNewBitmap(masterPtr, line, argc, argv)
711
    CmpMaster *masterPtr;
712
    CmpLine *line;
713
    int argc;                   /* Number of arguments. */
714
    char **argv;                /* Argument strings. */
715
{
716
    CmpItemPtr p;
717
    XGCValues gcValues;
718
 
719
    p.bitmap = (CmpBitmapItem*) ckalloc(sizeof(CmpBitmapItem));
720
    p.bitmap->line = line;
721
    p.bitmap->next = NULL;
722
    p.bitmap->anchor = TK_ANCHOR_CENTER;
723
    p.bitmap->type = TYPE_BITMAP;
724
    p.bitmap->padX = 0;
725
    p.bitmap->padY = 0;
726
    p.bitmap->width = 0;
727
    p.bitmap->height = 0;
728
 
729
    p.bitmap->bitmap = None;
730
    p.bitmap->foreground = NULL;
731
    p.bitmap->background = NULL;
732
    p.bitmap->gc = None;
733
 
734
    if (Tk_ConfigureWidget(masterPtr->interp, masterPtr->tkwin,
735
            bitmapConfigSpecs, argc, argv, (char *) p.bitmap,
736
            TK_CONFIG_ARGV_ONLY) != TCL_OK) {
737
        goto error;
738
    }
739
 
740
    /* Get the GC for the bitmap */
741
    if (p.bitmap->background) {
742
        gcValues.background = p.bitmap->background->pixel;
743
    } else {
744
        gcValues.background = Tk_3DBorderColor(masterPtr->background)->pixel;
745
    }
746
    if (p.bitmap->foreground) {
747
        gcValues.foreground = p.bitmap->foreground->pixel;
748
    } else {
749
        gcValues.foreground = masterPtr->foreground->pixel;
750
    }
751
    gcValues.graphics_exposures = False;
752
    p.bitmap->gc = Tk_GetGC(masterPtr->tkwin,
753
         GCBackground|GCForeground|GCGraphicsExposures,
754
         &gcValues);
755
 
756
    return p.bitmap;
757
 
758
  error:
759
 
760
    FreeItem(p);
761
    return NULL;
762
}
763
 
764
/*----------------------------------------------------------------------
765
 *
766
 *
767
 *----------------------------------------------------------------------
768
 */
769
CmpImageItem *
770
AddNewImage(masterPtr, line, argc, argv)
771
    CmpMaster *masterPtr;
772
    CmpLine *line;
773
    int argc;                   /* Number of arguments. */
774
    char **argv;                /* Argument strings. */
775
{
776
    CmpItemPtr p;
777
 
778
 
779
    p.image = (CmpImageItem*) ckalloc(sizeof(CmpImageItem));
780
    p.image->line = line;
781
    p.image->next = NULL;
782
    p.image->anchor = TK_ANCHOR_CENTER;
783
    p.image->type = TYPE_IMAGE;
784
    p.image->padX = 0;
785
    p.image->padY = 0;
786
    p.image->width = 0;
787
    p.image->height = 0;
788
 
789
    p.image->imageString = NULL;
790
    p.image->image = NULL;
791
 
792
    if (Tk_ConfigureWidget(masterPtr->interp, masterPtr->tkwin,
793
            imageConfigSpecs, argc, argv, (char *) p.image,
794
            TK_CONFIG_ARGV_ONLY) != TCL_OK) {
795
        goto error;
796
    }
797
 
798
    /* Get the image */
799
    if (p.image->imageString != NULL) {
800
        p.image->image = Tk_GetImage(masterPtr->interp, masterPtr->tkwin,
801
            p.image->imageString, ImageProc, (ClientData)p.image);
802
        if (p.image->image == NULL) {
803
            goto error;
804
        }
805
    }
806
 
807
    return p.image;
808
 
809
  error:
810
 
811
    FreeItem(p);
812
    return NULL;
813
}
814
 
815
/*----------------------------------------------------------------------
816
 *
817
 *
818
 *----------------------------------------------------------------------
819
 */
820
CmpSpaceItem *
821
AddNewSpace(masterPtr, line, argc, argv)
822
    CmpMaster *masterPtr;
823
    CmpLine *line;
824
    int argc;                   /* Number of arguments. */
825
    char **argv;                /* Argument strings. */
826
{
827
    CmpItemPtr p;
828
 
829
    p.space = (CmpSpaceItem*) ckalloc(sizeof(CmpSpaceItem));
830
    p.space->line = line;
831
    p.space->next = NULL;
832
    p.space->anchor = TK_ANCHOR_CENTER;
833
    p.space->type = TYPE_SPACE;
834
    p.space->padX = 0;
835
    p.space->padY = 0;
836
    p.space->width = 0;
837
    p.space->height = 0;
838
 
839
    if (Tk_ConfigureWidget(masterPtr->interp, masterPtr->tkwin,
840
        spaceConfigSpecs, argc, argv, (char *)p.space,
841
        TK_CONFIG_ARGV_ONLY) != TCL_OK) {
842
        goto error;
843
    }
844
 
845
    return p.space;
846
 
847
  error:
848
 
849
    FreeItem(p);
850
    return NULL;
851
}
852
 
853
/*----------------------------------------------------------------------
854
 *
855
 *
856
 *----------------------------------------------------------------------
857
 */
858
CmpTextItem *
859
AddNewText(masterPtr, line, argc, argv)
860
    CmpMaster *masterPtr;
861
    CmpLine *line;
862
    int argc;                   /* Number of arguments. */
863
    char **argv;                /* Argument strings. */
864
{
865
    CmpItemPtr p;
866
    XGCValues gcValues;
867
 
868
    p.text = (CmpTextItem*) ckalloc(sizeof(CmpTextItem));
869
    p.text->line = line;
870
    p.text->next = NULL;
871
    p.text->anchor = TK_ANCHOR_CENTER;
872
    p.text->type = TYPE_TEXT;
873
    p.text->padX = 0;
874
    p.text->padY = 0;
875
    p.text->width = 0;
876
    p.text->height = 0;
877
 
878
    p.text->text = NULL;
879
    p.text->numChars = 0;
880
    p.text->justify = TK_JUSTIFY_CENTER;
881
    p.text->underline = -1;
882
    p.text->wrapLength = 0;
883
 
884
    p.text->foreground = NULL;
885
    p.text->font = NULL;
886
    p.text->gc = None;
887
 
888
    if (Tk_ConfigureWidget(masterPtr->interp, masterPtr->tkwin,
889
        textConfigSpecs, argc, argv, (char *) p.text,
890
        TK_CONFIG_ARGV_ONLY) != TCL_OK) {
891
 
892
        goto error;
893
    }
894
 
895
    /* Get the GC for the text */
896
    if (p.text->foreground) {
897
        gcValues.foreground = p.text->foreground->pixel;
898
    } else {
899
        gcValues.foreground = masterPtr->foreground->pixel;
900
    }
901
    if (p.text->font) {
902
        gcValues.font = TixFontId(p.text->font);
903
    } else {
904
        gcValues.font = TixFontId(masterPtr->font);
905
    }
906
    gcValues.graphics_exposures = False;
907
    p.text->gc = Tk_GetGC(masterPtr->tkwin,
908
         GCFont|GCForeground|GCGraphicsExposures,
909
         &gcValues);
910
 
911
    return p.text;
912
 
913
  error:
914
 
915
    FreeItem(p);
916
    return NULL;
917
}
918
 
919
/*
920
 *----------------------------------------------------------------------
921
 *
922
 * ImgCmpGet --
923
 *
924
 *      This procedure is called for each use of a bitmap image in a
925
 *      widget.
926
 *
927
 * Results:
928
 *      The return value is a token for the instance, which is passed
929
 *      back to us in calls to ImgCmpDisplay and ImgCmpFree.
930
 *
931
 * Side effects:
932
 *      A data structure is set up for the instance (or, an existing
933
 *      instance is re-used for the new one).
934
 *
935
 *----------------------------------------------------------------------
936
 */
937
static ClientData
938
ImgCmpGet(tkwin, masterData)
939
    Tk_Window tkwin;            /* Window in which the instance will be
940
                                 * used. */
941
    ClientData masterData;      /* Pointer to our master structure for the
942
                                 * image. */
943
{
944
    CmpMaster *masterPtr = (CmpMaster *)masterData;
945
 
946
    if (tkwin == masterPtr->tkwin) {
947
        return masterData;
948
    }
949
 
950
    Tcl_AppendResult(masterPtr->interp,
951
        "Image \"",
952
        Tk_NameOfImage(masterPtr->tkMaster),
953
        "\" can only be assigned to window \"",
954
        Tk_PathName(masterPtr->tkwin), "\"", NULL);
955
    Tcl_AddErrorInfo(masterPtr->interp, "\n    (while configuring image \"");
956
    Tcl_AddErrorInfo(masterPtr->interp, Tk_NameOfImage(masterPtr->tkMaster));
957
    Tcl_AddErrorInfo(masterPtr->interp, "\")");
958
    Tk_BackgroundError(masterPtr->interp);
959
 
960
    return NULL;
961
}
962
 
963
static void
964
CalculateMasterSize(clientData)
965
    ClientData clientData;
966
{
967
    CmpMaster *masterPtr = (CmpMaster *)clientData;
968
    CmpLine *lPtr;
969
    CmpItemPtr p;
970
 
971
    masterPtr->width  = 0;
972
    masterPtr->height = 0;
973
 
974
    for (lPtr = masterPtr->lineHead; lPtr; lPtr=lPtr->next) {
975
        lPtr->width  = 0;
976
        lPtr->height = 0;
977
        for (p.item = lPtr->itemHead; p.item; p.item=p.item->next) {
978
 
979
            switch (p.item->type) {
980
              case TYPE_IMAGE:
981
                Tk_SizeOfImage(p.image->image,
982
                    &p.image->width, &p.image->height);
983
                break;
984
 
985
              case TYPE_SPACE:
986
                /* Do nothing */
987
                break;
988
 
989
              case TYPE_TEXT:
990
                {
991
                    TixFont font;
992
 
993
                    if (p.text->text == NULL) {
994
                        break;
995
                    }
996
 
997
                    if (p.text->font) {
998
                        font = p.text->font;
999
                    } else {
1000
                        font = masterPtr->font;
1001
                    }
1002
 
1003
                    p.text->numChars = strlen(p.text->text);
1004
                    TixComputeTextGeometry(font, p.text->text,
1005
                        p.text->numChars,
1006
                        p.text->wrapLength,
1007
                        &p.text->width, &p.text->height);
1008
                }
1009
                break;
1010
 
1011
              case TYPE_BITMAP:
1012
                Tk_SizeOfBitmap(Tk_Display(masterPtr->tkwin),
1013
                    p.bitmap->bitmap, &p.bitmap->width,
1014
                    &p.bitmap->height);
1015
                break;
1016
 
1017
              case TYPE_WIDGET:
1018
 
1019
 
1020
                break;
1021
            }
1022
            p.item->width  += 2*p.item->padX;
1023
            p.item->height += 2*p.item->padY;
1024
 
1025
            lPtr->width += p.item->width;
1026
            if (lPtr->height < p.item->height) {
1027
                lPtr->height = p.item->height;
1028
            }
1029
        }
1030
        lPtr->width  += 2*lPtr->padX;
1031
        lPtr->height += 2*lPtr->padY;
1032
 
1033
        if (masterPtr->width < lPtr->width) {
1034
            masterPtr->width = lPtr->width;
1035
        }
1036
        masterPtr->height += lPtr->height;
1037
    }
1038
    masterPtr->width  += 2*masterPtr->padX + 2*masterPtr->borderWidth;
1039
    masterPtr->height += 2*masterPtr->padY + 2*masterPtr->borderWidth;
1040
 
1041
    Tk_ImageChanged(masterPtr->tkMaster, 0, 0, masterPtr->width,
1042
        masterPtr->height, masterPtr->width, masterPtr->height);
1043
    masterPtr->changing = 0;
1044
}
1045
 
1046
static void
1047
ChangeImageWhenIdle(masterPtr)
1048
    CmpMaster *masterPtr;
1049
{
1050
    if (!masterPtr->changing) {
1051
        masterPtr->changing = 1;
1052
        Tk_DoWhenIdle(CalculateMasterSize, (ClientData)masterPtr);
1053
    }
1054
}
1055
 
1056
/*
1057
 *----------------------------------------------------------------------
1058
 *
1059
 * ImgCmpDisplay --
1060
 *
1061
 *      This procedure is invoked to draw a bitmap image.
1062
 *
1063
 * Results:
1064
 *      None.
1065
 *
1066
 * Side effects:
1067
 *      A portion of the image gets rendered in a pixmap or window.
1068
 *
1069
 *----------------------------------------------------------------------
1070
 */
1071
static void
1072
ImgCmpDisplay(clientData, display, drawable, imageX, imageY, width,
1073
        height, drawableX, drawableY)
1074
    ClientData clientData;      /* Pointer to CmpInstance structure for
1075
                                 * for instance to be displayed. */
1076
    Display *display;           /* Display on which to draw image. */
1077
    Drawable drawable;          /* Pixmap or window in which to draw image. */
1078
    int imageX, imageY;         /* Upper-left corner of region within image
1079
                                 * to draw. */
1080
    int width, height;          /* Dimensions of region within image to draw.*/
1081
    int drawableX, drawableY;   /* Coordinates within drawable that
1082
                                 * correspond to imageX and imageY. */
1083
{
1084
    CmpMaster * masterPtr = (CmpMaster*)clientData;
1085
    CmpLine *lPtr;
1086
    CmpItemPtr p;
1087
    int dx, dy, extraX;
1088
 
1089
    if (masterPtr == NULL) {
1090
        /* attempting to draw into a invalid window (can only be drawn into
1091
         * the original window set by the -window option */
1092
        return;
1093
    }
1094
 
1095
    if (masterPtr->showBackground) {
1096
        Tk_Fill3DRectangle(masterPtr->tkwin, drawable,
1097
            masterPtr->background,
1098
            drawableX + masterPtr->padX - imageX,
1099
            drawableY + masterPtr->padY - imageY,
1100
            masterPtr->width  - 2*masterPtr->padX,
1101
            masterPtr->height - 2*masterPtr->padY,
1102
            masterPtr->borderWidth, masterPtr->relief);
1103
    }
1104
 
1105
    /* ToDo: Set the clipping region according to the imageX,Y, and
1106
     * width, height */
1107
    dy = drawableY + masterPtr->padY + masterPtr->borderWidth - imageY;
1108
 
1109
    for (lPtr = masterPtr->lineHead; lPtr; lPtr=lPtr->next) {
1110
        dx = drawableX + masterPtr->padX - imageX;
1111
        dx += lPtr->padX;
1112
        dy += lPtr->padY;
1113
 
1114
        extraX = masterPtr->width - 2*masterPtr->padX - lPtr->width;
1115
        switch (lPtr->anchor) {
1116
          case TK_ANCHOR_SW: case TK_ANCHOR_W: case TK_ANCHOR_NW:
1117
            extraX = 0;
1118
            break;
1119
          case TK_ANCHOR_N: case TK_ANCHOR_CENTER: case TK_ANCHOR_S:
1120
            extraX /= 2;
1121
            break;
1122
          case TK_ANCHOR_SE: case TK_ANCHOR_E: case TK_ANCHOR_NE:
1123
            break;
1124
        }
1125
        dx += extraX;
1126
 
1127
        for (p.item = lPtr->itemHead; p.item; p.item=p.item->next) {
1128
            int extraY;
1129
            dx += p.item->padX;
1130
 
1131
            extraY = lPtr->height - 2*lPtr->padY - p.item->height;
1132
            switch (p.item->anchor) {
1133
              case TK_ANCHOR_SW: case TK_ANCHOR_S: case TK_ANCHOR_SE:
1134
                break;
1135
              case TK_ANCHOR_W: case TK_ANCHOR_CENTER: case TK_ANCHOR_E:
1136
                extraY /= 2;
1137
                break;
1138
              case TK_ANCHOR_NW: case TK_ANCHOR_N: case TK_ANCHOR_NE:
1139
                extraY = 0;
1140
                break;
1141
            }
1142
 
1143
            switch (p.item->type) {
1144
              case TYPE_IMAGE:
1145
                Tk_RedrawImage(p.image->image, 0, 0,
1146
                    p.image->width  - 2*p.item->padX,
1147
                    p.image->height - 2*p.item->padY,
1148
                    drawable, dx, dy+extraY);
1149
                break;
1150
 
1151
              case TYPE_SPACE:
1152
                /* Do nothing */
1153
                break;
1154
 
1155
              case TYPE_TEXT:
1156
                {
1157
                    TixFont font;
1158
 
1159
                    if (p.text->text == NULL) {
1160
                        break;
1161
                    }
1162
 
1163
                    if (p.text->font) {
1164
                        font = p.text->font;
1165
                    } else {
1166
                        font = masterPtr->font;
1167
                    }
1168
 
1169
                    TixDisplayText(Tk_Display(masterPtr->tkwin), drawable,
1170
                        font, p.text->text, p.text->numChars,
1171
                        dx, dy+extraY,
1172
                        p.text->width - 2*p.item->padX,
1173
                        p.text->justify,
1174
                        p.text->underline,
1175
                        p.text->gc);
1176
                }
1177
                break;
1178
 
1179
              case TYPE_BITMAP:
1180
                XCopyPlane(Tk_Display(masterPtr->tkwin), p.bitmap->bitmap,
1181
                    drawable, p.bitmap->gc, 0, 0,
1182
                    p.bitmap->width  - 2*p.item->padX,
1183
                    p.bitmap->height - 2*p.item->padY,
1184
                    dx, dy+extraY, 1);
1185
 
1186
                break;
1187
 
1188
              case TYPE_WIDGET:
1189
 
1190
 
1191
                break;
1192
            }
1193
            dx += p.item->width - p.item->padX;
1194
        }
1195
        dy += lPtr->height - lPtr->padY;
1196
    }
1197
}
1198
 
1199
/*
1200
 *----------------------------------------------------------------------
1201
 *
1202
 * ImgCmpFree --
1203
 *
1204
 *      This procedure is called when a widget ceases to use a
1205
 *      particular instance of an image.
1206
 *
1207
 * Results:
1208
 *      None.
1209
 *
1210
 * Side effects:
1211
 *      Internal data structures get cleaned up.
1212
 *
1213
 *----------------------------------------------------------------------
1214
 */
1215
 
1216
static void
1217
ImgCmpFree(clientData, display)
1218
    ClientData clientData;      /* Pointer to CmpInstance structure for
1219
                                 * for instance to be displayed. */
1220
    Display *display;           /* Display containing window that used image.*/
1221
{
1222
    /*
1223
     * Since one compound image can only be used in one window, when that
1224
     * window is deleted, this image is now useless and should be deleted as
1225
     * well
1226
     */
1227
}
1228
 
1229
static void FreeLine(lPtr)
1230
    CmpLine * lPtr;
1231
{
1232
    Tk_FreeOptions(lineConfigSpecs, (char *)lPtr,
1233
        Tk_Display(lPtr->masterPtr->tkwin), 0);
1234
    ckfree((char *) lPtr);
1235
}
1236
 
1237
static void FreeItem(p)
1238
    CmpItemPtr p;
1239
{
1240
    switch (p.item->type) {
1241
      case TYPE_IMAGE:
1242
        if (p.image->image) {
1243
            Tk_FreeImage(p.image->image);
1244
        }
1245
        Tk_FreeOptions(imageConfigSpecs, (char *)p.image,
1246
            Tk_Display(p.item->line->masterPtr->tkwin), 0);
1247
        break;
1248
 
1249
      case TYPE_SPACE:
1250
        Tk_FreeOptions(spaceConfigSpecs, (char *)p.space,
1251
            Tk_Display(p.item->line->masterPtr->tkwin), 0);
1252
        break;
1253
 
1254
      case TYPE_TEXT:
1255
        if (p.text->gc != None) {
1256
            Tk_FreeGC(Tk_Display(p.text->line->masterPtr->tkwin),
1257
                p.text->gc);
1258
        }
1259
        Tk_FreeOptions(textConfigSpecs, (char *)p.text,
1260
            Tk_Display(p.item->line->masterPtr->tkwin), 0);
1261
        break;
1262
 
1263
      case TYPE_BITMAP:
1264
        if (p.bitmap->gc != None) {
1265
            Tk_FreeGC(Tk_Display(p.bitmap->line->masterPtr->tkwin),
1266
                p.bitmap->gc);
1267
        }
1268
        Tk_FreeOptions(bitmapConfigSpecs, (char *)p.bitmap,
1269
            Tk_Display(p.item->line->masterPtr->tkwin), 0);
1270
        break;
1271
 
1272
      case TYPE_WIDGET:
1273
        break;
1274
    }
1275
    ckfree((char *) p.item);
1276
}
1277
 
1278
/*
1279
 *----------------------------------------------------------------------
1280
 *
1281
 * ImgCmpDelete --
1282
 *
1283
 *      This procedure is called by the image code to delete the
1284
 *      master structure for an image.
1285
 *
1286
 * Results:
1287
 *      None.
1288
 *
1289
 * Side effects:
1290
 *      Resources associated with the image get freed.
1291
 *
1292
 *----------------------------------------------------------------------
1293
 */
1294
static void
1295
ImgCmpDelete(masterData)
1296
    ClientData masterData;      /* Pointer to CmpMaster structure for
1297
                                 * image.  Must not have any more instances. */
1298
{
1299
    CmpMaster *masterPtr = (CmpMaster *) masterData;
1300
    CmpLine * lPtr;
1301
    CmpItemPtr p;
1302
 
1303
    if (masterPtr->tkwin == NULL) {
1304
        goto done;
1305
    }
1306
 
1307
    Tk_Preserve((ClientData) masterPtr);
1308
 
1309
    Tk_DeleteEventHandler(masterPtr->tkwin,
1310
        StructureNotifyMask, CmpEventProc, (ClientData)masterPtr);
1311
 
1312
    if (masterPtr->isDeleted) {
1313
        Tk_Release((ClientData) masterPtr);
1314
        return;
1315
    }
1316
    masterPtr->isDeleted = 1;
1317
 
1318
    for (lPtr=masterPtr->lineHead; lPtr;) {
1319
        CmpLine * toDelete = lPtr;
1320
        lPtr = lPtr->next;
1321
 
1322
        for (p.item=toDelete->itemHead; p.item;) {
1323
            CmpItemPtr toDelete;
1324
 
1325
            toDelete.item = p.item;
1326
            p.item=p.item->next;
1327
 
1328
            FreeItem(toDelete);
1329
        }
1330
        FreeLine(toDelete);
1331
    }
1332
 
1333
    if (masterPtr->changing) {
1334
        Tk_CancelIdleCall(CalculateMasterSize, (ClientData)masterPtr);
1335
    }
1336
    masterPtr->tkMaster = NULL;
1337
    if (masterPtr->imageCmd != NULL) {
1338
        char * cmd = Tcl_GetCommandName(masterPtr->interp,masterPtr->imageCmd);
1339
        masterPtr->imageCmd = NULL;
1340
        Tcl_DeleteCommand(masterPtr->interp, cmd);
1341
    }
1342
    if (masterPtr->gc != None) {
1343
        Tk_FreeGC(masterPtr->display, masterPtr->gc);
1344
    }
1345
 
1346
    Tk_FreeOptions(configSpecs, (char *) masterPtr, masterPtr->display, 0);
1347
    Tk_Release((ClientData) masterPtr);
1348
 
1349
  done:
1350
    ckfree((char *) masterPtr);
1351
}
1352
 
1353
/*
1354
 *----------------------------------------------------------------------
1355
 *
1356
 * ImgCmpCmdDeletedProc --
1357
 *
1358
 *      This procedure is invoked when the image command for an image
1359
 *      is deleted.  It deletes the image.
1360
 *
1361
 * Results:
1362
 *      None.
1363
 *
1364
 * Side effects:
1365
 *      The image is deleted.
1366
 *
1367
 *----------------------------------------------------------------------
1368
 */
1369
static void
1370
ImgCmpCmdDeletedProc(clientData)
1371
    ClientData clientData;      /* Pointer to CmpMaster structure for
1372
                                 * image. */
1373
{
1374
    CmpMaster *masterPtr = (CmpMaster *) clientData;
1375
 
1376
    Tk_Preserve((ClientData) masterPtr);
1377
    if (masterPtr->isDeleted == 1) {
1378
        Tk_Release((ClientData) masterPtr);
1379
        return;
1380
    } else {
1381
        if (masterPtr->tkMaster != NULL) {
1382
            if (Tk_MainWindow(masterPtr->interp) != NULL) {
1383
                Tk_DeleteImage(masterPtr->interp,
1384
                    Tk_NameOfImage(masterPtr->tkMaster));
1385
            }
1386
        }
1387
        Tk_Release((ClientData) masterPtr);
1388
    }
1389
}
1390
/*
1391
 *----------------------------------------------------------------------
1392
 *
1393
 * ImageProc --
1394
 *
1395
 *      This procedure is invoked by the image code whenever the manager
1396
 *      for an image does something that affects the size of contents
1397
 *      of an image displayed in a button.
1398
 *
1399
 * Results:
1400
 *      None.
1401
 *
1402
 * Side effects:
1403
 *      Arranges for the HList to get redisplayed.
1404
 *
1405
 *----------------------------------------------------------------------
1406
 */
1407
static void
1408
ImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
1409
    ClientData clientData;              /* Pointer to widget record. */
1410
    int x, y;                           /* Upper left pixel (within image)
1411
                                         * that must be redisplayed. */
1412
    int width, height;                  /* Dimensions of area to redisplay
1413
                                         * (may be <= 0). */
1414
    int imgWidth, imgHeight;            /* New dimensions of image. */
1415
{
1416
    CmpItemPtr p;
1417
 
1418
    p.image = (CmpImageItem *)clientData;
1419
 
1420
    ChangeImageWhenIdle(p.item->line->masterPtr);
1421
}
1422
 
1423
/*
1424
 *--------------------------------------------------------------
1425
 *
1426
 * CmpEventProc --
1427
 *
1428
 *      This procedure is invoked by the Tk dispatcher for various
1429
 *      events on the window that employs this compound image.
1430
 *
1431
 * Results:
1432
 *      None.
1433
 *
1434
 * Side effects:
1435
 *      When the window gets deleted, internal structures get
1436
 *      cleaned up.  When it gets exposed, it is redisplayed.
1437
 *
1438
 *--------------------------------------------------------------
1439
 */
1440
 
1441
static void
1442
CmpEventProc(clientData, eventPtr)
1443
    ClientData clientData;      /* Information about window. */
1444
    XEvent *eventPtr;           /* Information about event. */
1445
{
1446
    CmpMaster *masterPtr = (CmpMaster *)clientData;
1447
    char * cmd;
1448
 
1449
    if (eventPtr->type == DestroyNotify) {
1450
        if (masterPtr->imageCmd != NULL) {
1451
            cmd = Tcl_GetCommandName(masterPtr->interp,masterPtr->imageCmd);
1452
            masterPtr->imageCmd = NULL;
1453
            Tcl_DeleteCommand(masterPtr->interp, cmd);
1454
        }
1455
    }
1456
}

powered by: WebSVN 2.1.0

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