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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tkImage.c --
3
 *
4
 *      This module implements the image protocol, which allows lots
5
 *      of different kinds of images to be used in lots of different
6
 *      widgets.
7
 *
8
 * Copyright (c) 1994 The Regents of the University of California.
9
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
10
 *
11
 * See the file "license.terms" for information on usage and redistribution
12
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13
 *
14
 * RCS: @(#) $Id: tkImage.c,v 1.1.1.1 2002-01-16 10:25:52 markom Exp $
15
 */
16
 
17
#include "tkInt.h"
18
#include "tkPort.h"
19
 
20
/*
21
 * Each call to Tk_GetImage returns a pointer to one of the following
22
 * structures, which is used as a token by clients (widgets) that
23
 * display images.
24
 */
25
 
26
typedef struct Image {
27
    Tk_Window tkwin;            /* Window passed to Tk_GetImage (needed to
28
                                 * "re-get" the image later if the manager
29
                                 * changes). */
30
    Display *display;           /* Display for tkwin.  Needed because when
31
                                 * the image is eventually freed tkwin may
32
                                 * not exist anymore. */
33
    struct ImageMaster *masterPtr;
34
                                /* Master for this image (identifiers image
35
                                 * manager, for example). */
36
    ClientData instanceData;
37
                                /* One word argument to pass to image manager
38
                                 * when dealing with this image instance. */
39
    Tk_ImageChangedProc *changeProc;
40
                                /* Code in widget to call when image changes
41
                                 * in a way that affects redisplay. */
42
    ClientData widgetClientData;
43
                                /* Argument to pass to changeProc. */
44
    struct Image *nextPtr;      /* Next in list of all image instances
45
                                 * associated with the same name. */
46
 
47
} Image;
48
 
49
/*
50
 * For each image master there is one of the following structures,
51
 * which represents a name in the image table and all of the images
52
 * instantiated from it.  Entries in mainPtr->imageTable point to
53
 * these structures.
54
 */
55
 
56
typedef struct ImageMaster {
57
    Tk_ImageType *typePtr;      /* Information about image type.  NULL means
58
                                 * that no image manager owns this image:  the
59
                                 * image was deleted. */
60
    ClientData masterData;      /* One-word argument to pass to image mgr
61
                                 * when dealing with the master, as opposed
62
                                 * to instances. */
63
    int width, height;          /* Last known dimensions for image. */
64
    Tcl_HashTable *tablePtr;    /* Pointer to hash table containing image
65
                                 * (the imageTable field in some TkMainInfo
66
                                 * structure). */
67
    Tcl_HashEntry *hPtr;        /* Hash entry in mainPtr->imageTable for
68
                                 * this structure (used to delete the hash
69
                                 * entry). */
70
    Image *instancePtr;         /* Pointer to first in list of instances
71
                                 * derived from this name. */
72
} ImageMaster;
73
 
74
/*
75
 * The following variable points to the first in a list of all known
76
 * image types.
77
 */
78
 
79
static Tk_ImageType *imageTypeList = NULL;
80
 
81
/*
82
 * Prototypes for local procedures:
83
 */
84
 
85
static void             DeleteImage _ANSI_ARGS_((ImageMaster *masterPtr));
86
 
87
/*
88
 *----------------------------------------------------------------------
89
 *
90
 * Tk_CreateImageType --
91
 *
92
 *      This procedure is invoked by an image manager to tell Tk about
93
 *      a new kind of image and the procedures that manage the new type.
94
 *      The procedure is typically invoked during Tcl_AppInit.
95
 *
96
 * Results:
97
 *      None.
98
 *
99
 * Side effects:
100
 *      The new image type is entered into a table used in the "image
101
 *      create" command.
102
 *
103
 *----------------------------------------------------------------------
104
 */
105
 
106
void
107
Tk_CreateImageType(typePtr)
108
    Tk_ImageType *typePtr;      /* Structure describing the type.  All of
109
                                 * the fields except "nextPtr" must be filled
110
                                 * in by caller.  Must not have been passed
111
                                 * to Tk_CreateImageType previously. */
112
{
113
    typePtr->nextPtr = imageTypeList;
114
    imageTypeList = typePtr;
115
}
116
 
117
/*
118
 *----------------------------------------------------------------------
119
 *
120
 * Tk_ImageCmd --
121
 *
122
 *      This procedure is invoked to process the "image" Tcl command.
123
 *      See the user documentation for details on what it does.
124
 *
125
 * Results:
126
 *      A standard Tcl result.
127
 *
128
 * Side effects:
129
 *      See the user documentation.
130
 *
131
 *----------------------------------------------------------------------
132
 */
133
 
134
int
135
Tk_ImageCmd(clientData, interp, argc, objv)
136
    ClientData clientData;      /* Main window associated with interpreter. */
137
    Tcl_Interp *interp;         /* Current interpreter. */
138
    int argc;                   /* Number of arguments. */
139
    Tcl_Obj *CONST objv[];      /* Argument strings. */
140
{
141
    TkWindow *winPtr = (TkWindow *) clientData;
142
    int c, i, new, firstOption;
143
    size_t length;
144
    Tk_ImageType *typePtr;
145
    ImageMaster *masterPtr;
146
    Image *imagePtr;
147
    Tcl_HashEntry *hPtr;
148
    Tcl_HashSearch search;
149
    char idString[30], *name;
150
    static int id = 0;
151
 
152
    static char **argv = NULL;
153
    if (argv) ckfree((char *) argv);
154
    argv = (char **) ckalloc(argc * sizeof(char *));
155
    for (i = 0; i < argc; i++) {
156
        argv[i]=Tcl_GetStringFromObj(objv[i], (int *) NULL);
157
    }
158
    if (argc < 2) {
159
        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
160
                " option ?args?\"", (char *) NULL);
161
        return TCL_ERROR;
162
    }
163
    c = argv[1][0];
164
    length = strlen(argv[1]);
165
    if ((c == 'c') && (strncmp(argv[1], "create", length) == 0)) {
166
        if (argc < 3) {
167
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
168
                    " create type ?name? ?options?\"", (char *) NULL);
169
            return TCL_ERROR;
170
        }
171
        c = argv[2][0];
172
 
173
        /*
174
         * Look up the image type.
175
         */
176
 
177
        for (typePtr = imageTypeList; typePtr != NULL;
178
                typePtr = typePtr->nextPtr) {
179
            if ((c == typePtr->name[0])
180
                    && (strcmp(argv[2], typePtr->name) == 0)) {
181
                break;
182
            }
183
        }
184
        if (typePtr == NULL) {
185
            Tcl_AppendResult(interp, "image type \"", argv[2],
186
                    "\" doesn't exist", (char *) NULL);
187
            return TCL_ERROR;
188
        }
189
 
190
        /*
191
         * Figure out a name to use for the new image.
192
         */
193
 
194
        if ((argc == 3) || (argv[3][0] == '-')) {
195
            id++;
196
            sprintf(idString, "image%d", id);
197
            name = idString;
198
            firstOption = 3;
199
        } else {
200
            name = argv[3];
201
            firstOption = 4;
202
        }
203
 
204
        /*
205
         * Create the data structure for the new image.
206
         */
207
 
208
        hPtr = Tcl_CreateHashEntry(&winPtr->mainPtr->imageTable, name, &new);
209
        if (new) {
210
            masterPtr = (ImageMaster *) ckalloc(sizeof(ImageMaster));
211
            masterPtr->typePtr = NULL;
212
            masterPtr->masterData = NULL;
213
            masterPtr->width = masterPtr->height = 1;
214
            masterPtr->tablePtr = &winPtr->mainPtr->imageTable;
215
            masterPtr->hPtr = hPtr;
216
            masterPtr->instancePtr = NULL;
217
            Tcl_SetHashValue(hPtr, masterPtr);
218
        } else {
219
            /*
220
             * An image already exists by this name.  Disconnect the
221
             * instances from the master.
222
             */
223
 
224
            masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
225
            if (masterPtr->typePtr != NULL) {
226
                for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
227
                        imagePtr = imagePtr->nextPtr) {
228
                   (*masterPtr->typePtr->freeProc)(
229
                           imagePtr->instanceData, imagePtr->display);
230
                   (*imagePtr->changeProc)(imagePtr->widgetClientData, 0, 0,
231
                        masterPtr->width, masterPtr->height, masterPtr->width,
232
                        masterPtr->height);
233
                }
234
                (*masterPtr->typePtr->deleteProc)(masterPtr->masterData);
235
                masterPtr->typePtr = NULL;
236
            }
237
        }
238
 
239
        /*
240
         * Call the image type manager so that it can perform its own
241
         * initialization, then re-"get" for any existing instances of
242
         * the image.
243
         */
244
 
245
        if ((*typePtr->createProc)(interp, name, argc-firstOption,
246
                objv+firstOption, typePtr, (Tk_ImageMaster) masterPtr,
247
                &masterPtr->masterData) != TCL_OK) {
248
            DeleteImage(masterPtr);
249
            return TCL_ERROR;
250
        }
251
        masterPtr->typePtr = typePtr;
252
        for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
253
                imagePtr = imagePtr->nextPtr) {
254
           imagePtr->instanceData = (*typePtr->getProc)(
255
                   imagePtr->tkwin, masterPtr->masterData);
256
        }
257
        Tcl_AppendResult(interp, Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), (char *) NULL);
258
    } else if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0)) {
259
        for (i = 2; i < argc; i++) {
260
            hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, argv[i]);
261
            if (hPtr == NULL) {
262
            Tcl_AppendResult(interp, "image \"", argv[i],
263
                    "\" doesn't exist", (char *) NULL);
264
                return TCL_ERROR;
265
            }
266
            masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
267
            DeleteImage(masterPtr);
268
        }
269
    } else if ((c == 'h') && (strncmp(argv[1], "height", length) == 0)) {
270
        if (argc != 3) {
271
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
272
                    " height name\"", (char *) NULL);
273
            return TCL_ERROR;
274
        }
275
        hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, argv[2]);
276
        if (hPtr == NULL) {
277
            Tcl_AppendResult(interp, "image \"", argv[2],
278
                    "\" doesn't exist", (char *) NULL);
279
            return TCL_ERROR;
280
        }
281
        masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
282
        Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->height);
283
    } else if ((c == 'n') && (strncmp(argv[1], "names", length) == 0)) {
284
        if (argc != 2) {
285
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
286
                    " names\"", (char *) NULL);
287
            return TCL_ERROR;
288
        }
289
        for (hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search);
290
                hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
291
            Tcl_AppendElement(interp, Tcl_GetHashKey(
292
                    &winPtr->mainPtr->imageTable, hPtr));
293
        }
294
    } else if ((c == 't') && (strcmp(argv[1], "type") == 0)) {
295
        if (argc != 3) {
296
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
297
                    " type name\"", (char *) NULL);
298
            return TCL_ERROR;
299
        }
300
        hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, argv[2]);
301
        if (hPtr == NULL) {
302
            Tcl_AppendResult(interp, "image \"", argv[2],
303
                    "\" doesn't exist", (char *) NULL);
304
            return TCL_ERROR;
305
        }
306
        masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
307
        if (masterPtr->typePtr != NULL) {
308
            Tcl_AppendResult(interp, masterPtr->typePtr->name, (char *) NULL);
309
        }
310
    } else if ((c == 't') && (strcmp(argv[1], "types") == 0)) {
311
        if (argc != 2) {
312
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
313
                    " types\"", (char *) NULL);
314
            return TCL_ERROR;
315
        }
316
        for (typePtr = imageTypeList; typePtr != NULL;
317
                typePtr = typePtr->nextPtr) {
318
            Tcl_AppendElement(interp, typePtr->name);
319
        }
320
    } else if ((c == 'w') && (strncmp(argv[1], "width", length) == 0)) {
321
        if (argc != 3) {
322
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
323
                    " width name\"", (char *) NULL);
324
            return TCL_ERROR;
325
        }
326
        hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, argv[2]);
327
        if (hPtr == NULL) {
328
            Tcl_AppendResult(interp, "image \"", argv[2],
329
                    "\" doesn't exist", (char *) NULL);
330
            return TCL_ERROR;
331
        }
332
        masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
333
        Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->width);
334
    } else {
335
        Tcl_AppendResult(interp, "bad option \"", argv[1],
336
                "\": must be create, delete, height, names, type, types,",
337
                " or width", (char *) NULL);
338
        return TCL_ERROR;
339
    }
340
    return TCL_OK;
341
}
342
 
343
/*
344
 *----------------------------------------------------------------------
345
 *
346
 * Tk_ImageChanged --
347
 *
348
 *      This procedure is called by an image manager whenever something
349
 *      has happened that requires the image to be redrawn (some of its
350
 *      pixels have changed, or its size has changed).
351
 *
352
 * Results:
353
 *      None.
354
 *
355
 * Side effects:
356
 *      Any widgets that display the image are notified so that they
357
 *      can redisplay themselves as appropriate.
358
 *
359
 *----------------------------------------------------------------------
360
 */
361
 
362
void
363
Tk_ImageChanged(imageMaster, x, y, width, height, imageWidth,
364
        imageHeight)
365
    Tk_ImageMaster imageMaster; /* Image that needs redisplay. */
366
    int x, y;                   /* Coordinates of upper-left pixel of
367
                                 * region of image that needs to be
368
                                 * redrawn. */
369
    int width, height;          /* Dimensions (in pixels) of region of
370
                                 * image to redraw.  If either dimension
371
                                 * is zero then the image doesn't need to
372
                                 * be redrawn (perhaps all that happened is
373
                                 * that its size changed). */
374
    int imageWidth, imageHeight;/* New dimensions of image. */
375
{
376
    ImageMaster *masterPtr = (ImageMaster *) imageMaster;
377
    Image *imagePtr;
378
 
379
    masterPtr->width = imageWidth;
380
    masterPtr->height = imageHeight;
381
    for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
382
            imagePtr = imagePtr->nextPtr) {
383
        (*imagePtr->changeProc)(imagePtr->widgetClientData, x, y,
384
            width, height, imageWidth, imageHeight);
385
    }
386
}
387
 
388
/*
389
 *----------------------------------------------------------------------
390
 *
391
 * Tk_NameOfImage --
392
 *
393
 *      Given a token for an image master, this procedure returns
394
 *      the name of the image.
395
 *
396
 * Results:
397
 *      The return value is the string name for imageMaster.
398
 *
399
 * Side effects:
400
 *      None.
401
 *
402
 *----------------------------------------------------------------------
403
 */
404
 
405
char *
406
Tk_NameOfImage(imageMaster)
407
    Tk_ImageMaster imageMaster;         /* Token for image. */
408
{
409
    ImageMaster *masterPtr = (ImageMaster *) imageMaster;
410
 
411
    return Tcl_GetHashKey(masterPtr->tablePtr, masterPtr->hPtr);
412
}
413
 
414
/*
415
 *----------------------------------------------------------------------
416
 *
417
 * Tk_GetImage --
418
 *
419
 *      This procedure is invoked by a widget when it wants to use
420
 *      a particular image in a particular window.
421
 *
422
 * Results:
423
 *      The return value is a token for the image.  If there is no image
424
 *      by the given name, then NULL is returned and an error message is
425
 *      left in interp->result.
426
 *
427
 * Side effects:
428
 *      Tk records the fact that the widget is using the image, and
429
 *      it will invoke changeProc later if the widget needs redisplay
430
 *      (i.e. its size changes or some of its pixels change).  The
431
 *      caller must eventually invoke Tk_FreeImage when it no longer
432
 *      needs the image.
433
 *
434
 *----------------------------------------------------------------------
435
 */
436
 
437
Tk_Image
438
Tk_GetImage(interp, tkwin, name, changeProc, clientData)
439
    Tcl_Interp *interp;         /* Place to leave error message if image
440
                                 * can't be found. */
441
    Tk_Window tkwin;            /* Token for window in which image will
442
                                 * be used. */
443
    char *name;                 /* Name of desired image. */
444
    Tk_ImageChangedProc *changeProc;
445
                                /* Procedure to invoke when redisplay is
446
                                 * needed because image's pixels or size
447
                                 * changed. */
448
    ClientData clientData;      /* One-word argument to pass to damageProc. */
449
{
450
    Tcl_HashEntry *hPtr;
451
    ImageMaster *masterPtr;
452
    Image *imagePtr;
453
 
454
    hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->imageTable, name);
455
    if (hPtr == NULL) {
456
        goto noSuchImage;
457
    }
458
    masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
459
    if (masterPtr->typePtr == NULL) {
460
        goto noSuchImage;
461
    }
462
    imagePtr = (Image *) ckalloc(sizeof(Image));
463
    imagePtr->tkwin = tkwin;
464
    imagePtr->display = Tk_Display(tkwin);
465
    imagePtr->masterPtr = masterPtr;
466
    imagePtr->instanceData =
467
            (*masterPtr->typePtr->getProc)(tkwin, masterPtr->masterData);
468
    imagePtr->changeProc = changeProc;
469
    imagePtr->widgetClientData = clientData;
470
    imagePtr->nextPtr = masterPtr->instancePtr;
471
    masterPtr->instancePtr = imagePtr;
472
    return (Tk_Image) imagePtr;
473
 
474
    noSuchImage:
475
    Tcl_AppendResult(interp, "image \"", name, "\" doesn't exist",
476
            (char *) NULL);
477
    return NULL;
478
}
479
 
480
/*
481
 *----------------------------------------------------------------------
482
 *
483
 * Tk_FreeImage --
484
 *
485
 *      This procedure is invoked by a widget when it no longer needs
486
 *      an image acquired by a previous call to Tk_GetImage.  For each
487
 *      call to Tk_GetImage there must be exactly one call to Tk_FreeImage.
488
 *
489
 * Results:
490
 *      None.
491
 *
492
 * Side effects:
493
 *      The association between the image and the widget is removed.
494
 *
495
 *----------------------------------------------------------------------
496
 */
497
 
498
void
499
Tk_FreeImage(image)
500
    Tk_Image image;             /* Token for image that is no longer
501
                                 * needed by a widget. */
502
{
503
    Image *imagePtr = (Image *) image;
504
    ImageMaster *masterPtr = imagePtr->masterPtr;
505
    Image *prevPtr;
506
 
507
    /*
508
     * Clean up the particular instance.
509
     */
510
 
511
    if (masterPtr->typePtr != NULL) {
512
        (*masterPtr->typePtr->freeProc)(imagePtr->instanceData,
513
                imagePtr->display);
514
    }
515
    prevPtr = masterPtr->instancePtr;
516
    if (prevPtr == imagePtr) {
517
        masterPtr->instancePtr = imagePtr->nextPtr;
518
    } else {
519
        while (prevPtr->nextPtr != imagePtr) {
520
            prevPtr = prevPtr->nextPtr;
521
        }
522
        prevPtr->nextPtr = imagePtr->nextPtr;
523
    }
524
    ckfree((char *) imagePtr);
525
 
526
    /*
527
     * If there are no more instances left for the master, and if the
528
     * master image has been deleted, then delete the master too.
529
     */
530
 
531
    if ((masterPtr->typePtr == NULL) && (masterPtr->instancePtr == NULL)) {
532
        Tcl_DeleteHashEntry(masterPtr->hPtr);
533
        ckfree((char *) masterPtr);
534
    }
535
}
536
 
537
/*
538
 *----------------------------------------------------------------------
539
 *
540
 * Tk_RedrawImage --
541
 *
542
 *      This procedure is called by widgets that contain images in order
543
 *      to redisplay an image on the screen or an off-screen pixmap.
544
 *
545
 * Results:
546
 *      None.
547
 *
548
 * Side effects:
549
 *      The image's manager is notified, and it redraws the desired
550
 *      portion of the image before returning.
551
 *
552
 *----------------------------------------------------------------------
553
 */
554
 
555
void
556
Tk_RedrawImage(image, imageX, imageY, width, height, drawable,
557
        drawableX, drawableY)
558
    Tk_Image image;             /* Token for image to redisplay. */
559
    int imageX, imageY;         /* Upper-left pixel of region in image that
560
                                 * needs to be redisplayed. */
561
    int width, height;          /* Dimensions of region to redraw. */
562
    Drawable drawable;          /* Drawable in which to display image
563
                                 * (window or pixmap).  If this is a pixmap,
564
                                 * it must have the same depth as the window
565
                                 * used in the Tk_GetImage call for the
566
                                 * image. */
567
    int drawableX, drawableY;   /* Coordinates in drawable that correspond
568
                                 * to imageX and imageY. */
569
{
570
    Image *imagePtr = (Image *) image;
571
 
572
    if (imagePtr->masterPtr->typePtr == NULL) {
573
        /*
574
         * No master for image, so nothing to display.
575
         */
576
 
577
        return;
578
    }
579
 
580
    /*
581
     * Clip the redraw area to the area of the image.
582
     */
583
 
584
    if (imageX < 0) {
585
        width += imageX;
586
        drawableX -= imageX;
587
        imageX = 0;
588
    }
589
    if (imageY < 0) {
590
        height += imageY;
591
        drawableY -= imageY;
592
        imageY = 0;
593
    }
594
    if ((imageX + width) > imagePtr->masterPtr->width) {
595
        width = imagePtr->masterPtr->width - imageX;
596
    }
597
    if ((imageY + height) > imagePtr->masterPtr->height) {
598
        height = imagePtr->masterPtr->height - imageY;
599
    }
600
    (*imagePtr->masterPtr->typePtr->displayProc)(
601
            imagePtr->instanceData, imagePtr->display, drawable,
602
            imageX, imageY, width, height, drawableX, drawableY);
603
}
604
 
605
/*
606
 *----------------------------------------------------------------------
607
 *
608
 * Tk_SizeOfImage --
609
 *
610
 *      This procedure returns the current dimensions of an image.
611
 *
612
 * Results:
613
 *      The width and height of the image are returned in *widthPtr
614
 *      and *heightPtr.
615
 *
616
 * Side effects:
617
 *      None.
618
 *
619
 *----------------------------------------------------------------------
620
 */
621
 
622
void
623
Tk_SizeOfImage(image, widthPtr, heightPtr)
624
    Tk_Image image;             /* Token for image whose size is wanted. */
625
    int *widthPtr;              /* Return width of image here. */
626
    int *heightPtr;             /* Return height of image here. */
627
{
628
    Image *imagePtr = (Image *) image;
629
 
630
    *widthPtr = imagePtr->masterPtr->width;
631
    *heightPtr = imagePtr->masterPtr->height;
632
}
633
 
634
/*
635
 *----------------------------------------------------------------------
636
 *
637
 * Tk_DeleteImage --
638
 *
639
 *      Given the name of an image, this procedure destroys the
640
 *      image.
641
 *
642
 * Results:
643
 *      None.
644
 *
645
 * Side effects:
646
 *      The image is destroyed; existing instances will display as
647
 *      blank areas.  If no such image exists then the procedure does
648
 *      nothing.
649
 *
650
 *----------------------------------------------------------------------
651
 */
652
 
653
void
654
Tk_DeleteImage(interp, name)
655
    Tcl_Interp *interp;         /* Interpreter in which the image was
656
                                 * created. */
657
    char *name;                 /* Name of image. */
658
{
659
    Tcl_HashEntry *hPtr;
660
    TkWindow *winPtr;
661
 
662
    winPtr = (TkWindow *) Tk_MainWindow(interp);
663
    if (winPtr == NULL) {
664
        return;
665
    }
666
    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
667
    if (hPtr == NULL) {
668
        return;
669
    }
670
    DeleteImage((ImageMaster *) Tcl_GetHashValue(hPtr));
671
}
672
 
673
/*
674
 *----------------------------------------------------------------------
675
 *
676
 * DeleteImage --
677
 *
678
 *      This procedure is responsible for deleting an image.
679
 *
680
 * Results:
681
 *      None.
682
 *
683
 * Side effects:
684
 *      The connection is dropped between instances of this image and
685
 *      an image master.  Image instances will redisplay themselves
686
 *      as empty areas, but existing instances will not be deleted.
687
 *
688
 *----------------------------------------------------------------------
689
 */
690
 
691
static void
692
DeleteImage(masterPtr)
693
    ImageMaster *masterPtr;     /* Pointer to main data structure for image. */
694
{
695
    Image *imagePtr;
696
    Tk_ImageType *typePtr;
697
 
698
    typePtr = masterPtr->typePtr;
699
    masterPtr->typePtr = NULL;
700
    if (typePtr != NULL) {
701
        for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
702
                imagePtr = imagePtr->nextPtr) {
703
           (*typePtr->freeProc)(imagePtr->instanceData,
704
                   imagePtr->display);
705
           (*imagePtr->changeProc)(imagePtr->widgetClientData, 0, 0,
706
                    masterPtr->width, masterPtr->height, masterPtr->width,
707
                    masterPtr->height);
708
        }
709
        (*typePtr->deleteProc)(masterPtr->masterData);
710
    }
711
    if (masterPtr->instancePtr == NULL) {
712
        Tcl_DeleteHashEntry(masterPtr->hPtr);
713
        ckfree((char *) masterPtr);
714
    }
715
}
716
 
717
/*
718
 *----------------------------------------------------------------------
719
 *
720
 * TkDeleteAllImages --
721
 *
722
 *      This procedure is called when an application is deleted.  It
723
 *      calls back all of the managers for all images so that they
724
 *      can cleanup, then it deletes all of Tk's internal information
725
 *      about images.
726
 *
727
 * Results:
728
 *      None.
729
 *
730
 * Side effects:
731
 *      All information for all images gets deleted.
732
 *
733
 *----------------------------------------------------------------------
734
 */
735
 
736
void
737
TkDeleteAllImages(mainPtr)
738
    TkMainInfo *mainPtr;        /* Structure describing application that is
739
                                 * going away. */
740
{
741
    Tcl_HashSearch search;
742
    Tcl_HashEntry *hPtr;
743
    ImageMaster *masterPtr;
744
 
745
    for (hPtr = Tcl_FirstHashEntry(&mainPtr->imageTable, &search);
746
            hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
747
        masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
748
        DeleteImage(masterPtr);
749
    }
750
    Tcl_DeleteHashTable(&mainPtr->imageTable);
751
}
752
 
753
/*
754
 *----------------------------------------------------------------------
755
 *
756
 * Tk_GetImageMasterData --
757
 *
758
 *      Given the name of an image, this procedure returns the type
759
 *      of the image and the clientData associated with its master.
760
 *
761
 * Results:
762
 *      If there is no image by the given name, then NULL is returned
763
 *      and a NULL value is stored at *typePtrPtr.  Otherwise the return
764
 *      value is the clientData returned by the createProc when the
765
 *      image was created and a pointer to the type structure for the
766
 *      image is stored at *typePtrPtr.
767
 *
768
 * Side effects:
769
 *      None.
770
 *
771
 *----------------------------------------------------------------------
772
 */
773
 
774
ClientData
775
Tk_GetImageMasterData(interp, name, typePtrPtr)
776
    Tcl_Interp *interp;         /* Interpreter in which the image was
777
                                 * created. */
778
    char *name;                 /* Name of image. */
779
    Tk_ImageType **typePtrPtr;  /* Points to location to fill in with
780
                                 * pointer to type information for image. */
781
{
782
    Tcl_HashEntry *hPtr;
783
    TkWindow *winPtr;
784
    ImageMaster *masterPtr;
785
 
786
    winPtr = (TkWindow *) Tk_MainWindow(interp);
787
    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
788
    if (hPtr == NULL) {
789
        *typePtrPtr = NULL;
790
        return NULL;
791
    }
792
    masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
793
    *typePtrPtr = masterPtr->typePtr;
794
    return masterPtr->masterData;
795
}

powered by: WebSVN 2.1.0

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