From 9db63c3a0deba262eaef8b87ee78bf606837c0ae Mon Sep 17 00:00:00 2001 From: das Date: Fri, 9 Nov 2007 06:26:53 +0000 Subject: Backport from HEAD of Aqua changes from 2007-10-12 to 2007-11-09 --- ChangeLog | 115 ++++++++ library/bgerror.tcl | 7 +- library/console.tcl | 5 +- library/menu.tcl | 21 +- macosx/tkMacOSXButton.c | 181 +++++++----- macosx/tkMacOSXCarbonEvents.c | 154 ++++++---- macosx/tkMacOSXColor.c | 42 ++- macosx/tkMacOSXDebug.c | 28 +- macosx/tkMacOSXDebug.h | 8 +- macosx/tkMacOSXDefault.h | 36 ++- macosx/tkMacOSXDialog.c | 85 +++++- macosx/tkMacOSXDraw.c | 660 +++++++++++++++++++++++++----------------- macosx/tkMacOSXEmbed.c | 18 +- macosx/tkMacOSXEntry.c | 10 +- macosx/tkMacOSXEvent.c | 4 +- macosx/tkMacOSXFont.c | 11 +- macosx/tkMacOSXInit.c | 14 +- macosx/tkMacOSXInt.h | 13 +- macosx/tkMacOSXMenu.c | 25 +- macosx/tkMacOSXMenubutton.c | 255 ++++++++++------ macosx/tkMacOSXMenus.c | 196 +++++++++---- macosx/tkMacOSXPrivate.h | 38 ++- macosx/tkMacOSXRegion.c | 466 +++++++++++++++++++++++++++-- macosx/tkMacOSXSubwindows.c | 204 +++++++++---- macosx/tkMacOSXWindowEvent.c | 125 ++++---- macosx/tkMacOSXWm.c | 217 +++++++++++++- macosx/tkMacOSXXStubs.c | 109 ++++++- xlib/xgc.c | 121 +++++--- 28 files changed, 2344 insertions(+), 824 deletions(-) diff --git a/ChangeLog b/ChangeLog index e7289f7..8b64804 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,118 @@ +2007-11-09 Daniel Steffen + + Backport from HEAD of Aqua changes from 2007-10-12 to 2007-11-09: + + * macosx/tkMacOSXCarbonEvents.c + (InstallStandardApplicationEventHandler): on Mac OS X Leopard, replace + the 2005-11-27 approach of installing the standard application handler + by calling RAEL and immediately longjmping out of it from an event + handler, as that now leads to crashes in -[NSView unlockFocus] whenever + HIToolbox uses Cocoa in Leopard (Help menu, Nav Services, Color + Picker). Instead call InstallStandardEventHandler() on the application + and menubar event targets, as Leopard ISEH finally handles these + correctly. Unfortunately need a HIToolbox-internal SPI to retrieve the + menubar event target, no public API appears have that functionality. + + * macosx/tkMacOSXDebug.c: make TkMacOSXInitNamedDebugSymbol() + * macosx/tkMacOSXDebug.h: available outside of debug builds as + the new Leopard ISAEH needs it. + + * macosx/tkMacOSXButton.c: replace HiliteControl() by modern API + * macosx/tkMacOSXMenubutton.c: for activation and enabling; + distinguish inactive and disabled + look&feel; correct activation handling + to match that of container toplevel. + + * macosx/tkMacOSXMenubutton.c: correct size computation of bevelbutton + variant to match that of buttons; + fix crash with bitmap due to NULL GC; + delay picParams setup until needed; + formatting cleanup. [Bug 1824521] + + * library/menu.tcl: correct handling of menubutton "active" + state on Aqua to match that of buttons. + + * macosx/tkMacOSXDefault.h: correct button & menubutton active + foreground and background colors and + menubutton border width. + + * macosx/tkMacOSXWindowEvent.c: handle kEventWindowExpanding carbon + * macosx/tkMacOSXCarbonEvents.c: event instead of kEventWindowExpanded + to ensure activate event arrives after + window is remapped, also need to + process all Tk events generated by + remapping in the event handler to + ensure children are remapped before + activate event is processed. + + * macosx/tkMacOSXSubwindows.c: add pixmap size field to MacDrawable + * macosx/tkMacOSXInt.h: struct; add flag for B&W pixmaps. + * macosx/tkMacOSXDraw.c: + * macosx/tkMacOSXEmbed.c: + * macosx/tkMacOSXMenu.c: + + * macosx/tkMacOSXPrivate.h: correct Leopard HIToolboxVersionNumber. + + * macosx/tkMacOSXMenus.c: add "Run Widget Demo" menu item to the + default Edit menu along with associated carbon event handler enabling + the item only if demo files are installed; cleanup handling of "About" + and "Source" menu items. + + * library/bgerror.tcl: fix background of detail text on Aqua. + + * library/console.tcl: sync aqua font size with HEAD. + + * macosx/tkMacOSXEvent.c (TkMacOSXProcessCommandEvent): fix boolean arg + + * macosx/tkMacOSXColor.c (GetThemeColor): improve translation of RGB + pixel values into RGBColor. + + * 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/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. + + * xlib/xgc.c: factor out alloc/free of GC clip_mask; + * macosx/tkMacOSXXStubs.c: manage clip rgn lifetime with new + Tkp{Retain,Release}Region(). + + * macosx/tkMacOSXButton.c: delay picParams setup until needed. + 2007-10-30 Jeff Hobbs * library/entry.tcl: don't error with Clear event. [Bug 1509288] diff --git a/library/bgerror.tcl b/library/bgerror.tcl index 48c212e..2e6229b 100644 --- a/library/bgerror.tcl +++ b/library/bgerror.tcl @@ -7,10 +7,10 @@ # Donal K. Fellows. # # Copyright (c) 1998-2000 by Ajuba Solutions. -# All rights reserved. +# Copyright (c) 2007 Daniel A. Steffen # -# RCS: @(#) $Id: bgerror.tcl,v 1.23.2.8 2007/05/30 06:37:03 das Exp $ -# $Id: bgerror.tcl,v 1.23.2.8 2007/05/30 06:37:03 das Exp $ +# RCS: @(#) $Id: bgerror.tcl,v 1.23.2.9 2007/11/09 06:26:54 das Exp $ +# $Id: bgerror.tcl,v 1.23.2.9 2007/11/09 06:26:54 das Exp $ namespace eval ::tk::dialog::error { namespace import -force ::tk::msgcat::* @@ -21,6 +21,7 @@ namespace eval ::tk::dialog::error { if {[tk windowingsystem] eq "aqua"} { option add *ErrorDialog*background systemAlertBackgroundActive \ widgetDefault + option add *ErrorDialog*info.text.background white widgetDefault option add *ErrorDialog*Button.highlightBackground \ systemAlertBackgroundActive widgetDefault } diff --git a/library/console.tcl b/library/console.tcl index 037eb59..540fc3c 100644 --- a/library/console.tcl +++ b/library/console.tcl @@ -4,10 +4,11 @@ # can be used by non-unix systems that do not have built-in support # for shells. # -# RCS: @(#) $Id: console.tcl,v 1.22.2.5 2006/01/25 18:21:41 dgp Exp $ +# RCS: @(#) $Id: console.tcl,v 1.22.2.6 2007/11/09 06:26:54 das Exp $ # # Copyright (c) 1995-1997 Sun Microsystems, Inc. # Copyright (c) 1998-2000 Ajuba Solutions. +# Copyright (c) 2007 Daniel A. Steffen # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -105,7 +106,7 @@ proc ::tk::ConsoleInit {} { pack $con -fill both -expand 1 -side left switch -exact $tcl_platform(platform) { "macintosh" { - $con configure -font {Monaco 9 normal} -highlightthickness 0 + $con configure -font {Monaco 10 normal} -highlightthickness 0 } "windows" { $con configure -font systemfixed diff --git a/library/menu.tcl b/library/menu.tcl index aedeb95..d265156 100644 --- a/library/menu.tcl +++ b/library/menu.tcl @@ -4,11 +4,12 @@ # It also implements keyboard traversal of menus and implements a few # other utility procedures related to menus. # -# RCS: @(#) $Id: menu.tcl,v 1.18.2.4 2006/01/25 18:21:41 dgp Exp $ +# RCS: @(#) $Id: menu.tcl,v 1.18.2.5 2007/11/09 06:26:54 das Exp $ # # Copyright (c) 1992-1994 The Regents of the University of California. # Copyright (c) 1994-1997 Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. +# Copyright (c) 2007 Daniel A. Steffen # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -203,7 +204,7 @@ proc ::tk::MbEnter w { MbLeave $Priv(inMenubutton) } set Priv(inMenubutton) $w - if {[$w cget -state] ne "disabled"} { + if {[$w cget -state] ne "disabled" && [tk windowingsystem] ne "aqua"} { $w configure -state active } } @@ -222,7 +223,7 @@ proc ::tk::MbLeave w { if {![winfo exists $w]} { return } - if {[$w cget -state] eq "active"} { + if {[$w cget -state] eq "active" && [tk windowingsystem] ne "aqua"} { $w configure -state normal } } @@ -261,9 +262,13 @@ proc ::tk::MbPost {w {x {}} {y {}}} { MenuUnpost {} } set Priv(cursor) [$w cget -cursor] - set Priv(relief) [$w cget -relief] $w configure -cursor arrow - $w configure -relief raised + if {[tk windowingsystem] ne "aqua"} { + set Priv(relief) [$w cget -relief] + $w configure -relief raised + } else { + $w configure -state active + } set Priv(postedMb) $w set Priv(focus) [focus] @@ -405,7 +410,11 @@ proc ::tk::MenuUnpost menu { $menu unpost set Priv(postedMb) {} $mb configure -cursor $Priv(cursor) - $mb configure -relief $Priv(relief) + if {[tk windowingsystem] ne "aqua"} { + $mb configure -relief $Priv(relief) + } else { + $mb configure -state normal + } } elseif {$Priv(popup) ne ""} { $Priv(popup) unpost set Priv(popup) {} diff --git a/macosx/tkMacOSXButton.c b/macosx/tkMacOSXButton.c index edd641a..c3205b5 100644 --- a/macosx/tkMacOSXButton.c +++ b/macosx/tkMacOSXButton.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXButton.c,v 1.2.2.18 2007/06/29 03:22:00 das Exp $ + * RCS: @(#) $Id: tkMacOSXButton.c,v 1.2.2.19 2007/11/09 06:26:54 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -21,6 +21,12 @@ #define DEFAULT_USE_TK_TEXT 0 +#define CONTROL_INITIALIZED 1 +#define FIRST_DRAW 2 +#define ACTIVE 4 + +#define MAX_VALUE 1 + /* * Default insets for controls */ @@ -80,8 +86,6 @@ typedef struct { * The following are used to store the image content for * beveled buttons, i.e. buttons with images. */ - CCTabHandle tabHandle; - Pixmap picPixmap; ControlButtonContentInfo bevelButtonContent; OpenCPicParams picParams; } MacButton; @@ -90,7 +94,6 @@ typedef struct { * Forward declarations for procedures defined later in this file: */ - static OSStatus SetUserPaneDrawProc(ControlRef control, ControlUserPaneDrawProcPtr upp); static OSStatus SetUserPaneSetUpSpecialBackgroundProc(ControlRef control, @@ -120,7 +123,6 @@ Tk_ClassProcs tkpButtonProcs = { static int bCount; -int tkPictureIsOpen; /* *---------------------------------------------------------------------- @@ -154,16 +156,8 @@ TkpCreateButton( macButtonPtr->control = NULL; macButtonPtr->controlTitle[0] = 0; macButtonPtr->controlTitle[1] = 0; - macButtonPtr->picParams.version = -2; - macButtonPtr->picParams.hRes = 0x00480000; - macButtonPtr->picParams.vRes = 0x00480000; - macButtonPtr->picParams.srcRect.top = 0; - macButtonPtr->picParams.srcRect.left = 0; - macButtonPtr->picParams.reserved1 = 0; - macButtonPtr->picParams.reserved2 = 0; - macButtonPtr->bevelButtonContent.contentType = kControlContentPictHandle; bzero(&macButtonPtr->params, sizeof(macButtonPtr->params)); - bzero(&macButtonPtr->fontStyle,sizeof(macButtonPtr->fontStyle)); + bzero(&macButtonPtr->fontStyle, sizeof(macButtonPtr->fontStyle)); return (TkButton *)macButtonPtr; } @@ -190,7 +184,7 @@ void TkpDisplayButton( ClientData clientData) /* Information about widget. */ { - MacButton *macButtonPtr = (MacButton *)clientData; + MacButton *macButtonPtr = (MacButton *) clientData; TkButton *butPtr = (TkButton *) clientData; Tk_Window tkwin = butPtr->tkwin; CGrafPtr destPort, savePort; @@ -208,7 +202,6 @@ TkpDisplayButton( if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { return; } - pixmap = (Pixmap) Tk_WindowId(tkwin); wasUsingControl = macButtonPtr->usingControl; @@ -372,6 +365,12 @@ TkpDisplayButton( if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) { Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, pixmap, imageXOffset, imageYOffset); +#if 0 + } else if ((butPtr->tristateImage != NULL) && + (butPtr->flags & TRISTATED)) { + Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height, + pixmap, imageXOffset, imageYOffset); +#endif } else { Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, imageXOffset, imageYOffset); @@ -415,6 +414,12 @@ TkpDisplayButton( if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) { Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, pixmap, imageXOffset, imageYOffset); +#if 0 + } else if ((butPtr->tristateImage != NULL) && + (butPtr->flags & TRISTATED)) { + Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height, + pixmap, imageXOffset, imageYOffset); +#endif } else { Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, imageXOffset, imageYOffset); @@ -714,7 +719,7 @@ TkpComputeButtonGeometry( } } - if (TkMacOSXComputeDrawParams(butPtr,&drawParams)) { + if (TkMacOSXComputeDrawParams(butPtr, &drawParams)) { xInset = butPtr->indicatorSpace + DEF_INSET_LEFT + DEF_INSET_RIGHT; yInset = DEF_INSET_TOP + DEF_INSET_BOTTOM; } else { @@ -831,7 +836,10 @@ TkMacOSXInitControl( return 1; } - mbPtr->flags |= (1 + 2); + mbPtr->flags |= (CONTROL_INITIALIZED | FIRST_DRAW); + if (IsWindowActive(mbPtr->windowRef)) { + mbPtr->flags |= ACTIVE; + } return 0; } @@ -865,6 +873,8 @@ TkMacOSXDrawControl( TkButton *butPtr = (TkButton *) mbPtr; TkWindow *winPtr; Rect paneRect, cntrRect; + int active, enabled; + int rebuild; winPtr = (TkWindow *) butPtr->tkwin; @@ -890,12 +900,17 @@ TkMacOSXDrawControl( * The control has been previously initialised. * It may need to be re-initialised */ - +#ifdef TK_REBUILD_TOPLEVEL + rebuild = (winPtr->flags & TK_REBUILD_TOPLEVEL); + winPtr->flags &= ~TK_REBUILD_TOPLEVEL; +#else + rebuild = 0; +#endif if (mbPtr->flags) { MacControlParams params; TkMacOSXComputeControlParams(butPtr, ¶ms); - if (bcmp(¶ms, &mbPtr->params, sizeof(params))) { + if (rebuild || bcmp(¶ms, &mbPtr->params, sizeof(params))) { /* * The type of control has changed. * Clean it up and clear the flag. @@ -909,7 +924,7 @@ TkMacOSXDrawControl( mbPtr->flags = 0; } } - if (!(mbPtr->flags & 1)) { + if (!(mbPtr->flags & CONTROL_INITIALIZED)) { if (TkMacOSXInitControl(mbPtr, destPort, gc, pixmap, &paneRect, &cntrRect)) { return; @@ -933,7 +948,7 @@ TkMacOSXDrawControl( len = 0; controlTitle[0] = 0; } - if (bcmp(mbPtr->controlTitle, controlTitle, len+1)) { + if (rebuild || bcmp(mbPtr->controlTitle, controlTitle, len+1)) { CFStringRef cf = CFStringCreateWithCString(NULL, (char*) controlTitle, kCFStringEncodingUTF8); @@ -961,20 +976,31 @@ TkMacOSXDrawControl( if (butPtr->flags & SELECTED) { SetControlValue(mbPtr->control, 1); +#if 0 + } else if (butPtr->flags & TRISTATED) { + SetControlValue(mbPtr->control, 2); +#endif } else { SetControlValue(mbPtr->control, 0); } - if (!Tk_MacOSXIsAppInFront() || butPtr->state == STATE_DISABLED) { - HiliteControl(mbPtr->control, kControlInactivePart); - } else { - /* - * Use NoPart for normal and to ensure correct direct transition from - * disabled to active -state. [Bug 706446] - */ - - HiliteControl(mbPtr->control, kControlNoPart); - + active = ((mbPtr->flags & ACTIVE) != 0); + if (active != IsControlActive(mbPtr->control)) { + if (active) { + ChkErr(ActivateControl, mbPtr->control); + } else { + ChkErr(DeactivateControl, mbPtr->control); + } + } + enabled = !(butPtr->state == STATE_DISABLED); + if (enabled != IsControlEnabled(mbPtr->control)) { + if (enabled) { + ChkErr(EnableControl, mbPtr->control); + } else { + ChkErr(DisableControl, mbPtr->control); + } + } + if (active && enabled) { if (butPtr->state == STATE_ACTIVE) { if (mbPtr->params.isBevel) { HiliteControl(mbPtr->control, kControlButtonPart); @@ -991,6 +1017,8 @@ TkMacOSXDrawControl( break; } } + } else { + HiliteControl(mbPtr->control, kControlNoPart); } } UpdateControlColors(mbPtr); @@ -1007,17 +1035,20 @@ TkMacOSXDrawControl( kControlPushButtonDefaultTag, sizeof(isDefault), &isDefault); } - if (mbPtr->flags & 2) { + if (mbPtr->flags & FIRST_DRAW) { ShowControl(mbPtr->userPane); ShowControl(mbPtr->control); - mbPtr->flags ^= 2; + mbPtr->flags ^= FIRST_DRAW; } else { SetControlVisibility(mbPtr->control, true, true); Draw1Control(mbPtr->userPane); } if (mbPtr->params.isBevel) { - KillPicture(mbPtr->bevelButtonContent.u.picture); + if (mbPtr->bevelButtonContent.contentType == + kControlContentPictHandle) { + KillPicture(mbPtr->bevelButtonContent.u.picture); + } } } @@ -1052,9 +1083,7 @@ SetupBevelButton( int height, width; ControlButtonGraphicAlignment theAlignment; CGrafPtr savePort; - Boolean portChanged; - - portChanged = QDSwapPort(destPort, &savePort); + Boolean portChanged = false; if (butPtr->image != None) { Tk_SizeOfImage(butPtr->image, &width, &height); @@ -1069,27 +1098,38 @@ SetupBevelButton( height = butPtr->height; } - mbPtr->picParams.srcRect.right = width; - mbPtr->picParams.srcRect.bottom = height; - - /* - * Set the flag to circumvent clipping and bounds problems with OS 10.0.4 - */ - - mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams); - if (!mbPtr->bevelButtonContent.u.picture) { - TkMacOSXDbgMsg("OpenCPicture failed"); - } - tkPictureIsOpen = 1; + { + portChanged = QDSwapPort(destPort, &savePort); + mbPtr->picParams.version = -2; + mbPtr->picParams.hRes = 0x00480000; + mbPtr->picParams.vRes = 0x00480000; + mbPtr->picParams.srcRect.top = 0; + mbPtr->picParams.srcRect.left = 0; + mbPtr->picParams.srcRect.bottom = height; + mbPtr->picParams.srcRect.right = width; + mbPtr->picParams.reserved1 = 0; + mbPtr->picParams.reserved2 = 0; + mbPtr->bevelButtonContent.contentType = kControlContentPictHandle; + mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams); + if (!mbPtr->bevelButtonContent.u.picture) { + TkMacOSXDbgMsg("OpenCPicture failed"); + } + tkPictureIsOpen = 1; - /* - * TO DO - There is one case where XCopyPlane calls CopyDeepMask, - * which does not get recorded in the picture. So the bitmap code - * will fail in that case. - */ + /* + * TO DO - There is one case where XCopyPlane calls CopyDeepMask, + * which does not get recorded in the picture. So the bitmap code + * will fail in that case. + */ + } if (butPtr->selectImage != NULL && (butPtr->flags & SELECTED)) { Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, pixmap, 0, 0); +#if 0 + } else if (butPtr->tristateImage != NULL && (butPtr->flags & TRISTATED)) { + Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height, pixmap, 0, + 0); +#endif } else if (butPtr->image != NULL) { Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, 0, 0); } else { @@ -1098,11 +1138,16 @@ SetupBevelButton( height, 0, 0, 1); } - ClosePicture(); - tkPictureIsOpen = 0; - + { + ClosePicture(); + tkPictureIsOpen = 0; + if (portChanged) { + QDSwapPort(savePort, NULL); + } + } ChkErr(SetControlData, controlHandle, kControlButtonPart, - kControlBevelButtonContentTag, sizeof(ControlButtonContentInfo), + kControlBevelButtonContentTag, + sizeof(ControlButtonContentInfo), (char *) &mbPtr->bevelButtonContent); if (butPtr->anchor == TK_ANCHOR_N) { @@ -1124,7 +1169,6 @@ SetupBevelButton( } else if (butPtr->anchor == TK_ANCHOR_CENTER) { theAlignment = kControlBevelButtonAlignCenter; } - ChkErr(SetControlData, controlHandle, kControlButtonPart, kControlBevelButtonGraphicAlignTag, sizeof(ControlButtonGraphicAlignment), (char *) &theAlignment); @@ -1146,9 +1190,6 @@ SetupBevelButton( kControlBevelButtonTextPlaceTag, sizeof(ControlButtonTextPlacement), (char *) &thePlacement); } - if (portChanged) { - QDSwapPort(savePort, NULL); - } } /* @@ -1350,12 +1391,18 @@ ButtonEventProc( XEvent *eventPtr) /* Information about event. */ { TkButton *buttonPtr = (TkButton *) clientData; + MacButton *mbPtr = (MacButton *) clientData; if (eventPtr->type == ActivateNotify || eventPtr->type == DeactivateNotify) { if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) { return; } + if (eventPtr->type == ActivateNotify) { + mbPtr->flags |= ACTIVE; + } else { + mbPtr->flags &= ~ACTIVE; + } if ((buttonPtr->flags & REDRAW_PENDING) == 0) { Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) buttonPtr); buttonPtr->flags |= REDRAW_PENDING; @@ -1419,13 +1466,13 @@ TkMacOSXComputeControlParams( || (butPtr->indicatorOn)) { paramsPtr->initialValue = 1; paramsPtr->minValue = 0; - paramsPtr->maxValue = 1; + paramsPtr->maxValue = MAX_VALUE; paramsPtr->procID = kControlRadioButtonProc; } else { paramsPtr->initialValue = 0; paramsPtr->minValue = kControlBehaviorOffsetContents | kControlBehaviorSticky | kControlContentPictHandle; - paramsPtr->maxValue = 1; + paramsPtr->maxValue = MAX_VALUE; if (butPtr->borderWidth <= 2) { paramsPtr->procID = kControlBevelButtonSmallBevelProc; } else if (butPtr->borderWidth == 3) { @@ -1441,13 +1488,13 @@ TkMacOSXComputeControlParams( || (butPtr->indicatorOn)) { paramsPtr->initialValue = 1; paramsPtr->minValue = 0; - paramsPtr->maxValue = 1; + paramsPtr->maxValue = MAX_VALUE; paramsPtr->procID = kControlCheckBoxProc; } else { paramsPtr->initialValue = 0; paramsPtr->minValue = kControlBehaviorOffsetContents | kControlBehaviorSticky | kControlContentPictHandle; - paramsPtr->maxValue = 1; + paramsPtr->maxValue = MAX_VALUE; if (butPtr->borderWidth <= 2) { paramsPtr->procID = kControlBevelButtonSmallBevelProc; } else if (butPtr->borderWidth == 3) { diff --git a/macosx/tkMacOSXCarbonEvents.c b/macosx/tkMacOSXCarbonEvents.c index afdcb5f..3f9ed7a 100644 --- a/macosx/tkMacOSXCarbonEvents.c +++ b/macosx/tkMacOSXCarbonEvents.c @@ -60,7 +60,7 @@ * software in accordance with the terms specified in this * license. * - * RCS: @(#) $Id: tkMacOSXCarbonEvents.c,v 1.3.2.17 2007/06/29 03:22:01 das Exp $ + * RCS: @(#) $Id: tkMacOSXCarbonEvents.c,v 1.3.2.18 2007/11/09 06:26:54 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -80,21 +80,28 @@ static OSStatus CarbonEventHandlerProc(EventHandlerCallRef callRef, EventRef event, void *userData); static OSStatus InstallStandardApplicationEventHandler(void); -static void ExitRaelEventHandlerProc(EventHandlerCallRef callRef, - EventRef event, void *userData) __attribute__ ((__noreturn__)); static void CarbonTimerProc(EventLoopTimerRef timer, void *userData); /* * Static data used by several functions in this file: */ -static jmp_buf exitRaelJmpBuf; static EventLoopTimerRef carbonTimer = NULL; static int carbonTimerEnabled = 0; static EventHandlerUPP carbonEventHandlerUPP = NULL; static Tcl_Interp *carbonEventInterp = NULL; static int inTrackingLoop = 0; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 +/* + * For InstallStandardApplicationEventHandler(): + */ + +static jmp_buf exitRaelJmpBuf; +static void ExitRaelEventHandlerProc(EventHandlerCallRef callRef, + EventRef event, void *userData) __attribute__ ((__noreturn__)); +#endif + /* *---------------------------------------------------------------------- @@ -130,8 +137,9 @@ CarbonEventHandlerProc( bzero(&eventStatus, sizeof(eventStatus)); #ifdef TK_MAC_DEBUG_CARBON_EVENTS - if (macEvent.eKind != kEventMouseMoved && - macEvent.eKind != kEventMouseDragged) { + if (!(macEvent.eClass == kEventClassMouse && ( + macEvent.eKind == kEventMouseMoved || + macEvent.eKind == kEventMouseDragged))) { TkMacOSXDbgMsg("Started handling %s", TkMacOSXCarbonEventToAscii(event)); TkMacOSXInitNamedDebugSymbol(HIToolbox, void, _DebugPrintEvent, @@ -249,7 +257,7 @@ TkMacOSXInitCarbonEvents( _TraceEventByName(CFSTR("kEventWindowActivated")); _TraceEventByName(CFSTR("kEventWindowDeactivated")); _TraceEventByName(CFSTR("kEventWindowUpdate")); - _TraceEventByName(CFSTR("kEventWindowExpanded")); + _TraceEventByName(CFSTR("kEventWindowExpanding")); _TraceEventByName(CFSTR("kEventWindowBoundsChanged")); _TraceEventByName(CFSTR("kEventWindowDragStarted")); _TraceEventByName(CFSTR("kEventWindowDragCompleted")); @@ -289,7 +297,7 @@ TkMacOSXInstallWindowCarbonEventHandler( {kEventClassWindow, kEventWindowActivated}, {kEventClassWindow, kEventWindowDeactivated}, {kEventClassWindow, kEventWindowUpdate}, - {kEventClassWindow, kEventWindowExpanded}, + {kEventClassWindow, kEventWindowExpanding}, {kEventClassWindow, kEventWindowBoundsChanged}, {kEventClassWindow, kEventWindowDragStarted}, {kEventClassWindow, kEventWindowDragCompleted}, @@ -324,65 +332,92 @@ TkMacOSXInstallWindowCarbonEventHandler( static OSStatus InstallStandardApplicationEventHandler(void) { - /* - * This is a hack to workaround missing Carbon API to install the standard - * application event handler (InstallStandardEventHandler() does not work - * on the application target). The only way to install the standard app - * handler is to call RunApplicationEventLoop(), but since we are running - * our own event loop, we'll immediately need to break out of RAEL again: - * we do this via longjmp out of the ExitRaelEventHandlerProc event handler - * called first off from RAEL by posting a high priority dummy event. - * This workaround is derived from a similar approach in Technical Q&A 1061. - */ - enum { - kExitRaelEvent = 'ExiT' - }; - const EventTypeSpec exitRaelEventType = { - kExitRaelEvent, kExitRaelEvent - }; - EventHandlerUPP exitRaelEventHandler; - EventHandlerRef exitRaelEventHandlerRef = NULL; - EventRef exitRaelEvent = NULL; OSStatus err = memFullErr; - exitRaelEventHandler = NewEventHandlerUPP( - (EventHandlerProcPtr) ExitRaelEventHandlerProc); - if (exitRaelEventHandler) { - err = ChkErr(InstallEventHandler, GetEventDispatcherTarget(), - exitRaelEventHandler, 1, &exitRaelEventType, NULL, - &exitRaelEventHandlerRef); - } - if (err == noErr) { - err = ChkErr(CreateEvent, NULL, kExitRaelEvent, kExitRaelEvent, - GetCurrentEventTime(), kEventAttributeNone, &exitRaelEvent); - } - if (err == noErr) { - err = ChkErr(PostEventToQueue, GetMainEventQueue(), exitRaelEvent, - kEventPriorityHigh); - } - if (err == noErr) { - if (!setjmp(exitRaelJmpBuf)) { - RunApplicationEventLoop(); + TK_IF_HI_TOOLBOX(5, + /* + * The approach below does not work correctly in Leopard, it leads to + * crashes in [NSView unlockFocus] whenever HIToolbox uses Cocoa (Help + * menu, Nav Services, Color Picker). While it is now possible to + * install the standard app handler with InstallStandardEventHandler(), + * to fully replicate RAEL the standard menubar event handler also needs + * to be installed. Unfortunately there appears to be no public API to + * obtain the menubar event target. As a workaround, for now we resort + * to calling the HIToolbox-internal GetMenuBarEventTarget() directly + * (symbol acquired via TkMacOSXInitNamedDebugSymbol() from HIToolbox + * version 343, may not exist in later versions). + */ + err = ChkErr(InstallStandardEventHandler, GetApplicationEventTarget()); + TkMacOSXInitNamedDebugSymbol(HIToolbox, EventTargetRef, + GetMenuBarEventTarget, void); + if (GetMenuBarEventTarget) { + ChkErr(InstallStandardEventHandler, GetMenuBarEventTarget()); + } else { + TkMacOSXDbgMsg("Unable to install standard menubar event handler"); + } + ) TK_ELSE_HI_TOOLBOX (5, + /* + * This is a hack to workaround missing Carbon API to install the + * standard application event handler (InstallStandardEventHandler() + * does not work on the application target). The only way to install the + * standard app handler is to call RunApplicationEventLoop(), but since + * we are running our own event loop, we'll immediately need to break + * out of RAEL again: we do this via longjmp out of the + * ExitRaelEventHandlerProc event handler called first off from RAEL by + * posting a high priority dummy event. This workaround is derived from + * a similar approach in Technical Q&A 1061. + */ + enum { + kExitRaelEvent = 'ExiT' + }; + const EventTypeSpec exitRaelEventType = { + kExitRaelEvent, kExitRaelEvent + }; + EventHandlerUPP exitRaelEventHandler; + EventHandlerRef exitRaelEventHandlerRef = NULL; + EventRef exitRaelEvent = NULL; + + exitRaelEventHandler = NewEventHandlerUPP( + (EventHandlerProcPtr) ExitRaelEventHandlerProc); + if (exitRaelEventHandler) { + err = ChkErr(InstallEventHandler, GetEventDispatcherTarget(), + exitRaelEventHandler, 1, &exitRaelEventType, NULL, + &exitRaelEventHandlerRef); + } + if (err == noErr) { + err = ChkErr(CreateEvent, NULL, kExitRaelEvent, kExitRaelEvent, + GetCurrentEventTime(), kEventAttributeNone, + &exitRaelEvent); + } + if (err == noErr) { + err = ChkErr(PostEventToQueue, GetMainEventQueue(), exitRaelEvent, + kEventPriorityHigh); + } + if (err == noErr) { + if (!setjmp(exitRaelJmpBuf)) { + RunApplicationEventLoop(); - /* - * This point should never be reached! - */ + /* + * This point should never be reached! + */ - Tcl_Panic("RunApplicationEventLoop exited !"); + Tcl_Panic("RunApplicationEventLoop exited !"); + } } - } - if (exitRaelEvent) { - ReleaseEvent(exitRaelEvent); - } - if (exitRaelEventHandlerRef) { - RemoveEventHandler(exitRaelEventHandlerRef); - } - if (exitRaelEventHandler) { - DisposeEventHandlerUPP(exitRaelEventHandler); - } + if (exitRaelEvent) { + ReleaseEvent(exitRaelEvent); + } + if (exitRaelEventHandlerRef) { + RemoveEventHandler(exitRaelEventHandlerRef); + } + if (exitRaelEventHandler) { + DisposeEventHandlerUPP(exitRaelEventHandler); + } + ) TK_ENDIF return err; } +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 /* *---------------------------------------------------------------------- * @@ -409,6 +444,7 @@ ExitRaelEventHandlerProc( { longjmp(exitRaelJmpBuf, 1); } +#endif /* *---------------------------------------------------------------------- diff --git a/macosx/tkMacOSXColor.c b/macosx/tkMacOSXColor.c index cc2e674..2b6c32b 100644 --- a/macosx/tkMacOSXColor.c +++ b/macosx/tkMacOSXColor.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXColor.c,v 1.2.2.10 2007/07/02 13:06:14 das Exp $ + * RCS: @(#) $Id: tkMacOSXColor.c,v 1.2.2.11 2007/11/09 06:26:55 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -253,9 +253,12 @@ GetThemeColor( } else if (textColor) { err = ChkErr(GetThemeTextColor, textColor, 32, true, c); } else { - c->red = ((pixel >> 16) & 0xff) << 8; - c->green = ((pixel >> 8) & 0xff) << 8; - c->blue = ((pixel ) & 0xff) << 8; + c->red = (pixel >> 16) & 0xff; + c->green = (pixel >> 8) & 0xff; + c->blue = (pixel ) & 0xff; + c->red |= c->red << 8; + c->green |= c->green << 8; + c->blue |= c->blue << 8; } return err; } @@ -638,6 +641,37 @@ TkpGetColorByValue( return tkColPtr; } +#if 0 +/* + *---------------------------------------------------------------------- + * + * TkMacOSXCompareColors -- + * + * On Mac, color codes may specify symbolic values like "highlight + * foreground", but we really need the actual values to compare. + * Maybe see also: "TIP #154: Add Named Colors to Tk". + * + * Results: + * Returns true if both colors are the same, false otherwise. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TkMacOSXCompareColors( + unsigned long c1, + unsigned long c2) +{ + RGBColor col1, col2; + return TkSetMacColor(c1,&col1) && + TkSetMacColor(c1,&col2) && + !memcmp(&col1,&col2,sizeof(col1)); +} +#endif /* !TK_DRAW_IN_CONTEXT */ + /* *---------------------------------------------------------------------- * diff --git a/macosx/tkMacOSXDebug.c b/macosx/tkMacOSXDebug.c index 88d23f4..ac2bef8 100644 --- a/macosx/tkMacOSXDebug.c +++ b/macosx/tkMacOSXDebug.c @@ -54,7 +54,7 @@ * software in accordance with the terms specified in this * license. * - * RCS: @(#) $Id: tkMacOSXDebug.c,v 1.2.2.13 2007/06/29 03:22:01 das Exp $ + * RCS: @(#) $Id: tkMacOSXDebug.c,v 1.2.2.14 2007/11/09 06:26:55 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -62,9 +62,6 @@ #ifdef TK_MAC_DEBUG -#include -#include - typedef struct { EventKind kind; const char * name; @@ -456,22 +453,35 @@ TkMacOSXMouseTrackingResultToAscii(MouseTrackingResult r, char * buf) MODULE_SCOPE void TkMacOSXDebugFlashRegion( Drawable d, - RgnHandle rgn) + HIShapeRef rgn) { TkMacOSXInitNamedDebugSymbol(HIToolbox, int, QDDebugFlashRegion, CGrafPtr port, RgnHandle region); - if (d && rgn && QDDebugFlashRegion && !EmptyRgn(rgn)) { + CFShow(rgn); + if (d && rgn && QDDebugFlashRegion && !HIShapeIsEmpty(rgn)) { CGrafPtr port = TkMacOSXGetDrawablePort(d); if (port) { + static RgnHandle qdRgn = NULL; + + if (!qdRgn) { + qdRgn = NewRgn(); + } + ChkErr(HIShapeGetAsQDRgn, rgn, qdRgn); + /* * Carbon-internal region flashing SPI (c.f. Technote 2124) */ - QDDebugFlashRegion(port, rgn); + QDDebugFlashRegion(port, qdRgn); + SetEmptyRgn(qdRgn); } } } +#endif /* TK_MAC_DEBUG */ + +#include +#include /* *---------------------------------------------------------------------- @@ -511,7 +521,7 @@ TkMacOSXGetNamedDebugSymbol( if (!addr) { const struct mach_header *mh = NULL; uint32_t i, n = _dyld_image_count(); - size_t module_len; + size_t module_len = 0; if (module && *module) { module_len = strlen(module); @@ -606,5 +616,3 @@ TkMacOSXGetNamedDebugSymbol( #endif /* __LP64__ */ return addr; } - -#endif /* TK_MAC_DEBUG */ diff --git a/macosx/tkMacOSXDebug.h b/macosx/tkMacOSXDebug.h index 5798898..1ce594d 100644 --- a/macosx/tkMacOSXDebug.h +++ b/macosx/tkMacOSXDebug.h @@ -54,7 +54,7 @@ * software in accordance with the terms specified in this * license. * - * RCS: @(#) $Id: tkMacOSXDebug.h,v 1.2.2.10 2007/06/29 03:22:01 das Exp $ + * RCS: @(#) $Id: tkMacOSXDebug.h,v 1.2.2.11 2007/11/09 06:26:55 das Exp $ */ #ifndef _TKMACDEBUG @@ -82,7 +82,9 @@ MODULE_SCOPE char* TkMacOSXMenuMessageToAscii(int msg, char * s); MODULE_SCOPE char* TkMacOSXMouseTrackingResultToAscii(MouseTrackingResult r, char * buf ); #endif -MODULE_SCOPE void TkMacOSXDebugFlashRegion(Drawable d, RgnHandle rgn); +MODULE_SCOPE void TkMacOSXDebugFlashRegion(Drawable d, HIShapeRef rgn); + +#endif /* TK_MAC_DEBUG */ MODULE_SCOPE void* TkMacOSXGetNamedDebugSymbol(const char* module, const char* symbol); @@ -93,6 +95,4 @@ MODULE_SCOPE void* TkMacOSXGetNamedDebugSymbol(const char* module, const char* s symbol = TkMacOSXGetNamedDebugSymbol(STRINGIFY(module), STRINGIFY(_##symbol));\ } -#endif /* TK_MAC_DEBUG */ - #endif diff --git a/macosx/tkMacOSXDefault.h b/macosx/tkMacOSXDefault.h index 559a38e..7327ec0 100644 --- a/macosx/tkMacOSXDefault.h +++ b/macosx/tkMacOSXDefault.h @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXDefault.h,v 1.2.2.6 2007/10/30 01:54:59 das Exp $ + * RCS: @(#) $Id: tkMacOSXDefault.h,v 1.2.2.7 2007/11/09 06:26:55 das Exp $ */ #ifndef _TKMACDEFAULT @@ -32,7 +32,8 @@ #define BLACK "Black" #define WHITE "White" #define NORMAL_BG "systemWindowBody" -#define ACTIVE_BG "#ececec" +#define ACTIVE_BG "systemButtonFacePressed" +#define ACTIVE_FG "systemPushButtonPressedText" #define SELECT_BG "systemHighlight" #define SELECT_FG None #define INACTIVE_SELECT_BG "systemHighlightSecondary" @@ -45,9 +46,9 @@ */ #define DEF_BUTTON_ANCHOR "center" -#define DEF_BUTTON_ACTIVE_BG_COLOR "systemButtonText" +#define DEF_BUTTON_ACTIVE_BG_COLOR ACTIVE_BG #define DEF_BUTTON_ACTIVE_BG_MONO BLACK -#define DEF_BUTTON_ACTIVE_FG_COLOR "systemButtonFace" +#define DEF_BUTTON_ACTIVE_FG_COLOR ACTIVE_FG #define DEF_CHKRAD_ACTIVE_FG_COLOR DEF_BUTTON_ACTIVE_FG_COLOR #define DEF_BUTTON_ACTIVE_FG_MONO WHITE /* #define DEF_BUTTON_BG_COLOR "systemButtonFace"*/ @@ -227,8 +228,8 @@ * Defaults for listboxes: */ -#define DEF_LISTBOX_ACTIVE_STYLE "underline" -#define DEF_LISTBOX_BG_COLOR NORMAL_BG +#define DEF_LISTBOX_ACTIVE_STYLE "dotbox" +#define DEF_LISTBOX_BG_COLOR WHITE #define DEF_LISTBOX_BG_MONO WHITE #define DEF_LISTBOX_BORDER_WIDTH "1" #define DEF_LISTBOX_CURSOR "" @@ -298,7 +299,7 @@ #define DEF_MENU_CURSOR "arrow" #define DEF_MENU_DISABLED_FG_COLOR "systemMenuDisabled" #define DEF_MENU_DISABLED_FG_MONO "" -#define DEF_MENU_FONT "menu" +#define DEF_MENU_FONT "menu" /* special: see tkMacOSXMenu.c */ #define DEF_MENU_FG "systemMenuText" #define DEF_MENU_POST_COMMAND "" #define DEF_MENU_RELIEF "flat" @@ -322,7 +323,7 @@ #define DEF_MENUBUTTON_ANCHOR "center" #define DEF_MENUBUTTON_ACTIVE_BG_COLOR ACTIVE_BG #define DEF_MENUBUTTON_ACTIVE_BG_MONO BLACK -#define DEF_MENUBUTTON_ACTIVE_FG_COLOR BLACK +#define DEF_MENUBUTTON_ACTIVE_FG_COLOR ACTIVE_FG #define DEF_MENUBUTTON_ACTIVE_FG_MONO WHITE #define DEF_MENUBUTTON_BG_COLOR NORMAL_BG #define DEF_MENUBUTTON_BG_MONO WHITE @@ -363,7 +364,7 @@ #define DEF_MESSAGE_ASPECT "150" #define DEF_MESSAGE_BG_COLOR NORMAL_BG #define DEF_MESSAGE_BG_MONO WHITE -#define DEF_MESSAGE_BORDER_WIDTH "2" +#define DEF_MESSAGE_BORDER_WIDTH "1" #define DEF_MESSAGE_CURSOR "" #define DEF_MESSAGE_FG BLACK #define DEF_MESSAGE_FONT "system" @@ -384,19 +385,19 @@ #define DEF_PANEDWINDOW_BG_COLOR NORMAL_BG #define DEF_PANEDWINDOW_BG_MONO WHITE -#define DEF_PANEDWINDOW_BORDERWIDTH "2" +#define DEF_PANEDWINDOW_BORDERWIDTH "1" #define DEF_PANEDWINDOW_CURSOR "" #define DEF_PANEDWINDOW_HANDLEPAD "8" #define DEF_PANEDWINDOW_HANDLESIZE "8" #define DEF_PANEDWINDOW_HEIGHT "" -#define DEF_PANEDWINDOW_OPAQUERESIZE "0" +#define DEF_PANEDWINDOW_OPAQUERESIZE "1" #define DEF_PANEDWINDOW_ORIENT "horizontal" #define DEF_PANEDWINDOW_RELIEF "flat" #define DEF_PANEDWINDOW_SASHCURSOR "" -#define DEF_PANEDWINDOW_SASHPAD "2" -#define DEF_PANEDWINDOW_SASHRELIEF "raised" -#define DEF_PANEDWINDOW_SASHWIDTH "2" -#define DEF_PANEDWINDOW_SHOWHANDLE "1" +#define DEF_PANEDWINDOW_SASHPAD "0" +#define DEF_PANEDWINDOW_SASHRELIEF "flat" +#define DEF_PANEDWINDOW_SASHWIDTH "3" +#define DEF_PANEDWINDOW_SHOWHANDLE "0" #define DEF_PANEDWINDOW_WIDTH "" /* @@ -421,7 +422,7 @@ #define DEF_SCALE_BG_COLOR NORMAL_BG #define DEF_SCALE_BG_MONO WHITE #define DEF_SCALE_BIG_INCREMENT "0" -#define DEF_SCALE_BORDER_WIDTH "2" +#define DEF_SCALE_BORDER_WIDTH "1" #define DEF_SCALE_COMMAND "" #define DEF_SCALE_CURSOR "" #define DEF_SCALE_DIGITS "0" @@ -461,18 +462,15 @@ #define DEF_SCROLLBAR_ACTIVE_RELIEF "raised" #define DEF_SCROLLBAR_BG_COLOR NORMAL_BG #define DEF_SCROLLBAR_BG_MONO WHITE -/* #define DEF_SCROLLBAR_BORDER_WIDTH "2" */ #define DEF_SCROLLBAR_BORDER_WIDTH "0" #define DEF_SCROLLBAR_COMMAND "" #define DEF_SCROLLBAR_CURSOR "" #define DEF_SCROLLBAR_EL_BORDER_WIDTH "-1" #define DEF_SCROLLBAR_HIGHLIGHT_BG NORMAL_BG #define DEF_SCROLLBAR_HIGHLIGHT BLACK -/* #define DEF_SCROLLBAR_HIGHLIGHT_WIDTH "2" */ #define DEF_SCROLLBAR_HIGHLIGHT_WIDTH "0" #define DEF_SCROLLBAR_JUMP "0" #define DEF_SCROLLBAR_ORIENT "vertical" -/*#define DEF_SCROLLBAR_RELIEF "sunken" */ #define DEF_SCROLLBAR_RELIEF "flat" #define DEF_SCROLLBAR_REPEAT_DELAY "300" #define DEF_SCROLLBAR_REPEAT_INTERVAL "100" diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 86074b8..dd9a448 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.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: tkMacOSXDialog.c,v 1.4.2.20 2007/10/26 10:37:14 das Exp $ + * RCS: @(#) $Id: tkMacOSXDialog.c,v 1.4.2.21 2007/11/09 06:26:55 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -41,6 +41,7 @@ typedef struct _OpenFileData { FileFilterList fl; /* List of file filters. */ SInt16 curType; /* The filetype currently being listed. */ + short initialType; /* Type to use initially */ short popupItem; /* Item number of the popup in the dialog. */ short usePopup; /* True if we show the popup menu (this */ /* is an open operation and the */ @@ -84,7 +85,7 @@ static int NavServicesGetFile(Tcl_Interp *interp, OpenFileData *ofd, AEDesc *initialDescPtr, char *initialFile, AEDescList *selectDescPtr, CFStringRef title, CFStringRef message, - int multiple, int isOpen, + const char *initialType, int multiple, int isOpen, Tk_Window parent); static int HandleInitialDirectory(Tcl_Interp *interp, char *initialFile, char *initialDir, FSRef *dirRef, @@ -261,13 +262,18 @@ Tk_GetOpenFileObjCmd( AEDesc *initialPtr = NULL; AEDescList selectDesc = {typeNull, NULL}; char *initialFile = NULL, *initialDir = NULL; +#if 0 + Tcl_Obj *typeVariablePtr = NULL; +#endif + const char *initialtype = NULL; static const char *openOptionStrings[] = { "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-message", "-multiple", "-parent", "-title", NULL + "-message", "-multiple", "-parent", "-title",/* "-typevariable",*/ NULL }; enum openOptions { OPEN_DEFAULT, OPEN_FILETYPES, OPEN_INITDIR, OPEN_INITFILE, - OPEN_MESSAGE, OPEN_MULTIPLE, OPEN_PARENT, OPEN_TITLE + OPEN_MESSAGE, OPEN_MULTIPLE, OPEN_PARENT, OPEN_TITLE, + /*OPEN_TYPEVARIABLE,*/ }; if (!fileDlgInited) { @@ -275,6 +281,7 @@ Tk_GetOpenFileObjCmd( } TkInitFileFilters(&ofd.fl); ofd.curType = 0; + ofd.initialType = -1; ofd.popupItem = OPEN_POPUP_ITEM; ofd.usePopup = 1; @@ -338,6 +345,11 @@ Tk_GetOpenFileObjCmd( title = CFStringCreateWithBytes(NULL, (unsigned char*) choice, choiceLen, kCFStringEncodingUTF8, false); break; +#if 0 + case OPEN_TYPEVARIABLE: + typeVariablePtr = objv[i + 1]; + break; +#endif } } @@ -345,12 +357,29 @@ Tk_GetOpenFileObjCmd( &selectDesc, &initialDesc) != TCL_OK) { goto end; } - if (initialDesc.descriptorType == typeFSRef) { initialPtr = &initialDesc; } +#if 0 + if (typeVariablePtr) { + initialtype = Tcl_GetVar(interp, Tcl_GetString(typeVariablePtr), 0); + } +#endif result = NavServicesGetFile(interp, &ofd, initialPtr, NULL, &selectDesc, - title, message, multiple, OPEN_FILE, parent); + title, message, initialtype, multiple, OPEN_FILE, parent); + +#if 0 + if (typeVariablePtr) { + FileFilter *filterPtr = ofd.fl.filters; + int i = ofd.curType; + + while (filterPtr && i-- > 0) { + filterPtr = filterPtr->next; + } + Tcl_SetVar(interp, Tcl_GetString(typeVariablePtr), filterPtr->name, 0); + } +#endif + end: TkFreeFileFilters(&ofd.fl); if (initialDesc.dataHandle) { @@ -401,11 +430,11 @@ Tk_GetSaveFileObjCmd( OpenFileData ofd; static const char *saveOptionStrings[] = { "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-message", "-parent", "-title", NULL + "-message", "-parent", "-title",/* "-typevariable",*/ NULL }; enum saveOptions { SAVE_DEFAULT, SAVE_FILETYPES, SAVE_INITDIR, SAVE_INITFILE, - SAVE_MESSAGE, SAVE_PARENT, SAVE_TITLE + SAVE_MESSAGE, SAVE_PARENT, SAVE_TITLE,/* SAVE_TYPEVARIABLE,*/ }; if (!fileDlgInited) { @@ -480,7 +509,7 @@ Tk_GetSaveFileObjCmd( initialPtr = &initialDesc; } result = NavServicesGetFile(interp, &ofd, initialPtr, initialFile, NULL, - title, message, false, SAVE_FILE, parent); + title, message, NULL, false, SAVE_FILE, parent); TkFreeFileFilters(&ofd.fl); end: if (initialDesc.dataHandle) { @@ -588,7 +617,7 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) initialPtr = &initialDesc; } result = NavServicesGetFile(interp, &ofd, initialPtr, NULL, NULL, title, - message, false, CHOOSE_FOLDER, parent); + message, NULL, false, CHOOSE_FOLDER, parent); TkFreeFileFilters(&ofd.fl); end: if (initialDesc.dataHandle) { @@ -737,6 +766,7 @@ NavServicesGetFile( AEDescList *selectDescPtr, CFStringRef title, CFStringRef message, + const char *initialtype, int multiple, int isOpen, Tk_Window parent) @@ -800,6 +830,9 @@ NavServicesGetFile( filterPtr = filterPtr->next, index++) { menuItemNames[index] = CFStringCreateWithCString(NULL, filterPtr->name, kCFStringEncodingUTF8); + if (initialtype && strcmp(filterPtr->name, initialtype) == 0) { + ofdPtr->initialType = index; + } } options.popupExtension = CFArrayCreate(NULL, (const void **) menuItemNames, ofdPtr->fl.numFilters, NULL); @@ -991,6 +1024,29 @@ OpenEventProc( OpenFileData *ofd = data->ofdPtr; switch (callBackSelector) { + case kNavCBStart: + if (ofd && ofd->initialType >= 0) { + /* Select initial filter */ + FileFilter *filterPtr = ofd->fl.filters; + int i = ofd->initialType; + + while (filterPtr && i-- > 0) { + filterPtr = filterPtr->next; + } + if (filterPtr) { + NavMenuItemSpec selectItem; + + selectItem.version = kNavMenuItemSpecVersion; + selectItem.menuCreator = 0; + selectItem.menuType = ofd->initialType; + selectItem.menuItemName[0] = strlen(filterPtr->name); + strncpy((char*) &selectItem.menuItemName[1], + filterPtr->name, 255); + ChkErr(NavCustomControl, callBackParams->context, + kNavCtlSelectCustomType, &selectItem); + } + } + break; case kNavCBPopupMenuSelect: ofd->curType = ((NavMenuItemSpec *) callBackParams->eventData.eventDataParms.param)->menuType; @@ -1061,7 +1117,7 @@ OpenFileFilterProc( if (!theInfo->isFolder) { OSType fileType; - StringPtr fileNamePtr; + StringPtr fileNamePtr = NULL; Tcl_DString fileNameDString; int i; FileFilter *filterPtr; @@ -1077,7 +1133,6 @@ OpenFileFilterProc( strncpy(fileName, (char*) fileNamePtr + 1, len); fileName[len] = '\0'; fileNamePtr = (unsigned char*) fileName; - } else if ((theItem->descriptorType == typeFSRef)) { OSStatus err; FSRef *theRef = (FSRef *) *theItem->dataHandle; @@ -1091,8 +1146,6 @@ OpenFileFilterProc( uniFileName.length, &fileNameDString); fileNamePtr = (unsigned char*) Tcl_DStringValue(&fileNameDString); - } else { - fileNamePtr = NULL; } } if (ofdPtr->usePopup) { @@ -1423,13 +1476,13 @@ Tk_MessageBoxObjCmd( indexDefaultOption = i; break; -/* +#if 0 case ALERT_DETAIL: str = Tcl_GetString(objv[i + 1]); finemessageTextCF = CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8); break; -*/ +#endif case ALERT_ICON: if (Tcl_GetIndexFromObj(interp, objv[i + 1], diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c index 8960567..5d1157c 100644 --- a/macosx/tkMacOSXDraw.c +++ b/macosx/tkMacOSXDraw.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.2.2.29 2007/07/09 08:30:31 das Exp $ + * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.2.2.30 2007/11/09 06:26:55 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -43,6 +43,8 @@ RgnHandle tkMacOSXtmpQdRgn = NULL; int tkMacOSXUseCGDrawing = 1; +int tkPictureIsOpen; + static PixPatHandle penPat = NULL; static int cgAntiAliasLimit = 0; @@ -55,7 +57,7 @@ static int useThemedFrame = 0; * Prototypes for functions used only in this file. */ -static void ClipToGC(Drawable d, GC gc, CGrafPtr port, RgnHandle clipRgn); +static void ClipToGC(Drawable d, GC gc, HIShapeRef *clipRgnPtr); static void NoQDClip(CGrafPtr port); @@ -153,7 +155,7 @@ XCopyArea( GC gc, /* GC to use. */ int src_x, /* X & Y, width & height */ int src_y, /* define the source rectangle */ - unsigned int width, /* the will be copied. */ + unsigned int width, /* that will be copied. */ unsigned int height, int dest_x, /* Dest X & Y on dest rect. */ int dest_y) @@ -163,32 +165,50 @@ XCopyArea( display->request++; if (!width || !height) { - TkMacOSXDbgMsg("Drawing of emtpy area requested"); + /* TkMacOSXDbgMsg("Drawing of emtpy area requested"); */ return; } - if (!TkMacOSXSetupDrawingContext(dst, gc, 0, &dc)) { - Rect srcRect, dstRect, *srcPtr = &srcRect, *dstPtr = &dstRect; + { CGrafPtr srcPort; - const BitMap *srcBit, *dstBit; - RGBColor black = {0, 0, 0}, white = {0xffff, 0xffff, 0xffff}; srcPort = TkMacOSXGetDrawablePort(src); - srcBit = GetPortBitMapForCopyBits(srcPort); - dstBit = GetPortBitMapForCopyBits(dc.port); - SetRect(srcPtr, srcDraw->xOff + src_x, srcDraw->yOff + src_y, - srcDraw->xOff + src_x + width, srcDraw->yOff + src_y + height); - if (tkPictureIsOpen) { - dstPtr = srcPtr; + if (srcPort) { + Rect srcRect, dstRect, *srcPtr = &srcRect, *dstPtr = &dstRect; + const BitMap *srcBit, *dstBit; + RGBColor black = {0, 0, 0}, white = {0xffff, 0xffff, 0xffff}; + + if (!TkMacOSXSetupDrawingContext(dst, gc, 0, &dc)) { + return; + } + if (dc.context) { + TkMacOSXDbgMsg("Ignored CG drawing of QD drawable"); + goto end; + } + if (!dc.port) { + TkMacOSXDbgMsg("Invalid destination drawable"); + goto end; + } + srcBit = GetPortBitMapForCopyBits(srcPort); + dstBit = GetPortBitMapForCopyBits(dc.port); + SetRect(srcPtr, srcDraw->xOff + src_x, srcDraw->yOff + src_y, + srcDraw->xOff + src_x + width, + srcDraw->yOff + src_y + height); + if (tkPictureIsOpen) { + dstPtr = srcPtr; + } else { + SetRect(dstPtr, dstDraw->xOff + dest_x, dstDraw->yOff + dest_y, + dstDraw->xOff + dest_x + width, + dstDraw->yOff + dest_y + height); + } + RGBForeColor(&black); + RGBBackColor(&white); + CopyBits(srcBit, dstBit, srcPtr, dstPtr, srcCopy, NULL); +end: + TkMacOSXRestoreDrawingContext(&dc); } else { - SetRect(dstPtr, dstDraw->xOff + dest_x, dstDraw->yOff + dest_y, - dstDraw->xOff + dest_x + width, - dstDraw->yOff + dest_y + height); + TkMacOSXDbgMsg("Invalid source drawable"); } - RGBForeColor(&black); - RGBBackColor(&white); - CopyBits(srcBit, dstBit, srcPtr, dstPtr, srcCopy, NULL); } - TkMacOSXRestoreDrawingContext(&dc); } /* @@ -218,7 +238,7 @@ XCopyPlane( GC gc, /* GC to use. */ int src_x, /* X & Y, width & height */ int src_y, /* define the source rectangle */ - unsigned int width, /* the will be copied. */ + unsigned int width, /* that will be copied. */ unsigned int height, int dest_x, /* Dest X & Y on dest rect. */ int dest_y, @@ -229,61 +249,80 @@ XCopyPlane( display->request++; if (!width || !height) { - TkMacOSXDbgMsg("Drawing of emtpy area requested"); + /* TkMacOSXDbgMsg("Drawing of emtpy area requested"); */ return; } if (plane != 1) { Tcl_Panic("Unexpected plane specified for XCopyPlane"); } - if (!TkMacOSXSetupDrawingContext(dst, gc, 0, &dc)) { - Rect srcRect, dstRect, *srcPtr = &srcRect, *dstPtr = &dstRect; + { CGrafPtr srcPort; - const BitMap *srcBit, *dstBit; - TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask; srcPort = TkMacOSXGetDrawablePort(src); - srcBit = GetPortBitMapForCopyBits(srcPort); - dstBit = GetPortBitMapForCopyBits(dc.port); - SetRect(srcPtr, srcDraw->xOff + src_x, srcDraw->yOff + src_y, - srcDraw->xOff + src_x + width, srcDraw->yOff + src_y + height); - if (tkPictureIsOpen) { - dstPtr = srcPtr; - } else { - SetRect(dstPtr, dstDraw->xOff + dest_x, dstDraw->yOff + dest_y, - dstDraw->xOff + dest_x + width, - dstDraw->yOff + dest_y + height); - } - TkMacOSXSetColorInPort(gc->foreground, 1, NULL, dc.port); - if (!clipPtr || clipPtr->type == TKP_CLIP_REGION) { - /* - * Opaque bitmaps. - */ + if (srcPort) { + Rect srcRect, dstRect, *srcPtr = &srcRect, *dstPtr = &dstRect; + const BitMap *srcBit, *dstBit; + TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask; - TkMacOSXSetColorInPort(gc->background, 0, NULL, dc.port); - CopyBits(srcBit, dstBit, srcPtr, dstPtr, srcCopy, NULL); - } else if (clipPtr->type == TKP_CLIP_PIXMAP) { - if (clipPtr->value.pixmap == src) { - /* - * Transparent bitmaps. If it's color we ignore the forecolor. - */ - short tmode = GetPixDepth(GetPortPixMap(srcPort)) == 1 ? - srcOr : transparent; - - CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL); + if (!TkMacOSXSetupDrawingContext(dst, gc, 0, &dc)) { + return; + } + if (dc.context) { + TkMacOSXDbgMsg("Ignored CG drawing of QD drawable"); + goto end; + } + if (!dc.port) { + TkMacOSXDbgMsg("Invalid destination drawable"); + goto end; + } + srcBit = GetPortBitMapForCopyBits(srcPort); + dstBit = GetPortBitMapForCopyBits(dc.port); + SetRect(srcPtr, srcDraw->xOff + src_x, srcDraw->yOff + src_y, + srcDraw->xOff + src_x + width, + srcDraw->yOff + src_y + height); + if (tkPictureIsOpen) { + dstPtr = srcPtr; } else { + SetRect(dstPtr, dstDraw->xOff + dest_x, dstDraw->yOff + dest_y, + dstDraw->xOff + dest_x + width, + dstDraw->yOff + dest_y + height); + } + TkMacOSXSetColorInPort(gc->foreground, 1, NULL, dc.port); + if (!clipPtr || clipPtr->type == TKP_CLIP_REGION) { /* - * Two arbitrary bitmaps. + * Opaque bitmaps. */ - CGrafPtr mskPort = TkMacOSXGetDrawablePort(clipPtr->value.pixmap); - const BitMap *mskBit = GetPortBitMapForCopyBits(mskPort); + TkMacOSXSetColorInPort(gc->background, 0, NULL, dc.port); + CopyBits(srcBit, dstBit, srcPtr, dstPtr, srcCopy, NULL); + } else if (clipPtr->type == TKP_CLIP_PIXMAP) { + if (clipPtr->value.pixmap == src) { + /* + * Transparent bitmaps. If it's color ignore the forecolor. + */ + short tmode = GetPixDepth(GetPortPixMap(srcPort)) == 1 ? + srcOr : transparent; + + CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL); + } else { + /* + * Two arbitrary bitmaps. + */ + + CGrafPtr mskPort = TkMacOSXGetDrawablePort( + clipPtr->value.pixmap); + const BitMap *mskBit = GetPortBitMapForCopyBits(mskPort); - CopyDeepMask(srcBit, mskBit, dstBit, srcPtr, srcPtr, dstPtr, - srcCopy, NULL); + CopyDeepMask(srcBit, mskBit, dstBit, srcPtr, srcPtr, + dstPtr, srcCopy, NULL); + } } +end: + TkMacOSXRestoreDrawingContext(&dc); + } else { + TkMacOSXDbgMsg("Invalid source drawable"); } } - TkMacOSXRestoreDrawingContext(&dc); } /* @@ -323,14 +362,19 @@ TkPutImage( display->request++; if (!TkMacOSXSetupDrawingContext(d, gc, 0, &dc)) { + return; + } + if (dc.context) { + TkMacOSXDbgMsg("Ignored CG drawing of XImage"); + } else { Rect srcRect, dstRect, *srcPtr = &srcRect, *dstPtr = &dstRect; const BitMap *dstBit; RGBColor black = {0, 0, 0}, white = {0xffff, 0xffff, 0xffff}; int i, j; char *newData = NULL; char *dataPtr, *newPtr, *oldPtr; - int rowBytes = image->bytes_per_line; - int slices, sliceRowBytes, lastSliceRowBytes, sliceWidth, lastSliceWidth; + int rowBytes = image->bytes_per_line, sliceRowBytes, lastSliceRowBytes; + int slices, sliceWidth, lastSliceWidth; dstBit = GetPortBitMapForCopyBits(dc.port); SetRect(srcPtr, src_x, src_y, src_x + width, src_y + height); @@ -348,8 +392,9 @@ TkPutImage( * Image from XGetImage, copy from containing GWorld directly. */ - CopyBits(GetPortBitMapForCopyBits(TkMacOSXGetDrawablePort((Drawable) - image->obdata)), dstBit, srcPtr, dstPtr, srcCopy, NULL); + CopyBits(GetPortBitMapForCopyBits(TkMacOSXGetDrawablePort( + (Drawable)image->obdata)), dstBit, + srcPtr, dstPtr, srcCopy, NULL); } else if (image->depth == 1) { /* * BW image @@ -529,7 +574,10 @@ XDrawLines( } display->request++; - if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + return; + } + if (dc.context) { double prevx, prevy; double o = (lw % 2) ? .5 : 0; @@ -599,7 +647,10 @@ XDrawSegments( int i, lw = gc->line_width; display->request++; - if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + return; + } + if (dc.context) { double o = (lw % 2) ? .5 : 0; for (i = 0; i < nsegments; i++) { @@ -660,7 +711,10 @@ XFillPolygon( int i; display->request++; - if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + return; + } + if (dc.context) { double prevx, prevy; double o = (gc->line_width % 2) ? .5 : 0; @@ -735,7 +789,10 @@ XDrawRectangle( } display->request++; - if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + return; + } + if (dc.context) { CGRect rect; double o = (lw % 2) ? .5 : 0; @@ -798,7 +855,10 @@ XDrawRectangles( int i, lw = gc->line_width; display->request++; - if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + return; + } + if (dc.context) { CGRect rect; double o = (lw % 2) ? .5 : 0; @@ -858,7 +918,10 @@ XFillRectangles( int i; display->request++; - if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + return; + } + if (dc.context) { CGRect rect; for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) { @@ -921,7 +984,10 @@ XDrawArc( } display->request++; - if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + return; + } + if (dc.context) { CGRect rect; double o = (lw % 2) ? .5 : 0; @@ -1003,7 +1069,10 @@ XDrawArcs( int i, lw = gc->line_width; display->request++; - if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + return; + } + if (dc.context) { CGRect rect; double o = (lw % 2) ? .5 : 0; @@ -1096,7 +1165,10 @@ XFillArc( } display->request++; - if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + return; + } + if (dc.context) { CGRect rect; double o = (lw % 2) ? .5 : 0, u = 0; @@ -1210,7 +1282,10 @@ XFillArcs( int i, lw = gc->line_width; display->request++; - if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) { + return; + } + if (dc.context) { CGRect rect; double o = (lw % 2) ? .5 : 0, u = 0; @@ -1356,7 +1431,7 @@ TkScrollWindow( Boolean portChanged; Rect scrollRect; int result; - RgnHandle rgn = (RgnHandle) damageRgn; + HIShapeRef dmgRgn; /* * Due to the implementation below the behavior may be differnt @@ -1385,8 +1460,9 @@ TkScrollWindow( destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin)); + TkMacOSXCheckTmpQdRgnEmpty(); portChanged = QDSwapPort(destPort, &savePort); - ScrollRect(&scrollRect, dx, dy, rgn); + ScrollRect(&scrollRect, dx, dy, tkMacOSXtmpQdRgn); if (portChanged) { QDSwapPort(savePort, NULL); } @@ -1398,7 +1474,11 @@ TkScrollWindow( * created. */ - result = EmptyRgn(rgn) ? 0 : 1; + dmgRgn = HIShapeCreateWithQDRgn(tkMacOSXtmpQdRgn); + SetEmptyRgn(tkMacOSXtmpQdRgn); + TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn); + result = HIShapeIsEmpty(dmgRgn) ? 0 : 1; + CFRelease(dmgRgn); return result; } @@ -1456,7 +1536,9 @@ TkMacOSXSetUpGraphicsPort( * Set up a drawing context for the given drawable and GC. * * Results: - * Boolean indicating whether to use CG drawing. + * Boolean indicating whether it is ok to draw; if false, drawing + * context was not setup, so do not attempt to draw and do not call + * TkMacOSXRestoreDrawingContext(). * * Side effects: * None. @@ -1469,149 +1551,160 @@ TkMacOSXSetupDrawingContext( Drawable d, GC gc, int useCG, /* advisory only ! */ - TkMacOSXDrawingContext *dc) + TkMacOSXDrawingContext *dcPtr) { MacDrawable *macDraw = ((MacDrawable*)d); - CGContextRef context = macDraw->context; - CGrafPtr port; - Rect portBounds; - - dc->saveState = NULL; - dc->saveClip = NULL; - dc->penPat = NULL; - dc->portChanged = false; - port = TkMacOSXGetDrawablePort(d); - if (port) { - GetPortBounds(port, &portBounds); - dc->saveClip = NewRgn(); - GetPortClipRegion(port, dc->saveClip); - if (tkPictureIsOpen) { - NoQDClip(port); - } else { - TkMacOSXSetUpClippingRgn(d); + int dontDraw = 0; + TkMacOSXDrawingContext dc = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, + {SHRT_MIN, SHRT_MIN, SHRT_MAX, SHRT_MAX}, false}; + + if (tkPictureIsOpen) { + if (useCG) { + TkMacOSXDbgMsg("Ignored CG Drawing with QD Picture open"); + dontDraw = 1; } + } else { + dc.clipRgn = TkMacOSXGetClipRgn(d); } - if (context && useCG) { - if (!port) { - TK_IF_MAC_OS_X_API (3, CGContextGetClipBoundingBox, - CGRect r = CGContextGetClipBoundingBox(context); + if (!dontDraw) { + ClipToGC(d, gc, &dc.clipRgn); + dontDraw = dc.clipRgn ? HIShapeIsEmpty(dc.clipRgn) : 0; + } + if (dontDraw) { + if (dc.clipRgn) { + CFRelease(dc.clipRgn); + dc.clipRgn = NULL; + } + goto end; + } + if (useCG) { + dc.context = macDraw->context;; + } + if (!dc.context || !(macDraw->flags & TK_IS_PIXMAP)) { + dc.port = TkMacOSXGetDrawablePort(d); + if (dc.port) { + GetPortBounds(dc.port, &dc.portBounds); + } + } + if (dc.context) { + if (!dc.port) { + CGRect r; - SetRect(&portBounds, r.origin.x + macDraw->xOff, - r.origin.y + macDraw->yOff, - r.origin.x + r.size.width + macDraw->xOff, - r.origin.y + r.size.height + macDraw->yOff); + TK_IF_MAC_OS_X_API (3, CGContextGetClipBoundingBox, + r = CGContextGetClipBoundingBox(dc.context); + ) TK_ELSE_MAC_OS_X (3, + r.origin = CGPointZero; + r.size = macDraw->size; ) TK_ENDIF + SetRect(&dc.portBounds, r.origin.x + macDraw->xOff, + r.origin.y + macDraw->yOff, + r.origin.x + r.size.width + macDraw->xOff, + r.origin.y + r.size.height + macDraw->yOff); } - CGContextSaveGState(context); - dc->saveState = (void*)1; - port = NULL; - } else if (port) { - dc->portChanged = QDSwapPort(port, &(dc->savePort)); - if (useCG && ChkErr(QDBeginCGContext, port, &context) == noErr) { - SyncCGContextOriginWithPort(context, port); + CGContextSaveGState(dc.context); + dc.saveState = (void*)1; + dc.port = NULL; + } else if (dc.port) { + dc.portChanged = QDSwapPort(dc.port, &dc.savePort); + if (useCG && ChkErr(QDBeginCGContext, dc.port, &dc.context) == noErr) { + SyncCGContextOriginWithPort(dc.context, dc.port); } else { - context = NULL; - useCG = 0; + dc.context = NULL; } } else { Tcl_Panic("TkMacOSXSetupDrawingContext(): " "no port or context to draw into !"); } - if (useCG) { - if (tkPictureIsOpen) { - TkMacOSXDbgMsg("Ignored CG Drawing with QD Picture open"); - } else if (context) { - TkMacOSXCheckTmpQdRgnEmpty(); - RectRgn(tkMacOSXtmpQdRgn, &portBounds); - if (port) { - SectRegionWithPortClipRegion(port, tkMacOSXtmpQdRgn); - SectRegionWithPortVisibleRegion(port, tkMacOSXtmpQdRgn); - } else if (macDraw->flags & TK_CLIPPED_DRAW) { - OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff); - SectRgn(macDraw->clipRgn, macDraw->drawRgn, tkMacOSXtmpQdRgn); - OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff); + if (dc.context) { + CGContextConcatCTM(dc.context, CGAffineTransformMake(1.0, 0.0, 0.0, + -1.0, 0.0, dc.portBounds.bottom - dc.portBounds.top)); + if (dc.clipRgn) { +#ifdef TK_MAC_DEBUG_DRAWING + CGContextSaveGState(dc.context); + ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context); + CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.2); + CGContextEOFillPath(dc.context); + CGContextRestoreGState(dc.context); +#endif /* TK_MAC_DEBUG_DRAWING */ + ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context); + CGContextEOClip(dc.context); + } + if (gc) { + static const CGLineCap cgCap[] = { + [CapNotLast] = kCGLineCapButt, + [CapButt] = kCGLineCapButt, + [CapRound] = kCGLineCapRound, + [CapProjecting] = kCGLineCapSquare, + }; + static const CGLineJoin cgJoin[] = { + [JoinMiter] = kCGLineJoinMiter, + [JoinRound] = kCGLineJoinRound, + [JoinBevel] = kCGLineJoinBevel, + }; + bool shouldAntialias; + double w = gc->line_width; + + TkMacOSXSetColorInContext(gc->foreground, dc.context); + if (dc.port) { + CGContextSetPatternPhase(dc.context, CGSizeMake( + dc.portBounds.right - dc.portBounds.left, + dc.portBounds.bottom - dc.portBounds.top)); } - ClipToGC(d, gc, NULL, tkMacOSXtmpQdRgn); - ClipCGContextToRegion(context, &portBounds, tkMacOSXtmpQdRgn); - SetEmptyRgn(tkMacOSXtmpQdRgn); - CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0, - -1.0, 0.0, portBounds.bottom - portBounds.top)); - if (gc) { - double w = gc->line_width; - - TkMacOSXSetColorInContext(gc->foreground, context); - if (port) { - CGContextSetPatternPhase(context, - CGSizeMake(portBounds.right - portBounds.left, - portBounds.bottom - portBounds.top)); - } - if(gc->function != GXcopy) { - TkMacOSXDbgMsg("Logical functions other than GXcopy are " - "not supported for CG drawing!"); - } - /* When should we antialias? */ - if (notAA(gc->line_width)) { - /* Make non-antialiased CG drawing look more like X11 */ - w -= (gc->line_width ? NON_AA_CG_OFFSET : 0); - CGContextSetShouldAntialias(context, 0); - } else { - CGContextSetShouldAntialias(context, 1); - } - CGContextSetLineWidth(context, w); - if (gc->line_style != LineSolid) { - int num = 0; - char *p = &(gc->dashes); - double dashOffset = gc->dash_offset; - float lengths[10]; - - while (p[num] != '\0' && num < 10) { - lengths[num] = p[num]; - num++; - } - CGContextSetLineDash(context, dashOffset, lengths, num); - } - if (gc->cap_style == CapButt) { - /* - * What about CapNotLast, CapProjecting? - */ - - CGContextSetLineCap(context, kCGLineCapButt); - } else if (gc->cap_style == CapRound) { - CGContextSetLineCap(context, kCGLineCapRound); - } else if (gc->cap_style == CapProjecting) { - CGContextSetLineCap(context, kCGLineCapSquare); - } - if (gc->join_style == JoinMiter) { - CGContextSetLineJoin(context, kCGLineJoinMiter); - } else if (gc->join_style == JoinRound) { - CGContextSetLineJoin(context, kCGLineJoinRound); - } else if (gc->join_style == JoinBevel) { - CGContextSetLineJoin(context, kCGLineJoinBevel); + if(gc->function != GXcopy) { + TkMacOSXDbgMsg("Logical functions other than GXcopy are " + "not supported for CG drawing!"); + } + /* When should we antialias? */ + shouldAntialias = !notAA(gc->line_width); + if (!shouldAntialias) { + /* Make non-antialiased CG drawing look more like X11 */ + w -= (gc->line_width ? NON_AA_CG_OFFSET : 0); + } + CGContextSetShouldAntialias(dc.context, shouldAntialias); + CGContextSetLineWidth(dc.context, w); + if (gc->line_style != LineSolid) { + int num = 0; + char *p = &(gc->dashes); + double dashOffset = gc->dash_offset; + float lengths[10]; + + while (p[num] != '\0' && num < 10) { + lengths[num] = p[num]; + num++; } + CGContextSetLineDash(dc.context, dashOffset, lengths, num); } - } - } else { - if (port) { - PixPatHandle savePat = penPat; - - ChkErr(GetThemeDrawingState, &(dc->saveState)); - penPat = NULL; - TkMacOSXSetUpGraphicsPort(gc, port); - dc->penPat = penPat; - penPat = savePat; - if (gc) { - TkMacOSXCheckTmpQdRgnEmpty(); - ClipToGC(d, gc, port, tkMacOSXtmpQdRgn); + if ((unsigned)gc->cap_style < sizeof(cgCap)/sizeof(CGLineCap)) { + CGContextSetLineCap(dc.context, + cgCap[(unsigned)gc->cap_style]); } - if (!tkPictureIsOpen) { - ShowPen(); + if ((unsigned)gc->join_style < sizeof(cgJoin)/sizeof(CGLineJoin)) { + CGContextSetLineJoin(dc.context, + cgJoin[(unsigned)gc->join_style]); } } + } else if (dc.port) { + PixPatHandle savePat = penPat; + + ChkErr(GetThemeDrawingState, &dc.saveState); + penPat = NULL; + TkMacOSXSetUpGraphicsPort(gc, dc.port); + dc.penPat = penPat; + penPat = savePat; + dc.saveClip = NewRgn(); + GetPortClipRegion(dc.port, dc.saveClip); + if (dc.clipRgn) { + ChkErr(HIShapeSetQDClip, dc.clipRgn, dc.port); + } else { + NoQDClip(dc.port); + } + if (!tkPictureIsOpen) { + ShowPen(); + } } - dc->portBounds = portBounds; - dc->port = port; - dc->context = context; - return useCG; +end: + *dcPtr = dc; + return !dontDraw; } /* @@ -1631,87 +1724,130 @@ TkMacOSXSetupDrawingContext( */ void -TkMacOSXRestoreDrawingContext(TkMacOSXDrawingContext *dc) +TkMacOSXRestoreDrawingContext( + TkMacOSXDrawingContext *dcPtr) { - if (dc->context) { - CGContextSynchronize(dc->context); - if (dc->saveState) { - CGContextRestoreGState(dc->context); + if (dcPtr->context) { + CGContextSynchronize(dcPtr->context); + if (dcPtr->saveState) { + CGContextRestoreGState(dcPtr->context); } - if (dc->port) { - ChkErr(QDEndCGContext, dc->port, &(dc->context)); + if (dcPtr->port) { + ChkErr(QDEndCGContext, dcPtr->port, &(dcPtr->context)); } - } else if (dc->port) { + } else if (dcPtr->port) { if (!tkPictureIsOpen) { HidePen(); } PenNormal(); - if (dc->saveClip) { - SetPortClipRegion(dc->port, dc->saveClip); - DisposeRgn(dc->saveClip); + if (dcPtr->saveClip) { + SetPortClipRegion(dcPtr->port, dcPtr->saveClip); + DisposeRgn(dcPtr->saveClip); } - if (dc->penPat) { - DisposePixPat(dc->penPat); + if (dcPtr->penPat) { + DisposePixPat(dcPtr->penPat); } - if (dc->saveState) { - ChkErr(SetThemeDrawingState, dc->saveState, true); + if (dcPtr->saveState) { + ChkErr(SetThemeDrawingState, dcPtr->saveState, true); } } - if (dc->portChanged) { - QDSwapPort(dc->savePort, NULL); + if (dcPtr->clipRgn) { + CFRelease(dcPtr->clipRgn); + } + if (dcPtr->portChanged) { + QDSwapPort(dcPtr->savePort, NULL); } #ifdef TK_MAC_DEBUG - bzero(dc, sizeof(dc)); + bzero(dcPtr, sizeof(dcPtr)); #endif /* TK_MAC_DEBUG */ } /* *---------------------------------------------------------------------- * - * TkMacOSXSetUpClippingRgn -- + * TkMacOSXGetClipRgn -- * - * Set up the clipping region so that drawing only occurs on the - * specified X subwindow. + * Get the clipping region needed to restrict drawing to the given + * drawable. * * Results: - * None. + * Clipping region. If non-NULL, CFRelease it when done. * * Side effects: - * The clipping region in the current port is changed. + * None. * *---------------------------------------------------------------------- */ -void -TkMacOSXSetUpClippingRgn( - Drawable drawable) /* Drawable to update. */ +HIShapeRef +TkMacOSXGetClipRgn( + Drawable drawable) /* Drawable. */ { MacDrawable *macDraw = (MacDrawable *) drawable; - CGrafPtr port = TkMacOSXGetDrawablePort(drawable); + HIShapeRef clipRgn = NULL; + CGRect r; if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) { TkMacOSXUpdateClipRgn(macDraw->winPtr); #ifdef TK_MAC_DEBUG_DRAWING - TkMacOSXDbgMsg("%s clipRgn ", macDraw->winPtr->pathName); - TkMacOSXDebugFlashRegion(drawable, macDraw->clipRgn); + TkMacOSXDbgMsg("%s visRgn ", macDraw->winPtr->pathName); + TkMacOSXDebugFlashRegion(drawable, macDraw->visRgn); #endif /* TK_MAC_DEBUG_DRAWING */ } - if (macDraw->clipRgn) { + if (macDraw->flags & TK_CLIPPED_DRAW) { + r = CGRectOffset(macDraw->drawRect, macDraw->xOff, macDraw->yOff); + } + if (macDraw->visRgn) { if (macDraw->flags & TK_CLIPPED_DRAW) { - TkMacOSXCheckTmpQdRgnEmpty(); - OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff); - SectRgn(macDraw->clipRgn, macDraw->drawRgn, tkMacOSXtmpQdRgn); - OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff); - SetPortClipRegion(port, tkMacOSXtmpQdRgn); - SetEmptyRgn(tkMacOSXtmpQdRgn); + HIShapeRef rgn = HIShapeCreateWithRect(&r); + + clipRgn = HIShapeCreateIntersection(macDraw->visRgn, rgn); + CFRelease(rgn); } else { - SetPortClipRegion(port, macDraw->clipRgn); + clipRgn = HIShapeCreateCopy(macDraw->visRgn); } } else if (macDraw->flags & TK_CLIPPED_DRAW) { - OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff); - SetPortClipRegion(port, macDraw->drawRgn); - OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff); + clipRgn = HIShapeCreateWithRect(&r); + } +#ifdef TK_MAC_DEBUG_DRAWING + TkMacOSXDbgMsg("%s clipRgn ", macDraw->winPtr->pathName); + TkMacOSXDebugFlashRegion(drawable, clipRgn); +#endif /* TK_MAC_DEBUG_DRAWING */ + + return clipRgn; +} + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXSetUpClippingRgn -- + * + * Set up the clipping region so that drawing only occurs on the + * specified X subwindow. + * + * Results: + * None. + * + * Side effects: + * The clipping region in the current port is changed. + * + *---------------------------------------------------------------------- + */ + +void +TkMacOSXSetUpClippingRgn( + Drawable drawable) /* Drawable to update. */ +{ + CGrafPtr port = TkMacOSXGetDrawablePort(drawable); + + if (port) { + HIShapeRef clipRgn = TkMacOSXGetClipRgn(drawable); + + if (clipRgn) { + ChkErr(HIShapeSetQDClip, clipRgn, port); + CFRelease(clipRgn); + } } } @@ -1741,14 +1877,12 @@ TkpClipDrawableToRect( { MacDrawable *macDraw = (MacDrawable *) d; - if (macDraw->drawRgn) { - if (width < 0 && height < 0) { - SetEmptyRgn(macDraw->drawRgn); - macDraw->flags &= ~TK_CLIPPED_DRAW; - } else { - SetRectRgn(macDraw->drawRgn, x, y, x + width, y + height); - macDraw->flags |= TK_CLIPPED_DRAW; - } + if (width < 0 && height < 0) { + macDraw->drawRect = CGRectNull; + macDraw->flags &= ~TK_CLIPPED_DRAW; + } else { + macDraw->drawRect = CGRectMake(x, y, width, height); + macDraw->flags |= TK_CLIPPED_DRAW; } } @@ -1757,8 +1891,7 @@ TkpClipDrawableToRect( * * ClipToGC -- * - * Helper function to intersect the given port's clip region (or if - * port is NULL, the given clipRgn) with gc clip region. + * Helper function to intersect given region with gc clip region. * * Results: * None. @@ -1773,29 +1906,28 @@ static void ClipToGC( Drawable d, GC gc, - CGrafPtr port, /* can be NULL */ - RgnHandle clipRgn) /* tmp region or if port == NULL, region to intersect */ + HIShapeRef *clipRgnPtr) /* must point to initialized variable */ { if (gc && gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type == TKP_CLIP_REGION) { - RgnHandle gcClipRgn = (RgnHandle) - ((TkpClipMask*)gc->clip_mask)->value.region; + TkRegion gcClip = ((TkpClipMask*)gc->clip_mask)->value.region; int xOffset = ((MacDrawable *) d)->xOff + gc->clip_x_origin; int yOffset = ((MacDrawable *) d)->yOff + gc->clip_y_origin; + HIShapeRef clipRgn = *clipRgnPtr, gcClipRgn; if (!tkPictureIsOpen) { - OffsetRgn(gcClipRgn, xOffset, yOffset); + TkMacOSXOffsetRegion(gcClip, xOffset, yOffset); } - if (port) { - GetPortClipRegion(port, clipRgn); - } - SectRgn(clipRgn, gcClipRgn, clipRgn); - if (port) { - SetPortClipRegion(port, clipRgn); - SetEmptyRgn(clipRgn); + gcClipRgn = TkMacOSXGetNativeRegion(gcClip); + if (clipRgn) { + *clipRgnPtr = HIShapeCreateIntersection(gcClipRgn, clipRgn); + CFRelease(clipRgn); + } else { + *clipRgnPtr = HIShapeCreateCopy(gcClipRgn); } + CFRelease(gcClipRgn); if (!tkPictureIsOpen) { - OffsetRgn(gcClipRgn, -xOffset, -yOffset); + TkMacOSXOffsetRegion(gcClip, -xOffset, -yOffset); } } } diff --git a/macosx/tkMacOSXEmbed.c b/macosx/tkMacOSXEmbed.c index 0620dca..7b89f61 100644 --- a/macosx/tkMacOSXEmbed.c +++ b/macosx/tkMacOSXEmbed.c @@ -15,7 +15,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXEmbed.c,v 1.2.2.7 2007/06/04 09:28:44 das Exp $ + * RCS: @(#) $Id: tkMacOSXEmbed.c,v 1.2.2.8 2007/11/09 06:26:55 das Exp $ */ #include "tkMacOSXInt.h" @@ -148,14 +148,14 @@ TkpMakeWindow( } macWin->winPtr = winPtr; winPtr->privatePtr = macWin; - macWin->clipRgn = NewRgn(); - macWin->aboveClipRgn = NewRgn(); - macWin->drawRgn = NewRgn(); + macWin->visRgn = NULL; + macWin->aboveVisRgn = NULL; + macWin->drawRect = CGRectNull; macWin->referenceCount = 0; macWin->flags = TK_CLIP_INVALID; - macWin->grafPtr = NULL; macWin->context = NULL; + macWin->size = CGSizeZero; if (Tk_IsTopLevel(macWin->winPtr)) { /* *This will be set when we are mapped. @@ -299,10 +299,10 @@ TkpUseWindow( macWin->grafPtr = NULL; macWin->context = NULL; - - macWin->clipRgn = NewRgn(); - macWin->aboveClipRgn = NewRgn(); - macWin->drawRgn = NewRgn(); + macWin->size = CGSizeZero; + macWin->visRgn = NULL; + macWin->aboveVisRgn = NULL; + macWin->drawRect = CGRectNull; macWin->referenceCount = 0; macWin->flags = TK_CLIP_INVALID; macWin->toplevel = macWin; diff --git a/macosx/tkMacOSXEntry.c b/macosx/tkMacOSXEntry.c index 19303e5..6ddafab 100644 --- a/macosx/tkMacOSXEntry.c +++ b/macosx/tkMacOSXEntry.c @@ -53,7 +53,7 @@ * software in accordance with the terms specified in this * license. * - * RCS: @(#) $Id: tkMacOSXEntry.c,v 1.2.2.12 2007/06/29 03:22:01 das Exp $ + * RCS: @(#) $Id: tkMacOSXEntry.c,v 1.2.2.13 2007/11/09 06:26:55 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -197,7 +197,9 @@ TkpDrawEntryBorderAndFocus(Entry *entryPtr, Drawable d, int isSpinbox) } else { drawState = kThemeStateActive; } - TkMacOSXSetupDrawingContext(d, NULL, 0, &dc); + if (!TkMacOSXSetupDrawingContext(d, NULL, 0, &dc)) { + return 0; + } DrawThemeEditTextFrame(&bounds, drawState); if (entryPtr->flags & GOT_FOCUS) { /* @@ -307,7 +309,9 @@ TkpDrawSpinboxButtons(Spinbox *sbPtr, Drawable d) rects[0].height = Tk_Height(tkwin); XFillRectangles(Tk_Display(tkwin), d, bgGC, rects, 1); - TkMacOSXSetupDrawingContext(d, NULL, 0, &dc); + if (!TkMacOSXSetupDrawingContext(d, NULL, 0, &dc)) { + return 0; + } ChkErr(DrawThemeButton, &inBounds, inKind, &inNewInfo, inPrevInfo, inEraseProc, inLabelProc, inUserData); TkMacOSXRestoreDrawingContext(&dc); diff --git a/macosx/tkMacOSXEvent.c b/macosx/tkMacOSXEvent.c index e72a800..acc7d7d 100644 --- a/macosx/tkMacOSXEvent.c +++ b/macosx/tkMacOSXEvent.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: tkMacOSXEvent.c,v 1.3.2.15 2007/06/29 03:22:02 das Exp $ + * RCS: @(#) $Id: tkMacOSXEvent.c,v 1.3.2.16 2007/11/09 06:26:55 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -243,7 +243,7 @@ TkMacOSXProcessCommandEvent( (menuContext & kMenuContextMenuBarTracking)) { TkMacOSXHandleMenuSelect(GetMenuID(command.menu.menuRef), command.menu.menuItemIndex, - GetCurrentEventKeyModifiers() & optionKey); + (GetCurrentEventKeyModifiers() & optionKey) != 0); return 1; } } else { diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c index 94c2ade..23f279b 100644 --- a/macosx/tkMacOSXFont.c +++ b/macosx/tkMacOSXFont.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXFont.c,v 1.3.2.10 2007/06/29 03:22:02 das Exp $ + * RCS: @(#) $Id: tkMacOSXFont.c,v 1.3.2.11 2007/11/09 06:26:55 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -1025,7 +1025,9 @@ Tk_DrawChars( MacFont *fontPtr = (MacFont *) tkfont; TkMacOSXDrawingContext drawingContext; - TkMacOSXSetupDrawingContext(drawable, gc, 0, &drawingContext); + if (!TkMacOSXSetupDrawingContext(drawable, gc, 0, &drawingContext)) { + return; + } #if 0 /* * Stippled QD text drawing only kind of works and is ugly, so disable it @@ -1044,7 +1046,10 @@ Tk_DrawChars( stippleMap = TkMacOSXMakeStippleMap(drawable, gc->stipple); pixmap = Tk_GetPixmap(display, drawable, stippleMap->bounds.right, stippleMap->bounds.bottom, 0); - TkMacOSXSetupDrawingContext(pixmap, gc, 0, &pixmapDrawingContext); + if (!TkMacOSXSetupDrawingContext(pixmap, gc, 0, + &pixmapDrawingContext)) { + return; + } GetQDGlobalsWhite(&white); FillRect(&stippleMap->bounds, &white); MultiFontDrawText(fontPtr, source, numBytes, 0, macWin->yOff + y); diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index d87c8a4..23e003d 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXInit.c,v 1.3.2.24 2007/06/29 03:22:02 das Exp $ + * RCS: @(#) $Id: tkMacOSXInit.c,v 1.3.2.25 2007/11/09 06:26:55 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -332,6 +332,18 @@ TkpInit( TkMacOSXCarbonEncoding = Tcl_GetEncoding(NULL, NULL); } +#if 0 + /* + * FIXME: Close stdin & stdout for remote debugging otherwise we + * will fight with gdb for stdin & stdout + */ + + if (getenv("XCNOSTDIN") != NULL) { + close(0); + close(1); + } +#endif + /* * If we don't have a TTY and stdin is a special character file of * length 0, (e.g. /dev/null, which is what Finder sets when double diff --git a/macosx/tkMacOSXInt.h b/macosx/tkMacOSXInt.h index 98418aa..4c25061 100644 --- a/macosx/tkMacOSXInt.h +++ b/macosx/tkMacOSXInt.h @@ -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: tkMacOSXInt.h,v 1.3.2.22 2007/08/23 10:45:15 das Exp $ + * RCS: @(#) $Id: tkMacOSXInt.h,v 1.3.2.23 2007/11/09 06:26:55 das Exp $ */ #ifndef _TKMACINT @@ -39,9 +39,10 @@ struct TkWindowPrivate { ControlRef rootControl; int xOff; /* X offset from toplevel window */ int yOff; /* Y offset from toplevel window */ - RgnHandle clipRgn; /* Visible region of window */ - RgnHandle aboveClipRgn; /* Visible region of window & its children */ - RgnHandle drawRgn; /* Clipped drawing region */ + CGSize size; + HIShapeRef visRgn; /* Visible region of window */ + HIShapeRef aboveVisRgn; /* Visible region of window & its children */ + CGRect drawRect; /* Clipped drawing rect */ int referenceCount; /* Don't delete toplevel until children are * gone. */ struct TkWindowPrivate *toplevel; @@ -71,6 +72,8 @@ typedef struct TkMacOSXWindowList { #define TK_HOST_EXISTS 0x04 #define TK_DRAWN_UNDER_MENU 0x08 #define TK_CLIPPED_DRAW 0x10 +#define TK_IS_PIXMAP 0x20 +#define TK_IS_BW_PIXMAP 0x40 /* * I am reserving TK_EMBEDDED = 0x100 in the MacDrawable flags @@ -154,6 +157,8 @@ MODULE_SCOPE int XSetClipRectangles(Display *d, GC gc, int clip_x_origin, #endif MODULE_SCOPE void TkpClipDrawableToRect(Display *display, Drawable d, int x, int y, int width, int height); +MODULE_SCOPE void TkpRetainRegion(TkRegion r); +MODULE_SCOPE void TkpReleaseRegion(TkRegion r); /* * Include the stubbed internal platform-specific API. diff --git a/macosx/tkMacOSXMenu.c b/macosx/tkMacOSXMenu.c index 02039c2..17880c4 100644 --- a/macosx/tkMacOSXMenu.c +++ b/macosx/tkMacOSXMenu.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: tkMacOSXMenu.c,v 1.6.2.29 2007/06/29 03:22:02 das Exp $ + * RCS: @(#) $Id: tkMacOSXMenu.c,v 1.6.2.30 2007/11/09 06:26:56 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -343,10 +343,11 @@ DrawThemeText( cmdKeyBaseline); bounds = &adjustedBounds; } - TkMacOSXSetupDrawingContext(d, gc, 1, &dc); - ChkErr(DrawThemeTextBox, string, font, drawState, false, bounds, just, - dc.context); - TkMacOSXRestoreDrawingContext(&dc); + if (TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { + ChkErr(DrawThemeTextBox, string, font, drawState, false, bounds, just, + dc.context); + TkMacOSXRestoreDrawingContext(&dc); + } } /* @@ -2702,9 +2703,10 @@ DrawMenuSeparator( r.left = x; r.bottom = y + height; r.right = x + width; - TkMacOSXSetupDrawingContext(d, gc, 1, &dc); - ChkErr(DrawThemeMenuSeparator, &r); - TkMacOSXRestoreDrawingContext(&dc); + if (TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { + ChkErr(DrawThemeMenuSeparator, &r); + TkMacOSXRestoreDrawingContext(&dc); + } } #ifdef USE_TK_MDEF @@ -3983,14 +3985,15 @@ TkpMenuInit(void) macMDEFDrawable.winPtr = NULL; macMDEFDrawable.xOff = 0; macMDEFDrawable.yOff = 0; - macMDEFDrawable.clipRgn = NULL; - macMDEFDrawable.aboveClipRgn = NULL; - macMDEFDrawable.drawRgn = NewRgn(); + macMDEFDrawable.visRgn = NULL; + macMDEFDrawable.aboveVisRgn = NULL; + macMDEFDrawable.drawRect = CGRectNull; macMDEFDrawable.referenceCount = 0; macMDEFDrawable.toplevel = NULL; macMDEFDrawable.flags = 0; macMDEFDrawable.grafPtr = NULL; macMDEFDrawable.context = NULL; + macMDEFDrawable.size = CGSizeZero; #endif ChkErr(GetThemeMetric, kThemeMetricMenuMarkColumnWidth, diff --git a/macosx/tkMacOSXMenubutton.c b/macosx/tkMacOSXMenubutton.c index 8b03f32..1c54a5b 100644 --- a/macosx/tkMacOSXMenubutton.c +++ b/macosx/tkMacOSXMenubutton.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXMenubutton.c,v 1.2.2.11 2007/06/29 03:22:02 das Exp $ + * RCS: @(#) $Id: tkMacOSXMenubutton.c,v 1.2.2.12 2007/11/09 06:26:56 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -27,6 +27,9 @@ #define TK_POPUP_OFFSET 32 /* size of popup marker */ +#define FIRST_DRAW 2 +#define ACTIVE 4 + MODULE_SCOPE int TkMacOSXGetNewMenuID(Tcl_Interp *interp, TkMenu *menuInstPtr, int cascade, short *menuIDPtr); MODULE_SCOPE void TkMacOSXFreeMenuID(short menuID); @@ -76,6 +79,7 @@ static void UserPaneBackgroundProc(ControlHandle, ControlBackgroundPtr info); static int MenuButtonInitControl (MacMenuButton *mbPtr, Rect *paneRect, Rect *cntrRect ); +static void MenuButtonEventProc(ClientData clientData, XEvent *eventPtr); static int UpdateControlColors(MacMenuButton *mbPtr); static void ComputeMenuButtonControlParams(TkMenuButton *mbPtr, MenuButtonControlParams * paramsPtr); @@ -116,22 +120,17 @@ TkpCreateMenuButton( Tk_Window tkwin) { MacMenuButton *mbPtr = (MacMenuButton *) ckalloc(sizeof(MacMenuButton)); - mbPtr->userPaneBackground = PIXEL_MAGIC << 24; + + Tk_CreateEventHandler(tkwin, ActivateMask, + MenuButtonEventProc, (ClientData) mbPtr); mbPtr->flags = 0; + mbPtr->userPaneBackground = PIXEL_MAGIC << 24; mbPtr->userPane = NULL; mbPtr->control = NULL; - mbPtr->picParams.version = -2; - mbPtr->picParams.hRes = 0x00480000; - mbPtr->picParams.vRes = 0x00480000; - mbPtr->picParams.srcRect.top = 0; - mbPtr->picParams.srcRect.left = 0; - mbPtr->picParams.reserved1 = 0; - mbPtr->picParams.reserved2 = 0; - mbPtr->bevelButtonContent.contentType = kControlContentPictHandle; mbPtr->menuRef = NULL; - bzero(&mbPtr->params, sizeof(mbPtr->params)); - bzero(&mbPtr->titleParams,sizeof(mbPtr->titleParams)); + bzero(&mbPtr->titleParams, sizeof(mbPtr->titleParams)); + return (TkMenuButton *) mbPtr; } @@ -162,26 +161,25 @@ TkpDisplayMenuButton( Pixmap pixmap; MacMenuButton *mbPtr = (MacMenuButton *) butPtr; CGrafPtr destPort, savePort; - Boolean portChanged; + Boolean portChanged = false; int hasImageOrBitmap = 0, width, height; OSStatus err; ControlButtonGraphicAlignment theAlignment; Rect paneRect, cntrRect; + int active, enabled; butPtr->flags &= ~REDRAW_PENDING; if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { return; } pixmap = (Pixmap) Tk_WindowId(tkwin); - destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); - portChanged = QDSwapPort(destPort, &savePort); TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin)); winPtr = (TkWindow *)butPtr->tkwin; paneRect.left = winPtr->privatePtr->xOff; paneRect.top = winPtr->privatePtr->yOff; - paneRect.right = paneRect.left+Tk_Width(butPtr->tkwin)-1; - paneRect.bottom = paneRect.top+Tk_Height(butPtr->tkwin)-1; + paneRect.right = paneRect.left+Tk_Width(butPtr->tkwin); + paneRect.bottom = paneRect.top+Tk_Height(butPtr->tkwin); cntrRect = paneRect; @@ -193,8 +191,12 @@ TkpDisplayMenuButton( if (mbPtr->userPane) { MenuButtonControlParams params; bzero(¶ms, sizeof(params)); - ComputeMenuButtonControlParams(butPtr, ¶ms ); - if (bcmp(¶ms,&mbPtr->params,sizeof(params))) { + ComputeMenuButtonControlParams(butPtr, ¶ms); + if ( +#if 0 + (winPtr->flags & TK_REBUILD_TOPLEVEL) || +#endif + bcmp(¶ms,&mbPtr->params,sizeof(params))) { if (mbPtr->userPane) { DisposeControl(mbPtr->userPane); mbPtr->userPane = NULL; @@ -208,21 +210,29 @@ TkpDisplayMenuButton( return; } } - SetControlBounds(mbPtr->userPane,&paneRect); - SetControlBounds(mbPtr->control,&cntrRect); + SetControlBounds(mbPtr->userPane, &paneRect); + SetControlBounds(mbPtr->control, &cntrRect); + + if (butPtr->image != None) { + Tk_SizeOfImage(butPtr->image, &width, &height); + hasImageOrBitmap = 1; + } else if (butPtr->bitmap != None) { + Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); + hasImageOrBitmap = 1; + } /* * We need to cache the title and its style */ - if (!(mbPtr->flags & 2)) { + if (!(mbPtr->flags & FIRST_DRAW)) { ControlTitleParams titleParams; int titleChanged; int styleChanged; - ComputeControlTitleParams(butPtr,&titleParams); - CompareControlTitleParams(&titleParams,&mbPtr->titleParams, - &titleChanged,&styleChanged); + ComputeControlTitleParams(butPtr, &titleParams); + CompareControlTitleParams(&titleParams, &mbPtr->titleParams, + &titleChanged, &styleChanged); if (titleChanged) { CFStringRef cf = CFStringCreateWithCString(NULL, (char*) titleParams.title, kCFStringEncodingUTF8); @@ -249,43 +259,54 @@ TkpDisplayMenuButton( sizeof(titleParams.style)); } } - if (butPtr->image != None) { - Tk_SizeOfImage(butPtr->image, &width, &height); - hasImageOrBitmap = 1; - } else if (butPtr->bitmap != None) { - Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); - hasImageOrBitmap = 1; - } if (hasImageOrBitmap) { - mbPtr->picParams.srcRect.right = width; - mbPtr->picParams.srcRect.bottom = height; - - /* - * Set the flag to circumvent clipping and bounds problems with OS - * 10.0.4 - */ - - tkPictureIsOpen = 1; - mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams); - if (!mbPtr->bevelButtonContent.u.picture) { - TkMacOSXDbgMsg("OpenCPicture failed"); - } - - /* - * TO DO - There is one case where XCopyPlane calls CopyDeepMask, - * which does not get recorded in the picture. So the bitmap code - * will fail in that case. - */ + { + destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); + portChanged = QDSwapPort(destPort, &savePort); + mbPtr->picParams.version = -2; + mbPtr->picParams.hRes = 0x00480000; + mbPtr->picParams.vRes = 0x00480000; + mbPtr->picParams.srcRect.top = 0; + mbPtr->picParams.srcRect.left = 0; + mbPtr->picParams.srcRect.bottom = height; + mbPtr->picParams.srcRect.right = width; + mbPtr->picParams.reserved1 = 0; + mbPtr->picParams.reserved2 = 0; + mbPtr->bevelButtonContent.contentType = kControlContentPictHandle; + mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams); + if (!mbPtr->bevelButtonContent.u.picture) { + TkMacOSXDbgMsg("OpenCPicture failed"); + } + tkPictureIsOpen = 1; + /* + * TO DO - There is one case where XCopyPlane calls CopyDeepMask, + * which does not get recorded in the picture. So the bitmap code + * will fail in that case. + */ + } if (butPtr->image != NULL) { Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, 0, 0); } else { - XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, NULL, 0, 0, + GC gc; + + if (butPtr->state == STATE_DISABLED) { + gc = butPtr->disabledGC; + } else if (butPtr->state == STATE_ACTIVE) { + gc = butPtr->activeTextGC; + } else { + gc = butPtr->normalTextGC; + } + XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0, width, height, 0, 0, 1); } - ClosePicture(); - - tkPictureIsOpen = 0; + { + ClosePicture(); + tkPictureIsOpen = 0; + if (portChanged) { + QDSwapPort(savePort, NULL); + } + } ChkErr(SetControlData, mbPtr->control, kControlButtonPart, kControlBevelButtonContentTag, sizeof(ControlButtonContentInfo), @@ -324,25 +345,47 @@ TkpDisplayMenuButton( kControlBevelButtonGraphicAlignTag, sizeof(ControlButtonGraphicAlignment), (char *) &theAlignment); } - if (butPtr->flags & GOT_FOCUS) { - HiliteControl(mbPtr->control,kControlButtonPart); - } else { - HiliteControl(mbPtr->control,kControlNoPart); + active = ((mbPtr->flags & ACTIVE) != 0); + if (active != IsControlActive(mbPtr->control)) { + if (active) { + ChkErr(ActivateControl, mbPtr->control); + } else { + ChkErr(DeactivateControl, mbPtr->control); + } + } + enabled = !(butPtr->state == STATE_DISABLED); + if (enabled != IsControlEnabled(mbPtr->control)) { + if (enabled) { + ChkErr(EnableControl, mbPtr->control); + } else { + ChkErr(DisableControl, mbPtr->control); + } + } + if (active && enabled) { + if (butPtr->state == STATE_ACTIVE) { + if (hasImageOrBitmap) { + HiliteControl(mbPtr->control, kControlButtonPart); + } else { + HiliteControl(mbPtr->control, kControlLabelPart); + } + } else { + HiliteControl(mbPtr->control, kControlNoPart); + } } UpdateControlColors(mbPtr); - if (mbPtr->flags&2) { + if (mbPtr->flags & FIRST_DRAW) { ShowControl(mbPtr->control); ShowControl(mbPtr->userPane); - mbPtr->flags ^= 2; + mbPtr->flags ^= FIRST_DRAW; } else { - Draw1Control(mbPtr->userPane); SetControlVisibility(mbPtr->control, true, true); + Draw1Control(mbPtr->userPane); } if (hasImageOrBitmap) { - KillPicture(mbPtr->bevelButtonContent.u.picture); - } - if (portChanged) { - QDSwapPort(savePort, NULL); + if (mbPtr->bevelButtonContent.contentType == + kControlContentPictHandle) { + KillPicture(mbPtr->bevelButtonContent.u.picture); + } } } @@ -409,21 +452,9 @@ TkpComputeMenuButtonGeometry(mbPtr) mbPtr->inset = mbPtr->highlightWidth + mbPtr->borderWidth; if (mbPtr->image != None) { Tk_SizeOfImage(mbPtr->image, &width, &height); - if (mbPtr->width > 0) { - width = mbPtr->width; - } - if (mbPtr->height > 0) { - height = mbPtr->height; - } hasImageOrBitmap = 1; } else if (mbPtr->bitmap != None) { Tk_SizeOfBitmap(mbPtr->display, mbPtr->bitmap, &width, &height); - if (mbPtr->width > 0) { - width = mbPtr->width; - } - if (mbPtr->height > 0) { - height = mbPtr->height; - } hasImageOrBitmap = 1; } else { hasImageOrBitmap = 0; @@ -445,7 +476,19 @@ TkpComputeMenuButtonGeometry(mbPtr) width += 2*mbPtr->padX; height += 2*mbPtr->padY; } - + if (hasImageOrBitmap) { + if (mbPtr->width > 0) { + width = mbPtr->width; + } + if (mbPtr->height > 0) { + height = mbPtr->height; + } + mbPtr->inset = mbPtr->highlightWidth + 2; + width += (2 * mbPtr->borderWidth + 4); + height += (2 * mbPtr->borderWidth + 4); + } else { + width += TK_POPUP_OFFSET; + } if (mbPtr->indicatorOn) { mm = WidthMMOfScreen(Tk_Screen(mbPtr->tkwin)); pixels = WidthOfScreen(Tk_Screen(mbPtr->tkwin)); @@ -456,9 +499,6 @@ TkpComputeMenuButtonGeometry(mbPtr) mbPtr->indicatorHeight = 0; mbPtr->indicatorWidth = 0; } - if (!hasImageOrBitmap) { - width += TK_POPUP_OFFSET; - } Tk_GeometryRequest(mbPtr->tkwin, (int) (width + 2*mbPtr->inset), (int) (height + 2*mbPtr->inset)); @@ -636,7 +676,7 @@ MenuButtonInitControl( * Do this only if we are using bevel buttons. */ - ComputeControlTitleParams(butPtr,&mbPtr->titleParams); + ComputeControlTitleParams(butPtr, &mbPtr->titleParams); mbPtr->control = NewControl(mbPtr->windowRef, cntrRect, "\p" /* mbPtr->titleParams.title */, initiallyVisible, mbPtr->params.initialValue, @@ -702,7 +742,10 @@ MenuButtonInitControl( SetControlMaximum(mbPtr->control, 1); SetControlValue(mbPtr->control, 1); } - mbPtr->flags |= 2; + mbPtr->flags |= FIRST_DRAW; + if (IsWindowActive(mbPtr->windowRef)) { + mbPtr->flags |= ACTIVE; + } return 0; } @@ -859,7 +902,7 @@ UpdateControlColors( MacMenuButton *mbPtr) { XColor *xcolor; - TkMenuButton * butPtr = ( TkMenuButton * )mbPtr; + TkMenuButton * butPtr = (TkMenuButton *) mbPtr; /* * Under Appearance we cannot change the background of the @@ -877,3 +920,45 @@ UpdateControlColors( return false; } + +/* + *-------------------------------------------------------------- + * + * MenuButtonEventProc -- + * + * This procedure is invoked by the Tk dispatcher for various + * events on buttons. + * + * Results: + * None. + * + * Side effects: + * When it gets exposed, it is redisplayed. + * + *-------------------------------------------------------------- + */ + +static void +MenuButtonEventProc( + ClientData clientData, /* Information about window. */ + XEvent *eventPtr) /* Information about event. */ +{ + TkMenuButton *buttonPtr = (TkMenuButton *) clientData; + MacMenuButton *mbPtr = (MacMenuButton *) clientData; + + if (eventPtr->type == ActivateNotify + || eventPtr->type == DeactivateNotify) { + if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) { + return; + } + if (eventPtr->type == ActivateNotify) { + mbPtr->flags |= ACTIVE; + } else { + mbPtr->flags &= ~ACTIVE; + } + if ((buttonPtr->flags & REDRAW_PENDING) == 0) { + Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) buttonPtr); + buttonPtr->flags |= REDRAW_PENDING; + } + } +} diff --git a/macosx/tkMacOSXMenus.c b/macosx/tkMacOSXMenus.c index a9fa204..1cc7129 100644 --- a/macosx/tkMacOSXMenus.c +++ b/macosx/tkMacOSXMenus.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXMenus.c,v 1.2.2.15 2007/06/29 03:22:02 das Exp $ + * RCS: @(#) $Id: tkMacOSXMenus.c,v 1.2.2.16 2007/11/09 06:26:56 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -22,7 +22,8 @@ #define kEditMenu 3 #define kSourceItem 1 -#define kCloseItem 2 +#define kDemoItem 2 +#define kCloseItem 3 #define EDIT_CUT 1 #define EDIT_COPY 2 @@ -33,15 +34,52 @@ MenuRef tkAppleMenu; MenuRef tkFileMenu; MenuRef tkEditMenu; -static Tcl_Interp * gInterp; /* Interpreter for this application. */ +static Tcl_Interp * gInterp = NULL; /* Standard menu interpreter. */ +static EventHandlerRef menuEventHandlerRef = NULL; static void GenerateEditEvent(int flag); -static void SourceDialog(void); +static Tcl_Obj* GetWidgetDemoPath(Tcl_Interp *interp); +static OSStatus MenuEventHandlerProc(EventHandlerCallRef callRef, + EventRef event, void *userData); /* *---------------------------------------------------------------------- * + * GetWidgetDemoPath -- + * + * Get path to the widget demo. + * + * Results: + * pathObj with ref count 0. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj* +GetWidgetDemoPath( + Tcl_Interp *interp) +{ + Tcl_Obj *libpath , *result = NULL; + + libpath = Tcl_GetVar2Ex(gInterp, "tk_library", NULL, TCL_GLOBAL_ONLY); + if (libpath) { + Tcl_Obj *demo[2] = { Tcl_NewStringObj("demos", 5), + Tcl_NewStringObj("widget", 6) }; + + Tcl_IncrRefCount(libpath); + result = Tcl_FSJoinToPath(libpath, 2, demo); + Tcl_DecrRefCount(libpath); + } + return result; +} + +/* + *---------------------------------------------------------------------- + * * TkMacOSXHandleMenuSelect -- * * Handles events that occur in the Menu bar. @@ -81,8 +119,11 @@ TkMacOSXHandleMenuSelect( "tkAboutDialog", &dummy) == 0) { TkAboutDlg(); } else { - Tcl_EvalEx(gInterp, "tkAboutDialog", -1, - TCL_EVAL_GLOBAL); + if (Tcl_EvalEx(gInterp, "tkAboutDialog", -1, + TCL_EVAL_GLOBAL) != TCL_OK) { + Tcl_BackgroundError(gInterp); + } + Tcl_ResetResult(gInterp); } break; } @@ -91,11 +132,41 @@ TkMacOSXHandleMenuSelect( case kFileMenu: switch (theItem) { case kSourceItem: - /* - * TODO: source script - */ + if (gInterp) { + if(Tcl_EvalEx(gInterp, "tk_getOpenFile -filetypes {" + "{{TCL Scripts} {.tcl} TEXT} " + "{{Text Files} {} TEXT}}", -1, TCL_EVAL_GLOBAL) + == TCL_OK) { + Tcl_Obj *path = Tcl_GetObjResult(gInterp); + int len; + + Tcl_GetStringFromObj(path, &len); + if (len) { + Tcl_IncrRefCount(path); + if (Tcl_FSEvalFile(gInterp, path) + == TCL_ERROR) { + Tcl_BackgroundError(gInterp); + } + Tcl_DecrRefCount(path); + } + } + Tcl_ResetResult(gInterp); + } + break; + case kDemoItem: + if (gInterp) { + Tcl_Obj *path = GetWidgetDemoPath(gInterp); - SourceDialog(); + if (path) { + Tcl_IncrRefCount(path); + if (Tcl_FSEvalFile(gInterp, path) + == TCL_ERROR) { + Tcl_BackgroundError(gInterp); + } + Tcl_DecrRefCount(path); + Tcl_ResetResult(gInterp); + } + } break; case kCloseItem: /* Send close event */ @@ -127,6 +198,53 @@ TkMacOSXHandleMenuSelect( /* *---------------------------------------------------------------------- * + * MenuEventHandlerProc -- + * + * One-time handler of kEventMenuEnableItems for the edit menu. + * + * Results: + * OS status code. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static OSStatus +MenuEventHandlerProc( + EventHandlerCallRef callRef, + EventRef event, + void *userData) +{ + OSStatus result = eventNotHandledErr, err; + int menuContext; + + err = ChkErr(GetEventParameter, event, kEventParamMenuContext, typeUInt32, + NULL, sizeof(menuContext), NULL, &menuContext); + if (err == noErr && (menuContext & kMenuContextMenuBarTracking)) { + if (gInterp) { + Tcl_Obj *path = GetWidgetDemoPath(gInterp); + + if (path) { + Tcl_IncrRefCount(path); + if (Tcl_FSAccess(path, R_OK) == 0) { + EnableMenuItem(tkFileMenu, kDemoItem); + } + Tcl_DecrRefCount(path); + } + } + ChkErr(RemoveEventHandler, menuEventHandlerRef); + menuEventHandlerRef = NULL; + result = noErr; + } + + return result; +} + +/* + *---------------------------------------------------------------------- + * * TkMacOSXInitMenus -- * * This procedure initializes the Macintosh menu bar. @@ -145,8 +263,12 @@ TkMacOSXInitMenus( Tcl_Interp *interp) { OSStatus err; - gInterp = interp; + EventHandlerUPP menuEventHandlerUPP; + const EventTypeSpec menuEventTypes[] = { + {kEventClassMenu, kEventMenuEnableItems}, + }; + gInterp = interp; if (TkMacOSXUseMenuID(kAppleMenu) != TCL_OK) { Tcl_Panic("Menu ID %d is already in use!", kAppleMenu); } @@ -170,8 +292,15 @@ TkMacOSXInitMenus( } SetMenuTitle(tkFileMenu, "\pFile"); InsertMenu(tkFileMenu, 0); - AppendMenu(tkFileMenu, "\pSource\xc9"); - AppendMenu(tkFileMenu, "\pClose/W"); + InsertMenuItem(tkFileMenu, "\pSource\xc9", kSourceItem - 1); + InsertMenuItem(tkFileMenu, "\pRun Widget Demo", kDemoItem - 1); + InsertMenuItem(tkFileMenu, "\pClose/W", kCloseItem - 1); + DisableMenuItem(tkFileMenu, kDemoItem); + menuEventHandlerUPP = NewEventHandlerUPP(MenuEventHandlerProc); + ChkErr(InstallEventHandler, GetMenuEventTarget(tkFileMenu), + menuEventHandlerUPP, GetEventTypeCount(menuEventTypes), + menuEventTypes, NULL, &menuEventHandlerRef); + DisposeEventHandlerUPP(menuEventHandlerUPP); if (TkMacOSXUseMenuID(kEditMenu) != TCL_OK) { Tcl_Panic("Menu ID %d is already in use!", kEditMenu); @@ -270,44 +399,3 @@ GenerateEditEvent( } Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); } - -/* - *---------------------------------------------------------------------- - * - * SourceDialog -- - * - * Presents a dialog to the user for selecting a Tcl file. The - * selected file will be sourced into the main interpreter. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -SourceDialog(void) -{ - int result; - const char *path; - const char *openCmd = "tk_getOpenFile -filetypes {\ - {{TCL Scripts} {.tcl} TEXT} {{Text Files} {} TEXT}}"; - - if (gInterp == NULL) { - return; - } - if (Tcl_EvalEx(gInterp, openCmd, -1, TCL_EVAL_GLOBAL) != TCL_OK) { - return; - } - path = Tcl_GetStringResult(gInterp); - if (strlen(path) == 0) { - return; - } - result = Tcl_EvalFile(gInterp, path); - if (result == TCL_ERROR) { - Tcl_BackgroundError(gInterp); - } -} diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h index d184c3f..1cfd334 100644 --- a/macosx/tkMacOSXPrivate.h +++ b/macosx/tkMacOSXPrivate.h @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXPrivate.h,v 1.1.2.3 2007/08/23 10:45:16 das Exp $ + * RCS: @(#) $Id: tkMacOSXPrivate.h,v 1.1.2.4 2007/11/09 06:26:56 das Exp $ */ #ifndef _TKMACPRIV @@ -76,7 +76,7 @@ #define kHIToolboxVersionNumber10_4 (219) #endif #ifndef kHIToolboxVersionNumber10_5 - #define kHIToolboxVersionNumber10_5 (316) + #define kHIToolboxVersionNumber10_5 (343) #endif /* Macros for HIToolbox runtime version checking */ MODULE_SCOPE float tkMacOSXToolboxVersionNumber; @@ -252,6 +252,7 @@ typedef struct TkMacOSXDrawingContext { CGrafPtr port, savePort; ThemeDrawingState saveState; RgnHandle saveClip; + HIShapeRef clipRgn; PixPatHandle penPat; Rect portBounds; Boolean portChanged; @@ -265,6 +266,33 @@ MODULE_SCOPE RgnHandle tkMacOSXtmpQdRgn; MODULE_SCOPE int tkMacOSXUseCGDrawing; /* + * Prototypes for TkMacOSXRegion.c. + */ + +#if 0 +MODULE_SCOPE void TkMacOSXEmtpyRegion(TkRegion r); +MODULE_SCOPE int TkMacOSXIsEmptyRegion(TkRegion r); +#endif +MODULE_SCOPE HIShapeRef TkMacOSXGetNativeRegion(TkRegion r); +MODULE_SCOPE void TkMacOSXSetWithNativeRegion(TkRegion r, HIShapeRef rgn); +MODULE_SCOPE void TkMacOSXOffsetRegion(TkRegion r, short dx, short dy); +MODULE_SCOPE HIShapeRef TkMacOSXHIShapeCreateEmpty(void); +MODULE_SCOPE HIMutableShapeRef TkMacOSXHIShapeCreateMutableWithRect( + const CGRect *inRect); +MODULE_SCOPE OSStatus TkMacOSXHIShapeSetWithShape( + HIMutableShapeRef inDestShape, HIShapeRef inSrcShape); +#if 0 +MODULE_SCOPE OSStatus TkMacOSXHIShapeSetWithRect(HIMutableShapeRef inShape, + const CGRect *inRect); +#endif +MODULE_SCOPE OSStatus TkMacOSHIShapeDifferenceWithRect( + HIMutableShapeRef inShape, const CGRect *inRect); +MODULE_SCOPE OSStatus TkMacOSHIShapeUnionWithRect(HIMutableShapeRef inShape, + const CGRect *inRect); +MODULE_SCOPE OSStatus TkMacOSHIShapeUnion(HIShapeRef inShape1, + HIShapeRef inShape2, HIMutableShapeRef outResult); + +/* * Prototypes of TkAqua internal procs. */ @@ -285,8 +313,8 @@ MODULE_SCOPE int TkMacOSXIsWindowZoomed(TkWindow *winPtr); MODULE_SCOPE int TkGenerateButtonEventForXPointer(Window window); MODULE_SCOPE EventModifiers TkMacOSXModifierState(void); MODULE_SCOPE int TkMacOSXSetupDrawingContext(Drawable d, GC gc, int useCG, - TkMacOSXDrawingContext *dc); -MODULE_SCOPE void TkMacOSXRestoreDrawingContext(TkMacOSXDrawingContext *dc); + TkMacOSXDrawingContext *dcPtr); +MODULE_SCOPE void TkMacOSXRestoreDrawingContext(TkMacOSXDrawingContext *dcPtr); MODULE_SCOPE void TkMacOSXSetColorInPort(unsigned long pixel, int fg, PixPatHandle penPat, CGrafPtr port); MODULE_SCOPE void TkMacOSXSetColorInContext(unsigned long pixel, @@ -303,5 +331,7 @@ MODULE_SCOPE int TkMacOSXMakeFullscreen(TkWindow *winPtr, WindowRef window, MODULE_SCOPE void TkMacOSXEnterExitFullscreen(TkWindow *winPtr, int active); MODULE_SCOPE void TkMacOSXBringWindowForward(WindowRef wRef); MODULE_SCOPE WindowRef TkMacOSXDrawableWindow(Drawable drawable); +MODULE_SCOPE void TkMacOSXWinCGBounds(TkWindow *winPtr, CGRect *bounds); +MODULE_SCOPE HIShapeRef TkMacOSXGetClipRgn(Drawable drawable); #endif /* _TKMACPRIV */ diff --git a/macosx/tkMacOSXRegion.c b/macosx/tkMacOSXRegion.c index 4920958..39ba614 100644 --- a/macosx/tkMacOSXRegion.c +++ b/macosx/tkMacOSXRegion.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: tkMacOSXRegion.c,v 1.2.2.6 2007/06/29 03:22:02 das Exp $ + * RCS: @(#) $Id: tkMacOSXRegion.c,v 1.2.2.7 2007/11/09 06:26:56 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -36,7 +36,7 @@ TkRegion TkCreateRegion(void) { - return (TkRegion) NewRgn(); + return (TkRegion) HIShapeCreateMutable(); } /* @@ -60,7 +60,9 @@ void TkDestroyRegion( TkRegion r) { - DisposeRgn((RgnHandle) r); + if (r) { + CFRelease(r); + } } /* @@ -86,7 +88,8 @@ TkIntersectRegion( TkRegion srb, TkRegion dr_return) { - SectRgn((RgnHandle) sra, (RgnHandle) srb, (RgnHandle) dr_return); + ChkErr(HIShapeIntersect, (HIShapeRef) sra, (HIShapeRef) srb, + (HIMutableShapeRef) dr_return); } /* @@ -112,7 +115,8 @@ TkSubtractRegion( TkRegion srb, TkRegion dr_return) { - DiffRgn((RgnHandle) sra, (RgnHandle) srb, (RgnHandle) dr_return); + ChkErr(HIShapeDifference, (HIShapeRef) sra, (HIShapeRef) srb, + (HIMutableShapeRef) dr_return); } /* @@ -139,12 +143,19 @@ TkUnionRectWithRegion( TkRegion src_region, TkRegion dest_region_return) { - TkMacOSXCheckTmpQdRgnEmpty(); - SetRectRgn(tkMacOSXtmpQdRgn, rectangle->x, rectangle->y, - rectangle->x + rectangle->width, rectangle->y + rectangle->height); - UnionRgn((RgnHandle) src_region, tkMacOSXtmpQdRgn, - (RgnHandle) dest_region_return); - SetEmptyRgn(tkMacOSXtmpQdRgn); + const CGRect r = CGRectMake(rectangle->x, rectangle->y, + rectangle->width, rectangle->height); + + if (src_region == dest_region_return) { + ChkErr(TkMacOSHIShapeUnionWithRect, + (HIMutableShapeRef) dest_region_return, &r); + } else { + HIShapeRef rectRgn = HIShapeCreateWithRect(&r); + + ChkErr(TkMacOSHIShapeUnion, rectRgn, (HIShapeRef) src_region, + (HIMutableShapeRef) dest_region_return); + CFRelease(rectRgn); + } } /* @@ -156,7 +167,8 @@ TkUnionRectWithRegion( * XRectInRegion. See X window documentation for more details. * * Results: - * Returns one of: RectangleOut, RectangleIn, RectanglePart. + * Returns RectanglePart or RectangleOut. Note that this is not a + * complete implementation since it doesn't test for RectangleIn. * * Side effects: * None. @@ -173,18 +185,40 @@ TkRectInRegion( unsigned int height) { int result; + const CGRect r = CGRectMake(x, y, width, height); - TkMacOSXCheckTmpQdRgnEmpty(); - SetRectRgn(tkMacOSXtmpQdRgn, x, y, x + width, y + height); - SectRgn((RgnHandle) region, tkMacOSXtmpQdRgn, tkMacOSXtmpQdRgn); - if (EmptyRgn(tkMacOSXtmpQdRgn)) { - result = RectangleOut; - } else if (EqualRgn((RgnHandle) region, tkMacOSXtmpQdRgn)) { - result = RectangleIn; - } else { - result = RectanglePart; - } - SetEmptyRgn(tkMacOSXtmpQdRgn); + TK_IF_MAC_OS_X_API (4, HIShapeIntersectsRect, + result = HIShapeIntersectsRect((HIShapeRef) region, &r) ? + RectanglePart : RectangleOut; + ) TK_ELSE_MAC_OS_X (4, + HIShapeRef rectRgn = HIShapeCreateWithRect(&r); + HIShapeRef sectRgn = HIShapeCreateIntersection((HIShapeRef) region, + rectRgn); + +#if 1 + result = !HIShapeIsEmpty(sectRgn) ? RectanglePart : RectangleOut; +#else + /* + * More expensive full implementation that tests for RectangleIn, + * unused by Tk at present. + */ + + if (!HIShapeIsEmpty(sectRgn)) { + HIShapeRef diffRgn = HIShapeCreateDifference(rectRgn, sectRgn); + + if (HIShapeIsEmpty(diffRgn)) { + result = RectangleIn; + } else { + result = RectanglePart; + } + CFRelease(diffRgn); + } else { + result = RectangleOut; + } +#endif + CFRelease(sectRgn); + CFRelease(rectRgn); + ) TK_ENDIF return result; } @@ -210,11 +244,385 @@ TkClipBox( TkRegion r, XRectangle* rect_return) { - Rect rect; + CGRect rect; + + HIShapeGetBounds((HIShapeRef) r, &rect); + rect_return->x = rect.origin.x; + rect_return->y = rect.origin.y; + rect_return->width = rect.size.width; + rect_return->height = rect.size.height; +} + +/* + *---------------------------------------------------------------------- + * + * TkpBuildRegionFromAlphaData -- + * + * Set up a rectangle of the given region based on the supplied + * alpha data. + * + * Results: + * None + * + * Side effects: + * The region is updated, with extra pixels added to it. + * + *---------------------------------------------------------------------- + */ + +void +TkpBuildRegionFromAlphaData( + TkRegion region, /* Region to update. */ + unsigned int x, /* Where in region to update. */ + unsigned int y, /* Where in region to update. */ + unsigned int width, /* Size of rectangle to update. */ + unsigned int height, /* Size of rectangle to update. */ + unsigned char *dataPtr, /* Data to read from. */ + unsigned int pixelStride, /* num bytes from one piece of alpha + * data to the next in the line. */ + unsigned int lineStride) /* num bytes from one line of alpha + * data to the next line. */ +{ + unsigned char *lineDataPtr; + unsigned int x1, y1, end; + XRectangle rect; - GetRegionBounds((RgnHandle) r,&rect); - rect_return->x = rect.left; - rect_return->y = rect.top; - rect_return->width = rect.right-rect.left; - rect_return->height = rect.bottom-rect.top; + for (y1 = 0; y1 < height; y1++) { + lineDataPtr = dataPtr; + for (x1 = 0; x1 < width; x1 = end) { + /* search for first non-transparent pixel */ + while ((x1 < width) && !*lineDataPtr) { + x1++; + lineDataPtr += pixelStride; + } + end = x1; + /* search for first transparent pixel */ + while ((end < width) && *lineDataPtr) { + end++; + lineDataPtr += pixelStride; + } + if (end > x1) { + rect.x = x + x1; + rect.y = y + y1; + rect.width = end - x1; + rect.height = 1; + TkUnionRectWithRegion(&rect, region, region); + } + } + dataPtr += lineStride; + } +} + +/* + *---------------------------------------------------------------------- + * + * TkpRetainRegion -- + * + * Increases reference count of region. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TkpRetainRegion( + TkRegion r) +{ + CFRetain(r); +} + +/* + *---------------------------------------------------------------------- + * + * TkpReleaseRegion -- + * + * Decreases reference count of region. + * + * Results: + * None. + * + * Side effects: + * May free memory. + * + *---------------------------------------------------------------------- + */ + +void +TkpReleaseRegion( + TkRegion r) +{ + CFRelease(r); +} +#if 0 + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXEmtpyRegion -- + * + * Set region to emtpy. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TkMacOSXEmtpyRegion( + TkRegion r) +{ + ChkErr(HIShapeSetEmpty, (HIMutableShapeRef) r); +} + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXIsEmptyRegion -- + * + * Return native region for given tk region. + * + * Results: + * 1 if empty, 0 otherwise. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TkMacOSXIsEmptyRegion( + TkRegion r) +{ + return HIShapeIsEmpty((HIMutableShapeRef) r) ? 1 : 0; +} +#endif + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXGetNativeRegion -- + * + * Return native region for given tk region. + * + * Results: + * Native region, CFRelease when done. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +HIShapeRef +TkMacOSXGetNativeRegion( + TkRegion r) +{ + return (HIShapeRef) CFRetain(r); +} + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXSetWithNativeRegion -- + * + * Set region to the native region. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TkMacOSXSetWithNativeRegion( + TkRegion r, + HIShapeRef rgn) +{ + ChkErr(TkMacOSXHIShapeSetWithShape, (HIMutableShapeRef) r, rgn); +} + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXOffsetRegion -- + * + * Offsets region by given distances. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TkMacOSXOffsetRegion( + TkRegion r, + short dx, + short dy) +{ + ChkErr(HIShapeOffset, (HIMutableShapeRef) r, dx, dy); +} + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXHIShapeCreateEmpty, TkMacOSXHIShapeCreateMutableWithRect, + * TkMacOSXHIShapeSetWithShape, TkMacOSXHIShapeSetWithRect, + * TkMacOSHIShapeDifferenceWithRect, TkMacOSHIShapeUnionWithRect, + * TkMacOSHIShapeUnion -- + * + * Wrapper functions for missing/buggy HIShape API + * + *---------------------------------------------------------------------- + */ + +HIShapeRef +TkMacOSXHIShapeCreateEmpty(void) +{ + HIShapeRef result; + + TK_IF_MAC_OS_X_API (4, HIShapeCreateEmpty, + result = HIShapeCreateEmpty(); + ) TK_ELSE_MAC_OS_X (4, + static HIShapeRef emptyRgn = NULL; + + if (!emptyRgn) { + HIMutableShapeRef rgn = HIShapeCreateMutable(); + + emptyRgn = HIShapeCreateCopy(rgn); + CFRelease(rgn); + } + result = HIShapeCreateCopy(emptyRgn); + ) TK_ENDIF + + return result; +} + +HIMutableShapeRef +TkMacOSXHIShapeCreateMutableWithRect( + const CGRect *inRect) +{ + HIMutableShapeRef result; + + TK_IF_MAC_OS_X_API (5, HIShapeCreateMutableWithRect, + result = HIShapeCreateMutableWithRect(inRect); + ) TK_ELSE_MAC_OS_X (5, + HIShapeRef rgn = HIShapeCreateWithRect(inRect); + + result = HIShapeCreateMutableCopy(rgn); + CFRelease(rgn); + ) TK_ENDIF + + return result; +} + +OSStatus +TkMacOSXHIShapeSetWithShape( + HIMutableShapeRef inDestShape, + HIShapeRef inSrcShape) +{ + OSStatus result; + + TK_IF_MAC_OS_X_API (5, HIShapeSetWithShape, + result = HIShapeSetWithShape(inDestShape, inSrcShape); + ) TK_ELSE_MAC_OS_X (5, + result = HIShapeSetEmpty(inDestShape); + if (result == noErr) { + result = HIShapeDifference(inSrcShape, inDestShape, inDestShape); + } + ) TK_ENDIF + + return result; +} + +#if 0 +OSStatus +TkMacOSXHIShapeSetWithRect( + HIMutableShapeRef inShape, + const CGRect *inRect) +{ + OSStatus result; + HIShapeRef rgn = HIShapeCreateWithRect(inRect); + + result = TkMacOSXHIShapeSetWithShape(inShape, rgn); + CFRelease(rgn); + + return result; +} +#endif + +OSStatus +TkMacOSHIShapeDifferenceWithRect( + HIMutableShapeRef inShape, + const CGRect *inRect) +{ + OSStatus result; + HIShapeRef rgn = HIShapeCreateWithRect(inRect); + + result = HIShapeDifference(inShape, rgn, inShape); + CFRelease(rgn); + + return result; +} + +OSStatus +TkMacOSHIShapeUnionWithRect( + HIMutableShapeRef inShape, + const CGRect *inRect) +{ + OSStatus result; + + TK_IF_MAC_OS_X_API (5, HIShapeUnionWithRect, + result = HIShapeUnionWithRect(inShape, inRect); + ) TK_ELSE_MAC_OS_X (5, + HIShapeRef rgn = HIShapeCreateWithRect(inRect); + + result = TkMacOSHIShapeUnion(rgn, inShape, inShape); + CFRelease(rgn); + ) TK_ENDIF + + return result; +} + +OSStatus +TkMacOSHIShapeUnion( + HIShapeRef inShape1, + HIShapeRef inShape2, + HIMutableShapeRef outResult) +{ + OSStatus result; + + TK_IF_HI_TOOLBOX (4, + result = HIShapeUnion(inShape1, inShape2, outResult); + ) TK_ELSE_HI_TOOLBOX (4, + /* Workaround HIShapeUnion bug in 10.3 and earlier */ + HIShapeRef rgn = HIShapeCreateCopy(outResult); + + result = HIShapeUnion(inShape1, inShape2, (HIMutableShapeRef) rgn); + if (result == noErr) { + result = HIShapeSetEmpty(outResult); + if (result == noErr) { + result = HIShapeDifference(rgn, outResult, outResult); + } + } + CFRelease(rgn); + ) TK_ENDIF + + return result; } diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c index 9506d64..c06dbda 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.2.2.20 2007/06/29 03:22:02 das Exp $ + * RCS: @(#) $Id: tkMacOSXSubwindows.c,v 1.2.2.21 2007/11/09 06:26:56 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,19 @@ TkMacOSXGetDrawablePort( } else { resultPort = macWin->toplevel->grafPtr; } + } else { + if ((macWin->flags & TK_IS_PIXMAP) && !macWin->grafPtr) { + Rect bounds = {0, 0, macWin->size.height, macWin->size.width}; + + ChkErr(NewGWorld, &macWin->grafPtr, + (macWin->flags & TK_IS_BW_PIXMAP) ? 1 : 0, + &bounds, NULL, NULL, 0 +#ifdef __LITTLE_ENDIAN__ + | kNativeEndianPixMap +#endif + ); + } + resultPort = macWin->grafPtr; } } @@ -1062,8 +1117,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 +1188,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 +1298,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 +1307,25 @@ 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 | (depth == 1 ? TK_IS_BW_PIXMAP : 0); macPix->grafPtr = NULL; macPix->context = NULL; + macPix->size = CGSizeMake(width, height); + { + Rect bounds = {0, 0, height, width}; - err = ChkErr(NewGWorld, &gWorld, depth == 1 ? 1 : 0, &bounds, NULL, NULL, 0 + ChkErr(NewGWorld, &macPix->grafPtr, 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"); + ); } - macPix->grafPtr = gWorld; return (Pixmap) macPix; } @@ -1268,5 +1357,8 @@ Tk_FreePixmap( if (macPix->grafPtr) { DisposeGWorld(macPix->grafPtr); } + if (macPix->context) { + TkMacOSXDbgMsg("Cannot free CG backed Pixmap"); + } ckfree((char *) macPix); } diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c index f909f32..7ad33c8 100644 --- a/macosx/tkMacOSXWindowEvent.c +++ b/macosx/tkMacOSXWindowEvent.c @@ -54,7 +54,7 @@ * software in accordance with the terms specified in this * license. * - * RCS: @(#) $Id: tkMacOSXWindowEvent.c,v 1.3.2.25 2007/07/09 08:32:12 das Exp $ + * RCS: @(#) $Id: tkMacOSXWindowEvent.c,v 1.3.2.26 2007/11/09 06:26:56 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -73,10 +73,10 @@ */ static int GenerateUpdateEvent(Window window); -static int GenerateUpdates(RgnHandle updateRgn, Rect *updateBounds, +static int GenerateUpdates(HIMutableShapeRef updateRgn, CGRect *updateBounds, TkWindow *winPtr); static int GenerateActivateEvents(Window window, int activeFlag); -static void ClearPort(CGrafPtr port, RgnHandle updateRgn); +static void ClearPort(CGrafPtr port, HIShapeRef updateRgn); /* @@ -232,7 +232,7 @@ TkMacOSXProcessWindowEvent( case kEventWindowActivated: case kEventWindowDeactivated: case kEventWindowUpdate: - case kEventWindowExpanded: + case kEventWindowExpanding: case kEventWindowBoundsChanged: case kEventWindowDragStarted: case kEventWindowDragCompleted: @@ -275,10 +275,20 @@ TkMacOSXProcessWindowEvent( statusPtr->stopProcessing = 1; } break; - case kEventWindowExpanded: + case kEventWindowExpanding: if (winPtr) { - TkpWmSetState(winPtr, TkMacOSXIsWindowZoomed(winPtr) ? - ZoomState : NormalState); + winPtr->wmInfoPtr->hints.initial_state = + TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : + NormalState; + Tk_MapWindow((Tk_Window) winPtr); + /* + * Need to process all Tk events generated by Tk_MapWindow() + * before returning to ensure all children are mapped, as + * otherwise the Activate event that follows Expanding would + * not be processed by any unmapped children. + */ + while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {}; + while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}; } break; case kEventWindowBoundsChanged: @@ -430,12 +440,14 @@ TkMacOSXProcessWindowEvent( static int GenerateUpdateEvent(Window window) { - CGrafPtr destPort; WindowRef macWindow; TkDisplay *dispPtr; TkWindow *winPtr; int result = 0; - Rect updateBounds, bounds; + CGRect updateBounds; + HIShapeRef rgn; + HIMutableShapeRef updateRgn; + int dx, dy; dispPtr = TkGetDisplayList(); winPtr = (TkWindow *)Tk_IdToWindow(dispPtr->display, window); @@ -443,24 +455,37 @@ GenerateUpdateEvent(Window window) if (winPtr ==NULL ){ return result; } - TkMacOSXCheckTmpQdRgnEmpty(); - destPort = TkMacOSXGetDrawablePort(window); - macWindow = GetWindowFromPort(destPort); - ChkErr(GetWindowRegion, macWindow, kWindowUpdateRgn, tkMacOSXtmpQdRgn); - ChkErr(GetWindowBounds, macWindow, kWindowContentRgn, &bounds); - OffsetRgn(tkMacOSXtmpQdRgn, -bounds.left, -bounds.top); - SectRegionWithPortVisibleRegion(destPort, tkMacOSXtmpQdRgn); - GetRegionBounds(tkMacOSXtmpQdRgn, &updateBounds); + macWindow = TkMacOSXDrawableWindow(window); + TK_IF_MAC_OS_X_API (5, HIWindowCopyShape, + ChkErr(HIWindowCopyShape, macWindow, kWindowUpdateRgn, + kHICoordSpaceWindow, &rgn); + dx = -winPtr->wmInfoPtr->xInParent; + dy = -winPtr->wmInfoPtr->yInParent; + ) TK_ELSE_MAC_OS_X (5, + Rect bounds; + + TkMacOSXCheckTmpQdRgnEmpty(); + ChkErr(GetWindowRegion, macWindow, kWindowUpdateRgn, tkMacOSXtmpQdRgn); + rgn = HIShapeCreateWithQDRgn(tkMacOSXtmpQdRgn); + SetEmptyRgn(tkMacOSXtmpQdRgn); + ChkErr(GetWindowBounds, macWindow, kWindowContentRgn, &bounds); + dx = -bounds.left; + dy = -bounds.top; + ) TK_ENDIF + updateRgn = HIShapeCreateMutableCopy(rgn); + CFRelease(rgn); + ChkErr(HIShapeOffset, updateRgn, dx, dy); + HIShapeGetBounds(updateRgn, &updateBounds); #ifdef TK_MAC_DEBUG_CLIP_REGIONS - TkMacOSXDebugFlashRegion(window, tkMacOSXtmpQdRgn); + TkMacOSXDebugFlashRegion(window, updateRgn); #endif /* TK_MAC_DEBUG_CLIP_REGIONS */ BeginUpdate(macWindow); if (winPtr->wmInfoPtr->flags & WM_TRANSPARENT) { - ClearPort(destPort, tkMacOSXtmpQdRgn); + ClearPort(TkMacOSXGetDrawablePort(window), updateRgn); } - result = GenerateUpdates(tkMacOSXtmpQdRgn, &updateBounds, winPtr); + result = GenerateUpdates(updateRgn, &updateBounds, winPtr); EndUpdate(macWindow); - SetEmptyRgn(tkMacOSXtmpQdRgn); + CFRelease(updateRgn); if (result) { /* * Ensure there are no pending idle-time redraws that could prevent @@ -493,50 +518,51 @@ GenerateUpdateEvent(Window window) static int GenerateUpdates( - RgnHandle updateRgn, - Rect *updateBounds, + HIMutableShapeRef updateRgn, + CGRect *updateBounds, TkWindow *winPtr) { TkWindow *childPtr; XEvent event; - Rect bounds, damageBounds; - static RgnHandle damageRgn = NULL; - - TkMacOSXWinBounds(winPtr, &bounds); - if (bounds.top > updateBounds->bottom || - updateBounds->top > bounds.bottom || - bounds.left > updateBounds->right || - updateBounds->left > bounds.right) { - return 0; - } - if (!RectInRgn(&bounds, updateRgn)) { + CGRect bounds, damageBounds; + HIShapeRef boundsRgn, damageRgn; + + TkMacOSXWinCGBounds(winPtr, &bounds); + if (!CGRectIntersectsRect(bounds, *updateBounds)) { return 0; } + TK_IF_MAC_OS_X_API (4, HIShapeIntersectsRect, + if (!HIShapeIntersectsRect(updateRgn, &bounds)) { + return 0; + } + ) TK_ENDIF /* * Compute the bounding box of the area that the damage occured in. */ - if (damageRgn == NULL) { - damageRgn = NewRgn(); + boundsRgn = HIShapeCreateWithRect(&bounds); + damageRgn = HIShapeCreateIntersection(updateRgn, boundsRgn); + if (HIShapeIsEmpty(damageRgn)) { + CFRelease(damageRgn); + CFRelease(boundsRgn); + return 0; } - RectRgn(damageRgn, &bounds); - SectRgn(damageRgn, updateRgn, damageRgn); - GetRegionBounds(damageRgn, &damageBounds); - RectRgn(damageRgn, &bounds); - UnionRgn(damageRgn, updateRgn, updateRgn); - GetRegionBounds(updateRgn, updateBounds); - SetEmptyRgn(damageRgn); + HIShapeGetBounds(damageRgn, &damageBounds); + ChkErr(TkMacOSHIShapeUnion, boundsRgn, updateRgn, updateRgn); + HIShapeGetBounds(updateRgn, updateBounds); + CFRelease(damageRgn); + CFRelease(boundsRgn); event.xany.serial = Tk_Display(winPtr)->request; event.xany.send_event = false; event.xany.window = Tk_WindowId(winPtr); event.xany.display = Tk_Display(winPtr); event.type = Expose; - event.xexpose.x = damageBounds.left - bounds.left; - event.xexpose.y = damageBounds.top - bounds.top; - event.xexpose.width = damageBounds.right - damageBounds.left; - event.xexpose.height = damageBounds.bottom - damageBounds.top; + event.xexpose.x = damageBounds.origin.x - bounds.origin.x; + event.xexpose.y = damageBounds.origin.y - bounds.origin.y; + event.xexpose.width = damageBounds.size.width; + event.xexpose.height = damageBounds.size.height; event.xexpose.count = 0; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); @@ -945,7 +971,7 @@ Tk_MacOSXIsAppInFront(void) static void ClearPort( CGrafPtr port, - RgnHandle updateRgn) + HIShapeRef updateRgn) { CGContextRef context; Rect bounds; @@ -957,7 +983,8 @@ ClearPort( CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, bounds.bottom - bounds.top)); if (updateRgn) { - ClipCGContextToRegion(context, &bounds, updateRgn); + ChkErr(HIShapeReplacePathInCGContext, updateRgn, context); + CGContextEOClip(context); } rect = CGRectMake(0, 0, bounds.right, bounds.bottom); CGContextClearRect(context, rect); diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index 04a1882..a25512e 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXWm.c,v 1.7.2.44 2007/10/26 10:38:13 das Exp $ + * RCS: @(#) $Id: tkMacOSXWm.c,v 1.7.2.45 2007/11/09 06:26:57 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -77,9 +77,9 @@ static Tk_GeomMgr wmMgrType = { * The following keeps state for Aqua dock icon bounce notification. */ -/* +#if 0 static int tkMacOSXWmAttrNotifyVal = 0; -*/ +#endif /* * Hash table for Mac Window -> TkWindow mapping. @@ -115,6 +115,10 @@ static int WmDeiconifyCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int WmFocusmodelCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +#if 0 +static int WmForgetCmd(Tk_Window tkwin, TkWindow *winPtr, + Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +#endif static int WmFrameCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int WmGeometryCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, @@ -137,6 +141,10 @@ static int WmIconpositionCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int WmIconwindowCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +#if 0 +static int WmManageCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +#endif static int WmMaxsizeCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int WmMinsizeCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, @@ -170,6 +178,9 @@ static void ApplyWindowClassAttributeChanges(TkWindow *winPtr, static void ApplyMasterOverrideChanges(TkWindow *winPtr, WindowRef macWindow); static void GetMinSize(TkWindow *winPtr, int *minWidthPtr, int *minHeightPtr); static void GetMaxSize(TkWindow *winPtr, int *maxWidthPtr, int *maxHeightPtr); +#if 0 +static void RemapWindows(TkWindow *winPtr, MacDrawable *parentWin); +#endif /* @@ -516,21 +527,21 @@ Tk_WmObjCmd( Tk_Window tkwin = (Tk_Window) clientData; static const char *optionStrings[] = { "aspect", "attributes", "client", "colormapwindows", - "command", "deiconify", "focusmodel", + "command", "deiconify", "focusmodel",/* "forget",*/ "frame", "geometry", "grid", "group", "iconbitmap", "iconify", "iconmask", "iconname", "iconphoto", "iconposition", "iconwindow", - "maxsize", "minsize", "overrideredirect", + /*"manage", */"maxsize", "minsize", "overrideredirect", "positionfrom", "protocol", "resizable", "sizefrom", "stackorder", "state", "title", "transient", "withdraw", NULL }; enum options { WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS, - WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, + WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL,/* WMOPT_FORGET,*/ WMOPT_FRAME, WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP, WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME, WMOPT_ICONPHOTO, WMOPT_ICONPOSITION, WMOPT_ICONWINDOW, - WMOPT_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT, + /*WMOPT_MANAGE, */WMOPT_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT, WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM, WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT, WMOPT_WITHDRAW }; @@ -571,7 +582,11 @@ wrongNumArgs: != TCL_OK) { return TCL_ERROR; } - if (!Tk_IsTopLevel(winPtr)) { + if (!Tk_IsTopLevel(winPtr) +#if 0 + && (index != WMOPT_MANAGE) && (index != WMOPT_FORGET) +#endif + ) { Tcl_AppendResult(interp, "window \"", winPtr->pathName, "\" isn't a top-level window", NULL); return TCL_ERROR; @@ -592,6 +607,10 @@ wrongNumArgs: return WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv); case WMOPT_FOCUSMODEL: return WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv); +#if 0 + case WMOPT_FORGET: + return WmForgetCmd(tkwin, winPtr, interp, objc, objv); +#endif case WMOPT_FRAME: return WmFrameCmd(tkwin, winPtr, interp, objc, objv); case WMOPT_GEOMETRY: @@ -614,6 +633,10 @@ wrongNumArgs: return WmIconpositionCmd(tkwin, winPtr, interp, objc, objv); case WMOPT_ICONWINDOW: return WmIconwindowCmd(tkwin, winPtr, interp, objc, objv); +#if 0 + case WMOPT_MANAGE: + return WmManageCmd(tkwin, winPtr, interp, objc, objv); +#endif case WMOPT_MAXSIZE: return WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv); case WMOPT_MINSIZE: @@ -776,7 +799,7 @@ static int WmSetAttribute( ChkErr(SetWindowModified, macWindow, boolean); } break; -/* +#if 0 case WMATT_NOTIFY: if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) { return TCL_ERROR; @@ -795,7 +818,7 @@ static int WmSetAttribute( tkMacOSXWmAttrNotifyVal = boolean; } break; -*/ +#endif case WMATT_TITLEPATH: { const char *path; OSStatus err; @@ -925,11 +948,11 @@ static Tcl_Obj *WmGetAttribute( case WMATT_MODIFIED: result = Tcl_NewBooleanObj(IsWindowModified(macWindow)); break; -/* +#if 0 case WMATT_NOTIFY: result = Tcl_NewBooleanObj(tkMacOSXWmAttrNotifyVal); break; -*/ +#endif case WMATT_TITLEPATH: { FSRef ref; UInt8 path[PATH_MAX+1]; @@ -1347,6 +1370,69 @@ WmFocusmodelCmd( } return TCL_OK; } +#if 0 + +/* + *---------------------------------------------------------------------- + * + * WmForgetCmd -- + * + * This procedure is invoked to process the "wm forget" Tcl command. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +static int +WmForgetCmd(tkwin, winPtr, interp, objc, objv) + Tk_Window tkwin; /* Main window of the application. */ + TkWindow *winPtr; /* Toplevel or Frame to work with */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ +{ +#if 1 + Tcl_AppendResult(interp, "wm forget is not yet supported", (char*)NULL); + return TCL_ERROR; +#else + register Tk_Window frameWin = (Tk_Window)winPtr; + char *oldClass = (char*)Tk_Class(frameWin); + + if (Tk_IsTopLevel(frameWin)) { + MacDrawable *macWin = (MacDrawable *) winPtr->window; + CGrafPtr destPort = TkMacOSXGetDrawablePort(winPtr->window); + + TkFocusJoin(winPtr); + Tk_UnmapWindow(frameWin); + + if (destPort != NULL) { + WindowRef winRef; + winRef = GetWindowFromPort(destPort); + TkMacOSXUnregisterMacWindow(winRef); + DisposeWindow(winRef); + } + macWin->grafPtr = NULL; + macWin->toplevel = winPtr->parentPtr->privatePtr->toplevel; + macWin->flags &= ~TK_HOST_EXISTS; + + RemapWindows(winPtr, macWin); + TkWmDeadWindow(winPtr); + winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED); + + TkMapTopFrame(frameWin); + } else { + /* Already not managed by wm - ignore it */ + } + return TCL_OK; +#endif +} +#endif /* *---------------------------------------------------------------------- @@ -2040,6 +2126,69 @@ WmIconwindowCmd( } return TCL_OK; } +#if 0 + +/* + *---------------------------------------------------------------------- + * + * WmManageCmd -- + * + * This procedure is invoked to process the "wm manage" Tcl command. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +static int +WmManageCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel or Frame to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *CONST objv[]) /* Argument objects. */ +{ +#if 1 + Tcl_AppendResult(interp, "wm manage is not yet supported", (char*)NULL); + return TCL_ERROR; +#else + register Tk_Window frameWin = (Tk_Window)winPtr; + register WmInfo *wmPtr = winPtr->wmInfoPtr; + char *oldClass = (char*)Tk_Class(frameWin); + + if (!Tk_IsTopLevel(frameWin)) { + MacDrawable *macWin = (MacDrawable *) winPtr->window; + + TkFocusSplit(winPtr); + Tk_UnmapWindow(frameWin); + if (wmPtr == NULL) { + TkWmNewWindow(winPtr); + if (winPtr->window == None) { + Tk_MakeWindowExist((Tk_Window) winPtr); + macWin = (MacDrawable *) winPtr->window; + } + TkWmMapWindow(winPtr); + Tk_UnmapWindow(frameWin); + } + wmPtr = winPtr->wmInfoPtr; + winPtr->flags &= ~TK_MAPPED; + macWin->grafPtr = NULL; + macWin->toplevel = macWin; + RemapWindows(winPtr, macWin); + winPtr->flags |= (TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED); + TkMapTopFrame (frameWin); + } else if (Tk_IsTopLevel(frameWin)) { + /* Already managed by wm - ignore it */ + } + return TCL_OK; +#endif +} +#endif /* *---------------------------------------------------------------------- @@ -5870,6 +6019,7 @@ ApplyWindowClassAttributeChanges( ChkErr(HIGrowBoxViewSetTransparent, growBoxView, true); } } + TkMacOSXInvalClipRgns((Tk_Window) winPtr); TkMacOSXInvalidateWindow((MacDrawable *)(winPtr->window), TK_PARENT_WINDOW); } @@ -6242,3 +6392,46 @@ GetMaxSize( *maxHeightPtr = maxHeight; } } +#if 0 + +/* + *---------------------------------------------------------------------- + * + * RemapWindows + * + * Adjust parent/child relation ships of + * the given window hierarchy. + * + * Results: + * none + * + * Side effects: + * keeps windowing system (X11) happy + * + *---------------------------------------------------------------------- + */ +static void +RemapWindows(TkWindow *winPtr, MacDrawable *parentWin) +{ + TkWindow *childPtr; + + /* Remove the OS specific window. + * It will get rebuilt when the window gets Mapped. + */ + if (winPtr->window != None) { + MacDrawable *macWin = (MacDrawable *) winPtr->window; + macWin->grafPtr = NULL; + macWin->toplevel = parentWin->toplevel; + winPtr->flags &= ~TK_MAPPED; +#ifdef TK_REBUILD_TOPLEVEL + winPtr->flags |= TK_REBUILD_TOPLEVEL; +#endif + } + + /* Repeat for all the children */ + for (childPtr = winPtr->childList; childPtr != NULL; + childPtr = childPtr->nextPtr) { + RemapWindows(childPtr, (MacDrawable *) winPtr->window); + } +} +#endif diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c index 1232a01..1f48753 100644 --- a/macosx/tkMacOSXXStubs.c +++ b/macosx/tkMacOSXXStubs.c @@ -13,12 +13,16 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXXStubs.c,v 1.2.2.19 2007/07/04 18:10:52 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXXStubs.c,v 1.2.2.20 2007/11/09 06:26:57 das Exp $ */ #include "tkMacOSXPrivate.h" #include "tkMacOSXEvent.h" +#if 0 +#include +#endif + /* * Because this file is still under major development Debugger statements are * used through out this file. The define TCL_DEBUG will decide whether @@ -704,15 +708,7 @@ XSetClipRectangles( int n, int ordering) { - TkRegion clipRgn; - - if (gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type - == TKP_CLIP_REGION) { - clipRgn = ((TkpClipMask*)gc->clip_mask)->value.region; - SetEmptyRgn((RgnHandle) clipRgn); - } else { - clipRgn = TkCreateRegion(); /* LEAK! */ - } + TkRegion clipRgn = TkCreateRegion(); while (n--) { XRectangle rect = *rectangles; @@ -723,6 +719,7 @@ XSetClipRectangles( rectangles++; } TkSetRegion(d, gc, clipRgn); + TkDestroyRegion(clipRgn); return 1; } #endif @@ -1198,3 +1195,95 @@ TkGetDefaultScreenName( #endif return macScreenName; } +#if 0 + +/* + *---------------------------------------------------------------------- + * + * Tk_GetUserInactiveTime -- + * + * Return the number of milliseconds the user was inactive. + * + * Results: + * The number of milliseconds the user has been inactive, + * or -1 if querying the inactive time is not supported. + * + * Side effects: + * None. + *---------------------------------------------------------------------- + */ + +long +Tk_GetUserInactiveTime(Display *dpy) +{ + io_registry_entry_t regEntry; + CFMutableDictionaryRef props = NULL; + CFTypeRef timeObj; + long ret = -1l; + uint64_t time; + + regEntry = IOServiceGetMatchingService(kIOMasterPortDefault, + IOServiceMatching("IOHIDSystem")); + + if (regEntry == 0) { + return -1l; + } + + IOReturn result = IORegistryEntryCreateCFProperties(regEntry, &props, + kCFAllocatorDefault, 0); + IOObjectRelease(regEntry); + + if (result != KERN_SUCCESS || props == NULL) { + return -1l; + } + + timeObj = CFDictionaryGetValue(props, CFSTR("HIDIdleTime")); + + if (timeObj) { + CFTypeID type = CFGetTypeID(timeObj); + + if (type == CFDataGetTypeID()) { /* Jaguar */ + CFDataGetBytes((CFDataRef) timeObj, + CFRangeMake(0, sizeof(time)), (UInt8 *) &time); + /* Convert nanoseconds to milliseconds. */ + /* ret /= kMillisecondScale; */ + ret = (long)(time/kMillisecondScale); + } else if (type == CFNumberGetTypeID()) { /* Panther+ */ + CFNumberGetValue((CFNumberRef)timeObj, + kCFNumberSInt64Type, &time); + /* Convert nanoseconds to milliseconds. */ + /* ret /= kMillisecondScale; */ + ret = (long)(time/kMillisecondScale); + } else { + ret = -1l; + } + } + /* Cleanup */ + CFRelease(props); + + return ret; +} + +/* + *---------------------------------------------------------------------- + * + * Tk_ResetUserInactiveTime -- + * + * Reset the user inactivity timer + * + * Results: + * none + * + * Side effects: + * The user inactivity timer of the underlaying windowing system + * is reset to zero. + * + *---------------------------------------------------------------------- + */ + +void +Tk_ResetUserInactiveTime(Display *dpy) +{ + UpdateSystemActivity(OverallAct); +} +#endif diff --git a/xlib/xgc.c b/xlib/xgc.c index 57c1110..570d510 100644 --- a/xlib/xgc.c +++ b/xlib/xgc.c @@ -5,11 +5,12 @@ * contexts. * * Copyright (c) 1995-1996 Sun Microsystems, Inc. + * Copyright (c) 2002-2007 Daniel A. Steffen * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: xgc.c,v 1.6.2.5 2007/07/02 13:27:04 das Exp $ + * RCS: @(#) $Id: xgc.c,v 1.6.2.6 2007/11/09 06:26:57 das Exp $ */ #include @@ -24,6 +25,7 @@ # define Region XRegion #endif #ifdef MAC_OSX_TK +# include # include # include # define Cursor XCursor @@ -34,6 +36,64 @@ /* *---------------------------------------------------------------------- * + * AllocClipMask -- + * + * Static helper proc to allocate new or clear existing TkpClipMask. + * + * Results: + * Returns ptr to the new/cleared TkpClipMask. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static TkpClipMask *AllocClipMask(GC gc) { + TkpClipMask *clip_mask = (TkpClipMask*) gc->clip_mask; + + if (clip_mask == None) { + clip_mask = (TkpClipMask*) ckalloc(sizeof(TkpClipMask)); + gc->clip_mask = (Pixmap) clip_mask; +#ifdef MAC_OSX_TK + } else if (clip_mask->type == TKP_CLIP_REGION) { + TkpReleaseRegion(clip_mask->value.region); +#endif + } + return clip_mask; +} + +/* + *---------------------------------------------------------------------- + * + * FreeClipMask -- + * + * Static helper proc to free TkpClipMask. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void FreeClipMask(GC gc) { + if (gc->clip_mask != None) { +#ifdef MAC_OSX_TK + if (((TkpClipMask*) gc->clip_mask)->type == TKP_CLIP_REGION) { + TkpReleaseRegion(((TkpClipMask*) gc->clip_mask)->value.region); + } +#endif + ckfree((char*) gc->clip_mask); + gc->clip_mask = None; + } +} + +/* + *---------------------------------------------------------------------- + * * XCreateGC -- * * Allocate a new GC, and initialize the specified fields. @@ -95,12 +155,12 @@ XCreateGC(display, d, mask, values) gp->dashes = (mask & GCDashList) ?values->dashes :4; (&(gp->dashes))[1] = 0; + gp->clip_mask = None; if (mask & GCClipMask) { - gp->clip_mask = (Pixmap)ckalloc(sizeof(TkpClipMask)); - ((TkpClipMask*)gp->clip_mask)->type = TKP_CLIP_PIXMAP; - ((TkpClipMask*)gp->clip_mask)->value.pixmap = values->clip_mask; - } else { - gp->clip_mask = None; + TkpClipMask *clip_mask = AllocClipMask(gp); + + clip_mask->type = TKP_CLIP_PIXMAP; + clip_mask->value.pixmap = values->clip_mask; } return gp; @@ -176,9 +236,7 @@ void XFreeGC(d, gc) GC gc; { if (gc != None) { - if (gc->clip_mask != None) { - ckfree((char*) gc->clip_mask); - } + FreeClipMask(gc); ckfree((char *) gc); } } @@ -341,9 +399,9 @@ XSetClipOrigin(display, gc, clip_x_origin, clip_y_origin) * Sets the clipping region/pixmap for a GC. * * Note that unlike the Xlib equivalent, it is not safe to delete the - * region after setting it into the GC. The only uses of TkSetRegion - * are currently in DisplayFrame and in ImgPhotoDisplay, which use the - * GC immediately. + * region after setting it into the GC (except on Mac OS X). The only + * uses of TkSetRegion are currently in DisplayFrame and in + * ImgPhotoDisplay, which use the GC immediately. * * Results: * None. @@ -360,22 +418,17 @@ TkSetRegion(display, gc, r) GC gc; TkRegion r; { - TkpClipMask *clip_mask; - if (r == None) { - if (gc->clip_mask) { - ckfree((char*) gc->clip_mask); - gc->clip_mask = None; - } - return; - } + FreeClipMask(gc); + } else { + TkpClipMask *clip_mask = AllocClipMask(gc); - if (gc->clip_mask == None) { - gc->clip_mask = (Pixmap)ckalloc(sizeof(TkpClipMask)); + clip_mask->type = TKP_CLIP_REGION; + clip_mask->value.region = r; +#ifdef MAC_OSX_TK + TkpRetainRegion(r); +#endif } - clip_mask = (TkpClipMask*) gc->clip_mask; - clip_mask->type = TKP_CLIP_REGION; - clip_mask->value.region = r; } void @@ -384,22 +437,14 @@ XSetClipMask(display, gc, pixmap) GC gc; Pixmap pixmap; { - TkpClipMask *clip_mask; - if (pixmap == None) { - if (gc->clip_mask) { - ckfree((char*) gc->clip_mask); - gc->clip_mask = None; - } - return; - } + FreeClipMask(gc); + } else { + TkpClipMask *clip_mask = AllocClipMask(gc); - if (gc->clip_mask == None) { - gc->clip_mask = (Pixmap)ckalloc(sizeof(TkpClipMask)); + clip_mask->type = TKP_CLIP_PIXMAP; + clip_mask->value.pixmap = pixmap; } - clip_mask = (TkpClipMask*) gc->clip_mask; - clip_mask->type = TKP_CLIP_PIXMAP; - clip_mask->value.pixmap = pixmap; } /* -- cgit v0.12