summaryrefslogtreecommitdiffstats
path: root/tk8.6/generic/tkImage.c
diff options
context:
space:
mode:
Diffstat (limited to 'tk8.6/generic/tkImage.c')
-rw-r--r--tk8.6/generic/tkImage.c1142
1 files changed, 0 insertions, 1142 deletions
diff --git a/tk8.6/generic/tkImage.c b/tk8.6/generic/tkImage.c
deleted file mode 100644
index 359d6c6..0000000
--- a/tk8.6/generic/tkImage.c
+++ /dev/null
@@ -1,1142 +0,0 @@
-/*
- * tkImage.c --
- *
- * This module implements the image protocol, which allows lots of
- * different kinds of images to be used in lots of different widgets.
- *
- * Copyright (c) 1994 The Regents of the University of California.
- * Copyright (c) 1994-1997 Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
- */
-
-#include "tkInt.h"
-
-/*
- * Each call to Tk_GetImage returns a pointer to one of the following
- * structures, which is used as a token by clients (widgets) that display
- * images.
- */
-
-typedef struct Image {
- Tk_Window tkwin; /* Window passed to Tk_GetImage (needed to
- * "re-get" the image later if the manager
- * changes). */
- Display *display; /* Display for tkwin. Needed because when the
- * image is eventually freed tkwin may not
- * exist anymore. */
- struct ImageMaster *masterPtr;
- /* Master for this image (identifiers image
- * manager, for example). */
- ClientData instanceData; /* One word argument to pass to image manager
- * when dealing with this image instance. */
- Tk_ImageChangedProc *changeProc;
- /* Code in widget to call when image changes
- * in a way that affects redisplay. */
- ClientData widgetClientData;/* Argument to pass to changeProc. */
- struct Image *nextPtr; /* Next in list of all image instances
- * associated with the same name. */
-} Image;
-
-/*
- * For each image master there is one of the following structures, which
- * represents a name in the image table and all of the images instantiated
- * from it. Entries in mainPtr->imageTable point to these structures.
- */
-
-typedef struct ImageMaster {
- Tk_ImageType *typePtr; /* Information about image type. NULL means
- * that no image manager owns this image: the
- * image was deleted. */
- ClientData masterData; /* One-word argument to pass to image mgr when
- * dealing with the master, as opposed to
- * instances. */
- int width, height; /* Last known dimensions for image. */
- Tcl_HashTable *tablePtr; /* Pointer to hash table containing image (the
- * imageTable field in some TkMainInfo
- * structure). */
- Tcl_HashEntry *hPtr; /* Hash entry in mainPtr->imageTable for this
- * structure (used to delete the hash
- * entry). */
- Image *instancePtr; /* Pointer to first in list of instances
- * derived from this name. */
- int deleted; /* Flag set when image is being deleted. */
- TkWindow *winPtr; /* Main window of interpreter (used to detect
- * when the world is falling apart.) */
-} ImageMaster;
-
-typedef struct ThreadSpecificData {
- Tk_ImageType *imageTypeList;/* First in a list of all known image
- * types. */
- Tk_ImageType *oldImageTypeList;
- /* First in a list of all known old-style
- * image types. */
- int initialized; /* Set to 1 if we've initialized the
- * structure. */
-} ThreadSpecificData;
-static Tcl_ThreadDataKey dataKey;
-
-/*
- * Prototypes for local functions:
- */
-
-static void ImageTypeThreadExitProc(ClientData clientData);
-static void DeleteImage(ImageMaster *masterPtr);
-static void EventuallyDeleteImage(ImageMaster *masterPtr,
- int forgetImageHashNow);
-
-/*
- *----------------------------------------------------------------------
- *
- * ImageTypeThreadExitProc --
- *
- * Clean up the registered list of image types.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The thread's linked lists of photo image formats is deleted.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-ImageTypeThreadExitProc(
- ClientData clientData) /* not used */
-{
- Tk_ImageType *freePtr;
- ThreadSpecificData *tsdPtr =
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
- while (tsdPtr->oldImageTypeList != NULL) {
- freePtr = tsdPtr->oldImageTypeList;
- tsdPtr->oldImageTypeList = tsdPtr->oldImageTypeList->nextPtr;
- ckfree(freePtr);
- }
- while (tsdPtr->imageTypeList != NULL) {
- freePtr = tsdPtr->imageTypeList;
- tsdPtr->imageTypeList = tsdPtr->imageTypeList->nextPtr;
- ckfree(freePtr);
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_CreateOldImageType, Tk_CreateImageType --
- *
- * This function is invoked by an image manager to tell Tk about a new
- * kind of image and the functions that manage the new type. The function
- * is typically invoked during Tcl_AppInit.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The new image type is entered into a table used in the "image create"
- * command.
- *
- *----------------------------------------------------------------------
- */
-
-void
-Tk_CreateOldImageType(
- const Tk_ImageType *typePtr)
- /* Structure describing the type. All of the
- * fields except "nextPtr" must be filled in
- * by caller. */
-{
- Tk_ImageType *copyPtr;
- ThreadSpecificData *tsdPtr =
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
- if (!tsdPtr->initialized) {
- tsdPtr->initialized = 1;
- Tcl_CreateThreadExitHandler(ImageTypeThreadExitProc, NULL);
- }
- copyPtr = ckalloc(sizeof(Tk_ImageType));
- *copyPtr = *typePtr;
- copyPtr->nextPtr = tsdPtr->oldImageTypeList;
- tsdPtr->oldImageTypeList = copyPtr;
-}
-
-void
-Tk_CreateImageType(
- const Tk_ImageType *typePtr)
- /* Structure describing the type. All of the
- * fields except "nextPtr" must be filled in
- * by caller. */
-{
- Tk_ImageType *copyPtr;
- ThreadSpecificData *tsdPtr =
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
- if (!tsdPtr->initialized) {
- tsdPtr->initialized = 1;
- Tcl_CreateThreadExitHandler(ImageTypeThreadExitProc, NULL);
- }
- copyPtr = ckalloc(sizeof(Tk_ImageType));
- *copyPtr = *typePtr;
- copyPtr->nextPtr = tsdPtr->imageTypeList;
- tsdPtr->imageTypeList = copyPtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_ImageObjCmd --
- *
- * This function is invoked to process the "image" Tcl command. See the
- * user documentation for details on what it does.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * See the user documentation.
- *
- *----------------------------------------------------------------------
- */
-
-int
-Tk_ImageObjCmd(
- ClientData clientData, /* Main window associated with interpreter. */
- Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *const objv[]) /* Argument strings. */
-{
- static const char *const imageOptions[] = {
- "create", "delete", "height", "inuse", "names", "type", "types",
- "width", NULL
- };
- enum options {
- IMAGE_CREATE, IMAGE_DELETE, IMAGE_HEIGHT, IMAGE_INUSE, IMAGE_NAMES,
- IMAGE_TYPE, IMAGE_TYPES, IMAGE_WIDTH
- };
- TkWindow *winPtr = clientData;
- int i, isNew, firstOption, index;
- Tk_ImageType *typePtr;
- ImageMaster *masterPtr;
- Image *imagePtr;
- Tcl_HashEntry *hPtr;
- Tcl_HashSearch search;
- char idString[16 + TCL_INTEGER_SPACE];
- TkDisplay *dispPtr = winPtr->dispPtr;
- const char *arg, *name;
- Tcl_Obj *resultObj;
- ThreadSpecificData *tsdPtr =
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "option ?args?");
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObjStruct(interp, objv[1], imageOptions,
- sizeof(char *), "option", 0, &index) != TCL_OK) {
- return TCL_ERROR;
- }
- switch ((enum options) index) {
- case IMAGE_CREATE: {
- Tcl_Obj **args;
- int oldimage = 0;
-
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "type ?name? ?-option value ...?");
- return TCL_ERROR;
- }
-
- /*
- * Look up the image type.
- */
-
- arg = Tcl_GetString(objv[2]);
- for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
- typePtr = typePtr->nextPtr) {
- if ((*arg == typePtr->name[0])
- && (strcmp(arg, typePtr->name) == 0)) {
- break;
- }
- }
- if (typePtr == NULL) {
- oldimage = 1;
- for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
- typePtr = typePtr->nextPtr) {
- if ((*arg == typePtr->name[0])
- && (strcmp(arg, typePtr->name) == 0)) {
- break;
- }
- }
- }
- if (typePtr == NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "image type \"%s\" doesn't exist", arg));
- Tcl_SetErrorCode(interp, "TK", "LOOKUP", "IMAGE_TYPE", arg, NULL);
- return TCL_ERROR;
- }
-
- /*
- * Figure out a name to use for the new image.
- */
-
- if ((objc == 3) || (*(arg = Tcl_GetString(objv[3])) == '-')) {
- do {
- dispPtr->imageId++;
- sprintf(idString, "image%d", dispPtr->imageId);
- name = idString;
- } while (Tcl_FindCommand(interp, name, NULL, 0) != NULL);
- firstOption = 3;
- } else {
- TkWindow *topWin;
-
- name = arg;
- firstOption = 4;
-
- /*
- * Need to check if the _command_ that we are about to create is
- * the name of the current master widget command (normally "." but
- * could have been renamed) and fail in that case before a really
- * nasty and hard to stop crash happens.
- */
-
- topWin = (TkWindow *) TkToplevelWindowForCommand(interp, name);
- if (topWin != NULL && winPtr->mainPtr->winPtr == topWin) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "images may not be named the same as the main window",
- -1));
- Tcl_SetErrorCode(interp, "TK", "IMAGE", "SMASH_MAIN", NULL);
- return TCL_ERROR;
- }
- }
-
- /*
- * Create the data structure for the new image.
- */
-
- hPtr = Tcl_CreateHashEntry(&winPtr->mainPtr->imageTable, name, &isNew);
- if (isNew) {
- masterPtr = ckalloc(sizeof(ImageMaster));
- masterPtr->typePtr = NULL;
- masterPtr->masterData = NULL;
- masterPtr->width = masterPtr->height = 1;
- masterPtr->tablePtr = &winPtr->mainPtr->imageTable;
- masterPtr->hPtr = hPtr;
- masterPtr->instancePtr = NULL;
- masterPtr->deleted = 0;
- masterPtr->winPtr = winPtr->mainPtr->winPtr;
- Tcl_Preserve(masterPtr->winPtr);
- Tcl_SetHashValue(hPtr, masterPtr);
- } else {
- /*
- * An image already exists by this name. Disconnect the instances
- * from the master.
- */
-
- masterPtr = Tcl_GetHashValue(hPtr);
- if (masterPtr->typePtr != NULL) {
- for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
- imagePtr = imagePtr->nextPtr) {
- masterPtr->typePtr->freeProc(imagePtr->instanceData,
- imagePtr->display);
- imagePtr->changeProc(imagePtr->widgetClientData, 0, 0,
- masterPtr->width, masterPtr->height,
- masterPtr->width, masterPtr->height);
- }
- masterPtr->typePtr->deleteProc(masterPtr->masterData);
- masterPtr->typePtr = NULL;
- }
- masterPtr->deleted = 0;
- }
-
- /*
- * Call the image type manager so that it can perform its own
- * initialization, then re-"get" for any existing instances of the
- * image.
- */
-
- objv += firstOption;
- objc -= firstOption;
- args = (Tcl_Obj **) objv;
- if (oldimage) {
- int i;
-
- args = ckalloc((objc+1) * sizeof(char *));
- for (i = 0; i < objc; i++) {
- args[i] = (Tcl_Obj *) Tcl_GetString(objv[i]);
- }
- args[objc] = NULL;
- }
- Tcl_Preserve(masterPtr);
- if (typePtr->createProc(interp, name, objc, args, typePtr,
- (Tk_ImageMaster)masterPtr, &masterPtr->masterData) != TCL_OK){
- EventuallyDeleteImage(masterPtr, 0);
- Tcl_Release(masterPtr);
- if (oldimage) {
- ckfree(args);
- }
- return TCL_ERROR;
- }
- Tcl_Release(masterPtr);
- if (oldimage) {
- ckfree(args);
- }
- masterPtr->typePtr = typePtr;
- for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
- imagePtr = imagePtr->nextPtr) {
- imagePtr->instanceData = typePtr->getProc(imagePtr->tkwin,
- masterPtr->masterData);
- }
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), -1));
- break;
- }
- case IMAGE_DELETE:
- for (i = 2; i < objc; i++) {
- arg = Tcl_GetString(objv[i]);
- hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
- if (hPtr == NULL) {
- goto alreadyDeleted;
- }
- masterPtr = Tcl_GetHashValue(hPtr);
- if (masterPtr->deleted) {
- goto alreadyDeleted;
- }
- DeleteImage(masterPtr);
- }
- break;
- case IMAGE_NAMES:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
- }
- hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search);
- resultObj = Tcl_NewObj();
- for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- masterPtr = Tcl_GetHashValue(hPtr);
- if (masterPtr->deleted) {
- continue;
- }
- Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
- Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), -1));
- }
- Tcl_SetObjResult(interp, resultObj);
- break;
- case IMAGE_TYPES:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
- }
- resultObj = Tcl_NewObj();
- for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
- typePtr = typePtr->nextPtr) {
- Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
- typePtr->name, -1));
- }
- for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
- typePtr = typePtr->nextPtr) {
- Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
- typePtr->name, -1));
- }
- Tcl_SetObjResult(interp, resultObj);
- break;
-
- case IMAGE_HEIGHT:
- case IMAGE_INUSE:
- case IMAGE_TYPE:
- case IMAGE_WIDTH:
- /*
- * These operations all parse virtually identically. First check to
- * see if three args are given. Then get a non-deleted master from the
- * third arg.
- */
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "name");
- return TCL_ERROR;
- }
-
- arg = Tcl_GetString(objv[2]);
- hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
- if (hPtr == NULL) {
- goto alreadyDeleted;
- }
- masterPtr = Tcl_GetHashValue(hPtr);
- if (masterPtr->deleted) {
- goto alreadyDeleted;
- }
-
- /*
- * Now we read off the specific piece of data we were asked for.
- */
-
- switch ((enum options) index) {
- case IMAGE_HEIGHT:
- Tcl_SetObjResult(interp, Tcl_NewIntObj(masterPtr->height));
- break;
- case IMAGE_INUSE:
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
- masterPtr->typePtr && masterPtr->instancePtr));
- break;
- case IMAGE_TYPE:
- if (masterPtr->typePtr != NULL) {
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj(masterPtr->typePtr->name, -1));
- }
- break;
- case IMAGE_WIDTH:
- Tcl_SetObjResult(interp, Tcl_NewIntObj(masterPtr->width));
- break;
- default:
- Tcl_Panic("can't happen");
- }
- break;
- }
- return TCL_OK;
-
- alreadyDeleted:
- Tcl_SetObjResult(interp, Tcl_ObjPrintf("image \"%s\" doesn't exist",arg));
- Tcl_SetErrorCode(interp, "TK", "LOOKUP", "IMAGE", arg, NULL);
- return TCL_ERROR;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_ImageChanged --
- *
- * This function is called by an image manager whenever something has
- * happened that requires the image to be redrawn (some of its pixels
- * have changed, or its size has changed).
- *
- * Results:
- * None.
- *
- * Side effects:
- * Any widgets that display the image are notified so that they can
- * redisplay themselves as appropriate.
- *
- *----------------------------------------------------------------------
- */
-
-void
-Tk_ImageChanged(
- Tk_ImageMaster imageMaster, /* Image that needs redisplay. */
- int x, int y, /* Coordinates of upper-left pixel of region
- * of image that needs to be redrawn. */
- int width, int height, /* Dimensions (in pixels) of region of image
- * to redraw. If either dimension is zero then
- * the image doesn't need to be redrawn
- * (perhaps all that happened is that its size
- * changed). */
- int imageWidth, int imageHeight)
- /* New dimensions of image. */
-{
- ImageMaster *masterPtr = (ImageMaster *) imageMaster;
- Image *imagePtr;
-
- masterPtr->width = imageWidth;
- masterPtr->height = imageHeight;
- for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
- imagePtr = imagePtr->nextPtr) {
- imagePtr->changeProc(imagePtr->widgetClientData, x, y, width, height,
- imageWidth, imageHeight);
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_NameOfImage --
- *
- * Given a token for an image master, this function returns the name of
- * the image.
- *
- * Results:
- * The return value is the string name for imageMaster.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-const char *
-Tk_NameOfImage(
- Tk_ImageMaster imageMaster) /* Token for image. */
-{
- ImageMaster *masterPtr = (ImageMaster *) imageMaster;
-
- if (masterPtr->hPtr == NULL) {
- return NULL;
- }
- return Tcl_GetHashKey(masterPtr->tablePtr, masterPtr->hPtr);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_GetImage --
- *
- * This function is invoked by a widget when it wants to use a particular
- * image in a particular window.
- *
- * Results:
- * The return value is a token for the image. If there is no image by the
- * given name, then NULL is returned and an error message is left in the
- * interp's result.
- *
- * Side effects:
- * Tk records the fact that the widget is using the image, and it will
- * invoke changeProc later if the widget needs redisplay (i.e. its size
- * changes or some of its pixels change). The caller must eventually
- * invoke Tk_FreeImage when it no longer needs the image.
- *
- *----------------------------------------------------------------------
- */
-
-Tk_Image
-Tk_GetImage(
- Tcl_Interp *interp, /* Place to leave error message if image can't
- * be found. */
- Tk_Window tkwin, /* Token for window in which image will be
- * used. */
- const char *name, /* Name of desired image. */
- Tk_ImageChangedProc *changeProc,
- /* Function to invoke when redisplay is needed
- * because image's pixels or size changed. */
- ClientData clientData) /* One-word argument to pass to damageProc. */
-{
- Tcl_HashEntry *hPtr;
- ImageMaster *masterPtr;
- Image *imagePtr;
-
- hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->imageTable, name);
- if (hPtr == NULL) {
- goto noSuchImage;
- }
- masterPtr = Tcl_GetHashValue(hPtr);
- if (masterPtr->typePtr == NULL) {
- goto noSuchImage;
- }
- if (masterPtr->deleted) {
- goto noSuchImage;
- }
- imagePtr = ckalloc(sizeof(Image));
- imagePtr->tkwin = tkwin;
- imagePtr->display = Tk_Display(tkwin);
- imagePtr->masterPtr = masterPtr;
- imagePtr->instanceData =
- masterPtr->typePtr->getProc(tkwin, masterPtr->masterData);
- imagePtr->changeProc = changeProc;
- imagePtr->widgetClientData = clientData;
- imagePtr->nextPtr = masterPtr->instancePtr;
- masterPtr->instancePtr = imagePtr;
- return (Tk_Image) imagePtr;
-
- noSuchImage:
- if (interp) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "image \"%s\" doesn't exist", name));
- Tcl_SetErrorCode(interp, "TK", "LOOKUP", "IMAGE", name, NULL);
- }
- return NULL;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_FreeImage --
- *
- * This function is invoked by a widget when it no longer needs an image
- * acquired by a previous call to Tk_GetImage. For each call to
- * Tk_GetImage there must be exactly one call to Tk_FreeImage.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The association between the image and the widget is removed.
- *
- *----------------------------------------------------------------------
- */
-
-void
-Tk_FreeImage(
- Tk_Image image) /* Token for image that is no longer needed by
- * a widget. */
-{
- Image *imagePtr = (Image *) image;
- ImageMaster *masterPtr = imagePtr->masterPtr;
- Image *prevPtr;
-
- /*
- * Clean up the particular instance.
- */
-
- if (masterPtr->typePtr != NULL) {
- masterPtr->typePtr->freeProc(imagePtr->instanceData,
- imagePtr->display);
- }
- prevPtr = masterPtr->instancePtr;
- if (prevPtr == imagePtr) {
- masterPtr->instancePtr = imagePtr->nextPtr;
- } else {
- while (prevPtr->nextPtr != imagePtr) {
- prevPtr = prevPtr->nextPtr;
- }
- prevPtr->nextPtr = imagePtr->nextPtr;
- }
- ckfree(imagePtr);
-
- /*
- * If there are no more instances left for the master, and if the master
- * image has been deleted, then delete the master too.
- */
-
- if ((masterPtr->typePtr == NULL) && (masterPtr->instancePtr == NULL)) {
- if (masterPtr->hPtr != NULL) {
- Tcl_DeleteHashEntry(masterPtr->hPtr);
- }
- Tcl_Release(masterPtr->winPtr);
- ckfree(masterPtr);
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_PostscriptImage --
- *
- * This function is called by widgets that contain images in order to
- * redisplay an image on the screen or an off-screen pixmap.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The image's manager is notified, and it redraws the desired portion of
- * the image before returning.
- *
- *----------------------------------------------------------------------
- */
-
-int
-Tk_PostscriptImage(
- Tk_Image image, /* Token for image to redisplay. */
- Tcl_Interp *interp,
- Tk_Window tkwin,
- Tk_PostscriptInfo psinfo, /* postscript info */
- int x, int y, /* Upper-left pixel of region in image that
- * needs to be redisplayed. */
- int width, int height, /* Dimensions of region to redraw. */
- int prepass)
-{
- Image *imagePtr = (Image *) image;
- int result;
- XImage *ximage;
- Pixmap pmap;
- GC newGC;
- XGCValues gcValues;
-
- if (imagePtr->masterPtr->typePtr == NULL) {
- /*
- * No master for image, so nothing to display on postscript.
- */
-
- return TCL_OK;
- }
-
- /*
- * Check if an image specific postscript-generation function exists;
- * otherwise go on with generic code.
- */
-
- if (imagePtr->masterPtr->typePtr->postscriptProc != NULL) {
- return imagePtr->masterPtr->typePtr->postscriptProc(
- imagePtr->masterPtr->masterData, interp, tkwin, psinfo,
- x, y, width, height, prepass);
- }
-
- if (prepass) {
- return TCL_OK;
- }
-
- /*
- * Create a Pixmap, tell the image to redraw itself there, and then
- * generate an XImage from the Pixmap. We can then read pixel values out
- * of the XImage.
- */
-
- pmap = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin), width, height,
- Tk_Depth(tkwin));
-
- gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin));
- newGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
- if (newGC != None) {
- XFillRectangle(Tk_Display(tkwin), pmap, newGC, 0, 0,
- (unsigned) width, (unsigned) height);
- Tk_FreeGC(Tk_Display(tkwin), newGC);
- }
-
- Tk_RedrawImage(image, x, y, width, height, pmap, 0, 0);
-
- ximage = XGetImage(Tk_Display(tkwin), pmap, 0, 0,
- (unsigned) width, (unsigned) height, AllPlanes, ZPixmap);
-
- Tk_FreePixmap(Tk_Display(tkwin), pmap);
-
- if (ximage == NULL) {
- /*
- * The XGetImage() function is apparently not implemented on this
- * system. Just ignore it.
- */
-
- return TCL_OK;
- }
- result = TkPostscriptImage(interp, tkwin, psinfo, ximage, x, y,
- width, height);
-
- XDestroyImage(ximage);
- return result;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_RedrawImage --
- *
- * This function is called by widgets that contain images in order to
- * redisplay an image on the screen or an off-screen pixmap.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The image's manager is notified, and it redraws the desired portion of
- * the image before returning.
- *
- *----------------------------------------------------------------------
- */
-
-void
-Tk_RedrawImage(
- Tk_Image image, /* Token for image to redisplay. */
- int imageX, int imageY, /* Upper-left pixel of region in image that
- * needs to be redisplayed. */
- int width, int height, /* Dimensions of region to redraw. */
- Drawable drawable, /* Drawable in which to display image (window
- * or pixmap). If this is a pixmap, it must
- * have the same depth as the window used in
- * the Tk_GetImage call for the image. */
- int drawableX, int drawableY)
- /* Coordinates in drawable that correspond to
- * imageX and imageY. */
-{
- Image *imagePtr = (Image *) image;
-
- if (imagePtr->masterPtr->typePtr == NULL) {
- /*
- * No master for image, so nothing to display.
- */
-
- return;
- }
-
- /*
- * Clip the redraw area to the area of the image.
- */
-
- if (imageX < 0) {
- width += imageX;
- drawableX -= imageX;
- imageX = 0;
- }
- if (imageY < 0) {
- height += imageY;
- drawableY -= imageY;
- imageY = 0;
- }
- if ((imageX + width) > imagePtr->masterPtr->width) {
- width = imagePtr->masterPtr->width - imageX;
- }
- if ((imageY + height) > imagePtr->masterPtr->height) {
- height = imagePtr->masterPtr->height - imageY;
- }
- imagePtr->masterPtr->typePtr->displayProc(imagePtr->instanceData,
- imagePtr->display, drawable, imageX, imageY, width, height,
- drawableX, drawableY);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_SizeOfImage --
- *
- * This function returns the current dimensions of an image.
- *
- * Results:
- * The width and height of the image are returned in *widthPtr and
- * *heightPtr.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-Tk_SizeOfImage(
- Tk_Image image, /* Token for image whose size is wanted. */
- int *widthPtr, /* Return width of image here. */
- int *heightPtr) /* Return height of image here. */
-{
- Image *imagePtr = (Image *) image;
-
- *widthPtr = imagePtr->masterPtr->width;
- *heightPtr = imagePtr->masterPtr->height;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_DeleteImage --
- *
- * Given the name of an image, this function destroys the image.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The image is destroyed; existing instances will display as blank
- * areas. If no such image exists then the function does nothing.
- *
- *----------------------------------------------------------------------
- */
-
-void
-Tk_DeleteImage(
- Tcl_Interp *interp, /* Interpreter in which the image was
- * created. */
- const char *name) /* Name of image. */
-{
- Tcl_HashEntry *hPtr;
- TkWindow *winPtr;
-
- winPtr = (TkWindow *) Tk_MainWindow(interp);
- if (winPtr == NULL) {
- return;
- }
- hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
- if (hPtr == NULL) {
- return;
- }
- DeleteImage(Tcl_GetHashValue(hPtr));
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * DeleteImage --
- *
- * This function is responsible for deleting an image.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The connection is dropped between instances of this image and an image
- * master. Image instances will redisplay themselves as empty areas, but
- * existing instances will not be deleted.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-DeleteImage(
- ImageMaster *masterPtr) /* Pointer to main data structure for image. */
-{
- Image *imagePtr;
- Tk_ImageType *typePtr;
-
- typePtr = masterPtr->typePtr;
- masterPtr->typePtr = NULL;
- if (typePtr != NULL) {
- for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
- imagePtr = imagePtr->nextPtr) {
- typePtr->freeProc(imagePtr->instanceData, imagePtr->display);
- imagePtr->changeProc(imagePtr->widgetClientData, 0, 0,
- masterPtr->width, masterPtr->height, masterPtr->width,
- masterPtr->height);
- }
- typePtr->deleteProc(masterPtr->masterData);
- }
- if (masterPtr->instancePtr == NULL) {
- if (masterPtr->hPtr != NULL) {
- Tcl_DeleteHashEntry(masterPtr->hPtr);
- }
- Tcl_Release(masterPtr->winPtr);
- ckfree(masterPtr);
- } else {
- masterPtr->deleted = 1;
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * EventuallyDeleteImage --
- *
- * Arrange for an image to be deleted when it is safe to do so.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Image will get freed, though not until it is no longer Tcl_Preserve()d
- * by anything. May be called multiple times on the same image without
- * ill effects.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-EventuallyDeleteImage(
- ImageMaster *masterPtr, /* Pointer to main data structure for image. */
- int forgetImageHashNow) /* Flag to say whether the hash table is about
- * to vanish. */
-{
- if (forgetImageHashNow) {
- masterPtr->hPtr = NULL;
- }
- if (!masterPtr->deleted) {
- masterPtr->deleted = 1;
- Tcl_EventuallyFree(masterPtr, (Tcl_FreeProc *) DeleteImage);
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkDeleteAllImages --
- *
- * This function is called when an application is deleted. It calls back
- * all of the managers for all images so that they can cleanup, then it
- * deletes all of Tk's internal information about images.
- *
- * Results:
- * None.
- *
- * Side effects:
- * All information for all images gets deleted.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TkDeleteAllImages(
- TkMainInfo *mainPtr) /* Structure describing application that is
- * going away. */
-{
- Tcl_HashSearch search;
- Tcl_HashEntry *hPtr;
-
- for (hPtr = Tcl_FirstHashEntry(&mainPtr->imageTable, &search);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- EventuallyDeleteImage(Tcl_GetHashValue(hPtr), 1);
- }
- Tcl_DeleteHashTable(&mainPtr->imageTable);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_GetImageMasterData --
- *
- * Given the name of an image, this function returns the type of the
- * image and the clientData associated with its master.
- *
- * Results:
- * If there is no image by the given name, then NULL is returned and a
- * NULL value is stored at *typePtrPtr. Otherwise the return value is the
- * clientData returned by the createProc when the image was created and a
- * pointer to the type structure for the image is stored at *typePtrPtr.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-ClientData
-Tk_GetImageMasterData(
- Tcl_Interp *interp, /* Interpreter in which the image was
- * created. */
- const char *name, /* Name of image. */
- const Tk_ImageType **typePtrPtr)
- /* Points to location to fill in with pointer
- * to type information for image. */
-{
- TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp);
- Tcl_HashEntry *hPtr;
- ImageMaster *masterPtr;
-
- hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
- if (hPtr == NULL) {
- *typePtrPtr = NULL;
- return NULL;
- }
- masterPtr = Tcl_GetHashValue(hPtr);
- if (masterPtr->deleted) {
- *typePtrPtr = NULL;
- return NULL;
- }
- *typePtrPtr = masterPtr->typePtr;
- return masterPtr->masterData;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_SetTSOrigin --
- *
- * Set the pattern origin of the tile to a common point (i.e. the origin
- * (0,0) of the top level window) so that tiles from two different
- * widgets will match up. This done by setting the GCTileStipOrigin field
- * is set to the translated origin of the toplevel window in the
- * hierarchy.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * The GCTileStipOrigin is reset in the GC. This will cause the tile
- * origin to change when the GC is used for drawing.
- *
- *----------------------------------------------------------------------
- */
-
-/*ARGSUSED*/
-void
-Tk_SetTSOrigin(
- Tk_Window tkwin,
- GC gc,
- int x, int y)
-{
- while (!Tk_TopWinHierarchy(tkwin)) {
- x -= Tk_X(tkwin) + Tk_Changes(tkwin)->border_width;
- y -= Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width;
- tkwin = Tk_Parent(tkwin);
- }
- XSetTSOrigin(Tk_Display(tkwin), gc, x, y);
-}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */