2 * tkMacOSXSubwindows.c --
4 * Implements subwindows for the macintosh version of Tk.
6 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
7 * Copyright 2001, Apple Computer, Inc.
9 * See the file "license.terms" for information on usage and redistribution
10 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
20 #include <Carbon/Carbon.h>
21 #include "tkMacOSXInt.h"
22 #include "tkMacOSXDebug.h"
25 * Temporary region that can be reused.
27 static RgnHandle tmpRgn = NULL;
29 static void UpdateOffsets _ANSI_ARGS_((TkWindow *winPtr, int deltaX, int deltaY));
32 *----------------------------------------------------------------------
36 * Dealocates the given X Window.
39 * The window id is returned.
44 *----------------------------------------------------------------------
49 Display* display, /* Display. */
50 Window window) /* Window. */
52 MacDrawable *macWin = (MacDrawable *) window;
55 * Remove any dangling pointers that may exist if
56 * the window we are deleting is being tracked by
60 TkPointerDeadWindow(macWin->winPtr);
61 macWin->toplevel->referenceCount--;
64 if (Tk_IsTopLevel(macWin->winPtr)) {
65 DisposeRgn(macWin->clipRgn);
66 DisposeRgn(macWin->aboveClipRgn);
69 * Delete the Mac window and remove it from the windowTable.
70 * The window could be NULL if the window was never mapped.
71 * However, we don't do this for embedded windows, they don't
72 * go in the window list, and they do not own their portPtr's.
75 if (!(Tk_IsEmbedded(macWin->winPtr))) {
76 destPort = TkMacOSXGetDrawablePort(window);
77 if (destPort != NULL) {
78 TkMacOSXWindowList *listPtr, *prevPtr;
80 winRef = GetWindowFromPort(destPort);
81 TkMacOSXUnregisterMacWindow(winRef);
82 DisposeWindow(winRef);
84 for (listPtr = tkMacOSXWindowListPtr, prevPtr = NULL;
85 tkMacOSXWindowListPtr != NULL;
86 prevPtr = listPtr, listPtr = listPtr->nextPtr) {
87 if (listPtr->winPtr == macWin->winPtr) {
88 if (prevPtr == NULL) {
89 tkMacOSXWindowListPtr = listPtr->nextPtr;
91 prevPtr->nextPtr = listPtr->nextPtr;
93 ckfree((char *) listPtr);
100 macWin->grafPtr = NULL;
103 * Delay deletion of a toplevel data structure untill all
104 * children have been deleted.
106 if (macWin->toplevel->referenceCount == 0) {
107 ckfree((char *) macWin->toplevel);
111 destPort = TkMacOSXGetDrawablePort(window);
112 if (destPort != NULL) {
113 SetGWorld(destPort, NULL);
114 TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
116 if (macWin->winPtr->parentPtr != NULL) {
117 TkMacOSXInvalClipRgns(macWin->winPtr->parentPtr);
119 DisposeRgn(macWin->clipRgn);
120 DisposeRgn(macWin->aboveClipRgn);
122 if (macWin->toplevel->referenceCount == 0) {
123 ckfree((char *) macWin->toplevel);
125 ckfree((char *) macWin);
130 *----------------------------------------------------------------------
134 * Map the given X Window to the screen. See X window documentation
141 * The subwindow or toplevel may appear on the screen.
143 *----------------------------------------------------------------------
148 Display* display, /* Display. */
149 Window window) /* Window. */
151 MacDrawable *macWin = (MacDrawable *) window;
156 * Under certain situations it's possible for this function to be
157 * called before the toplevel window it's associated with has actually
158 * been mapped. In that case we need to create the real Macintosh
159 * window now as this function as well as other X functions assume that
160 * the portPtr is valid.
162 if (!TkMacOSXHostToplevelExists(macWin->toplevel->winPtr)) {
163 TkMacOSXMakeRealWindowExist(macWin->toplevel->winPtr);
165 destPort = TkMacOSXGetDrawablePort (window);
168 macWin->winPtr->flags |= TK_MAPPED;
169 if (Tk_IsTopLevel(macWin->winPtr)) {
170 if (!Tk_IsEmbedded(macWin->winPtr)) {
171 ShowWindow(GetWindowFromPort(destPort));
175 * We only need to send the MapNotify event
176 * for toplevel windows.
178 event.xany.serial = display->request;
179 event.xany.send_event = False;
180 event.xany.display = display;
182 event.xmap.window = window;
183 event.xmap.type = MapNotify;
184 event.xmap.event = window;
185 event.xmap.override_redirect = macWin->winPtr->atts.override_redirect;
186 Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
188 TkMacOSXInvalClipRgns(macWin->winPtr->parentPtr);
192 * Generate damage for that area of the window
194 SetGWorld (destPort, NULL);
195 TkMacOSXUpdateClipRgn(macWin->winPtr);
196 TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
200 *----------------------------------------------------------------------
204 * Unmap the given X Window to the screen. See X window
205 * documentation for more details.
211 * The subwindow or toplevel may be removed from the screen.
213 *----------------------------------------------------------------------
218 Display* display, /* Display. */
219 Window window) /* Window. */
221 MacDrawable *macWin = (MacDrawable *) window;
225 destPort = TkMacOSXGetDrawablePort(window);
228 macWin->winPtr->flags &= ~TK_MAPPED;
229 if (Tk_IsTopLevel(macWin->winPtr)) {
230 if (!Tk_IsEmbedded(macWin->winPtr)) {
231 HideWindow(GetWindowFromPort(destPort));
235 * We only need to send the UnmapNotify event
236 * for toplevel windows.
238 event.xany.serial = display->request;
239 event.xany.send_event = False;
240 event.xany.display = display;
242 event.xunmap.type = UnmapNotify;
243 event.xunmap.window = window;
244 event.xunmap.event = window;
245 event.xunmap.from_configure = false;
246 Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
249 * Generate damage for that area of the window.
251 SetGWorld(destPort, NULL);
252 TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); /* TODO: may not be valid */
253 TkMacOSXInvalClipRgns(macWin->winPtr->parentPtr);
258 *----------------------------------------------------------------------
262 * Resize a given X window. See X windows documentation for
271 *----------------------------------------------------------------------
276 Display* display, /* Display. */
277 Window window, /* Window. */
281 MacDrawable *macWin = (MacDrawable *) window;
284 destPort = TkMacOSXGetDrawablePort(window);
285 if (destPort == NULL) {
291 if (Tk_IsTopLevel(macWin->winPtr)) {
292 if (!Tk_IsEmbedded(macWin->winPtr)) {
294 * NOTE: we are not adding the new space to the update
295 * region. It is currently assumed that Tk will need
296 * to completely redraw anway.
298 SizeWindow(GetWindowFromPort(destPort),
299 (short) width, (short) height, false);
300 TkMacOSXInvalidateWindow(macWin, TK_WINDOW_ONLY);
301 TkMacOSXInvalClipRgns(macWin->winPtr);
306 * Find the Parent window -
307 * For an embedded window this will be its container.
309 TkWindow *contWinPtr;
311 contWinPtr = TkpGetOtherWindow(macWin->winPtr);
313 if (contWinPtr != NULL) {
314 MacDrawable *macParent = contWinPtr->privatePtr;
316 TkMacOSXInvalClipRgns(macParent->winPtr);
317 TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
319 deltaX = macParent->xOff +
320 macWin->winPtr->changes.x - macWin->xOff;
321 deltaY = macParent->yOff +
322 macWin->winPtr->changes.y - macWin->yOff;
324 UpdateOffsets(macWin->winPtr, deltaX, deltaY);
327 * This is the case where we are embedded in
328 * another app. At this point, we are assuming that
329 * the changes.x,y is not maintained, if you need
330 * the info get it from Tk_GetRootCoords,
331 * and that the toplevel sits at 0,0 when it is drawn.
334 TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
335 UpdateOffsets(macWin->winPtr, 0, 0);
340 /* TODO: update all xOff & yOffs */
341 int deltaX, deltaY, parentBorderwidth;
342 MacDrawable *macParent = macWin->winPtr->parentPtr->privatePtr;
344 if (macParent == NULL) {
345 return; /* TODO: Probably should be a panic */
348 TkMacOSXInvalClipRgns(macParent->winPtr);
349 TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
351 deltaX = - macWin->xOff;
352 deltaY = - macWin->yOff;
354 parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
356 deltaX += macParent->xOff + parentBorderwidth +
357 macWin->winPtr->changes.x;
358 deltaY += macParent->yOff + parentBorderwidth +
359 macWin->winPtr->changes.y;
361 UpdateOffsets(macWin->winPtr, deltaX, deltaY);
366 *----------------------------------------------------------------------
368 * XMoveResizeWindow --
370 * Move or resize a given X window. See X windows documentation
371 * for further details.
379 *----------------------------------------------------------------------
384 Display* display, /* Display. */
385 Window window, /* Window. */
390 MacDrawable * macWin = (MacDrawable *) window;
393 destPort = TkMacOSXGetDrawablePort(window);
394 if (destPort == NULL) {
399 if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
401 * NOTE: we are not adding the new space to the update
402 * region. It is currently assumed that Tk will need
403 * to completely redraw anway.
406 SizeWindow(GetWindowFromPort(destPort),
407 (short) width, (short) height, false);
408 MoveWindowStructure(GetWindowFromPort(destPort), x, y);
410 /* TODO: is the following right? */
411 TkMacOSXInvalidateWindow(macWin, TK_WINDOW_ONLY);
412 TkMacOSXInvalClipRgns(macWin->winPtr);
414 int deltaX, deltaY, parentBorderwidth;
416 MacDrawable *macParent;
419 * Find the Parent window -
420 * For an embedded window this will be its container.
423 if (Tk_IsEmbedded(macWin->winPtr)) {
424 TkWindow *contWinPtr;
426 contWinPtr = TkpGetOtherWindow(macWin->winPtr);
427 if (contWinPtr == NULL) {
428 panic("XMoveResizeWindow could not find container");
430 macParent = contWinPtr->privatePtr;
433 * NOTE: Here we should handle out of process embedding.
438 macParent = macWin->winPtr->parentPtr->privatePtr;
439 if (macParent == NULL) {
440 return; /* TODO: Probably should be a panic */
444 TkMacOSXInvalClipRgns(macParent->winPtr);
445 TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
447 deltaX = - macWin->xOff;
448 deltaY = - macWin->yOff;
451 * If macWin->winPtr is an embedded window, don't offset by its
452 * parent's borderwidth...
455 if (!Tk_IsEmbedded(macWin->winPtr)) {
456 parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
458 parentBorderwidth = 0;
460 deltaX += macParent->xOff + parentBorderwidth +
461 macWin->winPtr->changes.x;
462 deltaY += macParent->yOff + parentBorderwidth +
463 macWin->winPtr->changes.y;
465 UpdateOffsets(macWin->winPtr, deltaX, deltaY);
466 TkMacOSXWinBounds(macWin->winPtr, &bounds);
467 InvalWindowRect(GetWindowFromPort(destPort),&bounds);
472 *----------------------------------------------------------------------
476 * Move a given X window. See X windows documentation for further
485 *----------------------------------------------------------------------
490 Display* display, /* Display. */
491 Window window, /* Window. */
495 MacDrawable *macWin = (MacDrawable *) window;
498 destPort = TkMacOSXGetDrawablePort(window);
499 if (destPort == NULL) {
504 if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
506 * NOTE: we are not adding the new space to the update
507 * region. It is currently assumed that Tk will need
508 * to completely redraw anway.
510 MoveWindowStructure( GetWindowFromPort(destPort), x, y);
512 /* TODO: is the following right? */
513 TkMacOSXInvalidateWindow(macWin, TK_WINDOW_ONLY);
514 TkMacOSXInvalClipRgns(macWin->winPtr);
516 int deltaX, deltaY, parentBorderwidth;
518 MacDrawable *macParent;
521 * Find the Parent window -
522 * For an embedded window this will be its container.
525 if (Tk_IsEmbedded(macWin->winPtr)) {
526 TkWindow *contWinPtr;
528 contWinPtr = TkpGetOtherWindow(macWin->winPtr);
529 if (contWinPtr == NULL) {
530 panic("XMoveWindow could not find container");
532 macParent = contWinPtr->privatePtr;
535 * NOTE: Here we should handle out of process embedding.
539 macParent = macWin->winPtr->parentPtr->privatePtr;
540 if (macParent == NULL) {
541 return; /* TODO: Probably should be a panic */
545 TkMacOSXInvalClipRgns(macParent->winPtr);
546 TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
548 deltaX = - macWin->xOff;
549 deltaY = - macWin->yOff;
552 * If macWin->winPtr is an embedded window, don't offset by its
553 * parent's borderwidth...
556 if (!Tk_IsEmbedded(macWin->winPtr)) {
557 parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
559 parentBorderwidth = 0;
561 deltaX += macParent->xOff + parentBorderwidth +
562 macWin->winPtr->changes.x;
563 deltaY += macParent->yOff + parentBorderwidth +
564 macWin->winPtr->changes.y;
566 UpdateOffsets(macWin->winPtr, deltaX, deltaY);
567 TkMacOSXWinBounds(macWin->winPtr, &bounds);
568 InvalWindowRect(GetWindowFromPort(destPort),&bounds);
573 *----------------------------------------------------------------------
577 * Change the stacking order of a window.
583 * Changes the stacking order of the specified window.
585 *----------------------------------------------------------------------
590 Display* display, /* Display. */
591 Window window) /* Window. */
593 MacDrawable *macWin = (MacDrawable *) window;
596 if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
597 TkWmRestackToplevel(macWin->winPtr, Above, NULL);
599 /* TODO: this should generate damage */
604 *----------------------------------------------------------------------
608 * Change the stacking order of a window.
614 * Changes the stacking order of the specified window.
616 *----------------------------------------------------------------------
621 Display* display, /* Display. */
622 Window window) /* Window. */
624 MacDrawable *macWin = (MacDrawable *) window;
627 if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
628 TkWmRestackToplevel(macWin->winPtr, Below, NULL);
630 /* TODO: this should generate damage */
635 *----------------------------------------------------------------------
637 * XConfigureWindow --
639 * Change the size, position, stacking, or border of the specified
646 * Changes the attributes of the specified window. Note that we
647 * ignore the passed in values and use the values stored in the
648 * TkWindow data structure.
650 *----------------------------------------------------------------------
655 Display* display, /* Display. */
656 Window w, /* Window. */
657 unsigned int value_mask,
658 XWindowChanges* values)
660 MacDrawable *macWin = (MacDrawable *) w;
661 TkWindow *winPtr = macWin->winPtr;
666 * Change the shape and/or position of the window.
669 if (value_mask & (CWX|CWY|CWWidth|CWHeight)) {
670 XMoveResizeWindow(display, w, winPtr->changes.x, winPtr->changes.y,
671 winPtr->changes.width, winPtr->changes.height);
675 * Change the stacking order of the window. Tk actuall keeps all
676 * the information we need for stacking order. All we need to do
677 * is make sure the clipping regions get updated and generate damage
678 * that will ensure things get drawn correctly.
681 if (value_mask & CWStackMode) {
685 destPort = TkMacOSXGetDrawablePort(w);
686 if (destPort != NULL) {
688 TkMacOSXInvalClipRgns(winPtr->parentPtr);
689 TkMacOSXWinBounds(winPtr, &bounds);
690 InvalWindowRect(GetWindowFromPort(destPort),&bounds);
694 /* TkGenWMMoveRequestEvent(macWin->winPtr,
695 macWin->winPtr->changes.x, macWin->winPtr->changes.y); */
699 *----------------------------------------------------------------------
701 * TkMacOSXUpdateClipRgn --
703 * This function updates the cliping regions for a given window
704 * and all of its children. Once updated the TK_CLIP_INVALID flag
705 * in the subwindow data structure is unset. The TK_CLIP_INVALID
706 * flag should always be unset before any drawing is attempted.
712 * The clip regions for the window and its children are updated.
714 *----------------------------------------------------------------------
718 TkMacOSXUpdateClipRgn(
725 if (winPtr == NULL) {
729 if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
730 rgn = winPtr->privatePtr->aboveClipRgn;
731 if (tmpRgn == NULL) {
736 * Start with a region defined by the window bounds.
739 x = winPtr->privatePtr->xOff;
740 y = winPtr->privatePtr->yOff;
741 SetRectRgn(rgn, (short) x, (short) y,
742 (short) (winPtr->changes.width + x),
743 (short) (winPtr->changes.height + y));
746 * Clip away the area of any windows that may obscure this
748 * For a non-toplevel window, first, clip to the parents visable
750 * Second, clip away any siblings that are higher in the
752 * For an embedded toplevel, just clip to the container's visible
753 * clip region. Remember, we only allow one contained window
754 * in a frame, and don't support any other widgets in the frame either.
755 * This is not currently enforced, however.
758 if (!Tk_IsTopLevel(winPtr)) {
759 TkMacOSXUpdateClipRgn(winPtr->parentPtr);
761 winPtr->parentPtr->privatePtr->aboveClipRgn, rgn);
763 win2Ptr = winPtr->nextPtr;
764 while (win2Ptr != NULL) {
765 if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
766 win2Ptr = win2Ptr->nextPtr;
769 x = win2Ptr->privatePtr->xOff;
770 y = win2Ptr->privatePtr->yOff;
771 SetRectRgn(tmpRgn, (short) x, (short) y,
772 (short) (win2Ptr->changes.width + x),
773 (short) (win2Ptr->changes.height + y));
774 DiffRgn(rgn, tmpRgn, rgn);
776 win2Ptr = win2Ptr->nextPtr;
778 } else if (Tk_IsEmbedded(winPtr)) {
779 TkWindow *contWinPtr;
781 contWinPtr = TkpGetOtherWindow(winPtr);
783 if (contWinPtr != NULL) {
784 TkMacOSXUpdateClipRgn(contWinPtr);
786 contWinPtr->privatePtr->aboveClipRgn, rgn);
787 } else if (gMacEmbedHandler != NULL) {
788 gMacEmbedHandler->getClipProc((Tk_Window) winPtr, tmpRgn);
789 SectRgn(rgn, tmpRgn, rgn);
793 * NOTE: Here we should handle out of process embedding.
799 * The final clip region is the aboveClip region (or visable
800 * region) minus all the children of this window.
801 * Alternatively, if the window is a container, we must also
802 * subtract the region of the embedded window.
805 rgn = winPtr->privatePtr->clipRgn;
806 CopyRgn(winPtr->privatePtr->aboveClipRgn, rgn);
808 win2Ptr = winPtr->childList;
809 while (win2Ptr != NULL) {
810 if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
811 win2Ptr = win2Ptr->nextPtr;
814 x = win2Ptr->privatePtr->xOff;
815 y = win2Ptr->privatePtr->yOff;
816 SetRectRgn(tmpRgn, (short) x, (short) y,
817 (short) (win2Ptr->changes.width + x),
818 (short) (win2Ptr->changes.height + y));
819 DiffRgn(rgn, tmpRgn, rgn);
821 win2Ptr = win2Ptr->nextPtr;
824 if (Tk_IsContainer(winPtr)) {
825 win2Ptr = TkpGetOtherWindow(winPtr);
826 if (win2Ptr != NULL) {
827 if (Tk_IsMapped(win2Ptr)) {
828 x = win2Ptr->privatePtr->xOff;
829 y = win2Ptr->privatePtr->yOff;
830 SetRectRgn(tmpRgn, (short) x, (short) y,
831 (short) (win2Ptr->changes.width + x),
832 (short) (win2Ptr->changes.height + y));
833 DiffRgn(rgn, tmpRgn, rgn);
838 * NOTE: Here we should handle out of process embedding.
843 winPtr->privatePtr->flags &= ~TK_CLIP_INVALID;
848 *----------------------------------------------------------------------
850 * TkMacOSXVisableClipRgn --
852 * This function returnd the Macintosh cliping region for the
853 * given window. A NULL Rgn means the window is not visable.
861 *----------------------------------------------------------------------
865 TkMacOSXVisableClipRgn(
868 if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
869 TkMacOSXUpdateClipRgn(winPtr);
872 return winPtr->privatePtr->clipRgn;
876 *----------------------------------------------------------------------
878 * TkMacOSXInvalidateWindow --
880 * This function makes the window as invalid will generate damage
889 *----------------------------------------------------------------------
893 TkMacOSXInvalidateWindow(
894 MacDrawable *macWin, /* Make window that's causing damage. */
895 int flag) /* Should be TK_WINDOW_ONLY or
896 * TK_PARENT_WINDOW */
901 grafPtr=TkMacOSXGetDrawablePort((Drawable)macWin);
902 windowRef=GetWindowFromPort(grafPtr);
904 if (flag == TK_WINDOW_ONLY) {
905 InvalWindowRgn(windowRef,macWin->clipRgn);
907 if (!EmptyRgn(macWin->aboveClipRgn)) {
908 InvalWindowRgn(windowRef,macWin->aboveClipRgn);
914 *----------------------------------------------------------------------
916 * TkMacOSXGetDrawablePort --
918 * This function returns the Graphics Port for a given X drawable.
921 * A CGrafPort . Either an off screen pixmap or a Window.
926 *----------------------------------------------------------------------
930 TkMacOSXGetDrawablePort(
933 MacDrawable *macWin = (MacDrawable *) drawable;
934 GWorldPtr resultPort = NULL;
936 if (macWin == NULL) {
941 * This is NULL for off-screen pixmaps. Then the portPtr
942 * always points to the off-screen port, and we don't
943 * have to worry about containment
946 if (macWin->clipRgn == NULL) {
947 return macWin->grafPtr;
951 * If the Drawable is in an embedded window, use the Port of its container.
953 * TRICKY POINT: we can have cases when a toplevel is being destroyed
954 * where the winPtr for the toplevel has been freed, but the children
955 * are not all the way destroyed. The children will call this function
956 * as they are being destroyed, but Tk_IsEmbedded will return garbage.
957 * So we check the copy of the TK_EMBEDDED flag we put into the
958 * toplevel's macWin flags.
964 if (!(macWin->toplevel->flags & TK_EMBEDDED)) {
965 return macWin->toplevel->grafPtr;
967 TkWindow *contWinPtr;
969 contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);
971 if (contWinPtr != NULL) {
972 resultPort = TkMacOSXGetDrawablePort(
973 (Drawable) contWinPtr->privatePtr);
974 } else if (gMacEmbedHandler != NULL) {
975 resultPort = gMacEmbedHandler->getPortProc(
976 (Tk_Window) macWin->winPtr);
979 if (resultPort == NULL) {
983 * So far as I can tell, the only time that this happens is when
984 * we are tearing down an embedded child interpreter, and most
985 * of the time, this is harmless... However, we really need to
986 * find why the embedding loses.
988 DebugStr("\pTkMacOSXGetDrawablePort couldn't find container");
993 * NOTE: Here we should handle out of process embedding.
1001 *----------------------------------------------------------------------
1003 * TkMacOSXGetRootControl --
1005 * This function returns the Root Control for a given X drawable.
1013 *----------------------------------------------------------------------
1017 TkMacOSXGetRootControl(
1021 * will probably need to fix this up for embedding
1023 MacDrawable *macWin = (MacDrawable *) drawable;
1024 ControlRef result = NULL;
1026 if (macWin == NULL) {
1029 if (!(macWin->toplevel->flags & TK_EMBEDDED)) {
1030 return macWin->toplevel->rootControl;
1032 TkWindow *contWinPtr;
1034 contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);
1036 if (contWinPtr != NULL) {
1037 result = TkMacOSXGetRootControl(
1038 (Drawable) contWinPtr->privatePtr);
1039 } else if (gMacEmbedHandler != NULL) {
1047 *----------------------------------------------------------------------
1049 * TkMacOSXInvalClipRgns --
1051 * This function invalidates the clipping regions for a given
1052 * window and all of its children. This function should be
1053 * called whenever changes are made to subwindows that would
1054 * effect the size or position of windows.
1060 * The cliping regions for the window and its children are
1061 * mark invalid. (Make sure they are valid before drawing.)
1063 *----------------------------------------------------------------------
1067 TkMacOSXInvalClipRgns(
1073 * If already marked we can stop because all
1074 * decendants will also already be marked.
1076 if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
1080 winPtr->privatePtr->flags |= TK_CLIP_INVALID;
1083 * Invalidate clip regions for all children &
1084 * their decendants - unless the child is a toplevel.
1086 childPtr = winPtr->childList;
1087 while (childPtr != NULL) {
1088 if (!Tk_IsTopLevel(childPtr) && Tk_IsMapped(childPtr)) {
1089 TkMacOSXInvalClipRgns(childPtr);
1091 childPtr = childPtr->nextPtr;
1095 * Also, if the window is a container, mark its embedded window
1098 if (Tk_IsContainer(winPtr)) {
1099 childPtr = TkpGetOtherWindow(winPtr);
1101 if (childPtr != NULL && Tk_IsMapped(childPtr)) {
1102 TkMacOSXInvalClipRgns(childPtr);
1106 * NOTE: Here we should handle out of process embedding.
1113 *----------------------------------------------------------------------
1115 * TkMacOSXWinBounds --
1117 * Given a Tk window this function determines the windows
1118 * bounds in relation to the Macintosh window's coordinate
1119 * system. This is also the same coordinate system as the
1120 * Tk toplevel window in which this window is contained.
1128 *----------------------------------------------------------------------
1136 bounds->left = (short) winPtr->privatePtr->xOff;
1137 bounds->top = (short) winPtr->privatePtr->yOff;
1138 bounds->right = (short) (winPtr->privatePtr->xOff +
1139 winPtr->changes.width);
1140 bounds->bottom = (short) (winPtr->privatePtr->yOff +
1141 winPtr->changes.height);
1144 *----------------------------------------------------------------------
1148 * Updates the X & Y offsets of the given TkWindow from the
1149 * TopLevel it is a decendant of.
1155 * The xOff & yOff fields for the Mac window datastructure
1156 * is updated to the proper offset.
1158 *----------------------------------------------------------------------
1169 if (winPtr->privatePtr == NULL) {
1171 * We havn't called Tk_MakeWindowExist for this window yet. The
1172 * offset information will be postponed and calulated at that
1173 * time. (This will usually only happen when a mapped parent is
1174 * being moved but has child windows that have yet to be mapped.)
1179 winPtr->privatePtr->xOff += deltaX;
1180 winPtr->privatePtr->yOff += deltaY;
1182 childPtr = winPtr->childList;
1183 while (childPtr != NULL) {
1184 if (!Tk_IsTopLevel(childPtr)) {
1185 UpdateOffsets(childPtr, deltaX, deltaY);
1187 childPtr = childPtr->nextPtr;
1190 if (Tk_IsContainer(winPtr)) {
1191 childPtr = TkpGetOtherWindow(winPtr);
1192 if (childPtr != NULL) {
1193 UpdateOffsets(childPtr,deltaX,deltaY);
1197 * NOTE: Here we should handle out of process embedding.
1204 *----------------------------------------------------------------------
1208 * Creates an in memory drawing surface.
1211 * Returns a handle to a new pixmap.
1214 * Allocates a new Macintosh GWorld.
1216 *----------------------------------------------------------------------
1221 Display *display, /* Display for new pixmap (can be null). */
1222 Drawable d, /* Drawable where pixmap will be used (ignored). */
1223 int width, /* Dimensions of pixmap. */
1225 int depth) /* Bits per pixel for pixmap. */
1230 MacDrawable *macPix;
1231 PixMapHandle pixels;
1233 if (display != NULL) {
1236 macPix = (MacDrawable *) ckalloc(sizeof(MacDrawable));
1237 macPix->winPtr = NULL;
1240 macPix->clipRgn = NULL;
1241 macPix->aboveClipRgn = NULL;
1242 macPix->referenceCount = 0;
1243 macPix->toplevel = NULL;
1246 bounds.top = bounds.left = 0;
1247 bounds.right = (short) width;
1248 bounds.bottom = (short) height;
1253 * Allocate memory for the off screen pixmap. If we fail
1254 * try again from system memory. Eventually, we may have
1257 err = NewGWorld(&gWorld, depth, &bounds, NULL, NULL, 0);
1259 err = NewGWorld(&gWorld, depth, &bounds, NULL, NULL, useTempMem);
1262 panic("Out of memory: NewGWorld failed in Tk_GetPixmap");
1266 * Lock down the pixels so they don't move out from under us.
1268 pixels = GetGWorldPixMap(gWorld);
1270 macPix->grafPtr = gWorld;
1272 return (Pixmap) macPix;
1276 *----------------------------------------------------------------------
1280 * Release the resources associated with a pixmap.
1286 * Deletes the Macintosh GWorld created by Tk_GetPixmap.
1288 *----------------------------------------------------------------------
1293 Display *display, /* Display. */
1294 Pixmap pixmap) /* Pixmap to destroy */
1296 MacDrawable *macPix = (MacDrawable *) pixmap;
1297 PixMapHandle pixels;
1300 pixels = GetGWorldPixMap(macPix->grafPtr);
1301 UnlockPixels(pixels);
1302 DisposeGWorld(macPix->grafPtr);
1303 ckfree((char *) macPix);