home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tkisrc04.zip / tk / os2 / tkImage.c < prev    next >
C/C++ Source or Header  |  1998-08-07  |  22KB  |  753 lines

  1. /* 
  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.  * SCCS: @(#) tkImage.c 1.11 96/03/01 17:19:28
  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.     Tk_ImageType *typePtr2;
  114.  
  115.     typePtr2 = (Tk_ImageType *) ckalloc(sizeof(Tk_ImageType));
  116.     *typePtr2 = *typePtr;
  117.     typePtr2->name = (char *) ckalloc((unsigned) (strlen(typePtr->name) + 1));
  118.     strcpy(typePtr2->name, typePtr->name);
  119.     typePtr2->nextPtr = imageTypeList;
  120.     imageTypeList = typePtr2;
  121. }
  122.  
  123. /*
  124.  *----------------------------------------------------------------------
  125.  *
  126.  * Tk_ImageCmd --
  127.  *
  128.  *    This procedure is invoked to process the "image" Tcl command.
  129.  *    See the user documentation for details on what it does.
  130.  *
  131.  * Results:
  132.  *    A standard Tcl result.
  133.  *
  134.  * Side effects:
  135.  *    See the user documentation.
  136.  *
  137.  *----------------------------------------------------------------------
  138.  */
  139.  
  140. int
  141. Tk_ImageCmd(clientData, interp, argc, argv)
  142.     ClientData clientData;    /* Main window associated with interpreter. */
  143.     Tcl_Interp *interp;        /* Current interpreter. */
  144.     int argc;            /* Number of arguments. */
  145.     char **argv;        /* Argument strings. */
  146. {
  147.     TkWindow *winPtr = (TkWindow *) clientData;
  148.     int c, i, new, firstOption;
  149.     size_t length;
  150.     Tk_ImageType *typePtr;
  151.     ImageMaster *masterPtr;
  152.     Image *imagePtr;
  153.     Tcl_HashEntry *hPtr;
  154.     Tcl_HashSearch search;
  155.     char idString[30], *name;
  156.     static int id = 0;
  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.         argv+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.     interp->result = Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr);
  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.     sprintf(interp->result, "%d", 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.         interp->result = masterPtr->typePtr->name;
  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.     sprintf(interp->result, "%d", 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.     Tcl_CmdInfo info;
  661.     TkWindow *winPtr;
  662.  
  663.     if (Tcl_GetCommandInfo(interp, "winfo", &info) == 0) {
  664.     return;
  665.     }
  666.     winPtr = (TkWindow *) info.clientData;
  667.     hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
  668.     if (hPtr == NULL) {
  669.     return;
  670.     }
  671.     DeleteImage((ImageMaster *) Tcl_GetHashValue(hPtr));
  672. }
  673.  
  674. /*
  675.  *----------------------------------------------------------------------
  676.  *
  677.  * DeleteImage --
  678.  *
  679.  *    This procedure is responsible for deleting an image.
  680.  *
  681.  * Results:
  682.  *    None.
  683.  *
  684.  * Side effects:
  685.  *    The connection is dropped between instances of this image and
  686.  *    an image master.  Image instances will redisplay themselves
  687.  *    as empty areas, but existing instances will not be deleted.
  688.  *
  689.  *----------------------------------------------------------------------
  690.  */
  691.  
  692. static void
  693. DeleteImage(masterPtr)
  694.     ImageMaster *masterPtr;    /* Pointer to main data structure for image. */
  695. {
  696.     Image *imagePtr;
  697.     Tk_ImageType *typePtr;
  698.  
  699.     typePtr = masterPtr->typePtr;
  700.     masterPtr->typePtr = NULL;
  701.     if (typePtr != NULL) {
  702.     for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
  703.         imagePtr = imagePtr->nextPtr) {
  704.        (*typePtr->freeProc)(imagePtr->instanceData,
  705.            imagePtr->display);
  706.        (*imagePtr->changeProc)(imagePtr->widgetClientData, 0, 0,
  707.             masterPtr->width, masterPtr->height, masterPtr->width,
  708.             masterPtr->height);
  709.     }
  710.     (*typePtr->deleteProc)(masterPtr->masterData);
  711.     }
  712.     if (masterPtr->instancePtr == NULL) {
  713.     Tcl_DeleteHashEntry(masterPtr->hPtr);
  714.     ckfree((char *) masterPtr);
  715.     }
  716. }
  717.  
  718. /*
  719.  *----------------------------------------------------------------------
  720.  *
  721.  * TkDeleteAllImages --
  722.  *
  723.  *    This procedure is called when an application is deleted.  It
  724.  *    calls back all of the managers for all images so that they
  725.  *    can cleanup, then it deletes all of Tk's internal information
  726.  *    about images.
  727.  *
  728.  * Results:
  729.  *    None.
  730.  *
  731.  * Side effects:
  732.  *    All information for all images gets deleted.
  733.  *
  734.  *----------------------------------------------------------------------
  735.  */
  736.  
  737. void
  738. TkDeleteAllImages(mainPtr)
  739.     TkMainInfo *mainPtr;    /* Structure describing application that is
  740.                  * going away. */
  741. {
  742.     Tcl_HashSearch search;
  743.     Tcl_HashEntry *hPtr;
  744.     ImageMaster *masterPtr;
  745.  
  746.     for (hPtr = Tcl_FirstHashEntry(&mainPtr->imageTable, &search);
  747.         hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
  748.     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
  749.     DeleteImage(masterPtr);
  750.     }
  751.     Tcl_DeleteHashTable(&mainPtr->imageTable);
  752. }
  753.