/*1* tkCanvWind.c --2*3* This file implements window items for canvas widgets.4*5* Copyright (c) 1992-1994 The Regents of the University of California.6* Copyright (c) 1994-1995 Sun Microsystems, Inc.7*8* See the file "license.terms" for information on usage and redistribution9* of this file, and for a DISCLAIMER OF ALL WARRANTIES.10*11* SCCS: @(#) tkCanvWind.c 1.26 96/09/06 08:41:5212*/1314#include "tkInt.h"15#include "tkCanvas.h"1617/*18* The structure below defines the record for each window item.19*/2021typedef struct WindowItem {22Tk_Item header; /* Generic stuff that's the same for all23* types. MUST BE FIRST IN STRUCTURE. */24double x, y; /* Coordinates of positioning point for25* window. */26Tk_Window tkwin; /* Window associated with item. NULL means27* window has been destroyed. */28int width; /* Width to use for window (<= 0 means use29* window's requested width). */30int height; /* Width to use for window (<= 0 means use31* window's requested width). */32Tk_Anchor anchor; /* Where to anchor window relative to33* (x,y). */34Tk_Canvas canvas; /* Canvas containing this item. */35} WindowItem;3637/*38* Information used for parsing configuration specs:39*/4041static Tk_CustomOption tagsOption = {Tk_CanvasTagsParseProc,42Tk_CanvasTagsPrintProc, (ClientData) NULL43};4445static Tk_ConfigSpec configSpecs[] = {46{TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,47"center", Tk_Offset(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT},48{TK_CONFIG_PIXELS, "-height", (char *) NULL, (char *) NULL,49"0", Tk_Offset(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT},50{TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,51(char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},52{TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL,53"0", Tk_Offset(WindowItem, width), TK_CONFIG_DONT_SET_DEFAULT},54{TK_CONFIG_WINDOW, "-window", (char *) NULL, (char *) NULL,55(char *) NULL, Tk_Offset(WindowItem, tkwin), TK_CONFIG_NULL_OK},56{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,57(char *) NULL, 0, 0}58};5960/*61* Prototypes for procedures defined in this file:62*/6364static void ComputeWindowBbox _ANSI_ARGS_((Tk_Canvas canvas,65WindowItem *winItemPtr));66static int ConfigureWinItem _ANSI_ARGS_((Tcl_Interp *interp,67Tk_Canvas canvas, Tk_Item *itemPtr, int argc,68char **argv, int flags));69static int CreateWinItem _ANSI_ARGS_((Tcl_Interp *interp,70Tk_Canvas canvas, struct Tk_Item *itemPtr,71int argc, char **argv));72static void DeleteWinItem _ANSI_ARGS_((Tk_Canvas canvas,73Tk_Item *itemPtr, Display *display));74static void DisplayWinItem _ANSI_ARGS_((Tk_Canvas canvas,75Tk_Item *itemPtr, Display *display, Drawable dst,76int x, int y, int width, int height));77static void ScaleWinItem _ANSI_ARGS_((Tk_Canvas canvas,78Tk_Item *itemPtr, double originX, double originY,79double scaleX, double scaleY));80static void TranslateWinItem _ANSI_ARGS_((Tk_Canvas canvas,81Tk_Item *itemPtr, double deltaX, double deltaY));82static int WinItemCoords _ANSI_ARGS_((Tcl_Interp *interp,83Tk_Canvas canvas, Tk_Item *itemPtr, int argc,84char **argv));85static void WinItemLostSlaveProc _ANSI_ARGS_((86ClientData clientData, Tk_Window tkwin));87static void WinItemRequestProc _ANSI_ARGS_((ClientData clientData,88Tk_Window tkwin));89static void WinItemStructureProc _ANSI_ARGS_((90ClientData clientData, XEvent *eventPtr));91static int WinItemToArea _ANSI_ARGS_((Tk_Canvas canvas,92Tk_Item *itemPtr, double *rectPtr));93static double WinItemToPoint _ANSI_ARGS_((Tk_Canvas canvas,94Tk_Item *itemPtr, double *pointPtr));9596/*97* The structure below defines the window item type by means of procedures98* that can be invoked by generic item code.99*/100101Tk_ItemType tkWindowType = {102"window", /* name */103sizeof(WindowItem), /* itemSize */104CreateWinItem, /* createProc */105configSpecs, /* configSpecs */106ConfigureWinItem, /* configureProc */107WinItemCoords, /* coordProc */108DeleteWinItem, /* deleteProc */109DisplayWinItem, /* displayProc */1101, /* alwaysRedraw */111WinItemToPoint, /* pointProc */112WinItemToArea, /* areaProc */113(Tk_ItemPostscriptProc *) NULL, /* postscriptProc */114ScaleWinItem, /* scaleProc */115TranslateWinItem, /* translateProc */116(Tk_ItemIndexProc *) NULL, /* indexProc */117(Tk_ItemCursorProc *) NULL, /* cursorProc */118(Tk_ItemSelectionProc *) NULL, /* selectionProc */119(Tk_ItemInsertProc *) NULL, /* insertProc */120(Tk_ItemDCharsProc *) NULL, /* dTextProc */121(Tk_ItemType *) NULL /* nextPtr */122};123124125/*126* The structure below defines the official type record for the127* placer:128*/129130static Tk_GeomMgr canvasGeomType = {131"canvas", /* name */132WinItemRequestProc, /* requestProc */133WinItemLostSlaveProc, /* lostSlaveProc */134};135136/*137*--------------------------------------------------------------138*139* CreateWinItem --140*141* This procedure is invoked to create a new window142* item in a canvas.143*144* Results:145* A standard Tcl return value. If an error occurred in146* creating the item, then an error message is left in147* interp->result; in this case itemPtr is148* left uninitialized, so it can be safely freed by the149* caller.150*151* Side effects:152* A new window item is created.153*154*--------------------------------------------------------------155*/156157static int158CreateWinItem(interp, canvas, itemPtr, argc, argv)159Tcl_Interp *interp; /* Interpreter for error reporting. */160Tk_Canvas canvas; /* Canvas to hold new item. */161Tk_Item *itemPtr; /* Record to hold new item; header162* has been initialized by caller. */163int argc; /* Number of arguments in argv. */164char **argv; /* Arguments describing rectangle. */165{166WindowItem *winItemPtr = (WindowItem *) itemPtr;167168if (argc < 2) {169Tcl_AppendResult(interp, "wrong # args: should be \"",170Tk_PathName(Tk_CanvasTkwin(canvas)), " create ",171itemPtr->typePtr->name, " x y ?options?\"",172(char *) NULL);173return TCL_ERROR;174}175176/*177* Initialize item's record.178*/179180winItemPtr->tkwin = NULL;181winItemPtr->width = 0;182winItemPtr->height = 0;183winItemPtr->anchor = TK_ANCHOR_CENTER;184winItemPtr->canvas = canvas;185186/*187* Process the arguments to fill in the item record.188*/189190if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &winItemPtr->x) != TCL_OK)191|| (Tk_CanvasGetCoord(interp, canvas, argv[1],192&winItemPtr->y) != TCL_OK)) {193return TCL_ERROR;194}195196if (ConfigureWinItem(interp, canvas, itemPtr, argc-2, argv+2, 0)197!= TCL_OK) {198DeleteWinItem(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));199return TCL_ERROR;200}201return TCL_OK;202}203204/*205*--------------------------------------------------------------206*207* WinItemCoords --208*209* This procedure is invoked to process the "coords" widget210* command on window items. See the user documentation for211* details on what it does.212*213* Results:214* Returns TCL_OK or TCL_ERROR, and sets interp->result.215*216* Side effects:217* The coordinates for the given item may be changed.218*219*--------------------------------------------------------------220*/221222static int223WinItemCoords(interp, canvas, itemPtr, argc, argv)224Tcl_Interp *interp; /* Used for error reporting. */225Tk_Canvas canvas; /* Canvas containing item. */226Tk_Item *itemPtr; /* Item whose coordinates are to be227* read or modified. */228int argc; /* Number of coordinates supplied in229* argv. */230char **argv; /* Array of coordinates: x1, y1,231* x2, y2, ... */232{233WindowItem *winItemPtr = (WindowItem *) itemPtr;234char x[TCL_DOUBLE_SPACE], y[TCL_DOUBLE_SPACE];235236if (argc == 0) {237Tcl_PrintDouble(interp, winItemPtr->x, x);238Tcl_PrintDouble(interp, winItemPtr->y, y);239Tcl_AppendResult(interp, x, " ", y, (char *) NULL);240} else if (argc == 2) {241if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &winItemPtr->x)242!= TCL_OK) || (Tk_CanvasGetCoord(interp, canvas, argv[1],243&winItemPtr->y) != TCL_OK)) {244return TCL_ERROR;245}246ComputeWindowBbox(canvas, winItemPtr);247} else {248sprintf(interp->result,249"wrong # coordinates: expected 0 or 2, got %d", argc);250return TCL_ERROR;251}252return TCL_OK;253}254255/*256*--------------------------------------------------------------257*258* ConfigureWinItem --259*260* This procedure is invoked to configure various aspects261* of a window item, such as its anchor position.262*263* Results:264* A standard Tcl result code. If an error occurs, then265* an error message is left in interp->result.266*267* Side effects:268* Configuration information may be set for itemPtr.269*270*--------------------------------------------------------------271*/272273static int274ConfigureWinItem(interp, canvas, itemPtr, argc, argv, flags)275Tcl_Interp *interp; /* Used for error reporting. */276Tk_Canvas canvas; /* Canvas containing itemPtr. */277Tk_Item *itemPtr; /* Window item to reconfigure. */278int argc; /* Number of elements in argv. */279char **argv; /* Arguments describing things to configure. */280int flags; /* Flags to pass to Tk_ConfigureWidget. */281{282WindowItem *winItemPtr = (WindowItem *) itemPtr;283Tk_Window oldWindow;284Tk_Window canvasTkwin;285286oldWindow = winItemPtr->tkwin;287canvasTkwin = Tk_CanvasTkwin(canvas);288if (Tk_ConfigureWidget(interp, canvasTkwin, configSpecs, argc, argv,289(char *) winItemPtr, flags) != TCL_OK) {290return TCL_ERROR;291}292293/*294* A few of the options require additional processing.295*/296297if (oldWindow != winItemPtr->tkwin) {298if (oldWindow != NULL) {299Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,300WinItemStructureProc, (ClientData) winItemPtr);301Tk_ManageGeometry(oldWindow, (Tk_GeomMgr *) NULL,302(ClientData) NULL);303Tk_UnmaintainGeometry(oldWindow, canvasTkwin);304Tk_UnmapWindow(oldWindow);305}306if (winItemPtr->tkwin != NULL) {307Tk_Window ancestor, parent;308309/*310* Make sure that the canvas is either the parent of the311* window associated with the item or a descendant of that312* parent. Also, don't allow a top-level window to be313* managed inside a canvas.314*/315316parent = Tk_Parent(winItemPtr->tkwin);317for (ancestor = canvasTkwin; ;318ancestor = Tk_Parent(ancestor)) {319if (ancestor == parent) {320break;321}322if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_LEVEL) {323badWindow:324Tcl_AppendResult(interp, "can't use ",325Tk_PathName(winItemPtr->tkwin),326" in a window item of this canvas", (char *) NULL);327winItemPtr->tkwin = NULL;328return TCL_ERROR;329}330}331if (((Tk_FakeWin *) (winItemPtr->tkwin))->flags & TK_TOP_LEVEL) {332goto badWindow;333}334if (winItemPtr->tkwin == canvasTkwin) {335goto badWindow;336}337Tk_CreateEventHandler(winItemPtr->tkwin, StructureNotifyMask,338WinItemStructureProc, (ClientData) winItemPtr);339Tk_ManageGeometry(winItemPtr->tkwin, &canvasGeomType,340(ClientData) winItemPtr);341}342}343344ComputeWindowBbox(canvas, winItemPtr);345346return TCL_OK;347}348349/*350*--------------------------------------------------------------351*352* DeleteWinItem --353*354* This procedure is called to clean up the data structure355* associated with a window item.356*357* Results:358* None.359*360* Side effects:361* Resources associated with itemPtr are released.362*363*--------------------------------------------------------------364*/365366static void367DeleteWinItem(canvas, itemPtr, display)368Tk_Canvas canvas; /* Overall info about widget. */369Tk_Item *itemPtr; /* Item that is being deleted. */370Display *display; /* Display containing window for371* canvas. */372{373WindowItem *winItemPtr = (WindowItem *) itemPtr;374Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);375376if (winItemPtr->tkwin != NULL) {377Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,378WinItemStructureProc, (ClientData) winItemPtr);379Tk_ManageGeometry(winItemPtr->tkwin, (Tk_GeomMgr *) NULL,380(ClientData) NULL);381if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {382Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);383}384Tk_UnmapWindow(winItemPtr->tkwin);385}386}387388/*389*--------------------------------------------------------------390*391* ComputeWindowBbox --392*393* This procedure is invoked to compute the bounding box of394* all the pixels that may be drawn as part of a window item.395* This procedure is where the child window's placement is396* computed.397*398* Results:399* None.400*401* Side effects:402* The fields x1, y1, x2, and y2 are updated in the header403* for itemPtr.404*405*--------------------------------------------------------------406*/407408static void409ComputeWindowBbox(canvas, winItemPtr)410Tk_Canvas canvas; /* Canvas that contains item. */411WindowItem *winItemPtr; /* Item whose bbox is to be412* recomputed. */413{414int width, height, x, y;415416x = winItemPtr->x + ((winItemPtr->x >= 0) ? 0.5 : - 0.5);417y = winItemPtr->y + ((winItemPtr->y >= 0) ? 0.5 : - 0.5);418419if (winItemPtr->tkwin == NULL) {420winItemPtr->header.x1 = winItemPtr->header.x2 = x;421winItemPtr->header.y1 = winItemPtr->header.y2 = y;422return;423}424425/*426* Compute dimensions of window.427*/428429width = winItemPtr->width;430if (width <= 0) {431width = Tk_ReqWidth(winItemPtr->tkwin);432if (width <= 0) {433width = 1;434}435}436height = winItemPtr->height;437if (height <= 0) {438height = Tk_ReqHeight(winItemPtr->tkwin);439if (height <= 0) {440height = 1;441}442}443444/*445* Compute location of window, using anchor information.446*/447448switch (winItemPtr->anchor) {449case TK_ANCHOR_N:450x -= width/2;451break;452case TK_ANCHOR_NE:453x -= width;454break;455case TK_ANCHOR_E:456x -= width;457y -= height/2;458break;459case TK_ANCHOR_SE:460x -= width;461y -= height;462break;463case TK_ANCHOR_S:464x -= width/2;465y -= height;466break;467case TK_ANCHOR_SW:468y -= height;469break;470case TK_ANCHOR_W:471y -= height/2;472break;473case TK_ANCHOR_NW:474break;475case TK_ANCHOR_CENTER:476x -= width/2;477y -= height/2;478break;479}480481/*482* Store the information in the item header.483*/484485winItemPtr->header.x1 = x;486winItemPtr->header.y1 = y;487winItemPtr->header.x2 = x + width;488winItemPtr->header.y2 = y + height;489}490491/*492*--------------------------------------------------------------493*494* DisplayWinItem --495*496* This procedure is invoked to "draw" a window item in a given497* drawable. Since the window draws itself, we needn't do any498* actual redisplay here. However, this procedure takes care499* of actually repositioning the child window so that it occupies500* the correct screen position.501*502* Results:503* None.504*505* Side effects:506* The child window's position may get changed. Note: this507* procedure gets called both when a window needs to be displayed508* and when it ceases to be visible on the screen (e.g. it was509* scrolled or moved off-screen or the enclosing canvas is510* unmapped).511*512*--------------------------------------------------------------513*/514515static void516DisplayWinItem(canvas, itemPtr, display, drawable, regionX, regionY,517regionWidth, regionHeight)518Tk_Canvas canvas; /* Canvas that contains item. */519Tk_Item *itemPtr; /* Item to be displayed. */520Display *display; /* Display on which to draw item. */521Drawable drawable; /* Pixmap or window in which to draw522* item. */523int regionX, regionY, regionWidth, regionHeight;524/* Describes region of canvas that525* must be redisplayed (not used). */526{527WindowItem *winItemPtr = (WindowItem *) itemPtr;528int width, height;529short x, y;530Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);531532if (winItemPtr->tkwin == NULL) {533return;534}535536Tk_CanvasWindowCoords(canvas, (double) winItemPtr->header.x1,537(double) winItemPtr->header.y1, &x, &y);538width = winItemPtr->header.x2 - winItemPtr->header.x1;539height = winItemPtr->header.y2 - winItemPtr->header.y1;540541/*542* Reposition and map the window (but in different ways depending543* on whether the canvas is the window's parent).544*/545546if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {547if ((x != Tk_X(winItemPtr->tkwin)) || (y != Tk_Y(winItemPtr->tkwin))548|| (width != Tk_Width(winItemPtr->tkwin))549|| (height != Tk_Height(winItemPtr->tkwin))) {550Tk_MoveResizeWindow(winItemPtr->tkwin, x, y, width, height);551}552Tk_MapWindow(winItemPtr->tkwin);553} else {554Tk_MaintainGeometry(winItemPtr->tkwin, canvasTkwin, x, y,555width, height);556}557}558559/*560*--------------------------------------------------------------561*562* WinItemToPoint --563*564* Computes the distance from a given point to a given565* rectangle, in canvas units.566*567* Results:568* The return value is 0 if the point whose x and y coordinates569* are coordPtr[0] and coordPtr[1] is inside the window. If the570* point isn't inside the window then the return value is the571* distance from the point to the window.572*573* Side effects:574* None.575*576*--------------------------------------------------------------577*/578579static double580WinItemToPoint(canvas, itemPtr, pointPtr)581Tk_Canvas canvas; /* Canvas containing item. */582Tk_Item *itemPtr; /* Item to check against point. */583double *pointPtr; /* Pointer to x and y coordinates. */584{585WindowItem *winItemPtr = (WindowItem *) itemPtr;586double x1, x2, y1, y2, xDiff, yDiff;587588x1 = winItemPtr->header.x1;589y1 = winItemPtr->header.y1;590x2 = winItemPtr->header.x2;591y2 = winItemPtr->header.y2;592593/*594* Point is outside rectangle.595*/596597if (pointPtr[0] < x1) {598xDiff = x1 - pointPtr[0];599} else if (pointPtr[0] >= x2) {600xDiff = pointPtr[0] + 1 - x2;601} else {602xDiff = 0;603}604605if (pointPtr[1] < y1) {606yDiff = y1 - pointPtr[1];607} else if (pointPtr[1] >= y2) {608yDiff = pointPtr[1] + 1 - y2;609} else {610yDiff = 0;611}612613return hypot(xDiff, yDiff);614}615616/*617*--------------------------------------------------------------618*619* WinItemToArea --620*621* This procedure is called to determine whether an item622* lies entirely inside, entirely outside, or overlapping623* a given rectangle.624*625* Results:626* -1 is returned if the item is entirely outside the area627* given by rectPtr, 0 if it overlaps, and 1 if it is entirely628* inside the given area.629*630* Side effects:631* None.632*633*--------------------------------------------------------------634*/635636static int637WinItemToArea(canvas, itemPtr, rectPtr)638Tk_Canvas canvas; /* Canvas containing item. */639Tk_Item *itemPtr; /* Item to check against rectangle. */640double *rectPtr; /* Pointer to array of four coordinates641* (x1, y1, x2, y2) describing rectangular642* area. */643{644WindowItem *winItemPtr = (WindowItem *) itemPtr;645646if ((rectPtr[2] <= winItemPtr->header.x1)647|| (rectPtr[0] >= winItemPtr->header.x2)648|| (rectPtr[3] <= winItemPtr->header.y1)649|| (rectPtr[1] >= winItemPtr->header.y2)) {650return -1;651}652if ((rectPtr[0] <= winItemPtr->header.x1)653&& (rectPtr[1] <= winItemPtr->header.y1)654&& (rectPtr[2] >= winItemPtr->header.x2)655&& (rectPtr[3] >= winItemPtr->header.y2)) {656return 1;657}658return 0;659}660661/*662*--------------------------------------------------------------663*664* ScaleWinItem --665*666* This procedure is invoked to rescale a rectangle or oval667* item.668*669* Results:670* None.671*672* Side effects:673* The rectangle or oval referred to by itemPtr is rescaled674* so that the following transformation is applied to all675* point coordinates:676* x' = originX + scaleX*(x-originX)677* y' = originY + scaleY*(y-originY)678*679*--------------------------------------------------------------680*/681682static void683ScaleWinItem(canvas, itemPtr, originX, originY, scaleX, scaleY)684Tk_Canvas canvas; /* Canvas containing rectangle. */685Tk_Item *itemPtr; /* Rectangle to be scaled. */686double originX, originY; /* Origin about which to scale rect. */687double scaleX; /* Amount to scale in X direction. */688double scaleY; /* Amount to scale in Y direction. */689{690WindowItem *winItemPtr = (WindowItem *) itemPtr;691692winItemPtr->x = originX + scaleX*(winItemPtr->x - originX);693winItemPtr->y = originY + scaleY*(winItemPtr->y - originY);694if (winItemPtr->width > 0) {695winItemPtr->width = scaleX*winItemPtr->width;696}697if (winItemPtr->height > 0) {698winItemPtr->height = scaleY*winItemPtr->height;699}700ComputeWindowBbox(canvas, winItemPtr);701}702703/*704*--------------------------------------------------------------705*706* TranslateWinItem --707*708* This procedure is called to move a rectangle or oval by a709* given amount.710*711* Results:712* None.713*714* Side effects:715* The position of the rectangle or oval is offset by716* (xDelta, yDelta), and the bounding box is updated in the717* generic part of the item structure.718*719*--------------------------------------------------------------720*/721722static void723TranslateWinItem(canvas, itemPtr, deltaX, deltaY)724Tk_Canvas canvas; /* Canvas containing item. */725Tk_Item *itemPtr; /* Item that is being moved. */726double deltaX, deltaY; /* Amount by which item is to be727* moved. */728{729WindowItem *winItemPtr = (WindowItem *) itemPtr;730731winItemPtr->x += deltaX;732winItemPtr->y += deltaY;733ComputeWindowBbox(canvas, winItemPtr);734}735736/*737*--------------------------------------------------------------738*739* WinItemStructureProc --740*741* This procedure is invoked whenever StructureNotify events742* occur for a window that's managed as part of a canvas window743* item. This procudure's only purpose is to clean up when744* windows are deleted.745*746* Results:747* None.748*749* Side effects:750* The window is disassociated from the window item when it is751* deleted.752*753*--------------------------------------------------------------754*/755756static void757WinItemStructureProc(clientData, eventPtr)758ClientData clientData; /* Pointer to record describing window item. */759XEvent *eventPtr; /* Describes what just happened. */760{761WindowItem *winItemPtr = (WindowItem *) clientData;762763if (eventPtr->type == DestroyNotify) {764winItemPtr->tkwin = NULL;765}766}767768/*769*--------------------------------------------------------------770*771* WinItemRequestProc --772*773* This procedure is invoked whenever a window that's associated774* with a window canvas item changes its requested dimensions.775*776* Results:777* None.778*779* Side effects:780* The size and location on the screen of the window may change,781* depending on the options specified for the window item.782*783*--------------------------------------------------------------784*/785786static void787WinItemRequestProc(clientData, tkwin)788ClientData clientData; /* Pointer to record for window item. */789Tk_Window tkwin; /* Window that changed its desired790* size. */791{792WindowItem *winItemPtr = (WindowItem *) clientData;793794ComputeWindowBbox(winItemPtr->canvas, winItemPtr);795DisplayWinItem(winItemPtr->canvas, (Tk_Item *) winItemPtr,796(Display *) NULL, (Drawable) None, 0, 0, 0, 0);797}798799/*800*--------------------------------------------------------------801*802* WinItemLostSlaveProc --803*804* This procedure is invoked by Tk whenever some other geometry805* claims control over a slave that used to be managed by us.806*807* Results:808* None.809*810* Side effects:811* Forgets all canvas-related information about the slave.812*813*--------------------------------------------------------------814*/815816/* ARGSUSED */817static void818WinItemLostSlaveProc(clientData, tkwin)819ClientData clientData; /* WindowItem structure for slave window that820* was stolen away. */821Tk_Window tkwin; /* Tk's handle for the slave window. */822{823WindowItem *winItemPtr = (WindowItem *) clientData;824Tk_Window canvasTkwin = Tk_CanvasTkwin(winItemPtr->canvas);825826Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,827WinItemStructureProc, (ClientData) winItemPtr);828if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {829Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);830}831Tk_UnmapWindow(winItemPtr->tkwin);832winItemPtr->tkwin = NULL;833}834835836