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

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