OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tk/] [generic/] [tkCanvWind.c] - Blame information for rev 578

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.