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