Annotation of micropolis/src/tk/tkcvwind.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.