home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / tcl / tk3.3b1 / tkCanvWind.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-16  |  22.7 KB  |  789 lines

  1. /* 
  2.  * tkCanvWind.c --
  3.  *
  4.  *    This file implements window items for canvas widgets.
  5.  *
  6.  * Copyright (c) 1992-1993 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * Permission is hereby granted, without written agreement and without
  10.  * license or royalty fees, to use, copy, modify, and distribute this
  11.  * software and its documentation for any purpose, provided that the
  12.  * above copyright notice and the following two paragraphs appear in
  13.  * all copies of this software.
  14.  * 
  15.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  16.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  17.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  18.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  19.  *
  20.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  21.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  22.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  23.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  24.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  25.  */
  26.  
  27. #ifndef lint
  28. static char rcsid[] = "$Header: /user6/ouster/wish/RCS/tkCanvWind.c,v 1.8 93/06/16 17:16:45 ouster Exp $ SPRITE (Berkeley)";
  29. #endif
  30.  
  31. #include <stdio.h>
  32. #include <math.h>
  33. #include "tkInt.h"
  34. #include "tkCanvas.h"
  35.  
  36. /*
  37.  * The structure below defines the record for each window item.
  38.  */
  39.  
  40. typedef struct WindowItem  {
  41.     Tk_Item header;        /* Generic stuff that's the same for all
  42.                  * types.  MUST BE FIRST IN STRUCTURE. */
  43.     double x, y;        /* Coordinates of positioning point for
  44.                  * window. */
  45.     Tk_Window tkwin;        /* Window associated with item.  NULL means
  46.                  * window has been destroyed. */
  47.     int width;            /* Width to use for window (<= 0 means use
  48.                  * window's requested width). */
  49.     int height;            /* Width to use for window (<= 0 means use
  50.                  * window's requested width). */
  51.     Tk_Anchor anchor;        /* Where to anchor window relative to
  52.                  * (x,y). */
  53.     Tk_Canvas *canvasPtr;    /* Canvas containing this item. */
  54. } WindowItem;
  55.  
  56. /*
  57.  * Information used for parsing configuration specs:
  58.  */
  59.  
  60. static Tk_ConfigSpec configSpecs[] = {
  61.     {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
  62.     "center", Tk_Offset(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT},
  63.     {TK_CONFIG_PIXELS, "-height", (char *) NULL, (char *) NULL,
  64.     "0", Tk_Offset(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT},
  65.     {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
  66.     (char *) NULL, 0, TK_CONFIG_NULL_OK, &tkCanvasTagsOption},
  67.     {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL,
  68.     "0", Tk_Offset(WindowItem, width), TK_CONFIG_DONT_SET_DEFAULT},
  69.     {TK_CONFIG_WINDOW, "-window", (char *) NULL, (char *) NULL,
  70.     (char *) NULL, Tk_Offset(WindowItem, tkwin), TK_CONFIG_NULL_OK},
  71.     {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
  72.     (char *) NULL, 0, 0}
  73. };
  74.  
  75. /*
  76.  * Prototypes for procedures defined in this file:
  77.  */
  78.  
  79. static void        ComputeWindowBbox _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  80.                 WindowItem *winItemPtr));
  81. static int        ConfigureWinItem _ANSI_ARGS_((
  82.                 Tk_Canvas *canvasPtr, Tk_Item *itemPtr, int argc,
  83.                 char **argv, int flags));
  84. static int        CreateWinItem _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  85.                 struct Tk_Item *itemPtr, int argc, char **argv));
  86. static void        DeleteWinItem _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  87.                 Tk_Item *itemPtr));
  88. static void        DisplayWinItem _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  89.                 Tk_Item *itemPtr, Drawable dst));
  90. static void        ScaleWinItem _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  91.                 Tk_Item *itemPtr, double originX, double originY,
  92.                 double scaleX, double scaleY));
  93. static void        TranslateWinItem _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  94.                 Tk_Item *itemPtr, double deltaX, double deltaY));
  95. static int        WinItemCoords _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  96.                 Tk_Item *itemPtr, int argc, char **argv));
  97. static void        WinItemRequestProc _ANSI_ARGS_((ClientData clientData,
  98.                 Tk_Window tkwin));
  99. static void        WinItemStructureProc _ANSI_ARGS_((
  100.                 ClientData clientData, XEvent *eventPtr));
  101. static int        WinItemToArea _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  102.                 Tk_Item *itemPtr, double *rectPtr));
  103. static double        WinItemToPoint _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  104.                 Tk_Item *itemPtr, double *pointPtr));
  105.  
  106. /*
  107.  * The structures below defines the rectangle and oval item types
  108.  * by means of procedures that can be invoked by generic item code.
  109.  */
  110.  
  111. Tk_ItemType TkWindowType = {
  112.     "window",                /* name */
  113.     sizeof(WindowItem),            /* itemSize */
  114.     CreateWinItem,            /* createProc */
  115.     configSpecs,            /* configSpecs */
  116.     ConfigureWinItem,            /* configureProc */
  117.     WinItemCoords,            /* coordProc */
  118.     DeleteWinItem,            /* deleteProc */
  119.     DisplayWinItem,            /* displayProc */
  120.     1,                    /* alwaysRedraw */
  121.     WinItemToPoint,            /* pointProc */
  122.     WinItemToArea,            /* areaProc */
  123.     (Tk_ItemPostscriptProc *) NULL,    /* postscriptProc */
  124.     ScaleWinItem,            /* scaleProc */
  125.     TranslateWinItem,            /* translateProc */
  126.     (Tk_ItemIndexProc *) NULL,        /* indexProc */
  127.     (Tk_ItemCursorProc *) NULL,        /* cursorProc */
  128.     (Tk_ItemSelectionProc *) NULL,    /* selectionProc */
  129.     (Tk_ItemInsertProc *) NULL,        /* insertProc */
  130.     (Tk_ItemDCharsProc *) NULL,        /* dTextProc */
  131.     (Tk_ItemType *) NULL        /* nextPtr */
  132. };
  133.  
  134. /*
  135.  *--------------------------------------------------------------
  136.  *
  137.  * CreateWinItem --
  138.  *
  139.  *    This procedure is invoked to create a new window
  140.  *    item in a canvas.
  141.  *
  142.  * Results:
  143.  *    A standard Tcl return value.  If an error occurred in
  144.  *    creating the item, then an error message is left in
  145.  *    canvasPtr->interp->result;  in this case itemPtr is
  146.  *    left uninitialized, so it can be safely freed by the
  147.  *    caller.
  148.  *
  149.  * Side effects:
  150.  *    A new window item is created.
  151.  *
  152.  *--------------------------------------------------------------
  153.  */
  154.  
  155. static int
  156. CreateWinItem(canvasPtr, itemPtr, argc, argv)
  157.     register Tk_Canvas *canvasPtr;    /* Canvas to hold new item. */
  158.     Tk_Item *itemPtr;            /* Record to hold new item;  header
  159.                      * has been initialized by caller. */
  160.     int argc;                /* Number of arguments in argv. */
  161.     char **argv;            /* Arguments describing rectangle. */
  162. {
  163.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  164.  
  165.     if (argc < 2) {
  166.     Tcl_AppendResult(canvasPtr->interp, "wrong # args:  should be \"",
  167.         Tk_PathName(canvasPtr->tkwin), "\" create ",
  168.         itemPtr->typePtr->name, " x y ?options?",
  169.         (char *) NULL);
  170.     return TCL_ERROR;
  171.     }
  172.  
  173.     /*
  174.      * Initialize item's record.
  175.      */
  176.  
  177.     winItemPtr->tkwin = NULL;
  178.     winItemPtr->width = 0;
  179.     winItemPtr->height = 0;
  180.     winItemPtr->anchor = TK_ANCHOR_CENTER;
  181.     winItemPtr->canvasPtr = canvasPtr;
  182.  
  183.     /*
  184.      * Process the arguments to fill in the item record.
  185.      */
  186.  
  187.     if ((TkGetCanvasCoord(canvasPtr, argv[0], &winItemPtr->x) != TCL_OK)
  188.         || (TkGetCanvasCoord(canvasPtr, argv[1],
  189.         &winItemPtr->y) != TCL_OK)) {
  190.     return TCL_ERROR;
  191.     }
  192.  
  193.     if (ConfigureWinItem(canvasPtr, itemPtr, argc-2, argv+2, 0) != TCL_OK) {
  194.     DeleteWinItem(canvasPtr, itemPtr);
  195.     return TCL_ERROR;
  196.     }
  197.     return TCL_OK;
  198. }
  199.  
  200. /*
  201.  *--------------------------------------------------------------
  202.  *
  203.  * WinItemCoords --
  204.  *
  205.  *    This procedure is invoked to process the "coords" widget
  206.  *    command on window items.  See the user documentation for
  207.  *    details on what it does.
  208.  *
  209.  * Results:
  210.  *    Returns TCL_OK or TCL_ERROR, and sets canvasPtr->interp->result.
  211.  *
  212.  * Side effects:
  213.  *    The coordinates for the given item may be changed.
  214.  *
  215.  *--------------------------------------------------------------
  216.  */
  217.  
  218. static int
  219. WinItemCoords(canvasPtr, itemPtr, argc, argv)
  220.     register Tk_Canvas *canvasPtr;    /* Canvas containing item. */
  221.     Tk_Item *itemPtr;            /* Item whose coordinates are to be
  222.                      * read or modified. */
  223.     int argc;                /* Number of coordinates supplied in
  224.                      * argv. */
  225.     char **argv;            /* Array of coordinates: x1, y1,
  226.                      * x2, y2, ... */
  227. {
  228.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  229.     char x[TCL_DOUBLE_SPACE], y[TCL_DOUBLE_SPACE];
  230.  
  231.     if (argc == 0) {
  232.     Tcl_PrintDouble(canvasPtr->interp, winItemPtr->x, x);
  233.     Tcl_PrintDouble(canvasPtr->interp, winItemPtr->y, y);
  234.     Tcl_AppendResult(canvasPtr->interp, x, " ", y, (char *) NULL);
  235.     } else if (argc == 2) {
  236.     if ((TkGetCanvasCoord(canvasPtr, argv[0], &winItemPtr->x) != TCL_OK)
  237.         || (TkGetCanvasCoord(canvasPtr, argv[1],
  238.             &winItemPtr->y) != TCL_OK)) {
  239.         return TCL_ERROR;
  240.     }
  241.     ComputeWindowBbox(canvasPtr, winItemPtr);
  242.     } else {
  243.     sprintf(canvasPtr->interp->result,
  244.         "wrong # coordinates:  expected 0 or 2, got %d",
  245.         argc);
  246.     return TCL_ERROR;
  247.     }
  248.     return TCL_OK;
  249. }
  250.  
  251. /*
  252.  *--------------------------------------------------------------
  253.  *
  254.  * ConfigureWinItem --
  255.  *
  256.  *    This procedure is invoked to configure various aspects
  257.  *    of a window item, such as its anchor position.
  258.  *
  259.  * Results:
  260.  *    A standard Tcl result code.  If an error occurs, then
  261.  *    an error message is left in canvasPtr->interp->result.
  262.  *
  263.  * Side effects:
  264.  *    Configuration information may be set for itemPtr.
  265.  *
  266.  *--------------------------------------------------------------
  267.  */
  268.  
  269. static int
  270. ConfigureWinItem(canvasPtr, itemPtr, argc, argv, flags)
  271.     Tk_Canvas *canvasPtr;    /* Canvas containing itemPtr. */
  272.     Tk_Item *itemPtr;        /* Window item to reconfigure. */
  273.     int argc;            /* Number of elements in argv.  */
  274.     char **argv;        /* Arguments describing things to configure. */
  275.     int flags;            /* Flags to pass to Tk_ConfigureWidget. */
  276. {
  277.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  278.     Tk_Window oldWindow;
  279.  
  280.     oldWindow = winItemPtr->tkwin;
  281.     if (Tk_ConfigureWidget(canvasPtr->interp, canvasPtr->tkwin,
  282.         configSpecs, argc, argv, (char *) winItemPtr, flags) != TCL_OK) {
  283.     return TCL_ERROR;
  284.     }
  285.  
  286.     /*
  287.      * A few of the options require additional processing.
  288.      */
  289.  
  290.     if (oldWindow != winItemPtr->tkwin) {
  291.     if (oldWindow != NULL) {
  292.         Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
  293.             WinItemStructureProc, (ClientData) winItemPtr);
  294.         Tk_ManageGeometry(oldWindow, (Tk_GeometryProc *) NULL,
  295.             (ClientData) NULL);
  296.         Tk_UnmapWindow(oldWindow);
  297.     }
  298.     if (winItemPtr->tkwin != NULL) {
  299.         Tk_Window ancestor, parent;
  300.  
  301.         /*
  302.          * Make sure that the canvas is either the parent of the
  303.          * window associated with the item or a descendant of that
  304.          * parent.  Also, don't allow a top-level window to be
  305.          * managed inside a canvas.
  306.          */
  307.  
  308.         parent = Tk_Parent(winItemPtr->tkwin);
  309.         for (ancestor = canvasPtr->tkwin; ;
  310.             ancestor = Tk_Parent(ancestor)) {
  311.         if (ancestor == parent) {
  312.             break;
  313.         }
  314.         if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_LEVEL) {
  315.             badWindow:
  316.             Tcl_AppendResult(canvasPtr->interp, "can't use ",
  317.                 Tk_PathName(winItemPtr->tkwin),
  318.                 " in a window item of this canvas", (char *) NULL);
  319.             winItemPtr->tkwin = NULL;
  320.             return TCL_ERROR;
  321.         }
  322.         }
  323.         if (((Tk_FakeWin *) (winItemPtr->tkwin))->flags & TK_TOP_LEVEL) {
  324.         goto badWindow;
  325.         }
  326.         if (winItemPtr->tkwin == canvasPtr->tkwin) {
  327.         goto badWindow;
  328.         }
  329.         Tk_CreateEventHandler(winItemPtr->tkwin, StructureNotifyMask,
  330.             WinItemStructureProc, (ClientData) winItemPtr);
  331.         Tk_ManageGeometry(winItemPtr->tkwin, WinItemRequestProc,
  332.             (ClientData) winItemPtr);
  333.     }
  334.     }
  335.  
  336.     ComputeWindowBbox(canvasPtr, winItemPtr);
  337.  
  338.     return TCL_OK;
  339. }
  340.  
  341. /*
  342.  *--------------------------------------------------------------
  343.  *
  344.  * DeleteWinItem --
  345.  *
  346.  *    This procedure is called to clean up the data structure
  347.  *    associated with a window item.
  348.  *
  349.  * Results:
  350.  *    None.
  351.  *
  352.  * Side effects:
  353.  *    Resources associated with itemPtr are released.
  354.  *
  355.  *--------------------------------------------------------------
  356.  */
  357.  
  358.     /* ARGSUSED */
  359. static void
  360. DeleteWinItem(canvasPtr, itemPtr)
  361.     Tk_Canvas *canvasPtr;        /* Overall info about widget. */
  362.     Tk_Item *itemPtr;            /* Item that is being deleted. */
  363. {
  364.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  365.  
  366.     if (winItemPtr->tkwin != NULL) {
  367.     Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
  368.         WinItemStructureProc, (ClientData) winItemPtr);
  369.     Tk_ManageGeometry(winItemPtr->tkwin, (Tk_GeometryProc *) NULL,
  370.         (ClientData) NULL);
  371.     Tk_UnmapWindow(winItemPtr->tkwin);
  372.     }
  373. }
  374.  
  375. /*
  376.  *--------------------------------------------------------------
  377.  *
  378.  * ComputeWindowBbox --
  379.  *
  380.  *    This procedure is invoked to compute the bounding box of
  381.  *    all the pixels that may be drawn as part of a window item.
  382.  *    This procedure is where the child window's placement is
  383.  *    computed.
  384.  *
  385.  * Results:
  386.  *    None.
  387.  *
  388.  * Side effects:
  389.  *    The fields x1, y1, x2, and y2 are updated in the header
  390.  *    for itemPtr.
  391.  *
  392.  *--------------------------------------------------------------
  393.  */
  394.  
  395.     /* ARGSUSED */
  396. static void
  397. ComputeWindowBbox(canvasPtr, winItemPtr)
  398.     Tk_Canvas *canvasPtr;        /* Canvas that contains item. */
  399.     register WindowItem *winItemPtr;    /* Item whose bbox is to be
  400.                      * recomputed. */
  401. {
  402.     int width, height, x, y;
  403.  
  404.     x = winItemPtr->x + 0.5;
  405.     y = winItemPtr->y + 0.5;
  406.  
  407.     if (winItemPtr->tkwin == NULL) {
  408.     winItemPtr->header.x1 = winItemPtr->header.x2 = x;
  409.     winItemPtr->header.y1 = winItemPtr->header.y2 = y;
  410.     return;
  411.     }
  412.  
  413.     /*
  414.      * Compute dimensions of window.
  415.      */
  416.  
  417.     width = winItemPtr->width;
  418.     if (width <= 0) {
  419.     width = Tk_ReqWidth(winItemPtr->tkwin);
  420.     if (width <= 0) {
  421.         width = 1;
  422.     }
  423.     }
  424.     height = winItemPtr->height;
  425.     if (height <= 0) {
  426.     height = Tk_ReqHeight(winItemPtr->tkwin);
  427.     if (height <= 0) {
  428.         height = 1;
  429.     }
  430.     }
  431.  
  432.     /*
  433.      * Compute location of window, using anchor information.
  434.      */
  435.  
  436.     switch (winItemPtr->anchor) {
  437.     case TK_ANCHOR_N:
  438.         x -= width/2;
  439.         break;
  440.     case TK_ANCHOR_NE:
  441.         x -= width;
  442.         break;
  443.     case TK_ANCHOR_E:
  444.         x -= width;
  445.         y -= height/2;
  446.         break;
  447.     case TK_ANCHOR_SE:
  448.         x -= width;
  449.         y -= height;
  450.         break;
  451.     case TK_ANCHOR_S:
  452.         x -= width/2;
  453.         y -= height;
  454.         break;
  455.     case TK_ANCHOR_SW:
  456.         y -= height;
  457.         break;
  458.     case TK_ANCHOR_W:
  459.         y -= height/2;
  460.         break;
  461.     case TK_ANCHOR_NW:
  462.         break;
  463.     case TK_ANCHOR_CENTER:
  464.         x -= width/2;
  465.         y -= height/2;
  466.         break;
  467.     }
  468.  
  469.     /*
  470.      * Store the information in the item header.
  471.      */
  472.  
  473.     winItemPtr->header.x1 = x;
  474.     winItemPtr->header.y1 = y;
  475.     winItemPtr->header.x2 = x + width;
  476.     winItemPtr->header.y2 = y + height;
  477. }
  478.  
  479. /*
  480.  *--------------------------------------------------------------
  481.  *
  482.  * DisplayWinItem --
  483.  *
  484.  *    This procedure is invoked to "draw" a window item in a given
  485.  *    drawable.  Since the window draws itself, we needn't do any
  486.  *    actual redisplay here.  However, this procedure takes care
  487.  *    of actually repositioning the child window so that it occupies
  488.  *    the correct screen position.
  489.  *
  490.  * Results:
  491.  *    None.
  492.  *
  493.  * Side effects:
  494.  *    The child window's position may get changed.
  495.  *
  496.  *--------------------------------------------------------------
  497.  */
  498.  
  499.     /* ARGSUSED */
  500. static void
  501. DisplayWinItem(canvasPtr, itemPtr, drawable)
  502.     register Tk_Canvas *canvasPtr;    /* Canvas that contains item. */
  503.     Tk_Item *itemPtr;            /* Item to be displayed. */
  504.     Drawable drawable;            /* Pixmap or window in which to draw
  505.                      * item. */
  506. {
  507.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  508.     int x,y, width, height;
  509.     Tk_Window ancestor, parent;
  510.  
  511.     if (winItemPtr->tkwin == NULL) {
  512.     return;
  513.     }
  514.     x = winItemPtr->header.x1 - canvasPtr->xOrigin;
  515.     y = winItemPtr->header.y1 - canvasPtr->yOrigin;
  516.     width = winItemPtr->header.x2 - winItemPtr->header.x1;
  517.     height = winItemPtr->header.y2 - winItemPtr->header.y1;
  518.  
  519.     /*
  520.      * If the canvas isn't the parent of the window, then translate the
  521.      * coordinates from those of the canvas to those of the window's
  522.      * parent.
  523.      */
  524.  
  525.     parent = Tk_Parent(winItemPtr->tkwin);
  526.     for (ancestor = canvasPtr->tkwin; ancestor != parent;
  527.         ancestor = Tk_Parent(ancestor)) {
  528.     x += Tk_X(ancestor) + Tk_Changes(ancestor)->border_width;
  529.     y += Tk_Y(ancestor) + Tk_Changes(ancestor)->border_width;
  530.     }
  531.  
  532.     /*
  533.      * Reconfigure the window if it isn't already in the correct place.
  534.      */
  535.  
  536.     if ((x != Tk_X(winItemPtr->tkwin)) || (y != Tk_Y(winItemPtr->tkwin))
  537.         || (width != Tk_Width(winItemPtr->tkwin))
  538.         || (height != Tk_Height(winItemPtr->tkwin))) {
  539.     Tk_MoveResizeWindow(winItemPtr->tkwin, x, y, (unsigned int) width,
  540.         (unsigned int) height);
  541.     }
  542.     if (!Tk_IsMapped(winItemPtr->tkwin)) {
  543.     Tk_MapWindow(winItemPtr->tkwin);
  544.     }
  545. }
  546.  
  547. /*
  548.  *--------------------------------------------------------------
  549.  *
  550.  * WinItemToPoint --
  551.  *
  552.  *    Computes the distance from a given point to a given
  553.  *    rectangle, in canvas units.
  554.  *
  555.  * Results:
  556.  *    The return value is 0 if the point whose x and y coordinates
  557.  *    are coordPtr[0] and coordPtr[1] is inside the window.  If the
  558.  *    point isn't inside the window then the return value is the
  559.  *    distance from the point to the window.
  560.  *
  561.  * Side effects:
  562.  *    None.
  563.  *
  564.  *--------------------------------------------------------------
  565.  */
  566.  
  567.     /* ARGSUSED */
  568. static double
  569. WinItemToPoint(canvasPtr, itemPtr, pointPtr)
  570.     Tk_Canvas *canvasPtr;    /* Canvas containing item. */
  571.     Tk_Item *itemPtr;        /* Item to check against point. */
  572.     double *pointPtr;        /* Pointer to x and y coordinates. */
  573. {
  574.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  575.     double x1, x2, y1, y2, xDiff, yDiff;
  576.  
  577.     x1 = winItemPtr->header.x1;
  578.     y1 = winItemPtr->header.y1;
  579.     x2 = winItemPtr->header.x2;
  580.     y2 = winItemPtr->header.y2;
  581.  
  582.     /*
  583.      * Point is outside rectangle.
  584.      */
  585.  
  586.     if (pointPtr[0] < x1) {
  587.     xDiff = x1 - pointPtr[0];
  588.     } else if (pointPtr[0] >= x2)  {
  589.     xDiff = pointPtr[0] + 1 - x2;
  590.     } else {
  591.     xDiff = 0;
  592.     }
  593.  
  594.     if (pointPtr[1] < y1) {
  595.     yDiff = y1 - pointPtr[1];
  596.     } else if (pointPtr[1] >= y2)  {
  597.     yDiff = pointPtr[1] + 1 - y2;
  598.     } else {
  599.     yDiff = 0;
  600.     }
  601.  
  602.     return hypot(xDiff, yDiff);
  603. }
  604.  
  605. /*
  606.  *--------------------------------------------------------------
  607.  *
  608.  * WinItemToArea --
  609.  *
  610.  *    This procedure is called to determine whether an item
  611.  *    lies entirely inside, entirely outside, or overlapping
  612.  *    a given rectangle.
  613.  *
  614.  * Results:
  615.  *    -1 is returned if the item is entirely outside the area
  616.  *    given by rectPtr, 0 if it overlaps, and 1 if it is entirely
  617.  *    inside the given area.
  618.  *
  619.  * Side effects:
  620.  *    None.
  621.  *
  622.  *--------------------------------------------------------------
  623.  */
  624.  
  625.     /* ARGSUSED */
  626. static int
  627. WinItemToArea(canvasPtr, itemPtr, rectPtr)
  628.     Tk_Canvas *canvasPtr;    /* Canvas containing item. */
  629.     Tk_Item *itemPtr;        /* Item to check against rectangle. */
  630.     double *rectPtr;        /* Pointer to array of four coordinates
  631.                  * (x1, y1, x2, y2) describing rectangular
  632.                  * area.  */
  633. {
  634.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  635.  
  636.     if ((rectPtr[2] <= winItemPtr->header.x1)
  637.         || (rectPtr[0] >= winItemPtr->header.x2)
  638.         || (rectPtr[3] <= winItemPtr->header.y1)
  639.         || (rectPtr[1] >= winItemPtr->header.y2)) {
  640.     return -1;
  641.     }
  642.     if ((rectPtr[0] <= winItemPtr->header.x1)
  643.         && (rectPtr[1] <= winItemPtr->header.y1)
  644.         && (rectPtr[2] >= winItemPtr->header.x2)
  645.         && (rectPtr[3] >= winItemPtr->header.y2)) {
  646.     return 1;
  647.     }
  648.     return 0;
  649. }
  650.  
  651. /*
  652.  *--------------------------------------------------------------
  653.  *
  654.  * ScaleWinItem --
  655.  *
  656.  *    This procedure is invoked to rescale a rectangle or oval
  657.  *    item.
  658.  *
  659.  * Results:
  660.  *    None.
  661.  *
  662.  * Side effects:
  663.  *    The rectangle or oval referred to by itemPtr is rescaled
  664.  *    so that the following transformation is applied to all
  665.  *    point coordinates:
  666.  *        x' = originX + scaleX*(x-originX)
  667.  *        y' = originY + scaleY*(y-originY)
  668.  *
  669.  *--------------------------------------------------------------
  670.  */
  671.  
  672. static void
  673. ScaleWinItem(canvasPtr, itemPtr, originX, originY, scaleX, scaleY)
  674.     Tk_Canvas *canvasPtr;        /* Canvas containing rectangle. */
  675.     Tk_Item *itemPtr;            /* Rectangle to be scaled. */
  676.     double originX, originY;        /* Origin about which to scale rect. */
  677.     double scaleX;            /* Amount to scale in X direction. */
  678.     double scaleY;            /* Amount to scale in Y direction. */
  679. {
  680.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  681.  
  682.     winItemPtr->x = originX + scaleX*(winItemPtr->x - originX);
  683.     winItemPtr->y = originY + scaleY*(winItemPtr->y - originY);
  684.     if (winItemPtr->width > 0) {
  685.     winItemPtr->width = scaleY*winItemPtr->width;
  686.     }
  687.     if (winItemPtr->height > 0) {
  688.     winItemPtr->height = scaleY*winItemPtr->height;
  689.     }
  690.     ComputeWindowBbox(canvasPtr, winItemPtr);
  691. }
  692.  
  693. /*
  694.  *--------------------------------------------------------------
  695.  *
  696.  * TranslateWinItem --
  697.  *
  698.  *    This procedure is called to move a rectangle or oval by a
  699.  *    given amount.
  700.  *
  701.  * Results:
  702.  *    None.
  703.  *
  704.  * Side effects:
  705.  *    The position of the rectangle or oval is offset by
  706.  *    (xDelta, yDelta), and the bounding box is updated in the
  707.  *    generic part of the item structure.
  708.  *
  709.  *--------------------------------------------------------------
  710.  */
  711.  
  712. static void
  713. TranslateWinItem(canvasPtr, itemPtr, deltaX, deltaY)
  714.     Tk_Canvas *canvasPtr;        /* Canvas containing item. */
  715.     Tk_Item *itemPtr;            /* Item that is being moved. */
  716.     double deltaX, deltaY;        /* Amount by which item is to be
  717.                      * moved. */
  718. {
  719.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  720.  
  721.     winItemPtr->x += deltaX;
  722.     winItemPtr->y += deltaY;
  723.     ComputeWindowBbox(canvasPtr, winItemPtr);
  724. }
  725.  
  726. /*
  727.  *--------------------------------------------------------------
  728.  *
  729.  * WinItemStructureProc --
  730.  *
  731.  *    This procedure is invoked whenever StructureNotify events
  732.  *    occur for a window that's managed as part of a canvas window
  733.  *    item.  This procudure's only purpose is to clean up when
  734.  *    windows are deleted.
  735.  *
  736.  * Results:
  737.  *    None.
  738.  *
  739.  * Side effects:
  740.  *    The window is disassociated from the window item when it is
  741.  *    deleted.
  742.  *
  743.  *--------------------------------------------------------------
  744.  */
  745.  
  746. static void
  747. WinItemStructureProc(clientData, eventPtr)
  748.     ClientData clientData;    /* Pointer to record describing window item. */
  749.     XEvent *eventPtr;        /* Describes what just happened. */
  750. {
  751.     register WindowItem *winItemPtr = (WindowItem *) clientData;
  752.  
  753.     if (eventPtr->type == DestroyNotify) {
  754.     winItemPtr->tkwin = NULL;
  755.     }
  756. }
  757.  
  758. /*
  759.  *--------------------------------------------------------------
  760.  *
  761.  * WinItemRequestProc --
  762.  *
  763.  *    This procedure is invoked whenever a window that's associated
  764.  *    with a window canvas item changes its requested dimensions.
  765.  *
  766.  * Results:
  767.  *    None.
  768.  *
  769.  * Side effects:
  770.  *    The size and location on the screen of the window may change,
  771.  *    depending on the options specified for the window item.
  772.  *
  773.  *--------------------------------------------------------------
  774.  */
  775.  
  776.     /* ARGSUSED */
  777. static void
  778. WinItemRequestProc(clientData, tkwin)
  779.     ClientData clientData;        /* Pointer to record for window item. */
  780.     Tk_Window tkwin;            /* Window that changed its desired
  781.                      * size. */
  782. {
  783.     WindowItem *winItemPtr = (WindowItem *) clientData;
  784.  
  785.     ComputeWindowBbox(winItemPtr->canvasPtr, winItemPtr);
  786.     DisplayWinItem(winItemPtr->canvasPtr, (Tk_Item *) winItemPtr,
  787.         (Drawable) None);
  788. }
  789.