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