summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXSubwindows.c
diff options
context:
space:
mode:
authordas <das>2007-10-12 03:14:47 (GMT)
committerdas <das>2007-10-12 03:14:47 (GMT)
commitacc2acbb288f8a715cce7905093615b3a7fcbc47 (patch)
treeeb61b1b1e215cb3c0ce151014bd73b7b63db5257 /macosx/tkMacOSXSubwindows.c
parentd0945ac2cb3d92090109d0c3899b51284660db69 (diff)
downloadtk-acc2acbb288f8a715cce7905093615b3a7fcbc47.zip
tk-acc2acbb288f8a715cce7905093615b3a7fcbc47.tar.gz
tk-acc2acbb288f8a715cce7905093615b3a7fcbc47.tar.bz2
* macosx/tkMacOSXDraw.c: replace all (internal) use of QD region
* macosx/tkMacOSXSubwindows.c: API by HIShape API, with conversion to * macosx/tkMacOSXWindowEvent.c QD regions only when required by legacy * macosx/tkMacOSXPrivate.h: Carbon or Tk API. * macosx/tkMacOSXRegion.c: * macosx/tkMacOSXDebug.c: * macosx/tkMacOSXDebug.h: * macosx/tkMacOSXInt.h: replace MacDrawable's QD RgnHandles * macosx/tkMacOSXEmbed.c: clipRgn, aboveClipRgn & drawRgn by * macosx/tkMacOSXMenu.c: HIShapeRefs visRgn & aboveVisRgn and * macosx/tkMacOSXSubwindows.c: CGRect drawRect. * macosx/tkMacOSXWindowEvent.c: remove use of QD port vis rgn in window * macosx/tkMacOSXSubwindows.c: update rgn calculation, manually excise * macosx/tkMacOSXWm.c: growbox from toplevel clip rgn instead. * macosx/tkMacOSXDraw.c: replace use of QD port clip rgn by new * macosx/tkMacOSXPrivate.h: clipRgn fld in TkMacOSXDrawingContext; handle QD/CG drawing mismatches in XCopyArea, XCopyPlane and TkPutImage; cleanup/speedup CGContext setup in TkMacOSXSetupDrawingContext(). * macosx/tkMacOSXDraw.c: change TkMacOSXSetupDrawingContext() to * macosx/tkMacOSXEntry.c: return boolean indicating whether * macosx/tkMacOSXFont.c: drawing is allowed (and was setup) or * macosx/tkMacOSXMenu.c: not (e.g. when clipRgn is empty). * macosx/ttkMacOSXTheme.c: * macosx/tkMacOSXSubwindows.c: signal that drawable is a pixmap via * macosx/tkMacOSXInt.h: new explicit TK_IS_PIXMAP flag instead of a NULL cligRgn field. * macosx/tkMacOSXRegion.c: add wrappers for missing/buggy HIShape * macosx/tkMacOSXPrivate.h: API, and private helpers to operate on HIShapeRefs & convert to/from TkRegion. * macosx/tkMacOSXRegion.c: add Tkp{Retain,Release}Region() API for * macosx/tkMacOSXInt.h: TkRegion.
Diffstat (limited to 'macosx/tkMacOSXSubwindows.c')
-rw-r--r--macosx/tkMacOSXSubwindows.c195
1 files changed, 139 insertions, 56 deletions
diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c
index 46d299d..6810519 100644
--- a/macosx/tkMacOSXSubwindows.c
+++ b/macosx/tkMacOSXSubwindows.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXSubwindows.c,v 1.23 2007/06/29 03:20:02 das Exp $
+ * RCS: @(#) $Id: tkMacOSXSubwindows.c,v 1.24 2007/10/12 03:14:48 das Exp $
*/
#include "tkMacOSXPrivate.h"
@@ -90,9 +90,12 @@ XDestroyWindow(
}
}
}
- DisposeRgn(macWin->clipRgn);
- DisposeRgn(macWin->aboveClipRgn);
- DisposeRgn(macWin->drawRgn);
+ if (macWin->visRgn) {
+ CFRelease(macWin->visRgn);
+ }
+ if (macWin->aboveVisRgn) {
+ CFRelease(macWin->aboveVisRgn);
+ }
/*
* Delete the Mac window and remove it from the windowTable.
@@ -140,9 +143,12 @@ XDestroyWindow(
if (macWin->winPtr->parentPtr != NULL) {
TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr);
}
- DisposeRgn(macWin->clipRgn);
- DisposeRgn(macWin->aboveClipRgn);
- DisposeRgn(macWin->drawRgn);
+ if (macWin->visRgn) {
+ CFRelease(macWin->visRgn);
+ }
+ if (macWin->aboveVisRgn) {
+ CFRelease(macWin->aboveVisRgn);
+ }
if (macWin->toplevel->referenceCount == 0) {
ckfree((char *) macWin->toplevel);
@@ -690,15 +696,16 @@ TkMacOSXUpdateClipRgn(
TkWindow *win2Ptr;
if (Tk_IsMapped(winPtr)) {
- Rect bounds;
- RgnHandle rgn = macWin->aboveClipRgn;
+ int rgnChanged = 0;
+ CGRect bounds;
+ HIMutableShapeRef rgn;
/*
* Start with a region defined by the window bounds.
*/
- TkMacOSXWinBounds(winPtr, &bounds);
- RectRgn(rgn, &bounds);
+ TkMacOSXWinCGBounds(winPtr, &bounds);
+ rgn = TkMacOSXHIShapeCreateMutableWithRect(&bounds);
/*
* Clip away the area of any windows that may obscure this
@@ -715,9 +722,9 @@ TkMacOSXUpdateClipRgn(
if (!Tk_IsTopLevel(winPtr)) {
TkMacOSXUpdateClipRgn(winPtr->parentPtr);
- TkMacOSXCheckTmpQdRgnEmpty();
if (winPtr->parentPtr) {
- SectRgn(rgn, winPtr->parentPtr->privatePtr->aboveClipRgn,
+ ChkErr(HIShapeIntersect,
+ winPtr->parentPtr->privatePtr->aboveVisRgn, rgn,
rgn);
}
win2Ptr = winPtr;
@@ -725,46 +732,62 @@ TkMacOSXUpdateClipRgn(
if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
continue;
}
- TkMacOSXWinBounds(win2Ptr, &bounds);
- RectRgn(tkMacOSXtmpQdRgn, &bounds);
- DiffRgn(rgn, tkMacOSXtmpQdRgn, rgn);
+ TkMacOSXWinCGBounds(win2Ptr, &bounds);
+ ChkErr(TkMacOSHIShapeDifferenceWithRect, rgn, &bounds);
}
} else if (Tk_IsEmbedded(winPtr)) {
win2Ptr = TkpGetOtherWindow(winPtr);
if (win2Ptr) {
TkMacOSXUpdateClipRgn(win2Ptr);
- TkMacOSXCheckTmpQdRgnEmpty();
- SectRgn(rgn, win2Ptr->privatePtr->aboveClipRgn, rgn);
+ ChkErr(HIShapeIntersect,
+ win2Ptr->privatePtr->aboveVisRgn, rgn, rgn);
} else if (tkMacOSXEmbedHandler != NULL) {
+ HIShapeRef visRgn;
+
TkMacOSXCheckTmpQdRgnEmpty();
tkMacOSXEmbedHandler->getClipProc((Tk_Window) winPtr,
tkMacOSXtmpQdRgn);
- SectRgn(rgn, tkMacOSXtmpQdRgn, rgn);
+ visRgn = HIShapeCreateWithQDRgn(tkMacOSXtmpQdRgn);
+ SetEmptyRgn(tkMacOSXtmpQdRgn);
+ ChkErr(HIShapeIntersect, visRgn, rgn, rgn);
}
/*
* TODO: Here we should handle out of process embedding.
*/
+ } else if (winPtr->wmInfoPtr->attributes &
+ kWindowResizableAttribute) {
+ HIViewRef growBoxView;
+ OSErr err = HIViewFindByID(HIViewGetRoot(
+ TkMacOSXDrawableWindow(winPtr->window)),
+ kHIViewWindowGrowBoxID, &growBoxView);
+
+ if (err == noErr) {
+ ChkErr(HIViewGetFrame, growBoxView, &bounds);
+ bounds = CGRectOffset(bounds,
+ -winPtr->wmInfoPtr->xInParent,
+ -winPtr->wmInfoPtr->yInParent);
+ ChkErr(TkMacOSHIShapeDifferenceWithRect, rgn, &bounds);
+ }
}
+ macWin->aboveVisRgn = HIShapeCreateCopy(rgn);
/*
- * The final clip region is the aboveClip region (or visible
+ * The final clip region is the aboveVis region (or visible
* region) minus all the children of this window.
* If the window is a container, we must also subtract the region
* of the embedded window.
*/
- rgn = macWin->clipRgn;
- CopyRgn(macWin->aboveClipRgn, rgn);
win2Ptr = winPtr->childList;
while (win2Ptr) {
if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
win2Ptr = win2Ptr->nextPtr;
continue;
}
- TkMacOSXWinBounds(win2Ptr, &bounds);
- RectRgn(tkMacOSXtmpQdRgn, &bounds);
- DiffRgn(rgn, tkMacOSXtmpQdRgn, rgn);
+ TkMacOSXWinCGBounds(win2Ptr, &bounds);
+ ChkErr(TkMacOSHIShapeDifferenceWithRect, rgn, &bounds);
+ rgnChanged = 1;
win2Ptr = win2Ptr->nextPtr;
}
@@ -772,9 +795,9 @@ TkMacOSXUpdateClipRgn(
win2Ptr = TkpGetOtherWindow(winPtr);
if (win2Ptr) {
if (Tk_IsMapped(win2Ptr)) {
- TkMacOSXWinBounds(win2Ptr, &bounds);
- RectRgn(tkMacOSXtmpQdRgn, &bounds);
- DiffRgn(rgn, tkMacOSXtmpQdRgn, rgn);
+ TkMacOSXWinCGBounds(win2Ptr, &bounds);
+ ChkErr(TkMacOSHIShapeDifferenceWithRect, rgn, &bounds);
+ rgnChanged = 1;
}
}
@@ -782,7 +805,16 @@ TkMacOSXUpdateClipRgn(
* TODO: Here we should handle out of process embedding.
*/
}
- SetEmptyRgn(tkMacOSXtmpQdRgn);
+ if (rgnChanged) {
+ HIShapeRef diffRgn = HIShapeCreateDifference(
+ macWin->aboveVisRgn, rgn);
+
+ if (!HIShapeIsEmpty(diffRgn)) {
+ macWin->visRgn = HIShapeCreateCopy(rgn);
+ }
+ CFRelease(diffRgn);
+ }
+ CFRelease(rgn);
} else {
/*
* An unmapped window has empty clip regions to prevent any
@@ -798,13 +830,15 @@ TkMacOSXUpdateClipRgn(
TkMacOSXUpdateClipRgn(win2Ptr);
}
}
- SetEmptyRgn(macWin->aboveClipRgn);
- SetEmptyRgn(macWin->clipRgn);
+ macWin->aboveVisRgn = TkMacOSXHIShapeCreateEmpty();
+ }
+ if (!macWin->visRgn) {
+ macWin->visRgn = HIShapeCreateCopy(macWin->aboveVisRgn);
}
macWin->flags &= ~TK_CLIP_INVALID;
#ifdef TK_MAC_DEBUG_CLIP_REGIONS
- TkMacOSXDebugFlashRegion((Drawable) macWin, macWin->clipRgn);
+ TkMacOSXDebugFlashRegion((Drawable) macWin, macWin->visRgn);
#endif /* TK_MAC_DEBUG_CLIP_REGIONS */
}
}
@@ -830,10 +864,16 @@ RgnHandle
TkMacOSXVisableClipRgn(
TkWindow *winPtr)
{
+ static RgnHandle visQdRgn = NULL;
+
+ if (visQdRgn == NULL) {
+ visQdRgn = NewRgn();
+ }
if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
TkMacOSXUpdateClipRgn(winPtr);
}
- return winPtr->privatePtr->clipRgn;
+ ChkErr(HIShapeGetAsQDRgn, winPtr->privatePtr->visRgn, visQdRgn);
+ return visQdRgn;
}
/*
@@ -860,15 +900,18 @@ TkMacOSXInvalidateWindow(
* TK_PARENT_WINDOW */
{
WindowRef windowRef;
- RgnHandle rgn;
+ HIShapeRef rgn;
windowRef = TkMacOSXDrawableWindow((Drawable)macWin);
if (macWin->flags & TK_CLIP_INVALID) {
TkMacOSXUpdateClipRgn(macWin->winPtr);
}
- rgn = (flag == TK_WINDOW_ONLY) ? macWin->clipRgn : macWin->aboveClipRgn;
- if (!EmptyRgn(rgn)) {
- InvalWindowRgn(windowRef, rgn);
+ rgn = (flag == TK_WINDOW_ONLY) ? macWin->visRgn : macWin->aboveVisRgn;
+ if (!HIShapeIsEmpty(rgn)) {
+ TkMacOSXCheckTmpQdRgnEmpty();
+ ChkErr(HIShapeGetAsQDRgn, rgn, tkMacOSXtmpQdRgn);
+ InvalWindowRgn(windowRef, tkMacOSXtmpQdRgn);
+ SetEmptyRgn(tkMacOSXtmpQdRgn);
}
#ifdef TK_MAC_DEBUG_CLIP_REGIONS
TkMacOSXDebugFlashRegion((Drawable) macWin, rgn);
@@ -898,7 +941,7 @@ TkMacOSXDrawableWindow(
MacDrawable *macWin = (MacDrawable *) drawable;
WindowRef result = NULL;
- if (!macWin || !macWin->clipRgn) {
+ if (!macWin || macWin->flags & TK_IS_PIXMAP) {
result = NULL;
} else {
result = GetWindowFromPort(TkMacOSXGetDrawablePort(drawable));
@@ -930,8 +973,7 @@ TkMacOSXGetDrawablePort(
CGrafPtr resultPort = NULL;
if (macWin) {
- resultPort = macWin->grafPtr;
- if (macWin->toplevel && macWin->clipRgn) {
+ if (macWin->toplevel) {
/*
* If the Drawable is in an embedded window, use the Port of its
* container.
@@ -957,7 +999,7 @@ TkMacOSXGetDrawablePort(
(Tk_Window) macWin->winPtr);
}
- if (resultPort == NULL) {
+ if (!resultPort) {
/*
* FIXME: So far as I can tell, the only time that this
* happens is when we are tearing down an embedded child
@@ -973,6 +1015,8 @@ TkMacOSXGetDrawablePort(
} else {
resultPort = macWin->toplevel->grafPtr;
}
+ } else {
+ resultPort = macWin->grafPtr;
}
}
@@ -1062,8 +1106,14 @@ TkMacOSXInvalClipRgns(
}
macWin->flags |= TK_CLIP_INVALID;
- SetEmptyRgn(macWin->aboveClipRgn);
- SetEmptyRgn(macWin->clipRgn);
+ if (macWin->visRgn) {
+ CFRelease(macWin->visRgn);
+ macWin->visRgn = NULL;
+ }
+ if (macWin->aboveVisRgn) {
+ CFRelease(macWin->aboveVisRgn);
+ macWin->aboveVisRgn = NULL;
+ }
/*
* Invalidate clip regions for all children &
@@ -1127,6 +1177,36 @@ TkMacOSXWinBounds(
/*
*----------------------------------------------------------------------
*
+ * TkMacOSXWinCGBounds --
+ *
+ * Given a Tk window this function determines the windows
+ * bounds in relation to the Macintosh window's coordinate
+ * system. This is also the same coordinate system as the
+ * Tk toplevel window in which this window is contained.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXWinCGBounds(
+ TkWindow *winPtr,
+ CGRect *bounds)
+{
+ bounds->origin.x = winPtr->privatePtr->xOff;
+ bounds->origin.y = winPtr->privatePtr->yOff;
+ bounds->size.width = winPtr->changes.width;
+ bounds->size.height = winPtr->changes.height;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* UpdateOffsets --
*
* Updates the X & Y offsets of the given TkWindow from the
@@ -1207,9 +1287,6 @@ Tk_GetPixmap(
int height,
int depth) /* Bits per pixel for pixmap. */
{
- QDErr err;
- GWorldPtr gWorld;
- Rect bounds = {0, 0, height, width};
MacDrawable *macPix;
if (display != NULL) {
@@ -1219,24 +1296,30 @@ Tk_GetPixmap(
macPix->winPtr = NULL;
macPix->xOff = 0;
macPix->yOff = 0;
- macPix->clipRgn = NULL;
- macPix->aboveClipRgn = NULL;
- macPix->drawRgn = NULL;
+ macPix->visRgn = NULL;
+ macPix->aboveVisRgn = NULL;
+ macPix->drawRect = CGRectNull;
macPix->referenceCount = 0;
macPix->toplevel = NULL;
- macPix->flags = 0;
+ macPix->flags = TK_IS_PIXMAP;
macPix->grafPtr = NULL;
macPix->context = NULL;
+ {
+ OSStatus err;
+ GWorldPtr gWorld;
+ Rect bounds = {0, 0, height, width};
- err = ChkErr(NewGWorld, &gWorld, depth == 1 ? 1 : 0, &bounds, NULL, NULL, 0
+ err = ChkErr(NewGWorld, &gWorld, depth == 1 ? 1 : 0, &bounds, NULL,
+ NULL, 0
#ifdef __LITTLE_ENDIAN__
- | kNativeEndianPixMap
+ | kNativeEndianPixMap
#endif
- );
- if (err != noErr) {
- Tcl_Panic("Out of memory: NewGWorld failed in Tk_GetPixmap");
+ );
+ if (err != noErr) {
+ Tcl_Panic("Out of memory: NewGWorld failed in Tk_GetPixmap");
+ }
+ macPix->grafPtr = gWorld;
}
- macPix->grafPtr = gWorld;
return (Pixmap) macPix;
}