/[dtapublic]/projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkcanvwind.c
ViewVC logotype

Annotation of /projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkcanvwind.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 44 - (hide annotations) (download)
Fri Oct 14 02:09:58 2016 UTC (7 years, 5 months ago) by dashley
File MIME type: text/plain
File size: 33747 byte(s)
Rename for reorganization.
1 dashley 25 /* $Header: /cvsroot/esrg/sfesrg/esrgpcpj/shared/tk_base/tkcanvwind.c,v 1.1.1.1 2001/06/13 04:58:02 dtashley Exp $ */
2    
3     /*
4     * tkCanvWind.c --
5     *
6     * This file implements window items for canvas widgets.
7     *
8     * Copyright (c) 1992-1994 The Regents of the University of California.
9     * Copyright (c) 1994-1997 Sun Microsystems, Inc.
10     *
11     * See the file "license.terms" for information on usage and redistribution
12     * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13     *
14     * RCS: @(#) $Id: tkcanvwind.c,v 1.1.1.1 2001/06/13 04:58:02 dtashley Exp $
15     */
16    
17     #include <stdio.h>
18     #include "tkInt.h"
19     #include "tkPort.h"
20     #include "tkCanvas.h"
21    
22     /*
23     * The structure below defines the record for each window item.
24     */
25    
26     typedef struct WindowItem {
27     Tk_Item header; /* Generic stuff that's the same for all
28     * types. MUST BE FIRST IN STRUCTURE. */
29     double x, y; /* Coordinates of positioning point for
30     * window. */
31     Tk_Window tkwin; /* Window associated with item. NULL means
32     * window has been destroyed. */
33     int width; /* Width to use for window (<= 0 means use
34     * window's requested width). */
35     int height; /* Width to use for window (<= 0 means use
36     * window's requested width). */
37     Tk_Anchor anchor; /* Where to anchor window relative to
38     * (x,y). */
39     Tk_Canvas canvas; /* Canvas containing this item. */
40     } WindowItem;
41    
42     /*
43     * Information used for parsing configuration specs:
44     */
45    
46     static Tk_CustomOption stateOption = {
47     (Tk_OptionParseProc *) TkStateParseProc,
48     TkStatePrintProc, (ClientData) 2
49     };
50     static Tk_CustomOption tagsOption = {
51     (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
52     Tk_CanvasTagsPrintProc, (ClientData) NULL
53     };
54    
55     static Tk_ConfigSpec configSpecs[] = {
56     {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
57     "center", Tk_Offset(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT},
58     {TK_CONFIG_PIXELS, "-height", (char *) NULL, (char *) NULL,
59     "0", Tk_Offset(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT},
60     {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
61     (char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
62     &stateOption},
63     {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
64     (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
65     {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL,
66     "0", Tk_Offset(WindowItem, width), TK_CONFIG_DONT_SET_DEFAULT},
67     {TK_CONFIG_WINDOW, "-window", (char *) NULL, (char *) NULL,
68     (char *) NULL, Tk_Offset(WindowItem, tkwin), TK_CONFIG_NULL_OK},
69     {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
70     (char *) NULL, 0, 0}
71     };
72    
73     /*
74     * Prototypes for procedures defined in this file:
75     */
76    
77     static void ComputeWindowBbox _ANSI_ARGS_((Tk_Canvas canvas,
78     WindowItem *winItemPtr));
79     static int ConfigureWinItem _ANSI_ARGS_((Tcl_Interp *interp,
80     Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
81     Tcl_Obj *CONST argv[], int flags));
82     static int CreateWinItem _ANSI_ARGS_((Tcl_Interp *interp,
83     Tk_Canvas canvas, struct Tk_Item *itemPtr,
84     int argc, Tcl_Obj *CONST argv[]));
85     static void DeleteWinItem _ANSI_ARGS_((Tk_Canvas canvas,
86     Tk_Item *itemPtr, Display *display));
87     static void DisplayWinItem _ANSI_ARGS_((Tk_Canvas canvas,
88     Tk_Item *itemPtr, Display *display, Drawable dst,
89     int x, int y, int width, int height));
90     static void ScaleWinItem _ANSI_ARGS_((Tk_Canvas canvas,
91     Tk_Item *itemPtr, double originX, double originY,
92     double scaleX, double scaleY));
93     static void TranslateWinItem _ANSI_ARGS_((Tk_Canvas canvas,
94     Tk_Item *itemPtr, double deltaX, double deltaY));
95     static int WinItemCoords _ANSI_ARGS_((Tcl_Interp *interp,
96     Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
97     Tcl_Obj *CONST argv[]));
98     static void WinItemLostSlaveProc _ANSI_ARGS_((
99     ClientData clientData, Tk_Window tkwin));
100     static void WinItemRequestProc _ANSI_ARGS_((ClientData clientData,
101     Tk_Window tkwin));
102     static void WinItemStructureProc _ANSI_ARGS_((
103     ClientData clientData, XEvent *eventPtr));
104     static int WinItemToArea _ANSI_ARGS_((Tk_Canvas canvas,
105     Tk_Item *itemPtr, double *rectPtr));
106     static int WinItemToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
107     Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
108     static double WinItemToPoint _ANSI_ARGS_((Tk_Canvas canvas,
109     Tk_Item *itemPtr, double *pointPtr));
110     #ifdef X_GetImage
111     static int xerrorhandler _ANSI_ARGS_((ClientData clientData,
112     XErrorEvent *e));
113     #endif
114     static int CanvasPsWindow _ANSI_ARGS_((Tcl_Interp *interp,
115     Tk_Window tkwin, Tk_Canvas canvas, double x,
116     double y, int width, int height));
117    
118     /*
119     * The structure below defines the window item type by means of procedures
120     * that can be invoked by generic item code.
121     */
122    
123     Tk_ItemType tkWindowType = {
124     "window", /* name */
125     sizeof(WindowItem), /* itemSize */
126     CreateWinItem, /* createProc */
127     configSpecs, /* configSpecs */
128     ConfigureWinItem, /* configureProc */
129     WinItemCoords, /* coordProc */
130     DeleteWinItem, /* deleteProc */
131     DisplayWinItem, /* displayProc */
132     1|TK_CONFIG_OBJS, /* flags */
133     WinItemToPoint, /* pointProc */
134     WinItemToArea, /* areaProc */
135     WinItemToPostscript, /* postscriptProc */
136     ScaleWinItem, /* scaleProc */
137     TranslateWinItem, /* translateProc */
138     (Tk_ItemIndexProc *) NULL, /* indexProc */
139     (Tk_ItemCursorProc *) NULL, /* cursorProc */
140     (Tk_ItemSelectionProc *) NULL, /* selectionProc */
141     (Tk_ItemInsertProc *) NULL, /* insertProc */
142     (Tk_ItemDCharsProc *) NULL, /* dTextProc */
143     (Tk_ItemType *) NULL, /* nextPtr */
144     };
145    
146    
147     /*
148     * The structure below defines the official type record for the
149     * placer:
150     */
151    
152     static Tk_GeomMgr canvasGeomType = {
153     "canvas", /* name */
154     WinItemRequestProc, /* requestProc */
155     WinItemLostSlaveProc, /* lostSlaveProc */
156     };
157    
158     /*
159     *--------------------------------------------------------------
160     *
161     * CreateWinItem --
162     *
163     * This procedure is invoked to create a new window
164     * item in a canvas.
165     *
166     * Results:
167     * A standard Tcl return value. If an error occurred in
168     * creating the item, then an error message is left in
169     * the interp's result; in this case itemPtr is
170     * left uninitialized, so it can be safely freed by the
171     * caller.
172     *
173     * Side effects:
174     * A new window item is created.
175     *
176     *--------------------------------------------------------------
177     */
178    
179     static int
180     CreateWinItem(interp, canvas, itemPtr, argc, argv)
181     Tcl_Interp *interp; /* Interpreter for error reporting. */
182     Tk_Canvas canvas; /* Canvas to hold new item. */
183     Tk_Item *itemPtr; /* Record to hold new item; header
184     * has been initialized by caller. */
185     int argc; /* Number of arguments in argv. */
186     Tcl_Obj *CONST argv[]; /* Arguments describing window. */
187     {
188     WindowItem *winItemPtr = (WindowItem *) itemPtr;
189     int i;
190    
191     if (argc==1) {
192     i = 1;
193     } else {
194     char *arg = Tcl_GetStringFromObj(argv[1], NULL);
195     if (((argc>1) && (arg[0] == '-')
196     && (arg[1] >= 'a') && (arg[1] <= 'z'))) {
197     i = 1;
198     } else {
199     i = 2;
200     }
201     }
202    
203     if (argc < i) {
204     Tcl_AppendResult(interp, "wrong # args: should be \"",
205     Tk_PathName(Tk_CanvasTkwin(canvas)), " create ",
206     itemPtr->typePtr->name, " x y ?options?\"",
207     (char *) NULL);
208     return TCL_ERROR;
209     }
210    
211     /*
212     * Initialize item's record.
213     */
214    
215     winItemPtr->tkwin = NULL;
216     winItemPtr->width = 0;
217     winItemPtr->height = 0;
218     winItemPtr->anchor = TK_ANCHOR_CENTER;
219     winItemPtr->canvas = canvas;
220    
221     /*
222     * Process the arguments to fill in the item record.
223     */
224    
225     if ((WinItemCoords(interp, canvas, itemPtr, i, argv) != TCL_OK)) {
226     goto error;
227     }
228     if (ConfigureWinItem(interp, canvas, itemPtr, argc-i, argv+i, 0) == TCL_OK) {
229     return TCL_OK;
230     }
231    
232     error:
233     DeleteWinItem(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
234     return TCL_ERROR;
235     }
236    
237     /*
238     *--------------------------------------------------------------
239     *
240     * WinItemCoords --
241     *
242     * This procedure is invoked to process the "coords" widget
243     * command on window items. See the user documentation for
244     * details on what it does.
245     *
246     * Results:
247     * Returns TCL_OK or TCL_ERROR, and sets the interp's result.
248     *
249     * Side effects:
250     * The coordinates for the given item may be changed.
251     *
252     *--------------------------------------------------------------
253     */
254    
255     static int
256     WinItemCoords(interp, canvas, itemPtr, argc, argv)
257     Tcl_Interp *interp; /* Used for error reporting. */
258     Tk_Canvas canvas; /* Canvas containing item. */
259     Tk_Item *itemPtr; /* Item whose coordinates are to be
260     * read or modified. */
261     int argc; /* Number of coordinates supplied in
262     * argv. */
263     Tcl_Obj *CONST argv[]; /* Array of coordinates: x1, y1,
264     * x2, y2, ... */
265     {
266     WindowItem *winItemPtr = (WindowItem *) itemPtr;
267    
268     if (argc == 0) {
269     Tcl_Obj *obj = Tcl_NewObj();
270     Tcl_Obj *subobj = Tcl_NewDoubleObj(winItemPtr->x);
271     Tcl_ListObjAppendElement(interp, obj, subobj);
272     subobj = Tcl_NewDoubleObj(winItemPtr->y);
273     Tcl_ListObjAppendElement(interp, obj, subobj);
274     Tcl_SetObjResult(interp, obj);
275     } else if (argc < 3) {
276     if (argc==1) {
277     if (Tcl_ListObjGetElements(interp, argv[0], &argc,
278     (Tcl_Obj ***) &argv) != TCL_OK) {
279     return TCL_ERROR;
280     } else if (argc != 2) {
281     char buf[64 + TCL_INTEGER_SPACE];
282    
283     sprintf(buf, "wrong # coordinates: expected 2, got %d", argc);
284     Tcl_SetResult(interp, buf, TCL_VOLATILE);
285     return TCL_ERROR;
286     }
287     }
288     if ((Tk_CanvasGetCoordFromObj(interp, canvas, argv[0], &winItemPtr->x)
289     != TCL_OK) || (Tk_CanvasGetCoordFromObj(interp, canvas, argv[1],
290     &winItemPtr->y) != TCL_OK)) {
291     return TCL_ERROR;
292     }
293     ComputeWindowBbox(canvas, winItemPtr);
294     } else {
295     char buf[64 + TCL_INTEGER_SPACE];
296    
297     sprintf(buf, "wrong # coordinates: expected 0 or 2, got %d", argc);
298     Tcl_SetResult(interp, buf, TCL_VOLATILE);
299     return TCL_ERROR;
300     }
301     return TCL_OK;
302     }
303    
304     /*
305     *--------------------------------------------------------------
306     *
307     * ConfigureWinItem --
308     *
309     * This procedure is invoked to configure various aspects
310     * of a window item, such as its anchor position.
311     *
312     * Results:
313     * A standard Tcl result code. If an error occurs, then
314     * an error message is left in the interp's result.
315     *
316     * Side effects:
317     * Configuration information may be set for itemPtr.
318     *
319     *--------------------------------------------------------------
320     */
321    
322     static int
323     ConfigureWinItem(interp, canvas, itemPtr, argc, argv, flags)
324     Tcl_Interp *interp; /* Used for error reporting. */
325     Tk_Canvas canvas; /* Canvas containing itemPtr. */
326     Tk_Item *itemPtr; /* Window item to reconfigure. */
327     int argc; /* Number of elements in argv. */
328     Tcl_Obj *CONST argv[]; /* Arguments describing things to configure. */
329     int flags; /* Flags to pass to Tk_ConfigureWidget. */
330     {
331     WindowItem *winItemPtr = (WindowItem *) itemPtr;
332     Tk_Window oldWindow;
333     Tk_Window canvasTkwin;
334    
335     oldWindow = winItemPtr->tkwin;
336     canvasTkwin = Tk_CanvasTkwin(canvas);
337     if (Tk_ConfigureWidget(interp, canvasTkwin, configSpecs, argc, (char **) argv,
338     (char *) winItemPtr, flags|TK_CONFIG_OBJS) != TCL_OK) {
339     return TCL_ERROR;
340     }
341    
342     /*
343     * A few of the options require additional processing.
344     */
345    
346     if (oldWindow != winItemPtr->tkwin) {
347     if (oldWindow != NULL) {
348     Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
349     WinItemStructureProc, (ClientData) winItemPtr);
350     Tk_ManageGeometry(oldWindow, (Tk_GeomMgr *) NULL,
351     (ClientData) NULL);
352     Tk_UnmaintainGeometry(oldWindow, canvasTkwin);
353     Tk_UnmapWindow(oldWindow);
354     }
355     if (winItemPtr->tkwin != NULL) {
356     Tk_Window ancestor, parent;
357    
358     /*
359     * Make sure that the canvas is either the parent of the
360     * window associated with the item or a descendant of that
361     * parent. Also, don't allow a top-level window to be
362     * managed inside a canvas.
363     */
364    
365     parent = Tk_Parent(winItemPtr->tkwin);
366     for (ancestor = canvasTkwin; ;
367     ancestor = Tk_Parent(ancestor)) {
368     if (ancestor == parent) {
369     break;
370     }
371     if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_LEVEL) {
372     badWindow:
373     Tcl_AppendResult(interp, "can't use ",
374     Tk_PathName(winItemPtr->tkwin),
375     " in a window item of this canvas", (char *) NULL);
376     winItemPtr->tkwin = NULL;
377     return TCL_ERROR;
378     }
379     }
380     if (((Tk_FakeWin *) (winItemPtr->tkwin))->flags & TK_TOP_LEVEL) {
381     goto badWindow;
382     }
383     if (winItemPtr->tkwin == canvasTkwin) {
384     goto badWindow;
385     }
386     Tk_CreateEventHandler(winItemPtr->tkwin, StructureNotifyMask,
387     WinItemStructureProc, (ClientData) winItemPtr);
388     Tk_ManageGeometry(winItemPtr->tkwin, &canvasGeomType,
389     (ClientData) winItemPtr);
390     }
391     }
392    
393     ComputeWindowBbox(canvas, winItemPtr);
394    
395     return TCL_OK;
396     }
397    
398     /*
399     *--------------------------------------------------------------
400     *
401     * DeleteWinItem --
402     *
403     * This procedure is called to clean up the data structure
404     * associated with a window item.
405     *
406     * Results:
407     * None.
408     *
409     * Side effects:
410     * Resources associated with itemPtr are released.
411     *
412     *--------------------------------------------------------------
413     */
414    
415     static void
416     DeleteWinItem(canvas, itemPtr, display)
417     Tk_Canvas canvas; /* Overall info about widget. */
418     Tk_Item *itemPtr; /* Item that is being deleted. */
419     Display *display; /* Display containing window for
420     * canvas. */
421     {
422     WindowItem *winItemPtr = (WindowItem *) itemPtr;
423     Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);
424    
425     if (winItemPtr->tkwin != NULL) {
426     Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
427     WinItemStructureProc, (ClientData) winItemPtr);
428     Tk_ManageGeometry(winItemPtr->tkwin, (Tk_GeomMgr *) NULL,
429     (ClientData) NULL);
430     if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
431     Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
432     }
433     Tk_UnmapWindow(winItemPtr->tkwin);
434     }
435     }
436    
437     /*
438     *--------------------------------------------------------------
439     *
440     * ComputeWindowBbox --
441     *
442     * This procedure is invoked to compute the bounding box of
443     * all the pixels that may be drawn as part of a window item.
444     * This procedure is where the child window's placement is
445     * computed.
446     *
447     * Results:
448     * None.
449     *
450     * Side effects:
451     * The fields x1, y1, x2, and y2 are updated in the header
452     * for itemPtr.
453     *
454     *--------------------------------------------------------------
455     */
456    
457     static void
458     ComputeWindowBbox(canvas, winItemPtr)
459     Tk_Canvas canvas; /* Canvas that contains item. */
460     WindowItem *winItemPtr; /* Item whose bbox is to be
461     * recomputed. */
462     {
463     int width, height, x, y;
464     Tk_State state = winItemPtr->header.state;
465    
466     x = (int) (winItemPtr->x + ((winItemPtr->x >= 0) ? 0.5 : - 0.5));
467     y = (int) (winItemPtr->y + ((winItemPtr->y >= 0) ? 0.5 : - 0.5));
468    
469     if (state == TK_STATE_NULL) {
470     state = ((TkCanvas *)canvas)->canvas_state;
471     }
472     if ((winItemPtr->tkwin == NULL) || (state == TK_STATE_HIDDEN)) {
473     /*
474     * There is no window for this item yet. Just give it a 1x1
475     * bounding box. Don't give it a 0x0 bounding box; there are
476     * strange cases where this bounding box might be used as the
477     * dimensions of the window, and 0x0 causes problems under X.
478     */
479    
480     winItemPtr->header.x1 = x;
481     winItemPtr->header.x2 = winItemPtr->header.x1 + 1;
482     winItemPtr->header.y1 = y;
483     winItemPtr->header.y2 = winItemPtr->header.y1 + 1;
484     return;
485     }
486    
487     /*
488     * Compute dimensions of window.
489     */
490    
491     width = winItemPtr->width;
492     if (width <= 0) {
493     width = Tk_ReqWidth(winItemPtr->tkwin);
494     if (width <= 0) {
495     width = 1;
496     }
497     }
498     height = winItemPtr->height;
499     if (height <= 0) {
500     height = Tk_ReqHeight(winItemPtr->tkwin);
501     if (height <= 0) {
502     height = 1;
503     }
504     }
505    
506     /*
507     * Compute location of window, using anchor information.
508     */
509    
510     switch (winItemPtr->anchor) {
511     case TK_ANCHOR_N:
512     x -= width/2;
513     break;
514     case TK_ANCHOR_NE:
515     x -= width;
516     break;
517     case TK_ANCHOR_E:
518     x -= width;
519     y -= height/2;
520     break;
521     case TK_ANCHOR_SE:
522     x -= width;
523     y -= height;
524     break;
525     case TK_ANCHOR_S:
526     x -= width/2;
527     y -= height;
528     break;
529     case TK_ANCHOR_SW:
530     y -= height;
531     break;
532     case TK_ANCHOR_W:
533     y -= height/2;
534     break;
535     case TK_ANCHOR_NW:
536     break;
537     case TK_ANCHOR_CENTER:
538     x -= width/2;
539     y -= height/2;
540     break;
541     }
542    
543     /*
544     * Store the information in the item header.
545     */
546    
547     winItemPtr->header.x1 = x;
548     winItemPtr->header.y1 = y;
549     winItemPtr->header.x2 = x + width;
550     winItemPtr->header.y2 = y + height;
551     }
552    
553     /*
554     *--------------------------------------------------------------
555     *
556     * DisplayWinItem --
557     *
558     * This procedure is invoked to "draw" a window item in a given
559     * drawable. Since the window draws itself, we needn't do any
560     * actual redisplay here. However, this procedure takes care
561     * of actually repositioning the child window so that it occupies
562     * the correct screen position.
563     *
564     * Results:
565     * None.
566     *
567     * Side effects:
568     * The child window's position may get changed. Note: this
569     * procedure gets called both when a window needs to be displayed
570     * and when it ceases to be visible on the screen (e.g. it was
571     * scrolled or moved off-screen or the enclosing canvas is
572     * unmapped).
573     *
574     *--------------------------------------------------------------
575     */
576    
577     static void
578     DisplayWinItem(canvas, itemPtr, display, drawable, regionX, regionY,
579     regionWidth, regionHeight)
580     Tk_Canvas canvas; /* Canvas that contains item. */
581     Tk_Item *itemPtr; /* Item to be displayed. */
582     Display *display; /* Display on which to draw item. */
583     Drawable drawable; /* Pixmap or window in which to draw
584     * item. */
585     int regionX, regionY, regionWidth, regionHeight;
586     /* Describes region of canvas that
587     * must be redisplayed (not used). */
588     {
589     WindowItem *winItemPtr = (WindowItem *) itemPtr;
590     int width, height;
591     short x, y;
592     Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);
593     Tk_State state = itemPtr->state;
594    
595     if (winItemPtr->tkwin == NULL) {
596     return;
597     }
598     if(state == TK_STATE_NULL) {
599     state = ((TkCanvas *)canvas)->canvas_state;
600     }
601     if (state == TK_STATE_HIDDEN) {
602     Tk_UnmapWindow(winItemPtr->tkwin);
603     return;
604     }
605     Tk_CanvasWindowCoords(canvas, (double) winItemPtr->header.x1,
606     (double) winItemPtr->header.y1, &x, &y);
607     width = winItemPtr->header.x2 - winItemPtr->header.x1;
608     height = winItemPtr->header.y2 - winItemPtr->header.y1;
609    
610     /*
611     * If the window is completely out of the visible area of the canvas
612     * then unmap it. This code used not to be present (why unmap the
613     * window if it isn't visible anyway?) but this could cause the
614     * window to suddenly reappear if the canvas window got resized.
615     */
616    
617     if (((x + width) <= 0) || ((y + height) <= 0)
618     || (x >= Tk_Width(canvasTkwin)) || (y >= Tk_Height(canvasTkwin))) {
619     if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
620     Tk_UnmapWindow(winItemPtr->tkwin);
621     } else {
622     Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
623     }
624     return;
625     }
626    
627     /*
628     * Reposition and map the window (but in different ways depending
629     * on whether the canvas is the window's parent).
630     */
631    
632     if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
633     if ((x != Tk_X(winItemPtr->tkwin)) || (y != Tk_Y(winItemPtr->tkwin))
634     || (width != Tk_Width(winItemPtr->tkwin))
635     || (height != Tk_Height(winItemPtr->tkwin))) {
636     Tk_MoveResizeWindow(winItemPtr->tkwin, x, y, width, height);
637     }
638     Tk_MapWindow(winItemPtr->tkwin);
639     } else {
640     Tk_MaintainGeometry(winItemPtr->tkwin, canvasTkwin, x, y,
641     width, height);
642     }
643     }
644    
645     /*
646     *--------------------------------------------------------------
647     *
648     * WinItemToPoint --
649     *
650     * Computes the distance from a given point to a given
651     * window, in canvas units.
652     *
653     * Results:
654     * The return value is 0 if the point whose x and y coordinates
655     * are coordPtr[0] and coordPtr[1] is inside the window. If the
656     * point isn't inside the window then the return value is the
657     * distance from the point to the window.
658     *
659     * Side effects:
660     * None.
661     *
662     *--------------------------------------------------------------
663     */
664    
665     static double
666     WinItemToPoint(canvas, itemPtr, pointPtr)
667     Tk_Canvas canvas; /* Canvas containing item. */
668     Tk_Item *itemPtr; /* Item to check against point. */
669     double *pointPtr; /* Pointer to x and y coordinates. */
670     {
671     WindowItem *winItemPtr = (WindowItem *) itemPtr;
672     double x1, x2, y1, y2, xDiff, yDiff;
673    
674     x1 = winItemPtr->header.x1;
675     y1 = winItemPtr->header.y1;
676     x2 = winItemPtr->header.x2;
677     y2 = winItemPtr->header.y2;
678    
679     /*
680     * Point is outside window.
681     */
682    
683     if (pointPtr[0] < x1) {
684     xDiff = x1 - pointPtr[0];
685     } else if (pointPtr[0] >= x2) {
686     xDiff = pointPtr[0] + 1 - x2;
687     } else {
688     xDiff = 0;
689     }
690    
691     if (pointPtr[1] < y1) {
692     yDiff = y1 - pointPtr[1];
693     } else if (pointPtr[1] >= y2) {
694     yDiff = pointPtr[1] + 1 - y2;
695     } else {
696     yDiff = 0;
697     }
698    
699     return hypot(xDiff, yDiff);
700     }
701    
702     /*
703     *--------------------------------------------------------------
704     *
705     * WinItemToArea --
706     *
707     * This procedure is called to determine whether an item
708     * lies entirely inside, entirely outside, or overlapping
709     * a given rectangle.
710     *
711     * Results:
712     * -1 is returned if the item is entirely outside the area
713     * given by rectPtr, 0 if it overlaps, and 1 if it is entirely
714     * inside the given area.
715     *
716     * Side effects:
717     * None.
718     *
719     *--------------------------------------------------------------
720     */
721    
722     static int
723     WinItemToArea(canvas, itemPtr, rectPtr)
724     Tk_Canvas canvas; /* Canvas containing item. */
725     Tk_Item *itemPtr; /* Item to check against rectangle. */
726     double *rectPtr; /* Pointer to array of four coordinates
727     * (x1, y1, x2, y2) describing rectangular
728     * area. */
729     {
730     WindowItem *winItemPtr = (WindowItem *) itemPtr;
731    
732     if ((rectPtr[2] <= winItemPtr->header.x1)
733     || (rectPtr[0] >= winItemPtr->header.x2)
734     || (rectPtr[3] <= winItemPtr->header.y1)
735     || (rectPtr[1] >= winItemPtr->header.y2)) {
736     return -1;
737     }
738     if ((rectPtr[0] <= winItemPtr->header.x1)
739     && (rectPtr[1] <= winItemPtr->header.y1)
740     && (rectPtr[2] >= winItemPtr->header.x2)
741     && (rectPtr[3] >= winItemPtr->header.y2)) {
742     return 1;
743     }
744     return 0;
745     }
746    
747     /*
748     *--------------------------------------------------------------
749     *
750     * xerrorhandler --
751     *
752     * This is a dummy function to catch X11 errors during an
753     * attempt to print a canvas window.
754     *
755     * Results:
756     * None.
757     *
758     * Side effects:
759     * None.
760     *
761     *--------------------------------------------------------------
762     */
763    
764     #ifdef X_GetImage
765     static int
766     xerrorhandler(clientData, e)
767     ClientData clientData;
768     XErrorEvent *e;
769     {
770     return 0;
771     }
772     #endif
773    
774    
775     /*
776     *--------------------------------------------------------------
777     *
778     * WinItemToPostscript --
779     *
780     * This procedure is called to generate Postscript for
781     * window items.
782     *
783     * Results:
784     * The return value is a standard Tcl result. If an error
785     * occurs in generating Postscript then an error message is
786     * left in interp->result, replacing whatever used to be there.
787     * If no error occurs, then Postscript for the item is appended
788     * to the result.
789     *
790     * Side effects:
791     * None.
792     *
793     *--------------------------------------------------------------
794     */
795    
796     static int
797     WinItemToPostscript(interp, canvas, itemPtr, prepass)
798     Tcl_Interp *interp; /* Leave Postscript or error message
799     * here. */
800     Tk_Canvas canvas; /* Information about overall canvas. */
801     Tk_Item *itemPtr; /* Item for which Postscript is
802     * wanted. */
803     int prepass; /* 1 means this is a prepass to
804     * collect font information; 0 means
805     * final Postscript is being created.*/
806     {
807     WindowItem *winItemPtr = (WindowItem *)itemPtr;
808    
809     double x, y;
810     int width, height;
811     Tk_Window tkwin = winItemPtr->tkwin;
812    
813     if (prepass || winItemPtr->tkwin == NULL) {
814     return TCL_OK;
815     }
816    
817     width = Tk_Width(tkwin);
818     height = Tk_Height(tkwin);
819    
820     /*
821     * Compute the coordinates of the lower-left corner of the window,
822     * taking into account the anchor position for the window.
823     */
824    
825     x = winItemPtr->x;
826     y = Tk_CanvasPsY(canvas, winItemPtr->y);
827    
828     switch (winItemPtr->anchor) {
829     case TK_ANCHOR_NW: y -= height; break;
830     case TK_ANCHOR_N: x -= width/2.0; y -= height; break;
831     case TK_ANCHOR_NE: x -= width; y -= height; break;
832     case TK_ANCHOR_E: x -= width; y -= height/2.0; break;
833     case TK_ANCHOR_SE: x -= width; break;
834     case TK_ANCHOR_S: x -= width/2.0; break;
835     case TK_ANCHOR_SW: break;
836     case TK_ANCHOR_W: y -= height/2.0; break;
837     case TK_ANCHOR_CENTER: x -= width/2.0; y -= height/2.0; break;
838     }
839    
840     return CanvasPsWindow(interp, tkwin, canvas, x, y, width, height);
841     }
842    
843     static int
844     CanvasPsWindow(interp, tkwin, canvas, x, y, width, height)
845     Tcl_Interp *interp; /* Leave Postscript or error message
846     * here. */
847     Tk_Window tkwin; /* window to be printed */
848     Tk_Canvas canvas; /* Information about overall canvas. */
849     double x, y; /* origin of window. */
850     int width, height; /* width/height of window. */
851     {
852     char buffer[256];
853     TkWindow *winPtr;
854     XImage *ximage;
855     int result;
856     Tcl_DString buffer1, buffer2;
857     #ifdef X_GetImage
858     Tk_ErrorHandler handle;
859     #endif
860    
861     sprintf(buffer, "\n%%%% %s item (%s, %d x %d)\n%.15g %.15g translate\n",
862     Tk_Class(tkwin), Tk_PathName(tkwin), width, height, x, y);
863     Tcl_AppendResult(interp, buffer, (char *) NULL);
864    
865     /* first try if the widget has its own "postscript" command. If it
866     * exists, this will produce much better postscript than
867     * when a pixmap is used.
868     */
869    
870     Tcl_DStringInit(&buffer1);
871     Tcl_DStringInit(&buffer2);
872     Tcl_DStringGetResult(interp, &buffer2);
873     sprintf (buffer, "%s postscript -prolog 0\n", Tk_PathName(tkwin));
874     result = Tcl_Eval(interp, buffer);
875     Tcl_DStringGetResult(interp, &buffer1);
876     Tcl_DStringResult(interp, &buffer2);
877     Tcl_DStringFree(&buffer2);
878    
879     if (result == TCL_OK) {
880     Tcl_AppendResult(interp,
881     "50 dict begin\nsave\ngsave\n",
882     (char *) NULL);
883     sprintf (buffer,
884     "0 %d moveto %d 0 rlineto 0 -%d rlineto -%d",
885     height, width, height, width);
886     Tcl_AppendResult(interp, buffer, (char *) NULL);
887     Tcl_AppendResult(interp, " 0 rlineto closepath\n",
888     "1.000 1.000 1.000 setrgbcolor AdjustColor\nfill\ngrestore\n",
889     Tcl_DStringValue(&buffer1), "\nrestore\nend\n\n\n",
890     (char *) NULL);
891     Tcl_DStringFree(&buffer1);
892    
893     for (winPtr = ((TkWindow *) tkwin)->childList; winPtr != NULL;
894     winPtr = winPtr->nextPtr) {
895     if (Tk_IsMapped(winPtr)) {
896     /* printf("child window: %s\n", winPtr->pathName);*/
897     }
898     }
899     return result;
900     }
901     Tcl_DStringFree(&buffer1);
902    
903     /*
904     * If the window is off the screen it will generate an BadMatch/XError
905     * We catch any BadMatch errors here
906     */
907     #ifdef X_GetImage
908     handle = Tk_CreateErrorHandler(Tk_Display(tkwin), BadMatch,
909     X_GetImage, -1, xerrorhandler, (ClientData) tkwin);
910     #endif
911    
912     /*
913     * Generate an XImage from the window. We can then read pixel
914     * values out of the XImage.
915     */
916    
917     ximage = XGetImage(Tk_Display(tkwin), Tk_WindowId(tkwin), 0, 0,
918     (unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap);
919    
920     #ifdef X_GetImage
921     Tk_DeleteErrorHandler(handle);
922     #endif
923    
924     if (ximage == (XImage*) NULL) {
925     return TCL_OK;
926     }
927    
928     result = TkPostscriptImage(interp, tkwin,
929     ((TkCanvas *)canvas)->psInfo, ximage, 0, 0, width, height);
930    
931     XDestroyImage(ximage);
932     return result;
933     }
934    
935     /*
936     *--------------------------------------------------------------
937     *
938     * ScaleWinItem --
939     *
940     * This procedure is invoked to rescale a window item.
941     *
942     * Results:
943     * None.
944     *
945     * Side effects:
946     * The window referred to by itemPtr is rescaled
947     * so that the following transformation is applied to all
948     * point coordinates:
949     * x' = originX + scaleX*(x-originX)
950     * y' = originY + scaleY*(y-originY)
951     *
952     *--------------------------------------------------------------
953     */
954    
955     static void
956     ScaleWinItem(canvas, itemPtr, originX, originY, scaleX, scaleY)
957     Tk_Canvas canvas; /* Canvas containing window. */
958     Tk_Item *itemPtr; /* Window to be scaled. */
959     double originX, originY; /* Origin about which to scale window. */
960     double scaleX; /* Amount to scale in X direction. */
961     double scaleY; /* Amount to scale in Y direction. */
962     {
963     WindowItem *winItemPtr = (WindowItem *) itemPtr;
964    
965     winItemPtr->x = originX + scaleX*(winItemPtr->x - originX);
966     winItemPtr->y = originY + scaleY*(winItemPtr->y - originY);
967     if (winItemPtr->width > 0) {
968     winItemPtr->width = (int) (scaleX*winItemPtr->width);
969     }
970     if (winItemPtr->height > 0) {
971     winItemPtr->height = (int) (scaleY*winItemPtr->height);
972     }
973     ComputeWindowBbox(canvas, winItemPtr);
974     }
975    
976     /*
977     *--------------------------------------------------------------
978     *
979     * TranslateWinItem --
980     *
981     * This procedure is called to move a window by a given amount.
982     *
983     * Results:
984     * None.
985     *
986     * Side effects:
987     * The position of the window is offset by (xDelta, yDelta),
988     * and the bounding box is updated in the generic part of the
989     * item structure.
990     *
991     *--------------------------------------------------------------
992     */
993    
994     static void
995     TranslateWinItem(canvas, itemPtr, deltaX, deltaY)
996     Tk_Canvas canvas; /* Canvas containing item. */
997     Tk_Item *itemPtr; /* Item that is being moved. */
998     double deltaX, deltaY; /* Amount by which item is to be
999     * moved. */
1000     {
1001     WindowItem *winItemPtr = (WindowItem *) itemPtr;
1002    
1003     winItemPtr->x += deltaX;
1004     winItemPtr->y += deltaY;
1005     ComputeWindowBbox(canvas, winItemPtr);
1006     }
1007    
1008     /*
1009     *--------------------------------------------------------------
1010     *
1011     * WinItemStructureProc --
1012     *
1013     * This procedure is invoked whenever StructureNotify events
1014     * occur for a window that's managed as part of a canvas window
1015     * item. This procudure's only purpose is to clean up when
1016     * windows are deleted.
1017     *
1018     * Results:
1019     * None.
1020     *
1021     * Side effects:
1022     * The window is disassociated from the window item when it is
1023     * deleted.
1024     *
1025     *--------------------------------------------------------------
1026     */
1027    
1028     static void
1029     WinItemStructureProc(clientData, eventPtr)
1030     ClientData clientData; /* Pointer to record describing window item. */
1031     XEvent *eventPtr; /* Describes what just happened. */
1032     {
1033     WindowItem *winItemPtr = (WindowItem *) clientData;
1034    
1035     if (eventPtr->type == DestroyNotify) {
1036     winItemPtr->tkwin = NULL;
1037     }
1038     }
1039    
1040     /*
1041     *--------------------------------------------------------------
1042     *
1043     * WinItemRequestProc --
1044     *
1045     * This procedure is invoked whenever a window that's associated
1046     * with a window canvas item changes its requested dimensions.
1047     *
1048     * Results:
1049     * None.
1050     *
1051     * Side effects:
1052     * The size and location on the screen of the window may change,
1053     * depending on the options specified for the window item.
1054     *
1055     *--------------------------------------------------------------
1056     */
1057    
1058     static void
1059     WinItemRequestProc(clientData, tkwin)
1060     ClientData clientData; /* Pointer to record for window item. */
1061     Tk_Window tkwin; /* Window that changed its desired
1062     * size. */
1063     {
1064     WindowItem *winItemPtr = (WindowItem *) clientData;
1065    
1066     ComputeWindowBbox(winItemPtr->canvas, winItemPtr);
1067     DisplayWinItem(winItemPtr->canvas, (Tk_Item *) winItemPtr,
1068     (Display *) NULL, (Drawable) None, 0, 0, 0, 0);
1069     }
1070    
1071     /*
1072     *--------------------------------------------------------------
1073     *
1074     * WinItemLostSlaveProc --
1075     *
1076     * This procedure is invoked by Tk whenever some other geometry
1077     * claims control over a slave that used to be managed by us.
1078     *
1079     * Results:
1080     * None.
1081     *
1082     * Side effects:
1083     * Forgets all canvas-related information about the slave.
1084     *
1085     *--------------------------------------------------------------
1086     */
1087    
1088     /* ARGSUSED */
1089     static void
1090     WinItemLostSlaveProc(clientData, tkwin)
1091     ClientData clientData; /* WindowItem structure for slave window that
1092     * was stolen away. */
1093     Tk_Window tkwin; /* Tk's handle for the slave window. */
1094     {
1095     WindowItem *winItemPtr = (WindowItem *) clientData;
1096     Tk_Window canvasTkwin = Tk_CanvasTkwin(winItemPtr->canvas);
1097    
1098     Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
1099     WinItemStructureProc, (ClientData) winItemPtr);
1100     if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
1101     Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
1102     }
1103     Tk_UnmapWindow(winItemPtr->tkwin);
1104     winItemPtr->tkwin = NULL;
1105     }
1106    
1107    
1108     /* $History: tkCanvWind.c $
1109     *
1110     * ***************** Version 1 *****************
1111     * User: Dtashley Date: 1/02/01 Time: 2:42a
1112     * Created in $/IjuScripter, IjuConsole/Source/Tk Base
1113     * Initial check-in.
1114     */
1115    
1116     /* End of TKCANVWIND.C */

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25