4 * This module implements the image protocol, which allows lots
5 * of different kinds of images to be used in lots of different
8 * Copyright (c) 1994 The Regents of the University of California.
9 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
11 * See the file "license.terms" for information on usage and redistribution
12 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
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
26 typedef struct Image {
27 Tk_Window tkwin; /* Window passed to Tk_GetImage (needed to
28 * "re-get" the image later if the manager
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. */
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
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
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
67 Tcl_HashEntry *hPtr; /* Hash entry in mainPtr->imageTable for
68 * this structure (used to delete the hash
70 Image *instancePtr; /* Pointer to first in list of instances
71 * derived from this name. */
72 int deleted; /* Flag set when image is being deleted. */
73 TkWindow *winPtr; /* Main window of interpreter (used to
74 * detect when the world is falling apart.) */
77 typedef struct ThreadSpecificData {
78 Tk_ImageType *imageTypeList;/* First in a list of all known image
80 Tk_ImageType *oldImageTypeList;/* First in a list of all known old-style image
83 static Tcl_ThreadDataKey dataKey;
86 * Prototypes for local procedures:
89 static void DeleteImage _ANSI_ARGS_((ImageMaster *masterPtr));
90 static void EventuallyDeleteImage _ANSI_ARGS_((ImageMaster *masterPtr));
93 *----------------------------------------------------------------------
95 * Tk_CreateOldImageType, Tk_CreateImageType --
97 * This procedure is invoked by an image manager to tell Tk about
98 * a new kind of image and the procedures that manage the new type.
99 * The procedure is typically invoked during Tcl_AppInit.
105 * The new image type is entered into a table used in the "image
108 *----------------------------------------------------------------------
112 Tk_CreateOldImageType(typePtr)
113 Tk_ImageType *typePtr; /* Structure describing the type. All of
114 * the fields except "nextPtr" must be filled
115 * in by caller. Must not have been passed
116 * to Tk_CreateImageType previously. */
118 ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
119 Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
121 typePtr->nextPtr = tsdPtr->oldImageTypeList;
122 tsdPtr->oldImageTypeList = typePtr;
126 Tk_CreateImageType(typePtr)
127 Tk_ImageType *typePtr; /* Structure describing the type. All of
128 * the fields except "nextPtr" must be filled
129 * in by caller. Must not have been passed
130 * to Tk_CreateImageType previously. */
132 ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
133 Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
135 typePtr->nextPtr = tsdPtr->imageTypeList;
136 tsdPtr->imageTypeList = typePtr;
140 *----------------------------------------------------------------------
144 * This procedure is invoked to process the "image" Tcl command.
145 * See the user documentation for details on what it does.
148 * A standard Tcl result.
151 * See the user documentation.
153 *----------------------------------------------------------------------
157 Tk_ImageObjCmd(clientData, interp, objc, objv)
158 ClientData clientData; /* Main window associated with interpreter. */
159 Tcl_Interp *interp; /* Current interpreter. */
160 int objc; /* Number of arguments. */
161 Tcl_Obj *CONST objv[]; /* Argument strings. */
163 static CONST char *imageOptions[] = {
164 "create", "delete", "height", "inuse", "names", "type", "types",
165 "width", (char *) NULL
168 IMAGE_CREATE, IMAGE_DELETE, IMAGE_HEIGHT, IMAGE_INUSE, IMAGE_NAMES,
169 IMAGE_TYPE, IMAGE_TYPES, IMAGE_WIDTH
171 TkWindow *winPtr = (TkWindow *) clientData;
172 int i, new, firstOption, index;
173 Tk_ImageType *typePtr;
174 ImageMaster *masterPtr;
177 Tcl_HashSearch search;
178 char idString[16 + TCL_INTEGER_SPACE], *name;
179 TkDisplay *dispPtr = winPtr->dispPtr;
180 ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
181 Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
184 Tcl_WrongNumArgs(interp, 1, objv, "option ?args?");
188 if (Tcl_GetIndexFromObj(interp, objv[1], imageOptions, "option", 0,
192 switch ((enum options) index) {
198 Tcl_WrongNumArgs(interp, 2, objv, "type ?name? ?options?");
203 * Look up the image type.
206 arg = Tcl_GetString(objv[2]);
207 for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
208 typePtr = typePtr->nextPtr) {
209 if ((*arg == typePtr->name[0])
210 && (strcmp(arg, typePtr->name) == 0)) {
214 if (typePtr == NULL) {
216 for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
217 typePtr = typePtr->nextPtr) {
218 if ((*arg == typePtr->name[0])
219 && (strcmp(arg, typePtr->name) == 0)) {
224 if (typePtr == NULL) {
225 Tcl_AppendResult(interp, "image type \"", arg,
226 "\" doesn't exist", (char *) NULL);
231 * Figure out a name to use for the new image.
234 if ((objc == 3) || (*(arg = Tcl_GetString(objv[3])) == '-')) {
236 sprintf(idString, "image%d", dispPtr->imageId);
245 * Create the data structure for the new image.
248 hPtr = Tcl_CreateHashEntry(&winPtr->mainPtr->imageTable,
251 masterPtr = (ImageMaster *) ckalloc(sizeof(ImageMaster));
252 masterPtr->typePtr = NULL;
253 masterPtr->masterData = NULL;
254 masterPtr->width = masterPtr->height = 1;
255 masterPtr->tablePtr = &winPtr->mainPtr->imageTable;
256 masterPtr->hPtr = hPtr;
257 masterPtr->instancePtr = NULL;
258 masterPtr->deleted = 0;
259 masterPtr->winPtr = winPtr->mainPtr->winPtr;
260 Tcl_Preserve((ClientData) masterPtr->winPtr);
261 Tcl_SetHashValue(hPtr, masterPtr);
264 * An image already exists by this name. Disconnect the
265 * instances from the master.
268 masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
269 if (masterPtr->typePtr != NULL) {
270 for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
271 imagePtr = imagePtr->nextPtr) {
272 (*masterPtr->typePtr->freeProc)(
273 imagePtr->instanceData, imagePtr->display);
274 (*imagePtr->changeProc)(imagePtr->widgetClientData,
275 0, 0, masterPtr->width, masterPtr->height,
276 masterPtr->width, masterPtr->height);
278 (*masterPtr->typePtr->deleteProc)(masterPtr->masterData);
279 masterPtr->typePtr = NULL;
284 * Call the image type manager so that it can perform its own
285 * initialization, then re-"get" for any existing instances of
291 args = (Tcl_Obj **) objv;
294 args = (Tcl_Obj **) ckalloc((objc+1) * sizeof(char *));
295 for (i = 0; i < objc; i++) {
296 args[i] = (Tcl_Obj *) Tcl_GetString(objv[i]);
300 Tcl_Preserve((ClientData) masterPtr);
301 if ((*typePtr->createProc)(interp, name, objc,
302 args, typePtr, (Tk_ImageMaster) masterPtr,
303 &masterPtr->masterData) != TCL_OK) {
304 EventuallyDeleteImage(masterPtr);
305 Tcl_Release((ClientData) masterPtr);
307 ckfree((char *) args);
311 Tcl_Release((ClientData) masterPtr);
313 ckfree((char *) args);
315 masterPtr->typePtr = typePtr;
316 for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
317 imagePtr = imagePtr->nextPtr) {
318 imagePtr->instanceData = (*typePtr->getProc)(
319 imagePtr->tkwin, masterPtr->masterData);
321 Tcl_SetResult(interp,
322 Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr),
327 for (i = 2; i < objc; i++) {
328 char *arg = Tcl_GetString(objv[i]);
329 hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
331 Tcl_AppendResult(interp, "image \"", arg,
332 "\" doesn't exist", (char *) NULL);
335 DeleteImage((ImageMaster *) Tcl_GetHashValue(hPtr));
342 Tcl_WrongNumArgs(interp, 2, objv, "name");
345 arg = Tcl_GetString(objv[2]);
346 hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
348 Tcl_AppendResult(interp, "image \"", arg,
349 "\" doesn't exist", (char *) NULL);
352 masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
353 Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->height);
361 Tcl_WrongNumArgs(interp, 2, objv, "name");
364 arg = Tcl_GetString(objv[2]);
365 hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
367 Tcl_AppendResult(interp, "image \"", arg,
368 "\" doesn't exist", (char *) NULL);
371 masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
372 if (masterPtr->typePtr != NULL && masterPtr->instancePtr != NULL) {
375 Tcl_SetBooleanObj(Tcl_GetObjResult(interp), count);
381 Tcl_WrongNumArgs(interp, 2, objv, NULL);
384 hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search);
385 for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
386 Tcl_AppendElement(interp, Tcl_GetHashKey(
387 &winPtr->mainPtr->imageTable, hPtr));
395 Tcl_WrongNumArgs(interp, 2, objv, "name");
398 arg = Tcl_GetString(objv[2]);
399 hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
401 Tcl_AppendResult(interp, "image \"", arg,
402 "\" doesn't exist", (char *) NULL);
405 masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
406 if (masterPtr->typePtr != NULL) {
407 Tcl_SetResult(interp, masterPtr->typePtr->name, TCL_STATIC);
413 Tcl_WrongNumArgs(interp, 2, objv, NULL);
416 for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
417 typePtr = typePtr->nextPtr) {
418 Tcl_AppendElement(interp, typePtr->name);
420 for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
421 typePtr = typePtr->nextPtr) {
422 Tcl_AppendElement(interp, typePtr->name);
429 Tcl_WrongNumArgs(interp, 2, objv, "name");
432 arg = Tcl_GetString(objv[2]);
433 hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
435 Tcl_AppendResult(interp, "image \"", arg,
436 "\" doesn't exist", (char *) NULL);
439 masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
440 Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->width);
448 *----------------------------------------------------------------------
452 * This procedure is called by an image manager whenever something
453 * has happened that requires the image to be redrawn (some of its
454 * pixels have changed, or its size has changed).
460 * Any widgets that display the image are notified so that they
461 * can redisplay themselves as appropriate.
463 *----------------------------------------------------------------------
467 Tk_ImageChanged(imageMaster, x, y, width, height, imageWidth,
469 Tk_ImageMaster imageMaster; /* Image that needs redisplay. */
470 int x, y; /* Coordinates of upper-left pixel of
471 * region of image that needs to be
473 int width, height; /* Dimensions (in pixels) of region of
474 * image to redraw. If either dimension
475 * is zero then the image doesn't need to
476 * be redrawn (perhaps all that happened is
477 * that its size changed). */
478 int imageWidth, imageHeight;/* New dimensions of image. */
480 ImageMaster *masterPtr = (ImageMaster *) imageMaster;
483 masterPtr->width = imageWidth;
484 masterPtr->height = imageHeight;
485 for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
486 imagePtr = imagePtr->nextPtr) {
487 (*imagePtr->changeProc)(imagePtr->widgetClientData, x, y,
488 width, height, imageWidth, imageHeight);
493 *----------------------------------------------------------------------
497 * Given a token for an image master, this procedure returns
498 * the name of the image.
501 * The return value is the string name for imageMaster.
506 *----------------------------------------------------------------------
510 Tk_NameOfImage(imageMaster)
511 Tk_ImageMaster imageMaster; /* Token for image. */
513 ImageMaster *masterPtr = (ImageMaster *) imageMaster;
515 return Tcl_GetHashKey(masterPtr->tablePtr, masterPtr->hPtr);
519 *----------------------------------------------------------------------
523 * This procedure is invoked by a widget when it wants to use
524 * a particular image in a particular window.
527 * The return value is a token for the image. If there is no image
528 * by the given name, then NULL is returned and an error message is
529 * left in the interp's result.
532 * Tk records the fact that the widget is using the image, and
533 * it will invoke changeProc later if the widget needs redisplay
534 * (i.e. its size changes or some of its pixels change). The
535 * caller must eventually invoke Tk_FreeImage when it no longer
538 *----------------------------------------------------------------------
542 Tk_GetImage(interp, tkwin, name, changeProc, clientData)
543 Tcl_Interp *interp; /* Place to leave error message if image
545 Tk_Window tkwin; /* Token for window in which image will
547 CONST char *name; /* Name of desired image. */
548 Tk_ImageChangedProc *changeProc;
549 /* Procedure to invoke when redisplay is
550 * needed because image's pixels or size
552 ClientData clientData; /* One-word argument to pass to damageProc. */
555 ImageMaster *masterPtr;
558 hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->imageTable, name);
562 masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
563 if (masterPtr->typePtr == NULL) {
566 imagePtr = (Image *) ckalloc(sizeof(Image));
567 imagePtr->tkwin = tkwin;
568 imagePtr->display = Tk_Display(tkwin);
569 imagePtr->masterPtr = masterPtr;
570 imagePtr->instanceData =
571 (*masterPtr->typePtr->getProc)(tkwin, masterPtr->masterData);
572 imagePtr->changeProc = changeProc;
573 imagePtr->widgetClientData = clientData;
574 imagePtr->nextPtr = masterPtr->instancePtr;
575 masterPtr->instancePtr = imagePtr;
576 return (Tk_Image) imagePtr;
579 Tcl_AppendResult(interp, "image \"", name, "\" doesn't exist",
585 *----------------------------------------------------------------------
589 * This procedure is invoked by a widget when it no longer needs
590 * an image acquired by a previous call to Tk_GetImage. For each
591 * call to Tk_GetImage there must be exactly one call to Tk_FreeImage.
597 * The association between the image and the widget is removed.
599 *----------------------------------------------------------------------
604 Tk_Image image; /* Token for image that is no longer
605 * needed by a widget. */
607 Image *imagePtr = (Image *) image;
608 ImageMaster *masterPtr = imagePtr->masterPtr;
612 * Clean up the particular instance.
615 if (masterPtr->typePtr != NULL) {
616 (*masterPtr->typePtr->freeProc)(imagePtr->instanceData,
619 prevPtr = masterPtr->instancePtr;
620 if (prevPtr == imagePtr) {
621 masterPtr->instancePtr = imagePtr->nextPtr;
623 while (prevPtr->nextPtr != imagePtr) {
624 prevPtr = prevPtr->nextPtr;
626 prevPtr->nextPtr = imagePtr->nextPtr;
628 ckfree((char *) imagePtr);
631 * If there are no more instances left for the master, and if the
632 * master image has been deleted, then delete the master too.
635 if ((masterPtr->typePtr == NULL) && (masterPtr->instancePtr == NULL)) {
636 Tcl_DeleteHashEntry(masterPtr->hPtr);
637 ckfree((char *) masterPtr);
642 *----------------------------------------------------------------------
644 * Tk_PostscriptImage --
646 * This procedure is called by widgets that contain images in order
647 * to redisplay an image on the screen or an off-screen pixmap.
653 * The image's manager is notified, and it redraws the desired
654 * portion of the image before returning.
656 *----------------------------------------------------------------------
660 Tk_PostscriptImage(image, interp, tkwin, psinfo, x, y, width, height, prepass)
661 Tk_Image image; /* Token for image to redisplay. */
664 Tk_PostscriptInfo psinfo; /* postscript info */
665 int x, y; /* Upper-left pixel of region in image that
666 * needs to be redisplayed. */
667 int width, height; /* Dimensions of region to redraw. */
670 Image *imagePtr = (Image *) image;
677 if (imagePtr->masterPtr->typePtr == NULL) {
679 * No master for image, so nothing to display on postscript.
685 * Check if an image specific postscript-generation function
686 * exists; otherwise go on with generic code.
689 if (imagePtr->masterPtr->typePtr->postscriptProc != NULL) {
690 return (*imagePtr->masterPtr->typePtr->postscriptProc)(
691 imagePtr->masterPtr->masterData, interp, tkwin, psinfo,
692 x, y, width, height, prepass);
700 * Create a Pixmap, tell the image to redraw itself there, and then
701 * generate an XImage from the Pixmap. We can then read pixel
702 * values out of the XImage.
705 pmap = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin),
706 width, height, Tk_Depth(tkwin));
708 gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin));
709 newGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
711 XFillRectangle(Tk_Display(tkwin), pmap, newGC,
712 0, 0, (unsigned int)width, (unsigned int)height);
713 Tk_FreeGC(Tk_Display(tkwin), newGC);
716 Tk_RedrawImage(image, x, y, width, height, pmap, 0, 0);
718 ximage = XGetImage(Tk_Display(tkwin), pmap, 0, 0,
719 (unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap);
721 Tk_FreePixmap(Tk_Display(tkwin), pmap);
723 if (ximage == NULL) {
724 /* The XGetImage() function is apparently not
725 * implemented on this system. Just ignore it.
729 result = TkPostscriptImage(interp, tkwin, psinfo, ximage, x, y,
732 XDestroyImage(ximage);
737 *----------------------------------------------------------------------
741 * This procedure is called by widgets that contain images in order
742 * to redisplay an image on the screen or an off-screen pixmap.
748 * The image's manager is notified, and it redraws the desired
749 * portion of the image before returning.
751 *----------------------------------------------------------------------
755 Tk_RedrawImage(image, imageX, imageY, width, height, drawable,
756 drawableX, drawableY)
757 Tk_Image image; /* Token for image to redisplay. */
758 int imageX, imageY; /* Upper-left pixel of region in image that
759 * needs to be redisplayed. */
760 int width, height; /* Dimensions of region to redraw. */
761 Drawable drawable; /* Drawable in which to display image
762 * (window or pixmap). If this is a pixmap,
763 * it must have the same depth as the window
764 * used in the Tk_GetImage call for the
766 int drawableX, drawableY; /* Coordinates in drawable that correspond
767 * to imageX and imageY. */
769 Image *imagePtr = (Image *) image;
771 if (imagePtr->masterPtr->typePtr == NULL) {
773 * No master for image, so nothing to display.
780 * Clip the redraw area to the area of the image.
793 if ((imageX + width) > imagePtr->masterPtr->width) {
794 width = imagePtr->masterPtr->width - imageX;
796 if ((imageY + height) > imagePtr->masterPtr->height) {
797 height = imagePtr->masterPtr->height - imageY;
799 (*imagePtr->masterPtr->typePtr->displayProc)(
800 imagePtr->instanceData, imagePtr->display, drawable,
801 imageX, imageY, width, height, drawableX, drawableY);
805 *----------------------------------------------------------------------
809 * This procedure returns the current dimensions of an image.
812 * The width and height of the image are returned in *widthPtr
818 *----------------------------------------------------------------------
822 Tk_SizeOfImage(image, widthPtr, heightPtr)
823 Tk_Image image; /* Token for image whose size is wanted. */
824 int *widthPtr; /* Return width of image here. */
825 int *heightPtr; /* Return height of image here. */
827 Image *imagePtr = (Image *) image;
829 *widthPtr = imagePtr->masterPtr->width;
830 *heightPtr = imagePtr->masterPtr->height;
834 *----------------------------------------------------------------------
838 * Given the name of an image, this procedure destroys the
845 * The image is destroyed; existing instances will display as
846 * blank areas. If no such image exists then the procedure does
849 *----------------------------------------------------------------------
853 Tk_DeleteImage(interp, name)
854 Tcl_Interp *interp; /* Interpreter in which the image was
856 CONST char *name; /* Name of image. */
861 winPtr = (TkWindow *) Tk_MainWindow(interp);
862 if (winPtr == NULL) {
865 hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
869 DeleteImage((ImageMaster *)Tcl_GetHashValue(hPtr));
873 *----------------------------------------------------------------------
877 * This procedure is responsible for deleting an image.
883 * The connection is dropped between instances of this image and
884 * an image master. Image instances will redisplay themselves
885 * as empty areas, but existing instances will not be deleted.
887 *----------------------------------------------------------------------
891 DeleteImage(masterPtr)
892 ImageMaster *masterPtr; /* Pointer to main data structure for image. */
895 Tk_ImageType *typePtr;
897 typePtr = masterPtr->typePtr;
898 masterPtr->typePtr = NULL;
899 if (typePtr != NULL) {
900 for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
901 imagePtr = imagePtr->nextPtr) {
902 (*typePtr->freeProc)(imagePtr->instanceData,
904 (*imagePtr->changeProc)(imagePtr->widgetClientData, 0, 0,
905 masterPtr->width, masterPtr->height, masterPtr->width,
908 (*typePtr->deleteProc)(masterPtr->masterData);
910 if (masterPtr->instancePtr == NULL) {
911 if ((masterPtr->winPtr->flags & TK_ALREADY_DEAD) == 0) {
912 Tcl_DeleteHashEntry(masterPtr->hPtr);
914 Tcl_Release((ClientData) masterPtr->winPtr);
915 ckfree((char *) masterPtr);
920 *----------------------------------------------------------------------
922 * EventuallyDeleteImage --
924 * Arrange for an image to be deleted when it is safe to do so.
930 * Image will get freed, though not until it is no longer
931 * Tcl_Preserve()d by anything. May be called multiple times on
932 * the same image without ill effects.
934 *----------------------------------------------------------------------
938 EventuallyDeleteImage(masterPtr)
939 ImageMaster *masterPtr; /* Pointer to main data structure for image. */
941 if (!masterPtr->deleted) {
942 masterPtr->deleted = 1;
943 Tcl_EventuallyFree((ClientData) masterPtr,
944 (Tcl_FreeProc *)DeleteImage);
949 *----------------------------------------------------------------------
951 * TkDeleteAllImages --
953 * This procedure is called when an application is deleted. It
954 * calls back all of the managers for all images so that they
955 * can cleanup, then it deletes all of Tk's internal information
962 * All information for all images gets deleted.
964 *----------------------------------------------------------------------
968 TkDeleteAllImages(mainPtr)
969 TkMainInfo *mainPtr; /* Structure describing application that is
972 Tcl_HashSearch search;
975 for (hPtr = Tcl_FirstHashEntry(&mainPtr->imageTable, &search);
976 hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
977 EventuallyDeleteImage((ImageMaster *) Tcl_GetHashValue(hPtr));
979 Tcl_DeleteHashTable(&mainPtr->imageTable);
983 *----------------------------------------------------------------------
985 * Tk_GetImageMasterData --
987 * Given the name of an image, this procedure returns the type
988 * of the image and the clientData associated with its master.
991 * If there is no image by the given name, then NULL is returned
992 * and a NULL value is stored at *typePtrPtr. Otherwise the return
993 * value is the clientData returned by the createProc when the
994 * image was created and a pointer to the type structure for the
995 * image is stored at *typePtrPtr.
1000 *----------------------------------------------------------------------
1004 Tk_GetImageMasterData(interp, name, typePtrPtr)
1005 Tcl_Interp *interp; /* Interpreter in which the image was
1007 CONST char *name; /* Name of image. */
1008 Tk_ImageType **typePtrPtr; /* Points to location to fill in with
1009 * pointer to type information for image. */
1011 Tcl_HashEntry *hPtr;
1013 ImageMaster *masterPtr;
1015 winPtr = (TkWindow *) Tk_MainWindow(interp);
1016 hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
1021 masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
1022 *typePtrPtr = masterPtr->typePtr;
1023 return masterPtr->masterData;
1027 *----------------------------------------------------------------------
1031 * Set the pattern origin of the tile to a common point (i.e. the
1032 * origin (0,0) of the top level window) so that tiles from two
1033 * different widgets will match up. This done by setting the
1034 * GCTileStipOrigin field is set to the translated origin of the
1035 * toplevel window in the hierarchy.
1041 * The GCTileStipOrigin is reset in the GC. This will cause the
1042 * tile origin to change when the GC is used for drawing.
1044 *----------------------------------------------------------------------
1048 Tk_SetTSOrigin(tkwin, gc, x, y)
1053 while (!Tk_TopWinHierarchy(tkwin)) {
1054 x -= Tk_X(tkwin) + Tk_Changes(tkwin)->border_width;
1055 y -= Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width;
1056 tkwin = Tk_Parent(tkwin);
1058 XSetTSOrigin(Tk_Display(tkwin), gc, x, y);