diff options
author | das <das> | 2007-04-23 21:24:32 (GMT) |
---|---|---|
committer | das <das> | 2007-04-23 21:24:32 (GMT) |
commit | 11dbb8af58fd851913e5c781e3164e8211e93745 (patch) | |
tree | 1a0bc7c114e940c5e46d3704ac14fb34f4cc029e | |
parent | 24b160e09ae3ca4b52502fe59ddcd5fc80e00713 (diff) | |
download | tk-11dbb8af58fd851913e5c781e3164e8211e93745.zip tk-11dbb8af58fd851913e5c781e3164e8211e93745.tar.gz tk-11dbb8af58fd851913e5c781e3164e8211e93745.tar.bz2 |
* macosx/tkMacOSXCarbonEvents.c: add window event target carbon event
* macosx/tkMacOSXEvent.c: handler for all kEventClassWindow and
* macosx/tkMacOSXEvent.h: kEventClassMouse events;
* macosx/tkMacOSXNotify.c: move all remaining events except for
* macosx/tkMacOSXWindowEvent.c: kEventClassKeyboard from dispatcher to
application event handler; pass event handler callRef downstream; fix
debug event tracing; process all tcl event types in carbon event timer;
delay carbon event timer first fire; add TkMacOSXTrackingLoop() to mark
enter/exit of event tracking loop during which all tcl events but only
carbon update events should be processed by the timer (replaces various
calls to Tcl_SetServiceMode()); rename TkMacOSXReceiveAndProcessEvent()
to TkMacOSXReceiveAndDispatchEvent(), move it from tkMacOSXEvent.c to
tkMacOSXCarbonEvents.c and modify it to dequeue only update events
during a tracking loop; add TkMacOSXRunTclEventLoop() to standardize
the various ways in use to run the tcl event loop; add handling of
kEventClassAppearance events (for ScrollBarVariantChanged event).
* macosx/tkMacOSXDialog.c: use new TkMacOSXTrackingLoop() around
* macosx/tkMacOSXEvent.c: blocking API that puts up modal dialogs
* macosx/tkMacOSXMenu.c: or when entering/exiting menu/control
* macosx/tkMacOSXMouseEvent.c: tracking, window dragging and other
* macosx/tkMacOSXScale.c: mouse tracking loops.
* macosx/tkMacOSXScrlbr.c:
* macosx/tkMacOSXWindowEvent.c:
* macosx/tkMacOSXWm.c:
* macosx/tkMacOSXDialog.c: use new TkMacOSXRunTclEventLoop()
* macosx/tkMacOSXScale.c: instead of Tcl_DoOneEvent(),
* macosx/tkMacOSXScrlbr.c: Tcl_ServiceAll(), TclServiceIdle()
* macosx/tkMacOSXWindowEvent.c: and Tcl_GlobalEval("update idletasks").
* macosx/tkMacOSXColor.c: make available as Tk system colors all
* macosx/tkMacOSXPort.h: appearance manager brushes, text colors and
backgrounds with new and legacy names, as well as the fully transparent
color "systemTransparent"; add TkMacOSXSetColorIn{Port,Context}() to
directly set an X pixel color value in the current QD port resp. the
given CG context without requiring passage through rgb representation
(lossy for most system colors); modernize/remove Classic-era code;
replace crufty strcmp() elseifs by Tcl_GetIndexFromObjStruct().
* macosx/tkMacOSXButton.c: use new TkMacOSXSetColorInPort()
* macosx/tkMacOSXDraw.c: instead of setting rgb color directly
* macosx/tkMacOSXMenubutton.c: to allow for non-rgb system colors.
* macosx/tkMacOSXCursor.c: implement "none" cursor as on other
platforms [Patch 1615427]; add all missing appearance manager cursors.
* macosx/tkMacOSXDefault.h: set SELECT_FG_COLORs to None to match aqua
L&F; use standard system color names; use new 'menu' system font;
correct default scrollbar width.
* macosx/tkMacOSXDraw.c: standardize initialization, use and
* macosx/tkMacOSXInt.h: emptying of various static temp rgns
* macosx/tkMacOSXRegion.c: onto two global RgnHandles; in debug
* macosx/tkMacOSXSubwindows.c: builds, verify emptiness of these temp
* macosx/tkMacOSXWindowEvent.c: rgns before use.
* macosx/tkMacOSXDraw.c: add TkMacOSX{Setup,Restore}DrawingContext() to
* macosx/tkMacOSXInt.h: abstract common setup & teardown of drawing
environment (for both CG and QD); save/restore QD theme drawing state;
handle GC clip region; add TkpClipDrawableToRect() to allow clipped
drawing into drawable regardless of GC used; use new system color
"systemWindowHeaderBackground" to setup background in themed toplevels;
correct implementation of TkMacOSXMakeStippleMap().
* macosx/tkMacOSXEntry.c: use new TkMacOSXSetupDrawingContext() and
* macosx/tkMacOSXFont.c: TkMacOSXRestoreDrawingContext() instead of
* macosx/ttkMacOSXTheme.c: various setup/teardown procs like
TkMacOSX{SetUp,Release}CGContext(), TkMacOSXQuarz{Start,End}Draw(),
TkMacOSXSetUpGraphicsPort() etc.
* macosx/tkMacOSXEmbed.c: add CG context and drawable clip rgn fields
* macosx/tkMacOSXInt.h: to MacDrawable struct.
* macosx/tkMacOSXSubwindows.c:
* macosx/tkMacOSXDialog.c: make -parent option of tk_getOpenFile et al.
use the sheet version of NavServices dialogs; ensure native parent win
exists before using StandardSheet API for tk_messageBox [Bug 1677611];
force sheets to behave like app-modal dialogs via WindowModality() API;
use more modern ColorPicker API.
* macosx/tkAboutDlg.r: use themed movable modal dialog, fix (c) year.
* macosx/tkMacOSXEntry.c: take xOff/yOff of MacDrawable into account
* macosx/ttkMacOSXTheme.c: when computing locations/bounds to ensure
correct posititioning when not drawing into intermediate pixmap.
* macosx/tkMacOSXFont.c: use appearance manager API to map system font
* macosx/tkMacOSXFont.h: names to TkFonts; add "menu" system font for
menu item text drawing from MDEF; always draw with CG; remove QD
dependent stippling algorithm; move most header declarations into the
source file (as they were not used anywhere else).
* macosx/tkMacOSXMenu.c: large-scale rewrite of custom
* macosx/tkMacOSXMenu.r (removed): MDEF and related code that
* macosx/Wish.xcode/project.pbxproj: restores many longtime-MIA
* macosx/Wish.xcodeproj/project.pbxproj: features to working order
* unix/Makefile.in: (e.g. images, custom colors &
fonts in menus etc); implement compound menu items; use Appearance Mgr
and ThemeText APIs to mimic native MDEF as closely as possible when
default "menu" system font is used; remove now obsolete SICN drawing
code and resources.
* macosx/tkMacOSXCarbonEvents.c: handle additional menu carbon events
* macosx/tkMacOSXEvent.c: in order to support <<MenuSelect>> in
* macosx/tkMacOSXMenu.c: the menubar and in menus that are not
* macosx/tkMacOSXMenus.c: using the custom MDEF [Bug 1620826];
fix early and missing clearing of current Tk active menu entry; fix
extraneous sending of <<MenuSelect>> during active menu entry clearing.
* macosx/tkMacOSXMouseEvent.c: add support for async window dragging by
the window server; set the corresponding window attribute by default.
* macosx/tkMacOSXMouseEvent.c: rationalized handling order of
non-mousedown events; add TkMacOSXModifierState() to retrieve the
current key modifiers in carbon format.
* macosx/tkMacOSXScrlbr.c: use appearance manager API to retrieve
scrollbar component metrics; add awareness of multiple possibilites for
scrollbar arrow position in aqua and handle user changes to arrow
position pref; handle difference in metrics of small & large scrollbar
variants; handle aqua "jump to here" scrollbar behaviour; correct
computation of scroll view size and position; enforce min scrollbar
height to avoid scrollbar component overlap; erase scrollbar area
outside of standard width; remove broken auto-adjust code; account for
window class when leaving space for grow box; remove code to manually
draw grow box; use modern API for thumb scroll proc; replace
HiliteControl() by modern API; replace control mgr constants with
appearance mgr equivalents.
* macosx/tkMacOSXSubwindows.c: use SetWindowBounds() API instead of
SizeWindow(); invalidate clip regions after X{Map,Unmap}Window as fix
for [Bug 940117] made them dependent on mapping state; remove unneeded
calls to TkMacOSXInvalClipRgns() and unnecessary setting of QD port;
use native-endian pixmap on intel; remove obsolete pixmap pix locking.
* macosx/tkMacOSXWindowEvent.c: handle only the first of a batch of
kEventAppAvailableWindowBoundsChanged events sent per transaction;
handle kEventWindowBoundsChanged event to support live window resizing
and centralized sending of location/size changed ConfigureNotify
events; ensure HIGrowBox is redrawn after bounds change; constrain
window after dragging to ensure titlebar is not inacessible
offscreen or under dock/menubar; handle kEventWindowGetRegion and
kEventWindowDrawContent for transparent windows to mark resp. paint
content region as transparent; handle kEventWindowConstrain for
fullscreen windows to ensure bounds match new screen size; enter/exit
fullscreen UIMode upon activation/deactivation of fullscreen window.
* macosx/tkMacOSXWm.c: use live-resize and async-drag carbon window
* macosx/tkMacOSXWm.h: attributes for toplevels by default; implement
new [wm attributes] -topmost, -transparent and -fullscreen; refactor
WmAttributesCmd() parallelling the tkUnixWm.c implementation, use thus
factored proc to set proxy icon from [wm iconbitmap]; dynamically
determine default values for toplevel min and max sizes (similar to
tkWinWm.c impl): min sizes depend on window class & attributes to
ensure visibility of all titlebar widgets and grow box, max sizes
depend on maximal window bounds for all active displays; factor out
code that puts into effect changes to master or override_redirect; use
RepositionWindow() API to determine staggered initial window bounds;
correct resize limit calculations, handle gridding and use modern
resize API in TkMacOSXGrowToplevel(); remove sending of ConfigureNotify
after resize or zoom (now handled by BoundsChanged handler); correct
composite carbon window attribute handling, remove currently unusable
attributes and add new attributes in [tk::unsupported::MacWindowStyle];
ensure validity of window class and attributes before use; apply
changes to window class when handling carbon window attribute changes
(if HIWindowChangeClass() API available); add debug build warning
message when deprecated window style is used instead of window class;
use transparent HIGrowBox for resizable windows; avoid unnecessary
calls to window structure width API; use tcl time API in TkpGetMS();
add TkMacOSXEnterExitFullscreen() to enter/exit UIMode with dock and
menubar hidden; restrict wmTracing output to debug builds; remove
unneeded calls to TkMacOSXInvalClipRgns() and unnecessary setting of QD
port; workaround GetWindowStructureWidths() Carbon bug (bogus results
for never-mapped floating windows).
* macosx/tkMacOSXXStubs.c (TkMacOSXDisplayChanged): add maximal window
bounds field to Screen record (in ext_data), computed as the union of
available window positioning bounds of all graphics devices (displays).
* macosx/tkMacOSXBitmap.c: fix macRoman encoding leak.
* macosx/tkMacOSXCursor.c:
* macosx/tkMacOSXDebug.c (TkMacOSXCarbonEventToAscii): use static
* macosx/tkMacOSXDebug.h: buffer to simplify callers; const fixes.
* macosx/tkMacOSXBitmap.c: use more efficient QDSwapPort() instead of
* macosx/tkMacOSXButton.c: GetPort()/SetPort()/GetGWorld()/SetGWorld().
* macosx/tkMacOSXDraw.c:
* macosx/tkMacOSXMenubutton.c:
* macosx/tkMacOSXScale.c:
* macosx/tkMacOSXScrlbr.c:
* macosx/tkMacOSXXStubs.c:
* macosx/tkMacOSXColor.c: use kHIToolboxVersionNumber for runtime OS
* macosx/tkMacOSXEntry.c: version check rather than Gestalt() etc.
* macosx/tkMacOSXInt.h:
* macosx/tkMacOSXWm.c:
* macosx/tkMacOSXDraw.c: remove obsolete and now incorrect
* macosx/tkMacOSXInt.h: tkMenuCascadeRgn clipping code.
* macosx/tkMacOSXMenu.c:
* macosx/tkMacOSXHLEvents.c: replace Tcl_GlobalEval() resp. Tcl_Eval()
* macosx/tkMacOSXScrlbr.c: by Tcl_EvalEx().
* macosx/tkMacOSXInit.c:
* macosx/tkMacOSXInit.c (TkpInit): reorder initialization steps.
* macosx/tkMacOSXKeyEvent.c: remove pre-10.2 support.
* macosx/tkMacOSXMenus.c: remove now useless call to
TkMacOSXHandleTearoffMenu(); use \x.. quoting for non-latin1 macroman
literar chars to allow file to be edited as utf-8.
* macosx/tkMacOSXScale.c: replace TrackControl() by modern
* macosx/tkMacOSXScrlbr.c: HandleControlClick() API (using new
TkMacOSXModifierState()).
* macosx/tkMacOSXInt.h: move all constant #defines needed to
* macosx/tkMacOSXColor.c: support building on older OS X releases
* macosx/tkMacOSXEvent.h: to a central location in tkMacOSXInt.h.
* macosx/tkMacOSXFont.c:
* macosx/tkMacOSXMenu.c:
* macosx/tkMacOSXMenubutton.c:
* macosx/tkMacOSXMenus.c:
* macosx/tkMacOSXMouseEvent.c:
* macosx/tkMacOSXWm.c:
* macosx/ttkMacOSXTheme.c:
* macosx/tkMacOSXInt.h: add ChkErr() macro to factor out
* macosx/tkMacOSXButton.c: Carbon OSStatus return value checking
* macosx/tkMacOSXCarbonEvents.c: and TkMacOSXDbgMsg() macro to factour
* macosx/tkMacOSXClipboard.c: out debug message output; use these
* macosx/tkMacOSXColor.c: macros to replace #ifdef TK_MAC_DEBUG
* macosx/tkMacOSXCursor.c: blocks & direct printing to stderr,
* macosx/tkMacOSXDebug.c: and to do additional OSStatus return
* macosx/tkMacOSXDialog.c: checking, and to standardize OSStatus
* macosx/tkMacOSXDraw.c: usage.
* macosx/tkMacOSXEntry.c:
* macosx/tkMacOSXEvent.c:
* macosx/tkMacOSXFont.c:
* macosx/tkMacOSXHLEvents.c:
* macosx/tkMacOSXInit.c:
* macosx/tkMacOSXKeyEvent.c:
* macosx/tkMacOSXMenu.c:
* macosx/tkMacOSXMenubutton.c:
* macosx/tkMacOSXMenus.c:
* macosx/tkMacOSXMouseEvent.c:
* macosx/tkMacOSXScrlbr.c:
* macosx/tkMacOSXSubwindows.c:
* macosx/tkMacOSXWindowEvent.c:
* macosx/tkMacOSXWm.c:
* macosx/tkMacOSXXStubs.c:
* macosx/tkMacOSXSend.c: remove duplicate/unused declarations
* macosx/tkMacOSXXStubs.c:
* macosx/tkMacOSXDebug.c: const fixes.
* macosx/tkMacOSXInit.c:
* macosx/tkMacOSXTest.c:
* macosx/tkMacOSXWm.c:
* macosx/tkMacOSXXStubs.c:
* macosx/Wish-Info.plist.in: add tcl document extensions/mime types and
LSMinimumSystemVersion, LSRequiresCarbon & NSAppleScriptEnabled keys.
* macosx/Wish-Common.xcconfig: add Wish's Info.plist as __info_plist
section to tktest; enable more warnings.
* macosx/Wish.xcodeproj/project.pbxproj: add 'DebugMemCompile' build
configuration that calls configure with --enable-symbols=all; disable
configure check for __attribute__((__visibility__("hidden"))) in Debug
configuration to restore availability of ZeroLink.
* macosx/Wish-Common.xcconfig: fix whitespace.
* macosx/Wish-Debug.xcconfig:
* macosx/Wish-Release.xcconfig:
* macosx/tkMacOSXAETE.r:
* macosx/tkMacOSXConfig.c:
* macosx/tkMacOSXCursors.r:
* macosx/tkMacOSXKeyboard.c:
* macosx/tkMacOSXSend.c:
* macosx/ttkMacOSXTheme.c:
* macosx/tkMacOSXXCursors.r:
* macosx/README:
* macosx/GNUmakefile: fix/add copyright and license refs.
* macosx/Tk-Info.plist.in:
* macosx/Wish-Info.plist.in:
* macosx/Wish.xcode/project.pbxproj:
* macosx/Wish.xcodeproj/project.pbxproj:
* macosx/tkMacOSX.h:
58 files changed, 16443 insertions, 15795 deletions
@@ -1,7 +1,345 @@ -2007-04-21 Jeff Hobbs <jeffh@ActiveState.com> +2007-04-23 Daniel Steffen <das@users.sourceforge.net> *** 8.5a6 TAGGED FOR RELEASE *** + * generic/tkCanvas.c: allow -selectforeground option to be None; add + * generic/tkCanvText.c: fallback to fgColor when selFgColor is None + * generic/tkEntry.c: (new default on aqua to match native L&F). + * generic/tkListbox.c: + * generic/tkText.c: + + * generic/tkCanvas.c: add support for bypassing all of Tk's double + * generic/tkEntry.c: buffered drawing into intermediate pixmaps + * generic/tkFrame.c: (via TK_NO_DOUBLE_BUFFERING #define), it is + * generic/tkListbox.c: unnecessary & wasteful on aqua where all + * generic/tkPanedWindow.c: drawing is already double-buffered by the + * generic/tkTextDisp.c: window server. (Use of this on other + * generic/ttk/ttkWidget.c: platforms would only require implementation + * unix/tkUnixScale.c: of TkpClipDrawableToRect()). + * macosx/tkMacOSXPort.h: + + * library/bgerror.tcl: on aqua, use moveable alert resp. modal dialog + * library/dialog.tcl: window class and corresponding system + background pattern; fix button padding. + + * library/tearoff.tcl: correct aqua menu bar height; vertically offset + * library/tk.tcl: aqua tearoff floating window to match menu. + + * library/demos/goldberg.tcl: fix overwriting of widget demo global. + + * library/demos/menu.tcl: on aqua, use custom MDEF and tearoffs; + * library/demos/menubu.tcl: correct menubutton toplevel name. + + * library/demos/puzzle.tcl: fix button size & padding for aqua. + * library/demos/radio.tcl: + + * macosx/tkMacOSXCarbonEvents.c: add window event target carbon event + * macosx/tkMacOSXEvent.c: handler for all kEventClassWindow and + * macosx/tkMacOSXEvent.h: kEventClassMouse events; + * macosx/tkMacOSXNotify.c: move all remaining events except for + * macosx/tkMacOSXWindowEvent.c: kEventClassKeyboard from dispatcher to + application event handler; pass event handler callRef downstream; fix + debug event tracing; process all tcl event types in carbon event timer; + delay carbon event timer first fire; add TkMacOSXTrackingLoop() to mark + enter/exit of event tracking loop during which all tcl events but only + carbon update events should be processed by the timer (replaces various + calls to Tcl_SetServiceMode()); rename TkMacOSXReceiveAndProcessEvent() + to TkMacOSXReceiveAndDispatchEvent(), move it from tkMacOSXEvent.c to + tkMacOSXCarbonEvents.c and modify it to dequeue only update events + during a tracking loop; add TkMacOSXRunTclEventLoop() to standardize + the various ways in use to run the tcl event loop; add handling of + kEventClassAppearance events (for ScrollBarVariantChanged event). + + * macosx/tkMacOSXDialog.c: use new TkMacOSXTrackingLoop() around + * macosx/tkMacOSXEvent.c: blocking API that puts up modal dialogs + * macosx/tkMacOSXMenu.c: or when entering/exiting menu/control + * macosx/tkMacOSXMouseEvent.c: tracking, window dragging and other + * macosx/tkMacOSXScale.c: mouse tracking loops. + * macosx/tkMacOSXScrlbr.c: + * macosx/tkMacOSXWindowEvent.c: + * macosx/tkMacOSXWm.c: + + * macosx/tkMacOSXDialog.c: use new TkMacOSXRunTclEventLoop() + * macosx/tkMacOSXScale.c: instead of Tcl_DoOneEvent(), + * macosx/tkMacOSXScrlbr.c: Tcl_ServiceAll(), TclServiceIdle() + * macosx/tkMacOSXWindowEvent.c: and Tcl_GlobalEval("update idletasks"). + + * macosx/tkMacOSXColor.c: make available as Tk system colors all + * macosx/tkMacOSXPort.h: appearance manager brushes, text colors and + backgrounds with new and legacy names, as well as the fully transparent + color "systemTransparent"; add TkMacOSXSetColorIn{Port,Context}() to + directly set an X pixel color value in the current QD port resp. the + given CG context without requiring passage through rgb representation + (lossy for most system colors); modernize/remove Classic-era code; + replace crufty strcmp() elseifs by Tcl_GetIndexFromObjStruct(). + + * macosx/tkMacOSXButton.c: use new TkMacOSXSetColorInPort() + * macosx/tkMacOSXDraw.c: instead of setting rgb color directly + * macosx/tkMacOSXMenubutton.c: to allow for non-rgb system colors. + + * macosx/tkMacOSXCursor.c: implement "none" cursor as on other + platforms [Patch 1615427]; add all missing appearance manager cursors. + + * macosx/tkMacOSXDefault.h: set SELECT_FG_COLORs to None to match aqua + L&F; use standard system color names; use new 'menu' system font; + correct default scrollbar width. + + * macosx/tkMacOSXDraw.c: standardize initialization, use and + * macosx/tkMacOSXInt.h: emptying of various static temp rgns + * macosx/tkMacOSXRegion.c: onto two global RgnHandles; in debug + * macosx/tkMacOSXSubwindows.c: builds, verify emptiness of these temp + * macosx/tkMacOSXWindowEvent.c: rgns before use. + + * macosx/tkMacOSXDraw.c: add TkMacOSX{Setup,Restore}DrawingContext() to + * macosx/tkMacOSXInt.h: abstract common setup & teardown of drawing + environment (for both CG and QD); save/restore QD theme drawing state; + handle GC clip region; add TkpClipDrawableToRect() to allow clipped + drawing into drawable regardless of GC used; use new system color + "systemWindowHeaderBackground" to setup background in themed toplevels; + correct implementation of TkMacOSXMakeStippleMap(). + + * macosx/tkMacOSXEntry.c: use new TkMacOSXSetupDrawingContext() and + * macosx/tkMacOSXFont.c: TkMacOSXRestoreDrawingContext() instead of + * macosx/ttkMacOSXTheme.c: various setup/teardown procs like + TkMacOSX{SetUp,Release}CGContext(), TkMacOSXQuarz{Start,End}Draw(), + TkMacOSXSetUpGraphicsPort() etc. + + * macosx/tkMacOSXEmbed.c: add CG context and drawable clip rgn fields + * macosx/tkMacOSXInt.h: to MacDrawable struct. + * macosx/tkMacOSXSubwindows.c: + + * macosx/tkMacOSXDialog.c: make -parent option of tk_getOpenFile et al. + use the sheet version of NavServices dialogs; ensure native parent win + exists before using StandardSheet API for tk_messageBox [Bug 1677611]; + force sheets to behave like app-modal dialogs via WindowModality() API; + use more modern ColorPicker API. + + * macosx/tkAboutDlg.r: use themed movable modal dialog, fix (c) year. + + * macosx/tkMacOSXEntry.c: take xOff/yOff of MacDrawable into account + * macosx/ttkMacOSXTheme.c: when computing locations/bounds to ensure + correct posititioning when not drawing into intermediate pixmap. + + * macosx/tkMacOSXFont.c: use appearance manager API to map system font + * macosx/tkMacOSXFont.h: names to TkFonts; add "menu" system font for + menu item text drawing from MDEF; always draw with CG; remove QD + dependent stippling algorithm; move most header declarations into the + source file (as they were not used anywhere else). + + * macosx/tkMacOSXMenu.c: large-scale rewrite of custom + * macosx/tkMacOSXMenu.r (removed): MDEF and related code that + * macosx/Wish.xcode/project.pbxproj: restores many longtime-MIA + * macosx/Wish.xcodeproj/project.pbxproj: features to working order + * unix/Makefile.in: (e.g. images, custom colors & + fonts in menus etc); implement compound menu items; use Appearance Mgr + and ThemeText APIs to mimic native MDEF as closely as possible when + default "menu" system font is used; remove now obsolete SICN drawing + code and resources. + + * macosx/tkMacOSXCarbonEvents.c: handle additional menu carbon events + * macosx/tkMacOSXEvent.c: in order to support <<MenuSelect>> in + * macosx/tkMacOSXMenu.c: the menubar and in menus that are not + * macosx/tkMacOSXMenus.c: using the custom MDEF [Bug 1620826]; + fix early and missing clearing of current Tk active menu entry; fix + extraneous sending of <<MenuSelect>> during active menu entry clearing. + + * macosx/tkMacOSXMouseEvent.c: add support for async window dragging by + the window server; set the corresponding window attribute by default. + + * macosx/tkMacOSXMouseEvent.c: rationalized handling order of + non-mousedown events; add TkMacOSXModifierState() to retrieve the + current key modifiers in carbon format. + + * macosx/tkMacOSXScrlbr.c: use appearance manager API to retrieve + scrollbar component metrics; add awareness of multiple possibilites for + scrollbar arrow position in aqua and handle user changes to arrow + position pref; handle difference in metrics of small & large scrollbar + variants; handle aqua "jump to here" scrollbar behaviour; correct + computation of scroll view size and position; enforce min scrollbar + height to avoid scrollbar component overlap; erase scrollbar area + outside of standard width; remove broken auto-adjust code; account for + window class when leaving space for grow box; remove code to manually + draw grow box; use modern API for thumb scroll proc; replace + HiliteControl() by modern API; replace control mgr constants with + appearance mgr equivalents. + + * macosx/tkMacOSXSubwindows.c: use SetWindowBounds() API instead of + SizeWindow(); invalidate clip regions after X{Map,Unmap}Window as fix + for [Bug 940117] made them dependent on mapping state; remove unneeded + calls to TkMacOSXInvalClipRgns() and unnecessary setting of QD port; + use native-endian pixmap on intel; remove obsolete pixmap pix locking. + + * macosx/tkMacOSXWindowEvent.c: handle only the first of a batch of + kEventAppAvailableWindowBoundsChanged events sent per transaction; + handle kEventWindowBoundsChanged event to support live window resizing + and centralized sending of location/size changed ConfigureNotify + events; ensure HIGrowBox is redrawn after bounds change; constrain + window after dragging to ensure titlebar is not inacessible + offscreen or under dock/menubar; handle kEventWindowGetRegion and + kEventWindowDrawContent for transparent windows to mark resp. paint + content region as transparent; handle kEventWindowConstrain for + fullscreen windows to ensure bounds match new screen size; enter/exit + fullscreen UIMode upon activation/deactivation of fullscreen window. + + * macosx/tkMacOSXWm.c: use live-resize and async-drag carbon window + * macosx/tkMacOSXWm.h: attributes for toplevels by default; implement + new [wm attributes] -topmost, -transparent and -fullscreen; refactor + WmAttributesCmd() parallelling the tkUnixWm.c implementation, use thus + factored proc to set proxy icon from [wm iconbitmap]; dynamically + determine default values for toplevel min and max sizes (similar to + tkWinWm.c impl): min sizes depend on window class & attributes to + ensure visibility of all titlebar widgets and grow box, max sizes + depend on maximal window bounds for all active displays; factor out + code that puts into effect changes to master or override_redirect; use + RepositionWindow() API to determine staggered initial window bounds; + correct resize limit calculations, handle gridding and use modern + resize API in TkMacOSXGrowToplevel(); remove sending of ConfigureNotify + after resize or zoom (now handled by BoundsChanged handler); correct + composite carbon window attribute handling, remove currently unusable + attributes and add new attributes in [tk::unsupported::MacWindowStyle]; + ensure validity of window class and attributes before use; apply + changes to window class when handling carbon window attribute changes + (if HIWindowChangeClass() API available); add debug build warning + message when deprecated window style is used instead of window class; + use transparent HIGrowBox for resizable windows; avoid unnecessary + calls to window structure width API; use tcl time API in TkpGetMS(); + add TkMacOSXEnterExitFullscreen() to enter/exit UIMode with dock and + menubar hidden; restrict wmTracing output to debug builds; remove + unneeded calls to TkMacOSXInvalClipRgns() and unnecessary setting of QD + port; workaround GetWindowStructureWidths() Carbon bug (bogus results + for never-mapped floating windows). + + * macosx/tkMacOSXXStubs.c (TkMacOSXDisplayChanged): add maximal window + bounds field to Screen record (in ext_data), computed as the union of + available window positioning bounds of all graphics devices (displays). + + * macosx/tkMacOSXBitmap.c: fix macRoman encoding leak. + * macosx/tkMacOSXCursor.c: + + * macosx/tkMacOSXDebug.c (TkMacOSXCarbonEventToAscii): use static + * macosx/tkMacOSXDebug.h: buffer to simplify callers; const fixes. + + * macosx/tkMacOSXBitmap.c: use more efficient QDSwapPort() instead of + * macosx/tkMacOSXButton.c: GetPort()/SetPort()/GetGWorld()/SetGWorld(). + * macosx/tkMacOSXDraw.c: + * macosx/tkMacOSXMenubutton.c: + * macosx/tkMacOSXScale.c: + * macosx/tkMacOSXScrlbr.c: + * macosx/tkMacOSXXStubs.c: + + * macosx/tkMacOSXColor.c: use kHIToolboxVersionNumber for runtime OS + * macosx/tkMacOSXEntry.c: version check rather than Gestalt() etc. + * macosx/tkMacOSXInt.h: + * macosx/tkMacOSXWm.c: + + * macosx/tkMacOSXDraw.c: remove obsolete and now incorrect + * macosx/tkMacOSXInt.h: tkMenuCascadeRgn clipping code. + * macosx/tkMacOSXMenu.c: + + * macosx/tkMacOSXHLEvents.c: replace Tcl_GlobalEval() resp. Tcl_Eval() + * macosx/tkMacOSXScrlbr.c: by Tcl_EvalEx(). + * macosx/tkMacOSXInit.c: + + * macosx/tkMacOSXInit.c (TkpInit): reorder initialization steps. + + * macosx/tkMacOSXKeyEvent.c: remove pre-10.2 support. + + * macosx/tkMacOSXMenus.c: remove now useless call to + TkMacOSXHandleTearoffMenu(); use \x.. quoting for non-latin1 macroman + literar chars to allow file to be edited as utf-8. + + * macosx/tkMacOSXScale.c: replace TrackControl() by modern + * macosx/tkMacOSXScrlbr.c: HandleControlClick() API (using new + TkMacOSXModifierState()). + + * macosx/tkMacOSXInt.h: move all constant #defines needed to + * macosx/tkMacOSXColor.c: support building on older OS X releases + * macosx/tkMacOSXEvent.h: to a central location in tkMacOSXInt.h. + * macosx/tkMacOSXFont.c: + * macosx/tkMacOSXMenu.c: + * macosx/tkMacOSXMenubutton.c: + * macosx/tkMacOSXMenus.c: + * macosx/tkMacOSXMouseEvent.c: + * macosx/tkMacOSXWm.c: + * macosx/ttkMacOSXTheme.c: + + * macosx/tkMacOSXInt.h: add ChkErr() macro to factor out + * macosx/tkMacOSXButton.c: Carbon OSStatus return value checking + * macosx/tkMacOSXCarbonEvents.c: and TkMacOSXDbgMsg() macro to factour + * macosx/tkMacOSXClipboard.c: out debug message output; use these + * macosx/tkMacOSXColor.c: macros to replace #ifdef TK_MAC_DEBUG + * macosx/tkMacOSXCursor.c: blocks & direct printing to stderr, + * macosx/tkMacOSXDebug.c: and to do additional OSStatus return + * macosx/tkMacOSXDialog.c: checking, and to standardize OSStatus + * macosx/tkMacOSXDraw.c: usage. + * macosx/tkMacOSXEntry.c: + * macosx/tkMacOSXEvent.c: + * macosx/tkMacOSXFont.c: + * macosx/tkMacOSXHLEvents.c: + * macosx/tkMacOSXInit.c: + * macosx/tkMacOSXKeyEvent.c: + * macosx/tkMacOSXMenu.c: + * macosx/tkMacOSXMenubutton.c: + * macosx/tkMacOSXMenus.c: + * macosx/tkMacOSXMouseEvent.c: + * macosx/tkMacOSXScrlbr.c: + * macosx/tkMacOSXSubwindows.c: + * macosx/tkMacOSXWindowEvent.c: + * macosx/tkMacOSXWm.c: + * macosx/tkMacOSXXStubs.c: + + * macosx/tkMacOSXSend.c: remove duplicate/unused declarations + * macosx/tkMacOSXXStubs.c: + + * macosx/tkMacOSXDebug.c: const fixes. + * macosx/tkMacOSXInit.c: + * macosx/tkMacOSXTest.c: + * macosx/tkMacOSXWm.c: + * macosx/tkMacOSXXStubs.c: + + * macosx/Wish-Info.plist.in: add tcl document extensions/mime types and + LSMinimumSystemVersion, LSRequiresCarbon & NSAppleScriptEnabled keys. + + * macosx/Wish-Common.xcconfig: add Wish's Info.plist as __info_plist + section to tktest; enable more warnings. + + * macosx/Wish.xcodeproj/project.pbxproj: add 'DebugMemCompile' build + configuration that calls configure with --enable-symbols=all; disable + configure check for __attribute__((__visibility__("hidden"))) in Debug + configuration to restore availability of ZeroLink. + + * macosx/Wish-Common.xcconfig: fix whitespace. + * macosx/Wish-Debug.xcconfig: + * macosx/Wish-Release.xcconfig: + * macosx/tkMacOSXAETE.r: + * macosx/tkMacOSXConfig.c: + * macosx/tkMacOSXCursors.r: + * macosx/tkMacOSXKeyboard.c: + * macosx/tkMacOSXSend.c: + * macosx/ttkMacOSXTheme.c: + * macosx/tkMacOSXXCursors.r: + * macosx/README: + + * macosx/GNUmakefile: fix/add copyright and license refs. + * macosx/Tk-Info.plist.in: + * macosx/Wish-Info.plist.in: + * macosx/Wish.xcode/project.pbxproj: + * macosx/Wish.xcodeproj/project.pbxproj: + * macosx/tkMacOSX.h: + + * unix/configure.in: install license.terms into Tk.framework; fix tk + debug build detection. + * unix/configure: autoconf-2.59 + + * doc/colors.n: document new Mac OS X system colors. + * doc/cursors.n: document new Mac OS X native cursors. + * doc/font.n: document new Mac OS X 'menu' system font. + * doc/wm.n: document new Mac OS X [wm attributes]. + * doc/ttk_image.n: fix 'make html' warning. + * doc/canvas.n: fix nroff typo. + +2007-04-21 Jeff Hobbs <jeffh@ActiveState.com> + * macosx/tkMacOSXBitmap.c, macosx/tkMacOSXButton.c: * macosx/tkMacOSXCarbonEvents.c, macosx/tkMacOSXClipboard.c: * macosx/tkMacOSXCursor.c, macosx/tkMacOSXDialog.c: @@ -2,7 +2,7 @@ This file summarizes all changes made to Tk since version 1.0 was released on March 13, 1991. Changes that aren't backward compatible are marked specially. -RCS: @(#) $Id: changes,v 1.104 2007/04/22 07:04:41 hobbs Exp $ +RCS: @(#) $Id: changes,v 1.105 2007/04/23 21:24:32 das Exp $ 3/16/91 (bug fix) Modified tkWindow.c to remove Tk's Tcl commands from the interpreter when the main window is deleted (otherwise there will @@ -6251,7 +6251,7 @@ ttk::radiobutton, ttk::checkbutton, ttk::treeview, ttk::separator, ttk::scrollbar, ttk::entry, ttk::frame and ttk::labelframe widgets. Adds ttk::style command. -2006-11-02 (enhancement) Improve OS X Carbon event handling +2006-11-02 (enhancement) Improve OS X Carbon event handling. 2006-11-07 (configure change) Unix --enable-xft is enabled by default now. @@ -6262,7 +6262,7 @@ control display of console. 2006-11-30 (bug fix) Fix handling of Escape binding on OS X dialogs. -2006-12-01 (new feature) add -transparentcolor wm attribute on Windows. +2006-12-01 (new feature) Add -transparentcolor wm attribute on Windows. 2006-12-02 (new feature)[TIP 300] Added [font actual $font $char]. @@ -6271,11 +6271,55 @@ control display of console. 2006-12-11 (enhancement) Improved EWMH support for _NET_WM_PID and _NET_WM_PING. -2007-01-19 (configure change) ensre CPPFLAGS env var is used when set. +2007-01-19 (configure change) Ensure CPPFLAGS env var is used when set. -2007-02-19 (configure change) use SHLIB_SUFFIX=".so" on HP-UX IA64 (was +2007-02-19 (configure change) Use SHLIB_SUFFIX=".so" on HP-UX IA64 (was ".sl"). -2007-04-10 (platform support) correctly handling theming on Vista/Aero. +2007-04-10 (platform support) Correctly handle theming on Vista/Aero. + +2007-04-23 (enhancement) Allow empty value for -selectforeground option. + +2007-04-23 (platform support) Aqua: remove Tk-internal double buffering that is +wasteful on Aqua; allows direct-to-window CoreGraphics drawing (e.g. adding +support for colors with alpha). + +2007-04-23 (platform support) Aqua: add all OS theme colors/brushes (patterns) +as system colors. + +2007-04-23 (platform support) Aqua: use OS theme for tk_dialog and bgerror. + +2007-04-23 (platform support) Aqua: add 'none' cursor. + +2007-04-23 (platform support) Aqua: [tk_getOpenFile -parent] uses sheet dialog. + +2007-04-23 (bug fix) Aqua: fix custom MDEF and tearoff menu display. + +2007-04-23 (bug fix)[1620826] Aqua: fix <<MenuSelect>> support. + +2007-04-23 (platform support) Aqua: add support for live window resizing and +asynchronous window dragging; prevent window from becoming inacessible +offscreen or under Dock after dragging; use transparent grow box. + +2007-04-23 (platform support) Aqua: improve event processing during nested +event loops (e.g. modal dialogs, menu tracking, window resizing etc). + +2007-04-23 (bug fix) Aqua: add support for all possible aqua scrollbar arrow +positions, scrollbar variants and for "jump to here" scrollbar behaviour; +correct scroll view size computation; enforce minimal scrollbar height. + +2007-04-23 (platform support) Aqua: add [wm attributes] -topmost, -fullscreen +and -transparent (allows fully transparent window via -bg "systemTransparent"). + +2007-04-23 (platform support) Aqua: determine win min/max sizes dynamically; +correct size handling of gridded windows; improve computation of initial +window bounds; correct window size handling on multi-headed systems. + +2007-04-23 (platform support) Aqua: correct composite attribute handling in +[tk::unsupported::MacWindowStyle] and add new attributes; allow changing +window class of already existing windows. + +2007-04-23 (platform support) Aqua: add tcl document extensions and mime type +to Wish.app's Info.plist. --- Released 8.5a6, April 25, 2007 --- See ChangeLog for details --- diff --git a/macosx/GNUmakefile b/macosx/GNUmakefile index 3e2e286..8514f71 100644 --- a/macosx/GNUmakefile +++ b/macosx/GNUmakefile @@ -4,7 +4,12 @@ # uses the standard unix build system in tk/unix (which can be used directly instead of this # if you are not using the tk/macosx projects). # -# RCS: @(#) $Id: GNUmakefile,v 1.7 2006/10/16 17:36:18 das Exp $ +# Copyright (c) 2002-2007 Daniel A. Steffen <das@users.sourceforge.net> +# +# See the file "license.terms" for information on usage and redistribution of +# this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# RCS: @(#) $Id: GNUmakefile,v 1.8 2007/04/23 21:24:32 das Exp $ # ######################################################################################################## @@ -18,8 +23,8 @@ BUILD_DIR ?= ${CURDIR}/../../build SYMROOT ?= ${BUILD_DIR}/${PROJECT} OBJROOT ?= ${SYMROOT} -EXTRA_CONFIGURE_ARGS ?= -EXTRA_MAKE_ARGS ?= +EXTRA_CONFIGURE_ARGS ?= +EXTRA_MAKE_ARGS ?= INSTALL_PATH ?= /Library/Frameworks APPLICATION_INSTALL_PATH ?= /Applications/Utilities @@ -35,7 +40,7 @@ TCL_FRAMEWORK_DIR ?= /Library/Frameworks TCLSH_DIR ?= ${PREFIX} # set to non-empty value to install manpages in addition to html help: -INSTALL_MANPAGES ?= +INSTALL_MANPAGES ?= # set to non-empty value to build TkX11 instead of TkAqua: TK_X11 ?= @@ -43,7 +48,7 @@ TK_X11 ?= #------------------------------------------------------------------------------------------------------- # meta targets -meta := all install embedded install-embedded clean distclean test +meta := all install embedded install-embedded clean distclean test styles := develop deploy @@ -84,7 +89,7 @@ deploy_make_args := BUILD_STYLE=Deployment INSTALL_TARGET=install-strip embedded_make_args := EMBEDDED_BUILD=1 install_make_args := INSTALL_BUILD=1 -${targets}: +${targets}: ${MAKE} ${action}${PROJECT} \ $(foreach s,${styles} embedded install,$(if $(findstring $s,$@),${${s}_make_args})) @@ -108,7 +113,7 @@ TCL_DIR := ${TCL_BUILD_DIR} TCL_FRAMEWORK_DIR := ${TCL_BUILD_DIR}/.. else TCL_DIR := ${TCL_FRAMEWORK_DIR}/Tcl.framework -TCL_EXE := ${TCLSH_DIR}/tclsh${TCL_VERSION} +TCL_EXE := ${TCLSH_DIR}/tclsh${TCL_VERSION} MAKE_VARS = TCL_EXE export DYLD_FRAMEWORK_PATH := ${TCL_FRAMEWORK_DIR} endif @@ -166,7 +171,7 @@ ${PROJECT}: ${MAKE} install-${PROJECT} INSTALL_ROOT=${OBJ_DIR}/ ${OBJ_DIR}/Makefile: ${UNIX_DIR}/Makefile.in ${UNIX_DIR}/configure \ - ${UNIX_DIR}/tkConfig.sh.in Tk-Info.plist.in Wish-Info.plist.in + ${UNIX_DIR}/tkConfig.sh.in Tk-Info.plist.in Wish-Info.plist.in mkdir -p ${OBJ_DIR} && cd ${OBJ_DIR} && \ if [ ${UNIX_DIR}/configure -nt config.status ]; then ${UNIX_DIR}/configure -C \ --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} \ @@ -291,7 +296,7 @@ clean-${PROJECT}: %-${PROJECT}: distclean-${PROJECT}: %-${PROJECT}: clean-${PROJECT} ${DO_MAKE} rm -rf ${OBJ_DIR} - + test-${PROJECT}: %-${PROJECT}: build-${PROJECT} ${DO_MAKE} diff --git a/macosx/README b/macosx/README index 4bef580..4a9c917 100644 --- a/macosx/README +++ b/macosx/README @@ -1,7 +1,7 @@ -Tcl/Tk Mac OS X README +Tcl/Tk Mac OS X README ---------------------- -RCS: @(#) $Id: README,v 1.22 2007/01/28 01:42:16 das Exp $ +RCS: @(#) $Id: README,v 1.23 2007/04/23 21:24:32 das Exp $ This is the README file for the Mac OS X/Darwin version of Tcl/Tk. @@ -98,7 +98,7 @@ inherits loginwindow's environment variables, which are essentially those set in $HOME/.MacOSX/environment.plist, and are unrelated to those set in your shell). - As of Tk 8.4.7, TkAqua has a version of the low-level drawing primitives using -the CoreGraphics routines - the code is primarily due to James Tittle. There +the CoreGraphics routines - the code is primarily due to James Tittle. There were numerous problems with the QD version, mostly due to the different drawing model of QD & Tk. CG also trivially supports dashed lines, and the various end caps & miters. The old QD code is retained for now, just in case there are any @@ -132,8 +132,8 @@ have a base name: Then to get the sequential variants, add an integer to the end of the base name. So, for instance this code will spin the spinner: proc spinCursor {widget count} { - $widget configure -cursor spinning$count - after 100 spinCursor [incr count] + $widget configure -cursor spinning$count + after 100 spinCursor [incr count] } This was added in Tk 8.4.2 @@ -238,7 +238,7 @@ Detailed Instructions for building with macosx/GNUmakefile trees in a common parent directory. [ If you don't want have the two source trees in one directory, you'll need to ] [ create the following symbolic link for the build to work as setup by default ] -[ ln -fs /path_to_tcl/build /path_to_tk/build ] +[ ln -fs /path_to_tcl/build /path_to_tk/build ] [ (where /path_to_{tcl,tk} is the directory containing the tcl resp. tk tree) ] [ or you can pass an argument of BUILD_DIR=/somewhere to the tcl and tk make. ] @@ -247,12 +247,12 @@ trees in a common parent directory. containing the Tcl and Tk version number (for example '8.4.12'). Setup the shell variable as follows: set ver="8.4.12" ;: if your shell is csh - ver="8.4.12" ;: if your shell is sh + ver="8.4.12" ;: if your shell is sh The source trees will be named this way only if you are building from a release archive, if you are building from CVS, the version numbers will be missing; so set ${ver} to the empty string instead: - set ver="" ;: if your shell is csh - ver="" ;: if your shell is sh + set ver="" ;: if your shell is csh + ver="" ;: if your shell is sh - The following steps will build Tcl and Tk from the Terminal, assuming you are located in the directory containing the tcl and tk source trees: diff --git a/macosx/Tk-Info.plist.in b/macosx/Tk-Info.plist.in index a392991..dfb0044 100644 --- a/macosx/Tk-Info.plist.in +++ b/macosx/Tk-Info.plist.in @@ -1,5 +1,13 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<!-- + Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> + + See the file "license.terms" for information on usage and redistribution of + this file, and for a DISCLAIMER OF ALL WARRANTIES. + + RCS: @(#) $Id: Tk-Info.plist.in,v 1.2 2007/04/23 21:24:32 das Exp $ +--> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> @@ -7,14 +15,17 @@ <key>CFBundleExecutable</key> <string>@TK_LIB_FILE@</string> <key>CFBundleGetInfoString</key> - <string>Tk @TK_WINDOWINGSYSTEM@ Library @TK_VERSION@, Copyright © @TK_YEAR@ Tcl Core Team. -Initial MacOS X Port by Jim Ingham <jingham@apple.com> & Ian Reid, Copyright © 2001-2002, Apple Computer, Inc.</string> + <string>Tk @TK_WINDOWINGSYSTEM@ @TK_VERSION@@TK_PATCH_LEVEL@, +Copyright © @TK_YEAR@ Tcl Core Team, +Copyright © 2002-@TK_YEAR@ Daniel A. Steffen, +Initial MacOS X Port by Jim Ingham & Ian Reid, +Copyright © 2001-2002, Apple Computer, Inc.</string> <key>CFBundleIdentifier</key> <string>com.tcltk.tklibrary</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> - <string>Tk @TK_WINDOWINGSYSTEM@ Library @TK_VERSION@</string> + <string>Tk @TK_WINDOWINGSYSTEM@ @TK_VERSION@</string> <key>CFBundlePackageType</key> <string>FMWK</string> <key>CFBundleShortVersionString</key> diff --git a/macosx/Wish-Common.xcconfig b/macosx/Wish-Common.xcconfig index 08e041e..635fbbb 100644 --- a/macosx/Wish-Common.xcconfig +++ b/macosx/Wish-Common.xcconfig @@ -1,4 +1,4 @@ -// +// // Wish-Common.xcconfig -- // // This file contains the Xcode build settings comon to all @@ -9,12 +9,12 @@ // See the file "license.terms" for information on usage and redistribution // of this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// RCS: @(#) $Id: Wish-Common.xcconfig,v 1.2 2007/03/07 23:46:34 das Exp $ +// RCS: @(#) $Id: Wish-Common.xcconfig,v 1.3 2007/04/23 21:24:32 das Exp $ // HEADER_SEARCH_PATHS = $(TK_SRCROOT)/generic $(TK_SRCROOT)/xlib $(DERIVED_FILE_DIR)/tcl $(DERIVED_FILE_DIR)/tk $(HEADER_SEARCH_PATHS) REZ_SEARCH_PATHS = $(TK_SRCROOT)/generic $(TCL_SRCROOT)/generic $(REZ_SEARCH_PATHS) -OTHER_LDFLAGS = -headerpad_max_install_names -sectcreate __TEXT __tk_rsrc $(REZ_COLLECTOR_DIR)/$(PRODUCT_NAME).rsrc $(OTHER_LDFLAGS) +OTHER_LDFLAGS = -headerpad_max_install_names -sectcreate __TEXT __tk_rsrc $(REZ_COLLECTOR_DIR)/$(PRODUCT_NAME).rsrc -sectcreate __TEXT __info_plist $(DERIVED_FILE_DIR)/tk/Wish-Info.plist $(OTHER_LDFLAGS) INSTALL_PATH = "$(BINDIR)" GCC_PREFIX_HEADER = $(DERIVED_FILE_DIR)/tk/tkConfig.h OTHER_CFLAGS = -imacros $(DERIVED_FILE_DIR)/tcl/tclConfig.h $(OTHER_CFLAGS) @@ -25,7 +25,7 @@ GCC = /usr/bin/gcc GCC_VERSION = 4.0 CC = $(GCC)-$(GCC_VERSION) WARNING_CFLAGS_GCC3 = -Wall -Wno-implicit-int -Wno-unused-parameter -Wno-deprecated-declarations -WARNING_CFLAGS = -Wextra -Wno-missing-field-initializers $(WARNING_CFLAGS_GCC3) $(WARNING_CFLAGS) +WARNING_CFLAGS = -Wextra -Wno-missing-field-initializers -Winit-self -Wpointer-arith -Wcast-align -Wdisabled-optimization -Winline $(WARNING_CFLAGS_GCC3) $(WARNING_CFLAGS) REZ_RESOURCE_MAP_READ_ONLY = YES APPLICATION_INSTALL_PATH = /Applications/Utilities BINDIR = $(PREFIX)/bin diff --git a/macosx/Wish-Debug.xcconfig b/macosx/Wish-Debug.xcconfig index 14e80fd..19c1f71 100644 --- a/macosx/Wish-Debug.xcconfig +++ b/macosx/Wish-Debug.xcconfig @@ -1,4 +1,4 @@ -// +// // Wish-Debug.xcconfig -- // // This file contains the Xcode build settings for all Debug @@ -9,7 +9,7 @@ // See the file "license.terms" for information on usage and redistribution // of this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// RCS: @(#) $Id: Wish-Debug.xcconfig,v 1.1 2007/01/28 01:42:16 das Exp $ +// RCS: @(#) $Id: Wish-Debug.xcconfig,v 1.2 2007/04/23 21:24:32 das Exp $ // #include "Wish-Common.xcconfig" diff --git a/macosx/Wish-Info.plist.in b/macosx/Wish-Info.plist.in index 08fff5a..6cc3eef 100644 --- a/macosx/Wish-Info.plist.in +++ b/macosx/Wish-Info.plist.in @@ -1,5 +1,13 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<!-- + Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> + + See the file "license.terms" for information on usage and redistribution of + this file, and for a DISCLAIMER OF ALL WARRANTIES. + + RCS: @(#) $Id: Wish-Info.plist.in,v 1.2 2007/04/23 21:24:32 das Exp $ +--> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> @@ -9,13 +17,21 @@ <dict> <key>CFBundleTypeExtensions</key> <array> + <string>tcl</string> + <string>TCL</string> <string>*</string> </array> + <key>CFBundleTypeMIMETypes</key> + <array> + <string>application/x-tcl</string> + <string>text/plain</string> + </array> <key>CFBundleTypeName</key> <string>NSStringPboardType</string> <key>CFBundleTypeOSTypes</key> <array> <string>TEXT</string> + <string>****</string> </array> <key>CFBundleTypeRole</key> <string>Viewer</string> @@ -24,8 +40,11 @@ <key>CFBundleExecutable</key> <string>Wish</string> <key>CFBundleGetInfoString</key> - <string>Wish Shell @TK_VERSION@, Copyright © @TK_YEAR@ Tcl Core Team. -Initial MacOS X Port by Jim Ingham <jingham@apple.com> & Ian Reid, Copyright © 2001-2002, Apple Computer, Inc.</string> + <string>Wish Shell @TK_VERSION@@TK_PATCH_LEVEL@, +Copyright © @TK_YEAR@ Tcl Core Team, +Copyright © 2002-@TK_YEAR@ Daniel A. Steffen, +Initial MacOS X Port by Jim Ingham & Ian Reid, +Copyright © 2001-2002, Apple Computer, Inc.</string> <key>CFBundleIconFile</key> <string>Wish.icns</string> <key>CFBundleIdentifier</key> @@ -42,5 +61,11 @@ Initial MacOS X Port by Jim Ingham <jingham@apple.com> & Ian Reid, Cop <string>WiSH</string> <key>CFBundleVersion</key> <string>@TK_VERSION@@TK_PATCH_LEVEL@</string> + <key>LSMinimumSystemVersion</key> + <string>10.2.0</string> + <key>LSRequiresCarbon</key> + <true/> + <key>NSAppleScriptEnabled</key> + <true/> </dict> </plist> diff --git a/macosx/Wish-Release.xcconfig b/macosx/Wish-Release.xcconfig index 4bcc74c..e1a8752 100644 --- a/macosx/Wish-Release.xcconfig +++ b/macosx/Wish-Release.xcconfig @@ -1,4 +1,4 @@ -// +// // Wish-Release.xcconfig -- // // This file contains the Xcode build settings for all Release @@ -9,7 +9,7 @@ // See the file "license.terms" for information on usage and redistribution // of this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// RCS: @(#) $Id: Wish-Release.xcconfig,v 1.1 2007/01/28 01:42:16 das Exp $ +// RCS: @(#) $Id: Wish-Release.xcconfig,v 1.2 2007/04/23 21:24:32 das Exp $ // #include "Wish-Common.xcconfig" diff --git a/macosx/Wish.xcode/project.pbxproj b/macosx/Wish.xcode/project.pbxproj index 81abdac..6f1f009 100644 --- a/macosx/Wish.xcode/project.pbxproj +++ b/macosx/Wish.xcode/project.pbxproj @@ -75,6 +75,7 @@ F966C06F08F281DC005CB29B, 1AB674ADFE9D54B511CA2CBB, ); + comments = "Copyright (c) 2004-2007 Daniel A. Steffen <das@users.sourceforge.net>\n\nSee the file \"license.terms\" for information on usage and redistribution of\nthis file, and for a DISCLAIMER OF ALL WARRANTIES.\n\nRCS: @(#) $Id: project.pbxproj,v 1.13 2007/04/23 21:24:34 das Exp $\n"; isa = PBXGroup; name = Wish; path = .; @@ -3747,7 +3748,6 @@ F966BBDB08F27A3B005CB29B, F966BBDC08F27A3B005CB29B, F966BBDD08F27A3B005CB29B, - F966BBDF08F27A3B005CB29B, F966BBE008F27A3B005CB29B, F966BBE108F27A3B005CB29B, F966BBE208F27A3B005CB29B, @@ -4021,14 +4021,6 @@ refType = 4; sourceTree = "<group>"; }; - F966BBDF08F27A3B005CB29B = { - fileEncoding = 4; - isa = PBXFileReference; - lastKnownFileType = sourcecode.rez; - path = tkMacOSXMenu.r; - refType = 4; - sourceTree = "<group>"; - }; F966BBE008F27A3B005CB29B = { fileEncoding = 4; isa = PBXFileReference; @@ -15036,7 +15028,6 @@ buildActionMask = 2147483647; files = ( F9EA4AF008FA3BD500B1F5F0, - F9EA4AF108FA3BD700B1F5F0, F9EA4AF208FA3BD800B1F5F0, F9EA4AF308FA3BDA00B1F5F0, F9EA4AF408FA3BDB00B1F5F0, @@ -15050,12 +15041,6 @@ settings = { }; }; - F9EA4AF108FA3BD700B1F5F0 = { - fileRef = F966BBDF08F27A3B005CB29B; - isa = PBXBuildFile; - settings = { - }; - }; F9EA4AF208FA3BD800B1F5F0 = { fileRef = F966BBCC08F27A3B005CB29B; isa = PBXBuildFile; diff --git a/macosx/Wish.xcodeproj/project.pbxproj b/macosx/Wish.xcodeproj/project.pbxproj index a0a4fbd..bcdd9f7 100644 --- a/macosx/Wish.xcodeproj/project.pbxproj +++ b/macosx/Wish.xcodeproj/project.pbxproj @@ -304,7 +304,6 @@ F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */; }; F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */; }; F9EA4AF008FA3BD500B1F5F0 /* tkMacOSXXCursors.r in Rez */ = {isa = PBXBuildFile; fileRef = F966BBF408F27A3C005CB29B /* tkMacOSXXCursors.r */; }; - F9EA4AF108FA3BD700B1F5F0 /* tkMacOSXMenu.r in Rez */ = {isa = PBXBuildFile; fileRef = F966BBDF08F27A3B005CB29B /* tkMacOSXMenu.r */; }; F9EA4AF208FA3BD800B1F5F0 /* tkMacOSXCursors.r in Rez */ = {isa = PBXBuildFile; fileRef = F966BBCC08F27A3B005CB29B /* tkMacOSXCursors.r */; }; F9EA4AF308FA3BDA00B1F5F0 /* tkMacOSXAETE.r in Rez */ = {isa = PBXBuildFile; fileRef = F966BBC408F27A3B005CB29B /* tkMacOSXAETE.r */; }; F9EA4AF408FA3BDB00B1F5F0 /* tkAboutDlg.r in Rez */ = {isa = PBXBuildFile; fileRef = F966BBC108F27A3B005CB29B /* tkAboutDlg.r */; }; @@ -698,7 +697,6 @@ F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMacOSXKeyboard.c; sourceTree = "<group>"; }; F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMacOSXKeyEvent.c; sourceTree = "<group>"; }; F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMacOSXMenu.c; sourceTree = "<group>"; }; - F966BBDF08F27A3B005CB29B /* tkMacOSXMenu.r */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.rez; path = tkMacOSXMenu.r; sourceTree = "<group>"; }; F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMacOSXMenubutton.c; sourceTree = "<group>"; }; F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMacOSXMenus.c; sourceTree = "<group>"; }; F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMacOSXMouseEvent.c; sourceTree = "<group>"; }; @@ -1788,6 +1786,7 @@ F966C06F08F281DC005CB29B /* Frameworks */, 1AB674ADFE9D54B511CA2CBB /* Products */, ); + comments = "Copyright (c) 2004-2007 Daniel A. Steffen <das@users.sourceforge.net>\n\nSee the file \"license.terms\" for information on usage and redistribution of\nthis file, and for a DISCLAIMER OF ALL WARRANTIES.\n\nRCS: @(#) $Id: project.pbxproj,v 1.19 2007/04/23 21:24:35 das Exp $\n"; name = Wish; path = .; sourceTree = SOURCE_ROOT; @@ -2252,7 +2251,6 @@ F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */, F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */, F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */, - F966BBDF08F27A3B005CB29B /* tkMacOSXMenu.r */, F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */, F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */, F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */, @@ -3601,7 +3599,6 @@ buildActionMask = 2147483647; files = ( F9EA4AF008FA3BD500B1F5F0 /* tkMacOSXXCursors.r in Rez */, - F9EA4AF108FA3BD700B1F5F0 /* tkMacOSXMenu.r in Rez */, F9EA4AF208FA3BD800B1F5F0 /* tkMacOSXCursors.r in Rez */, F9EA4AF308FA3BDA00B1F5F0 /* tkMacOSXAETE.r in Rez */, F9EA4AF408FA3BDB00B1F5F0 /* tkAboutDlg.r in Rez */, @@ -4013,6 +4010,30 @@ }; name = ReleaseUniversal; }; + F94173790BC145DD00C54E27 /* DebugMemCompile */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = Wish; + }; + name = DebugMemCompile; + }; + F941737A0BC145DD00C54E27 /* DebugMemCompile */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = tktest; + }; + name = DebugMemCompile; + }; + F941737B0BC145DD00C54E27 /* DebugMemCompile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Wish-Debug.xcconfig */; + buildSettings = { + CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-symbols=all"; + MACOSX_DEPLOYMENT_TARGET = 10.2; + PREBINDING = NO; + }; + name = DebugMemCompile; + }; F95CC8AC09158F3100EA5ACE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -4037,6 +4058,7 @@ F95CC8B109158F3100EA5ACE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)"; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "__private_extern__=extern", @@ -4188,6 +4210,7 @@ buildConfigurations = ( F95CC8AC09158F3100EA5ACE /* Debug */, F95CC8AE09158F3100EA5ACE /* DebugNoFixZL */, + F94173790BC145DD00C54E27 /* DebugMemCompile */, F95CC8AD09158F3100EA5ACE /* Release */, F91BCC4F093152310042A6BF /* ReleaseUniversal */, F9DB62080B65ADA800A370FB /* ReleaseUniversal10.4uSDK */, @@ -4202,6 +4225,7 @@ buildConfigurations = ( F95CC8B109158F3100EA5ACE /* Debug */, F95CC8B309158F3100EA5ACE /* DebugNoFixZL */, + F941737A0BC145DD00C54E27 /* DebugMemCompile */, F95CC8B209158F3100EA5ACE /* Release */, F91BCC50093152310042A6BF /* ReleaseUniversal */, F9DB62090B65ADA800A370FB /* ReleaseUniversal10.4uSDK */, @@ -4216,6 +4240,7 @@ buildConfigurations = ( F95CC8B609158F3100EA5ACE /* Debug */, F95CC8B809158F3100EA5ACE /* DebugNoFixZL */, + F941737B0BC145DD00C54E27 /* DebugMemCompile */, F95CC8B709158F3100EA5ACE /* Release */, F91BCC51093152310042A6BF /* ReleaseUniversal */, F9DB620A0B65ADA800A370FB /* ReleaseUniversal10.4uSDK */, diff --git a/macosx/tkAboutDlg.r b/macosx/tkAboutDlg.r index 3bbdc28..9f42997 100644 --- a/macosx/tkAboutDlg.r +++ b/macosx/tkAboutDlg.r @@ -1,16 +1,15 @@ /* * tkAboutDlg.r -- * - * This file creates resources for use in most Tk applications. - * This is designed to be an example of using the Tcl/Tk - * libraries in a Macintosh Application. + * This file creates resources for the Tk "About Box" dialog. * * Copyright (c) 1996 Sun Microsystems, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkAboutDlg.r,v 1.7 2006/04/28 06:02:48 das Exp $ + * RCS: @(#) $Id: tkAboutDlg.r,v 1.8 2007/04/23 21:24:32 das Exp $ */ /* @@ -26,15 +25,15 @@ /* * The following two resources define the default "About Box" for Mac Tk. * This dialog appears if the "About Tk..." menu item is selected from - * the Apple menu. This dialog may be overridden by defining a Tcl procedure - * with the name of "tkAboutDialog". If this procedure is defined the + * the Apple menu. This dialog may be overridden by defining a Tcl procedure + * with the name of "tkAboutDialog". If this procedure is defined the * default dialog will not be shown and the Tcl procedure is expected to * create and manage an About Dialog box. */ - + resource 'DLOG' (128, "About Box", purgeable) { {60, 40, 332, 404}, - movableDBoxProc, + kWindowMovableModalDialogProc, visible, noGoAway, 0x0, @@ -46,19 +45,26 @@ resource 'DLOG' (128, "About Box", purgeable) { resource 'DITL' (128, "About Box", purgeable) { { {232, 147, 252, 217}, Button {enabled, "Ok"}, - { 20, 108, 212, 344}, StaticText {disabled, - "Tcl " TCL_PATCH_LEVEL " & Tk " TK_PATCH_LEVEL "\n\n" - "© 2002-2006 Tcl Core Team." "\n\n" - "© 2002-2006 Daniel A. Steffen." "\n\n" + { 20, 108, 212, 344}, StaticText {disabled, + "Tcl " TCL_PATCH_LEVEL " & Tk " TK_PATCH_LEVEL "\n\n" + "© 2002-2007 Tcl Core Team." "\n\n" + "© 2002-2007 Daniel A. Steffen." "\n\n" "Jim Ingham & Ian Reid" "\n" - "© 2001-2002 Apple Computer, Inc." "\n\n" + "© 2001-2002 Apple Computer, Inc." "\n\n" "Jim Ingham & Ray Johnson" "\n" "© 1998-2000 Scriptics Inc." "\n" - "© 1996-1997 Sun Microsystems Inc."}, + "© 1996-1997 Sun Microsystems Inc."}, { 20, 24, 120, 92}, Picture {enabled, 128} } }; +resource 'dlgx' (128, "About Box", purgeable) { + versionZero { + kDialogFlagsUseThemeBackground | kDialogFlagsUseControlHierarchy + | kDialogFlagsHandleMovableModal | kDialogFlagsUseThemeControls + } +}; + data 'PICT' (128, purgeable) { $"13A4 0000 0000 0064 0044 0011 02FF 0C00" $"FFFE 0000 0048 0000 0048 0000 0000 0000" diff --git a/macosx/tkMacOSX.h b/macosx/tkMacOSX.h index 1fb92f4..4b92458 100644 --- a/macosx/tkMacOSX.h +++ b/macosx/tkMacOSX.h @@ -5,11 +5,12 @@ * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSX.h,v 1.4 2006/03/24 14:58:00 das Exp $ + * RCS: @(#) $Id: tkMacOSX.h,v 1.5 2007/04/23 21:24:32 das Exp $ */ #ifndef _TKMAC @@ -25,11 +26,11 @@ * Structures and function types for handling Netscape-type in process * embedding where Tk does not control the top-level */ - -typedef int (Tk_MacOSXEmbedRegisterWinProc) (int winID, Tk_Window window); -typedef GWorldPtr (Tk_MacOSXEmbedGetGrafPortProc) (Tk_Window window); -typedef int (Tk_MacOSXEmbedMakeContainerExistProc) (Tk_Window window); -typedef void (Tk_MacOSXEmbedGetClipProc) (Tk_Window window, RgnHandle rgn); + +typedef int (Tk_MacOSXEmbedRegisterWinProc) (int winID, Tk_Window window); +typedef GWorldPtr (Tk_MacOSXEmbedGetGrafPortProc) (Tk_Window window); +typedef int (Tk_MacOSXEmbedMakeContainerExistProc) (Tk_Window window); +typedef void (Tk_MacOSXEmbedGetClipProc) (Tk_Window window, RgnHandle rgn); typedef void (Tk_MacOSXEmbedGetOffsetInParentProc) (Tk_Window window, Point *ulCorner); #include "tkPlatDecls.h" diff --git a/macosx/tkMacOSXAETE.r b/macosx/tkMacOSXAETE.r index 86b860d..87f2a73 100644 --- a/macosx/tkMacOSXAETE.r +++ b/macosx/tkMacOSXAETE.r @@ -1,18 +1,15 @@ /* * tclMacAETE.r -- * - * This file creates the Apple Event Terminology resources - * for use Tcl and Tk. It is not used in the Simple Tcl shell - * since SIOUX does not support AppleEvents. An example of its - * use in Tcl is the TclBGOnly project. And it is used in all the - * Tk Shells. + * This file creates the Apple Event Terminology resources + * for use by Wish.app. * * Copyright (c) 1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXAETE.r,v 1.1 2003/02/25 18:24:31 wolfsuit Exp $ + * RCS: @(#) $Id: tkMacOSXAETE.r,v 1.2 2007/04/23 21:24:32 das Exp $ */ #define SystemSevenOrLater 1 @@ -27,8 +24,8 @@ resource 'aete' (0, "Wish Suite") { 0x01, 0x00, english, roman, { - "Required Suite", - "Events that every application should support", + "Required Suite", + "Events that every application should support", 'reqd', 1, 1, {}, {}, @@ -41,12 +38,12 @@ resource 'aete' (0, "Wish Suite") { 'TEXT', "Result", replyOptional, singleItem, notEnumerated, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, - reserved, reserved, reserved, reserved, + reserved, reserved, reserved, reserved, 'TEXT', "Script to execute", directParamRequired, singleItem, notEnumerated, changesState, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, - reserved, + reserved, {}, }, {}, diff --git a/macosx/tkMacOSXBitmap.c b/macosx/tkMacOSXBitmap.c index dc05bc8..7b66a38 100644 --- a/macosx/tkMacOSXBitmap.c +++ b/macosx/tkMacOSXBitmap.c @@ -1,15 +1,16 @@ -/* +/* * tkMacOSXBitmap.c -- * - * This file handles the implementation of native bitmaps. + * This file handles the implementation of native bitmaps. * * Copyright (c) 1996-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXBitmap.c,v 1.6 2007/04/21 19:06:37 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXBitmap.c,v 1.7 2007/04/23 21:24:32 das Exp $ */ #include "tkMacOSXInt.h" @@ -18,17 +19,17 @@ * Depending on the resource type there are different ways to * draw native icons. */ -#define TYPE1 0 /* Family icon suite. */ -#define TYPE2 1 /* ICON resource. */ -#define TYPE3 2 /* cicn resource. */ +#define TYPE1 0 /* Family icon suite. */ +#define TYPE2 1 /* ICON resource. */ +#define TYPE3 2 /* cicn resource. */ /* * This data structure describes the id and type of a given icon. * It is used as the source for native icons. */ typedef struct { - int id; /* Resource Id for Icon. */ - long int type; /* Type of icon. */ + int id; /* Resource Id for Icon. */ + long int type; /* Type of icon. */ } NativeIcon; /* @@ -36,10 +37,10 @@ typedef struct { */ typedef struct { - char *name; /* Name of icon. */ - long int type; /* Type of icon. */ - int id; /* Id of icon. */ - int size; /* Size of icon. */ + const char *name; /* Name of icon. */ + long int type; /* Type of icon. */ + int id; /* Id of icon. */ + int size; /* Size of icon. */ } BuiltInIcon; /* @@ -48,23 +49,23 @@ typedef struct { */ static BuiltInIcon builtInIcons[] = { - {"document", TYPE1, kGenericDocumentIconResource, 32}, - {"stationery", TYPE1, kGenericStationeryIconResource, 32}, - {"edition", TYPE1, kGenericEditionFileIconResource, 32}, - {"application", TYPE1, kGenericApplicationIconResource, 32}, - {"accessory", TYPE1, kGenericDeskAccessoryIconResource, 32}, - {"folder", TYPE1, kGenericFolderIconResource, 32}, - {"pfolder", TYPE1, kPrivateFolderIconResource, 32}, - {"trash", TYPE1, kTrashIconResource, 32}, - {"floppy", TYPE1, kFloppyIconResource, 32}, - {"ramdisk", TYPE1, kGenericRAMDiskIconResource, 32}, - {"cdrom", TYPE1, kGenericCDROMIconResource, 32}, - {"preferences", TYPE1, kGenericPreferencesIconResource, 32}, - {"querydoc", TYPE1, kGenericQueryDocumentIconResource, 32}, - {"stop", TYPE2, kStopIcon, 32}, - {"note", TYPE2, kNoteIcon, 32}, - {"caution", TYPE2, kCautionIcon, 32}, - {(char *) NULL, 0, 0, 0} + {"document", TYPE1, kGenericDocumentIconResource, 32}, + {"stationery", TYPE1, kGenericStationeryIconResource, 32}, + {"edition", TYPE1, kGenericEditionFileIconResource, 32}, + {"application", TYPE1, kGenericApplicationIconResource, 32}, + {"accessory", TYPE1, kGenericDeskAccessoryIconResource, 32}, + {"folder", TYPE1, kGenericFolderIconResource, 32}, + {"pfolder", TYPE1, kPrivateFolderIconResource, 32}, + {"trash", TYPE1, kTrashIconResource, 32}, + {"floppy", TYPE1, kFloppyIconResource, 32}, + {"ramdisk", TYPE1, kGenericRAMDiskIconResource, 32}, + {"cdrom", TYPE1, kGenericCDROMIconResource, 32}, + {"preferences", TYPE1, kGenericPreferencesIconResource, 32}, + {"querydoc", TYPE1, kGenericQueryDocumentIconResource, 32}, + {"stop", TYPE2, kStopIcon, 32}, + {"note", TYPE2, kNoteIcon, 32}, + {"caution", TYPE2, kCautionIcon, 32}, + {NULL, 0, 0, 0} }; /* @@ -72,46 +73,46 @@ static BuiltInIcon builtInIcons[] = { * * TkpDefineNativeBitmaps -- * - * Add native bitmaps. + * Add native bitmaps. * * Results: - * A standard Tcl result. If an error occurs then TCL_ERROR is - * returned and a message is left in the interp's result. + * A standard Tcl result. If an error occurs then TCL_ERROR is + * returned and a message is left in the interp's result. * * Side effects: - * "Name" is entered into the bitmap table and may be used from - * here on to refer to the given bitmap. + * "Name" is entered into the bitmap table and may be used from + * here on to refer to the given bitmap. * *---------------------------------------------------------------------- */ void -TkpDefineNativeBitmaps() +TkpDefineNativeBitmaps(void) { - int new; - Tcl_HashEntry *predefHashPtr; - TkPredefBitmap *predefPtr; - CONST char * name; + Tcl_HashTable *tablePtr = TkGetBitmapPredefTable(); BuiltInIcon *builtInPtr; - NativeIcon *nativeIconPtr; - Tcl_HashTable *tablePtr; - + for (builtInPtr = builtInIcons; builtInPtr->name != NULL; builtInPtr++) { - name = Tk_GetUid(builtInPtr->name); - tablePtr = TkGetBitmapPredefTable(); - predefHashPtr = Tcl_CreateHashEntry(tablePtr, name, &new); - if (!new) { - continue; - } - predefPtr = (TkPredefBitmap *) ckalloc(sizeof(TkPredefBitmap)); - nativeIconPtr = (NativeIcon *) ckalloc(sizeof(NativeIcon)); - nativeIconPtr->id = builtInPtr->id; - nativeIconPtr->type = builtInPtr->type; - predefPtr->source = (char *) nativeIconPtr; - predefPtr->width = builtInPtr->size; - predefPtr->height = builtInPtr->size; - predefPtr->native = 1; - Tcl_SetHashValue(predefHashPtr, predefPtr); + Tcl_HashEntry *predefHashPtr; + const char * name; + int isNew; + + name = Tk_GetUid(builtInPtr->name); + predefHashPtr = Tcl_CreateHashEntry(tablePtr, name, &isNew); + if (isNew) { + TkPredefBitmap *predefPtr = (TkPredefBitmap *) + ckalloc(sizeof(TkPredefBitmap)); + NativeIcon *nativeIconPtr = (NativeIcon *) + ckalloc(sizeof(NativeIcon)); + + nativeIconPtr->id = builtInPtr->id; + nativeIconPtr->type = builtInPtr->type; + predefPtr->source = (char *) nativeIconPtr; + predefPtr->width = builtInPtr->size; + predefPtr->height = builtInPtr->size; + predefPtr->native = 1; + Tcl_SetHashValue(predefHashPtr, predefPtr); + } } } @@ -120,15 +121,15 @@ TkpDefineNativeBitmaps() * * TkpCreateNativeBitmap -- * - * Add native bitmaps. + * Add native bitmaps. * * Results: - * A standard Tcl result. If an error occurs then TCL_ERROR is - * returned and a message is left in the interp's result. + * A standard Tcl result. If an error occurs then TCL_ERROR is + * returned and a message is left in the interp's result. * * Side effects: - * "Name" is entered into the bitmap table and may be used from - * here on to refer to the given bitmap. + * "Name" is entered into the bitmap table and may be used from + * here on to refer to the given bitmap. * *---------------------------------------------------------------------- */ @@ -136,42 +137,40 @@ TkpDefineNativeBitmaps() Pixmap TkpCreateNativeBitmap( Display *display, - CONST char * source) /* Info about the icon to build. */ + CONST char *source) /* Info about the icon to build. */ { Pixmap pix; - GWorldPtr destPort; Rect destRect; - Handle icon; - CGrafPtr saveWorld; - GDHandle saveDevice; - NativeIcon *nativeIconPtr; - - pix = Tk_GetPixmap(display, None, 32, 32, 0); - destPort = TkMacOSXGetDrawablePort(pix); + CGrafPtr savePort; + Boolean portChanged; + const NativeIcon *nativeIconPtr; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); + pix = Tk_GetPixmap(display, None, 32, 32, 0); + portChanged = QDSwapPort(TkMacOSXGetDrawablePort(pix), &savePort); - nativeIconPtr = (NativeIcon *) source; + nativeIconPtr = (const NativeIcon *) source; SetRect(&destRect, 0, 0, 32, 32); if (nativeIconPtr->type == TYPE1) { - RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF}; + RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF}; - RGBForeColor(&white); - PaintRect(&destRect); - PlotIconID(&destRect, atAbsoluteCenter, ttNone, nativeIconPtr->id); + RGBForeColor(&white); + PaintRect(&destRect); + PlotIconID(&destRect, atAbsoluteCenter, ttNone, nativeIconPtr->id); } else if (nativeIconPtr->type == TYPE2) { - icon = GetIcon(nativeIconPtr->id); - if (icon != NULL) { - RGBColor black = {0, 0, 0}; - - RGBForeColor(&black); - PlotIcon(&destRect, icon); - ReleaseResource(icon); - } + Handle icon = GetIcon(nativeIconPtr->id); + + if (icon != NULL) { + RGBColor black = {0, 0, 0}; + + RGBForeColor(&black); + PlotIcon(&destRect, icon); + ReleaseResource(icon); + } } - SetGWorld(saveWorld, saveDevice); + if (portChanged) { + QDSwapPort(savePort, NULL); + } return pix; } @@ -180,94 +179,94 @@ TkpCreateNativeBitmap( * * TkpGetNativeAppBitmap -- * - * Add native bitmaps. + * Add native bitmaps. * * Results: - * A standard Tcl result. If an error occurs then TCL_ERROR is - * returned and a message is left in the interp's result. + * A standard Tcl result. If an error occurs then TCL_ERROR is + * returned and a message is left in the interp's result. * * Side effects: - * "Name" is entered into the bitmap table and may be used from - * here on to refer to the given bitmap. + * "Name" is entered into the bitmap table and may be used from + * here on to refer to the given bitmap. * *---------------------------------------------------------------------- */ Pixmap TkpGetNativeAppBitmap( - Display *display, /* The display. */ - CONST char *name, /* The name of the bitmap. */ - int *width, /* The width & height of the bitmap. */ + Display *display, /* The display. */ + CONST char *name, /* The name of the bitmap. */ + int *width, /* The width & height of the bitmap. */ int *height) { Pixmap pix; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + CGrafPtr savePort; + Boolean portChanged; Rect destRect; Handle resource; int type = -1, destWrote; Str255 nativeName; - + Tcl_Encoding encoding; + /* * macRoman is the encoding that the resource fork uses. */ - Tcl_UtfToExternal(NULL, Tcl_GetEncoding(NULL, "macRoman"), name, - strlen(name), 0, NULL, - (char *) &nativeName[1], - 255, NULL, &destWrote, NULL); /* Internalize native */ + encoding = Tcl_GetEncoding(NULL, "macRoman"); + Tcl_UtfToExternal(NULL, encoding, name, strlen(name), 0, NULL, + (char *) &nativeName[1], 255, NULL, &destWrote, NULL); nativeName[0] = destWrote; + Tcl_FreeEncoding(encoding); resource = GetNamedResource('cicn', nativeName); if (resource != NULL) { - type = TYPE3; + type = TYPE3; } else { - resource = GetNamedResource('ICON', nativeName); - if (resource != NULL) { - type = TYPE2; - } + resource = GetNamedResource('ICON', nativeName); + if (resource != NULL) { + type = TYPE2; + } } - + if (resource == NULL) { - return (Pixmap) NULL; + return (Pixmap) NULL; } - + pix = Tk_GetPixmap(display, None, 32, 32, 0); - destPort = TkMacOSXGetDrawablePort(pix); + portChanged = QDSwapPort(TkMacOSXGetDrawablePort(pix), &savePort); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - SetRect(&destRect, 0, 0, 32, 32); if (type == TYPE2) { - RGBColor black = {0, 0, 0}; - - RGBForeColor(&black); - PlotIcon(&destRect, resource); - ReleaseResource(resource); + RGBColor black = {0, 0, 0}; + + RGBForeColor(&black); + PlotIcon(&destRect, resource); + ReleaseResource(resource); } else if (type == TYPE3) { - RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF}; - short id; - ResType theType; - Str255 dummy; - - /* - * We need to first paint the background white. Also, for - * some reason we *must* use GetCIcon instead of GetNamedResource - * for PlotCIcon to work - so we use GetResInfo to get the id. - */ - RGBForeColor(&white); - PaintRect(&destRect); - GetResInfo(resource, &id, &theType, dummy); - ReleaseResource(resource); - resource = (Handle) GetCIcon(id); - PlotCIcon(&destRect, (CIconHandle) resource); - DisposeCIcon((CIconHandle) resource); + RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF}; + short id; + ResType theType; + Str255 dummy; + + /* + * We need to first paint the background white. Also, for + * some reason we *must* use GetCIcon instead of GetNamedResource + * for PlotCIcon to work - so we use GetResInfo to get the id. + */ + + RGBForeColor(&white); + PaintRect(&destRect); + GetResInfo(resource, &id, &theType, dummy); + ReleaseResource(resource); + resource = (Handle) GetCIcon(id); + PlotCIcon(&destRect, (CIconHandle) resource); + DisposeCIcon((CIconHandle) resource); } - + *width = 32; *height = 32; - SetGWorld(saveWorld, saveDevice); + if (portChanged) { + QDSwapPort(savePort, NULL); + } return pix; } diff --git a/macosx/tkMacOSXButton.c b/macosx/tkMacOSXButton.c index 84addc5..dadf6cb 100644 --- a/macosx/tkMacOSXButton.c +++ b/macosx/tkMacOSXButton.c @@ -1,16 +1,17 @@ -/* +/* * tkMacOSXButton.c -- * - * This file implements the Macintosh specific portion of the - * button widgets. + * This file implements the Macintosh specific portion of the + * button widgets. * * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.22 2007/04/21 19:06:37 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXButton.c,v 1.23 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" @@ -23,6 +24,7 @@ /* * Default insets for controls */ + #define DEF_INSET_LEFT 2 #define DEF_INSET_RIGHT 2 #define DEF_INSET_TOP 2 @@ -37,7 +39,7 @@ #define DRAW_CUSTOM 2 /* Make our own button drawing. */ #define DRAW_BEVEL 3 -/* +/* * Declaration of Mac specific button structure. */ @@ -46,43 +48,42 @@ typedef struct { SInt16 minValue; SInt16 maxValue; SInt16 procID; - int isBevel; + int isBevel; } MacControlParams; typedef struct { int drawType; Tk_3DBorder border; int relief; - int offset; /* 0 means this is a normal widget. 1 means + int offset; /* 0 means this is a normal widget. 1 means * it is an image button, so we offset the * image to make the button appear to move * up and down as the relief changes. */ - GC gc; + GC gc; int hasImageOrBitmap; } DrawParams; - typedef struct { - TkButton info; /* generic button info */ - int id; - int usingControl; - int useTkText; - int flags; /* initialisation status */ - MacControlParams params; - WindowRef windowRef; - RGBColor userPaneBackground; - ControlRef userPane; /* Carbon control */ - ControlRef control; /* Carbon control */ - Str255 controlTitle; - ControlFontStyleRec fontStyle; - /* - * the following are used to store the image content for - * beveled buttons - i.e. buttons with images. + TkButton info; /* Generic button info */ + int id; + int usingControl; + int useTkText; + int flags; /* Initialisation status */ + MacControlParams params; + WindowRef windowRef; + unsigned long userPaneBackground; + ControlRef userPane; /* Carbon control */ + ControlRef control; /* Carbon control */ + Str255 controlTitle; + ControlFontStyleRec fontStyle; + /* + * The following are used to store the image content for + * beveled buttons, i.e. buttons with images. */ - CCTabHandle tabHandle; + CCTabHandle tabHandle; + Pixmap picPixmap; ControlButtonContentInfo bevelButtonContent; - OpenCPicParams picParams; - Pixmap picPixmap; + OpenCPicParams picParams; } MacButton; /* @@ -90,31 +91,31 @@ typedef struct { */ -static OSErr SetUserPaneDrawProc(ControlRef control, - ControlUserPaneDrawProcPtr upp); -static OSErr SetUserPaneSetUpSpecialBackgroundProc(ControlRef control, - ControlUserPaneBackgroundProcPtr upp); +static OSStatus SetUserPaneDrawProc(ControlRef control, + ControlUserPaneDrawProcPtr upp); +static OSStatus SetUserPaneSetUpSpecialBackgroundProc(ControlRef control, + ControlUserPaneBackgroundProcPtr upp); static void UserPaneDraw(ControlRef control, ControlPartCode cpc); static void UserPaneBackgroundProc(ControlHandle, - ControlBackgroundPtr info); - -static void ButtonEventProc _ANSI_ARGS_(( ClientData clientData, XEvent *eventPtr)); -static int UpdateControlColors _ANSI_ARGS_((MacButton *mbPtr )); -static void TkMacOSXComputeControlParams _ANSI_ARGS_((TkButton * butPtr, MacControlParams * paramsPtr)); -static int TkMacOSXComputeDrawParams _ANSI_ARGS_((TkButton * butPtr, DrawParams * dpPtr)); -static void TkMacOSXDrawControl _ANSI_ARGS_((MacButton *butPtr, - GWorldPtr destPort, GC gc, Pixmap pixmap)); -static void SetupBevelButton _ANSI_ARGS_((MacButton *butPtr, - ControlRef controlHandle, - GWorldPtr destPort, GC gc, Pixmap pixmap)); + ControlBackgroundPtr info); + +static void ButtonEventProc(ClientData clientData, XEvent *eventPtr); +static int UpdateControlColors(MacButton *mbPtr); +static void TkMacOSXComputeControlParams(TkButton *butPtr, + MacControlParams *paramsPtr); +static int TkMacOSXComputeDrawParams(TkButton *butPtr, DrawParams *dpPtr); +static void TkMacOSXDrawControl(MacButton *butPtr, GWorldPtr destPort, GC gc, + Pixmap pixmap); +static void SetupBevelButton(MacButton *butPtr, ControlRef controlHandle, + GWorldPtr destPort, GC gc, Pixmap pixmap); /* * The class procedure table for the button widgets. */ -Tk_ClassProcs tkpButtonProcs = { - sizeof(Tk_ClassProcs), /* size */ - TkButtonWorldChanged, /* worldChangedProc */ +Tk_ClassProcs tkpButtonProcs = { + sizeof(Tk_ClassProcs), /* size */ + TkButtonWorldChanged, /* worldChangedProc */ }; static int bCount; @@ -126,13 +127,13 @@ int tkPictureIsOpen; * * TkpCreateButton -- * - * Allocate a new TkButton structure. + * Allocate a new TkButton structure. * * Results: - * Returns a newly allocated TkButton structure. + * Returns a newly allocated TkButton structure. * * Side effects: - * Registers an event handler for the widget. + * Registers an event handler for the widget. * *---------------------------------------------------------------------- */ @@ -141,16 +142,14 @@ TkButton * TkpCreateButton( Tk_Window tkwin) { - MacButton *macButtonPtr; - macButtonPtr = (MacButton *) ckalloc(sizeof(MacButton)); + MacButton *macButtonPtr = (MacButton *) ckalloc(sizeof(MacButton)); + Tk_CreateEventHandler(tkwin, ActivateMask, - ButtonEventProc, (ClientData) macButtonPtr); + ButtonEventProc, (ClientData) macButtonPtr); macButtonPtr->id = bCount++; macButtonPtr->usingControl = 0; macButtonPtr->flags = 0; - macButtonPtr->userPaneBackground.red = 0; - macButtonPtr->userPaneBackground.green = 0; - macButtonPtr->userPaneBackground.blue = ~0; + macButtonPtr->userPaneBackground = PIXEL_MAGIC << 24; macButtonPtr->userPane = NULL; macButtonPtr->control = NULL; macButtonPtr->controlTitle[0] = 0; @@ -165,6 +164,7 @@ TkpCreateButton( macButtonPtr->bevelButtonContent.contentType = kControlContentPictHandle; bzero(&macButtonPtr->params, sizeof(macButtonPtr->params)); bzero(&macButtonPtr->fontStyle,sizeof(macButtonPtr->fontStyle)); + return (TkButton *)macButtonPtr; } @@ -173,309 +173,300 @@ TkpCreateButton( * * TkpDisplayButton -- * - * This procedure is invoked to display a button widget. It is - * normally invoked as an idle handler. + * This procedure is invoked to display a button widget. It is + * normally invoked as an idle handler. * * Results: - * None. + * None. * * Side effects: - * Commands are output to X to display the button in its - * current mode. The REDRAW_PENDING flag is cleared. + * Commands are output to X to display the button in its + * current mode. The REDRAW_PENDING flag is cleared. * *---------------------------------------------------------------------- */ void TkpDisplayButton( - ClientData clientData) /* Information about widget. */ + ClientData clientData) /* Information about widget. */ { MacButton *macButtonPtr = (MacButton *)clientData; - TkButton *butPtr = (TkButton *) clientData; - Tk_Window tkwin = butPtr->tkwin; - int width, height, fullWidth, fullHeight; - int textXOffset, textYOffset; - int haveImage = 0, haveText = 0; - GWorldPtr destPort; - int borderWidth; + TkButton *butPtr = (TkButton *) clientData; + Tk_Window tkwin = butPtr->tkwin; + CGrafPtr destPort, savePort; + Boolean portChanged; Pixmap pixmap; - int wasUsingControl; - int imageWidth = 0, imageHeight = 0; + int width, height, fullWidth, fullHeight, textXOffset, textYOffset; + int borderWidth, wasUsingControl; + int haveImage = 0, haveText = 0, imageWidth = 0, imageHeight = 0; int imageXOffset = 0, imageYOffset = 0; /* image information that will * be used to restrict disabled * pixmap as well */ - DrawParams drawParams, * dpPtr = &drawParams; + DrawParams drawParams, *dpPtr = &drawParams; butPtr->flags &= ~REDRAW_PENDING; if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { - return; + return; } pixmap = (Pixmap) Tk_WindowId(tkwin); wasUsingControl = macButtonPtr->usingControl; if (TkMacOSXComputeDrawParams(butPtr, &drawParams) ) { - macButtonPtr->usingControl = 1; - if (butPtr->type == TYPE_BUTTON) { - macButtonPtr->useTkText = 0; - } else { - macButtonPtr->useTkText = 1; - } + macButtonPtr->usingControl = 1; + if (butPtr->type == TYPE_BUTTON) { + macButtonPtr->useTkText = 0; + } else { + macButtonPtr->useTkText = 1; + } } else { - macButtonPtr->usingControl = 0; - macButtonPtr->useTkText = 1; + macButtonPtr->usingControl = 0; + macButtonPtr->useTkText = 1; } - - /* - * set up clipping region. Make sure the we are using the port - * for this button, or we will set the wrong window's clip. + + /* + * Set up clipping region. Make sure the we are using the port + * for this button, or we will set the wrong window's clip. */ - + destPort = TkMacOSXGetDrawablePort(pixmap); - SetGWorld(destPort, NULL); + portChanged = QDSwapPort(destPort, &savePort); TkMacOSXSetUpClippingRgn(pixmap); - /* - * See the comment in UpdateControlColors as to why we use the + * See the comment in UpdateControlColors as to why we use the * highlightbackground for the border of Macintosh buttons. */ if (macButtonPtr->useTkText) { - if (butPtr->type == TYPE_BUTTON) { - Tk_Fill3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0, 0, - Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT); - } else { - Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0, - Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT); - } + if (butPtr->type == TYPE_BUTTON) { + Tk_Fill3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0, 0, + Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT); + } else { + Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0, + Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT); + } } /* * Draw the native portion of the buttons. Start by creating the control - * if it doesn't already exist. Then configure the Macintosh control from - * the Tk info. Finally, we call Draw1Control to draw to the screen. + * if it doesn't already exist. Then configure the Macintosh control from + * the Tk info. Finally, we call Draw1Control to draw to the screen. */ if (macButtonPtr->usingControl) { - borderWidth = 0; - TkMacOSXDrawControl(macButtonPtr, destPort, dpPtr->gc, pixmap); - } else { - if (wasUsingControl && macButtonPtr->userPane) { - DisposeControl(macButtonPtr->userPane); - macButtonPtr->userPane = NULL; - macButtonPtr->control = NULL; - macButtonPtr->flags = 0; - } + borderWidth = 0; + TkMacOSXDrawControl(macButtonPtr, destPort, dpPtr->gc, pixmap); + } else if (wasUsingControl && macButtonPtr->userPane) { + DisposeControl(macButtonPtr->userPane); + macButtonPtr->userPane = NULL; + macButtonPtr->control = NULL; + macButtonPtr->flags = 0; } if ((dpPtr->drawType == DRAW_CUSTOM) || (dpPtr->drawType == DRAW_LABEL)) { - borderWidth = butPtr->borderWidth; + borderWidth = butPtr->borderWidth; } /* - * Display image or bitmap or text for button. This has + * Display image or bitmap or text for button. This has * already been done under Appearance with the Bevel * button types. */ if (dpPtr->drawType == DRAW_BEVEL) { - /* Empty Body */ - } else { - if (butPtr->image != None) { - Tk_SizeOfImage(butPtr->image, &width, &height); - haveImage = 1; - } else if (butPtr->bitmap != None) { - Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); - haveImage = 1; - } - imageWidth = width; - imageHeight = height; - - haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0); - if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) { - int x; - int y; - textXOffset = 0; - textYOffset = 0; - fullWidth = 0; - fullHeight = 0; - - switch ((enum compound) butPtr->compound) { - case COMPOUND_TOP: - case COMPOUND_BOTTOM: { - /* Image is above or below text */ - if (butPtr->compound == COMPOUND_TOP) { - textYOffset = height + butPtr->padY; - } else { - imageYOffset = butPtr->textHeight + butPtr->padY; - } - fullHeight = height + butPtr->textHeight + butPtr->padY; - fullWidth = (width > butPtr->textWidth ? width : - butPtr->textWidth); - textXOffset = (fullWidth - butPtr->textWidth)/2; - imageXOffset = (fullWidth - width)/2; - break; - } - case COMPOUND_LEFT: - case COMPOUND_RIGHT: { - /* - * Image is left or right of text - */ - - if (butPtr->compound == COMPOUND_LEFT) { - textXOffset = width + butPtr->padX; - } else { - imageXOffset = butPtr->textWidth + butPtr->padX; - } - fullWidth = butPtr->textWidth + butPtr->padX + width; - fullHeight = (height > butPtr->textHeight ? height : - butPtr->textHeight); - textYOffset = (fullHeight - butPtr->textHeight)/2; - imageYOffset = (fullHeight - height)/2; - break; - } - case COMPOUND_CENTER: { - /* - * Image and text are superimposed - */ - - fullWidth = (width > butPtr->textWidth ? width : - butPtr->textWidth); - fullHeight = (height > butPtr->textHeight ? height : - butPtr->textHeight); - textXOffset = (fullWidth - butPtr->textWidth)/2; - imageXOffset = (fullWidth - width)/2; - textYOffset = (fullHeight - butPtr->textHeight)/2; - imageYOffset = (fullHeight - height)/2; - break; - } - case COMPOUND_NONE: {break;} - } - - TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY, - butPtr->indicatorSpace + fullWidth, fullHeight, &x, &y); - - x += butPtr->indicatorSpace; - - x += dpPtr->offset; - y += dpPtr->offset; - if (dpPtr->relief == TK_RELIEF_RAISED) { - x -= dpPtr->offset; - y -= dpPtr->offset; - } else if (dpPtr->relief == TK_RELIEF_SUNKEN) { - x += dpPtr->offset; - y += dpPtr->offset; - } - imageXOffset += x; - imageYOffset += y; - if (butPtr->image != NULL) { - if ((butPtr->selectImage != NULL) && - (butPtr->flags & SELECTED)) { - Tk_RedrawImage(butPtr->selectImage, 0, 0, - width, height, pixmap, imageXOffset, imageYOffset); - } else if ((butPtr->tristateImage != NULL) && - (butPtr->flags & TRISTATED)) { - Tk_RedrawImage(butPtr->tristateImage, 0, 0, - width, height, pixmap, imageXOffset, imageYOffset); - } else { - Tk_RedrawImage(butPtr->image, 0, 0, width, - height, pixmap, imageXOffset, imageYOffset); - } - } else { - XSetClipOrigin(butPtr->display, dpPtr->gc, - imageXOffset, imageYOffset); - XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc, - 0, 0, (unsigned int) width, (unsigned int) height, - imageXOffset, imageYOffset, 1); - XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0); - } - - if (macButtonPtr->useTkText) { - Tk_DrawTextLayout(butPtr->display, pixmap, - dpPtr->gc, butPtr->textLayout, - x + textXOffset, y + textYOffset, 0, -1); - Tk_UnderlineTextLayout(butPtr->display, pixmap, dpPtr->gc, - butPtr->textLayout, - x + textXOffset, y + textYOffset, - butPtr->underline); - } - y += fullHeight/2; - } else { - if (haveImage) { - int x = 0; - int y; - - TkComputeAnchor(butPtr->anchor, tkwin, 0, 0, - butPtr->indicatorSpace + width, height, &x, &y); - x += butPtr->indicatorSpace; - - x += dpPtr->offset; - y += dpPtr->offset; - if (dpPtr->relief == TK_RELIEF_RAISED) { - x -= dpPtr->offset; - y -= dpPtr->offset; - } else if (dpPtr->relief == TK_RELIEF_SUNKEN) { - x += dpPtr->offset; - y += dpPtr->offset; - } - imageXOffset += x; - imageYOffset += y; - if (butPtr->image != NULL) { - if ((butPtr->selectImage != NULL) && - (butPtr->flags & SELECTED)) { - Tk_RedrawImage(butPtr->selectImage, 0, 0, width, - height, pixmap, imageXOffset, imageYOffset); - } else if ((butPtr->tristateImage != NULL) && - (butPtr->flags & TRISTATED)) { - Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, - height, pixmap, imageXOffset, imageYOffset); - } else { - Tk_RedrawImage(butPtr->image, 0, 0, width, height, - pixmap, imageXOffset, imageYOffset); - } - } else { - XSetClipOrigin(butPtr->display, dpPtr->gc, x, y); - XCopyPlane(butPtr->display, butPtr->bitmap, - pixmap, dpPtr->gc, - 0, 0, (unsigned int) width, - (unsigned int) height, x, y, 1); - XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0); - } - y += height/2; - } else if (macButtonPtr->useTkText) { - int x = 0; - int y; - TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, - butPtr->padY, - butPtr->indicatorSpace + butPtr->textWidth, - butPtr->textHeight, &x, &y); - x += butPtr->indicatorSpace; - Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc, - butPtr->textLayout, x, y, 0, -1); - } - } + goto applyStipple; + } + + if (butPtr->image != None) { + Tk_SizeOfImage(butPtr->image, &width, &height); + haveImage = 1; + } else if (butPtr->bitmap != None) { + Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); + haveImage = 1; + } + imageWidth = width; + imageHeight = height; + + haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0); + if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) { + int x, y; + + textXOffset = 0; + textYOffset = 0; + fullWidth = 0; + fullHeight = 0; + + switch ((enum compound) butPtr->compound) { + case COMPOUND_TOP: + case COMPOUND_BOTTOM: + /* + * Image is above or below text. + */ + if (butPtr->compound == COMPOUND_TOP) { + textYOffset = height + butPtr->padY; + } else { + imageYOffset = butPtr->textHeight + butPtr->padY; + } + fullHeight = height + butPtr->textHeight + butPtr->padY; + fullWidth = (width > butPtr->textWidth ? width : + butPtr->textWidth); + textXOffset = (fullWidth - butPtr->textWidth)/2; + imageXOffset = (fullWidth - width)/2; + break; + + case COMPOUND_LEFT: + case COMPOUND_RIGHT: + /* + * Image is left or right of text. + */ + + if (butPtr->compound == COMPOUND_LEFT) { + textXOffset = width + butPtr->padX; + } else { + imageXOffset = butPtr->textWidth + butPtr->padX; + } + fullWidth = butPtr->textWidth + butPtr->padX + width; + fullHeight = (height > butPtr->textHeight ? height : + butPtr->textHeight); + textYOffset = (fullHeight - butPtr->textHeight)/2; + imageYOffset = (fullHeight - height)/2; + break; + + case COMPOUND_CENTER: + /* + * Image and text are superimposed. + */ + + fullWidth = (width > butPtr->textWidth ? width : + butPtr->textWidth); + fullHeight = (height > butPtr->textHeight ? height : + butPtr->textHeight); + textXOffset = (fullWidth - butPtr->textWidth)/2; + imageXOffset = (fullWidth - width)/2; + textYOffset = (fullHeight - butPtr->textHeight)/2; + imageYOffset = (fullHeight - height)/2; + break; + + case COMPOUND_NONE: + break; + } + + TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY, + butPtr->indicatorSpace + fullWidth, fullHeight, &x, &y); + + x += butPtr->indicatorSpace; + + x += dpPtr->offset; + y += dpPtr->offset; + if (dpPtr->relief == TK_RELIEF_RAISED) { + x -= dpPtr->offset; + y -= dpPtr->offset; + } else if (dpPtr->relief == TK_RELIEF_SUNKEN) { + x += dpPtr->offset; + y += dpPtr->offset; + } + imageXOffset += x; + imageYOffset += y; + if (butPtr->image != NULL) { + if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) { + Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, + pixmap, imageXOffset, imageYOffset); + } else if ((butPtr->tristateImage != NULL) && + (butPtr->flags & TRISTATED)) { + Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height, + pixmap, imageXOffset, imageYOffset); + } else { + Tk_RedrawImage(butPtr->image, 0, 0, width, height, + pixmap, imageXOffset, imageYOffset); + } + } else { + XSetClipOrigin(butPtr->display, dpPtr->gc, imageXOffset, + imageYOffset); + XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc, + 0, 0, width, height, imageXOffset, imageYOffset, 1); + XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0); + } + + if (macButtonPtr->useTkText) { + Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc, + butPtr->textLayout, x + textXOffset, y + textYOffset, 0, + -1); + Tk_UnderlineTextLayout(butPtr->display, pixmap, dpPtr->gc, + butPtr->textLayout, x + textXOffset, y + textYOffset, + butPtr->underline); + } + y += fullHeight/2; + } else if (haveImage) { + int x = 0, y; + + TkComputeAnchor(butPtr->anchor, tkwin, 0, 0, + butPtr->indicatorSpace + width, height, &x, &y); + x += butPtr->indicatorSpace; + + x += dpPtr->offset; + y += dpPtr->offset; + if (dpPtr->relief == TK_RELIEF_RAISED) { + x -= dpPtr->offset; + y -= dpPtr->offset; + } else if (dpPtr->relief == TK_RELIEF_SUNKEN) { + x += dpPtr->offset; + y += dpPtr->offset; + } + imageXOffset += x; + imageYOffset += y; + if (butPtr->image != NULL) { + if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) { + Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, + pixmap, imageXOffset, imageYOffset); + } else if ((butPtr->tristateImage != NULL) && + (butPtr->flags & TRISTATED)) { + Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height, + pixmap, imageXOffset, imageYOffset); + } else { + Tk_RedrawImage(butPtr->image, 0, 0, width, height, + pixmap, imageXOffset, imageYOffset); + } + } else { + XSetClipOrigin(butPtr->display, dpPtr->gc, x, y); + XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc, + 0, 0, width, height, x, y, 1); + XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0); + } + y += height/2; + } else if (macButtonPtr->useTkText) { + int x = 0, y; + + TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY, + butPtr->indicatorSpace + butPtr->textWidth, + butPtr->textHeight, &x, &y); + x += butPtr->indicatorSpace; + Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc, + butPtr->textLayout, x, y, 0, -1); } /* * If the button is disabled with a stipple rather than a special - * foreground color, generate the stippled effect. If the widget + * foreground color, generate the stippled effect. If the widget * is selected and we use a different background color when selected, * must temporarily modify the GC so the stippling is the right color. */ + applyStipple: if (macButtonPtr->useTkText) { - if ((butPtr->state == STATE_DISABLED) - && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) { - if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn + if ((butPtr->state == STATE_DISABLED) + && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) { + if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn && (butPtr->selectBorder != NULL)) { - XSetForeground(butPtr->display, butPtr->stippleGC, + XSetForeground(butPtr->display, butPtr->stippleGC, Tk_3DBorderColor(butPtr->selectBorder)->pixel); - } + } + /* * Stipple the whole button if no disabledFg was specified, * otherwise restrict stippling only to displayed image */ + if (butPtr->disabledFg == NULL) { XFillRectangle(butPtr->display, pixmap, butPtr->stippleGC, 0, 0, (unsigned) Tk_Width(tkwin), @@ -485,24 +476,28 @@ TkpDisplayButton( imageXOffset, imageYOffset, (unsigned) imageWidth, (unsigned) imageHeight); } - if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn + if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn && (butPtr->selectBorder != NULL)) { XSetForeground(butPtr->display, butPtr->stippleGC, Tk_3DBorderColor(butPtr->normalBorder)->pixel); } - } - - /* - * Draw the border and traversal highlight last. This way, if the - * button's contents overflow they'll be covered up by the border. - */ - - if (dpPtr->relief != TK_RELIEF_FLAT) { - int inset = butPtr->highlightWidth; - Tk_Draw3DRectangle(tkwin, pixmap, dpPtr->border, inset, inset, - Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset, - butPtr->borderWidth, dpPtr->relief); - } + } + + /* + * Draw the border and traversal highlight last. This way, if the + * button's contents overflow they'll be covered up by the border. + */ + + if (dpPtr->relief != TK_RELIEF_FLAT) { + int inset = butPtr->highlightWidth; + + Tk_Draw3DRectangle(tkwin, pixmap, dpPtr->border, inset, inset, + Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset, + butPtr->borderWidth, dpPtr->relief); + } + } + if (portChanged) { + QDSwapPort(savePort, NULL); } } @@ -511,60 +506,58 @@ TkpDisplayButton( * * TkpComputeButtonGeometry -- * - * After changes in a button's text or bitmap, this procedure - * recomputes the button's geometry and passes this information - * along to the geometry manager for the window. + * After changes in a button's text or bitmap, this procedure + * recomputes the button's geometry and passes this information + * along to the geometry manager for the window. * * Results: - * None. + * None. * * Side effects: - * The button's window may change size. + * The button's window may change size. * *---------------------------------------------------------------------- */ void TkpComputeButtonGeometry( - TkButton *butPtr) /* Button whose geometry may have changed. */ + TkButton *butPtr) /* Button whose geometry may have changed. */ { int width, height, avgWidth, haveImage = 0, haveText = 0; - int xInset, yInset; - int txtWidth, txtHeight; + int xInset, yInset, txtWidth, txtHeight; Tk_FontMetrics fm; DrawParams drawParams; /* * First figure out the size of the contents of the button. */ - + width = 0; height = 0; txtWidth = 0; txtHeight = 0; avgWidth = 0; - butPtr->indicatorSpace = 0; if (butPtr->image != NULL) { - Tk_SizeOfImage(butPtr->image, &width, &height); - haveImage = 1; + Tk_SizeOfImage(butPtr->image, &width, &height); + haveImage = 1; } else if (butPtr->bitmap != None) { - Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); - haveImage = 1; + Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); + haveImage = 1; } if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) { - Tk_FreeTextLayout(butPtr->textLayout); - butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont, - Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength, - butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight); - - txtWidth = butPtr->textWidth; - txtHeight = butPtr->textHeight; - avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1); - Tk_GetFontMetrics(butPtr->tkfont, &fm); - haveText = (txtWidth != 0 && txtHeight != 0); + Tk_FreeTextLayout(butPtr->textLayout); + butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont, + Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength, + butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight); + + txtWidth = butPtr->textWidth; + txtHeight = butPtr->textHeight; + avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1); + Tk_GetFontMetrics(butPtr->tkfont, &fm); + haveText = (txtWidth != 0 && txtHeight != 0); } /* @@ -575,172 +568,166 @@ TkpComputeButtonGeometry( */ if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) { - switch ((enum compound) butPtr->compound) { - case COMPOUND_TOP: - case COMPOUND_BOTTOM: { - /* - * Image is above or below text - */ - - height += txtHeight + butPtr->padY; - width = (width > txtWidth ? width : txtWidth); - break; - } - case COMPOUND_LEFT: - case COMPOUND_RIGHT: { - /* - * Image is left or right of text - */ - - width += txtWidth + butPtr->padX; - height = (height > txtHeight ? height : txtHeight); - break; - } - case COMPOUND_CENTER: { - /* - * Image and text are superimposed - */ - - width = (width > txtWidth ? width : txtWidth); - height = (height > txtHeight ? height : txtHeight); - break; - } - case COMPOUND_NONE: {break;} - } - if (butPtr->width > 0) { - width = butPtr->width; - } - if (butPtr->height > 0) { - height = butPtr->height; - } - - if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) { - butPtr->indicatorSpace = height; - if (butPtr->type == TYPE_CHECK_BUTTON) { - butPtr->indicatorDiameter = (65 * height)/100; - } else { - butPtr->indicatorDiameter = (75 * height)/100; - } - } - - width += 2 * butPtr->padX; - height += 2 * butPtr->padY; + switch ((enum compound) butPtr->compound) { + case COMPOUND_TOP: + case COMPOUND_BOTTOM: + /* + * Image is above or below text. + */ + + height += txtHeight + butPtr->padY; + width = (width > txtWidth ? width : txtWidth); + break; + case COMPOUND_LEFT: + case COMPOUND_RIGHT: + /* + * Image is left or right of text. + */ + + width += txtWidth + butPtr->padX; + height = (height > txtHeight ? height : txtHeight); + break; + case COMPOUND_CENTER: + /* + * Image and text are superimposed. + */ + + width = (width > txtWidth ? width : txtWidth); + height = (height > txtHeight ? height : txtHeight); + break; + case COMPOUND_NONE: + break; + } + if (butPtr->width > 0) { + width = butPtr->width; + } + if (butPtr->height > 0) { + height = butPtr->height; + } + if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) { + butPtr->indicatorSpace = height; + if (butPtr->type == TYPE_CHECK_BUTTON) { + butPtr->indicatorDiameter = (65 * height)/100; + } else { + butPtr->indicatorDiameter = (75 * height)/100; + } + } + + width += 2 * butPtr->padX; + height += 2 * butPtr->padY; + } else if (haveImage) { + if (butPtr->width > 0) { + width = butPtr->width; + } + if (butPtr->height > 0) { + height = butPtr->height; + } + if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) { + butPtr->indicatorSpace = height; + if (butPtr->type == TYPE_CHECK_BUTTON) { + butPtr->indicatorDiameter = (65 * height)/100; + } else { + butPtr->indicatorDiameter = (75 * height)/100; + } + } } else { - if (haveImage) { - if (butPtr->width > 0) { - width = butPtr->width; - } - if (butPtr->height > 0) { - height = butPtr->height; - } - if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) { - butPtr->indicatorSpace = height; - if (butPtr->type == TYPE_CHECK_BUTTON) { - butPtr->indicatorDiameter = (65 * height)/100; - } else { - butPtr->indicatorDiameter = (75 * height)/100; - } - } - } else { - width = txtWidth; - height = txtHeight; - if (butPtr->width > 0) { - width = butPtr->width * avgWidth; - } - if (butPtr->height > 0) { - height = butPtr->height * fm.linespace; - } - if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) { - butPtr->indicatorDiameter = fm.linespace; - if (butPtr->type == TYPE_CHECK_BUTTON) { - butPtr->indicatorDiameter = - (80 * butPtr->indicatorDiameter)/100; - } - butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth; - } - } + width = txtWidth; + height = txtHeight; + if (butPtr->width > 0) { + width = butPtr->width * avgWidth; + } + if (butPtr->height > 0) { + height = butPtr->height * fm.linespace; + } + if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) { + butPtr->indicatorDiameter = fm.linespace; + if (butPtr->type == TYPE_CHECK_BUTTON) { + butPtr->indicatorDiameter = + (80 * butPtr->indicatorDiameter)/100; + } + butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth; + } } /* * Now figure out the size of the border decorations for the button. */ - + if (butPtr->highlightWidth < 0) { - butPtr->highlightWidth = 0; + butPtr->highlightWidth = 0; } - + /* - * The width and height calculation for Appearance buttons with images & - * non-Appearance buttons with images is different. In the latter case, + * The width and height calculation for Appearance buttons with images & + * non-Appearance buttons with images is different. In the latter case, * we add the borderwidth to the inset, since we are going to stamp a - * 3-D border over the image. In the former, we add it to the height, + * 3-D border over the image. In the former, we add it to the height, * directly, since Appearance will draw the border as part of our control. * * When issuing the geometry request, add extra space for the indicator, - * if any, and for the border and padding, plus if this is an image two + * if any, and for the border and padding, plus if this is an image two * extra pixels so the display can be offset by 1 pixel in either * direction for the raised or lowered effect. * * The highlight width corresponds to the default ring on the Macintosh. * As such, the highlight width is only added if the button is the default - * button. The actual width of the default ring is one less than the + * button. The actual width of the default ring is one less than the * highlight width as there is also one pixel of spacing. - * Appearance buttons with images do not have a highlight ring, because the + * Appearance buttons with images do not have a highlight ring, because the * Bevel button type does not support one. */ if ((butPtr->image == None) && (butPtr->bitmap == None)) { - width += 2*butPtr->padX; - height += 2*butPtr->padY; + width += 2*butPtr->padX; + height += 2*butPtr->padY; } - + if ((butPtr->type == TYPE_BUTTON)) { - if ((butPtr->image == None) && (butPtr->bitmap == None)) { - butPtr->inset = 0; - if (butPtr->defaultState != STATE_DISABLED) { - butPtr->inset += butPtr->highlightWidth; - } - } else { - butPtr->inset = 0; - width += (2 * butPtr->borderWidth + 4); - height += (2 * butPtr->borderWidth + 4); - } - } else if ((butPtr->type != TYPE_LABEL)) { - if (butPtr->indicatorOn) { - butPtr->inset = 0; - } else { - /* - * Under Appearance, the Checkbutton or radiobutton with an image - * is represented by a BevelButton with the Sticky defProc... - * So we must set its height in the same way as the Button - * with an image or bitmap. - */ - - if ( (butPtr->image != None) || (butPtr->bitmap != None)) { - int border; - butPtr->inset = 0; - if ( butPtr->borderWidth <= 2 ) { - border = 6; - } else { - border = 2 * butPtr->borderWidth + 2; - } - width += border; - height += border; - } else { - butPtr->inset = butPtr->borderWidth; - } - } + if ((butPtr->image == None) && (butPtr->bitmap == None)) { + butPtr->inset = 0; + if (butPtr->defaultState != STATE_DISABLED) { + butPtr->inset += butPtr->highlightWidth; + } + } else { + butPtr->inset = 0; + width += (2 * butPtr->borderWidth + 4); + height += (2 * butPtr->borderWidth + 4); + } + } else if (butPtr->type == TYPE_LABEL) { + butPtr->inset = butPtr->borderWidth; + } else if (butPtr->indicatorOn) { + butPtr->inset = 0; } else { - butPtr->inset = butPtr->borderWidth; + /* + * Under Appearance, the Checkbutton or radiobutton with an image + * is represented by a BevelButton with the Sticky defProc... + * So we must set its height in the same way as the Button + * with an image or bitmap. + */ + + if (butPtr->image != None || butPtr->bitmap != None) { + int border; + + butPtr->inset = 0; + if (butPtr->borderWidth <= 2) { + border = 6; + } else { + border = 2 * butPtr->borderWidth + 2; + } + width += border; + height += border; + } else { + butPtr->inset = butPtr->borderWidth; + } } if (TkMacOSXComputeDrawParams(butPtr,&drawParams)) { - xInset = butPtr->indicatorSpace + DEF_INSET_LEFT + DEF_INSET_RIGHT; - yInset = DEF_INSET_TOP + DEF_INSET_BOTTOM; + xInset = butPtr->indicatorSpace + DEF_INSET_LEFT + DEF_INSET_RIGHT; + yInset = DEF_INSET_TOP + DEF_INSET_BOTTOM; } else { - xInset = butPtr->indicatorSpace+butPtr->inset*2; - yInset = butPtr->inset*2; + xInset = butPtr->indicatorSpace+butPtr->inset*2; + yInset = butPtr->inset*2; } Tk_GeometryRequest(butPtr->tkwin, width + xInset, height + yInset); Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset); @@ -751,13 +738,13 @@ TkpComputeButtonGeometry( * * TkpDestroyButton -- * - * Free data structures associated with the button control. + * Free data structures associated with the button control. * * Results: - * None. + * None. * * Side effects: - * Restores the default control state. + * Restores the default control state. * *---------------------------------------------------------------------- */ @@ -766,10 +753,11 @@ void TkpDestroyButton( TkButton *butPtr) { - MacButton *mbPtr = ( MacButton *) butPtr; /* Mac button. */ + MacButton *mbPtr = (MacButton *) butPtr; /* Mac button. */ + if (mbPtr->userPane) { - DisposeControl(mbPtr->userPane); - mbPtr->userPane = NULL; + DisposeControl(mbPtr->userPane); + mbPtr->userPane = NULL; } } @@ -778,246 +766,214 @@ TkpDestroyButton( * * TkMacOSXInitControl -- * - * This procedure initialises a Carbon control + * This procedure initialises a Carbon control. * * Results: - * 0 on success, 1 on failure. + * 0 on success, 1 on failure. * * Side effects: - * A background pane control and the control itself is created - * The contol is embedded in the background control - * The background control is embedded in the root control - * of the containing window - * The creation parameters for the control are also computed + * A background pane control and the control itself is created + * The contol is embedded in the background control + * The background control is embedded in the root control + * of the containing window + * The creation parameters for the control are also computed * *---------------------------------------------------------------------- */ static int -TkMacOSXInitControl ( - MacButton *mbPtr, /* Mac button. */ - GWorldPtr destPort, - GC gc, - Pixmap pixmap, - Rect *paneRect, - Rect *cntrRect -) +TkMacOSXInitControl( + MacButton *mbPtr, /* Mac button. */ + GWorldPtr destPort, + GC gc, + Pixmap pixmap, + Rect *paneRect, + Rect *cntrRect) { - OSErr status; - TkButton * butPtr = ( TkButton * )mbPtr; + TkButton *butPtr = (TkButton *) mbPtr; ControlRef rootControl; - SInt16 procID; - Boolean initiallyVisible; - SInt16 initialValue; - SInt16 minValue; - SInt16 maxValue; - SInt32 controlReference; + SInt16 procID, initialValue, minValue, maxValue; + Boolean initiallyVisible; + SInt32 controlReference; rootControl = TkMacOSXGetRootControl(Tk_WindowId(butPtr->tkwin)); - mbPtr->windowRef - = GetWindowFromPort(TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin))); + mbPtr->windowRef = GetWindowFromPort( + TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin))); - /* - * Set up the user pane + /* + * Set up the user pane. */ initiallyVisible = false; - initialValue = kControlSupportsEmbedding|kControlHasSpecialBackground; - minValue = 0; - maxValue = 1; - procID = kControlUserPaneProc; + initialValue = kControlSupportsEmbedding|kControlHasSpecialBackground; + minValue = 0; + maxValue = 1; + procID = kControlUserPaneProc; controlReference = (SInt32)mbPtr; - mbPtr->userPane = NewControl(mbPtr->windowRef, - paneRect, "\p", - initiallyVisible, - initialValue, - minValue, - maxValue, - procID, - controlReference ); - + mbPtr->userPane = NewControl(mbPtr->windowRef, paneRect, "\p", + initiallyVisible, initialValue, minValue, maxValue, procID, + controlReference); + if (!mbPtr->userPane) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"Failed to create user pane control\n"); -#endif - return 1; + TkMacOSXDbgMsg("Failed to create user pane control"); + return 1; } - - if ((status = EmbedControl(mbPtr->userPane,rootControl)) != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"Failed to embed user pane control %d\n", status); -#endif - return 1; + if (ChkErr(EmbedControl, mbPtr->userPane,rootControl) != noErr) { + return 1; } - + SetUserPaneSetUpSpecialBackgroundProc(mbPtr->userPane, - UserPaneBackgroundProc); + UserPaneBackgroundProc); SetUserPaneDrawProc(mbPtr->userPane,UserPaneDraw); initiallyVisible = false; TkMacOSXComputeControlParams(butPtr,&mbPtr->params); - mbPtr->control = NewControl(mbPtr->windowRef, - cntrRect, "\p", - initiallyVisible, - mbPtr->params.initialValue, - mbPtr->params.minValue, - mbPtr->params.maxValue, - mbPtr->params.procID, - controlReference ); - + mbPtr->control = NewControl(mbPtr->windowRef, cntrRect, "\p", + initiallyVisible, mbPtr->params.initialValue, + mbPtr->params.minValue, mbPtr->params.maxValue, + mbPtr->params.procID, controlReference); + if (!mbPtr->control) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"failed to create control of type %d\n",procID); -#endif - return 1; + TkMacOSXDbgMsg("failed to create control of type %d\n", procID); + return 1; } - - if (EmbedControl(mbPtr->control,mbPtr->userPane) != noErr ) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"failed to embed control of type %d\n",procID); -#endif - return 1; + if (ChkErr(EmbedControl, mbPtr->control,mbPtr->userPane) != noErr ) { + return 1; } - + mbPtr->flags |= (1 + 2); return 0; } - + /* *-------------------------------------------------------------- * * TkMacOSXDrawControl -- * - * This function draws the tk button using Mac controls - * In addition, this code may apply custom colors passed - * in the TkButton. + * This function draws the tk button using Mac controls + * In addition, this code may apply custom colors passed + * in the TkButton. * * Results: - * None. + * None. * * Side effects: - * The control is created, or reinitialised as needed - * + * The control is created, or reinitialised as needed. * *-------------------------------------------------------------- */ static void TkMacOSXDrawControl( - MacButton *mbPtr, /* Mac button. */ - GWorldPtr destPort, /* Off screen GWorld. */ - GC gc, /* The GC we are drawing into - needed for - * the bevel button */ - Pixmap pixmap) /* The pixmap we are drawing into - needed - * for the bevel button */ - + MacButton *mbPtr, /* Mac button. */ + GWorldPtr destPort, /* Off screen GWorld. */ + GC gc, /* The GC we are drawing into - needed for the + * bevel button */ + Pixmap pixmap) /* The pixmap we are drawing into - needed for + * the bevel button */ { - TkButton * butPtr = ( TkButton *)mbPtr; - int err; - TkWindow * winPtr; - Rect paneRect; - Rect cntrRect; - - winPtr = (TkWindow *)butPtr->tkwin; - - paneRect.left = winPtr->privatePtr->xOff; - paneRect.top = winPtr->privatePtr->yOff; - paneRect.right = paneRect.left + Tk_Width(butPtr->tkwin); + TkButton *butPtr = (TkButton *) mbPtr; + TkWindow *winPtr; + Rect paneRect, cntrRect; + + winPtr = (TkWindow *) butPtr->tkwin; + + paneRect.left = winPtr->privatePtr->xOff; + paneRect.top = winPtr->privatePtr->yOff; + paneRect.right = paneRect.left + Tk_Width(butPtr->tkwin); paneRect.bottom = paneRect.top + Tk_Height(butPtr->tkwin); cntrRect = paneRect; /* - cntrRect.left += butPtr->inset; - cntrRect.top += butPtr->inset; - cntrRect.right -= butPtr->inset; + cntrRect.left += butPtr->inset; + cntrRect.top += butPtr->inset; + cntrRect.right -= butPtr->inset; cntrRect.bottom -= butPtr->inset; */ - cntrRect.left += DEF_INSET_LEFT; - cntrRect.top += DEF_INSET_TOP; - cntrRect.right -= DEF_INSET_RIGHT; + cntrRect.left += DEF_INSET_LEFT; + cntrRect.top += DEF_INSET_TOP; + cntrRect.right -= DEF_INSET_RIGHT; cntrRect.bottom -= DEF_INSET_BOTTOM; - /* - * The control has been previously initialised - * It may need to be re-initialised + /* + * The control has been previously initialised. + * It may need to be re-initialised */ - + if (mbPtr->flags) { - MacControlParams params; - TkMacOSXComputeControlParams(butPtr, ¶ms); - if (bcmp(¶ms, &mbPtr->params, sizeof(params))) { - /* - * the type of control has changed - * Clean it up and clear the flag - */ - - if (mbPtr->userPane) { - DisposeControl(mbPtr->userPane); - mbPtr->userPane = NULL; - mbPtr->control = NULL; - } - mbPtr->flags = 0; - } + MacControlParams params; + + TkMacOSXComputeControlParams(butPtr, ¶ms); + if (bcmp(¶ms, &mbPtr->params, sizeof(params))) { + /* + * The type of control has changed. + * Clean it up and clear the flag. + */ + + if (mbPtr->userPane) { + DisposeControl(mbPtr->userPane); + mbPtr->userPane = NULL; + mbPtr->control = NULL; + } + mbPtr->flags = 0; + } } if (!(mbPtr->flags & 1)) { - if (TkMacOSXInitControl(mbPtr, destPort, gc, - pixmap, &paneRect, &cntrRect) ) { - return; - } + if (TkMacOSXInitControl(mbPtr, destPort, gc, pixmap, &paneRect, + &cntrRect)) { + return; + } } SetControlBounds(mbPtr->userPane, &paneRect); SetControlBounds(mbPtr->control, &cntrRect); if (!mbPtr->useTkText) { - Str255 controlTitle; - ControlFontStyleRec fontStyle; - Tk_Font font; - int len; - - if (((mbPtr->info.image == NULL) && (mbPtr->info.bitmap == None)) - || (mbPtr->info.compound != COMPOUND_NONE)) { - len = TkFontGetFirstTextLayout(butPtr->textLayout, - &font, (char*) controlTitle); - controlTitle[len] = 0; - } else { - len = 0; - controlTitle[0] = 0; - } - if (bcmp(mbPtr->controlTitle, controlTitle, len+1)) { - CFStringRef cf; - cf = CFStringCreateWithCString(NULL, - (char*) controlTitle, kCFStringEncodingUTF8); - if (cf != NULL) { - SetControlTitleWithCFString(mbPtr->control, cf); - CFRelease(cf); - } - bcopy(controlTitle, mbPtr->controlTitle, len+1); - } - if (len) { - TkMacOSXInitControlFontStyle(font, &fontStyle); - if (bcmp(&mbPtr->fontStyle, &fontStyle, sizeof(fontStyle)) ) { - if (SetControlFontStyle(mbPtr->control, &fontStyle) != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"SetControlFontStyle failed\n"); -#endif - } - bcopy(&fontStyle, &mbPtr->fontStyle, - sizeof(fontStyle)); - } - } + Str255 controlTitle; + ControlFontStyleRec fontStyle; + Tk_Font font; + int len; + + if (((mbPtr->info.image == NULL) && (mbPtr->info.bitmap == None)) + || (mbPtr->info.compound != COMPOUND_NONE)) { + len = TkFontGetFirstTextLayout(butPtr->textLayout, + &font, (char*) controlTitle); + controlTitle[len] = 0; + } else { + len = 0; + controlTitle[0] = 0; + } + if (bcmp(mbPtr->controlTitle, controlTitle, len+1)) { + CFStringRef cf = CFStringCreateWithCString(NULL, + (char*) controlTitle, kCFStringEncodingUTF8); + + if (cf != NULL) { + SetControlTitleWithCFString(mbPtr->control, cf); + CFRelease(cf); + } + bcopy(controlTitle, mbPtr->controlTitle, len+1); + } + if (len) { + TkMacOSXInitControlFontStyle(font, &fontStyle); + if (bcmp(&mbPtr->fontStyle, &fontStyle, sizeof(fontStyle)) ) { + ChkErr(SetControlFontStyle, mbPtr->control, &fontStyle); + bcopy(&fontStyle, &mbPtr->fontStyle, sizeof(fontStyle)); + } + } } if (mbPtr->params.isBevel) { - /* Initialiase the image/button parameters */ - SetupBevelButton(mbPtr, mbPtr->control, destPort, - gc, pixmap); + /* + * Initialiase the image/button parameters. + */ + + SetupBevelButton(mbPtr, mbPtr->control, destPort, gc, pixmap); } if (butPtr->flags & SELECTED) { - SetControlValue(mbPtr->control, 1); + SetControlValue(mbPtr->control, 1); } else if (butPtr->flags & TRISTATED) { - SetControlValue(mbPtr->control, 2); + SetControlValue(mbPtr->control, 2); } else { - SetControlValue(mbPtr->control, 0); + SetControlValue(mbPtr->control, 0); } if (!Tk_MacOSXIsAppInFront() || butPtr->state == STATE_DISABLED) { @@ -1027,6 +983,7 @@ TkMacOSXDrawControl( * Use NoPart for normal and to ensure correct direct transition from * disabled to active -state. [Bug 706446] */ + HiliteControl(mbPtr->control, kControlNoPart); if (butPtr->state == STATE_ACTIVE) { @@ -1035,7 +992,7 @@ TkMacOSXDrawControl( } else { switch (butPtr->type) { case TYPE_BUTTON: - HiliteControl(mbPtr->control, kControlButtonPart); + HiliteControl(mbPtr->control, kControlButtonPart); break; case TYPE_RADIO_BUTTON: HiliteControl(mbPtr->control, kControlRadioButtonPart); @@ -1050,30 +1007,28 @@ TkMacOSXDrawControl( UpdateControlColors(mbPtr); if (butPtr->type == TYPE_BUTTON) { - Boolean isDefault; - - if (butPtr->defaultState == STATE_ACTIVE) { - isDefault = true; - } else { - isDefault = false; - } - if ((err=SetControlData(mbPtr->control, kControlNoPart, - kControlPushButtonDefaultTag, - sizeof(isDefault), (Ptr) &isDefault)) != noErr) { - } + Boolean isDefault; + + if (butPtr->defaultState == STATE_ACTIVE) { + isDefault = true; + } else { + isDefault = false; + } + ChkErr(SetControlData, mbPtr->control, kControlNoPart, + kControlPushButtonDefaultTag, sizeof(isDefault), &isDefault); } - if (mbPtr->flags&2) { - ShowControl(mbPtr->userPane); - ShowControl(mbPtr->control); - mbPtr->flags ^= 2; + if (mbPtr->flags & 2) { + ShowControl(mbPtr->userPane); + ShowControl(mbPtr->control); + mbPtr->flags ^= 2; } else { - SetControlVisibility(mbPtr->control, true, true); - Draw1Control(mbPtr->userPane); + SetControlVisibility(mbPtr->control, true, true); + Draw1Control(mbPtr->userPane); } if (mbPtr->params.isBevel) { - KillPicture(mbPtr->bevelButtonContent.u.picture); + KillPicture(mbPtr->bevelButtonContent.u.picture); } } @@ -1082,150 +1037,131 @@ TkMacOSXDrawControl( * * SetupBevelButton -- * - * Sets up the Bevel Button with image by copying the - * source image onto the PicHandle for the button. + * Sets up the Bevel Button with image by copying the + * source image onto the PicHandle for the button. * * Results: - * None + * None * * Side effects: - * The image or bitmap for the button is copied over to a picture. + * The image or bitmap for the button is copied over to a picture. * *-------------------------------------------------------------- */ + void SetupBevelButton( - MacButton *mbPtr, /* Mac button. */ - ControlRef controlHandle, /* The control to set this picture to */ - GWorldPtr destPort, /* Off screen GWorld. */ - GC gc, /* The GC we are drawing into - needed for - * the bevel button */ - Pixmap pixmap /* The pixmap we are drawing into - needed - for the bevel button */ - ) + MacButton *mbPtr, /* Mac button. */ + ControlRef controlHandle, /* The control to set this picture to. */ + GWorldPtr destPort, /* Off screen GWorld. */ + GC gc, /* The GC we are drawing into - needed for the + * bevel button. */ + Pixmap pixmap) /* The pixmap we are drawing into - needed for + * the bevel button. */ { - int err; - TkButton *butPtr = ( TkButton *)mbPtr; + TkButton *butPtr = (TkButton *) mbPtr; int height, width; ControlButtonGraphicAlignment theAlignment; - - SetPort(destPort); + CGrafPtr savePort; + Boolean portChanged; + + portChanged = QDSwapPort(destPort, &savePort); if (butPtr->image != None) { - Tk_SizeOfImage(butPtr->image, - &width, &height); + Tk_SizeOfImage(butPtr->image, &width, &height); } else { - Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, - &width, &height); + Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); } - + if ((butPtr->width > 0) && (butPtr->width < width)) { - width = butPtr->width; + width = butPtr->width; } if ((butPtr->height > 0) && (butPtr->height < height)) { - height = butPtr->height; + 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 + /* + * Set the flag to circumvent clipping and bounds problems with OS 10.0.4 */ - - if (!(mbPtr->bevelButtonContent.u.picture - = OpenCPicture(&mbPtr->picParams)) ) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"OpenCPicture failed\n"); -#endif + + 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 + * 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); - } else if ((butPtr->tristateImage != NULL) && (butPtr->flags & TRISTATED)) { - Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height, - pixmap, 0, 0); + + if (butPtr->selectImage != NULL && (butPtr->flags & SELECTED)) { + Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, pixmap, 0, 0); + } else if (butPtr->tristateImage != NULL && (butPtr->flags & TRISTATED)) { + Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height, pixmap, 0, + 0); } else if (butPtr->image != NULL) { - Tk_RedrawImage(butPtr->image, 0, 0, width, - height, pixmap, 0, 0); - } else { - XSetClipOrigin(butPtr->display, gc, 0, 0); - XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0, - (unsigned int) width, (unsigned int) height, 0, 0, 1); + Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, 0, 0); + } else { + XSetClipOrigin(butPtr->display, gc, 0, 0); + XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0, width, + height, 0, 0, 1); } - + ClosePicture(); tkPictureIsOpen = 0; - - if ((err = SetControlData(controlHandle, kControlButtonPart, - kControlBevelButtonContentTag, - sizeof(ControlButtonContentInfo), - (char *) &mbPtr->bevelButtonContent)) != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr, - "SetControlData BevelButtonContent failed, %d\n", err ); -#endif - } - + + ChkErr(SetControlData, controlHandle, kControlButtonPart, + kControlBevelButtonContentTag, sizeof(ControlButtonContentInfo), + (char *) &mbPtr->bevelButtonContent); + if (butPtr->anchor == TK_ANCHOR_N) { - theAlignment = kControlBevelButtonAlignTop; - } else if (butPtr->anchor == TK_ANCHOR_NE) { - theAlignment = kControlBevelButtonAlignTopRight; - } else if (butPtr->anchor == TK_ANCHOR_E) { - theAlignment = kControlBevelButtonAlignRight; + theAlignment = kControlBevelButtonAlignTop; + } else if (butPtr->anchor == TK_ANCHOR_NE) { + theAlignment = kControlBevelButtonAlignTopRight; + } else if (butPtr->anchor == TK_ANCHOR_E) { + theAlignment = kControlBevelButtonAlignRight; } else if (butPtr->anchor == TK_ANCHOR_SE) { - theAlignment = kControlBevelButtonAlignBottomRight; + theAlignment = kControlBevelButtonAlignBottomRight; } else if (butPtr->anchor == TK_ANCHOR_S) { - theAlignment = kControlBevelButtonAlignBottom; + theAlignment = kControlBevelButtonAlignBottom; } else if (butPtr->anchor == TK_ANCHOR_SW) { - theAlignment = kControlBevelButtonAlignBottomLeft; + theAlignment = kControlBevelButtonAlignBottomLeft; } else if (butPtr->anchor == TK_ANCHOR_W) { - theAlignment = kControlBevelButtonAlignLeft; + theAlignment = kControlBevelButtonAlignLeft; } else if (butPtr->anchor == TK_ANCHOR_NW) { - theAlignment = kControlBevelButtonAlignTopLeft; + theAlignment = kControlBevelButtonAlignTopLeft; } else if (butPtr->anchor == TK_ANCHOR_CENTER) { - theAlignment = kControlBevelButtonAlignCenter; + theAlignment = kControlBevelButtonAlignCenter; } - if ((err = SetControlData(controlHandle, kControlButtonPart, - kControlBevelButtonGraphicAlignTag, - sizeof(ControlButtonGraphicAlignment), - (char *) &theAlignment)) != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr, - "SetControlData BevelButtonGraphicAlign failed, %d\n", err ); -#endif - } + ChkErr(SetControlData, controlHandle, kControlButtonPart, + kControlBevelButtonGraphicAlignTag, + sizeof(ControlButtonGraphicAlignment), (char *) &theAlignment); if (butPtr->compound != COMPOUND_NONE) { - ControlButtonTextPlacement thePlacement = \ - kControlBevelButtonPlaceNormally; - if (butPtr->compound == COMPOUND_TOP) { - thePlacement = kControlBevelButtonPlaceBelowGraphic; - } else if (butPtr->compound == COMPOUND_BOTTOM) { - thePlacement = kControlBevelButtonPlaceAboveGraphic; - } else if (butPtr->compound == COMPOUND_LEFT) { - thePlacement = kControlBevelButtonPlaceToRightOfGraphic; - } else if (butPtr->compound == COMPOUND_RIGHT) { - thePlacement = kControlBevelButtonPlaceToLeftOfGraphic; - } - if ((err = SetControlData(controlHandle, kControlButtonPart, - kControlBevelButtonTextPlaceTag, - sizeof(ControlButtonTextPlacement), - (char *) &thePlacement)) != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr, - "SetControlData BevelButtonTextPlace failed, %d\n", err ); -#endif - } + ControlButtonTextPlacement thePlacement = + kControlBevelButtonPlaceNormally; + + if (butPtr->compound == COMPOUND_TOP) { + thePlacement = kControlBevelButtonPlaceBelowGraphic; + } else if (butPtr->compound == COMPOUND_BOTTOM) { + thePlacement = kControlBevelButtonPlaceAboveGraphic; + } else if (butPtr->compound == COMPOUND_LEFT) { + thePlacement = kControlBevelButtonPlaceToRightOfGraphic; + } else if (butPtr->compound == COMPOUND_RIGHT) { + thePlacement = kControlBevelButtonPlaceToLeftOfGraphic; + } + ChkErr(SetControlData, controlHandle, kControlButtonPart, + kControlBevelButtonTextPlaceTag, + sizeof(ControlButtonTextPlacement), (char *) &thePlacement); + } + if (portChanged) { + QDSwapPort(savePort, NULL); } } @@ -1234,28 +1170,30 @@ SetupBevelButton( * * SetUserPaneDrawProc -- * - * Utility function to add a UserPaneDrawProc - * to a userPane control. From MoreControls code - * from Apple DTS. + * Utility function to add a UserPaneDrawProc + * to a userPane control. From MoreControls code + * from Apple DTS. * * Results: - * MacOS system error. + * MacOS system error. * * Side effects: - * The user pane gets a new UserPaneDrawProc. + * The user pane gets a new UserPaneDrawProc. * *-------------------------------------------------------------- */ -OSErr SetUserPaneDrawProc ( + +OSStatus +SetUserPaneDrawProc( ControlRef control, ControlUserPaneDrawProcPtr upp) { ControlUserPaneDrawUPP myControlUserPaneDrawUPP; - myControlUserPaneDrawUPP = NewControlUserPaneDrawUPP(upp); - return SetControlData (control, - kControlNoPart, kControlUserPaneDrawProcTag, - sizeof(myControlUserPaneDrawUPP), - (Ptr) &myControlUserPaneDrawUPP); + + myControlUserPaneDrawUPP = NewControlUserPaneDrawUPP(upp); + return SetControlData(control, kControlNoPart, + kControlUserPaneDrawProcTag, sizeof(myControlUserPaneDrawUPP), + (Ptr) &myControlUserPaneDrawUPP); } /* @@ -1263,28 +1201,30 @@ OSErr SetUserPaneDrawProc ( * * SetUserPaneSetUpSpecialBackgroundProc -- * - * Utility function to add a UserPaneBackgroundProc - * to a userPane control + * Utility function to add a UserPaneBackgroundProc + * to a userPane control * * Results: - * MacOS system error. + * MacOS system error. * * Side effects: - * The user pane gets a new UserPaneBackgroundProc. + * The user pane gets a new UserPaneBackgroundProc. * *-------------------------------------------------------------- */ -OSErr + +OSStatus SetUserPaneSetUpSpecialBackgroundProc( - ControlRef control, + ControlRef control, ControlUserPaneBackgroundProcPtr upp) { ControlUserPaneBackgroundUPP myControlUserPaneBackgroundUPP; + myControlUserPaneBackgroundUPP = NewControlUserPaneBackgroundUPP(upp); - return SetControlData (control, kControlNoPart, - kControlUserPaneBackgroundProcTag, - sizeof(myControlUserPaneBackgroundUPP), - (Ptr) &myControlUserPaneBackgroundUPP); + return SetControlData(control, kControlNoPart, + kControlUserPaneBackgroundProcTag, + sizeof(myControlUserPaneBackgroundUPP), + (Ptr) &myControlUserPaneBackgroundUPP); } /* @@ -1292,28 +1232,29 @@ SetUserPaneSetUpSpecialBackgroundProc( * * UserPaneDraw -- * - * This function draws the background of the user pane that will - * lie under checkboxes and radiobuttons. + * This function draws the background of the user pane that will + * lie under checkboxes and radiobuttons. * * Results: - * None. + * None. * * Side effects: - * The user pane gets updated to the current color. + * The user pane gets updated to the current color. * *-------------------------------------------------------------- */ + void UserPaneDraw( ControlRef control, ControlPartCode cpc) { + MacButton *mbPtr = (MacButton *)(intptr_t)GetControlReference(control); Rect contrlRect; - MacButton * mbPtr; - mbPtr = ( MacButton *)GetControlReference(control); + GetControlBounds(control,&contrlRect); - RGBBackColor (&mbPtr->userPaneBackground); - EraseRect (&contrlRect); + TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL); + EraseRect(&contrlRect); } /* @@ -1321,14 +1262,14 @@ UserPaneDraw( * * UserPaneBackgroundProc -- * - * This function sets up the background of the user pane that will - * lie under checkboxes and radiobuttons. + * This function sets up the background of the user pane that will + * lie under checkboxes and radiobuttons. * * Results: - * None. + * None. * * Side effects: - * The user pane background gets set to the current color. + * The user pane background gets set to the current color. * *-------------------------------------------------------------- */ @@ -1338,10 +1279,10 @@ UserPaneBackgroundProc( ControlHandle control, ControlBackgroundPtr info) { - MacButton * mbPtr; - mbPtr = ( MacButton *)GetControlReference(control); + MacButton * mbPtr = (MacButton *)(intptr_t)GetControlReference(control); + if (info->colorDevice) { - RGBBackColor (&mbPtr->userPaneBackground); + TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL); } } @@ -1350,82 +1291,84 @@ UserPaneBackgroundProc( * * UpdateControlColors -- * - * This function will review the colors used to display - * a Macintosh button. If any non-standard colors are - * used we create a custom palette for the button, populate - * with the colors for the button and install the palette. + * This function will review the colors used to display + * a Macintosh button. If any non-standard colors are + * used we create a custom palette for the button, populate + * with the colors for the button and install the palette. * - * Under Appearance, we just set the pointer that will be - * used by the UserPaneDrawProc. + * Under Appearance, we just set the pointer that will be + * used by the UserPaneDrawProc. * * Results: - * None. + * None. * * Side effects: - * The Macintosh control may get a custom palette installed. + * The Macintosh control may get a custom palette installed. * *-------------------------------------------------------------- */ static int -UpdateControlColors(MacButton * mbPtr) +UpdateControlColors( + MacButton *mbPtr) { XColor *xcolor; - TkButton * butPtr = ( TkButton * )mbPtr; - + TkButton *butPtr = (TkButton *) mbPtr; + /* * Under Appearance we cannot change the background of the - * button itself. However, the color we are setting is the color - * of the containing userPane. This will be the color that peeks - * around the rounded corners of the button. + * button itself. However, the color we are setting is the color + * of the containing userPane. This will be the color that peeks + * around the rounded corners of the button. * We make this the highlightbackground rather than the background, * because if you color the background of a frame containing a * button, you usually also color the highlightbackground as well, * or you will get a thin grey ring around the button. */ - + if (butPtr->type == TYPE_BUTTON) { - xcolor = Tk_3DBorderColor(butPtr->highlightBorder); + xcolor = Tk_3DBorderColor(butPtr->highlightBorder); } else { - xcolor = Tk_3DBorderColor(butPtr->normalBorder); + xcolor = Tk_3DBorderColor(butPtr->normalBorder); } - TkSetMacColor(xcolor->pixel, &mbPtr->userPaneBackground); - + mbPtr->userPaneBackground = xcolor->pixel; + return false; -} +} + /* *-------------------------------------------------------------- * * ButtonEventProc -- * - * This procedure is invoked by the Tk dispatcher for various - * events on buttons. + * This procedure is invoked by the Tk dispatcher for various + * events on buttons. * * Results: - * None. + * None. * * Side effects: - * When it gets exposed, it is redisplayed. + * When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */ static void ButtonEventProc( - ClientData clientData, /* Information about window. */ - XEvent *eventPtr) /* Information about event. */ + ClientData clientData, /* Information about window. */ + XEvent *eventPtr) /* Information about event. */ { TkButton *buttonPtr = (TkButton *) clientData; + if (eventPtr->type == ActivateNotify - || eventPtr->type == DeactivateNotify) { - if ((buttonPtr->tkwin == NULL) - || (!Tk_IsMapped(buttonPtr->tkwin))) { - return; - } - if ((buttonPtr->flags & REDRAW_PENDING) == 0) { - Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) buttonPtr); - buttonPtr->flags |= REDRAW_PENDING; - } + || eventPtr->type == DeactivateNotify) { + if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) { + return; + } + if ((buttonPtr->flags & REDRAW_PENDING) == 0) { + Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) buttonPtr); + buttonPtr->flags |= REDRAW_PENDING; + } } } @@ -1434,143 +1377,141 @@ ButtonEventProc( * * TkMacOSXComputeControlParams -- * - * This procedure computes the various parameters used - * when creating a Carbon control (NewControl) - * These are determined by the various tk button parameters + * This procedure computes the various parameters used + * when creating a Carbon control (NewControl). + * These are determined by the various tk button parameters * * Results: - * None. + * None. * * Side effects: - * Sets the control initialisation parameters + * Sets the control initialisation parameters * *---------------------------------------------------------------------- */ static void -TkMacOSXComputeControlParams(TkButton * butPtr, MacControlParams * paramsPtr ) +TkMacOSXComputeControlParams( + TkButton *butPtr, + MacControlParams *paramsPtr) { paramsPtr->isBevel = 0; - - /* - * Determine ProcID based on button type and dimensions + + /* + * Determine ProcID based on button type and dimensions. */ - + switch (butPtr->type) { - case TYPE_BUTTON: - if ((butPtr->image == None) && (butPtr->bitmap == None)) { - paramsPtr->initialValue = 1; - paramsPtr->minValue = 0; - paramsPtr->maxValue = 1; - paramsPtr->procID = kControlPushButtonProc; - } else { - paramsPtr->initialValue = 0; - paramsPtr->minValue = kControlBehaviorOffsetContents - | kControlContentPictHandle; - paramsPtr->maxValue = 1; - if (butPtr->borderWidth <= 2) { - paramsPtr->procID = kControlBevelButtonSmallBevelProc; - } else if (butPtr->borderWidth == 3) { - paramsPtr->procID = kControlBevelButtonNormalBevelProc; - } else { - paramsPtr->procID = kControlBevelButtonLargeBevelProc; - } - paramsPtr->isBevel = 1; - } - break; - case TYPE_RADIO_BUTTON: - if (((butPtr->image == None) && (butPtr->bitmap == None)) - || (butPtr->indicatorOn)) { - paramsPtr->initialValue = 1; - paramsPtr->minValue = 0; - paramsPtr->maxValue = 2; - paramsPtr->procID = kControlRadioButtonProc; - } else { - paramsPtr->initialValue = 0; - paramsPtr->minValue = kControlBehaviorOffsetContents| - kControlBehaviorSticky| - kControlContentPictHandle; - paramsPtr->maxValue = 2; - if (butPtr->borderWidth <= 2) { - paramsPtr->procID = kControlBevelButtonSmallBevelProc; - } else if (butPtr->borderWidth == 3) { - paramsPtr->procID = kControlBevelButtonNormalBevelProc; - } else { - paramsPtr->procID = kControlBevelButtonLargeBevelProc; - } - paramsPtr->isBevel = 1; - } - break; - case TYPE_CHECK_BUTTON: - if (((butPtr->image == None) - && (butPtr->bitmap == None)) - || (butPtr->indicatorOn)) { - paramsPtr->initialValue = 1; - paramsPtr->minValue = 0; - paramsPtr->maxValue = 2; - paramsPtr->procID = kControlCheckBoxProc; - } else { - paramsPtr->initialValue = 0; - paramsPtr->minValue = kControlBehaviorOffsetContents - | kControlBehaviorSticky - | kControlContentPictHandle; - paramsPtr->maxValue = 2; - if (butPtr->borderWidth <= 2) { - paramsPtr->procID = kControlBevelButtonSmallBevelProc; - } else if (butPtr->borderWidth == 3) { - paramsPtr->procID = kControlBevelButtonNormalBevelProc; - } else { - paramsPtr->procID = kControlBevelButtonLargeBevelProc; - } - paramsPtr->isBevel = 1; - } - break; + case TYPE_BUTTON: + if ((butPtr->image == None) && (butPtr->bitmap == None)) { + paramsPtr->initialValue = 1; + paramsPtr->minValue = 0; + paramsPtr->maxValue = 1; + paramsPtr->procID = kControlPushButtonProc; + } else { + paramsPtr->initialValue = 0; + paramsPtr->minValue = kControlBehaviorOffsetContents | + kControlContentPictHandle; + paramsPtr->maxValue = 1; + if (butPtr->borderWidth <= 2) { + paramsPtr->procID = kControlBevelButtonSmallBevelProc; + } else if (butPtr->borderWidth == 3) { + paramsPtr->procID = kControlBevelButtonNormalBevelProc; + } else { + paramsPtr->procID = kControlBevelButtonLargeBevelProc; + } + paramsPtr->isBevel = 1; + } + break; + case TYPE_RADIO_BUTTON: + if (((butPtr->image == None) && (butPtr->bitmap == None)) + || (butPtr->indicatorOn)) { + paramsPtr->initialValue = 1; + paramsPtr->minValue = 0; + paramsPtr->maxValue = 2; + paramsPtr->procID = kControlRadioButtonProc; + } else { + paramsPtr->initialValue = 0; + paramsPtr->minValue = kControlBehaviorOffsetContents | + kControlBehaviorSticky | kControlContentPictHandle; + paramsPtr->maxValue = 2; + if (butPtr->borderWidth <= 2) { + paramsPtr->procID = kControlBevelButtonSmallBevelProc; + } else if (butPtr->borderWidth == 3) { + paramsPtr->procID = kControlBevelButtonNormalBevelProc; + } else { + paramsPtr->procID = kControlBevelButtonLargeBevelProc; + } + paramsPtr->isBevel = 1; + } + break; + case TYPE_CHECK_BUTTON: + if (((butPtr->image == None) && (butPtr->bitmap == None)) + || (butPtr->indicatorOn)) { + paramsPtr->initialValue = 1; + paramsPtr->minValue = 0; + paramsPtr->maxValue = 2; + paramsPtr->procID = kControlCheckBoxProc; + } else { + paramsPtr->initialValue = 0; + paramsPtr->minValue = kControlBehaviorOffsetContents | + kControlBehaviorSticky | kControlContentPictHandle; + paramsPtr->maxValue = 2; + if (butPtr->borderWidth <= 2) { + paramsPtr->procID = kControlBevelButtonSmallBevelProc; + } else if (butPtr->borderWidth == 3) { + paramsPtr->procID = kControlBevelButtonNormalBevelProc; + } else { + paramsPtr->procID = kControlBevelButtonLargeBevelProc; + } + paramsPtr->isBevel = 1; + } + break; } -} +} + /* *---------------------------------------------------------------------- * * TkMacOSXComputeDrawParams -- * - * This procedure computes the various parameters used - * when drawing a button - * These are determined by the various tk button parameters + * This procedure computes the various parameters used + * when drawing a button + * These are determined by the various tk button parameters * * Results: - * 1 if control will be used, 0 otherwise. + * 1 if control will be used, 0 otherwise. * * Side effects: - * Sets the button draw parameters + * Sets the button draw parameters * *---------------------------------------------------------------------- */ static int -TkMacOSXComputeDrawParams(TkButton * butPtr, DrawParams * dpPtr) +TkMacOSXComputeDrawParams( + TkButton *butPtr, + DrawParams *dpPtr) { - dpPtr->hasImageOrBitmap = ((butPtr->image != NULL) - || (butPtr->bitmap != None)); - dpPtr->offset = (butPtr->type == TYPE_BUTTON) - && dpPtr->hasImageOrBitmap; + dpPtr->hasImageOrBitmap = ((butPtr->image != NULL) + || (butPtr->bitmap != None)); + dpPtr->offset = (butPtr->type == TYPE_BUTTON) + && dpPtr->hasImageOrBitmap; dpPtr->border = butPtr->normalBorder; - if ((butPtr->state == STATE_DISABLED) - && (butPtr->disabledFg != NULL)) { - dpPtr->gc = butPtr->disabledGC; - } else if ((butPtr->type == TYPE_BUTTON) - && (butPtr->state == STATE_ACTIVE)) { - dpPtr->gc = butPtr->activeTextGC; - dpPtr->border = butPtr->activeBorder; + if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) { + dpPtr->gc = butPtr->disabledGC; + } else if (butPtr->type == TYPE_BUTTON && butPtr->state == STATE_ACTIVE) { + dpPtr->gc = butPtr->activeTextGC; + dpPtr->border = butPtr->activeBorder; } else { - dpPtr->gc = butPtr->normalTextGC; + dpPtr->gc = butPtr->normalTextGC; } - if ((butPtr->flags & SELECTED) - && (butPtr->state != STATE_ACTIVE) - && (butPtr->selectBorder != NULL) - && !butPtr->indicatorOn) { - dpPtr->border = butPtr->selectBorder; + if ((butPtr->flags & SELECTED) && (butPtr->state != STATE_ACTIVE) + && (butPtr->selectBorder != NULL) && !butPtr->indicatorOn) { + dpPtr->border = butPtr->selectBorder; } - + /* * Override the relief specified for the button if this is a * checkbutton or radiobutton and there's no indicator. @@ -1581,69 +1522,70 @@ TkMacOSXComputeDrawParams(TkButton * butPtr, DrawParams * dpPtr) dpPtr->relief = butPtr->relief; if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) { - if (!dpPtr->hasImageOrBitmap) { - dpPtr->relief = (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN - : TK_RELIEF_RAISED; - } + if (!dpPtr->hasImageOrBitmap) { + dpPtr->relief = (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN + : TK_RELIEF_RAISED; + } } /* * Determine the draw type */ + if (butPtr->type == TYPE_LABEL) { - dpPtr->drawType = DRAW_LABEL; + dpPtr->drawType = DRAW_LABEL; } else if (butPtr->type == TYPE_BUTTON) { - if (!dpPtr->hasImageOrBitmap) { - dpPtr->drawType = DRAW_CONTROL; - } else if (butPtr->image != None) { - dpPtr->drawType = DRAW_BEVEL; - } else { - /* - * TO DO - The current way the we draw bitmaps (XCopyPlane) - * uses CopyDeepMask in this one case. The Picture recording - * does not record this call, and so we can't use the - * Appearance bevel button here. The only case that would - * exercise this is if you use a bitmap, with - * -data & -mask specified. We should probably draw the - * appearance button and overprint the image in this case. - * This just punts and draws the old-style, ugly, button. - */ - - if (dpPtr->gc->clip_mask == 0) { - dpPtr->drawType = DRAW_BEVEL; - } else { - TkpClipMask *clipPtr = (TkpClipMask*) dpPtr->gc->clip_mask; - if ((clipPtr->type == TKP_CLIP_PIXMAP) && - (clipPtr->value.pixmap != butPtr->bitmap)) { - dpPtr->drawType = DRAW_CUSTOM; - } else { - dpPtr->drawType = DRAW_BEVEL; - } - } - } + if (!dpPtr->hasImageOrBitmap) { + dpPtr->drawType = DRAW_CONTROL; + } else if (butPtr->image != None) { + dpPtr->drawType = DRAW_BEVEL; + } else { + /* + * TO DO - The current way the we draw bitmaps (XCopyPlane) + * uses CopyDeepMask in this one case. The Picture recording + * does not record this call, and so we can't use the + * Appearance bevel button here. The only case that would + * exercise this is if you use a bitmap, with + * -data & -mask specified. We should probably draw the + * appearance button and overprint the image in this case. + * This just punts and draws the old-style, ugly, button. + */ + + if (dpPtr->gc->clip_mask == 0) { + dpPtr->drawType = DRAW_BEVEL; + } else { + TkpClipMask *clipPtr = (TkpClipMask *) dpPtr->gc->clip_mask; + + if ((clipPtr->type == TKP_CLIP_PIXMAP) && + (clipPtr->value.pixmap != butPtr->bitmap)) { + dpPtr->drawType = DRAW_CUSTOM; + } else { + dpPtr->drawType = DRAW_BEVEL; + } + } + } + } else if (butPtr->indicatorOn) { + dpPtr->drawType = DRAW_CONTROL; + } else if (dpPtr->hasImageOrBitmap) { + if (dpPtr->gc->clip_mask == 0) { + dpPtr->drawType = DRAW_BEVEL; + } else { + TkpClipMask *clipPtr = (TkpClipMask*) dpPtr->gc->clip_mask; + + if ((clipPtr->type == TKP_CLIP_PIXMAP) && + (clipPtr->value.pixmap != butPtr->bitmap)) { + dpPtr->drawType = DRAW_CUSTOM; + } else { + dpPtr->drawType = DRAW_BEVEL; + } + } } else { - if (butPtr->indicatorOn) { - dpPtr->drawType = DRAW_CONTROL; - } else if (dpPtr->hasImageOrBitmap) { - if (dpPtr->gc->clip_mask == 0) { - dpPtr->drawType = DRAW_BEVEL; - } else { - TkpClipMask *clipPtr = (TkpClipMask*) dpPtr->gc->clip_mask; - if ((clipPtr->type == TKP_CLIP_PIXMAP) && - (clipPtr->value.pixmap != butPtr->bitmap)) { - dpPtr->drawType = DRAW_CUSTOM; - } else { - dpPtr->drawType = DRAW_BEVEL; - } - } - } else { - dpPtr->drawType = DRAW_CUSTOM; - } + dpPtr->drawType = DRAW_CUSTOM; } if ((dpPtr->drawType == DRAW_CONTROL) || (dpPtr->drawType == DRAW_BEVEL)) { - return 1; + return 1; } else { - return 0; + return 0; } } diff --git a/macosx/tkMacOSXCarbonEvents.c b/macosx/tkMacOSXCarbonEvents.c index 18c519e..a6916bc 100644 --- a/macosx/tkMacOSXCarbonEvents.c +++ b/macosx/tkMacOSXCarbonEvents.c @@ -11,56 +11,56 @@ * application event target. * * Copyright 2001, Apple Computer, Inc. - * Copyright (c) 2005 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * The following terms apply to all files originating from Apple - * Computer, Inc. ("Apple") and associated with the software - * unless explicitly disclaimed in individual files. - * - * - * Apple hereby grants permission to use, copy, modify, - * distribute, and license this software and its documentation - * for any purpose, provided that existing copyright notices are - * retained in all copies and that this notice is included - * verbatim in any distributions. No written agreement, license, - * or royalty fee is required for any of the authorized - * uses. Modifications to this software may be copyrighted by - * their authors and need not follow the licensing terms - * described here, provided that the new terms are clearly - * indicated on the first page of each file where they apply. - * - * - * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE - * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, - * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF - * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, - * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND - * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS - * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE - * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * GOVERNMENT USE: If you are acquiring this software on behalf - * of the U.S. government, the Government shall have only - * "Restricted Rights" in the software and related documentation - * as defined in the Federal Acquisition Regulations (FARs) in - * Clause 52.227.19 (c) (2). If you are acquiring the software - * on behalf of the Department of Defense, the software shall be - * classified as "Commercial Computer Software" and the - * Government shall have only "Restricted Rights" as defined in - * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the - * foregoing, the authors grant the U.S. Government and others - * acting in its behalf permission to use and distribute the - * software in accordance with the terms specified in this - * license. - * - * RCS: @(#) $Id: tkMacOSXCarbonEvents.c,v 1.15 2007/04/21 19:06:37 hobbs Exp $ + * The following terms apply to all files originating from Apple + * Computer, Inc. ("Apple") and associated with the software + * unless explicitly disclaimed in individual files. + * + * + * Apple hereby grants permission to use, copy, modify, + * distribute, and license this software and its documentation + * for any purpose, provided that existing copyright notices are + * retained in all copies and that this notice is included + * verbatim in any distributions. No written agreement, license, + * or royalty fee is required for any of the authorized + * uses. Modifications to this software may be copyrighted by + * their authors and need not follow the licensing terms + * described here, provided that the new terms are clearly + * indicated on the first page of each file where they apply. + * + * + * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE + * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, + * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF + * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, + * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND + * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS + * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE + * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * GOVERNMENT USE: If you are acquiring this software on behalf + * of the U.S. government, the Government shall have only + * "Restricted Rights" in the software and related documentation + * as defined in the Federal Acquisition Regulations (FARs) in + * Clause 52.227.19 (c) (2). If you are acquiring the software + * on behalf of the Department of Defense, the software shall be + * classified as "Commercial Computer Software" and the + * Government shall have only "Restricted Rights" as defined in + * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the + * foregoing, the authors grant the U.S. Government and others + * acting in its behalf permission to use and distribute the + * software in accordance with the terms specified in this + * license. + * + * RCS: @(#) $Id: tkMacOSXCarbonEvents.c,v 1.16 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" @@ -68,66 +68,79 @@ #include "tkMacOSXDebug.h" /* -#ifdef TK_MAC_DEBUG +#ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_CARBON_EVENTS #endif */ -/* Declarations of functions used only in this file */ +/* + * Declarations of functions used only in this file: + */ + static OSStatus CarbonEventHandlerProc(EventHandlerCallRef callRef, - EventRef event, void *userData); -static OSStatus InstallStandardApplicationEventHandler(); -static void ExitRaelEventHandlerProc (EventHandlerCallRef, EventRef, void*) - __attribute__ ((__noreturn__)); + 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 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; + /* *---------------------------------------------------------------------- * * CarbonEventHandlerProc -- * - * This procedure is the handler for all registered CarbonEvents. + * This procedure is the handler for all registered CarbonEvents. * * Results: - * OS status code. + * OS status code. * * Side effects: - * Dispatches CarbonEvents. + * Dispatches CarbonEvents. * *---------------------------------------------------------------------- */ static OSStatus -CarbonEventHandlerProc ( - EventHandlerCallRef callRef, - EventRef event, - void *userData) +CarbonEventHandlerProc( + EventHandlerCallRef callRef, + EventRef event, + void *userData) { - OSStatus result = eventNotHandledErr; - TkMacOSXEvent macEvent; - MacEventStatus eventStatus; + OSStatus err = eventNotHandledErr; + TkMacOSXEvent macEvent; + MacEventStatus eventStatus; macEvent.eventRef = event; - macEvent.eClass = GetEventClass(macEvent.eventRef); - macEvent.eKind = GetEventKind(macEvent.eventRef); + macEvent.eClass = GetEventClass(event); + macEvent.eKind = GetEventKind(event); macEvent.interp = (Tcl_Interp *) userData; + macEvent.callRef = callRef; bzero(&eventStatus, sizeof(eventStatus)); -#if defined(TK_MAC_DEBUG) && defined(TK_MAC_DEBUG_CARBON_EVENTS) - char buf [256]; +#ifdef TK_MAC_DEBUG_CARBON_EVENTS if (macEvent.eKind != kEventMouseMoved && macEvent.eKind != kEventMouseDragged) { - TkMacOSXCarbonEventToAscii(event, buf); - fprintf(stderr, "CarbonEventHandlerProc started handling %s\n", buf); + TkMacOSXDbgMsg("Started handling %s", + TkMacOSXCarbonEventToAscii(event)); TkMacOSXInitNamedDebugSymbol(HIToolbox, void, _DebugPrintEvent, EventRef inEvent); if (_DebugPrintEvent) { - /* Carbon-internal event debugging (c.f. Technote 2124) */ + /* + * Carbon-internal event debugging (c.f. Technote 2124) + */ + _DebugPrintEvent(event); } } @@ -135,18 +148,18 @@ CarbonEventHandlerProc ( TkMacOSXProcessEvent(&macEvent,&eventStatus); if (eventStatus.stopProcessing) { - result = noErr; + err = noErr; } -#if defined(TK_MAC_DEBUG) && defined(TK_MAC_DEBUG_CARBON_EVENTS) +#ifdef TK_MAC_DEBUG_CARBON_EVENTS if (macEvent.eKind != kEventMouseMoved && macEvent.eKind != kEventMouseDragged) { - fprintf(stderr, - "CarbonEventHandlerProc finished handling %s: %s handled\n", - buf, eventStatus.stopProcessing ? " " : "not"); + TkMacOSXDbgMsg("Finished handling %s: %s handled", + TkMacOSXCarbonEventToAscii(event), + eventStatus.stopProcessing ? " " : "not"); } #endif /* TK_MAC_DEBUG_CARBON_EVENTS */ - return result; + return err; } /* @@ -154,104 +167,95 @@ CarbonEventHandlerProc ( * * TkMacOSXInitCarbonEvents -- * - * This procedure initializes all CarbonEvent handlers. + * This procedure initializes all CarbonEvent handlers. * * Results: - * None. + * None. * * Side effects: - * Handlers for Carbon Events are registered. + * Handlers for Carbon Events are registered. * *---------------------------------------------------------------------- */ MODULE_SCOPE void -TkMacOSXInitCarbonEvents ( - Tcl_Interp *interp) +TkMacOSXInitCarbonEvents( + Tcl_Interp *interp) { - OSStatus err; const EventTypeSpec dispatcherEventTypes[] = { - {kEventClassMouse, kEventMouseDown}, - {kEventClassMouse, kEventMouseUp}, - {kEventClassMouse, kEventMouseMoved}, - {kEventClassMouse, kEventMouseDragged}, - {kEventClassMouse, kEventMouseWheelMoved}, - {kEventClassWindow, kEventWindowUpdate}, - {kEventClassWindow, kEventWindowActivated}, - {kEventClassWindow, kEventWindowDeactivated}, - {kEventClassKeyboard, kEventRawKeyDown}, - {kEventClassKeyboard, kEventRawKeyRepeat}, - {kEventClassKeyboard, kEventRawKeyUp}, - {kEventClassKeyboard, kEventRawKeyModifiersChanged}, - {kEventClassKeyboard, kEventRawKeyRepeat}, - {kEventClassApplication, kEventAppActivated}, - {kEventClassApplication, kEventAppDeactivated}, - {kEventClassApplication, kEventAppQuit}, + {kEventClassKeyboard, kEventRawKeyDown}, + {kEventClassKeyboard, kEventRawKeyRepeat}, + {kEventClassKeyboard, kEventRawKeyUp}, + {kEventClassKeyboard, kEventRawKeyModifiersChanged}, + {kEventClassKeyboard, kEventRawKeyRepeat}, }; const EventTypeSpec applicationEventTypes[] = { - {kEventClassMenu, kEventMenuBeginTracking}, - {kEventClassMenu, kEventMenuEndTracking}, - {kEventClassCommand, kEventCommandProcess}, - {kEventClassCommand, kEventCommandUpdateStatus}, - {kEventClassMouse, kEventMouseWheelMoved}, - {kEventClassWindow, kEventWindowExpanded}, - {kEventClassApplication, kEventAppHidden}, - {kEventClassApplication, kEventAppShown}, - {kEventClassApplication, kEventAppAvailableWindowBoundsChanged}, + {kEventClassMenu, kEventMenuBeginTracking}, + {kEventClassMenu, kEventMenuEndTracking}, + {kEventClassMenu, kEventMenuOpening}, + {kEventClassMenu, kEventMenuTargetItem}, + {kEventClassCommand, kEventCommandProcess}, + {kEventClassCommand, kEventCommandUpdateStatus}, + {kEventClassApplication, kEventAppActivated}, + {kEventClassApplication, kEventAppDeactivated}, + {kEventClassApplication, kEventAppQuit}, + {kEventClassApplication, kEventAppHidden}, + {kEventClassApplication, kEventAppShown}, + {kEventClassApplication, kEventAppAvailableWindowBoundsChanged}, + {kEventClassAppearance, kEventAppearanceScrollBarVariantChanged}, }; - EventHandlerUPP handler = NewEventHandlerUPP(CarbonEventHandlerProc); - err = InstallStandardApplicationEventHandler(); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr, "InstallStandardApplicationEventHandler failed, %d\n", - (int) err); -#endif - } - err = InstallEventHandler(GetEventDispatcherTarget(), handler, - GetEventTypeCount(dispatcherEventTypes), dispatcherEventTypes, - (void *) interp, NULL); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr, "InstallEventHandler failed, %d\n", (int) err); -#endif - } - err = InstallEventHandler(GetApplicationEventTarget(), handler, - GetEventTypeCount(applicationEventTypes), applicationEventTypes, - (void *) interp, NULL); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr, "InstallEventHandler failed, %d\n", (int) err); -#endif - } + carbonEventHandlerUPP = NewEventHandlerUPP(CarbonEventHandlerProc); + carbonEventInterp = interp; + ChkErr(InstallStandardApplicationEventHandler); + ChkErr(InstallEventHandler, GetEventDispatcherTarget(), + carbonEventHandlerUPP, GetEventTypeCount(dispatcherEventTypes), + dispatcherEventTypes, (void *) carbonEventInterp, NULL); + ChkErr(InstallEventHandler, GetApplicationEventTarget(), + carbonEventHandlerUPP, GetEventTypeCount(applicationEventTypes), + applicationEventTypes, (void *) carbonEventInterp, NULL); -#if defined(TK_MAC_DEBUG) && defined(TK_MAC_DEBUG_CARBON_EVENTS) - TkMacOSXInitNamedDebugSymbol(HIToolbox, void, TraceEventByName, char*); - if (TraceEventByName) { +#ifdef TK_MAC_DEBUG_CARBON_EVENTS + TkMacOSXInitNamedDebugSymbol(HIToolbox, void, _TraceEventByName, + CFStringRef); + if (_TraceEventByName) { /* Carbon-internal event debugging (c.f. Technote 2124) */ - TraceEventByName("kEventMouseDown"); - TraceEventByName("kEventMouseUp"); - TraceEventByName("kEventMouseWheelMoved"); - TraceEventByName("kEventMouseScroll"); - TraceEventByName("kEventWindowUpdate"); - TraceEventByName("kEventWindowActivated"); - TraceEventByName("kEventWindowDeactivated"); - TraceEventByName("kEventRawKeyDown"); - TraceEventByName("kEventRawKeyRepeat"); - TraceEventByName("kEventRawKeyUp"); - TraceEventByName("kEventRawKeyModifiersChanged"); - TraceEventByName("kEventRawKeyRepeat"); - TraceEventByName("kEventAppActivated"); - TraceEventByName("kEventAppDeactivated"); - TraceEventByName("kEventAppQuit"); - TraceEventByName("kEventMenuBeginTracking"); - TraceEventByName("kEventMenuEndTracking"); - TraceEventByName("kEventCommandProcess"); - TraceEventByName("kEventCommandUpdateStatus"); - TraceEventByName("kEventWindowExpanded"); - TraceEventByName("kEventAppHidden"); - TraceEventByName("kEventAppShown"); - TraceEventByName("kEventAppAvailableWindowBoundsChanged"); + _TraceEventByName(CFSTR("kEventRawKeyDown")); + _TraceEventByName(CFSTR("kEventRawKeyRepeat")); + _TraceEventByName(CFSTR("kEventRawKeyUp")); + _TraceEventByName(CFSTR("kEventRawKeyModifiersChanged")); + _TraceEventByName(CFSTR("kEventRawKeyRepeat")); + _TraceEventByName(CFSTR("kEventMenuBeginTracking")); + _TraceEventByName(CFSTR("kEventMenuEndTracking")); + _TraceEventByName(CFSTR("kEventMenuOpening")); + _TraceEventByName(CFSTR("kEventMenuTargetItem")); + _TraceEventByName(CFSTR("kEventCommandProcess")); + _TraceEventByName(CFSTR("kEventCommandUpdateStatus")); + _TraceEventByName(CFSTR("kEventAppActivated")); + _TraceEventByName(CFSTR("kEventAppDeactivated")); + _TraceEventByName(CFSTR("kEventAppQuit")); + _TraceEventByName(CFSTR("kEventAppHidden")); + _TraceEventByName(CFSTR("kEventAppShown")); + _TraceEventByName(CFSTR("kEventAppAvailableWindowBoundsChanged")); + _TraceEventByName(CFSTR("kEventAppearanceScrollBarVariantChanged")); + _TraceEventByName(CFSTR("kEventMouseDown")); + _TraceEventByName(CFSTR("kEventMouseUp")); +#if 0 + _TraceEventByName(CFSTR("kEventMouseMoved")); + _TraceEventByName(CFSTR("kEventMouseDragged")); +#endif + _TraceEventByName(CFSTR("kEventMouseWheelMoved")); + _TraceEventByName(CFSTR("kEventMouseScroll")); + _TraceEventByName(CFSTR("kEventWindowActivated")); + _TraceEventByName(CFSTR("kEventWindowDeactivated")); + _TraceEventByName(CFSTR("kEventWindowUpdate")); + _TraceEventByName(CFSTR("kEventWindowExpanded")); + _TraceEventByName(CFSTR("kEventWindowBoundsChanged")); + _TraceEventByName(CFSTR("kEventWindowDragStarted")); + _TraceEventByName(CFSTR("kEventWindowDragCompleted")); + _TraceEventByName(CFSTR("kEventWindowConstrain")); + _TraceEventByName(CFSTR("kEventWindowGetRegion")); + _TraceEventByName(CFSTR("kEventWindowDrawContent")); } #endif /* TK_MAC_DEBUG_CARBON_EVENTS */ } @@ -259,22 +263,66 @@ TkMacOSXInitCarbonEvents ( /* *---------------------------------------------------------------------- * + * TkMacOSXInstallWindowCarbonEventHandler -- + * + * This procedure installs our window CarbonEvent handler. + * + * Results: + * None. + * + * Side effects: + * Handler for Carbon Events is registered. + * + *---------------------------------------------------------------------- + */ + +MODULE_SCOPE void +TkMacOSXInstallWindowCarbonEventHandler( + Tcl_Interp *interp, WindowRef window) +{ + const EventTypeSpec windowEventTypes[] = { + {kEventClassMouse, kEventMouseDown}, + {kEventClassMouse, kEventMouseUp}, + {kEventClassMouse, kEventMouseMoved}, + {kEventClassMouse, kEventMouseDragged}, + {kEventClassMouse, kEventMouseWheelMoved}, + {kEventClassWindow, kEventWindowActivated}, + {kEventClassWindow, kEventWindowDeactivated}, + {kEventClassWindow, kEventWindowUpdate}, + {kEventClassWindow, kEventWindowExpanded}, + {kEventClassWindow, kEventWindowBoundsChanged}, + {kEventClassWindow, kEventWindowDragStarted}, + {kEventClassWindow, kEventWindowDragCompleted}, + {kEventClassWindow, kEventWindowConstrain}, + {kEventClassWindow, kEventWindowGetRegion}, + {kEventClassWindow, kEventWindowDrawContent}, + }; + + ChkErr(InstallEventHandler, GetWindowEventTarget(window), + carbonEventHandlerUPP, GetEventTypeCount(windowEventTypes), + windowEventTypes, (void *) (interp ? interp : carbonEventInterp), + NULL); +} + +/* + *---------------------------------------------------------------------- + * * InstallStandardApplicationEventHandler -- * - * This procedure installs the carbon standard application event - * handler. + * This procedure installs the carbon standard application event + * handler. * * Results: - * OS status code. + * OS status code. * * Side effects: - * Standard handlers for application Carbon Events are registered. + * Standard handlers for application Carbon Events are registered. * *---------------------------------------------------------------------- */ static OSStatus -InstallStandardApplicationEventHandler() +InstallStandardApplicationEventHandler(void) { /* * This is a hack to workaround missing Carbon API to install the standard @@ -286,9 +334,12 @@ InstallStandardApplicationEventHandler() * 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}; + enum { + kExitRaelEvent = 'ExiT' + }; + const EventTypeSpec exitRaelEventType = { + kExitRaelEvent, kExitRaelEvent + }; EventHandlerUPP exitRaelEventHandler; EventHandlerRef exitRaelEventHandlerRef = NULL; EventRef exitRaelEvent = NULL; @@ -297,22 +348,26 @@ InstallStandardApplicationEventHandler() exitRaelEventHandler = NewEventHandlerUPP( (EventHandlerProcPtr) ExitRaelEventHandlerProc); if (exitRaelEventHandler) { - err = InstallEventHandler(GetEventDispatcherTarget(), + err = ChkErr(InstallEventHandler, GetEventDispatcherTarget(), exitRaelEventHandler, 1, &exitRaelEventType, NULL, &exitRaelEventHandlerRef); } if (err == noErr) { - err = CreateEvent(NULL, kExitRaelEvent, kExitRaelEvent, + err = ChkErr(CreateEvent, NULL, kExitRaelEvent, kExitRaelEvent, GetCurrentEventTime(), kEventAttributeNone, &exitRaelEvent); } if (err == noErr) { - err = PostEventToQueue(GetMainEventQueue(), exitRaelEvent, + 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 !"); } } @@ -333,23 +388,24 @@ InstallStandardApplicationEventHandler() * * ExitRaelEventHandlerProc -- * - * This procedure is the dummy event handler used to break out of - * RAEL via longjmp, it is called as the first ever event handler - * in RAEL by posting a high priority dummy event. + * This procedure is the dummy event handler used to break out of + * RAEL via longjmp, it is called as the first ever event handler + * in RAEL by posting a high priority dummy event. * * Results: - * None. Never returns ! + * None. Never returns ! * * Side effects: - * longjmp back to InstallStandardApplicationEventHandler(). + * longjmp back to InstallStandardApplicationEventHandler(). * *---------------------------------------------------------------------- */ static void -ExitRaelEventHandlerProc ( - EventHandlerCallRef callRef, - EventRef event, void *userData) +ExitRaelEventHandlerProc( + EventHandlerCallRef callRef, + EventRef event, + void *userData) { longjmp(exitRaelJmpBuf, 1); } @@ -357,37 +413,57 @@ ExitRaelEventHandlerProc ( /* *---------------------------------------------------------------------- * + * TkMacOSXRunTclEventLoop -- + * + * Process a limited number of tcl events. + * + * Results: + * Returns 1 if events were handled and 0 otherwise. + * + * Side effects: + * Runs the Tcl event loop. + * + *---------------------------------------------------------------------- + */ + +MODULE_SCOPE int +TkMacOSXRunTclEventLoop(void) +{ + int i = 4, result = 0; + + /* Avoid starving main event loop: process at most 4 events. */ + while(--i && Tcl_ServiceAll()) { + result = 1; + } + return result; +} + +/* + *---------------------------------------------------------------------- + * * CarbonTimerProc -- * - * This procedure is the carbon timer handler that runs the tcl - * event loop periodically. It does not process TCL_WINDOW_EVENTS - * to avoid reentry issues with Carbon, nor TCL_IDLE_EVENTS since - * it is only intended to be called during short periods of busy - * time such as during menu tracking. + * This procedure is the carbon timer handler that runs the tcl + * event loop periodically. * * Results: - * None. + * None. * * Side effects: - * Runs the Tcl event loop. + * Runs the Tcl event loop. * *---------------------------------------------------------------------- */ static void -CarbonTimerProc ( - EventLoopTimerRef timer, - void *userData) +CarbonTimerProc( + EventLoopTimerRef timer, + void *userData) { - if(carbonTimerEnabled) { - /* Avoid starving main event loop: process at most 4 events. */ - int i = 4; - while(--i && Tcl_DoOneEvent( - TCL_FILE_EVENTS|TCL_TIMER_EVENTS|TCL_DONT_WAIT)) { -#if defined(TK_MAC_DEBUG) && defined(TK_MAC_DEBUG_CARBON_EVENTS) - fprintf(stderr, "Processed tcl event from carbon timer\n"); + if(carbonTimerEnabled > 0 && TkMacOSXRunTclEventLoop()) { +#ifdef TK_MAC_DEBUG_CARBON_EVENTS + TkMacOSXDbgMsg("Processed tcl events from carbon timer"); #endif /* TK_MAC_DEBUG_CARBON_EVENTS */ - } } } @@ -396,80 +472,183 @@ CarbonTimerProc ( * * TkMacOSXStartTclEventLoopCarbonTimer -- * - * This procedure installs (if necessary) and starts a carbon - * event timer that runs the tcl event loop periodically. - * It should be called whenever a nested carbon event loop is - * run by HIToolbox (e.g. during menutracking) to ensure that - * non-window non-idle tcl events are processed. + * This procedure installs (if necessary) and starts a carbon + * event timer that runs the tcl event loop periodically. + * It should be called whenever a nested carbon event loop might + * run by HIToolbox (e.g. during mouse tracking) to ensure that + * tcl events continue to be processed. * * Results: - * OS status code. + * OS status code. * * Side effects: - * Carbon event timer is installed and started. + * Carbon event timer is installed and started. * *---------------------------------------------------------------------- */ MODULE_SCOPE OSStatus -TkMacOSXStartTclEventLoopCarbonTimer() +TkMacOSXStartTclEventLoopCarbonTimer(void) { - OSStatus err; + OSStatus err = noErr; - if(!carbonTimer) { - EventLoopTimerUPP timerUPP = NewEventLoopTimerUPP(CarbonTimerProc); - err = InstallEventLoopTimer(GetMainEventLoop(), kEventDurationNoWait, - 5 * kEventDurationMillisecond, timerUPP, NULL, &carbonTimer); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr, "InstallEventLoopTimer failed, %d\n", (int) err); -#endif - } - } else { - err = SetEventLoopTimerNextFireTime(carbonTimer, kEventDurationNoWait); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr, "SetEventLoopTimerNextFireTime failed, %d\n", - (int) err); -#endif + if (++carbonTimerEnabled > 0) { + if(!carbonTimer) { + EventLoopTimerUPP timerUPP = NewEventLoopTimerUPP(CarbonTimerProc); + + err = ChkErr(InstallEventLoopTimer, GetMainEventLoop(), + 5 * kEventDurationMillisecond, + 5 * kEventDurationMillisecond, + timerUPP, NULL, &carbonTimer); + } else { + err = ChkErr(SetEventLoopTimerNextFireTime, carbonTimer, + 5 * kEventDurationMillisecond); } } - carbonTimerEnabled = 1; return err; } - + /* *---------------------------------------------------------------------- * * TkMacOSXStopTclEventLoopCarbonTimer -- * - * This procedure stops the carbon event timer started by - * TkMacOSXStartTclEventLoopCarbonTimer(). + * This procedure stops the carbon event timer started by + * TkMacOSXStartTclEventLoopCarbonTimer(). * * Results: - * OS status code. + * OS status code. * * Side effects: - * Carbon event timer is stopped. + * Carbon event timer is stopped. * *---------------------------------------------------------------------- */ MODULE_SCOPE OSStatus -TkMacOSXStopTclEventLoopCarbonTimer() +TkMacOSXStopTclEventLoopCarbonTimer(void) { OSStatus err = noErr; - if(carbonTimer) { - err = SetEventLoopTimerNextFireTime(carbonTimer, kEventDurationForever); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr, "SetEventLoopTimerNextFireTime failed, %d\n", - (int) err); -#endif + if (--carbonTimerEnabled == 0) { + if(carbonTimer) { + err = ChkErr(SetEventLoopTimerNextFireTime, carbonTimer, + kEventDurationForever); } } - carbonTimerEnabled = 0; return err; } +/* + *---------------------------------------------------------------------- + * + * TkMacOSXTrackingLoop -- + * + * Call with 1 before entering a mouse tracking loop (e.g. window + * resizing or menu tracking) to enable tcl event processing but + * disable carbon event processing (except for update events) + * during the loop, and with 0 after exiting the loop to reset. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +MODULE_SCOPE void +TkMacOSXTrackingLoop(int tracking) +{ + static int previousServiceMode = TCL_SERVICE_NONE; + + if (tracking) { + inTrackingLoop++; + previousServiceMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); + TkMacOSXStartTclEventLoopCarbonTimer(); +#ifdef TK_MAC_DEBUG_CARBON_EVENTS + TkMacOSXDbgMsg("Entering tracking loop"); +#endif /* TK_MAC_DEBUG_CARBON_EVENTS */ + } else { + TkMacOSXStopTclEventLoopCarbonTimer(); + previousServiceMode = Tcl_SetServiceMode(previousServiceMode); + inTrackingLoop--; +#ifdef TK_MAC_DEBUG_CARBON_EVENTS + TkMacOSXDbgMsg("Exiting tracking loop"); +#endif /* TK_MAC_DEBUG_CARBON_EVENTS */ + } +} + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXReceiveAndDispatchEvent -- + * + * This receives a carbon event and sends it to the carbon event + * dispatcher. + * + * Results: + * Mac OS status + * + * Side effects: + * This receives and dispatches the next Carbon event. + * + *---------------------------------------------------------------------- + */ +MODULE_SCOPE OSStatus +TkMacOSXReceiveAndDispatchEvent(void) +{ + static EventTargetRef targetRef = NULL; + int numEventTypes = 0; + const EventTypeSpec *eventTypes = NULL; + EventRef eventRef; + OSStatus err; + const EventTypeSpec trackingEventTypes[] = { + {'dniw', kEventWindowUpdate}, + {kEventClassWindow, kEventWindowUpdate}, + }; + + if (inTrackingLoop > 0) { + eventTypes = trackingEventTypes; + numEventTypes = GetEventTypeCount(trackingEventTypes); + } + + /* + * This is a poll, since we have already counted the events coming + * into this routine, and are guaranteed to have one waiting. + */ + + err = ReceiveNextEvent(numEventTypes, eventTypes, + kEventDurationNoWait, true, &eventRef); + if (err == noErr) { +#ifdef TK_MAC_DEBUG_CARBON_EVENTS + UInt32 kind = GetEventKind(eventRef); + + if (kind != kEventMouseMoved && kind != kEventMouseDragged) { + TkMacOSXDbgMsg("Dispatching %s", TkMacOSXCarbonEventToAscii(eventRef)); + TkMacOSXInitNamedDebugSymbol(HIToolbox, void, _DebugPrintEvent, + EventRef inEvent); + if (_DebugPrintEvent) { + /* Carbon-internal event debugging (c.f. Technote 2124) */ + _DebugPrintEvent(eventRef); + } + } +#endif /* TK_MAC_DEBUG_CARBON_EVENTS */ + if (!targetRef) { + targetRef = GetEventDispatcherTarget(); + } + TkMacOSXStartTclEventLoopCarbonTimer(); + err = SendEventToEventTarget(eventRef, targetRef); + TkMacOSXStopTclEventLoopCarbonTimer(); + if (err != noErr && err != eventLoopTimedOutErr + && err != eventNotHandledErr) { + TkMacOSXDbgMsg("SendEventToEventTarget(%s) failed: %ld", + TkMacOSXCarbonEventToAscii(eventRef), err); + } + ReleaseEvent(eventRef); + } else if (err != eventLoopTimedOutErr) { + TkMacOSXDbgMsg("ReceiveNextEvent failed: %ld", err); + } + return err; +} diff --git a/macosx/tkMacOSXClipboard.c b/macosx/tkMacOSXClipboard.c index fb83d02..635d51b 100644 --- a/macosx/tkMacOSXClipboard.c +++ b/macosx/tkMacOSXClipboard.c @@ -1,15 +1,16 @@ /* * tkMacOSXClipboard.c -- * - * This file manages the clipboard for the Tk toolkit. + * This file manages the clipboard for the Tk toolkit. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXClipboard.c,v 1.9 2007/04/21 19:06:37 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXClipboard.c,v 1.10 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" @@ -21,66 +22,66 @@ * * TkSelGetSelection -- * - * Retrieve the specified selection from another process. For - * now, only fetching XA_STRING from CLIPBOARD is supported. - * Eventually other types should be allowed. - * + * Retrieve the specified selection from another process. For + * now, only fetching XA_STRING from CLIPBOARD is supported. + * Eventually other types should be allowed. + * * Results: - * The return value is a standard Tcl return value. - * If an error occurs (such as no selection exists) - * then an error message is left in the interp's result. + * The return value is a standard Tcl return value. + * If an error occurs (such as no selection exists) + * then an error message is left in the interp's result. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ int TkSelGetSelection( - Tcl_Interp *interp, /* Interpreter to use for reporting - * errors. */ - Tk_Window tkwin, /* Window on whose behalf to retrieve - * the selection (determines display - * from which to retrieve). */ - Atom selection, /* Selection to retrieve. */ - Atom target, /* Desired form in which selection - * is to be returned. */ - Tk_GetSelProc *proc, /* Procedure to call to process the - * selection, once it has been retrieved. */ - ClientData clientData) /* Arbitrary value to pass to proc. */ + Tcl_Interp *interp, /* Interpreter to use for reporting errors. */ + Tk_Window tkwin, /* Window on whose behalf to retrieve the + * selection (determines display from which to + * retrieve). */ + Atom selection, /* Selection to retrieve. */ + Atom target, /* Desired form in which selection is to be + * returned. */ + Tk_GetSelProc *proc, /* Procedure to call to process the selection, + * once it has been retrieved. */ + ClientData clientData) /* Arbitrary value to pass to proc. */ { int result; - int err; + OSStatus err; long length; ScrapRef scrapRef; - char * buf; + char *buf; if ((selection == Tk_InternAtom(tkwin, "CLIPBOARD")) - && (target == XA_STRING)) { - /* - * Get the scrap from the Macintosh global clipboard. - */ - - err = GetCurrentScrap(&scrapRef); - if (err != noErr) { - Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), - " GetCurrentScrap failed.", (char *) NULL); - return TCL_ERROR; - } + && (target == XA_STRING)) { + /* + * Get the scrap from the Macintosh global clipboard. + */ + + err = ChkErr(GetCurrentScrap, &scrapRef); + if (err != noErr) { + Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), + " GetCurrentScrap failed.", NULL); + return TCL_ERROR; + } /* * Try UNICODE first */ - err = GetScrapFlavorSize(scrapRef, kScrapFlavorTypeUnicode, &length); - if (err == noErr && length > 0) { + err = ChkErr(GetScrapFlavorSize, scrapRef, kScrapFlavorTypeUnicode, + &length); + if (err == noErr && length > 0) { Tcl_DString ds; char *data; buf = (char *) ckalloc(length + 2); buf[length] = 0; buf[length+1] = 0; /* 2-byte unicode null */ - err = GetScrapFlavorData(scrapRef, kScrapFlavorTypeUnicode, + err = ChkErr(GetScrapFlavorData, scrapRef, kScrapFlavorTypeUnicode, &length, buf); if (err == noErr) { Tcl_DStringInit(&ds); @@ -98,49 +99,49 @@ TkSelGetSelection( } } - err = GetScrapFlavorSize(scrapRef, 'TEXT', &length); - if (err != noErr) { - Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), - " GetScrapFlavorSize failed.", (char *) NULL); - return TCL_ERROR; - } - if (length > 0) { - Tcl_DString encodedText; - char *data; - - buf = (char *) ckalloc(length + 1); + err = ChkErr(GetScrapFlavorSize, scrapRef, 'TEXT', &length); + if (err != noErr) { + Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), + " GetScrapFlavorSize failed.", NULL); + return TCL_ERROR; + } + if (length > 0) { + Tcl_DString encodedText; + char *data; + + buf = (char *) ckalloc(length + 1); buf[length] = 0; - err = GetScrapFlavorData(scrapRef, 'TEXT', &length, buf); - if (err != noErr) { - Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), - " GetScrapFlavorData failed.", (char *) NULL); - return TCL_ERROR; - } - - /* - * Tcl expects '\n' not '\r' as the line break character. - */ - - for (data = buf; *data != '\0'; data++) { - if (*data == '\r') { - *data = '\n'; - } - } - - Tcl_ExternalToUtfDString(TkMacOSXCarbonEncoding, buf, length, - &encodedText); - result = (*proc)(clientData, interp, - Tcl_DStringValue(&encodedText)); - Tcl_DStringFree(&encodedText); - - ckfree(buf); - return result; - } + err = ChkErr(GetScrapFlavorData, scrapRef, 'TEXT', &length, buf); + if (err != noErr) { + Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), + " GetScrapFlavorData failed.", NULL); + return TCL_ERROR; + } + + /* + * Tcl expects '\n' not '\r' as the line break character. + */ + + for (data = buf; *data != '\0'; data++) { + if (*data == '\r') { + *data = '\n'; + } + } + + Tcl_ExternalToUtfDString(TkMacOSXCarbonEncoding, buf, length, + &encodedText); + result = (*proc)(clientData, interp, + Tcl_DStringValue(&encodedText)); + Tcl_DStringFree(&encodedText); + + ckfree(buf); + return result; + } } - + Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), - " selection doesn't exist or form \"", Tk_GetAtomName(tkwin, target), - "\" not defined", (char *) NULL); + " selection doesn't exist or form \"", + Tk_GetAtomName(tkwin, target), "\" not defined", NULL); return TCL_ERROR; } @@ -149,25 +150,25 @@ TkSelGetSelection( * * TkSetSelectionOwner -- * - * This function claims ownership of the specified selection. - * If the selection is CLIPBOARD, then we empty the system - * clipboard. + * This function claims ownership of the specified selection. + * If the selection is CLIPBOARD, then we empty the system + * clipboard. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ void XSetSelectionOwner( - Display* display, /* X Display. */ - Atom selection, /* What selection to own. */ - Window owner, /* Window to be the owner. */ - Time time) /* The current time? */ + Display *display, /* X Display. */ + Atom selection, /* What selection to own. */ + Window owner, /* Window to be the owner. */ + Time time) /* The current time? */ { Tk_Window tkwin; TkDisplay *dispPtr; @@ -180,17 +181,16 @@ XSetSelectionOwner( tkwin = (Tk_Window) TkGetMainInfoList()->winPtr; if (selection == Tk_InternAtom(tkwin, "CLIPBOARD")) { + /* + * Only claim and empty the clipboard if we aren't already the + * owner of the clipboard. + */ - /* - * Only claim and empty the clipboard if we aren't already the - * owner of the clipboard. - */ - - dispPtr = TkGetMainInfoList()->winPtr->dispPtr; - if (dispPtr->clipboardActive) { - return; - } - ClearCurrentScrap(); + dispPtr = TkGetMainInfoList()->winPtr->dispPtr; + if (dispPtr->clipboardActive) { + return; + } + ClearCurrentScrap(); } } @@ -199,23 +199,24 @@ XSetSelectionOwner( * * TkSelUpdateClipboard -- * - * This function is called to force the clipboard to be updated - * after new data is added. On the Mac we don't need to do - * anything. + * This function is called to force the clipboard to be updated + * after new data is added. On the Mac we don't need to do + * anything. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ void TkSelUpdateClipboard( - TkWindow *winPtr, /* Window associated with clipboard. */ - TkClipboardTarget *targetPtr) /* Info about the content. */ + TkWindow *winPtr, /* Window associated with clipboard. */ + TkClipboardTarget *targetPtr) + /* Info about the content. */ { } @@ -224,28 +225,26 @@ TkSelUpdateClipboard( * * TkSelEventProc -- * - * This procedure is invoked whenever a selection-related - * event occurs. + * This procedure is invoked whenever a selection-related + * event occurs. * * Results: - * None. + * None. * * Side effects: - * Lots: depends on the type of event. + * Lots: depends on the type of event. * *-------------------------------------------------------------- */ void TkSelEventProc( - Tk_Window tkwin, /* Window for which event was - * targeted. */ - register XEvent *eventPtr) /* X event: either SelectionClear, - * SelectionRequest, or - * SelectionNotify. */ + Tk_Window tkwin, /* Window for which event was targeted. */ + register XEvent *eventPtr) /* X event: either SelectionClear, + * SelectionRequest, or SelectionNotify. */ { if (eventPtr->type == SelectionClear) { - TkSelClearSelection(tkwin, eventPtr); + TkSelClearSelection(tkwin, eventPtr); } } @@ -254,22 +253,22 @@ TkSelEventProc( * * TkSelPropProc -- * - * This procedure is invoked when property-change events - * occur on windows not known to the toolkit. This is a stub - * function under Windows. + * This procedure is invoked when property-change events + * occur on windows not known to the toolkit. This is a stub + * function under Windows. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ void TkSelPropProc( - register XEvent *eventPtr) /* X PropertyChange event. */ + register XEvent *eventPtr) /* X PropertyChange event. */ { } @@ -278,20 +277,20 @@ TkSelPropProc( * * TkSuspendClipboard -- * - * Handle clipboard conversion as required by the suppend event. - * This function is also called on exit. + * Handle clipboard conversion as required by the suppend event. + * This function is also called on exit. * * Results: - * None. + * None. * * Side effects: - * The local scrap is moved to the global scrap. + * The local scrap is moved to the global scrap. * *---------------------------------------------------------------------- */ void -TkSuspendClipboard() +TkSuspendClipboard(void) { TkClipboardTarget *targetPtr; TkClipboardBuffer *cbPtr; @@ -302,50 +301,50 @@ TkSuspendClipboard() dispPtr = TkGetDisplayList(); if ((dispPtr == NULL) || !dispPtr->clipboardActive) { - return; + return; } for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL; - targetPtr = targetPtr->nextPtr) { - if (targetPtr->type == XA_STRING) - break; + targetPtr = targetPtr->nextPtr) { + if (targetPtr->type == XA_STRING) { + break; + } } if (targetPtr != NULL) { - Tcl_DString encodedText; - Tcl_DString unicodedText; - - length = 0; - for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL; - cbPtr = cbPtr->nextPtr) { - length += cbPtr->length; - } - - buffer = ckalloc(length); - buffPtr = buffer; - for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL; - cbPtr = cbPtr->nextPtr) { - for (p = cbPtr->buffer, endPtr = p + cbPtr->length; - p < endPtr; p++) { - if (*p == '\n') { - *buffPtr++ = '\r'; - } else { - *buffPtr++ = *p; - } - } - } - - ClearCurrentScrap(); - GetCurrentScrap(&scrapRef); - Tcl_UtfToExternalDString(TkMacOSXCarbonEncoding, buffer, - length, &encodedText); - PutScrapFlavor(scrapRef, 'TEXT', 0, - Tcl_DStringLength(&encodedText), - Tcl_DStringValue(&encodedText) ); - Tcl_DStringFree(&encodedText); + Tcl_DString encodedText, unicodedText; + + length = 0; + for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL; + cbPtr = cbPtr->nextPtr) { + length += cbPtr->length; + } + + buffer = ckalloc(length); + buffPtr = buffer; + for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL; + cbPtr = cbPtr->nextPtr) { + for (p = cbPtr->buffer, endPtr = p + cbPtr->length; + p < endPtr; p++) { + if (*p == '\n') { + *buffPtr++ = '\r'; + } else { + *buffPtr++ = *p; + } + } + } + + ClearCurrentScrap(); + GetCurrentScrap(&scrapRef); + Tcl_UtfToExternalDString(TkMacOSXCarbonEncoding, buffer, length, + &encodedText); + PutScrapFlavor(scrapRef, 'TEXT', 0, Tcl_DStringLength(&encodedText), + Tcl_DStringValue(&encodedText)); + Tcl_DStringFree(&encodedText); /* - * Also put unicode data on scrap + * Also put unicode data on scrap. */ + Tcl_DStringInit(&unicodedText); Tcl_UtfToUniCharDString(buffer, length, &unicodedText); PutScrapFlavor(scrapRef, kScrapFlavorTypeUnicode, 0, @@ -353,19 +352,19 @@ TkSuspendClipboard() Tcl_DStringValue(&unicodedText)); Tcl_DStringFree(&unicodedText); - ckfree(buffer); + ckfree(buffer); } /* - * The system now owns the scrap. We tell Tk that it has + * The system now owns the scrap. We tell Tk that it has * lost the selection so that it will look for it the next time - * it needs it. (Window list NULL if quiting.) + * it needs it. (Window list NULL if quiting.) */ if (TkGetMainInfoList() != NULL) { - Tk_ClearSelection((Tk_Window) TkGetMainInfoList()->winPtr, - Tk_InternAtom((Tk_Window) TkGetMainInfoList()->winPtr, - "CLIPBOARD")); + Tk_ClearSelection((Tk_Window) TkGetMainInfoList()->winPtr, + Tk_InternAtom((Tk_Window) TkGetMainInfoList()->winPtr, + "CLIPBOARD")); } return; diff --git a/macosx/tkMacOSXColor.c b/macosx/tkMacOSXColor.c index 9d65ac9..434f0ea 100644 --- a/macosx/tkMacOSXColor.c +++ b/macosx/tkMacOSXColor.c @@ -1,228 +1,527 @@ -/* +/* * tkMacOSXColor.c -- * - * This file maintains a database of color values for the Tk - * toolkit, in order to avoid round-trips to the server to - * map color names to pixel values. + * This file maintains a database of color values for the Tk + * toolkit, in order to avoid round-trips to the server to + * map color names to pixel values. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1996 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.7 2006/11/03 03:05:03 das Exp $ + * RCS: @(#) $Id: tkMacOSXColor.c,v 1.8 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" #include "tkColor.h" -/* Define constants only available on Mac OS X 10.3 or later */ -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 - #define kThemeBrushAlternatePrimaryHighlightColor -5 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 +/* Undocumented CG API for creating CGPattern from CGImage */ +extern CGPatternRef CGPatternCreateWithImage(CGImageRef img, int i) WEAK_IMPORT_ATTRIBUTE; #endif +struct SystemColorMapEntry { + const char *name; + ThemeBrush brush; + ThemeTextColor textColor; + ThemeBackgroundKind background; +}; /* unsigned char pixelCode; */ + /* - * Default Auxillary Control Record for all controls. This is cached once - * and is updated by the system. We use this to get the default system - * colors used by controls. + * Array of system color definitions: the array index is required to equal the + * color's (pixelCode - MIN_PIXELCODE), i.e. the array order needs to be kept + * in sync with the public pixel code values in tkMacOSXPort.h ! */ -/* - * Stubbed out for OS X -static AuxCtlHandle defaultAuxCtlHandle = NULL; -*/ + +#define MIN_PIXELCODE 30 +static const struct SystemColorMapEntry systemColorMap[] = { + { "Transparent", 0, 0, 0 }, /* 30: TRANSPARENT_PIXEL */ + { "Highlight", kThemeBrushPrimaryHighlightColor, 0, 0 }, /* 31: HIGHLIGHT_PIXEL */ + { "HighlightSecondary", kThemeBrushSecondaryHighlightColor, 0, 0 }, /* 32: HIGHLIGHT_SECONDARY_PIXEL */ + { "HighlightText", kThemeBrushBlack, 0, 0 }, /* 33: HIGHLIGHT_TEXT_PIXEL */ + { "HighlightAlternate", kThemeBrushAlternatePrimaryHighlightColor, 0, 0 }, /* 34: HIGHLIGHT_ALTERNATE_PIXEL */ + { "ButtonText", 0, kThemeTextColorPushButtonActive, 0 }, /* 35: CONTROL_TEXT_PIXEL */ + { "PrimaryHighlightColor", kThemeBrushPrimaryHighlightColor, 0, 0 }, /* 36 */ + { "ButtonFace", kThemeBrushButtonFaceActive, 0, 0 }, /* 37: CONTROL_BODY_PIXEL */ + { "SecondaryHighlightColor", kThemeBrushSecondaryHighlightColor, 0, 0 }, /* 38 */ + { "ButtonFrame", kThemeBrushButtonFrameActive, 0, 0 }, /* 39: CONTROL_FRAME_PIXEL */ + { "AlternatePrimaryHighlightColor", kThemeBrushAlternatePrimaryHighlightColor, 0, 0 }, /* 40 */ + { "WindowBody", kThemeBrushDocumentWindowBackground, 0, 0 }, /* 41: WINDOW_BODY_PIXEL */ + { "SheetBackground", kThemeBrushSheetBackground, 0, 0 }, /* 42 */ + { "MenuActive", kThemeBrushMenuBackgroundSelected, 0, 0 }, /* 43: MENU_ACTIVE_PIXEL */ + { "Black", kThemeBrushBlack, 0, 0 }, /* 44 */ + { "MenuActiveText", 0, kThemeTextColorMenuItemSelected, 0 }, /* 45: MENU_ACTIVE_TEXT_PIXEL */ + { "White", kThemeBrushWhite, 0, 0 }, /* 46 */ + { "Menu", kThemeBrushMenuBackground, 0, 0 }, /* 47: MENU_BACKGROUND_PIXEL */ + { "DialogBackgroundActive", kThemeBrushDialogBackgroundActive, 0, 0 }, /* 48 */ + { "MenuDisabled", 0, kThemeTextColorMenuItemDisabled, 0 }, /* 49: MENU_DISABLED_PIXEL */ + { "DialogBackgroundInactive", kThemeBrushDialogBackgroundInactive, 0, 0 }, /* 50 */ + { "MenuText", 0, kThemeTextColorMenuItemActive, 0 }, /* 51: MENU_TEXT_PIXEL */ + { "AppearanceColor", 0, 0, 0 }, /* 52: APPEARANCE_PIXEL */ + { "AlertBackgroundActive", kThemeBrushAlertBackgroundActive, 0, 0 }, /* 53 */ + { "AlertBackgroundInactive", kThemeBrushAlertBackgroundInactive, 0, 0 }, /* 54 */ + { "ModelessDialogBackgroundActive", kThemeBrushModelessDialogBackgroundActive, 0, 0 }, /* 55 */ + { "ModelessDialogBackgroundInactive", kThemeBrushModelessDialogBackgroundInactive, 0, 0 }, /* 56 */ + { "UtilityWindowBackgroundActive", kThemeBrushUtilityWindowBackgroundActive, 0, 0 }, /* 57 */ + { "UtilityWindowBackgroundInactive", kThemeBrushUtilityWindowBackgroundInactive, 0, 0 }, /* 58 */ + { "ListViewSortColumnBackground", kThemeBrushListViewSortColumnBackground, 0, 0 }, /* 59 */ + { "ListViewBackground", kThemeBrushListViewBackground, 0, 0 }, /* 60 */ + { "IconLabelBackground", kThemeBrushIconLabelBackground, 0, 0 }, /* 61 */ + { "ListViewSeparator", kThemeBrushListViewSeparator, 0, 0 }, /* 62 */ + { "ChasingArrows", kThemeBrushChasingArrows, 0, 0 }, /* 63 */ + { "DragHilite", kThemeBrushDragHilite, 0, 0 }, /* 64 */ + { "DocumentWindowBackground", kThemeBrushDocumentWindowBackground, 0, 0 }, /* 65 */ + { "FinderWindowBackground", kThemeBrushFinderWindowBackground, 0, 0 }, /* 66 */ + { "ScrollBarDelimiterActive", kThemeBrushScrollBarDelimiterActive, 0, 0 }, /* 67 */ + { "ScrollBarDelimiterInactive", kThemeBrushScrollBarDelimiterInactive, 0, 0 }, /* 68 */ + { "FocusHighlight", kThemeBrushFocusHighlight, 0, 0 }, /* 69 */ + { "PopupArrowActive", kThemeBrushPopupArrowActive, 0, 0 }, /* 70 */ + { "PopupArrowPressed", kThemeBrushPopupArrowPressed, 0, 0 }, /* 71 */ + { "PopupArrowInactive", kThemeBrushPopupArrowInactive, 0, 0 }, /* 72 */ + { "AppleGuideCoachmark", kThemeBrushAppleGuideCoachmark, 0, 0 }, /* 73 */ + { "IconLabelBackgroundSelected", kThemeBrushIconLabelBackgroundSelected, 0, 0 }, /* 74 */ + { "StaticAreaFill", kThemeBrushStaticAreaFill, 0, 0 }, /* 75 */ + { "ActiveAreaFill", kThemeBrushActiveAreaFill, 0, 0 }, /* 76 */ + { "ButtonFrameActive", kThemeBrushButtonFrameActive, 0, 0 }, /* 77 */ + { "ButtonFrameInactive", kThemeBrushButtonFrameInactive, 0, 0 }, /* 78 */ + { "ButtonFaceActive", kThemeBrushButtonFaceActive, 0, 0 }, /* 79 */ + { "ButtonFaceInactive", kThemeBrushButtonFaceInactive, 0, 0 }, /* 80 */ + { "ButtonFacePressed", kThemeBrushButtonFacePressed, 0, 0 }, /* 81 */ + { "ButtonActiveDarkShadow", kThemeBrushButtonActiveDarkShadow, 0, 0 }, /* 82 */ + { "ButtonActiveDarkHighlight", kThemeBrushButtonActiveDarkHighlight, 0, 0 }, /* 83 */ + { "ButtonActiveLightShadow", kThemeBrushButtonActiveLightShadow, 0, 0 }, /* 84 */ + { "ButtonActiveLightHighlight", kThemeBrushButtonActiveLightHighlight, 0, 0 }, /* 85 */ + { "ButtonInactiveDarkShadow", kThemeBrushButtonInactiveDarkShadow, 0, 0 }, /* 86 */ + { "ButtonInactiveDarkHighlight", kThemeBrushButtonInactiveDarkHighlight, 0, 0 }, /* 87 */ + { "ButtonInactiveLightShadow", kThemeBrushButtonInactiveLightShadow, 0, 0 }, /* 88 */ + { "ButtonInactiveLightHighlight", kThemeBrushButtonInactiveLightHighlight, 0, 0 }, /* 89 */ + { "ButtonPressedDarkShadow", kThemeBrushButtonPressedDarkShadow, 0, 0 }, /* 90 */ + { "ButtonPressedDarkHighlight", kThemeBrushButtonPressedDarkHighlight, 0, 0 }, /* 91 */ + { "ButtonPressedLightShadow", kThemeBrushButtonPressedLightShadow, 0, 0 }, /* 92 */ + { "ButtonPressedLightHighlight", kThemeBrushButtonPressedLightHighlight, 0, 0 }, /* 93 */ + { "BevelActiveLight", kThemeBrushBevelActiveLight, 0, 0 }, /* 94 */ + { "BevelActiveDark", kThemeBrushBevelActiveDark, 0, 0 }, /* 95 */ + { "BevelInactiveLight", kThemeBrushBevelInactiveLight, 0, 0 }, /* 96 */ + { "BevelInactiveDark", kThemeBrushBevelInactiveDark, 0, 0 }, /* 97 */ + { "NotificationWindowBackground", kThemeBrushNotificationWindowBackground, 0, 0 }, /* 98 */ + { "MovableModalBackground", kThemeBrushMovableModalBackground, 0, 0 }, /* 99 */ + { "SheetBackgroundOpaque", kThemeBrushSheetBackgroundOpaque, 0, 0 }, /* 100 */ + { "DrawerBackground", kThemeBrushDrawerBackground, 0, 0 }, /* 101 */ + { "ToolbarBackground", kThemeBrushToolbarBackground, 0, 0 }, /* 102 */ + { "SheetBackgroundTransparent", kThemeBrushSheetBackgroundTransparent, 0, 0 }, /* 103 */ + { "MenuBackground", kThemeBrushMenuBackground, 0, 0 }, /* 104 */ + { "Pixel", 0, 0, 0 }, /* 105: PIXEL_MAGIC */ + { "MenuBackgroundSelected", kThemeBrushMenuBackgroundSelected, 0, 0 }, /* 106 */ + { "ListViewOddRowBackground", kThemeBrushListViewOddRowBackground, 0, 0 }, /* 107 */ + { "ListViewEvenRowBackground", kThemeBrushListViewEvenRowBackground, 0, 0 }, /* 108 */ + { "ListViewColumnDivider", kThemeBrushListViewColumnDivider, 0, 0 }, /* 109 */ + { "BlackText", 0, kThemeTextColorBlack, 0 }, /* 110 */ + { "DialogActiveText", 0, kThemeTextColorDialogActive, 0 }, /* 111 */ + { "DialogInactiveText", 0, kThemeTextColorDialogInactive, 0 }, /* 112 */ + { "AlertActiveText", 0, kThemeTextColorAlertActive, 0 }, /* 113 */ + { "AlertInactiveText", 0, kThemeTextColorAlertInactive, 0 }, /* 114 */ + { "ModelessDialogActiveText", 0, kThemeTextColorModelessDialogActive, 0 }, /* 115 */ + { "ModelessDialogInactiveText", 0, kThemeTextColorModelessDialogInactive, 0 }, /* 116 */ + { "WindowHeaderActiveText", 0, kThemeTextColorWindowHeaderActive, 0 }, /* 117 */ + { "WindowHeaderInactiveText", 0, kThemeTextColorWindowHeaderInactive, 0 }, /* 118 */ + { "PlacardActiveText", 0, kThemeTextColorPlacardActive, 0 }, /* 119 */ + { "PlacardInactiveText", 0, kThemeTextColorPlacardInactive, 0 }, /* 120 */ + { "PlacardPressedText", 0, kThemeTextColorPlacardPressed, 0 }, /* 121 */ + { "PushButtonActiveText", 0, kThemeTextColorPushButtonActive, 0 }, /* 122 */ + { "PushButtonInactiveText", 0, kThemeTextColorPushButtonInactive, 0 }, /* 123 */ + { "PushButtonPressedText", 0, kThemeTextColorPushButtonPressed, 0 }, /* 124 */ + { "BevelButtonActiveText", 0, kThemeTextColorBevelButtonActive, 0 }, /* 125 */ + { "BevelButtonInactiveText", 0, kThemeTextColorBevelButtonInactive, 0 }, /* 126 */ + { "BevelButtonPressedText", 0, kThemeTextColorBevelButtonPressed, 0 }, /* 127 */ + { "PopupButtonActiveText", 0, kThemeTextColorPopupButtonActive, 0 }, /* 128 */ + { "PopupButtonInactiveText", 0, kThemeTextColorPopupButtonInactive, 0 }, /* 129 */ + { "PopupButtonPressedText", 0, kThemeTextColorPopupButtonPressed, 0 }, /* 130 */ + { "IconLabelText", 0, kThemeTextColorIconLabel, 0 }, /* 131 */ + { "ListViewText", 0, kThemeTextColorListView, 0 }, /* 132 */ + { "DocumentWindowTitleActiveText", 0, kThemeTextColorDocumentWindowTitleActive, 0 }, /* 133 */ + { "DocumentWindowTitleInactiveText", 0, kThemeTextColorDocumentWindowTitleInactive, 0 }, /* 134 */ + { "MovableModalWindowTitleActiveText", 0, kThemeTextColorMovableModalWindowTitleActive, 0 }, /* 135 */ + { "MovableModalWindowTitleInactiveText",0, kThemeTextColorMovableModalWindowTitleInactive, 0 }, /* 136 */ + { "UtilityWindowTitleActiveText", 0, kThemeTextColorUtilityWindowTitleActive, 0 }, /* 137 */ + { "UtilityWindowTitleInactiveText", 0, kThemeTextColorUtilityWindowTitleInactive, 0 }, /* 138 */ + { "PopupWindowTitleActiveText", 0, kThemeTextColorPopupWindowTitleActive, 0 }, /* 139 */ + { "PopupWindowTitleInactiveText", 0, kThemeTextColorPopupWindowTitleInactive, 0 }, /* 140 */ + { "RootMenuActiveText", 0, kThemeTextColorRootMenuActive, 0 }, /* 141 */ + { "RootMenuSelectedText", 0, kThemeTextColorRootMenuSelected, 0 }, /* 142 */ + { "RootMenuDisabledText", 0, kThemeTextColorRootMenuDisabled, 0 }, /* 143 */ + { "MenuItemActiveText", 0, kThemeTextColorMenuItemActive, 0 }, /* 144 */ + { "MenuItemSelectedText", 0, kThemeTextColorMenuItemSelected, 0 }, /* 145 */ + { "MenuItemDisabledText", 0, kThemeTextColorMenuItemDisabled, 0 }, /* 146 */ + { "PopupLabelActiveText", 0, kThemeTextColorPopupLabelActive, 0 }, /* 147 */ + { "PopupLabelInactiveText", 0, kThemeTextColorPopupLabelInactive, 0 }, /* 148 */ + { "TabFrontActiveText", 0, kThemeTextColorTabFrontActive, 0 }, /* 149 */ + { "TabNonFrontActiveText", 0, kThemeTextColorTabNonFrontActive, 0 }, /* 150 */ + { "TabNonFrontPressedText", 0, kThemeTextColorTabNonFrontPressed, 0 }, /* 151 */ + { "TabFrontInactiveText", 0, kThemeTextColorTabFrontInactive, 0 }, /* 152 */ + { "TabNonFrontInactiveText", 0, kThemeTextColorTabNonFrontInactive, 0 }, /* 153 */ + { "IconLabelSelectedText", 0, kThemeTextColorIconLabelSelected, 0 }, /* 154 */ + { "BevelButtonStickyActiveText", 0, kThemeTextColorBevelButtonStickyActive, 0 }, /* 155 */ + { "BevelButtonStickyInactiveText", 0, kThemeTextColorBevelButtonStickyInactive, 0 }, /* 156 */ + { "NotificationText", 0, kThemeTextColorNotification, 0 }, /* 157 */ + { "SystemDetailText", 0, kThemeTextColorSystemDetail, 0 }, /* 158 */ + { "WhiteText", 0, kThemeTextColorWhite, 0 }, /* 159 */ + { "TabPaneBackground", 0, 0, kThemeBackgroundTabPane }, /* 160 */ + { "PlacardBackground", 0, 0, kThemeBackgroundPlacard }, /* 161 */ + { "WindowHeaderBackground", 0, 0, kThemeBackgroundWindowHeader }, /* 162 */ + { "ListViewWindowHeaderBackground", 0, 0, kThemeBackgroundListViewWindowHeader }, /* 163 */ + { "SecondaryGroupBoxBackground", 0, 0, kThemeBackgroundSecondaryGroupBox }, /* 164 */ + { "MetalBackground", 0, 0, kThemeBackgroundMetal }, /* 165 */ + { NULL, 0, 0, 0 } +}; +#define MAX_PIXELCODE 165 /* - * Forward declarations for procedures defined later in this file: + *---------------------------------------------------------------------- + * + * GetThemeFromPixelCode -- + * + * When given a pixel code corresponding to a theme system color, + * set one of brush, textColor or background to the corresponding + * Appearance Mgr theme constant. + * + * Results: + * Returns false if not a real pixel, true otherwise. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- */ -static int GetControlPartColor _ANSI_ARGS_((short part, RGBColor *macColor)); -static int GetMenuPartColor _ANSI_ARGS_((int part, RGBColor *macColor)); -static int GetWindowPartColor _ANSI_ARGS_((short part, RGBColor *macColor)); +static int +GetThemeFromPixelCode(unsigned char code, ThemeBrush *brush, + ThemeTextColor *textColor, ThemeBackgroundKind *background) +{ + if (code >= MIN_PIXELCODE && code <= MAX_PIXELCODE && code != PIXEL_MAGIC) { + *brush = systemColorMap[code - MIN_PIXELCODE].brush; + *textColor = systemColorMap[code - MIN_PIXELCODE].textColor; + *background = systemColorMap[code - MIN_PIXELCODE].background; + } else { + *brush = 0; + *textColor = 0; + *background = 0; + } + if (!*brush && !*textColor && !*background && code != PIXEL_MAGIC) { + return false; + } else { + return true; + } +} /* *---------------------------------------------------------------------- * - * TkSetMacColor -- + * GetThemeColor -- * - * Populates a Macintosh RGBColor structure from a X style - * pixel value. + * Get RGB color for a given system color or pixel value. * * Results: - * Returns false if not a real pixel, true otherwise. + * OSStatus * * Side effects: - * The variable macColor is updated to the pixels value. + * None. * *---------------------------------------------------------------------- */ -int -TkSetMacColor( - unsigned long pixel, /* Pixel value to convert. */ - RGBColor *macColor) /* Mac color struct to modify. */ +static OSStatus +GetThemeColor(unsigned long pixel, ThemeBrush brush, ThemeTextColor textColor, + ThemeBackgroundKind background, RGBColor *c) { - OSStatus err; + OSStatus err = noErr; - switch (pixel >> 24) { - case HIGHLIGHT_PIXEL: - err = GetThemeBrushAsColor(kThemeBrushPrimaryHighlightColor, - 32, true, macColor); - if (err != noErr) { - LMGetHiliteRGB(macColor); - } - return true; - case HIGHLIGHT_SECONDARY_PIXEL: - err = GetThemeBrushAsColor(kThemeBrushSecondaryHighlightColor, - 32, true, macColor); - if (err != noErr) { - LMGetHiliteRGB(macColor); - } - return true; - case HIGHLIGHT_ALTERNATE_PIXEL: - err = GetThemeBrushAsColor(kThemeBrushAlternatePrimaryHighlightColor, - 32, true, macColor); - if (err != noErr) { - LMGetHiliteRGB(macColor); - } - return true; - case HIGHLIGHT_TEXT_PIXEL: - err = GetThemeBrushAsColor(kThemeBrushPrimaryHighlightColor, - 32, true, macColor); - if (err != noErr) { - LMGetHiliteRGB(macColor); - } - if ((macColor->red == 0) && (macColor->green == 0) - && (macColor->blue == 0)) { - macColor->red = macColor->green = macColor->blue = 0xFFFF; - } else { - macColor->red = macColor->green = macColor->blue = 0; - } - return true; - case CONTROL_TEXT_PIXEL: - GetControlPartColor(cTextColor, macColor); - return true; - case CONTROL_BODY_PIXEL: - GetControlPartColor(cBodyColor, macColor); - return true; - case CONTROL_FRAME_PIXEL: - GetControlPartColor(cFrameColor, macColor); - return true; - case WINDOW_BODY_PIXEL: - GetWindowPartColor(wContentColor, macColor); - return true; - case MENU_ACTIVE_PIXEL: - case MENU_ACTIVE_TEXT_PIXEL: - case MENU_BACKGROUND_PIXEL: - case MENU_DISABLED_PIXEL: - case MENU_TEXT_PIXEL: - return GetMenuPartColor((pixel >> 24), macColor); - case APPEARANCE_PIXEL: - return false; - case PIXEL_MAGIC: - default: - macColor->blue = (unsigned short) ((pixel & 0xFF) << 8); - macColor->green = (unsigned short) (((pixel >> 8) & 0xFF) << 8); - macColor->red = (unsigned short) (((pixel >> 16) & 0xFF) << 8); - return true; + if (brush) { + err = ChkErr(GetThemeBrushAsColor, + brush == kThemeBrushMenuBackgroundSelected ? + kThemeBrushFocusHighlight : brush, 32, true, c); + } 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; } + return err; } -#if !TK_DRAW_IN_CONTEXT /* *---------------------------------------------------------------------- * - * TkMacOSXCompareColors -- + * TkSetMacColor -- * - * 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". + * Populates a Macintosh RGBColor structure from a X style + * pixel value. * * Results: - * Returns true if both colors are the same, false otherwise. + * Returns false if not a real pixel, true otherwise. * * Side effects: - * None. + * The variable macColor is updated to the pixels value. * *---------------------------------------------------------------------- */ int -TkMacOSXCompareColors( - unsigned long c1, - unsigned long c2) +TkSetMacColor( + unsigned long pixel, /* Pixel value to convert. */ + RGBColor *macColor) /* Mac color struct to modify. */ { - RGBColor col1, col2; - return TkSetMacColor(c1,&col1) && - TkSetMacColor(c1,&col2) && - !memcmp(&col1,&col2,sizeof(col1)); + OSStatus err = -1; + ThemeBrush brush; + ThemeTextColor textColor; + ThemeBackgroundKind background; + + if (GetThemeFromPixelCode((pixel >> 24) & 0xff, &brush, &textColor, + &background)) { + err = ChkErr(GetThemeColor, pixel, brush, textColor, background, + macColor); + } + return (err == noErr); } -#endif /* !TK_DRAW_IN_CONTEXT */ /* *---------------------------------------------------------------------- * - * Stub functions -- + * TkMacOSXSetColorInPort -- * - * These functions are just stubs for functions that either - * don't make sense on the Mac or have yet to be implemented. + * Sets fore or back color in the current QD port from an X pixel + * value, and if the pixel code indicates a system color, sets + * the corresponding brush, textColor or background via + * Appearance mgr APIs. * * Results: - * None. + * None. * * Side effects: - * These calls do nothing - which may not be expected. + * If penPat is non-NULL it is set to the forground color/pattern. * *---------------------------------------------------------------------- */ -Status -XAllocColor( - Display *display, /* Display. */ - Colormap map, /* Not used. */ - XColor *colorPtr) /* XColor struct to modify. */ +void +TkMacOSXSetColorInPort(unsigned long pixel, int fg, PixPatHandle penPat) { - display->request++; - colorPtr->pixel = TkpGetPixel(colorPtr); - return 1; -} + OSStatus err; + RGBColor c; + ThemeBrush brush; + ThemeTextColor textColor; + ThemeBackgroundKind background; -Colormap -XCreateColormap( - Display *display, /* Display. */ - Window window, /* X window. */ - Visual *visual, /* Not used. */ - int alloc) /* Not used. */ -{ - static Colormap index = 1; - - /* - * Just return a new value each time. - */ - return index++; -} + if (GetThemeFromPixelCode((pixel >> 24) & 0xff, &brush, &textColor, + &background)) { + CGrafPtr port; -void -XFreeColormap( - Display* display, /* Display. */ - Colormap colormap) /* Colormap. */ -{ + GetPort(&port); + err = ChkErr(GetThemeColor, pixel, brush, textColor, background, &c); + if (err == noErr) { + if (fg) { + RGBForeColor(&c); + if (penPat) { + MakeRGBPat(penPat, &c); + } + } else { + RGBBackColor(&c); + } + } + err = -1; + if (brush) { + err = ChkErr(SetThemeBackground, + brush == kThemeBrushMenuBackgroundSelected ? + kThemeBrushFocusHighlight : brush, 32, true); + } else if (textColor && fg) { + err = ChkErr(SetThemeTextColor, textColor, 32, true); + } else if (background) { + Rect bounds; + + GetPortBounds(port, &bounds); + err = ChkErr(ApplyThemeBackground, background, &bounds, + kThemeStateActive, 32, true); + } + if (penPat && err == noErr && !textColor) { + GetPortBackPixPat(port, penPat); + } + } } + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXSetColorInContext -- + * + * Sets fill and stroke color in the given CG context from an X + * pixel value, or if the pixel code indicates a system color, + * sets the corresponding brush, textColor or background via + * HITheme APIs if available or Appearance mgr APIs. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ void -XFreeColors( - Display* display, /* Display. */ - Colormap colormap, /* Colormap. */ - unsigned long* pixels, /* Array of pixels. */ - int npixels, /* Number of pixels. */ - unsigned long planes) /* Number of pixel planes. */ +TkMacOSXSetColorInContext(unsigned long pixel, CGContextRef context) { - /* - * The Macintosh version of Tk uses TrueColor. Nothing - * needs to be done to release colors as there really is - * no colormap in the Tk sense. - */ + OSStatus err = -1; + RGBColor c; + ThemeBrush brush; + ThemeTextColor textColor; + ThemeBackgroundKind background; + + if (GetThemeFromPixelCode((pixel >> 24) & 0xff, &brush, &textColor, + &background)) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 + if (brush) { + if (1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + && HIThemeSetFill != NULL && HIThemeSetStroke != NULL +#endif + ) { + err = ChkErr(HIThemeSetFill, brush, NULL, context, + kHIThemeOrientationNormal); + if (err == noErr) { + err = ChkErr(HIThemeSetStroke, brush, NULL, context, + kHIThemeOrientationNormal); + } + } + } else if (textColor) { + if (1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + && HIThemeSetTextFill != NULL +#endif + ) { + err = ChkErr(HIThemeSetTextFill, textColor, NULL, context, + kHIThemeOrientationNormal); + } + } else +#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 */ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + if (background) { + if (1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1030 + && CGContextGetClipBoundingBox != NULL + && HIThemeApplyBackground != NULL + && &kHIToolboxVersionNumber != NULL /* c.f. QA1377 */ + && kHIToolboxVersionNumber >= kHIToolboxVersionNumber10_3 +#endif + ) { + CGRect rect = CGContextGetClipBoundingBox(context); + HIThemeBackgroundDrawInfo info = { 0, kThemeStateActive, + background }; + + err = ChkErr(HIThemeApplyBackground, &rect, &info, context, + kHIThemeOrientationNormal); + } + } +#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */ + if (err == noErr) { + return; + } +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + /* + * Convert Appearance theme pattern to CGPattern: + */ + if ((brush || background) && CGPatternCreateWithImage != NULL) { + static PixPatHandle pixpat = NULL; + static GWorldPtr patGWorld = NULL; + static uint32_t bitmapInfo = 0; + const short patDim = 16; + const Rect bounds = {0, 0, patDim, patDim}; + CGrafPtr savePort; + Boolean portChanged; + PixMapHandle pixmap; + long rowbytes; + CGImageRef img; + CGColorSpaceRef rgbCspace; + CGDataProviderRef provider; + + if (!pixpat) { + pixpat = NewPixPat(); + err = ChkErr(NewGWorld, &patGWorld, 32, &bounds, NULL, NULL, 0 +#ifdef __LITTLE_ENDIAN__ + | kNativeEndianPixMap +#endif + ); + if (!pixpat || err != noErr || !patGWorld) { + Tcl_Panic("TkMacOSXSetColorInContext(): " + "pattern initialization failed !"); + } + bitmapInfo = +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 + (1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + && &kHIToolboxVersionNumber != NULL + && kHIToolboxVersionNumber >= kHIToolboxVersionNumber10_4 +#endif + ) ? kCGBitmapByteOrder32Host : +#endif + 0; + } + portChanged = QDSwapPort(patGWorld, &savePort); + TkMacOSXSetColorInPort(pixel, 1, pixpat); +#ifdef TK_MAC_DEBUG + Rect patBounds; + GetPixBounds((**pixpat).patMap, &patBounds); + if (patBounds.right > patDim || patBounds.bottom > patDim) { + Tcl_Panic("TkMacOSXSetColorInContext(): " + "pattern larger than expected !"); + } +#endif /* TK_MAC_DEBUG */ + FillCRect(&bounds, pixpat); + if (portChanged) { + QDSwapPort(savePort, NULL); + } + pixmap = GetPortPixMap(patGWorld); + rowbytes = GetPixRowBytes(pixmap); + provider = CGDataProviderCreateWithData(&patGWorld, + GetPixBaseAddr(pixmap), rowbytes * patDim, NULL); + rgbCspace = CGColorSpaceCreateDeviceRGB(); + img = CGImageCreate(patDim, patDim, 8, 32, + rowbytes, rgbCspace, kCGImageAlphaFirst | bitmapInfo, + provider, NULL, 0, kCGRenderingIntentDefault); + CGColorSpaceRelease(rgbCspace); + CGDataProviderRelease(provider); + if (img) { + CGPatternRef pat = CGPatternCreateWithImage(img, 2); + CGColorSpaceRef patCSpace = CGColorSpaceCreatePattern(NULL); + const float alpha = 1; + + CGContextSetFillColorSpace(context, patCSpace); + CGContextSetFillPattern(context, pat, &alpha); + CGContextSetStrokeColorSpace(context, patCSpace); + CGContextSetStrokePattern(context, pat, &alpha); + CGColorSpaceRelease(patCSpace); + CGPatternRelease(pat); + CGImageRelease(img); + return; + } + } +#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1040 */ + err = ChkErr(GetThemeColor, pixel, brush, textColor, background, &c); + if (err == noErr) { + double r = c.red / 65535.0; + double g = c.green / 65535.0; + double b = c.blue / 65535.0; + + CGContextSetRGBFillColor(context, r, g, b, 1.0); + CGContextSetRGBStrokeColor(context, r, g, b, 1.0); + } + } else if (((pixel >> 24) & 0xff) == TRANSPARENT_PIXEL) { + CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 0.0); + CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 0.0); + } } /* @@ -230,24 +529,24 @@ XFreeColors( * * TkpGetColor -- * - * Allocate a new TkColor for the color with the given name. + * Allocate a new TkColor for the color with the given name. * * Results: - * Returns a newly allocated TkColor, or NULL on failure. + * Returns a newly allocated TkColor, or NULL on failure. * * Side effects: - * May invalidate the colormap cache associated with tkwin upon - * allocating a new colormap entry. Allocates a new TkColor - * structure. + * May invalidate the colormap cache associated with tkwin upon + * allocating a new colormap entry. Allocates a new TkColor + * structure. * *---------------------------------------------------------------------- */ TkColor * TkpGetColor( - Tk_Window tkwin, /* Window in which color will be used. */ - Tk_Uid name) /* Name of color to allocated (in form - * suitable for passing to XParseColor). */ + Tk_Window tkwin, /* Window in which color will be used. */ + Tk_Uid name) /* Name of color to allocated (in form + * suitable for passing to XParseColor). */ { Display *display = Tk_Display(tkwin); Colormap colormap = Tk_Colormap(tkwin); @@ -255,116 +554,43 @@ TkpGetColor( XColor color; /* - * Check to see if this is a system color. Otherwise, XParseColor + * Check to see if this is a system color. Otherwise, XParseColor * will do all the work. */ if (strncasecmp(name, "system", 6) == 0) { - OSStatus err; - int foundSystemColor = false; - RGBColor rgbValue; - char pixelCode = 0; - - if (!strcasecmp(name+6, "Highlight")) { - err = GetThemeBrushAsColor(kThemeBrushPrimaryHighlightColor, - 32, true, &rgbValue); - if (err != noErr) { - LMGetHiliteRGB(&rgbValue); - } - pixelCode = HIGHLIGHT_PIXEL; - foundSystemColor = true; - } else if (!strcasecmp(name+6, "HighlightSecondary")) { - err = GetThemeBrushAsColor(kThemeBrushSecondaryHighlightColor, - 32, true, &rgbValue); - if (err != noErr) { - LMGetHiliteRGB(&rgbValue); - } - pixelCode = HIGHLIGHT_SECONDARY_PIXEL; - foundSystemColor = true; - } else if (!strcasecmp(name+6, "HighlightAlternate")) { - err = GetThemeBrushAsColor(kThemeBrushAlternatePrimaryHighlightColor, - 32, true, &rgbValue); - if (err != noErr) { - LMGetHiliteRGB(&rgbValue); - } - pixelCode = HIGHLIGHT_ALTERNATE_PIXEL; - foundSystemColor = true; - } else if (!strcasecmp(name+6, "HighlightText")) { - err = GetThemeBrushAsColor(kThemeBrushPrimaryHighlightColor, - 32, true, &rgbValue); - if (err != noErr) { - LMGetHiliteRGB(&rgbValue); + Tcl_Obj *strPtr = Tcl_NewStringObj(name+6, -1); + int idx, result; + + result = Tcl_GetIndexFromObjStruct(NULL, strPtr, systemColorMap, + sizeof(struct SystemColorMapEntry), NULL, TCL_EXACT, &idx); + Tcl_DecrRefCount(strPtr); + if (result == TCL_OK) { + OSStatus err; + RGBColor c; + unsigned char pixelCode = idx + MIN_PIXELCODE; + ThemeBrush brush = systemColorMap[idx].brush; + ThemeTextColor textColor = systemColorMap[idx].textColor; + ThemeBackgroundKind background = systemColorMap[idx].background; + + err = ChkErr(GetThemeColor, 0, brush, textColor, background, &c); + if (err == noErr) { + color.red = c.red; + color.green = c.green; + color.blue = c.blue; + color.pixel = ((((((pixelCode << 8) + | ((color.red >> 8) & 0xff)) << 8) + | ((color.green >> 8) & 0xff)) << 8) + | ((color.blue >> 8) & 0xff)); + goto validXColor; } - if ((rgbValue.red == 0) && (rgbValue.green == 0) - && (rgbValue.blue == 0)) { - rgbValue.red = rgbValue.green = rgbValue.blue = 0xFFFF; - } else { - rgbValue.red = rgbValue.green = rgbValue.blue = 0; - } - pixelCode = HIGHLIGHT_TEXT_PIXEL; - foundSystemColor = true; - } else if (!strcasecmp(name+6, "ButtonText")) { - GetControlPartColor(cTextColor, &rgbValue); - pixelCode = CONTROL_TEXT_PIXEL; - foundSystemColor = true; - } else if (!strcasecmp(name+6, "ButtonFace")) { - GetControlPartColor(cBodyColor, &rgbValue); - pixelCode = CONTROL_BODY_PIXEL; - foundSystemColor = true; - } else if (!strcasecmp(name+6, "ButtonFrame")) { - GetControlPartColor(cFrameColor, &rgbValue); - pixelCode = CONTROL_FRAME_PIXEL; - foundSystemColor = true; - } else if (!strcasecmp(name+6, "WindowBody")) { - GetWindowPartColor(wContentColor, &rgbValue); - pixelCode = WINDOW_BODY_PIXEL; - foundSystemColor = true; - } else if (!strcasecmp(name+6, "MenuActive")) { - GetMenuPartColor(MENU_ACTIVE_PIXEL, &rgbValue); - pixelCode = MENU_ACTIVE_PIXEL; - foundSystemColor = true; - } else if (!strcasecmp(name+6, "MenuActiveText")) { - GetMenuPartColor(MENU_ACTIVE_TEXT_PIXEL, &rgbValue); - pixelCode = MENU_ACTIVE_TEXT_PIXEL; - foundSystemColor = true; - } else if (!strcasecmp(name+6, "Menu")) { - GetMenuPartColor(MENU_BACKGROUND_PIXEL, &rgbValue); - pixelCode = MENU_BACKGROUND_PIXEL; - foundSystemColor = true; - } else if (!strcasecmp(name+6, "MenuDisabled")) { - GetMenuPartColor(MENU_DISABLED_PIXEL, &rgbValue); - pixelCode = MENU_DISABLED_PIXEL; - foundSystemColor = true; - } else if (!strcasecmp(name+6, "MenuText")) { - GetMenuPartColor(MENU_TEXT_PIXEL, &rgbValue); - pixelCode = MENU_TEXT_PIXEL; - foundSystemColor = true; - } else if (!strcasecmp(name+6, "AppearanceColor")) { - color.red = 0; - color.green = 0; - color.blue = 0; - pixelCode = APPEARANCE_PIXEL; - foundSystemColor = true; - } - - if (foundSystemColor) { - color.red = rgbValue.red; - color.green = rgbValue.green; - color.blue = rgbValue.blue; - color.pixel = ((((((pixelCode << 8) - | ((color.red >> 8) & 0xff)) << 8) - | ((color.green >> 8) & 0xff)) << 8) - | ((color.blue >> 8) & 0xff)); - - tkColPtr = (TkColor *) ckalloc(sizeof(TkColor)); - tkColPtr->color = color; - return tkColPtr; - } + } } - + if (XParseColor(display, colormap, name, &color) == 0) { - return (TkColor *) NULL; + return (TkColor *) NULL; } - + +validXColor: tkColPtr = (TkColor *) ckalloc(sizeof(TkColor)); tkColPtr->color = color; @@ -376,28 +602,28 @@ TkpGetColor( * * TkpGetColorByValue -- * - * Given a desired set of red-green-blue intensities for a color, - * locate a pixel value to use to draw that color in a given - * window. + * Given a desired set of red-green-blue intensities for a color, + * locate a pixel value to use to draw that color in a given + * window. * * Results: - * The return value is a pointer to an TkColor structure that - * indicates the closest red, blue, and green intensities available - * to those specified in colorPtr, and also specifies a pixel - * value to use to draw in that color. + * The return value is a pointer to an TkColor structure that + * indicates the closest red, blue, and green intensities available + * to those specified in colorPtr, and also specifies a pixel + * value to use to draw in that color. * * Side effects: - * May invalidate the colormap cache for the specified window. - * Allocates a new TkColor structure. + * May invalidate the colormap cache for the specified window. + * Allocates a new TkColor structure. * *---------------------------------------------------------------------- */ TkColor * TkpGetColorByValue( - Tk_Window tkwin, /* Window in which color will be used. */ - XColor *colorPtr) /* Red, green, and blue fields indicate - * desired color. */ + Tk_Window tkwin, /* Window in which color will be used. */ + XColor *colorPtr) /* Red, green, and blue fields indicate + * desired color. */ { TkColor *tkColPtr = (TkColor *) ckalloc(sizeof(TkColor)); @@ -408,123 +634,98 @@ TkpGetColorByValue( return tkColPtr; } +#if !TK_DRAW_IN_CONTEXT /* *---------------------------------------------------------------------- * - * GetControlPartColor -- + * TkMacOSXCompareColors -- * - * Given a part number this function will return the standard - * system default color for that part. On MacOS X this uses the - * Theme Brushes to find the active color, though for now, only - * the "Text Color" is supported. + * 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: - * True if a color is found, false otherwise. + * Returns true if both colors are the same, false otherwise. * * Side effects: - * If a color is found then the RGB variable will be changed to - * the parts color. + * None. * *---------------------------------------------------------------------- */ -static int -GetControlPartColor( - short part, /* Part code. */ - RGBColor *macColor) /* Pointer to Mac color. */ +int +TkMacOSXCompareColors( + unsigned long c1, + unsigned long c2) { - int retVal = false; - OSErr err; - - switch (part) { - case cTextColor: - err = GetThemeTextColor(kThemeTextColorPushButtonActive, 32, - true, macColor); - if (err == noErr) { - retVal = true; - } - break; - default: - retVal = false; - } - return retVal; + RGBColor col1, col2; + return TkSetMacColor(c1,&col1) && + TkSetMacColor(c1,&col2) && + !memcmp(&col1,&col2,sizeof(col1)); } +#endif /* !TK_DRAW_IN_CONTEXT */ /* *---------------------------------------------------------------------- * - * GetWindowPartColor -- + * Stub functions -- * - * Given a part number this function will return the standard - * system default color for that part. It does this by looking - * in the system's 'wctb' resource. + * These functions are just stubs for functions that either + * don't make sense on the Mac or have yet to be implemented. * * Results: - * True if a color is found, false otherwise. + * None. * * Side effects: - * If a color is found then the RGB variable will be changed to - * the parts color. + * These calls do nothing - which may not be expected. * *---------------------------------------------------------------------- */ -static int -GetWindowPartColor( - short part, /* Part code. */ - RGBColor *macColor) /* Pointer to Mac color. */ +Status +XAllocColor( + Display *display, /* Display. */ + Colormap map, /* Not used. */ + XColor *colorPtr) /* XColor struct to modify. */ { - short index; - WCTabHandle wcTab; + display->request++; + colorPtr->pixel = TkpGetPixel(colorPtr); + return 1; +} - if (part == wContentColor) { - GetThemeBrushAsColor(kThemeBrushDocumentWindowBackground, - 0xFFFF, true, macColor); - return true; - } else { - wcTab = (WCTabHandle) GetResource('wctb', 0); - if(wcTab && (ResError() == noErr)) { - for(index = 0; index <= (**wcTab).ctSize; index++) { - if((**wcTab).ctTable[index].value == part) { - *macColor = (**wcTab).ctTable[index].rgb; - return true; - } - } - } - return false; - } +Colormap +XCreateColormap( + Display *display, /* Display. */ + Window window, /* X window. */ + Visual *visual, /* Not used. */ + int alloc) /* Not used. */ +{ + static Colormap index = 1; + + /* + * Just return a new value each time. + */ + return index++; } - -/* - *---------------------------------------------------------------------- - * - * GetMenuPartColor -- - * - * Given a magic pixel value, returns the RGB color associated - * with it by looking the value up in the system's 'mctb' resource. - * - * Results: - * True if a color is found, false otherwise. - * - * Side effects: - * If a color is found then the RGB variable will be changed to - * the parts color. - * - *---------------------------------------------------------------------- - */ -static int -GetMenuPartColor( - int pixel, /* The magic pixel value */ - RGBColor *macColor) /* Pointer to Mac color */ +void +XFreeColormap( + Display* display, /* Display. */ + Colormap colormap) /* Colormap. */ +{ +} + +void +XFreeColors( + Display* display, /* Display. */ + Colormap colormap, /* Colormap. */ + unsigned long* pixels, /* Array of pixels. */ + int npixels, /* Number of pixels. */ + unsigned long planes) /* Number of pixel planes. */ { - - /* Under Appearance, we don't want to set any menu colors when we - are asked for the standard menu colors. So we return false (which - means don't use this color... */ - - macColor->red = 0xFFFF; - macColor->green = 0; - macColor->blue = 0; - return false; + /* + * The Macintosh version of Tk uses TrueColor. Nothing + * needs to be done to release colors as there really is + * no colormap in the Tk sense. + */ } diff --git a/macosx/tkMacOSXConfig.c b/macosx/tkMacOSXConfig.c index fa1e62e..197cfbe 100644 --- a/macosx/tkMacOSXConfig.c +++ b/macosx/tkMacOSXConfig.c @@ -1,8 +1,8 @@ -/* +/* * tkMacOSXConfig.c -- * - * This module implements the Macintosh system defaults for - * the configuration package. + * This module implements the Macintosh system defaults for + * the configuration package. * * Copyright (c) 1997 by Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. @@ -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: tkMacOSXConfig.c,v 1.3 2006/03/24 14:58:01 das Exp $ + * RCS: @(#) $Id: tkMacOSXConfig.c,v 1.4 2007/04/23 21:24:33 das Exp $ */ #include "tkInt.h" @@ -21,25 +21,25 @@ * * TkpGetSystemDefault -- * - * Given a dbName and className for a configuration option, - * return a string representation of the option. + * Given a dbName and className for a configuration option, + * return a string representation of the option. * * Results: - * Returns a Tk_Uid that is the string identifier that identifies - * this option. Returns NULL if there are no system defaults - * that match this pair. + * Returns a Tk_Uid that is the string identifier that identifies + * this option. Returns NULL if there are no system defaults + * that match this pair. * * Side effects: - * None, once the package is initialized. + * None, once the package is initialized. * *---------------------------------------------------------------------- */ Tcl_Obj * TkpGetSystemDefault( - Tk_Window tkwin, /* A window to use. */ - CONST char *dbName, /* The option database name. */ - CONST char *className) /* The name of the option class. */ + Tk_Window tkwin, /* A window to use. */ + CONST char *dbName, /* The option database name. */ + CONST char *className) /* The name of the option class. */ { return NULL; } diff --git a/macosx/tkMacOSXCursor.c b/macosx/tkMacOSXCursor.c index 571f5b6..bbb72e1 100644 --- a/macosx/tkMacOSXCursor.c +++ b/macosx/tkMacOSXCursor.c @@ -1,15 +1,16 @@ -/* +/* * tkMacOSXCursor.c -- * - * This file contains Macintosh specific cursor related routines. + * This file contains Macintosh specific cursor related routines. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXCursor.c,v 1.10 2007/04/21 19:06:37 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXCursor.c,v 1.11 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" @@ -20,10 +21,11 @@ * color resource cursors, & normal cursors. */ -#define THEME 0 /* Theme cursors */ -#define ANIMATED 1 /* Animated theme cursors */ -#define COLOR 2 /* Cursors of type crsr. */ -#define NORMAL 3 /* Cursors of type CURS. */ +#define NONE -1 /* Hidden cursor */ +#define THEME 0 /* Theme cursors */ +#define ANIMATED 1 /* Animated theme cursors */ +#define COLOR 2 /* Cursors of type crsr. */ +#define NORMAL 3 /* Cursors of type CURS. */ /* * The following data structure contains the system specific data @@ -31,14 +33,14 @@ */ typedef struct { - TkCursor info; /* Generic cursor info used by tkCursor.c */ - Handle macCursor; /* Resource containing Macintosh cursor. - * For theme cursors, this is -1. */ - int type; /* Type of Mac cursor: for theme cursors - * this is the theme cursor constant, - * otherwise one of crsr or CURS */ - int count; /* For animating cursors, the count for the - cursor. */ + TkCursor info; /* Generic cursor info used by tkCursor.c */ + Handle macCursor; /* Resource containing Macintosh cursor. + * For theme cursors, this is -1. */ + int type; /* Type of Mac cursor: for theme cursors + * this is the theme cursor constant, + * otherwise one of crsr or CURS */ + int count; /* For animating cursors, the count for the + * cursor. */ } TkMacOSXCursor; /* @@ -47,119 +49,128 @@ typedef struct { */ struct CursorName { - char *name; + const char *name; int id; }; +static struct CursorName noneCursorName = {"none", 0}; + static struct CursorName themeCursorNames[] = { - {"ibeam", kThemeIBeamCursor}, - {"text", kThemeIBeamCursor}, - {"xterm", kThemeIBeamCursor}, - {"cross", kThemeCrossCursor}, - {"crosshair", kThemeCrossCursor}, - {"cross-hair", kThemeCrossCursor}, - {"plus", kThemePlusCursor}, - {"arrow", kThemeArrowCursor}, - {"closedhand", kThemeClosedHandCursor}, - {"openhand", kThemeOpenHandCursor}, - {"pointinghand", kThemePointingHandCursor}, - {NULL, 0} + {"arrow", kThemeArrowCursor}, + {"copyarrow", kThemeCopyArrowCursor}, + {"aliasarrow", kThemeAliasArrowCursor}, + {"contextualmenuarrow", kThemeContextualMenuArrowCursor}, + {"ibeam", kThemeIBeamCursor}, + {"text", kThemeIBeamCursor}, + {"xterm", kThemeIBeamCursor}, + {"cross", kThemeCrossCursor}, + {"crosshair", kThemeCrossCursor}, + {"cross-hair", kThemeCrossCursor}, + {"plus", kThemePlusCursor}, + {"closedhand", kThemeClosedHandCursor}, + {"openhand", kThemeOpenHandCursor}, + {"pointinghand", kThemePointingHandCursor}, + {"resizeleft", kThemeResizeLeftCursor}, + {"resizeright", kThemeResizeRightCursor}, + {"resizeleftright", kThemeResizeLeftRightCursor}, + {"resizeup", kThemeResizeUpCursor}, + {"resizedown", kThemeResizeDownCursor}, + {"resizeupdown", kThemeResizeUpDownCursor}, + {"notallowed", kThemeNotAllowedCursor}, + {"poof", kThemePoofCursor}, + {NULL, 0} }; static struct CursorName animatedThemeCursorNames[] = { - {"watch", kThemeWatchCursor}, - {"countinguphand", kThemeCountingUpHandCursor}, + {"watch", kThemeWatchCursor}, + {"countinguphand", kThemeCountingUpHandCursor}, {"countingdownhand", kThemeCountingDownHandCursor}, {"countingupanddownhand", kThemeCountingUpAndDownHandCursor}, - {"spinning", kThemeSpinningCursor}, - {NULL, 0} + {"spinning", kThemeSpinningCursor}, + {NULL, 0} }; /* * Declarations of static variables used in this file. */ -static TkMacOSXCursor * gCurrentCursor = NULL; /* A pointer to the current - * cursor. */ -static int gResizeOverride = false; /* A boolean indicating whether - * we should use the resize - * cursor during installations. */ -static int gTkOwnsCursor = true; /* A boolean indicating whether - Tk owns the cursor. If not (for - instance, in the case where a Tk - window is embedded in another app's - window, and the cursor is out of - the tk window, we will not attempt - to adjust the cursor */ +static TkMacOSXCursor * gCurrentCursor = NULL; /* A pointer to the current + * cursor. */ +static int gResizeOverride = false; /* A boolean indicating whether + * we should use the resize + * cursor during installations. */ +static int gTkOwnsCursor = true; /* A boolean indicating whether + * Tk owns the cursor. If not (for + * instance, in the case where a Tk + * window is embedded in another app's + * window, and the cursor is out of + * the tk window, we will not attempt + * to adjust the cursor */ /* * Declarations of procedures local to this file */ -static void FindCursorByName _ANSI_ARGS_ ((TkMacOSXCursor *macCursorPtr, - CONST char *string)); +static void FindCursorByName(TkMacOSXCursor *macCursorPtr, const char *string); + /* *---------------------------------------------------------------------- * * FindCursorByName -- * - * Retrieve a system cursor by name, and fill the macCursorPtr - * structure. If the cursor cannot be found, the macCursor field - * will be NULL. The function first attempts to load a color - * cursor. If that fails it will attempt to load a black & white - * cursor. + * Retrieve a system cursor by name, and fill the macCursorPtr + * structure. If the cursor cannot be found, the macCursor field + * will be NULL. The function first attempts to load a color + * cursor. If that fails it will attempt to load a black & white + * cursor. * * Results: - * Fills the macCursorPtr record. + * Fills the macCursorPtr record. * * Side effects: - * None + * None * *---------------------------------------------------------------------- */ - -void + +void FindCursorByName( TkMacOSXCursor *macCursorPtr, - CONST char *string) + const char *string) { Handle resource; Str255 curName; int destWrote, inCurLen; + Tcl_Encoding encoding; inCurLen = strlen(string); if (inCurLen > 255) { - return; + return; } /* * macRoman is the encoding that the resource fork uses. */ - Tcl_UtfToExternal(NULL, Tcl_GetEncoding(NULL, "macRoman"), string, - inCurLen, 0, NULL, - (char *) &curName[1], - 255, NULL, &destWrote, NULL); /* Internalize native */ + encoding = Tcl_GetEncoding(NULL, "macRoman"); + Tcl_UtfToExternal(NULL, encoding, string, inCurLen, 0, NULL, + (char *) &curName[1], 255, NULL, &destWrote, NULL); curName[0] = destWrote; + Tcl_FreeEncoding(encoding); resource = GetNamedResource('crsr', curName); - - if (resource != NULL) { - short id; - Str255 theName; - ResType theType; - - HLock(resource); - GetResInfo(resource, &id, &theType, theName); - HUnlock(resource); - macCursorPtr->macCursor = (Handle) GetCCursor(id); - macCursorPtr->type = COLOR; - } - - if (resource == NULL) { - macCursorPtr->macCursor = GetNamedResource('CURS', curName); - macCursorPtr->type = NORMAL; + if (resource) { + short id; + Str255 theName; + ResType theType; + + GetResInfo(resource, &id, &theType, theName); + macCursorPtr->macCursor = (Handle) GetCCursor(id); + macCursorPtr->type = COLOR; + } else { + macCursorPtr->macCursor = GetNamedResource('CURS', curName); + macCursorPtr->type = NORMAL; } } @@ -168,28 +179,28 @@ FindCursorByName( * * TkGetCursorByName -- * - * Retrieve a system cursor by name. + * Retrieve a system cursor by name. * * Results: - * Returns a new cursor, or NULL on errors. + * Returns a new cursor, or NULL on errors. * * Side effects: - * Allocates a new cursor. + * Allocates a new cursor. * *---------------------------------------------------------------------- */ TkCursor * TkGetCursorByName( - Tcl_Interp *interp, /* Interpreter to use for error reporting. */ - Tk_Window tkwin, /* Window in which cursor will be used. */ - Tk_Uid string) /* Description of cursor. See manual entry - * for details on legal syntax. */ + Tcl_Interp *interp, /* Interpreter to use for error reporting. */ + Tk_Window tkwin, /* Window in which cursor will be used. */ + Tk_Uid string) /* Description of cursor. See manual entry + * for details on legal syntax. */ { struct CursorName *namePtr; TkMacOSXCursor *macCursorPtr; int count = -1; - + macCursorPtr = (TkMacOSXCursor *) ckalloc(sizeof(TkMacOSXCursor)); macCursorPtr->info.cursor = (Tk_Cursor) macCursorPtr; @@ -199,71 +210,67 @@ TkGetCursorByName( * attempt to load the cursor as a named Mac resource. */ - for (namePtr = themeCursorNames; namePtr->name != NULL; namePtr++) { - if (strcmp(namePtr->name, string) == 0) { - macCursorPtr->count = -1; - macCursorPtr->macCursor = (Handle) namePtr; - macCursorPtr->type = THEME; - break; - } + if (strcmp(noneCursorName.name, string) == 0) { + namePtr = &noneCursorName; + macCursorPtr->type = NONE; + } else { + for (namePtr = themeCursorNames; namePtr->name != NULL; namePtr++) { + if (strcmp(namePtr->name, string) == 0) { + macCursorPtr->type = THEME; + break; + } + } } if (namePtr->name == NULL) { - for (namePtr = animatedThemeCursorNames; - namePtr->name != NULL; namePtr++) { - int namelen = strlen (namePtr->name); - if (strncmp(namePtr->name, string, namelen) == 0) { - const char *numPtr = string + namelen; - if (*numPtr == '\0') { - count = -1; - } else { - int result; - result = Tcl_GetInt(NULL, numPtr, &count); - if (result != TCL_OK) { - continue; - } - } - macCursorPtr->macCursor = (Handle) namePtr; - macCursorPtr->type = ANIMATED; - macCursorPtr->count = count; - break; - } - } + for (namePtr = animatedThemeCursorNames; + namePtr->name != NULL; namePtr++) { + int namelen = strlen (namePtr->name); + if (strncmp(namePtr->name, string, namelen) == 0) { + const char *numPtr = string + namelen; + if (*numPtr) { + int result = Tcl_GetInt(NULL, numPtr, &count); + if (result != TCL_OK) { + continue; + } + } + macCursorPtr->type = ANIMATED; + break; + } + } } - - - if (namePtr->name == NULL) { - FindCursorByName(macCursorPtr, string); - - if (macCursorPtr->macCursor == NULL) { - CONST char **argv; - int argc, err; - - /* - * The user may be trying to specify an XCursor with fore - * & back colors. We don't want this to be an error, so pick - * off the first word, and try again. - */ - - err = Tcl_SplitList(interp, string, &argc, &argv); - if (err == TCL_OK ) { - if (argc > 1) { - FindCursorByName(macCursorPtr, argv[0]); - } - - ckfree((char *) argv); - } - } + if (namePtr->name != NULL) { + macCursorPtr->macCursor = (Handle) namePtr; + macCursorPtr->count = count; + } else { + FindCursorByName(macCursorPtr, string); + + if (macCursorPtr->macCursor == NULL) { + const char **argv; + int argc; + + /* + * The user may be trying to specify an XCursor with fore + * & back colors. We don't want this to be an error, so pick + * off the first word, and try again. + */ + + if (Tcl_SplitList(interp, string, &argc, &argv) == TCL_OK ) { + if (argc > 1) { + FindCursorByName(macCursorPtr, argv[0]); + } + ckfree((char *) argv); + } + } } if (macCursorPtr->macCursor == NULL) { - ckfree((char *)macCursorPtr); - Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"", - (char *) NULL); - return NULL; + ckfree((char *)macCursorPtr); + Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"", NULL); + return NULL; } else { - return (TkCursor *) macCursorPtr; + return (TkCursor *) macCursorPtr; } } @@ -272,26 +279,26 @@ TkGetCursorByName( * * TkCreateCursorFromData -- * - * Creates a cursor from the source and mask bits. + * Creates a cursor from the source and mask bits. * * Results: - * Returns a new cursor, or NULL on errors. + * Returns a new cursor, or NULL on errors. * * Side effects: - * Allocates a new cursor. + * Allocates a new cursor. * *---------------------------------------------------------------------- */ TkCursor * TkCreateCursorFromData( - Tk_Window tkwin, /* Window in which cursor will be used. */ - CONST char *source, /* Bitmap data for cursor shape. */ - CONST char *mask, /* Bitmap data for cursor mask. */ - int width, int height, /* Dimensions of cursor. */ - int xHot, int yHot, /* Location of hot-spot in cursor. */ - XColor fgColor, /* Foreground color for cursor. */ - XColor bgColor) /* Background color for cursor. */ + Tk_Window tkwin, /* Window in which cursor will be used. */ + CONST char *source, /* Bitmap data for cursor shape. */ + CONST char *mask, /* Bitmap data for cursor mask. */ + int width, int height, /* Dimensions of cursor. */ + int xHot, int yHot, /* Location of hot-spot in cursor. */ + XColor fgColor, /* Foreground color for cursor. */ + XColor bgColor) /* Background color for cursor. */ { return NULL; } @@ -301,14 +308,14 @@ TkCreateCursorFromData( * * TkpFreeCursor -- * - * This procedure is called to release a cursor allocated by - * TkGetCursorByName. + * This procedure is called to release a cursor allocated by + * TkGetCursorByName. * * Results: - * None. + * None. * * Side effects: - * The cursor data structure is deallocated. + * The cursor data structure is deallocated. * *---------------------------------------------------------------------- */ @@ -320,32 +327,33 @@ TkpFreeCursor( TkMacOSXCursor *macCursorPtr = (TkMacOSXCursor *) cursorPtr; switch (macCursorPtr->type) { - case COLOR: - DisposeCCursor((CCrsrHandle) macCursorPtr->macCursor); - break; - case NORMAL: - ReleaseResource(macCursorPtr->macCursor); - break; + case COLOR: + DisposeCCursor((CCrsrHandle) macCursorPtr->macCursor); + break; + case NORMAL: + ReleaseResource(macCursorPtr->macCursor); + break; } if (macCursorPtr == gCurrentCursor) { - gCurrentCursor = NULL; + gCurrentCursor = NULL; } } + /* *---------------------------------------------------------------------- * * TkMacOSXInstallCursor -- * - * Installs either the current cursor as defined by TkpSetCursor - * or a resize cursor as the cursor the Macintosh should currently - * display. + * Installs either the current cursor as defined by TkpSetCursor + * or a resize cursor as the cursor the Macintosh should currently + * display. * * Results: - * None. + * None. * * Side effects: - * Changes the Macintosh mouse cursor. + * Changes the Macintosh mouse cursor. * *---------------------------------------------------------------------- */ @@ -358,45 +366,56 @@ TkMacOSXInstallCursor( CCrsrHandle ccursor; CursHandle cursor; static unsigned int cursorStep = 0; - + static int cursorHidden = 0; + int cursorNone = 0; + gResizeOverride = resizeOverride; if (resizeOverride) { - cursor = (CursHandle) GetNamedResource('CURS', "\presize"); - if (cursor) { - SetCursor(*cursor); - } else { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"Resize cursor failed, %d\n", ResError()); -#endif - } + cursor = (CursHandle) GetNamedResource('CURS', "\presize"); + if (cursor) { + SetCursor(*cursor); + } else { + TkMacOSXDbgMsg("Resize cursor failed: %d", ResError()); + } } else if (macCursorPtr == NULL) { - SetThemeCursor(kThemeArrowCursor); + SetThemeCursor(kThemeArrowCursor); } else { - struct CursorName *namePtr; - switch (macCursorPtr->type) { - case THEME: - namePtr = (struct CursorName *) macCursorPtr->macCursor; - SetThemeCursor( - namePtr->id); - break; - case ANIMATED: - namePtr = (struct CursorName *) macCursorPtr->macCursor; - if (macCursorPtr->count == -1) { - SetAnimatedThemeCursor(namePtr->id, cursorStep++); - } else { - SetAnimatedThemeCursor(namePtr->id, macCursorPtr->count); - } - break; - case COLOR: - ccursor = (CCrsrHandle) macCursorPtr->macCursor; - SetCCursor(ccursor); - break; - case NORMAL: - cursor = (CursHandle) macCursorPtr->macCursor; - SetCursor(*cursor); - break; - } + struct CursorName *namePtr; + switch (macCursorPtr->type) { + case NONE: + if (!cursorHidden) { + cursorHidden = 1; + HideCursor(); + } + cursorNone = 1; + break; + case THEME: + namePtr = (struct CursorName *) macCursorPtr->macCursor; + SetThemeCursor( + namePtr->id); + break; + case ANIMATED: + namePtr = (struct CursorName *) macCursorPtr->macCursor; + if (macCursorPtr->count == -1) { + SetAnimatedThemeCursor(namePtr->id, cursorStep++); + } else { + SetAnimatedThemeCursor(namePtr->id, macCursorPtr->count); + } + break; + case COLOR: + ccursor = (CCrsrHandle) macCursorPtr->macCursor; + SetCCursor(ccursor); + break; + case NORMAL: + cursor = (CursHandle) macCursorPtr->macCursor; + SetCursor(*cursor); + break; + } + } + if (cursorHidden && !cursorNone) { + cursorHidden = 0; + ShowCursor(); } } @@ -405,13 +424,13 @@ TkMacOSXInstallCursor( * * TkpSetCursor -- * - * Set the current cursor and install it. + * Set the current cursor and install it. * * Results: - * None. + * None. * * Side effects: - * Changes the current cursor. + * Changes the current cursor. * *---------------------------------------------------------------------- */ @@ -421,30 +440,30 @@ TkpSetCursor( TkpCursor cursor) { int cursorChanged = 1; - + if (!gTkOwnsCursor) { - return; + return; } - + if (cursor == None) { - /* - * This is a little tricky. We can't really tell whether - * gCurrentCursor is NULL because it was NULL last time around - * or because we just freed the current cursor. So if the input - * cursor is NULL, we always need to reset it, we can't trust the - * cursorChanged logic. - */ - - gCurrentCursor = NULL; + /* + * This is a little tricky. We can't really tell whether + * gCurrentCursor is NULL because it was NULL last time around + * or because we just freed the current cursor. So if the input + * cursor is NULL, we always need to reset it, we can't trust the + * cursorChanged logic. + */ + + gCurrentCursor = NULL; } else { - if (gCurrentCursor == (TkMacOSXCursor *) cursor) { - cursorChanged = 0; - } - gCurrentCursor = (TkMacOSXCursor *) cursor; + if (gCurrentCursor == (TkMacOSXCursor *) cursor) { + cursorChanged = 0; + } + gCurrentCursor = (TkMacOSXCursor *) cursor; } if (Tk_MacOSXIsAppInFront() && cursorChanged) { - TkMacOSXInstallCursor(gResizeOverride); + TkMacOSXInstallCursor(gResizeOverride); } } @@ -453,13 +472,13 @@ TkpSetCursor( * * Tk_MacOSXTkOwnsCursor -- * - * Sets whether Tk has the right to adjust the cursor. + * Sets whether Tk has the right to adjust the cursor. * * Results: - * None. + * None. * * Side effects: - * May keep Tk from changing the cursor. + * May keep Tk from changing the cursor. * *---------------------------------------------------------------------- */ diff --git a/macosx/tkMacOSXCursors.r b/macosx/tkMacOSXCursors.r index 51abc74..248c8ba 100644 --- a/macosx/tkMacOSXCursors.r +++ b/macosx/tkMacOSXCursors.r @@ -1,21 +1,21 @@ -/* +/* * tkMacOSXCursors.r -- * * This file defines a set of Macintosh cursor resources that - * are only available on the Macintosh platform. + * are only available on the Macintosh platform. * * Copyright (c) 1995-1996 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXCursors.r,v 1.2 2002/08/31 06:12:29 das Exp $ + * RCS: @(#) $Id: tkMacOSXCursors.r,v 1.3 2007/04/23 21:24:33 das Exp $ */ /* * These are resource definitions for Macintosh cursors. * The are identified and loaded by the "name" of the - * cursor. However, the ids must be unique. + * cursor. However, the ids must be unique. */ data 'CURS' (1000, "hand") { @@ -23,7 +23,7 @@ data 'CURS' (1000, "hand") { $"8802 4002 2002 2004 1004 0808 0408 0408" $"0180 1BF0 3FF8 3FFA 1FFF 1FFF 6FFF FFFF" $"FFFE 7FFE 3FFE 3FFC 1FFC 0FF8 07F8 07F8" - $"0009 0008" + $"0009 0008" }; data 'CURS' (1002, "bucket") { @@ -31,7 +31,7 @@ data 'CURS' (1002, "bucket") { $"129C 212C 104C 088C 050C 0208 0000 0000" $"0000 0000 0600 0980 09C0 0BF0 0FF8 0FFC" $"1FFC 3FEC 1FCC 0F8C 070C 0208 0000 0000" - $"000D 000C" + $"000D 000C" }; data 'CURS' (1003, "cancel") { @@ -39,7 +39,7 @@ data 'CURS' (1003, "cancel") { $"0A00 3F80 4A40 4A46 3186 0000 0000 0000" $"0000 0000 0000 3180 7BC0 FFE0 FFE0 7FC0" $"3F80 7FC0 FFE6 FFEF 7BCF 3186 0000 0000" - $"0008 0005" + $"0008 0005" }; data 'CURS' (1004, "resize") { @@ -47,7 +47,7 @@ data 'CURS' (1004, "resize") { $"9F8D 880D 880D 880D 8FFD 87FD 8001 FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" - $"0008 0008" + $"0008 0008" }; data 'CURS' (1005, "eyedrop") { @@ -55,7 +55,7 @@ data 'CURS' (1005, "eyedrop") { $"0440 0880 1100 2200 4400 4800 B000 4000" $"000E 001F 001F 00FF 007E 00F8 01F8 03E8" $"07C0 0F80 1F00 3E00 7C00 7800 F000 4000" - $"000F 0000" + $"000F 0000" }; data 'CURS' (1006, "eyedrop-full") { @@ -63,7 +63,7 @@ data 'CURS' (1006, "eyedrop-full") { $"07C0 0F80 1F00 3E00 7C00 7800 F000 4000" $"000E 001F 001F 00FF 007E 00F8 01F8 03E8" $"07C0 0F80 1F00 3E00 7C00 7800 F000 4000" - $"000F 0000" + $"000F 0000" }; data 'CURS' (1007, "zoom-in") { @@ -71,7 +71,7 @@ data 'CURS' (1007, "zoom-in") { $"A014 5028 5868 2798 187C 078E 0007 0003" $"0780 1FE0 3FF0 7878 7038 E01C EFDC EFDC" $"E01C 7038 7878 3FF8 1FFC 078E 0007 0003" - $"0007 0007" + $"0007 0007" }; data 'CURS' (1008, "zoom-out") { @@ -79,13 +79,13 @@ data 'CURS' (1008, "zoom-out") { $"A314 5328 5868 2798 187C 078E 0007 0003" $"0780 1FE0 3FF0 7878 7338 E31C EFDC EFDC" $"E31C 7338 7878 3FF8 1FFC 078E 0007 0003" - $"0007 0007" + $"0007 0007" }; /* * The following are resource definitions for color - * cursors on the Macintosh. If a color cursor and - * a black & white cursor are both defined with the + * cursors on the Macintosh. If a color cursor and + * a black & white cursor are both defined with the * same name preference will be given to the color * cursors. */ @@ -106,7 +106,7 @@ data 'crsr' (1000, "hand") { $"5570 0355 5570 00D5 55C0 0035 55C0 0035" $"55C0 0000 0000 0000 0002 0000 FFFF FFFF" $"FFFF 0001 FFFF CCCC 9999 0003 0000 0000" - $"0000" + $"0000" }; data 'crsr' (1001, "fist") { @@ -125,6 +125,6 @@ data 'crsr' (1001, "fist") { $"5570 0355 5570 00D5 55C0 0035 55C0 0035" $"55C0 0000 0000 0000 0002 0000 FFFF FFFF" $"FFFF 0001 FFFF CCCC 9999 0003 0000 0000" - $"0000" + $"0000" }; diff --git a/macosx/tkMacOSXDebug.c b/macosx/tkMacOSXDebug.c index 5537d1c..b0dc136 100644 --- a/macosx/tkMacOSXDebug.c +++ b/macosx/tkMacOSXDebug.c @@ -2,7 +2,7 @@ * tkMacOSXDebug.c -- * * Implementation of Macintosh specific functions for debugging MacOS events, - * regions, etc... + * regions, etc... * * Copyright 2001, Apple Computer, Inc. * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> @@ -10,51 +10,51 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * The following terms apply to all files originating from Apple - * Computer, Inc. ("Apple") and associated with the software - * unless explicitly disclaimed in individual files. + * The following terms apply to all files originating from Apple + * Computer, Inc. ("Apple") and associated with the software + * unless explicitly disclaimed in individual files. * * - * Apple hereby grants permission to use, copy, modify, - * distribute, and license this software and its documentation - * for any purpose, provided that existing copyright notices are - * retained in all copies and that this notice is included - * verbatim in any distributions. No written agreement, license, - * or royalty fee is required for any of the authorized - * uses. Modifications to this software may be copyrighted by - * their authors and need not follow the licensing terms - * described here, provided that the new terms are clearly - * indicated on the first page of each file where they apply. + * Apple hereby grants permission to use, copy, modify, + * distribute, and license this software and its documentation + * for any purpose, provided that existing copyright notices are + * retained in all copies and that this notice is included + * verbatim in any distributions. No written agreement, license, + * or royalty fee is required for any of the authorized + * uses. Modifications to this software may be copyrighted by + * their authors and need not follow the licensing terms + * described here, provided that the new terms are clearly + * indicated on the first page of each file where they apply. * * - * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE - * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, - * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF - * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, - * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND - * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS - * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE - * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE + * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, + * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF + * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, + * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND + * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS + * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE + * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * - * GOVERNMENT USE: If you are acquiring this software on behalf - * of the U.S. government, the Government shall have only - * "Restricted Rights" in the software and related documentation - * as defined in the Federal Acquisition Regulations (FARs) in - * Clause 52.227.19 (c) (2). If you are acquiring the software - * on behalf of the Department of Defense, the software shall be - * classified as "Commercial Computer Software" and the - * Government shall have only "Restricted Rights" as defined in - * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the - * foregoing, the authors grant the U.S. Government and others - * acting in its behalf permission to use and distribute the - * software in accordance with the terms specified in this - * license. + * GOVERNMENT USE: If you are acquiring this software on behalf + * of the U.S. government, the Government shall have only + * "Restricted Rights" in the software and related documentation + * as defined in the Federal Acquisition Regulations (FARs) in + * Clause 52.227.19 (c) (2). If you are acquiring the software + * on behalf of the Department of Defense, the software shall be + * classified as "Commercial Computer Software" and the + * Government shall have only "Restricted Rights" as defined in + * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the + * foregoing, the authors grant the U.S. Government and others + * acting in its behalf permission to use and distribute the + * software in accordance with the terms specified in this + * license. * - * RCS: @(#) $Id: tkMacOSXDebug.c,v 1.11 2007/03/07 23:46:34 das Exp $ + * RCS: @(#) $Id: tkMacOSXDebug.c,v 1.12 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" @@ -66,13 +66,13 @@ #include <mach-o/nlist.h> typedef struct { - EventKind kind; - char * name; + EventKind kind; + const char * name; } MyEventName; typedef struct { - EventClass c; - MyEventName * names; + EventClass c; + MyEventName * names; } MyEventNameList; static MyEventName windowEventNames [] = { @@ -161,7 +161,7 @@ static MyEventName keyboardEventNames [] = { static MyEventName appEventNames [] = { { kEventAppActivated, "Activated"}, - { kEventAppDeactivated, "Deactivated"}, + { kEventAppDeactivated, "Deactivated"}, { kEventAppQuit, "Quit"}, { kEventAppLaunchNotification, "LaunchNotification"}, { kEventAppLaunched, "Launched"}, @@ -253,83 +253,79 @@ static MyEventName classicEventNames [] = { }; #endif /* TK_MACOSXDEBUG_UNUSED */ -MODULE_SCOPE char * -TkMacOSXCarbonEventToAscii(EventRef eventRef, char * buf) -{ +MODULE_SCOPE char * +TkMacOSXCarbonEventToAscii(EventRef eventRef) +{ EventClass eventClass; - EventKind eventKind; + EventKind eventKind; MyEventNameList * list = eventNameList; - MyEventName * names = NULL; - int * iPtr = ( int * )buf; - char * iBuf = buf; + MyEventName * names = NULL; + static char str[256]; + char *buf = str; + int *iPtr = (int*)str; int found = 0; eventClass = GetEventClass(eventRef); eventKind = GetEventKind(eventRef); *iPtr = eventClass; - buf [ 4 ] = 0; + buf[4] = 0; strcat(buf, " "); buf += strlen(buf); while (list->names && (!names) ) { - if (eventClass == list->c) { - names = list -> names; - } else { - list++; - } + if (eventClass == list->c) { + names = list -> names; + } else { + list++; + } } - if (names) { - found = 0; - while (names->name && !found) { - if (eventKind == names->kind) { - sprintf(buf, "%-20s", names->name); - found = 1; - } else { - names++; - } - } - if (!found) { - sprintf(buf, "%-20d", eventKind ); - } - } else { - sprintf(buf, "%-20d", eventKind ); + while (names && names->name) { + if (eventKind == names->kind) { + snprintf(buf, 250, "%-20s", names->name); + break; + } else { + names++; + } + } + if (!found) { + snprintf(buf, 250, "%-20d", eventKind); } - return iBuf; + return str; } #ifdef TK_MACOSXDEBUG_UNUSED MODULE_SCOPE char * TkMacOSXCarbonEventKindToAscii(EventRef eventRef, char * buf ) -{ +{ EventClass eventClass; EventKind eventKind; MyEventNameList * list = eventNameList; - MyEventName * names = NULL; - int found = 0; + MyEventName * names = NULL; + int found = 0; eventClass = GetEventClass(eventRef); eventKind = GetEventKind(eventRef); while (list->names && (!names) ) { if (eventClass == list -> c) { - names = list -> names; + names = list -> names; } else { - list++; + list++; } } if (names) { found = 0; while ( names->name && !found ) { - if (eventKind == names->kind) { - sprintf(buf,"%s",names->name); - found = 1; - } else { - names++; - } + if (eventKind == names->kind) { + sprintf(buf,"%s",names->name); + found = 1; + } else { + names++; + } } } if (!found) { - sprintf ( buf,"%d", eventKind ); + sprintf ( buf,"%d", eventKind ); } else { - sprintf ( buf,"%d", eventKind ); + sprintf ( buf,"%d", eventKind ); } return buf; } @@ -337,46 +333,45 @@ TkMacOSXCarbonEventKindToAscii(EventRef eventRef, char * buf ) MODULE_SCOPE char * TkMacOSXClassicEventToAscii(EventRecord * eventPtr, char * buf ) { - MyEventName * names = NULL; + MyEventName * names = NULL; int found = 0; names = classicEventNames; while ( names -> name && !found ) - if (eventPtr->what == names->kind) { - int * iPtr; - char cBuf[8]; - iPtr=(int *) &cBuf; - *iPtr = eventPtr->message; - cBuf[4] = 0; - sprintf(buf, "%-16s %08x %04x %s", names->name, - (int) eventPtr->message, - eventPtr->modifiers, - cBuf); - found = 1; - } else { - names++; - } + if (eventPtr->what == names->kind) { + int * iPtr; + char cBuf[8]; + iPtr=(int *) &cBuf; + *iPtr = eventPtr->message; + cBuf[4] = 0; + sprintf(buf, "%-16s %08x %04x %s", names->name, + (int) eventPtr->message, + eventPtr->modifiers, + cBuf); + found = 1; + } else { + names++; + } if (!found) { - sprintf(buf,"%-16d %08x %08x, %s", - eventPtr->what, (int) eventPtr->message, - eventPtr->modifiers, buf); + sprintf(buf,"%-16d %08x %08x, %s", + eventPtr->what, (int) eventPtr->message, + eventPtr->modifiers, buf); } return buf; - + } MODULE_SCOPE void TkMacOSXPrintPoint(char * tag, Point * p ) { - fprintf(stderr,"%s %4d %4d\n", - tag,p->h,p->v ); + TkMacOSXDbgMsg("%s %4d %4d", tag,p->h,p->v ); } MODULE_SCOPE void TkMacOSXPrintRect(char * tag, Rect * r ) { - fprintf(stderr,"%s %4d %4d %4d %4d (%dx%d)\n", - tag, r->left, r->top, r->right, r->bottom, - r->right - r->left + 1, r->bottom - r->top + 1); + TkMacOSXDbgMsg("%s %4d %4d %4d %4d (%dx%d)", + tag, r->left, r->top, r->right, r->bottom, + r->right - r->left + 1, r->bottom - r->top + 1); } MODULE_SCOPE void @@ -393,23 +388,23 @@ TkMacOSXPrintWindowTitle(char * tag, WindowRef window ) Str255 title; GetWTitle(window,title); title [title[0] + 1] = 0; - fprintf(stderr, "%s %s\n", tag, title +1 ); + TkMacOSXDbgMsg("%s %s", tag, title +1 ); } typedef struct { - int msg; + int msg; char * name; } MsgName; static MsgName msgNames [] = { - { kMenuDrawMsg, "Draw"}, - { kMenuSizeMsg, "Size"}, - { kMenuPopUpMsg, "PopUp"}, - { kMenuCalcItemMsg, "CalcItem" }, + { kMenuDrawMsg, "Draw"}, + { kMenuSizeMsg, "Size"}, + { kMenuPopUpMsg, "PopUp"}, + { kMenuCalcItemMsg, "CalcItem" }, { kMenuThemeSavvyMsg, "ThemeSavvy"}, - { kMenuInitMsg, "Init" }, - { kMenuDisposeMsg, "Dispose" }, - { kMenuFindItemMsg, "FindItem" }, + { kMenuInitMsg, "Init" }, + { kMenuDisposeMsg, "Dispose" }, + { kMenuFindItemMsg, "FindItem" }, { kMenuHiliteItemMsg, "HiliteItem" }, { kMenuDrawItemsMsg, "DrawItems" }, { -1, NULL } @@ -420,12 +415,12 @@ TkMacOSXMenuMessageToAscii(int msg, char * s) { MsgName * msgNamePtr; for (msgNamePtr = msgNames;msgNamePtr->name;) { - if (msgNamePtr->msg == msg) { - strcpy(s,msgNamePtr->name); - return s; - } else { - msgNamePtr++; - } + if (msgNamePtr->msg == msg) { + strcpy(s,msgNamePtr->name); + return s; + } else { + msgNamePtr++; + } } sprintf(s,"unknown : %d", msg ); return s; @@ -434,24 +429,24 @@ TkMacOSXMenuMessageToAscii(int msg, char * s) static MsgName trackingNames [] = { { kMouseTrackingMousePressed , "MousePressed " }, { kMouseTrackingMouseReleased , "MouseReleased " }, - { kMouseTrackingMouseExited , "MouseExited " }, + { kMouseTrackingMouseExited , "MouseExited " }, { kMouseTrackingMouseEntered , "MouseEntered " }, - { kMouseTrackingMouseMoved , "MouseMoved " }, + { kMouseTrackingMouseMoved , "MouseMoved " }, { kMouseTrackingKeyModifiersChanged, "KeyModifiersChanged" }, { kMouseTrackingUserCancelled , "UserCancelled " }, - { kMouseTrackingTimedOut , "TimedOut " }, + { kMouseTrackingTimedOut , "TimedOut " }, { -1, NULL } }; MODULE_SCOPE char * -TkMacOSXMouseTrackingResultToAscii(MouseTrackingResult r, char * buf) +TkMacOSXMouseTrackingResultToAscii(MouseTrackingResult r, char * buf) { MsgName * namePtr; for (namePtr = trackingNames; namePtr->name; namePtr++) { - if (namePtr->msg == r) { - strcpy(buf, namePtr->name); - return buf; - } + if (namePtr->msg == r) { + strcpy(buf, namePtr->name); + return buf; + } } sprintf(buf, "Unknown mouse tracking result : %d", r); return buf; @@ -464,24 +459,24 @@ TkMacOSXMouseTrackingResultToAscii(MouseTrackingResult r, char * buf) * TkMacOSXGetNamedDebugSymbol -- * * - * Dynamically acquire address of a named symbol from a loaded - * dynamic library, so that we can use API that may not be - * available on all OS versions. - * For debugging purposes, if we cannot find the symbol with the - * usual dynamic library APIs, we manually walk the symbol table - * of the loaded library. This allows access to unexported - * symbols such as private_extern internal debugging functions. - * If module is NULL or the empty string, search all loaded - * libraries (could be very expensive and should be avoided). + * Dynamically acquire address of a named symbol from a loaded + * dynamic library, so that we can use API that may not be + * available on all OS versions. + * For debugging purposes, if we cannot find the symbol with the + * usual dynamic library APIs, we manually walk the symbol table + * of the loaded library. This allows access to unexported + * symbols such as private_extern internal debugging functions. + * If module is NULL or the empty string, search all loaded + * libraries (could be very expensive and should be avoided). + * + * THIS FUCTION IS ONLY TO BE USED FOR DEBUGGING PURPOSES, IT MAY + * BREAK UNEXPECTEDLY IN THE FUTURE ! * - * THIS FUCTION IS ONLY TO BE USED FOR DEBUGGING PURPOSES, IT MAY - * BREAK UNEXPECTEDLY IN THE FUTURE ! - * * Results: - * Address of given symbol or NULL if unavailable. + * Address of given symbol or NULL if unavailable. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -519,8 +514,8 @@ TkMacOSXGetNamedDebugSymbol(const char* module, const char* symbol) struct symtab_command *st = NULL; struct segment_command *sg = NULL; uint32_t j, m, nsect = 0, txtsectx = 0; - - lc = (struct load_command*)((char *) mh + + + lc = (struct load_command*)((const char*) mh + sizeof(struct mach_header)); m = mh->ncmds; for (j = 0; j < m; j++) { @@ -531,12 +526,12 @@ TkMacOSXGetNamedDebugSymbol(const char* module, const char* symbol) if (!txtsectx) { /* Count total sections until (__TEXT, __text) */ uint32_t k, ns = sg->nsects; - + if (strcmp(sg->segname, SEG_TEXT) == 0) { struct section *s = (struct section *)( (char *)sg + sizeof(struct segment_command)); - + for(k = 0; k < ns; k++) { if (strcmp(s->sectname, SECT_TEXT) == 0) { txtsectx = nsect+k+1; @@ -559,7 +554,7 @@ TkMacOSXGetNamedDebugSymbol(const char* module, const char* symbol) struct nlist *sym; uint32_t strsize = st->strsize; int32_t strx; - + /* Offset file positions by difference to actual position in memory of last segment before symbol table: */ base = (intptr_t) sg->vmaddr + slide - sg->fileoff; @@ -573,7 +568,7 @@ TkMacOSXGetNamedDebugSymbol(const char* module, const char* symbol) sym->n_sect == txtsectx && strx > 0 && (uint32_t) strx < strsize && strcmp(strings + strx, symbol) == 0) { - addr = (void*) sym->n_value + slide; + addr = (char*) sym->n_value + slide; break; } sym++; diff --git a/macosx/tkMacOSXDebug.h b/macosx/tkMacOSXDebug.h index 9531ac8..235060d 100644 --- a/macosx/tkMacOSXDebug.h +++ b/macosx/tkMacOSXDebug.h @@ -2,55 +2,59 @@ * tkMacOSXDebug.h -- * * Declarations of Macintosh specific functions for debugging MacOS events, - * regions, etc... + * regions, etc... * - * Copyright 2001, Apple Computer, Inc. + * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * - * The following terms apply to all files originating from Apple - * Computer, Inc. ("Apple") and associated with the software - * unless explicitly disclaimed in individual files. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * + * The following terms apply to all files originating from Apple + * Computer, Inc. ("Apple") and associated with the software + * unless explicitly disclaimed in individual files. * - * Apple hereby grants permission to use, copy, modify, - * distribute, and license this software and its documentation - * for any purpose, provided that existing copyright notices are - * retained in all copies and that this notice is included - * verbatim in any distributions. No written agreement, license, - * or royalty fee is required for any of the authorized - * uses. Modifications to this software may be copyrighted by - * their authors and need not follow the licensing terms - * described here, provided that the new terms are clearly - * indicated on the first page of each file where they apply. * + * Apple hereby grants permission to use, copy, modify, + * distribute, and license this software and its documentation + * for any purpose, provided that existing copyright notices are + * retained in all copies and that this notice is included + * verbatim in any distributions. No written agreement, license, + * or royalty fee is required for any of the authorized + * uses. Modifications to this software may be copyrighted by + * their authors and need not follow the licensing terms + * described here, provided that the new terms are clearly + * indicated on the first page of each file where they apply. * - * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE - * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, - * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF - * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, - * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND - * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS - * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE - * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * - * GOVERNMENT USE: If you are acquiring this software on behalf - * of the U.S. government, the Government shall have only - * "Restricted Rights" in the software and related documentation - * as defined in the Federal Acquisition Regulations (FARs) in - * Clause 52.227.19 (c) (2). If you are acquiring the software - * on behalf of the Department of Defense, the software shall be - * classified as "Commercial Computer Software" and the - * Government shall have only "Restricted Rights" as defined in - * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the - * foregoing, the authors grant the U.S. Government and others - * acting in its behalf permission to use and distribute the - * software in accordance with the terms specified in this - * license. + * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE + * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, + * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF + * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, + * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND + * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS + * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE + * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * - * RCS: @(#) $Id: tkMacOSXDebug.h,v 1.9 2006/10/31 22:33:34 das Exp $ + * GOVERNMENT USE: If you are acquiring this software on behalf + * of the U.S. government, the Government shall have only + * "Restricted Rights" in the software and related documentation + * as defined in the Federal Acquisition Regulations (FARs) in + * Clause 52.227.19 (c) (2). If you are acquiring the software + * on behalf of the Department of Defense, the software shall be + * classified as "Commercial Computer Software" and the + * Government shall have only "Restricted Rights" as defined in + * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the + * foregoing, the authors grant the U.S. Government and others + * acting in its behalf permission to use and distribute the + * software in accordance with the terms specified in this + * license. + * + * RCS: @(#) $Id: tkMacOSXDebug.h,v 1.10 2007/04/23 21:24:33 das Exp $ */ #ifndef _TKMACDEBUG @@ -60,12 +64,9 @@ #include "tkMacOSXInt.h" #endif -/* The following define enables printing of debug messages to stderr: */ -/* #define TK_MAC_DEBUG 1 */ - #ifdef TK_MAC_DEBUG -MODULE_SCOPE char* TkMacOSXCarbonEventToAscii(EventRef eventRef, char * buf ); +MODULE_SCOPE char* TkMacOSXCarbonEventToAscii(EventRef eventRef); #ifdef TK_MACOSXDEBUG_UNUSED MODULE_SCOPE char* TkMacOSXCarbonEventKindToAscii(EventRef eventRef, char * buf ); @@ -87,7 +88,7 @@ MODULE_SCOPE void* TkMacOSXGetNamedDebugSymbol(const char* module, const char* s #define TkMacOSXInitNamedDebugSymbol(module, ret, symbol, ...) \ static ret (* symbol)(__VA_ARGS__) = (void*)(-1L); \ if (symbol == (void*)(-1L)) { \ - symbol = TkMacOSXGetNamedDebugSymbol(STRINGIFY(module), STRINGIFY(_##symbol));\ + symbol = TkMacOSXGetNamedDebugSymbol(STRINGIFY(module), STRINGIFY(_##symbol));\ } #endif /* TK_MAC_DEBUG */ diff --git a/macosx/tkMacOSXDefault.h b/macosx/tkMacOSXDefault.h index 54f5f66..0a997ec 100644 --- a/macosx/tkMacOSXDefault.h +++ b/macosx/tkMacOSXDefault.h @@ -7,11 +7,12 @@ * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.11 2006/09/10 17:06:32 das Exp $ + * RCS: @(#) $Id: tkMacOSXDefault.h,v 1.12 2007/04/23 21:24:33 das Exp $ */ #ifndef _TKMACDEFAULT @@ -28,17 +29,16 @@ * DISABLED - Foreground color when widget is disabled. */ -#define BLACK "Black" -#define WHITE "White" - -#define NORMAL_BG "systemWindowBody" -#define ACTIVE_BG "#ececec" -#define SELECT_BG "systemHighlight" -#define SELECT_FG "systemHighlightText" -#define INACTIVE_SELECT_BG "systemHighlightSecondary" -#define TROUGH "#c3c3c3" -#define INDICATOR "#b03060" -#define DISABLED "#a3a3a3" +#define BLACK "Black" +#define WHITE "White" +#define NORMAL_BG "systemWindowBody" +#define ACTIVE_BG "#ececec" +#define SELECT_BG "systemHighlight" +#define SELECT_FG None +#define INACTIVE_SELECT_BG "systemHighlightSecondary" +#define TROUGH "#c3c3c3" +#define INDICATOR "#b03060" +#define DISABLED "#a3a3a3" /* * Defaults for labels, buttons, checkbuttons, and radiobuttons: @@ -50,7 +50,7 @@ #define DEF_BUTTON_ACTIVE_FG_COLOR "systemButtonFace" #define DEF_CHKRAD_ACTIVE_FG_COLOR DEF_BUTTON_ACTIVE_FG_COLOR #define DEF_BUTTON_ACTIVE_FG_MONO WHITE -//IGR#define DEF_BUTTON_BG_COLOR "systemButtonFace" +/* #define DEF_BUTTON_BG_COLOR "systemButtonFace"*/ #define DEF_BUTTON_BG_COLOR WHITE #define DEF_BUTTON_BG_MONO WHITE #define DEF_BUTTON_BITMAP "" @@ -61,8 +61,7 @@ #define DEF_BUTTON_DEFAULT "disabled" #define DEF_BUTTON_DISABLED_FG_COLOR DISABLED #define DEF_BUTTON_DISABLED_FG_MONO "" -//IGR#define DEF_BUTTON_FG "systemButtonText" -#define DEF_BUTTON_FG BLACK +#define DEF_BUTTON_FG "systemButtonText" #define DEF_CHKRAD_FG DEF_BUTTON_FG #define DEF_BUTTON_FONT "system" #define DEF_BUTTON_HEIGHT "0" @@ -127,7 +126,7 @@ #define DEF_CANVAS_SELECT_MONO BLACK #define DEF_CANVAS_SELECT_BD_COLOR "1" #define DEF_CANVAS_SELECT_BD_MONO "0" -#define DEF_CANVAS_SELECT_FG_COLOR BLACK +#define DEF_CANVAS_SELECT_FG_COLOR SELECT_FG #define DEF_CANVAS_SELECT_FG_MONO WHITE #define DEF_CANVAS_TAKE_FOCUS (char *) NULL #define DEF_CANVAS_WIDTH "10c" @@ -139,14 +138,14 @@ /* * Defaults for entries: */ - -/* + +/* * I test the following two values in TkpDrawEntryBorderAndFocus - * to determine whether to use the native entry widget. So if + * to determine whether to use the native entry widget. So if * you change the defaults to be different from these, then you * won't get the native widget by default. */ - + #define MAC_OSX_FOCUS_WIDTH 3 #define MAC_OSX_ENTRY_BORDER 2 #define MAC_OSX_ENTRY_RELIEF TK_RELIEF_SUNKEN @@ -289,29 +288,29 @@ * Defaults for menus overall: */ -#define DEF_MENU_ACTIVE_BG_COLOR "SystemMenuActive" +#define DEF_MENU_ACTIVE_BG_COLOR "systemMenuActive" #define DEF_MENU_ACTIVE_BG_MONO BLACK #define DEF_MENU_ACTIVE_BORDER_WIDTH "0" -#define DEF_MENU_ACTIVE_FG_COLOR "SystemMenuActiveText" +#define DEF_MENU_ACTIVE_FG_COLOR "systemMenuActiveText" #define DEF_MENU_ACTIVE_FG_MONO WHITE -#define DEF_MENU_BG_COLOR "SystemMenu" +#define DEF_MENU_BG_COLOR "systemMenu" #define DEF_MENU_BG_MONO WHITE #define DEF_MENU_BORDER_WIDTH "0" #define DEF_MENU_CURSOR "arrow" -#define DEF_MENU_DISABLED_FG_COLOR "SystemMenuDisabled" +#define DEF_MENU_DISABLED_FG_COLOR "systemMenuDisabled" #define DEF_MENU_DISABLED_FG_MONO "" -#define DEF_MENU_FONT "system" -#define DEF_MENU_FG "SystemMenuText" +#define DEF_MENU_FONT "menu" +#define DEF_MENU_FG "systemMenuText" #define DEF_MENU_POST_COMMAND "" #define DEF_MENU_RELIEF "flat" -#define DEF_MENU_SELECT_COLOR "SystemMenuActive" +#define DEF_MENU_SELECT_COLOR "systemMenuActive" #define DEF_MENU_SELECT_MONO BLACK #define DEF_MENU_TAKE_FOCUS "0" /* * FIXME: Turn the default back to 1 when we make tearoff menus work again. */ - + #define DEF_MENU_TEAROFF "0" #define DEF_MENU_TEAROFF_CMD (char *) NULL #define DEF_MENU_TITLE "" @@ -334,7 +333,7 @@ #define DEF_MENUBUTTON_DIRECTION "below" #define DEF_MENUBUTTON_DISABLED_FG_COLOR DISABLED #define DEF_MENUBUTTON_DISABLED_FG_MONO "" -#define DEF_MENUBUTTON_FONT "system" +#define DEF_MENUBUTTON_FONT "menu" #define DEF_MENUBUTTON_FG BLACK #define DEF_MENUBUTTON_HEIGHT "0" #define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR @@ -483,8 +482,7 @@ #define DEF_SCROLLBAR_TAKE_FOCUS (char *) NULL #define DEF_SCROLLBAR_TROUGH_COLOR TROUGH #define DEF_SCROLLBAR_TROUGH_MONO WHITE -/*#define DEF_SCROLLBAR_WIDTH "15" */ -#define DEF_SCROLLBAR_WIDTH "16" +#define DEF_SCROLLBAR_WIDTH "15" /* * Defaults for texts: @@ -509,7 +507,7 @@ #define DEF_TEXT_INSERT_OFF_TIME "300" #define DEF_TEXT_INSERT_ON_TIME "600" #define DEF_TEXT_INSERT_WIDTH "1" -#define DEF_TEXT_MAX_UNDO "0" +#define DEF_TEXT_MAX_UNDO "0" #define DEF_TEXT_PADX "1" #define DEF_TEXT_PADY "1" #define DEF_TEXT_RELIEF "flat" @@ -529,7 +527,7 @@ #define DEF_TEXT_TABS "" #define DEF_TEXT_TABSTYLE "tabular" #define DEF_TEXT_TAKE_FOCUS (char *) NULL -#define DEF_TEXT_UNDO "0" +#define DEF_TEXT_UNDO "0" #define DEF_TEXT_WIDTH "80" #define DEF_TEXT_WRAP "char" #define DEF_TEXT_XSCROLL_COMMAND "" diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 2db0ca5..114962b 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -1,15 +1,16 @@ /* * tkMacOSXDialog.c -- * - * Contains the Mac implementation of the common dialog boxes. + * Contains the Mac implementation of the common dialog boxes. * * Copyright (c) 1996-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.23 2007/04/21 19:06:37 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXDialog.c,v 1.24 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" @@ -22,28 +23,23 @@ #define StrBody(s) ((char *) (s) + 1) #endif -/* - * The following are ID's for resources that are defined in tkMacOSXResource.r - */ -#define OPEN_BOX 130 -#define OPEN_POPUP 131 -#define OPEN_MENU 132 #define OPEN_POPUP_ITEM 10 -#define SAVE_FILE 0 -#define OPEN_FILE 1 -#define CHOOSE_FOLDER 2 +#define SAVE_FILE 0 +#define OPEN_FILE 1 +#define CHOOSE_FOLDER 2 -#define MATCHED 0 -#define UNMATCHED 1 +#define MATCHED 0 +#define UNMATCHED 1 #define TK_DEFAULT_ABOUT 128 /* - * The following structure is used in the GetFileName() function. It stored + * The following structures are used in the GetFileName() function. They store * information about the file dialog and the file filters. */ -typedef struct _OpenFileData { + +typedef struct OpenFileData { FileFilterList fl; /* List of file filters. */ SInt16 curType; /* The filetype currently being listed. */ short popupItem; /* Item number of the popup in the dialog. */ @@ -52,37 +48,47 @@ typedef struct _OpenFileData { * option is set). */ } OpenFileData; +typedef struct NavHandlerUserData { + OpenFileData *ofdPtr; + NavReplyRecord reply; + OSStatus err; + CFStringRef saveNameRef; + int sheet; + WindowRef dialogWindow, origUnavailWindow; + WindowModality origModality; +} NavHandlerUserData; /* - * The following structure is used in the tk_messageBox - * implementation. + * The following structure is used in the tk_messageBox implementation. */ + typedef struct { - WindowRef windowRef; - int buttonIndex; -} CallbackUserData; + int buttonIndex; + WindowRef dialogWindow, origUnavailWindow; + WindowModality origModality; + EventHandlerRef handlerRef; +} AlertHandlerUserData; static OSStatus AlertHandler(EventHandlerCallRef callRef, EventRef eventRef, void *userData); -static Boolean MatchOneType(StringPtr fileNamePtr, OSType fileType, +static Boolean MatchOneType(StringPtr fileNamePtr, OSType fileType, OpenFileData *myofdPtr, FileFilter *filterPtr); -static pascal Boolean OpenFileFilterProc(AEDesc* theItem, void* info, +static pascal Boolean OpenFileFilterProc(AEDesc* theItem, void* info, NavCallBackUserData callBackUD, NavFilterModes filterMode); -static pascal void OpenEventProc(NavEventCallbackMessage callBackSelector, +static pascal void OpenEventProc(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, NavCallBackUserData callBackUD); -static void InitFileDialogs(); -static int NavServicesGetFile(Tcl_Interp *interp, OpenFileData *ofd, - AEDesc *initialDescPtr, +static void InitFileDialogs(void); +static int NavServicesGetFile(Tcl_Interp *interp, + OpenFileData *ofd, AEDesc *initialDescPtr, char *initialFile, AEDescList *selectDescPtr, - CFStringRef title, CFStringRef message, int multiple, int isOpen); -static int HandleInitialDirectory (Tcl_Interp *interp, - char *initialFile, char *initialDir, - FSRef *dirRef, - AEDescList *selectDescPtr, - AEDesc *dirDescPtr); + CFStringRef title, CFStringRef message, + int multiple, int isOpen, Tk_Window parent); +static int HandleInitialDirectory(Tcl_Interp *interp, + char *initialFile, char *initialDir, FSRef *dirRef, + AEDescList *selectDescPtr, AEDesc *dirDescPtr); /* * Have we initialized the file dialog subsystem @@ -104,87 +110,87 @@ static NavEventUPP openFileEventUPP; * * Tk_ChooseColorObjCmd -- * - * This procedure implements the color dialog box for the Mac - * platform. See the user documentation for details on what it - * does. + * This procedure implements the color dialog box for the Mac + * platform. See the user documentation for details on what it + * does. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * See the user documentation. + * See the user documentation. * *---------------------------------------------------------------------- */ int Tk_ChooseColorObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + ClientData clientData, /* Main window associated with interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *CONST objv[]) /* Argument objects. */ { - Tk_Window parent; - char *title; - int i, picked, srcRead, dstWrote; - ColorPickerInfo cpinfo; + OSStatus err; + Tk_Window parent, tkwin = (Tk_Window) clientData; + const char *title; + int i, picked = 0, srcRead, dstWrote; + CMError cmerr; + CMProfileRef prof; + NColorPickerInfo cpinfo; static int inited = 0; static RGBColor in; - static CONST char *optionStrings[] = { - "-initialcolor", "-parent", "-title", NULL + static const char *optionStrings[] = { + "-initialcolor", "-parent", "-title", NULL }; enum options { - COLOR_INITIAL, COLOR_PARENT, COLOR_TITLE + COLOR_INITIAL, COLOR_PARENT, COLOR_TITLE }; if (inited == 0) { - /* - * 'in' stores the last color picked. The next time the color dialog - * pops up, the last color will remain in the dialog. - */ + /* + * 'in' stores the last color picked. The next time the color + * dialog pops up, the last color will remain in the dialog. + */ in.red = 0xffff; in.green = 0xffff; in.blue = 0xffff; inited = 1; } - - parent = (Tk_Window) clientData; title = "Choose a color:"; - picked = 0; for (i = 1; i < objc; i += 2) { - int index; - char *option, *value; + int index; + const char *option, *value; if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", TCL_EXACT, &index) != TCL_OK) { return TCL_ERROR; } if (i + 1 == objc) { - option = Tcl_GetStringFromObj(objv[i], NULL); + option = Tcl_GetString(objv[i]); Tcl_AppendResult(interp, "value for \"", option, "\" missing", - (char *) NULL); + NULL); return TCL_ERROR; } - value = Tcl_GetStringFromObj(objv[i + 1], NULL); + value = Tcl_GetString(objv[i + 1]); switch ((enum options) index) { case COLOR_INITIAL: { XColor *colorPtr; - colorPtr = Tk_GetColor(interp, parent, value); + colorPtr = Tk_GetColor(interp, tkwin, value); if (colorPtr == NULL) { return TCL_ERROR; } - in.red = colorPtr->red; + in.red = colorPtr->red; in.green = colorPtr->green; - in.blue = colorPtr->blue; + in.blue = colorPtr->blue; Tk_FreeColor(colorPtr); break; } case COLOR_PARENT: { - parent = Tk_NameToWindow(interp, value, parent); + parent = Tk_NameToWindow(interp, value, tkwin); if (parent == NULL) { return TCL_ERROR; } @@ -197,31 +203,31 @@ Tk_ChooseColorObjCmd( } } - - cpinfo.theColor.profile = 0L; + cmerr = CMGetDefaultProfileBySpace(cmRGBData, &prof); + bzero(&cpinfo, sizeof(cpinfo)); + cpinfo.theColor.profile = prof; cpinfo.theColor.color.rgb.red = in.red; cpinfo.theColor.color.rgb.green = in.green; cpinfo.theColor.color.rgb.blue = in.blue; - cpinfo.dstProfile = 0L; - cpinfo.flags = kColorPickerCanModifyPalette - | kColorPickerCanAnimatePalette; - cpinfo.placeWhere = kDeepestColorScreen; - cpinfo.pickerType = 0L; - cpinfo.eventProc = NULL; - cpinfo.colorProc = NULL; - cpinfo.colorProcData = 0; - - /* This doesn't seem to actually set the title! */ - Tcl_UtfToExternal(NULL, NULL, title, -1, 0, NULL, + cpinfo.dstProfile = prof; + cpinfo.flags = kColorPickerDialogIsMoveable + | kColorPickerCanAnimatePalette; + cpinfo.placeWhere = kCenterOnMainScreen; + /* Currently, this does not actually change the colorpicker title */ + Tcl_UtfToExternal(NULL, TkMacOSXCarbonEncoding, title, -1, 0, NULL, StrBody(cpinfo.prompt), 255, &srcRead, &dstWrote, NULL); StrLength(cpinfo.prompt) = (unsigned char) dstWrote; - if ((PickColor(&cpinfo) == noErr) && (cpinfo.newColorChosen != 0)) { - in.red = cpinfo.theColor.color.rgb.red; - in.green = cpinfo.theColor.color.rgb.green; - in.blue = cpinfo.theColor.color.rgb.blue; + TkMacOSXTrackingLoop(1); + err = ChkErr(NPickColor, &cpinfo); + TkMacOSXTrackingLoop(0); + if ((err == noErr) && (cpinfo.newColorChosen != 0)) { + in.red = cpinfo.theColor.color.rgb.red; + in.green = cpinfo.theColor.color.rgb.green; + in.blue = cpinfo.theColor.color.rgb.blue; picked = 1; } + cmerr = CMCloseProfile(prof); if (picked != 0) { char result[32]; @@ -239,78 +245,65 @@ Tk_ChooseColorObjCmd( * * Tk_GetOpenFileObjCmd -- * - * This procedure implements the "open file" dialog box for the - * Mac platform. See the user documentation for details on what - * it does. + * This procedure implements the "open file" dialog box for the + * Mac platform. See the user documentation for details on what + * it does. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * See user documentation. + * See user documentation. *---------------------------------------------------------------------- */ int Tk_GetOpenFileObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + ClientData clientData, /* Main window associated with interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *CONST objv[]) /* Argument objects. */ { - int i, result, multiple; + int i, result = TCL_ERROR, multiple = 0; OpenFileData ofd; - Tk_Window parent; - CFStringRef message, title; + Tk_Window parent = NULL; + CFStringRef message = NULL, title = NULL; AEDesc initialDesc = {typeNull, NULL}; FSRef dirRef; AEDesc *initialPtr = NULL; AEDescList selectDesc = {typeNull, NULL}; char *initialFile = NULL, *initialDir = NULL; - static CONST char *openOptionStrings[] = { - "-defaultextension", "-filetypes", - "-initialdir", "-initialfile", - "-message", "-multiple", - "-parent", "-title", NULL + static const char *openOptionStrings[] = { + "-defaultextension", "-filetypes", "-initialdir", "-initialfile", + "-message", "-multiple", "-parent", "-title", NULL }; enum openOptions { - OPEN_DEFAULT, OPEN_FILETYPES, - OPEN_INITDIR, OPEN_INITFILE, - OPEN_MESSAGE, OPEN_MULTIPLE, - OPEN_PARENT, OPEN_TITLE + OPEN_DEFAULT, OPEN_FILETYPES, OPEN_INITDIR, OPEN_INITFILE, + OPEN_MESSAGE, OPEN_MULTIPLE, OPEN_PARENT, OPEN_TITLE }; if (!fileDlgInited) { InitFileDialogs(); } - - result = TCL_ERROR; - parent = (Tk_Window) clientData; - multiple = false; - title = NULL; - message = NULL; - TkInitFileFilters(&ofd.fl); - - ofd.curType = 0; - ofd.popupItem = OPEN_POPUP_ITEM; - ofd.usePopup = 1; + ofd.curType = 0; + ofd.popupItem = OPEN_POPUP_ITEM; + ofd.usePopup = 1; for (i = 1; i < objc; i += 2) { char *choice; int index, choiceLen; char *string; + Tcl_Obj *types; if (Tcl_GetIndexFromObj(interp, objv[i], openOptionStrings, "option", TCL_EXACT, &index) != TCL_OK) { - result = TCL_ERROR; goto end; } if (i + 1 == objc) { - string = Tcl_GetStringFromObj(objv[i], NULL); + string = Tcl_GetString(objv[i]); Tcl_AppendResult(interp, "value for \"", string, "\" missing", - (char *) NULL); - result = TCL_ERROR; + NULL); goto end; } @@ -318,9 +311,8 @@ Tk_GetOpenFileObjCmd( case OPEN_DEFAULT: break; case OPEN_FILETYPES: - if (TkGetFileFilters(interp, &ofd.fl, objv[i + 1], 0) - != TCL_OK) { - result = TCL_ERROR; + types = objv[i + 1]; + if (TkGetFileFilters(interp, &ofd.fl, types, 0) != TCL_OK) { goto end; } break; @@ -330,61 +322,61 @@ Tk_GetOpenFileObjCmd( if (choiceLen == 0) { initialDir = NULL; } break; case OPEN_INITFILE: - initialFile = Tcl_GetStringFromObj(objv[i + 1], NULL); + initialFile = Tcl_GetString(objv[i + 1]); /* empty strings should be like no selection given */ if (choiceLen == 0) { initialFile = NULL; } break; case OPEN_MESSAGE: choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen); - message = CFStringCreateWithBytes(NULL, (unsigned char*) choice, choiceLen, - kCFStringEncodingUTF8, false); + message = CFStringCreateWithBytes(NULL, (unsigned char*) + choice, choiceLen, kCFStringEncodingUTF8, false); break; case OPEN_MULTIPLE: if (Tcl_GetBooleanFromObj(interp, objv[i + 1], &multiple) != TCL_OK) { - result = TCL_ERROR; goto end; } break; case OPEN_PARENT: choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen); - parent = Tk_NameToWindow(interp, choice, parent); + parent = Tk_NameToWindow(interp, choice, + (Tk_Window) clientData); if (parent == NULL) { - result = TCL_ERROR; goto end; } break; case OPEN_TITLE: choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen); - title = CFStringCreateWithBytes(NULL, (unsigned char*) choice, choiceLen, - kCFStringEncodingUTF8, false); + title = CFStringCreateWithBytes(NULL, (unsigned char*) + choice, choiceLen, kCFStringEncodingUTF8, false); break; } } if (HandleInitialDirectory(interp, initialFile, initialDir, &dirRef, - &selectDesc, &initialDesc) != TCL_OK) { - result = TCL_ERROR; + &selectDesc, &initialDesc) != TCL_OK) { goto end; } if (initialDesc.descriptorType == typeFSRef) { initialPtr = &initialDesc; } - result = NavServicesGetFile(interp, &ofd, initialPtr, - NULL, &selectDesc, title, message, multiple, OPEN_FILE); - - end: + result = NavServicesGetFile(interp, &ofd, initialPtr, NULL, &selectDesc, + title, message, multiple, OPEN_FILE, parent); +end: TkFreeFileFilters(&ofd.fl); - AEDisposeDesc(&initialDesc); - AEDisposeDesc(&selectDesc); - if (title != NULL) { + if (initialDesc.dataHandle) { + ChkErr(AEDisposeDesc, &initialDesc); + } + if (selectDesc.dataHandle) { + ChkErr(AEDisposeDesc, &selectDesc); + } + if (title) { CFRelease(title); } - if (message != NULL) { + if (message) { CFRelease(message); } - return result; } @@ -393,64 +385,58 @@ Tk_GetOpenFileObjCmd( * * Tk_GetSaveFileObjCmd -- * - * Same as Tk_GetOpenFileCmd but opens a "save file" dialog box - * instead + * Same as Tk_GetOpenFileCmd but opens a "save file" dialog box + * instead * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * See user documentation. + * See user documentation. *---------------------------------------------------------------------- */ int Tk_GetSaveFileObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + ClientData clientData, /* Main window associated with interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *CONST objv[]) /* Argument objects. */ { - int i, result; + int i, result = TCL_ERROR; char *initialFile = NULL; - Tk_Window parent; + Tk_Window parent = NULL; AEDesc initialDesc = {typeNull, NULL}; AEDesc *initialPtr = NULL; FSRef dirRef; - CFStringRef title, message; + CFStringRef title = NULL, message = NULL; OpenFileData ofd; - static CONST char *saveOptionStrings[] = { - "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-message", "-parent", "-title", NULL + static const char *saveOptionStrings[] = { + "-defaultextension", "-filetypes", "-initialdir", "-initialfile", + "-message", "-parent", "-title", NULL }; enum saveOptions { - SAVE_DEFAULT, SAVE_FILETYPES, SAVE_INITDIR, SAVE_INITFILE, - SAVE_MESSAGE, SAVE_PARENT, SAVE_TITLE + SAVE_DEFAULT, SAVE_FILETYPES, SAVE_INITDIR, SAVE_INITFILE, + SAVE_MESSAGE, SAVE_PARENT, SAVE_TITLE }; if (!fileDlgInited) { InitFileDialogs(); } - result = TCL_ERROR; - parent = (Tk_Window) clientData; - title = NULL; - message = NULL; - for (i = 1; i < objc; i += 2) { - char *choice; + char *choice, *string; int index, choiceLen; - char *string; if (Tcl_GetIndexFromObj(interp, objv[i], saveOptionStrings, "option", TCL_EXACT, &index) != TCL_OK) { - return TCL_ERROR; + goto end; } if (i + 1 == objc) { - string = Tcl_GetStringFromObj(objv[i], NULL); + string = Tcl_GetString(objv[i]); Tcl_AppendResult(interp, "value for \"", string, "\" missing", - (char *) NULL); - return TCL_ERROR; + NULL); + goto end; } switch (index) { case SAVE_DEFAULT: @@ -461,58 +447,57 @@ Tk_GetSaveFileObjCmd( case SAVE_INITDIR: choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen); /* empty strings should be like no selection given */ - if (choiceLen && - HandleInitialDirectory(interp, NULL, choice, &dirRef, - NULL, &initialDesc) != TCL_OK) { - result = TCL_ERROR; + if (choiceLen && HandleInitialDirectory(interp, NULL, choice, + &dirRef, NULL, &initialDesc) != TCL_OK) { goto end; } break; case SAVE_INITFILE: initialFile = Tcl_GetStringFromObj(objv[i + 1], &choiceLen); /* empty strings should be like no selection given */ - if (choiceLen == 0) { initialFile = NULL; } + if (choiceLen == 0) { + initialFile = NULL; + } break; case SAVE_MESSAGE: choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen); - message = CFStringCreateWithBytes(NULL, (unsigned char*) choice, choiceLen, - kCFStringEncodingUTF8, false); + message = CFStringCreateWithBytes(NULL, (unsigned char*) + choice, choiceLen, kCFStringEncodingUTF8, false); break; case SAVE_PARENT: choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen); - parent = Tk_NameToWindow(interp, choice, parent); + parent = Tk_NameToWindow(interp, choice, + (Tk_Window) clientData); if (parent == NULL) { - result = TCL_ERROR; goto end; } break; case SAVE_TITLE: choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen); - title = CFStringCreateWithBytes(NULL, (unsigned char*) choice, choiceLen, - kCFStringEncodingUTF8, false); + title = CFStringCreateWithBytes(NULL, (unsigned char*) + choice, choiceLen, kCFStringEncodingUTF8, false); break; } } TkInitFileFilters(&ofd.fl); ofd.usePopup = 0; - if (initialDesc.descriptorType == typeFSRef) { initialPtr = &initialDesc; } result = NavServicesGetFile(interp, &ofd, initialPtr, initialFile, NULL, - title, message, false, SAVE_FILE); - - end: - - AEDisposeDesc(&initialDesc); - if (title != NULL) { + title, message, false, SAVE_FILE, parent); + TkFreeFileFilters(&ofd.fl); +end: + if (initialDesc.dataHandle) { + ChkErr(AEDisposeDesc, &initialDesc); + } + if (title) { CFRelease(title); } - if (message != NULL) { + if (message) { CFRelease(message); } - return result; } @@ -521,53 +506,43 @@ Tk_GetSaveFileObjCmd( * * Tk_ChooseDirectoryObjCmd -- * - * This procedure implements the "tk_chooseDirectory" dialog box - * for the Windows platform. See the user documentation for details - * on what it does. + * This procedure implements the "tk_chooseDirectory" dialog box + * for the Windows platform. See the user documentation for details + * on what it does. * * Results: - * See user documentation. + * See user documentation. * * Side effects: - * A modal dialog window is created. Tcl_SetServiceMode() is - * called to allow background events to be processed + * A modal dialog window is created. * *---------------------------------------------------------------------- */ int Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Main window associated with interpreter. */ - Tcl_Interp *interp; /* Current interpreter. */ - int objc; /* Number of arguments. */ - Tcl_Obj *CONST objv[]; /* Argument objects. */ + ClientData clientData; /* Main window associated with interpreter. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ { - int i, result; - Tk_Window parent; - AEDesc initialDesc = {typeNull, NULL}; - AEDesc *initialPtr = NULL; + int i, result = TCL_ERROR; + Tk_Window parent = NULL; + AEDesc initialDesc = {typeNull, NULL}, *initialPtr = NULL; FSRef dirRef; - CFStringRef message, title; + CFStringRef message = NULL, title = NULL; OpenFileData ofd; - static CONST char *chooseOptionStrings[] = { + static const char *chooseOptionStrings[] = { "-initialdir", "-message", "-mustexist", "-parent", "-title", NULL }; enum chooseOptions { - CHOOSE_INITDIR, CHOOSE_MESSAGE, CHOOSE_MUSTEXIST, - CHOOSE_PARENT, CHOOSE_TITLE + CHOOSE_INITDIR, CHOOSE_MESSAGE, CHOOSE_MUSTEXIST, CHOOSE_PARENT, + CHOOSE_TITLE }; - if (!NavServicesAvailable()) { - return TCL_ERROR; - } - if (!fileDlgInited) { InitFileDialogs(); } - result = TCL_ERROR; - parent = (Tk_Window) clientData; - title = NULL; - message = NULL; for (i = 1; i < objc; i += 2) { char *choice; @@ -576,68 +551,82 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) if (Tcl_GetIndexFromObj(interp, objv[i], chooseOptionStrings, "option", TCL_EXACT, &index) != TCL_OK) { - return TCL_ERROR; + goto end; } if (i + 1 == objc) { - string = Tcl_GetStringFromObj(objv[i], NULL); + string = Tcl_GetString(objv[i]); Tcl_AppendResult(interp, "value for \"", string, "\" missing", - (char *) NULL); - return TCL_ERROR; + NULL); + goto end; } switch (index) { case CHOOSE_INITDIR: choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen); - if (choiceLen && - HandleInitialDirectory(interp, NULL, choice, &dirRef, - NULL, &initialDesc) != TCL_OK) { - result = TCL_ERROR; + if (choiceLen && HandleInitialDirectory(interp, NULL, choice, + &dirRef, NULL, &initialDesc) != TCL_OK) { goto end; } break; case CHOOSE_MESSAGE: choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen); - message = CFStringCreateWithBytes(NULL, (unsigned char*) choice, choiceLen, - kCFStringEncodingUTF8, false); + message = CFStringCreateWithBytes(NULL, (unsigned char*) + choice, choiceLen, kCFStringEncodingUTF8, false); break; case CHOOSE_PARENT: choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen); - parent = Tk_NameToWindow(interp, choice, parent); + parent = Tk_NameToWindow(interp, choice, + (Tk_Window) clientData); if (parent == NULL) { - result = TCL_ERROR; goto end; } break; case CHOOSE_TITLE: choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen); - title = CFStringCreateWithBytes(NULL, (unsigned char*) choice, choiceLen, - kCFStringEncodingUTF8, false); + title = CFStringCreateWithBytes(NULL, (unsigned char*) choice, + choiceLen, kCFStringEncodingUTF8, false); break; } } TkInitFileFilters(&ofd.fl); ofd.usePopup = 0; - if (initialDesc.descriptorType == typeFSRef) { initialPtr = &initialDesc; } - result = NavServicesGetFile(interp, &ofd, initialPtr, NULL, NULL, - title, message, false, CHOOSE_FOLDER); - - end: - AEDisposeDesc(&initialDesc); - if (title != NULL) { + result = NavServicesGetFile(interp, &ofd, initialPtr, NULL, NULL, title, + message, false, CHOOSE_FOLDER, parent); + TkFreeFileFilters(&ofd.fl); +end: + if (initialDesc.dataHandle) { + ChkErr(AEDisposeDesc, &initialDesc); + } + if (title) { CFRelease(title); } - if (message != NULL) { + if (message) { CFRelease(message); } - return result; } + +/* + *---------------------------------------------------------------------- + * + * HandleInitialDirectory -- + * + * Helper for -initialdir setup. + * + * Results: + * Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ int -HandleInitialDirectory ( +HandleInitialDirectory( Tcl_Interp *interp, char *initialFile, char *initialDir, @@ -646,42 +635,37 @@ HandleInitialDirectory ( AEDesc *dirDescPtr) { Tcl_DString ds; - OSErr err; + OSStatus err; Boolean isDirectory; char *dirName = NULL; - int result = TCL_OK; + int result = TCL_ERROR; - if (initialDir != NULL) { + if (initialDir) { dirName = Tcl_TranslateFileName(interp, initialDir, &ds); if (dirName == NULL) { - return TCL_ERROR; + goto end; } - - err = FSPathMakeRef((unsigned char*) dirName, + err = ChkErr(FSPathMakeRef, (unsigned char*) dirName, dirRef, &isDirectory); - if (err != noErr) { - Tcl_AppendResult(interp, "bad directory \"", - initialDir, "\"", NULL); - result = TCL_ERROR; + Tcl_AppendResult(interp, "bad directory \"", initialDir, "\"", + NULL); goto end; } if (!isDirectory) { Tcl_AppendResult(interp, "-intialdir \"", initialDir, " is a file, not a directory.\"", NULL); - result = TCL_ERROR; goto end; } - - AECreateDesc(typeFSRef, dirRef, sizeof(*dirRef), dirDescPtr); + ChkErr(AECreateDesc, typeFSRef, dirRef, sizeof(*dirRef), dirDescPtr); } - if (initialFile != NULL && selectDescPtr != NULL) { + if (initialFile && selectDescPtr) { FSRef fileRef; AEDesc fileDesc; char *namePtr; - if (initialDir != NULL) { + if (initialDir) { Tcl_DStringAppend(&ds, "/", 1); Tcl_DStringAppend(&ds, initialFile, -1); namePtr = Tcl_DStringValue(&ds); @@ -689,35 +673,68 @@ HandleInitialDirectory ( namePtr = initialFile; } - AECreateList(NULL, 0, false, selectDescPtr); + ChkErr(AECreateList, NULL, 0, false, selectDescPtr); - err = FSPathMakeRef((unsigned char*) namePtr, &fileRef, &isDirectory); + err = ChkErr(FSPathMakeRef, (unsigned char*) namePtr, &fileRef, + &isDirectory); if (err != noErr) { Tcl_AppendResult(interp, "bad initialfile \"", initialFile, "\" file does not exist.", NULL); - return TCL_ERROR; + goto end; } - AECreateDesc(typeFSRef, &fileRef, sizeof(fileRef), &fileDesc); - AEPutDesc(selectDescPtr, 1, &fileDesc); - AEDisposeDesc(&fileDesc); + ChkErr(AECreateDesc, typeFSRef, &fileRef, sizeof(fileRef), &fileDesc); + ChkErr(AEPutDesc, selectDescPtr, 1, &fileDesc); + ChkErr(AEDisposeDesc, &fileDesc); } - + result = TCL_OK; end: - if (dirName != NULL) { + if (dirName) { Tcl_DStringFree(&ds); } return result; } + +/* + *---------------------------------------------------------------------- + * + * InitFileDialogs -- + * + * Initialize file dialog subsystem. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ -static void -InitFileDialogs() +void +InitFileDialogs(void) { fileDlgInited = 1; openFileFilterUPP = NewNavObjectFilterUPP(OpenFileFilterProc); openFileEventUPP = NewNavEventUPP(OpenEventProc); } + +/* + *---------------------------------------------------------------------- + * + * NavServicesGetFile -- + * + * Common wrapper for NavServices API. + * + * Results: + * Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ -static int +int NavServicesGetFile( Tcl_Interp *interp, OpenFileData *ofdPtr, @@ -727,30 +744,43 @@ NavServicesGetFile( CFStringRef title, CFStringRef message, int multiple, - int isOpen) + int isOpen, + Tk_Window parent) { - NavReplyRecord theReply; - NavDialogCreationOptions diagOptions; + NavHandlerUserData data; + NavDialogCreationOptions options; NavDialogRef dialogRef = NULL; CFStringRef * menuItemNames = NULL; - OSErr err; + OSStatus err; Tcl_Obj *theResult = NULL; - int result; + int result = TCL_ERROR; - err = NavGetDefaultDialogCreationOptions(&diagOptions); - if (err!=noErr) { - return TCL_ERROR; + bzero(&data, sizeof(data)); + err = NavGetDefaultDialogCreationOptions(&options); + if (err != noErr) { + return result; } - diagOptions.location.h = -1; - diagOptions.location.v = -1; - diagOptions.optionFlags = kNavDontAutoTranslate - + kNavDontAddTranslateItems; + options.optionFlags = kNavDontAutoTranslate | kNavDontAddTranslateItems + | kNavSupportPackages | kNavAllFilesInPopup; if (multiple) { - diagOptions.optionFlags += kNavAllowMultipleFiles; + options.optionFlags |= kNavAllowMultipleFiles; + } + options.modality = kWindowModalityAppModal; + if (parent && ((TkWindow*)parent)->window != None && + TkMacOSXHostToplevelExists(parent)) { + options.parentWindow = GetWindowFromPort(TkMacOSXGetDrawablePort( + Tk_WindowId(parent))); + if (options.parentWindow) { + options.modality = kWindowModalityWindowModal; + data.sheet = 1; + } } - diagOptions.modality = kWindowModalityAppModal; - if (ofdPtr != NULL && ofdPtr->usePopup) { + /* + * Now process the selection list. We have to use the popupExtension + * to fill the menu. + */ + if (ofdPtr && ofdPtr->usePopup) { FileFilter *filterPtr; filterPtr = ofdPtr->fl.filters; @@ -758,13 +788,12 @@ NavServicesGetFile( ofdPtr->usePopup = 0; } } - - if (ofdPtr != NULL && ofdPtr->usePopup) { + if (ofdPtr && ofdPtr->usePopup) { FileFilter *filterPtr; int index = 0; ofdPtr->curType = 0; - menuItemNames = (CFStringRef *)ckalloc(ofdPtr->fl.numFilters + menuItemNames = (CFStringRef *) ckalloc(ofdPtr->fl.numFilters * sizeof(CFStringRef)); for (filterPtr = ofdPtr->fl.filters; filterPtr != NULL; @@ -772,98 +801,60 @@ NavServicesGetFile( menuItemNames[index] = CFStringCreateWithCString(NULL, filterPtr->name, kCFStringEncodingUTF8); } - diagOptions.popupExtension = CFArrayCreate(NULL, + options.popupExtension = CFArrayCreate(NULL, (const void **) menuItemNames, ofdPtr->fl.numFilters, NULL); } else { - diagOptions.optionFlags += kNavNoTypePopup; - diagOptions.popupExtension = NULL; + options.optionFlags |= kNavNoTypePopup; + options.popupExtension = NULL; } - - /* - * This is required to allow App packages to be selectable in the - * file dialogs... - */ - - diagOptions.optionFlags += kNavSupportPackages; - - diagOptions.clientName = CFStringCreateWithCString(NULL, "Wish", kCFStringEncodingUTF8); - diagOptions.message = message; - diagOptions.windowTitle = title; + options.clientName = CFSTR("Wish"); + options.message = message; + options.windowTitle = title; if (initialFile) { - diagOptions.saveFileName = CFStringCreateWithCString(NULL, + options.saveFileName = CFStringCreateWithCString(NULL, initialFile, kCFStringEncodingUTF8); } else { - diagOptions.saveFileName = NULL; + options.saveFileName = NULL; } - - diagOptions.actionButtonLabel = NULL; - diagOptions.cancelButtonLabel = NULL; - diagOptions.preferenceKey = 0; - - /* - * Now process the selection list. We have to use the popupExtension - * to fill the menu. - */ - if (isOpen == OPEN_FILE) { - err = NavCreateGetFileDialog(&diagOptions, - NULL, - openFileEventUPP, - NULL, - openFileFilterUPP, - ofdPtr, - &dialogRef); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"NavCreateGetFileDialog failed, %d\n", err); -#endif - dialogRef = NULL; - } + data.ofdPtr = ofdPtr; + err = ChkErr(NavCreateGetFileDialog, &options, NULL, + openFileEventUPP, NULL, openFileFilterUPP, &data, &dialogRef); } else if (isOpen == SAVE_FILE) { - err = NavCreatePutFileDialog(&diagOptions, 'TEXT', 'WIsH', - openFileEventUPP, NULL, &dialogRef); - if (err!=noErr){ -#ifdef TK_MAC_DEBUG - fprintf(stderr,"NavCreatePutFileDialog failed, %d\n", err); -#endif - dialogRef = NULL; - } + err = ChkErr(NavCreatePutFileDialog, &options, 'TEXT', 'WIsH', + openFileEventUPP, &data, &dialogRef); } else if (isOpen == CHOOSE_FOLDER) { - err = NavCreateChooseFolderDialog(&diagOptions, openFileEventUPP, - openFileFilterUPP, NULL, &dialogRef); - if (err!=noErr){ -#ifdef TK_MAC_DEBUG - fprintf(stderr,"NavCreateChooseFolderDialog failed, %d\n", err); -#endif - dialogRef = NULL; - } + err = ChkErr(NavCreateChooseFolderDialog, &options, + openFileEventUPP, openFileFilterUPP, &data, &dialogRef); } - - if (dialogRef) { - if (initialDescPtr != NULL) { - NavCustomControl (dialogRef, kNavCtlSetLocation, initialDescPtr); + if (err == noErr && dialogRef) { + if (initialDescPtr) { + ChkErr(NavCustomControl, dialogRef, kNavCtlSetLocation, + initialDescPtr); } - if ((selectDescPtr != NULL) - && (selectDescPtr->descriptorType != typeNull)) { - NavCustomControl(dialogRef, kNavCtlSetSelection, selectDescPtr); + if (selectDescPtr && selectDescPtr->descriptorType != typeNull) { + ChkErr(NavCustomControl, dialogRef, kNavCtlSetSelection, + selectDescPtr); } - - if ((err = NavDialogRun(dialogRef)) != noErr){ -#ifdef TK_MAC_DEBUG - fprintf(stderr,"NavDialogRun failed, %d\n", err); -#endif - } else { - if ((err = NavDialogGetReply(dialogRef, &theReply)) != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"NavGetReply failed, %d\n", err); -#endif + TkMacOSXTrackingLoop(1); + err = ChkErr(NavDialogRun, dialogRef); + if (err == noErr) { + if (data.sheet) { + data.dialogWindow = NavDialogGetWindow(dialogRef); + ChkErr(GetWindowModality, data.dialogWindow, + &data.origModality, &data.origUnavailWindow); + ChkErr(SetWindowModality, data.dialogWindow, + kWindowModalityAppModal, NULL); + ChkErr(RunAppModalLoopForWindow, data.dialogWindow); } + err = data.err; } + TkMacOSXTrackingLoop(0); } /* * Most commands assume that the file dialogs return a single - * item, not a list. So only build a list if multiple is true... + * item, not a list. So only build a list if multiple is true... */ if (err == noErr) { if (multiple) { @@ -875,55 +866,51 @@ NavServicesGetFile( err = memFullErr; } } - if (theReply.validRecord && err == noErr) { + if (err == noErr && data.reply.validRecord) { AEDesc resultDesc; long count; - FSRef fsRef; - char pathPtr[1024]; - int pathValid = 0; - err = AECountItems(&theReply.selection, &count); + FSRef fsRef; + char pathPtr[PATH_MAX + 1]; + + err = ChkErr(AECountItems, &data.reply.selection, &count); if (err == noErr) { long i; + for (i = 1; i <= count; i++) { - err = AEGetNthDesc(&theReply.selection, - i, typeFSRef, NULL, &resultDesc); - pathValid = 0; + err = ChkErr(AEGetNthDesc, &data.reply.selection, i, + typeFSRef, NULL, &resultDesc); if (err == noErr) { - if ((err = AEGetDescData(&resultDesc, &fsRef, sizeof(fsRef))) - != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"AEGetDescData failed %d\n", err); -#endif - } else { - if ((err = FSRefMakePath(&fsRef, (unsigned char*) pathPtr, 1024))) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"FSRefMakePath failed, %d\n", err); -#endif - } else { + err = ChkErr(AEGetDescData, &resultDesc, &fsRef, + sizeof(fsRef)); + if (err == noErr) { + err = ChkErr(FSRefMakePath, &fsRef, (unsigned char*) + pathPtr, PATH_MAX + 1); + if (err == noErr) { + int pathValid = 0; + if (isOpen == SAVE_FILE) { - CFStringRef saveNameRef; - char saveName [1024]; - if ((saveNameRef = NavDialogGetSaveFileName(dialogRef))) { - if (CFStringGetCString(saveNameRef, saveName, - 1024, kCFStringEncodingUTF8)) { - if (strlen(pathPtr) + strlen(saveName) < 1023) { + if (data.saveNameRef) { + char saveName [PATH_MAX + 1]; + + if (CFStringGetCString(data.saveNameRef, + saveName, PATH_MAX + 1, + kCFStringEncodingUTF8)) { + if (strlen(pathPtr) + strlen(saveName) + < PATH_MAX) { strcat(pathPtr, "/"); strcat(pathPtr, saveName); pathValid = 1; } else { -#ifdef TK_MAC_DEBUG - fprintf(stderr, "Path name too long\n"); -#endif + TkMacOSXDbgMsg("Path name too " + "long"); } } else { -#ifdef TK_MAC_DEBUG - fprintf(stderr, "CFStringGetCString failed\n"); -#endif + TkMacOSXDbgMsg("CFStringGetCString " + "failed"); } } else { -#ifdef TK_MAC_DEBUG - fprintf(stderr, "NavDialogGetSaveFileName failed\n"); -#endif + TkMacOSXDbgMsg("NavDialogGetSaveFileName " + "failed"); } } else { pathValid = 1; @@ -938,73 +925,137 @@ NavServicesGetFile( } } } - AEDisposeDesc(&resultDesc); + ChkErr(AEDisposeDesc, &resultDesc); } } - } - err = NavDisposeReply(&theReply); - Tcl_SetObjResult(interp, theResult); - result = TCL_OK; + } + Tcl_SetObjResult(interp, theResult); + result = TCL_OK; } else if (err == userCanceledErr) { result = TCL_OK; - } else { - result = TCL_ERROR; } /* - * Clean up any allocated strings - * dispose of things in reverse order of creation + * Clean up any allocated memory. */ - if (diagOptions.windowTitle) { - CFRelease(diagOptions.windowTitle); + if (data.reply.validRecord) { + ChkErr(NavDisposeReply, &data.reply); } - if (diagOptions.saveFileName) { - CFRelease(diagOptions.saveFileName); + if (data.saveNameRef) { + CFRelease(data.saveNameRef); } - if (diagOptions.message) { - CFRelease(diagOptions.message); + if (options.saveFileName) { + CFRelease(options.saveFileName); } - if (diagOptions.clientName) { - CFRelease(diagOptions.clientName); + if (options.clientName) { + CFRelease(options.clientName); } - /* - * dispose of the CFArray diagOptions.popupExtension - */ - if (menuItemNames) { int i; - for (i = 0;i < ofdPtr->fl.numFilters; i++) { + for (i = 0; i < ofdPtr->fl.numFilters; i++) { CFRelease(menuItemNames[i]); } ckfree((void *)menuItemNames); } - if (diagOptions.popupExtension != NULL) { - CFRelease(diagOptions.popupExtension); + if (options.popupExtension) { + CFRelease(options.popupExtension); } - return result; } + +/* + *---------------------------------------------------------------------- + * + * OpenEventProc -- + * + * NavServices event handling callback. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +pascal void +OpenEventProc( + NavEventCallbackMessage callBackSelector, + NavCBRecPtr callBackParams, + NavCallBackUserData callBackUD) +{ + NavHandlerUserData *data = (NavHandlerUserData*) callBackUD; -static pascal Boolean + switch (callBackSelector) { + case kNavCBPopupMenuSelect: + data->ofdPtr->curType = ((NavMenuItemSpec *) + callBackParams->eventData.eventDataParms.param)->menuType; + break; + case kNavCBAccept: + case kNavCBCancel: + if (data->sheet) { + ChkErr(QuitAppModalLoopForWindow, data->dialogWindow); + ChkErr(SetWindowModality, data->dialogWindow, + data->origModality, data->origUnavailWindow); + } + break; + case kNavCBUserAction: + if (data->reply.validRecord) { + ChkErr(NavDisposeReply, &data->reply); + data->reply.validRecord = 0; + } + data->err = NavDialogGetReply(callBackParams->context, + &data->reply); + if (callBackParams->userAction == kNavUserActionSaveAs) { + data->saveNameRef = NavDialogGetSaveFileName( + callBackParams->context); + if (data->saveNameRef) { + CFRetain(data->saveNameRef); + } + } + break; + case kNavCBTerminate: + NavDialogDispose(callBackParams->context); + break; + case kNavCBEvent: + TkMacOSXRunTclEventLoop(); + break; + } +} + +/* + *---------------------------------------------------------------------- + * + * OpenFileFilterProc -- + * + * NavServices file filter callback. + * + * Results: + * Whether to use the file in question. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +pascal Boolean OpenFileFilterProc( AEDesc* theItem, void* info, NavCallBackUserData callBackUD, NavFilterModes filterMode) { - OpenFileData *ofdPtr = (OpenFileData *) callBackUD; + OpenFileData *ofdPtr = ((NavHandlerUserData*) callBackUD)->ofdPtr; + int result = MATCHED; - if (!ofdPtr || !ofdPtr->usePopup) { - return true; - } else { - if (ofdPtr->fl.numFilters == 0) { - return true; - } else { + if (ofdPtr && ofdPtr->usePopup) { + if (ofdPtr->fl.numFilters > 0) { if ((theItem->descriptorType == typeFSS) - || (theItem->descriptorType = typeFSRef)) { + || (theItem->descriptorType == typeFSRef)) { NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo *) info; char fileName[256]; - int result; if (!theInfo->isFolder) { OSType fileType; @@ -1019,7 +1070,7 @@ OpenFileFilterProc( if (theItem->descriptorType == typeFSS) { int len; - fileNamePtr = (((FSSpec *) *theItem->dataHandle)->name); + fileNamePtr = ((FSSpec *) *theItem->dataHandle)->name; len = fileNamePtr[0]; strncpy(fileName, (char*) fileNamePtr + 1, len); fileName[len] = '\0'; @@ -1029,15 +1080,15 @@ OpenFileFilterProc( OSStatus err; FSRef *theRef = (FSRef *) *theItem->dataHandle; HFSUniStr255 uniFileName; - err = FSGetCatalogInfo (theRef, kFSCatInfoNone, NULL, - &uniFileName, NULL, NULL); + err = ChkErr(FSGetCatalogInfo, theRef, kFSCatInfoNone, + NULL, &uniFileName, NULL, NULL); if (err == noErr) { Tcl_UniCharToUtfDString ( (Tcl_UniChar *) uniFileName.unicode, - uniFileName.length, - &fileNameDString); - fileNamePtr = (unsigned char*) Tcl_DStringValue(&fileNameDString); + uniFileName.length, &fileNameDString); + fileNamePtr = (unsigned char*) + Tcl_DStringValue(&fileNameDString); } else { fileNamePtr = NULL; } @@ -1052,7 +1103,7 @@ OpenFileFilterProc( result = MatchOneType(fileNamePtr, fileType, ofdPtr, filterPtr); } else { - result = false; + result = UNMATCHED; } } else { /* @@ -1071,42 +1122,12 @@ OpenFileFilterProc( } } } - Tcl_DStringFree (&fileNameDString); - return (result == MATCHED); - } else { - return true; } } } - - return true; - } -} - -pascal void -OpenEventProc( - NavEventCallbackMessage callBackSelector, - NavCBRecPtr callBackParams, - NavCallBackUserData callBackUD) -{ - NavMenuItemSpec *chosenItem; - OpenFileData *ofd = (OpenFileData *) callBackUD; - static SInt32 otherEvent = ~(kNavCBCustomize|kNavCBStart|kNavCBTerminate - |kNavCBNewLocation|kNavCBShowDesktop|kNavCBSelectEntry|kNavCBAccept - |kNavCBCancel|kNavCBAdjustPreview); - - if (callBackSelector == kNavCBPopupMenuSelect) { - chosenItem = (NavMenuItemSpec *) callBackParams->eventData.eventDataParms.param; - ofd->curType = chosenItem->menuType; - } else if (callBackSelector == kNavCBAdjustRect - || (callBackSelector & otherEvent) != 0) { - while (Tcl_DoOneEvent(TCL_IDLE_EVENTS - | TCL_DONT_WAIT - | TCL_WINDOW_EVENTS)) { - /* Empty Body */ - } } + return (result == MATCHED); } /* @@ -1114,27 +1135,28 @@ OpenEventProc( * * MatchOneType -- * - * Match a file with one file type in the list of file types. + * Match a file with one file type in the list of file types. * * Results: - * Returns MATCHED if the file matches with the file type; returns - * UNMATCHED otherwise. + * Returns MATCHED if the file matches with the file type; returns + * UNMATCHED otherwise. * * Side effects: - * None + * None * *---------------------------------------------------------------------- */ -static Boolean +Boolean MatchOneType( - StringPtr fileNamePtr, /* Name of the file */ - OSType fileType, /* Type of the file, 0 means there was no specified type. */ - OpenFileData * ofdPtr, /* Information about this file dialog */ - FileFilter * filterPtr) /* Match the file described by pb against - * this filter */ + StringPtr fileNamePtr, /* Name of the file */ + OSType fileType, /* Type of the file, 0 means there was no + * specified type. */ + OpenFileData *ofdPtr, /* Information about this file dialog */ + FileFilter *filterPtr) /* Match the file described by pb against this + * filter */ { - FileFilterClause * clausePtr; + FileFilterClause *clausePtr; /* * A file matches with a file type if it matches with at least one @@ -1155,10 +1177,10 @@ MatchOneType( for (clausePtr = filterPtr->clauses; clausePtr; clausePtr = clausePtr->next) { - int macMatched = 0; + int macMatched = 0; int globMatched = 0; - GlobPattern * globPtr; - MacFileType * mfPtr; + GlobPattern *globPtr; + MacFileType *mfPtr; if (clausePtr->patterns == NULL) { globMatched = 1; @@ -1196,10 +1218,10 @@ MatchOneType( goto glob_unmatched; } - glob_unmatched: + glob_unmatched: continue; - glob_matched: + glob_matched: globMatched = 1; break; } @@ -1213,11 +1235,11 @@ MatchOneType( /* * On Mac OS X, it is not uncommon for files to have NO - * file type. But folks with Tcl code on Classic MacOS pretty - * much assume that a generic file will have type TEXT. So + * file type. But folks with Tcl code on Classic MacOS pretty + * much assume that a generic file will have type TEXT. So * if we were strict about matching types when the source file * had NO type set, they would have to add another rule always - * with no fileType. To avoid that, we pass the macMatch side + * with no fileType. To avoid that, we pass the macMatch side * of the test if no fileType is set. */ @@ -1228,146 +1250,126 @@ MatchOneType( return UNMATCHED; } - + /* *---------------------------------------------------------------------- * * TkAboutDlg -- * - * Displays the default Tk About box. This code uses Macintosh - * resources to define the content of the About Box. + * Displays the default Tk About box. This code uses Macintosh + * resources to define the content of the About Box. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ void -TkAboutDlg() +TkAboutDlg(void) { DialogPtr aboutDlog; WindowRef windowRef; short itemHit = -9; - aboutDlog = GetNewDialog(128, NULL, (void *) (-1)); - + aboutDlog = GetNewDialog(TK_DEFAULT_ABOUT, NULL, (void *) (-1)); if (!aboutDlog) { return; } - windowRef = GetDialogWindow(aboutDlog); SelectWindow(windowRef); - + TkMacOSXTrackingLoop(1); while (itemHit != 1) { ModalDialog(NULL, &itemHit); } + TkMacOSXTrackingLoop(0); DisposeDialog(aboutDlog); - aboutDlog = NULL; - SelectWindow(ActiveNonFloatingWindow()); - - return; } - + /* *---------------------------------------------------------------------- * * Tk_MessageBoxObjCmd -- * - * Implements the tk_messageBox in native Mac OS X style. + * Implements the tk_messageBox in native Mac OS X style. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * none + * none * *---------------------------------------------------------------------- */ int Tk_MessageBoxObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + ClientData clientData, /* Main window associated with interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *CONST objv[]) /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData; + Tk_Window tkwin = (Tk_Window) clientData; AlertStdCFStringAlertParamRec paramCFStringRec; - AlertType alertType; - DialogRef dialogRef; - CFStringRef messageTextCF = NULL; - CFStringRef finemessageTextCF = NULL; - OSErr osError; - SInt16 itemHit; - Boolean haveDefaultOption = false; - Boolean haveParentOption = false; - char *str; - int index; - int defaultButtonIndex; - int defaultNativeButtonIndex; /* 1, 2, 3: right to left. */ - int typeIndex; - int i; - int indexDefaultOption = 0; - int result = TCL_OK; - - static CONST char *movableAlertStrings[] = { - "-default", "-detail", "-icon", - "-message", "-parent", - "-title", "-type", - (char *)NULL + AlertType alertType; + DialogRef dialogRef; + CFStringRef messageTextCF = NULL, finemessageTextCF = NULL; + OSStatus err; + SInt16 itemHit; + Boolean haveDefaultOption = false, haveParentOption = false; + char *str; + int index, defaultButtonIndex; + int defaultNativeButtonIndex; /* 1, 2, 3: right to left */ + int typeIndex, i, indexDefaultOption = 0, result = TCL_ERROR; + + static const char *movableAlertStrings[] = { + "-default", "-detail", "-icon", "-message", "-parent", "-title", + "-type", NULL }; - static CONST char *movableTypeStrings[] = { - "abortretryignore", "ok", - "okcancel", "retrycancel", - "yesno", "yesnocancel", - (char *)NULL + static const char *movableTypeStrings[] = { + "abortretryignore", "ok", "okcancel", "retrycancel", "yesno", + "yesnocancel", NULL }; - static CONST char *movableButtonStrings[] = { - "abort", "retry", "ignore", - "ok", "cancel", "yes", "no", - (char *)NULL + static const char *movableButtonStrings[] = { + "abort", "retry", "ignore", "ok", "cancel", "yes", "no", NULL }; - static CONST char *movableIconStrings[] = { - "error", "info", "question", "warning", - (char *)NULL + static const char *movableIconStrings[] = { + "error", "info", "question", "warning", NULL }; enum movableAlertOptions { - ALERT_DEFAULT, ALERT_DETAIL, ALERT_ICON, - ALERT_MESSAGE, ALERT_PARENT, + ALERT_DEFAULT, ALERT_DETAIL, ALERT_ICON, ALERT_MESSAGE, ALERT_PARENT, ALERT_TITLE, ALERT_TYPE }; enum movableTypeOptions { - TYPE_ABORTRETRYIGNORE, TYPE_OK, - TYPE_OKCANCEL, TYPE_RETRYCANCEL, + TYPE_ABORTRETRYIGNORE, TYPE_OK, TYPE_OKCANCEL, TYPE_RETRYCANCEL, TYPE_YESNO, TYPE_YESNOCANCEL }; enum movableButtonOptions { - TEXT_ABORT, TEXT_RETRY, TEXT_IGNORE, - TEXT_OK, TEXT_CANCEL, TEXT_YES, TEXT_NO + TEXT_ABORT, TEXT_RETRY, TEXT_IGNORE, TEXT_OK, TEXT_CANCEL, TEXT_YES, + TEXT_NO }; enum movableIconOptions { ICON_ERROR, ICON_INFO, ICON_QUESTION, ICON_WARNING }; /* - * Need to map from 'movableButtonStrings' and its corresponding integer index, - * to the native button index, which is 1, 2, 3, from right to left. + * Need to map from 'movableButtonStrings' and its corresponding integer, + * index to the native button index, which is 1, 2, 3, from right to left. * This is necessary to do for each separate '-type' of button sets. */ - short buttonIndexAndTypeToNativeButtonIndex[][7] = { - /* abort retry ignore ok cancel yes no */ - {1, 2, 3, 0, 0, 0, 0}, /* abortretryignore */ - {0, 0, 0, 1, 0, 0, 0}, /* ok */ - {0, 0, 0, 1, 2, 0, 0}, /* okcancel */ - {0, 1, 0, 0, 2, 0, 0}, /* retrycancel */ - {0, 0, 0, 0, 0, 1, 2}, /* yesno */ - {0, 0, 0, 0, 3, 1, 2}, /* yesnocancel */ + short buttonIndexAndTypeToNativeButtonIndex[][7] = { + /* abort retry ignore ok cancel yes no */ + {1, 2, 3, 0, 0, 0, 0}, /* abortretryignore */ + {0, 0, 0, 1, 0, 0, 0}, /* ok */ + {0, 0, 0, 1, 2, 0, 0}, /* okcancel */ + {0, 1, 0, 0, 2, 0, 0}, /* retrycancel */ + {0, 0, 0, 0, 0, 1, 2}, /* yesno */ + {0, 0, 0, 0, 3, 1, 2}, /* yesnocancel */ }; /* @@ -1375,137 +1377,137 @@ Tk_MessageBoxObjCmd( * descriptive button text string index. */ - short nativeButtonIndexAndTypeToButtonIndex[][4] = { - {-1, 0, 1, 2}, /* abortretryignore */ - {-1, 3, 0, 0}, /* ok */ - {-1, 3, 4, 0}, /* okcancel */ - {-1, 1, 4, 0}, /* retrycancel */ - {-1, 5, 6, 0}, /* yesno */ - {-1, 5, 6, 4}, /* yesnocancel */ + short nativeButtonIndexAndTypeToButtonIndex[][4] = { + {-1, 0, 1, 2}, /* abortretryignore */ + {-1, 3, 0, 0}, /* ok */ + {-1, 3, 4, 0}, /* okcancel */ + {-1, 1, 4, 0}, /* retrycancel */ + {-1, 5, 6, 0}, /* yesno */ + {-1, 5, 6, 4}, /* yesnocancel */ }; alertType = kAlertPlainAlert; typeIndex = TYPE_OK; - GetStandardAlertDefaultParams(¶mCFStringRec, kStdCFStringAlertVersionOne); + ChkErr(GetStandardAlertDefaultParams, ¶mCFStringRec, + kStdCFStringAlertVersionOne); paramCFStringRec.movable = true; paramCFStringRec.helpButton = false; paramCFStringRec.defaultButton = kAlertStdAlertOKButton; paramCFStringRec.cancelButton = kAlertStdAlertCancelButton; for (i = 1; i < objc; i += 2) { - int iconIndex; - char *string; + int iconIndex; + char *string; if (Tcl_GetIndexFromObj(interp, objv[i], movableAlertStrings, "option", - TCL_EXACT, &index) != TCL_OK) { - result = TCL_ERROR; + TCL_EXACT, &index) != TCL_OK) { goto end; } if (i + 1 == objc) { - string = Tcl_GetStringFromObj(objv[i], NULL); + string = Tcl_GetString(objv[i]); Tcl_AppendResult(interp, "value for \"", string, "\" missing", - (char *) NULL); - result = TCL_ERROR; + NULL); goto end; } switch (index) { - case ALERT_DEFAULT: - - /* - * Need to postpone processing of this option until we are - * sure to know the '-type' as well. - */ - - haveDefaultOption = true; - indexDefaultOption = i; - break; + /* + * Need to postpone processing of this option until we are + * sure to know the '-type' as well. + */ + haveDefaultOption = true; + indexDefaultOption = i; + break; case ALERT_DETAIL: - str = Tcl_GetStringFromObj(objv[i + 1], NULL); - finemessageTextCF = CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8); - break; + str = Tcl_GetString(objv[i + 1]); + finemessageTextCF = CFStringCreateWithCString(NULL, str, + kCFStringEncodingUTF8); + break; case ALERT_ICON: - /* not sure about UTF translation here... */ - if (Tcl_GetIndexFromObj(interp, objv[i + 1], movableIconStrings, - "value", TCL_EXACT, &iconIndex) != TCL_OK) { - result = TCL_ERROR; - goto end; - } - switch (iconIndex) { - case ICON_ERROR: - alertType = kAlertStopAlert; - break; - case ICON_INFO: - alertType = kAlertNoteAlert; - break; - case ICON_QUESTION: - alertType = kAlertCautionAlert; - break; - case ICON_WARNING: - alertType = kAlertCautionAlert; + if (Tcl_GetIndexFromObj(interp, objv[i + 1], + movableIconStrings, "value", TCL_EXACT, &iconIndex) + != TCL_OK) { + goto end; + } + switch (iconIndex) { + case ICON_ERROR: + alertType = kAlertStopAlert; + break; + case ICON_INFO: + alertType = kAlertNoteAlert; + break; + case ICON_QUESTION: + alertType = kAlertCautionAlert; + break; + case ICON_WARNING: + alertType = kAlertCautionAlert; + break; + } break; - } - break; case ALERT_MESSAGE: - str = Tcl_GetStringFromObj(objv[i + 1], NULL); - messageTextCF = CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8); - break; + str = Tcl_GetString(objv[i + 1]); + messageTextCF = CFStringCreateWithCString(NULL, str, + kCFStringEncodingUTF8); + break; case ALERT_PARENT: - str = Tcl_GetStringFromObj(objv[i + 1], NULL); - tkwin = Tk_NameToWindow(interp, str, tkwin); - if (tkwin == NULL) { - result = TCL_ERROR; - goto end; - } - haveParentOption = true; - break; + str = Tcl_GetString(objv[i + 1]); + tkwin = Tk_NameToWindow(interp, str, tkwin); + if (tkwin == NULL) { + goto end; + } + if (((TkWindow*)tkwin)->window != None && + TkMacOSXHostToplevelExists(tkwin)) { + haveParentOption = true; + } + break; case ALERT_TITLE: - break; + break; case ALERT_TYPE: - /* not sure about UTF translation here... */ - if (Tcl_GetIndexFromObj(interp, objv[i + 1], movableTypeStrings, - "value", TCL_EXACT, &typeIndex) != TCL_OK) { - result = TCL_ERROR; - goto end; - } - switch (typeIndex) { - case TYPE_ABORTRETRYIGNORE: - paramCFStringRec.defaultText = CFSTR("Abort"); - paramCFStringRec.cancelText = CFSTR("Retry"); - paramCFStringRec.otherText = CFSTR("Ignore"); - paramCFStringRec.cancelButton = kAlertStdAlertOtherButton; - break; - case TYPE_OK: - paramCFStringRec.defaultText = CFSTR("OK"); - break; - case TYPE_OKCANCEL: - paramCFStringRec.defaultText = CFSTR("OK"); - paramCFStringRec.cancelText = CFSTR("Cancel"); - break; - case TYPE_RETRYCANCEL: - paramCFStringRec.defaultText = CFSTR("Retry"); - paramCFStringRec.cancelText = CFSTR("Cancel"); - break; - case TYPE_YESNO: - paramCFStringRec.defaultText = CFSTR("Yes"); - paramCFStringRec.cancelText = CFSTR("No"); - break; - case TYPE_YESNOCANCEL: - paramCFStringRec.defaultText = CFSTR("Yes"); - paramCFStringRec.cancelText = CFSTR("No"); - paramCFStringRec.otherText = CFSTR("Cancel"); - paramCFStringRec.cancelButton = kAlertStdAlertOtherButton; + if (Tcl_GetIndexFromObj(interp, objv[i + 1],\ + movableTypeStrings, "value", TCL_EXACT, &typeIndex) + != TCL_OK) { + goto end; + } + switch (typeIndex) { + case TYPE_ABORTRETRYIGNORE: + paramCFStringRec.defaultText = CFSTR("Abort"); + paramCFStringRec.cancelText = CFSTR("Retry"); + paramCFStringRec.otherText = CFSTR("Ignore"); + paramCFStringRec.cancelButton = + kAlertStdAlertOtherButton; + break; + case TYPE_OK: + paramCFStringRec.defaultText = CFSTR("OK"); + break; + case TYPE_OKCANCEL: + paramCFStringRec.defaultText = CFSTR("OK"); + paramCFStringRec.cancelText = CFSTR("Cancel"); + break; + case TYPE_RETRYCANCEL: + paramCFStringRec.defaultText = CFSTR("Retry"); + paramCFStringRec.cancelText = CFSTR("Cancel"); + break; + case TYPE_YESNO: + paramCFStringRec.defaultText = CFSTR("Yes"); + paramCFStringRec.cancelText = CFSTR("No"); + break; + case TYPE_YESNOCANCEL: + paramCFStringRec.defaultText = CFSTR("Yes"); + paramCFStringRec.cancelText = CFSTR("No"); + paramCFStringRec.otherText = CFSTR("Cancel"); + paramCFStringRec.cancelButton = + kAlertStdAlertOtherButton; + break; + } break; - } - break; } } @@ -1516,22 +1518,22 @@ Tk_MessageBoxObjCmd( * we do this here. */ - str = Tcl_GetStringFromObj(objv[indexDefaultOption + 1], NULL); + str = Tcl_GetString(objv[indexDefaultOption + 1]); if (Tcl_GetIndexFromObj(interp, objv[indexDefaultOption + 1], - movableButtonStrings, "value", TCL_EXACT, - &defaultButtonIndex) != TCL_OK) { - result = TCL_ERROR; + movableButtonStrings, "value", TCL_EXACT, &defaultButtonIndex) + != TCL_OK) { goto end; } - /* Need to map from "ok" etc. to 1, 2, 3, right to left. */ + /* + * Need to map from "ok" etc. to 1, 2, 3, right to left. + */ defaultNativeButtonIndex = buttonIndexAndTypeToNativeButtonIndex[typeIndex][defaultButtonIndex]; if (defaultNativeButtonIndex == 0) { Tcl_SetObjResult(interp, - Tcl_NewStringObj("Illegal default option", -1)); - result = TCL_ERROR; + Tcl_NewStringObj("Illegal default option", -1)); goto end; } paramCFStringRec.defaultButton = defaultNativeButtonIndex; @@ -1539,89 +1541,83 @@ Tk_MessageBoxObjCmd( paramCFStringRec.cancelButton = 0; } } - SetThemeCursor(kThemeArrowCursor); + ChkErr(SetThemeCursor, kThemeArrowCursor); if (haveParentOption) { - TkWindow *winPtr; - WindowRef windowRef; - EventTargetRef notifyTarget; - EventHandlerUPP handler; - CallbackUserData data; + AlertHandlerUserData data; + static EventHandlerUPP handler = NULL; + WindowRef windowRef; const EventTypeSpec kEvents[] = { {kEventClassCommand, kEventProcessCommand} }; - winPtr = (TkWindow *) tkwin; - - /* - * Create the underlying Mac window for this Tk window. - */ - - windowRef = GetWindowFromPort( - TkMacOSXGetDrawablePort(Tk_WindowId(tkwin))); - notifyTarget = GetWindowEventTarget(windowRef); - osError = CreateStandardSheet(alertType, messageTextCF, - finemessageTextCF, ¶mCFStringRec, - notifyTarget, &dialogRef); - if(osError != noErr) { - result = TCL_ERROR; + bzero(&data, sizeof(data)); + if (!handler) { + handler = NewEventHandlerUPP(AlertHandler); + } + windowRef = GetWindowFromPort(TkMacOSXGetDrawablePort( + Tk_WindowId(tkwin))); + if (!windowRef) { goto end; } - data.windowRef = windowRef; - data.buttonIndex = 1; - handler = NewEventHandlerUPP(AlertHandler); - InstallEventHandler(notifyTarget, handler, - GetEventTypeCount(kEvents), - kEvents, &data, NULL); - osError = ShowSheetWindow(GetDialogWindow(dialogRef), windowRef); - if(osError != noErr) { - result = TCL_ERROR; + err = ChkErr(CreateStandardSheet, alertType, messageTextCF, + finemessageTextCF, ¶mCFStringRec, NULL, &dialogRef); + if(err != noErr) { goto end; } - osError = RunAppModalLoopForWindow(windowRef); - if (osError != noErr) { - result = TCL_ERROR; + data.dialogWindow = GetDialogWindow(dialogRef); + err = ChkErr(ShowSheetWindow, data.dialogWindow, windowRef); + if(err != noErr) { + DisposeDialog(dialogRef); goto end; } + ChkErr(GetWindowModality, data.dialogWindow, &data.origModality, + &data.origUnavailWindow); + ChkErr(SetWindowModality, data.dialogWindow, kWindowModalityAppModal, + NULL); + ChkErr(InstallEventHandler, GetWindowEventTarget(data.dialogWindow), + handler, GetEventTypeCount(kEvents), kEvents, &data, + &data.handlerRef); + TkMacOSXTrackingLoop(1); + ChkErr(RunAppModalLoopForWindow, data.dialogWindow); + TkMacOSXTrackingLoop(0); itemHit = data.buttonIndex; - DisposeEventHandlerUPP(handler); } else { - osError = CreateStandardAlert(alertType, messageTextCF, - finemessageTextCF, ¶mCFStringRec, &dialogRef); - if(osError != noErr) { - result = TCL_ERROR; + err = ChkErr(CreateStandardAlert, alertType, messageTextCF, + finemessageTextCF, ¶mCFStringRec, &dialogRef); + if(err != noErr) { goto end; } - osError = RunStandardAlert(dialogRef, NULL, &itemHit); - if (osError != noErr) { - result = TCL_ERROR; + TkMacOSXTrackingLoop(1); + err = ChkErr(RunStandardAlert, dialogRef, NULL, &itemHit); + TkMacOSXTrackingLoop(0); + if (err != noErr) { goto end; } } - if(osError == noErr) { - int ind; + if (err == noErr) { + int ind; /* * Map 'itemHit' (1, 2, 3) to descriptive text string. */ ind = nativeButtonIndexAndTypeToButtonIndex[typeIndex][itemHit]; - Tcl_SetObjResult(interp, - Tcl_NewStringObj(movableButtonStrings[ind], -1)); - } else { - result = TCL_ERROR; + Tcl_SetObjResult(interp, Tcl_NewStringObj(movableButtonStrings[ind], + -1)); + result = TCL_OK; } - end: - if (finemessageTextCF != NULL) { +end: + if (finemessageTextCF) { CFRelease(finemessageTextCF); } - if (messageTextCF != NULL) { + if (messageTextCF) { CFRelease(messageTextCF); } return result; } - + /* *---------------------------------------------------------------------- * @@ -1638,31 +1634,33 @@ Tk_MessageBoxObjCmd( *---------------------------------------------------------------------- */ -static OSStatus -AlertHandler(EventHandlerCallRef callRef, EventRef eventRef, void *userData) +OSStatus +AlertHandler( + EventHandlerCallRef callRef, + EventRef eventRef, + void *userData) { - OSStatus result = eventNotHandledErr; - HICommand cmd; - CallbackUserData *dataPtr = (CallbackUserData *) userData; + AlertHandlerUserData *data = (AlertHandlerUserData *) userData; + HICommand cmd; - GetEventParameter(eventRef, kEventParamDirectObject, typeHICommand, - NULL, sizeof(cmd), NULL, &cmd); + ChkErr(GetEventParameter,eventRef, kEventParamDirectObject, typeHICommand, + NULL, sizeof(cmd), NULL, &cmd); switch (cmd.commandID) { case kHICommandOK: - dataPtr->buttonIndex = 1; - result = noErr; - break; + data->buttonIndex = 1; + break; case kHICommandCancel: - dataPtr->buttonIndex = 2; - result = noErr; - break; + data->buttonIndex = 2; + break; case kHICommandOther: - dataPtr->buttonIndex = 3; - result = noErr; - break; + data->buttonIndex = 3; + break; } - if (result == noErr) { - result = QuitAppModalLoopForWindow(dataPtr->windowRef); + if (data->buttonIndex) { + ChkErr(QuitAppModalLoopForWindow, data->dialogWindow); + ChkErr(RemoveEventHandler, data->handlerRef); + ChkErr(SetWindowModality, data->dialogWindow, + data->origModality, data->origUnavailWindow); } - return result; + return eventNotHandledErr; } diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c index 8ecb7d9..d01a669 100644 --- a/macosx/tkMacOSXDraw.c +++ b/macosx/tkMacOSXDraw.c @@ -1,18 +1,18 @@ -/* +/* * tkMacOSXDraw.c -- * - * This file contains functions that perform drawing to - * Xlib windows. Most of the functions simple emulate - * Xlib functions. + * This file contains functions that perform drawing to + * Xlib windows. Most of the functions simple emulate + * Xlib functions. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. - * Copyright (c) 2006 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.20 2007/04/21 19:06:37 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.21 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" @@ -24,10 +24,7 @@ #endif */ -#define RGBFLOATRED(c) ((c).red / 65535.0) -#define RGBFLOATGREEN(c) ((c).green / 65535.0) -#define RGBFLOATBLUE(c) ((c).blue / 65535.0) -#define radians(d) ((d) * (M_PI/180.0)) +#define radians(d) ((d) * (M_PI/180.0)) /* * Non-antialiased CG drawing looks better and more like X11 drawing when using @@ -39,8 +36,9 @@ * Temporary regions that can be reused. */ -static RgnHandle tmpRgn = NULL; -static RgnHandle tmpRgn2 = NULL; +RgnHandle tkMacOSXtmpRgn1 = NULL; +RgnHandle tkMacOSXtmpRgn2 = NULL; + static PixPatHandle gPenPat = NULL; static int useCGDrawing = 1; @@ -54,32 +52,29 @@ static int useThemedFrame = 0; * Prototypes for functions used only in this file. */ static unsigned char InvertByte(unsigned char data); -static void TkMacOSXSetUpCGContext(MacDrawable *macWin, CGrafPtr destPort, - GC gc, CGContextRef *contextPtr); -static void TkMacOSXReleaseCGContext(MacDrawable *macWin, CGrafPtr destPort, - CGContextRef *context); + /* *---------------------------------------------------------------------- * * TkMacOSXInitCGDrawing -- * - * Initializes link vars that control CG drawing. + * Initializes link vars that control CG drawing. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ MODULE_SCOPE int -TkMacOSXInitCGDrawing(interp, enable, limit) - Tcl_Interp *interp; - int enable; - int limit; +TkMacOSXInitCGDrawing( + Tcl_Interp *interp, + int enable, + int limit) { static Boolean initialized = FALSE; @@ -104,15 +99,29 @@ TkMacOSXInitCGDrawing(interp, enable, limit) /* * Piggy-back the themed drawing var init here. */ + if (Tcl_LinkVar(interp, "::tk::mac::useThemedToplevel", - (char *) &useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) { + (char *) &useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) { Tcl_ResetResult(interp); } if (Tcl_LinkVar(interp, "::tk::mac::useThemedFrame", - (char *) &useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) { + (char *) &useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) { Tcl_ResetResult(interp); } + + if (tkMacOSXtmpRgn1 == NULL) { + tkMacOSXtmpRgn1 = NewRgn(); + } + if (tkMacOSXtmpRgn2 == NULL) { + tkMacOSXtmpRgn2 = NewRgn(); + } } +#ifdef TK_MAC_DEBUG_DRAWING + TkMacOSXInitNamedDebugSymbol(QD, void, QD_DebugPrint, char*); + if (QD_DebugPrint) { + ; /* gdb: b *QD_DebugPrint */ + } +#endif /* TK_MAC_DEBUG_WINDOWS */ return TCL_OK; } @@ -121,41 +130,37 @@ TkMacOSXInitCGDrawing(interp, enable, limit) * * XCopyArea -- * - * Copies data from one drawable to another using block transfer - * routines. + * Copies data from one drawable to another using block transfer + * routines. * * Results: - * None. + * None. * * Side effects: - * Data is moved from a window or bitmap to a second window or - * bitmap. + * Data is moved from a window or bitmap to a second window or + * bitmap. * *---------------------------------------------------------------------- */ void XCopyArea( - Display* display, /* Display. */ - Drawable src, /* Source drawable. */ - Drawable dst, /* Destination drawable. */ - 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. */ + Display *display, /* Display. */ + Drawable src, /* Source drawable. */ + Drawable dst, /* Destination drawable. */ + 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 height, - int dest_x, /* Dest X & Y on dest rect. */ + int dest_x, /* Dest X & Y on dest rect. */ int dest_y) { - Rect srcRect, dstRect; - Rect * srcPtr, * dstPtr; - const BitMap * srcBit; - const BitMap * dstBit; - MacDrawable *srcDraw = (MacDrawable *) src; - MacDrawable *dstDraw = (MacDrawable *) dst; - CGrafPtr srcPort, dstPort; - CGrafPtr saveWorld; - GDHandle saveDevice; + Rect srcRect, dstRect, *srcPtr, *dstPtr; + const BitMap *srcBit, *dstBit; + MacDrawable *srcDraw = (MacDrawable *) src, *dstDraw = (MacDrawable *) dst; + CGrafPtr srcPort, dstPort, savePort; + Boolean portChanged; short tmode; RGBColor origForeColor, origBackColor, whiteColor, blackColor; Rect clpRect; @@ -164,8 +169,7 @@ XCopyArea( srcPort = TkMacOSXGetDrawablePort(src); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(dstPort, NULL); + portChanged = QDSwapPort(dstPort, &savePort); GetForeColor(&origForeColor); GetBackColor(&origBackColor); whiteColor.red = 0; @@ -177,9 +181,6 @@ XCopyArea( blackColor.green = 0xFFFF; RGBBackColor(&blackColor); - if (tmpRgn2 == NULL) { - tmpRgn2 = NewRgn(); - } srcPtr = &srcRect; SetRect(&srcRect, (short) (srcDraw->xOff + src_x), (short) (srcDraw->yOff + src_y), @@ -195,18 +196,20 @@ XCopyArea( (short) (dstDraw->yOff + dest_y + height)); } TkMacOSXSetUpClippingRgn(dst); + /* - * We will change the clip rgn in this routine, so we need to - * be able to restore it when we exit. + * We will change the clip rgn in this routine, so we need to + * be able to restore it when we exit. */ - GetClip(tmpRgn2); + TkMacOSXCheckTmpRgnEmpty(2); + GetClip(tkMacOSXtmpRgn2); if (tkPictureIsOpen) { /* * When rendering into a picture, after a call to "OpenCPicture" * the clipping is seriously WRONG and also INCONSISTENT with the * clipping for single plane bitmaps. - * To circumvent this problem, we clip to the whole window + * To circumvent this problem, we clip to the whole window * In this case, would have also clipped to the srcRect * ClipRect(&srcRect); */ @@ -215,23 +218,22 @@ XCopyArea( dstPtr = &srcRect; ClipRect(&clpRect); } - if (!gc->clip_mask) { - } else if (((TkpClipMask*)gc->clip_mask)->type == TKP_CLIP_REGION) { + if (gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type + == TKP_CLIP_REGION) { RgnHandle clipRgn = (RgnHandle) ((TkpClipMask*)gc->clip_mask)->value.region; - int xOffset = 0, yOffset = 0; - if (tmpRgn == NULL) { - tmpRgn = NewRgn(); - } + if (!tkPictureIsOpen) { xOffset = dstDraw->xOff + gc->clip_x_origin; yOffset = dstDraw->yOff + gc->clip_y_origin; OffsetRgn(clipRgn, xOffset, yOffset); } - GetClip(tmpRgn); - SectRgn(tmpRgn, clipRgn, tmpRgn); - SetClip(tmpRgn); + TkMacOSXCheckTmpRgnEmpty(1); + GetClip(tkMacOSXtmpRgn1); + SectRgn(tkMacOSXtmpRgn1, clipRgn, tkMacOSXtmpRgn1); + SetClip(tkMacOSXtmpRgn1); + SetEmptyRgn(tkMacOSXtmpRgn1); if (!tkPictureIsOpen) { OffsetRgn(clipRgn, -xOffset, -yOffset); } @@ -243,8 +245,11 @@ XCopyArea( CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL); RGBForeColor(&origForeColor); RGBBackColor(&origBackColor); - SetClip(tmpRgn2); - SetGWorld(saveWorld, saveDevice); + SetClip(tkMacOSXtmpRgn2); + SetEmptyRgn(tkMacOSXtmpRgn2); + if (portChanged) { + QDSwapPort(savePort, NULL); + } } /* @@ -252,45 +257,37 @@ XCopyArea( * * XCopyPlane -- * - * Copies a bitmap from a source drawable to a destination - * drawable. The plane argument specifies which bit plane of - * the source contains the bitmap. Note that this implementation - * ignores the gc->function. + * Copies a bitmap from a source drawable to a destination + * drawable. The plane argument specifies which bit plane of + * the source contains the bitmap. Note that this implementation + * ignores the gc->function. * * Results: - * None. + * None. * * Side effects: - * Changes the destination drawable. + * Changes the destination drawable. * *---------------------------------------------------------------------- */ void XCopyPlane( - Display* display, /* Display. */ - Drawable src, /* Source drawable. */ - Drawable dst, /* Destination drawable. */ - GC gc, /* The GC to use. */ - int src_x, /* X, Y, width & height */ - int src_y, /* define the source rect. */ - unsigned int width, - unsigned int height, - int dest_x, /* X & Y on dest where we will copy. */ - int dest_y, - unsigned long plane) /* Which plane to copy. */ + Display *display, /* Display. */ + Drawable src, /* Source drawable. */ + Drawable dst, /* Destination drawable. */ + GC gc, /* The GC to use. */ + int src_x, int src_y, /* X, Y, width & height define the source + * rect. */ + unsigned int width, unsigned int height, + int dest_x, int dest_y, /* X & Y on dest where we will copy. */ + unsigned long plane) /* Which plane to copy. */ { - Rect srcRect, dstRect; - Rect * srcPtr, * dstPtr; - const BitMap * srcBit; - const BitMap * dstBit; - const BitMap * mskBit; - MacDrawable *srcDraw = (MacDrawable *) src; - MacDrawable *dstDraw = (MacDrawable *) dst; - GWorldPtr srcPort, dstPort, mskPort; - CGrafPtr saveWorld; - GDHandle saveDevice; - RGBColor macColor; + Rect srcRect, dstRect, *srcPtr, *dstPtr; + const BitMap *srcBit, *dstBit, *mskBit; + MacDrawable *srcDraw = (MacDrawable *) src, *dstDraw = (MacDrawable *) dst; + CGrafPtr srcPort, dstPort, mskPort, savePort; + Boolean portChanged; TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask; short tmode; @@ -298,8 +295,7 @@ XCopyPlane( dstPort = TkMacOSXGetDrawablePort(dst); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(dstPort, NULL); + portChanged = QDSwapPort(dstPort, &savePort); TkMacOSXSetUpClippingRgn(dst); srcBit = GetPortBitMapForCopyBits(srcPort); @@ -314,7 +310,7 @@ XCopyPlane( * When rendering into a picture, after a call to "OpenCPicture" * the clipping is seriously WRONG and also INCONSISTENT with the * clipping for color bitmaps. - * To circumvent this problem, we clip to the whole window + * To circumvent this problem, we clip to the whole window */ Rect clpRect; @@ -331,24 +327,21 @@ XCopyPlane( tmode = srcOr; tmode = srcCopy + transparent; - if (TkSetMacColor(gc->foreground, &macColor) == true) { - RGBForeColor(&macColor); - } + TkMacOSXSetColorInPort(gc->foreground, 1, NULL); if (clipPtr == NULL || clipPtr->type == TKP_CLIP_REGION) { /* * Case 1: opaque bitmaps. */ - TkSetMacColor(gc->background, &macColor); - RGBBackColor(&macColor); + TkMacOSXSetColorInPort(gc->background, 0, NULL); tmode = srcCopy; CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL); } else if (clipPtr->type == TKP_CLIP_PIXMAP) { if (clipPtr->value.pixmap == src) { PixMapHandle pm; /* - * Case 2: transparent bitmaps. If it's color we ignore + * Case 2: transparent bitmaps. If it's color we ignore * the forecolor. */ @@ -371,8 +364,9 @@ XCopyPlane( srcPtr, srcPtr, dstPtr, tmode, NULL); } } - - SetGWorld(saveWorld, saveDevice); + if (portChanged) { + QDSwapPort(savePort, NULL); + } } /* @@ -380,14 +374,14 @@ XCopyPlane( * * TkPutImage -- * - * Copies a subimage from an in-memory image to a rectangle of - * of the specified drawable. + * Copies a subimage from an in-memory image to a rectangle of + * of the specified drawable. * * Results: - * None. + * None. * * Side effects: - * Draws the image on the specified drawable. + * Draws the image on the specified drawable. * *---------------------------------------------------------------------- */ @@ -407,9 +401,8 @@ TkPutImage( unsigned int width, /* Same width & height for both */ unsigned int height) /* distination and source. */ { - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + CGrafPtr destPort, savePort; + Boolean portChanged; const BitMap * destBits; MacDrawable *dstDraw = (MacDrawable *) d; int i, j; @@ -420,9 +413,8 @@ TkPutImage( int slices, sliceRowBytes, lastSliceRowBytes, sliceWidth, lastSliceWidth; display->request++; - GetGWorld(&saveWorld, &saveDevice); destPort = TkMacOSXGetDrawablePort(d); - SetGWorld(destPort, NULL); + portChanged = QDSwapPort(destPort, &savePort); destBits = GetPortBitMapForCopyBits(destPort); TkMacOSXSetUpClippingRgn(d); @@ -433,10 +425,11 @@ TkPutImage( * When rendering into a picture, after a call to "OpenCPicture" * the clipping is seriously WRONG and also INCONSISTENT with the * clipping for single plane bitmaps. - * To circumvent this problem, we clip to the whole window + * To circumvent this problem, we clip to the whole window */ Rect clpRect; + GetPortBounds(destPort,&clpRect); ClipRect(&clpRect); destPtr = srcPtr; @@ -447,14 +440,17 @@ TkPutImage( } if (image->obdata) { - /* Image from XGetImage, copy from containing GWorld directly */ - GWorldPtr srcPort = TkMacOSXGetDrawablePort((Drawable)image->obdata); - CopyBits(GetPortBitMapForCopyBits(srcPort), - destBits, srcPtr, destPtr, srcCopy, NULL); + /* + * Image from XGetImage, copy from containing GWorld directly. + */ + + CopyBits(GetPortBitMapForCopyBits(TkMacOSXGetDrawablePort((Drawable) + image->obdata)), destBits, srcPtr, destPtr, srcCopy, NULL); } else if (image->depth == 1) { /* * BW image */ + const int maxRowBytes = 0x3ffe; BitMap bitmap; int odd; @@ -487,7 +483,7 @@ TkPutImage( oldPtr = dataPtr; odd = sliceRowBytes % 2; if (!newData) { - newData = (char *) ckalloc(image->height * (sliceRowBytes+odd)); + newData = ckalloc(image->height * (sliceRowBytes+odd)); } newPtr = newData; for (i = 0; i < image->height; i++) { @@ -512,6 +508,7 @@ TkPutImage( /* * Color image */ + const int maxRowBytes = 0x3ffc; PixMap pixmap; @@ -519,7 +516,7 @@ TkPutImage( pixmap.bounds.top = 0; pixmap.bounds.bottom = (short) image->height; pixmap.pixelType = RGBDirect; - pixmap.pmVersion = baseAddr32; /* 32bit clean */ + pixmap.pmVersion = baseAddr32; /* 32bit clean */ pixmap.packType = 0; pixmap.packSize = 0; pixmap.hRes = 0x00480000; @@ -580,8 +577,9 @@ TkPutImage( if (newData != NULL) { ckfree(newData); } - - SetGWorld(saveWorld, saveDevice); + if (portChanged) { + QDSwapPort(savePort, NULL); + } } /* @@ -589,74 +587,62 @@ TkPutImage( * * XDrawLines -- * - * Draw connected lines. + * Draw connected lines. * * Results: - * None. + * None. * * Side effects: - * Renders a series of connected lines. + * Renders a series of connected lines. * *---------------------------------------------------------------------- */ void XDrawLines( - Display* display, /* Display. */ + Display *display, /* Display. */ Drawable d, /* Draw on this. */ GC gc, /* Use this GC. */ - XPoint* points, /* Array of points. */ + XPoint *points, /* Array of points. */ int npoints, /* Number of points. */ int mode) /* Line drawing mode. */ { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GWorldPtr destPort; - GDHandle saveDevice; + TkMacOSXDrawingContext dc; int i, lw = gc->line_width; if (npoints < 2) { return; /* TODO: generate BadValue error. */ } - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; - float prevx, prevy; - float o = (lw % 2) ? .5 : 0; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { + double prevx, prevy; + double o = (lw % 2) ? .5 : 0; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); - CGContextBeginPath(outContext); + CGContextBeginPath(dc.context); prevx = macWin->xOff + points[0].x + o; prevy = macWin->yOff + points[0].y + o; - CGContextMoveToPoint(outContext, prevx, prevy); + CGContextMoveToPoint(dc.context, prevx, prevy); for (i = 1; i < npoints; i++) { if (mode == CoordModeOrigin) { - CGContextAddLineToPoint(outContext, + CGContextAddLineToPoint(dc.context, macWin->xOff + points[i].x + o, macWin->yOff + points[i].y + o); } else { prevx += points[i].x; prevy += points[i].y; - CGContextAddLineToPoint(outContext, prevx, prevy); + CGContextAddLineToPoint(dc.context, prevx, prevy); } } - CGContextStrokePath(outContext); - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); + CGContextStrokePath(dc.context); } else { int o = -lw/2; - TkMacOSXSetUpGraphicsPort(gc, destPort); - ShowPen(); - PenPixPat(gPenPat); /* This is broken for fat lines, it is not possible to correctly * imitate X11 drawing of oblique fat lines with QD line drawing, * we should draw a filled polygon instead. */ + MoveTo((short) (macWin->xOff + points[0].x + o), (short) (macWin->yOff + points[0].y + o)); for (i = 1; i < npoints; i++) { @@ -667,10 +653,8 @@ XDrawLines( Line((short) points[i].x, (short) points[i].y); } } - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } /* @@ -678,71 +662,58 @@ XDrawLines( * * XDrawSegments -- * - * Draw unconnected lines. + * Draw unconnected lines. * * Results: - * None. + * None. * * Side effects: - * Renders a series of unconnected lines. + * Renders a series of unconnected lines. * *---------------------------------------------------------------------- */ -void XDrawSegments( +void +XDrawSegments( Display *display, - Drawable d, + Drawable d, GC gc, XSegment *segments, - int nsegments) + int nsegments) { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GWorldPtr destPort; - GDHandle saveDevice; + TkMacOSXDrawingContext dc; int i, lw = gc->line_width; - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { + double o = (lw % 2) ? .5 : 0; - if (useCGDrawing) { - CGContextRef outContext; - float o = (lw % 2) ? .5 : 0; - - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); for (i = 0; i < nsegments; i++) { - CGContextBeginPath(outContext); - CGContextMoveToPoint(outContext, + CGContextBeginPath(dc.context); + CGContextMoveToPoint(dc.context, macWin->xOff + segments[i].x1 + o, macWin->yOff + segments[i].y1 + o); - CGContextAddLineToPoint(outContext, + CGContextAddLineToPoint(dc.context, macWin->xOff + segments[i].x2 + o, macWin->yOff + segments[i].y2 + o); - CGContextStrokePath(outContext); + CGContextStrokePath(dc.context); } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { int o = -lw/2; - TkMacOSXSetUpGraphicsPort(gc, destPort); - ShowPen(); - PenPixPat(gPenPat); /* This is broken for fat lines, it is not possible to correctly * imitate X11 drawing of oblique fat lines with QD line drawing, * we should draw a filled polygon instead. */ + for (i = 0; i < nsegments; i++) { MoveTo((short) (macWin->xOff + segments[i].x1 + o), (short) (macWin->yOff + segments[i].y1 + o)); LineTo((short) (macWin->xOff + segments[i].x2 + o), (short) (macWin->yOff + segments[i].y2 + o)); } - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } /* @@ -750,13 +721,13 @@ void XDrawSegments( * * XFillPolygon -- * - * Draws a filled polygon. + * Draws a filled polygon. * * Results: - * None. + * None. * * Side effects: - * Draws a filled polygon on the specified drawable. + * Draws a filled polygon on the specified drawable. * *---------------------------------------------------------------------- */ @@ -772,45 +743,33 @@ XFillPolygon( int mode) /* Drawing mode. */ { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; int i; - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; - float prevx, prevy; - float o = (gc->line_width % 2) ? .5 : 0; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { + double prevx, prevy; + double o = (gc->line_width % 2) ? .5 : 0; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); - CGContextBeginPath(outContext); + CGContextBeginPath(dc.context); prevx = macWin->xOff + points[0].x + o; prevy = macWin->yOff + points[0].y + o; - CGContextMoveToPoint(outContext, prevx, prevy); + CGContextMoveToPoint(dc.context, prevx, prevy); for (i = 1; i < npoints; i++) { if (mode == CoordModeOrigin) { - CGContextAddLineToPoint(outContext, + CGContextAddLineToPoint(dc.context, macWin->xOff + points[i].x + o, macWin->yOff + points[i].y + o); } else { prevx += points[i].x; prevy += points[i].y; - CGContextAddLineToPoint(outContext, prevx, prevy); + CGContextAddLineToPoint(dc.context, prevx, prevy); } } - CGContextEOFillPath(outContext); - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); + CGContextEOFillPath(dc.context); } else { PolyHandle polygon; - TkMacOSXSetUpGraphicsPort(gc, destPort); - PenNormal(); polygon = OpenPoly(); MoveTo((short) (macWin->xOff + points[0].x), (short) (macWin->yOff + points[0].y)); @@ -823,11 +782,10 @@ XFillPolygon( } } ClosePoly(); - FillCPoly(polygon, gPenPat); + FillCPoly(polygon, dc.penPat); KillPoly(polygon); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } /* @@ -835,71 +793,55 @@ XFillPolygon( * * XDrawRectangle -- * - * Draws a rectangle. + * Draws a rectangle. * * Results: - * None. + * None. * * Side effects: - * Draws a rectangle on the specified drawable. + * Draws a rectangle on the specified drawable. * *---------------------------------------------------------------------- */ void XDrawRectangle( - Display* display, /* Display. */ - Drawable d, /* Draw on this. */ - GC gc, /* Use this GC. */ - int x, /* Upper left corner. */ - int y, - unsigned int width, /* Width & height of rect. */ + Display *display, /* Display. */ + Drawable d, /* Draw on this. */ + GC gc, /* Use this GC. */ + int x, int y, /* Upper left corner. */ + unsigned int width, /* Width & height of rect. */ unsigned int height) { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; int lw = gc->line_width; if (width == 0 || height == 0) { return; } - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - float o = (lw % 2) ? .5 : 0; + double o = (lw % 2) ? .5 : 0; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); rect = CGRectMake( macWin->xOff + x + o, macWin->yOff + y + o, width, height); - CGContextStrokeRect(outContext, rect); - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); + CGContextStrokeRect(dc.context, rect); } else { Rect theRect; int o = -lw/2; - TkMacOSXSetUpGraphicsPort(gc, destPort); - ShowPen(); - PenPixPat(gPenPat); - theRect.left = (short) (macWin->xOff + x + o); - theRect.top = (short) (macWin->yOff + y + o); - theRect.right = (short) (theRect.left + width + lw); + theRect.left = (short) (macWin->xOff + x + o); + theRect.top = (short) (macWin->yOff + y + o); + theRect.right = (short) (theRect.left + width + lw); theRect.bottom = (short) (theRect.top + height + lw); FrameRect(&theRect); - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #ifdef TK_MACOSXDRAW_UNUSED @@ -908,27 +850,27 @@ XDrawRectangle( * * XDrawRectangles -- * - * Draws the outlines of the specified rectangles as if a - * five-point PolyLine protocol request were specified for each - * rectangle: + * Draws the outlines of the specified rectangles as if a + * five-point PolyLine protocol request were specified for each + * rectangle: * - * [x,y] [x+width,y] [x+width,y+height] [x,y+height] - * [x,y] + * [x,y] [x+width,y] [x+width,y+height] [x,y+height] [x,y] * - * For the specified rectangles, these functions do not draw a - * pixel more than once. XDrawRectangles draws the rectangles in - * the order listed in the array. If rectangles intersect, the - * intersecting pixels are drawn multiple times. Draws a - * rectangle. + * For the specified rectangles, these functions do not draw a + * pixel more than once. XDrawRectangles draws the rectangles in + * the order listed in the array. If rectangles intersect, the + * intersecting pixels are drawn multiple times. Draws a + * rectangle. * * Results: - * None. + * None. * * Side effects: - * Draws rectangles on the specified drawable. + * Draws rectangles on the specified drawable. * *---------------------------------------------------------------------- */ + void XDrawRectangles( Display *display, @@ -938,24 +880,15 @@ XDrawRectangles( int nRects) { MacDrawable *macWin = (MacDrawable *) drawable; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; XRectangle * rectPtr; int i, lw = gc->line_width; - destPort = TkMacOSXGetDrawablePort(drawable); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(drawable); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - float o = (lw % 2) ? .5 : 0; + double o = (lw % 2) ? .5 : 0; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); for (i = 0, rectPtr = rectArr; i < nRects; i++, rectPtr++) { if (rectPtr->width == 0 || rectPtr->height == 0) { continue; @@ -964,16 +897,12 @@ XDrawRectangles( macWin->xOff + rectPtr->x + o, macWin->yOff + rectPtr->y + o, rectPtr->width, rectPtr->height); - CGContextStrokeRect(outContext, rect); + CGContextStrokeRect(dc.context, rect); } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { Rect theRect; int o = -lw/2; - TkMacOSXSetUpGraphicsPort(gc, destPort); - ShowPen(); - PenPixPat(gPenPat); for (i = 0, rectPtr = rectArr; i < nRects;i++, rectPtr++) { theRect.left = (short) (macWin->xOff + rectPtr->x + o); theRect.top = (short) (macWin->yOff + rectPtr->y + o); @@ -981,10 +910,8 @@ XDrawRectangles( theRect.bottom = (short) (theRect.top + rectPtr->height + lw); FrameRect(&theRect); } - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #endif @@ -993,42 +920,34 @@ XDrawRectangles( * * XFillRectangles -- * - * Fill multiple rectangular areas in the given drawable. + * Fill multiple rectangular areas in the given drawable. * * Results: - * None. + * None. * * Side effects: - * Draws onto the specified drawable. + * Draws onto the specified drawable. * *---------------------------------------------------------------------- */ + void XFillRectangles( - Display* display, /* Display. */ - Drawable d, /* Draw on this. */ - GC gc, /* Use this GC. */ - XRectangle *rectangles, /* Rectangle array. */ - int n_rectangles) /* Number of rectangles. */ + Display* display, /* Display. */ + Drawable d, /* Draw on this. */ + GC gc, /* Use this GC. */ + XRectangle *rectangles, /* Rectangle array. */ + int n_rectangles) /* Number of rectangles. */ { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; XRectangle * rectPtr; int i; - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) { if (rectPtr->width == 0 || rectPtr->height == 0) { continue; @@ -1037,23 +956,20 @@ XFillRectangles( macWin->xOff + rectPtr->x, macWin->yOff + rectPtr->y, rectPtr->width, rectPtr->height); - CGContextFillRect(outContext, rect); + CGContextFillRect(dc.context, rect); } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { Rect theRect; - TkMacOSXSetUpGraphicsPort(gc, destPort); for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) { theRect.left = (short) (macWin->xOff + rectPtr->x); theRect.top = (short) (macWin->yOff + rectPtr->y); theRect.right = (short) (theRect.left + rectPtr->width); theRect.bottom = (short) (theRect.top + rectPtr->height); - FillCRect(&theRect, gPenPat); + FillCRect(&theRect, dc.penPat); } } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } /* @@ -1061,98 +977,85 @@ XFillRectangles( * * XDrawArc -- * - * Draw an arc. + * Draw an arc. * * Results: - * None. + * None. * * Side effects: - * Draws an arc on the specified drawable. + * Draws an arc on the specified drawable. * *---------------------------------------------------------------------- */ void XDrawArc( - Display* display, /* Display. */ - Drawable d, /* Draw on this. */ - GC gc, /* Use this GC. */ - int x, /* Upper left of */ - int y, /* bounding rect. */ - unsigned int width, /* Width & height. */ + Display* display, /* Display. */ + Drawable d, /* Draw on this. */ + GC gc, /* Use this GC. */ + int x, int y, /* Upper left of bounding rect. */ + unsigned int width, /* Width & height. */ unsigned int height, - int angle1, /* Staring angle of arc. */ - int angle2) /* Extent of arc. */ + int angle1, /* Staring angle of arc. */ + int angle2) /* Extent of arc. */ { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; int lw = gc->line_width; if (width == 0 || height == 0 || angle2 == 0) { return; } - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - float o = (lw % 2) ? .5 : 0; + double o = (lw % 2) ? .5 : 0; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); rect = CGRectMake( macWin->xOff + x + o, macWin->yOff + y + o, width, height); #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 - if (angle1 == 0 && angle2 == 23040 && - CGContextStrokeEllipseInRect != NULL) { - CGContextStrokeEllipseInRect(outContext, rect); + if (angle1 == 0 && angle2 == 23040 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + && CGContextStrokeEllipseInRect != NULL +#endif + ) { + CGContextStrokeEllipseInRect(dc.context, rect); } else #endif { CGMutablePathRef p = CGPathCreateMutable(); CGAffineTransform t = CGAffineTransformIdentity; CGPoint c = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); - float w = CGRectGetWidth(rect); + double w = CGRectGetWidth(rect); if (width != height) { - t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w); + t = CGAffineTransformMakeScale(1.0, CGRectGetHeight(rect)/w); c = CGPointApplyAffineTransform(c, CGAffineTransformInvert(t)); } CGPathAddArc(p, &t, c.x, c.y, w/2, radians(-angle1/64.0), radians(-(angle1 + angle2)/64.0), angle2 > 0); - CGContextAddPath(outContext, p); + CGContextAddPath(dc.context, p); CGPathRelease(p); - CGContextStrokePath(outContext); + CGContextStrokePath(dc.context); } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { Rect theRect; short start, extent; int o = -lw/2; - TkMacOSXSetUpGraphicsPort(gc, destPort); - ShowPen(); - PenPixPat(gPenPat); - theRect.left = (short) (macWin->xOff + x + o); - theRect.top = (short) (macWin->yOff + y + o); - theRect.right = (short) (theRect.left + width + lw); + theRect.left = (short) (macWin->xOff + x + o); + theRect.top = (short) (macWin->yOff + y + o); + theRect.right = (short) (theRect.left + width + lw); theRect.bottom = (short) (theRect.top + height + lw); - start = (short) (90 - (angle1/64)); + start = (short) (90 - (angle1/64)); extent = (short) (-(angle2/64)); FrameArc(&theRect, start, extent); - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #ifdef TK_MACOSXDRAW_UNUSED @@ -1161,23 +1064,24 @@ XDrawArc( * * XDrawArcs -- * - * Draws multiple circular or elliptical arcs. Each arc is - * specified by a rectangle and two angles. The center of the - * circle or ellipse is the center of the rect- angle, and the - * major and minor axes are specified by the width and height. - * Positive angles indicate counterclock- wise motion, and - * negative angles indicate clockwise motion. If the magnitude - * of angle2 is greater than 360 degrees, XDrawArcs truncates it - * to 360 degrees. + * Draws multiple circular or elliptical arcs. Each arc is + * specified by a rectangle and two angles. The center of the + * circle or ellipse is the center of the rect- angle, and the + * major and minor axes are specified by the width and height. + * Positive angles indicate counterclock- wise motion, and + * negative angles indicate clockwise motion. If the magnitude + * of angle2 is greater than 360 degrees, XDrawArcs truncates it + * to 360 degrees. * * Results: - * None. + * None. * * Side effects: - * Draws an arc for each array element on the specified drawable. + * Draws an arc for each array element on the specified drawable. * *---------------------------------------------------------------------- */ + void XDrawArcs( Display *display, @@ -1188,24 +1092,15 @@ XDrawArcs( { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; - XArc * arcPtr; + TkMacOSXDrawingContext dc; + XArc *arcPtr; int i, lw = gc->line_width; - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - float o = (lw % 2) ? .5 : 0; + double o = (lw % 2) ? .5 : 0; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); for (i=0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) { if (arcPtr->width == 0 || arcPtr->height == 0 || arcPtr->angle2 == 0) { @@ -1217,41 +1112,40 @@ XDrawArcs( arcPtr->width, arcPtr->height); #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 - if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040 && - CGContextStrokeEllipseInRect != NULL) { - CGContextStrokeEllipseInRect(outContext, rect); + if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + && CGContextStrokeEllipseInRect != NULL +#endif + ) { + CGContextStrokeEllipseInRect(dc.context, rect); } else #endif { CGMutablePathRef p = CGPathCreateMutable(); CGAffineTransform t = CGAffineTransformIdentity; CGPoint c = CGPointMake(CGRectGetMidX(rect), - CGRectGetMidY(rect)); - float w = CGRectGetWidth(rect); + CGRectGetMidY(rect)); + double w = CGRectGetWidth(rect); if (arcPtr->width != arcPtr->height) { t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w); c = CGPointApplyAffineTransform(c, - CGAffineTransformInvert(t)); + CGAffineTransformInvert(t)); } CGPathAddArc(p, &t, c.x, c.y, w/2, radians(-arcPtr->angle1/64.0), radians(-(arcPtr->angle1 + arcPtr->angle2)/64.0), arcPtr->angle2 > 0); - CGContextAddPath(outContext, p); + CGContextAddPath(dc.context, p); CGPathRelease(p); - CGContextStrokePath(outContext); + CGContextStrokePath(dc.context); } } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { Rect theRect; short start, extent; int o = -lw/2; - TkMacOSXSetUpGraphicsPort(gc, destPort); - ShowPen(); - PenPixPat(gPenPat); for (i = 0, arcPtr = arcArr;i < nArcs;i++, arcPtr++) { theRect.left = (short) (macWin->xOff + arcPtr->x + o); theRect.top = (short) (macWin->yOff + arcPtr->y + o); @@ -1261,10 +1155,8 @@ XDrawArcs( extent = (short) (-(arcPtr->angle2/64)); FrameArc(&theRect, start, extent); } - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #endif @@ -1273,71 +1165,64 @@ XDrawArcs( * * XFillArc -- * - * Draw a filled arc. + * Draw a filled arc. * * Results: - * None. + * None. * * Side effects: - * Draws a filled arc on the specified drawable. + * Draws a filled arc on the specified drawable. * *---------------------------------------------------------------------- */ void XFillArc( - Display* display, /* Display. */ - Drawable d, /* Draw on this. */ - GC gc, /* Use this GC. */ - int x, /* Upper left of */ - int y, /* bounding rect. */ - unsigned int width, /* Width & height. */ + Display* display, /* Display. */ + Drawable d, /* Draw on this. */ + GC gc, /* Use this GC. */ + int x, int y, /* Upper left of bounding rect. */ + unsigned int width, /* Width & height. */ unsigned int height, - int angle1, /* Staring angle of arc. */ - int angle2) /* Extent of arc. */ + int angle1, /* Staring angle of arc. */ + int angle2) /* Extent of arc. */ { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; int lw = gc->line_width; if (width == 0 || height == 0 || angle2 == 0) { return; } - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - float o = (lw % 2) ? .5 : 0, u = 0; + double o = (lw % 2) ? .5 : 0, u = 0; if (notAA(lw)) { o += NON_AA_CG_OFFSET/2; u += NON_AA_CG_OFFSET; } - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); rect = CGRectMake( macWin->xOff + x + o, macWin->yOff + y + o, width - u, height - u); #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 - if (angle1 == 0 && angle2 == 23040 && - CGContextFillEllipseInRect != NULL) { - CGContextFillEllipseInRect(outContext, rect); + if (angle1 == 0 && angle2 == 23040 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + && CGContextFillEllipseInRect != NULL +#endif + ) { + CGContextFillEllipseInRect(dc.context, rect); } else #endif { CGMutablePathRef p = CGPathCreateMutable(); CGAffineTransform t = CGAffineTransformIdentity; CGPoint c = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); - float w = CGRectGetWidth(rect); + double w = CGRectGetWidth(rect); if (width != height) { t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w); @@ -1349,11 +1234,10 @@ XFillArc( CGPathAddArc(p, &t, c.x, c.y, w/2, radians(-angle1/64.0), radians(-(angle1 + angle2)/64.0), angle2 > 0); CGPathCloseSubpath(p); - CGContextAddPath(outContext, p); + CGContextAddPath(dc.context, p); CGPathRelease(p); - CGContextFillPath(outContext); + CGContextFillPath(dc.context); } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { Rect theRect; short start, extent; @@ -1363,10 +1247,9 @@ XFillArc( double boxWidth, boxHeight; double vertex[2], center1[2], center2[2]; - TkMacOSXSetUpGraphicsPort(gc, destPort); - theRect.left = (short) (macWin->xOff + x + o); - theRect.top = (short) (macWin->yOff + y + o); - theRect.right = (short) (theRect.left + width + lw); + theRect.left = (short) (macWin->xOff + x + o); + theRect.top = (short) (macWin->yOff + y + o); + theRect.right = (short) (theRect.left + width + lw); theRect.bottom = (short) (theRect.top + height + lw); start = (short) (90 - (angle1/64)); extent = (short) (-(angle2/64)); @@ -1392,19 +1275,14 @@ XFillArc( LineTo((short) (center1[0] + .5), (short) (center1[1] + .5)); LineTo((short) (center2[0] + .5), (short) (center2[1] + .5)); ClosePoly(); - ShowPen(); - FillCArc(&theRect, start, extent, gPenPat); - FillCPoly(polygon, gPenPat); - HidePen(); + FillCArc(&theRect, start, extent, dc.penPat); + FillCPoly(polygon, dc.penPat); KillPoly(polygon); } else { - ShowPen(); - FillCArc(&theRect, start, extent, gPenPat); - HidePen(); + FillCArc(&theRect, start, extent, dc.penPat); } } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #ifdef TK_MACOSXDRAW_UNUSED @@ -1413,16 +1291,17 @@ XFillArc( * * XFillArcs -- * - * Draw a filled arc. + * Draw a filled arc. * * Results: - * None. + * None. * * Side effects: - * Draws a filled arc for each array element on the specified drawable. + * Draws a filled arc for each array element on the specified drawable. * *---------------------------------------------------------------------- */ + void XFillArcs( Display *display, @@ -1432,28 +1311,19 @@ XFillArcs( int nArcs) { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; XArc * arcPtr; int i, lw = gc->line_width; - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - float o = (lw % 2) ? .5 : 0, u = 0; + double o = (lw % 2) ? .5 : 0, u = 0; if (notAA(lw)) { o += NON_AA_CG_OFFSET/2; u += NON_AA_CG_OFFSET; } - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); for (i = 0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) { if (arcPtr->width == 0 || arcPtr->height == 0 || arcPtr->angle2 == 0) { @@ -1465,22 +1335,25 @@ XFillArcs( arcPtr->width - u, arcPtr->height - u); #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 - if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040 && - CGContextFillEllipseInRect != NULL) { - CGContextFillEllipseInRect(outContext, rect); + if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + && CGContextFillEllipseInRect != NULL +#endif + ) { + CGContextFillEllipseInRect(dc.context, rect); } else #endif { CGMutablePathRef p = CGPathCreateMutable(); CGAffineTransform t = CGAffineTransformIdentity; CGPoint c = CGPointMake(CGRectGetMidX(rect), - CGRectGetMidY(rect)); - float w = CGRectGetWidth(rect); + CGRectGetMidY(rect)); + double w = CGRectGetWidth(rect); if (arcPtr->width != arcPtr->height) { t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w); c = CGPointApplyAffineTransform(c, - CGAffineTransformInvert(t)); + CGAffineTransformInvert(t)); } if (gc->arc_mode == ArcPieSlice) { CGPathMoveToPoint(p, &t, c.x, c.y); @@ -1490,12 +1363,11 @@ XFillArcs( radians(-(arcPtr->angle1 + arcPtr->angle2)/64.0), arcPtr->angle2 > 0); CGPathCloseSubpath(p); - CGContextAddPath(outContext, p); + CGContextAddPath(dc.context, p); CGPathRelease(p); - CGContextFillPath(outContext); + CGContextFillPath(dc.context); } } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { Rect theRect; short start, extent; @@ -1505,7 +1377,6 @@ XFillArcs( double boxWidth, boxHeight; double vertex[2], center1[2], center2[2]; - TkMacOSXSetUpGraphicsPort(gc, destPort); for (i = 0, arcPtr = arcArr;i<nArcs;i++, arcPtr++) { theRect.left = (short) (macWin->xOff + arcPtr->x + o); theRect.top = (short) (macWin->yOff + arcPtr->y + o); @@ -1536,20 +1407,15 @@ XFillArcs( LineTo((short) (center1[0] + .5), (short) (center1[1] + .5)); LineTo((short) (center2[0] + .5), (short) (center2[1] + .5)); ClosePoly(); - ShowPen(); - FillCArc(&theRect, start, extent, gPenPat); - FillCPoly(polygon, gPenPat); - HidePen(); + FillCArc(&theRect, start, extent, dc.penPat); + FillCPoly(polygon, dc.penPat); KillPoly(polygon); } else { - ShowPen(); - FillCArc(&theRect, start, extent, gPenPat); - HidePen(); + FillCArc(&theRect, start, extent, dc.penPat); } } } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #endif @@ -1561,8 +1427,10 @@ XFillArcs( * *---------------------------------------------------------------------- */ + long -XMaxRequestSize(Display *display) +XMaxRequestSize( + Display *display) { return (SHRT_MAX / 4); } @@ -1573,51 +1441,45 @@ XMaxRequestSize(Display *display) * * TkScrollWindow -- * - * Scroll a rectangle of the specified window and accumulate - * a damage region. + * Scroll a rectangle of the specified window and accumulate + * a damage region. * * Results: - * Returns 0 if the scroll genereated no additional damage. - * Otherwise, sets the region that needs to be repainted after - * scrolling and returns 1. + * Returns 0 if the scroll genereated no additional damage. + * Otherwise, sets the region that needs to be repainted after + * scrolling and returns 1. * * Side effects: - * Scrolls the bits in the window. + * Scrolls the bits in the window. * *---------------------------------------------------------------------- */ int TkScrollWindow( - Tk_Window tkwin, /* The window to be scrolled. */ - GC gc, /* GC for window to be scrolled. */ - int x, /* Position rectangle to be scrolled. */ - int y, - int width, - int height, - int dx, /* Distance rectangle should be moved. */ - int dy, - TkRegion damageRgn) /* Region to accumulate damage in. */ + Tk_Window tkwin, /* The window to be scrolled. */ + GC gc, /* GC for window to be scrolled. */ + int x, int y, /* Position rectangle to be scrolled. */ + int width, int height, + int dx, int dy, /* Distance rectangle should be moved. */ + TkRegion damageRgn) /* Region to accumulate damage in. */ { MacDrawable *destDraw = (MacDrawable *) Tk_WindowId(tkwin); RgnHandle rgn = (RgnHandle) damageRgn; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + CGrafPtr destPort, savePort; + Boolean portChanged; Rect srcRect, scrollRect; - RgnHandle visRgn, clipRgn; destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); + portChanged = QDSwapPort(destPort, &savePort); TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin)); /* * Due to the implementation below the behavior may be differnt - * than X in certain cases that should never occur in Tk. The + * than X in certain cases that should never occur in Tk. The * scrollRect is the source rect extended by the offset (the union - * of the source rect and the offset rect). Everything - * in the extended scrollRect is scrolled. On X, it's possible + * of the source rect and the offset rect). Everything + * in the extended scrollRect is scrolled. On X, it's possible * to "skip" over an area if the offset makes the source and * destination rects disjoint and non-aligned. */ @@ -1642,45 +1504,27 @@ TkScrollWindow( * Adjust clip region so that we don't copy any windows * that may overlap us. */ - visRgn = NewRgn(); - clipRgn = NewRgn(); + + TkMacOSXCheckTmpRgnEmpty(1); + TkMacOSXCheckTmpRgnEmpty(2); RectRgn(rgn, &srcRect); - GetPortVisibleRegion(destPort,visRgn); - DiffRgn(rgn, visRgn, rgn); + GetPortVisibleRegion(destPort,tkMacOSXtmpRgn1); + DiffRgn(rgn, tkMacOSXtmpRgn1, rgn); OffsetRgn(rgn, dx, dy); - GetPortClipRegion(destPort, clipRgn); - DiffRgn(clipRgn, rgn, clipRgn); - SetPortClipRegion(destPort, clipRgn); + GetPortClipRegion(destPort, tkMacOSXtmpRgn2); + DiffRgn(tkMacOSXtmpRgn2, rgn, tkMacOSXtmpRgn2); + SetPortClipRegion(destPort, tkMacOSXtmpRgn2); + SetEmptyRgn(tkMacOSXtmpRgn1); + SetEmptyRgn(tkMacOSXtmpRgn2); SetEmptyRgn(rgn); - /* - * When a menu is up, the Mac does not expect drawing to occur and - * does not clip out the menu. We have to do it ourselves. This - * is pretty gross. - */ - - if (tkUseMenuCascadeRgn == 1) { - Point scratch = {0, 0}; - MacDrawable *macDraw = (MacDrawable *) Tk_WindowId(tkwin); - - LocalToGlobal(&scratch); - CopyRgn(tkMenuCascadeRgn, rgn); - OffsetRgn(rgn, -scratch.h, -scratch.v); - DiffRgn(clipRgn, rgn, clipRgn); - SetPortClipRegion(destPort, clipRgn); - SetEmptyRgn(rgn); - macDraw->toplevel->flags |= TK_DRAWN_UNDER_MENU; - } - ScrollRect(&scrollRect, dx, dy, rgn); - - SetGWorld(saveWorld, saveDevice); - - DisposeRgn(clipRgn); - DisposeRgn(visRgn); + if (portChanged) { + QDSwapPort(savePort, NULL); + } /* - * Fortunantly, the region returned by ScrollRect is symanticlly - * the same as what we need to return in this function. If the + * Fortunately, the region returned by ScrollRect is semantically + * the same as what we need to return in this function. If the * region is empty we return zero to denote that no damage was * created. */ @@ -1696,220 +1540,300 @@ TkScrollWindow( * * TkMacOSXSetUpGraphicsPort -- * - * Set up the graphics port from the given GC. + * Set up the graphics port from the given GC. * * Results: - * None. + * None. * * Side effects: - * The current port is adjusted. + * The current port is adjusted. * *---------------------------------------------------------------------- */ void TkMacOSXSetUpGraphicsPort( - GC gc, - GWorldPtr destPort) /* GC to apply to current port. */ + GC gc, /* GC to apply to current port. */ + GWorldPtr destPort) { - RGBColor macColor; - - if (gPenPat == NULL) { - gPenPat = NewPixPat(); - } - - if (TkSetMacColor(gc->foreground, &macColor) == true) { - /* TODO: cache RGBPats for preformace - measure gains... */ - MakeRGBPat(gPenPat, &macColor); - } - PenNormal(); - if(gc->function == GXxor) { - PenMode(patXor); - } - if (gc->line_width > 1) { - PenSize(gc->line_width, gc->line_width); - } - if (gc->line_style != LineSolid) { - /* - * Here the dash pattern should be set in the drawing, - * environment, but I don't know how to do that for the Mac. - * - * p[] is an array of unsigned chars containing the dash list. - * A '\0' indicates the end of this list. - * - * Someone knows how to implement this? If you have a more - * complete implementation of SetUpGraphicsPort() for - * the Mac (or for Windows), please let me know. - * - * Jan Nijtmans - * CMG Arnhem, B.V. - * email: j.nijtmans@chello.nl (private) - * jan.nijtmans@cmg.nl (work) - * url: http://purl.oclc.org/net/nijtmans/ - * - * FIXME: - * This is not possible with QuickDraw line drawing. As of - * Tk 8.4.7 we have a complete set of drawing routines using - * CG, so there is no reason to support this here. - */ + if (gc) { + if (gPenPat == NULL) { + gPenPat = NewPixPat(); + } + TkMacOSXSetColorInPort(gc->foreground, 1, gPenPat); + PenPixPat(gPenPat); + if(gc->function == GXxor) { + PenMode(patXor); + } + if (gc->line_width > 1) { + PenSize(gc->line_width, gc->line_width); + } + if (gc->line_style != LineSolid) { + /* + * FIXME: + * Here the dash pattern should be set in the drawing environment. + * This is not possible with QuickDraw line drawing. + */ + } } } /* *---------------------------------------------------------------------- * - * TkMacOSXSetUpCGContext -- + * TkMacOSXSetUpDrawingContext -- * - * Set up a CGContext for the given graphics port. + * Set up a drawing context for the given drawable and GC. * * Results: - * None. + * Boolean indicating whether to use CG drawing. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -static void -TkMacOSXSetUpCGContext( - MacDrawable *macWin, - CGrafPtr destPort, - GC gc, - CGContextRef *contextPtr) +int +TkMacOSXSetupDrawingContext(Drawable d, GC gc, int useCG, + TkMacOSXDrawingContext *dc) { - RGBColor macColor; - CGContextRef outContext; - OSStatus err; - Rect boundsRect; - CGAffineTransform coordsTransform; - static RgnHandle clipRgn = NULL; - float w; - - err = QDBeginCGContext(destPort, contextPtr); - outContext = *contextPtr; - - /* - * Now clip the CG Context to the port. Note, we have already - * set up the port with our clip region, so we can just get - * the clip back out of there. If we use the macWin->clipRgn - * directly at this point, we get some odd drawing effects. - * - * We also have to intersect our clip region with the port - * visible region so we don't overwrite the window decoration. - */ - - if (!clipRgn) { - clipRgn = NewRgn(); + MacDrawable *macDraw = ((MacDrawable*)d); + CGContextRef context = macDraw->context; + CGrafPtr port; + Rect portBounds; + + port = TkMacOSXGetDrawablePort(d); + if (port) { + GetPortBounds(port, &portBounds); } - GetPortBounds(destPort, &boundsRect); - - RectRgn(clipRgn, &boundsRect); - SectRegionWithPortClipRegion(destPort, clipRgn); - SectRegionWithPortVisibleRegion(destPort, clipRgn); - ClipCGContextToRegion(outContext, &boundsRect, clipRgn); - SetEmptyRgn(clipRgn); + dc->saveState = NULL; + if (port && !context) { + dc->portChanged = QDSwapPort(port, &(dc->savePort)); + TkMacOSXSetUpClippingRgn(d); + TkMacOSXCheckTmpRgnEmpty(1); + if (useCG) { + if (ChkErr(QDBeginCGContext, port, &context) == noErr) { + /* + * Now clip the CG Context to the port. Note, we have already + * set up the port with our clip region, so we can just get + * the clip back out of there. If we use the macWin->clipRgn + * directly at this point, we get some odd drawing effects. + * + * We also have to intersect our clip region with the port + * visible region so we don't overwrite the window decoration. + */ + + RectRgn(tkMacOSXtmpRgn1, &portBounds); + SectRegionWithPortClipRegion(port, tkMacOSXtmpRgn1); + SectRegionWithPortVisibleRegion(port, tkMacOSXtmpRgn1); + if (gc && gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type + == TKP_CLIP_REGION) { + RgnHandle clipRgn = (RgnHandle) + ((TkpClipMask*)gc->clip_mask)->value.region; + int xOffset = macDraw->xOff + gc->clip_x_origin; + int yOffset = macDraw->yOff + gc->clip_y_origin; + + OffsetRgn(clipRgn, xOffset, yOffset); + SectRgn(clipRgn, tkMacOSXtmpRgn1, tkMacOSXtmpRgn1); + OffsetRgn(clipRgn, -xOffset, -yOffset); + } + ClipCGContextToRegion(context, &portBounds, tkMacOSXtmpRgn1); + SetEmptyRgn(tkMacOSXtmpRgn1); - /* - * Note: You have to call SyncCGContextOriginWithPort - * AFTER all the clip region manipulations. - */ + /* + * Note: You have to call SyncCGContextOriginWithPort + * AFTER all the clip region manipulations. + */ - SyncCGContextOriginWithPort(outContext, destPort); - - coordsTransform = CGAffineTransformMake(1, 0, 0, -1, 0, - boundsRect.bottom - boundsRect.top); - CGContextConcatCTM(outContext, coordsTransform); - - /* Now offset the CTM to the subwindow offset */ - - if (TkSetMacColor(gc->foreground, &macColor) == true) { - CGContextSetRGBFillColor(outContext, - RGBFLOATRED(macColor), - RGBFLOATGREEN(macColor), - RGBFLOATBLUE(macColor), - 1); - CGContextSetRGBStrokeColor(outContext, - RGBFLOATRED(macColor), - RGBFLOATGREEN(macColor), - RGBFLOATBLUE(macColor), - 1); - } + SyncCGContextOriginWithPort(context, port); + } else { + context = NULL; + useCG = 0; + } + } + } else if (context) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + if (!port +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1030 + && CGContextGetClipBoundingBox != NULL +#endif + ) { + CGRect r = CGContextGetClipBoundingBox(context); - if(gc->function == GXxor) { - } + 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); + } +#endif + CGContextSaveGState(context); + TkMacOSXCheckTmpRgnEmpty(1); + RectRgn(tkMacOSXtmpRgn1, &portBounds); + if (port) { + TkMacOSXSetUpClippingRgn(d); + SectRegionWithPortClipRegion(port, tkMacOSXtmpRgn1); + SectRegionWithPortVisibleRegion(port, tkMacOSXtmpRgn1); + } else if (macDraw->flags & TK_CLIPPED_DRAW) { + OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff); + SectRgn(macDraw->clipRgn, macDraw->drawRgn, tkMacOSXtmpRgn1); + OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff); + } + if (gc && gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type + == TKP_CLIP_REGION) { + RgnHandle clipRgn = (RgnHandle) + ((TkpClipMask*)gc->clip_mask)->value.region; + int xOffset = macDraw->xOff + gc->clip_x_origin; + int yOffset = macDraw->yOff + gc->clip_y_origin; - w = gc->line_width; - /* 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(outContext, 0); - } else { - CGContextSetShouldAntialias(outContext, 1); + OffsetRgn(clipRgn, xOffset, yOffset); + SectRgn(clipRgn, tkMacOSXtmpRgn1, tkMacOSXtmpRgn1); + OffsetRgn(clipRgn, -xOffset, -yOffset); + } + ClipCGContextToRegion(context, &portBounds, tkMacOSXtmpRgn1); + SetEmptyRgn(tkMacOSXtmpRgn1); + port = NULL; + dc->portChanged = false; + dc->saveState = (void*)1; + useCG = 1; } - CGContextSetLineWidth(outContext, w); + if (useCG) { + 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 == GXxor) { + TkMacOSXDbgMsg("GXxor mode 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); - float dashOffset = gc->dash_offset; - float lengths[10]; + if (gc->line_style != LineSolid) { + int num = 0; + char *p = &(gc->dashes); + double dashOffset = gc->dash_offset; + float lengths[10]; - while (p[num] != '\0') { - lengths[num] = p[num]; - num++; - } - CGContextSetLineDash(outContext, dashOffset, lengths, num); - } + 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? - */ + if (gc->cap_style == CapButt) { + /* + * What about CapNotLast, CapProjecting? + */ - CGContextSetLineCap(outContext, kCGLineCapButt); - } else if (gc->cap_style == CapRound) { - CGContextSetLineCap(outContext, kCGLineCapRound); - } else if (gc->cap_style == CapProjecting) { - CGContextSetLineCap(outContext, kCGLineCapSquare); - } + 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(outContext, kCGLineJoinMiter); - } else if (gc->join_style == JoinRound) { - CGContextSetLineJoin(outContext, kCGLineJoinRound); - } else if (gc->join_style == JoinBevel) { - CGContextSetLineJoin(outContext, kCGLineJoinBevel); + 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); + } + } + } else { + ChkErr(GetThemeDrawingState, &(dc->saveState)); + if (gc) { + PixPatHandle savePat = gPenPat; + + gPenPat = NULL; + TkMacOSXSetUpGraphicsPort(gc, port); + dc->penPat = gPenPat; + gPenPat = savePat; + if (gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type + == TKP_CLIP_REGION) { + RgnHandle clipRgn = (RgnHandle) + ((TkpClipMask*)gc->clip_mask)->value.region; + int xOffset = macDraw->xOff + gc->clip_x_origin; + int yOffset = macDraw->yOff + gc->clip_y_origin; + + OffsetRgn(clipRgn, xOffset, yOffset); + GetClip(tkMacOSXtmpRgn1); + SectRgn(clipRgn, tkMacOSXtmpRgn1, tkMacOSXtmpRgn1); + SetClip(tkMacOSXtmpRgn1); + SetEmptyRgn(tkMacOSXtmpRgn1); + OffsetRgn(clipRgn, -xOffset, -yOffset); + } + } else { + TkMacOSXSetUpGraphicsPort(NULL, port); + dc->penPat = NULL; + } + ShowPen(); } + dc->port = port; + dc->portBounds = portBounds; + dc->context = context; + return useCG; } /* *---------------------------------------------------------------------- * - * TkMacOSXReleaseCGContext -- + * TkMacOSXRestoreDrawingContext -- * - * Release the CGContext for the given graphics port. + * Restore drawing context. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -static void -TkMacOSXReleaseCGContext( - MacDrawable *macWin, - CGrafPtr destPort, - CGContextRef *outContext) +void +TkMacOSXRestoreDrawingContext(TkMacOSXDrawingContext *dc) { - CGContextSynchronize(*outContext); - QDEndCGContext(destPort, outContext); + if (dc->context) { + CGContextSynchronize(dc->context); + if (dc->saveState) { + CGContextRestoreGState(dc->context); + } + if (dc->port) { + ChkErr(QDEndCGContext, dc->port, &(dc->context)); + } + } else { + HidePen(); + PenNormal(); + if (dc->penPat) { + DisposePixPat(dc->penPat); + } + if (dc->saveState) { + ChkErr(SetThemeDrawingState, dc->saveState, true); + } + } + if (dc->portChanged) { + QDSwapPort(dc->savePort, NULL); + } +#ifdef TK_MAC_DEBUG + bzero(dc, sizeof(dc)); +#endif /* TK_MAC_DEBUG */ } /* @@ -1917,21 +1841,21 @@ TkMacOSXReleaseCGContext( * * TkMacOSXSetUpClippingRgn -- * - * Set up the clipping region so that drawing only occurs on the - * specified X subwindow. + * Set up the clipping region so that drawing only occurs on the + * specified X subwindow. * * Results: - * None. + * None. * * Side effects: - * The clipping region in the current port is changed. + * The clipping region in the current port is changed. * *---------------------------------------------------------------------- */ void TkMacOSXSetUpClippingRgn( - Drawable drawable) /* Drawable to update. */ + Drawable drawable) /* Drawable to update. */ { MacDrawable *macDraw = (MacDrawable *) drawable; @@ -1940,43 +1864,72 @@ TkMacOSXSetUpClippingRgn( TkMacOSXUpdateClipRgn(macDraw->winPtr); } -#if defined(TK_MAC_DEBUG) && defined(TK_MAC_DEBUG_DRAWING) +#ifdef TK_MAC_DEBUG_DRAWING TkMacOSXInitNamedDebugSymbol(HIToolbox, int, QDDebugFlashRegion, - CGrafPtr port, RgnHandle region); + CGrafPtr port, RgnHandle region); if (QDDebugFlashRegion) { CGrafPtr grafPtr = TkMacOSXGetDrawablePort(drawable); - /* Carbon-internal region flashing SPI (c.f. Technote 2124) */ + + /* + * Carbon-internal region flashing SPI (c.f. Technote 2124) + */ + QDDebugFlashRegion(grafPtr, macDraw->clipRgn); } #endif /* TK_MAC_DEBUG_DRAWING */ + } - /* - * When a menu is up, the Mac does not expect drawing to occur and - * does not clip out the menu. We have to do it ourselves. This - * is pretty gross. - */ + if (macDraw->clipRgn != NULL) { + if (macDraw->flags & TK_CLIPPED_DRAW) { + TkMacOSXCheckTmpRgnEmpty(1); + OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff); + SectRgn(macDraw->clipRgn, macDraw->drawRgn, tkMacOSXtmpRgn1); + OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff); + SetClip(tkMacOSXtmpRgn1); + SetEmptyRgn(tkMacOSXtmpRgn1); + } else { + SetClip(macDraw->clipRgn); + } + } else if (macDraw->flags & TK_CLIPPED_DRAW) { + OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff); + SetClip(macDraw->drawRgn); + OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff); + } +} + +/* + *---------------------------------------------------------------------- + * + * TkpClipDrawableToRect -- + * + * Clip all drawing into the drawable d to the given rectangle. + * If width and height are negative, reset to no clipping. + * + * Results: + * None. + * + * Side effects: + * Subsequent drawing into d is offset and clipped as specified. + * + *---------------------------------------------------------------------- + */ - if (macDraw->clipRgn != NULL) { - if (tkUseMenuCascadeRgn == 1) { - Point scratch = {0, 0}; - GDHandle saveDevice; - GWorldPtr saveWorld; - - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(TkMacOSXGetDrawablePort(drawable), NULL); - LocalToGlobal(&scratch); - SetGWorld(saveWorld, saveDevice); - if (tmpRgn == NULL) { - tmpRgn = NewRgn(); - } - CopyRgn(tkMenuCascadeRgn, tmpRgn); - OffsetRgn(tmpRgn, -scratch.h, -scratch.v); - DiffRgn(macDraw->clipRgn, tmpRgn, tmpRgn); - SetClip(tmpRgn); - macDraw->toplevel->flags |= TK_DRAWN_UNDER_MENU; - } else { - SetClip(macDraw->clipRgn); - } +void +TkpClipDrawableToRect( + Display *display, + Drawable d, + int x, int y, + int width, int height) +{ + 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; } } } @@ -1986,48 +1939,45 @@ TkMacOSXSetUpClippingRgn( * * TkMacOSXMakeStippleMap -- * - * Given a drawable and a stipple pattern this function draws the - * pattern repeatedly over the drawable. The drawable can then - * be used as a mask for bit-bliting a stipple pattern over an - * object. + * Given a drawable and a stipple pattern this function draws the + * pattern repeatedly over the drawable. The drawable can then + * be used as a mask for bit-bliting a stipple pattern over an + * object. * * Results: - * A BitMap data structure. + * A BitMap data structure. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ BitMapPtr TkMacOSXMakeStippleMap( - Drawable drawable, /* Window to apply stipple. */ - Drawable stipple) /* The stipple pattern. */ + Drawable drawable, /* Window to apply stipple. */ + Drawable stipple) /* The stipple pattern. */ { - GWorldPtr destPort; + CGrafPtr stipplePort; BitMapPtr bitmapPtr; - Rect portRect; - int width, height, stippleHeight, stippleWidth; - int i, j; - char * data; + const BitMap *stippleBitmap; + Rect portRect; + int width, height, stippleHeight, stippleWidth, i, j; Rect bounds; - destPort = TkMacOSXGetDrawablePort(drawable); - - GetPortBounds (destPort, &portRect); + GetPortBounds(TkMacOSXGetDrawablePort(drawable), &portRect); width = portRect.right - portRect.left; height = portRect.bottom - portRect.top; - bitmapPtr = (BitMap *) ckalloc(sizeof(BitMap)); - data = (char *) ckalloc(height * ((width / 8) + 1)); bitmapPtr->bounds.top = bitmapPtr->bounds.left = 0; bitmapPtr->bounds.right = (short) width; bitmapPtr->bounds.bottom = (short) height; - bitmapPtr->baseAddr = data; bitmapPtr->rowBytes = (width / 8) + 1; + bitmapPtr->baseAddr = ckalloc(height * bitmapPtr->rowBytes); - destPort = TkMacOSXGetDrawablePort(stipple); + stipplePort = TkMacOSXGetDrawablePort(stipple); + stippleBitmap = GetPortBitMapForCopyBits(stipplePort); + GetPortBounds(stipplePort, &portRect); stippleWidth = portRect.right - portRect.left; stippleHeight = portRect.bottom - portRect.top; @@ -2037,9 +1987,8 @@ TkMacOSXMakeStippleMap( bounds.top = i; bounds.right = j + stippleWidth; bounds.bottom = i + stippleHeight; - - CopyBits(GetPortBitMapForCopyBits(destPort), bitmapPtr, - &portRect, &bounds, srcCopy, NULL); + CopyBits(stippleBitmap, bitmapPtr, &portRect, &bounds, srcCopy, + NULL); } } return bitmapPtr; @@ -2050,20 +1999,20 @@ TkMacOSXMakeStippleMap( * * InvertByte -- * - * This function reverses the bits in the passed in Byte of data. + * This function reverses the bits in the passed in Byte of data. * * Results: - * The incoming byte in reverse bit order. + * The incoming byte in reverse bit order. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ static unsigned char InvertByte( - unsigned char data) /* Byte of data. */ + unsigned char data) /* Byte of data. */ { unsigned char i; unsigned char mask = 1, result = 0; @@ -2082,32 +2031,32 @@ InvertByte( * * TkpDrawHighlightBorder -- * - * This procedure draws a rectangular ring around the outside of - * a widget to indicate that it has received the input focus. + * This procedure draws a rectangular ring around the outside of + * a widget to indicate that it has received the input focus. * - * On the Macintosh, this puts a 1 pixel border in the bgGC color - * between the widget and the focus ring, except in the case where - * highlightWidth is 1, in which case the border is left out. + * On the Macintosh, this puts a 1 pixel border in the bgGC color + * between the widget and the focus ring, except in the case where + * highlightWidth is 1, in which case the border is left out. * - * For proper Mac L&F, use highlightWidth of 3. + * For proper Mac L&F, use highlightWidth of 3. * * Results: - * None. + * None. * * Side effects: - * A rectangle "width" pixels wide is drawn in "drawable", - * corresponding to the outer area of "tkwin". + * A rectangle "width" pixels wide is drawn in "drawable", + * corresponding to the outer area of "tkwin". * *---------------------------------------------------------------------- */ void TkpDrawHighlightBorder ( - Tk_Window tkwin, - GC fgGC, - GC bgGC, - int highlightWidth, - Drawable drawable) + Tk_Window tkwin, + GC fgGC, + GC bgGC, + int highlightWidth, + Drawable drawable) { if (highlightWidth == 1) { TkDrawInsetFocusHighlight (tkwin, fgGC, highlightWidth, drawable, 0); @@ -2125,7 +2074,7 @@ TkpDrawHighlightBorder ( * * TkpDrawFrame -- * - * This procedure draws the rectangular frame area. If the user + * This procedure draws the rectangular frame area. If the user * has request themeing, it draws with a the background theme. * * Results: @@ -2138,52 +2087,27 @@ TkpDrawHighlightBorder ( */ void -TkpDrawFrame (Tk_Window tkwin, Tk_3DBorder border, - int highlightWidth, int borderWidth, int relief) +TkpDrawFrame( + Tk_Window tkwin, + Tk_3DBorder border, + int highlightWidth, + int borderWidth, + int relief) { if (useThemedToplevel && Tk_IsTopLevel(tkwin)) { - /* - * Currently only support themed toplevels, until we can better - * factor this to handle individual windows (blanket theming of - * frames will work for very few UIs). - */ - Rect bounds; - Point origin; - CGrafPtr saveWorld; - GDHandle saveDevice; - XGCValues gcValues; - GC gc; - Pixmap pixmap; - Display *display = Tk_Display(tkwin); - - pixmap = Tk_GetPixmap(display, Tk_WindowId(tkwin), - Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin)); - - gc = Tk_GetGC(tkwin, 0, &gcValues); - TkMacOSXWinBounds((TkWindow *) tkwin, &bounds); - origin.v = -bounds.top; - origin.h = -bounds.left; - bounds.top = bounds.left = 0; - bounds.right = Tk_Width(tkwin); - bounds.bottom = Tk_Height(tkwin); - - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(TkMacOSXGetDrawablePort(pixmap), 0); - ApplyThemeBackground(kThemeBackgroundWindowHeader, &bounds, - kThemeStateActive, 32 /* depth */, true /* inColor */); - QDSetPatternOrigin(origin); - EraseRect(&bounds); - SetGWorld(saveWorld, saveDevice); - - XCopyArea(display, pixmap, Tk_WindowId(tkwin), - gc, 0, 0, bounds.right, bounds.bottom, 0, 0); - Tk_FreePixmap(display, pixmap); - Tk_FreeGC(display, gc); - } else { - Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), - border, highlightWidth, highlightWidth, - Tk_Width(tkwin) - 2 * highlightWidth, - Tk_Height(tkwin) - 2 * highlightWidth, - borderWidth, relief); + static Tk_3DBorder themedBorder = NULL; + + if (!themedBorder) { + themedBorder = Tk_Get3DBorder(NULL, tkwin, + "systemWindowHeaderBackground"); + } + if (themedBorder) { + border = themedBorder; + } } + Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), + border, highlightWidth, highlightWidth, + Tk_Width(tkwin) - 2 * highlightWidth, + Tk_Height(tkwin) - 2 * highlightWidth, + borderWidth, relief); } diff --git a/macosx/tkMacOSXEmbed.c b/macosx/tkMacOSXEmbed.c index c82a649..bfd500c 100644 --- a/macosx/tkMacOSXEmbed.c +++ b/macosx/tkMacOSXEmbed.c @@ -1,51 +1,52 @@ -/* +/* * tkMacOSXEmbed.c -- * - * This file contains platform-specific procedures for theMac to provide - * basic operations needed for application embedding (where one - * application can use as its main window an internal window from - * some other application). - * Currently only Toplevel embedding within the same Tk application is - * allowed on the Macintosh. + * This file contains platform-specific procedures for theMac to provide + * basic operations needed for application embedding (where one + * application can use as its main window an internal window from + * some other application). + * Currently only Toplevel embedding within the same Tk application is + * allowed on the Macintosh. * * Copyright (c) 1996-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.8 2006/10/31 22:33:34 das Exp $ + * RCS: @(#) $Id: tkMacOSXEmbed.c,v 1.9 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" /* * One of the following structures exists for each container in this - * application. It keeps track of the container window and its + * application. It keeps track of the container window and its * associated embedded window. */ typedef struct Container { - Window parent; /* The Mac Drawable for the parent of - * the pair (the container). */ - TkWindow *parentPtr; /* Tk's information about the container, - * or NULL if the container isn't - * in this process. */ - Window embedded; /* The MacDrawable for the embedded - * window. Starts off as None, but - * gets filled in when the window is - * eventually created. */ - TkWindow *embeddedPtr; /* Tk's information about the embedded - * window, or NULL if the - * embedded application isn't in - * this process. */ - struct Container *nextPtr; /* Next in list of all containers in - * this process. */ + Window parent; /* The Mac Drawable for the parent of + * the pair (the container). */ + TkWindow *parentPtr; /* Tk's information about the container, + * or NULL if the container isn't + * in this process. */ + Window embedded; /* The MacDrawable for the embedded + * window. Starts off as None, but + * gets filled in when the window is + * eventually created. */ + TkWindow *embeddedPtr; /* Tk's information about the embedded + * window, or NULL if the + * embedded application isn't in + * this process. */ + struct Container *nextPtr; /* Next in list of all containers in + * this process. */ } Container; static Container *firstContainerPtr = NULL; - /* First in list of all containers - * managed by this process. */ + /* First in list of all containers + * managed by this process. */ /* * Globals defined in this file */ @@ -56,21 +57,15 @@ TkMacOSXEmbedHandler *tkMacOSXEmbedHandler = NULL; * Prototypes for static procedures defined in this file: */ -static void ContainerEventProc _ANSI_ARGS_(( - ClientData clientData, XEvent *eventPtr)); -static void EmbeddedEventProc _ANSI_ARGS_(( - ClientData clientData, XEvent *eventPtr)); -static void EmbedActivateProc _ANSI_ARGS_((ClientData clientData, - XEvent *eventPtr)); -static void EmbedFocusProc _ANSI_ARGS_((ClientData clientData, - XEvent *eventPtr)); -static void EmbedGeometryRequest _ANSI_ARGS_(( - Container * containerPtr, int width, int height)); -static void EmbedSendConfigure _ANSI_ARGS_(( - Container *containerPtr)); -static void EmbedStructureProc _ANSI_ARGS_((ClientData clientData, - XEvent *eventPtr)); -static void EmbedWindowDeleted _ANSI_ARGS_((TkWindow *winPtr)); +static void ContainerEventProc(ClientData clientData, XEvent *eventPtr); +static void EmbeddedEventProc(ClientData clientData, XEvent *eventPtr); +static void EmbedActivateProc(ClientData clientData, XEvent *eventPtr); +static void EmbedFocusProc(ClientData clientData, XEvent *eventPtr); +static void EmbedGeometryRequest(Container * containerPtr, int width, + int height); +static void EmbedSendConfigure(Container *containerPtr); +static void EmbedStructureProc(ClientData clientData, XEvent *eventPtr); +static void EmbedWindowDeleted(TkWindow *winPtr); /* @@ -78,15 +73,15 @@ static void EmbedWindowDeleted _ANSI_ARGS_((TkWindow *winPtr)); * * Tk_MacOSXSetEmbedHandler -- * - * Registers a handler for an in process form of embedding, like - * Netscape plugins, where Tk is loaded into the process, but does - * not control the main window + * Registers a handler for an in process form of embedding, like + * Netscape plugins, where Tk is loaded into the process, but does + * not control the main window * * Results: - * None + * None * * Side effects: - * The embed handler is set. + * The embed handler is set. * *---------------------------------------------------------------------- */ @@ -99,28 +94,27 @@ Tk_MacOSXSetEmbedHandler( Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc) { if (tkMacOSXEmbedHandler == NULL) { - tkMacOSXEmbedHandler = (TkMacOSXEmbedHandler *) ckalloc(sizeof(TkMacOSXEmbedHandler)); + tkMacOSXEmbedHandler = (TkMacOSXEmbedHandler *) ckalloc(sizeof(TkMacOSXEmbedHandler)); } tkMacOSXEmbedHandler->registerWinProc = registerWinProc; tkMacOSXEmbedHandler->getPortProc = getPortProc; tkMacOSXEmbedHandler->containerExistProc = containerExistProc; tkMacOSXEmbedHandler->getClipProc = getClipProc; - tkMacOSXEmbedHandler->getOffsetProc = getOffsetProc; + tkMacOSXEmbedHandler->getOffsetProc = getOffsetProc; } - /* *---------------------------------------------------------------------- * * TkpMakeWindow -- * - * Creates an X Window (Mac subwindow). + * Creates an X Window (Mac subwindow). * * Results: - * The window id is returned. + * The window id is returned. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -138,57 +132,55 @@ TkpMakeWindow( * the window structure should have already been * created in the TkpUseWindow function. */ - + if (Tk_IsEmbedded(winPtr)) { - return (Window) winPtr->privatePtr; + return (Window) winPtr->privatePtr; } - + /* * Allocate sub window */ - + macWin = (MacDrawable *) ckalloc(sizeof(MacDrawable)); if (macWin == NULL) { - winPtr->privatePtr = NULL; - return None; + winPtr->privatePtr = NULL; + return None; } macWin->winPtr = winPtr; winPtr->privatePtr = macWin; macWin->clipRgn = NewRgn(); macWin->aboveClipRgn = NewRgn(); + macWin->drawRgn = NewRgn(); macWin->referenceCount = 0; macWin->flags = TK_CLIP_INVALID; + macWin->grafPtr = NULL; + macWin->context = NULL; if (Tk_IsTopLevel(macWin->winPtr)) { - - /* - *This will be set when we are mapped. - */ - - macWin->grafPtr = NULL; - macWin->toplevel = macWin; - macWin->xOff = 0; - macWin->yOff = 0; + /* + *This will be set when we are mapped. + */ + macWin->xOff = 0; + macWin->yOff = 0; + macWin->toplevel = macWin; } else { - macWin->grafPtr = NULL; - macWin->xOff = winPtr->parentPtr->privatePtr->xOff + - winPtr->parentPtr->changes.border_width + - winPtr->changes.x; - macWin->yOff = winPtr->parentPtr->privatePtr->yOff + - winPtr->parentPtr->changes.border_width + - winPtr->changes.y; - macWin->toplevel = winPtr->parentPtr->privatePtr->toplevel; + macWin->xOff = winPtr->parentPtr->privatePtr->xOff + + winPtr->parentPtr->changes.border_width + + winPtr->changes.x; + macWin->yOff = winPtr->parentPtr->privatePtr->yOff + + winPtr->parentPtr->changes.border_width + + winPtr->changes.y; + macWin->toplevel = winPtr->parentPtr->privatePtr->toplevel; } - macWin->toplevel->referenceCount++; - - /* + + /* * TODO: need general solution for visibility events. */ event.xany.serial = Tk_Display(winPtr)->request; event.xany.send_event = False; event.xany.display = Tk_Display(winPtr); - + event.xvisibility.type = VisibilityNotify; event.xvisibility.window = (Window) macWin; event.xvisibility.state = VisibilityUnobscured; @@ -202,31 +194,31 @@ TkpMakeWindow( * * TkpUseWindow -- * - * This procedure causes a Tk window to use a given X window as - * its parent window, rather than the root window for the screen. - * It is invoked by an embedded application to specify the window - * in which it is embedded. + * This procedure causes a Tk window to use a given X window as + * its parent window, rather than the root window for the screen. + * It is invoked by an embedded application to specify the window + * in which it is embedded. * * Results: - * The return value is normally TCL_OK. If an error occurs (such - * as string not being a valid window spec), then the return value - * is TCL_ERROR and an error message is left in the interp's result if - * interp is non-NULL. + * The return value is normally TCL_OK. If an error occurs (such + * as string not being a valid window spec), then the return value + * is TCL_ERROR and an error message is left in the interp's result if + * interp is non-NULL. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ int TkpUseWindow( - Tcl_Interp *interp, /* If not NULL, used for error reporting - * if string is bogus. */ - Tk_Window tkwin, /* Tk window that does not yet have an - * associated X window. */ - CONST char *string) /* String identifying an X window to use - * for tkwin; must be an integer value. */ + Tcl_Interp *interp, /* If not NULL, used for error reporting + * if string is bogus. */ + Tk_Window tkwin, /* Tk window that does not yet have an + * associated X window. */ + CONST char *string) /* String identifying an X window to use + * for tkwin; must be an integer value. */ { TkWindow *winPtr = (TkWindow *) tkwin; TkWindow *usePtr; @@ -235,12 +227,13 @@ TkpUseWindow( XEvent event; if (winPtr->window != None) { - Tcl_AppendResult(interp, "can't modify container after widget is created", (char *) NULL); + Tcl_AppendResult(interp, "can't modify container after widget is " + "created", NULL); return TCL_ERROR; } - + /* - * Decode the container pointer, and look for it among the + * Decode the container pointer, and look for it among the *list of available containers. * * N.B. For now, we are limiting the containers to be in the same Tk @@ -248,9 +241,9 @@ TkpUseWindow( * of containers. * */ - + if (Tcl_GetInt(interp, string, (int*) &parent) != TCL_OK) { - return TCL_ERROR; + return TCL_ERROR; } usePtr = (TkWindow *) Tk_IdToWindow(winPtr->display, (Window) parent); @@ -261,158 +254,159 @@ TkpUseWindow( return TCL_ERROR; } } - - /* + + /* * The code below can probably be simplified given we have already * discovered 'usePtr' above. */ /* * Save information about the container and the embedded window - * in a Container structure. Currently, there must already be an existing - * Container structure, since we only allow the case where both container + * in a Container structure. Currently, there must already be an existing + * Container structure, since we only allow the case where both container * and embedded app. are in the same process. */ for (containerPtr = firstContainerPtr; containerPtr != NULL; - containerPtr = containerPtr->nextPtr) { - if (containerPtr->parent == (Window) parent) { - winPtr->flags |= TK_BOTH_HALVES; - containerPtr->parentPtr->flags |= TK_BOTH_HALVES; - break; - } + containerPtr = containerPtr->nextPtr) { + if (containerPtr->parent == (Window) parent) { + winPtr->flags |= TK_BOTH_HALVES; + containerPtr->parentPtr->flags |= TK_BOTH_HALVES; + break; + } } - + /* - * Make the embedded window. + * Make the embedded window. */ macWin = (MacDrawable *) ckalloc(sizeof(MacDrawable)); if (macWin == NULL) { - winPtr->privatePtr = NULL; - return TCL_ERROR; + winPtr->privatePtr = NULL; + return TCL_ERROR; } - + macWin->winPtr = winPtr; winPtr->privatePtr = macWin; /* * The grafPtr will be NULL for a Tk in Tk embedded window. * It is none of our business what it is for a Tk not in Tk embedded window, - * but we will initialize it to NULL, and let the registerWinProc - * set it. In any case, you must always use TkMacOSXGetDrawablePort - * to get the portPtr. It will correctly find the container's port. + * but we will initialize it to NULL, and let the registerWinProc + * set it. In any case, you must always use TkMacOSXGetDrawablePort + * to get the portPtr. It will correctly find the container's port. */ macWin->grafPtr = NULL; + macWin->context = NULL; macWin->clipRgn = NewRgn(); macWin->aboveClipRgn = NewRgn(); + macWin->drawRgn = NewRgn(); macWin->referenceCount = 0; macWin->flags = TK_CLIP_INVALID; macWin->toplevel = macWin; macWin->toplevel->referenceCount++; - + winPtr->flags |= TK_EMBEDDED; - - + + /* * Make a copy of the TK_EMBEDDED flag, since sometimes * we need this to get the port after the TkWindow structure * has been freed. */ - + macWin->flags |= TK_EMBEDDED; - + /* - * Now check whether it is embedded in another Tk widget. If not (the first + * Now check whether it is embedded in another Tk widget. If not (the first * case below) we see if there is an in-process embedding handler registered, * and if so, let that fill in the rest of the macWin. */ - + if (containerPtr == NULL) { - /* - * If someone has registered an in process embedding handler, then - * see if it can handle this window... - */ - - if (tkMacOSXEmbedHandler == NULL || - tkMacOSXEmbedHandler->registerWinProc((int) parent, - (Tk_Window) winPtr) != TCL_OK) { - Tcl_AppendResult(interp, "The window ID ", string, - " does not correspond to a valid Tk Window.", - (char *) NULL); - return TCL_ERROR; - } else { - containerPtr = (Container *) ckalloc(sizeof(Container)); - - containerPtr->parentPtr = NULL; - containerPtr->embedded = (Window) macWin; - containerPtr->embeddedPtr = macWin->winPtr; - containerPtr->nextPtr = firstContainerPtr; - firstContainerPtr = containerPtr; - - } + /* + * If someone has registered an in process embedding handler, then + * see if it can handle this window... + */ + + if (tkMacOSXEmbedHandler == NULL || + tkMacOSXEmbedHandler->registerWinProc((int) parent, + (Tk_Window) winPtr) != TCL_OK) { + Tcl_AppendResult(interp, "The window ID ", string, + " does not correspond to a valid Tk Window.", NULL); + return TCL_ERROR; + } else { + containerPtr = (Container *) ckalloc(sizeof(Container)); + + containerPtr->parentPtr = NULL; + containerPtr->embedded = (Window) macWin; + containerPtr->embeddedPtr = macWin->winPtr; + containerPtr->nextPtr = firstContainerPtr; + firstContainerPtr = containerPtr; + + } } else { - - /* - * The window is embedded in another Tk window. - */ - - macWin->xOff = parent->winPtr->privatePtr->xOff + - parent->winPtr->changes.border_width + - winPtr->changes.x; - macWin->yOff = parent->winPtr->privatePtr->yOff + - parent->winPtr->changes.border_width + - winPtr->changes.y; - - - /* - * Finish filling up the container structure with the embedded window's - * information. - */ - - containerPtr->embedded = (Window) macWin; - containerPtr->embeddedPtr = macWin->winPtr; - - /* - * Create an event handler to clean up the Container structure when - * tkwin is eventually deleted. - */ - - Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc, - (ClientData) winPtr); + + /* + * The window is embedded in another Tk window. + */ + + macWin->xOff = parent->winPtr->privatePtr->xOff + + parent->winPtr->changes.border_width + + winPtr->changes.x; + macWin->yOff = parent->winPtr->privatePtr->yOff + + parent->winPtr->changes.border_width + + winPtr->changes.y; + + + /* + * Finish filling up the container structure with the embedded window's + * information. + */ + + containerPtr->embedded = (Window) macWin; + containerPtr->embeddedPtr = macWin->winPtr; + + /* + * Create an event handler to clean up the Container structure when + * tkwin is eventually deleted. + */ + + Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc, + (ClientData) winPtr); } - /* + /* * TODO: need general solution for visibility events. */ - + event.xany.serial = Tk_Display(winPtr)->request; event.xany.send_event = False; event.xany.display = Tk_Display(winPtr); - + event.xvisibility.type = VisibilityNotify; event.xvisibility.window = (Window) macWin;; event.xvisibility.state = VisibilityUnobscured; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - - /* + + /* * TODO: need general solution for visibility events. */ - + event.xany.serial = Tk_Display(winPtr)->request; event.xany.send_event = False; event.xany.display = Tk_Display(winPtr); - + event.xvisibility.type = VisibilityNotify; event.xvisibility.window = (Window) macWin;; event.xvisibility.state = VisibilityUnobscured; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - + return TCL_OK; } @@ -421,24 +415,24 @@ TkpUseWindow( * * TkpMakeContainer -- * - * This procedure is called to indicate that a particular window - * will be a container for an embedded application. This changes - * certain aspects of the window's behavior, such as whether it - * will receive events anymore. + * This procedure is called to indicate that a particular window + * will be a container for an embedded application. This changes + * certain aspects of the window's behavior, such as whether it + * will receive events anymore. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ void TkpMakeContainer( - Tk_Window tkwin) /* Token for a window that is about to - * become a container. */ + Tk_Window tkwin) /* Token for a window that is about to + * become a container. */ { TkWindow *winPtr = (TkWindow *) tkwin; Container *containerPtr; @@ -458,25 +452,25 @@ TkpMakeContainer( containerPtr->nextPtr = firstContainerPtr; firstContainerPtr = containerPtr; winPtr->flags |= TK_CONTAINER; - + /* * Request SubstructureNotify events so that we can find out when * the embedded application creates its window or attempts to - * resize it. Also watch Configure events on the container so that - * we can resize the child to match. Also, pass activate events from + * resize it. Also watch Configure events on the container so that + * we can resize the child to match. Also, pass activate events from * the container down to the embedded toplevel. */ Tk_CreateEventHandler(tkwin, - SubstructureNotifyMask|SubstructureRedirectMask, - ContainerEventProc, (ClientData) winPtr); + SubstructureNotifyMask|SubstructureRedirectMask, + ContainerEventProc, (ClientData) winPtr); Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbedStructureProc, - (ClientData) containerPtr); + (ClientData) containerPtr); Tk_CreateEventHandler(tkwin, ActivateMask, EmbedActivateProc, - (ClientData) containerPtr); + (ClientData) containerPtr); Tk_CreateEventHandler(tkwin, FocusChangeMask, EmbedFocusProc, - (ClientData) containerPtr); - + (ClientData) containerPtr); + } /* @@ -484,30 +478,30 @@ TkpMakeContainer( * * TkMacOSXContainerId -- * - * Given an embedded window, this procedure returns the MacDrawable - * identifier for the associated container window. + * Given an embedded window, this procedure returns the MacDrawable + * identifier for the associated container window. * * Results: - * The return value is the MacDrawable for winPtr's - * container window. + * The return value is the MacDrawable for winPtr's + * container window. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ MacDrawable * TkMacOSXContainerId(winPtr) - TkWindow *winPtr; /* Tk's structure for an embedded window. */ + TkWindow *winPtr; /* Tk's structure for an embedded window. */ { Container *containerPtr; for (containerPtr = firstContainerPtr; containerPtr != NULL; - containerPtr = containerPtr->nextPtr) { - if (containerPtr->embeddedPtr == winPtr) { - return (MacDrawable *) containerPtr->parent; - } + containerPtr = containerPtr->nextPtr) { + if (containerPtr->embeddedPtr == winPtr) { + return (MacDrawable *) containerPtr->parent; + } } Tcl_Panic("TkMacOSXContainerId couldn't find window"); return None; @@ -518,39 +512,39 @@ TkMacOSXContainerId(winPtr) * * TkMacOSXGetHostToplevel -- * - * Given the TkWindow, return the MacDrawable for the outermost - * toplevel containing it. This will be a real Macintosh window. + * Given the TkWindow, return the MacDrawable for the outermost + * toplevel containing it. This will be a real Macintosh window. * * Results: - * Returns a MacDrawable corresponding to a Macintosh Toplevel + * Returns a MacDrawable corresponding to a Macintosh Toplevel * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ MacDrawable * TkMacOSXGetHostToplevel( - TkWindow *winPtr) /* Tk's structure for a window. */ + TkWindow *winPtr) /* Tk's structure for a window. */ { TkWindow *contWinPtr, *topWinPtr; topWinPtr = winPtr->privatePtr->toplevel->winPtr; if (!Tk_IsEmbedded(topWinPtr)) { - return winPtr->privatePtr->toplevel; + return winPtr->privatePtr->toplevel; } else { - contWinPtr = TkpGetOtherWindow(topWinPtr); - - /* - * NOTE: Here we should handle out of process embedding. - */ - - if (contWinPtr != NULL) { - return TkMacOSXGetHostToplevel(contWinPtr); - } else { - return None; - } + contWinPtr = TkpGetOtherWindow(topWinPtr); + + /* + * NOTE: Here we should handle out of process embedding. + */ + + if (contWinPtr != NULL) { + return TkMacOSXGetHostToplevel(contWinPtr); + } else { + return None; + } } } @@ -559,41 +553,41 @@ TkMacOSXGetHostToplevel( * * TkpClaimFocus -- * - * This procedure is invoked when someone asks for the input focus - * to be put on a window in an embedded application, but the - * application doesn't currently have the focus. It requests the - * input focus from the container application. + * This procedure is invoked when someone asks for the input focus + * to be put on a window in an embedded application, but the + * application doesn't currently have the focus. It requests the + * input focus from the container application. * * Results: - * None. + * None. * * Side effects: - * The input focus may change. + * The input focus may change. * *---------------------------------------------------------------------- */ void TkpClaimFocus( - TkWindow *topLevelPtr, /* Top-level window containing desired - * focus window; should be embedded. */ - int force) /* One means that the container should - * claim the focus if it doesn't - * currently have it. */ + TkWindow *topLevelPtr, /* Top-level window containing desired + * focus window; should be embedded. */ + int force) /* One means that the container should + * claim the focus if it doesn't + * currently have it. */ { XEvent event; Container *containerPtr; if (!(topLevelPtr->flags & TK_EMBEDDED)) { - return; + return; } for (containerPtr = firstContainerPtr; - containerPtr->embeddedPtr != topLevelPtr; - containerPtr = containerPtr->nextPtr) { - /* Empty loop body. */ + containerPtr->embeddedPtr != topLevelPtr; + containerPtr = containerPtr->nextPtr) { + /* Empty loop body. */ } - + event.xfocus.type = FocusIn; event.xfocus.serial = LastKnownRequestProcessed(topLevelPtr->display); @@ -610,25 +604,25 @@ TkpClaimFocus( * * TkpTestembedCmd -- * - * This procedure implements the "testembed" command. It returns - * some or all of the information in the list pointed to by - * firstContainerPtr. + * This procedure implements the "testembed" command. It returns + * some or all of the information in the list pointed to by + * firstContainerPtr. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ int TkpTestembedCmd( - ClientData clientData, /* Main window for application. */ - Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - CONST char **argv) /* Argument strings. */ + ClientData clientData, /* Main window for application. */ + Tcl_Interp *interp, /* Current interpreter. */ + int argc, /* Number of arguments. */ + CONST char **argv) /* Argument strings. */ { int all; Container *containerPtr; @@ -636,47 +630,47 @@ TkpTestembedCmd( char buffer[50]; if ((argc > 1) && (strcmp(argv[1], "all") == 0)) { - all = 1; + all = 1; } else { - all = 0; + all = 0; } Tcl_DStringInit(&dString); for (containerPtr = firstContainerPtr; containerPtr != NULL; - containerPtr = containerPtr->nextPtr) { - Tcl_DStringStartSublist(&dString); - if (containerPtr->parent == None) { - Tcl_DStringAppendElement(&dString, ""); - } else { - if (all) { - sprintf(buffer, "0x%x", (int) containerPtr->parent); - Tcl_DStringAppendElement(&dString, buffer); - } else { - Tcl_DStringAppendElement(&dString, "XXX"); - } - } - if (containerPtr->parentPtr == NULL) { - Tcl_DStringAppendElement(&dString, ""); - } else { - Tcl_DStringAppendElement(&dString, - containerPtr->parentPtr->pathName); - } - if (containerPtr->embedded == None) { - Tcl_DStringAppendElement(&dString, ""); - } else { - if (all) { - sprintf(buffer, "0x%x", (int) containerPtr->embedded); - Tcl_DStringAppendElement(&dString, buffer); - } else { - Tcl_DStringAppendElement(&dString, "XXX"); - } - } - if (containerPtr->embeddedPtr == NULL) { - Tcl_DStringAppendElement(&dString, ""); - } else { - Tcl_DStringAppendElement(&dString, - containerPtr->embeddedPtr->pathName); - } - Tcl_DStringEndSublist(&dString); + containerPtr = containerPtr->nextPtr) { + Tcl_DStringStartSublist(&dString); + if (containerPtr->parent == None) { + Tcl_DStringAppendElement(&dString, ""); + } else { + if (all) { + sprintf(buffer, "0x%x", (int) containerPtr->parent); + Tcl_DStringAppendElement(&dString, buffer); + } else { + Tcl_DStringAppendElement(&dString, "XXX"); + } + } + if (containerPtr->parentPtr == NULL) { + Tcl_DStringAppendElement(&dString, ""); + } else { + Tcl_DStringAppendElement(&dString, + containerPtr->parentPtr->pathName); + } + if (containerPtr->embedded == None) { + Tcl_DStringAppendElement(&dString, ""); + } else { + if (all) { + sprintf(buffer, "0x%x", (int) containerPtr->embedded); + Tcl_DStringAppendElement(&dString, buffer); + } else { + Tcl_DStringAppendElement(&dString, "XXX"); + } + } + if (containerPtr->embeddedPtr == NULL) { + Tcl_DStringAppendElement(&dString, ""); + } else { + Tcl_DStringAppendElement(&dString, + containerPtr->embeddedPtr->pathName); + } + Tcl_DStringEndSublist(&dString); } Tcl_DStringResult(interp, &dString); return TCL_OK; @@ -687,29 +681,29 @@ TkpTestembedCmd( * * TkpRedirectKeyEvent -- * - * This procedure is invoked when a key press or release event - * arrives for an application that does not believe it owns the - * input focus. This can happen because of embedding; for example, - * X can send an event to an embedded application when the real - * focus window is in the container application and is an ancestor - * of the container. This procedure's job is to forward the event - * back to the application where it really belongs. + * This procedure is invoked when a key press or release event + * arrives for an application that does not believe it owns the + * input focus. This can happen because of embedding; for example, + * X can send an event to an embedded application when the real + * focus window is in the container application and is an ancestor + * of the container. This procedure's job is to forward the event + * back to the application where it really belongs. * * Results: - * None. + * None. * * Side effects: - * The event may get sent to a different application. + * The event may get sent to a different application. * *---------------------------------------------------------------------- */ void TkpRedirectKeyEvent( - TkWindow *winPtr, /* Window to which the event was originally - * reported. */ - XEvent *eventPtr) /* X event to redirect (should be KeyPress - * or KeyRelease). */ + TkWindow *winPtr, /* Window to which the event was originally + * reported. */ + XEvent *eventPtr) /* X event to redirect (should be KeyPress + * or KeyRelease). */ { } @@ -718,24 +712,24 @@ TkpRedirectKeyEvent( * * TkpGetOtherWindow -- * - * If both the container and embedded window are in the same - * process, this procedure will return either one, given the other. + * If both the container and embedded window are in the same + * process, this procedure will return either one, given the other. * * Results: - * If winPtr is a container, the return value is the token for the - * embedded window, and vice versa. If the "other" window isn't in - * this process, NULL is returned. + * If winPtr is a container, the return value is the token for the + * embedded window, and vice versa. If the "other" window isn't in + * this process, NULL is returned. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ TkWindow * TkpGetOtherWindow( - TkWindow *winPtr) /* Tk's structure for a container or - * embedded window. */ + TkWindow *winPtr) /* Tk's structure for a container or + * embedded window. */ { Container *containerPtr; @@ -745,47 +739,48 @@ TkpGetOtherWindow( */ if (!(winPtr->flags & TK_BOTH_HALVES)) { - return NULL; + return NULL; } - + for (containerPtr = firstContainerPtr; containerPtr != NULL; - containerPtr = containerPtr->nextPtr) { - if (containerPtr->embeddedPtr == winPtr) { - return containerPtr->parentPtr; - } else if (containerPtr->parentPtr == winPtr) { - return containerPtr->embeddedPtr; - } + containerPtr = containerPtr->nextPtr) { + if (containerPtr->embeddedPtr == winPtr) { + return containerPtr->parentPtr; + } else if (containerPtr->parentPtr == winPtr) { + return containerPtr->embeddedPtr; + } } return NULL; } + /* *---------------------------------------------------------------------- * * EmbeddedEventProc -- * - * This procedure is invoked by the Tk event dispatcher when various - * useful events are received for a window that is embedded in - * another application. + * This procedure is invoked by the Tk event dispatcher when various + * useful events are received for a window that is embedded in + * another application. * * Results: - * None. + * None. * * Side effects: - * Our internal state gets cleaned up when an embedded window is - * destroyed. + * Our internal state gets cleaned up when an embedded window is + * destroyed. * *---------------------------------------------------------------------- */ static void EmbeddedEventProc(clientData, eventPtr) - ClientData clientData; /* Token for container window. */ - XEvent *eventPtr; /* ResizeRequest event. */ + ClientData clientData; /* Token for container window. */ + XEvent *eventPtr; /* ResizeRequest event. */ { TkWindow *winPtr = (TkWindow *) clientData; if (eventPtr->type == DestroyNotify) { - EmbedWindowDeleted(winPtr); + EmbedWindowDeleted(winPtr); } } @@ -794,28 +789,28 @@ EmbeddedEventProc(clientData, eventPtr) * * ContainerEventProc -- * - * This procedure is invoked by the Tk event dispatcher when various - * useful events are received for the children of a container - * window. It forwards relevant information, such as geometry - * requests, from the events into the container's application. + * This procedure is invoked by the Tk event dispatcher when various + * useful events are received for the children of a container + * window. It forwards relevant information, such as geometry + * requests, from the events into the container's application. * - * NOTE: on the Mac, only the DestroyNotify branch is ever taken. - * We don't synthesize the other events. + * NOTE: on the Mac, only the DestroyNotify branch is ever taken. + * We don't synthesize the other events. * * Results: - * None. + * None. * * Side effects: - * Depends on the event. For example, when ConfigureRequest events - * occur, geometry information gets set for the container window. + * Depends on the event. For example, when ConfigureRequest events + * occur, geometry information gets set for the container window. * *---------------------------------------------------------------------- */ static void ContainerEventProc(clientData, eventPtr) - ClientData clientData; /* Token for container window. */ - XEvent *eventPtr; /* ResizeRequest event. */ + ClientData clientData; /* Token for container window. */ + XEvent *eventPtr; /* ResizeRequest event. */ { TkWindow *winPtr = (TkWindow *) clientData; Container *containerPtr; @@ -828,67 +823,67 @@ ContainerEventProc(clientData, eventPtr) */ errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1, - -1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL); + -1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL); /* * Find the Container structure associated with the parent window. */ for (containerPtr = firstContainerPtr; - containerPtr->parent != eventPtr->xmaprequest.parent; - containerPtr = containerPtr->nextPtr) { - if (containerPtr == NULL) { - Tcl_Panic("ContainerEventProc couldn't find Container record"); - } + containerPtr->parent != eventPtr->xmaprequest.parent; + containerPtr = containerPtr->nextPtr) { + if (containerPtr == NULL) { + Tcl_Panic("ContainerEventProc couldn't find Container record"); + } } if (eventPtr->type == CreateNotify) { - /* - * A new child window has been created in the container. Record - * its id in the Container structure (if more than one child is - * created, just remember the last one and ignore the earlier - * ones). - */ - - containerPtr->embedded = eventPtr->xcreatewindow.window; + /* + * A new child window has been created in the container. Record + * its id in the Container structure (if more than one child is + * created, just remember the last one and ignore the earlier + * ones). + */ + + containerPtr->embedded = eventPtr->xcreatewindow.window; } else if (eventPtr->type == ConfigureRequest) { - if ((eventPtr->xconfigurerequest.x != 0) - || (eventPtr->xconfigurerequest.y != 0)) { - /* - * The embedded application is trying to move itself, which - * isn't legal. At this point, the window hasn't actually - * moved, but we need to send it a ConfigureNotify event to - * let it know that its request has been denied. If the - * embedded application was also trying to resize itself, a - * ConfigureNotify will be sent by the geometry management - * code below, so we don't need to do anything. Otherwise, - * generate a synthetic event. - */ - - if ((eventPtr->xconfigurerequest.width == winPtr->changes.width) - && (eventPtr->xconfigurerequest.height - == winPtr->changes.height)) { - EmbedSendConfigure(containerPtr); - } - } - EmbedGeometryRequest(containerPtr, - eventPtr->xconfigurerequest.width, - eventPtr->xconfigurerequest.height); + if ((eventPtr->xconfigurerequest.x != 0) + || (eventPtr->xconfigurerequest.y != 0)) { + /* + * The embedded application is trying to move itself, which + * isn't legal. At this point, the window hasn't actually + * moved, but we need to send it a ConfigureNotify event to + * let it know that its request has been denied. If the + * embedded application was also trying to resize itself, a + * ConfigureNotify will be sent by the geometry management + * code below, so we don't need to do anything. Otherwise, + * generate a synthetic event. + */ + + if ((eventPtr->xconfigurerequest.width == winPtr->changes.width) + && (eventPtr->xconfigurerequest.height + == winPtr->changes.height)) { + EmbedSendConfigure(containerPtr); + } + } + EmbedGeometryRequest(containerPtr, + eventPtr->xconfigurerequest.width, + eventPtr->xconfigurerequest.height); } else if (eventPtr->type == MapRequest) { - /* - * The embedded application's map request was ignored and simply - * passed on to us, so we have to map the window for it to appear - * on the screen. - */ - - XMapWindow(eventPtr->xmaprequest.display, - eventPtr->xmaprequest.window); + /* + * The embedded application's map request was ignored and simply + * passed on to us, so we have to map the window for it to appear + * on the screen. + */ + + XMapWindow(eventPtr->xmaprequest.display, + eventPtr->xmaprequest.window); } else if (eventPtr->type == DestroyNotify) { - /* - * The embedded application is gone. Destroy the container window. - */ + /* + * The embedded application is gone. Destroy the container window. + */ - Tk_DestroyWindow((Tk_Window) winPtr); + Tk_DestroyWindow((Tk_Window) winPtr); } Tk_DeleteErrorHandler(errHandler); } @@ -898,47 +893,47 @@ ContainerEventProc(clientData, eventPtr) * * EmbedStructureProc -- * - * This procedure is invoked by the Tk event dispatcher when - * a container window owned by this application gets resized - * (and also at several other times that we don't care about). - * This procedure reflects the size change in the embedded - * window that corresponds to the container. + * This procedure is invoked by the Tk event dispatcher when + * a container window owned by this application gets resized + * (and also at several other times that we don't care about). + * This procedure reflects the size change in the embedded + * window that corresponds to the container. * * Results: - * None. + * None. * * Side effects: - * The embedded window gets resized to match the container. + * The embedded window gets resized to match the container. * *---------------------------------------------------------------------- */ static void EmbedStructureProc(clientData, eventPtr) - ClientData clientData; /* Token for container window. */ - XEvent *eventPtr; /* ResizeRequest event. */ + ClientData clientData; /* Token for container window. */ + XEvent *eventPtr; /* ResizeRequest event. */ { Container *containerPtr = (Container *) clientData; Tk_ErrorHandler errHandler; if (eventPtr->type == ConfigureNotify) { - if (containerPtr->embedded != None) { - /* - * Ignore errors, since the embedded application could have - * deleted its window. - */ - - errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1, - -1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL); - Tk_MoveResizeWindow((Tk_Window) containerPtr->embeddedPtr, 0, 0, - (unsigned int) Tk_Width( - (Tk_Window) containerPtr->parentPtr), - (unsigned int) Tk_Height( - (Tk_Window) containerPtr->parentPtr)); - Tk_DeleteErrorHandler(errHandler); - } + if (containerPtr->embedded != None) { + /* + * Ignore errors, since the embedded application could have + * deleted its window. + */ + + errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1, + -1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL); + Tk_MoveResizeWindow((Tk_Window) containerPtr->embeddedPtr, 0, 0, + (unsigned int) Tk_Width( + (Tk_Window) containerPtr->parentPtr), + (unsigned int) Tk_Height( + (Tk_Window) containerPtr->parentPtr)); + Tk_DeleteErrorHandler(errHandler); + } } else if (eventPtr->type == DestroyNotify) { - EmbedWindowDeleted(containerPtr->parentPtr); + EmbedWindowDeleted(containerPtr->parentPtr); } } @@ -947,33 +942,33 @@ EmbedStructureProc(clientData, eventPtr) * * EmbedActivateProc -- * - * This procedure is invoked by the Tk event dispatcher when - * Activate and Deactivate events occur for a container window owned - * by this application. It is responsible for forwarding an activate - * event down into the embedded toplevel. + * This procedure is invoked by the Tk event dispatcher when + * Activate and Deactivate events occur for a container window owned + * by this application. It is responsible for forwarding an activate + * event down into the embedded toplevel. * * Results: - * None. + * None. * * Side effects: - * The X focus may change. + * The X focus may change. * *---------------------------------------------------------------------- */ static void EmbedActivateProc(clientData, eventPtr) - ClientData clientData; /* Token for container window. */ - XEvent *eventPtr; /* ResizeRequest event. */ + ClientData clientData; /* Token for container window. */ + XEvent *eventPtr; /* ResizeRequest event. */ { Container *containerPtr = (Container *) clientData; - + if (containerPtr->embeddedPtr != NULL) { - if (eventPtr->type == ActivateNotify) { - TkGenerateActivateEvents(containerPtr->embeddedPtr,1); - } else if (eventPtr->type == DeactivateNotify) { - TkGenerateActivateEvents(containerPtr->embeddedPtr,0); - } + if (eventPtr->type == ActivateNotify) { + TkGenerateActivateEvents(containerPtr->embeddedPtr,1); + } else if (eventPtr->type == DeactivateNotify) { + TkGenerateActivateEvents(containerPtr->embeddedPtr,0); + } } } @@ -982,25 +977,25 @@ EmbedActivateProc(clientData, eventPtr) * * EmbedFocusProc -- * - * This procedure is invoked by the Tk event dispatcher when - * FocusIn and FocusOut events occur for a container window owned - * by this application. It is responsible for moving the focus - * back and forth between a container application and an embedded - * application. + * This procedure is invoked by the Tk event dispatcher when + * FocusIn and FocusOut events occur for a container window owned + * by this application. It is responsible for moving the focus + * back and forth between a container application and an embedded + * application. * * Results: - * None. + * None. * * Side effects: - * The X focus may change. + * The X focus may change. * *---------------------------------------------------------------------- */ static void EmbedFocusProc(clientData, eventPtr) - ClientData clientData; /* Token for container window. */ - XEvent *eventPtr; /* ResizeRequest event. */ + ClientData clientData; /* Token for container window. */ + XEvent *eventPtr; /* ResizeRequest event. */ { Container *containerPtr = (Container *) clientData; Display *display; @@ -1008,34 +1003,34 @@ EmbedFocusProc(clientData, eventPtr) if (containerPtr->embeddedPtr != NULL) { display = Tk_Display(containerPtr->parentPtr); - event.xfocus.serial = LastKnownRequestProcessed(display); - event.xfocus.send_event = false; - event.xfocus.display = display; - event.xfocus.mode = NotifyNormal; - event.xfocus.window = containerPtr->embedded; - + event.xfocus.serial = LastKnownRequestProcessed(display); + event.xfocus.send_event = false; + event.xfocus.display = display; + event.xfocus.mode = NotifyNormal; + event.xfocus.window = containerPtr->embedded; + if (eventPtr->type == FocusIn) { - /* - * The focus just arrived at the container. Change the X focus - * to move it to the embedded application, if there is one. - * Ignore X errors that occur during this operation (it's - * possible that the new focus window isn't mapped). - */ - - event.xfocus.detail = NotifyNonlinear; - event.xfocus.type = FocusIn; - - } else if (eventPtr->type == FocusOut) { - /* When the container gets a FocusOut event, it has to tell the embedded app - * that it has lost the focus. - */ - - event.xfocus.type = FocusOut; - event.xfocus.detail = NotifyNonlinear; - } - - Tk_QueueWindowEvent(&event, TCL_QUEUE_MARK); - } + /* + * The focus just arrived at the container. Change the X focus + * to move it to the embedded application, if there is one. + * Ignore X errors that occur during this operation (it's + * possible that the new focus window isn't mapped). + */ + + event.xfocus.detail = NotifyNonlinear; + event.xfocus.type = FocusIn; + + } else if (eventPtr->type == FocusOut) { + /* When the container gets a FocusOut event, it has to tell the embedded app + * that it has lost the focus. + */ + + event.xfocus.type = FocusOut; + event.xfocus.detail = NotifyNonlinear; + } + + Tk_QueueWindowEvent(&event, TCL_QUEUE_MARK); + } } /* @@ -1043,36 +1038,36 @@ EmbedFocusProc(clientData, eventPtr) * * EmbedGeometryRequest -- * - * This procedure is invoked when an embedded application requests - * a particular size. It processes the request (which may or may - * not actually honor the request) and reflects the results back - * to the embedded application. + * This procedure is invoked when an embedded application requests + * a particular size. It processes the request (which may or may + * not actually honor the request) and reflects the results back + * to the embedded application. * - * NOTE: On the Mac, this is a stub, since we don't synthesize - * ConfigureRequest events. + * NOTE: On the Mac, this is a stub, since we don't synthesize + * ConfigureRequest events. * * Results: - * None. + * None. * * Side effects: - * If we deny the child's size change request, a Configure event - * is synthesized to let the child know how big it ought to be. - * Events get processed while we're waiting for the geometry - * managers to do their thing. + * If we deny the child's size change request, a Configure event + * is synthesized to let the child know how big it ought to be. + * Events get processed while we're waiting for the geometry + * managers to do their thing. * *---------------------------------------------------------------------- */ static void EmbedGeometryRequest(containerPtr, width, height) - Container *containerPtr; /* Information about the embedding. */ - int width, height; /* Size that the child has requested. */ + Container *containerPtr; /* Information about the embedding. */ + int width, height; /* Size that the child has requested. */ { TkWindow *winPtr = containerPtr->parentPtr; /* * Forward the requested size into our geometry management hierarchy - * via the container window. We need to send a Configure event back + * via the container window. We need to send a Configure event back * to the embedded application if we decide not to honor its * request; to make this happen, process all idle event handlers * synchronously here (so that the geometry managers have had a @@ -1082,11 +1077,11 @@ EmbedGeometryRequest(containerPtr, width, height) Tk_GeometryRequest((Tk_Window) winPtr, width, height); while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) { - /* Empty loop body. */ + /* Empty loop body. */ } if ((winPtr->changes.width != width) - || (winPtr->changes.height != height)) { - EmbedSendConfigure(containerPtr); + || (winPtr->changes.height != height)) { + EmbedSendConfigure(containerPtr); } } @@ -1095,26 +1090,26 @@ EmbedGeometryRequest(containerPtr, width, height) * * EmbedSendConfigure -- * - * This is currently a stub. It is called to notify an - * embedded application of its current size and location. This - * procedure is called when the embedded application made a - * geometry request that we did not grant, so that the embedded - * application knows that its geometry didn't change after all. - * It is a response to ConfigureRequest events, which we do not - * currently synthesize on the Mac + * This is currently a stub. It is called to notify an + * embedded application of its current size and location. This + * procedure is called when the embedded application made a + * geometry request that we did not grant, so that the embedded + * application knows that its geometry didn't change after all. + * It is a response to ConfigureRequest events, which we do not + * currently synthesize on the Mac * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ static void EmbedSendConfigure(containerPtr) - Container *containerPtr; /* Information about the embedding. */ + Container *containerPtr; /* Information about the embedding. */ { } @@ -1123,28 +1118,28 @@ EmbedSendConfigure(containerPtr) * * EmbedWindowDeleted -- * - * This procedure is invoked when a window involved in embedding - * (as either the container or the embedded application) is - * destroyed. It cleans up the Container structure for the window. + * This procedure is invoked when a window involved in embedding + * (as either the container or the embedded application) is + * destroyed. It cleans up the Container structure for the window. * * Results: - * None. + * None. * * Side effects: - * A Container structure may be freed. + * A Container structure may be freed. * *---------------------------------------------------------------------- */ static void EmbedWindowDeleted(winPtr) - TkWindow *winPtr; /* Tk's information about window that - * was deleted. */ + TkWindow *winPtr; /* Tk's information about window that + * was deleted. */ { Container *containerPtr, *prevPtr; /* - * Find the Container structure for this window. Delete the + * Find the Container structure for this window. Delete the * information about the embedded application and free the container's * record. */ @@ -1152,49 +1147,48 @@ EmbedWindowDeleted(winPtr) prevPtr = NULL; containerPtr = firstContainerPtr; while (1) { - if (containerPtr->embeddedPtr == winPtr) { - - /* - * We also have to destroy our parent, to clean up the container. - * Fabricate an event to do this. - */ - - if (containerPtr->parentPtr != NULL && - containerPtr->parentPtr->flags & TK_BOTH_HALVES) { - XEvent event; - - event.xany.serial = - Tk_Display(containerPtr->parentPtr)->request; - event.xany.send_event = False; - event.xany.display = Tk_Display(containerPtr->parentPtr); - - event.xany.type = DestroyNotify; - event.xany.window = containerPtr->parent; - event.xdestroywindow.event = containerPtr->parent; - Tk_QueueWindowEvent(&event, TCL_QUEUE_HEAD); - - } - - containerPtr->embedded = None; - containerPtr->embeddedPtr = NULL; - - break; - } - if (containerPtr->parentPtr == winPtr) { - containerPtr->parentPtr = NULL; - break; - } - prevPtr = containerPtr; - containerPtr = containerPtr->nextPtr; + if (containerPtr->embeddedPtr == winPtr) { + + /* + * We also have to destroy our parent, to clean up the container. + * Fabricate an event to do this. + */ + + if (containerPtr->parentPtr != NULL && + containerPtr->parentPtr->flags & TK_BOTH_HALVES) { + XEvent event; + + event.xany.serial = + Tk_Display(containerPtr->parentPtr)->request; + event.xany.send_event = False; + event.xany.display = Tk_Display(containerPtr->parentPtr); + + event.xany.type = DestroyNotify; + event.xany.window = containerPtr->parent; + event.xdestroywindow.event = containerPtr->parent; + Tk_QueueWindowEvent(&event, TCL_QUEUE_HEAD); + + } + + containerPtr->embedded = None; + containerPtr->embeddedPtr = NULL; + + break; + } + if (containerPtr->parentPtr == winPtr) { + containerPtr->parentPtr = NULL; + break; + } + prevPtr = containerPtr; + containerPtr = containerPtr->nextPtr; } if ((containerPtr->embeddedPtr == NULL) - && (containerPtr->parentPtr == NULL)) { - if (prevPtr == NULL) { - firstContainerPtr = containerPtr->nextPtr; - } else { - prevPtr->nextPtr = containerPtr->nextPtr; - } - ckfree((char *) containerPtr); + && (containerPtr->parentPtr == NULL)) { + if (prevPtr == NULL) { + firstContainerPtr = containerPtr->nextPtr; + } else { + prevPtr->nextPtr = containerPtr->nextPtr; + } + ckfree((char *) containerPtr); } } - diff --git a/macosx/tkMacOSXEntry.c b/macosx/tkMacOSXEntry.c index bc9a181..f12f624 100644 --- a/macosx/tkMacOSXEntry.c +++ b/macosx/tkMacOSXEntry.c @@ -1,56 +1,59 @@ /* * tkMacOSXEntry.c -- * - * This file implements functions that decode & handle keyboard events - * on MacOS X. + * This file implements the native aqua entry widget. * - * Copyright 2001, Apple Computer, Inc. + * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * - * The following terms apply to all files originating from Apple - * Computer, Inc. ("Apple") and associated with the software - * unless explicitly disclaimed in individual files. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * + * The following terms apply to all files originating from Apple + * Computer, Inc. ("Apple") and associated with the software + * unless explicitly disclaimed in individual files. * - * Apple hereby grants permission to use, copy, modify, - * distribute, and license this software and its documentation - * for any purpose, provided that existing copyright notices are - * retained in all copies and that this notice is included - * verbatim in any distributions. No written agreement, license, - * or royalty fee is required for any of the authorized - * uses. Modifications to this software may be copyrighted by - * their authors and need not follow the licensing terms - * described here, provided that the new terms are clearly - * indicated on the first page of each file where they apply. * + * Apple hereby grants permission to use, copy, modify, + * distribute, and license this software and its documentation + * for any purpose, provided that existing copyright notices are + * retained in all copies and that this notice is included + * verbatim in any distributions. No written agreement, license, + * or royalty fee is required for any of the authorized + * uses. Modifications to this software may be copyrighted by + * their authors and need not follow the licensing terms + * described here, provided that the new terms are clearly + * indicated on the first page of each file where they apply. * - * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE - * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, - * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF - * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, - * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND - * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS - * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE - * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * - * GOVERNMENT USE: If you are acquiring this software on behalf - * of the U.S. government, the Government shall have only - * "Restricted Rights" in the software and related documentation - * as defined in the Federal Acquisition Regulations (FARs) in - * Clause 52.227.19 (c) (2). If you are acquiring the software - * on behalf of the Department of Defense, the software shall be - * classified as "Commercial Computer Software" and the - * Government shall have only "Restricted Rights" as defined in - * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the - * foregoing, the authors grant the U.S. Government and others - * acting in its behalf permission to use and distribute the - * software in accordance with the terms specified in this - * license. + * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE + * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, + * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF + * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, + * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND + * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS + * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE + * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * - * RCS: @(#) $Id: tkMacOSXEntry.c,v 1.7 2006/09/10 17:06:32 das Exp $ + * GOVERNMENT USE: If you are acquiring this software on behalf + * of the U.S. government, the Government shall have only + * "Restricted Rights" in the software and related documentation + * as defined in the Federal Acquisition Regulations (FARs) in + * Clause 52.227.19 (c) (2). If you are acquiring the software + * on behalf of the Department of Defense, the software shall be + * classified as "Commercial Computer Software" and the + * Government shall have only "Restricted Rights" as defined in + * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the + * foregoing, the authors grant the U.S. Government and others + * acting in its behalf permission to use and distribute the + * software in accordance with the terms specified in this + * license. + * + * RCS: @(#) $Id: tkMacOSXEntry.c,v 1.8 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" @@ -65,8 +68,8 @@ static ThemeButtonKind ComputeIncDecParameters (int height, int *width); * ComputeIncDecParameters -- * * This procedure figures out which of the kThemeIncDec - * buttons to use. It also sets width to the width of the - * IncDec button. + * buttons to use. It also sets width to the width of the + * IncDec button. * * Results: * The ThemeButtonKind of the button we should use. @@ -79,45 +82,37 @@ static ThemeButtonKind ComputeIncDecParameters (int height, int *width); static ThemeButtonKind ComputeIncDecParameters (int height, int *width) { - static int version = 0; - - if (version == 0) { - Gestalt(gestaltSystemVersion, (long *) &version); - } - - /* - * The small and mini incDec buttons were introduced in 10.3. - */ - #ifndef kThemeIncDecButtonSmall - #define kThemeIncDecButtonSmall 21 - #endif - #ifndef kThemeIncDecButtonMini - #define kThemeIncDecButtonMini 22 - #endif - - if (version >= 0x1030) { - if (height < 11 || height > 28) { - *width = 0; - return (ThemeButtonKind) 0; - } - - if (height >= 21) { - *width = 13; - return kThemeIncDecButton; - } else if (height >= 18) { - *width = 12; - return kThemeIncDecButtonSmall; - } else { - *width = 11; - return kThemeIncDecButtonMini; - } - } else { - if (height < 21 || height > 28) { - *width = 0; - return (ThemeButtonKind) 0; - } - *width = 13; - return kThemeIncDecButton; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + if (1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1030 + && &kHIToolboxVersionNumber != NULL + && kHIToolboxVersionNumber >= kHIToolboxVersionNumber10_3 +#endif + ) { + if (height < 11 || height > 28) { + *width = 0; + return (ThemeButtonKind) 0; + } + + if (height >= 21) { + *width = 13; + return kThemeIncDecButton; + } else if (height >= 18) { + *width = 12; + return kThemeIncDecButtonSmall; + } else { + *width = 11; + return kThemeIncDecButtonMini; + } + } else +#endif + { + if (height < 21 || height > 28) { + *width = 0; + return (ThemeButtonKind) 0; + } + *width = 13; + return kThemeIncDecButton; } } @@ -127,11 +122,11 @@ ComputeIncDecParameters (int height, int *width) * TkpDrawEntryBorderAndFocus -- * * This procedure redraws the border of an entry window. - * It overrides the generic border drawing code if the - * entry widget parameters are such that the native widget - * drawing is a good fit. - * This version just returns 1, so platforms that don't - * do special native drawing don't have to implement it. + * It overrides the generic border drawing code if the + * entry widget parameters are such that the native widget + * drawing is a good fit. + * This version just returns 1, so platforms that don't + * do special native drawing don't have to implement it. * * Results: * 1 if it has drawn the border, 0 if not. @@ -145,44 +140,41 @@ int TkpDrawEntryBorderAndFocus(Entry *entryPtr, Drawable d, int isSpinbox) { Rect bounds; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; GC bgGC; Tk_Window tkwin = entryPtr->tkwin; ThemeDrawState drawState; int oldWidth = 0; + MacDrawable *macDraw = (MacDrawable *) d; - /* - * I use 6 as the borderwidth. 2 of the 5 go into the actual frame the + /* + * I use 6 as the borderwidth. 2 of the 5 go into the actual frame the * 3 are because the Mac OS Entry widgets leave more space around the * Text than Tk does on X11. */ - - if (entryPtr->borderWidth != MAC_OSX_ENTRY_BORDER - || entryPtr->highlightWidth != MAC_OSX_FOCUS_WIDTH - || entryPtr->relief != MAC_OSX_ENTRY_RELIEF) { - return 0; + + if (entryPtr->borderWidth != MAC_OSX_ENTRY_BORDER + || entryPtr->highlightWidth != MAC_OSX_FOCUS_WIDTH + || entryPtr->relief != MAC_OSX_ENTRY_RELIEF) { + return 0; } - - destPort = TkMacOSXGetDrawablePort(d); /* * For the spinbox, we have to make the entry part smaller by the size - * of the buttons. We also leave 2 pixels to the left (as per the HIG) + * of the buttons. We also leave 2 pixels to the left (as per the HIG) * and space for one pixel to the right, 'cause it makes the buttons look - * nicer. + * nicer. */ - + if (isSpinbox) { - ThemeButtonKind buttonKind; - int incDecWidth; - - oldWidth = Tk_Width(tkwin); - - buttonKind = ComputeIncDecParameters(Tk_Height(tkwin) - - 2 * MAC_OSX_FOCUS_WIDTH, &incDecWidth); - Tk_Width(tkwin) -= incDecWidth + 1; + ThemeButtonKind buttonKind; + int incDecWidth; + + oldWidth = Tk_Width(tkwin); + + buttonKind = ComputeIncDecParameters(Tk_Height(tkwin) + - 2 * MAC_OSX_FOCUS_WIDTH, &incDecWidth); + Tk_Width(tkwin) -= incDecWidth + 1; } /* @@ -190,42 +182,39 @@ TkpDrawEntryBorderAndFocus(Entry *entryPtr, Drawable d, int isSpinbox) * part of the ring, so we have to draw over the edges of the * ring before drawing the focus or the text will peep through. */ - + bgGC = Tk_GCForColor(entryPtr->highlightBgColorPtr, d); TkDrawInsetFocusHighlight(entryPtr->tkwin, bgGC, MAC_OSX_FOCUS_WIDTH, d, 0); - - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - + /* - * Inset the entry Frame by the maximum width of the focus rect, + * Inset the entry Frame by the maximum width of the focus rect, * which is 3 according to the Carbon docs. */ - - bounds.top = MAC_OSX_FOCUS_WIDTH; - bounds.left = MAC_OSX_FOCUS_WIDTH; - bounds.right = Tk_Width(tkwin) - MAC_OSX_FOCUS_WIDTH; - bounds.bottom = Tk_Height(tkwin) - MAC_OSX_FOCUS_WIDTH; + + bounds.left = macDraw->xOff + MAC_OSX_FOCUS_WIDTH; + bounds.top = macDraw->yOff + MAC_OSX_FOCUS_WIDTH; + bounds.right = macDraw->xOff + Tk_Width(tkwin) - MAC_OSX_FOCUS_WIDTH; + bounds.bottom = macDraw->yOff + Tk_Height(tkwin) - MAC_OSX_FOCUS_WIDTH; if (entryPtr->state == STATE_DISABLED) { - drawState = kThemeStateInactive; + drawState = kThemeStateInactive; } else { - drawState = kThemeStateActive; + drawState = kThemeStateActive; } + TkMacOSXSetupDrawingContext(d, NULL, 0, &dc); DrawThemeEditTextFrame(&bounds, drawState); if (entryPtr->flags & GOT_FOCUS) { - /* - * Don't call this if we don't have the focus, because then it - * erases the focus rect to white, but we've already drawn the - * highlightbackground above. - */ + /* + * Don't call this if we don't have the focus, because then it + * erases the focus rect to white, but we've already drawn the + * highlightbackground above. + */ - DrawThemeFocusRect(&bounds, (entryPtr->flags & GOT_FOCUS) != 0); + DrawThemeFocusRect(&bounds, (entryPtr->flags & GOT_FOCUS) != 0); } - SetGWorld(saveWorld, saveDevice); - if (isSpinbox) { - Tk_Width(tkwin) = oldWidth; + Tk_Width(tkwin) = oldWidth; } + TkMacOSXRestoreDrawingContext(&dc); return 1; } /* @@ -234,11 +223,11 @@ TkpDrawEntryBorderAndFocus(Entry *entryPtr, Drawable d, int isSpinbox) * TkpDrawSpinboxButtons -- * * This procedure redraws the buttons of an spinbox widget. - * It overrides the generic button drawing code if the - * spinbox widget parameters are such that the native widget - * drawing is a good fit. - * This version just returns 0, so platforms that don't - * do special native drawing don't have to implement it. + * It overrides the generic button drawing code if the + * spinbox widget parameters are such that the native widget + * drawing is a good fit. + * This version just returns 0, so platforms that don't + * do special native drawing don't have to implement it. * * Results: * 1 if it has drawn the border, 0 if not. @@ -252,7 +241,6 @@ TkpDrawEntryBorderAndFocus(Entry *entryPtr, Drawable d, int isSpinbox) int TkpDrawSpinboxButtons(Spinbox *sbPtr, Drawable d) { - OSStatus err; Rect inBounds; ThemeButtonKind inKind; ThemeButtonDrawInfo inNewInfo; @@ -264,71 +252,65 @@ TkpDrawSpinboxButtons(Spinbox *sbPtr, Drawable d) int height = Tk_Height(tkwin); int buttonHeight = height - 2 * MAC_OSX_FOCUS_WIDTH; int incDecWidth; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; XRectangle rects[1]; GC bgGC; + MacDrawable *macDraw = (MacDrawable *) d; /* FIXME RAISED really makes more sense */ if (sbPtr->buRelief != TK_RELIEF_FLAT) { - return 0; + return 0; } - - /* + + /* * The actual sizes of the IncDec button are 21 for the normal, - * 18 for the small and 15 for the mini. But the spinbox still + * 18 for the small and 15 for the mini. But the spinbox still * looks okay if the entry is a little bigger than this, so we * give it a little slop. */ - + inKind = ComputeIncDecParameters(buttonHeight, &incDecWidth); if (inKind == (ThemeButtonKind) 0) { - return 0; + return 0; } - - destPort = TkMacOSXGetDrawablePort(d); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); if (sbPtr->entry.state == STATE_DISABLED) { - inNewInfo.state = kThemeStateInactive; - inNewInfo.value = kThemeButtonOff; + inNewInfo.state = kThemeStateInactive; + inNewInfo.value = kThemeButtonOff; } else if (sbPtr->selElement == SEL_BUTTONUP) { - inNewInfo.state = kThemeStatePressedUp; - inNewInfo.value = kThemeButtonOn; + inNewInfo.state = kThemeStatePressedUp; + inNewInfo.value = kThemeButtonOn; } else if (sbPtr->selElement == SEL_BUTTONDOWN) { - inNewInfo.state = kThemeStatePressedDown; - inNewInfo.value = kThemeButtonOn; + inNewInfo.state = kThemeStatePressedDown; + inNewInfo.value = kThemeButtonOn; } else { - inNewInfo.state = kThemeStateActive; - inNewInfo.value = kThemeButtonOff; + inNewInfo.state = kThemeStateActive; + inNewInfo.value = kThemeButtonOff; } - + inNewInfo.adornment = kThemeAdornmentNone; - inBounds.left = Tk_Width(tkwin) - incDecWidth - 1; - inBounds.right = Tk_Width(tkwin) - 1; - inBounds.top = MAC_OSX_FOCUS_WIDTH; - inBounds.bottom = Tk_Height(tkwin) - MAC_OSX_FOCUS_WIDTH; - + inBounds.left = macDraw->xOff + Tk_Width(tkwin) - incDecWidth - 1; + inBounds.right = macDraw->xOff + Tk_Width(tkwin) - 1; + inBounds.top = macDraw->yOff + MAC_OSX_FOCUS_WIDTH; + inBounds.bottom = macDraw->yOff + Tk_Height(tkwin) - MAC_OSX_FOCUS_WIDTH; + /* We had to make the entry part of the window smaller so that we - * wouldn't overdraw the spin buttons with the focus highlight. SO + * wouldn't overdraw the spin buttons with the focus highlight. So * now we have to draw the highlightbackground. */ - + bgGC = Tk_GCForColor(sbPtr->entry.highlightBgColorPtr, d); rects[0].x = inBounds.left; rects[0].y = 0; rects[0].width = Tk_Width(tkwin); rects[0].height = Tk_Height(tkwin); XFillRectangles(Tk_Display(tkwin), d, bgGC, rects, 1); - - err = DrawThemeButton (&inBounds, inKind, &inNewInfo, inPrevInfo, - inEraseProc, inLabelProc, inUserData); - - SetGWorld(saveWorld, saveDevice); + TkMacOSXSetupDrawingContext(d, NULL, 0, &dc); + ChkErr(DrawThemeButton, &inBounds, inKind, &inNewInfo, inPrevInfo, + inEraseProc, inLabelProc, inUserData); + TkMacOSXRestoreDrawingContext(&dc); return 1; } diff --git a/macosx/tkMacOSXEvent.c b/macosx/tkMacOSXEvent.c index b94606e..82aea7a 100644 --- a/macosx/tkMacOSXEvent.c +++ b/macosx/tkMacOSXEvent.c @@ -1,109 +1,110 @@ -/* +/* * tkMacOSXEvent.c -- * - * This file contains the basic Mac OS X Event handling routines. + * This file contains the basic Mac OS X Event handling routines. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. - * Copyright (c) 2005-2006 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.14 2007/04/21 19:06:38 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXEvent.c,v 1.15 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" #include "tkMacOSXEvent.h" #include "tkMacOSXDebug.h" + /* *---------------------------------------------------------------------- * * TkMacOSXFlushWindows -- * - * This routine flushes all the Carbon windows of the application. It - * is called by the setup procedure for the Tcl/Carbon event source. + * This routine flushes all the Carbon windows of the application. It + * is called by the setup procedure for the Tcl/Carbon event source. * * Results: - * None. + * None. * * Side effects: - * Flushes all Carbon windows + * Flushes all Carbon windows * *---------------------------------------------------------------------- */ MODULE_SCOPE void -TkMacOSXFlushWindows () +TkMacOSXFlushWindows (void) { WindowRef wRef = GetWindowList(); - + while (wRef) { - CGrafPtr portPtr = GetWindowPort(wRef); - if (QDIsPortBuffered(portPtr)) { - QDFlushPortBuffer(portPtr, NULL); - } - wRef = GetNextWindow(wRef); + CGrafPtr portPtr = GetWindowPort(wRef); + if (QDIsPortBuffered(portPtr)) { + QDFlushPortBuffer(portPtr, NULL); + } + wRef = GetNextWindow(wRef); } } -/* +/* *---------------------------------------------------------------------- - * + * * TkMacOSXProcessEvent -- - * - * This dispatches a filtered Carbon event to the appropriate handler * - * Note on MacEventStatus.stopProcessing: Please be conservative in the - * individual handlers and don't assume the event is fully handled - * unless you *really* need to ensure that other handlers don't see the - * event anymore. Some OS manager or library might be interested in - * events even after they are already handled on the Tk level. + * This dispatches a filtered Carbon event to the appropriate handler * - * Results: - * 0 on success - * -1 on failure + * Note on MacEventStatus.stopProcessing: Please be conservative in the + * individual handlers and don't assume the event is fully handled + * unless you *really* need to ensure that other handlers don't see the + * event anymore. Some OS manager or library might be interested in + * events even after they are already handled on the Tk level. + * + * Results: + * 0 on success + * -1 on failure * * Side effects: - * Converts a Carbon event to a Tk event - * + * Converts a Carbon event to a Tk event + * *---------------------------------------------------------------------- */ -MODULE_SCOPE int -TkMacOSXProcessEvent(TkMacOSXEvent * eventPtr, MacEventStatus * statusPtr) +MODULE_SCOPE int +TkMacOSXProcessEvent( + TkMacOSXEvent *eventPtr, + MacEventStatus *statusPtr) { switch (eventPtr->eClass) { - case kEventClassMouse: - TkMacOSXProcessMouseEvent(eventPtr, statusPtr); - break; - case kEventClassWindow: - TkMacOSXProcessWindowEvent(eventPtr, statusPtr); - break; - case kEventClassKeyboard: - TkMacOSXProcessKeyboardEvent(eventPtr, statusPtr); - break; - case kEventClassApplication: - TkMacOSXProcessApplicationEvent(eventPtr, statusPtr); - break; - case kEventClassMenu: - TkMacOSXProcessMenuEvent(eventPtr, statusPtr); - break; - case kEventClassCommand: - TkMacOSXProcessCommandEvent(eventPtr, statusPtr); - break; - default: -#ifdef TK_MAC_DEBUG - { - char buf [256]; - fprintf(stderr, - "Unrecognised event : %s\n", - TkMacOSXCarbonEventToAscii(eventPtr->eventRef, buf)); - } -#endif - break; - } + case kEventClassMouse: + TkMacOSXProcessMouseEvent(eventPtr, statusPtr); + break; + case kEventClassWindow: + TkMacOSXProcessWindowEvent(eventPtr, statusPtr); + break; + case kEventClassKeyboard: + TkMacOSXProcessKeyboardEvent(eventPtr, statusPtr); + break; + case kEventClassApplication: + TkMacOSXProcessApplicationEvent(eventPtr, statusPtr); + break; + case kEventClassAppearance: + TkMacOSXProcessAppearanceEvent(eventPtr, statusPtr); + break; + case kEventClassMenu: + TkMacOSXProcessMenuEvent(eventPtr, statusPtr); + break; + case kEventClassCommand: + TkMacOSXProcessCommandEvent(eventPtr, statusPtr); + break; + default: { + TkMacOSXDbgMsg("Unrecognised event: %s", + TkMacOSXCarbonEventToAscii(eventPtr->eventRef)); + break; + } + } return 0; } @@ -112,51 +113,81 @@ TkMacOSXProcessEvent(TkMacOSXEvent * eventPtr, MacEventStatus * statusPtr) * * TkMacOSXProcessMenuEvent -- * - * This routine processes the event in eventPtr, and - * generates the appropriate Tk events from it. + * This routine processes the event in eventPtr, and + * generates the appropriate Tk events from it. * * Results: - * True if event(s) are generated - false otherwise. + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. + * Additional events may be place on the Tk event queue. * *---------------------------------------------------------------------- */ MODULE_SCOPE int -TkMacOSXProcessMenuEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) +TkMacOSXProcessMenuEvent( + TkMacOSXEvent *eventPtr, + MacEventStatus *statusPtr) { - int menuContext; - OSStatus status; + int menuContext; + OSStatus err; switch (eventPtr->eKind) { case kEventMenuBeginTracking: case kEventMenuEndTracking: + case kEventMenuOpening: + case kEventMenuTargetItem: break; default: return 0; break; } - status = GetEventParameter(eventPtr->eventRef, - kEventParamMenuContext, - typeUInt32, NULL, - sizeof(menuContext), NULL, - &menuContext); - if (status == noErr && (menuContext & kMenuContextMenuBar)) { - static int oldMode = TCL_SERVICE_ALL; - if (eventPtr->eKind == kEventMenuBeginTracking) { - oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - TkMacOSXClearMenubarActive(); - - /* - * Handle -postcommand - */ - - TkMacOSXPreprocessMenu(); - } else { - Tcl_SetServiceMode(oldMode); - } + err = ChkErr(GetEventParameter, eventPtr->eventRef, kEventParamMenuContext, + typeUInt32, NULL, sizeof(menuContext), NULL, &menuContext); + if (err == noErr && ((menuContext & kMenuContextMenuBarTracking) || + (menuContext & kMenuContextPopUpTracking))) { + switch (eventPtr->eKind) { + MenuRef menu; + + case kEventMenuBeginTracking: + TkMacOSXClearMenubarActive(); + + /* + * Handle -postcommand + */ + + TkMacOSXPreprocessMenu(); + TkMacOSXTrackingLoop(1); + break; + case kEventMenuEndTracking: + TkMacOSXTrackingLoop(0); + break; + case kEventMenuOpening: + err = ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamDirectObject, typeMenuRef, NULL, + sizeof(menu), NULL, &menu); + if (err == noErr) { + TkMacOSXClearActiveMenu(menu); + return TkMacOSXGenerateParentMenuSelectEvent(menu); + } + break; + case kEventMenuTargetItem: + err = ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamDirectObject, typeMenuRef, NULL, + sizeof(menu), NULL, &menu); + if (err == noErr) { + MenuItemIndex index; + + err = ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamMenuItemIndex, typeMenuItemIndex, NULL, + sizeof(index), NULL, &index); + if (err == noErr) { + return TkMacOSXGenerateMenuSelectEvent(menu, index); + } + } + break; + } } return 0; } @@ -166,24 +197,26 @@ TkMacOSXProcessMenuEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) * * TkMacOSXProcessCommandEvent -- * - * This routine processes the event in eventPtr, and - * generates the appropriate Tk events from it. + * This routine processes the event in eventPtr, and + * generates the appropriate Tk events from it. * * Results: - * True if event(s) are generated - false otherwise. + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. + * Additional events may be place on the Tk event queue. * *---------------------------------------------------------------------- */ MODULE_SCOPE int -TkMacOSXProcessCommandEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) +TkMacOSXProcessCommandEvent( + TkMacOSXEvent *eventPtr, + MacEventStatus * statusPtr) { - HICommand command; - int menuContext; - OSStatus status; + HICommand command; + int menuContext; + OSStatus err; switch (eventPtr->eKind) { case kEventCommandProcess: @@ -193,19 +226,15 @@ TkMacOSXProcessCommandEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) return 0; break; } - status = GetEventParameter(eventPtr->eventRef, - kEventParamDirectObject, - typeHICommand, NULL, - sizeof(command), NULL, - &command); - if (status == noErr && (command.attributes & kHICommandFromMenu)) { + err = ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamDirectObject, typeHICommand, NULL, sizeof(command), + NULL, &command); + if (err == noErr && (command.attributes & kHICommandFromMenu)) { if (eventPtr->eKind == kEventCommandProcess) { - status = GetEventParameter(eventPtr->eventRef, - kEventParamMenuContext, - typeUInt32, NULL, - sizeof(menuContext), NULL, - &menuContext); - if (status == noErr && (menuContext & kMenuContextMenuBar) && + err = ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamMenuContext, typeUInt32, NULL, + sizeof(menuContext), NULL, &menuContext); + if (err == noErr && (menuContext & kMenuContextMenuBar) && (menuContext & kMenuContextMenuBarTracking)) { TkMacOSXHandleMenuSelect(GetMenuID(command.menu.menuRef), command.menu.menuItemIndex, @@ -215,15 +244,15 @@ TkMacOSXProcessCommandEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) } else { Tcl_CmdInfo dummy; if (command.commandID == kHICommandPreferences && eventPtr->interp) { - if (Tcl_GetCommandInfo(eventPtr->interp, + if (Tcl_GetCommandInfo(eventPtr->interp, "::tk::mac::ShowPreferences", &dummy)) { - if (!IsMenuItemEnabled(command.menu.menuRef, + if (!IsMenuItemEnabled(command.menu.menuRef, command.menu.menuItemIndex)) { EnableMenuItem(command.menu.menuRef, command.menu.menuItemIndex); } } else { - if (IsMenuItemEnabled(command.menu.menuRef, + if (IsMenuItemEnabled(command.menu.menuRef, command.menu.menuItemIndex)) { DisableMenuItem(command.menu.menuRef, command.menu.menuItemIndex); @@ -236,56 +265,3 @@ TkMacOSXProcessCommandEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) } return 0; } - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXReceiveAndProcessEvent -- - * - * This receives a carbon event and converts it to a Tk event - * - * Results: - * 0 on success - * Mac OS error number on failure - * - * Side effects: - * This receives the next Carbon event and converts it to the - * appropriate Tk event - * - *---------------------------------------------------------------------- - */ - -MODULE_SCOPE OSStatus -TkMacOSXReceiveAndProcessEvent() -{ - static EventTargetRef targetRef = NULL; - EventRef eventRef; - OSStatus err; - - /* - * This is a poll, since we have already counted the events coming - * into this routine, and are guaranteed to have one waiting. - */ - - err = ReceiveNextEvent(0, NULL, kEventDurationNoWait, true, &eventRef); - if (err == noErr) { - if (!targetRef) { - targetRef = GetEventDispatcherTarget(); - } - TkMacOSXStartTclEventLoopCarbonTimer(); - err = SendEventToEventTarget(eventRef,targetRef); - TkMacOSXStopTclEventLoopCarbonTimer(); -#ifdef TK_MAC_DEBUG - if (err != noErr && err != eventLoopTimedOutErr - && err != eventNotHandledErr - ) { - char buf [256]; - fprintf(stderr, - "RCNE SendEventToEventTarget (%s) failed, %d\n", - TkMacOSXCarbonEventToAscii(eventRef, buf), (int)err); - } -#endif - ReleaseEvent(eventRef); - } - return err; -} diff --git a/macosx/tkMacOSXEvent.h b/macosx/tkMacOSXEvent.h index 9c5f583..7fcb503 100644 --- a/macosx/tkMacOSXEvent.h +++ b/macosx/tkMacOSXEvent.h @@ -2,55 +2,59 @@ * tkMacOSXEvent.h -- * * Declarations of Macintosh specific functions for implementing the - * Mac OS X Notifier. + * Mac OS X Notifier. * - * Copyright 2001, Apple Computer, Inc. + * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * - * The following terms apply to all files originating from Apple - * Computer, Inc. ("Apple") and associated with the software - * unless explicitly disclaimed in individual files. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * + * The following terms apply to all files originating from Apple + * Computer, Inc. ("Apple") and associated with the software + * unless explicitly disclaimed in individual files. * - * Apple hereby grants permission to use, copy, modify, - * distribute, and license this software and its documentation - * for any purpose, provided that existing copyright notices are - * retained in all copies and that this notice is included - * verbatim in any distributions. No written agreement, license, - * or royalty fee is required for any of the authorized - * uses. Modifications to this software may be copyrighted by - * their authors and need not follow the licensing terms - * described here, provided that the new terms are clearly - * indicated on the first page of each file where they apply. * + * Apple hereby grants permission to use, copy, modify, + * distribute, and license this software and its documentation + * for any purpose, provided that existing copyright notices are + * retained in all copies and that this notice is included + * verbatim in any distributions. No written agreement, license, + * or royalty fee is required for any of the authorized + * uses. Modifications to this software may be copyrighted by + * their authors and need not follow the licensing terms + * described here, provided that the new terms are clearly + * indicated on the first page of each file where they apply. * - * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE - * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, - * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF - * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, - * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND - * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS - * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE - * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * - * GOVERNMENT USE: If you are acquiring this software on behalf - * of the U.S. government, the Government shall have only - * "Restricted Rights" in the software and related documentation - * as defined in the Federal Acquisition Regulations (FARs) in - * Clause 52.227.19 (c) (2). If you are acquiring the software - * on behalf of the Department of Defense, the software shall be - * classified as "Commercial Computer Software" and the - * Government shall have only "Restricted Rights" as defined in - * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the - * foregoing, the authors grant the U.S. Government and others - * acting in its behalf permission to use and distribute the - * software in accordance with the terms specified in this - * license. + * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE + * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, + * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF + * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, + * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND + * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS + * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE + * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * - * RCS: @(#) $Id: tkMacOSXEvent.h,v 1.11 2006/07/20 06:25:19 das Exp $ + * GOVERNMENT USE: If you are acquiring this software on behalf + * of the U.S. government, the Government shall have only + * "Restricted Rights" in the software and related documentation + * as defined in the Federal Acquisition Regulations (FARs) in + * Clause 52.227.19 (c) (2). If you are acquiring the software + * on behalf of the Department of Defense, the software shall be + * classified as "Commercial Computer Software" and the + * Government shall have only "Restricted Rights" as defined in + * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the + * foregoing, the authors grant the U.S. Government and others + * acting in its behalf permission to use and distribute the + * software in accordance with the terms specified in this + * license. + * + * RCS: @(#) $Id: tkMacOSXEvent.h,v 1.12 2007/04/23 21:24:33 das Exp $ */ #ifndef _TKMACEVENT @@ -72,37 +76,32 @@ typedef struct { typedef struct { EventRef eventRef; UInt32 eClass; /* Defines the class of event : see CarbonEvents.h */ - UInt32 eKind; /* Defines the kind of the event : see CarbonEvents.h */ + UInt32 eKind; /* Defines the kind of the event : see CarbonEvents.h */ Tcl_Interp *interp; /* Interp to handle events in */ + EventHandlerCallRef callRef; } TkMacOSXEvent; -MODULE_SCOPE OSStatus TkMacOSXReceiveAndProcessEvent(); -MODULE_SCOPE void TkMacOSXFlushWindows(); -MODULE_SCOPE int TkMacOSXProcessEvent(TkMacOSXEvent *eventPtr, - MacEventStatus *statusPtr); +MODULE_SCOPE void TkMacOSXFlushWindows(void); +MODULE_SCOPE int TkMacOSXProcessEvent(TkMacOSXEvent *eventPtr, + MacEventStatus *statusPtr); MODULE_SCOPE int TkMacOSXProcessMouseEvent(TkMacOSXEvent *e, - MacEventStatus *statusPtr); + MacEventStatus *statusPtr); MODULE_SCOPE int TkMacOSXProcessWindowEvent(TkMacOSXEvent *e, - MacEventStatus *statusPtr); + MacEventStatus *statusPtr); MODULE_SCOPE int TkMacOSXProcessKeyboardEvent(TkMacOSXEvent *e, - MacEventStatus *statusPtr); + MacEventStatus *statusPtr); MODULE_SCOPE int TkMacOSXProcessApplicationEvent(TkMacOSXEvent *e, - MacEventStatus *statusPtr); + MacEventStatus *statusPtr); +MODULE_SCOPE int TkMacOSXProcessAppearanceEvent(TkMacOSXEvent *e, + MacEventStatus *statusPtr); MODULE_SCOPE int TkMacOSXProcessMenuEvent(TkMacOSXEvent *e, - MacEventStatus *statusPtr); + MacEventStatus *statusPtr); MODULE_SCOPE int TkMacOSXProcessCommandEvent(TkMacOSXEvent *e, - MacEventStatus *statusPtr); + MacEventStatus *statusPtr); MODULE_SCOPE int TkMacOSXKeycodeToUnicode( - UniChar * uniChars, int maxChars, - EventKind eKind, - UInt32 keycode, UInt32 modifiers, - UInt32 * deadKeyStatePtr); -MODULE_SCOPE OSStatus TkMacOSXStartTclEventLoopCarbonTimer(); -MODULE_SCOPE OSStatus TkMacOSXStopTclEventLoopCarbonTimer(); - -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 -/* Define constants only available on Mac OS X 10.3 or later */ -#define kEventAppAvailableWindowBoundsChanged 110 -#endif + UniChar * uniChars, int maxChars, + EventKind eKind, + UInt32 keycode, UInt32 modifiers, + UInt32 * deadKeyStatePtr); #endif diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c index 2f81ae5..1a4a399 100644 --- a/macosx/tkMacOSXFont.c +++ b/macosx/tkMacOSXFont.c @@ -1,10 +1,11 @@ /* * tkMacOSXFont.c -- * - * Contains the Macintosh implementation of the platform-independant - * font package interface. This version uses ATSU instead of Quickdraw. + * Contains the Macintosh implementation of the platform-independant + * font package interface. This version uses ATSU instead of Quickdraw. * * Copyright 2002-2004 Benjamin Riefenstahl, Benjamin.Riefenstahl@epost.de + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * Some functions were originally copied verbatim from the QuickDraw version * of tkMacOSXFont.c, which had these copyright notices: @@ -16,7 +17,6 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * * Todos: * * - Get away from Font Manager and Quickdraw functions as much as possible, @@ -26,39 +26,31 @@ * instead of just assuming that they are the same. * * - Get a second font register going for fonts that are not assigned to a - * font family by the OS. On my system I have 27 fonts of that type, + * font family by the OS. On my system I have 27 fonts of that type, * Hebrew, Arabic and Hindi fonts that actually come with the system. * FMGetFontFamilyInstanceFromFont() returns -981 (kFMInvalidFontFamilyErr) * for these and they are not listed when enumerating families, but they - * are when enumerating fonts directly. The problem that the OS sees may - * be that at least some of them do not contain any Latin characters. Note + * are when enumerating fonts directly. The problem that the OS sees may + * be that at least some of them do not contain any Latin characters. Note * that such fonts can not be used for controls, because controls * definitely require a family id (this assertion needs testing). * - * RCS: @(#) $Id: tkMacOSXFont.c,v 1.23 2007/04/21 19:06:38 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXFont.c,v 1.24 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" #include "tkMacOSXFont.h" /* -#ifdef TK_MAC_DEBUG +#ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_FONTS #endif */ -/* Define macros only available on Mac OS X 10.3 or later */ -#ifndef FixedToInt -#define FixedToInt(a) ((short)(((Fixed)(a) + fixed1/2) >> 16)) -#endif -#ifndef IntToFixed -#define IntToFixed(a) ((Fixed)(a) << 16) -#endif - /* - * Problem: The sum of two parts is not the same as the whole. In particular + * Problem: The sum of two parts is not the same as the whole. In particular * the width of two separately measured strings will usually be larger than - * the width of them pasted together. Tk has a design bug here, because it + * the width of them pasted together. Tk has a design bug here, because it * generally assumes that this kind of arithmetic works. * To workaround this, #define TK_MAC_COALESCE_LINE to 1 below, we then avoid * lines that tremble and shiver while the cursor passes through them by @@ -68,17 +60,45 @@ */ #define TK_MAC_COALESCE_LINE 0 -typedef TkMacOSXFont MacFont; -typedef TkMacOSXFontDrawingContext DrawingContext; +/* + * The following structure represents our Macintosh-specific implementation + * of a font object. + */ + +typedef struct { + TkFont font; /* Stuff used by generic font package. Must + * be first in structure. */ + + /* + * The ATSU view of the font and other text properties. Used for drawing + * and measuring. + */ + + ATSUFontID atsuFontId; /* == FMFont. */ + ATSUTextLayout atsuLayout; /* ATSU layout object, representing the whole + * text that ATSU sees with some option + * bits. */ + ATSUStyle atsuStyle; /* ATSU style object, representing a run of + * text with the same properties. */ + + /* + * The QuickDraw view of the font. Used to configure controls. + */ + + FMFontFamily qdFont; /* == FMFontFamilyId, Carbon replacement for + * QD face numbers. */ + short qdSize; /* Font size in points. */ + short qdStyle; /* QuickDraw style bits. */ +} MacFont; /* - * Information about font families, initialized at startup time. Font + * Information about font families, initialized at startup time. Font * families are described by a mapping from UTF-8 names to MacOS font family - * IDs. The whole list is kept as the sorted array "familyList", allocated + * IDs. The whole list is kept as the sorted array "familyList", allocated * with ckrealloc(). * * Note: This would have been easier, if we could just have used Tcl hash - * arrays. Unfortunately there seems to be no pre-packaged + * arrays. Unfortunately there seems to be no pre-packaged * non-case-sensitive version of that available. */ @@ -89,137 +109,121 @@ typedef struct { static MacFontFamily * familyList = NULL; static int - familyListNextFree = 0, /* The next free slot in familyList. */ - familyListMaxValid = 0, /* The top of the sorted area. */ - familyListSize = 0; /* The size of the whole array. */ + familyListNextFree = 0, /* The next free slot in familyList. */ + familyListMaxValid = 0, /* The top of the sorted area. */ + familyListSize = 0; /* The size of the whole array. */ /* * A simple one-shot sub-allocator for fast and efficient allocation of - * strings. Used by the familyList array for the names. These strings are - * only allocated once at startup and never freed. If you ever need to + * strings. Used by the familyList array for the names. These strings are + * only allocated once at startup and never freed. If you ever need to * re-initialize this, you can just ckfree() all the StringBlocks in the list * and start over. */ -#define STRING_BLOCK_MAX (1024-8) /* Make sizeof(StringBlock) == - * 1024. */ +#define STRING_BLOCK_MAX (1024-8) /* Make sizeof(StringBlock) == + * 1024. */ typedef struct StringBlock { - struct StringBlock * next; /* Starting from "stringMemory" these - * blocks form a linked list. */ - int nextFree; /* Top of the used area in the - * "strings" member. */ - char strings[STRING_BLOCK_MAX]; /* The actual memory managed here. */ + struct StringBlock *next; /* Starting from "stringMemory" these + * blocks form a linked list. */ + int nextFree; /* Top of the used area in the + * "strings" member. */ + char strings[STRING_BLOCK_MAX]; /* The actual memory managed here. */ } StringBlock; -static StringBlock * stringMemory = NULL; - +static StringBlock *stringMemory = NULL; #if TK_MAC_COALESCE_LINE -static Tcl_DString currentLine; /* The current line as seen so far. This - * contains a Tcl_UniChar DString. */ +static Tcl_DString currentLine; /* The current line as seen so far. This + * contains a Tcl_UniChar DString. */ static int - currentY = -1, /* The Y position (row in pixels) of the - * current line. */ - currentLeft = -1, /* The left edge (pixels) of the current - * line. */ - currentRight = -1; /* The right edge (pixels) of the current - * line. */ -static const MacFont * currentFontPtr = NULL; - /* The font of the current line. */ + currentY = -1, /* The Y position (row in pixels) of the + * current line. */ + currentLeft = -1, /* The left edge (pixels) of the current + * line. */ + currentRight = -1; /* The right edge (pixels) of the current + * line. */ +static const MacFont *currentFontPtr = NULL; + /* The font of the current line. */ #endif /* TK_MAC_COALESCE_LINE */ static int antialiasedTextEnabled; /* - * The names for our two "native" fonts. + * The names for our "native" fonts. */ -#define SYSTEMFONT_NAME "system" -#define APPLFONT_NAME "application" +#define SYSTEMFONT_NAME "system" +#define APPLFONT_NAME "application" +#define MENUITEMFONT_NAME "menu" /* * Procedures used only in this file. */ +static void LayoutSetString(const MacFont *fontPtr, + const TkMacOSXDrawingContext *drawingContextPtr, + const UniChar * uchars, int ulen); + /* * The actual workers. */ -static void MacFontDrawText( - const MacFont * fontPtr, - const char * source, int numBytes, - int rangeStart, int rangeLength, - int x, int y); -static int MeasureStringWidth( - const MacFont * fontPtr, - int start, int end); +static int MeasureStringWidth(const MacFont *fontPtr, int start, int end); #if TK_MAC_COALESCE_LINE -static const Tcl_UniChar * UpdateLineBuffer( - const MacFont * fontPtr, - const DrawingContext * drawingContextPtr, - const char * source, int numBytes, - int x, int y, - int * offset); +static const Tcl_UniChar *UpdateLineBuffer(const MacFont *fontPtr, + const TkMacOSXDrawingContext *drawingContextPtr, const char *source, + int numBytes, int x, int y, int * offset); #endif /* TK_MAC_COALESCE_LINE */ /* * Initialization and setup of a font data structure. */ -static void InitFont( - Tk_Window tkwin, - FMFontFamily familyId, const char * familyName, - int size, int qdStyle, MacFont * fontPtr); -static void InitATSUObjects( - FMFontFamily familyId, - short qdsize, short qdStyle, - ATSUFontID * fontIdPtr, - ATSUTextLayout * layoutPtr, ATSUStyle * stylePtr); -static void InitATSUStyle( - ATSUFontID fontId, short ptSize, short qdStyle, - ATSUStyle style); -static void SetFontFeatures( - ATSUFontID fontId, int fixed, - ATSUStyle style); -static void AdjustFontHeight( - MacFont * fontPtr); -static void InitATSULayout( - const DrawingContext * drawingContextPtr, - ATSUTextLayout layout, int fixed); -static void ReleaseFont( - MacFont * fontPtr); +static void InitFont(Tk_Window tkwin, FMFontFamily familyId, + const char *familyName, int size, int qdStyle, MacFont *fontPtr); +static void InitATSUObjects(FMFontFamily familyId, short qdsize, short qdStyle, + ATSUFontID *fontIdPtr, ATSUTextLayout *layoutPtr, ATSUStyle *stylePtr); +static void InitATSUStyle(ATSUFontID fontId, short ptSize, short qdStyle, + ATSUStyle style); +static void SetFontFeatures(ATSUFontID fontId, int fixed, ATSUStyle style); +static void AdjustFontHeight(MacFont *fontPtr); +static void InitATSULayout(const TkMacOSXDrawingContext *drawingContextPtr, + ATSUTextLayout layout, int fixed); +static void ReleaseFont(MacFont *fontPtr); /* * Finding fonts by name. */ -static const MacFontFamily * FindFontFamilyOrAlias( - const char * name); -static const MacFontFamily * FindFontFamilyOrAliasOrFallback( - const char * name); +static const MacFontFamily *FindFontFamilyOrAlias(const char *name); +static const MacFontFamily *FindFontFamilyOrAliasOrFallback(const char *name); /* * Doing interesting things with font families and fonts. */ static void InitFontFamilies(void); -static OSStatus GetFontFamilyName( - FMFontFamily fontFamily, char * name, int numBytes); +static OSStatus GetFontFamilyName(FMFontFamily fontFamily, char *name, + int numBytes); /* * Accessor functions and internal utilities for the font family list. */ -static const MacFontFamily * AddFontFamily( - const char * name, FMFontFamily familyId); -static const MacFontFamily * FindFontFamily(const char * name); -static Tcl_Obj * EnumFontFamilies(void); +static const MacFontFamily *AddFontFamily(const char *name, + FMFontFamily familyId); +static const MacFontFamily *FindFontFamily(const char *name); +static Tcl_Obj *EnumFontFamilies(void); static OSStatus FontFamilyEnumCallback(ATSFontFamilyRef family, void *refCon); static void SortFontFamilies(void); -static int CompareFontFamilies(const void * vp1, const void * vp2); -static const char * AddString(const char * in); +static int CompareFontFamilies(const void *vp1, const void *vp2); +static const char *AddString(const char *in); +static OSStatus GetThemeFontAndFamily(const ThemeFontID themeFontId, + FMFontFamily *fontFamily, unsigned char *fontName, SInt16 *fontSize, + Style *fontStyle); /* @@ -227,33 +231,60 @@ static const char * AddString(const char * in); * * TkpFontPkgInit -- * - * This procedure is called when an application is created. It - * initializes all the structures that are used by the - * platform-dependant code on a per application basis. + * This procedure is called when an application is created. It + * initializes all the structures that are used by the + * platform-dependant code on a per application basis. * * Results: - * None. + * None. * * Side effects: - * Initialization of variables local to this file. + * Initialization of variables local to this file. * *------------------------------------------------------------------------- */ void TkpFontPkgInit( - TkMainInfo * mainPtr) /* The application being created. */ + TkMainInfo *mainPtr) /* The application being created. */ { InitFontFamilies(); #if TK_MAC_COALESCE_LINE Tcl_DStringInit(¤tLine); #endif +} + +/* + *--------------------------------------------------------------------------- + * + * GetThemeFontAndFamily -- + * + * Wrapper around the GetThemeFont and FMGetFontFamilyFromName APIs. + * + *--------------------------------------------------------------------------- + */ -#ifdef TK_MAC_DEBUG_FONTS - fprintf(stderr, "tkMacOSXFont.c (ATSU version) intialized " - "(" __TIME__ ")\n"); -#endif +OSStatus +GetThemeFontAndFamily( + const ThemeFontID themeFontId, + FMFontFamily* fontFamily, + unsigned char *fontName, + SInt16 *fontSize, + Style *fontStyle) +{ + OSStatus err = ChkErr(GetThemeFont, themeFontId, smSystemScript, fontName, + fontSize, fontStyle); + + if (err == noErr) { + *fontFamily = FMGetFontFamilyFromName(fontName); + if (*fontFamily == kInvalidFontFamily) { + err = kFMInvalidFontFamilyErr; + TkMacOSXDbgMsg("FMGetFontFamilyFromName failed."); + } + } + + return err; } /* @@ -261,45 +292,56 @@ TkpFontPkgInit( * * TkpGetNativeFont -- * - * Map a platform-specific native font name to a TkFont. + * Map a platform-specific native font name to a TkFont. * * Results: - * The return value is a pointer to a TkFont that represents the - * native font. If a native font by the given name could not be - * found, the return value is NULL. + * The return value is a pointer to a TkFont that represents the + * native font. If a native font by the given name could not be + * found, the return value is NULL. * - * Every call to this procedure returns a new TkFont structure, even - * if the name has already been seen before. The caller should call - * TkpDeleteFont() when the font is no longer needed. + * Every call to this procedure returns a new TkFont structure, even + * if the name has already been seen before. The caller should call + * TkpDeleteFont() when the font is no longer needed. * - * The caller is responsible for initializing the memory associated - * with the generic TkFont when this function returns and releasing - * the contents of the generics TkFont before calling TkpDeleteFont(). + * The caller is responsible for initializing the memory associated + * with the generic TkFont when this function returns and releasing + * the contents of the generics TkFont before calling TkpDeleteFont(). * * Side effects: - * None. + * None. * *--------------------------------------------------------------------------- */ TkFont * TkpGetNativeFont( - Tk_Window tkwin, /* For display where font will be used. */ - const char * name) /* Platform-specific font name. */ + Tk_Window tkwin, /* For display where font will be used. */ + const char * name) /* Platform-specific font name. */ { - FMFontFamily familyId; + ThemeFontID themeFontId; + FMFontFamily fontFamily; + Str255 fontName; + SInt16 fontSize; + Style fontStyle; MacFont * fontPtr; if (strcmp(name, SYSTEMFONT_NAME) == 0) { - familyId = GetSysFont(); + themeFontId = kThemeSystemFont; } else if (strcmp(name, APPLFONT_NAME) == 0) { - familyId = GetAppFont(); + themeFontId = kThemeApplicationFont; + } else if (strcmp(name, MENUITEMFONT_NAME) == 0) { + themeFontId = kThemeMenuItemFont; } else { - return NULL; + return NULL; } + if (GetThemeFontAndFamily(themeFontId, &fontFamily, fontName, &fontSize, + &fontStyle) != noErr) { + return NULL; + } + CopyPascalStringToC(fontName, (char*)fontName); fontPtr = (MacFont *) ckalloc(sizeof(MacFont)); - InitFont(tkwin, familyId, NULL, 0, 0, fontPtr); + InitFont(tkwin, fontFamily, (char*)fontName, fontSize, fontStyle, fontPtr); return (TkFont *) fontPtr; } @@ -309,74 +351,74 @@ TkpGetNativeFont( * * TkpGetFontFromAttributes -- * - * Given a desired set of attributes for a font, find a font with the - * closest matching attributes. + * Given a desired set of attributes for a font, find a font with the + * closest matching attributes. * * Results: - * The return value is a pointer to a TkFont that represents the font - * with the desired attributes. If a font with the desired attributes - * could not be constructed, some other font will be substituted - * automatically. + * The return value is a pointer to a TkFont that represents the font + * with the desired attributes. If a font with the desired attributes + * could not be constructed, some other font will be substituted + * automatically. * - * Every call to this procedure returns a new TkFont structure, even - * if the specified attributes have already been seen before. The - * caller should call TkpDeleteFont() to free the platform- specific - * data when the font is no longer needed. + * Every call to this procedure returns a new TkFont structure, even + * if the specified attributes have already been seen before. The + * caller should call TkpDeleteFont() to free the platform- specific + * data when the font is no longer needed. * - * The caller is responsible for initializing the memory associated - * with the generic TkFont when this function returns and releasing - * the contents of the generic TkFont before calling TkpDeleteFont(). + * The caller is responsible for initializing the memory associated + * with the generic TkFont when this function returns and releasing + * the contents of the generic TkFont before calling TkpDeleteFont(). * * Side effects: - * None. + * None. * *--------------------------------------------------------------------------- */ TkFont * TkpGetFontFromAttributes( - TkFont * tkFontPtr, /* If non-NULL, store the information in this - * existing TkFont structure, rather than - * allocating a new structure to hold the font; - * the existing contents of the font will be - * released. If NULL, a new TkFont structure is - * allocated. */ - Tk_Window tkwin, /* For display where font will be used. */ - const TkFontAttributes * faPtr) - /* Set of attributes to match. */ + TkFont *tkFontPtr, /* If non-NULL, store the information in this + * existing TkFont structure, rather than + * allocating a new structure to hold the + * font; the existing contents of the font + * will be released. If NULL, a new TkFont + * structure is allocated. */ + Tk_Window tkwin, /* For display where font will be used. */ + const TkFontAttributes *faPtr) + /* Set of attributes to match. */ { short qdStyle; FMFontFamily familyId; - const char * name; - const MacFontFamily * familyPtr; - MacFont * fontPtr; + const char *name; + const MacFontFamily *familyPtr; + MacFont *fontPtr; familyId = GetAppFont(); name = NULL; qdStyle = 0; if (faPtr->family != NULL) { - familyPtr = FindFontFamilyOrAliasOrFallback(faPtr->family); - if (familyPtr != NULL) { - name = familyPtr->name; - familyId = familyPtr->familyId; - } + familyPtr = FindFontFamilyOrAliasOrFallback(faPtr->family); + if (familyPtr != NULL) { + name = familyPtr->name; + familyId = familyPtr->familyId; + } } if (faPtr->weight != TK_FW_NORMAL) { - qdStyle |= bold; + qdStyle |= bold; } if (faPtr->slant != TK_FS_ROMAN) { - qdStyle |= italic; + qdStyle |= italic; } if (faPtr->underline) { - qdStyle |= underline; + qdStyle |= underline; } if (tkFontPtr == NULL) { - fontPtr = (MacFont *) ckalloc(sizeof(MacFont)); + fontPtr = (MacFont *) ckalloc(sizeof(MacFont)); } else { - fontPtr = (MacFont *) tkFontPtr; - ReleaseFont(fontPtr); + fontPtr = (MacFont *) tkFontPtr; + ReleaseFont(fontPtr); } InitFont(tkwin, familyId, name, faPtr->size, qdStyle, fontPtr); @@ -388,23 +430,23 @@ TkpGetFontFromAttributes( * * TkpDeleteFont -- * - * Called to release a font allocated by TkpGetNativeFont() or - * TkpGetFontFromAttributes(). The caller should have already - * released the fields of the TkFont that are used exclusively by the - * generic TkFont code. + * Called to release a font allocated by TkpGetNativeFont() or + * TkpGetFontFromAttributes(). The caller should have already + * released the fields of the TkFont that are used exclusively by the + * generic TkFont code. * * Results: - * TkFont is deallocated. + * TkFont is deallocated. * * Side effects: - * None. + * None. * *--------------------------------------------------------------------------- */ void TkpDeleteFont( - TkFont * tkFontPtr) /* Token of font to be deleted. */ + TkFont *tkFontPtr) /* Token of font to be deleted. */ { ReleaseFont((MacFont *) tkFontPtr); } @@ -414,25 +456,25 @@ TkpDeleteFont( * * TkpGetFontFamilies -- * - * Return information about the font families that are available on - * the display of the given window. + * Return information about the font families that are available on + * the display of the given window. * * Results: - * Modifies interp's result object to hold a list of all the available - * font families. + * Modifies interp's result object to hold a list of all the available + * font families. * * Side effects: - * None. + * None. * *--------------------------------------------------------------------------- */ void TkpGetFontFamilies( - Tcl_Interp * interp, /* Interp to hold result. */ - Tk_Window tkwin) /* For display to query. */ + Tcl_Interp *interp, /* Interp to hold result. */ + Tk_Window tkwin) /* For display to query. */ { - Tcl_SetObjResult(interp,EnumFontFamilies()); + Tcl_SetObjResult(interp, EnumFontFamilies()); } /* @@ -440,26 +482,26 @@ TkpGetFontFamilies( * * TkpGetSubFonts -- * - * A function used by the testing package for querying the actual - * screen fonts that make up a font object. + * A function used by the testing package for querying the actual + * screen fonts that make up a font object. * * Results: - * Modifies interp's result object to hold a list containing the names - * of the screen fonts that make up the given font object. + * Modifies interp's result object to hold a list containing the names + * of the screen fonts that make up the given font object. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ void TkpGetSubFonts( - Tcl_Interp * interp, /* Interp to hold result. */ - Tk_Font tkfont) /* Font object to query. */ + Tcl_Interp *interp, /* Interp to hold result. */ + Tk_Font tkfont) /* Font object to query. */ { /* We don't know much about our fallback fonts, ATSU does all that for - * us. We could use ATSUMatchFont to implement this function. But as + * us. We could use ATSUMatchFont to implement this function. But as * the information is only used for testing, such an effort seems not * very useful. */ } @@ -469,35 +511,35 @@ TkpGetSubFonts( * * TkpGetFontAttrsForChar -- * - * Retrieve the font attributes of the actual font used to render a - * given character. + * Retrieve the font attributes of the actual font used to render a + * given character. * * Results: - * None. + * None. * * Side effects: - * The font attributes are stored in *faPtr. + * The font attributes are stored in *faPtr. * *---------------------------------------------------------------------- */ void TkpGetFontAttrsForChar( - Tk_Window tkwin, /* Window on the font's display */ - Tk_Font tkfont, /* Font to query */ - Tcl_UniChar c, /* Character of interest */ - TkFontAttributes* faPtr) /* Output: Font attributes */ + Tk_Window tkwin, /* Window on the font's display */ + Tk_Font tkfont, /* Font to query */ + Tcl_UniChar c, /* Character of interest */ + TkFontAttributes* faPtr) /* Output: Font attributes */ { - TkMacOSXFont* fontPtr = (TkMacOSXFont*) tkfont; + const MacFont * fontPtr = (const MacFont *) tkfont; UniChar uchar = c; - DrawingContext drawingContext; + TkMacOSXDrawingContext drawingContext; OSStatus err; ATSUFontID fontId; UniCharArrayOffset changedOffset; UniCharCount changedLength; /* - * Most of the attributes are just copied from the base font. This + * Most of the attributes are just copied from the base font. This * assumes that all fonts can have all attributes. */ @@ -507,202 +549,172 @@ TkpGetFontAttrsForChar( * But the name of the actual font may still differ, so we activate the * string as an ATSU layout and ask ATSU about the fallback. */ + TkMacOSXSetupDrawingContext(Tk_WindowId(tkwin), NULL, 1, &drawingContext); -#if TK_MAC_USE_QUARZ - TkMacOSXQuarzStartDraw(&drawingContext); -#endif - - TkMacOSXLayoutSetString(fontPtr, &drawingContext, &uchar, 1); + LayoutSetString(fontPtr, &drawingContext, &uchar, 1); fontId = fontPtr->atsuFontId; err = ATSUMatchFontsToText( - fontPtr->atsuLayout, 0, 1, - &fontId, &changedOffset, &changedLength); -#ifdef TK_MAC_DEBUG_FONTS + fontPtr->atsuLayout, 0, 1, + &fontId, &changedOffset, &changedLength); if (err != kATSUFontsMatched && err != noErr) { - fprintf(stderr, "TkpGetFontAttrsForChar: " - "Can't match \\u%04X\n", - (unsigned) c); + TkMacOSXDbgMsg("Can't match \\u%04X", (unsigned) c); } -#endif if (err == kATSUFontsMatched) { - - /* - * A fallback was used and the actual font is in fontId. Determine - * the name. - */ - - FMFontFamily fontFamilyId; - FMFontStyle fontStyle; - int i; - - err = FMGetFontFamilyInstanceFromFont( - fontId, &fontFamilyId, &fontStyle); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "FMGetFontFamilyInstanceFromFont: Error %d\n", - (int) err); - } -#endif - - if (err == noErr) { - - /* - * Find the canonical name in our global list. - */ - - for (i=0; i<familyListMaxValid; ++i) { - if (fontFamilyId == familyList[i].familyId) { - faPtr->family = familyList[i].name; - break; - } - } -#ifdef TK_MAC_DEBUG_FONTS - if (i >= familyListMaxValid) { - fprintf(stderr, "TkpGetFontAttrsForChar: " - "Can't find font %d for \\u%04X\n", - (int) fontFamilyId, (unsigned) c); - } -#endif - } + /* + * A fallback was used and the actual font is in fontId. Determine + * the name. + */ + + FMFontFamily fontFamilyId; + FMFontStyle fontStyle; + int i; + + err = ChkErr(FMGetFontFamilyInstanceFromFont, fontId, &fontFamilyId, + &fontStyle); + if (err == noErr) { + /* + * Find the canonical name in our global list. + */ + + for (i=0; i<familyListMaxValid; ++i) { + if (fontFamilyId == familyList[i].familyId) { + faPtr->family = familyList[i].name; + break; + } + } + if (i >= familyListMaxValid) { + TkMacOSXDbgMsg("Can't find font %d for \\u%04X", fontFamilyId, + (unsigned) c); + } + } } -#if TK_MAC_USE_QUARZ - TkMacOSXQuarzEndDraw(&drawingContext); -#endif + TkMacOSXRestoreDrawingContext(&drawingContext); } /* *--------------------------------------------------------------------------- * - * Tk_MeasureChars -- + * Tk_MeasureChars -- * - * Determine the number of characters from the string that will fit in - * the given horizontal span. The measurement is done under the - * assumption that Tk_DrawChars() will be used to actually display the - * characters. + * Determine the number of characters from the string that will fit in + * the given horizontal span. The measurement is done under the + * assumption that Tk_DrawChars() will be used to actually display the + * characters. * - * With ATSUI we need the line context to do this right, so we have the - * actual implementation in TkpMeasureCharsInContext(). + * With ATSUI we need the line context to do this right, so we have the + * actual implementation in TkpMeasureCharsInContext(). * * Results: - * - * The return value is the number of bytes from source that fit into the - * span that extends from 0 to maxLength. *lengthPtr is filled with the - * x-coordinate of the right edge of the last character that did fit. + * The return value is the number of bytes from source that fit into the + * span that extends from 0 to maxLength. *lengthPtr is filled with the + * x-coordinate of the right edge of the last character that did fit. * * Side effects: - * - * None. + * None. * * Todo: - * - * Effects of the "flags" parameter are untested. + * Effects of the "flags" parameter are untested. * *--------------------------------------------------------------------------- */ int Tk_MeasureChars( - Tk_Font tkfont, /* Font in which characters will be drawn. */ - const char * source, /* UTF-8 string to be displayed. Need not be - * '\0' terminated. */ - int numBytes, /* Maximum number of bytes to consider from - * source string. */ - int maxLength, /* If >= 0, maxLength specifies the longest - * permissible line length; don't consider any - * character that would cross this x-position. - * If < 0, then line length is unbounded and the - * flags argument is ignored. */ - int flags, /* Various flag bits OR-ed together: - * TK_PARTIAL_OK means include the last char - * which only partially fit on this line. - * TK_WHOLE_WORDS means stop on a word boundary, - * if possible. TK_AT_LEAST_ONE means return at - * least one character even if no characters - * fit. */ - int * lengthPtr) /* Filled with x-location just after the - * terminating character. */ + Tk_Font tkfont, /* Font in which characters will be drawn. */ + const char *source, /* UTF-8 string to be displayed. Need not be + * '\0' terminated. */ + int numBytes, /* Maximum number of bytes to consider from + * source string. */ + int maxLength, /* If >= 0, maxLength specifies the longest + * permissible line length; don't consider any + * character that would cross this x-position. + * If < 0, then line length is unbounded and + * the flags argument is ignored. */ + int flags, /* Various flag bits OR-ed together: + * TK_PARTIAL_OK means include the last char + * which only partially fit on this line. + * TK_WHOLE_WORDS means stop on a word + * boundary, if possible. TK_AT_LEAST_ONE + * means return at least one character even if + * no characters fit. */ + int *lengthPtr) /* Filled with x-location just after the + * terminating character. */ { - return TkpMeasureCharsInContext( - tkfont, source, numBytes, 0, numBytes, maxLength, flags, lengthPtr); + return TkpMeasureCharsInContext(tkfont, source, numBytes, 0, numBytes, + maxLength, flags, lengthPtr); } /* *--------------------------------------------------------------------------- * - * TkpMeasureCharsInContext -- + * TkpMeasureCharsInContext -- * - * Determine the number of bytes from the string that will fit in the - * given horizontal span. The measurement is done under the assumption - * that TkpDrawCharsInContext() will be used to actually display the - * characters. + * Determine the number of bytes from the string that will fit in the + * given horizontal span. The measurement is done under the assumption + * that TkpDrawCharsInContext() will be used to actually display the + * characters. * - * This one is almost the same as Tk_MeasureChars(), but with access to - * all the characters on the line for context. + * This one is almost the same as Tk_MeasureChars(), but with access to + * all the characters on the line for context. * * Results: - * The return value is the number of bytes from source that - * fit into the span that extends from 0 to maxLength. *lengthPtr is - * filled with the x-coordinate of the right edge of the last - * character that did fit. + * The return value is the number of bytes from source that + * fit into the span that extends from 0 to maxLength. *lengthPtr is + * filled with the x-coordinate of the right edge of the last + * character that did fit. * * Side effects: - * None. + * None. * *--------------------------------------------------------------------------- */ int TkpMeasureCharsInContext( - Tk_Font tkfont, /* Font in which characters will be drawn. */ - const char * source, /* UTF-8 string to be displayed. Need not be - * '\0' terminated. */ - int numBytes, /* Maximum number of bytes to consider from - * source string in all. */ - int rangeStart, /* Index of first byte to measure. */ - int rangeLength, /* Length of range to measure in bytes. */ - int maxLength, /* If >= 0, maxLength specifies the longest - * permissible line length; don't consider any - * character that would cross this x-position. - * If < 0, then line length is unbounded and the - * flags argument is ignored. */ - int flags, /* Various flag bits OR-ed together: - * TK_PARTIAL_OK means include the last char - * which only partially fits on this line. - * TK_WHOLE_WORDS means stop on a word boundary, - * if possible. - * TK_AT_LEAST_ONE means return at least one - * character (or at least the first partial word - * in case TK_WHOLE_WORDS is also set) even if no - * characters (words) fit. - * TK_ISOLATE_END means that the last character - * should not be considered in context with the - * rest of the string (used for breaking - * lines). */ - int * lengthPtr) /* Filled with x-location just after the - * terminating character. */ + Tk_Font tkfont, /* Font in which characters will be drawn. */ + const char * source, /* UTF-8 string to be displayed. Need not be + * '\0' terminated. */ + int numBytes, /* Maximum number of bytes to consider from + * source string in all. */ + int rangeStart, /* Index of first byte to measure. */ + int rangeLength, /* Length of range to measure in bytes. */ + int maxLength, /* If >= 0, maxLength specifies the longest + * permissible line length; don't consider any + * character that would cross this x-position. + * If < 0, then line length is unbounded and + * the flags argument is ignored. */ + int flags, /* Various flag bits OR-ed together: + * TK_PARTIAL_OK means include the last char + * which only partially fits on this line. + * TK_WHOLE_WORDS means stop on a word + * boundary, if possible. TK_AT_LEAST_ONE + * means return at least one character (or at + * least the first partial word in case + * TK_WHOLE_WORDS is also set) even if no + * characters (words) fit. TK_ISOLATE_END + * means that the last character should not be + * considered in context with the rest of the + * string (used for breaking lines). */ + int *lengthPtr) /* Filled with x-location just after the + * terminating character. */ { - const MacFont * fontPtr = (const MacFont *) tkfont; - int curX = -1; - int curByte = 0; - UniChar * uchars; + const MacFont *fontPtr = (const MacFont *) tkfont; + int curX = -1, curByte = 0; + UniChar *uchars; int ulen, urstart, urlen, urend; Tcl_DString ucharBuffer; - DrawingContext drawingContext; - /* * Sanity checks. */ - if ((rangeStart < 0) || ((rangeStart+rangeLength) > numBytes)) { -#ifdef TK_MAC_DEBUG_FONTS - fprintf(stderr, "MeasureChars: bad parameters\n"); -#endif - *lengthPtr = 0; - return 0; + if (rangeStart < 0 || (rangeStart+rangeLength) > numBytes) { + TkMacOSXDbgMsg("Bad parameters"); + *lengthPtr = 0; + return 0; } /* @@ -710,284 +722,243 @@ TkpMeasureCharsInContext( */ if (rangeLength == 0 || (maxLength == 0 && !(flags & TK_AT_LEAST_ONE))) { -#ifdef TK_MAC_DEBUG_FONTS - fflush(stdout); - fprintf(stderr, "measure: '%.*s', empty\n", - rangeLength, source+rangeStart); - fflush(stderr); -#endif - *lengthPtr = 0; - return 0; + *lengthPtr = 0; + return 0; } -#if TK_MAC_USE_QUARZ - TkMacOSXQuarzStartDraw(&drawingContext); -#endif - Tcl_DStringInit(&ucharBuffer); uchars = Tcl_UtfToUniCharDString(source, numBytes, &ucharBuffer); ulen = Tcl_DStringLength(&ucharBuffer) / sizeof(Tcl_UniChar); - TkMacOSXLayoutSetString(fontPtr, &drawingContext, uchars, ulen); + LayoutSetString(fontPtr, NULL, uchars, ulen); urstart = Tcl_NumUtfChars(source, rangeStart); urlen = Tcl_NumUtfChars(source+rangeStart,rangeLength); urend = urstart + urlen; if (maxLength < 0) { - - curX = MeasureStringWidth(fontPtr, urstart, urend); - curByte = rangeLength; - + curX = MeasureStringWidth(fontPtr, urstart, urend); + curByte = rangeLength; } else { - - UniCharArrayOffset offset = 0; - OSStatus err; - - /* - * Have some upper limit on the size actually used. - */ - - if (maxLength > 32767) { - maxLength = 32767; - } - - offset = urstart; - err = noErr; - - if (maxLength > 1) { - - /* - * Let the system do some work by calculating a line break. - * - * Somehow ATSUBreakLine seems to assume that it needs at least - * one pixel padding. So we add one to the limit. Note also - * that ATSUBreakLine sometimes runs into an endless loop when - * the third parameter is equal or less than IntToFixed(2), so we - * need at least IntToFixed(3) (at least that's the current state - * of my knowledge). - */ - - err = ATSUBreakLine( - fontPtr->atsuLayout, - urstart, - IntToFixed(maxLength+1), - false, /* !iUseAsSoftLineBreak */ - &offset); - - /* - * There is no way to signal an error from this routine, so we - * use predefined offset=urstart and otherwise ignore the - * possibility. - */ + UniCharArrayOffset offset = 0; + OSStatus err; + + /* + * Have some upper limit on the size actually used. + */ + + if (maxLength > 32767) { + maxLength = 32767; + } + + offset = urstart; + err = noErr; + + if (maxLength > 1) { + /* + * Let the system do some work by calculating a line break. + * + * Somehow ATSUBreakLine seems to assume that it needs at least + * one pixel padding. So we add one to the limit. Note also + * that ATSUBreakLine sometimes runs into an endless loop when + * the third parameter is equal or less than IntToFixed(2), so we + * need at least IntToFixed(3) (at least that's the current state + * of my knowledge). + */ + + err = ATSUBreakLine(fontPtr->atsuLayout, urstart, + IntToFixed(maxLength+1), false, /* !iUseAsSoftLineBreak */ + &offset); + + /* + * There is no way to signal an error from this routine, so we + * use predefined offset=urstart and otherwise ignore the + * possibility. + */ + + if ((err != noErr) && (err != kATSULineBreakInWord)) { + TkMacOSXDbgMsg("ATSUBreakLine failed: %ld for '%.*s'", err, + rangeLength, source+rangeStart); + } #ifdef TK_MAC_DEBUG_FONTS - if ((err != noErr) && (err != kATSULineBreakInWord)) { - fprintf(stderr, "ATSUBreakLine(): Error %d for '%.*s'\n", - (int) err, rangeLength, source+rangeStart); - } + TkMacOSXDbgMsg("measure: '%.*s', break offset=%ld, errcode=%ld", + rangeLength, source+rangeStart, offset, err); #endif -#ifdef TK_MAC_DEBUG_FONTS - fprintf(stderr, "measure: '%.*s', break offset=%d, errcode=%d\n", - rangeLength, source+rangeStart, (int) offset, (int) err); -#endif - - /* - * ATSUBreakLine includes the whitespace that separates words, - * but we don't want that. Besides, ATSUBreakLine thinks that - * spaces don't occupy pixels at the end of the break, which is - * also something we like to decide for ourself. - */ - - while ((offset > (UniCharArrayOffset)urstart) && (uchars[offset-1] == ' ')) { - offset--; - } - - /* - * Fix up left-overs for the TK_WHOLE_WORDS case. - */ - - if (flags & TK_WHOLE_WORDS) { - if(flags & TK_AT_LEAST_ONE) { - - /* - * If we are the the start of the range, we need to look - * forward. If we are not at the end of a word, we must - * be in the middle of the first word, so we also look - * forward. - */ - - if ((offset == (UniCharArrayOffset)urstart) || (uchars[offset] != ' ')) { - while ((offset < (UniCharArrayOffset)urend) - && (uchars[offset] != ' ')) { - offset++; - } - } - } else { - - /* - * If we are not at the end of a word, we need to look - * backward. - */ - - if ((offset != (UniCharArrayOffset)urend) && (uchars[offset] != ' ')) { - while ((offset > (UniCharArrayOffset)urstart) - && (uchars[offset-1] != ' ')) { - offset--; - } - while ((offset > (UniCharArrayOffset)urstart) - && (uchars[offset-1] == ' ')) { - offset--; - } - } - } - } - } - - if (offset > (UniCharArrayOffset)urend) { - offset = urend; - } - - /* - * If "flags" says that we don't actually want a word break, we need - * to find the next character break ourself, as ATSUBreakLine() will - * only give us word breaks. Do a simple linear search. - */ - - if ((err != kATSULineBreakInWord) - && !(flags & TK_WHOLE_WORDS) - && (offset <= (UniCharArrayOffset)urend)) { - - UniCharArrayOffset lastOffset = offset; - UniCharArrayOffset nextoffset; - int lastX = -1; - int wantonemorechar = -1; /* undecided */ - - while (offset <= (UniCharArrayOffset)urend) { - - if (flags & TK_ISOLATE_END) { - TkMacOSXLayoutSetString(fontPtr, &drawingContext, - uchars, offset); - } - curX = MeasureStringWidth(fontPtr, urstart, offset); + /* + * ATSUBreakLine includes the whitespace that separates words, + * but we don't want that. Besides, ATSUBreakLine thinks that + * spaces don't occupy pixels at the end of the break, which is + * also something we like to decide for ourself. + */ + + while ((offset > (UniCharArrayOffset)urstart) && + (uchars[offset-1] == ' ')) { + offset--; + } + + /* + * Fix up left-overs for the TK_WHOLE_WORDS case. + */ + + if (flags & TK_WHOLE_WORDS) { + if (flags & TK_AT_LEAST_ONE) { + /* + * If we are the the start of the range, we need to look + * forward. If we are not at the end of a word, we must + * be in the middle of the first word, so we also look + * forward. + */ + + if ((offset == (UniCharArrayOffset)urstart) || + (uchars[offset] != ' ')) { + while ((offset < (UniCharArrayOffset)urend) + && (uchars[offset] != ' ')) { + offset++; + } + } + } else { + /* + * If we are not at the end of a word, we need to look + * backward. + */ + + if ((offset != (UniCharArrayOffset)urend) && + (uchars[offset] != ' ')) { + while ((offset > (UniCharArrayOffset)urstart) + && (uchars[offset-1] != ' ')) { + offset--; + } + while ((offset > (UniCharArrayOffset)urstart) + && (uchars[offset-1] == ' ')) { + offset--; + } + } + } + } + } + + if (offset > (UniCharArrayOffset)urend) { + offset = urend; + } + + /* + * If "flags" says that we don't actually want a word break, we need + * to find the next character break ourself, as ATSUBreakLine() will + * only give us word breaks. Do a simple linear search. + */ + + if ((err != kATSULineBreakInWord) + && !(flags & TK_WHOLE_WORDS) + && (offset <= (UniCharArrayOffset)urend)) { + UniCharArrayOffset lastOffset = offset; + UniCharArrayOffset nextoffset; + int lastX = -1; + int wantonemorechar = -1; /* undecided */ + + while (offset <= (UniCharArrayOffset)urend) { + if (flags & TK_ISOLATE_END) { + LayoutSetString(fontPtr, NULL, uchars, offset); + } + curX = MeasureStringWidth(fontPtr, urstart, offset); #ifdef TK_MAC_DEBUG_FONTS - fprintf(stderr, "measure: '%.*s', try until=%d, width=%d\n", - rangeLength, source+rangeStart, (int) offset, curX); + TkMacOSXDbgMsg("measure: '%.*s', try until=%ld, width=%d", + rangeLength, source+rangeStart, offset, curX); #endif - if (curX > maxLength) { - - /* - * Even if we are over the limit, we may want another - * character in some situations. Than we keep looking - * for one more character. - */ - - if (wantonemorechar == -1) { - wantonemorechar = - ((flags & TK_AT_LEAST_ONE) - && (lastOffset == (UniCharArrayOffset)urstart)) - || - ((flags & TK_PARTIAL_OK) - && (lastX != maxLength)) - ; - if (!wantonemorechar) { - break; - } - lastX = curX; - } - - /* - * There may belong combining marks to this character. - * Wait for a new curX to collect them all. - */ - - if (lastX != curX) { - break; - } - } - - /* - * Save this position, so we can come back to it. - */ - - lastX = curX; - lastOffset = offset; - - /* - * Increment offset by one character, taking combining marks - * into account. - */ - - if (offset >= (UniCharArrayOffset)urend) { - break; - } - nextoffset = 0; - if (flags & TK_ISOLATE_END) { - TkMacOSXLayoutSetString(fontPtr, &drawingContext, - uchars, ulen); - } - err = ATSUNextCursorPosition( - fontPtr->atsuLayout, - offset, - kATSUByCluster, - &nextoffset); - if (err != noErr) { -#ifdef TK_MAC_DEBUG_FONTS - fprintf(stderr, "ATSUNextCursorPosition(): " - "Error %d\n", (int) err); -#endif - break; - } - if (nextoffset <= offset) { + if (curX > maxLength) { + /* + * Even if we are over the limit, we may want another + * character in some situations. Than we keep looking + * for one more character. + */ + + if (wantonemorechar == -1) { + wantonemorechar = ((flags & TK_AT_LEAST_ONE) && + (lastOffset == (UniCharArrayOffset)urstart)) || + ((flags & TK_PARTIAL_OK) && + (lastX != maxLength)); + if (!wantonemorechar) { + break; + } + lastX = curX; + } + + /* + * There may belong combining marks to this character. + * Wait for a new curX to collect them all. + */ + + if (lastX != curX) { + break; + } + } + + /* + * Save this position, so we can come back to it. + */ + + lastX = curX; + lastOffset = offset; + + /* + * Increment offset by one character, taking combining marks + * into account. + */ + + if (offset >= (UniCharArrayOffset)urend) { + break; + } + nextoffset = 0; + if (flags & TK_ISOLATE_END) { + LayoutSetString(fontPtr, NULL, uchars, ulen); + } + err = ChkErr(ATSUNextCursorPosition, fontPtr->atsuLayout, + offset, kATSUByCluster, &nextoffset); + if (err != noErr) { + break; + } + if (nextoffset <= offset) { #ifdef TK_MAC_DEBUG_FONTS - fprintf(stderr, "ATSUNextCursorPosition(): " - "Can't move further " - "(shouldn't happen, bad data?)\n"); + TkMacOSXDbgMsg("ATSUNextCursorPosition: Can't move further" + " (shouldn't happen, bad data?)"); #endif - break; - } - - offset = nextoffset; - } - - /* - * We have overshot one character, so backup one position. - */ - - curX = lastX; - offset = lastOffset; - } - - if (curX < 0) { - if (flags & TK_ISOLATE_END) { - TkMacOSXLayoutSetString(fontPtr, &drawingContext, - uchars, offset); - } - curX = MeasureStringWidth(fontPtr, urstart, offset); - } - - curByte = Tcl_UtfAtIndex(source, offset) - source; - curByte -= rangeStart; + break; + } + + offset = nextoffset; + } + + /* + * We have overshot one character, so backup one position. + */ + + curX = lastX; + offset = lastOffset; + } + + if (curX < 0) { + if (flags & TK_ISOLATE_END) { + LayoutSetString(fontPtr, NULL, uchars, offset); + } + curX = MeasureStringWidth(fontPtr, urstart, offset); + } + + curByte = Tcl_UtfAtIndex(source, offset) - source; + curByte -= rangeStart; } Tcl_DStringFree(&ucharBuffer); -#if TK_MAC_USE_QUARZ - TkMacOSXQuarzEndDraw(&drawingContext); -#endif - #ifdef TK_MAC_DEBUG_FONTS - fflush(stdout); - fprintf(stderr, "measure: '%.*s', maxpix=%d, -> width=%d, bytes=%d, " - "flags=%s%s%s%s\n", - rangeLength, source+rangeStart, maxLength, curX, curByte, - flags & TK_PARTIAL_OK ? "partialOk " : "", - flags & TK_WHOLE_WORDS ? "wholeWords " : "", - flags & TK_AT_LEAST_ONE ? "atLeastOne " : "", - flags & TK_ISOLATE_END ? "isolateEnd " : ""); - fflush(stderr); + TkMacOSXDbgMsg("measure: '%.*s', maxpix=%d, -> width=%d, bytes=%d, " + "flags=%s%s%s%s", rangeLength, source+rangeStart, maxLength, curX, + curByte, + flags & TK_PARTIAL_OK ? "partialOk " : "", + flags & TK_WHOLE_WORDS ? "wholeWords " : "", + flags & TK_AT_LEAST_ONE ? "atLeastOne " : "", + flags & TK_ISOLATE_END ? "isolateEnd " : ""); #endif *lengthPtr = curX; @@ -999,360 +970,120 @@ TkpMeasureCharsInContext( * * Tk_DrawChars -- * - * Draw a string of characters on the screen. + * Draw a string of characters on the screen. * - * With ATSUI we need the line context to do this right, so we have the - * actual implementation in TkpDrawCharsInContext(). + * With ATSUI we need the line context to do this right, so we have the + * actual implementation in TkpDrawCharsInContext(). * * Results: - * - * None. + * None. * * Side effects: - * - * Information gets drawn on the screen. + * Information gets drawn on the screen. * *--------------------------------------------------------------------------- */ void Tk_DrawChars( - Display * display, /* Display on which to draw. */ - Drawable drawable, /* Window or pixmap in which to draw. */ - GC gc, /* Graphics context for drawing characters. */ - Tk_Font tkfont, /* Font in which characters will be drawn; must - * be the same as font used in GC. */ - const char * source, /* UTF-8 string to be displayed. Need not be - * '\0' terminated. All Tk meta-characters - * (tabs, control characters, and newlines) - * should be stripped out of the string that is - * passed to this function. If they are not - * stripped out, they will be displayed as - * regular printing characters. */ - int numBytes, /* Number of bytes in string. */ - int x, int y) /* Coordinates at which to place origin of the - * string when drawing. */ + Display *display, /* Display on which to draw. */ + Drawable drawable, /* Window or pixmap in which to draw. */ + GC gc, /* Graphics context for drawing characters. */ + Tk_Font tkfont, /* Font in which characters will be drawn; must + * be the same as font used in GC. */ + const char *source, /* UTF-8 string to be displayed. Need not be + * '\0' terminated. All Tk meta-characters + * (tabs, control characters, and newlines) + * should be stripped out of the string that + * is passed to this function. If they are not + * stripped out, they will be displayed as + * regular printing characters. */ + int numBytes, /* Number of bytes in string. */ + int x, int y) /* Coordinates at which to place origin of the + * string when drawing. */ { TkpDrawCharsInContext(display, drawable, gc, tkfont, source, numBytes, - 0, numBytes, x, y); + 0, numBytes, x, y); } - /* *--------------------------------------------------------------------------- * * TkpDrawCharsInContext -- * - * Draw a string of characters on the screen like Tk_DrawChars(), with - * access to all the characters on the line for context. + * Draw a string of characters on the screen like Tk_DrawChars(), with + * access to all the characters on the line for context. * * Results: - * None. + * None. * * Side effects: - * Information gets drawn on the screen. + * Information gets drawn on the screen. * * Todo: - * - * We could try to implement a correct stipple algorithm. - * - * The fiddling with QD GraphPorts can be replaced with just working - * with the Quarz CGContext (see TkMacOSXQuarzStartDraw()), once we - * decide to stick to Quarz and really forget about QD drawing in here. + * Stippled text drawing. * *--------------------------------------------------------------------------- */ void TkpDrawCharsInContext( - Display * display, /* Display on which to draw. */ - Drawable drawable, /* Window or pixmap in which to draw. */ - GC gc, /* Graphics context for drawing characters. */ - Tk_Font tkfont, /* Font in which characters will be drawn; must - * be the same as font used in GC. */ - const char * source, /* UTF-8 string to be displayed. Need not be - * '\0' terminated. All Tk meta-characters - * (tabs, control characters, and newlines) - * should be stripped out of the string that is - * passed to this function. If they are not - * stripped out, they will be displayed as - * regular printing characters. */ - int numBytes, /* Number of bytes in string. */ - int rangeStart, /* Index of first byte to draw. */ - int rangeLength, /* Length of range to draw in bytes. */ - int x, int y) /* Coordinates at which to place origin of the - * whole (not just the range) string when - * drawing. */ -{ - const MacFont * fontPtr; - MacDrawable * macWin; - RGBColor macColor, origColor; - GWorldPtr destPort; - CGrafPtr saveWorld; - GDHandle saveDevice; - BitMapPtr stippleMap; - Rect portRect; - - fontPtr = (const MacFont *) tkfont; - macWin = (MacDrawable *) drawable; - - destPort = TkMacOSXGetDrawablePort(drawable); - GetPortBounds(destPort, &portRect); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - - TkMacOSXSetUpClippingRgn(drawable); - TkMacOSXSetUpGraphicsPort(gc, destPort); - - GetForeColor(&origColor); - - if ((gc->fill_style == FillStippled - || gc->fill_style == FillOpaqueStippled) - && gc->stipple != None) { - - Pixmap pixmap; - GWorldPtr bufferPort; - Pattern white; - - stippleMap = TkMacOSXMakeStippleMap(drawable, gc->stipple); - - pixmap = Tk_GetPixmap(display, drawable, - stippleMap->bounds.right, stippleMap->bounds.bottom, 0); - - bufferPort = TkMacOSXGetDrawablePort(pixmap); - SetGWorld(bufferPort, NULL); - - if (TkSetMacColor(gc->foreground, &macColor)) { - RGBForeColor(&macColor); - } - GetQDGlobalsWhite(&white); - ShowPen(); - FillRect(&stippleMap->bounds, &white); - MacFontDrawText(fontPtr, source, numBytes, rangeStart, rangeLength, - 0, 0); - HidePen(); - - SetGWorld(destPort, NULL); - - CopyDeepMask(GetPortBitMapForCopyBits(bufferPort), stippleMap, - GetPortBitMapForCopyBits(destPort), &stippleMap->bounds, - &stippleMap->bounds, &portRect, - srcOr, NULL); - - /* - * TODO: this doesn't work quite right - it does a blend. you can't - * draw white text when you have a stipple. - */ - - Tk_FreePixmap(display, pixmap); - ckfree(stippleMap->baseAddr); - ckfree((char *)stippleMap); - } else { - if (TkSetMacColor(gc->foreground, &macColor)) { - RGBForeColor(&macColor); - } - ShowPen(); - MacFontDrawText(fontPtr, source, numBytes, rangeStart, rangeLength, - macWin->xOff + x, macWin->yOff + y); - HidePen(); - } - - RGBForeColor(&origColor); - - SetGWorld(saveWorld, saveDevice); -} - -#if TK_MAC_USE_QUARZ -#define RGBFLOATRED(c) (float)((float)(c.red) / 65535.0f) -#define RGBFLOATGREEN(c) (float)((float)(c.green) / 65535.0f) -#define RGBFLOATBLUE(c) (float)((float)(c.blue) / 65535.0f) -/* - *------------------------------------------------------------------------- - * - * TkMacOSXQuarzStartDraw -- - * - * Setup a Quarz CGContext from the current QD GraphPort for use in - * drawing or measuring. - * - * Results: - * - * A CGContext is allocated, configured and returned in - * drawingContextPtr. Also drawingContextPtr->portRect is filled in. - * - * Side effects: - * - * None. - * - * Assumptions: - * - * The current QD GraphPort contains all the data necessary. This is - * clearly the case for the actual drawing, but not so clear for - * measuring. OTOH for measuring the specific parameters are not really - * interesting and the GraphPort is not changed either. The - * availability of a CGContext may be important for the measuring - * process though. - * - *------------------------------------------------------------------------- - */ - -void -TkMacOSXQuarzStartDraw( - DrawingContext * drawingContextPtr) /* Quarz context data filled in - * by this function. */ -{ - GDHandle currentDevice; - CGrafPtr destPort; - RGBColor macColor; - CGContextRef outContext; - OSStatus err; - Rect boundsRect; - static RgnHandle clipRgn = NULL; - - GetGWorld(&destPort, ¤tDevice); - - err = QDBeginCGContext(destPort, &outContext); - - if (err == noErr && outContext) { - /* - * Now clip the CG Context to the port. We also have to intersect our clip - * region with the port visible region so we don't overwrite the window - * decoration. - */ - - if (!clipRgn) { - clipRgn = NewRgn(); - } - - GetPortBounds(destPort, &boundsRect); - - RectRgn(clipRgn, &boundsRect); - SectRegionWithPortClipRegion(destPort, clipRgn); - SectRegionWithPortVisibleRegion(destPort, clipRgn); - ClipCGContextToRegion(outContext, &boundsRect, clipRgn); - SetEmptyRgn(clipRgn); - - /* - * Note: You have to call SyncCGContextOriginWithPort - * AFTER all the clip region manipulations. - */ - - SyncCGContextOriginWithPort(outContext, destPort); - - /* - * Scale the color values, as QD uses UInt16 with the range [0..2^16-1] - * while Quarz uses float with [0..1]. NB: Only - * CGContextSetRGBFillColor() seems to be actually used by ATSU. - */ - - GetForeColor(&macColor); - CGContextSetRGBFillColor(outContext, - RGBFLOATRED(macColor), - RGBFLOATGREEN(macColor), - RGBFLOATBLUE(macColor), - 1.0f); - #ifdef TK_MAC_DEBUG_FONTS - } else { - fprintf(stderr, "QDBeginCGContext(): Error %d\n", (int) err); - #endif - } - - drawingContextPtr->graphPort = destPort; - drawingContextPtr->cgContext = outContext; - drawingContextPtr->portRect = boundsRect; - -} - -/* - *------------------------------------------------------------------------- - * - * TkMacOSXQuarzEndDraw -- - * - * Free the Quarz CGContext in drawingContextPtr. - * - * Results: - * - * The CGContext is de-allocated. drawingContextPtr->cgContext will be - * invalid after this. - * - * Side effects: - * - * None. - * - *------------------------------------------------------------------------- - */ - -void -TkMacOSXQuarzEndDraw( - DrawingContext * drawingContextPtr) -{ - if (drawingContextPtr->cgContext) { - QDEndCGContext( - drawingContextPtr->graphPort, - &drawingContextPtr->cgContext); - } -} -#endif /* TK_MAC_USE_QUARZ */ - -/* - *------------------------------------------------------------------------- - * - * MacFontDrawText -- - * - * Helper function for Tk_DrawChars. Draws characters, using the - * screen font in fontPtr to draw multilingual characters. - * - * Results: - * None. - * - * Side effects: - * Information gets drawn on the screen. - * - *------------------------------------------------------------------------- - */ - -static void -MacFontDrawText( - const MacFont * fontPtr, /* Contains font to use when drawing - * following string. */ - const char * source, /* Potentially multilingual UTF-8 string. */ - int numBytes, /* Length of string in bytes. */ - int rangeStart, /* Index of first byte to draw. */ - int rangeLength, /* Length of range to draw in bytes. */ - int x, int y) /* Coordinates at which to place origin of - * string when drawing. */ + Display *display, /* Display on which to draw. */ + Drawable drawable, /* Window or pixmap in which to draw. */ + GC gc, /* Graphics context for drawing characters. */ + Tk_Font tkfont, /* Font in which characters will be drawn; must + * be the same as font used in GC. */ + const char * source, /* UTF-8 string to be displayed. Need not be + * '\0' terminated. All Tk meta-characters + * (tabs, control characters, and newlines) + * should be stripped out of the string that + * is passed to this function. If they are not + * stripped out, they will be displayed as + * regular printing characters. */ + int numBytes, /* Number of bytes in string. */ + int rangeStart, /* Index of first byte to draw. */ + int rangeLength, /* Length of range to draw in bytes. */ + int x, int y) /* Coordinates at which to place origin of the + * whole (not just the range) string when + * drawing. */ { + const MacFont * fontPtr = (const MacFont *) tkfont; + MacDrawable *macWin = (MacDrawable *) drawable; Fixed fx, fy; int ulen, urstart, urlen; const UniChar * uchars; int lineOffset; - DrawingContext drawingContext; - OSStatus err; - + TkMacOSXDrawingContext drawingContext; #if !TK_MAC_COALESCE_LINE Tcl_DString runString; #endif + TkMacOSXSetupDrawingContext(drawable, gc, 1, &drawingContext); -#if TK_MAC_USE_QUARZ - TkMacOSXQuarzStartDraw(&drawingContext); - - /* - * Turn the y coordinate upside-down for Quarz drawing. We would have - * liked to just use a CTM transform in the CGContext, but than we get - * upside-down text, so doing it that way gets more painfull than to just - * hack around the problem right here. - */ - - y = drawingContext.portRect.bottom - drawingContext.portRect.top - y; - fy = IntToFixed(y); -#else - fy = IntToFixed(y); +#if 0 + /* TODO: implement stippled text drawing */ + if ((gc->fill_style == FillStippled + || gc->fill_style == FillOpaqueStippled) + && gc->stipple != None) { + #error Stippling not implemented + } #endif + x += macWin->xOff; + y += macWin->yOff; + /* Turn the y coordinate upside-down for Quarz drawing. */ + if (drawingContext.context) { + CGContextConcatCTM(drawingContext.context, CGAffineTransformMake(1.0, + 0.0, 0.0, -1.0, 0.0, drawingContext.portBounds.bottom - + drawingContext.portBounds.top)); + y = drawingContext.portBounds.bottom - + drawingContext.portBounds.top - y; + } + fy = IntToFixed(y); #if TK_MAC_COALESCE_LINE UpdateLineBuffer( - fontPtr, &drawingContext, source, numBytes, x, y, &lineOffset); + fontPtr, &drawingContext, source, numBytes, x, y, &lineOffset); fx = IntToFixed(currentLeft); @@ -1366,67 +1097,54 @@ MacFontDrawText( uchars = Tcl_UtfToUniCharDString(source, numBytes, &runString); ulen = Tcl_DStringLength(&runString) / sizeof(uchars[0]); - TkMacOSXLayoutSetString(fontPtr, &drawingContext, uchars, ulen); + LayoutSetString(fontPtr, &drawingContext, uchars, ulen); #endif urstart = Tcl_NumUtfChars(source, rangeStart); urlen = Tcl_NumUtfChars(source+rangeStart,rangeLength); - err = ATSUDrawText( - fontPtr->atsuLayout, - lineOffset+urstart, urlen, - fx, fy); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "ATSUDrawText(): Error %d\n", (int) err); - } -#endif + ChkErr(ATSUDrawText, fontPtr->atsuLayout, lineOffset+urstart, urlen, fx, + fy); #if !TK_MAC_COALESCE_LINE Tcl_DStringFree(&runString); #endif -#if TK_MAC_USE_QUARZ - TkMacOSXQuarzEndDraw(&drawingContext); -#endif + TkMacOSXRestoreDrawingContext(&drawingContext); } - /* *--------------------------------------------------------------------------- * * MeasureStringWidth -- * - * Low-level measuring of strings. + * Low-level measuring of strings. * * Results: - * - * The width of the string in pixels. + * The width of the string in pixels. * * Side effects: - * - * None. + * None. * * Assumptions: - * - * fontPtr->atsuLayout is setup with the actual string data to measure. + * fontPtr->atsuLayout is setup with the actual string data to measure. * *--------------------------------------------------------------------------- */ static int MeasureStringWidth( - const MacFont * fontPtr, /* Contains font, ATSU layout and string data - * to measure. */ - int start, int end) /* Start and end positions to measure in that - * string. */ + const MacFont *fontPtr, /* Contains font, ATSU layout and string data + * to measure. */ + int start, int end) /* Start and end positions to measure in that + * string. */ { /* * This implementation of measuring via ATSUGetGlyphBounds() does not * quite conform with the specification given for [font measure]: * - * The return value is the total width in pixels of text, not - * including the extra pixels used by highly exagerrated characters - * such as cursive "f". + * The return value is the total width in pixels of text, not + * including the extra pixels used by highly exagerrated characters + * such as cursive "f". * * Instead the result of ATSUGetGlyphBounds() *does* include these * "extra pixels". @@ -1434,26 +1152,18 @@ MeasureStringWidth( ATSTrapezoid bounds; ItemCount numBounds; - OSStatus err; if (end <= start) { - return 0; + return 0; } bounds.upperRight.x = bounds.upperLeft.x = 0; - err = ATSUGetGlyphBounds( - fontPtr->atsuLayout, - 0, 0, - start, end-start, - kATSUseFractionalOrigins, - 1, &bounds, &numBounds); + ChkErr(ATSUGetGlyphBounds, fontPtr->atsuLayout, 0, 0, start, end-start, + kATSUseFractionalOrigins, 1, &bounds, &numBounds); #ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "ATSUGetGlyphBounds(): Error %d\n", (int) err); - } else if (numBounds < 1) { - fprintf(stderr, "ATSUGetGlyphBounds(): No output\n"); - } else if (numBounds > 1) { - fprintf(stderr, "ATSUGetGlyphBounds(): More output\n"); + if (numBounds < 1 || numBounds > 1) { + TkMacOSXDbgMsg("ATSUGetGlyphBounds: %s output", + numBounds < 1 ? "No " : "More"); } #endif @@ -1466,58 +1176,57 @@ MeasureStringWidth( * * UpdateLineBuffer -- * - * See the general dicussion of TK_MAC_COALESCE_LINE on the header - * pages. This function maintains the data for this feature. + * See the general dicussion of TK_MAC_COALESCE_LINE on the header + * pages. This function maintains the data for this feature. * * Results: * - * The Tcl_UniChar string of the whole line as seen so far. + * The Tcl_UniChar string of the whole line as seen so far. * * Side effects: + * "*offset" is filled with the index of the first new character in + * "currentLine". The globals currentLine, currentY, currentLeft, + * currentRight and currentFontPtr are updated as necessary. * - * "*offset" is filled with the index of the first new character in - * "currentLine". The globals currentLine, currentY, currentLeft, - * currentRight and currentFontPtr are updated as necessary. - * - * The currentLine string is set as the current text in - * fontPtr->atsuLayout (see TkMacOSXLayoutSetString()). + * The currentLine string is set as the current text in + * fontPtr->atsuLayout (see LayoutSetString()). * *------------------------------------------------------------------------- */ static const Tcl_UniChar * UpdateLineBuffer( - const MacFont * fontPtr,/* The font to be used for the new piece of - * text. */ - const DrawingContext * drawingContextPtr, - /* The Quarz drawing parameters. Needed for - * measuring the new piece. */ - const char * source, /* A new piece of line to be added. */ - int numBytes, /* Length of the new piece. */ - int x, int y, /* Position of the new piece in the window. */ - int * offset) /* Filled with the offset of the new piece in - * currentLine. */ + const MacFont *fontPtr, /* The font to be used for the new piece of + * text. */ + const TkMacOSXDrawingContext *drawingContextPtr, + /* The Quarz drawing parameters. Needed for + * measuring the new piece. */ + const char *source, /* A new piece of line to be added. */ + int numBytes, /* Length of the new piece. */ + int x, int y, /* Position of the new piece in the window. */ + int *offset) /* Filled with the offset of the new piece in + * currentLine. */ { const Tcl_UniChar * uchars; int ulen; if (y != currentY - || x < currentRight-1 || x > currentRight+2 - || currentFontPtr != fontPtr) { - Tcl_DStringFree(¤tLine); - Tcl_DStringInit(¤tLine); - currentY = y; - currentLeft = x; - currentFontPtr = fontPtr; - *offset = 0; + || x < currentRight-1 || x > currentRight+2 + || currentFontPtr != fontPtr) { + Tcl_DStringFree(¤tLine); + Tcl_DStringInit(¤tLine); + currentY = y; + currentLeft = x; + currentFontPtr = fontPtr; + *offset = 0; } else { - *offset = Tcl_DStringLength(¤tLine) / 2; + *offset = Tcl_DStringLength(¤tLine) / 2; } Tcl_UtfToUniCharDString(source, numBytes, ¤tLine); uchars = (const Tcl_UniChar*) Tcl_DStringValue(¤tLine); ulen = Tcl_DStringLength(¤tLine) / sizeof(*uchars); - TkMacOSXLayoutSetString(fontPtr, drawingContextPtr, uchars, ulen); + LayoutSetString(fontPtr, drawingContextPtr, uchars, ulen); currentRight = x + MeasureStringWidth(fontPtr, *offset, ulen); return uchars; @@ -1529,33 +1238,33 @@ UpdateLineBuffer( * * InitFont -- * - * Helper for TkpGetNativeFont() and TkpGetFontFromAttributes(). - * Initializes the memory for a MacFont that wraps the - * platform-specific data. + * Helper for TkpGetNativeFont() and TkpGetFontFromAttributes(). + * Initializes the memory for a MacFont that wraps the + * platform-specific data. * - * The caller is responsible for initializing the fields of the TkFont - * that are used exclusively by the generic TkFont code, and for - * releasing those fields before calling TkpDeleteFont(). + * The caller is responsible for initializing the fields of the TkFont + * that are used exclusively by the generic TkFont code, and for + * releasing those fields before calling TkpDeleteFont(). * * Results: - * Fills the MacFont structure. + * Fills the MacFont structure. * * Side effects: - * Memory allocated. + * Memory allocated. * *--------------------------------------------------------------------------- */ static void InitFont( - Tk_Window tkwin, /* For display where font will be used. */ - FMFontFamily familyId, /* The font family to initialize for. */ - const char * familyName,/* The font family name, if known. Otherwise - * this can be NULL. */ - int size, /* Point size for the font. */ - int qdStyle, /* QuickDraw style bits. */ - MacFont * fontPtr) /* Filled with information constructed from the - * above arguments. */ + Tk_Window tkwin, /* For display where font will be used. */ + FMFontFamily familyId, /* The font family to initialize for. */ + const char * familyName, /* The font family name, if known. Otherwise + * this can be NULL. */ + int size, /* Point size for the font. */ + int qdStyle, /* QuickDraw style bits. */ + MacFont * fontPtr) /* Filled with information constructed from the + * above arguments. */ { OSStatus err; FontInfo fi; @@ -1565,38 +1274,30 @@ InitFont( int periodWidth, wWidth; if (size == 0) { - size = GetDefFontSize(); + size = GetDefFontSize(); } points = (short) TkFontGetPoints(tkwin, size); - - err = FetchFontInfo(familyId, points, qdStyle, &fi); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "FetchFontInfo(): Error %d\n", (int) err); - } -#endif - + ChkErr(FetchFontInfo, familyId, points, qdStyle, &fi); if (familyName == NULL) { - char name[256] = ""; - const MacFontFamily * familyPtr; - - err = GetFontFamilyName(familyId, name, sizeof(name)); - if (err == noErr) { - - /* - * We find the canonical font name, so we can avoid unnecessary - * memory management. - */ - - familyPtr = FindFontFamily(name); - if (familyPtr != NULL) { - familyName = familyPtr->name; - } else { + char name[256] = ""; + const MacFontFamily * familyPtr; + + err = ChkErr(GetFontFamilyName, familyId, name, sizeof(name)); + if (err == noErr) { + /* + * We find the canonical font name, so we can avoid unnecessary + * memory management. + */ + + familyPtr = FindFontFamily(name); + if (familyPtr != NULL) { + familyName = familyPtr->name; + } else { #ifdef TK_MAC_DEBUG_FONTS - fprintf(stderr, "Font family '%s': Not found\n", name); + TkMacOSXDbgMsg("Font family '%s' not found", name); #endif - } - } + } + } } fontPtr->font.fid = (Font) fontPtr; @@ -1613,8 +1314,8 @@ InitFont( /* * Note: Macs measure the line height as ascent + descent + - * leading. Leading as a separate entity does not exist in X11 - * and Tk. We add it to the ascent at the moment, because adding + * leading. Leading as a separate entity does not exist in X11 + * and Tk. We add it to the ascent at the moment, because adding * it to the descent, as the Mac docs would indicate, would change * the position of self-drawn underlines. */ @@ -1627,9 +1328,8 @@ InitFont( fontPtr->qdSize = points; fontPtr->qdStyle = (short) qdStyle; - InitATSUObjects( - familyId, points, qdStyle, - &fontPtr->atsuFontId, &fontPtr->atsuLayout, &fontPtr->atsuStyle); + InitATSUObjects(familyId, points, qdStyle, &fontPtr->atsuFontId, + &fontPtr->atsuLayout, &fontPtr->atsuStyle); Tk_MeasureChars((Tk_Font)fontPtr, ".", 1, -1, 0, &periodWidth); Tk_MeasureChars((Tk_Font)fontPtr, "W", 1, -1, 0, &wWidth); @@ -1645,31 +1345,29 @@ InitFont( * * InitATSUObjects -- * - * Helper for InitFont(). Initializes the ATSU data handles for a - * MacFont. + * Helper for InitFont(). Initializes the ATSU data handles for a + * MacFont. * * Results: - * - * Sets up all we know and can do at this point in time in fontIdPtr, - * layoutPtr and stylePtr. + * Sets up all we know and can do at this point in time in fontIdPtr, + * layoutPtr and stylePtr. * * Side effects: - * - * Allocates data structures inside of ATSU. + * Allocates data structures inside of ATSU. * *--------------------------------------------------------------------------- */ static void InitATSUObjects( - FMFontFamily familyId, /* The font family to use. */ - short ptSize, short qdStyles, /* The additional font parameters. */ - ATSUFontID * fontIdPtr, /* Filled with the font id. */ - ATSUTextLayout * layoutPtr, /* Filled with the ATSU layout handle. */ - ATSUStyle * stylePtr) /* Filled with the ATSU style handle, - * configured with all parameters. */ + FMFontFamily familyId, /* The font family to use. */ + short ptSize, short qdStyles, + /* The additional font parameters. */ + ATSUFontID *fontIdPtr, /* Filled with the font id. */ + ATSUTextLayout *layoutPtr, /* Filled with the ATSU layout handle. */ + ATSUStyle *stylePtr) /* Filled with the ATSU style handle, + * configured with all parameters. */ { - OSStatus err; FMFontStyle stylesDone, stylesLeft; /* @@ -1684,14 +1382,8 @@ InitATSUObjects( * Generate a font id from family id and QD style bits. */ - err = FMGetFontFromFontFamilyInstance( - familyId, qdStyles, fontIdPtr, &stylesDone); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "FMGetFontFromFontFamilyInstance(): Error %d\n", - (int) err); - } -#endif + ChkErr(FMGetFontFromFontFamilyInstance, familyId, qdStyles, fontIdPtr, + &stylesDone); /* * We see what style bits are left and tell ATSU to synthesize what's @@ -1704,25 +1396,15 @@ InitATSUObjects( * Create the style and set its attributes. */ - err = ATSUCreateStyle(stylePtr); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "ATSUCreateStyle(): Error %d\n", (int) err); - } -#endif + ChkErr(ATSUCreateStyle, stylePtr); InitATSUStyle(*fontIdPtr, ptSize, stylesLeft, *stylePtr); /* - * Create the layout. Note: We can't set the layout attributes here, + * Create the layout. Note: We can't set the layout attributes here, * because the text and the style must be set first. */ - err = ATSUCreateTextLayout(layoutPtr); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "ATSUCreateTextLayout(): Error %d\n", (int) err); - } -#endif + ChkErr(ATSUCreateTextLayout, layoutPtr); /*InitATSULayout(*layoutPtr);*/ } @@ -1731,25 +1413,24 @@ InitATSUObjects( * * InitATSUStyle -- * - * Helper for InitATSUObjects(). Initializes the ATSU style for a - * MacFont. + * Helper for InitATSUObjects(). Initializes the ATSU style for a + * MacFont. * * Results: - * - * Sets up all parameters needed for an ATSU style. + * Sets up all parameters needed for an ATSU style. * * Side effects: - * - * Allocates data structures for the style inside of ATSU. + * Allocates data structures for the style inside of ATSU. * *--------------------------------------------------------------------------- */ static void InitATSUStyle( - ATSUFontID fontId, /* The font id to use. */ - short ptSize, short qdStyles, /* Additional font parameters. */ - ATSUStyle style) /* The style handle to configure. */ + ATSUFontID fontId, /* The font id to use. */ + short ptSize, short qdStyles, + /* Additional font parameters. */ + ATSUStyle style) /* The style handle to configure. */ { /* * Attributes for the style. @@ -1757,69 +1438,57 @@ InitATSUStyle( Fixed fsize = IntToFixed(ptSize); Boolean - isBold = (qdStyles&bold) != 0, - isUnderline = (qdStyles&underline) != 0, - isItalic = (qdStyles&italic) != 0; + isBold = (qdStyles&bold) != 0, + isUnderline = (qdStyles&underline) != 0, + isItalic = (qdStyles&italic) != 0; ATSStyleRenderingOptions options = - antialiasedTextEnabled == -1 ? kATSStyleNoOptions : - antialiasedTextEnabled == 0 ? kATSStyleNoAntiAliasing : - kATSStyleApplyAntiAliasing; + antialiasedTextEnabled == -1 ? kATSStyleNoOptions : + antialiasedTextEnabled == 0 ? kATSStyleNoAntiAliasing : + kATSStyleApplyAntiAliasing; static const ATSUAttributeTag styleTags[] = { - kATSUFontTag, kATSUSizeTag, - kATSUQDBoldfaceTag, kATSUQDItalicTag, kATSUQDUnderlineTag, - kATSUStyleRenderingOptionsTag, + kATSUFontTag, kATSUSizeTag, + kATSUQDBoldfaceTag, kATSUQDItalicTag, kATSUQDUnderlineTag, + kATSUStyleRenderingOptionsTag, }; static const ByteCount styleSizes[] = { - sizeof(ATSUFontID), sizeof(Fixed), - sizeof(Boolean), sizeof(Boolean), sizeof(Boolean), - sizeof(ATSStyleRenderingOptions), + sizeof(ATSUFontID), sizeof(Fixed), + sizeof(Boolean), sizeof(Boolean), sizeof(Boolean), + sizeof(ATSStyleRenderingOptions), }; const ATSUAttributeValuePtr styleValues[] = { - &fontId, &fsize, - &isBold, &isItalic, &isUnderline, - &options, + &fontId, &fsize, + &isBold, &isItalic, &isUnderline, + &options, }; - OSStatus err; - - err = ATSUSetAttributes( - style, - sizeof(styleTags)/sizeof(styleTags[0]), - styleTags, styleSizes, styleValues); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "ATSUSetAttributes(): Error %d\n", (int) err); - } -#endif + ChkErr(ATSUSetAttributes, style, sizeof(styleTags)/sizeof(styleTags[0]), + styleTags, styleSizes, styleValues); } - /* *--------------------------------------------------------------------------- * * SetFontFeatures -- * - * Helper for InitFont(). Request specific font features of the ATSU - * style object for a MacFont. + * Helper for InitFont(). Request specific font features of the ATSU + * style object for a MacFont. * * Results: - * - * None. + * None. * * Side effects: - * - * Specific font features are enabled on the ATSU style object. + * Specific font features are enabled on the ATSU style object. * *--------------------------------------------------------------------------- */ static void SetFontFeatures( - ATSUFontID fontId, /* The font id to use. */ - int fixed, /* Is this a fixed font? */ - ATSUStyle style) /* The style handle to configure. */ + ATSUFontID fontId, /* The font id to use. */ + int fixed, /* Is this a fixed font? */ + ATSUStyle style) /* The style handle to configure. */ { /* * Don't use the standard latin ligatures, if this is determined to be a @@ -1827,24 +1496,16 @@ SetFontFeatures( */ static const ATSUFontFeatureType fixed_featureTypes[] = { - kLigaturesType, kLigaturesType + kLigaturesType, kLigaturesType }; static const ATSUFontFeatureSelector fixed_featureSelectors[] = { - kCommonLigaturesOffSelector, kRareLigaturesOffSelector + kCommonLigaturesOffSelector, kRareLigaturesOffSelector }; - OSStatus err; - if (fixed) { - err = ATSUSetFontFeatures( - style, - sizeof(fixed_featureTypes)/sizeof(fixed_featureTypes[0]), - fixed_featureTypes, fixed_featureSelectors); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "ATSUSetFontFeatures(): Error %d\n", (int) err); - } -#endif + ChkErr(ATSUSetFontFeatures, style, sizeof(fixed_featureTypes) / + sizeof(fixed_featureTypes[0]), fixed_featureTypes, + fixed_featureSelectors); } } @@ -1853,17 +1514,15 @@ SetFontFeatures( * * AdjustFontHeight -- * - * Helper for InitFont(). Check font height against some real world - * examples. + * Helper for InitFont(). Check font height against some real world + * examples. * * Results: - * - * None. + * None. * * Side effects: - * - * The metrics in fontPtr->font.fm are adjusted so that typical combined - * characters fit into ascent+descent. + * The metrics in fontPtr->font.fm are adjusted so that typical combined + * characters fit into ascent+descent. * *--------------------------------------------------------------------------- */ @@ -1875,7 +1534,7 @@ AdjustFontHeight( /* * The standard values for ascent, descent and leading as determined in * InitFont do not take composition into account, they are designed for - * plain ASCII characters. This code measures the actual size of some + * plain ASCII characters. This code measures the actual size of some * typical composed characters from the Latin-1 range and corrects these * factors, especially the ascent. * @@ -1883,237 +1542,174 @@ AdjustFontHeight( * than requested. * * An alternative would be to instruct ATSU to shrink oversized combined - * characters. I think I have seen that feature somewhere, but I can't + * characters. I think I have seen that feature somewhere, but I can't * find it now [BR]. */ static const UniChar chars[] - /* Auml, Aacute, Acirc, Atilde, Ccedilla */ - = {0x00C4, 0x00C1, 0x00C2, 0x00C3, 0x00C7}; + /* Auml, Aacute, Acirc, Atilde, Ccedilla */ + = {0x00C4, 0x00C1, 0x00C2, 0x00C3, 0x00C7}; static const int charslen = sizeof(chars) / sizeof(chars[0]); - - DrawingContext drawingContext; Rect size; OSStatus err; - -#if TK_MAC_USE_QUARZ - TkMacOSXQuarzStartDraw(&drawingContext); -#endif - - TkMacOSXLayoutSetString(fontPtr, &drawingContext, chars, charslen); + LayoutSetString(fontPtr, NULL, chars, charslen); size.top = size.bottom = 0; - err = ATSUMeasureTextImage( - fontPtr->atsuLayout, - 0, charslen, - 0, 0, - &size); - -#if TK_MAC_USE_QUARZ - TkMacOSXQuarzEndDraw(&drawingContext); -#endif + err = ChkErr(ATSUMeasureTextImage, fontPtr->atsuLayout, 0, charslen, 0, 0, + &size); - if (err != noErr) { -#ifdef TK_MAC_DEBUG_FONTS - fprintf(stderr, "ATSUMeasureTextImage(): Error %d\n", (int) err); -#endif - } else { - TkFontMetrics * fmPtr = &fontPtr->font.fm; - int ascent = -size.top; - int descent = size.bottom; - - if (ascent > fmPtr->ascent) { - fmPtr->ascent = ascent; - } - if (descent > fmPtr->descent) { - fmPtr->descent = descent; - } + if (err == noErr) { + TkFontMetrics * fmPtr = &fontPtr->font.fm; + int ascent = -size.top; + int descent = size.bottom; + + if (ascent > fmPtr->ascent) { + fmPtr->ascent = ascent; + } + if (descent > fmPtr->descent) { + fmPtr->descent = descent; + } } } - /* *--------------------------------------------------------------------------- * * InitATSULayout -- * - * Helper for TkMacOSXLayoutSetString(). Initializes the ATSU layout - * object for a MacFont and a specific string. + * Helper for LayoutSetString(). Initializes the ATSU layout + * object for a MacFont and a specific string. * * Results: - * - * Sets up all parameters needed for an ATSU layout object. + * Sets up all parameters needed for an ATSU layout object. * * Side effects: - * - * Allocates data structures for the layout object inside of ATSU. + * Allocates data structures for the layout object inside of ATSU. * * Assumptions: - * - * The actual string data and style information is already set by - * ATSUSetTextPointerLocation() and ATSUSetRunStyle() (see - * TkMacOSXLayoutSetString()). + * The actual string data and style information is already set by + * ATSUSetTextPointerLocation() and ATSUSetRunStyle() (see + * LayoutSetString()). * *--------------------------------------------------------------------------- */ static void InitATSULayout( - const DrawingContext * drawingContextPtr, - /* Specifies the CGContext to use. */ - ATSUTextLayout layout, /* The layout object to configure. */ - int fixed) /* Is this a fixed font? */ + const TkMacOSXDrawingContext *drawingContextPtr, + /* Specifies the CGContext to use. */ + ATSUTextLayout layout, /* The layout object to configure. */ + int fixed) /* Is this a fixed font? */ { /* * Attributes for the layout. */ - ATSLineLayoutOptions layoutOptions = - 0 + ATSLineLayoutOptions layoutOptions = 0 #if TK_MAC_COALESCE_LINE - /* - * Options to use unconditionally, when we try to do coalescing in here. - */ - | kATSLineDisableAllLayoutOperations - | kATSLineFractDisable - | kATSLineUseDeviceMetrics + /* + * Options to use unconditionally when we try to do coalescing. + */ + | kATSLineDisableAllLayoutOperations + | kATSLineFractDisable + | kATSLineUseDeviceMetrics #endif - ; + ; + CGContextRef context = drawingContextPtr ? + drawingContextPtr->context : NULL; static const ATSUAttributeTag layoutTags[] = { -#if TK_MAC_USE_QUARZ - kATSUCGContextTag, -#endif - kATSULineLayoutOptionsTag, + kATSUCGContextTag, + kATSULineLayoutOptionsTag, }; static const ByteCount layoutSizes[] = { -#if TK_MAC_USE_QUARZ - sizeof(CGContextRef), -#endif - sizeof(ATSLineLayoutOptions), + sizeof(CGContextRef), + sizeof(ATSLineLayoutOptions), }; const ATSUAttributeValuePtr layoutValues[] = { -#if TK_MAC_USE_QUARZ - (void*)&drawingContextPtr->cgContext, -#endif - &layoutOptions, + &context, + &layoutOptions, }; - OSStatus err; - /* * Ensure W(abcdefg) == W(a)*7 for fixed fonts (Latin scripts only). */ if (fixed) { - layoutOptions |= - kATSLineFractDisable - | kATSLineUseDeviceMetrics - ; - } - - err = ATSUSetLayoutControls( - layout, - sizeof(layoutTags)/sizeof(layoutTags[0]), - layoutTags, layoutSizes, layoutValues); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "ATSUSetLayoutControls(): Error %d\n", (int) err); + layoutOptions |= kATSLineFractDisable | kATSLineUseDeviceMetrics; } -#endif - err = ATSUSetTransientFontMatching(layout, true); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "ATSUSetTransientFontMatching(): Error %d\n", - (int) err); - } -#endif + ChkErr(ATSUSetLayoutControls, layout, sizeof(layoutTags) / + sizeof(layoutTags[0]), layoutTags, layoutSizes, layoutValues); + ChkErr(ATSUSetTransientFontMatching, layout, true); } /* *--------------------------------------------------------------------------- * - * TkMacOSXLayoutSetString -- + * LayoutSetString -- * - * Setup the MacFont for a specific string. + * Setup the MacFont for a specific string. * * Results: - * - * Sets up all parameters so that ATSU can work with the objects in - * MacFont. + * Sets up all parameters so that ATSU can work with the objects in + * MacFont. * * Side effects: - * - * Sets parameters on the layout object fontPtr->atsuLayout. + * Sets parameters on the layout object fontPtr->atsuLayout. * *--------------------------------------------------------------------------- */ void -TkMacOSXLayoutSetString( - const MacFont * fontPtr, /* The fontPtr to configure. */ - const DrawingContext * drawingContextPtr, - /* For the CGContext to be used.*/ - const UniChar * uchars, int ulen) /* The UniChar string to set into - * fontPtr->atsuLayout. */ +LayoutSetString( + const MacFont *fontPtr, /* The fontPtr to configure. */ + const TkMacOSXDrawingContext *drawingContextPtr, + /* For the CGContext to be used.*/ + const UniChar *uchars, int ulen) + /* The UniChar string to set into + * fontPtr->atsuLayout. */ { - OSStatus err; - err = ATSUSetTextPointerLocation( - fontPtr->atsuLayout, - uchars, kATSUFromTextBeginning, ulen, - ulen); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "ATSUSetTextPointerLocation(): Error %d\n", (int) err); - } -#endif + ChkErr(ATSUSetTextPointerLocation, fontPtr->atsuLayout, uchars, + kATSUFromTextBeginning, ulen, ulen); /* * Styles can only be set after the text is set. */ - err = ATSUSetRunStyle( - fontPtr->atsuLayout, fontPtr->atsuStyle, - kATSUFromTextBeginning, kATSUToTextEnd); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "ATSUSetRunStyle(): Error %d\n", (int) err); - } -#endif + ChkErr(ATSUSetRunStyle, fontPtr->atsuLayout, fontPtr->atsuStyle, + kATSUFromTextBeginning, kATSUToTextEnd); /* * Layout attributes can only be set after the styles are set. */ - InitATSULayout( - drawingContextPtr, fontPtr->atsuLayout, - fontPtr->font.fm.fixed); + InitATSULayout(drawingContextPtr, fontPtr->atsuLayout, + fontPtr->font.fm.fixed); } - /* *------------------------------------------------------------------------- * * ReleaseFont -- * - * Called to release the Macintosh-specific contents of a TkFont. The - * caller is responsible for freeing the memory used by the font - * itself. + * Called to release the Macintosh-specific contents of a TkFont. The + * caller is responsible for freeing the memory used by the font + * itself. * * Results: - * None. + * None. * * Side effects: - * Memory is freed. + * Memory is freed. * *--------------------------------------------------------------------------- */ static void ReleaseFont( - MacFont * fontPtr) /* The font to delete. */ + MacFont *fontPtr) /* The font to delete. */ { ATSUDisposeTextLayout(fontPtr->atsuLayout); ATSUDisposeStyle(fontPtr->atsuStyle); @@ -2124,40 +1720,40 @@ ReleaseFont( * * FindFontFamilyOrAlias, FindFontFamilyOrAliasOrFallback -- * - * Determine if any physical screen font exists on the system with The - * given family name. If the family exists, then it should be possible - * to construct some physical screen font with that family name. + * Determine if any physical screen font exists on the system with the + * given family name. If the family exists, then it should be possible + * to construct some physical screen font with that family name. * - * FindFontFamilyOrAlias also considers font aliases as determined by - * TkFontGetAliasList(). + * FindFontFamilyOrAlias also considers font aliases as determined by + * TkFontGetAliasList(). * - * FindFontFamilyOrAliasOrFallback also considers font aliases as - * determined by TkFontGetFallbacks(). + * FindFontFamilyOrAliasOrFallback also considers font aliases as + * determined by TkFontGetFallbacks(). * - * The overall algorithm to get the closest font to the one requested is - * this: + * The overall algorithm to get the closest font to the one requested is + * this: * - * try fontname - * try all aliases for fontname - * foreach fallback for fontname - * try the fallback - * try all aliases for the fallback + * try fontname + * try all aliases for fontname + * foreach fallback for fontname + * try the fallback + * try all aliases for the fallback * * Results: * - * The return value is NULL if the specified font family does not exist, - * a valid MacFontFamily* otherwise. + * The return value is NULL if the specified font family does not exist, + * a valid MacFontFamily* otherwise. * * Side effects: * - * None. + * None. * *------------------------------------------------------------------------- */ static const MacFontFamily * FindFontFamilyOrAlias( - const char * name) /* Name or alias name of the font to find. */ + const char *name) /* Name or alias name of the font to find. */ { const MacFontFamily * familyPtr; char ** aliases; @@ -2165,24 +1761,24 @@ FindFontFamilyOrAlias( familyPtr = FindFontFamily(name); if (familyPtr != NULL) { - return familyPtr; + return familyPtr; } aliases = TkFontGetAliasList(name); if (aliases != NULL) { - for (i = 0; aliases[i] != NULL; i++) { - familyPtr = FindFontFamily(aliases[i]); - if (familyPtr != NULL) { - return familyPtr; - } - } + for (i = 0; aliases[i] != NULL; i++) { + familyPtr = FindFontFamily(aliases[i]); + if (familyPtr != NULL) { + return familyPtr; + } + } } return NULL; } - + static const MacFontFamily * FindFontFamilyOrAliasOrFallback( - const char * name) /* Name or alias name of the font to find. */ + const char *name) /* Name or alias name of the font to find. */ { const MacFontFamily * familyPtr; const char * fallback; @@ -2191,36 +1787,36 @@ FindFontFamilyOrAliasOrFallback( familyPtr = FindFontFamilyOrAlias(name); if (familyPtr != NULL) { - return familyPtr; + return familyPtr; } fallbacks = TkFontGetFallbacks(); for (i = 0; fallbacks[i] != NULL; i++) { - for (j = 0; (fallback = fallbacks[i][j]) != NULL; j++) { - if (strcasecmp(name, fallback) == 0) { - for (j = 0; (fallback = fallbacks[i][j]) != NULL; j++) { - familyPtr = FindFontFamilyOrAlias(fallback); - if (familyPtr != NULL) { - return familyPtr; - } - } - } - break; /* benny: This "break" is a carry-over from - * tkMacOSXFont.c, but what is actually its purpose - * ???? */ - } + for (j = 0; (fallback = fallbacks[i][j]) != NULL; j++) { + if (strcasecmp(name, fallback) == 0) { + for (j = 0; (fallback = fallbacks[i][j]) != NULL; j++) { + familyPtr = FindFontFamilyOrAlias(fallback); + if (familyPtr != NULL) { + return familyPtr; + } + } + } + break; /* benny: This "break" is a carry-over from + * tkMacOSXFont.c, but what is actually its purpose + * ???? */ + } } /* - * FIXME: We would have liked to recover by re-enumerating fonts. But + * FIXME: We would have liked to recover by re-enumerating fonts. But * that doesn't work, because Carbon seems to cache the inital list of - * fonts. Fonts newly installed don't show up with + * fonts. Fonts newly installed don't show up with * FMCreateFontFamilyIterator()/FMGetNextFontFamily() without a restart - * of the app. Similar problem with fonts removed. + * of the app. Similar problem with fonts removed. */ #ifdef TK_MAC_DEBUG_FONTS - fprintf(stderr, "Font family '%s': Not found\n", name); + TkMacOSXDbgMsg("Font family '%s' not found", name); #endif return NULL; @@ -2231,16 +1827,16 @@ FindFontFamilyOrAliasOrFallback( * * InitFontFamilies -- * - * Helper to TkpFontPkgInit. Use the Font Manager to fill in the - * familyList global array. + * Helper to TkpFontPkgInit. Use the Font Manager to fill in the + * familyList global array. * * Results: * - * None. + * None. * * Side effects: * - * Allocates memory. + * Allocates memory. * *------------------------------------------------------------------------- */ @@ -2248,32 +1844,58 @@ FindFontFamilyOrAliasOrFallback( static void InitFontFamilies(void) { - OSStatus err; + FMFontFamily fontFamily; + Str255 fontName; + SInt16 fontSize; + Style fontStyle; /* * Has this been called before? */ if (familyListNextFree > 0) { - return; + return; } - err = ATSFontFamilyApplyFunction(FontFamilyEnumCallback,NULL); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "ATSFontFamilyApplyFunction(): Error %d\n", (int) err); - } -#endif + ChkErr(ATSFontFamilyApplyFunction, FontFamilyEnumCallback,NULL); - AddFontFamily(APPLFONT_NAME, GetAppFont()); - AddFontFamily(SYSTEMFONT_NAME, GetSysFont()); + if (GetThemeFontAndFamily(kThemeSystemFont, &fontFamily, fontName, + &fontSize, &fontStyle) == noErr) { + AddFontFamily(SYSTEMFONT_NAME, fontFamily); + } + if (GetThemeFontAndFamily(kThemeApplicationFont, &fontFamily, fontName, + &fontSize, &fontStyle) == noErr) { + AddFontFamily(APPLFONT_NAME, fontFamily); + } + if (GetThemeFontAndFamily(kThemeMenuItemFont, &fontFamily, fontName, + &fontSize, &fontStyle) == noErr) { + AddFontFamily(MENUITEMFONT_NAME, fontFamily); + } SortFontFamilies(); } + +/* + *------------------------------------------------------------------------- + * + * FontFamilyEnumCallback -- + * + * Callback for ATSFontFamilyApplyFunction(). + * + * Results: + * + * noErr. + * + * Side effects: + * + * None. + * + *------------------------------------------------------------------------- + */ static OSStatus FontFamilyEnumCallback( - ATSFontFamilyRef family, + ATSFontFamilyRef family, void *refCon) { OSStatus err; @@ -2281,42 +1903,41 @@ FontFamilyEnumCallback( (void) refCon; - err = GetFontFamilyName(family, name, sizeof(name)); + err = ChkErr(GetFontFamilyName, family, name, sizeof(name)); if (err == noErr) { - AddFontFamily(name, family); + AddFontFamily(name, family); } return noErr; } - /* *------------------------------------------------------------------------- * * GetFontFamilyName -- * - * Use the Font Manager to get the name of a given FMFontfamily. This - * currently gets the standard, non-localized QuickDraw name. Other - * names would be possible, see docs for ATSUFindFontName for a - * selection. The MacOSX font selector seems to use the localized - * family name given by ATSUFindFontName(kFontFamilyName), but that API - * doesn't give us a name at all for some fonts. + * Use the Font Manager to get the name of a given FMFontfamily. This + * currently gets the standard, non-localized QuickDraw name. Other + * names would be possible, see docs for ATSUFindFontName for a + * selection. The MacOSX font selector seems to use the localized + * family name given by ATSUFindFontName(kFontFamilyName), but that API + * doesn't give us a name at all for some fonts. * * Results: - * An OS error code, noErr on success. name is filled with the - * resulting name. + * An OS error code, noErr on success. name is filled with the + * resulting name. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static OSStatus GetFontFamilyName( - FMFontFamily fontFamily, /* The font family for which to find the - * name. */ - char * name, int numBytes) /* Filled with the result. */ + FMFontFamily fontFamily, /* The font family for which to find the + * name. */ + char * name, int numBytes) /* Filled with the result. */ { OSStatus err; Str255 nativeName; @@ -2326,13 +1947,9 @@ GetFontFamilyName( nativeName[0] = 0; name[0] = 0; - - err = FMGetFontFamilyName(fontFamily, nativeName); + err = ChkErr(FMGetFontFamilyName, fontFamily, nativeName); if (err != noErr) { -#ifdef TK_MAC_DEBUG_FONTS - fprintf(stderr, "FMGetFontFamilyName(): Error %d\n", (int) err); -#endif - return err; + return err; } /* @@ -2341,36 +1958,25 @@ GetFontFamilyName( */ encoding = kTextEncodingMacRoman; - err = FMGetFontFamilyTextEncoding(fontFamily, &encoding); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "FMGetFontFamilyTextEncoding(): Error %d\n", (int) err); - } -#endif - + ChkErr(FMGetFontFamilyTextEncoding, fontFamily, &encoding); nameencoding = encoding; - err = RevertTextEncodingToScriptInfo(encoding, &nameencoding, NULL, NULL); -#ifdef TK_MAC_DEBUG_FONTS - if (err != noErr) { - fprintf(stderr, "RevertTextEncodingToScriptInfo(): Error %d\n", - (int) err); - } -#endif + ChkErr(RevertTextEncodingToScriptInfo, encoding, &nameencoding, NULL, + NULL); /* - * Note: We could use Tcl facilities to do the re-encoding here. We'd + * Note: We could use Tcl facilities to do the re-encoding here. We'd * have to maintain tables to map OS encoding codes to Tcl encoding names - * like tkMacOSXFont.c did. Using native re-encoding directly instead is - * a lot easier and future-proof than that. There is one snag, though: I - * have seen CFStringGetCString() crash with invalid encoding ids. But + * like tkMacOSXFont.c did. Using native re-encoding directly instead is + * a lot easier and future-proof than that. There is one snag, though: I + * have seen CFStringGetCString() crash with invalid encoding ids. But * than if that happens it would be a bug in * FMGetFontFamilyTextEncoding() or RevertTextEncodingToScriptInfo(). */ cfString = CFStringCreateWithPascalStringNoCopy( - NULL, nativeName, nameencoding, kCFAllocatorNull); + NULL, nativeName, nameencoding, kCFAllocatorNull); CFStringGetCString( - cfString, name, numBytes, kCFStringEncodingUTF8); + cfString, name, numBytes, kCFStringEncodingUTF8); CFRelease(cfString); return noErr; @@ -2381,41 +1987,39 @@ GetFontFamilyName( * * FindFontFamily -- * - * Find the font family with the given name in the global familyList. - * Uses bsearch() for convenient access. Comparision is done - * non-case-sensitively with CompareFontFamilies() which see. + * Find the font family with the given name in the global familyList. + * Uses bsearch() for convenient access. Comparision is done + * non-case-sensitively with CompareFontFamilies() which see. * * Results: * - * MacFontFamily: A pair of family id and the actual name registered for - * the font. + * MacFontFamily: A pair of family id and the actual name registered for + * the font. * * Side effects: * - * None. + * None. * * Assumption: * - * Requires the familyList array to be sorted. + * Requires the familyList array to be sorted. * *------------------------------------------------------------------------- */ static const MacFontFamily * FindFontFamily( - const char * name) /* The family name. Note: Names are compared - * non-case-sensitive. */ + const char *name) /* The family name. Note: Names are compared + * non-case-sensitive. */ { const MacFontFamily key = {name,-1}; if(familyListMaxValid <= 0) { - return NULL; + return NULL; } - return bsearch( - &key, - familyList, familyListMaxValid, sizeof(*familyList), - CompareFontFamilies); + return bsearch(&key, familyList, familyListMaxValid, sizeof(*familyList), + CompareFontFamilies); } /* @@ -2423,15 +2027,13 @@ FindFontFamily( * * EnumFontFamilies -- * - * Create a Tcl list with the registered names in the global familyList. + * Create a Tcl list with the registered names in the global familyList. * * Results: - * - * A Tcl list of names. + * A Tcl list of names. * * Side effects: - * - * None. + * None. * *------------------------------------------------------------------------- */ @@ -2444,8 +2046,8 @@ EnumFontFamilies(void) tclList = Tcl_NewListObj(0, NULL); for (i=0; i<familyListMaxValid; ++i) { - Tcl_ListObjAppendElement( - NULL, tclList, Tcl_NewStringObj(familyList[i].name, -1)); + Tcl_ListObjAppendElement(NULL, tclList, + Tcl_NewStringObj(familyList[i].name, -1)); } return tclList; @@ -2456,33 +2058,32 @@ EnumFontFamilies(void) * * AddFontFamily -- * - * Register a font family in familyList. Until SortFontFamilies() is - * called, this is not actually available for FindFontFamily(). + * Register a font family in familyList. Until SortFontFamilies() is + * called, this is not actually available for FindFontFamily(). * * Results: * - * MacFontFamily: The new pair of family id and the actual name - * registered for the font. + * MacFontFamily: The new pair of family id and the actual name + * registered for the font. * * Side effects: * - * New entry in familyList and familyListNextFree updated. + * New entry in familyList and familyListNextFree updated. * *------------------------------------------------------------------------- */ static const MacFontFamily * AddFontFamily( - const char * name, /* Font family name to register. */ - FMFontFamily familyId) /* Font family id to register. */ + const char *name, /* Font family name to register. */ + FMFontFamily familyId) /* Font family id to register. */ { MacFontFamily * familyPtr; if (familyListNextFree >= familyListSize) { - familyListSize += 100; - familyList = (MacFontFamily *) ckrealloc( - (void*) familyList, - familyListSize * sizeof(*familyList)); + familyListSize += 100; + familyList = (MacFontFamily *) ckrealloc((void*) familyList, + familyListSize * sizeof(*familyList)); } familyPtr = familyList + familyListNextFree; @@ -2499,18 +2100,18 @@ AddFontFamily( * * SortFontFamilies -- * - * Sort the entries in familyList. Only after calling - * SortFontFamilies(), the new families registered with AddFontFamily() - * are actually available for FindFontFamily(), because FindFontFamily() - * requires the array to be sorted. + * Sort the entries in familyList. Only after calling + * SortFontFamilies(), the new families registered with AddFontFamily() + * are actually available for FindFontFamily(), because FindFontFamily() + * requires the array to be sorted. * * Results: * - * None. + * None. * * Side effects: * - * familyList is sorted and familyListMaxValid is updated. + * familyList is sorted and familyListMaxValid is updated. * *------------------------------------------------------------------------- */ @@ -2519,8 +2120,8 @@ static void SortFontFamilies(void) { if (familyListNextFree > 0) { - qsort( familyList, familyListNextFree, sizeof(*familyList), - CompareFontFamilies); + qsort(familyList, familyListNextFree, sizeof(*familyList), + CompareFontFamilies); } familyListMaxValid = familyListNextFree; } @@ -2530,21 +2131,19 @@ SortFontFamilies(void) * * CompareFontFamilies -- * - * Comparison function used by SortFontFamilies() and FindFontFamily(). + * Comparison function used by SortFontFamilies() and FindFontFamily(). * * Results: + * Result as required to generate a stable sort order for bsearch() and + * qsort(). The ordering is not case-sensitive as far as + * Tcl_UtfNcasecmp() (which see) can provide that. * - * Result as required to generate a stable sort order for bsearch() and - * qsort(). The ordering is not case-sensitive as far as - * Tcl_UtfNcasecmp() (which see) can provide that. - * - * Note: It would be faster to compare first the length and the actual - * strings only as a tie-breaker, but than the ordering wouldn't look so - * pretty in [font families] ;-). + * Note: It would be faster to compare first the length and the actual + * strings only as a tie-breaker, but than the ordering wouldn't look so + * pretty in [font families] ;-). * * Side effects: - * - * None. + * None. * *------------------------------------------------------------------------- */ @@ -2556,9 +2155,7 @@ CompareFontFamilies( { const char * name1; const char * name2; - int len1; - int len2; - int diff; + int len1, len2, diff; name1 = ((const MacFontFamily *) vp1)->name; name2 = ((const MacFontFamily *) vp2)->name; @@ -2576,36 +2173,34 @@ CompareFontFamilies( * * AddString -- * - * Helper for AddFontFamily(). Allocates a string in the one-shot - * allocator. + * Helper for AddFontFamily(). Allocates a string in the one-shot + * allocator. * * Results: - * - * A duplicated string in the one-shot allocator. + * A duplicated string in the one-shot allocator. * * Side effects: - * - * May allocate a new memory block. + * May allocate a new memory block. * *------------------------------------------------------------------------- */ static const char * AddString( - const char * in) /* String to add, zero-terminated. */ + const char *in) /* String to add, zero-terminated. */ { int len; - char * result; - + char *result; + len = strlen(in) +1; if (stringMemory == NULL - || (stringMemory->nextFree+len) > STRING_BLOCK_MAX ) { - StringBlock * newblock = - (StringBlock *) ckalloc(sizeof(StringBlock)); - newblock->next = stringMemory; - newblock->nextFree = 0; - stringMemory = newblock; + || (stringMemory->nextFree+len) > STRING_BLOCK_MAX) { + StringBlock * newblock = (StringBlock *) ckalloc(sizeof(StringBlock)); + + newblock->next = stringMemory; + newblock->nextFree = 0; + stringMemory = newblock; } result = stringMemory->strings + stringMemory->nextFree; @@ -2621,27 +2216,27 @@ AddString( * * TkMacOSXIsCharacterMissing -- * - * Given a tkFont and a character determine whether the character has - * a glyph defined in the font or not. + * Given a tkFont and a character determine whether the character has + * a glyph defined in the font or not. * * Results: - * Returns a 1 if the character is missing, a 0 if it is not. + * Returns a 1 if the character is missing, a 0 if it is not. * * Side effects: - * None. + * None. * *--------------------------------------------------------------------------- */ int TkMacOSXIsCharacterMissing( - Tk_Font tkfont, /* The font we are looking in. */ - unsigned int searchChar) /* The character we are looking for. */ + Tk_Font tkfont, /* The font we are looking in. */ + unsigned int searchChar) /* The character we are looking for. */ { /* Background: This function is private and only used in * tkMacOSXMenu.c:FindMarkCharacter(). * - * We could use ATSUMatchFont() to implement. We'd have to change the + * We could use ATSUMatchFont() to implement. We'd have to change the * definition of the encoding of the parameter searchChar from MacRoman * to UniChar for that. * @@ -2656,30 +2251,27 @@ TkMacOSXIsCharacterMissing( * * TkMacOSXInitControlFontStyle -- * - * This procedure sets up the appropriate ControlFontStyleRec - * for a Mac control. + * This procedure sets up the appropriate ControlFontStyleRec + * for a Mac control. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ void TkMacOSXInitControlFontStyle( - Tk_Font tkfont, /* Tk font object to use for the control. */ - ControlFontStylePtr fsPtr) /* The style object to configure. */ + Tk_Font tkfont, /* Tk font object to use for the control. */ + ControlFontStylePtr fsPtr) /* The style object to configure. */ { - const MacFont * fontPtr; - fontPtr = (MacFont *) tkfont; - fsPtr->flags = - kControlUseFontMask| - kControlUseSizeMask| - kControlUseFaceMask| - kControlUseJustMask; + const MacFont * fontPtr = (MacFont *) tkfont; + + fsPtr->flags = kControlUseFontMask | kControlUseSizeMask | + kControlUseFaceMask | kControlUseJustMask; fsPtr->font = fontPtr->qdFont; fsPtr->size = fontPtr->qdSize; fsPtr->style = fontPtr->qdStyle; @@ -2691,46 +2283,46 @@ TkMacOSXInitControlFontStyle( * * TkMacOSXUseAntialiasedText -- * - * Enables or disables application-wide use of antialiased text (where - * available). Sets up a linked Tcl global variable to allow - * disabling of antialiased text from tcl. - * The possible values for this variable are: + * Enables or disables application-wide use of antialiased text (where + * available). Sets up a linked Tcl global variable to allow + * disabling of antialiased text from tcl. + * The possible values for this variable are: * - * -1 - Use system default as configurable in "System Preferences" -> - * "General". - * 0 - Unconditionally disable antialiasing. - * 1 - Unconditionally enable antialiasing. + * -1 - Use system default as configurable in "System Preferences" -> + * "General". + * 0 - Unconditionally disable antialiasing. + * 1 - Unconditionally enable antialiasing. * * Results: * - * TCL_OK. + * TCL_OK. * * Side effects: * - * None. + * None. * *---------------------------------------------------------------------- */ MODULE_SCOPE int TkMacOSXUseAntialiasedText( - Tcl_Interp * interp, /* The Tcl interpreter to receive the - * variable .*/ - int enable) /* Initial value. */ + Tcl_Interp * interp, /* The Tcl interpreter to receive the + * variable.*/ + int enable) /* Initial value. */ { static Boolean initialized = FALSE; - if(!initialized) { - initialized = TRUE; - - if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) { - Tcl_ResetResult(interp); - } - if (Tcl_LinkVar(interp, "::tk::mac::antialiasedtext", - (char *) &antialiasedTextEnabled, - TCL_LINK_INT) != TCL_OK) { - Tcl_ResetResult(interp); - } + if (!initialized) { + initialized = TRUE; + + if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) { + Tcl_ResetResult(interp); + } + if (Tcl_LinkVar(interp, "::tk::mac::antialiasedtext", + (char *) &antialiasedTextEnabled, + TCL_LINK_INT) != TCL_OK) { + Tcl_ResetResult(interp); + } } antialiasedTextEnabled = enable; return TCL_OK; diff --git a/macosx/tkMacOSXFont.h b/macosx/tkMacOSXFont.h index 22555a5..56c0bbc 100644 --- a/macosx/tkMacOSXFont.h +++ b/macosx/tkMacOSXFont.h @@ -1,19 +1,22 @@ /* * tkMacOSXFont.h -- * - * Private functions and structs exported from tkMacOSXFont.c - * for use in ATSU specific extensions. + * Contains the Macintosh implementation of the platform-independant + * font package interface. * - * Copyright 2002-2004 Benjamin Riefenstahl, Benjamin.Riefenstahl@epost.de + * Copyright (c) 1990-1994 The Regents of the University of California. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXFont.h,v 1.4 2006/04/28 06:02:48 das Exp $ + * RCS: @(#) $Id: tkMacOSXFont.h,v 1.5 2007/04/23 21:24:33 das Exp $ */ -#ifndef TKMACOSXFONT_H -#define TKMACOSXFONT_H 1 +#ifndef TKMACOSXFONT_H +#define TKMACOSXFONT_H 1 #include "tkFont.h" @@ -22,93 +25,10 @@ #endif /* - * Switches - */ - -#define TK_MAC_USE_QUARZ 1 - -/* - * Types - */ - -/* - * The following structure represents our Macintosh-specific implementation - * of a font object. - */ - -typedef struct { - TkFont font; /* Stuff used by generic font package. Must - * be first in structure. */ - - /* - * The ATSU view of the font and other text properties. Used for drawing - * and measuring. - */ - - ATSUFontID atsuFontId; /* == FMFont. */ - ATSUTextLayout atsuLayout; /* ATSU layout object, representing the whole - * text that ATSU sees with some option - * bits. */ - ATSUStyle atsuStyle; /* ATSU style object, representing a run of - * text with the same properties. */ - - /* - * The QuickDraw view of the font. Used to configure controls. - */ - - FMFontFamily qdFont; /* == FMFontFamilyId, Carbon replacement for - * QD face numbers. */ - short qdSize; /* Font size in points. */ - short qdStyle; /* QuickDraw style bits. */ -} TkMacOSXFont; - - -#if TK_MAC_USE_QUARZ - -/* - * To use Quarz drawing we need some additional context. FIXME: We would - * have liked to use the similar functions from tkMacOSXDraw.c to do this - * (TkMacOSXSetUpCGContext(), etc), but a) those don't quite work for us - * (e.g. we can't use a simple upside-down coordinate system transformation, - * as we don't want upside-down characters ;-), and b) we don't have the - * necessary context information (MacDrawable), that we need as parameter for - * those functions. So I just cobbled together a limited edition, getting - * the necessary parameters from the current QD GraphPort. - */ - -typedef struct { - CGContextRef cgContext; /* Quarz context. */ - CGrafPtr graphPort; /* QD graph port to which this belongs. - * Needed for releasing cgContext. */ - Rect portRect; /* Cached size of port. */ -} TkMacOSXFontDrawingContext; - -#else /* ! TK_MAC_USE_QUARZ */ - -/* - * Just a dummy, so we don't have to #ifdef the parameter lists of functions - * that use this. - */ - -typedef struct {} DrawingContext; - -#endif /* ? TK_MAC_USE_QUARZ */ - -/* * Function prototypes */ -MODULE_SCOPE void TkMacOSXLayoutSetString(const TkMacOSXFont * fontPtr, - const TkMacOSXFontDrawingContext *drawingContextPtr, - const UniChar * uchars, int ulen); -MODULE_SCOPE void TkMacOSXInitControlFontStyle(Tk_Font tkfont, - ControlFontStylePtr fsPtr); - -#if TK_MAC_USE_QUARZ -MODULE_SCOPE void TkMacOSXQuarzStartDraw( - TkMacOSXFontDrawingContext * contextPtr); -MODULE_SCOPE void TkMacOSXQuarzEndDraw( - TkMacOSXFontDrawingContext * contextPtr); -#endif /* TK_MAC_USE_QUARZ */ +MODULE_SCOPE void TkMacOSXInitControlFontStyle(Tk_Font tkfont, + ControlFontStylePtr fsPtr); -#endif /*TKMACOSXFONT_H*/ +#endif /*TKMACOSXFONT_H*/ diff --git a/macosx/tkMacOSXHLEvents.c b/macosx/tkMacOSXHLEvents.c index 4355316..850d80f 100644 --- a/macosx/tkMacOSXHLEvents.c +++ b/macosx/tkMacOSXHLEvents.c @@ -1,8 +1,8 @@ -/* +/* * tkMacOSXHLEvents.c -- * - * Implements high level event support for the Macintosh. Currently, - * the only event that really does anything is the Quit event. + * Implements high level event support for the Macintosh. Currently, + * the only event that really does anything is the Quit event. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. @@ -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: tkMacOSXHLEvents.c,v 1.12 2006/05/12 18:18:36 das Exp $ + * RCS: @(#) $Id: tkMacOSXHLEvents.c,v 1.13 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" @@ -20,12 +20,12 @@ * This is a Tcl_Event structure that the Quit AppleEvent handler * uses to schedule the ReallyKillMe function. */ - + typedef struct KillEvent { - Tcl_Event header; /* Information that is standard for - * all events. */ - Tcl_Interp *interp; /* Interp that was passed to the - * Quit AppleEvent */ + Tcl_Event header; /* Information that is standard for + * all events. */ + Tcl_Interp *interp; /* Interp that was passed to the + * Quit AppleEvent */ } KillEvent; /* @@ -49,68 +49,66 @@ static OSErr PrefsHandler(const AppleEvent * event, AppleEvent * reply, static int MissedAnyParameters(const AppleEvent *theEvent); static int ReallyKillMe(Tcl_Event *eventPtr, int flags); -static OSErr FSRefToDString(const FSRef *fsref, Tcl_DString *ds); +static OSStatus FSRefToDString(const FSRef *fsref, Tcl_DString *ds); /* *---------------------------------------------------------------------- * * TkMacOSXInitAppleEvents -- * - * Initilize the Apple Events on the Macintosh. This registers the - * core event handlers. + * Initilize the Apple Events on the Macintosh. This registers the + * core event handlers. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -void +void TkMacOSXInitAppleEvents( - Tcl_Interp *interp) /* Interp to handle basic events. */ + Tcl_Interp *interp) /* Interp to handle basic events. */ { - OSErr err; - AEEventHandlerUPP OappHandlerUPP, RappHandlerUPP, OdocHandlerUPP, - PrintHandlerUPP, QuitHandlerUPP, ScriptHandlerUPP, - PrefsHandlerUPP; + AEEventHandlerUPP OappHandlerUPP, RappHandlerUPP, OdocHandlerUPP, + PrintHandlerUPP, QuitHandlerUPP, ScriptHandlerUPP, PrefsHandlerUPP; static Boolean initialized = FALSE; if (!initialized) { - initialized = TRUE; + initialized = TRUE; /* * Install event handlers for the core apple events. */ QuitHandlerUPP = NewAEEventHandlerUPP(QuitHandler); - err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, + ChkErr(AEInstallEventHandler, kCoreEventClass, kAEQuitApplication, QuitHandlerUPP, (long) interp, false); OappHandlerUPP = NewAEEventHandlerUPP(OappHandler); - err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, + ChkErr(AEInstallEventHandler, kCoreEventClass, kAEOpenApplication, OappHandlerUPP, (long) interp, false); RappHandlerUPP = NewAEEventHandlerUPP(RappHandler); - err = AEInstallEventHandler(kCoreEventClass, kAEReopenApplication, + ChkErr(AEInstallEventHandler, kCoreEventClass, kAEReopenApplication, RappHandlerUPP, (long) interp, false); OdocHandlerUPP = NewAEEventHandlerUPP(OdocHandler); - err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, + ChkErr(AEInstallEventHandler, kCoreEventClass, kAEOpenDocuments, OdocHandlerUPP, (long) interp, false); PrintHandlerUPP = NewAEEventHandlerUPP(PrintHandler); - err = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, + ChkErr(AEInstallEventHandler, kCoreEventClass, kAEPrintDocuments, PrintHandlerUPP, (long) interp, false); PrefsHandlerUPP = NewAEEventHandlerUPP(PrefsHandler); - err = AEInstallEventHandler(kCoreEventClass, kAEShowPreferences, + ChkErr(AEInstallEventHandler, kCoreEventClass, kAEShowPreferences, PrefsHandlerUPP, (long) interp, false); if (interp) { ScriptHandlerUPP = NewAEEventHandlerUPP(ScriptHandler); - err = AEInstallEventHandler(kAEMiscStandards, kAEDoScript, + ChkErr(AEInstallEventHandler, kAEMiscStandards, kAEDoScript, ScriptHandlerUPP, (long) interp, false); } } @@ -121,13 +119,13 @@ TkMacOSXInitAppleEvents( * * TkMacOSXDoHLEvent -- * - * Dispatch incomming highlevel events. + * Dispatch incomming highlevel events. * * Results: - * None. + * None. * * Side effects: - * Depends on the incoming event. + * Depends on the incoming event. * *---------------------------------------------------------------------- */ @@ -142,46 +140,63 @@ TkMacOSXDoHLEvent( /* *---------------------------------------------------------------------- * - * QuitHandler, OappHandler, etc. -- + * QuitHandler -- * - * These are the core Apple event handlers. + * This is the 'quit' core Apple event handler. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -static OSErr -QuitHandler ( + +OSErr +QuitHandler( const AppleEvent * event, AppleEvent * reply, long handlerRefcon) { Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon; KillEvent *eventPtr; - + if (interp) { /* * Call the exit command from the event loop, since you are not supposed - * to call ExitToShell in an Apple Event Handler. We put this at the head + * to call ExitToShell in an Apple Event Handler. We put this at the head * of Tcl's event queue because this message usually comes when the Mac is * shutting down, and we want to kill the shell as quickly as possible. */ - + eventPtr = (KillEvent *) ckalloc(sizeof(KillEvent)); eventPtr->header.proc = ReallyKillMe; eventPtr->interp = interp; - + Tcl_QueueEvent((Tcl_Event *) eventPtr, TCL_QUEUE_HEAD); } return noErr; } -static OSErr -OappHandler ( +/* + *---------------------------------------------------------------------- + * + * OappHandler -- + * + * This is the 'oapp' core Apple event handler. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +OSErr +OappHandler( const AppleEvent * event, AppleEvent * reply, long handlerRefcon) @@ -196,8 +211,24 @@ OappHandler ( return noErr; } -static OSErr -RappHandler ( +/* + *---------------------------------------------------------------------- + * + * RappHandler -- + * + * This is the 'rapp' core Apple event handler. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +OSErr +RappHandler( const AppleEvent * event, AppleEvent * reply, long handlerRefcon) @@ -205,18 +236,34 @@ RappHandler ( Tcl_CmdInfo dummy; Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon; ProcessSerialNumber thePSN = {0, kCurrentProcess}; - OSStatus status = SetFrontProcess(&thePSN); - + OSStatus err = ChkErr(SetFrontProcess, &thePSN); + if (interp && Tcl_GetCommandInfo(interp, "::tk::mac::ReopenApplication", &dummy)) { Tcl_GlobalEval(interp, "::tk::mac::ReopenApplication"); } - return status; + return err; } -/* Called when the user selects 'Preferences...' in MacOS X */ -static OSErr -PrefsHandler ( +/* + *---------------------------------------------------------------------- + * + * PrefsHandler -- + * + * This is the 'pref' core Apple event handler. + * Called when the user selects 'Preferences...' in MacOS X + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +OSErr +PrefsHandler( const AppleEvent * event, AppleEvent * reply, long handlerRefcon) @@ -231,8 +278,24 @@ PrefsHandler ( return noErr; } -static OSErr -OdocHandler ( +/* + *---------------------------------------------------------------------- + * + * OdocHandler -- + * + * This is the 'odoc' core Apple event handler. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +OSErr +OdocHandler( const AppleEvent * event, AppleEvent * reply, long handlerRefcon) @@ -240,7 +303,7 @@ OdocHandler ( Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon; AEDescList fileSpecList; FSRef file; - OSErr err; + OSStatus err; DescType type; Size actual; long count; @@ -255,56 +318,73 @@ OdocHandler ( * the open document procedure doesn't exist. */ - if ((interp == NULL) || - (Tcl_GetCommandInfo(interp, "::tk::mac::OpenDocument", &dummy)) == 0) { - return noErr; + if ((interp == NULL) || + (Tcl_GetCommandInfo(interp, "::tk::mac::OpenDocument", &dummy)) == 0) { + return noErr; } - + /* * If we get any errors wil retrieving our parameters * we just return with no error. */ - err = AEGetParamDesc(event, keyDirectObject, - typeAEList, &fileSpecList); + err = ChkErr(AEGetParamDesc, event, keyDirectObject, typeAEList, + &fileSpecList); if (err != noErr) { - return noErr; + return noErr; } err = MissedAnyParameters(event); if (err != noErr) { - return noErr; + return noErr; } - err = AECountItems(&fileSpecList, &count); + err = ChkErr(AECountItems, &fileSpecList, &count); if (err != noErr) { - return noErr; + return noErr; } Tcl_DStringInit(&command); Tcl_DStringAppend(&command, "::tk::mac::OpenDocument", -1); for (index = 1; index <= count; index++) { - err = AEGetNthPtr(&fileSpecList, index, typeFSRef, - &keyword, &type, (Ptr) &file, sizeof(FSRef), &actual); - if ( err != noErr ) { - continue; - } - - err = FSRefToDString(&file, &pathName); - if (err == noErr) { - Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName)); - Tcl_DStringFree(&pathName); - } + err = ChkErr(AEGetNthPtr, &fileSpecList, index, typeFSRef, + &keyword, &type, (Ptr) &file, sizeof(FSRef), &actual); + if ( err != noErr ) { + continue; + } + + err = ChkErr(FSRefToDString, &file, &pathName); + if (err == noErr) { + Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName)); + Tcl_DStringFree(&pathName); + } } - - Tcl_GlobalEval(interp, Tcl_DStringValue(&command)); + + Tcl_EvalEx(interp, Tcl_DStringValue(&command), Tcl_DStringLength(&command), + TCL_EVAL_GLOBAL); Tcl_DStringFree(&command); return noErr; } -static OSErr -PrintHandler ( +/* + *---------------------------------------------------------------------- + * + * PrintHandler -- + * + * This is the 'pdoc' core Apple event handler. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +OSErr +PrintHandler( const AppleEvent * event, AppleEvent * reply, long handlerRefcon) @@ -312,7 +392,7 @@ PrintHandler ( Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon; AEDescList fileSpecList; FSRef file; - OSErr err; + OSStatus err; DescType type; Size actual; long count; @@ -327,49 +407,50 @@ PrintHandler ( * the print document procedure doesn't exist. */ - if ((interp == NULL) || - (Tcl_GetCommandInfo(interp, "::tk::mac::PrintDocument", &dummy)) == 0) { - return noErr; + if ((interp == NULL) || + (Tcl_GetCommandInfo(interp, "::tk::mac::PrintDocument", &dummy)) == 0) { + return noErr; } - + /* * If we get any errors wil retrieving our parameters * we just return with no error. */ - err = AEGetParamDesc(event, keyDirectObject, - typeAEList, &fileSpecList); + err = ChkErr(AEGetParamDesc, event, keyDirectObject, typeAEList, + &fileSpecList); if (err != noErr) { - return noErr; + return noErr; } - err = MissedAnyParameters(event); + err = ChkErr(MissedAnyParameters, event); if (err != noErr) { - return noErr; + return noErr; } - err = AECountItems(&fileSpecList, &count); + err = ChkErr(AECountItems, &fileSpecList, &count); if (err != noErr) { - return noErr; + return noErr; } Tcl_DStringInit(&command); Tcl_DStringAppend(&command, "::tk::mac::PrintDocument", -1); for (index = 1; index <= count; index++) { - err = AEGetNthPtr(&fileSpecList, index, typeFSRef, - &keyword, &type, (Ptr) &file, sizeof(FSRef), &actual); - if ( err != noErr ) { - continue; - } - - err = FSRefToDString(&file, &pathName); - if (err == noErr) { - Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName)); - Tcl_DStringFree(&pathName); - } + err = ChkErr(AEGetNthPtr, &fileSpecList, index, typeFSRef, &keyword, + &type, (Ptr) &file, sizeof(FSRef), &actual); + if ( err != noErr ) { + continue; + } + + err = ChkErr(FSRefToDString, &file, &pathName); + if (err == noErr) { + Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName)); + Tcl_DStringFree(&pathName); + } } - - Tcl_GlobalEval(interp, Tcl_DStringValue(&command)); + + Tcl_EvalEx(interp, Tcl_DStringValue(&command), Tcl_DStringLength(&command), + TCL_EVAL_GLOBAL); Tcl_DStringFree(&command); return noErr; @@ -380,24 +461,24 @@ PrintHandler ( * * ScriptHandler -- * - * This handler process the script event. + * This handler process the script event. * * Results: - * Schedules the given event to be processed. + * Schedules the given event to be processed. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -static OSErr -ScriptHandler ( +OSErr +ScriptHandler( const AppleEvent * event, AppleEvent * reply, long handlerRefcon) { - OSErr theErr; + OSStatus theErr; AEDescList theDesc; int tclErr = -1; Tcl_Interp *interp; @@ -409,98 +490,100 @@ ScriptHandler ( * The do script event receives one parameter that should be data or a file. */ theErr = AEGetParamDesc(event, keyDirectObject, typeWildCard, - &theDesc); + &theDesc); if (theErr != noErr) { - sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", theErr); - theErr = AEPutParamPtr(reply, keyErrorString, typeChar, errString, - strlen(errString)); + sprintf(errString, "AEDoScriptHandler: GetParamDesc error %ld", + theErr); + theErr = AEPutParamPtr(reply, keyErrorString, typeChar, errString, + strlen(errString)); } else if (MissedAnyParameters(event)) { - sprintf(errString, "AEDoScriptHandler: extra parameters"); - AEPutParamPtr(reply, keyErrorString, typeChar, errString, - strlen(errString)); - theErr = -1771; + sprintf(errString, "AEDoScriptHandler: extra parameters"); + AEPutParamPtr(reply, keyErrorString, typeChar, errString, + strlen(errString)); + theErr = -1771; } else { - if (theDesc.descriptorType == (DescType)typeChar) { - Tcl_DString encodedText; - short i; - Size size; - char * data; - - size = AEGetDescDataSize(&theDesc); - - data = (char *)ckalloc(size + 1); - if ( !data ) { - theErr = -1771; - } - else { - AEGetDescData(&theDesc,data,size); - data [ size ] = 0; - for (i = 0; i < size; i++) - if (data[i] == '\r') - data[i] = '\n'; - AEReplaceDescData(theDesc.descriptorType, data, - size + 1, &theDesc); - } - Tcl_ExternalToUtfDString(NULL, data, size, - &encodedText); - tclErr = Tcl_GlobalEval(interp, Tcl_DStringValue(&encodedText)); - Tcl_DStringFree(&encodedText); - } else if (theDesc.descriptorType == (DescType)typeAlias) { - Boolean dummy; - FSRef file; - AliasPtr alias; - Size theSize; - - theSize = AEGetDescDataSize(&theDesc); - alias = (AliasPtr) ckalloc(theSize); - if (alias) { - AEGetDescData (&theDesc, alias, theSize); - - theErr = FSResolveAlias(NULL, &alias, - &file, &dummy); - ckfree((char*)alias); - } else { - theErr = memFullErr; - } - if (theErr == noErr) { - Tcl_DString scriptName; - theErr = FSRefToDString(&file, &scriptName); - if (theErr == noErr) { - Tcl_EvalFile(interp, Tcl_DStringValue(&scriptName)); - Tcl_DStringFree(&scriptName); - } - } else { - sprintf(errString, "AEDoScriptHandler: file not found"); - AEPutParamPtr(reply, keyErrorString, typeChar, - errString, strlen(errString)); - } - } else { - sprintf(errString, - "AEDoScriptHandler: invalid script type '%-4.4s', must be 'alis' or 'TEXT'", - (char *)(&theDesc.descriptorType)); - AEPutParamPtr(reply, keyErrorString, typeChar, - errString, strlen(errString)); - theErr = -1770; - } + if (theDesc.descriptorType == (DescType)typeChar) { + Tcl_DString encodedText; + short i; + Size size; + char * data; + + size = AEGetDescDataSize(&theDesc); + + data = (char *)ckalloc(size + 1); + if ( !data ) { + theErr = -1771; + } + else { + AEGetDescData(&theDesc,data,size); + data [ size ] = 0; + for (i = 0; i < size; i++) + if (data[i] == '\r') + data[i] = '\n'; + AEReplaceDescData(theDesc.descriptorType, data, + size + 1, &theDesc); + } + Tcl_ExternalToUtfDString(NULL, data, size, + &encodedText); + tclErr = Tcl_EvalEx(interp, Tcl_DStringValue(&encodedText), + Tcl_DStringLength(&encodedText), TCL_EVAL_GLOBAL); + Tcl_DStringFree(&encodedText); + } else if (theDesc.descriptorType == (DescType)typeAlias) { + Boolean dummy; + FSRef file; + AliasPtr alias; + Size theSize; + + theSize = AEGetDescDataSize(&theDesc); + alias = (AliasPtr) ckalloc(theSize); + if (alias) { + AEGetDescData (&theDesc, alias, theSize); + + theErr = FSResolveAlias(NULL, &alias, + &file, &dummy); + ckfree((char*)alias); + } else { + theErr = memFullErr; + } + if (theErr == noErr) { + Tcl_DString scriptName; + theErr = FSRefToDString(&file, &scriptName); + if (theErr == noErr) { + Tcl_EvalFile(interp, Tcl_DStringValue(&scriptName)); + Tcl_DStringFree(&scriptName); + } + } else { + sprintf(errString, "AEDoScriptHandler: file not found"); + AEPutParamPtr(reply, keyErrorString, typeChar, + errString, strlen(errString)); + } + } else { + sprintf(errString, + "AEDoScriptHandler: invalid script type '%-4.4s', must be 'alis' or 'TEXT'", + (char *)(&theDesc.descriptorType)); + AEPutParamPtr(reply, keyErrorString, typeChar, + errString, strlen(errString)); + theErr = -1770; + } } /* * If we actually go to run Tcl code - put the result in the reply. */ if (tclErr >= 0) { - if (tclErr == TCL_OK) { - AEPutParamPtr(reply, keyDirectObject, typeChar, - Tcl_GetStringResult(interp), - strlen(Tcl_GetStringResult(interp))); - } else { - AEPutParamPtr(reply, keyErrorString, typeChar, - Tcl_GetStringResult(interp), - strlen(Tcl_GetStringResult(interp))); - AEPutParamPtr(reply, keyErrorNumber, typeInteger, - (Ptr) &tclErr, sizeof(int)); - } + if (tclErr == TCL_OK) { + AEPutParamPtr(reply, keyDirectObject, typeChar, + Tcl_GetStringResult(interp), + strlen(Tcl_GetStringResult(interp))); + } else { + AEPutParamPtr(reply, keyErrorString, typeChar, + Tcl_GetStringResult(interp), + strlen(Tcl_GetStringResult(interp))); + AEPutParamPtr(reply, keyErrorNumber, typeInteger, + (Ptr) &tclErr, sizeof(int)); + } } - + AEDisposeDesc(&theDesc); return theErr; @@ -511,22 +594,22 @@ ScriptHandler ( * * ReallyKillMe -- * - * This proc tries to kill the shell by running exit, - * called from an event scheduled by the "Quit" AppleEvent handler. + * This proc tries to kill the shell by running exit, + * called from an event scheduled by the "Quit" AppleEvent handler. * * Results: - * Runs the "exit" command which might kill the shell. + * Runs the "exit" command which might kill the shell. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -static int +static int ReallyKillMe( Tcl_Event *eventPtr, - int flags) + int flags) { Tcl_Interp *interp = ((KillEvent *) eventPtr)->interp; Tcl_CmdInfo dummy; @@ -543,28 +626,28 @@ ReallyKillMe( * * MissedAnyParameters -- * - * Checks to see if parameters are still left in the event. + * Checks to see if parameters are still left in the event. * * Results: - * True or false. + * True or false. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ - -static int + +int MissedAnyParameters( const AppleEvent *theEvent) { DescType returnedType; Size actualSize; - OSErr err; + OSStatus err; + + err = ChkErr(AEGetAttributePtr, theEvent, keyMissedKeywordAttr, + typeWildCard, &returnedType, NULL, 0, &actualSize); - err = AEGetAttributePtr(theEvent, keyMissedKeywordAttr, typeWildCard, - &returnedType, NULL, 0, &actualSize); - return (err != errAEDescNotFound); } @@ -573,28 +656,28 @@ MissedAnyParameters( * * FSRefToDString -- * - * Get a POSIX path from an FSRef. + * Get a POSIX path from an FSRef. * * Results: - * In the parameter ds. + * In the parameter ds. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -static OSErr +OSStatus FSRefToDString( const FSRef *fsref, Tcl_DString *ds) { UInt8 fileName[PATH_MAX+1]; - OSErr err; + OSStatus err; - err = FSRefMakePath(fsref, fileName, sizeof(fileName)); + err = ChkErr(FSRefMakePath, fsref, fileName, sizeof(fileName)); if (err == noErr) { - Tcl_ExternalToUtfDString(NULL, (char*) fileName, -1, ds); + Tcl_ExternalToUtfDString(NULL, (char*) fileName, -1, ds); } return err; } diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index cde0be8..6625e4a 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -1,17 +1,17 @@ -/* +/* * tkMacOSXInit.c -- * - * This file contains Mac OS X -specific interpreter initialization - * functions. + * This file contains Mac OS X -specific interpreter initialization + * functions. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. - * Copyright (c) 2005-2006 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.27 2007/04/21 19:06:38 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXInit.c,v 1.28 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" @@ -40,13 +40,13 @@ /* * The following structures are used to map the script/language codes of a * font to the name that should be passed to Tcl_GetEncoding() to obtain - * the encoding for that font. The set of numeric constants is fixed and + * the encoding for that font. The set of numeric constants is fixed and * defined by Apple. */ typedef struct Map { CFStringEncoding numKey; - char *strKey; + const char *strKey; } Map; static Map scriptMap[] = { @@ -82,7 +82,7 @@ static Map scriptMap[] = { {smEastEurRoman, "macCentEuro"}, {smVietnamese, "macVietnam"}, {smExtArabic, "macSindhi"}, - {0, NULL} + {0, NULL} }; Tcl_Encoding TkMacOSXCarbonEncoding = NULL; @@ -93,79 +93,60 @@ Tcl_Encoding TkMacOSXCarbonEncoding = NULL; */ static char scriptPath[PATH_MAX + 1] = ""; + /* *---------------------------------------------------------------------- * * TkpInit -- * - * Performs Mac-specific interpreter initialization related to the - * tk_library variable. + * Performs Mac-specific interpreter initialization related to the + * tk_library variable. * * Results: - * Returns a standard Tcl result. Leaves an error message or result - * in the interp's result. + * Returns a standard Tcl result. Leaves an error message or result + * in the interp's result. * * Side effects: - * Sets "tk_library" Tcl variable, runs "tk.tcl" script. + * Sets "tk_library" Tcl variable, runs "tk.tcl" script. * *---------------------------------------------------------------------- */ int -TkpInit(interp) - Tcl_Interp *interp; +TkpInit( + Tcl_Interp *interp) { static char tkLibPath[PATH_MAX + 1]; - static int tkMacOSXInitialized = false; + static int tkMacOSXInitialized = 0; Tk_MacOSXSetupTkNotifier(); - /* + /* * Since it is possible for TkInit to be called multiple times - * and we don't want to do the initialization multiple times + * and we don't want to do the following initialization multiple times * we protect against doing it more than once. */ - if (tkMacOSXInitialized == false) { + if (!tkMacOSXInitialized) { + int bundledExecutable = 0; + CFBundleRef bundleRef; + CFURLRef bundleUrl = NULL; CFStringEncoding encoding; - char *encodingStr = NULL; + const char *encodingStr = NULL; int i; - tkMacOSXInitialized = true; - - TkMacOSXInitAppleEvents(interp); - TkMacOSXInitCarbonEvents(interp); - TkMacOSXInitMenus(interp); - TkMacOSXUseAntialiasedText(interp, -1); - TkMacOSXInitCGDrawing(interp, TRUE, 0); - TkMacOSXInitKeyboard(interp); - - encoding = CFStringGetSystemEncoding(); - - for (i = 0; scriptMap[i].strKey != NULL; i++) { - if (scriptMap[i].numKey == encoding) { - encodingStr = scriptMap[i].strKey; - break; - } - } - if (encodingStr == NULL) { - encodingStr = "macRoman"; - } - - TkMacOSXCarbonEncoding = Tcl_GetEncoding (NULL, encodingStr); - if (TkMacOSXCarbonEncoding == NULL) { - TkMacOSXCarbonEncoding = Tcl_GetEncoding (NULL, NULL); - } + tkMacOSXInitialized = 1; /* - * When Tk is in a framework, force tcl_findLibrary to look in the + * When Tk is in a framework, force tcl_findLibrary to look in the * framework scripts directory. * FIXME: Should we come up with a more generic way of doing this? */ #ifdef TK_FRAMEWORK if (Tcl_MacOSXOpenVersionedBundleResources(interp, - "com.tcltk.tklibrary", TK_FRAMEWORK_VERSION, 1, PATH_MAX, tkLibPath) != TCL_OK) + "com.tcltk.tklibrary", TK_FRAMEWORK_VERSION, 1, PATH_MAX, + tkLibPath) != TCL_OK) #endif { /* Tk.framework not found, check if resource file is open */ @@ -181,12 +162,13 @@ TkpInit(interp) char fileName[L_tmpnam + 15]; uint32_t i, n; - /* Get resource data from __tk_rsrc section of tk library file */ + /* Get resource data from __tk_rsrc section of tk dylib file*/ n = _dyld_image_count(); for (i = 0; i < n; i++) { image = _dyld_get_image_header(i); if (image) { - data = getsectdatafromheader(image, SEG_TEXT, "__tk_rsrc", &size); + data = getsectdatafromheader(image, SEG_TEXT, + "__tk_rsrc", (void*)&size); if (data) { data += _dyld_get_image_vmaddr_slide(i); break; @@ -194,26 +176,32 @@ TkpInit(interp) } } while (data) { - OSStatus err; FSRef ref; SInt16 refNum; - /* Write resource data to temporary file and open it */ + /* + * Write resource data to temporary file and open it. + */ + strcpy(fileName, P_tmpdir); if (fileName[strlen(fileName) - 1] != '/') { strcat(fileName, "/"); } strcat(fileName, "tkMacOSX_XXXXXX"); fd = mkstemp(fileName); - if (fd == -1) break; + if (fd == -1) { + break; + } fcntl(fd, F_SETFD, FD_CLOEXEC); - if (write(fd, data, size) == -1) break; - err = FSPathMakeRef((unsigned char*)fileName, &ref, NULL); - if (err != noErr) break; - err = FSOpenResourceFile(&ref, 0, NULL, fsRdPerm, &refNum); -#ifdef TK_MAC_DEBUG - if (err != noErr) fprintf(stderr,"FSOpenResourceFile error %ld\n",err); -#endif + if (write(fd, data, size) == -1) { + break; + } + if(ChkErr(FSPathMakeRef, (unsigned char*)fileName, &ref, + NULL) != noErr) { + break; + } + ChkErr(FSOpenResourceFile, &ref, 0, NULL, fsRdPerm, + &refNum); break; } if (fd != -1) { @@ -224,13 +212,108 @@ TkpInit(interp) } } - /* REMOVE ME: Close stdin & stdout for remote debugging otherwise we - * will fight with gdb for stdin & stdout + /* + * If we are loaded into an executable that is not a bundled + * application, the window server does not let us come to the + * foreground. For such an executable, notify the window server that + * we are now a full GUI application. */ - if (getenv ("XCNOSTDIN") != NULL) { - close (0); - close (1); + /* Check whether we are a bundled executable: */ + bundleRef = CFBundleGetMainBundle(); + if (bundleRef) { + bundleUrl = CFBundleCopyBundleURL(bundleRef); + } + if (bundleUrl) { + /* + * A bundled executable is two levels down from its main bundle + * directory (e.g. Wish.app/Contents/MacOS/Wish), whereas an + * unbundled executable's main bundle directory is just the + * directory containing the executable. So to check whether we are + * bundled, we delete the last three path components of the + * executable's url and compare the resulting url with the main + * bundle url. + */ + int j = 3; + CFURLRef url = CFBundleCopyExecutableURL(bundleRef); + while (url && j--) { + CFURLRef parent = CFURLCreateCopyDeletingLastPathComponent(NULL, + url); + CFRelease(url); + url = parent; + } + if (url) { + bundledExecutable = CFEqual(bundleUrl, url); + CFRelease(url); + } + CFRelease(bundleUrl); + } + + /* If we are not a bundled executable, notify the window server that + * we are a foregroundable app. */ + if (!bundledExecutable) { + OSStatus err = procNotFound; + ProcessSerialNumber psn = { 0, kCurrentProcess }; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + if (1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1030 + && TransformProcessType != NULL +#endif + ) { + err = ChkErr(TransformProcessType, &psn, + kProcessTransformToForegroundApplication); + } +#endif +#if MAC_OSX_TK_USE_CPS_SPI + if (err != noErr) { + /* + * When building or running on 10.2 or when the above fails, + * attempt to use undocumented CPS SPI to notify the window + * server. Load the SPI symbol dynamically, so that we don't + * break if it ever disappears or changes its name. + */ + TkMacOSXInitNamedSymbol(CoreGraphics, OSStatus, + CPSEnableForegroundOperation, ProcessSerialNumberPtr); + if (CPSEnableForegroundOperation) { + ChkErr(CPSEnableForegroundOperation, &psn); + } + } +#endif /* MAC_OSX_TK_USE_CPS_SPI */ + } + + TkMacOSXInitAppleEvents(interp); + TkMacOSXInitCarbonEvents(interp); + TkMacOSXInitMenus(interp); + TkMacOSXUseAntialiasedText(interp, -1); + TkMacOSXInitCGDrawing(interp, TRUE, 0); + TkMacOSXInitKeyboard(interp); + + encoding = CFStringGetSystemEncoding(); + + for (i = 0; scriptMap[i].strKey != NULL; i++) { + if (scriptMap[i].numKey == encoding) { + encodingStr = scriptMap[i].strKey; + break; + } + } + if (encodingStr == NULL) { + encodingStr = "macRoman"; + } + + TkMacOSXCarbonEncoding = Tcl_GetEncoding(NULL, encodingStr); + if (TkMacOSXCarbonEncoding == NULL) { + TkMacOSXCarbonEncoding = Tcl_GetEncoding(NULL, NULL); + } + + /* + * REMOVE ME: Close stdin & stdout for remote debugging otherwise we + * will fight with gdb for stdin & stdout + */ + + if (getenv("XCNOSTDIN") != NULL) { + close(0); + close(1); } /* @@ -241,18 +324,22 @@ TkpInit(interp) if (!isatty(0)) { struct stat st; + if (fstat(0, &st) || (S_ISCHR(st.st_mode) && st.st_blocks == 0)) { Tk_InitConsoleChannels(interp); Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDIN)); Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDOUT)); Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDERR)); + /* * Only show the console if we don't have a startup script * and tcl_interactive hasn't been set already. */ + if (Tcl_GetStartupScript(NULL) == NULL) { - CONST char *intvar = - Tcl_GetVar(interp, "tcl_interactive", TCL_GLOBAL_ONLY); + const char *intvar = Tcl_GetVar(interp, + "tcl_interactive", TCL_GLOBAL_ONLY); + if (intvar == NULL) { Tcl_SetVar(interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY); @@ -263,73 +350,6 @@ TkpInit(interp) } } } - - /* - * If we are loaded into an executable that is not a bundled - * application, the window server does not let us come to the - * foreground. For such an executable, notify the window server that - * we are now a full GUI application. - */ - { - /* Check whether we are a bundled executable: */ - int bundledExecutable = 0; - CFBundleRef bundleRef = CFBundleGetMainBundle(); - CFURLRef bundleUrl = NULL; - if (bundleRef) { - bundleUrl = CFBundleCopyBundleURL(bundleRef); - } - if (bundleUrl) { - /* - * A bundled executable is two levels down from its main bundle - * directory (e.g. Wish.app/Contents/MacOS/Wish), whereas - * an unbundled executable's main bundle directory is just - * the directory containing the executable. - * So to check whether we are bundled, we delete the last three - * path components of the executable's url and compare the - * resulting url with the main bundle url. - */ - int j = 3; - CFURLRef url = CFBundleCopyExecutableURL(bundleRef); - while (url && j--) { - CFURLRef parent = CFURLCreateCopyDeletingLastPathComponent(NULL, url); - CFRelease(url); - url = parent; - } - if (url) { - bundledExecutable = CFEqual(bundleUrl, url); - CFRelease(url); - } - CFRelease(bundleUrl); - } - - /* If we are not a bundled executable, notify the window server that - * we are a foregroundable app. */ - if (!bundledExecutable) { - OSStatus err = procNotFound; - ProcessSerialNumber psn = { 0, kCurrentProcess }; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 - if (TransformProcessType != NULL) { - err = TransformProcessType(&psn, - kProcessTransformToForegroundApplication); - } -#endif -#if MAC_OSX_TK_USE_CPS_SPI - if (err != noErr) { - /* - * When building or running on 10.2 or when the above fails, - * attempt to use undocumented CPS SPI to notify the window - * server. Load the SPI symbol dynamically, so that we don't - * break if it ever disappears or changes its name. - */ - TkMacOSXInitNamedSymbol(CoreGraphics, OSErr, - CPSEnableForegroundOperation, ProcessSerialNumberPtr); - if (CPSEnableForegroundOperation) { - CPSEnableForegroundOperation(&psn); - } - } -#endif /* MAC_OSX_TK_USE_CPS_SPI */ - } - } } if (tkLibPath[0] != '\0') { @@ -341,7 +361,7 @@ TkpInit(interp) TCL_GLOBAL_ONLY|TCL_LIST_ELEMENT|TCL_APPEND_VALUE); } - return Tcl_Eval(interp, initScript); + return Tcl_EvalEx(interp, initScript, -1, TCL_EVAL_GLOBAL); } /* @@ -349,25 +369,25 @@ TkpInit(interp) * * TkpGetAppName -- * - * Retrieves the name of the current application from a platform - * specific location. For Unix, the application name is the tail - * of the path contained in the tcl variable argv0. + * Retrieves the name of the current application from a platform + * specific location. For Unix, the application name is the tail + * of the path contained in the tcl variable argv0. * * Results: - * Returns the application name in the given Tcl_DString. + * Returns the application name in the given Tcl_DString. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ void -TkpGetAppName(interp, namePtr) - Tcl_Interp *interp; - Tcl_DString *namePtr; /* A previously initialized Tcl_DString. */ +TkpGetAppName( + Tcl_Interp *interp, + Tcl_DString *namePtr) /* A previously initialized Tcl_DString. */ { - CONST char *p, *name; + const char *p, *name; name = Tcl_GetVar(interp, "argv0", TCL_GLOBAL_ONLY); if ((name == NULL) || (*name == 0)) { @@ -386,22 +406,22 @@ TkpGetAppName(interp, namePtr) * * TkpDisplayWarning -- * - * This routines is called from Tk_Main to display warning - * messages that occur during startup. + * This routines is called from Tk_Main to display warning + * messages that occur during startup. * * Results: - * None. + * None. * * Side effects: - * Generates messages on stdout. + * Generates messages on stdout. * *---------------------------------------------------------------------- */ void -TkpDisplayWarning(msg, title) - CONST char *msg; /* Message to be displayed. */ - CONST char *title; /* Title of warning. */ +TkpDisplayWarning( + CONST char *msg, /* Message to be displayed. */ + CONST char *title) /* Title of warning. */ { Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR); if (errChannel) { @@ -418,18 +438,18 @@ TkpDisplayWarning(msg, title) * TkMacOSXDefaultStartupScript -- * * - * On MacOS X, we look for a file in the Resources/Scripts - * directory called AppMain.tcl and if found, we set argv[1] to - * that, so that the rest of the code will find it, and add the - * Scripts folder to the auto_path. If we don't find the startup - * script, we just bag it, assuming the user is starting up some - * other way. + * On MacOS X, we look for a file in the Resources/Scripts + * directory called AppMain.tcl and if found, we set argv[1] to + * that, so that the rest of the code will find it, and add the + * Scripts folder to the auto_path. If we don't find the startup + * script, we just bag it, assuming the user is starting up some + * other way. * * Results: - * None. + * None. * * Side effects: - * Tcl_SetStartupScript() called when AppMain.tcl found. + * Tcl_SetStartupScript() called when AppMain.tcl found. * *---------------------------------------------------------------------- */ @@ -443,9 +463,9 @@ TkMacOSXDefaultStartupScript(void) if (bundleRef != NULL) { CFURLRef appMainURL; - appMainURL = CFBundleCopyResourceURL(bundleRef, - CFSTR("AppMain"), - CFSTR("tcl"), + appMainURL = CFBundleCopyResourceURL(bundleRef, + CFSTR("AppMain"), + CFSTR("tcl"), CFSTR("Scripts")); if (appMainURL != NULL) { @@ -458,7 +478,7 @@ TkMacOSXDefaultStartupScript(void) scriptFldrURL = CFURLCreateCopyDeletingLastPathComponent( NULL, appMainURL); if (scriptFldrURL != NULL) { - CFURLGetFileSystemRepresentation(scriptFldrURL, + CFURLGetFileSystemRepresentation(scriptFldrURL, true, (unsigned char*) scriptPath, PATH_MAX); CFRelease(scriptFldrURL); } @@ -474,23 +494,25 @@ TkMacOSXDefaultStartupScript(void) * TkMacOSXGetNamedSymbol -- * * - * Dynamically acquire address of a named symbol from a loaded - * dynamic library, so that we can use API that may not be - * available on all OS versions. - * If module is non-NULL and not the empty string, use twolevel - * namespace lookup. - * + * Dynamically acquire address of a named symbol from a loaded + * dynamic library, so that we can use API that may not be + * available on all OS versions. + * If module is non-NULL and not the empty string, use twolevel + * namespace lookup. + * * Results: - * Address of given symbol or NULL if unavailable. + * Address of given symbol or NULL if unavailable. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ MODULE_SCOPE void* -TkMacOSXGetNamedSymbol(const char* module, const char* symbol) +TkMacOSXGetNamedSymbol( + const char* module, + const char* symbol) { NSSymbol nsSymbol = NULL; if (module && *module) { @@ -502,7 +524,7 @@ TkMacOSXGetNamedSymbol(const char* module, const char* symbol) nsSymbol = NSLookupAndBindSymbol(symbol); } } - if(nsSymbol) { + if (nsSymbol) { return NSAddressOfSymbol(nsSymbol); } else { return NULL; diff --git a/macosx/tkMacOSXInt.h b/macosx/tkMacOSXInt.h index 9ff9069..06f73bc 100644 --- a/macosx/tkMacOSXInt.h +++ b/macosx/tkMacOSXInt.h @@ -5,11 +5,12 @@ * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.22 2007/04/21 19:06:38 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXInt.h,v 1.23 2007/04/23 21:24:33 das Exp $ */ #ifndef _TKMACINT @@ -23,6 +24,66 @@ #include <Carbon/Carbon.h> #undef TextStyle +/* Define constants only available on Mac OS X 10.3 or later */ +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 + #define kEventAppAvailableWindowBoundsChanged 110 + #define kEventParamTransactionID 'trns' + #define kEventParamWindowPartCode 'wpar' + #define typeWindowPartCode 'wpar' + #define kMenuAttrDoNotUseUserCommandKeys (1 << 7) + #define kSimpleWindowClass 18 + #define kWindowDoesNotCycleAttribute (1L << 15) + #define kWindowAsyncDragAttribute (1L << 23) + #define kThemeBrushAlternatePrimaryHighlightColor -5 + #define kThemeResizeUpCursor 19 + #define kThemeResizeDownCursor 19 + #define kThemeResizeUpDownCursor 19 + #define kThemePoofCursor 19 + #define kThemeBackgroundMetal 6 + #define kThemeIncDecButtonSmall 21 + #define kThemeIncDecButtonMini 22 + #define kAppearancePartUpButton 20 + #define kAppearancePartDownButton 21 + #define kAppearancePartPageUpArea 22 + #define kAppearancePartPageDownArea 23 + #define kAppearancePartIndicator 129 + #define FixedToInt(a) ((short)(((Fixed)(a) + fixed1/2) >> 16)) + #define IntToFixed(a) ((Fixed)(a) << 16) +#endif +/* Define constants only available on Mac OS X 10.4 or later */ +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1040 + #define kWindowNoTitleBarAttribute (1L << 9) + #define kWindowMetalNoContentSeparatorAttribute (1L << 11) + #define kThemeDisclosureTriangle 6 + #define kThemeBrushListViewOddRowBackground 56 + #define kThemeBrushListViewEvenRowBackground 57 + #define kThemeBrushListViewColumnDivider 58 + #define kThemeMetricScrollBarMinThumbHeight 132 + #define kThemeMetricSmallScrollBarMinThumbHeight 134 + #define kThemeScrollBarMedium kThemeMediumScrollBar + #define kThemeScrollBarSmall kThemeSmallScrollBar + #ifdef __BIG_ENDIAN__ + #define kCGBitmapByteOrder32Host (4 << 12) + #else + #define kCGBitmapByteOrder32Host (2 << 12) + #endif + #endif +/* Define constants only available on Mac OS X 10.5 or later */ +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 + #define kWindowUnifiedTitleAndToolbarAttribute (1L << 7) + #define kWindowTexturedSquareCornersAttribute (1L << 10) +#endif +/* Runtime HIToolbox version checking */ +#ifndef kHIToolboxVersionNumber10_3 + #define kHIToolboxVersionNumber10_3 (145) +#endif +#ifndef kHIToolboxVersionNumber10_4 + #define kHIToolboxVersionNumber10_4 (219) +#endif +#ifndef kHIToolboxVersionNumber10_5 + #define kHIToolboxVersionNumber10_5 (291) +#endif + /* * Include platform specific public interfaces. */ @@ -32,17 +93,19 @@ #endif struct TkWindowPrivate { - TkWindow *winPtr; /* Ptr to tk window or NULL if Pixmap */ - CGrafPtr grafPtr; + TkWindow *winPtr; /* Ptr to tk window or NULL if Pixmap */ + CGrafPtr grafPtr; + CGContextRef context; ControlRef rootControl; - int xOff; /* X offset from toplevel window */ - int yOff; /* Y offset from toplevel window */ + 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 & it's children */ + RgnHandle drawRgn; /* Clipped drawing region */ int referenceCount; /* Don't delete toplevel until children are * gone. */ - struct TkWindowPrivate *toplevel; /* Pointer to the toplevel - * datastruct. */ + struct TkWindowPrivate *toplevel; + /* Pointer to the toplevel datastruct. */ int flags; /* Various state see defines below. */ }; typedef struct TkWindowPrivate MacDrawable; @@ -54,50 +117,65 @@ typedef struct TkWindowPrivate MacDrawable; */ typedef struct TkMacOSXWindowList { - struct TkMacOSXWindowList *nextPtr; /* The next window in the list. */ - TkWindow *winPtr; /* This window */ + struct TkMacOSXWindowList *nextPtr; + /* The next window in the list. */ + TkWindow *winPtr; /* This window */ } TkMacOSXWindowList; /* * Defines use for the flags field of the MacDrawable data structure. */ - -#define TK_SCROLLBAR_GROW 1 -#define TK_CLIP_INVALID 2 -#define TK_HOST_EXISTS 4 -#define TK_DRAWN_UNDER_MENU 8 + +#define TK_SCROLLBAR_GROW 0x01 +#define TK_CLIP_INVALID 0x02 +#define TK_HOST_EXISTS 0x04 +#define TK_DRAWN_UNDER_MENU 0x08 +#define TK_CLIPPED_DRAW 0x10 /* * I am reserving TK_EMBEDDED = 0x100 in the MacDrawable flags * This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the - * TkWindow structure for the window, but in the MacWin. This way we can + * TkWindow structure for the window, but in the MacWin. This way we can * still tell what the correct port is after the TKWindow structure has been - * freed. This actually happens when you bind destroy of a toplevel to + * freed. This actually happens when you bind destroy of a toplevel to * Destroy of a child. */ /* * This structure is for handling Netscape-type in process - * embedding where Tk does not control the top-level. It contains + * embedding where Tk does not control the top-level. It contains * various functions that are needed by Mac specific routines, like - * TkMacOSXGetDrawablePort. The definitions of the function types + * TkMacOSXGetDrawablePort. The definitions of the function types * are in tkMacOSX.h. */ typedef struct { - Tk_MacOSXEmbedRegisterWinProc *registerWinProc; - Tk_MacOSXEmbedGetGrafPortProc *getPortProc; - Tk_MacOSXEmbedMakeContainerExistProc *containerExistProc; - Tk_MacOSXEmbedGetClipProc *getClipProc; - Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc; + Tk_MacOSXEmbedRegisterWinProc *registerWinProc; + Tk_MacOSXEmbedGetGrafPortProc *getPortProc; + Tk_MacOSXEmbedMakeContainerExistProc *containerExistProc; + Tk_MacOSXEmbedGetClipProc *getClipProc; + Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc; } TkMacOSXEmbedHandler; MODULE_SCOPE TkMacOSXEmbedHandler *tkMacOSXEmbedHandler; /* + * Structure encapsulating current drawing environment. + */ + +typedef struct TkMacOSXDrawingContext { + CGContextRef context; + CGrafPtr port, savePort; + ThemeDrawingState saveState; + PixPatHandle penPat; + Rect portBounds; + Boolean portChanged; +} TkMacOSXDrawingContext; + +/* * Defines used for TkMacOSXInvalidateWindow */ - + #define TK_WINDOW_ONLY 0 #define TK_PARENT_WINDOW 1 @@ -120,14 +198,57 @@ MODULE_SCOPE TkMacOSXEmbedHandler *tkMacOSXEmbedHandler; * Defines for tkTextDisp.c */ -#define TK_LAYOUT_WITH_BASE_CHUNKS 1 -#define TK_DRAW_IN_CONTEXT 1 +#define TK_LAYOUT_WITH_BASE_CHUNKS 1 +#define TK_DRAW_IN_CONTEXT 1 + +#if !TK_DRAW_IN_CONTEXT +MODULE_SCOPE int TkMacOSXCompareColors(unsigned long c1, unsigned long c2); +#endif + +/* + * Macros abstracting checks only active in a debug build. + */ + +#ifdef TK_MAC_DEBUG +/* + * Macro to do debug message output. + */ +#define TkMacOSXDbgMsg(m, ...) do { \ + fprintf(stderr, "%s:%d: %s(): " m "\n", strrchr(__FILE__, '/')+1, \ + __LINE__, __func__, ##__VA_ARGS__); \ + } while (0) +/* + * Macro to do very common check for noErr return from given API and output + * debug message in case of failure. + */ +#define ChkErr(f, ...) ({ \ + OSStatus err = f(__VA_ARGS__); \ + if (err != noErr) { \ + TkMacOSXDbgMsg("%s failed: %ld", #f, err); \ + } \ + err;}) +/* + * Macro to check emptyness of shared temp regions before use in debug builds. + */ +#define TkMacOSXCheckTmpRgnEmpty(r) do { \ + if (!EmptyRgn(tkMacOSXtmpRgn##r)) { \ + Tcl_Panic("tkMacOSXtmpRgn%s nonempty", #r); \ + } \ + } while(0) +#else /* TK_MAC_DEBUG */ +#define TkMacOSXDbgMsg(m, ...) +#define ChkErr(f, ...) ({f(__VA_ARGS__);}) +#define TkMacOSXCheckTmpRgnEmpty(r) +#endif /* TK_MAC_DEBUG */ /* * Variables shared among various Mac Tk modules but are not * exported to the outside world. */ +MODULE_SCOPE RgnHandle tkMacOSXtmpRgn1; +MODULE_SCOPE RgnHandle tkMacOSXtmpRgn2; + /* * Globals shared among Macintosh Tk */ @@ -136,13 +257,6 @@ MODULE_SCOPE MenuHandle tkCurrentAppleMenu; /* Handle to current Apple Menu */ MODULE_SCOPE MenuHandle tkAppleMenu; /* Handle to default Apple Menu */ MODULE_SCOPE MenuHandle tkFileMenu; /* Handles to menus */ MODULE_SCOPE MenuHandle tkEditMenu; /* Handles to menus */ -MODULE_SCOPE RgnHandle tkMenuCascadeRgn;/* A region to clip with. */ -MODULE_SCOPE int tkUseMenuCascadeRgn; /* If this is 1, clipping code - * should intersect tkMenuCascadeRgn - * before drawing occurs. - * tkMenuCascadeRgn will only - * be valid when the value of this - * variable is 1. */ MODULE_SCOPE int tkPictureIsOpen; /* If this is 1, we are drawing to a * picture The clipping should then be * done relative to the bounds of the @@ -154,31 +268,72 @@ MODULE_SCOPE int tkPictureIsOpen; /* If this is 1, we are drawing to a * for CopyBits should also have * top,left values of 0,0 */ -MODULE_SCOPE TkMacOSXWindowList *tkMacOSXWindowListPtr; - /* The list of toplevels */ - +MODULE_SCOPE TkMacOSXWindowList *tkMacOSXWindowListPtr; /* List of toplevels */ MODULE_SCOPE Tcl_Encoding TkMacOSXCarbonEncoding; +/* + * Prototypes of internal procs not in the stubs table. + */ + +#if 0 +MODULE_SCOPE int XSetClipRectangles(Display *d, GC gc, int clip_x_origin, + int clip_y_origin, XRectangle* rectangles, int n, int ordering); +#endif +MODULE_SCOPE void TkpClipDrawableToRect(Display *display, Drawable d, int x, + int y, int width, int height); MODULE_SCOPE void TkMacOSXDisplayChanged(Display *display); +MODULE_SCOPE void TkMacOSXInitScrollbarMetrics(void); MODULE_SCOPE int TkMacOSXUseAntialiasedText(Tcl_Interp *interp, int enable); MODULE_SCOPE void TkMacOSXInitCarbonEvents(Tcl_Interp *interp); -MODULE_SCOPE int TkMacOSXInitCGDrawing(Tcl_Interp *interp, int enable, int antiAlias); +MODULE_SCOPE int TkMacOSXInitCGDrawing(Tcl_Interp *interp, int enable, + int antiAlias); MODULE_SCOPE void TkMacOSXInitKeyboard(Tcl_Interp *interp); MODULE_SCOPE void TkMacOSXDefaultStartupScript(void); -MODULE_SCOPE int TkMacOSXGenerateFocusEvent( Window window, int activeFlag); +MODULE_SCOPE int TkMacOSXGenerateFocusEvent(Window window, int activeFlag); +MODULE_SCOPE int TkMacOSXGenerateParentMenuSelectEvent(MenuRef menu); +MODULE_SCOPE int TkMacOSXGenerateMenuSelectEvent(MenuRef menu, + MenuItemIndex index); +MODULE_SCOPE void TkMacOSXClearActiveMenu(MenuRef menu); MODULE_SCOPE WindowClass TkMacOSXWindowClass(TkWindow *winPtr); MODULE_SCOPE int TkMacOSXIsWindowZoomed(TkWindow *winPtr); MODULE_SCOPE int TkGenerateButtonEventForXPointer(Window window); -MODULE_SCOPE int TkMacOSXCompareColors(unsigned long c1, unsigned long c2); +MODULE_SCOPE EventModifiers TkMacOSXModifierState(void); +MODULE_SCOPE int TkMacOSXSetupDrawingContext(Drawable d, GC gc, int useCG, + TkMacOSXDrawingContext *dc); +MODULE_SCOPE void TkMacOSXRestoreDrawingContext(TkMacOSXDrawingContext *dc); +MODULE_SCOPE void TkMacOSXSetColorInPort(unsigned long pixel, int fg, + PixPatHandle penPat); +MODULE_SCOPE void TkMacOSXSetColorInContext(unsigned long pixel, + CGContextRef context); +MODULE_SCOPE int TkMacOSXRunTclEventLoop(void); +MODULE_SCOPE OSStatus TkMacOSXStartTclEventLoopCarbonTimer(void); +MODULE_SCOPE OSStatus TkMacOSXStopTclEventLoopCarbonTimer(void); +MODULE_SCOPE void TkMacOSXTrackingLoop(int tracking); +MODULE_SCOPE OSStatus TkMacOSXReceiveAndDispatchEvent(void); +MODULE_SCOPE void TkMacOSXInstallWindowCarbonEventHandler(Tcl_Interp *interp, + WindowRef window); +MODULE_SCOPE int TkMacOSXMakeFullscreen(TkWindow *winPtr, WindowRef window, + int fullscreen, Tcl_Interp *interp); +MODULE_SCOPE void TkMacOSXEnterExitFullscreen(TkWindow *winPtr, int active); + +MODULE_SCOPE void* TkMacOSXGetNamedSymbol(const char* module, + const char* symbol); + +/* + * Macro abstracting use of TkMacOSXGetNamedSymbol to init named symbols. + */ -MODULE_SCOPE void* TkMacOSXGetNamedSymbol(const char* module, const char* symbol); -/* Macro to abstract common use of TkMacOSXGetNamedSymbol to initialize named symbols */ #define TkMacOSXInitNamedSymbol(module, ret, symbol, ...) \ static ret (* symbol)(__VA_ARGS__) = (void*)(-1L); \ if (symbol == (void*)(-1L)) { \ - symbol = TkMacOSXGetNamedSymbol(STRINGIFY(module), STRINGIFY(_##symbol));\ + symbol = TkMacOSXGetNamedSymbol(STRINGIFY(module), \ + STRINGIFY(_##symbol)); \ } +/* + * Include the stubbed internal platform-specific API. + */ + #include "tkIntPlatDecls.h" #endif /* _TKMACINT */ diff --git a/macosx/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c index 08d61a4..14bf641 100644 --- a/macosx/tkMacOSXKeyEvent.c +++ b/macosx/tkMacOSXKeyEvent.c @@ -1,190 +1,172 @@ /* * tkMacOSXKeyEvent.c -- * - * This file implements functions that decode & handle keyboard events - * on MacOS X. + * This file implements functions that decode & handle keyboard events + * on MacOS X. * * Copyright 2001, Apple Computer, Inc. - * Copyright (c) 2006 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * The following terms apply to all files originating from Apple - * Computer, Inc. ("Apple") and associated with the software - * unless explicitly disclaimed in individual files. - * - * - * Apple hereby grants permission to use, copy, modify, - * distribute, and license this software and its documentation - * for any purpose, provided that existing copyright notices are - * retained in all copies and that this notice is included - * verbatim in any distributions. No written agreement, license, - * or royalty fee is required for any of the authorized - * uses. Modifications to this software may be copyrighted by - * their authors and need not follow the licensing terms - * described here, provided that the new terms are clearly - * indicated on the first page of each file where they apply. - * - * - * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE - * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, - * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF - * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, - * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND - * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS - * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE - * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * GOVERNMENT USE: If you are acquiring this software on behalf - * of the U.S. government, the Government shall have only - * "Restricted Rights" in the software and related documentation - * as defined in the Federal Acquisition Regulations (FARs) in - * Clause 52.227.19 (c) (2). If you are acquiring the software - * on behalf of the Department of Defense, the software shall be - * classified as "Commercial Computer Software" and the - * Government shall have only "Restricted Rights" as defined in - * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the - * foregoing, the authors grant the U.S. Government and others - * acting in its behalf permission to use and distribute the - * software in accordance with the terms specified in this - * license. - * - * RCS: @(#) $Id: tkMacOSXKeyEvent.c,v 1.20 2007/04/21 19:06:38 hobbs Exp $ + * The following terms apply to all files originating from Apple + * Computer, Inc. ("Apple") and associated with the software + * unless explicitly disclaimed in individual files. + * + * + * Apple hereby grants permission to use, copy, modify, + * distribute, and license this software and its documentation + * for any purpose, provided that existing copyright notices are + * retained in all copies and that this notice is included + * verbatim in any distributions. No written agreement, license, + * or royalty fee is required for any of the authorized + * uses. Modifications to this software may be copyrighted by + * their authors and need not follow the licensing terms + * described here, provided that the new terms are clearly + * indicated on the first page of each file where they apply. + * + * + * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE + * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, + * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF + * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, + * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND + * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS + * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE + * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * GOVERNMENT USE: If you are acquiring this software on behalf + * of the U.S. government, the Government shall have only + * "Restricted Rights" in the software and related documentation + * as defined in the Federal Acquisition Regulations (FARs) in + * Clause 52.227.19 (c) (2). If you are acquiring the software + * on behalf of the Department of Defense, the software shall be + * classified as "Commercial Computer Software" and the + * Government shall have only "Restricted Rights" as defined in + * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the + * foregoing, the authors grant the U.S. Government and others + * acting in its behalf permission to use and distribute the + * software in accordance with the terms specified in this + * license. + * + * RCS: @(#) $Id: tkMacOSXKeyEvent.c,v 1.21 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" #include "tkMacOSXEvent.h" /* -#ifdef TK_MAC_DEBUG +#ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_KEYBOARD #endif */ typedef struct { - WindowRef whichWindow; - int global_x, global_y; - int local_x, local_y; + WindowRef whichWindow; + int global_x, global_y; + int local_x, local_y; unsigned int state; + UInt32 keyCode; + UInt32 keyModifiers; + UInt32 message; unsigned char ch; - UInt32 keyCode; - UInt32 keyModifiers; - UInt32 message; } KeyEventData; -static Tk_Window gGrabWinPtr = NULL; /* Current grab window, - * NULL if no grab. */ -static Tk_Window gKeyboardWinPtr = NULL; /* Current keyboard grab window. */ - -static UInt32 deadKeyStateUp = 0; /* The deadkey state for the current - * sequence of keyup events or 0 if - * not in a deadkey sequence */ -static UInt32 deadKeyStateDown = 0; /* Ditto for keydown */ +static Tk_Window grabWinPtr = NULL; + /* Current grab window, NULL if no grab. */ +static Tk_Window keyboardGrabWinPtr = NULL; + /* Current keyboard grab window. */ +static UInt32 deadKeyStateUp = 0; + /* The deadkey state for the current sequence + * of keyup events or 0 if not in a deadkey + * sequence */ +static UInt32 deadKeyStateDown = 0; + /* Ditto for keydown */ /* * Declarations for functions used only in this file. */ - -static int InitKeyData( - KeyEventData * keyEventDataPtr); - -static int InitKeyEvent( - XEvent * eventPtr, - KeyEventData * e, - UInt32 savedKeyCode, - UInt32 savedModifiers); - -static int GenerateKeyEvent ( - UInt32 eKind, - KeyEventData * e, - UInt32 savedKeyCode, - UInt32 savedModifiers, - const UniChar * chars, int numChars); - -static int GetKeyboardLayout ( - Ptr * resourcePtr, TextEncoding * encodingPtr); -static TextEncoding GetKCHREncoding( - ScriptCode script, SInt32 layoutid); - -static int KeycodeToUnicodeViaUnicodeResource( - UniChar * uniChars, int maxChars, - Ptr uchr, - EventKind eKind, - UInt32 keycode, UInt32 modifiers, - UInt32 * deadKeyStatePtr); - -static int KeycodeToUnicodeViaKCHRResource( - UniChar * uniChars, int maxChars, - Ptr kchr, TextEncoding encoding, - EventKind eKind, - UInt32 keycode, UInt32 modifiers, - UInt32 * deadKeyStatePtr); + +static int InitKeyData(KeyEventData *keyEventDataPtr); +static int InitKeyEvent(XEvent *eventPtr, KeyEventData *e, UInt32 savedKeyCode, + UInt32 savedModifiers); +static int GenerateKeyEvent(UInt32 eKind, KeyEventData *e, UInt32 savedKeyCode, + UInt32 savedModifiers, const UniChar *chars, int numChars); +static int GetKeyboardLayout(Ptr *resourcePtr, TextEncoding *encodingPtr); +static TextEncoding GetKCHREncoding(ScriptCode script, SInt32 layoutid); +static int KeycodeToUnicodeViaUnicodeResource(UniChar *uniChars, int maxChars, + Ptr uchr, EventKind eKind, UInt32 keycode, UInt32 modifiers, + UInt32 *deadKeyStatePtr); +static int KeycodeToUnicodeViaKCHRResource(UniChar *uniChars, int maxChars, + Ptr kchr, TextEncoding encoding, EventKind eKind, UInt32 keycode, + UInt32 modifiers, UInt32 *deadKeyStatePtr); + /* *---------------------------------------------------------------------- * * TkMacOSXProcessKeyboardEvent -- * - * This routine processes the event in eventPtr, and - * generates the appropriate Tk events from it. + * This routine processes the event in eventPtr, and + * generates the appropriate Tk events from it. * * Results: - * True if event(s) are generated - false otherwise. + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. + * Additional events may be place on the Tk event queue. * *---------------------------------------------------------------------- */ MODULE_SCOPE int TkMacOSXProcessKeyboardEvent( - TkMacOSXEvent * eventPtr, - MacEventStatus * statusPtr) + TkMacOSXEvent *eventPtr, + MacEventStatus *statusPtr) { static UInt32 savedKeyCode = 0; static UInt32 savedModifiers = 0; static UniChar savedChar = 0; - OSStatus status; + OSStatus err; KeyEventData keyEventData; - MenuRef menuRef; + MenuRef menuRef; MenuItemIndex menuItemIndex; int eventGenerated; UniChar uniChars[5]; /* make this larger, if needed */ UInt32 uniCharsLen = 0; if (!InitKeyData(&keyEventData)) { - statusPtr->err = 1; - return false; + statusPtr->err = 1; + return false; } - + /* * Because of the way that Tk operates, we can't in general funnel menu - * accelerators through IsMenuKeyEvent. Tk treats accelerators as mere + * accelerators through IsMenuKeyEvent. Tk treats accelerators as mere * decoration, and the user has to install bindings to get them to fire. * * However, the only way to trigger the Hide & Hide Others functions - * is by invoking the Menu command for Hide. So there is no nice way to + * is by invoking the Menu command for Hide. So there is no nice way to * provide a Tk command to hide the app which would be available for a - * binding. So I am going to hijack Command-H and Command-Shift-H - * here, and run the menu commands. Since the HI Guidelines explicitly - * reserve these for Hide, this isn't such a bad thing. Also, if you do + * binding. So I am going to hijack Command-H and Command-Shift-H + * here, and run the menu commands. Since the HI Guidelines explicitly + * reserve these for Hide, this isn't such a bad thing. Also, if you do * rebind Command-H to another menu item, Hide will lose its binding. - * - * Note that I don't really do anything at this point, + * + * Note that I don't really do anything at this point, * I just mark stopProcessing as 0 and return, and then the * RecieveAndProcessEvent code will dispatch the event to the default * handler. */ - if ((eventPtr->eKind == kEventRawKeyDown + if ((eventPtr->eKind == kEventRawKeyDown || eventPtr->eKind == kEventRawKeyRepeat) - && IsMenuKeyEvent(tkCurrentAppleMenu, eventPtr->eventRef, + && IsMenuKeyEvent(tkCurrentAppleMenu, eventPtr->eventRef, kMenuEventQueryOnly, &menuRef, &menuItemIndex)) { MenuCommand menuCmd; @@ -203,114 +185,97 @@ TkMacOSXProcessKeyboardEvent( } } - status = GetEventParameter(eventPtr->eventRef, - kEventParamKeyMacCharCodes, - typeChar, NULL, - sizeof(keyEventData.ch), NULL, - &keyEventData.ch); - if (status != noErr) { -#ifdef TK_MAC_DEBUG - fprintf (stderr, "Failed to retrieve KeyMacCharCodes\n"); -#endif - statusPtr->err = 1; - return false; - } - status = GetEventParameter(eventPtr->eventRef, - kEventParamKeyCode, - typeUInt32, NULL, - sizeof(keyEventData.keyCode), NULL, - &keyEventData.keyCode); - if (status != noErr) { -#ifdef TK_MAC_DEBUG - fprintf (stderr, "Failed to retrieve KeyCode\n"); -#endif - statusPtr->err = 1; - return false; + err = ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamKeyMacCharCodes, typeChar, NULL, + sizeof(keyEventData.ch), NULL, &keyEventData.ch); + if (err != noErr) { + statusPtr->err = 1; + return false; } - status = GetEventParameter(eventPtr->eventRef, - kEventParamKeyModifiers, - typeUInt32, NULL, - sizeof(keyEventData.keyModifiers), NULL, - &keyEventData.keyModifiers); - if (status != noErr) { -#ifdef TK_MAC_DEBUG - fprintf (stderr, "Failed to retrieve KeyModifiers\n"); -#endif - statusPtr->err = 1; - return false; + err = ChkErr(GetEventParameter, eventPtr->eventRef, kEventParamKeyCode, + typeUInt32, NULL, sizeof(keyEventData.keyCode), NULL, + &keyEventData.keyCode); + if (err != noErr) { + statusPtr->err = 1; + return false; + } + err = ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamKeyModifiers, typeUInt32, NULL, + sizeof(keyEventData.keyModifiers), NULL, + &keyEventData.keyModifiers); + if (err != noErr) { + statusPtr->err = 1; + return false; } switch (eventPtr->eKind) { - case kEventRawKeyUp: - case kEventRawKeyDown: - case kEventRawKeyRepeat: - { - UInt32 *deadKeyStatePtr; - - if (kEventRawKeyDown == eventPtr->eKind) { - deadKeyStatePtr = &deadKeyStateDown; - } else { - deadKeyStatePtr = &deadKeyStateUp; - } - - uniCharsLen = TkMacOSXKeycodeToUnicode( - uniChars, sizeof(uniChars)/sizeof(*uniChars), - eventPtr->eKind, - keyEventData.keyCode, keyEventData.keyModifiers, - deadKeyStatePtr); - } + case kEventRawKeyUp: + case kEventRawKeyDown: + case kEventRawKeyRepeat: { + UInt32 *deadKeyStatePtr; + + if (kEventRawKeyDown == eventPtr->eKind) { + deadKeyStatePtr = &deadKeyStateDown; + } else { + deadKeyStatePtr = &deadKeyStateUp; + } + + uniCharsLen = TkMacOSXKeycodeToUnicode(uniChars, + sizeof(uniChars)/sizeof(*uniChars), eventPtr->eKind, + keyEventData.keyCode, keyEventData.keyModifiers, + deadKeyStatePtr); + break; + } } if (kEventRawKeyUp == eventPtr->eKind) { - /* - * For some reason the deadkey processing for KeyUp doesn't work - * sometimes, so we fudge and use the last detected KeyDown. - */ - - if((0 == uniCharsLen) && (0 != savedChar)) { - uniChars[0] = savedChar; - uniCharsLen = 1; - } - - /* - * Suppress keyup events while we have a deadkey sequence on keydown. - * We still *do* want to collect deadkey state in this situation if - * the system provides it, that's why we do this only after - * TkMacOSXKeycodeToUnicode(). - */ - - if (0 != deadKeyStateDown) { - uniCharsLen = 0; - } + /* + * For some reason the deadkey processing for KeyUp doesn't work + * sometimes, so we fudge and use the last detected KeyDown. + */ + + if ((0 == uniCharsLen) && (0 != savedChar)) { + uniChars[0] = savedChar; + uniCharsLen = 1; + } + + /* + * Suppress keyup events while we have a deadkey sequence on keydown. + * We still *do* want to collect deadkey state in this situation if + * the system provides it, that's why we do this only after + * TkMacOSXKeycodeToUnicode(). + */ + + if (0 != deadKeyStateDown) { + uniCharsLen = 0; + } } keyEventData.message = keyEventData.ch|(keyEventData.keyCode << 8); - eventGenerated = GenerateKeyEvent( - eventPtr->eKind, &keyEventData, - savedKeyCode, savedModifiers, - uniChars, uniCharsLen); + eventGenerated = GenerateKeyEvent(eventPtr->eKind, &keyEventData, + savedKeyCode, savedModifiers, uniChars, uniCharsLen); savedModifiers = keyEventData.keyModifiers; if ((kEventRawKeyDown == eventPtr->eKind) && (uniCharsLen > 0)) { - savedChar = uniChars[0]; + savedChar = uniChars[0]; } else { - savedChar = 0; + savedChar = 0; } - + statusPtr->stopProcessing = 1; if (eventGenerated == 0) { - savedKeyCode = keyEventData.message; - return false; + savedKeyCode = keyEventData.message; + return false; } else if (eventGenerated == -1) { - savedKeyCode = 0; - statusPtr->stopProcessing = 0; - return false; + savedKeyCode = 0; + statusPtr->stopProcessing = 0; + return false; } else { - savedKeyCode = 0; - return true; + savedKeyCode = 0; + return true; } } @@ -319,107 +284,101 @@ TkMacOSXProcessKeyboardEvent( * * GenerateKeyEvent -- * - * Given Macintosh keyUp, keyDown & autoKey events (in their "raw" - * form) and a list of unicode characters this function generates the - * appropriate X key events. + * Given Macintosh keyUp, keyDown & autoKey events (in their "raw" + * form) and a list of unicode characters this function generates the + * appropriate X key events. * - * Parameter eKind is a raw keyboard event. e contains the data sent - * with the event. savedKeyCode and savedModifiers contain the values - * from the last event that came before (see - * TkMacOSXProcessKeyboardEvent()). chars/numChars has the Unicode - * characters for which we want to create events. + * Parameter eKind is a raw keyboard event. e contains the data sent + * with the event. savedKeyCode and savedModifiers contain the values + * from the last event that came before (see + * TkMacOSXProcessKeyboardEvent()). chars/numChars has the Unicode + * characters for which we want to create events. * * Results: - * 1 if an event was generated, -1 for any error. + * 1 if an event was generated, -1 for any error. * * Side effects: - * Additional events may be place on the Tk event queue. + * Additional events may be place on the Tk event queue. * *---------------------------------------------------------------------- */ static int GenerateKeyEvent( - UInt32 eKind, - KeyEventData * e, - UInt32 savedKeyCode, - UInt32 savedModifiers, - const UniChar * chars, int numChars) + UInt32 eKind, + KeyEventData * e, + UInt32 savedKeyCode, + UInt32 savedModifiers, + const UniChar * chars, + int numChars) { XEvent event; int i; - + if (-1 == InitKeyEvent(&event, e, savedKeyCode, savedModifiers)) { - return -1; + return -1; } if (kEventRawKeyModifiersChanged == eKind) { + if (savedModifiers > e->keyModifiers) { + event.xany.type = KeyRelease; + } else { + event.xany.type = KeyPress; + } - if (savedModifiers > e->keyModifiers) { - event.xany.type = KeyRelease; - } else { - event.xany.type = KeyPress; - } - - /* - * Use special '-1' to signify a special keycode to our - * platform specific code in tkMacOSXKeyboard.c. This is - * rather like what happens on Windows. - */ - - event.xany.send_event = -1; - - /* - * Set keycode (which was zero) to the changed modifier - */ - - event.xkey.keycode = (e->keyModifiers ^ savedModifiers); - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + /* + * Use special '-1' to signify a special keycode to our + * platform specific code in tkMacOSXKeyboard.c. This is + * rather like what happens on Windows. + */ - } else { + event.xany.send_event = -1; - for (i = 0; i < numChars; ++i) { - - /* - * Encode one char in the trans_chars array that was already - * introduced for MS Windows. Don't encode the string, if it is - * a control character but was not generated with a real control - * modifier. Such control characters get generated by KeyTrans() - * for special keys, but we rather want to identify those by - * their KeySyms. - */ - - event.xkey.trans_chars[0] = 0; - if ((controlKey & e->keyModifiers) || (chars[i] >= ' ')) { - int done; - done = Tcl_UniCharToUtf(chars[i],event.xkey.trans_chars); - event.xkey.trans_chars[done] = 0; - } - - switch(eKind) { - case kEventRawKeyDown: - event.xany.type = KeyPress; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - break; - case kEventRawKeyUp: - event.xany.type = KeyRelease; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - break; - case kEventRawKeyRepeat: - event.xany.type = KeyRelease; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - event.xany.type = KeyPress; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - break; - default: -#ifdef TK_MAC_DEBUG - fprintf (stderr, - "GenerateKeyEvent(): Invalid parameter eKind %d\n", - (int) eKind); -#endif - return -1; - } - } + /* + * Set keycode (which was zero) to the changed modifier + */ + + event.xkey.keycode = (e->keyModifiers ^ savedModifiers); + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + + } else { + for (i = 0; i < numChars; ++i) { + /* + * Encode one char in the trans_chars array that was already + * introduced for MS Windows. Don't encode the string, if it is + * a control character but was not generated with a real control + * modifier. Such control characters get generated by KeyTrans() + * for special keys, but we rather want to identify those by + * their KeySyms. + */ + + event.xkey.trans_chars[0] = 0; + if ((controlKey & e->keyModifiers) || (chars[i] >= ' ')) { + int done; + done = Tcl_UniCharToUtf(chars[i],event.xkey.trans_chars); + event.xkey.trans_chars[done] = 0; + } + + switch(eKind) { + case kEventRawKeyDown: + event.xany.type = KeyPress; + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + break; + case kEventRawKeyUp: + event.xany.type = KeyRelease; + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + break; + case kEventRawKeyRepeat: + event.xany.type = KeyRelease; + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + event.xany.type = KeyPress; + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + break; + default: + TkMacOSXDbgMsg("Invalid parameter eKind %ld", eKind); + return -1; + } + } } return 1; @@ -430,33 +389,32 @@ GenerateKeyEvent( * * InitKeyData -- * - * This routine initializes a KeyEventData structure by asking the OS - * and Tk for all the global information needed here. + * This routine initializes a KeyEventData structure by asking the OS + * and Tk for all the global information needed here. * * Results: - * True if the current front window can be found in Tk data structures - * - false otherwise. + * True if the current front window can be found in Tk data structures + * - false otherwise. * * Side Effects: - * None + * None * *---------------------------------------------------------------------- */ -static int -InitKeyData(KeyEventData * keyEventDataPtr) + +static int +InitKeyData( + KeyEventData *keyEventDataPtr) { - memset (keyEventDataPtr, 0, sizeof(*keyEventDataPtr)); + memset(keyEventDataPtr, 0, sizeof(*keyEventDataPtr)); keyEventDataPtr->whichWindow = ActiveNonFloatingWindow(); if (keyEventDataPtr->whichWindow == NULL) { - return false; + return false; } - XQueryPointer(NULL, None, NULL, NULL, - &keyEventDataPtr->global_x, - &keyEventDataPtr->global_y, - &keyEventDataPtr->local_x, - &keyEventDataPtr->local_y, - &keyEventDataPtr->state); + XQueryPointer(NULL, None, NULL, NULL, &keyEventDataPtr->global_x, + &keyEventDataPtr->global_y, &keyEventDataPtr->local_x, + &keyEventDataPtr->local_y, &keyEventDataPtr->state); return true; } @@ -466,52 +424,52 @@ InitKeyData(KeyEventData * keyEventDataPtr) * * InitKeyEvent -- * - * Initialize an XEvent structure by asking Tk for global information. - * Also uses a KeyEventData structure and other current state. + * Initialize an XEvent structure by asking Tk for global information. + * Also uses a KeyEventData structure and other current state. * * Results: - * 1 on success, -1 for any error. + * 1 on success, -1 for any error. * * Side effects: - * Additional events may be place on the Tk event queue. + * Additional events may be place on the Tk event queue. * *---------------------------------------------------------------------- */ -/* - * We have a general problem here. How do we handle 'Option-char' - * keypresses? The problem is that we might want to bind to some of these - * (e.g. Cmd-Opt-d is 'uncomment' in Alpha). OTOH Option-d actually produces +/* + * We have a general problem here. How do we handle 'Option-char' + * keypresses? The problem is that we might want to bind to some of these + * (e.g. Cmd-Opt-d is 'uncomment' in Alpha). OTOH Option-d actually produces * a real character on MacOS, namely a mathematical delta. * * The current behaviour is that a binding goes by the combinations of - * modifiers and base keysym, that is Option-d. The string value of the + * modifiers and base keysym, that is Option-d. The string value of the * event is the mathematical delta character, so if no binding calls * [break], the text widget will insert that character. * - * Note that this is similar to control combinations on all platforms. They + * Note that this is similar to control combinations on all platforms. They * also generate events that have the base character as keysym and a real - * control character as character value. So Ctrl+C gets us the keysym XK_C, + * control character as character value. So Ctrl+C gets us the keysym XK_C, * the modifier Control (so you can bind <Control-C>) and a string value as * "\u0003". - * + * * For a different solutions we may want for the event to contain keysyms for - * *both* the 'Opt-d' side of things and the mathematical delta. Then a + * *both* the 'Opt-d' side of things and the mathematical delta. Then a * binding on Opt-d will trigger, but a binding on mathematical delta would - * also trigger. This would require changes in the core, though. + * also trigger. This would require changes in the core, though. */ static int InitKeyEvent( - XEvent * eventPtr, - KeyEventData * e, - UInt32 savedKeyCode, - UInt32 savedModifiers) + XEvent * eventPtr, + KeyEventData * e, + UInt32 savedKeyCode, + UInt32 savedModifiers) { Window window; Tk_Window tkwin; TkDisplay *dispPtr; - + /* * The focus must be in the FrontWindow on the Macintosh. * We then query Tk to determine the exact Tk window @@ -521,20 +479,16 @@ InitKeyEvent( window = TkMacOSXGetXWindow(e->whichWindow); dispPtr = TkGetDisplayList(); tkwin = Tk_IdToWindow(dispPtr->display, window); - - if (tkwin == NULL) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"tkwin == NULL, %d\n", __LINE__); -#endif - return -1; + + if (!tkwin) { + TkMacOSXDbgMsg("tkwin == NULL"); + return -1; } - + tkwin = (Tk_Window) ((TkWindow *) tkwin)->dispPtr->focusPtr; - if (tkwin == NULL) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"tkwin == NULL, %d\n", __LINE__); -#endif - return -1; + if (!tkwin) { + TkMacOSXDbgMsg("tkwin == NULL"); + return -1; } eventPtr->xany.send_event = false; @@ -551,302 +505,223 @@ InitKeyEvent( eventPtr->xkey.state = e->state; eventPtr->xkey.trans_chars[0] = 0; - Tk_TopCoordsToWindow( - tkwin, e->local_x, e->local_y, - &eventPtr->xkey.x, &eventPtr->xkey.y); + Tk_TopCoordsToWindow(tkwin, e->local_x, e->local_y, &eventPtr->xkey.x, + &eventPtr->xkey.y); - eventPtr->xkey.keycode = e->ch | - ((savedKeyCode & charCodeMask) << 8) | - ((e->message&keyCodeMask) << 8); + eventPtr->xkey.keycode = e->ch | ((savedKeyCode & charCodeMask) << 8) | + ((e->message&keyCodeMask) << 8); return 1; } - /* - * If we have old headers, we need to define these types and constants - * ourself. We use preprocessor macros instead of enums and typedefs, - * because macros work even in case of version misunderstandings, while - * duplicate enums and typedefs would give errrors. - */ - -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1020 -#define KeyboardLayoutRef Ptr -#define KeyboardLayoutPropertyTag UInt32 -#define kKLKCHRData 0 -#define kKLuchrData 1 -#define kKLIdentifier 2 -#endif - -/* *---------------------------------------------------------------------- * * GetKeyboardLayout -- * - * Queries the OS for a pointer to a keyboard resource. + * Queries the OS for a pointer to a keyboard resource. * - * This function works with the keyboard layout switch menu. It uses - * Keyboard Layout Services, where available. + * This function works with the keyboard layout switch menu. It uses + * Keyboard Layout Services, where available. * * Results: - * 1 if there is returned a Unicode 'uchr' resource in *resourcePtr, 0 - * if it is a classic 'KCHR' resource. A pointer to the actual resource - * data goes into *resourcePtr. If the resource is a 'KCHR' resource, - * the corresponding Mac encoding goes into *encodingPtr. + * 1 if there is returned a Unicode 'uchr' resource in *resourcePtr, 0 + * if it is a classic 'KCHR' resource. A pointer to the actual resource + * data goes into *resourcePtr. If the resource is a 'KCHR' resource, + * the corresponding Mac encoding goes into *encodingPtr. * * Side effects: - * Sets some internal static variables. + * Sets some internal static variables. * *---------------------------------------------------------------------- */ static int -GetKeyboardLayout (Ptr * resourcePtr, TextEncoding * encodingPtr) +GetKeyboardLayout( + Ptr *resourcePtr, + TextEncoding *encodingPtr) { static KeyboardLayoutRef lastLayout = NULL; static SInt32 lastLayoutId; static TextEncoding lastEncoding = kTextEncodingMacRoman; static Ptr uchr = NULL; static Ptr KCHR = NULL; - static Handle handle = NULL; - int hasLayoutChanged = false; KeyboardLayoutRef currentLayout = NULL; SInt32 currentLayoutId = 0; ScriptCode currentKeyScript; - /* - * Several code branches need this information. - */ - currentKeyScript = GetScriptManagerVariable(smKeyScript); - TkMacOSXInitNamedSymbol(HIToolbox, OSStatus, KLGetCurrentKeyboardLayout, - KeyboardLayoutRef*); - TkMacOSXInitNamedSymbol(HIToolbox, OSStatus, KLGetKeyboardLayoutProperty, - KeyboardLayoutRef, KeyboardLayoutPropertyTag, const void**); - if (KLGetCurrentKeyboardLayout && KLGetKeyboardLayoutProperty) { - - /* - * Use the Keyboard Layout Services (these functions only exist since - * 10.2). - */ - - KLGetCurrentKeyboardLayout(¤tLayout); - - if (currentLayout != NULL) { - - /* - * The layout pointer could in theory be the same for different - * layouts, only the id gives us the information that the - * keyboard has actually changed. OTOH the layout object can - * also change and it could still be the same layoutid. - */ - - KLGetKeyboardLayoutProperty(currentLayout, kKLIdentifier, - (const void**)¤tLayoutId); - - if ((lastLayout != currentLayout) - || (lastLayoutId != currentLayoutId)) { - -#ifdef TK_MAC_DEBUG_KEYBOARD - fprintf (stderr, "GetKeyboardLayout(): Use KLS\n"); -#endif + /* + * Use the Keyboard Layout Services. + */ - hasLayoutChanged = true; - - /* - * Reinitialize all relevant variables. - */ - - lastLayout = currentLayout; - lastLayoutId = currentLayoutId; - uchr = NULL; - KCHR = NULL; - - if ((KLGetKeyboardLayoutProperty(currentLayout, - kKLuchrData, (const void**)&uchr) - == noErr) - && (uchr != NULL)) { - /* done */ - } else if ((KLGetKeyboardLayoutProperty(currentLayout, - kKLKCHRData, (const void**)&KCHR) - == noErr) - && (KCHR != NULL)) { - /* done */ - } - } - } + KLGetCurrentKeyboardLayout(¤tLayout); - } else { + if (currentLayout != NULL) { - /* - * Use the classic approach as shown in Apple code samples, loading - * the keyboard resources directly. This is broken for 10.3 and - * possibly already in 10.2. - */ + /* + * The layout pointer could in theory be the same for different + * layouts, only the id gives us the information that the + * keyboard has actually changed. OTOH the layout object can + * also change and it could still be the same layoutid. + */ - currentLayoutId = GetScriptVariable(currentKeyScript,smScriptKeys); + KLGetKeyboardLayoutProperty(currentLayout, kKLIdentifier, + (const void**)¤tLayoutId); - if ((lastLayout == NULL) || (lastLayoutId != currentLayoutId)) { + if ((lastLayout != currentLayout) + || (lastLayoutId != currentLayoutId)) { #ifdef TK_MAC_DEBUG_KEYBOARD - fprintf (stderr, "GetKeyboardLayout(): Use GetResource()\n"); + TkMacOSXDbgMsg("Use KLS"); #endif - hasLayoutChanged = true; - - /* - * Reinitialize all relevant variables. - */ - - lastLayout = (KeyboardLayoutRef)-1; - lastLayoutId = currentLayoutId; - uchr = NULL; - KCHR = NULL; - - /* - * Get the new layout resource in the classic way. - */ - - if (handle != NULL) { - HUnlock(handle); - } - - if ((handle = GetResource('uchr',currentLayoutId)) != NULL) { - HLock(handle); - uchr = *handle; - } else if ((handle = GetResource('KCHR',currentLayoutId)) != NULL) { - HLock(handle); - KCHR = *handle; - } - } + hasLayoutChanged = true; + + /* + * Reinitialize all relevant variables. + */ + + lastLayout = currentLayout; + lastLayoutId = currentLayoutId; + uchr = NULL; + KCHR = NULL; + + if ((KLGetKeyboardLayoutProperty(currentLayout, + kKLuchrData, (const void**)&uchr) + == noErr) + && (uchr != NULL)) { + /* done */ + } else if ((KLGetKeyboardLayoutProperty(currentLayout, + kKLKCHRData, (const void**)&KCHR) + == noErr) + && (KCHR != NULL)) { + /* done */ + } + } } if (hasLayoutChanged) { - #ifdef TK_MAC_DEBUG_KEYBOARD - if (KCHR != NULL) { - fprintf (stderr, "GetKeyboardLayout(): New 'KCHR' layout %d\n", - (int) (short) currentLayoutId); - } else if (uchr != NULL) { - fprintf (stderr, "GetKeyboardLayout(): New 'uchr' layout %d\n", - (int) (short) currentLayoutId); - } else { - fprintf (stderr, "GetKeyboardLayout(): Use cached layout " - "(should have been %d)\n", - (int) (short) currentLayoutId); - } + if (KCHR) { + TkMacOSXDbgMsg("New 'KCHR' layout %ld", currentLayoutId); + } else if (uchr) { + TkMacOSXDbgMsg("New 'uchr' layout %ld", currentLayoutId); + } else { + TkMacOSXDbgMsg("Use cached layout (should have been %ld)", + currentLayoutId); + } #endif - deadKeyStateUp = deadKeyStateDown = 0; + deadKeyStateUp = deadKeyStateDown = 0; - /* - * If we did get a new 'KCHR', compute its encoding and put it into - * lastEncoding. - * - * If we didn't get a new 'KCHR' and if we have no 'uchr' either, get - * some 'KCHR' from the OS cache and leave lastEncoding at its - * current value. This should better not happen, it doesn't really - * work. - */ + /* + * If we did get a new 'KCHR', compute its encoding and put it into + * lastEncoding. + * + * If we didn't get a new 'KCHR' and if we have no 'uchr' either, get + * some 'KCHR' from the OS cache and leave lastEncoding at its + * current value. This should better not happen, it doesn't really + * work. + */ - if (KCHR != NULL) { - lastEncoding = GetKCHREncoding(currentKeyScript, currentLayoutId); + if (KCHR) { + lastEncoding = GetKCHREncoding(currentKeyScript, currentLayoutId); #ifdef TK_MAC_DEBUG_KEYBOARD - fprintf (stderr, "GetKeyboardLayout(): New 'KCHR' encoding %lu " - "(%lu + 0x%lX)\n", - lastEncoding, lastEncoding & 0xFFFFL, - lastEncoding & ~0xFFFFL); + TkMacOSXDbgMsg("New 'KCHR' encoding %lu (%lu + 0x%lX)", + lastEncoding, lastEncoding & 0xFFFFL, + lastEncoding & ~0xFFFFL); #endif - } else if (uchr == NULL) { - KCHR = (Ptr) GetScriptManagerVariable(smKCHRCache); - } + } else if (!uchr) { + KCHR = (Ptr)(intptr_t)GetScriptManagerVariable(smKCHRCache); + } } - if (uchr != NULL) { - *resourcePtr = uchr; - return 1; + if (uchr) { + *resourcePtr = uchr; + return 1; } else { - *resourcePtr = KCHR; - *encodingPtr = lastEncoding; - return 0; + *resourcePtr = KCHR; + *encodingPtr = lastEncoding; + return 0; } } - /* *---------------------------------------------------------------------- * * GetKCHREncoding -- * - * Upgrade a WorldScript code to a TEC encoding based on the keyboard - * layout id. + * Upgrade a WorldScript code to a TEC encoding based on the keyboard + * layout id. * * Results: - * The TEC code that corresponds best to the combination of WorldScript - * code and 'KCHR' id. + * The TEC code that corresponds best to the combination of WorldScript + * code and 'KCHR' id. * * Side effects: - * None. + * None. * * Rationale and Notes: - * WorldScript codes are sometimes not unique encodings. E.g. Icelandic - * uses script smRoman (0), but the actual encoding is - * kTextEncodingMacIcelandic (37). ftp://ftp.unicode.org/Public - * /MAPPINGS/VENDORS/APPLE/README.TXT has a good summary of these - * variants. So we need to upgrade the script to an encoding with - * GetTextEncodingFromScriptInfo(). + * WorldScript codes are sometimes not unique encodings. E.g. Icelandic + * uses script smRoman (0), but the actual encoding is + * kTextEncodingMacIcelandic (37). ftp://ftp.unicode.org/Public + * /MAPPINGS/VENDORS/APPLE/README.TXT has a good summary of these + * variants. So we need to upgrade the script to an encoding with + * GetTextEncodingFromScriptInfo(). * - * 'KCHR' ids are usually region codes (see the comments in Script.h). - * Where they are not, we get a paramErr from the OS function and have - * appropriate fallbacks. + * 'KCHR' ids are usually region codes (see the comments in Script.h). + * Where they are not, we get a paramErr from the OS function and have + * appropriate fallbacks. * *---------------------------------------------------------------------- */ static TextEncoding -GetKCHREncoding(ScriptCode script, SInt32 layoutid) +GetKCHREncoding( + ScriptCode script, + SInt32 layoutid) { RegionCode region = layoutid; TextEncoding encoding = script; if (GetTextEncodingFromScriptInfo(script, kTextLanguageDontCare, region, - &encoding) == noErr) { - return encoding; + &encoding) == noErr) { + return encoding; } /* * GetTextEncodingFromScriptInfo() doesn't know about more exotic - * layouts. This provides a fallback for good measure. In an ideal + * layouts. This provides a fallback for good measure. In an ideal * world, exotic layouts would always provide a 'uchr' resource anyway, * so we wouldn't need this. * - * We can add more keyboard layouts, if we get actual complaints. Farsi + * We can add more keyboard layouts, if we get actual complaints. Farsi * or other Celtic/Gaelic layouts would be candidates. */ switch (layoutid) { - - /* - * Icelandic and Faroese (planned). These layouts are sold by Apple - * Iceland for legacy applications. - */ - - case 1800: case 1821: - return kTextEncodingMacIcelandic; - - /* - * Irish and Welsh. These layouts are mentioned in <Script.h>. - * - * FIXME: This may have to be kTextEncodingMacGaelic instead, but I - * can't locate layouts of this type for testing. - */ - - case 581: case 779: - return kTextEncodingMacCeltic; + /* + * Icelandic and Faroese (planned). These layouts are sold by Apple + * Iceland for legacy applications. + */ + + case 1800: case 1821: + return kTextEncodingMacIcelandic; + + /* + * Irish and Welsh. These layouts are mentioned in <Script.h>. + * + * FIXME: This may have to be kTextEncodingMacGaelic instead, but I + * can't locate layouts of this type for testing. + */ + + case 581: case 779: + return kTextEncodingMacCeltic; } - + /* * The valid script codes are also the valid default encoding codes, so * if nothing else helps, fall back on those. @@ -854,275 +729,266 @@ GetKCHREncoding(ScriptCode script, SInt32 layoutid) return script; } - /* *---------------------------------------------------------------------- * * KeycodeToUnicodeViaUnicodeResource -- * - * Given MacOS key event data this function generates the Unicode - * characters. It does this using a 'uchr' and the UCKeyTranslate - * API. + * Given MacOS key event data this function generates the Unicode + * characters. It does this using a 'uchr' and the UCKeyTranslate + * API. * - * The parameter deadKeyStatePtr can be NULL, if no deadkey handling - * is needed. + * The parameter deadKeyStatePtr can be NULL, if no deadkey handling + * is needed. * - * Tested and known to work with US, Hebrew, Greek and Russian layouts - * as well as "Unicode Hex Input". + * Tested and known to work with US, Hebrew, Greek and Russian layouts + * as well as "Unicode Hex Input". * * Results: - * The number of characters generated if any, 0 if we are waiting for - * another byte of a dead-key sequence. Fills in the uniChars array - * with a Unicode string. + * The number of characters generated if any, 0 if we are waiting for + * another byte of a dead-key sequence. Fills in the uniChars array + * with a Unicode string. * * Side Effects: - * None + * None * *---------------------------------------------------------------------- */ static int KeycodeToUnicodeViaUnicodeResource( - UniChar * uniChars, int maxChars, - Ptr uchr, - EventKind eKind, - UInt32 keycode, UInt32 modifiers, - UInt32 * deadKeyStatePtr) + UniChar *uniChars, + int maxChars, + Ptr uchr, + EventKind eKind, + UInt32 keycode, + UInt32 modifiers, + UInt32 *deadKeyStatePtr) { int action; unsigned long keyboardType; OptionBits options = 0; UInt32 dummy_state; - UniCharCount actuallength; - OSStatus status; + UniCharCount actuallength; + OSStatus err; keycode &= 0xFF; modifiers = (modifiers >> 8) & 0xFF; keyboardType = LMGetKbdType(); if (NULL==deadKeyStatePtr) { - options = kUCKeyTranslateNoDeadKeysMask; - dummy_state = 0; - deadKeyStatePtr = &dummy_state; + options = kUCKeyTranslateNoDeadKeysMask; + dummy_state = 0; + deadKeyStatePtr = &dummy_state; } - switch(eKind) { - case kEventRawKeyDown: - action = kUCKeyActionDown; - break; - case kEventRawKeyUp: - action = kUCKeyActionUp; - break; - case kEventRawKeyRepeat: - action = kUCKeyActionAutoKey; - break; - default: -#ifdef TK_MAC_DEBUG - fprintf (stderr, - "KeycodeToUnicodeViaUnicodeResource(): " - "Invalid parameter eKind %d\n", - (int) eKind); -#endif - return 0; + switch(eKind) { + case kEventRawKeyDown: + action = kUCKeyActionDown; + break; + case kEventRawKeyUp: + action = kUCKeyActionUp; + break; + case kEventRawKeyRepeat: + action = kUCKeyActionAutoKey; + break; + default: + TkMacOSXDbgMsg("Invalid parameter eKind %d", eKind); + return 0; } - status = UCKeyTranslate( - (const UCKeyboardLayout *) uchr, - keycode, action, modifiers, keyboardType, - options, deadKeyStatePtr, - maxChars, &actuallength, uniChars); + err = ChkErr(UCKeyTranslate, (const UCKeyboardLayout *) uchr, keycode, + action, modifiers, keyboardType, options, deadKeyStatePtr, + maxChars, &actuallength, uniChars); if ((0 == actuallength) && (0 != *deadKeyStatePtr)) { - /* - * More data later - */ - - return 0; + /* + * More data later + */ + + return 0; } - + /* * some IMEs leave residue :-( */ - - *deadKeyStatePtr = 0; - if (noErr != status) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"UCKeyTranslate failed: %d", (int) status); -#endif - actuallength = 0; + *deadKeyStatePtr = 0; + + if (err != noErr) { + actuallength = 0; } return actuallength; } - /* *---------------------------------------------------------------------- * * KeycodeToUnicodeViaKCHRResource -- * - * Given MacOS key event data this function generates the Unicode - * characters. It does this using a 'KCHR' and the KeyTranslate API. + * Given MacOS key event data this function generates the Unicode + * characters. It does this using a 'KCHR' and the KeyTranslate API. * - * The parameter deadKeyStatePtr can be NULL, if no deadkey handling - * is needed. + * The parameter deadKeyStatePtr can be NULL, if no deadkey handling + * is needed. * * Results: - * The number of characters generated if any, 0 if we are waiting for - * another byte of a dead-key sequence. Fills in the uniChars array - * with a Unicode string. + * The number of characters generated if any, 0 if we are waiting for + * another byte of a dead-key sequence. Fills in the uniChars array + * with a Unicode string. * * Side Effects: - * None + * None * *---------------------------------------------------------------------- */ static int KeycodeToUnicodeViaKCHRResource( - UniChar * uniChars, int maxChars, - Ptr kchr, TextEncoding encoding, - EventKind eKind, - UInt32 keycode, UInt32 modifiers, - UInt32 * deadKeyStatePtr) + UniChar *uniChars, + int maxChars, + Ptr kchr, + TextEncoding encoding, + EventKind eKind, + UInt32 keycode, + UInt32 modifiers, + UInt32 *deadKeyStatePtr) { UInt32 result; char macBuff[3]; - char * macStr; + char *macStr; int macStrLen; UInt32 dummy_state = 0; - if (NULL == deadKeyStatePtr) { - deadKeyStatePtr = &dummy_state; + deadKeyStatePtr = &dummy_state; } keycode |= modifiers; result = KeyTranslate(kchr, keycode, deadKeyStatePtr); if ((0 == result) && (0 != dummy_state)) { - /* - * 'dummy_state' gets only filled if the caller did not want deadkey - * processing (deadKeyStatePtr was NULL originally), but we still - * have a deadkey. We just push the keycode for the space bar to get - * the real key value. - */ - - result = KeyTranslate(kchr, 0x31, deadKeyStatePtr); - *deadKeyStatePtr = 0; + /* + * 'dummy_state' gets only filled if the caller did not want deadkey + * processing (deadKeyStatePtr was NULL originally), but we still + * have a deadkey. We just push the keycode for the space bar to get + * the real key value. + */ + + result = KeyTranslate(kchr, 0x31, deadKeyStatePtr); + *deadKeyStatePtr = 0; } if ((0 == result) && (0 != *deadKeyStatePtr)) { - /* - * More data later - */ - - return 0; + /* + * More data later + */ + + return 0; } macBuff[0] = (char) (result >> 16); - macBuff[1] = (char) result; + macBuff[1] = (char) result; macBuff[2] = 0; if (0 != macBuff[0]) { - /* - * If the first byte is valid, the second is too - */ - - macStr = macBuff; - macStrLen = 2; + /* + * If the first byte is valid, the second is too + */ + + macStr = macBuff; + macStrLen = 2; } else if (0 != macBuff[1]) { - /* - * Only the second is valid - */ - - macStr = macBuff+1; - macStrLen = 1; + /* + * Only the second is valid + */ + + macStr = macBuff+1; + macStrLen = 1; } else { - /* - * No valid bytes at all -- shouldn't happen - */ - - macStr = NULL; - macStrLen = 0; + /* + * No valid bytes at all -- shouldn't happen + */ + + macStr = NULL; + macStrLen = 0; } if (macStrLen <= 0) { - return 0; + return 0; } else { - /* - * Use the CFString conversion routines. This is the easiest and - * most compatible way to get from an 8-bit string and a MacOS script - * code to a Unicode string. - * - * FIXME: The system ships with an Irish 'KCHR' but without the - * corresponding macCeltic encoding, which triggers the error below. - * Tcl doesn't have the macCeltic encoding either right now, so until - * we get that, we can just as well stick to this code. The right - * fix would be to use the Tcl encodings and add macCeltic and - * probably others there. Suitable Unicode data files for the - * missing encodings are available from www.evertype.com. - */ - - CFStringRef cfString; - int uniStrLen; - - cfString = CFStringCreateWithCStringNoCopy( - NULL, macStr, encoding, kCFAllocatorNull); - if (cfString == NULL) { -#ifdef TK_MAC_DEBUG - fprintf(stderr, "CFString: Can't convert with encoding %d\n", - (int) encoding); -#endif - return 0; - } + /* + * Use the CFString conversion routines. This is the easiest and + * most compatible way to get from an 8-bit string and a MacOS script + * code to a Unicode string. + * + * FIXME: The system ships with an Irish 'KCHR' but without the + * corresponding macCeltic encoding, which triggers the error below. + * Tcl doesn't have the macCeltic encoding either right now, so until + * we get that, we can just as well stick to this code. The right + * fix would be to use the Tcl encodings and add macCeltic and + * probably others there. Suitable Unicode data files for the + * missing encodings are available from www.evertype.com. + */ + + CFStringRef cfString; + int uniStrLen; + + cfString = CFStringCreateWithCStringNoCopy(NULL, macStr, encoding, + kCFAllocatorNull); + if (cfString == NULL) { + TkMacOSXDbgMsg("CFString: Can't convert with encoding %ld", + encoding); + return 0; + } - uniStrLen = CFStringGetLength(cfString); - if (uniStrLen > maxChars) { - uniStrLen = maxChars; - } - CFStringGetCharacters(cfString, CFRangeMake(0,uniStrLen), uniChars); - CFRelease(cfString); + uniStrLen = CFStringGetLength(cfString); + if (uniStrLen > maxChars) { + uniStrLen = maxChars; + } + CFStringGetCharacters(cfString, CFRangeMake(0,uniStrLen), uniChars); + CFRelease(cfString); - return uniStrLen; + return uniStrLen; } } - /* *---------------------------------------------------------------------- * * TkMacOSXKeycodeToUnicode -- * - * Given MacOS key event data this function generates the Unicode - * characters. It does this using OS resources and APIs. + * Given MacOS key event data this function generates the Unicode + * characters. It does this using OS resources and APIs. * - * The parameter deadKeyStatePtr can be NULL, if no deadkey handling - * is needed. + * The parameter deadKeyStatePtr can be NULL, if no deadkey handling + * is needed. * - * This function is called from XKeycodeToKeysym() in - * tkMacOSKeyboard.c. + * This function is called from XKeycodeToKeysym() in + * tkMacOSKeyboard.c. * * Results: - * The number of characters generated if any, 0 if we are waiting for - * another byte of a dead-key sequence. Fills in the uniChars array - * with a Unicode string. + * The number of characters generated if any, 0 if we are waiting for + * another byte of a dead-key sequence. Fills in the uniChars array + * with a Unicode string. * * Side Effects: - * None + * None * *---------------------------------------------------------------------- */ MODULE_SCOPE int TkMacOSXKeycodeToUnicode( - UniChar * uniChars, int maxChars, - EventKind eKind, - UInt32 keycode, UInt32 modifiers, - UInt32 * deadKeyStatePtr) + UniChar *uniChars, + int maxChars, + EventKind eKind, + UInt32 keycode, + UInt32 modifiers, + UInt32 *deadKeyStatePtr) { Ptr resource = NULL; TextEncoding encoding; @@ -1130,32 +996,30 @@ TkMacOSXKeycodeToUnicode( if (GetKeyboardLayout(&resource,&encoding)) { - len = KeycodeToUnicodeViaUnicodeResource( - uniChars, maxChars, resource, eKind, - keycode, modifiers, deadKeyStatePtr); + len = KeycodeToUnicodeViaUnicodeResource( + uniChars, maxChars, resource, eKind, + keycode, modifiers, deadKeyStatePtr); } else { - len = KeycodeToUnicodeViaKCHRResource( - uniChars, maxChars, resource, encoding, eKind, - keycode, modifiers, deadKeyStatePtr); + len = KeycodeToUnicodeViaKCHRResource( + uniChars, maxChars, resource, encoding, eKind, + keycode, modifiers, deadKeyStatePtr); } return len; } - - /* *---------------------------------------------------------------------- * * XGrabKeyboard -- * - * Simulates a keyboard grab by setting the focus. + * Simulates a keyboard grab by setting the focus. * * Results: - * Always returns GrabSuccess. + * Always returns GrabSuccess. * * Side effects: - * Sets the keyboard focus to the specified window. + * Sets the keyboard focus to the specified window. * *---------------------------------------------------------------------- */ @@ -1169,7 +1033,7 @@ XGrabKeyboard( int keyboard_mode, Time time) { - gKeyboardWinPtr = Tk_IdToWindow(display, grab_window); + keyboardGrabWinPtr = Tk_IdToWindow(display, grab_window); return GrabSuccess; } @@ -1178,13 +1042,13 @@ XGrabKeyboard( * * XUngrabKeyboard -- * - * Releases the simulated keyboard grab. + * Releases the simulated keyboard grab. * * Results: - * None. + * None. * * Side effects: - * Sets the keyboard focus back to the value before the grab. + * Sets the keyboard focus back to the value before the grab. * *---------------------------------------------------------------------- */ @@ -1194,7 +1058,7 @@ XUngrabKeyboard( Display* display, Time time) { - gKeyboardWinPtr = NULL; + keyboardGrabWinPtr = NULL; } /* @@ -1203,15 +1067,16 @@ XUngrabKeyboard( * TkMacOSXGetCapture -- * * Results: - * Returns the current grab window + * Returns the current grab window * Side effects: - * None. + * None. * */ + Tk_Window -TkMacOSXGetCapture() +TkMacOSXGetCapture(void) { - return gGrabWinPtr; + return grabWinPtr; } /* @@ -1219,28 +1084,46 @@ TkMacOSXGetCapture() * * TkpSetCapture -- * - * This function captures the mouse so that all future events - * will be reported to this window, even if the mouse is outside - * the window. If the specified window is NULL, then the mouse - * is released. + * This function captures the mouse so that all future events + * will be reported to this window, even if the mouse is outside + * the window. If the specified window is NULL, then the mouse + * is released. * * Results: - * None. + * None. * * Side effects: - * Sets the capture flag and captures the mouse. + * Sets the capture flag and captures the mouse. * *---------------------------------------------------------------------- */ void TkpSetCapture( - TkWindow *winPtr) /* Capture window, or NULL. */ + TkWindow *winPtr) /* Capture window, or NULL. */ { - while ((winPtr != NULL) && !Tk_IsTopLevel(winPtr)) { - winPtr = winPtr->parentPtr; + while (winPtr && !Tk_IsTopLevel(winPtr)) { + winPtr = winPtr->parentPtr; } - gGrabWinPtr = (Tk_Window) winPtr; +#if 0 + { + TkWindow *w = NULL; + WindowModality m; + + if (winPtr) { + w = winPtr; + m = kWindowModalityAppModal; + } else if (grabWinPtr) { + w = (TkWindow*)grabWinPtr; + m = kWindowModalityNone; + } + if (w && w->window != None && TkMacOSXHostToplevelExists(w)) { + ChkErr(SetWindowModality, GetWindowFromPort( + TkMacOSXGetDrawablePort(w->window)), m, NULL); + } + } +#endif + grabWinPtr = (Tk_Window) winPtr; } /* @@ -1248,25 +1131,25 @@ TkpSetCapture( * * Tk_SetCaretPos -- * - * This enables correct placement of the XIM caret. This is called - * by widgets to indicate their cursor placement, and the caret - * location is used by TkpGetString to place the XIM caret. + * This enables correct placement of the XIM caret. This is called + * by widgets to indicate their cursor placement, and the caret + * location is used by TkpGetString to place the XIM caret. * * Results: - * None + * None * * Side effects: - * None + * None * *---------------------------------------------------------------------- */ void -Tk_SetCaretPos(tkwin, x, y, height) - Tk_Window tkwin; - int x; - int y; - int height; +Tk_SetCaretPos( + Tk_Window tkwin, + int x, + int y, + int height) { } @@ -1275,23 +1158,23 @@ Tk_SetCaretPos(tkwin, x, y, height) * * TkMacOSXInitKeyboard -- * - * This procedure initializes the keyboard layout. + * This procedure initializes the keyboard layout. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ MODULE_SCOPE void -TkMacOSXInitKeyboard ( - Tcl_Interp *interp) +TkMacOSXInitKeyboard( + Tcl_Interp *interp) { Ptr resource; TextEncoding encoding; - - GetKeyboardLayout(&resource,&encoding); + + GetKeyboardLayout(&resource, &encoding); } diff --git a/macosx/tkMacOSXKeyboard.c b/macosx/tkMacOSXKeyboard.c index e767dbf..ce16324 100644 --- a/macosx/tkMacOSXKeyboard.c +++ b/macosx/tkMacOSXKeyboard.c @@ -1,20 +1,21 @@ -/* +/* * tkMacOSXKeyboard.c -- * - * Routines to support keyboard events on the Macintosh. + * Routines to support keyboard events on the Macintosh. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXKeyboard.c,v 1.20 2006/07/21 06:26:28 das Exp $ + * RCS: @(#) $Id: tkMacOSXKeyboard.c,v 1.21 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" -#include "tkMacOSXEvent.h" /* TkMacOSXKeycodeToUnicode() FIXME: That - * function should probably move here. */ +#include "tkMacOSXEvent.h" /* TkMacOSXKeycodeToUnicode() FIXME: That + * function should probably move here. */ /* * A couple of simple definitions to make code a bit more self-explaining. @@ -23,22 +24,22 @@ * tkMacOSXMouseEvent.c. */ -#define LATIN1_MAX 255 -#define MAC_KEYCODE_MAX 0x7F +#define LATIN1_MAX 255 +#define MAC_KEYCODE_MAX 0x7F #define MAC_KEYCODE_MASK 0x7F -#define COMMAND_MASK Mod1Mask -#define OPTION_MASK Mod2Mask +#define COMMAND_MASK Mod1Mask +#define OPTION_MASK Mod2Mask /* - * Tables enumerating the special keys defined on Mac keyboards. These are + * Tables enumerating the special keys defined on Mac keyboards. These are * necessary for correct keysym mappings for all keys where the keysyms are * not identical with their ASCII or Latin-1 code points. */ typedef struct { - int keycode; /* Macintosh keycode. */ - KeySym keysym; /* X windows keysym. */ + int keycode; /* Macintosh keycode. */ + KeySym keysym; /* X windows keysym. */ } KeyInfo; /* @@ -55,64 +56,64 @@ typedef struct { */ static KeyInfo keyArray[] = { - {0x24, XK_Return}, - {0x30, XK_Tab}, - {0x33, XK_BackSpace}, - {0x34, XK_Return}, - {0x35, XK_Escape}, - - {0x47, XK_Clear}, - {0x4C, XK_KP_Enter}, - - {0x72, XK_Help}, - {0x73, XK_Home}, - {0x74, XK_Page_Up}, - {0x75, XK_Delete}, - {0x77, XK_End}, - {0x79, XK_Page_Down}, - - {0x7B, XK_Left}, - {0x7C, XK_Right}, - {0x7D, XK_Down}, - {0x7E, XK_Up}, - - {0, 0} + {0x24, XK_Return}, + {0x30, XK_Tab}, + {0x33, XK_BackSpace}, + {0x34, XK_Return}, + {0x35, XK_Escape}, + + {0x47, XK_Clear}, + {0x4C, XK_KP_Enter}, + + {0x72, XK_Help}, + {0x73, XK_Home}, + {0x74, XK_Page_Up}, + {0x75, XK_Delete}, + {0x77, XK_End}, + {0x79, XK_Page_Down}, + + {0x7B, XK_Left}, + {0x7C, XK_Right}, + {0x7D, XK_Down}, + {0x7E, XK_Up}, + + {0, 0} }; static KeyInfo virtualkeyArray[] = { - {122, XK_F1}, - {120, XK_F2}, - {99, XK_F3}, - {118, XK_F4}, - {96, XK_F5}, - {97, XK_F6}, - {98, XK_F7}, - {100, XK_F8}, - {101, XK_F9}, - {109, XK_F10}, - {103, XK_F11}, - {111, XK_F12}, - {105, XK_F13}, - {107, XK_F14}, - {113, XK_F15}, - {0, 0} + {122, XK_F1}, + {120, XK_F2}, + {99, XK_F3}, + {118, XK_F4}, + {96, XK_F5}, + {97, XK_F6}, + {98, XK_F7}, + {100, XK_F8}, + {101, XK_F9}, + {109, XK_F10}, + {103, XK_F11}, + {111, XK_F12}, + {105, XK_F13}, + {107, XK_F14}, + {113, XK_F15}, + {0, 0} }; static int initialized = 0; -static Tcl_HashTable keycodeTable; /* keyArray hashed by keycode value. */ -static Tcl_HashTable vkeyTable; /* virtualkeyArray hashed by virtual - * keycode value. */ +static Tcl_HashTable keycodeTable; /* keyArray hashed by keycode value. */ +static Tcl_HashTable vkeyTable; /* virtualkeyArray hashed by virtual + * keycode value. */ -static int latin1Table[LATIN1_MAX+1]; /* Reverse mapping table for - * controls, ASCII and Latin-1. */ +static int latin1Table[LATIN1_MAX+1]; /* Reverse mapping table for + * controls, ASCII and Latin-1. */ /* * Prototypes for static functions used in this file. */ -static void InitKeyMaps (void); -static void InitLatin1Table(Display *display); -static int XKeysymToMacKeycode(Display *display, KeySym keysym); +static void InitKeyMaps (void); +static void InitLatin1Table(Display *display); +static int XKeysymToMacKeycode(Display *display, KeySym keysym); /* @@ -120,39 +121,39 @@ static int XKeysymToMacKeycode(Display *display, KeySym keysym); * * InitKeyMaps -- * - * Creates hash tables used by some of the functions in this file. + * Creates hash tables used by some of the functions in this file. * - * FIXME: As keycodes are defined to be in the limited range 0-127, it - * would be easier and more efficient to use directly initialized plain - * arrays and drop this function. + * FIXME: As keycodes are defined to be in the limited range 0-127, it + * would be easier and more efficient to use directly initialized plain + * arrays and drop this function. * * Results: - * None. + * None. * * Side effects: - * Allocates memory & creates some hash tables. + * Allocates memory & creates some hash tables. * *---------------------------------------------------------------------- */ static void -InitKeyMaps() +InitKeyMaps(void) { Tcl_HashEntry *hPtr; KeyInfo *kPtr; int dummy; - + Tcl_InitHashTable(&keycodeTable, TCL_ONE_WORD_KEYS); for (kPtr = keyArray; kPtr->keycode != 0; kPtr++) { - hPtr = Tcl_CreateHashEntry(&keycodeTable, (char *) kPtr->keycode, - &dummy); - Tcl_SetHashValue(hPtr, kPtr->keysym); + hPtr = Tcl_CreateHashEntry(&keycodeTable, (char *) kPtr->keycode, + &dummy); + Tcl_SetHashValue(hPtr, kPtr->keysym); } Tcl_InitHashTable(&vkeyTable, TCL_ONE_WORD_KEYS); for (kPtr = virtualkeyArray; kPtr->keycode != 0; kPtr++) { - hPtr = Tcl_CreateHashEntry(&vkeyTable, (char *) kPtr->keycode, - &dummy); - Tcl_SetHashValue(hPtr, kPtr->keysym); + hPtr = Tcl_CreateHashEntry(&vkeyTable, (char *) kPtr->keycode, + &dummy); + Tcl_SetHashValue(hPtr, kPtr->keysym); } initialized = 1; } @@ -162,16 +163,16 @@ InitKeyMaps() * * InitLatin1Table -- * - * Creates a simple table to be used for mapping from keysyms to - * keycodes. Always needs to be called before using latin1Table, - * because the keyboard layout may have changed, and than the table must - * be re-computed. + * Creates a simple table to be used for mapping from keysyms to + * keycodes. Always needs to be called before using latin1Table, + * because the keyboard layout may have changed, and than the table must + * be re-computed. * * Results: - * None. + * None. * * Side effects: - * Sets the global latin1Table. + * Sets the global latin1Table. * *---------------------------------------------------------------------- */ @@ -190,46 +191,46 @@ InitLatin1Table( keyLayoutID = GetScriptVariable(keyScript,smScriptKeys); if (!latin1_initialized || (lastKeyLayoutID != keyLayoutID)) { - int keycode; - KeySym keysym; - int state; - int modifiers; - - latin1_initialized = true; - lastKeyLayoutID = keyLayoutID; - - memset(latin1Table, 0, sizeof(latin1Table)); - - /* - * In the common X11 implementations, a keymap has four columns - * "plain", "Shift", "Mode_switch" and "Mode_switch + Shift". We - * don't use "Mode_switch", but we use "Option" instead. (This is - * similar to Apple's X11 implementation, where "Mode_switch" is used - * as an alias for "Option".) - * - * So here we go through all 4 columns of the keymap and find all - * Latin-1 compatible keycodes. We go through the columns - * back-to-front from the more exotic columns to the more simple, so - * that simple keycode-modifier combinations are preferred in the - * resulting table. - */ - - for (state = 3; state >= 0; state--) { - modifiers = 0; - if (state & 1) { - modifiers |= shiftKey; - } - if (state & 2) { - modifiers |= optionKey; - } - - for (keycode = 0; keycode <= MAC_KEYCODE_MAX; keycode++) { - keysym = XKeycodeToKeysym(display,keycode<<16,state); - if (keysym <= LATIN1_MAX) { - latin1Table[keysym] = keycode | modifiers; - } - } - } + int keycode; + KeySym keysym; + int state; + int modifiers; + + latin1_initialized = true; + lastKeyLayoutID = keyLayoutID; + + memset(latin1Table, 0, sizeof(latin1Table)); + + /* + * In the common X11 implementations, a keymap has four columns + * "plain", "Shift", "Mode_switch" and "Mode_switch + Shift". We + * don't use "Mode_switch", but we use "Option" instead. (This is + * similar to Apple's X11 implementation, where "Mode_switch" is used + * as an alias for "Option".) + * + * So here we go through all 4 columns of the keymap and find all + * Latin-1 compatible keycodes. We go through the columns + * back-to-front from the more exotic columns to the more simple, so + * that simple keycode-modifier combinations are preferred in the + * resulting table. + */ + + for (state = 3; state >= 0; state--) { + modifiers = 0; + if (state & 1) { + modifiers |= shiftKey; + } + if (state & 2) { + modifiers |= optionKey; + } + + for (keycode = 0; keycode <= MAC_KEYCODE_MAX; keycode++) { + keysym = XKeycodeToKeysym(display,keycode<<16,state); + if (keysym <= LATIN1_MAX) { + latin1Table[keysym] = keycode | modifiers; + } + } + } } } @@ -238,19 +239,19 @@ InitLatin1Table( * * XKeycodeToKeysym -- * - * Translate from a system-dependent keycode to a system-independent - * keysym. + * Translate from a system-dependent keycode to a system-independent + * keysym. * * Results: - * Returns the translated keysym, or NoSymbol on failure. + * Returns the translated keysym, or NoSymbol on failure. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -KeySym +KeySym XKeycodeToKeysym( Display* display, KeyCode keycode, @@ -263,55 +264,55 @@ XKeycodeToKeysym( (void) display; /*unused*/ if (!initialized) { - InitKeyMaps(); + InitKeyMaps(); } /* * When determining what keysym to produce we first check to see if the - * key is a function key. We then check to see if the character is - * another non-printing key. Finally, we return the key syms for all + * key is a function key. We then check to see if the character is + * another non-printing key. Finally, we return the key syms for all * ASCII and Latin-1 chars. */ newKeycode = keycode >> 16; if ((keycode & 0xFFFF) == 0x10) { - hPtr = Tcl_FindHashEntry(&vkeyTable, (char *) newKeycode); - if (hPtr != NULL) { - return (KeySym) Tcl_GetHashValue(hPtr); - } + hPtr = Tcl_FindHashEntry(&vkeyTable, (char *) newKeycode); + if (hPtr != NULL) { + return (KeySym) Tcl_GetHashValue(hPtr); + } } hPtr = Tcl_FindHashEntry(&keycodeTable, (char *) newKeycode); if (hPtr != NULL) { - return (KeySym) Tcl_GetHashValue(hPtr); + return (KeySym) Tcl_GetHashValue(hPtr); } - /* + /* * Add in the Mac modifier flags for shift and option. */ if (index & 1) { - newKeycode |= shiftKey; + newKeycode |= shiftKey; } if (index & 2) { - newKeycode |= optionKey; + newKeycode |= optionKey; } newChar = 0; TkMacOSXKeycodeToUnicode( - &newChar, 1, kEventRawKeyDown, - newKeycode & 0x00FF, newKeycode & 0xFF00, NULL); + &newChar, 1, kEventRawKeyDown, + newKeycode & 0x00FF, newKeycode & 0xFF00, NULL); /* - * X11 keysyms are identical to Unicode for ASCII and Latin-1. Give up + * X11 keysyms are identical to Unicode for ASCII and Latin-1. Give up * for other characters for now. */ if ((newChar >= XK_space) && (newChar <= LATIN1_MAX)) { - return newChar; + return newChar; } - return NoSymbol; + return NoSymbol; } /* @@ -319,24 +320,24 @@ XKeycodeToKeysym( * * TkpGetString -- * - * Retrieve the string equivalent for the given keyboard event. + * Retrieve the string equivalent for the given keyboard event. * * Results: - * Returns the UTF string. + * Returns the UTF string. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ char * TkpGetString( - TkWindow *winPtr, /* Window where event occurred: Needed to get - * input context. */ - XEvent *eventPtr, /* X keyboard event. */ - Tcl_DString *dsPtr) /* Uninitialized or empty string to hold - * result. */ + TkWindow *winPtr, /* Window where event occurred: Needed to get + * input context. */ + XEvent *eventPtr, /* X keyboard event. */ + Tcl_DString *dsPtr) /* Uninitialized or empty string to hold + * result. */ { (void) winPtr; /*unused*/ Tcl_DStringInit(dsPtr); @@ -348,28 +349,28 @@ TkpGetString( * * XGetModifierMapping -- * - * Fetch the current keycodes used as modifiers. + * Fetch the current keycodes used as modifiers. * * Results: - * Returns a new modifier map. + * Returns a new modifier map. * * Side effects: - * Allocates a new modifier map data structure. + * Allocates a new modifier map data structure. * *---------------------------------------------------------------------- */ -XModifierKeymap * +XModifierKeymap * XGetModifierMapping( Display* display) -{ +{ XModifierKeymap * modmap; (void) display; /*unused*/ /* * MacOSX doesn't use the key codes for the modifiers for anything, and - * we don't generate them either. So there is no modifier map. + * we don't generate them either. So there is no modifier map. */ modmap = (XModifierKeymap *) ckalloc(sizeof(XModifierKeymap)); @@ -383,23 +384,23 @@ XGetModifierMapping( * * XFreeModifiermap -- * - * Deallocate a modifier map that was created by XGetModifierMapping. + * Deallocate a modifier map that was created by XGetModifierMapping. * * Results: - * None. + * None. * * Side effects: - * Frees the datastructure referenced by modmap. + * Frees the datastructure referenced by modmap. * *---------------------------------------------------------------------- */ -void +void XFreeModifiermap( XModifierKeymap *modmap) { if (modmap->modifiermap != NULL) { - ckfree((char *) modmap->modifiermap); + ckfree((char *) modmap->modifiermap); } ckfree((char *) modmap); } @@ -409,31 +410,31 @@ XFreeModifiermap( * * XKeysymToString, XStringToKeysym -- * - * These X window functions map keysyms to strings & strings to keysyms. - * However, Tk already does this for the most common keysyms. - * Therefore, these functions only need to support keysyms that will be - * specific to the Macintosh. Currently, there are none. + * These X window functions map keysyms to strings & strings to keysyms. + * However, Tk already does this for the most common keysyms. + * Therefore, these functions only need to support keysyms that will be + * specific to the Macintosh. Currently, there are none. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -char * +char * XKeysymToString( KeySym keysym) { - return NULL; + return NULL; } -KeySym +KeySym XStringToKeysym( const char* string) -{ +{ return NoSymbol; } @@ -442,15 +443,15 @@ XStringToKeysym( * * XKeysymToMacKeycode -- * - * An internal function like XKeysymToKeycode but only generating the - * Mac specific keycode plus the modifiers Shift and Option. + * An internal function like XKeysymToKeycode but only generating the + * Mac specific keycode plus the modifiers Shift and Option. * * Results: - * A Mac keycode with the actual keycode in the low byte and Mac-style - * modifier bits in the high byte. + * A Mac keycode with the actual keycode in the low byte and Mac-style + * modifier bits in the high byte. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -462,42 +463,42 @@ XKeysymToMacKeycode( { if (keysym <= LATIN1_MAX) { - /* - * Handle keysyms in the Latin-1 range where keysym and Unicode - * character code point are the same. - */ + /* + * Handle keysyms in the Latin-1 range where keysym and Unicode + * character code point are the same. + */ - InitLatin1Table(display); - return latin1Table[keysym]; + InitLatin1Table(display); + return latin1Table[keysym]; } else { - /* - * Handle special keys from our exception tables. Don't mind if this - * is slow, neither the test suite nor [event generate] need to be - * optimized (we hope). - */ - - KeyInfo *kPtr; - - for (kPtr = keyArray; kPtr->keycode != 0; kPtr++) { - if (kPtr->keysym == keysym) { - return kPtr->keycode; - } - } - for (kPtr = virtualkeyArray; kPtr->keycode != 0; kPtr++) { - if (kPtr->keysym == keysym) { - return kPtr->keycode; - } - } - - /* - * For other keysyms (not Latin-1 and not special keys), we'd need a - * generic keysym-to-unicode table. We don't have that, so we give - * up here. - */ - - return 0; + /* + * Handle special keys from our exception tables. Don't mind if this + * is slow, neither the test suite nor [event generate] need to be + * optimized (we hope). + */ + + KeyInfo *kPtr; + + for (kPtr = keyArray; kPtr->keycode != 0; kPtr++) { + if (kPtr->keysym == keysym) { + return kPtr->keycode; + } + } + for (kPtr = virtualkeyArray; kPtr->keycode != 0; kPtr++) { + if (kPtr->keysym == keysym) { + return kPtr->keycode; + } + } + + /* + * For other keysyms (not Latin-1 and not special keys), we'd need a + * generic keysym-to-unicode table. We don't have that, so we give + * up here. + */ + + return 0; } } @@ -506,17 +507,17 @@ XKeysymToMacKeycode( * * XKeysymToKeycode -- * - * The function XKeysymToKeycode takes an X11 keysym and converts it - * into a Mac keycode. It is in the stubs table for compatibility but - * not used anywhere in the core. + * The function XKeysymToKeycode takes an X11 keysym and converts it + * into a Mac keycode. It is in the stubs table for compatibility but + * not used anywhere in the core. * * Results: - * A 32 bit keycode with the the mac keycode (without modifiers) in the - * higher 16 bits of the keycode and the ASCII or Latin-1 code in the - * lower 8 bits of the keycode. + * A 32 bit keycode with the the mac keycode (without modifiers) in the + * higher 16 bits of the keycode and the ASCII or Latin-1 code in the + * lower 8 bits of the keycode. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -528,17 +529,17 @@ XKeysymToKeycode( { int macKeycode = XKeysymToMacKeycode(display, keysym); KeyCode result; - + /* - * See also TkpSetKeycodeAndState. The 0x0010 magic is used in - * XKeycodeToKeysym. For special keys like XK_Return the lower 8 bits of + * See also TkpSetKeycodeAndState. The 0x0010 magic is used in + * XKeycodeToKeysym. For special keys like XK_Return the lower 8 bits of * the keysym are usually a related ASCII control code. */ if ((keysym >= XK_F1) && (keysym <= XK_F35)) { - result = 0x0010; + result = 0x0010; } else { - result = 0x00FF & keysym; + result = 0x00FF & keysym; } result |= (macKeycode & MAC_KEYCODE_MASK) << 16; @@ -549,23 +550,23 @@ XKeysymToKeycode( NB: Keep this commented code for a moment for reference. if ((keysym >= XK_space) && (XK_asciitilde)) { - if (keysym == 'a') { - virtualKeyCode = 0x00; - } else if (keysym == 'b' || keysym == 'B') { - virtualKeyCode = 0x0B; - } else if (keysym == 'c') { - virtualKeyCode = 0x08; - } else if (keysym == 'x' || keysym == 'X') { - virtualKeyCode = 0x07; - } else if (keysym == 'z') { - virtualKeyCode = 0x06; - } else if (keysym == ' ') { - virtualKeyCode = 0x31; - } else if (keysym == XK_Return) { - virtualKeyCode = 0x24; - keysym = '\r'; - } - keycode = keysym + (virtualKeyCode <<16); + if (keysym == 'a') { + virtualKeyCode = 0x00; + } else if (keysym == 'b' || keysym == 'B') { + virtualKeyCode = 0x0B; + } else if (keysym == 'c') { + virtualKeyCode = 0x08; + } else if (keysym == 'x' || keysym == 'X') { + virtualKeyCode = 0x07; + } else if (keysym == 'z') { + virtualKeyCode = 0x06; + } else if (keysym == ' ') { + virtualKeyCode = 0x31; + } else if (keysym == XK_Return) { + virtualKeyCode = 0x24; + keysym = '\r'; + } + keycode = keysym + (virtualKeyCode <<16); } return keycode; @@ -576,19 +577,19 @@ NB: Keep this commented code for a moment for reference. * * TkpSetKeycodeAndState -- * - * The function TkpSetKeycodeAndState takes a keysym and fills in the - * appropriate members of an XEvent. It is similar to XKeysymToKeycode, - * but it also sets the modifier mask in the XEvent. It is used by - * [event generate] and it is in the stubs table. + * The function TkpSetKeycodeAndState takes a keysym and fills in the + * appropriate members of an XEvent. It is similar to XKeysymToKeycode, + * but it also sets the modifier mask in the XEvent. It is used by + * [event generate] and it is in the stubs table. * * Results: - * Fills an XEvent, sets the member xkey.keycode with a keycode - * formatted the same as XKeysymToKeycode and the member xkey.state with - * the modifiers implied by the keysym. Also fills in xkey.trans_chars, - * so that the actual characters can be retrieved later. + * Fills an XEvent, sets the member xkey.keycode with a keycode + * formatted the same as XKeysymToKeycode and the member xkey.state with + * the modifiers implied by the keysym. Also fills in xkey.trans_chars, + * so that the actual characters can be retrieved later. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -600,36 +601,36 @@ TkpSetKeycodeAndState( XEvent *eventPtr) { if (keysym == NoSymbol) { - eventPtr->xkey.keycode = 0; + eventPtr->xkey.keycode = 0; } else { - Display *display = Tk_Display(tkwin); - int macKeycode = XKeysymToMacKeycode(display, keysym); - - /* - * See also XKeysymToKeycode. - */ - - if ((keysym >= XK_F1) && (keysym <= XK_F35)) { - eventPtr->xkey.keycode = 0x0010; - } else { - eventPtr->xkey.keycode = 0x00FF & keysym; - } - eventPtr->xkey.keycode |= (macKeycode & MAC_KEYCODE_MASK) << 16; - - if (shiftKey & macKeycode) { - eventPtr->xkey.state |= ShiftMask; - } - if (optionKey & macKeycode) { - eventPtr->xkey.state |= OPTION_MASK; - } - - if (keysym <= LATIN1_MAX) { - int done; - done = Tcl_UniCharToUtf(keysym,eventPtr->xkey.trans_chars); - eventPtr->xkey.trans_chars[done] = 0; - } else { - eventPtr->xkey.trans_chars[0] = 0; - } + Display *display = Tk_Display(tkwin); + int macKeycode = XKeysymToMacKeycode(display, keysym); + + /* + * See also XKeysymToKeycode. + */ + + if ((keysym >= XK_F1) && (keysym <= XK_F35)) { + eventPtr->xkey.keycode = 0x0010; + } else { + eventPtr->xkey.keycode = 0x00FF & keysym; + } + eventPtr->xkey.keycode |= (macKeycode & MAC_KEYCODE_MASK) << 16; + + if (shiftKey & macKeycode) { + eventPtr->xkey.state |= ShiftMask; + } + if (optionKey & macKeycode) { + eventPtr->xkey.state |= OPTION_MASK; + } + + if (keysym <= LATIN1_MAX) { + int done; + done = Tcl_UniCharToUtf(keysym,eventPtr->xkey.trans_chars); + eventPtr->xkey.trans_chars[done] = 0; + } else { + eventPtr->xkey.trans_chars[0] = 0; + } } } @@ -638,24 +639,24 @@ TkpSetKeycodeAndState( * * TkpGetKeySym -- * - * Given an X KeyPress or KeyRelease event, map the keycode in the event - * into a keysym. + * Given an X KeyPress or KeyRelease event, map the keycode in the event + * into a keysym. * * Results: - * The return value is the keysym corresponding to eventPtr, or NoSymbol - * if no matching keysym could be found. + * The return value is the keysym corresponding to eventPtr, or NoSymbol + * if no matching keysym could be found. * * Side effects: - * In the first call for a given display, keycode-to-keysym maps get - * loaded. + * In the first call for a given display, keycode-to-keysym maps get + * loaded. * *---------------------------------------------------------------------- */ KeySym TkpGetKeySym( - TkDisplay *dispPtr, /* Display in which to map keycode. */ - XEvent *eventPtr) /* Description of X event. */ + TkDisplay *dispPtr, /* Display in which to map keycode. */ + XEvent *eventPtr) /* Description of X event. */ { KeySym sym; int index; @@ -665,50 +666,50 @@ TkpGetKeySym( */ if (dispPtr->bindInfoStale) { - TkpInitKeymapInfo(dispPtr); + TkpInitKeymapInfo(dispPtr); } /* - * Handle pure modifier keys specially. We use -1 as a signal for + * Handle pure modifier keys specially. We use -1 as a signal for * this. */ if (eventPtr->xany.send_event == -1) { - int modifier = eventPtr->xkey.keycode; - if (modifier == cmdKey) { - return XK_Meta_L; - } else if (modifier == shiftKey) { - return XK_Shift_L; - } else if (modifier == alphaLock) { - return XK_Caps_Lock; - } else if (modifier == optionKey) { - return XK_Alt_L; - } else if (modifier == controlKey) { - return XK_Control_L; - } else if (modifier == kEventKeyModifierNumLockMask) { - return XK_Num_Lock; - } else if (modifier == kEventKeyModifierFnMask) { - return XK_Super_L; - } else if (modifier == rightShiftKey) { - return XK_Shift_R; - } else if (modifier == rightOptionKey) { - return XK_Alt_R; - } else if (modifier == rightControlKey) { - return XK_Control_R; - } else { - - /* - * If we get here, we probably need to implement something new. - */ - - return NoSymbol; - } + int modifier = eventPtr->xkey.keycode; + if (modifier == cmdKey) { + return XK_Meta_L; + } else if (modifier == shiftKey) { + return XK_Shift_L; + } else if (modifier == alphaLock) { + return XK_Caps_Lock; + } else if (modifier == optionKey) { + return XK_Alt_L; + } else if (modifier == controlKey) { + return XK_Control_L; + } else if (modifier == kEventKeyModifierNumLockMask) { + return XK_Num_Lock; + } else if (modifier == kEventKeyModifierFnMask) { + return XK_Super_L; + } else if (modifier == rightShiftKey) { + return XK_Shift_R; + } else if (modifier == rightOptionKey) { + return XK_Alt_R; + } else if (modifier == rightControlKey) { + return XK_Control_R; + } else { + + /* + * If we get here, we probably need to implement something new. + */ + + return NoSymbol; + } } /* * Figure out which of the four slots in the keymap vector to use for - * this key. Refer to Xlib documentation for more info on how this - * computation works. (Note: We use "Option" in keymap columns 2 and 3 + * this key. Refer to Xlib documentation for more info on how this + * computation works. (Note: We use "Option" in keymap columns 2 and 3 * where other implementations have "Mode_switch".) */ @@ -721,14 +722,14 @@ TkpGetKeySym( #if 0 if (eventPtr->xkey.state & OPTION_MASK) { - index |= 2; + index |= 2; } #endif if ((eventPtr->xkey.state & ShiftMask) - || (/* (dispPtr->lockUsage != LU_IGNORE) - && */ (eventPtr->xkey.state & LockMask))) { - index |= 1; + || (/* (dispPtr->lockUsage != LU_IGNORE) + && */ (eventPtr->xkey.state & LockMask))) { + index |= 1; } /* @@ -744,20 +745,20 @@ TkpGetKeySym( */ if ((index & 1) && !(eventPtr->xkey.state & ShiftMask) - /*&& (dispPtr->lockUsage == LU_CAPS)*/ ) { - - /* - * FIXME: Keysyms are only identical to Unicode for ASCII and - * Latin-1, so we can't use Tcl_UniCharIsUpper() for keysyms outside - * that range. This may be a serious problem here. - */ - - if ((sym == NoSymbol) || (sym > LATIN1_MAX) - || !Tcl_UniCharIsUpper(sym)) { - index &= ~1; - sym = XKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode, - index); - } + /*&& (dispPtr->lockUsage == LU_CAPS)*/ ) { + + /* + * FIXME: Keysyms are only identical to Unicode for ASCII and + * Latin-1, so we can't use Tcl_UniCharIsUpper() for keysyms outside + * that range. This may be a serious problem here. + */ + + if ((sym == NoSymbol) || (sym > LATIN1_MAX) + || !Tcl_UniCharIsUpper(sym)) { + index &= ~1; + sym = XKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode, + index); + } } /* @@ -766,8 +767,8 @@ TkpGetKeySym( */ if ((index & 1) && (sym == NoSymbol)) { - sym = XKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode, - index & ~1); + sym = XKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode, + index & ~1); } return sym; } @@ -777,30 +778,30 @@ TkpGetKeySym( * * TkpInitKeymapInfo -- * - * This procedure is invoked to scan keymap information to recompute - * stuff that's important for binding, such as the modifier key (if any) - * that corresponds to the "Mode_switch" keysym. + * This procedure is invoked to scan keymap information to recompute + * stuff that's important for binding, such as the modifier key (if any) + * that corresponds to the "Mode_switch" keysym. * * Results: - * None. + * None. * * Side effects: - * Keymap-related information in dispPtr is updated. + * Keymap-related information in dispPtr is updated. * *-------------------------------------------------------------- */ void TkpInitKeymapInfo( - TkDisplay *dispPtr) /* Display for which to recompute keymap - * information. */ + TkDisplay *dispPtr) /* Display for which to recompute keymap + * information. */ { dispPtr->bindInfoStale = 0; /* * Behaviours that are variable on X11 are defined constant on MacOSX. * lockUsage is only used above in TkpGetKeySym(), nowhere else - * currently. There is no offical "Mode_switch" key. + * currently. There is no offical "Mode_switch" key. */ dispPtr->lockUsage = LU_CAPS; @@ -810,9 +811,9 @@ TkpInitKeymapInfo( /* * With this, <Alt> and <Meta> become synonyms for <Command> and <Option> * in bindings like they are (and always have been) in the keysyms that - * are reported by KeyPress events. But the init scripts like text.tcl + * are reported by KeyPress events. But the init scripts like text.tcl * have some disabling bindings for <Meta>, so we don't want this without - * some changes in those scripts. See also bug #700311. + * some changes in those scripts. See also bug #700311. */ dispPtr->altModMask = OPTION_MASK; @@ -825,13 +826,13 @@ TkpInitKeymapInfo( /* * MacOSX doesn't use the keycodes for the modifiers for anything, and we * don't generate them either (the keycodes actually given in the - * simulated modifier events are bogus). So there is no modifier map. + * simulated modifier events are bogus). So there is no modifier map. * If we ever want to simulate real modifier keycodes, the list will be * constant in the Carbon implementation. */ if (dispPtr->modKeyCodes != NULL) { - ckfree((char *) dispPtr->modKeyCodes); + ckfree((char *) dispPtr->modKeyCodes); } dispPtr->numModKeyCodes = 0; dispPtr->modKeyCodes = NULL; diff --git a/macosx/tkMacOSXMenu.c b/macosx/tkMacOSXMenu.c index 0d80798..46cdf5d 100644 --- a/macosx/tkMacOSXMenu.c +++ b/macosx/tkMacOSXMenu.c @@ -1,45 +1,38 @@ -/* +/* * tkMacOSXMenu.c -- * * This module implements the Mac-platform specific features of menus. * * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. - * Copyright (c) 2005-2006 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.36 2007/04/21 19:06:38 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXMenu.c,v 1.37 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" #include "tkMenubutton.h" #include "tkMenu.h" #include "tkColor.h" +#include "tkFont.h" #include "tkMacOSXDebug.h" -#define USE_TK_MDEF -//#define USE_ATSU - /* -#ifdef TK_MAC_DEBUG +#ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_MENUS #endif */ -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 - /* Define constants only available on Mac OS X 10.3 or later */ - #define kMenuAttrDoNotUseUserCommandKeys (1 << 7) -#endif +#define USE_TK_MDEF typedef struct MacMenu { MenuRef menuHdl; /* The Menu Manager data structure. */ - Rect menuRect; /* The rectangle as calculated in the - * MDEF. This is used to figure ou the - * clipping rgn before we push - * the <<MenuSelect>> virtual binding - * through. */ +#ifdef USE_TK_MDEF + int useMDEF; /* true if this menu uses the MDEF */ +#endif } MacMenu; typedef struct MenuEntryUserData { @@ -48,36 +41,6 @@ typedef struct MenuEntryUserData { Tk_Font tkfont; Tk_FontMetrics *fmPtr; } MenuEntryUserData; -/* - * Various geometry definitions: - */ - -#define CASCADE_ARROW_HEIGHT 10 -#define CASCADE_ARROW_WIDTH 8 -#define DECORATION_BORDER_WIDTH 2 -#define MAC_MARGIN_WIDTH 8 - -/* - * The following are constants relating to the SICNs used for drawing the MDEF. - */ - -#define SICN_RESOURCE_NUMBER 128 - -#define SICN_HEIGHT 16 -#define SICN_ROWS 2 -#define CASCADE_ICON_WIDTH 7 -#define SHIFT_ICON_WIDTH 10 -#define OPTION_ICON_WIDTH 16 -#define CONTROL_ICON_WIDTH 12 -#define COMMAND_ICON_WIDTH 10 - -#define CASCADE_ARROW 0 -#define SHIFT_ICON 1 -#define OPTION_ICON 2 -#define CONTROL_ICON 3 -#define COMMAND_ICON 4 -#define DOWN_ARROW 5 -#define UP_ARROW 6 /* * Platform specific flags for menu entries @@ -98,6 +61,7 @@ typedef struct MenuEntryUserData { #define ENTRY_CONTROL_ACCEL ENTRY_PLATFORM_FLAG4 #define ENTRY_ACCEL_MASK (ENTRY_COMMAND_ACCEL | ENTRY_OPTION_ACCEL \ | ENTRY_SHIFT_ACCEL | ENTRY_CONTROL_ACCEL) +#define MODIFIER_NUM 4 /* * This structure is used to keep track of subfields within Macintosh menu @@ -106,14 +70,18 @@ typedef struct MenuEntryUserData { typedef struct EntryGeometry { int accelTextStart; /* Offset into the accel string where - * the text starts. Everything before - * this is modifier key descriptions. - */ + * the text starts. Everything before + * this is modifier key descriptions. + */ int modifierWidth; /* Width of modifier symbols. */ - int accelTextWidth; /* Width of the text after the modifier - * keys. */ + int accelTextWidth; /* Width of the text after the modifier + * keys. */ int nonAccelMargin; /* The width of the margin for entries - * without accelerators. */ + * without accelerators. */ + int modifierNum; /* Number of modifiers */ + Tcl_UniChar modifierUniChars[MODIFIER_NUM]; + /* Modifiers in unicode */ + char accelGlyph; /* Accelerator glyph, if any */ } EntryGeometry; /* @@ -122,10 +90,10 @@ typedef struct EntryGeometry { typedef struct TopLevelMenubarList { struct TopLevelMenubarList *nextPtr; - /* The next window in the list. */ + /* The next window in the list. */ Tk_Window tkwin; /* The toplevel window. */ TkMenu *menuPtr; /* The menu associated with this - * toplevel. */ + * toplevel. */ } TopLevelMenubarList; /* @@ -146,24 +114,12 @@ typedef struct TopLevelMenubarList { #define MENU_HELP_MENU MENU_PLATFORM_FLAG2 #define MENU_RECONFIGURE_PENDING MENU_PLATFORM_FLAG3 -#define CASCADE_CMD (0x1b) - /* The special command char for cascade - * menus. */ +#define CASCADE_CMD (0x1b) /* The special command char for cascade + * menus. */ #define MENUBAR_REDRAW_PENDING 1 -#define SCREEN_MARGIN 5 -static int gNoTkMenus = 0; /* This is used by Tk_MacOSXTurnOffMenus as the - * flag that Tk is not to draw any menus. */ - -RgnHandle tkMenuCascadeRgn = NULL; - /* The region to clip drawing to when the - * MDEF is up. */ -int tkUseMenuCascadeRgn = 0; /* If this is 1, clipping code - * should intersect tkMenuCascadeRgn - * before drawing occurs. - * tkMenuCascadeRgn will only - * be valid when the value of this - * variable is 1. */ +static int gNoTkMenus = 0; /* This is used by Tk_MacOSXTurnOffMenus as the + * flag that Tk is not to draw any menus. */ static Tcl_HashTable commandTable; /* The list of menuInstancePtrs associated with @@ -182,9 +138,6 @@ static char *currentMenuBarName; * DString. */ static Tk_Window currentMenuBarOwner; /* Which window owns the current menu bar. */ -static char elipsisString[TCL_UTF_MAX + 1]; - /* The UTF representation of the elipsis (...) - * character. */ static int inPostMenu; /* We cannot be re-entrant like X * windows. */ static short lastMenuID; /* To pass to NewMenu; need to figure out @@ -192,161 +145,237 @@ static short lastMenuID; /* To pass to NewMenu; need to figure out static short lastCascadeID; /* Cascades have to have ids that are * less than 256. */ -static MacDrawable macMDEFDrawable; - /* Drawable for use by MDEF code */ -static int MDEFScrollFlag = 0; /* Used so that popups don't scroll too soon. */ static int menuBarFlags; /* Used for whether the menu bar needs * redrawing or not. */ - -static struct TearoffSelect { - TkMenu *menuPtr; /* The menu that is torn off */ - Point point; /* The point to place the new menu */ - Rect excludeRect; /* We don't want to drag tearoff highlights - * when we are in this menu */ -} tearoffStruct; struct MenuCommandHandlerData { /* This is the ClientData we pass to */ - TkMenu *menuPtr; /* Tcl_DoWhenIdle to move handling */ - int index; /* menu commands to the event loop. */ + TkMenu *menuPtr; /* Tcl_DoWhenIdle to move handling */ + int index; /* menu commands to the event loop. */ }; -static RgnHandle totalMenuRgn = NULL; - /* Used to update windows which have been - * obscured by menus. */ -static RgnHandle utilRgn = NULL;/* Used when creating the region that is to - * be clipped out while the MDEF is active. */ - static TopLevelMenubarList *windowListPtr; /* A list of windows that have menubars set. */ -static MenuItemDrawingUPP tkThemeMenuItemDrawingUPP; - /* Points to the UPP for theme Item drawing. */ -static Tcl_Obj *useMDEFVar; + +/* + * Array of unicode, charcode and utf representations of the most common + * special menu symbols. + */ +typedef struct MenuSymbol { + const Tcl_UniChar unicode; + const char charCode; + /* char padding; */ + int utfLen, width; + char utf[TCL_UTF_MAX + 1]; +} MenuSymbol; + +static MenuSymbol menuSymbols[] = { + {kCommandUnicode, kCommandCharCode}, + {kOptionUnicode, kMenuOptionGlyph}, + {kControlUnicode, kMenuControlGlyph}, + {kShiftUnicode, kMenuShiftGlyph}, + {kCheckUnicode, kCheckCharCode}, + {kDiamondUnicode, kDiamondCharCode}, + {kBulletUnicode, kBulletCharCode}, + {0x2026, kNullCharCode}, + {0, 0}, +}; + +enum MenuSymbolIdx { + COMMAND_SYMBOL, + OPTION_SYMBOL, + CONTROL_SYMBOL, + SHIFT_SYMBOL, + CHECK_SYMBOL, + DIAMDOND_SYMBOL, + BULLET_SYMBOL, + ELLIPSIS_SYMBOL, +}; MenuRef tkCurrentAppleMenu = NULL; +static SInt32 menuMarkColumnWidth = 0, menuMarkIndent = 0; +static SInt32 menuTextLeadingEdgeMargin = 0, menuTextTrailingEdgeMargin = 0; +static SInt16 menuItemExtraHeight = 0, menuItemExtraWidth = 0; +static SInt16 menuSeparatorHeight = 0; + /* * Forward declarations for procedures defined later in this file: */ -MODULE_SCOPE int TkMacOSXGetNewMenuID _ANSI_ARGS_((Tcl_Interp *interp, - TkMenu *menuInstPtr, - int cascade, - short *menuIDPtr)); -MODULE_SCOPE void TkMacOSXFreeMenuID _ANSI_ARGS_((short menuID)); - -static void CompleteIdlers _ANSI_ARGS_((TkMenu *menuPtr)); -static void DrawMenuBarWhenIdle _ANSI_ARGS_(( - ClientData clientData)); -static void DrawMenuBackground _ANSI_ARGS_(( - Rect *menuRectPtr, Drawable d, ThemeMenuType type)); -static void DrawMenuEntryAccelerator _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, GC gc, Tk_Font tkfont, - CONST Tk_FontMetrics *fmPtr, - Tk_3DBorder activeBorder, int x, int y, - int width, int height, int drawArrow)); -static void DrawMenuEntryBackground _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, Tk_3DBorder activeBorder, - Tk_3DBorder bgBorder, int x, int y, - int width, int heigth)); -static void DrawMenuEntryIndicator _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, GC gc, GC indicatorGC, - Tk_Font tkfont, - CONST Tk_FontMetrics *fmPtr, int x, int y, - int width, int height)); -static void DrawMenuEntryLabel _ANSI_ARGS_(( - TkMenu * menuPtr, TkMenuEntry *mePtr, Drawable d, - GC gc, Tk_Font tkfont, - CONST Tk_FontMetrics *fmPtr, int x, int y, - int width, int height)); -static void DrawMenuSeparator _ANSI_ARGS_((TkMenu *menuPtr, - TkMenuEntry *mePtr, Drawable d, GC gc, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int x, int y, int width, int height)); -static void DrawTearoffEntry _ANSI_ARGS_((TkMenu *menuPtr, - TkMenuEntry *mePtr, Drawable d, GC gc, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int x, int y, int width, int height)); -static void EventuallyInvokeMenu (ClientData data); -static void GetEntryText _ANSI_ARGS_((TkMenuEntry *mePtr, - Tcl_DString *dStringPtr)); -static void GetMenuAccelGeometry _ANSI_ARGS_((TkMenu *menuPtr, - TkMenuEntry *mePtr, Tk_Font tkfont, - CONST Tk_FontMetrics *fmPtr, int *modWidthPtr, - int *textWidthPtr, int *heightPtr)); -static void GetMenuLabelGeometry _ANSI_ARGS_((TkMenuEntry *mePtr, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int *widthPtr, int *heightPtr)); -static void GetMenuIndicatorGeometry _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int *widthPtr, int *heightPtr)); -static void GetMenuSeparatorGeometry _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int *widthPtr, int *heightPtr)); -static void GetTearoffEntryGeometry _ANSI_ARGS_((TkMenu *menuPtr, - TkMenuEntry *mePtr, Tk_Font tkfont, - CONST Tk_FontMetrics *fmPtr, int *widthPtr, - int *heightPtr)); -static char FindMarkCharacter _ANSI_ARGS_((TkMenuEntry *mePtr)); -static void InvalidateMDEFRgns _ANSI_ARGS_((void)); - -static void MenuDefProc _ANSI_ARGS_((short message, - MenuHandle menu, Rect *menuRectPtr, - Point hitPt, short *whichItem )); -static void HandleMenuHiliteMsg (MenuRef menu, - Rect *menuRectPtr, - Point hitPt, - SInt16 *whichItem, - TkMenu *menuPtr); -static void HandleMenuDrawMsg (MenuRef menu, - Rect *menuRectPtr, - Point hitPt, - SInt16 *whichItem, - TkMenu *menuPtr); -static void HandleMenuFindItemsMsg (MenuRef menu, - Rect *menuRectPtr, - Point hitPt, - SInt16 *whichItem, - TkMenu *menuPtr); -static void HandleMenuPopUpMsg (MenuRef menu, - Rect *menuRectPtr, - Point hitPt, - SInt16 *whichItem, - TkMenu *menuPtr); -static void HandleMenuCalcItemMsg (MenuRef menu, - Rect *menuRectPtr, - Point hitPt, - SInt16 *whichItem, - TkMenu *menuPtr); - -static void MenuSelectEvent _ANSI_ARGS_((TkMenu *menuPtr)); -static void ReconfigureIndividualMenu _ANSI_ARGS_(( - TkMenu *menuPtr, MenuHandle macMenuHdl, - int base)); -static void ReconfigureMacintoshMenu _ANSI_ARGS_ (( - ClientData clientData)); -static void RecursivelyClearActiveMenu _ANSI_ARGS_(( - TkMenu *menuPtr)); -static void RecursivelyDeleteMenu _ANSI_ARGS_(( - TkMenu *menuPtr)); -static void RecursivelyInsertMenu _ANSI_ARGS_(( - TkMenu *menuPtr)); -static void SetDefaultMenubar _ANSI_ARGS_((void)); -static int SetMenuCascade _ANSI_ARGS_((TkMenu *menuPtr)); -static void mySetMenuTitle _ANSI_ARGS_((MenuHandle menuHdl, - Tcl_Obj *titlePtr)); -static void AppearanceEntryDrawWrapper _ANSI_ARGS_((TkMenuEntry *mePtr, - Rect * menuRectPtr, MenuTrackingData *mtdPtr, - Drawable d, Tk_FontMetrics *fmPtr, Tk_Font tkfont, - int x, int y, int width, int height)); -static pascal void ThemeMenuItemDrawingProc _ANSI_ARGS_ ((const Rect *inBounds, - SInt16 inDepth, Boolean inIsColorDevice, - SInt32 inUserData)); +MODULE_SCOPE int TkMacOSXGetNewMenuID(Tcl_Interp *interp, TkMenu *menuInstPtr, + int cascade, short *menuIDPtr); +MODULE_SCOPE void TkMacOSXFreeMenuID(short menuID); + +static void CompleteIdlers(TkMenu *menuPtr); +static void DrawMenuBarWhenIdle(ClientData clientData); +static void DrawMenuEntryAccelerator(TkMenu *menuPtr, TkMenuEntry *mePtr, + Drawable d, GC gc, Tk_Font tkfont, const Tk_FontMetrics *fmPtr, + Tk_3DBorder activeBorder, int x, int y, int width, int height, + int drawArrow); +static void DrawMenuEntryBackground(TkMenu *menuPtr, TkMenuEntry *mePtr, + Drawable d, Tk_3DBorder activeBorder, Tk_3DBorder bgBorder, int x, + int y, int width, int heigth); +static void DrawMenuEntryIndicator(TkMenu *menuPtr, TkMenuEntry *mePtr, + Drawable d, GC gc, GC indicatorGC, Tk_Font tkfont, + const Tk_FontMetrics *fmPtr, int x, int y, int width, int height); +static void DrawMenuEntryLabel(TkMenu * menuPtr, TkMenuEntry *mePtr, + Drawable d, GC gc, Tk_Font tkfont, const Tk_FontMetrics *fmPtr, int x, + int y, int width, int height); +static void DrawMenuSeparator(TkMenu *menuPtr, TkMenuEntry *mePtr, Drawable d, + GC gc, Tk_Font tkfont, const Tk_FontMetrics *fmPtr, int x, int y, + int width, int height); +static void DrawTearoffEntry(TkMenu *menuPtr, TkMenuEntry *mePtr, Drawable d, + GC gc, Tk_Font tkfont, const Tk_FontMetrics *fmPtr, int x, int y, + int width, int height); +static void EventuallyInvokeMenu(ClientData data); +static void GetEntryText(TkMenuEntry *mePtr, Tcl_DString *dStringPtr); +static void GetMenuAccelGeometry(TkMenu *menuPtr, TkMenuEntry *mePtr, + Tk_Font tkfont, const Tk_FontMetrics *fmPtr, int *modWidthPtr, + int *textWidthPtr, int *heightPtr); +static void GetMenuLabelGeometry(TkMenuEntry *mePtr, Tk_Font tkfont, + const Tk_FontMetrics *fmPtr, int *widthPtr, int *heightPtr); +static void GetMenuIndicatorGeometry(TkMenu *menuPtr, TkMenuEntry *mePtr, + Tk_Font tkfont, const Tk_FontMetrics *fmPtr, int *widthPtr, + int *heightPtr); +static void GetMenuSeparatorGeometry(TkMenu *menuPtr, TkMenuEntry *mePtr, + Tk_Font tkfont, const Tk_FontMetrics *fmPtr, int *widthPtr, + int *heightPtr); +static TkMenuEntry* GetParentMenuEntry(TkMenu *menuPtr); +static void GetTearoffEntryGeometry(TkMenu *menuPtr, TkMenuEntry *mePtr, + Tk_Font tkfont, const Tk_FontMetrics *fmPtr, int *widthPtr, + int *heightPtr); +static char FindMarkCharacter(TkMenuEntry *mePtr); +static int GetUtfMarkCharacter(char markChar, const char **markUtfPtr); +static TkMenu* MenuPtrForMenuRef(MenuRef menu); +static int ParseAccelerators(const char **accelStringPtr, int *modifierNumPtr, + Tcl_UniChar *modifierUniChars, int *modifierWidth); +static void MenuSelectEvent(TkMenu *menuPtr); +static void ReconfigureIndividualMenu(TkMenu *menuPtr, MenuHandle macMenuHdl, + int base); +static void ReconfigureMacintoshMenu(ClientData clientData); +static void RecursivelyClearActiveMenu(TkMenu *menuPtr); +static void RecursivelyDeleteMenu(TkMenu *menuPtr); +static void RecursivelyInsertMenu(TkMenu *menuPtr); +static void SetDefaultMenubar(void); +static int SetMenuCascade(TkMenu *menuPtr); + +#ifdef USE_TK_MDEF +#define SCREEN_MARGIN 5 +static MacDrawable macMDEFDrawable; + /* Drawable for use by MDEF code */ +static int MDEFScrollFlag = 0; /* Used so that popups don't scroll too soon.*/ +static MenuItemDrawingUPP tkThemeMenuItemDrawingUPP; + /* Points to the UPP for theme Item drawing. */ +static Tcl_Obj *useMDEFVar; + +static void DrawMenuBackground(TkMenu *menuPtr, Rect *menuRectPtr, + Drawable d); +static void MenuDefProc(short message, MenuHandle menu, Rect *menuRectPtr, + Point hitPt, short *whichItem ); +static void HandleMenuHiliteMsg(MenuRef menu, Rect *menuRectPtr, Point hitPt, + SInt16 *whichItem, TkMenu *menuPtr); +static void HandleMenuDrawMsg(MenuRef menu, Rect *menuRectPtr, Point hitPt, + SInt16 *whichItem, TkMenu *menuPtr); +static void HandleMenuFindItemMsg(MenuRef menu, Rect *menuRectPtr, + Point hitPt, SInt16 *whichItem, TkMenu *menuPtr); +static void HandleMenuPopUpMsg(MenuRef menu, Rect *menuRectPtr, Point hitPt, + SInt16 *whichItem, TkMenu *menuPtr); +static void HandleMenuCalcItemMsg(MenuRef menu, Rect *menuRectPtr, Point hitPt, + SInt16 *whichItem, TkMenu *menuPtr); +static void AppearanceEntryDrawWrapper(TkMenuEntry *mePtr, Rect * menuRectPtr, + MenuTrackingData *mtdPtr, Drawable d, Tk_FontMetrics *fmPtr, + Tk_Font tkfont, int erase); +static pascal void ThemeMenuItemDrawingProc(const Rect *inBounds, + SInt16 inDepth, Boolean inIsColorDevice, SInt32 inUserData); +#else /* USE_TK_MDEF */ +# define useMDEF 0 +#endif /* USE_TK_MDEF */ + +#define IS_THEME_MENU_FONT(tkfont) (strcmp(Tk_NameOfFont(tkfont), "menu") == 0) + + +/* + *---------------------------------------------------------------------- + * + * DrawThemeText -- + * + * Wrapper for DrawThemeTextBox API. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +DrawThemeText( + Drawable d, + GC gc, + CFStringRef string, + ThemeFontID font, + ThemeDrawState drawState, + const Rect* bounds, + int baseline, + int just) +{ + TkMacOSXDrawingContext dc; + Rect adjustedBounds; + + /* + * Menu item text drawn with the .Keyboard font (used for + * kThemeMenuItemCmdKeyFont) won't always have the same ascent and + * baseline as text drawn with the regular menu item font, since the + * glyphs in the .Keyboard font may have a different height. Therefore, we + * first determine the baseline of the text and then adjust the bounds + * rect so the baseline aligns with the overall baseline of the menu item. + */ + if (font == kThemeMenuItemCmdKeyFont) { + Point size; + SInt16 cmdKeyBaseline; + + GetThemeTextDimensions(string, font, drawState, false, &size, + &cmdKeyBaseline); + adjustedBounds = *bounds; + OffsetRect(&adjustedBounds, 0, baseline - bounds->top - size.v - + cmdKeyBaseline); + bounds = &adjustedBounds; + } + TkMacOSXSetupDrawingContext(d, gc, 1, &dc); + ChkErr(DrawThemeTextBox, string, font, drawState, false, bounds, just, + dc.context); + TkMacOSXRestoreDrawingContext(&dc); +} + +/* + *---------------------------------------------------------------------- + * + * MeasureThemeText -- + * + * Wrapper for GetThemeTextDimensions API. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +MeasureThemeText( + CFStringRef string, + ThemeFontID font) +{ + Point pt; + ChkErr(GetThemeTextDimensions, string, font, kThemeStateActive, false, &pt, + NULL); + return pt.h; +} /* *---------------------------------------------------------------------- @@ -375,16 +404,15 @@ TkMacOSXUseMenuID( Tcl_HashEntry *commandEntryPtr; int newEntry; int iMacID = macID; /* Do this to remove compiler warning */ - + TkMenuInit(); commandEntryPtr = Tcl_CreateHashEntry(&commandTable, (char *) iMacID, - &newEntry); - if (newEntry == 1) { - Tcl_SetHashValue(commandEntryPtr, NULL); - return TCL_OK; - } else { - return TCL_ERROR; + &newEntry); + if (!newEntry) { + return TCL_ERROR; } + Tcl_SetHashValue(commandEntryPtr, NULL); + return TCL_OK; } /* @@ -400,8 +428,8 @@ TkMacOSXUseMenuID( * is no hash entry, we know that we can use the id. * * Carbon allows a much larger number of menus than the old APIs. - * I believe this is 32768, but am not sure. This code just uses - * 2000 as the upper limit. Unfortunately tk leaks menus when + * I believe this is 32768, but am not sure. This code just uses + * 2000 as the upper limit. Unfortunately tk leaks menus when * cloning, under some circumstances (see bug on sourceforge). * * Results: @@ -416,12 +444,13 @@ TkMacOSXUseMenuID( * *---------------------------------------------------------------------- */ + int TkMacOSXGetNewMenuID( Tcl_Interp *interp, /* Used for error reporting */ TkMenu *menuPtr, /* The menu we are working with */ int cascade, /* 0 if we are working with a normal menu; - 1 if we are working with a cascade */ + * 1 if we are working with a cascade */ short *menuIDPtr) /* The resulting id */ { int found = 0; @@ -434,65 +463,64 @@ int * when the highest value is incremented. Also, the values between * 236 and 255 inclusive are reserved for DA's by the Mac OS. */ - + if (!cascade) { - short curID = lastMenuID + 1; - if (curID == 236) { - curID = 256; - } - - while (curID != lastMenuID) { - int iCurID = curID; - commandEntryPtr = Tcl_CreateHashEntry(&commandTable, + short curID = lastMenuID + 1; + + if (curID == 236) { + curID = 256; + } + + while (curID != lastMenuID) { + int iCurID = curID; + commandEntryPtr = Tcl_CreateHashEntry(&commandTable, (char *) iCurID, &newEntry); - if (newEntry == 1) { - found = 1; - lastMenuID = returnID = curID; - break; - } - curID++; - if (curID == 236) { - curID = 256; - } - } + if (newEntry == 1) { + found = 1; + lastMenuID = returnID = curID; + break; + } + curID++; + if (curID == 236) { + curID = 256; + } + } } else { - - /* - * Cascade ids must be between 0 and 235 only, so they must be - * dealt with separately. - */ - - short curID = lastCascadeID + 1; - if (curID == 2000) { - curID = 0; - } - - while (curID != lastCascadeID) { - int iCurID = curID; - commandEntryPtr = Tcl_CreateHashEntry(&commandTable, + /* + * Cascade ids must be between 0 and 235 only, so they must be + * dealt with separately. + */ + + short curID = lastCascadeID + 1; + + if (curID == 2000) { + curID = 0; + } + + while (curID != lastCascadeID) { + int iCurID = curID; + commandEntryPtr = Tcl_CreateHashEntry(&commandTable, (char *) iCurID, &newEntry); - if (newEntry == 1) { - found = 1; - lastCascadeID = returnID = curID; - break; - } - curID++; - if (curID == 2000) { - curID = 0; - } - } + if (newEntry == 1) { + found = 1; + lastCascadeID = returnID = curID; + break; + } + curID++; + if (curID == 2000) { + curID = 0; + } + } } - if (found) { - Tcl_SetHashValue(commandEntryPtr, (char *) menuPtr); - *menuIDPtr = returnID; - return TCL_OK; - } else { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "No more menus can be allocated.", - (char *) NULL); - return TCL_ERROR; + if (!found) { + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, "No more menus can be allocated.", NULL); + return TCL_ERROR; } + Tcl_SetHashValue(commandEntryPtr, (char *) menuPtr); + *menuIDPtr = returnID; + return TCL_OK; } /* @@ -513,20 +541,87 @@ int void TkMacOSXFreeMenuID( - short menuID) /* The id to free */ + short menuID) /* The id to free */ { Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&commandTable, - (char *) ((int)menuID)); - + (char*)(intptr_t)menuID); + if (entryPtr != NULL) { - Tcl_DeleteHashEntry(entryPtr); + Tcl_DeleteHashEntry(entryPtr); } if (menuID == currentAppleMenuID) { - currentAppleMenuID = 0; + currentAppleMenuID = 0; } if (menuID == currentHelpMenuID) { - currentHelpMenuID = 0; + currentHelpMenuID = 0; + } +} + +/* + *---------------------------------------------------------------------- + * + * MenuPtrForMenuRef -- + * + * Returns a pointer to the TkMenu corresponding to a given + * Carbon MenuRef. + * + * Results: + * Returns a pointer to a TkMenu or NULL. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +TkMenu* +MenuPtrForMenuRef( + MenuRef menu) +{ + TkMenu *menuPtr = NULL; + MenuID menuID = GetMenuID(menu); + Tcl_HashEntry *commandEntryPtr = Tcl_FindHashEntry(&commandTable, + (char*)(intptr_t)menuID); + + if (commandEntryPtr) { + menuPtr = (TkMenu *) Tcl_GetHashValue(commandEntryPtr); } + return menuPtr; +} + +/* + *---------------------------------------------------------------------- + * + * GetParentMenuEntry -- + * + * Returns a pointer to the parent's TkMenuEntry of a given TkMenu. + * + * Results: + * Returns a pointer to a TkMenuEntry or NULL. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +TkMenuEntry* +GetParentMenuEntry( + TkMenu *menuPtr) +{ + TkMenuEntry *cascadeEntryPtr; + + for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr; + cascadeEntryPtr != NULL; + cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) { + const char *name = (cascadeEntryPtr->namePtr == NULL) ? "" + : Tcl_GetString(cascadeEntryPtr->namePtr); + + if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) { + break; + } + } + return cascadeEntryPtr; } /* @@ -550,81 +645,82 @@ TkMacOSXFreeMenuID( int TkpNewMenu( TkMenu *menuPtr) /* The common structure we are making the - * platform structure for. */ + * platform structure for. */ { short menuID; MenuRef macMenuHdl; +#ifdef USE_TK_MDEF MenuDefSpec menuDefSpec; Tcl_Obj *useMDEFObjPtr; - int useMDEF; + int useMDEF = 1; +#endif int error = TCL_OK; OSStatus err; CFStringRef cfStr; - + error = TkMacOSXGetNewMenuID(menuPtr->interp, menuPtr, 0, &menuID); if (error != TCL_OK) { - return error; + return error; } - err = CreateNewMenu(menuID, kMenuAttrDoNotUseUserCommandKeys, &macMenuHdl); + err = ChkErr(CreateNewMenu, menuID, kMenuAttrDoNotUseUserCommandKeys, + &macMenuHdl); if (err != noErr) { - Tcl_AppendResult(menuPtr->interp, "CreateNewMenu failed.", - (char *) NULL); - return TCL_ERROR; + Tcl_AppendResult(menuPtr->interp, "CreateNewMenu failed.", NULL); + return TCL_ERROR; } cfStr = CFStringCreateWithCString(NULL, Tk_PathName(menuPtr->tkwin), - kCFStringEncodingUTF8); + kCFStringEncodingUTF8); if (!cfStr) { - Tcl_AppendResult(menuPtr->interp, "CFStringCreateWithCString failed.", - (char *) NULL); - return TCL_ERROR; + Tcl_AppendResult(menuPtr->interp, "CFStringCreateWithCString failed.", + NULL); + return TCL_ERROR; } - err = SetMenuTitleWithCFString(macMenuHdl, cfStr); + err = ChkErr(SetMenuTitleWithCFString, macMenuHdl, cfStr); CFRelease(cfStr); if (err != noErr) { - Tcl_AppendResult(menuPtr->interp, "SetMenuTitleWithCFString failed.", - (char *) NULL); - return TCL_ERROR; + Tcl_AppendResult(menuPtr->interp, "SetMenuTitleWithCFString failed.", + NULL); + return TCL_ERROR; } - + + menuPtr->platformData = (TkMenuPlatformData) ckalloc(sizeof(MacMenu)); + ((MacMenu *) menuPtr->platformData)->menuHdl = macMenuHdl; + +#ifdef USE_TK_MDEF /* - * Check whether we want to use the custom mdef or not. For now + * Check whether we want to use the custom mdef or not. For now * the default is to use it unless the variable is explicitly * set to no. */ - - useMDEFObjPtr = Tcl_ObjGetVar2(menuPtr->interp, useMDEFVar, NULL, TCL_GLOBAL_ONLY); - if (useMDEFObjPtr == NULL - || Tcl_GetBooleanFromObj(NULL, useMDEFObjPtr, &useMDEF) == TCL_ERROR - || useMDEF) { - menuDefSpec.defType = kMenuDefProcPtr; - menuDefSpec.u.defProc = MenuDefProc; - if ((err = SetMenuDefinition(macMenuHdl, &menuDefSpec)) != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr, "SetMenuDefinition failed %d\n", (int) err); -#endif - } + + useMDEFObjPtr = Tcl_ObjGetVar2(menuPtr->interp, useMDEFVar, NULL, + TCL_GLOBAL_ONLY); + if (useMDEFObjPtr == NULL || Tcl_GetBooleanFromObj(NULL, useMDEFObjPtr, + &useMDEF) == TCL_ERROR || useMDEF) { + menuDefSpec.defType = kMenuDefProcPtr; + menuDefSpec.u.defProc = MenuDefProc; + ChkErr(SetMenuDefinition, macMenuHdl, &menuDefSpec); } - menuPtr->platformData = (TkMenuPlatformData) ckalloc(sizeof(MacMenu)); - ((MacMenu *) menuPtr->platformData)->menuHdl = macMenuHdl; - SetRect(&((MacMenu *) menuPtr->platformData)->menuRect, 0, 0, 0, 0); + ((MacMenu *) menuPtr->platformData)->useMDEF = useMDEF; +#endif /* USE_TK_MDEF */ if ((currentMenuBarInterp == menuPtr->interp) - && (currentMenuBarName != NULL)) { - Tk_Window parentWin = Tk_Parent(menuPtr->tkwin); - - if (strcmp(currentMenuBarName, Tk_PathName(parentWin)) == 0) { - if ((strcmp(Tk_PathName(menuPtr->tkwin) - + strlen(Tk_PathName(parentWin)), ".apple") == 0) - || (strcmp(Tk_PathName(menuPtr->tkwin) - + strlen(Tk_PathName(parentWin)), ".help") == 0)) { - if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) { - Tcl_DoWhenIdle(DrawMenuBarWhenIdle, (ClientData *) NULL); - menuBarFlags |= MENUBAR_REDRAW_PENDING; - } - } - } + && (currentMenuBarName != NULL)) { + Tk_Window parentWin = Tk_Parent(menuPtr->tkwin); + + if (strcmp(currentMenuBarName, Tk_PathName(parentWin)) == 0) { + if ((strcmp(Tk_PathName(menuPtr->tkwin) + + strlen(Tk_PathName(parentWin)), ".apple") == 0) + || (strcmp(Tk_PathName(menuPtr->tkwin) + + strlen(Tk_PathName(parentWin)), ".help") == 0)) { + if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) { + Tcl_DoWhenIdle(DrawMenuBarWhenIdle, NULL); + menuBarFlags |= MENUBAR_REDRAW_PENDING; + } + } + } } - + menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr); return TCL_OK; @@ -653,35 +749,34 @@ TkpDestroyMenu( MenuRef macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl; if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) { - Tcl_CancelIdleCall(ReconfigureMacintoshMenu, (ClientData) menuPtr); - menuPtr->menuFlags &= ~MENU_RECONFIGURE_PENDING; + Tcl_CancelIdleCall(ReconfigureMacintoshMenu, (ClientData) menuPtr); + menuPtr->menuFlags &= ~MENU_RECONFIGURE_PENDING; } if (GetMenuID(macMenuHdl) == currentHelpMenuID) { - MenuRef helpMenuHdl; - MenuItemIndex helpIndex; - - if ((HMGetHelpMenu(&helpMenuHdl,&helpIndex) == noErr) - && (helpMenuHdl != NULL)) { - int i, count = CountMenuItems(helpMenuHdl); - - for (i = helpIndex; i <= count; i++) { - DeleteMenuItem(helpMenuHdl, helpIndex); - } - } - currentHelpMenuID = 0; + MenuRef helpMenuHdl; + MenuItemIndex helpIndex; + + if ((HMGetHelpMenu(&helpMenuHdl,&helpIndex) == noErr) + && (helpMenuHdl != NULL)) { + int i, count = CountMenuItems(helpMenuHdl); + + for (i = helpIndex; i <= count; i++) { + DeleteMenuItem(helpMenuHdl, helpIndex); + } + } + currentHelpMenuID = 0; } if (menuPtr->platformData != NULL) { - MenuID menuID; - menuID = GetMenuID(macMenuHdl); - DeleteMenu(menuID); - TkMacOSXFreeMenuID(menuID); - DisposeMenu(macMenuHdl); - ckfree((char *) menuPtr->platformData); + MenuID menuID = GetMenuID(macMenuHdl); + + DeleteMenu(menuID); + TkMacOSXFreeMenuID(menuID); + DisposeMenu(macMenuHdl); + ckfree((char *) menuPtr->platformData); menuPtr->platformData = NULL; } } - - + /* *---------------------------------------------------------------------- * @@ -698,7 +793,7 @@ TkpDestroyMenu( *---------------------------------------------------------------------- */ -static int +int SetMenuCascade( TkMenu* menuPtr) /* The menu we are setting up to be a * cascade. */ @@ -706,12 +801,13 @@ SetMenuCascade( MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl; MenuID newMenuID, menuID = GetMenuID(macMenuHdl); int error = TCL_OK; + if (menuID >= 256) { - error = TkMacOSXGetNewMenuID(menuPtr->interp, menuPtr, 1, &newMenuID); - if (error == TCL_OK) { - TkMacOSXFreeMenuID(menuID); - SetMenuID (macMenuHdl,newMenuID); - } + error = TkMacOSXGetNewMenuID(menuPtr->interp, menuPtr, 1, &newMenuID); + if (error == TCL_OK) { + TkMacOSXFreeMenuID(menuID); + SetMenuID(macMenuHdl,newMenuID); + } } return error; } @@ -734,16 +830,15 @@ SetMenuCascade( void TkpDestroyMenuEntry( - TkMenuEntry *mePtr) /* The common structure for the menu - * entry. */ + TkMenuEntry *mePtr) /* The common structure for the menu entry. */ { - TkMenu *menuPtr = mePtr->menuPtr; - + TkMenu *menuPtr = mePtr->menuPtr; + ckfree((char *) mePtr->platformEntryData); - if ((menuPtr->platformData != NULL) - && !(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) { - menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr); + if ((menuPtr->platformData != NULL) + && !(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) { + menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; + Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr); } } @@ -766,45 +861,51 @@ TkpDestroyMenuEntry( *---------------------------------------------------------------------- */ -static void +void GetEntryText( TkMenuEntry *mePtr, /* A pointer to the menu entry. */ Tcl_DString *dStringPtr) /* The DString to put the text into. This - * will be initialized by this routine. */ + * will be initialized by this routine. */ { +#ifdef USE_TK_MDEF + const int useMDEF = ((MacMenu *) mePtr->menuPtr->platformData)->useMDEF; +#endif + int noLabel = (mePtr->labelPtr == NULL || mePtr->labelLength == 0); + Tcl_DStringInit(dStringPtr); - if (mePtr->type == TEAROFF_ENTRY) { - Tcl_DStringAppend(dStringPtr, "(Tear-off)", -1); - } else if (mePtr->imagePtr != NULL) { - Tcl_DStringAppend(dStringPtr, "(Image)", -1); - } else if (mePtr->bitmapPtr != NULL) { - Tcl_DStringAppend(dStringPtr, "(Pixmap)", -1); - } else if (mePtr->labelPtr == NULL || mePtr->labelLength == 0) { + if (mePtr->type == TEAROFF_ENTRY && (useMDEF || noLabel)) { + Tcl_DStringAppend(dStringPtr, "(Tear-off)", -1); + } else if (mePtr->imagePtr != NULL && (useMDEF || noLabel) && + mePtr->compound == COMPOUND_NONE) { + Tcl_DStringAppend(dStringPtr, "(Image)", -1); + } else if (mePtr->bitmapPtr != NULL && (useMDEF || noLabel) && + mePtr->compound == COMPOUND_NONE) { + Tcl_DStringAppend(dStringPtr, "(Pixmap)", -1); + } else if (noLabel) { /* * The Mac menu manager does not like null strings. */ Tcl_DStringAppend(dStringPtr, " ", -1); } else { - int length; - char *text = Tcl_GetStringFromObj(mePtr->labelPtr, &length); - char *dStringText; - int i; + int length; + char *text = Tcl_GetStringFromObj(mePtr->labelPtr, &length); + char *dStringText; + int i; for (i = 0; *text; text++, i++) { - if ((*text == '.') - && (*(text + 1) != '\0') && (*(text + 1) == '.') - && (*(text + 2) != '\0') && (*(text + 2) == '.')) { - Tcl_DStringAppend(dStringPtr, elipsisString, -1); - i += strlen(elipsisString) - 1; + if ((*text == '.') && (*(text+1) == '.') && (*(text+2) == '.')) { + Tcl_DStringAppend(dStringPtr, menuSymbols[ELLIPSIS_SYMBOL].utf, + menuSymbols[ELLIPSIS_SYMBOL].utfLen); + i += menuSymbols[ELLIPSIS_SYMBOL].utfLen - 1; text += 2; - } else { - Tcl_DStringSetLength(dStringPtr, + } else { + Tcl_DStringSetLength(dStringPtr, Tcl_DStringLength(dStringPtr) + 1); - dStringText = Tcl_DStringValue(dStringPtr); - dStringText[i] = *text; - } - } + dStringText = Tcl_DStringValue(dStringPtr); + dStringText[i] = *text; + } + } } } @@ -815,134 +916,159 @@ GetEntryText( * * Finds the Macintosh mark character based on the font of the * item. We calculate a good mark character based on the font - * that this item is rendered in. - * - * We try the following special mac characters. If none of them - * are present, just use the check mark. - * '' - Check mark character (\022) - * 'Â¥' - Mac Bullet character (\245) - * '' - Filled diamond (\023) - * '—' - Hollow diamond (\327) - * '‘' = Mac Long dash ("em dash") (\321) - * '-' = short dash (minus, "en dash"); + * that this item is rendered in. * * Results: - * None. + * Mark char. * * Side effects: - * New item is added to platform menu + * None. * *---------------------------------------------------------------------- */ -static char +char FindMarkCharacter( TkMenuEntry *mePtr) /* The entry we are finding the character - * for. */ + * for. */ { - char markChar; + static const char markChars[] = {kCheckCharCode, kDiamondCharCode, + kBulletCharCode, '-', kCheckCharCode}; + const char *markChar = markChars; + int i = sizeof(markChars); Tk_Font tkfont; tkfont = Tk_GetFontFromObj(mePtr->menuPtr->tkwin, - (mePtr->fontPtr == NULL) ? mePtr->menuPtr->fontPtr + (mePtr->fontPtr == NULL) ? mePtr->menuPtr->fontPtr : mePtr->fontPtr); - - if (!TkMacOSXIsCharacterMissing(tkfont, '\022')) { - markChar = '\022'; /* Check mark */ - } else if (!TkMacOSXIsCharacterMissing(tkfont, '\245')) { - markChar = '\245'; /* Bullet */ - } else if (!TkMacOSXIsCharacterMissing(tkfont, '\023')) { - markChar = '\023'; /* Filled Diamond */ - } else if (!TkMacOSXIsCharacterMissing(tkfont, '\327')) { - markChar = '\327'; /* Hollow Diamond */ - } else if (!TkMacOSXIsCharacterMissing(tkfont, '\321')) { - markChar = '\321'; /* Long Dash */ - } else if (!TkMacOSXIsCharacterMissing(tkfont, '-')) { - markChar = '-'; /* Short Dash */ - } else { - markChar = '\022'; /* Check mark */ + + while (--i) { + if (!TkMacOSXIsCharacterMissing(tkfont, *markChar)) { + break; + } + markChar++; } - return markChar; + return *markChar; } /* *---------------------------------------------------------------------- * - * SetMenuTitle -- + * GetUtfMarkCharacter -- * - * Sets title of menu so that the text displays correctly in menubar. - * This code directly manipulates menu handle data. This code - * was originally part of an ancient Apple Developer Response mail. + * Get the utf8 string for the given mark character, taking into + * account the special menu font char codes. * * Results: - * None. + * Length of returned utf8 string. * * Side effects: - * The menu handle will change size depending on the length of the - * title + * None. * *---------------------------------------------------------------------- */ -static void -mySetMenuTitle( - MenuRef menuHdl, /* The menu we are setting the title of. */ - Tcl_Obj *titlePtr) /* The C string to set the title to. */ +int +GetUtfMarkCharacter( + char markChar, + const char **markUtfPtr) { - char *title = (titlePtr == NULL) ? "" - : Tcl_GetStringFromObj(titlePtr, NULL); - CFStringRef cf = CFStringCreateWithCString(NULL, - title, kCFStringEncodingUTF8); + const MenuSymbol *ms = menuSymbols; + int len = 0; - SetMenuTitleWithCFString(menuHdl, cf); - CFRelease(cf); + while (ms->unicode) { + if (ms->charCode && ms->charCode == markChar) { + *markUtfPtr = ms->utf; + len = ms->utfLen; + break; + } + ms++; + } + if (!len) { + static char markUtf[TCL_UTF_MAX + 1]; + + Tcl_ExternalToUtf(NULL, TkMacOSXCarbonEncoding, &markChar, 1, 0, NULL, + markUtf, TCL_UTF_MAX + 1, NULL, &len, NULL); + *markUtfPtr = markUtf; + } + return len; } + +/* + *---------------------------------------------------------------------- + * + * ParseAccelerators -- + * + * Parse menu accelerator string. + * + * Results: + * Accelerator flags. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +ParseAccelerators( + const char **accelStringPtr, + int *modifierNumPtr, + Tcl_UniChar *modifierUniChars, + int *modifierWidth) +{ + struct Modif { + const char *name; + const size_t len; + const int flag, symbol; + }; +#define MODIF(n, f) { #n, sizeof(#n)-1, ENTRY_##f##_ACCEL, f##_SYMBOL } + static const struct Modif modifs[] = { + MODIF(Control, CONTROL), + MODIF(Ctrl, CONTROL), + MODIF(Option, OPTION), + MODIF(Opt, OPTION), + MODIF(Alt, OPTION), + MODIF(Shift, SHIFT), + MODIF(Command, COMMAND), + MODIF(Cmd, COMMAND), + MODIF(Meta, COMMAND), + { NULL, 0, 0, 0} + }; +#undef MODIF + const char *accelString = *accelStringPtr; + int flags = 0, num = 0, seen = 0, width = 0; + const struct Modif *m; -static int ParseAccelerators(char **accelStringPtr) { - char *accelString = *accelStringPtr; - int flags = 0; while (1) { - if ((0 == strncasecmp("Control", accelString, 6)) - && (('-' == accelString[6]) || ('+' == accelString[6]))) { - flags |= ENTRY_CONTROL_ACCEL; - accelString += 7; - } else if ((0 == strncasecmp("Ctrl", accelString, 4)) - && (('-' == accelString[4]) || ('+' == accelString[4]))) { - flags |= ENTRY_CONTROL_ACCEL; - accelString += 5; - } else if ((0 == strncasecmp("Shift", accelString, 5)) - && (('-' == accelString[5]) || ('+' == accelString[5]))) { - flags |= ENTRY_SHIFT_ACCEL; - accelString += 6; - } else if ((0 == strncasecmp("Option", accelString, 6)) - && (('-' == accelString[6]) || ('+' == accelString[6]))) { - flags |= ENTRY_OPTION_ACCEL; - accelString += 7; - } else if ((0 == strncasecmp("Opt", accelString, 3)) - && (('-' == accelString[3]) || ('+' == accelString[3]))) { - flags |= ENTRY_OPTION_ACCEL; - accelString += 4; - } else if ((0 == strncasecmp("Command", accelString, 7)) - && (('-' == accelString[7]) || ('+' == accelString[7]))) { - flags |= ENTRY_COMMAND_ACCEL; - accelString += 8; - } else if ((0 == strncasecmp("Cmd", accelString, 3)) - && (('-' == accelString[3]) || ('+' == accelString[3]))) { - flags |= ENTRY_COMMAND_ACCEL; - accelString += 4; - } else if ((0 == strncasecmp("Alt", accelString, 3)) - && (('-' == accelString[3]) || ('+' == accelString[3]))) { - flags |= ENTRY_OPTION_ACCEL; - accelString += 4; - } else if ((0 == strncasecmp("Meta", accelString, 4)) - && (('-' == accelString[4]) || ('+' == accelString[4]))) { - flags |= ENTRY_COMMAND_ACCEL; - accelString += 5; - } else { + m = modifs; + while (m->name) { + int l = m->len; + + if (!strncasecmp(accelString, m->name, l) && + (accelString[l] == '-' || accelString[l] == '+')) { + flags |= m->flag; + accelString += l+1; + break; + } + m++; + } + if (!m->name || !*accelString) { break; } } + m = modifs; + while (m->name && num < MODIFIER_NUM) { + if (flags & m->flag && !(seen & m->flag)) { + modifierUniChars[num++] = menuSymbols[m->symbol].unicode; + width += menuSymbols[m->symbol].width; + seen |= m->flag; + } + m++; + } *accelStringPtr = accelString; + *modifierNumPtr = num; + *modifierWidth = width; return flags; } @@ -966,72 +1092,75 @@ static int ParseAccelerators(char **accelStringPtr) { int TkpConfigureMenuEntry( - TkMenuEntry *mePtr) /* Information about menu entry; may - * or may not already have values for - * some fields. */ + TkMenuEntry *mePtr) /* Information about menu entry; may + * or may not already have values for + * some fields. */ { TkMenu *menuPtr = mePtr->menuPtr; -#if 0 /* Unused */ - int index = mePtr->index; - MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl; - MenuHandle helpMenuHdl = NULL; -#endif + EntryGeometry *geometryPtr = (EntryGeometry *) mePtr->platformEntryData; /* * Cascade menus have to have menu IDs of less than 256. So * we need to change the child menu if this has been configured * for a cascade item. */ - + if (mePtr->type == CASCADE_ENTRY) { - if ((mePtr->childMenuRefPtr != NULL) - && (mePtr->childMenuRefPtr->menuPtr != NULL)) { - MenuHandle childMenuHdl = ((MacMenu *) mePtr - ->childMenuRefPtr->menuPtr->platformData)->menuHdl; - - if (childMenuHdl != NULL) { - int error = SetMenuCascade(mePtr->childMenuRefPtr->menuPtr); - - if (error != TCL_OK) { - return error; - } - - if (menuPtr->menuType == MENUBAR) { - mySetMenuTitle(childMenuHdl, mePtr->labelPtr); - } - } - } + if ((mePtr->childMenuRefPtr != NULL) + && (mePtr->childMenuRefPtr->menuPtr != NULL)) { + MenuHandle childMenuHdl = ((MacMenu *) mePtr + ->childMenuRefPtr->menuPtr->platformData)->menuHdl; + + if (childMenuHdl != NULL) { + int error = SetMenuCascade(mePtr->childMenuRefPtr->menuPtr); + + if (error != TCL_OK) { + return error; + } + + if (menuPtr->menuType == MENUBAR) { + CFStringRef cfStr = CFStringCreateWithCString(NULL, + (!(mePtr->labelPtr) ? "" : + Tcl_GetString(mePtr->labelPtr)), + kCFStringEncodingUTF8); + + if (cfStr) { + SetMenuTitleWithCFString(childMenuHdl, cfStr); + CFRelease(cfStr); + } + } + } + } } - + /* * We need to parse the accelerator string. If it has the strings * for Command, Control, Shift or Option, we need to flag it * so we can draw the symbols for it. We also need to precalcuate * the position of the first real character we are drawing. */ - + if (0 == mePtr->accelLength) { - ((EntryGeometry *)mePtr->platformEntryData)->accelTextStart = -1; + geometryPtr->accelTextStart = -1; } else { - char *accelString = (mePtr->accelPtr == NULL) ? "" - : Tcl_GetStringFromObj(mePtr->accelPtr, NULL); - char *accel = accelString; + const char *accelString = (mePtr->accelPtr == NULL) ? "" + : Tcl_GetString(mePtr->accelPtr); + const char *accelStart = accelString; + mePtr->entryFlags &= ~ENTRY_ACCEL_MASK; - - mePtr->entryFlags |= ParseAccelerators(&accelString); - - ((EntryGeometry *)mePtr->platformEntryData)->accelTextStart - = ((long) accelString - (long) accel); + mePtr->entryFlags |= ParseAccelerators(&accelString, + &geometryPtr->modifierNum, geometryPtr->modifierUniChars, + &geometryPtr->modifierWidth); + geometryPtr->accelTextStart = (ptrdiff_t)(accelString - accelStart); } - + if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) { - menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr); + menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; + Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr); } - + return TCL_OK; } - /* *---------------------------------------------------------------------- @@ -1053,146 +1182,140 @@ TkpConfigureMenuEntry( *---------------------------------------------------------------------- */ -static void +void ReconfigureIndividualMenu( TkMenu *menuPtr, /* The menu we are affecting. */ MenuHandle macMenuHdl, /* The macintosh menu we are affecting. - * Will not necessarily be - * menuPtr->platformData because this could - * be the help menu. */ + * Will not necessarily be + * menuPtr->platformData because this could + * be the help menu. */ int base) /* The last index that we do not want - * touched. 0 for normal menus; - * # of system help menu items - * for help menus. */ + * touched. 0 for normal menus; + * # of system help menu items + * for help menus. */ { int count; int index; TkMenuEntry *mePtr; int parentDisabled = 0; -#if defined(TK_MAC_DEBUG) && defined(TK_MAC_DEBUG_MENUS) - /* Carbon-internal menu debugging (c.f. Technote 2124) */ - TkMacOSXInitNamedDebugSymbol(HIToolbox, void, DebugPrintMenu, MenuRef menu); +#ifdef TK_MAC_DEBUG_MENUS + /* + * Carbon-internal menu debugging (c.f. Technote 2124) + */ + + TkMacOSXInitNamedDebugSymbol(HIToolbox, void, DebugPrintMenu, + MenuRef menu); if (DebugPrintMenu) { - DebugPrintMenu(macMenuHdl); + DebugPrintMenu(macMenuHdl); } #endif - for (mePtr = menuPtr->menuRefPtr->parentEntryPtr; mePtr != NULL; - mePtr = mePtr->nextCascadePtr) { - char *name = (mePtr->namePtr == NULL) ? "" - : Tcl_GetStringFromObj(mePtr->namePtr, NULL); - - if (strcmp(Tk_PathName(menuPtr->tkwin), name) == 0) { - if (mePtr->state == ENTRY_DISABLED) { - parentDisabled = 1; - } - break; - } + mePtr = GetParentMenuEntry(menuPtr); + if (mePtr && mePtr->state == ENTRY_DISABLED) { + parentDisabled = 1; } - + /* * First, we get rid of all of the old items. */ - + count = CountMenuItems(macMenuHdl); for (index = base; index < count; index++) { - DeleteMenuItem(macMenuHdl, base + 1); + DeleteMenuItem(macMenuHdl, base + 1); } count = menuPtr->numEntries; - + for (index = 1; index <= count; index++) { - mePtr = menuPtr->entries[index - 1]; - - /* - * We have to do separators separately because SetMenuItemText - * does not parse meta-characters. - */ - - if (mePtr->type == SEPARATOR_ENTRY) { - AppendMenuItemTextWithCFString (macMenuHdl, NULL, - kMenuItemAttrSeparator | kMenuItemAttrDisabled, - 0, NULL); - } else { - Tcl_DString itemTextDString; - CFStringRef cf; + mePtr = menuPtr->entries[index - 1]; + + /* + * We have to do separators separately because SetMenuItemText + * does not parse meta-characters. + */ + + if (mePtr->type == SEPARATOR_ENTRY) { + AppendMenuItemTextWithCFString(macMenuHdl, NULL, + kMenuItemAttrSeparator | kMenuItemAttrDisabled, 0, NULL); + } else { + Tcl_DString itemTextDString; + CFStringRef cfStr; + GetEntryText(mePtr, &itemTextDString); - cf = CFStringCreateWithCString(NULL, - Tcl_DStringValue(&itemTextDString), kCFStringEncodingUTF8); - if (cf != NULL) { - AppendMenuItemTextWithCFString (macMenuHdl, cf, 0, 0, NULL); - CFRelease(cf); + cfStr = CFStringCreateWithCString(NULL, + Tcl_DStringValue(&itemTextDString), kCFStringEncodingUTF8); + if (cfStr) { + AppendMenuItemTextWithCFString(macMenuHdl, cfStr, 0, 0, NULL); + CFRelease(cfStr); } else { - cf = CFSTR ("<Error>"); - AppendMenuItemTextWithCFString (macMenuHdl, cf, 0, 0, NULL); + AppendMenuItemTextWithCFString(macMenuHdl, CFSTR ("<Error>"), + 0, 0, NULL); } Tcl_DStringFree(&itemTextDString); - - /* - * Set enabling and disabling correctly. - */ + + /* + * Set enabling and disabling correctly. + */ if (parentDisabled || (mePtr->state == ENTRY_DISABLED)) { - DisableMenuItem(macMenuHdl, base + index); + DisableMenuItem(macMenuHdl, base + index); } else { - EnableMenuItem(macMenuHdl, base + index); + EnableMenuItem(macMenuHdl, base + index); } - - /* - * Set the check mark for check entries and radio entries. - */ - - SetItemMark(macMenuHdl, base + index, 0); + + /* + * Set the check mark for check entries and radio entries. + */ + + SetItemMark(macMenuHdl, base + index, 0); if ((mePtr->type == CHECK_BUTTON_ENTRY) || (mePtr->type == RADIO_BUTTON_ENTRY)) { - CheckMenuItem(macMenuHdl, base + index, (mePtr->entryFlags - & ENTRY_SELECTED) && mePtr->indicatorOn); + CheckMenuItem(macMenuHdl, base + index, (mePtr->entryFlags + & ENTRY_SELECTED) && mePtr->indicatorOn); if (mePtr->indicatorOn && (mePtr->entryFlags & ENTRY_SELECTED)) { SetItemMark(macMenuHdl, base + index, - FindMarkCharacter(mePtr)); - } + FindMarkCharacter(mePtr)); + } } - + if (mePtr->type == CASCADE_ENTRY) { - if ((mePtr->childMenuRefPtr != NULL) - && (mePtr->childMenuRefPtr->menuPtr != NULL)) { - MenuHandle childMenuHdl = - ((MacMenu *) mePtr->childMenuRefPtr + if ((mePtr->childMenuRefPtr != NULL) + && (mePtr->childMenuRefPtr->menuPtr != NULL)) { + MenuHandle childMenuHdl = + ((MacMenu *) mePtr->childMenuRefPtr ->menuPtr->platformData)->menuHdl; if (childMenuHdl != NULL) { - { - SetMenuItemHierarchicalID(macMenuHdl, base + index, - GetMenuID(childMenuHdl)); - } - } - /* - * If we changed the highligthing of this menu, its - * children all have to be reconfigured so that - * their state will be reflected in the menubar. - */ - - if (!(mePtr->childMenuRefPtr->menuPtr->menuFlags - & MENU_RECONFIGURE_PENDING)) { - mePtr->childMenuRefPtr->menuPtr->menuFlags - |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, - (ClientData) mePtr->childMenuRefPtr->menuPtr); - } - } + SetMenuItemHierarchicalID(macMenuHdl, base + index, + GetMenuID(childMenuHdl)); + } + /* + * If we changed the highligthing of this menu, its + * children all have to be reconfigured so that + * their state will be reflected in the menubar. + */ + + if (!(mePtr->childMenuRefPtr->menuPtr->menuFlags + & MENU_RECONFIGURE_PENDING)) { + mePtr->childMenuRefPtr->menuPtr->menuFlags + |= MENU_RECONFIGURE_PENDING; + Tcl_DoWhenIdle(ReconfigureMacintoshMenu, + (ClientData) mePtr->childMenuRefPtr->menuPtr); + } + } } - - if ((mePtr->type != CASCADE_ENTRY) && (mePtr->accelPtr != NULL)) { - int accelLen; - int modifiers = 0; - int hasCmd = 0; - int offset = ((EntryGeometry *)mePtr->platformEntryData)->accelTextStart; - char *accel = Tcl_GetStringFromObj(mePtr->accelPtr, &accelLen); - accelLen -= offset; - accel+= offset; - + + if ((mePtr->type != CASCADE_ENTRY) && (mePtr->accelPtr != NULL)) { + int accelLen, modifiers = 0, hasCmd = 0; + EntryGeometry *geometryPtr = + (EntryGeometry*)mePtr->platformEntryData; + int offset = geometryPtr->accelTextStart; + char *accel = Tcl_GetStringFromObj(mePtr->accelPtr, &accelLen); + + accelLen -= offset; + accel += offset; if (mePtr->entryFlags & ENTRY_OPTION_ACCEL) { modifiers |= kMenuOptionModifier; } @@ -1205,74 +1328,87 @@ ReconfigureIndividualMenu( if (mePtr->entryFlags & ENTRY_COMMAND_ACCEL) { hasCmd = 1; } - if (accelLen == 1) { - if (hasCmd || (modifiers != 0 && modifiers != kMenuShiftModifier)) { - SetItemCmd(macMenuHdl, base + index, accel[0]); + if (accelLen == 1) { + if (hasCmd || (modifiers != 0 && modifiers != + kMenuShiftModifier)) { + SetItemCmd(macMenuHdl, base + index, accel[0]); if (!hasCmd) { modifiers |= kMenuNoCommandModifier; } } - } else { - /* - * Now we need to convert from various textual names - * to Carbon codes + } else { + /* + * Convert from accelerator names to Carbon menu glyphs. */ - char glyph = 0x0; - char first = UCHAR(accel[0]); - if (first == 'F' && (accel[1] > '0' && accel[1] <= '9')) { + struct Glyph { + const char *name; + const size_t len; + const char glyph; + }; +#define GLYPH(n, g) { #n, sizeof(#n)-1, kMenu##g##Glyph } + static const struct Glyph glyphs[] = { + GLYPH(PageUp, PageUp), + GLYPH(PageDown, PageDown), + GLYPH(Left, LeftArrow), + GLYPH(Right, RightArrow), + GLYPH(Up, UpArrow), + GLYPH(Down, DownArrow), + GLYPH(Escape, Escape), + GLYPH(Clear, Clear), + GLYPH(Enter, Enter), + GLYPH(Backspace,DeleteLeft), + GLYPH(Space, Space), + GLYPH(Tab, TabRight), + GLYPH(Delete, DeleteRight), + GLYPH(Home, NorthwestArrow), + GLYPH(End, SoutheastArrow), + GLYPH(Return, Return), + GLYPH(Help, Help), + GLYPH(Power, Power), + { NULL, 0, 0} + }; +#undef GLYPH + const struct Glyph *g = glyphs; + char glyph = 0; + + if (accel[0] == 'F' && accelLen < 4 && + (accel[1] > '0' && accel[1] <= '9')) { int fkey = accel[1] - '0'; - if (accel[2] > '0' && accel[2] <= '9') { - fkey = 10*fkey + (accel[2] - '0'); + + if (accelLen == 3) { + if (accel[2] >= '0' && accel[2] <= '9') { + fkey = 10 * fkey + (accel[2] - '0'); + } else { + fkey = 0; + } } - if (fkey > 0 && fkey < 16) { + if (fkey >= 1 && fkey <= 12) { glyph = kMenuF1Glyph + fkey - 1; + } else if (fkey >= 13 && fkey <= 15) { + glyph = kMenuF13Glyph + fkey - 13; + } + } else while (g->name) { + if (accel[0] == g->name[0] && + (size_t)accelLen == g->len && + !strncasecmp(accel, g->name, g->len)) { + glyph = g->glyph; + break; } - } else if (first == 'P' && 0 ==strcasecmp(accel,"pageup")) { - glyph = kMenuPageUpGlyph; - } else if (first == 'P' && 0 ==strcasecmp(accel,"pagedown")) { - glyph = kMenuPageDownGlyph; - } else if (first == 'L' && 0 ==strcasecmp(accel,"left")) { - glyph = kMenuLeftArrowGlyph; - } else if (first == 'R' && 0 ==strcasecmp(accel,"right")) { - glyph = kMenuRightArrowGlyph; - } else if (first == 'U' && 0 ==strcasecmp(accel,"up")) { - glyph = kMenuUpArrowGlyph; - } else if (first == 'D' && 0 ==strcasecmp(accel,"down")) { - glyph = kMenuDownArrowGlyph; - } else if (first == 'E' && 0 ==strcasecmp(accel,"escape")) { - glyph = kMenuEscapeGlyph; - } else if (first == 'C' && 0 ==strcasecmp(accel,"clear")) { - glyph = kMenuClearGlyph; - } else if (first == 'E' && 0 ==strcasecmp(accel,"enter")) { - glyph = kMenuEnterGlyph; - } else if (first == 'D' && 0 ==strcasecmp(accel,"backspace")) { - glyph = kMenuDeleteLeftGlyph; - } else if (first == 'S' && 0 ==strcasecmp(accel,"space")) { - glyph = kMenuSpaceGlyph; - } else if (first == 'T' && 0 ==strcasecmp(accel,"tab")) { - glyph = kMenuTabRightGlyph; - } else if (first == 'F' && 0 ==strcasecmp(accel,"delete")) { - glyph = kMenuDeleteRightGlyph; - } else if (first == 'H' && 0 ==strcasecmp(accel,"home")) { - glyph = kMenuNorthwestArrowGlyph; - } else if (first == 'R' && 0 ==strcasecmp(accel,"return")) { - glyph = kMenuReturnGlyph; - } else if (first == 'H' && 0 ==strcasecmp(accel,"help")) { - glyph = kMenuHelpGlyph; - } else if (first == 'P' && 0 ==strcasecmp(accel,"power")) { - glyph = kMenuPowerGlyph; - } - if (glyph != 0x0) { - SetMenuItemKeyGlyph(macMenuHdl, base + index, glyph); + g++; + } + if (glyph) { + ChkErr(SetMenuItemKeyGlyph, macMenuHdl, base + index, + glyph); if (!hasCmd) { modifiers |= kMenuNoCommandModifier; } + geometryPtr->accelGlyph = glyph; } - } - - SetMenuItemModifiers(macMenuHdl, base + index, modifiers); + } + ChkErr(SetMenuItemModifiers, macMenuHdl, base + index, + modifiers); } - } + } } } @@ -1295,11 +1431,11 @@ ReconfigureIndividualMenu( *---------------------------------------------------------------------- */ -static void +void ReconfigureMacintoshMenu( - ClientData clientData) /* Information about menu entry; may - * or may not already have values for - * some fields. */ + ClientData clientData) /* Information about menu entry; may + * or may not already have values for + * some fields. */ { TkMenu *menuPtr = (TkMenu *) clientData; MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl; @@ -1308,30 +1444,24 @@ ReconfigureMacintoshMenu( menuPtr->menuFlags &= ~MENU_RECONFIGURE_PENDING; if (NULL == macMenuHdl) { - return; + return; } ReconfigureIndividualMenu(menuPtr, macMenuHdl, 0); - /* Not necessary in Carbon: - if (menuPtr->menuFlags & MENU_APPLE_MENU) { - AppendResMenu(macMenuHdl, 'DRVR'); - } - */ if (GetMenuID(macMenuHdl) == currentHelpMenuID) { - MenuItemIndex helpIndex; - HMGetHelpMenu(&helpMenuHdl,&helpIndex); - if (helpMenuHdl != NULL) { - ReconfigureIndividualMenu(menuPtr, helpMenuHdl, - helpIndex - 1); - } + MenuItemIndex helpIndex; + HMGetHelpMenu(&helpMenuHdl,&helpIndex); + if (helpMenuHdl != NULL) { + ReconfigureIndividualMenu(menuPtr, helpMenuHdl, helpIndex - 1); + } } if (menuPtr->menuType == MENUBAR) { - if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) { - Tcl_DoWhenIdle(DrawMenuBarWhenIdle, (ClientData *) NULL); - menuBarFlags |= MENUBAR_REDRAW_PENDING; - } + if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) { + Tcl_DoWhenIdle(DrawMenuBarWhenIdle, NULL); + menuBarFlags |= MENUBAR_REDRAW_PENDING; + } } } @@ -1352,26 +1482,23 @@ ReconfigureMacintoshMenu( *---------------------------------------------------------------------- */ -static void +void CompleteIdlers( - TkMenu *menuPtr) /* The menu we are completing. */ + TkMenu *menuPtr) /* The menu we are completing. */ { int i; if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) { - Tcl_CancelIdleCall(ReconfigureMacintoshMenu, (ClientData) menuPtr); - ReconfigureMacintoshMenu((ClientData) menuPtr); + Tcl_CancelIdleCall(ReconfigureMacintoshMenu, (ClientData) menuPtr); + ReconfigureMacintoshMenu((ClientData) menuPtr); } - + for (i = 0; i < menuPtr->numEntries; i++) { - if (menuPtr->entries[i]->type == CASCADE_ENTRY) { - if ((menuPtr->entries[i]->childMenuRefPtr != NULL) - && (menuPtr->entries[i]->childMenuRefPtr->menuPtr - != NULL)) { - CompleteIdlers(menuPtr->entries[i]->childMenuRefPtr - ->menuPtr); - } - } + if ((menuPtr->entries[i]->type == CASCADE_ENTRY) && + (menuPtr->entries[i]->childMenuRefPtr != NULL) && + (menuPtr->entries[i]->childMenuRefPtr->menuPtr != NULL)) { + CompleteIdlers(menuPtr->entries[i]->childMenuRefPtr->menuPtr); + } } } @@ -1396,113 +1523,62 @@ TkpPostMenu( Tcl_Interp *interp, /* The interpreter this menu lives in */ TkMenu *menuPtr, /* The menu we are posting */ int x, /* The global x-coordinate of the top, left- - * hand corner of where the menu is supposed - * to be posted. */ + * hand corner of where the menu is supposed + * to be posted. */ int y) /* The global y-coordinate */ { MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl; long popUpResult; int result; - int oldMode; - if (inPostMenu) { - Tcl_AppendResult(interp, - "Cannot call post menu while already posting menu", - (char *) NULL); - result = TCL_ERROR; + if (inPostMenu > 0) { + Tcl_AppendResult(interp, + "Cannot call post menu while already posting menu", NULL); + result = TCL_ERROR; } else { - short menuID; + short menuID; Window window; int oldWidth = menuPtr->totalWidth; - Tk_Window parentWindow = Tk_Parent(menuPtr->tkwin); - - inPostMenu++; - - result = TkPreprocessMenu(menuPtr); - if (result != TCL_OK) { - inPostMenu--; - return result; - } - - /* - * The post commands could have deleted the menu, which means - * we are dead and should go away. - */ - - if (menuPtr->tkwin == NULL) { - inPostMenu--; - return TCL_OK; - } - - CompleteIdlers(menuPtr); - if (menuBarFlags & MENUBAR_REDRAW_PENDING) { - Tcl_CancelIdleCall(DrawMenuBarWhenIdle, (ClientData *) NULL); - DrawMenuBarWhenIdle((ClientData *) NULL); - } - - if (NULL == parentWindow) { - tearoffStruct.excludeRect.top = tearoffStruct.excludeRect.left - = tearoffStruct.excludeRect.bottom - = tearoffStruct.excludeRect.right = SHRT_MAX; - } else { - int left, top; - - Tk_GetRootCoords(parentWindow, &left, &top); - tearoffStruct.excludeRect.left = left; - tearoffStruct.excludeRect.top = top; - tearoffStruct.excludeRect.right = left + Tk_Width(parentWindow); - tearoffStruct.excludeRect.bottom = top + Tk_Height(parentWindow); - if (Tk_Class(parentWindow) == Tk_GetUid("Menubutton")) { - TkWindow *parentWinPtr = (TkWindow *) parentWindow; - TkMenuButton *mbPtr = - (TkMenuButton *) parentWinPtr->instanceData; - int menuButtonWidth = Tk_Width(parentWindow) - - 2 * (mbPtr->highlightWidth + mbPtr->borderWidth + 1); - menuPtr->totalWidth = menuButtonWidth > menuPtr->totalWidth - ? menuButtonWidth : menuPtr->totalWidth; - } + + inPostMenu++; + result = TkPreprocessMenu(menuPtr); + /* + * The post commands could have deleted the menu, which means + * we are dead and should go away. + */ + + if (result != TCL_OK || !menuPtr->tkwin) { + goto endPostMenu; + } + + CompleteIdlers(menuPtr); + if (menuBarFlags & MENUBAR_REDRAW_PENDING) { + Tcl_CancelIdleCall(DrawMenuBarWhenIdle, NULL); + DrawMenuBarWhenIdle(NULL); } - - InsertMenu(macMenuHdl, -1); - RecursivelyInsertMenu(menuPtr); - CountMenuItems(macMenuHdl); - - oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - popUpResult = PopUpMenuSelect(macMenuHdl, y, x, menuPtr->active); - Tcl_SetServiceMode(oldMode); + TkMacOSXTrackingLoop(1); + popUpResult = PopUpMenuSelect(macMenuHdl, y, x, menuPtr->active); + TkMacOSXTrackingLoop(0); menuPtr->totalWidth = oldWidth; - RecursivelyDeleteMenu(menuPtr); - DeleteMenu(GetMenuID(macMenuHdl)); - + /* * Simulate the mouse up. */ - + window = Tk_WindowId(menuPtr->tkwin); TkGenerateButtonEventForXPointer(window); - + /* * Dispatch the command. */ - + menuID = HiWord(popUpResult); if (menuID != 0) { result = TkMacOSXDispatchMenuEvent(menuID, LoWord(popUpResult)); - } else { - TkMacOSXHandleTearoffMenu(); - result = TCL_OK; } - /* - * Be careful, here. The command executed in handling the menu event - * could destroy the window. Don't try to do anything with it then. - */ - - if (menuPtr->tkwin) { - InvalidateMDEFRgns(); - RecursivelyClearActiveMenu(menuPtr); - } +endPostMenu: inPostMenu--; } return result; @@ -1535,15 +1611,17 @@ TkpMenuNewEntry( EntryGeometry *geometryPtr = (EntryGeometry *) ckalloc(sizeof(EntryGeometry)); TkMenu *menuPtr = mePtr->menuPtr; - + geometryPtr->accelTextStart = 0; geometryPtr->accelTextWidth = 0; geometryPtr->nonAccelMargin = 0; geometryPtr->modifierWidth = 0; + geometryPtr->modifierNum = 0; + geometryPtr->accelGlyph = 0; mePtr->platformEntryData = (TkMenuPlatformEntryData) geometryPtr; if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) { - menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr); + menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; + Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr); } return TCL_OK; } @@ -1551,12 +1629,11 @@ TkpMenuNewEntry( /* *---------------------------------------------------------------------- * - * * Tk_MacOSXTurnOffMenus -- * - * Turns off all the menu drawing code. This is more than just disabling - * the "menu" command, this means that Tk will NEVER touch the menubar. - * It is needed in the Plugin, where Tk does not own the menubar. + * Turns off all the menu drawing code. This is more than just disabling + * the "menu" command, this means that Tk will NEVER touch the menubar. + * It is needed in the Plugin, where Tk does not own the menubar. * * Results: * None. @@ -1568,7 +1645,7 @@ TkpMenuNewEntry( */ void -Tk_MacOSXTurnOffMenus() +Tk_MacOSXTurnOffMenus(void) { gNoTkMenus = 1; } @@ -1576,7 +1653,6 @@ Tk_MacOSXTurnOffMenus() /* *---------------------------------------------------------------------- * - * * DrawMenuBarWhenIdle -- * * Update the menu bar next time there is an idle event. @@ -1590,248 +1666,229 @@ Tk_MacOSXTurnOffMenus() *---------------------------------------------------------------------- */ -static void +void DrawMenuBarWhenIdle( ClientData clientData) /* ignored here */ { TkMenuReferences *menuRefPtr; - TkMenu *appleMenuPtr, *helpMenuPtr; + TkMenu *appleMenuPtr, *helpMenuPtr, *menuBarPtr; MenuHandle macMenuHdl; Tcl_HashEntry *hashEntryPtr; - + /* * If we have been turned off, exit. */ - + if (gNoTkMenus) { - return; + return; } - + /* * We need to clear the apple and help menus of any extra items. */ - + if (currentAppleMenuID != 0) { - hashEntryPtr = Tcl_FindHashEntry(&commandTable, - (char *) ((int)currentAppleMenuID)); - appleMenuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); - TkpDestroyMenu(appleMenuPtr); - TkpNewMenu(appleMenuPtr); - appleMenuPtr->menuFlags &= ~MENU_APPLE_MENU; - appleMenuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, - (ClientData) appleMenuPtr); + hashEntryPtr = Tcl_FindHashEntry(&commandTable, + (char*)(intptr_t)currentAppleMenuID); + appleMenuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); + TkpDestroyMenu(appleMenuPtr); + TkpNewMenu(appleMenuPtr); + appleMenuPtr->menuFlags &= ~MENU_APPLE_MENU; + appleMenuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; + Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) appleMenuPtr); } if (currentHelpMenuID != 0) { - hashEntryPtr = Tcl_FindHashEntry(&commandTable, - (char *) ((int)currentHelpMenuID)); - helpMenuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); - TkpDestroyMenu(helpMenuPtr); - TkpNewMenu(helpMenuPtr); - helpMenuPtr->menuFlags &= ~MENU_HELP_MENU; - helpMenuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, - (ClientData) helpMenuPtr); + hashEntryPtr = Tcl_FindHashEntry(&commandTable, + (char*)(intptr_t)currentHelpMenuID); + helpMenuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); + TkpDestroyMenu(helpMenuPtr); + TkpNewMenu(helpMenuPtr); + helpMenuPtr->menuFlags &= ~MENU_HELP_MENU; + helpMenuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; + Tcl_DoWhenIdle(ReconfigureMacintoshMenu, + (ClientData) helpMenuPtr); } - + /* * We need to find the clone of this menu that is the menubar. - * Once we do that, for every cascade in the menu, we need to + * Once we do that, for every cascade in the menu, we need to * insert the Mac menu in the Mac menubar. Finally, we need * to redraw the menubar. */ menuRefPtr = NULL; if (currentMenuBarName != NULL) { - menuRefPtr = TkFindMenuReferences(currentMenuBarInterp, - currentMenuBarName); + menuRefPtr = TkFindMenuReferences(currentMenuBarInterp, + currentMenuBarName); } - if (menuRefPtr != NULL) { - TkMenu *menuPtr, *menuBarPtr; - TkMenu *cascadeMenuPtr; - char *appleMenuName, *helpMenuName; - int appleIndex = -1, helpIndex = -1; - int i; - - menuPtr = menuRefPtr->menuPtr; - if (menuPtr != NULL) { - TkMenuReferences *specialMenuRefPtr; - TkMenuEntry *specialEntryPtr; - - appleMenuName = ckalloc(strlen(currentMenuBarName) - + 1 + strlen(".apple") + 1); - sprintf(appleMenuName, "%s.apple", - Tk_PathName(menuPtr->tkwin)); - specialMenuRefPtr = TkFindMenuReferences(currentMenuBarInterp, - appleMenuName); - if ((specialMenuRefPtr != NULL) - && (specialMenuRefPtr->menuPtr != NULL)) { - for (specialEntryPtr - = specialMenuRefPtr->parentEntryPtr; - specialEntryPtr != NULL; - specialEntryPtr - = specialEntryPtr->nextCascadePtr) { + if (menuRefPtr) { + TkMenu *menuPtr; + TkMenu *cascadeMenuPtr; + char *appleMenuName, *helpMenuName; + int appleIndex = -1, helpIndex = -1, i; + + menuPtr = menuRefPtr->menuPtr; + if (menuPtr != NULL) { + TkMenuReferences *specialMenuRefPtr; + TkMenuEntry *specialEntryPtr; + + appleMenuName = ckalloc(strlen(currentMenuBarName) + 1 + + strlen(".apple") + 1); + sprintf(appleMenuName, "%s.apple", Tk_PathName(menuPtr->tkwin)); + specialMenuRefPtr = TkFindMenuReferences(currentMenuBarInterp, + appleMenuName); + if ((specialMenuRefPtr != NULL) + && (specialMenuRefPtr->menuPtr != NULL)) { + for (specialEntryPtr = specialMenuRefPtr->parentEntryPtr; + specialEntryPtr != NULL; + specialEntryPtr = specialEntryPtr->nextCascadePtr) { if (specialEntryPtr->menuPtr == menuPtr) { - appleIndex = specialEntryPtr->index; - break; + appleIndex = specialEntryPtr->index; + break; } } - } - ckfree(appleMenuName); - - helpMenuName = ckalloc(strlen(currentMenuBarName) - + 1 + strlen(".help") + 1); - sprintf(helpMenuName, "%s.help", - Tk_PathName(menuPtr->tkwin)); - specialMenuRefPtr = TkFindMenuReferences(currentMenuBarInterp, - helpMenuName); - if ((specialMenuRefPtr != NULL) - && (specialMenuRefPtr->menuPtr != NULL)) { - for (specialEntryPtr - = specialMenuRefPtr->parentEntryPtr; - specialEntryPtr != NULL; - specialEntryPtr - = specialEntryPtr->nextCascadePtr) { + } + ckfree(appleMenuName); + + helpMenuName = ckalloc(strlen(currentMenuBarName) + 1 + + strlen(".help") + 1); + sprintf(helpMenuName, "%s.help", Tk_PathName(menuPtr->tkwin)); + specialMenuRefPtr = TkFindMenuReferences(currentMenuBarInterp, + helpMenuName); + if ((specialMenuRefPtr != NULL) + && (specialMenuRefPtr->menuPtr != NULL)) { + for (specialEntryPtr = specialMenuRefPtr->parentEntryPtr; + specialEntryPtr != NULL; + specialEntryPtr = specialEntryPtr->nextCascadePtr) { if (specialEntryPtr->menuPtr == menuPtr) { - helpIndex = specialEntryPtr->index; - break; + helpIndex = specialEntryPtr->index; + break; } } } - ckfree(helpMenuName); - - } - - for (menuBarPtr = menuPtr; - (menuBarPtr != NULL) - && (menuBarPtr->menuType != MENUBAR); - menuBarPtr = menuBarPtr->nextInstancePtr) { - - /* - * Null loop body. - */ - - } - - if (menuBarPtr == NULL) { - SetDefaultMenubar(); - } else { + ckfree(helpMenuName); + } + + for (menuBarPtr = menuPtr; + (menuBarPtr != NULL) && (menuBarPtr->menuType != MENUBAR); + menuBarPtr = menuBarPtr->nextInstancePtr) { + /* + * Null loop body. + */ + } + + if (menuBarPtr) { if (menuBarPtr->tearoff != menuPtr->tearoff) { - if (menuBarPtr->tearoff) { - appleIndex = (-1 == appleIndex) ? appleIndex - : appleIndex + 1; - helpIndex = (-1 == helpIndex) ? helpIndex - : helpIndex + 1; - } else { - appleIndex = (-1 == appleIndex) ? appleIndex - : appleIndex - 1; - helpIndex = (-1 == helpIndex) ? helpIndex - : helpIndex - 1; - } + if (menuBarPtr->tearoff) { + appleIndex = (-1 == appleIndex) ? appleIndex + : appleIndex + 1; + helpIndex = (-1 == helpIndex) ? helpIndex + : helpIndex + 1; + } else { + appleIndex = (-1 == appleIndex) ? appleIndex + : appleIndex - 1; + helpIndex = (-1 == helpIndex) ? helpIndex + : helpIndex - 1; + } } ClearMenuBar(); - + if (appleIndex == -1) { - InsertMenu(tkAppleMenu, 0); - currentAppleMenuID = 0; + InsertMenu(tkAppleMenu, 0); + currentAppleMenuID = 0; tkCurrentAppleMenu = tkAppleMenu; } else { - short appleID; - appleMenuPtr = menuBarPtr->entries[appleIndex] - ->childMenuRefPtr->menuPtr; + short appleID; + + appleMenuPtr = menuBarPtr->entries[appleIndex] + ->childMenuRefPtr->menuPtr; TkpDestroyMenu(appleMenuPtr); - TkMacOSXGetNewMenuID(appleMenuPtr->interp, appleMenuPtr, 0, - &appleID); - macMenuHdl = NewMenu(appleID, "\p\024"); - appleMenuPtr->platformData = - (TkMenuPlatformData) ckalloc(sizeof(MacMenu)); - ((MacMenu *)appleMenuPtr->platformData)->menuHdl - = macMenuHdl; - SetRect(&((MacMenu *) appleMenuPtr->platformData)->menuRect, - 0, 0, 0, 0); - appleMenuPtr->menuFlags |= MENU_APPLE_MENU; - if (!(appleMenuPtr->menuFlags - & MENU_RECONFIGURE_PENDING)) { - appleMenuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, - (ClientData) appleMenuPtr); - } - InsertMenu(macMenuHdl, 0); - RecursivelyInsertMenu(appleMenuPtr); - currentAppleMenuID = appleID; + TkMacOSXGetNewMenuID(appleMenuPtr->interp, appleMenuPtr, 0, + &appleID); + macMenuHdl = NewMenu(appleID, "\p\024"); + appleMenuPtr->platformData = + (TkMenuPlatformData) ckalloc(sizeof(MacMenu)); + ((MacMenu *)appleMenuPtr->platformData)->menuHdl + = macMenuHdl; + appleMenuPtr->menuFlags |= MENU_APPLE_MENU; + if (!(appleMenuPtr->menuFlags + & MENU_RECONFIGURE_PENDING)) { + appleMenuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; + Tcl_DoWhenIdle(ReconfigureMacintoshMenu, + (ClientData) appleMenuPtr); + } + InsertMenu(macMenuHdl, 0); + RecursivelyInsertMenu(appleMenuPtr); + currentAppleMenuID = appleID; tkCurrentAppleMenu = macMenuHdl; } if (helpIndex == -1) { - currentHelpMenuID = 0; + currentHelpMenuID = 0; } - + for (i = 0; i < menuBarPtr->numEntries; i++) { - if (i == appleIndex) { - if (menuBarPtr->entries[i]->state == ENTRY_DISABLED) { - DisableMenuItem(((MacMenu *) menuBarPtr->entries[i] - ->childMenuRefPtr->menuPtr - ->platformData)->menuHdl, - 0); - } else { - EnableMenuItem(((MacMenu *) menuBarPtr->entries[i] - ->childMenuRefPtr->menuPtr - ->platformData)->menuHdl, - 0); + if (i == appleIndex) { + if (menuBarPtr->entries[i]->state == ENTRY_DISABLED) { + DisableMenuItem(((MacMenu *) menuBarPtr->entries[i] + ->childMenuRefPtr->menuPtr + ->platformData)->menuHdl, 0); + } else { + EnableMenuItem(((MacMenu *) menuBarPtr->entries[i] + ->childMenuRefPtr->menuPtr + ->platformData)->menuHdl, 0); + } + continue; + } else if (i == helpIndex) { + TkMenu *helpMenuPtr = menuBarPtr->entries[i] + ->childMenuRefPtr->menuPtr; + + if (helpMenuPtr == NULL) { + continue; + } + helpMenuPtr->menuFlags |= MENU_HELP_MENU; + if (!(helpMenuPtr->menuFlags + & MENU_RECONFIGURE_PENDING)) { + helpMenuPtr->menuFlags + |= MENU_RECONFIGURE_PENDING; + Tcl_DoWhenIdle(ReconfigureMacintoshMenu, + (ClientData) helpMenuPtr); } - continue; - } else if (i == helpIndex) { - TkMenu *helpMenuPtr = menuBarPtr->entries[i] - ->childMenuRefPtr->menuPtr; - - if (helpMenuPtr == NULL) { - continue; - } - helpMenuPtr->menuFlags |= MENU_HELP_MENU; - if (!(helpMenuPtr->menuFlags - & MENU_RECONFIGURE_PENDING)) { - helpMenuPtr->menuFlags - |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, - (ClientData) helpMenuPtr); - } - macMenuHdl = - ((MacMenu *) helpMenuPtr->platformData)->menuHdl; - currentHelpMenuID = GetMenuID(macMenuHdl); - } else if (menuBarPtr->entries[i]->type - == CASCADE_ENTRY) { - if ((menuBarPtr->entries[i]->childMenuRefPtr != NULL) - && menuBarPtr->entries[i]->childMenuRefPtr + macMenuHdl = + ((MacMenu *) helpMenuPtr->platformData)->menuHdl; + currentHelpMenuID = GetMenuID(macMenuHdl); + } else if (menuBarPtr->entries[i]->type + == CASCADE_ENTRY) { + if ((menuBarPtr->entries[i]->childMenuRefPtr != NULL) + && menuBarPtr->entries[i]->childMenuRefPtr ->menuPtr != NULL) { - cascadeMenuPtr = menuBarPtr->entries[i] - ->childMenuRefPtr->menuPtr; - macMenuHdl = ((MacMenu *) cascadeMenuPtr - ->platformData)->menuHdl; - DeleteMenu(GetMenuID(macMenuHdl)); - InsertMenu(macMenuHdl, 0); - RecursivelyInsertMenu(cascadeMenuPtr); - if (menuBarPtr->entries[i]->state == ENTRY_DISABLED) { - DisableMenuItem(((MacMenu *) menuBarPtr->entries[i] - ->childMenuRefPtr->menuPtr - ->platformData)->menuHdl, - 0); - } else { - EnableMenuItem(((MacMenu *) menuBarPtr->entries[i] - ->childMenuRefPtr->menuPtr - ->platformData)->menuHdl, - 0); - } - } - } + cascadeMenuPtr = menuBarPtr->entries[i] + ->childMenuRefPtr->menuPtr; + macMenuHdl = ((MacMenu *) cascadeMenuPtr + ->platformData)->menuHdl; + DeleteMenu(GetMenuID(macMenuHdl)); + InsertMenu(macMenuHdl, 0); + RecursivelyInsertMenu(cascadeMenuPtr); + if (menuBarPtr->entries[i]->state == ENTRY_DISABLED) { + DisableMenuItem(((MacMenu *) menuBarPtr->entries[i] + ->childMenuRefPtr->menuPtr + ->platformData)->menuHdl, 0); + } else { + EnableMenuItem(((MacMenu *) menuBarPtr->entries[i] + ->childMenuRefPtr->menuPtr + ->platformData)->menuHdl, 0); + } + } + } } } - } else { - SetDefaultMenubar(); + } + if (!menuRefPtr || !menuBarPtr) { + SetDefaultMenubar(); } DrawMenuBar(); menuBarFlags &= ~MENUBAR_REDRAW_PENDING; } - /* *---------------------------------------------------------------------- @@ -1840,7 +1897,6 @@ DrawMenuBarWhenIdle( * * Puts all of the cascades of this menu in the Mac hierarchical list. * - * * Results: * None. * @@ -1850,27 +1906,26 @@ DrawMenuBarWhenIdle( *---------------------------------------------------------------------- */ -static void +void RecursivelyInsertMenu( TkMenu *menuPtr) /* All of the cascade items in this menu - * will be inserted into the mac menubar. */ + * will be inserted into the mac menubar. */ { int i; TkMenu *cascadeMenuPtr; MenuHandle macMenuHdl; - + for (i = 0; i < menuPtr->numEntries; i++) { - if (menuPtr->entries[i]->type == CASCADE_ENTRY) { - if ((menuPtr->entries[i]->childMenuRefPtr != NULL) - && (menuPtr->entries[i]->childMenuRefPtr->menuPtr - != NULL)) { - cascadeMenuPtr = menuPtr->entries[i]->childMenuRefPtr->menuPtr; - macMenuHdl = - ((MacMenu *) cascadeMenuPtr->platformData)->menuHdl; - InsertMenu(macMenuHdl, -1); - RecursivelyInsertMenu(cascadeMenuPtr); + if (menuPtr->entries[i]->type == CASCADE_ENTRY) { + if ((menuPtr->entries[i]->childMenuRefPtr != NULL) && + (menuPtr->entries[i]->childMenuRefPtr->menuPtr != NULL)) { + cascadeMenuPtr = menuPtr->entries[i]->childMenuRefPtr->menuPtr; + macMenuHdl = + ((MacMenu *) cascadeMenuPtr->platformData)->menuHdl; + InsertMenu(macMenuHdl, -1); + RecursivelyInsertMenu(cascadeMenuPtr); } - } + } } } @@ -1882,7 +1937,6 @@ RecursivelyInsertMenu( * Takes all of the cascades of this menu out of the Mac hierarchical * list. * - * * Results: * None. * @@ -1892,27 +1946,26 @@ RecursivelyInsertMenu( *---------------------------------------------------------------------- */ -static void +void RecursivelyDeleteMenu( TkMenu *menuPtr) /* All of the cascade items in this menu - * will be inserted into the mac menubar. */ + * will be deleted from the mac menubar. */ { int i; TkMenu *cascadeMenuPtr; MenuHandle macMenuHdl; - + for (i = 0; i < menuPtr->numEntries; i++) { - if (menuPtr->entries[i]->type == CASCADE_ENTRY) { - if ((menuPtr->entries[i]->childMenuRefPtr != NULL) - && (menuPtr->entries[i]->childMenuRefPtr->menuPtr - != NULL)) { - cascadeMenuPtr = menuPtr->entries[i]->childMenuRefPtr->menuPtr; - macMenuHdl = - ((MacMenu *) cascadeMenuPtr->platformData)->menuHdl; - DeleteMenu(GetMenuID(macMenuHdl)); - RecursivelyInsertMenu(cascadeMenuPtr); + if (menuPtr->entries[i]->type == CASCADE_ENTRY) { + if ((menuPtr->entries[i]->childMenuRefPtr != NULL) && + (menuPtr->entries[i]->childMenuRefPtr->menuPtr != NULL)) { + cascadeMenuPtr = menuPtr->entries[i]->childMenuRefPtr->menuPtr; + macMenuHdl = + ((MacMenu *) cascadeMenuPtr->platformData)->menuHdl; + DeleteMenu(GetMenuID(macMenuHdl)); + RecursivelyDeleteMenu(cascadeMenuPtr); } - } + } } } @@ -1932,12 +1985,12 @@ RecursivelyDeleteMenu( *---------------------------------------------------------------------- */ -static void -SetDefaultMenubar() +void +SetDefaultMenubar(void) { if (currentMenuBarName != NULL) { - ckfree(currentMenuBarName); - currentMenuBarName = NULL; + ckfree(currentMenuBarName); + currentMenuBarName = NULL; } currentMenuBarOwner = NULL; ClearMenuBar(); @@ -1945,8 +1998,8 @@ SetDefaultMenubar() InsertMenu(tkFileMenu, 0); InsertMenu(tkEditMenu, 0); if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) { - Tcl_DoWhenIdle(DrawMenuBarWhenIdle, (ClientData *) NULL); - menuBarFlags |= MENUBAR_REDRAW_PENDING; + Tcl_DoWhenIdle(DrawMenuBarWhenIdle, NULL); + menuBarFlags |= MENUBAR_REDRAW_PENDING; } } @@ -1972,80 +2025,77 @@ TkpSetMainMenubar( Tcl_Interp *interp, /* The interpreter of the application */ Tk_Window tkwin, /* The frame we are setting up */ char *menuName) /* The name of the menu to put in front. - * If NULL, use the default menu bar. - */ + * If NULL, use the default menu bar. + */ { TkWindow *winPtr = (TkWindow *) tkwin; - CGrafPtr winPort; + CGrafPtr winPort; WindowRef macWindowPtr; WindowRef frontNonFloating; winPort = TkMacOSXGetDrawablePort(winPtr->window); if (!winPort) { - return; + return; } macWindowPtr = GetWindowFromPort(winPort); - - frontNonFloating = ActiveNonFloatingWindow(); + + frontNonFloating = ActiveNonFloatingWindow(); if ((macWindowPtr == NULL) || (macWindowPtr != frontNonFloating)) { - return; + return; } - if ((currentMenuBarInterp != interp) - || (currentMenuBarOwner != tkwin) - || (currentMenuBarName == NULL) - || (menuName == NULL) - || (strcmp(menuName, currentMenuBarName) != 0)) { + if ((currentMenuBarInterp != interp) || (currentMenuBarOwner != tkwin) + || (currentMenuBarName == NULL) || (menuName == NULL) + || (strcmp(menuName, currentMenuBarName) != 0)) { Tk_Window searchWindow; - TopLevelMenubarList *listPtr; - - if (currentMenuBarName != NULL) { - ckfree(currentMenuBarName); - } + TopLevelMenubarList *listPtr; + + if (currentMenuBarName != NULL) { + ckfree(currentMenuBarName); + } if (menuName == NULL) { searchWindow = tkwin; if (strcmp(Tk_Class(searchWindow), "Menu") == 0) { - TkMenuReferences *menuRefPtr; - - menuRefPtr = TkFindMenuReferences(interp, Tk_PathName(tkwin)); - if (menuRefPtr != NULL) { - TkMenu *menuPtr = menuRefPtr->menuPtr; - if (menuPtr != NULL) { - menuPtr = menuPtr->masterMenuPtr; - searchWindow = menuPtr->tkwin; - } - } - } + TkMenuReferences *menuRefPtr; + + menuRefPtr = TkFindMenuReferences(interp, Tk_PathName(tkwin)); + if (menuRefPtr != NULL) { + TkMenu *menuPtr = menuRefPtr->menuPtr; + + if (menuPtr != NULL) { + searchWindow = menuPtr->masterMenuPtr->tkwin; + } + } + } for (; searchWindow != NULL; searchWindow = Tk_Parent(searchWindow)) { - - for (listPtr = windowListPtr; listPtr != NULL; - listPtr = listPtr->nextPtr) { - if (listPtr->tkwin == searchWindow) { - break; - } - } - if (listPtr != NULL) { - menuName = Tk_PathName(listPtr->menuPtr->masterMenuPtr - ->tkwin); - break; - } + for (listPtr = windowListPtr; listPtr != NULL; + listPtr = listPtr->nextPtr) { + if (listPtr->tkwin == searchWindow) { + break; + } + } + if (listPtr != NULL) { + menuName = Tk_PathName( + listPtr->menuPtr->masterMenuPtr->tkwin); + break; + } } } - + if (menuName == NULL) { currentMenuBarName = NULL; - } else { - currentMenuBarName = ckalloc(strlen(menuName) + 1); + } else { + currentMenuBarName = ckalloc(strlen(menuName) + 1); strcpy(currentMenuBarName, menuName); - } - currentMenuBarOwner = tkwin; - currentMenuBarInterp = interp; + } + currentMenuBarOwner = tkwin; + currentMenuBarInterp = interp; } if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) { - Tcl_DoWhenIdle(DrawMenuBarWhenIdle, (ClientData *) NULL); - menuBarFlags |= MENUBAR_REDRAW_PENDING; + Tcl_DoWhenIdle(DrawMenuBarWhenIdle, NULL); + menuBarFlags |= MENUBAR_REDRAW_PENDING; } } @@ -2072,45 +2122,44 @@ TkpSetWindowMenuBar( TkMenu *menuPtr) /* The menu we are setting */ { TopLevelMenubarList *listPtr, *prevPtr; - + /* * Remove any existing reference to this window. */ - - for (prevPtr = NULL, listPtr = windowListPtr; - listPtr != NULL; - prevPtr = listPtr, listPtr = listPtr->nextPtr) { + + for (prevPtr = NULL, listPtr = windowListPtr; + listPtr != NULL; + prevPtr = listPtr, listPtr = listPtr->nextPtr) { if (listPtr->tkwin == tkwin) { break; - } + } } - + if (listPtr != NULL) { - if (prevPtr != NULL) { - prevPtr->nextPtr = listPtr->nextPtr; - } else { - windowListPtr = listPtr->nextPtr; - } - ckfree((char *) listPtr); + if (prevPtr != NULL) { + prevPtr->nextPtr = listPtr->nextPtr; + } else { + windowListPtr = listPtr->nextPtr; + } + ckfree((char *) listPtr); } - + if (menuPtr != NULL) { - listPtr = (TopLevelMenubarList *) ckalloc(sizeof(TopLevelMenubarList)); - listPtr->nextPtr = windowListPtr; - windowListPtr = listPtr; - listPtr->tkwin = tkwin; - listPtr->menuPtr = menuPtr; + listPtr = (TopLevelMenubarList *) ckalloc(sizeof(TopLevelMenubarList)); + listPtr->nextPtr = windowListPtr; + windowListPtr = listPtr; + listPtr->tkwin = tkwin; + listPtr->menuPtr = menuPtr; } } - -static void + /* *---------------------------------------------------------------------- * * EventuallyInvokeMenu -- * * This IdleTime callback actually invokes the menu command - * scheduled in TkMacOSXDispatchMenuEvent. + * scheduled in TkMacOSXDispatchMenuEvent. * * Results: * None. @@ -2121,25 +2170,31 @@ static void *---------------------------------------------------------------------- */ -EventuallyInvokeMenu (ClientData data) +void +EventuallyInvokeMenu ( + ClientData data) { - struct MenuCommandHandlerData *realData - = (struct MenuCommandHandlerData *) data; + struct MenuCommandHandlerData *realData = + (struct MenuCommandHandlerData *) data; int code; code = TkInvokeMenu(realData->menuPtr->interp, realData->menuPtr, - realData->index); - - if (code != TCL_OK && code != TCL_CONTINUE - && code != TCL_BREAK) { - Tcl_AddErrorInfo(realData->menuPtr->interp, "\n (menu invoke)"); - Tcl_BackgroundError(realData->menuPtr->interp); + realData->index); + + if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) { + Tcl_AddErrorInfo(realData->menuPtr->interp, "\n (menu invoke)"); + Tcl_BackgroundError(realData->menuPtr->interp); + } + + if (realData->menuPtr->tkwin) { + RecursivelyClearActiveMenu(realData->menuPtr); } - + TkMacOSXClearMenubarActive(); + Tcl_Release(realData->menuPtr->interp); Tcl_Release(realData->menuPtr); } - + /* *---------------------------------------------------------------------- * @@ -2159,64 +2214,69 @@ EventuallyInvokeMenu (ClientData data) int TkMacOSXDispatchMenuEvent( - int menuID, /* The menu id of the menu we are invoking */ - int index) /* The one-based index of the item that was - * selected. */ + int menuID, /* The menu id of the menu we are invoking */ + int index) /* The one-based index of the item that was + * selected. */ { int result = TCL_OK; + if (menuID != 0) { - if (menuID == kHMHelpMenuID) { - if (currentMenuBarOwner != NULL) { - TkMenuReferences *helpMenuRef; - char *helpMenuName = ckalloc(strlen(currentMenuBarName) - + strlen(".help") + 1); - sprintf(helpMenuName, "%s.help", currentMenuBarName); - helpMenuRef = TkFindMenuReferences(currentMenuBarInterp, - helpMenuName); - ckfree(helpMenuName); - if ((helpMenuRef != NULL) && (helpMenuRef->menuPtr != NULL)) { + if (menuID == kHMHelpMenuID) { + if (currentMenuBarOwner != NULL) { + TkMenuReferences *helpMenuRef; + char *helpMenuName = ckalloc(strlen(currentMenuBarName) + + strlen(".help") + 1); + + sprintf(helpMenuName, "%s.help", currentMenuBarName); + helpMenuRef = TkFindMenuReferences(currentMenuBarInterp, + helpMenuName); + ckfree(helpMenuName); + if ((helpMenuRef != NULL) && (helpMenuRef->menuPtr != NULL)) { MenuRef outHelpMenu; MenuItemIndex itemIndex; int newIndex; + HMGetHelpMenu(&outHelpMenu, &itemIndex); - newIndex = index - itemIndex; - result = TkInvokeMenu(currentMenuBarInterp, - helpMenuRef->menuPtr, newIndex); - } - } - } else { - Tcl_HashEntry *commandEntryPtr = - Tcl_FindHashEntry(&commandTable, (char *) ((int)menuID)); - if (commandEntryPtr != NULL) { - TkMenu *menuPtr = (TkMenu *) Tcl_GetHashValue(commandEntryPtr); - if ((currentAppleMenuID == menuID) - && (index > menuPtr->numEntries + 1)) { - /* - * We don't need to do anything here, the standard - * Application event handler will open the built-in - * Apple menu item for us. - */ - result = TCL_OK; - } else { - struct MenuCommandHandlerData *data - = (struct MenuCommandHandlerData *) - ckalloc(sizeof(struct MenuCommandHandlerData)); - Tcl_Preserve(menuPtr->interp); - Tcl_Preserve(menuPtr); - data->menuPtr = menuPtr; - data->index = index - 1; - Tcl_DoWhenIdle (EventuallyInvokeMenu, - (ClientData) data); - /* result = TkInvokeMenu(menuPtr->interp, menuPtr, index - 1); */ - } - } else { - return TCL_ERROR; - } + newIndex = index - itemIndex; + result = TkInvokeMenu(currentMenuBarInterp, + helpMenuRef->menuPtr, newIndex); + } + } + } else { + Tcl_HashEntry *commandEntryPtr = + Tcl_FindHashEntry(&commandTable, (char*)(intptr_t)menuID); + if (commandEntryPtr != NULL) { + TkMenu *menuPtr = (TkMenu *) Tcl_GetHashValue(commandEntryPtr); + + if ((currentAppleMenuID == menuID) + && (index > menuPtr->numEntries + 1)) { + /* + * We don't need to do anything here, the standard + * Application event handler will open the built-in + * Apple menu item for us. + */ + result = TCL_OK; + } else { + struct MenuCommandHandlerData *data + = (struct MenuCommandHandlerData *) + ckalloc(sizeof(struct MenuCommandHandlerData)); + + Tcl_Preserve(menuPtr->interp); + Tcl_Preserve(menuPtr); + data->menuPtr = menuPtr; + data->index = index - 1; + Tcl_DoWhenIdle(EventuallyInvokeMenu, + (ClientData) data); + /* result = TkInvokeMenu(menuPtr->interp, menuPtr, index - 1); */ + } + } else { + return TCL_ERROR; + } } } return result; } - + /* *---------------------------------------------------------------------- * @@ -2233,21 +2293,26 @@ TkMacOSXDispatchMenuEvent( *---------------------------------------------------------------------- */ -static void +void GetMenuIndicatorGeometry ( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* Precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* Precalculated font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ + TkMenu *menuPtr, /* The menu we are drawing */ + TkMenuEntry *mePtr, /* The entry we are measuring */ + Tk_Font tkfont, /* Precalculated font */ + const Tk_FontMetrics *fmPtr,/* Precalculated font metrics */ + int *widthPtr, /* The resulting width */ + int *heightPtr) /* The resulting height */ { - char markChar; - - *heightPtr = fmPtr->linespace; - - markChar = (char) FindMarkCharacter(mePtr); - *widthPtr = Tk_TextWidth(tkfont, &markChar, 1) + 4; + *heightPtr = fmPtr->linespace + menuItemExtraHeight; + if (IS_THEME_MENU_FONT(tkfont)) { + *widthPtr = menuMarkColumnWidth; + } else { + const char markChar = FindMarkCharacter(mePtr); + const char *markUtf = NULL; + int len; + + len = GetUtfMarkCharacter(markChar, &markUtf); + *widthPtr = Tk_TextWidth(tkfont, markUtf, len) + 2*menuMarkIndent; + } } /* @@ -2266,63 +2331,67 @@ GetMenuIndicatorGeometry ( *---------------------------------------------------------------------- */ -static void +void GetMenuAccelGeometry ( - TkMenu *menuPtr, /* The menu we are measuring */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int *modWidthPtr, /* The width of all of the key - * modifier symbols. */ - int *textWidthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ + TkMenu *menuPtr, /* The menu we are measuring */ + TkMenuEntry *mePtr, /* The entry we are measuring */ + Tk_Font tkfont, /* The precalculated font */ + const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ + int *modWidthPtr, /* The width of all of the key + * modifier symbols. */ + int *textWidthPtr, /* The resulting width */ + int *heightPtr) /* The resulting height */ { - *heightPtr = fmPtr->linespace; - *modWidthPtr = 0; - if (mePtr->type == CASCADE_ENTRY) { - *textWidthPtr = SICN_HEIGHT; - *modWidthPtr = Tk_TextWidth(tkfont, "W", 1); - } else if (0 == mePtr->accelLength) { - *textWidthPtr = 0; - } else { - char *accel = (mePtr->accelPtr == NULL) ? "" - : Tcl_GetStringFromObj(mePtr->accelPtr, NULL); - - if (NULL == GetResource('SICN', SICN_RESOURCE_NUMBER)) { - *textWidthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength); - } else { - int emWidth = Tk_TextWidth(tkfont, "W", 1) + 1; - if ((mePtr->entryFlags & ENTRY_ACCEL_MASK) == 0) { - int width = Tk_TextWidth(tkfont, accel, mePtr->accelLength); - *textWidthPtr = emWidth; - if (width < emWidth) { - *modWidthPtr = 0; - } else { - *modWidthPtr = width - emWidth; - } - } else { - int length = ((EntryGeometry *)mePtr->platformEntryData) - ->accelTextStart; - if (mePtr->entryFlags & ENTRY_CONTROL_ACCEL) { - *modWidthPtr += CONTROL_ICON_WIDTH; - } - if (mePtr->entryFlags & ENTRY_SHIFT_ACCEL) { - *modWidthPtr += SHIFT_ICON_WIDTH; - } - if (mePtr->entryFlags & ENTRY_OPTION_ACCEL) { - *modWidthPtr += OPTION_ICON_WIDTH; - } - if (mePtr->entryFlags & ENTRY_COMMAND_ACCEL) { - *modWidthPtr += COMMAND_ICON_WIDTH; - } - if (1 == (mePtr->accelLength - length)) { - *textWidthPtr = emWidth; - } else { - *textWidthPtr += Tk_TextWidth(tkfont, accel - + length, mePtr->accelLength - length); - } - } - } + *heightPtr = fmPtr->linespace + menuItemExtraHeight; + *modWidthPtr = menuSymbols[COMMAND_SYMBOL].width; + *textWidthPtr = 0; + if (mePtr->type != CASCADE_ENTRY && mePtr->accelLength > 0) { + const char *accel = (mePtr->accelPtr == NULL) ? "" + : Tcl_GetString(mePtr->accelPtr); + EntryGeometry *geometryPtr = (EntryGeometry*)mePtr->platformEntryData; + + if (IS_THEME_MENU_FONT(tkfont)) { + CFStringRef cfStr; + int width = 0; + int maxWidth = ((TkFont *)tkfont)->fm.maxWidth; + + if (geometryPtr->accelGlyph) { + cfStr = CFStringCreateWithBytes(NULL, + (UInt8*)&geometryPtr->accelGlyph, 1, + kTextEncodingMacKeyboardGlyphs, false); + if (cfStr) { + width = MeasureThemeText(cfStr, kThemeMenuItemCmdKeyFont); + CFRelease(cfStr); + } + } + if ((mePtr->entryFlags & ENTRY_ACCEL_MASK) == 0) { + if (!geometryPtr->accelGlyph) { + width = Tk_TextWidth(tkfont, accel, mePtr->accelLength); + } + *textWidthPtr = maxWidth; + if (width < maxWidth) { + *modWidthPtr = 0; + } else { + *modWidthPtr = width - maxWidth; + } + } else { + if (!geometryPtr->accelGlyph) { + width = Tk_TextWidth(tkfont, accel + + geometryPtr->accelTextStart, mePtr->accelLength - + geometryPtr->accelTextStart); + } + if (width < maxWidth) { + *textWidthPtr = maxWidth; + } else { + *textWidthPtr = width; + } + if (geometryPtr->modifierNum) { + *modWidthPtr = geometryPtr->modifierWidth; + } + } + } else { + *textWidthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength); + } } } @@ -2342,19 +2411,21 @@ GetMenuAccelGeometry ( *---------------------------------------------------------------------- */ -static void +void GetTearoffEntryGeometry ( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ + TkMenu *menuPtr, /* The menu we are drawing */ + TkMenuEntry *mePtr, /* The entry we are measuring */ + Tk_Font tkfont, /* The precalculated font */ + const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ + int *widthPtr, /* The resulting width */ + int *heightPtr) /* The resulting height */ { - if ((GetResource('MDEF', 591) == NULL) && - (menuPtr->menuType == MASTER_MENU)) { - *heightPtr = fmPtr->linespace; - *widthPtr = 0; +#ifdef USE_TK_MDEF + const int useMDEF = ((MacMenu *) menuPtr->platformData)->useMDEF; +#endif + if (useMDEF && menuPtr->menuType != TEAROFF_MENU) { + *heightPtr = fmPtr->linespace + menuItemExtraHeight; + *widthPtr = menuPtr->totalWidth; } else { *widthPtr = *heightPtr = 0; } @@ -2376,20 +2447,17 @@ GetTearoffEntryGeometry ( *---------------------------------------------------------------------- */ -static void +void GetMenuSeparatorGeometry( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalcualted font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ + TkMenu *menuPtr, /* The menu we are drawing */ + TkMenuEntry *mePtr, /* The entry we are measuring */ + Tk_Font tkfont, /* The precalculated font */ + const Tk_FontMetrics *fmPtr,/* The precalcualted font metrics */ + int *widthPtr, /* The resulting width */ + int *heightPtr) /* The resulting height */ { - SInt16 outHeight; - - GetThemeMenuSeparatorHeight(&outHeight); - *widthPtr = 0; - *heightPtr = outHeight; + *widthPtr = 0; + *heightPtr = menuSeparatorHeight; } /* @@ -2409,50 +2477,70 @@ GetMenuSeparatorGeometry( *---------------------------------------------------------------------- */ -static void +void DrawMenuEntryIndicator( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* The drawable we are drawing */ - GC gc, /* The GC we are drawing with */ - GC indicatorGC, /* The GC to use for the indicator */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int x, /* topleft hand corner of entry */ - int y, /* topleft hand corner of entry */ - int width, /* width of entry */ - int height) /* height of entry */ + TkMenu *menuPtr, /* The menu we are drawing */ + TkMenuEntry *mePtr, /* The entry we are drawing */ + Drawable d, /* The drawable we are drawing */ + GC gc, /* The GC we are drawing with */ + GC indicatorGC, /* The GC to use for the indicator */ + Tk_Font tkfont, /* The precalculated font */ + const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ + int x, /* topleft hand corner of entry */ + int y, /* topleft hand corner of entry */ + int width, /* width of entry */ + int height) /* height of entry */ { - if ((mePtr->type == CHECK_BUTTON_ENTRY) || - (mePtr->type == RADIO_BUTTON_ENTRY)) { - if (mePtr->indicatorOn - && (mePtr->entryFlags & ENTRY_SELECTED)) { - int baseline; - short markShort; - - baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; - GetItemMark(((MacMenu *) menuPtr->platformData)->menuHdl, - mePtr->index + 1, &markShort); - if (markShort != 0) { - char markChar; - char markCharUTF[TCL_UTF_MAX + 1]; - int dstWrote; - - markChar = (char) markShort; - /* - * Not sure if this is the correct encoding, but this function - * doesn't appear to be used at all in, since the Carbon Menus - * draw themselves - */ - Tcl_ExternalToUtf(NULL, NULL, &markChar, 1, 0, NULL, - markCharUTF, TCL_UTF_MAX + 1, NULL, &dstWrote, NULL); - Tk_DrawChars(menuPtr->display, d, gc, tkfont, markCharUTF, - dstWrote, x + 2, baseline); - } + if ((mePtr->type == CHECK_BUTTON_ENTRY) || + (mePtr->type == RADIO_BUTTON_ENTRY)) { + if (mePtr->indicatorOn && (mePtr->entryFlags & ENTRY_SELECTED)) { + short mark; + int baseline = y + (height + fmPtr->ascent - fmPtr->descent)/2; + + GetItemMark(((MacMenu *) menuPtr->platformData)->menuHdl, + mePtr->index + 1, &mark); + if (IS_THEME_MENU_FONT(tkfont)) { + ThemeFontID font = kThemeMenuItemMarkFont; + TextEncoding encoding = GetApplicationTextEncoding(); + CFStringRef cfStr; + ThemeDrawState drawState; + Rect bounds = {y, x + menuMarkIndent, y + height, x + width}; + + if (mark < kSpaceCharCode) { + font = kThemeMenuItemCmdKeyFont; + encoding = kTextEncodingMacKeyboardGlyphs; + } + switch (mePtr->state) { + case ENTRY_ACTIVE: + drawState = kThemeStatePressed; + break; + case ENTRY_DISABLED: + drawState = kThemeStateInactive; + break; + default: + drawState = kThemeStateActive; + break; + } + cfStr = CFStringCreateWithBytes(NULL, (UInt8*)&mark, 1, + encoding, false); + if (cfStr) { + DrawThemeText(d, gc, cfStr, font, drawState, &bounds, + baseline, teFlushDefault); + CFRelease(cfStr); + } + } else if (mark != 0) { + const char *markUtf = NULL; + int len; + + len = GetUtfMarkCharacter(mark, &markUtf); + Tk_DrawChars(menuPtr->display, d, gc, tkfont, markUtf, len, + x + menuMarkIndent, baseline); + } } - } + } } +#ifdef USE_TK_MDEF /* *---------------------------------------------------------------------- * @@ -2469,106 +2557,30 @@ DrawMenuEntryIndicator( * *---------------------------------------------------------------------- */ -static void +void DrawMenuBackground( + TkMenu *menuPtr, Rect *menuRectPtr, /* The menu rect */ - Drawable d, /* What we are drawing into */ - ThemeMenuType type /* Type of menu */ - ) -{ - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; - - destPort = TkMacOSXGetDrawablePort(d); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - DrawThemeMenuBackground (menuRectPtr, type); - SetGWorld(saveWorld, saveDevice); - return; -} - -/* - *---------------------------------------------------------------------- - * - * DrawSICN -- - * - * Given a resource id and an index, loads the appropriate SICN - * and draws it into a given drawable using the given gc. - * - * Results: - * Returns 1 if the SICN was found, 0 if not found. - * - * Side effects: - * Commands are output to X to display the menu in its - * current mode. - * - *---------------------------------------------------------------------- - */ -static int -DrawSICN( - int resourceID, /* The resource # of the SICN table */ - int index, /* The index into the SICN table of the - * icon we want. */ - Drawable d, /* What we are drawing into */ - GC gc, /* The GC to draw with */ - int x, /* The left hand coord of the SICN */ - int y) /* The top coord of the SICN */ + Drawable d) /* What we are drawing into */ { - Handle sicnHandle = (Handle) GetResource('SICN', SICN_RESOURCE_NUMBER); - - if (NULL == sicnHandle) { - return 0; - } else { - BitMap sicnBitmap; - Rect destRect; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; - const BitMap *destBitMap; - RGBColor origForeColor, origBackColor, foreColor, backColor; - - HLock(sicnHandle); - destPort = TkMacOSXGetDrawablePort(d); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - TkMacOSXSetUpGraphicsPort(gc, destPort); - GetForeColor(&origForeColor); - GetBackColor(&origBackColor); - - if (TkSetMacColor(gc->foreground, &foreColor)) { - RGBForeColor(&foreColor); - } - - if (TkSetMacColor(gc->background, &backColor)) { - RGBBackColor(&backColor); - } + Tk_3DBorder border; - SetRect(&destRect, x, y, x + SICN_HEIGHT, y + SICN_HEIGHT); - sicnBitmap.baseAddr = (Ptr) (*sicnHandle) + index * SICN_HEIGHT - * SICN_ROWS; - sicnBitmap.rowBytes = SICN_ROWS; - SetRect(&sicnBitmap.bounds, 0, 0, 16, 16); - destBitMap = GetPortBitMapForCopyBits(destPort); - CopyBits(&sicnBitmap, destBitMap, &sicnBitmap.bounds, &destRect, GetPortTextMode(destPort), NULL); - HUnlock(sicnHandle); - RGBForeColor(&origForeColor); - RGBBackColor(&origBackColor); - SetGWorld(saveWorld, saveDevice); - return 1; - } + EraseMenuBackground(((MacMenu *) menuPtr->platformData)->menuHdl, + menuRectPtr, ((MacDrawable*)d)->context); + border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); + Tk_Fill3DRectangle(menuPtr->tkwin, d, border, + menuRectPtr->left, menuRectPtr->top, + menuRectPtr->right - menuRectPtr->left, + menuRectPtr->bottom - menuRectPtr->top, 0, TK_RELIEF_FLAT); } +#endif /* USE_TK_MDEF */ /* *---------------------------------------------------------------------- * * DrawMenuEntryAccelerator -- * - * This procedure draws the accelerator part of a menu. We - * need to decide what to draw here. Should we replace strings - * like "Control", "Command", etc? + * This procedure draws the accelerator part of a menu. * * Results: * None. @@ -2580,79 +2592,80 @@ DrawSICN( *---------------------------------------------------------------------- */ -static void +void DrawMenuEntryAccelerator( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* The drawable we are drawing in */ - GC gc, /* The gc to draw into */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - Tk_3DBorder activeBorder, /* border for menu background */ - int x, /* The left side of the entry */ - int y, /* The top of the entry */ - int width, /* The width of the entry */ - int height, /* The height of the entry */ - int drawArrow) /* Whether or not to draw cascade arrow */ + TkMenu *menuPtr, /* The menu we are drawing */ + TkMenuEntry *mePtr, /* The entry we are drawing */ + Drawable d, /* The drawable we are drawing in */ + GC gc, /* The gc to draw into */ + Tk_Font tkfont, /* The precalculated font */ + const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ + Tk_3DBorder activeBorder, /* border for menu background */ + int x, /* The left side of the entry */ + int y, /* The top of the entry */ + int width, /* The width of the entry */ + int height, /* The height of the entry */ + int drawArrow) /* Whether or not to draw cascade arrow */ { - int activeBorderWidth; - - Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr, - &activeBorderWidth); - if (mePtr->type == CASCADE_ENTRY) { - /* - * Under Appearance, we let the Appearance Manager draw the icon - */ - - } else if (mePtr->accelLength != 0) { - int leftEdge = x + width; - int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; - char *accel; - - accel = Tcl_GetStringFromObj(mePtr->accelPtr, NULL); - - if (NULL == GetResource('SICN', SICN_RESOURCE_NUMBER)) { - leftEdge -= ((EntryGeometry *) mePtr->platformEntryData) - ->accelTextWidth; - Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel, - mePtr->accelLength, leftEdge, baseline); - } else { - EntryGeometry *geometryPtr = - (EntryGeometry *) mePtr->platformEntryData; - int length = mePtr->accelLength - geometryPtr->accelTextStart; - - leftEdge -= geometryPtr->accelTextWidth; - if ((mePtr->entryFlags & ENTRY_ACCEL_MASK) == 0) { - leftEdge -= geometryPtr->modifierWidth; - } - - Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel - + geometryPtr->accelTextStart, length, leftEdge, baseline); - - if (mePtr->entryFlags & ENTRY_COMMAND_ACCEL) { - leftEdge -= COMMAND_ICON_WIDTH; - DrawSICN(SICN_RESOURCE_NUMBER, COMMAND_ICON, d, gc, - leftEdge, (y + (height / 2)) - (SICN_HEIGHT / 2) - 1); + if (mePtr->type != CASCADE_ENTRY && mePtr->accelLength > 0) { + const char *accel = (mePtr->accelPtr == NULL) ? "" + : Tcl_GetString(mePtr->accelPtr); + EntryGeometry *geometryPtr = (EntryGeometry*)mePtr->platformEntryData; + int leftEdge = x + width - geometryPtr->accelTextWidth; + int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; + + if (IS_THEME_MENU_FONT(tkfont)) { + CFStringRef cfStr; + ThemeDrawState drawState; + + switch (mePtr->state) { + case ENTRY_ACTIVE: + drawState = kThemeStatePressed; + break; + case ENTRY_DISABLED: + drawState = kThemeStateInactive; + break; + default: + drawState = kThemeStateActive; + break; } - - if (mePtr->entryFlags & ENTRY_OPTION_ACCEL) { - leftEdge -= OPTION_ICON_WIDTH; - DrawSICN(SICN_RESOURCE_NUMBER, OPTION_ICON, d, gc, - leftEdge, (y + (height / 2)) - (SICN_HEIGHT / 2) - 1); + if ((mePtr->entryFlags & ENTRY_ACCEL_MASK) == 0) { + leftEdge -= geometryPtr->modifierWidth; } - - if (mePtr->entryFlags & ENTRY_SHIFT_ACCEL) { - leftEdge -= SHIFT_ICON_WIDTH; - DrawSICN(SICN_RESOURCE_NUMBER, SHIFT_ICON, d, gc, - leftEdge, (y + (height / 2)) - (SICN_HEIGHT / 2) - 1); + if (geometryPtr->accelGlyph) { + Rect bounds = {y, leftEdge, y + height, leftEdge + + geometryPtr->accelTextWidth}; + + cfStr = CFStringCreateWithBytes(NULL, + (UInt8*)&geometryPtr->accelGlyph, 1, + kTextEncodingMacKeyboardGlyphs, false); + if (cfStr) { + DrawThemeText(d, gc, cfStr, kThemeMenuItemCmdKeyFont, + drawState, &bounds, baseline, teFlushDefault); + CFRelease(cfStr); + } + } else { + Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel + + geometryPtr->accelTextStart, mePtr->accelLength - + geometryPtr->accelTextStart, leftEdge, baseline); } - - if (mePtr->entryFlags & ENTRY_CONTROL_ACCEL) { - leftEdge -= CONTROL_ICON_WIDTH; - DrawSICN(SICN_RESOURCE_NUMBER, CONTROL_ICON, d, gc, - leftEdge, (y + (height / 2)) - (SICN_HEIGHT / 2) - 1); + if (geometryPtr->modifierNum) { + Rect bounds = {y, leftEdge - geometryPtr->modifierWidth, + y + height, leftEdge}; + + cfStr = CFStringCreateWithCharacters(NULL, + geometryPtr->modifierUniChars, + geometryPtr->modifierNum); + if (cfStr) { + DrawThemeText(d, gc, cfStr, kThemeMenuItemCmdKeyFont, + drawState, &bounds, baseline, teFlushDefault); + CFRelease(cfStr); + } } - } + } else { + Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel, + mePtr->accelLength, leftEdge, baseline); + } } } @@ -2673,43 +2686,44 @@ DrawMenuEntryAccelerator( *---------------------------------------------------------------------- */ -static void +void DrawMenuSeparator( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* The drawable we are drawing into */ - GC gc, /* The gc we are drawing with */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int x, /* left coordinate of entry */ - int y, /* top coordinate of entry */ - int width, /* width of entry */ - int height) /* height of entry */ + TkMenu *menuPtr, /* The menu we are drawing */ + TkMenuEntry *mePtr, /* The entry we are drawing */ + Drawable d, /* The drawable we are drawing into */ + GC gc, /* The gc we are drawing with */ + Tk_Font tkfont, /* The precalculated font */ + const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ + int x, /* left coordinate of entry */ + int y, /* top coordinate of entry */ + int width, /* width of entry */ + int height) /* height of entry */ { - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + CGrafPtr destPort, savePort; + Boolean portChanged; Rect r; - + destPort = TkMacOSXGetDrawablePort(d); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); + portChanged = QDSwapPort(destPort, &savePort); TkMacOSXSetUpClippingRgn(d); r.top = y; r.left = x; r.bottom = y + height; r.right = x + width; - DrawThemeMenuSeparator(&r); + if (portChanged) { + QDSwapPort(savePort, NULL); + } } +#ifdef USE_TK_MDEF /* *---------------------------------------------------------------------- * - * AppearanceEntryDrawWrapper -- + * AppearanceEntryDrawWrapper -- * - * It routes to the Appearance Managers DrawThemeEntry, which will - * then call us back after setting up the drawing context. + * It routes to the Appearance Managers DrawThemeEntry, which will + * then call us back after setting up the drawing context. * * Results: * A menu entry is drawn @@ -2719,59 +2733,68 @@ DrawMenuSeparator( * *---------------------------------------------------------------------- */ -static void +void AppearanceEntryDrawWrapper( TkMenuEntry *mePtr, Rect *menuRectPtr, - MenuTrackingData *mtdPtr, + MenuTrackingData *mtdPtr, Drawable d, - Tk_FontMetrics *fmPtr, - Tk_Font tkfont, - int x, - int y, - int width, - int height) + Tk_FontMetrics *fmPtr, + Tk_Font tkfont, + int erase) { MenuEntryUserData meData; Rect itemRect; ThemeMenuState theState; ThemeMenuItemType theType; + Tk_FontMetrics entryMetrics; meData.mePtr = mePtr; meData.mdefDrawable = d; - meData.fmPtr = fmPtr; - meData.tkfont = tkfont; - - itemRect.top = y; - itemRect.left = x; - itemRect.bottom = itemRect.top + height; - itemRect.right = itemRect.left + width; - + if (mePtr->fontPtr == NULL) { + meData.fmPtr = fmPtr; + meData.tkfont = tkfont; + } else { + meData.tkfont = Tk_GetFontFromObj(mePtr->menuPtr->tkwin, + mePtr->fontPtr); + Tk_GetFontMetrics(meData.tkfont, &entryMetrics); + fmPtr = &entryMetrics; + } + itemRect.left = menuRectPtr->left + mePtr->x; + itemRect.top = mtdPtr->virtualMenuTop + mePtr->y; + itemRect.right = mePtr->entryFlags & ENTRY_LAST_COLUMN ? + menuRectPtr->right : itemRect.left + mePtr->width; + itemRect.bottom = itemRect.top + mePtr->height; + if (mePtr->state == ENTRY_ACTIVE) { - theState = kThemeMenuSelected; + theState = kThemeMenuSelected; } else if (mePtr->state == ENTRY_DISABLED) { - theState = kThemeMenuDisabled; + theState = kThemeMenuDisabled; } else { - theState = kThemeMenuActive; + theState = kThemeMenuActive; } - if (mePtr->type == CASCADE_ENTRY) { - theType = kThemeMenuItemHierarchical; + theType = kThemeMenuItemHierarchical; } else { - theType = kThemeMenuItemPlain; + theType = kThemeMenuItemPlain; + } + if (erase) { + DisableScreenUpdates(); + DrawMenuBackground(mePtr->menuPtr, &itemRect, d); + } + DrawThemeMenuItem(menuRectPtr, &itemRect, + mtdPtr->virtualMenuTop, mtdPtr->virtualMenuBottom, theState, + theType | kThemeMenuItemNoBackground, tkThemeMenuItemDrawingUPP, + (unsigned long) &meData); + if (erase) { + EnableScreenUpdates(); } - - DrawThemeMenuItem (menuRectPtr, &itemRect, - mtdPtr->virtualMenuTop, mtdPtr->virtualMenuBottom, theState, - theType, tkThemeMenuItemDrawingUPP, - (unsigned long) &meData); - } /* *---------------------------------------------------------------------- * - * ThemeMenuItemDrawingProc -- + * ThemeMenuItemDrawingProc -- * * This routine is called from the Appearance DrawThemeMenuEntry * @@ -2783,19 +2806,21 @@ AppearanceEntryDrawWrapper( * *---------------------------------------------------------------------- */ -static pascal void -ThemeMenuItemDrawingProc ( +pascal void +ThemeMenuItemDrawingProc( const Rect *inBounds, - SInt16 inDepth, - Boolean inIsColorDevice, + SInt16 inDepth, + Boolean inIsColorDevice, SInt32 inUserData) { MenuEntryUserData *meData = (MenuEntryUserData *) inUserData; - TkpDrawMenuEntry(meData->mePtr, meData->mdefDrawable, - meData->tkfont, meData->fmPtr, inBounds->left, - inBounds->top, inBounds->right - inBounds->left, - inBounds->bottom - inBounds->top, 0, 1); + + TkpDrawMenuEntry(meData->mePtr, meData->mdefDrawable, meData->tkfont, + meData->fmPtr, inBounds->left, inBounds->top, inBounds->right - + inBounds->left + menuItemExtraWidth, inBounds->bottom - + inBounds->top + menuItemExtraHeight, 0, 1); } +#endif /* USE_TK_MDEF */ /* *---------------------------------------------------------------------- @@ -2817,29 +2842,9 @@ ThemeMenuItemDrawingProc ( void TkMacOSXHandleTearoffMenu(void) { - if (tearoffStruct.menuPtr != NULL) { - Tcl_DString tearoffCmdStr; - char intString[TCL_INTEGER_SPACE]; - short windowPart; - WindowRef whichWindow; - - windowPart = FindWindow(tearoffStruct.point, &whichWindow); - - if (windowPart != inMenuBar) { - Tcl_DStringInit(&tearoffCmdStr); - Tcl_DStringAppendElement(&tearoffCmdStr, "tkTearOffMenu"); - Tcl_DStringAppendElement(&tearoffCmdStr, - Tk_PathName(tearoffStruct.menuPtr->tkwin)); - sprintf(intString, "%d", tearoffStruct.point.h); - Tcl_DStringAppendElement(&tearoffCmdStr, intString); - sprintf(intString, "%d", tearoffStruct.point.v); - Tcl_DStringAppendElement(&tearoffCmdStr, intString); - Tcl_Eval(tearoffStruct.menuPtr->interp, - Tcl_DStringValue(&tearoffCmdStr)); - Tcl_DStringFree(&tearoffCmdStr); - tearoffStruct.menuPtr = NULL; - } - } + /* + * Obsolete: Nothing to do. + */ } /* @@ -2862,9 +2867,10 @@ TkMacOSXHandleTearoffMenu(void) */ void -TkpInitializeMenuBindings(interp, bindingTable) - Tcl_Interp *interp; /* The interpreter to set. */ - Tk_BindingTable bindingTable; /* The table to add to. */ +TkpInitializeMenuBindings( + Tcl_Interp *interp, /* The interpreter to set. */ + Tk_BindingTable bindingTable) + /* The table to add to. */ { /* * Nothing to do. @@ -2891,8 +2897,8 @@ TkpInitializeMenuBindings(interp, bindingTable) */ void -TkpComputeMenubarGeometry(menuPtr) - TkMenu *menuPtr; /* Structure describing menu. */ +TkpComputeMenubarGeometry( + TkMenu *menuPtr) /* Structure describing menu. */ { TkpComputeStandardMenuGeometry(menuPtr); } @@ -2902,7 +2908,7 @@ TkpComputeMenubarGeometry(menuPtr) * * DrawTearoffEntry -- * - * This procedure draws the background part of a menu. + * This procedure draws a tearoff entry. * * Results: * None. @@ -2916,16 +2922,16 @@ TkpComputeMenubarGeometry(menuPtr) void DrawTearoffEntry( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* The drawable we are drawing into */ - GC gc, /* The gc we are drawing with */ - Tk_Font tkfont, /* The font we are drawing with */ - CONST Tk_FontMetrics *fmPtr, /* The metrics we are drawing with */ - int x, /* Left edge of entry. */ - int y, /* Top edge of entry. */ - int width, /* Width of entry. */ - int height) /* Height of entry. */ + TkMenu *menuPtr, /* The menu we are drawing */ + TkMenuEntry *mePtr, /* The entry we are drawing */ + Drawable d, /* The drawable we are drawing into */ + GC gc, /* The gc we are drawing with */ + Tk_Font tkfont, /* The font we are drawing with */ + const Tk_FontMetrics *fmPtr,/* The metrics we are drawing with */ + int x, /* Left edge of entry. */ + int y, /* Top edge of entry. */ + int width, /* Width of entry. */ + int height) /* Height of entry. */ { XPoint points[2]; int margin, segmentWidth, maxX; @@ -2934,13 +2940,13 @@ DrawTearoffEntry( if (menuPtr->menuType != MASTER_MENU ) { return; } - - margin = (fmPtr->ascent + fmPtr->descent)/2; + + margin = fmPtr->linespace/2; points[0].x = x; points[0].y = y + height/2; points[1].y = points[0].y; segmentWidth = 6; - maxX = width - 1; + maxX = x + menuPtr->totalWidth - 1; border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); while (points[0].x < maxX) { @@ -2962,9 +2968,9 @@ DrawTearoffEntry( * Has to be called after the first call to InsertMenu. Sets * up the global variable for the number of items in the * unmodified help menu. - * NB. Nobody uses this any more, since you can get the number - * of system help items from HMGetHelpMenu trivially. - * But it is in the stubs table... + * NB. Nobody uses this any more, since you can get the number + * of system help items from HMGetHelpMenu trivially. + * But it is in the stubs table... * * Results: * None. @@ -2975,9 +2981,12 @@ DrawTearoffEntry( *---------------------------------------------------------------------- */ -void -TkMacOSXSetHelpMenuItemCount() +void +TkMacOSXSetHelpMenuItemCount(void) { + /* + * Obsolete: Nothing to do. + */ } /* @@ -2997,26 +3006,26 @@ TkMacOSXSetHelpMenuItemCount() */ void -TkMacOSXMenuClick() +TkMacOSXMenuClick(void) { TkMenu *menuPtr; TkMenuReferences *menuRefPtr; - + if ((currentMenuBarInterp != NULL) && (currentMenuBarName != NULL)) { - menuRefPtr = TkFindMenuReferences(currentMenuBarInterp, - currentMenuBarName); - for (menuPtr = menuRefPtr->menuPtr->masterMenuPtr; - menuPtr != NULL; menuPtr = menuPtr->nextInstancePtr) { - if (menuPtr->menuType == MENUBAR) { - CompleteIdlers(menuPtr); - break; - } - } + menuRefPtr = TkFindMenuReferences(currentMenuBarInterp, + currentMenuBarName); + for (menuPtr = menuRefPtr->menuPtr->masterMenuPtr; + menuPtr != NULL; menuPtr = menuPtr->nextInstancePtr) { + if (menuPtr->menuType == MENUBAR) { + CompleteIdlers(menuPtr); + break; + } + } } - + if (menuBarFlags & MENUBAR_REDRAW_PENDING) { - Tcl_CancelIdleCall(DrawMenuBarWhenIdle, (ClientData *) NULL); - DrawMenuBarWhenIdle((ClientData *) NULL); + Tcl_CancelIdleCall(DrawMenuBarWhenIdle, NULL); + DrawMenuBarWhenIdle(NULL); } } @@ -3039,19 +3048,19 @@ TkMacOSXMenuClick() void TkpDrawMenuEntry( - TkMenuEntry *mePtr, /* The entry to draw */ - Drawable d, /* What to draw into */ - Tk_Font tkfont, /* Precalculated font for menu */ - CONST Tk_FontMetrics *menuMetricsPtr, - /* Precalculated metrics for menu */ - int x, /* X-coordinate of topleft of entry */ - int y, /* Y-coordinate of topleft of entry */ - int width, /* Width of the entry rectangle */ - int height, /* Height of the current rectangle */ - int strictMotif, /* Boolean flag */ - int drawArrow) /* Whether or not to draw the cascade - * arrow for cascade items. Only applies - * to Windows. */ + TkMenuEntry *mePtr, /* The entry to draw */ + Drawable d, /* What to draw into */ + Tk_Font tkfont, /* Precalculated font for menu */ + const Tk_FontMetrics *menuMetricsPtr, + /* Precalculated metrics for menu */ + int x, /* X-coordinate of topleft of entry */ + int y, /* Y-coordinate of topleft of entry */ + int width, /* Width of the entry rectangle */ + int height, /* Height of the current rectangle */ + int strictMotif, /* Boolean flag */ + int drawArrow) /* Whether or not to draw the cascade + * arrow for cascade items. Only applies + * to Windows. */ { GC gc; TkMenu *menuPtr = mePtr->menuPtr; @@ -3065,35 +3074,21 @@ TkpDrawMenuEntry( /* * Choose the gc for drawing the foreground part of the entry. - * Under Appearance, we pass a null (appearanceGC) to tell + * Under Appearance, we pass a null (appearanceGC) to tell * ourselves not to change whatever color the appearance manager has set. */ if ((mePtr->state == ENTRY_ACTIVE) && !strictMotif) { gc = mePtr->activeGC; if (gc == NULL) { - gc = menuPtr->activeGC; + gc = menuPtr->activeGC; } } else { - TkMenuEntry *cascadeEntryPtr; - int parentDisabled = 0; - - for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr; - cascadeEntryPtr != NULL; - cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) { - char *name = (cascadeEntryPtr->namePtr == NULL) ? "" - : Tcl_GetStringFromObj(cascadeEntryPtr->namePtr, NULL); - - if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) { - if (cascadeEntryPtr->state == ENTRY_DISABLED) { - parentDisabled = 1; - } - break; - } - } - - if (((parentDisabled || (mePtr->state == ENTRY_DISABLED))) - && (menuPtr->disabledFgPtr != NULL)) { + TkMenuEntry *parentEntryPtr = GetParentMenuEntry(menuPtr); + + if (((parentEntryPtr && parentEntryPtr->state == ENTRY_DISABLED) || + (mePtr->state == ENTRY_DISABLED)) && + (menuPtr->disabledFgPtr != NULL)) { gc = mePtr->disabledGC; if (gc == NULL) { gc = menuPtr->disabledGC; @@ -3103,9 +3098,9 @@ TkpDrawMenuEntry( if (gc == NULL) { gc = menuPtr->textGC; } - } + } } - + indicatorGC = mePtr->indicatorGC; if (indicatorGC == NULL) { indicatorGC = menuPtr->indicatorGC; @@ -3135,18 +3130,18 @@ TkpDrawMenuEntry( * for menubars, we have to draw the rest of the entry taking * into account the padding. */ - - DrawMenuEntryBackground(menuPtr, mePtr, d, activeBorder, - bgBorder, x, y, width, height); - + + DrawMenuEntryBackground(menuPtr, mePtr, d, activeBorder, bgBorder, x, y, + width, height); + if (mePtr->type == SEPARATOR_ENTRY) { - DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont, + DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY, width, adjustedHeight); } else if (mePtr->type == TEAROFF_ENTRY) { DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY, width, adjustedHeight); } else { - DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, + DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY, width, adjustedHeight); DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr, activeBorder, x, adjustedY, width, adjustedHeight, drawArrow); @@ -3154,7 +3149,6 @@ TkpDrawMenuEntry( DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, fmPtr, x, adjustedY, width, adjustedHeight); } - } } @@ -3190,15 +3184,16 @@ TkpComputeStandardMenuGeometry( int entryWidth, maxIndicatorSpace, borderWidth, activeBorderWidth; TkMenuEntry *mePtr, *columnEntryPtr; EntryGeometry *geometryPtr; - + int haveAccel = 0; + if (menuPtr->tkwin == NULL) { return; } Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr, - &borderWidth); + &borderWidth); Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr, - &activeBorderWidth); + &activeBorderWidth); x = y = borderWidth; indicatorSpace = labelWidth = accelWidth = maxAccelTextWidth = 0; windowHeight = windowWidth = maxWidth = lastColumnBreak = 0; @@ -3221,27 +3216,35 @@ TkpComputeStandardMenuGeometry( Tk_GetFontMetrics(menuFont, &menuMetrics); for (i = 0; i < menuPtr->numEntries; i++) { - mePtr = menuPtr->entries[i]; - if (mePtr->fontPtr == NULL) { + mePtr = menuPtr->entries[i]; + if (mePtr->type == CASCADE_ENTRY || mePtr->accelLength > 0) { + haveAccel = 1; + break; + } + } + + for (i = 0; i < menuPtr->numEntries; i++) { + mePtr = menuPtr->entries[i]; + if (mePtr->fontPtr == NULL) { tkfont = menuFont; fmPtr = &menuMetrics; - } else { + } else { tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr); - Tk_GetFontMetrics(tkfont, &entryMetrics); - fmPtr = &entryMetrics; - } - + Tk_GetFontMetrics(tkfont, &entryMetrics); + fmPtr = &entryMetrics; + } + if ((i > 0) && mePtr->columnBreak) { if (maxIndicatorSpace != 0) { maxIndicatorSpace += 2; } for (j = lastColumnBreak; j < i; j++) { - columnEntryPtr = menuPtr->entries[j]; - geometryPtr = - (EntryGeometry *) columnEntryPtr->platformEntryData; - - columnEntryPtr->indicatorSpace = maxIndicatorSpace; - columnEntryPtr->width = maxIndicatorSpace + maxWidth + columnEntryPtr = menuPtr->entries[j]; + geometryPtr = + (EntryGeometry *) columnEntryPtr->platformEntryData; + + columnEntryPtr->indicatorSpace = maxIndicatorSpace; + columnEntryPtr->width = maxIndicatorSpace + maxWidth + 2 * activeBorderWidth; geometryPtr->accelTextWidth = maxAccelTextWidth; geometryPtr->modifierWidth = maxModifierWidth; @@ -3249,13 +3252,13 @@ TkpComputeStandardMenuGeometry( columnEntryPtr->entryFlags &= ~ENTRY_LAST_COLUMN; if (maxEntryWithoutAccelWidth > maxEntryWithAccelWidth) { geometryPtr->nonAccelMargin = maxEntryWithoutAccelWidth - - maxEntryWithAccelWidth; + - maxEntryWithAccelWidth; if (geometryPtr->nonAccelMargin > maxNonAccelMargin) { - geometryPtr->nonAccelMargin = maxNonAccelMargin; + geometryPtr->nonAccelMargin = maxNonAccelMargin; } } else { geometryPtr->nonAccelMargin = 0; - } + } } x += maxIndicatorSpace + maxWidth + 2 * borderWidth; windowWidth = x; @@ -3265,14 +3268,15 @@ TkpComputeStandardMenuGeometry( lastColumnBreak = i; y = borderWidth; } + geometryPtr = (EntryGeometry *) mePtr->platformEntryData; if (mePtr->type == SEPARATOR_ENTRY) { GetMenuSeparatorGeometry(menuPtr, mePtr, tkfont, - fmPtr, &entryWidth, &height); + fmPtr, &entryWidth, &height); mePtr->height = height; } else if (mePtr->type == TEAROFF_ENTRY) { - GetTearoffEntryGeometry(menuPtr, mePtr, tkfont, - fmPtr, &entryWidth, &height); + GetTearoffEntryGeometry(menuPtr, mePtr, tkfont, + fmPtr, &entryWidth, &height); mePtr->height = height; } else { /* @@ -3281,75 +3285,78 @@ TkpComputeStandardMenuGeometry( * label, the width to allow for an indicator to be displayed * to the left of the label (if any), and the width of the * accelerator to be displayed to the right of the label - * (if any). These sizes depend, of course, on the type + * (if any). These sizes depend, of course, on the type * of the entry. */ - - GetMenuLabelGeometry(mePtr, tkfont, fmPtr, &labelWidth, - &height); + + GetMenuLabelGeometry(mePtr, tkfont, fmPtr, &labelWidth, &height); mePtr->height = height; - + + nonAccelMargin = 0; if (mePtr->type == CASCADE_ENTRY) { - GetMenuAccelGeometry(menuPtr, mePtr, tkfont, fmPtr, - &modifierWidth, &accelWidth, &height); - nonAccelMargin = 0; + GetMenuAccelGeometry(menuPtr, mePtr, tkfont, fmPtr, + &modifierWidth, &accelWidth, &height); } else if (mePtr->accelLength == 0) { - nonAccelMargin = mePtr->hideMargin ? 0 - : Tk_TextWidth(tkfont, "m", 1); - accelWidth = modifierWidth = 0; + if (haveAccel && !mePtr->hideMargin) { + if (IS_THEME_MENU_FONT(tkfont)) { + nonAccelMargin = menuSymbols[COMMAND_SYMBOL].width; + } else { + nonAccelMargin = Tk_TextWidth(tkfont, + menuSymbols[COMMAND_SYMBOL].utf, + menuSymbols[COMMAND_SYMBOL].utfLen); + } + } + accelWidth = modifierWidth = 0; } else { - labelWidth += Tk_TextWidth(tkfont, "m", 1); - GetMenuAccelGeometry(menuPtr, mePtr, tkfont, - fmPtr, &modifierWidth, &accelWidth, &height); - if (height > mePtr->height) { - mePtr->height = height; - } - nonAccelMargin = 0; + GetMenuAccelGeometry(menuPtr, mePtr, tkfont, + fmPtr, &modifierWidth, &accelWidth, &height); + if (height > mePtr->height) { + mePtr->height = height; + } } if (!(mePtr->hideMargin)) { - GetMenuIndicatorGeometry(menuPtr, mePtr, tkfont, - fmPtr, &indicatorSpace, &height); - if (height > mePtr->height) { - mePtr->height = height; - } + GetMenuIndicatorGeometry(menuPtr, mePtr, tkfont, + fmPtr, &indicatorSpace, &height); + if (height > mePtr->height) { + mePtr->height = height; + } } else { - indicatorSpace = 0; + indicatorSpace = 0; } if (nonAccelMargin > maxNonAccelMargin) { - maxNonAccelMargin = nonAccelMargin; + maxNonAccelMargin = nonAccelMargin; } if (accelWidth > maxAccelTextWidth) { - maxAccelTextWidth = accelWidth; + maxAccelTextWidth = accelWidth; } if (modifierWidth > maxModifierWidth) { - maxModifierWidth = modifierWidth; + maxModifierWidth = modifierWidth; } if (indicatorSpace > maxIndicatorSpace) { - maxIndicatorSpace = indicatorSpace; + maxIndicatorSpace = indicatorSpace; } entryWidth = labelWidth + modifierWidth + accelWidth + nonAccelMargin; if (entryWidth > maxWidth) { - maxWidth = entryWidth; + maxWidth = entryWidth; } - + if (mePtr->accelLength > 0) { - if (entryWidth > maxEntryWithAccelWidth) { - maxEntryWithAccelWidth = entryWidth; - } + if (entryWidth > maxEntryWithAccelWidth) { + maxEntryWithAccelWidth = entryWidth; + } } else { - if (entryWidth > maxEntryWithoutAccelWidth) { - maxEntryWithoutAccelWidth = entryWidth; - } + if (entryWidth > maxEntryWithoutAccelWidth) { + maxEntryWithoutAccelWidth = entryWidth; + } } - mePtr->height += 2 * activeBorderWidth; - } - mePtr->y = y; + } + mePtr->y = y; y += menuPtr->entries[i]->height + borderWidth; if (y > windowHeight) { windowHeight = y; @@ -3357,30 +3364,29 @@ TkpComputeStandardMenuGeometry( } for (j = lastColumnBreak; j < menuPtr->numEntries; j++) { - columnEntryPtr = menuPtr->entries[j]; - geometryPtr = (EntryGeometry *) columnEntryPtr->platformEntryData; - - columnEntryPtr->indicatorSpace = maxIndicatorSpace; - columnEntryPtr->width = maxIndicatorSpace + maxWidth + columnEntryPtr = menuPtr->entries[j]; + geometryPtr = (EntryGeometry *) columnEntryPtr->platformEntryData; + + columnEntryPtr->indicatorSpace = maxIndicatorSpace; + columnEntryPtr->width = maxIndicatorSpace + maxWidth + 2 * activeBorderWidth; geometryPtr->accelTextWidth = maxAccelTextWidth; - geometryPtr->modifierWidth = maxModifierWidth; columnEntryPtr->x = x; columnEntryPtr->entryFlags |= ENTRY_LAST_COLUMN; if (maxEntryWithoutAccelWidth > maxEntryWithAccelWidth) { geometryPtr->nonAccelMargin = maxEntryWithoutAccelWidth - - maxEntryWithAccelWidth; + - maxEntryWithAccelWidth; if (geometryPtr->nonAccelMargin > maxNonAccelMargin) { - geometryPtr->nonAccelMargin = maxNonAccelMargin; + geometryPtr->nonAccelMargin = maxNonAccelMargin; } } else { geometryPtr->nonAccelMargin = 0; - } + } } windowWidth = x + maxIndicatorSpace + maxWidth + 2 * activeBorderWidth + borderWidth; windowHeight += borderWidth; - + /* * The X server doesn't like zero dimensions, so round up to at least * 1 (a zero-sized menu should never really occur, anyway). @@ -3413,171 +3419,147 @@ TkpComputeStandardMenuGeometry( *---------------------------------------------------------------------- */ -static void +void DrawMenuEntryLabel( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* What we are drawing into */ - GC gc, /* The gc we are drawing into */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int x, /* left edge */ - int y, /* right edge */ - int width, /* width of entry */ - int height) /* height of entry */ + TkMenu *menuPtr, /* The menu we are drawing */ + TkMenuEntry *mePtr, /* The entry we are drawing */ + Drawable d, /* What we are drawing into */ + GC gc, /* The gc we are drawing into */ + Tk_Font tkfont, /* The precalculated font */ + const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ + int x, /* left edge */ + int y, /* right edge */ + int width, /* width of entry */ + int height) /* height of entry */ { - int baseline; + int imageWidth, imageHeight, textWidth = 0, textHeight = 0; int indicatorSpace = mePtr->indicatorSpace; int leftEdge = x + indicatorSpace; - int imageHeight, imageWidth; - + int haveImage = 0, haveText = 0; + int imageXOffset = 0, imageYOffset = 0; + int textXOffset = 0, textYOffset = 0; + Pixmap bitmap = (Pixmap) NULL; + Tcl_DString itemTextDString; + /* - * Draw label or bitmap or image for entry. + * Work out what we will need to draw first. */ - baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; if (mePtr->image != NULL) { - Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight); - if ((mePtr->selectImage != NULL) - && (mePtr->entryFlags & ENTRY_SELECTED)) { - Tk_RedrawImage(mePtr->selectImage, 0, 0, - imageWidth, imageHeight, d, leftEdge, - (int) (y + (mePtr->height - imageHeight)/2)); - } else { - Tk_RedrawImage(mePtr->image, 0, 0, imageWidth, - imageHeight, d, leftEdge, - (int) (y + (mePtr->height - imageHeight)/2)); - } + Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight); + haveImage = 1; } else if (mePtr->bitmapPtr != NULL) { - int width, height; - Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); - Tk_SizeOfBitmap(menuPtr->display, - bitmap, &width, &height); - XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0, - (unsigned) width, (unsigned) height, leftEdge, - (int) (y + (mePtr->height - height)/2), 1); - } else { - if (mePtr->labelLength > 0) { - Tcl_DString itemTextDString, convertedTextDString; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; -#ifdef USE_ATSU - int xLocation; - int yLocation; - int runLengths; - CFStringRef stringRef; - ATSUTextLayout textLayout; - UniCharCount runLength; - ATSUStyle style; - int length; - int err; - Str255 fontName; - SInt16 fontSize; - Style fontStyle; - ATSUAttributeValuePtr valuePtr; - ByteCount valueSize; - Fixed fixedSize; - short iFONDNumber; - ATSUFontID fontID; - ATSUAttributeTag tag; - - GetThemeFont (kThemeMenuItemFont, smSystemScript, fontName, &fontSize, &fontStyle); - if ((err = ATSUCreateStyle(&style)) != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"ATSUCreateStyle failed, %d\n", err); -#endif - return; - } - fixedSize = fontSize<<16; - tag = kATSUSizeTag; - valueSize = sizeof(fixedSize); - valuePtr = &fixedSize; - err = ATSUSetAttributes(style, 1, &tag, &valueSize, &valuePtr); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"ATSUSetAttributes failed,%d\n", err ); -#endif - } - - GetFNum(fontName, &iFONDNumber); - ATSUFONDtoFontID(iFONDNumber, NULL, &fontID); - tag = kATSUFontTag; - valueSize = sizeof(fontID); - valuePtr = &fontID; - err = ATSUSetAttributes(style, 1, &tag, &valueSize, &valuePtr); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"ATSUSetAttributes failed,%d\n", err ); -#endif - } + bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); + Tk_SizeOfBitmap(menuPtr->display, bitmap, &imageWidth, &imageHeight); + haveImage = 1; + } + if (!haveImage || (mePtr->compound != COMPOUND_NONE)) { + if (mePtr->labelLength > 0) { + GetEntryText(mePtr, &itemTextDString); + if (mePtr->compound != COMPOUND_NONE) { + textWidth = Tk_TextWidth(tkfont, + Tcl_DStringValue(&itemTextDString), + Tcl_DStringLength(&itemTextDString)) + + menuTextLeadingEdgeMargin + menuTextTrailingEdgeMargin; + textHeight = fmPtr->linespace; + } + haveText = 1; + } + } -#endif - - GetEntryText(mePtr, &itemTextDString); -#ifdef USE_ATSU - runLengths = 1; - length = Tcl_DStringLength(&itemTextDString); - stringRef = CFStringCreateWithCString(NULL, Tcl_DStringValue(&itemTextDString), - kCFStringEncodingUTF8); - if (!stringRef) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"CFStringCreateWithCString failed\n"); -#endif - } - err = ATSUCreateTextLayoutWithTextPtr(CFStringGetCharactersPtr(stringRef), - 0, length, length, - 1, &runLengths, &style, &textLayout) - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"ATSUCreateTextLayoutWithTextPtr failed, %d\n", err); -#endif - return; - } -#endif - - /* Somehow DrawChars is changing the colors, it is odd, since - it works for the Apple Platinum Appearance, but not for - some Kaleidoscope Themes... Untill I can figure out what - exactly is going on, this will have to do: */ - - destPort = TkMacOSXGetDrawablePort(d); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpGraphicsPort(gc, destPort); - - MoveTo((short) leftEdge, (short) baseline); - Tcl_UtfToExternalDString(TkMacOSXCarbonEncoding, Tcl_DStringValue(&itemTextDString), - Tcl_DStringLength(&itemTextDString), &convertedTextDString); -#ifdef USE_ATSU - xLocation = leftEdge << 16; - yLocation = baseline << 16; - ATSUDrawText(textLayout,kATSUFromTextBeginning, kATSUToTextEnd, xLocation, yLocation); - ATSUDisposeTextLayout(textLayout); - CFRelease(stringRef); -#else - DrawText(Tcl_DStringValue(&convertedTextDString), 0, - Tcl_DStringLength(&convertedTextDString)); -#endif - - /* Tk_DrawChars(menuPtr->display, d, gc, - tkfont, Tcl_DStringValue(&itemTextDString), - Tcl_DStringLength(&itemTextDString), - leftEdge, baseline); */ - - Tcl_DStringFree(&convertedTextDString); - Tcl_DStringFree(&itemTextDString); - } + /* + * Now work out what the relative positions are. + */ + + if (haveImage && haveText && (mePtr->compound != COMPOUND_NONE)) { + int fullWidth = (imageWidth > textWidth ? imageWidth : textWidth); + + switch ((enum compound) mePtr->compound) { + case COMPOUND_TOP: + textXOffset = (fullWidth - textWidth)/2; + textYOffset = imageHeight/2 + 2; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = -textHeight/2; + break; + case COMPOUND_BOTTOM: + textXOffset = (fullWidth - textWidth)/2; + textYOffset = -imageHeight/2; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = textHeight/2 + 2; + break; + case COMPOUND_LEFT: + /* + * Position image in the indicator space to the left of the + * entries, unless this entry is a radio|check button because + * then the indicator space will be used. + */ + + textXOffset = imageWidth + 2 - menuTextLeadingEdgeMargin; + if ((mePtr->type != CHECK_BUTTON_ENTRY) + && (mePtr->type != RADIO_BUTTON_ENTRY)) { + textXOffset -= indicatorSpace; + imageXOffset = -indicatorSpace; + } + if (textXOffset < 0) { + textXOffset = 0; + } + break; + case COMPOUND_RIGHT: + imageXOffset = textWidth + 2 - menuTextTrailingEdgeMargin; + break; + case COMPOUND_CENTER: + textXOffset = (fullWidth - textWidth)/2; + imageXOffset = (fullWidth - imageWidth)/2; + break; + case COMPOUND_NONE: + /* + * Never reached. + */ + break; + } + } + + /* + * Draw label and/or bitmap or image for entry. + */ + + if (mePtr->image != NULL) { + if ((mePtr->selectImage != NULL) + && (mePtr->entryFlags & ENTRY_SELECTED)) { + Tk_RedrawImage(mePtr->selectImage, 0, 0, imageWidth, imageHeight, + d, leftEdge + imageXOffset, + y + (mePtr->height - imageHeight)/2 + imageYOffset); + } else { + Tk_RedrawImage(mePtr->image, 0, 0, imageWidth, imageHeight, + d, leftEdge + imageXOffset, + y + (mePtr->height - imageHeight)/2 + imageYOffset); + } + } else if (mePtr->bitmapPtr != NULL) { + XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0, imageWidth, + imageHeight, leftEdge + imageXOffset, + y + (mePtr->height - imageHeight)/2 + imageYOffset, 1); + } + if (haveText) { + int baseline = y + (height + fmPtr->ascent - fmPtr->descent)/2; + + Tk_DrawChars(menuPtr->display, d, gc, tkfont, + Tcl_DStringValue(&itemTextDString), + Tcl_DStringLength(&itemTextDString), + leftEdge + menuTextLeadingEdgeMargin + textXOffset, + baseline + textYOffset); + Tcl_DStringFree(&itemTextDString); } if (mePtr->state == ENTRY_DISABLED) { if (menuPtr->disabledFgPtr == NULL) { - } else if ((mePtr->image != NULL) + /* XFillRectangle(menuPtr->display, d, menuPtr->disabledGC, x, y, + width, height); */ + } else if ((mePtr->image != NULL) && (menuPtr->disabledImageGC != None)) { XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC, - leftEdge, - (int) (y + (mePtr->height - imageHeight)/2), - (unsigned) imageWidth, (unsigned) imageHeight); + leftEdge + imageXOffset, + y + (mePtr->height - imageHeight)/2 + imageYOffset, + imageWidth, imageHeight); } } } @@ -3588,8 +3570,8 @@ DrawMenuEntryLabel( * DrawMenuEntryBackground -- * * This procedure draws the background part of a menu entry. - * Under Appearance, we only draw the background if the entry's - * border is set, we DO NOT inherit it from the menu... + * Under Appearance, we only draw the background if the entry's + * border is set, we DO NOT inherit it from the menu... * * Results: * None. @@ -3601,27 +3583,27 @@ DrawMenuEntryLabel( *---------------------------------------------------------------------- */ -static void +void DrawMenuEntryBackground( - TkMenu *menuPtr, /* The menu we are drawing. */ - TkMenuEntry *mePtr, /* The entry we are drawing. */ - Drawable d, /* What we are drawing into */ - Tk_3DBorder activeBorder, /* Border for active items */ - Tk_3DBorder bgBorder, /* Border for the background */ - int x, /* left edge */ - int y, /* top edge */ - int width, /* width of rectangle to draw */ - int height) /* height of rectangle to draw */ + TkMenu *menuPtr, /* The menu we are drawing. */ + TkMenuEntry *mePtr, /* The entry we are drawing. */ + Drawable d, /* What we are drawing into */ + Tk_3DBorder activeBorder, /* Border for active items */ + Tk_3DBorder bgBorder, /* Border for the background */ + int x, /* left edge */ + int y, /* top edge */ + int width, /* width of rectangle to draw */ + int height) /* height of rectangle to draw */ { if ((menuPtr->menuType == TEAROFF_MENU) - || ((mePtr->state == ENTRY_ACTIVE) - && (mePtr->activeBorderPtr != None)) - || ((mePtr->state != ENTRY_ACTIVE) && (mePtr->borderPtr != None))) { - if (mePtr->state == ENTRY_ACTIVE) { + || ((mePtr->state == ENTRY_ACTIVE) + && (mePtr->activeBorderPtr != None)) + || ((mePtr->state != ENTRY_ACTIVE) && (mePtr->borderPtr != None))) { + if (mePtr->state == ENTRY_ACTIVE) { bgBorder = activeBorder; - } - Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, - x, y, width, height, 0, TK_RELIEF_FLAT); + } + Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, + x, y, width, height, 0, TK_RELIEF_FLAT); } } @@ -3642,44 +3624,171 @@ DrawMenuEntryBackground( *---------------------------------------------------------------------- */ -static void +void GetMenuLabelGeometry( - TkMenuEntry *mePtr, /* The entry we are computing */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated metrics */ - int *widthPtr, /* The resulting width of the label - * portion */ - int *heightPtr) /* The resulting height of the label - * portion */ + TkMenuEntry *mePtr, /* The entry we are computing */ + Tk_Font tkfont, /* The precalculated font */ + const Tk_FontMetrics *fmPtr,/* The precalculated metrics */ + int *widthPtr, /* The resulting width of the label portion */ + int *heightPtr) /* The resulting height of the label portion */ { TkMenu *menuPtr = mePtr->menuPtr; - - if (mePtr->image != NULL) { - Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr); - } else if (mePtr->bitmapPtr != NULL) { - Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); - Tk_SizeOfBitmap(menuPtr->display, bitmap, widthPtr, heightPtr); - } else { - *heightPtr = fmPtr->linespace; - - if (mePtr->labelPtr != NULL) { - Tcl_DString itemTextDString; - - GetEntryText(mePtr, &itemTextDString); - *widthPtr = Tk_TextWidth(tkfont, - Tcl_DStringValue(&itemTextDString), - Tcl_DStringLength(&itemTextDString)); - Tcl_DStringFree(&itemTextDString); - } else { - *widthPtr = 0; - } + int haveImage = 0, tornOff = (menuPtr->menuType == TEAROFF_MENU); +#ifdef USE_TK_MDEF + const int useMDEF = ((MacMenu *) menuPtr->platformData)->useMDEF; +#endif + + if (mePtr->image != NULL && (useMDEF || tornOff)) { + Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr); + haveImage = 1; + } else if (mePtr->bitmapPtr != NULL && (useMDEF || tornOff)) { + Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); + Tk_SizeOfBitmap(menuPtr->display, bitmap, widthPtr, heightPtr); + haveImage = 1; + } + if (!haveImage || (mePtr->compound != COMPOUND_NONE)) { + int textWidth = 0, textHeight = fmPtr->linespace; + + if (mePtr->labelPtr != NULL) { + Tcl_DString itemTextDString; + + GetEntryText(mePtr, &itemTextDString); + textWidth = Tk_TextWidth(tkfont, + Tcl_DStringValue(&itemTextDString), + Tcl_DStringLength(&itemTextDString)) + + menuTextLeadingEdgeMargin + menuTextTrailingEdgeMargin; + Tcl_DStringFree(&itemTextDString); + + if (haveImage && (mePtr->compound != COMPOUND_NONE)) { + switch ((enum compound) mePtr->compound) { + int margin; + + case COMPOUND_TOP: + case COMPOUND_BOTTOM: + if (textWidth > *widthPtr) { + *widthPtr = textWidth; + } + *heightPtr += textHeight + 2; + break; + case COMPOUND_LEFT: + margin = *widthPtr + 2; + if (margin > menuTextLeadingEdgeMargin) { + margin = menuTextLeadingEdgeMargin; + } + *widthPtr += textWidth + 2 - margin; + if (textHeight > *heightPtr) { + *heightPtr = textHeight; + } + break; + case COMPOUND_RIGHT: + margin = menuTextTrailingEdgeMargin; + *widthPtr += textWidth + 2 - margin; + if (textHeight > *heightPtr) { + *heightPtr = textHeight; + } + break; + case COMPOUND_CENTER: + if (textWidth > *widthPtr) { + *widthPtr = textWidth; + } + if (textHeight > *heightPtr) { + *heightPtr = textHeight; + } + break; + case COMPOUND_NONE: + /* + * Never reached. + */ + break; + } + goto labelGeomDone; + } + } + *widthPtr = textWidth; + *heightPtr = textHeight; } - *heightPtr += 1; + +labelGeomDone: + *heightPtr += menuItemExtraHeight; + *widthPtr += menuItemExtraWidth; } /* *---------------------------------------------------------------------- * + * TkMacOSXGenerateParentMenuSelectEvent -- + * + * Respond to a hierarchical menu being opened. + * + * Results: + * True if event(s) are generated - false otherwise. + * + * Side effects: + * Places a virtual event on the event queue. + * + *---------------------------------------------------------------------- + */ + +int +TkMacOSXGenerateParentMenuSelectEvent( + MenuRef menu) +{ + TkMenu *menuPtr = MenuPtrForMenuRef(menu); + + if (menuPtr) { + TkMenuEntry *parentEntryPtr = GetParentMenuEntry(menuPtr); + + if (parentEntryPtr && (menuPtr = parentEntryPtr->menuPtr)) { + TkActivateMenuEntry(menuPtr, parentEntryPtr->index); + MenuSelectEvent(menuPtr); + Tcl_ServiceAll(); + return true; + } + } + return false; +} + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXGenerateMenuSelectEvent -- + * + * Respond to a menu item being selected. + * + * Results: + * True if event(s) are generated - false otherwise. + * + * Side effects: + * Places a virtual event on the event queue. + * + *---------------------------------------------------------------------- + */ + +int +TkMacOSXGenerateMenuSelectEvent( + MenuRef menu, + MenuItemIndex index) +{ + TkMenu *menuPtr = MenuPtrForMenuRef(menu); + int item = index - 1; + + if (menuPtr) { + if (item < 0 || item >= menuPtr->numEntries || + (menuPtr->entries[item])->state == ENTRY_DISABLED) { + TkActivateMenuEntry(menuPtr, -1); + } else { + TkActivateMenuEntry(menuPtr, item); + MenuSelectEvent(menuPtr); + Tcl_ServiceAll(); + return true; + } + } + return false; +} + +/* + *---------------------------------------------------------------------- + * * MenuSelectEvent -- * * Generates a "MenuSelect" virtual event. This can be used to @@ -3694,12 +3803,12 @@ GetMenuLabelGeometry( *---------------------------------------------------------------------- */ -static void +void MenuSelectEvent( TkMenu *menuPtr) /* the menu we have selected. */ { XVirtualEvent event; - + bzero(&event, sizeof(XVirtualEvent)); event.type = VirtualEvent; event.serial = menuPtr->display->request; @@ -3710,9 +3819,9 @@ MenuSelectEvent( event.root = XRootWindow(menuPtr->display, 0); event.subwindow = None; event.time = TkpGetMS(); - - XQueryPointer(NULL, None, NULL, NULL, - &event.x_root, &event.y_root, NULL, NULL, &event.state); + + XQueryPointer(NULL, None, NULL, NULL, &event.x_root, &event.y_root, NULL, + NULL, &event.state); event.same_screen = true; event.name = Tk_GetUid("MenuSelect"); Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); @@ -3721,9 +3830,9 @@ MenuSelectEvent( /* *---------------------------------------------------------------------- * - * RecursivelyClearActiveMenu -- + * TkMacOSXClearActiveMenu -- * - * Recursively clears the active entry in the menu's cascade hierarchy. + * Clears Tk's active entry for the given MenuRef. * * Results: * None. @@ -3735,73 +3844,49 @@ MenuSelectEvent( */ void -RecursivelyClearActiveMenu( - TkMenu *menuPtr) /* The menu to reset. */ +TkMacOSXClearActiveMenu( + MenuRef menu) { - int i; - TkMenuEntry *mePtr; - - TkActivateMenuEntry(menuPtr, -1); - MenuSelectEvent(menuPtr); - for (i = 0; i < menuPtr->numEntries; i++) { - mePtr = menuPtr->entries[i]; - if (mePtr->type == CASCADE_ENTRY) { - if ((mePtr->childMenuRefPtr != NULL) - && (mePtr->childMenuRefPtr->menuPtr != NULL)) { - RecursivelyClearActiveMenu(mePtr->childMenuRefPtr->menuPtr); - } - } + TkMenu *menuPtr = MenuPtrForMenuRef(menu); + + if (menuPtr) { + RecursivelyClearActiveMenu(menuPtr); } } /* *---------------------------------------------------------------------- * - * InvalidateMDEFRgns -- + * RecursivelyClearActiveMenu -- * - * Invalidates the regions covered by menus that did redrawing and - * might be damaged. + * Recursively clears the active entry in the menu's cascade hierarchy. * * Results: * None. * * Side effects: - * Generates Mac update events for affected windows. + * Generates <<MenuSelect>> virtual events. * *---------------------------------------------------------------------- */ void -InvalidateMDEFRgns(void) +RecursivelyClearActiveMenu( + TkMenu *menuPtr) /* The menu to reset. */ { - GDHandle saveDevice; - GWorldPtr saveWorld, destPort; - Point scratch; - MacDrawable *macDraw; - TkMacOSXWindowList *listPtr; - - if (totalMenuRgn == NULL) { - return; - } - - GetGWorld(&saveWorld, &saveDevice); - for (listPtr = tkMacOSXWindowListPtr ; listPtr != NULL; - listPtr = listPtr->nextPtr) { - macDraw = (MacDrawable *) Tk_WindowId(listPtr->winPtr); - if (macDraw->flags & TK_DRAWN_UNDER_MENU) { - destPort = TkMacOSXGetDrawablePort(Tk_WindowId(listPtr->winPtr)); - SetGWorld(destPort, NULL); - scratch.h = scratch.v = 0; - GlobalToLocal(&scratch); - OffsetRgn(totalMenuRgn, scratch.v, scratch.h); - InvalWindowRgn(GetWindowFromPort(destPort),totalMenuRgn); - OffsetRgn(totalMenuRgn, -scratch.v, -scratch.h); - macDraw->flags &= ~TK_DRAWN_UNDER_MENU; - } + int i; + TkMenuEntry *mePtr; + + TkActivateMenuEntry(menuPtr, -1); + for (i = 0; i < menuPtr->numEntries; i++) { + mePtr = menuPtr->entries[i]; + if (mePtr->type == CASCADE_ENTRY) { + if ((mePtr->childMenuRefPtr != NULL) + && (mePtr->childMenuRefPtr->menuPtr != NULL)) { + RecursivelyClearActiveMenu(mePtr->childMenuRefPtr->menuPtr); + } + } } - - SetGWorld(saveWorld, saveDevice); - SetEmptyRgn(totalMenuRgn); } /* @@ -3824,22 +3909,21 @@ void TkMacOSXClearMenubarActive(void) { TkMenuReferences *menuBarRefPtr; - + if (currentMenuBarName != NULL) { - menuBarRefPtr = TkFindMenuReferences(currentMenuBarInterp, - currentMenuBarName); - if ((menuBarRefPtr != NULL) && (menuBarRefPtr->menuPtr != NULL)) { - TkMenu *menuPtr; - - for (menuPtr = menuBarRefPtr->menuPtr->masterMenuPtr; menuPtr != NULL; - menuPtr = menuPtr->nextInstancePtr) { - if (menuPtr->menuType == MENUBAR) { - RecursivelyClearActiveMenu(menuPtr); - } - } - } + menuBarRefPtr = TkFindMenuReferences(currentMenuBarInterp, + currentMenuBarName); + if ((menuBarRefPtr != NULL) && (menuBarRefPtr->menuPtr != NULL)) { + TkMenu *menuPtr; + + for (menuPtr = menuBarRefPtr->menuPtr->masterMenuPtr; + menuPtr != NULL; menuPtr = menuPtr->nextInstancePtr) { + if (menuPtr->menuType == MENUBAR) { + RecursivelyClearActiveMenu(menuPtr); + } + } + } } - InvalidateMDEFRgns(); } /* @@ -3862,9 +3946,8 @@ TkMacOSXClearMenubarActive(void) void TkpMenuNotifyToplevelCreate( - Tcl_Interp *interp, /* The interp the menu lives in. */ - char *menuName) /* The name of the menu to - * reconfigure. */ + Tcl_Interp *interp, /* The interp the menu lives in. */ + char *menuName) /* The name of the menu to reconfigure. */ { /* * Nothing to do. @@ -3889,30 +3972,47 @@ TkpMenuNotifyToplevelCreate( void TkpMenuInit(void) -{ +{ + MenuSymbol *ms = menuSymbols; + CFStringRef cfStr; + lastMenuID = 256; Tcl_InitHashTable(&commandTable, TCL_ONE_WORD_KEYS); currentMenuBarOwner = NULL; - tearoffStruct.menuPtr = NULL; currentAppleMenuID = 0; currentHelpMenuID = 0; currentMenuBarInterp = NULL; currentMenuBarName = NULL; windowListPtr = NULL; - tkThemeMenuItemDrawingUPP - = NewMenuItemDrawingUPP(ThemeMenuItemDrawingProc); - - /* - * We should just hardcode the utf-8 ellipsis character into - * 'elipsisString' here - */ - Tcl_ExternalToUtf(NULL, Tcl_GetEncoding(NULL, "macRoman"), - "\311", /* ellipsis character */ - -1, 0, NULL, elipsisString, - TCL_UTF_MAX + 1, NULL, NULL, NULL); - +#ifdef USE_TK_MDEF + tkThemeMenuItemDrawingUPP + = NewMenuItemDrawingUPP(ThemeMenuItemDrawingProc); useMDEFVar = Tcl_NewStringObj("::tk::mac::useCustomMDEF", -1); + macMDEFDrawable.drawRgn = NewRgn(); +#endif + + ChkErr(GetThemeMetric, kThemeMetricMenuMarkColumnWidth, + &menuMarkColumnWidth); + ChkErr(GetThemeMetric, kThemeMetricMenuMarkIndent, &menuMarkIndent); + ChkErr(GetThemeMetric, kThemeMetricMenuTextLeadingEdgeMargin, + &menuTextLeadingEdgeMargin); + ChkErr(GetThemeMetric, kThemeMetricMenuTextTrailingEdgeMargin, + &menuTextTrailingEdgeMargin); + ChkErr(GetThemeMenuItemExtra, kThemeMenuItemPlain, &menuItemExtraHeight, + &menuItemExtraWidth); + ChkErr(GetThemeMenuSeparatorHeight, &menuSeparatorHeight); + + while (ms->unicode) { + ms->utfLen = Tcl_UniCharToUtf(ms->unicode, ms->utf); + ms->utf[ms->utfLen] = 0; + cfStr = CFStringCreateWithCharacters(NULL, &ms->unicode, 1); + if (cfStr) { + ms->width = MeasureThemeText(cfStr, kThemeMenuItemCmdKeyFont); + CFRelease(cfStr); + } + ms++; + } } /* @@ -3921,7 +4021,7 @@ TkpMenuInit(void) * TkpMenuThreadInit -- * * Does platform-specific initialization of thread-specific - * menu state. + * menu state. * * Results: * None. @@ -3933,7 +4033,7 @@ TkpMenuInit(void) */ void -TkpMenuThreadInit() +TkpMenuThreadInit(void) { /* * Nothing to do. @@ -3957,16 +4057,16 @@ TkpMenuThreadInit() */ void -TkMacOSXPreprocessMenu() +TkMacOSXPreprocessMenu(void) { - TkMenuReferences *mbRefPtr; - int code; - if ((currentMenuBarName != NULL) && (currentMenuBarInterp != NULL)) { - mbRefPtr = TkFindMenuReferences(currentMenuBarInterp, - currentMenuBarName); - if ((mbRefPtr != NULL) && (mbRefPtr->menuPtr != NULL)) { - Tcl_Preserve((ClientData)currentMenuBarInterp); + TkMenuReferences *mbRefPtr = + TkFindMenuReferences(currentMenuBarInterp,currentMenuBarName); + + if ((mbRefPtr != NULL) && (mbRefPtr->menuPtr != NULL)) { + int code; + + Tcl_Preserve((ClientData) currentMenuBarInterp); code = TkPreprocessMenu(mbRefPtr->menuPtr->masterMenuPtr); if ((code != TCL_OK) && (code != TCL_CONTINUE) && (code != TCL_BREAK)) { @@ -3974,11 +4074,13 @@ TkMacOSXPreprocessMenu() "\n (menu preprocess)"); Tcl_BackgroundError(currentMenuBarInterp); } - Tcl_Release((ClientData)currentMenuBarInterp); - } + Tcl_Release((ClientData) currentMenuBarInterp); + } } } +#ifdef USE_TK_MDEF +#pragma mark MDEF /* *---------------------------------------------------------------------- * @@ -3998,174 +4100,139 @@ TkMacOSXPreprocessMenu() *---------------------------------------------------------------------- */ -static void +void MenuDefProc( - SInt16 message, /* What action are we taking? */ - MenuRef menu, /* The menu we are working with */ - Rect *menuRectPtr, /* A pointer to the rect for the - * whole menu. */ - Point hitPt, /* Where the mouse was clicked for - * the appropriate messages. */ - SInt16 *whichItem) /* Output result. Which item was - * hit by the user? */ + SInt16 message, /* What action are we taking? */ + MenuRef menu, /* The menu we are working with */ + Rect *menuRectPtr, /* A pointer to the rect for the + * whole menu. */ + Point hitPt, /* Where the mouse was clicked for + * the appropriate messages. */ + SInt16 *whichItem) /* Output result. Which item was + * hit by the user? */ { TkMenu *menuPtr; Tcl_HashEntry *commandEntryPtr; - int maxMenuHeight; MenuID menuID; - BitMap screenBits; - + menuID = GetMenuID(menu); - commandEntryPtr = Tcl_FindHashEntry(&commandTable, (char *) ((int)menuID)); - + commandEntryPtr = Tcl_FindHashEntry(&commandTable, (char*)(intptr_t)menuID); + if (commandEntryPtr) { - menuPtr = (TkMenu *) Tcl_GetHashValue(commandEntryPtr); + menuPtr = (TkMenu *) Tcl_GetHashValue(commandEntryPtr); } else { - menuPtr = NULL; + menuPtr = NULL; } switch (message) { - case kMenuInitMsg: - *whichItem = noErr; - break; - case kMenuDisposeMsg: - break; - case kMenuHiliteItemMsg: { - HandleMenuHiliteMsg (menu, menuRectPtr, hitPt, whichItem, menuPtr); - break; - } - case kMenuCalcItemMsg: - HandleMenuCalcItemMsg (menu, menuRectPtr, hitPt, whichItem, menuPtr); - break; - case kMenuDrawItemsMsg: { - /* - * We do nothing here, because we don't support the Menu Managers - * dynamic item groups - */ - - break; - } - case kMenuThemeSavvyMsg: - *whichItem = kThemeSavvyMenuResponse; - break; - case kMenuSizeMsg: - GetQDGlobalsScreenBits(&screenBits); - maxMenuHeight = screenBits.bounds.bottom - - screenBits.bounds.top - - GetMBarHeight() - SCREEN_MARGIN; - SetMenuWidth(menu, menuPtr->totalWidth ); - SetMenuHeight(menu,maxMenuHeight < menuPtr->totalHeight ? maxMenuHeight : menuPtr->totalHeight ); - break; - case kMenuDrawMsg: - HandleMenuDrawMsg (menu, menuRectPtr, hitPt, whichItem, menuPtr); - break; - case kMenuFindItemMsg: - HandleMenuFindItemsMsg (menu, menuRectPtr, hitPt, whichItem, menuPtr); - break; - case kMenuPopUpMsg: - HandleMenuPopUpMsg (menu, menuRectPtr, hitPt, whichItem, menuPtr); - break; + case kMenuInitMsg: + *whichItem = noErr; + break; + case kMenuDisposeMsg: + break; + case kMenuHiliteItemMsg: + HandleMenuHiliteMsg(menu, menuRectPtr, hitPt, whichItem, menuPtr); + break; + case kMenuCalcItemMsg: + HandleMenuCalcItemMsg(menu, menuRectPtr, hitPt, whichItem, + menuPtr); + break; + case kMenuDrawItemsMsg: +#ifdef TK_MAC_DEBUG_MENUS + TkMacOSXDbgMsg("MDEF: DrawItemsMsg"); +#endif + /* + * We do nothing here, because we don't support the Menu Managers + * dynamic item groups + */ + break; + case kMenuThemeSavvyMsg: + *whichItem = kThemeSavvyMenuResponse; + break; + case kMenuSizeMsg: +#ifdef TK_MAC_DEBUG_MENUS + TkMacOSXDbgMsg("MDEF: SizeMsg %d, %d", hitPt.h, hitPt.v); +#endif + SetMenuWidth(menu, hitPt.h < menuPtr->totalWidth ? hitPt.h : + menuPtr->totalWidth); + SetMenuHeight(menu, hitPt.v < menuPtr->totalHeight ? hitPt.v : + menuPtr->totalHeight); + break; + case kMenuDrawMsg: + HandleMenuDrawMsg(menu, menuRectPtr, hitPt, whichItem, menuPtr); + break; + case kMenuFindItemMsg: + HandleMenuFindItemMsg(menu, menuRectPtr, hitPt, whichItem, + menuPtr); + break; + case kMenuPopUpMsg: + HandleMenuPopUpMsg(menu, menuRectPtr, hitPt, whichItem, menuPtr); + break; } } + +/* + *---------------------------------------------------------------------- + * + * HandleMenuHiliteMsg -- + * + * Handles the MenuDefProc's hilite message. + * + * Results: + * A menu entry is drawn + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ void -HandleMenuHiliteMsg (MenuRef menu, - Rect *menuRectPtr, - Point hitPt, - SInt16 *whichItem, - TkMenu *menuPtr) +HandleMenuHiliteMsg( + MenuRef menu, + Rect *menuRectPtr, + Point hitPt, + SInt16 *whichItem, + TkMenu *menuPtr) { - TkMenuEntry *mePtr = NULL; + OSStatus err; Tk_Font tkfont; Tk_FontMetrics fontMetrics; - int oldItem; - int newItem = -1; - MDEFHiliteItemData * hidPtr = ( MDEFHiliteItemData *)whichItem; - MenuTrackingData mtd, *mtdPtr = &mtd; - int err; - oldItem = hidPtr->previousItem - 1; - newItem = hidPtr->newItem - 1; - - err = GetMenuTrackingData(menu, mtdPtr); - if (err !=noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"GetMenuTrackingData failed : %d\n", err ); + MDEFHiliteItemData *hidPtr = (MDEFHiliteItemData *)whichItem; + int oldItem = hidPtr->previousItem - 1; + int newItem = hidPtr->newItem - 1; + MenuTrackingData mtd, *mtdPtr = &mtd; + +#ifdef TK_MAC_DEBUG_MENUS + TkMacOSXDbgMsg("MDEF: HiliteMsg %d -> %d", hidPtr->previousItem, + hidPtr->newItem); #endif - return; + GetPort(&macMDEFDrawable.grafPtr); + macMDEFDrawable.context = (CGContextRef)hidPtr->context; + + err = ChkErr(GetMenuTrackingData, menu, mtdPtr); + if (err != noErr) { + return; } - + + tkfont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); + Tk_GetFontMetrics(tkfont, &fontMetrics); if (oldItem >= 0) { - Rect oldItemRect; - int width; - - mePtr = menuPtr->entries[oldItem]; - if (mePtr->fontPtr == NULL) { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, - menuPtr->fontPtr); - } else { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, - mePtr->fontPtr); - } - Tk_GetFontMetrics(tkfont, &fontMetrics); - - width = (mePtr->entryFlags & ENTRY_LAST_COLUMN) - ? menuPtr->totalWidth - mePtr->x : mePtr->width; - - /* - * In Aqua, have to call EraseMenuBackground when you overdraw - * a previously selected menu item, otherwise you will see the - * old select highlight under the transparency of the new menu item. - */ - - oldItemRect.left = menuRectPtr->left + mePtr->x; - oldItemRect.right = oldItemRect.left +width; - oldItemRect.top = mtdPtr->virtualMenuTop + mePtr->y; - oldItemRect.bottom = oldItemRect.top + mePtr->height; - - EraseMenuBackground(menu, & oldItemRect, NULL); - - AppearanceEntryDrawWrapper(mePtr, menuRectPtr, mtdPtr, - (Drawable) &macMDEFDrawable, &fontMetrics, tkfont, - oldItemRect.left, - oldItemRect.top, - width, - mePtr->height); + AppearanceEntryDrawWrapper(menuPtr->entries[oldItem], menuRectPtr, + mtdPtr, (Drawable) &macMDEFDrawable, &fontMetrics, tkfont, 1); } - if (newItem != -1) { - mePtr = menuPtr->entries[newItem]; - if (mePtr->state != ENTRY_DISABLED) { - TkActivateMenuEntry(menuPtr, newItem); - } - if (mePtr->fontPtr == NULL) { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); - } else { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr); - } - Tk_GetFontMetrics(tkfont, &fontMetrics); - AppearanceEntryDrawWrapper(mePtr, menuRectPtr, mtdPtr, - (Drawable) &macMDEFDrawable, &fontMetrics, tkfont, - menuRectPtr->left + mePtr->x, - mtdPtr->virtualMenuTop + mePtr->y, - (mePtr->entryFlags & ENTRY_LAST_COLUMN) ? - menuPtr->totalWidth - mePtr->x : mePtr->width, - mePtr->height); + if (newItem >= 0) { + AppearanceEntryDrawWrapper(menuPtr->entries[newItem], menuRectPtr, + mtdPtr, (Drawable) &macMDEFDrawable, &fontMetrics, tkfont, 0); } - tkUseMenuCascadeRgn = 1; - MenuSelectEvent(menuPtr); - Tcl_ServiceAll(); - tkUseMenuCascadeRgn = 0; - if (newItem!=-1 && mePtr->state != ENTRY_DISABLED) { - TkActivateMenuEntry(menuPtr, -1); - } - } - + /* *---------------------------------------------------------------------- * - * HandleMenuDrawMsg -- + * HandleMenuDrawMsg -- * - * It handles the MenuDefProc's draw message. + * Handles the MenuDefProc's draw message. * * Results: * A menu entry is drawn @@ -4175,159 +4242,133 @@ HandleMenuHiliteMsg (MenuRef menu, * *---------------------------------------------------------------------- */ + void -HandleMenuDrawMsg(MenuRef menu, - Rect *menuRectPtr, - Point hitPt, - SInt16 *whichItem, - TkMenu *menuPtr) +HandleMenuDrawMsg( + MenuRef menu, + Rect *menuRectPtr, + Point hitPt, + SInt16 *whichItem, + TkMenu *menuPtr) { - Tk_Font tkfont, menuFont; - Tk_FontMetrics fontMetrics, entryMetrics; - Tk_FontMetrics *fmPtr; + Tk_Font menuFont; + Tk_FontMetrics fontMetrics; TkMenuEntry *mePtr; int i; - GDHandle device; - TkMenu *searchMenuPtr; - Rect menuClipRect; - ThemeMenuType menuType; - MenuTrackingData * mtdPtr = (MenuTrackingData *)whichItem; - /* - * Store away the menu rectangle so we can keep track of the - * different regions that the menu obscures. - */ - - ((MacMenu *) menuPtr->platformData)->menuRect = *menuRectPtr; - if (tkMenuCascadeRgn == NULL) { - tkMenuCascadeRgn = NewRgn(); - } - if (utilRgn == NULL) { - utilRgn = NewRgn(); - } - if (totalMenuRgn == NULL) { - totalMenuRgn = NewRgn(); - } - SetEmptyRgn(tkMenuCascadeRgn); - for (searchMenuPtr = menuPtr; searchMenuPtr != NULL; ) { - RectRgn(utilRgn, - &((MacMenu *) searchMenuPtr->platformData)->menuRect); - InsetRgn(utilRgn, -1, -1); - UnionRgn(tkMenuCascadeRgn, utilRgn, tkMenuCascadeRgn); - OffsetRgn(utilRgn, 1, 1); - UnionRgn(tkMenuCascadeRgn, utilRgn, tkMenuCascadeRgn); - - if (searchMenuPtr->menuRefPtr->parentEntryPtr != NULL) { - searchMenuPtr = searchMenuPtr->menuRefPtr - ->parentEntryPtr->menuPtr; - } else { - break; - } - if (searchMenuPtr->menuType == MENUBAR) { - break; - } - } - UnionRgn(totalMenuRgn, tkMenuCascadeRgn, totalMenuRgn); - SetEmptyRgn(utilRgn); - - /* - * Now draw the background if Appearance is present... - */ - - GetGWorld(&macMDEFDrawable.grafPtr, &device); - + Rect menuClipRect, bounds; + MDEFDrawData *ddPtr = (MDEFDrawData*)whichItem; + MenuTrackingData *mtdPtr = &(ddPtr->trackingData); + TkWindow *winPtr = (TkWindow*)menuPtr->tkwin; + + GetPort(&macMDEFDrawable.grafPtr); + GetPortBounds(macMDEFDrawable.grafPtr, &bounds); + macMDEFDrawable.context = (CGContextRef)ddPtr->context; +#ifdef TK_MAC_DEBUG_MENUS + TkMacOSXDbgMsg("MDEF: DrawMsg %d - %d; %d - %d", menuRectPtr->top, + menuRectPtr->bottom, bounds.top, bounds.bottom); +#endif + winPtr->changes.x = menuRectPtr->left; + winPtr->changes.y = menuRectPtr->top; + winPtr->changes.width = menuRectPtr->right - menuRectPtr->left; + winPtr->changes.height = menuRectPtr->bottom - menuRectPtr->top; + TkpClipDrawableToRect(menuPtr->display, (Drawable) &macMDEFDrawable, + 0, 0, -1, -1); +#if 0 if (menuPtr->menuRefPtr->topLevelListPtr != NULL) { - menuType = kThemeMenuTypePullDown; + menuType = kThemeMenuTypePullDown; } else if (menuPtr->menuRefPtr->parentEntryPtr != NULL) { - menuType = kThemeMenuTypeHierarchical; + menuType = kThemeMenuTypeHierarchical; } else { - menuType = kThemeMenuTypePopUp; + menuType = kThemeMenuTypePopUp; } - - DrawMenuBackground(menuRectPtr, (Drawable) &macMDEFDrawable, menuType); - - /* - * Next, figure out scrolling information. - */ - +#endif + DrawMenuBackground(menuPtr, menuRectPtr, (Drawable) &macMDEFDrawable); + menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); + Tk_GetFontMetrics(menuFont, &fontMetrics); menuClipRect = *menuRectPtr; - if ((menuClipRect.bottom - menuClipRect.top) - < menuPtr->totalHeight) { - if (mtdPtr->virtualMenuTop < menuRectPtr->top) { - DrawSICN(SICN_RESOURCE_NUMBER, UP_ARROW, - (Drawable) &macMDEFDrawable, - menuPtr->textGC, - menuRectPtr->left + menuPtr->entries[1]->indicatorSpace, - menuRectPtr->top); - menuClipRect.top += SICN_HEIGHT; - } - if ((mtdPtr->virtualMenuTop + menuPtr->totalHeight) - > menuRectPtr->bottom) { - DrawSICN(SICN_RESOURCE_NUMBER, DOWN_ARROW, - (Drawable) &macMDEFDrawable, - menuPtr->textGC, - menuRectPtr->left + menuPtr->entries[1]->indicatorSpace, - menuRectPtr->bottom - SICN_HEIGHT); - menuClipRect.bottom -= SICN_HEIGHT; - } - GetClip(utilRgn); + mtdPtr->virtualMenuBottom = mtdPtr->virtualMenuTop + menuPtr->totalHeight; + + /* + * Next, figure out scrolling information. + */ + + if ((menuRectPtr->bottom - menuRectPtr->top) < menuPtr->totalHeight) { + short arrowHeight = fontMetrics.linespace + 1; + Rect arrowRect, eraseRect; + ThemeMenuState menuState = IsMenuItemEnabled(menu, 0) ? + kThemeMenuActive : kThemeMenuDisabled; + + if (mtdPtr->virtualMenuTop < menuRectPtr->top) { + arrowRect = bounds; + /*arrowRect.top += 1;*/ + arrowRect.bottom = arrowRect.top + arrowHeight; + eraseRect = arrowRect; + eraseRect.top = menuRectPtr->top; + menuClipRect.top = arrowRect.bottom; + ChkErr(EraseMenuBackground, menu, &eraseRect, + macMDEFDrawable.context); + ChkErr(DrawThemeMenuItem, menuRectPtr, &arrowRect, + mtdPtr->virtualMenuTop, mtdPtr->virtualMenuBottom, + menuState, kThemeMenuItemScrollUpArrow, NULL, 0); +#ifdef TK_MAC_DEBUG_MENUS + TkMacOSXDbgMsg("upArrow: %d - %d, %d - %d", arrowRect.top, + arrowRect.bottom, arrowRect.left, arrowRect.right); +#endif + } + if (mtdPtr->virtualMenuBottom > menuRectPtr->bottom) { + arrowRect = bounds; + arrowRect.bottom -= 1; + arrowRect.top = arrowRect.bottom - arrowHeight; + eraseRect = arrowRect; + eraseRect.bottom = menuRectPtr->bottom; + menuClipRect.bottom = arrowRect.top; + ChkErr(EraseMenuBackground, menu, &eraseRect, + macMDEFDrawable.context); + ChkErr(DrawThemeMenuItem, menuRectPtr, &arrowRect, + mtdPtr->virtualMenuTop, mtdPtr->virtualMenuBottom, + menuState, kThemeMenuItemScrollDownArrow, NULL, 0); +#ifdef TK_MAC_DEBUG_MENUS + TkMacOSXDbgMsg("downArrow: %d - %d, %d - %d", arrowRect.top, + arrowRect.bottom, arrowRect.left, arrowRect.right); +#endif + } + TkpClipDrawableToRect(menuPtr->display, (Drawable) &macMDEFDrawable, + menuClipRect.left, menuClipRect.top, menuClipRect.right - + menuClipRect.left, menuClipRect.bottom - menuClipRect.top); } - + /* - * Now, actually draw the menu. Don't draw entries that - * are higher than the top arrow, and don't draw entries - * that are lower than the bottom. - */ - - menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); - Tk_GetFontMetrics(menuFont, &fontMetrics); + * Now, actually draw the menu. Don't draw entries that + * are higher than the top arrow, and don't draw entries + * that are lower than the bottom. + */ + for (i = 0; i < menuPtr->numEntries; i++) { - mePtr = menuPtr->entries[i]; - if (mtdPtr->virtualMenuTop + mePtr->y + mePtr->height - < menuClipRect.top) { - continue; - } else if (mtdPtr->virtualMenuTop + mePtr->y - > menuClipRect.bottom) { - continue; - } - ClipRect(&menuClipRect); - if (mePtr->fontPtr == NULL) { - fmPtr = &fontMetrics; - tkfont = menuFont; - } else { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr); - Tk_GetFontMetrics(tkfont, &entryMetrics); - fmPtr = &entryMetrics; - } - AppearanceEntryDrawWrapper(mePtr, menuRectPtr, mtdPtr, - (Drawable) &macMDEFDrawable, fmPtr, tkfont, - menuRectPtr->left + mePtr->x, - mtdPtr->virtualMenuTop + mePtr->y, - (mePtr->entryFlags & ENTRY_LAST_COLUMN) ? - menuPtr->totalWidth - mePtr->x : mePtr->width, - menuPtr->entries[i]->height); - } - mtdPtr->virtualMenuBottom = mtdPtr->virtualMenuTop - + menuPtr->totalHeight; - if (!EmptyRgn(utilRgn)) { - SetClip(utilRgn); - SetEmptyRgn(utilRgn); + mePtr = menuPtr->entries[i]; + if (mtdPtr->virtualMenuTop + mePtr->y + mePtr->height < + menuClipRect.top || mtdPtr->virtualMenuTop + mePtr->y > + menuClipRect.bottom) { + continue; + } + AppearanceEntryDrawWrapper(mePtr, menuRectPtr, mtdPtr, + (Drawable) &macMDEFDrawable, &fontMetrics, menuFont, 0); } MDEFScrollFlag = 1; } - + /* *---------------------------------------------------------------------- * - * HandleMenuFindItemsMsg -- + * HandleMenuFindItemMsg -- * - * It handles the MenuDefProc's FindItems message. We have to - * respond by filling in the itemSelected, itemUnderMouse and - * itemRect fields. This is also the time to scroll the menu if - * it is too long to fit on the screen. + * Handles the MenuDefProc's FindItems message. We have to + * respond by filling in the itemSelected, itemUnderMouse and + * itemRect fields. This is also the time to scroll the menu if + * it is too long to fit on the screen. * * Results: * The Menu system is informed of the selected item & the item - * under the mouse. + * under the mouse. * * Side effects: * The menu might get scrolled. @@ -4335,327 +4376,226 @@ HandleMenuDrawMsg(MenuRef menu, *---------------------------------------------------------------------- */ void -HandleMenuFindItemsMsg (MenuRef menu, - Rect *menuRectPtr, - Point hitPt, - SInt16 *whichItem, - TkMenu *menuPtr) +HandleMenuFindItemMsg( + MenuRef menu, + Rect *menuRectPtr, + Point hitPt, + SInt16 *whichItem, + TkMenu *menuPtr) { - TkMenuEntry *parentEntryPtr; -#if 0 /* Unused */ - Tk_Font tkfont; - Tk_FontMetrics fontMetrics, entryMetrics; - Tk_FontMetrics *fmPtr; -#endif + Tk_Font menuFont; + Tk_FontMetrics fontMetrics; TkMenuEntry *mePtr; - int i; - int newItem = -1; - GDHandle device; - Rect itemRect; - short windowPart; - WindowRef whichWindow; - RGBColor bgColor; - RGBColor fgColor; - RGBColor origFgColor; - PenState origPenState; - Rect dragRect; - Rect scratchRect = {-32768, -32768, 32767, 32767}; - RgnHandle oldClipRgn; - TkMenuReferences *menuRefPtr; - Rect menuClipRect; - + int i, newItem = -1, itemUnderMouse = -1; + Rect itemRect = {0, 0, 0, 0}, menuClipRect, bounds; int hasTopScroll, hasBottomScroll; - MenuTrackingData * mtdPtr = (MenuTrackingData *)whichItem; - int itemUnderMouse = -1; + MDEFFindItemData *fiPtr = (MDEFFindItemData *)whichItem; + MenuTrackingData *mtdPtr = &(fiPtr->trackingData), topMtd; enum { - DONT_SCROLL, DOWN_SCROLL, UP_SCROLL + DONT_SCROLL, DOWN_SCROLL, UP_SCROLL } scrollDirection; - Rect updateRect; - short scrollAmt = 0; - RGBColor origForeColor, origBackColor; - - /* - * Find out which item was hit. If it is the same as the old item, - * we don't need to do anything. - */ + short arrowHeight; - if (PtInRect(hitPt, menuRectPtr)) { - for (i = 0; i < menuPtr->numEntries; i++) { - mePtr = menuPtr->entries[i]; - itemRect.left = menuRectPtr->left + mePtr->x; - itemRect.top = mtdPtr->virtualMenuTop + mePtr->y; - if (mePtr->entryFlags & ENTRY_LAST_COLUMN) { - itemRect.right = itemRect.left + menuPtr->totalWidth - - mePtr->x; - } else { - itemRect.right = itemRect.left + mePtr->width; - } - itemRect.bottom = itemRect.top - + mePtr->height; - if (PtInRect(hitPt, &itemRect)) { - if ((mePtr->type == SEPARATOR_ENTRY) - || (mePtr->state == ENTRY_DISABLED)) { - newItem = -1; - itemUnderMouse = i; - } else { - TkMenuEntry *cascadeEntryPtr; - int parentDisabled = 0; - - for (cascadeEntryPtr - = menuPtr->menuRefPtr->parentEntryPtr; - cascadeEntryPtr != NULL; - cascadeEntryPtr - = cascadeEntryPtr->nextCascadePtr) { - char *name; - - name = Tcl_GetStringFromObj( - cascadeEntryPtr->namePtr, NULL); - if (strcmp(name, Tk_PathName(menuPtr->tkwin)) - == 0) { - if (cascadeEntryPtr->state == ENTRY_DISABLED) { - parentDisabled = 1; - } - break; - } - } - - if (parentDisabled) { - newItem = -1; - itemUnderMouse = i; - } else { - newItem = i; - itemUnderMouse = i; - } - } - break; - } - } - } else { +#ifdef TK_MAC_DEBUG_MENUS + static Point lastHitPt = {0, 0}; + if (hitPt.h != lastHitPt.h || hitPt.v != lastHitPt.v) { + lastHitPt = hitPt; + TkMacOSXDbgMsg("MDEF: FindItemMsg: %d, %d", hitPt.h, hitPt.v); } +#endif + + GetPort(&macMDEFDrawable.grafPtr); + GetPortBounds(macMDEFDrawable.grafPtr, &bounds); + macMDEFDrawable.context = (CGContextRef)fiPtr->context; /* * Now we need to take care of scrolling the menu. */ - + + menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); + Tk_GetFontMetrics(menuFont, &fontMetrics); + arrowHeight = fontMetrics.linespace + 1; + menuClipRect = *menuRectPtr; hasTopScroll = mtdPtr->virtualMenuTop < menuRectPtr->top; hasBottomScroll = mtdPtr->virtualMenuBottom > menuRectPtr->bottom; scrollDirection = DONT_SCROLL; - if (hasTopScroll && (hitPt.v < menuRectPtr->top + SICN_HEIGHT)) { - newItem = -1; - scrollDirection = DOWN_SCROLL; - } else if (hasBottomScroll && (hitPt.v > (menuRectPtr->bottom - SICN_HEIGHT))) { - newItem = -1; - scrollDirection = UP_SCROLL; - } - - menuClipRect = *menuRectPtr; if (hasTopScroll) { - menuClipRect.top += SICN_HEIGHT; + menuClipRect.top = bounds.top + arrowHeight; + if (hitPt.v < menuClipRect.top) { + newItem = -1; + scrollDirection = DOWN_SCROLL; + } } if (hasBottomScroll) { - menuClipRect.bottom -= SICN_HEIGHT; + menuClipRect.bottom = bounds.bottom - 1 - arrowHeight; + if (hitPt.v > menuClipRect.bottom) { + newItem = -1; + scrollDirection = UP_SCROLL; + } } if (MDEFScrollFlag) { - scrollDirection = DONT_SCROLL; - MDEFScrollFlag = 0; + scrollDirection = DONT_SCROLL; + MDEFScrollFlag = 0; } - GetClip(utilRgn); - ClipRect(&menuClipRect); - - mtdPtr->itemSelected = newItem + 1; - mtdPtr->itemUnderMouse = itemUnderMouse + 1; - mtdPtr->itemRect = itemRect; - - GetGWorld(&macMDEFDrawable.grafPtr, &device); - GetForeColor(&origForeColor); - GetBackColor(&origBackColor); - - if (scrollDirection == UP_SCROLL) { - scrollAmt = menuClipRect.bottom - hitPt.v; - if (scrollAmt < menuRectPtr->bottom - - mtdPtr->virtualMenuBottom) { - scrollAmt = menuRectPtr->bottom - mtdPtr->virtualMenuBottom; - } - if (!hasTopScroll && ((mtdPtr->virtualMenuTop + scrollAmt) - < menuRectPtr->top)) { - SetRect(&updateRect, menuRectPtr->left, - mtdPtr->virtualMenuTop, menuRectPtr->right, - mtdPtr->virtualMenuTop + SICN_HEIGHT); - EraseRect(&updateRect); - DrawSICN(SICN_RESOURCE_NUMBER, UP_ARROW, - (Drawable) &macMDEFDrawable, - menuPtr->textGC, menuRectPtr->left - + menuPtr->entries[1]->indicatorSpace, - menuRectPtr->top); - menuClipRect.top += SICN_HEIGHT; - } - } else if (scrollDirection == DOWN_SCROLL) { - - scrollAmt = menuClipRect.top - hitPt.v; - if (scrollAmt > menuRectPtr->top - mtdPtr->virtualMenuTop) { - scrollAmt = menuRectPtr->top - mtdPtr->virtualMenuTop; - } - - if (!hasBottomScroll && ((mtdPtr->virtualMenuBottom + scrollAmt) - > menuRectPtr->bottom)) { - SetRect(&updateRect, menuRectPtr->left, - mtdPtr->virtualMenuBottom - SICN_HEIGHT, - menuRectPtr->right, mtdPtr->virtualMenuBottom); - EraseRect(&updateRect); - DrawSICN(SICN_RESOURCE_NUMBER, DOWN_ARROW, - (Drawable) &macMDEFDrawable, - menuPtr->textGC, menuRectPtr->left - + menuPtr->entries[1]->indicatorSpace, - menuRectPtr->bottom - SICN_HEIGHT); - menuClipRect.bottom -= SICN_HEIGHT; - } + /* + * Don't scroll if there are other menus open above us + */ + ChkErr(GetMenuTrackingData, NULL, &topMtd); + if (menu != topMtd.menu) { + scrollDirection = DONT_SCROLL; } - - if (scrollDirection != DONT_SCROLL) { -#if 0 - Tk_Font menuFont; - RgnHandle updateRgn = NewRgn(); + if (scrollDirection == DONT_SCROLL) { + /* + * Find out which item was hit. If it is the same as the old item, + * we don't need to do anything. + */ + + if (PtInRect(hitPt, menuRectPtr)) { + for (i = 0; i < menuPtr->numEntries; i++) { + mePtr = menuPtr->entries[i]; + itemRect.left = menuRectPtr->left + mePtr->x; + itemRect.top = mtdPtr->virtualMenuTop + mePtr->y; + itemRect.right = mePtr->entryFlags & ENTRY_LAST_COLUMN ? + menuRectPtr->right : itemRect.left + mePtr->width; + itemRect.bottom = itemRect.top + mePtr->height; + if (PtInRect(hitPt, &itemRect)) { + if ((mePtr->type == SEPARATOR_ENTRY) + || (mePtr->state == ENTRY_DISABLED)) { + newItem = -1; + itemUnderMouse = i; + } else { + TkMenuEntry *parentEntryPtr = + GetParentMenuEntry(menuPtr); + + if (parentEntryPtr && + parentEntryPtr->state == ENTRY_DISABLED) { + newItem = -1; + itemUnderMouse = i; + } else { + newItem = i; + itemUnderMouse = i; + } + } + break; + } + } + } + } else { + short scrollAmt; + unsigned long scrollDelay; + Rect arrowRect, eraseRect, scrolledMenuClipRect; + ThemeMenuState menuState = IsMenuItemEnabled(menu, 0) ? + kThemeMenuActive : kThemeMenuDisabled; + int oldItem = mtdPtr->itemSelected - 1; + short d; + + TkpClipDrawableToRect(menuPtr->display, (Drawable) &macMDEFDrawable, + 0, 0, -1, -1); + scrollAmt = fontMetrics.linespace + menuItemExtraHeight; + if (scrollDirection == UP_SCROLL) { + scrollAmt = -scrollAmt; + d = hitPt.v - bounds.bottom; + } else { + d = bounds.top - hitPt.v; + } + scrollDelay = (d >= scrollAmt/2) ? 1 : 10; + menuClipRect = *menuRectPtr; + if (mtdPtr->virtualMenuTop + scrollAmt < menuRectPtr->top) { + arrowRect = bounds; + /*arrowRect.top += 1;*/ + arrowRect.bottom = arrowRect.top + arrowHeight; + eraseRect = arrowRect; + eraseRect.top = menuRectPtr->top; + menuClipRect.top = arrowRect.bottom; + if (!hasTopScroll) { + ChkErr(EraseMenuBackground, menu, &eraseRect, + macMDEFDrawable.context); + ChkErr(DrawThemeMenuItem, menuRectPtr, &arrowRect, + mtdPtr->virtualMenuTop + scrollAmt, + mtdPtr->virtualMenuBottom + scrollAmt, + menuState, kThemeMenuItemScrollUpArrow, NULL, 0); +#ifdef TK_MAC_DEBUG_MENUS + TkMacOSXDbgMsg("upArrow: %d - %d, %d - %d", arrowRect.top, + arrowRect.bottom, arrowRect.left, arrowRect.right); #endif - - ScrollMenuImage(menu, menuRectPtr, 0, scrollAmt, NULL); - mtdPtr->virtualMenuTop += scrollAmt; - mtdPtr->virtualMenuBottom += scrollAmt; -#if 0 - GetRegionBounds(updateRgn,&updateRect); - DisposeRgn(updateRgn); - if (mtdPtr->virtualMenuTop == menuRectPtr->top) { - updateRect.top -= SICN_HEIGHT; - } - if (mtdPtr->virtualMenuBottom == menuRectPtr->bottom) { - updateRect.bottom += SICN_HEIGHT; - } - ClipRect(&updateRect); - EraseRect(&updateRect); - menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); - Tk_GetFontMetrics(menuFont, &fontMetrics); - for (i = 0; i < menuPtr->numEntries; i++) { - mePtr = menuPtr->entries[i]; - if (mtdPtr->virtualMenuTop + mePtr->y + mePtr->height - < updateRect.top) { - continue; - } else if (mtdPtr->virtualMenuTop + mePtr->y - > updateRect.bottom) { - continue; - } - if (mePtr->fontPtr == NULL) { - fmPtr = &fontMetrics; - tkfont = menuFont; - } else { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, - mePtr->fontPtr); - Tk_GetFontMetrics(tkfont, &entryMetrics); - fmPtr = &entryMetrics; - } - AppearanceEntryDrawWrapper(mePtr, menuRectPtr, mtdPtr, - (Drawable) &macMDEFDrawable, fmPtr, tkfont, - menuRectPtr->left + mePtr->x, - mtdPtr->virtualMenuTop + mePtr->y, - (mePtr->entryFlags & ENTRY_LAST_COLUMN) ? - menuPtr->totalWidth - mePtr->x : mePtr->width, - menuPtr->entries[i]->height); - } + } + } + if (mtdPtr->virtualMenuBottom + scrollAmt > menuRectPtr->bottom) { + arrowRect = bounds; + arrowRect.bottom -= 1; + arrowRect.top = arrowRect.bottom - arrowHeight; + eraseRect = arrowRect; + eraseRect.bottom = menuRectPtr->bottom; + menuClipRect.bottom = arrowRect.top; + if (!hasBottomScroll) { + ChkErr(EraseMenuBackground, menu, &eraseRect, + macMDEFDrawable.context); + ChkErr(DrawThemeMenuItem, menuRectPtr, &arrowRect, + mtdPtr->virtualMenuTop + scrollAmt, + mtdPtr->virtualMenuBottom + scrollAmt, + menuState, kThemeMenuItemScrollDownArrow, NULL, 0); +#ifdef TK_MAC_DEBUG_MENUS + TkMacOSXDbgMsg("downArrow: %d - %d, %d - %d", arrowRect.top, + arrowRect.bottom, arrowRect.left, arrowRect.right); #endif + } + } + TkpClipDrawableToRect(menuPtr->display, (Drawable) &macMDEFDrawable, + menuClipRect.left, menuClipRect.top, menuClipRect.right - + menuClipRect.left, menuClipRect.bottom - menuClipRect.top); + TkActivateMenuEntry(menuPtr, -1); + if (oldItem >= 0) { + AppearanceEntryDrawWrapper(menuPtr->entries[oldItem], menuRectPtr, + mtdPtr, (Drawable) &macMDEFDrawable, &fontMetrics, + menuFont, 1); + } + ChkErr(ScrollMenuImage, menu, &menuClipRect, 0, scrollAmt, + macMDEFDrawable.context); + mtdPtr->virtualMenuTop += scrollAmt; + mtdPtr->virtualMenuBottom += scrollAmt; + scrolledMenuClipRect = menuClipRect; + OffsetRect(&scrolledMenuClipRect, 0, scrollAmt); + menuClipRect = bounds; + if (mtdPtr->virtualMenuTop < menuRectPtr->top) { + menuClipRect.top += arrowHeight; + } + if (mtdPtr->virtualMenuBottom > menuRectPtr->bottom) { + menuClipRect.bottom -= arrowHeight; + } + TkpClipDrawableToRect(menuPtr->display, (Drawable) &macMDEFDrawable, + menuClipRect.left, menuClipRect.top, menuClipRect.right - + menuClipRect.left, menuClipRect.bottom - menuClipRect.top); + if (scrolledMenuClipRect.bottom < menuClipRect.bottom) { + menuClipRect.top = scrolledMenuClipRect.bottom; + } else if (scrolledMenuClipRect.top < menuClipRect.top) { + menuClipRect.bottom = scrolledMenuClipRect.top; + } + for (i = 0; i < menuPtr->numEntries; i++) { + mePtr = menuPtr->entries[i]; + if (mtdPtr->virtualMenuTop + mePtr->y + mePtr->height < + menuClipRect.top || mtdPtr->virtualMenuTop + mePtr->y > + menuClipRect.bottom) { + continue; + } +#ifdef TK_MAC_DEBUG_MENUS + TkMacOSXDbgMsg("Drawing item %i", i); +#endif + AppearanceEntryDrawWrapper(mePtr, menuRectPtr, mtdPtr, + (Drawable) &macMDEFDrawable, &fontMetrics, menuFont, 1); + } + Delay(scrollDelay, NULL); } - - SetClip(utilRgn); - SetEmptyRgn(utilRgn); - RGBForeColor(&origForeColor); - RGBBackColor(&origBackColor); - - /* - * If the menu is a tearoff, and the mouse is outside the menu, - * we need to draw the drag rectangle. - * - * In order for tearoffs to work properly, we need to set - * the active member of the containing menubar. - */ - - menuRefPtr = TkFindMenuReferences(menuPtr->interp, - Tk_PathName(menuPtr->tkwin)); - - if ((menuRefPtr != NULL) && (menuRefPtr->parentEntryPtr != NULL)) { - char *name; - for (parentEntryPtr = menuRefPtr->parentEntryPtr; - parentEntryPtr != NULL - ; parentEntryPtr = parentEntryPtr->nextCascadePtr) { - name = Tcl_GetStringFromObj(parentEntryPtr->namePtr, - NULL); - if (strcmp(name, Tk_PathName(menuPtr->tkwin)) != 0) { - break; - } - } - if (parentEntryPtr != NULL) { - TkActivateMenuEntry(parentEntryPtr->menuPtr, - parentEntryPtr->index); - } - } - - if (menuPtr->tearoff) { - scratchRect = *menuRectPtr; - if (tearoffStruct.menuPtr == NULL) { - scratchRect.top -= 10; - scratchRect.bottom += 10; - scratchRect.left -= 10; - scratchRect.right += 10; - } - - windowPart = FindWindow(hitPt, &whichWindow); - if ((windowPart != inMenuBar) && (newItem == -1) - && (hitPt.v != 0) && (hitPt.h != 0) - && (!PtInRect(hitPt, &scratchRect)) - && (!PtInRect(hitPt, &tearoffStruct.excludeRect))) { - unsigned long dummy; - oldClipRgn = NewRgn(); - GetClip(oldClipRgn); - GetForeColor(&origFgColor); - GetPenState(&origPenState); - GetForeColor(&fgColor); - GetBackColor(&bgColor); - GetGray(device, &bgColor, &fgColor); - RGBForeColor(&fgColor); - SetRect(&scratchRect, -32768, -32768, 32767, 32767); - ClipRect(&scratchRect); - - dragRect = *menuRectPtr; - tearoffStruct.menuPtr = menuPtr; - - PenMode(srcXor); - dragRect = *menuRectPtr; - OffsetRect(&dragRect, -dragRect.left, -dragRect.top); - OffsetRect(&dragRect, tearoffStruct.point.h, - tearoffStruct.point.v); - if ((dragRect.top != 0) && (dragRect.left != 0)) { - FrameRect(&dragRect); - Delay(1, &dummy); - FrameRect(&dragRect); - } - tearoffStruct.point = hitPt; - - SetClip(oldClipRgn); - DisposeRgn(oldClipRgn); - RGBForeColor(&origFgColor); - SetPenState(&origPenState); - } else { - tearoffStruct.menuPtr = NULL; - tearoffStruct.point.h = tearoffStruct.point.v = 0; - } - } else { - tearoffStruct.menuPtr = NULL; - tearoffStruct.point.h = tearoffStruct.point.v = 0; - } + mtdPtr->itemSelected = newItem + 1; + mtdPtr->itemUnderMouse = itemUnderMouse + 1; + mtdPtr->itemRect = itemRect; } - + /* *---------------------------------------------------------------------- * - * HandleMenuPopUpMsg -- + * HandleMenuPopUpMsg -- * - * It handles the MenuDefProc's PopUp message. The menu is + * Handles the MenuDefProc's PopUp message. The menu is * posted with the selected item at the point given in hitPt. * * Results: @@ -4667,84 +4607,93 @@ HandleMenuFindItemsMsg (MenuRef menu, *---------------------------------------------------------------------- */ void -HandleMenuPopUpMsg (MenuRef menu, - Rect *menuRectPtr, - Point hitPt, - SInt16 *whichItem, - TkMenu *menuPtr) +HandleMenuPopUpMsg( + MenuRef menu, + Rect *menuRectPtr, + Point hitPt, + SInt16 *whichItem, + TkMenu *menuPtr) { int maxMenuHeight; int oldItem; Rect portRect; BitMap screenBits; + static SInt16 menuBarHeight = 0; - /* - * Note that for some oddball reason, h and v are reversed in the - * point given to us by the MDEF. - */ +#ifdef TK_MAC_DEBUG_MENUS + TkMacOSXDbgMsg("MDEF: PopUpMsg"); +#endif + + if (!menuBarHeight) { + ChkErr(GetThemeMenuBarHeight, &menuBarHeight); + } GetQDGlobalsScreenBits(&screenBits); + /* + * Note that for some oddball reason, h and v are reversed in the + * point given to us by the MDEF. + */ + oldItem = *whichItem; if (oldItem >= menuPtr->numEntries) { - oldItem = -1; + oldItem = -1; } portRect.top = 0; portRect.bottom = 1280; - maxMenuHeight = screenBits.bounds.bottom - - screenBits.bounds.top - - GetMBarHeight() - SCREEN_MARGIN; + maxMenuHeight = screenBits.bounds.bottom - screenBits.bounds.top + - menuBarHeight - SCREEN_MARGIN; if (menuPtr->totalHeight > maxMenuHeight) { - menuRectPtr->top = GetMBarHeight(); + menuRectPtr->top = menuBarHeight; } else { - int delta; - menuRectPtr->top = hitPt.h; - if (oldItem >= 0) { - menuRectPtr->top -= menuPtr->entries[oldItem]->y; - } - - if (menuRectPtr->top < GetMBarHeight()) { - /* Displace downward if the menu would stick off the - * top of the screen. - */ - - menuRectPtr->top = GetMBarHeight() + SCREEN_MARGIN; - } else { - /* - * Or upward if the menu sticks off the - * bottom end... - */ - - delta = menuRectPtr->top + menuPtr->totalHeight - - maxMenuHeight; - if (delta > 0) { - menuRectPtr->top -= delta; - } - } + int delta; + + menuRectPtr->top = hitPt.h; + if (oldItem >= 0) { + menuRectPtr->top -= menuPtr->entries[oldItem]->y; + } + + if (menuRectPtr->top < menuBarHeight) { + /* + * Displace downward if the menu would stick off the top of the + * screen. + */ + + menuRectPtr->top = menuBarHeight + SCREEN_MARGIN; + } else { + /* + * Or upward if the menu sticks off the bottom end... + */ + + delta = menuRectPtr->top + menuPtr->totalHeight - maxMenuHeight; + if (delta > 0) { + menuRectPtr->top -= delta; + } + } } menuRectPtr->left = hitPt.v; menuRectPtr->right = menuRectPtr->left + menuPtr->totalWidth; - menuRectPtr->bottom = menuRectPtr->top + - ((maxMenuHeight < menuPtr->totalHeight) - ? maxMenuHeight : menuPtr->totalHeight); - if (menuRectPtr->top == GetMBarHeight()) { - *whichItem = hitPt.h; + menuRectPtr->bottom = menuRectPtr->top + + ((maxMenuHeight < menuPtr->totalHeight) + ? maxMenuHeight : menuPtr->totalHeight); + if (menuRectPtr->top == menuBarHeight) { + *whichItem = hitPt.h; } else { - *whichItem = menuRectPtr->top; + *whichItem = menuRectPtr->top; } } - + /* *---------------------------------------------------------------------- * - * HandleMenuCalcItemMsg -- + * HandleMenuCalcItemMsg -- * - * It handles the MenuDefProc's CalcItem message. It is supposed - * to calculate the Rect of the menu entry in whichItem in the - * menu, and put that in menuRectPtr. I assume this works, but I - * have never seen the MenuManager send this message. + * Handles the MenuDefProc's CalcItem message. It is supposed + * to calculate the Rect of the menu entry in whichItem in the + * menu, and put that in menuRectPtr. I assume this works, but I + * have never seen the MenuManager send this message. * * Results: - * The Menu Manager is informed of the bounding rect of a + * The Menu Manager is informed of the bounding rect of a * menu rect. * * Side effects: @@ -4752,32 +4701,41 @@ HandleMenuPopUpMsg (MenuRef menu, * *---------------------------------------------------------------------- */ + void -HandleMenuCalcItemMsg(MenuRef menu, - Rect *menuRectPtr, - Point hitPt, - SInt16 *whichItem, - TkMenu *menuPtr) +HandleMenuCalcItemMsg( + MenuRef menu, + Rect *menuRectPtr, + Point hitPt, + SInt16 *whichItem, + TkMenu *menuPtr) { TkMenuEntry *mePtr; - MenuTrackingData mtd, *mtdPtr = &mtd; - int err, virtualTop; - - err = GetMenuTrackingData(menu, mtdPtr); + MenuTrackingData mtd, *mtdPtr = &mtd; + OSStatus err; + int virtualTop, item = *whichItem-1; + + err = ChkErr(GetMenuTrackingData, menu, mtdPtr); if (err == noErr) { - virtualTop = mtdPtr->virtualMenuTop; + virtualTop = mtdPtr->virtualMenuTop; } else { - virtualTop = 0; + virtualTop = 0; } - - mePtr = menuPtr->entries[*whichItem]; - menuRectPtr->left = mePtr->x; - menuRectPtr->top = mePtr->y - virtualTop; - if (mePtr->entryFlags & ENTRY_LAST_COLUMN) { - menuRectPtr->right = menuPtr->totalWidth; - } else { - menuRectPtr->right = mePtr->x + mePtr->width; + + if (item >= 0 && item < menuPtr->numEntries) { + mePtr = menuPtr->entries[item]; + menuRectPtr->left = mePtr->x; + menuRectPtr->top = mePtr->y + virtualTop; + if (mePtr->entryFlags & ENTRY_LAST_COLUMN) { + menuRectPtr->right = menuPtr->totalWidth; + } else { + menuRectPtr->right = mePtr->x + mePtr->width; + } + menuRectPtr->bottom = menuRectPtr->top + mePtr->height; } - menuRectPtr->bottom = menuRectPtr->top - + mePtr->height; +#ifdef TK_MAC_DEBUG_MENUS + TkMacOSXDbgMsg("MDEF: CalcItemMsg %d: %d, %d", *whichItem, + menuRectPtr->left, menuRectPtr->top); +#endif } +#endif /* USE_TK_MDEF */ diff --git a/macosx/tkMacOSXMenu.r b/macosx/tkMacOSXMenu.r deleted file mode 100644 index 3a71886..0000000 --- a/macosx/tkMacOSXMenu.r +++ /dev/null @@ -1,47 +0,0 @@ -/* - * tkMacOSXMenu.r -- - * - * Resources needed by menus. - * - * This file also contains the icons 'SICN' used by the menu code - * in menu items. - * - * Copyright (c) 1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tkMacOSXMenu.r,v 1.2 2002/08/31 06:12:30 das Exp $ - */ - -#include <Carbon.r> - -/* - * Icons used in menu items. - */ - -resource 'SICN' (128, preload, locked) { - { /* array: 7 elements */ - /* [1] */ - $"0000 0000 8000 C000 E000 F000 F800 FC00" - $"F800 F000 E000 C000 80", - /* [2] */ - $"0000 0000 0000 0800 1400 2200 4100 8080" - $"E380 2200 2200 2200 3E", - /* [3] */ - $"0000 0000 0000 0000 0000 F8F0 C4F0 F270" - $"0900 0480 0270 0130 00F0", - /* [4] */ - $"0000 0000 0000 0000 0000 0000 0000 0000" - $"0000 E4E0 CE60 1B00 3180", - /* [5] */ - $"0000 0000 0000 0000 6300 9480 9480 7F00" - $"1400 7F00 9480 9480 63", - /* [6] */ - $"0000 0000 0000 0000 0000 3FF8 1FF0 0FE0" - $"07C0 0380 01", - /* [7] */ - $"0000 0000 0000 0000 0000 0100 0380 07C0" - $"0FE0 1FF0 3FF8" - } -}; diff --git a/macosx/tkMacOSXMenubutton.c b/macosx/tkMacOSXMenubutton.c index 79cd37a..5e05d19 100644 --- a/macosx/tkMacOSXMenubutton.c +++ b/macosx/tkMacOSXMenubutton.c @@ -1,16 +1,17 @@ -/* +/* * tkMacOSXMenubutton.c -- * - * This file implements the Macintosh specific portion of the - * menubutton widget. + * This file implements the Macintosh specific portion of the + * menubutton widget. * * Copyright (c) 1996 by Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.13 2007/04/21 19:06:38 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXMenubutton.c,v 1.14 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" @@ -19,33 +20,29 @@ #include "tkMacOSXFont.h" #include "tkMacOSXDebug.h" -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 - /* Define constants only available on Mac OS X 10.3 or later */ - #define kMenuAttrDoNotUseUserCommandKeys (1 << 7) -#endif - -#define kShadowOffset (3) /* amount to offset shadow from frame */ -#define kTriangleWidth (11) /* width of the triangle */ -#define kTriangleHeight (6) /* height of the triangle */ -#define kTriangleMargin (5) /* margin around triangle */ +#define kShadowOffset (3) /* amount to offset shadow from frame */ +#define kTriangleWidth (11) /* width of the triangle */ +#define kTriangleHeight (6) /* height of the triangle */ +#define kTriangleMargin (5) /* margin around triangle */ -#define TK_POPUP_OFFSET 32 /* size of popup marker */ +#define TK_POPUP_OFFSET 32 /* size of popup marker */ -MODULE_SCOPE int TkMacOSXGetNewMenuID _ANSI_ARGS_((Tcl_Interp *interp, TkMenu *menuInstPtr, int cascade, short *menuIDPtr)); -MODULE_SCOPE void TkMacOSXFreeMenuID _ANSI_ARGS_((short menuID)); +MODULE_SCOPE int TkMacOSXGetNewMenuID(Tcl_Interp *interp, TkMenu *menuInstPtr, + int cascade, short *menuIDPtr); +MODULE_SCOPE void TkMacOSXFreeMenuID(short menuID); typedef struct { SInt16 initialValue; SInt16 minValue; SInt16 maxValue; SInt16 procID; - int isBevel; + int isBevel; } MenuButtonControlParams; typedef struct { - int len; - Str255 title; - ControlFontStyleRec style; + int len; + Str255 title; + ControlFontStyleRec style; } ControlTitleParams; /* @@ -53,41 +50,39 @@ typedef struct { */ typedef struct MacMenuButton { - TkMenuButton info; /* Generic button info. */ - WindowRef windowRef; - ControlRef userPane; - ControlRef control; - MenuRef menuRef; - RGBColor userPaneBackground; - MenuButtonControlParams params; - ControlTitleParams titleParams; + TkMenuButton info; /* Generic button info. */ + WindowRef windowRef; + ControlRef userPane; + ControlRef control; + MenuRef menuRef; + unsigned long userPaneBackground; + int flags; + MenuButtonControlParams params; + ControlTitleParams titleParams; ControlButtonContentInfo bevelButtonContent; - OpenCPicParams picParams; - int flags; + OpenCPicParams picParams; } MacMenuButton; /* * Forward declarations for procedures defined later in this file: */ -static OSErr SetUserPaneDrawProc(ControlRef control, - ControlUserPaneDrawProcPtr upp); -static OSErr SetUserPaneSetUpSpecialBackgroundProc(ControlRef control, - ControlUserPaneBackgroundProcPtr upp); +static OSStatus SetUserPaneDrawProc(ControlRef control, + ControlUserPaneDrawProcPtr upp); +static OSStatus SetUserPaneSetUpSpecialBackgroundProc(ControlRef control, + ControlUserPaneBackgroundProcPtr upp); static void UserPaneDraw(ControlRef control, ControlPartCode cpc); static void UserPaneBackgroundProc(ControlHandle, - ControlBackgroundPtr info); -static int MenuButtonInitControl ( MacMenuButton *mbPtr, Rect *paneRect, Rect *cntrRect ); - -static int UpdateControlColors _ANSI_ARGS_((MacMenuButton *mbPtr )); -static void ComputeMenuButtonControlParams _ANSI_ARGS_((TkMenuButton * mbPtr, MenuButtonControlParams * paramsPtr)); -static void ComputeControlTitleParams _ANSI_ARGS_((TkMenuButton * mbPtr, ControlTitleParams * paramsPtr)); -static void CompareControlTitleParams( - ControlTitleParams * p1Ptr, - ControlTitleParams * p2Ptr, - int * titleChanged, - int * styleChanged -); + ControlBackgroundPtr info); +static int MenuButtonInitControl (MacMenuButton *mbPtr, Rect *paneRect, + Rect *cntrRect ); +static int UpdateControlColors(MacMenuButton *mbPtr); +static void ComputeMenuButtonControlParams(TkMenuButton *mbPtr, + MenuButtonControlParams * paramsPtr); +static void ComputeControlTitleParams(TkMenuButton *mbPtr, + ControlTitleParams *paramsPtr); +static void CompareControlTitleParams(ControlTitleParams *p1Ptr, + ControlTitleParams *p2Ptr, int *titleChanged, int *styleChanged); /* * The structure below defines menubutton class behavior by means of @@ -95,22 +90,23 @@ static void CompareControlTitleParams( */ Tk_ClassProcs tkpMenubuttonClass = { - sizeof(Tk_ClassProcs), /* size */ - TkMenuButtonWorldChanged, /* worldChangedProc */ + sizeof(Tk_ClassProcs), /* size */ + TkMenuButtonWorldChanged, /* worldChangedProc */ }; + /* *---------------------------------------------------------------------- * * TkpCreateMenuButton -- * - * Allocate a new TkMenuButton structure. + * Allocate a new TkMenuButton structure. * * Results: - * Returns a newly allocated TkMenuButton structure. + * Returns a newly allocated TkMenuButton structure. * * Side effects: - * Registers an event handler for the widget. + * Registers an event handler for the widget. * *---------------------------------------------------------------------- */ @@ -120,9 +116,7 @@ TkpCreateMenuButton( Tk_Window tkwin) { MacMenuButton *mbPtr = (MacMenuButton *) ckalloc(sizeof(MacMenuButton)); - mbPtr->userPaneBackground.red = 0; - mbPtr->userPaneBackground.green = 0; - mbPtr->userPaneBackground.blue = ~0; + mbPtr->userPaneBackground = PIXEL_MAGIC << 24; mbPtr->flags = 0; mbPtr->userPane = NULL; mbPtr->control = NULL; @@ -146,45 +140,41 @@ TkpCreateMenuButton( * * TkpDisplayMenuButton -- * - * This procedure is invoked to display a menubutton widget. + * This procedure is invoked to display a menubutton widget. * * Results: - * None. + * None. * * Side effects: - * Commands are output to X to display the menubutton in its - * current mode. + * Commands are output to X to display the menubutton in its + * current mode. * *---------------------------------------------------------------------- */ void TkpDisplayMenuButton( - ClientData clientData) /* Information about widget. */ + ClientData clientData) /* Information about widget. */ { TkMenuButton *butPtr = (TkMenuButton *) clientData; Tk_Window tkwin = butPtr->tkwin; - TkWindow * winPtr; - Pixmap pixmap; - MacMenuButton * mbPtr = (MacMenuButton *) butPtr; - GWorldPtr dstPort; - CGrafPtr saveWorld; - GDHandle saveDevice; - int hasImageOrBitmap = 0; - int width, height; - int err; + TkWindow *winPtr; + Pixmap pixmap; + MacMenuButton *mbPtr = (MacMenuButton *) butPtr; + CGrafPtr destPort, savePort; + Boolean portChanged; + int hasImageOrBitmap = 0, width, height; + OSStatus err; ControlButtonGraphicAlignment theAlignment; - Rect paneRect, cntrRect; butPtr->flags &= ~REDRAW_PENDING; if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { - return; + return; } - pixmap = ( Pixmap )Tk_WindowId(tkwin); - GetGWorld(&saveWorld, &saveDevice); - dstPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); - SetGWorld(dstPort, NULL); + pixmap = (Pixmap) Tk_WindowId(tkwin); + destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); + portChanged = QDSwapPort(destPort, &savePort); TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin)); winPtr = (TkWindow *)butPtr->tkwin; @@ -192,172 +182,168 @@ TkpDisplayMenuButton( paneRect.top = winPtr->privatePtr->yOff; paneRect.right = paneRect.left+Tk_Width(butPtr->tkwin)-1; paneRect.bottom = paneRect.top+Tk_Height(butPtr->tkwin)-1; - + cntrRect = paneRect; - + cntrRect.left += butPtr->inset; cntrRect.top += butPtr->inset; cntrRect.right -= butPtr->inset; cntrRect.bottom -= butPtr->inset; if (mbPtr->userPane) { - MenuButtonControlParams params; - bzero(¶ms, sizeof(params)); - ComputeMenuButtonControlParams(butPtr, ¶ms ); - if (bcmp(¶ms,&mbPtr->params,sizeof(params))) { - if (mbPtr->userPane) { - DisposeControl(mbPtr->userPane); - mbPtr->userPane = NULL; - mbPtr->control = NULL; - } - } - } - if (!mbPtr->userPane) { - if (MenuButtonInitControl(mbPtr,&paneRect,&cntrRect ) ) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"Init Control failed\n" ); -#endif - return; - } - } + MenuButtonControlParams params; + bzero(¶ms, sizeof(params)); + ComputeMenuButtonControlParams(butPtr, ¶ms ); + if (bcmp(¶ms,&mbPtr->params,sizeof(params))) { + if (mbPtr->userPane) { + DisposeControl(mbPtr->userPane); + mbPtr->userPane = NULL; + mbPtr->control = NULL; + } + } + } + if (!mbPtr->userPane) { + if (MenuButtonInitControl(mbPtr, &paneRect, &cntrRect)) { + TkMacOSXDbgMsg("Init Control failed"); + return; + } + } SetControlBounds(mbPtr->userPane,&paneRect); - SetControlBounds(mbPtr->control,&cntrRect); + SetControlBounds(mbPtr->control,&cntrRect); /* * We need to cache the title and its style */ - if (!(mbPtr->flags&2)) { - ControlTitleParams titleParams; - int titleChanged; - int styleChanged; - ComputeControlTitleParams(butPtr,&titleParams); - CompareControlTitleParams(&titleParams,&mbPtr->titleParams, - &titleChanged,&styleChanged); - if (titleChanged) { - CFStringRef cf; - cf = CFStringCreateWithCString(NULL, - (char*) titleParams.title, kCFStringEncodingUTF8); - if (hasImageOrBitmap) { - SetControlTitleWithCFString(mbPtr->control, cf); - } else { - SetMenuItemTextWithCFString(mbPtr->menuRef, 1, cf); - } - CFRelease(cf); - bcopy(titleParams.title,mbPtr->titleParams.title,titleParams.len+1); - mbPtr->titleParams.len = titleParams.len; - } - if ((titleChanged||styleChanged) && titleParams .len) { - if (hasImageOrBitmap) { - err = SetControlFontStyle(mbPtr->control,&titleParams.style); - if (err !=noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"SetControlFontStyle failed %d\n", err); -#endif - return; - } - } - bcopy(&titleParams.style,&mbPtr->titleParams.style,sizeof(titleParams.style)); - } + + if (!(mbPtr->flags & 2)) { + ControlTitleParams titleParams; + int titleChanged; + int styleChanged; + + ComputeControlTitleParams(butPtr,&titleParams); + CompareControlTitleParams(&titleParams,&mbPtr->titleParams, + &titleChanged,&styleChanged); + if (titleChanged) { + CFStringRef cf = CFStringCreateWithCString(NULL, + (char*) titleParams.title, kCFStringEncodingUTF8); + + if (hasImageOrBitmap) { + SetControlTitleWithCFString(mbPtr->control, cf); + } else { + SetMenuItemTextWithCFString(mbPtr->menuRef, 1, cf); + } + CFRelease(cf); + bcopy(titleParams.title, mbPtr->titleParams.title, + titleParams.len + 1); + mbPtr->titleParams.len = titleParams.len; + } + if ((titleChanged||styleChanged) && titleParams .len) { + if (hasImageOrBitmap) { + err = ChkErr(SetControlFontStyle, mbPtr->control, + &titleParams.style); + if (err != noErr) { + return; + } + } + bcopy(&titleParams.style, &mbPtr->titleParams.style, + sizeof(titleParams.style)); + } } if (butPtr->image != None) { - Tk_SizeOfImage(butPtr->image, &width, &height); - hasImageOrBitmap = 1; + Tk_SizeOfImage(butPtr->image, &width, &height); + hasImageOrBitmap = 1; } else if (butPtr->bitmap != None) { - Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); - hasImageOrBitmap = 1; + 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; - if (!(mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams)) ) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"OpenCPicture failed\n"); -#endif - } - /* - * 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, - (unsigned int) width, (unsigned int) height, 0, 0, 1); - } - ClosePicture(); - - tkPictureIsOpen = 0; - err = SetControlData(mbPtr->control, kControlButtonPart, - kControlBevelButtonContentTag, - sizeof(ControlButtonContentInfo), - (char *) &mbPtr->bevelButtonContent); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"SetControlData BevelButtonContent failed, %d\n", err ); -#endif - } - switch (butPtr->anchor) { - case TK_ANCHOR_N: - theAlignment = kControlBevelButtonAlignTop; - break; - case TK_ANCHOR_NE: - theAlignment = kControlBevelButtonAlignTopRight; - break; - case TK_ANCHOR_E: - theAlignment = kControlBevelButtonAlignRight; - break; - case TK_ANCHOR_SE: - theAlignment = kControlBevelButtonAlignBottomRight; - break; - case TK_ANCHOR_S: - theAlignment = kControlBevelButtonAlignBottom; - break; - case TK_ANCHOR_SW: - theAlignment = kControlBevelButtonAlignBottomLeft; - break; - case TK_ANCHOR_W: - theAlignment = kControlBevelButtonAlignLeft; - break; - case TK_ANCHOR_NW: - theAlignment = kControlBevelButtonAlignTopLeft; - break; - case TK_ANCHOR_CENTER: - theAlignment = kControlBevelButtonAlignCenter; - break; - } - - err = SetControlData(mbPtr->control, kControlButtonPart, - kControlBevelButtonGraphicAlignTag, - sizeof(ControlButtonGraphicAlignment), - (char *) &theAlignment); - if (err != noErr ) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"SetControlData BevelButtonGraphicAlign failed, %d\n", err ); -#endif - } + 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. + */ + + 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, + width, height, 0, 0, 1); + } + ClosePicture(); + + tkPictureIsOpen = 0; + ChkErr(SetControlData, mbPtr->control, kControlButtonPart, + kControlBevelButtonContentTag, + sizeof(ControlButtonContentInfo), + (char *) &mbPtr->bevelButtonContent); + switch (butPtr->anchor) { + case TK_ANCHOR_N: + theAlignment = kControlBevelButtonAlignTop; + break; + case TK_ANCHOR_NE: + theAlignment = kControlBevelButtonAlignTopRight; + break; + case TK_ANCHOR_E: + theAlignment = kControlBevelButtonAlignRight; + break; + case TK_ANCHOR_SE: + theAlignment = kControlBevelButtonAlignBottomRight; + break; + case TK_ANCHOR_S: + theAlignment = kControlBevelButtonAlignBottom; + break; + case TK_ANCHOR_SW: + theAlignment = kControlBevelButtonAlignBottomLeft; + break; + case TK_ANCHOR_W: + theAlignment = kControlBevelButtonAlignLeft; + break; + case TK_ANCHOR_NW: + theAlignment = kControlBevelButtonAlignTopLeft; + break; + case TK_ANCHOR_CENTER: + theAlignment = kControlBevelButtonAlignCenter; + break; + } + + ChkErr(SetControlData, mbPtr->control, kControlButtonPart, + kControlBevelButtonGraphicAlignTag, + sizeof(ControlButtonGraphicAlignment), (char *) &theAlignment); } if (butPtr->flags & GOT_FOCUS) { - HiliteControl(mbPtr->control,kControlButtonPart); + HiliteControl(mbPtr->control,kControlButtonPart); } else { - HiliteControl(mbPtr->control,kControlNoPart); + HiliteControl(mbPtr->control,kControlNoPart); } UpdateControlColors(mbPtr); if (mbPtr->flags&2) { - ShowControl(mbPtr->control); - ShowControl(mbPtr->userPane); - mbPtr->flags ^= 2; + ShowControl(mbPtr->control); + ShowControl(mbPtr->userPane); + mbPtr->flags ^= 2; } else { - Draw1Control(mbPtr->userPane); - SetControlVisibility(mbPtr->control, true, true); + Draw1Control(mbPtr->userPane); + SetControlVisibility(mbPtr->control, true, true); } if (hasImageOrBitmap) { - KillPicture(mbPtr->bevelButtonContent.u.picture); + KillPicture(mbPtr->bevelButtonContent.u.picture); + } + if (portChanged) { + QDSwapPort(savePort, NULL); } - SetGWorld(saveWorld, saveDevice); } /* @@ -365,13 +351,13 @@ TkpDisplayMenuButton( * * TkpDestroyMenuButton -- * - * Free data structures associated with the menubutton control. + * Free data structures associated with the menubutton control. * * Results: - * None. + * None. * * Side effects: - * Restores the default control state. + * Restores the default control state. * *---------------------------------------------------------------------- */ @@ -380,17 +366,18 @@ void TkpDestroyMenuButton( TkMenuButton *mbPtr) { - MacMenuButton * macMbPtr = (MacMenuButton *)mbPtr; + MacMenuButton *macMbPtr = (MacMenuButton *) mbPtr; + if (macMbPtr->userPane) { - DisposeControl(macMbPtr->userPane); - macMbPtr->userPane = NULL; + DisposeControl(macMbPtr->userPane); + macMbPtr->userPane = NULL; } if (macMbPtr->menuRef) { - short menuID; - menuID = GetMenuID(macMbPtr->menuRef); - TkMacOSXFreeMenuID(menuID); - DisposeMenu(macMbPtr->menuRef); - macMbPtr->menuRef = NULL; + short menuID = GetMenuID(macMbPtr->menuRef); + + TkMacOSXFreeMenuID(menuID); + DisposeMenu(macMbPtr->menuRef); + macMbPtr->menuRef = NULL; } } @@ -399,82 +386,82 @@ TkpDestroyMenuButton( * * TkpComputeMenuButtonGeometry -- * - * After changes in a menu button's text or bitmap, this procedure - * recomputes the menu button's geometry and passes this information - * along to the geometry manager for the window. + * After changes in a menu button's text or bitmap, this procedure + * recomputes the menu button's geometry and passes this information + * along to the geometry manager for the window. * * Results: - * None. + * None. * * Side effects: - * The menu button's window may change size. + * The menu button's window may change size. * *---------------------------------------------------------------------- */ void TkpComputeMenuButtonGeometry(mbPtr) - register TkMenuButton *mbPtr; /* Widget record for menu button. */ + register TkMenuButton *mbPtr; /* Widget record for menu button. */ { int width, height, mm, pixels; int hasImageOrBitmap = 0; 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; + 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; + 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; - Tk_FreeTextLayout(mbPtr->textLayout); - mbPtr->textLayout = Tk_ComputeTextLayout(mbPtr->tkfont, mbPtr->text, - -1, mbPtr->wrapLength, mbPtr->justify, 0, &mbPtr->textWidth, - &mbPtr->textHeight); - width = mbPtr->textWidth; - height = mbPtr->textHeight; - if (mbPtr->width > 0) { - width = mbPtr->width * Tk_TextWidth(mbPtr->tkfont, "0", 1); - } - if (mbPtr->height > 0) { - Tk_FontMetrics fm; - - Tk_GetFontMetrics(mbPtr->tkfont, &fm); - height = mbPtr->height * fm.linespace; - } - width += 2*mbPtr->padX; - height += 2*mbPtr->padY; + hasImageOrBitmap = 0; + Tk_FreeTextLayout(mbPtr->textLayout); + mbPtr->textLayout = Tk_ComputeTextLayout(mbPtr->tkfont, mbPtr->text, + -1, mbPtr->wrapLength, mbPtr->justify, 0, &mbPtr->textWidth, + &mbPtr->textHeight); + width = mbPtr->textWidth; + height = mbPtr->textHeight; + if (mbPtr->width > 0) { + width = mbPtr->width * Tk_TextWidth(mbPtr->tkfont, "0", 1); + } + if (mbPtr->height > 0) { + Tk_FontMetrics fm; + + Tk_GetFontMetrics(mbPtr->tkfont, &fm); + height = mbPtr->height * fm.linespace; + } + width += 2*mbPtr->padX; + height += 2*mbPtr->padY; } if (mbPtr->indicatorOn) { - mm = WidthMMOfScreen(Tk_Screen(mbPtr->tkwin)); - pixels = WidthOfScreen(Tk_Screen(mbPtr->tkwin)); - mbPtr->indicatorHeight = kTriangleHeight; - mbPtr->indicatorWidth = kTriangleWidth + kTriangleMargin; - width += mbPtr->indicatorWidth; + mm = WidthMMOfScreen(Tk_Screen(mbPtr->tkwin)); + pixels = WidthOfScreen(Tk_Screen(mbPtr->tkwin)); + mbPtr->indicatorHeight = kTriangleHeight; + mbPtr->indicatorWidth = kTriangleWidth + kTriangleMargin; + width += mbPtr->indicatorWidth; } else { - mbPtr->indicatorHeight = 0; - mbPtr->indicatorWidth = 0; + mbPtr->indicatorHeight = 0; + mbPtr->indicatorWidth = 0; } if (!hasImageOrBitmap) { - width += TK_POPUP_OFFSET; + width += TK_POPUP_OFFSET; } Tk_GeometryRequest(mbPtr->tkwin, (int) (width + 2*mbPtr->inset), - (int) (height + 2*mbPtr->inset)); + (int) (height + 2*mbPtr->inset)); Tk_SetInternalBorder(mbPtr->tkwin, mbPtr->inset); } @@ -483,26 +470,27 @@ TkpComputeMenuButtonGeometry(mbPtr) * * ComputeMenuButtonControlParams -- * - * This procedure computes the various parameters used - * when creating a Carbon control (NewControl) - * These are determined by the various tk menu button parameters + * This procedure computes the various parameters used + * when creating a Carbon control (NewControl) + * These are determined by the various tk menu button parameters * * Results: - * None. + * None. * * Side effects: - * Sets the control initialisation parameters + * Sets the control initialisation parameters * *---------------------------------------------------------------------- */ static void -ComputeMenuButtonControlParams(TkMenuButton * mbPtr, - MenuButtonControlParams * paramsPtr ) +ComputeMenuButtonControlParams( + TkMenuButton *mbPtr, + MenuButtonControlParams *paramsPtr) { int fakeMenuID = 256; - /* + /* * Determine ProcID based on button type and dimensions * * We need to set minValue to some non-zero value, @@ -512,26 +500,26 @@ ComputeMenuButtonControlParams(TkMenuButton * mbPtr, paramsPtr->minValue = kControlBehaviorMultiValueMenu; paramsPtr->maxValue = 0; if (mbPtr->image || mbPtr->bitmap) { - paramsPtr->isBevel = 1; - if (mbPtr->borderWidth <= 2) { - paramsPtr->procID = kControlBevelButtonSmallBevelProc; - } else if (mbPtr->borderWidth == 3) { - paramsPtr->procID = kControlBevelButtonNormalBevelProc; - } else { - paramsPtr->procID = kControlBevelButtonLargeBevelProc; - } - if (mbPtr->indicatorOn) { - paramsPtr->initialValue = fakeMenuID; - } else { - paramsPtr->initialValue = 0; - } + paramsPtr->isBevel = 1; + if (mbPtr->borderWidth <= 2) { + paramsPtr->procID = kControlBevelButtonSmallBevelProc; + } else if (mbPtr->borderWidth == 3) { + paramsPtr->procID = kControlBevelButtonNormalBevelProc; + } else { + paramsPtr->procID = kControlBevelButtonLargeBevelProc; + } + if (mbPtr->indicatorOn) { + paramsPtr->initialValue = fakeMenuID; + } else { + paramsPtr->initialValue = 0; + } } else { - paramsPtr->isBevel = 0; - paramsPtr->procID = kControlPopupButtonProc - + kControlPopupVariableWidthVariant; - paramsPtr->minValue = -12345; - paramsPtr->maxValue = -1; - paramsPtr->initialValue = 0; + paramsPtr->isBevel = 0; + paramsPtr->procID = kControlPopupButtonProc + + kControlPopupVariableWidthVariant; + paramsPtr->minValue = -12345; + paramsPtr->maxValue = -1; + paramsPtr->initialValue = 0; } } @@ -539,201 +527,181 @@ ComputeMenuButtonControlParams(TkMenuButton * mbPtr, *---------------------------------------------------------------------- * * returns 0 if same, 1 otherwise + * *---------------------------------------------------------------------- */ + static void -CompareControlTitleParams( - ControlTitleParams * p1Ptr, - ControlTitleParams * p2Ptr, - int * titleChanged, - int * styleChanged -) +CompareControlTitleParams( + ControlTitleParams *p1Ptr, + ControlTitleParams *p2Ptr, + int *titleChanged, + int *styleChanged) { if (p1Ptr->len != p2Ptr->len) { - *titleChanged = 1; + *titleChanged = 1; + } else if (bcmp(p1Ptr->title,p2Ptr->title,p1Ptr->len)) { + *titleChanged = 1; } else { - if (bcmp(p1Ptr->title,p2Ptr->title,p1Ptr->len)) { - *titleChanged = 1; - } else { - *titleChanged = 0; - } + *titleChanged = 0; } + if (p1Ptr->len && p2Ptr->len) { - *styleChanged = bcmp(&p1Ptr->style, &p2Ptr->style, sizeof(p2Ptr->style)); + *styleChanged = bcmp(&p1Ptr->style, &p2Ptr->style, + sizeof(p2Ptr->style)); } else { - *styleChanged = p1Ptr->len||p2Ptr->len; + *styleChanged = p1Ptr->len||p2Ptr->len; } } - + static void -ComputeControlTitleParams(TkMenuButton * butPtr, ControlTitleParams * paramsPtr ) +ComputeControlTitleParams( + TkMenuButton *butPtr, + ControlTitleParams *paramsPtr) { Tk_Font font; - paramsPtr->len =TkFontGetFirstTextLayout(butPtr->textLayout,&font, (char*) paramsPtr->title); - paramsPtr->title [paramsPtr->len] = 0; + + paramsPtr->len = TkFontGetFirstTextLayout(butPtr->textLayout, &font, + (char*) paramsPtr->title); + paramsPtr->title[paramsPtr->len] = 0; if (paramsPtr->len) { - TkMacOSXInitControlFontStyle(font,¶msPtr->style); + TkMacOSXInitControlFontStyle(font,¶msPtr->style); } } - /* *---------------------------------------------------------------------- * * MenuButtonInitControl -- * - * This procedure initialises a Carbon control + * This procedure initialises a Carbon control * * Results: - * 0 on success, 1 on failure. + * 0 on success, 1 on failure. * * Side effects: - * A background pane control and the control itself is created - * The contol is embedded in the background control - * The background control is embedded in the root control - * of the containing window - * The creation parameters for the control are also computed + * A background pane control and the control itself is created + * The contol is embedded in the background control + * The background control is embedded in the root control + * of the containing window + * The creation parameters for the control are also computed * *---------------------------------------------------------------------- */ int -MenuButtonInitControl ( - MacMenuButton *mbPtr, /* Mac button. */ - Rect *paneRect, - Rect *cntrRect -) +MenuButtonInitControl( + MacMenuButton *mbPtr, /* Mac button. */ + Rect *paneRect, + Rect *cntrRect) { - OSStatus err; - TkMenuButton * butPtr = ( TkMenuButton * )mbPtr; - ControlRef rootControl; - SInt16 procID; - Boolean initiallyVisible; - SInt16 initialValue; - SInt16 minValue; - SInt16 maxValue; - SInt32 controlReference; - short menuID; - - rootControl = TkMacOSXGetRootControl(Tk_WindowId(butPtr->tkwin)); - mbPtr->windowRef = GetWindowFromPort(TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin))); - /* + OSStatus err; + TkMenuButton *butPtr = (TkMenuButton *) mbPtr; + SInt16 procID, initialValue, minValue, maxValue; + Boolean initiallyVisible; + SInt32 controlReference; + short menuID; + ControlRef rootControl = + TkMacOSXGetRootControl(Tk_WindowId(butPtr->tkwin)); + + mbPtr->windowRef = GetWindowFromPort( + TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin))); + + /* * Set up the user pane */ + initiallyVisible = false; - initialValue = kControlSupportsEmbedding| - kControlHasSpecialBackground; + initialValue = kControlSupportsEmbedding | kControlHasSpecialBackground; minValue = 0; maxValue = 1; procID = kControlUserPaneProc; controlReference = (SInt32)mbPtr; - mbPtr->userPane = NewControl(mbPtr->windowRef, - paneRect, "\p", - initiallyVisible, - initialValue, - minValue, - maxValue, - procID, - controlReference ); + mbPtr->userPane = NewControl(mbPtr->windowRef, paneRect, "\p", + initiallyVisible, initialValue, minValue, maxValue, procID, + controlReference); if (!mbPtr->userPane) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"Failed to create user pane control\n"); -#endif - return 1; + TkMacOSXDbgMsg("Failed to create user pane control"); + return 1; } - err = EmbedControl(mbPtr->userPane,rootControl); + err = ChkErr(EmbedControl, mbPtr->userPane, rootControl); if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"Failed to embed user pane control %d\n", (int) err); -#endif - return 1; + return 1; } SetUserPaneSetUpSpecialBackgroundProc(mbPtr->userPane, - UserPaneBackgroundProc); + UserPaneBackgroundProc); SetUserPaneDrawProc(mbPtr->userPane,UserPaneDraw); initiallyVisible = false; ComputeMenuButtonControlParams(butPtr,&mbPtr->params); - /* Do this only if we are using bevel buttons */ + + /* + * Do this only if we are using bevel buttons. + */ + ComputeControlTitleParams(butPtr,&mbPtr->titleParams); mbPtr->control = NewControl(mbPtr->windowRef, - cntrRect, "\p", //mbPtr->titleParams.title, - initiallyVisible, - mbPtr->params.initialValue, - mbPtr->params.minValue, - mbPtr->params.maxValue, - mbPtr->params.procID, - controlReference ); + cntrRect, "\p" /* mbPtr->titleParams.title */, + initiallyVisible, mbPtr->params.initialValue, + mbPtr->params.minValue, mbPtr->params.maxValue, + mbPtr->params.procID, controlReference); if (!mbPtr->control) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"failed to create control of type %d : line %d\n",mbPtr->params.procID, __LINE__); -#endif - return 1; + TkMacOSXDbgMsg("Failed to create control of type %d", + mbPtr->params.procID); + return 1; } - err = EmbedControl(mbPtr->control,mbPtr->userPane); + err = ChkErr(EmbedControl, mbPtr->control, mbPtr->userPane); if (err != noErr ) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"failed to embed control of type %d,%d\n",procID, (int) err); -#endif - return 1; + return 1; } if (mbPtr->params.isBevel) { - CFStringRef cf; - cf = CFStringCreateWithCString(NULL, - (char*) mbPtr->titleParams.title, kCFStringEncodingUTF8); - SetControlTitleWithCFString(mbPtr->control, cf); - CFRelease(cf); - if (mbPtr->titleParams.len) { - err = SetControlFontStyle(mbPtr->control,&mbPtr->titleParams.style); - if (err !=noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"SetControlFontStyle failed %d\n", (int) err); -#endif - return 1; - } - } + CFStringRef cf = CFStringCreateWithCString(NULL, + (char*) mbPtr->titleParams.title, kCFStringEncodingUTF8); + + SetControlTitleWithCFString(mbPtr->control, cf); + CFRelease(cf); + if (mbPtr->titleParams.len) { + err = ChkErr(SetControlFontStyle, mbPtr->control, + &mbPtr->titleParams.style); + if (err != noErr) { + return 1; + } + } } else { - CFStringRef cfStr; - err = TkMacOSXGetNewMenuID(mbPtr->info.interp, (TkMenu *)mbPtr, 0, &menuID); - if (err != TCL_OK) { - return 1; - } - err = CreateNewMenu(menuID, kMenuAttrDoNotUseUserCommandKeys, - &(mbPtr->menuRef)); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"CreateNewMenu failed, %d.\n", (int) err); -#endif - return 1; - } - cfStr = CFStringCreateWithCString(NULL, Tk_PathName(mbPtr->info.tkwin), - kCFStringEncodingUTF8); - if (!cfStr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"CFStringCreateWithCString failed.\n"); -#endif - return 1; - } - err = SetMenuTitleWithCFString(mbPtr->menuRef, cfStr); - CFRelease(cfStr); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"SetMenuTitleWithCFString failed, %d.\n", (int) err); -#endif - return 1; - } - cfStr = CFStringCreateWithCString(NULL, - (char*) mbPtr->titleParams.title, kCFStringEncodingUTF8); - AppendMenuItemText(mbPtr->menuRef, "\px"); - if (cfStr) { - SetMenuItemTextWithCFString(mbPtr->menuRef, 1, cfStr); - CFRelease(cfStr); - } - err = SetControlData(mbPtr->control, - kControlNoPart, - kControlPopupButtonMenuRefTag, - sizeof(mbPtr->menuRef), &mbPtr->menuRef); - SetControlMinimum(mbPtr->control, 1); - SetControlMaximum(mbPtr->control, 1); - SetControlValue(mbPtr->control, 1); + CFStringRef cfStr; + + err = TkMacOSXGetNewMenuID(mbPtr->info.interp, (TkMenu *) mbPtr, 0, + &menuID); + if (err != TCL_OK) { + return 1; + } + err = ChkErr(CreateNewMenu, menuID, kMenuAttrDoNotUseUserCommandKeys, + &(mbPtr->menuRef)); + if (err != noErr) { + return 1; + } + cfStr = CFStringCreateWithCString(NULL, Tk_PathName(mbPtr->info.tkwin), + kCFStringEncodingUTF8); + if (!cfStr) { + TkMacOSXDbgMsg("CFStringCreateWithCString failed"); + return 1; + } + err = ChkErr(SetMenuTitleWithCFString, mbPtr->menuRef, cfStr); + CFRelease(cfStr); + if (err != noErr) { + return 1; + } + cfStr = CFStringCreateWithCString(NULL, + (char*) mbPtr->titleParams.title, kCFStringEncodingUTF8); + AppendMenuItemText(mbPtr->menuRef, "\px"); + if (cfStr) { + SetMenuItemTextWithCFString(mbPtr->menuRef, 1, cfStr); + CFRelease(cfStr); + } + ChkErr(SetControlData, mbPtr->control, kControlNoPart, + kControlPopupButtonMenuRefTag, sizeof(mbPtr->menuRef), + &mbPtr->menuRef); + SetControlMinimum(mbPtr->control, 1); + SetControlMaximum(mbPtr->control, 1); + SetControlValue(mbPtr->control, 1); } mbPtr->flags |= 2; return 0; @@ -744,28 +712,28 @@ MenuButtonInitControl ( * * SetUserPane * - * Utility function to add a UserPaneDrawProc - * to a userPane control. From MoreControls code - * from Apple DTS. + * Utility function to add a UserPaneDrawProc + * to a userPane control. From MoreControls code + * from Apple DTS. * * Results: - * MacOS system error. + * MacOS system error. * * Side effects: - * The user pane gets a new UserPaneDrawProc. + * The user pane gets a new UserPaneDrawProc. * *-------------------------------------------------------------- */ -OSErr SetUserPaneDrawProc ( +OSStatus +SetUserPaneDrawProc( ControlRef control, ControlUserPaneDrawProcPtr upp) { - ControlUserPaneDrawUPP myControlUserPaneDrawUPP; - myControlUserPaneDrawUPP = NewControlUserPaneDrawUPP(upp); - return SetControlData (control, - kControlNoPart, kControlUserPaneDrawProcTag, - sizeof(myControlUserPaneDrawUPP), - (Ptr) &myControlUserPaneDrawUPP); + ControlUserPaneDrawUPP myControlUserPaneDrawUPP = + NewControlUserPaneDrawUPP(upp); + + return SetControlData(control, kControlNoPart,kControlUserPaneDrawProcTag, + sizeof(myControlUserPaneDrawUPP), (Ptr)&myControlUserPaneDrawUPP); } /* @@ -773,28 +741,30 @@ OSErr SetUserPaneDrawProc ( * * SetUserPaneSetUpSpecialBackgroundProc -- * - * Utility function to add a UserPaneBackgroundProc - * to a userPane control + * Utility function to add a UserPaneBackgroundProc + * to a userPane control * * Results: - * MacOS system error. + * MacOS system error. * * Side effects: - * The user pane gets a new UserPaneBackgroundProc. + * The user pane gets a new UserPaneBackgroundProc. * *-------------------------------------------------------------- */ -OSErr + +OSStatus SetUserPaneSetUpSpecialBackgroundProc( - ControlRef control, + ControlRef control, ControlUserPaneBackgroundProcPtr upp) { - ControlUserPaneBackgroundUPP myControlUserPaneBackgroundUPP; - myControlUserPaneBackgroundUPP = NewControlUserPaneBackgroundUPP(upp); - return SetControlData (control, kControlNoPart, - kControlUserPaneBackgroundProcTag, - sizeof(myControlUserPaneBackgroundUPP), - (Ptr) &myControlUserPaneBackgroundUPP); + ControlUserPaneBackgroundUPP myControlUserPaneBackgroundUPP = + NewControlUserPaneBackgroundUPP(upp); + + return SetControlData(control, kControlNoPart, + kControlUserPaneBackgroundProcTag, + sizeof(myControlUserPaneBackgroundUPP), + (Ptr) &myControlUserPaneBackgroundUPP); } /* @@ -802,27 +772,29 @@ SetUserPaneSetUpSpecialBackgroundProc( * * UserPaneDraw -- * - * This function draws the background of the user pane that will - * lie under checkboxes and radiobuttons. + * This function draws the background of the user pane that will + * lie under checkboxes and radiobuttons. * * Results: - * None. + * None. * * Side effects: - * The user pane gets updated to the current color. + * The user pane gets updated to the current color. * *-------------------------------------------------------------- */ + void UserPaneDraw( ControlRef control, ControlPartCode cpc) { Rect contrlRect; - MacMenuButton * mbPtr; - mbPtr = ( MacMenuButton *)GetControlReference(control); + MacMenuButton * mbPtr = + (MacMenuButton *)(intptr_t)GetControlReference(control); + GetControlBounds(control,&contrlRect); - RGBBackColor (&mbPtr->userPaneBackground); + TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL); EraseRect (&contrlRect); } @@ -831,14 +803,14 @@ UserPaneDraw( * * UserPaneBackgroundProc -- * - * This function sets up the background of the user pane that will - * lie under checkboxes and radiobuttons. + * This function sets up the background of the user pane that will + * lie under checkboxes and radiobuttons. * * Results: - * None. + * None. * * Side effects: - * The user pane background gets set to the current color. + * The user pane background gets set to the current color. * *-------------------------------------------------------------- */ @@ -848,45 +820,47 @@ UserPaneBackgroundProc( ControlHandle control, ControlBackgroundPtr info) { - MacMenuButton * mbPtr; - mbPtr = (MacMenuButton *)GetControlReference(control); + MacMenuButton *mbPtr = + (MacMenuButton *)(intptr_t)GetControlReference(control); + if (info->colorDevice) { - RGBBackColor (&mbPtr->userPaneBackground); + TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL); } } -/* +/* *-------------------------------------------------------------- - * + * * UpdateControlColors -- - * - * This function will review the colors used to display - * a Macintosh button. If any non-standard colors are - * used we create a custom palette for the button, populate - * with the colors for the button and install the palette. - * - * Under Appearance, we just set the pointer that will be - * used by the UserPaneDrawProc. - * + * + * This function will review the colors used to display + * a Macintosh button. If any non-standard colors are + * used we create a custom palette for the button, populate + * with the colors for the button and install the palette. + * + * Under Appearance, we just set the pointer that will be + * used by the UserPaneDrawProc. + * * Results: - * None. - * + * None. + * * Side effects: - * The Macintosh control may get a custom palette installed. + * The Macintosh control may get a custom palette installed. * *-------------------------------------------------------------- */ static int -UpdateControlColors(MacMenuButton * mbPtr) +UpdateControlColors( + MacMenuButton *mbPtr) { XColor *xcolor; TkMenuButton * butPtr = ( TkMenuButton * )mbPtr; - + /* * Under Appearance we cannot change the background of the - * button itself. However, the color we are setting is the color - * of the containing userPane. This will be the color that peeks + * button itself. However, the color we are setting is the color + * of the containing userPane. This will be the color that peeks * around the rounded corners of the button. * We make this the highlightbackground rather than the background, * because if you color the background of a frame containing a @@ -895,7 +869,7 @@ UpdateControlColors(MacMenuButton * mbPtr) */ xcolor = Tk_3DBorderColor(butPtr->normalBorder); - TkSetMacColor(xcolor->pixel, &mbPtr->userPaneBackground); - + mbPtr->userPaneBackground = xcolor->pixel; + return false; } diff --git a/macosx/tkMacOSXMenus.c b/macosx/tkMacOSXMenus.c index 22d75d0..4bf138d 100644 --- a/macosx/tkMacOSXMenus.c +++ b/macosx/tkMacOSXMenus.c @@ -1,65 +1,61 @@ -/* +/* * tkMacOSXMenus.c -- * - * These calls set up and manage the menubar for the - * Macintosh version of Tk. + * These calls set up and manage the menubar for the + * Macintosh version of Tk. * * Copyright (c) 1995-1996 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. - * Copyright (c) 2005-2006 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.15 2006/08/18 07:47:11 das Exp $ + * RCS: @(#) $Id: tkMacOSXMenus.c,v 1.16 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 - /* Define constants only available on Mac OS X 10.3 or later */ - #define kMenuAttrDoNotUseUserCommandKeys (1 << 7) -#endif - -#define kAppleMenu 256 -#define kAppleAboutItem 1 -#define kFileMenu 2 -#define kEditMenu 3 +#define kAppleMenu 256 +#define kAppleAboutItem 1 +#define kFileMenu 2 +#define kEditMenu 3 -#define kSourceItem 1 -#define kCloseItem 2 +#define kSourceItem 1 +#define kCloseItem 2 -#define EDIT_CUT 1 -#define EDIT_COPY 2 -#define EDIT_PASTE 3 -#define EDIT_CLEAR 4 +#define EDIT_CUT 1 +#define EDIT_COPY 2 +#define EDIT_PASTE 3 +#define EDIT_CLEAR 4 MenuRef tkAppleMenu; MenuRef tkFileMenu; MenuRef tkEditMenu; -static Tcl_Interp * gInterp; /* Interpreter for this application. */ +static Tcl_Interp * gInterp; /* Interpreter for this application. */ -static void GenerateEditEvent _ANSI_ARGS_((int flag)); -static void SourceDialog _ANSI_ARGS_((void)); +static void GenerateEditEvent(int flag); +static void SourceDialog(void); + /* *---------------------------------------------------------------------- * * TkMacOSXHandleMenuSelect -- * - * Handles events that occur in the Menu bar. + * Handles events that occur in the Menu bar. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -void +void TkMacOSXHandleMenuSelect( MenuID theMenu, MenuItemIndex theItem, @@ -70,79 +66,78 @@ TkMacOSXHandleMenuSelect( TkDisplay *dispPtr; if (theItem == 0) { - TkMacOSXHandleTearoffMenu(); - TkMacOSXClearMenubarActive(); - return; + TkMacOSXClearMenubarActive(); + return; } switch (theMenu) { - case kAppleMenu: - switch (theItem) { - case kAppleAboutItem: - { - Tcl_CmdInfo dummy; - if (optionKeyPressed || gInterp == NULL || - Tcl_GetCommandInfo(gInterp, - "tkAboutDialog", &dummy) == 0) { - TkAboutDlg(); - } else { - Tcl_Eval(gInterp, "tkAboutDialog"); - } - break; - } - } - break; - case kFileMenu: - switch (theItem) { - case kSourceItem: - /* TODO: source script */ - SourceDialog(); - break; - case kCloseItem: - /* Send close event */ - window = TkMacOSXGetXWindow(ActiveNonFloatingWindow()); - dispPtr = TkGetDisplayList(); - tkwin = Tk_IdToWindow(dispPtr->display, window); - TkGenWMDestroyEvent(tkwin); - break; - } - break; - case kEditMenu: - /* - * This implementation just send keysyms - * the Tk thinks are associated with function keys that - * do Cut, Copy & Paste on a Sun keyboard. - */ - GenerateEditEvent(theItem); - break; - default: - TkMacOSXDispatchMenuEvent(theMenu, theItem); - TkMacOSXClearMenubarActive(); - break; + case kAppleMenu: + switch (theItem) { + case kAppleAboutItem: + { + Tcl_CmdInfo dummy; + if (optionKeyPressed || gInterp == NULL || + Tcl_GetCommandInfo(gInterp, + "tkAboutDialog", &dummy) == 0) { + TkAboutDlg(); + } else { + Tcl_EvalEx(gInterp, "tkAboutDialog", -1, + TCL_EVAL_GLOBAL); + } + break; + } + } + break; + case kFileMenu: + switch (theItem) { + case kSourceItem: + /* TODO: source script */ + SourceDialog(); + break; + case kCloseItem: + /* Send close event */ + window = TkMacOSXGetXWindow(ActiveNonFloatingWindow()); + dispPtr = TkGetDisplayList(); + tkwin = Tk_IdToWindow(dispPtr->display, window); + TkGenWMDestroyEvent(tkwin); + break; + } + break; + case kEditMenu: + /* + * This implementation just send the keysyms Tk thinks are + * associated with function keys that do Cut, Copy & Paste on + * a Sun keyboard. + */ + GenerateEditEvent(theItem); + break; + default: + TkMacOSXDispatchMenuEvent(theMenu, theItem); + break; } /* * Finally we unhighlight the menu. */ HiliteMenu(0); } - + /* *---------------------------------------------------------------------- * * TkMacOSXInitMenus -- * - * This procedure initializes the Macintosh menu bar. + * This procedure initializes the Macintosh menu bar. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -void +void TkMacOSXInitMenus( Tcl_Interp *interp) { @@ -152,36 +147,36 @@ TkMacOSXInitMenus( if (TkMacOSXUseMenuID(kAppleMenu) != TCL_OK) { Tcl_Panic("Menu ID %d is already in use!", kAppleMenu); } - err = CreateNewMenu(kAppleMenu, kMenuAttrDoNotUseUserCommandKeys, - &tkAppleMenu); + err = ChkErr(CreateNewMenu, kAppleMenu, kMenuAttrDoNotUseUserCommandKeys, + &tkAppleMenu); if (err != noErr) { - Tcl_Panic("CreateNewMenu failed !"); + Tcl_Panic("CreateNewMenu failed !"); } SetMenuTitle(tkAppleMenu, "\p\024"); InsertMenu(tkAppleMenu, 0); - AppendMenu(tkAppleMenu, "\pAbout Tcl & TkÉ"); + AppendMenu(tkAppleMenu, "\pAbout Tcl & Tk\xc9"); AppendMenu(tkAppleMenu, "\p(-"); if (TkMacOSXUseMenuID(kFileMenu) != TCL_OK) { Tcl_Panic("Menu ID %d is already in use!", kFileMenu); } - err = CreateNewMenu(kFileMenu, kMenuAttrDoNotUseUserCommandKeys, - &tkFileMenu); + err = ChkErr(CreateNewMenu, kFileMenu, kMenuAttrDoNotUseUserCommandKeys, + &tkFileMenu); if (err != noErr) { - Tcl_Panic("CreateNewMenu failed !"); + Tcl_Panic("CreateNewMenu failed !"); } SetMenuTitle(tkFileMenu, "\pFile"); InsertMenu(tkFileMenu, 0); - AppendMenu(tkFileMenu, "\pSourceÉ"); + AppendMenu(tkFileMenu, "\pSource\xc9"); AppendMenu(tkFileMenu, "\pClose/W"); if (TkMacOSXUseMenuID(kEditMenu) != TCL_OK) { Tcl_Panic("Menu ID %d is already in use!", kEditMenu); } - err = CreateNewMenu(kEditMenu, kMenuAttrDoNotUseUserCommandKeys, - &tkEditMenu); + err = ChkErr(CreateNewMenu, kEditMenu, kMenuAttrDoNotUseUserCommandKeys, + &tkEditMenu); if (err != noErr) { - Tcl_Panic("CreateNewMenu failed !"); + Tcl_Panic("CreateNewMenu failed !"); } SetMenuTitle(tkEditMenu, "\pEdit"); InsertMenu(tkEditMenu, 0); @@ -211,19 +206,19 @@ TkMacOSXInitMenus( * * GenerateEditEvent -- * - * Takes an edit menu item and posts the corasponding a virtual - * event to Tk's event queue. + * Takes an edit menu item and posts the corasponding a virtual + * event to Tk's event queue. * * Results: - * None. + * None. * * Side effects: - * May place events of queue. + * May place events of queue. * *---------------------------------------------------------------------- */ -static void +static void GenerateEditEvent( int flag) { @@ -238,7 +233,7 @@ GenerateEditEvent( tkwin = Tk_IdToWindow(dispPtr->display, window); tkwin = (Tk_Window) ((TkWindow *) tkwin)->dispPtr->focusPtr; if (tkwin == NULL) { - return; + return; } bzero(&event, sizeof(XVirtualEvent)); @@ -250,25 +245,25 @@ GenerateEditEvent( event.root = XRootWindow(Tk_Display(tkwin), 0); event.subwindow = None; event.time = TkpGetMS(); - + XQueryPointer(NULL, None, NULL, NULL, - &event.x_root, &event.y_root, &x, &y, &event.state); + &event.x_root, &event.y_root, &x, &y, &event.state); tkwin = Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y); event.same_screen = true; switch (flag) { - case EDIT_CUT: - event.name = Tk_GetUid("Cut"); - break; - case EDIT_COPY: - event.name = Tk_GetUid("Copy"); - break; - case EDIT_PASTE: - event.name = Tk_GetUid("Paste"); - break; - case EDIT_CLEAR: - event.name = Tk_GetUid("Clear"); - break; + case EDIT_CUT: + event.name = Tk_GetUid("Cut"); + break; + case EDIT_COPY: + event.name = Tk_GetUid("Copy"); + break; + case EDIT_PASTE: + event.name = Tk_GetUid("Paste"); + break; + case EDIT_CLEAR: + event.name = Tk_GetUid("Clear"); + break; } Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); } @@ -278,43 +273,38 @@ GenerateEditEvent( * * SourceDialog -- * - * Presents a dialog to the user for selecting a Tcl file. The - * selected file will be sourced into the main interpreter. + * Presents a dialog to the user for selecting a Tcl file. The + * selected file will be sourced into the main interpreter. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -static void -SourceDialog() +static void +SourceDialog(void) { int result; - CONST char *path; - CONST char *openCmd = "tk_getOpenFile -filetypes {\ - {{TCL Scripts} {.tcl} TEXT} {{Text Files} {} TEXT}}"; - + const char *path; + const char *openCmd = "tk_getOpenFile -filetypes {\ + {{TCL Scripts} {.tcl} TEXT} {{Text Files} {} TEXT}}"; + if (gInterp == NULL) { - return; + return; } - if (Tcl_Eval(gInterp, openCmd) != TCL_OK) { - return; + if (Tcl_EvalEx(gInterp, openCmd, -1, TCL_EVAL_GLOBAL) != TCL_OK) { + return; } path = Tcl_GetStringResult(gInterp); if (strlen(path) == 0) { - return; + return; } result = Tcl_EvalFile(gInterp, path); if (result == TCL_ERROR) { - Tcl_BackgroundError(gInterp); - } + Tcl_BackgroundError(gInterp); + } } -/* - * Local Variables: - * coding: macintosh; - * End: - */ diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c index b49bc4b..d3d1f61 100644 --- a/macosx/tkMacOSXMouseEvent.c +++ b/macosx/tkMacOSXMouseEvent.c @@ -5,56 +5,56 @@ * on MacOS X. * * Copyright 2001, Apple Computer, Inc. - * Copyright (c) 2005-2006 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * The following terms apply to all files originating from Apple - * Computer, Inc. ("Apple") and associated with the software - * unless explicitly disclaimed in individual files. - * - * - * Apple hereby grants permission to use, copy, modify, - * distribute, and license this software and its documentation - * for any purpose, provided that existing copyright notices are - * retained in all copies and that this notice is included - * verbatim in any distributions. No written agreement, license, - * or royalty fee is required for any of the authorized - * uses. Modifications to this software may be copyrighted by - * their authors and need not follow the licensing terms - * described here, provided that the new terms are clearly - * indicated on the first page of each file where they apply. - * - * - * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE - * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, - * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF - * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, - * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND - * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS - * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE - * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * GOVERNMENT USE: If you are acquiring this software on behalf - * of the U.S. government, the Government shall have only - * "Restricted Rights" in the software and related documentation - * as defined in the Federal Acquisition Regulations (FARs) in - * Clause 52.227.19 (c) (2). If you are acquiring the software - * on behalf of the Department of Defense, the software shall be - * classified as "Commercial Computer Software" and the - * Government shall have only "Restricted Rights" as defined in - * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the - * foregoing, the authors grant the U.S. Government and others - * acting in its behalf permission to use and distribute the - * software in accordance with the terms specified in this - * license. - * - * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.27 2007/04/21 19:06:38 hobbs Exp $ + * The following terms apply to all files originating from Apple + * Computer, Inc. ("Apple") and associated with the software + * unless explicitly disclaimed in individual files. + * + * + * Apple hereby grants permission to use, copy, modify, + * distribute, and license this software and its documentation + * for any purpose, provided that existing copyright notices are + * retained in all copies and that this notice is included + * verbatim in any distributions. No written agreement, license, + * or royalty fee is required for any of the authorized + * uses. Modifications to this software may be copyrighted by + * their authors and need not follow the licensing terms + * described here, provided that the new terms are clearly + * indicated on the first page of each file where they apply. + * + * + * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE + * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, + * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF + * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, + * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND + * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS + * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE + * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * GOVERNMENT USE: If you are acquiring this software on behalf + * of the U.S. government, the Government shall have only + * "Restricted Rights" in the software and related documentation + * as defined in the Federal Acquisition Regulations (FARs) in + * Clause 52.227.19 (c) (2). If you are acquiring the software + * on behalf of the Department of Defense, the software shall be + * classified as "Commercial Computer Software" and the + * Government shall have only "Restricted Rights" as defined in + * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the + * foregoing, the authors grant the U.S. Government and others + * acting in its behalf permission to use and distribute the + * software in accordance with the terms specified in this + * license. + * + * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.28 2007/04/23 21:24:33 das Exp $ */ #include "tkMacOSXInt.h" @@ -62,21 +62,15 @@ #include "tkMacOSXEvent.h" #include "tkMacOSXDebug.h" -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 - /* Define constants only available on Mac OS X 10.3 or later */ - #define kEventParamWindowPartCode 'wpar' - #define typeWindowPartCode 'wpar' -#endif - typedef struct { WindowRef whichWin; WindowRef activeNonFloating; WindowPartCode windowPart; - Point global; - Point local; unsigned int state; long delta; Window window; + Point global; + Point local; } MouseEventData; /* @@ -97,22 +91,23 @@ static int GenerateToolbarButtonEvent(MouseEventData * medPtr); static int HandleWindowTitlebarMouseDown(MouseEventData * medPtr, Tk_Window tkwin); static unsigned int ButtonModifiers2State(UInt32 buttonState, UInt32 keyModifiers); -static int TkMacOSXGetEatButtonUp(); +static int TkMacOSXGetEatButtonUp(void); static void TkMacOSXSetEatButtonUp(int f); + /* *---------------------------------------------------------------------- * * TkMacOSXProcessMouseEvent -- * - * This routine processes the event in eventPtr, and - * generates the appropriate Tk events from it. + * This routine processes the event in eventPtr, and + * generates the appropriate Tk events from it. * * Results: - * True if event(s) are generated - false otherwise. + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. + * Additional events may be place on the Tk event queue. * *---------------------------------------------------------------------- */ @@ -120,18 +115,18 @@ static void TkMacOSXSetEatButtonUp(int f); MODULE_SCOPE int TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) { - Tk_Window tkwin; - Point where, where2; - int xOffset, yOffset, result; - TkDisplay * dispPtr; - OSStatus status; + Tk_Window tkwin; + Point where, where2; + int result; + TkDisplay * dispPtr; + OSStatus err; MouseEventData mouseEventData, * medPtr = &mouseEventData; ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess}; - Boolean isFrontProcess = true; + Boolean isFrontProcess = true; switch (eventPtr->eKind) { - case kEventMouseUp: case kEventMouseDown: + case kEventMouseUp: case kEventMouseMoved: case kEventMouseDragged: case kEventMouseWheelMoved: @@ -140,27 +135,27 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) return false; break; } - status = GetEventParameter(eventPtr->eventRef, + err = ChkErr(GetEventParameter, eventPtr->eventRef, kEventParamMouseLocation, - typeQDPoint, NULL, + typeQDPoint, NULL, sizeof(where), NULL, &where); - if (status != noErr) { + if (err != noErr) { GetGlobalMouse(&where); } - status = GetEventParameter(eventPtr->eventRef, + err = ChkErr(GetEventParameter, eventPtr->eventRef, kEventParamWindowRef, - typeWindowRef, NULL, + typeWindowRef, NULL, sizeof(WindowRef), NULL, &medPtr->whichWin); - if (status == noErr) { - status = GetEventParameter(eventPtr->eventRef, + if (err == noErr) { + err = ChkErr(GetEventParameter, eventPtr->eventRef, kEventParamWindowPartCode, - typeWindowPartCode, NULL, + typeWindowPartCode, NULL, sizeof(WindowPartCode), NULL, &medPtr->windowPart); } - if (status != noErr) { + if (err != noErr) { medPtr->windowPart = FindWindow(where, &medPtr->whichWin); } medPtr->window = TkMacOSXGetXWindow(medPtr->whichWin); @@ -169,21 +164,23 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) } if (eventPtr->eKind == kEventMouseDown) { if (IsWindowPathSelectEvent(medPtr->whichWin, eventPtr->eventRef)) { - status = WindowPathSelect(medPtr->whichWin, NULL, NULL); + ChkErr(WindowPathSelect, medPtr->whichWin, NULL, NULL); return false; } if (medPtr->windowPart == inProxyIcon) { - status = TrackWindowProxyDrag(medPtr->whichWin, where); - if (status == errUserWantsToDragWindow) { + TkMacOSXTrackingLoop(1); + err = ChkErr(TrackWindowProxyDrag, medPtr->whichWin, where); + TkMacOSXTrackingLoop(0); + if (err == errUserWantsToDragWindow) { medPtr->windowPart = inDrag; } else { return false; } } } - status = GetFrontProcess(&frontPsn); - if (status == noErr) { - SameProcess(&frontPsn, &ourPsn, &isFrontProcess); + err = ChkErr(GetFrontProcess, &frontPsn); + if (err == noErr) { + ChkErr(SameProcess, &frontPsn, &ourPsn, &isFrontProcess); } if (isFrontProcess) { medPtr->state = ButtonModifiers2State(GetCurrentEventButtonState(), @@ -193,89 +190,80 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) GetCurrentKeyModifiers()); } medPtr->global = where; - status = GetEventParameter(eventPtr->eventRef, + err = ChkErr(GetEventParameter, eventPtr->eventRef, kEventParamWindowMouseLocation, - typeQDPoint, NULL, + typeQDPoint, NULL, sizeof(Point), NULL, &medPtr->local); - if (status == noErr) { + if (err == noErr) { if (medPtr->whichWin) { Rect widths; GetWindowStructureWidths(medPtr->whichWin, &widths); medPtr->local.h -= widths.left; - medPtr->local.v -= widths.top; + medPtr->local.v -= widths.top; } } else { medPtr->local = where; if (medPtr->whichWin) { QDGlobalToLocalPoint(GetWindowPort(medPtr->whichWin), - &medPtr->local); + &medPtr->local); } } medPtr->activeNonFloating = ActiveNonFloatingWindow(); - - /* - * The window manager only needs to know about mouse down events - * and sometimes we need to "eat" the mouse up. Otherwise, we - * just pass the event to Tk. - - */ - if (eventPtr->eKind == kEventMouseUp) { - if (TkMacOSXGetEatButtonUp()) { - TkMacOSXSetEatButtonUp(false); - return false; - } - return GenerateButtonEvent(medPtr); - } - if (eventPtr->eKind == kEventMouseDown) { - TkMacOSXSetEatButtonUp(false); - } - if (eventPtr->eKind == kEventMouseWheelMoved) { - status = GetEventParameter(eventPtr->eventRef, - kEventParamMouseWheelDelta, typeLongInteger, NULL, - sizeof(long), NULL, &medPtr->delta); - if (status != noErr ) { -#ifdef TK_MAC_DEBUG - fprintf (stderr, - "Failed to retrieve mouse wheel delta, %d\n", (int) status); -#endif - statusPtr->err = 1; - return false; - } else { - EventMouseWheelAxis axis; - status = GetEventParameter(eventPtr->eventRef, - kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL, - sizeof(EventMouseWheelAxis), NULL, &axis); - if (status == noErr && axis == kEventMouseWheelAxisX) { - medPtr->state |= ShiftMask; - } - } - } - dispPtr = TkGetDisplayList(); tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window); if (eventPtr->eKind != kEventMouseDown) { - /* - * MouseMoved, MouseDragged or MouseWheelMoved - */ + int res = false; - if (eventPtr->eKind == kEventMouseWheelMoved) { - int res = GenerateMouseWheelEvent(medPtr); - if (res) { - statusPtr->stopProcessing = 1; - } - return res; - } else { - return GeneratePollingEvents(medPtr); + switch (eventPtr->eKind) { + case kEventMouseUp: + /* + * The window manager only needs to know about mouse down + * events and sometimes we need to "eat" the mouse up. + * Otherwise, we just pass the event to Tk. + */ + if (TkMacOSXGetEatButtonUp()) { + TkMacOSXSetEatButtonUp(false); + } else { + res = GenerateButtonEvent(medPtr); + } + break; + case kEventMouseWheelMoved: + err = ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamMouseWheelDelta, typeLongInteger, NULL, + sizeof(long), NULL, &medPtr->delta); + if (err != noErr ) { + statusPtr->err = 1; + } else { + EventMouseWheelAxis axis; + err = ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamMouseWheelAxis, typeMouseWheelAxis, + NULL, sizeof(EventMouseWheelAxis), NULL, &axis); + if (err == noErr && axis == kEventMouseWheelAxisX) { + medPtr->state |= ShiftMask; + } + res = GenerateMouseWheelEvent(medPtr); + } + break; + case kEventMouseMoved: + case kEventMouseDragged: + res = GeneratePollingEvents(medPtr); + break; + default: + Tcl_Panic("Unknown mouse event !"); } + if (res) { + statusPtr->stopProcessing = 1; + } + return res; } - + TkMacOSXSetEatButtonUp(false); if (medPtr->whichWin) { /* * We got a mouse down in a window * See if this is the activate click - * This click moves the window forward. We don't want + * This click moves the window forward. We don't want * the corresponding mouse-up to be reported to the application * or else it will mess up some Tk scripts. */ @@ -284,20 +272,20 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) && (medPtr->whichWin != medPtr->activeNonFloating || !isFrontProcess)) { Tk_Window grabWin = TkMacOSXGetCapture(); - if ((grabWin == NULL)) { + if (!grabWin) { int grabState = TkGrabState((TkWindow*)tkwin); if (grabState != TK_GRAB_NONE && grabState != TK_GRAB_IN_TREE) { /* Now we want to set the focus to the local grabWin */ TkMacOSXSetEatButtonUp(true); grabWin = (Tk_Window) (((TkWindow*)tkwin)->dispPtr->grabWinPtr); BringWindowForward(GetWindowFromPort( - TkMacOSXGetDrawablePort(((TkWindow*)grabWin)->window)), - isFrontProcess); + TkMacOSXGetDrawablePort(((TkWindow*)grabWin)->window)), + isFrontProcess); statusPtr->stopProcessing = 1; return false; } } - if ((grabWin != NULL) && (grabWin != tkwin)) { + if (grabWin && grabWin != tkwin) { TkWindow * tkw, * grb; tkw = (TkWindow *)tkwin; grb = (TkWindow *)grabWin; @@ -314,9 +302,9 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) * Clicks in the titlebar widgets are handled without bringing the * window forward. */ - if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) { - return result; - } else + if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) { + return result; + } else /* * Only windows with the kWindowNoActivatesAttribute can * receive mouse events in the background. @@ -326,51 +314,55 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) /* * Allow background window dragging & growing with Command down */ - if (!((medPtr->windowPart == inDrag || + if (!((medPtr->windowPart == inDrag || medPtr->windowPart == inGrow) && medPtr->state & Mod1Mask)) { TkMacOSXSetEatButtonUp(true); BringWindowForward(medPtr->whichWin, isFrontProcess); - } - /* - * Allow dragging & growing of windows that were/are in the - * background. - */ - if (!(medPtr->windowPart == inDrag || + } + /* + * Allow dragging & growing of windows that were/are in the + * background. + */ + if (!(medPtr->windowPart == inDrag || medPtr->windowPart == inGrow)) { return false; - } - } + } + } } else { if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) { return result; } } switch (medPtr->windowPart) { - case inDrag: - SetPort(GetWindowPort(medPtr->whichWin)); - DragWindow(medPtr->whichWin, where, NULL); - where2.h = where2.v = 0; - LocalToGlobal(&where2); - if (EqualPt(where, where2)) { - return false; + case inDrag: { + WindowAttributes attributes; + + GetWindowAttributes(medPtr->whichWin, &attributes); + if (!(attributes & kWindowAsyncDragAttribute)) { + TkMacOSXTrackingLoop(1); + DragWindow(medPtr->whichWin, where, NULL); + TkMacOSXTrackingLoop(0); + where2.h = where2.v = 0; + QDLocalToGlobalPoint(GetWindowPort(medPtr->whichWin), + &where2); + if (EqualPt(where, where2)) { + return false; + } + return true; } - TkMacOSXWindowOffset(medPtr->whichWin, &xOffset, &yOffset); - where2.h -= xOffset; - where2.v -= yOffset; - TkGenWMConfigureEvent(tkwin, where2.h, where2.v, - -1, -1, TK_LOCATION_CHANGED); - return true; break; + } case inGrow: /* * Generally the content region is the domain of Tk - * sub-windows. However, one exception is the grow - * region. A button down in this area will be handled - * by the window manager. Note: this means that Tk + * sub-windows. However, one exception is the grow + * region. A button down in this area will be handled + * by the window manager. Note: this means that Tk * may not get button down events in this area! */ if (TkMacOSXGrowToplevel(medPtr->whichWin, where) == true) { + statusPtr->stopProcessing = 1; return true; } else { return GenerateButtonEvent(medPtr); @@ -392,14 +384,14 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) * * HandleWindowTitlebarMouseDown -- * - * Handle clicks in window titlebar. + * Handle clicks in window titlebar. * * Results: - * 1 if event was handled, 0 if event was not handled, - * -1 if MouseDown was not in window titlebar. + * 1 if event was handled, 0 if event was not handled, + * -1 if MouseDown was not in window titlebar. * * Side effects: - * Additional events may be place on the Tk event queue. + * Additional events may be place on the Tk event queue. * *---------------------------------------------------------------------- */ @@ -408,40 +400,41 @@ int HandleWindowTitlebarMouseDown(MouseEventData * medPtr, Tk_Window tkwin) { int result = 0; - + + TkMacOSXTrackingLoop(1); switch (medPtr->windowPart) { - case inGoAway: - if (TrackGoAway(medPtr->whichWin, medPtr->global)) { - if (tkwin) { - TkGenWMDestroyEvent(tkwin); - result = 1; - } - } - break; - case inCollapseBox: - if (TrackBox(medPtr->whichWin, medPtr->global, medPtr->windowPart)) { - if (tkwin) { - TkpWmSetState((TkWindow *)tkwin, IconicState); - result = 1; - } - } - break; - case inZoomIn: - case inZoomOut: - if (TrackBox(medPtr->whichWin, medPtr->global, medPtr->windowPart)) { - result = TkMacOSXZoomToplevel(medPtr->whichWin, medPtr->windowPart); - } - break; - case inToolbarButton: - if (TrackBox(medPtr->whichWin, medPtr->global, medPtr->windowPart)) { - result = GenerateToolbarButtonEvent(medPtr); - } - break; - default: - result = -1; - break; + case inGoAway: + if (TrackGoAway(medPtr->whichWin, medPtr->global)) { + if (tkwin) { + TkGenWMDestroyEvent(tkwin); + result = 1; + } + } + break; + case inCollapseBox: + if (TrackBox(medPtr->whichWin, medPtr->global, medPtr->windowPart)) { + if (tkwin) { + TkpWmSetState((TkWindow *)tkwin, IconicState); + result = 1; + } + } + break; + case inZoomIn: + case inZoomOut: + if (TrackBox(medPtr->whichWin, medPtr->global, medPtr->windowPart)) { + result = TkMacOSXZoomToplevel(medPtr->whichWin, medPtr->windowPart); + } + break; + case inToolbarButton: + if (TrackBox(medPtr->whichWin, medPtr->global, medPtr->windowPart)) { + result = GenerateToolbarButtonEvent(medPtr); + } + break; + default: + result = -1; + break; } - + TkMacOSXTrackingLoop(0); return result; } @@ -450,16 +443,16 @@ HandleWindowTitlebarMouseDown(MouseEventData * medPtr, Tk_Window tkwin) * * GeneratePollingEvents -- * - * This function polls the mouse position and generates X Motion, - * Enter & Leave events. The cursor is also updated at this - * time. + * This function polls the mouse position and generates X Motion, + * Enter & Leave events. The cursor is also updated at this + * time. * * Results: - * True if event(s) are generated - false otherwise. + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. - * The cursor may be changed. + * Additional events may be place on the Tk event queue. + * The cursor may be changed. * *---------------------------------------------------------------------- */ @@ -474,12 +467,12 @@ GeneratePollingEvents(MouseEventData * medPtr) grabWin = TkMacOSXGetCapture(); - if ((!TkpIsWindowFloating(medPtr->whichWin) + if ((!TkpIsWindowFloating(medPtr->whichWin) && (medPtr->activeNonFloating != medPtr->whichWin))) { /* * If the window for this event is not floating, and is not the * active non-floating window, don't generate polling events. - * We don't send events to backgrounded windows. So either send + * We don't send events to backgrounded windows. So either send * it to the grabWin, or NULL if there is no grabWin. */ @@ -487,23 +480,23 @@ GeneratePollingEvents(MouseEventData * medPtr) } else { /* * First check whether the toplevel containing this mouse - * event is the grab window. If not, then send the event - * to the grab window. Otherwise, set tkWin to the subwindow + * event is the grab window. If not, then send the event + * to the grab window. Otherwise, set tkWin to the subwindow * which most closely contains the mouse event. */ - + dispPtr = TkGetDisplayList(); rootwin = Tk_IdToWindow(dispPtr->display, medPtr->window); - if ((rootwin == NULL) + if ((rootwin == NULL) || ((grabWin != NULL) && (rootwin != grabWin))) { tkwin = grabWin; } else { - tkwin = Tk_TopCoordsToWindow(rootwin, - medPtr->local.h, medPtr->local.v, + tkwin = Tk_TopCoordsToWindow(rootwin, + medPtr->local.h, medPtr->local.v, &local_x, &local_y); } } - + /* * The following call will generate the appropiate X events and * adjust any state that Tk must remember. @@ -511,7 +504,7 @@ GeneratePollingEvents(MouseEventData * medPtr) Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v, medPtr->state); - + return true; } @@ -520,7 +513,7 @@ GeneratePollingEvents(MouseEventData * medPtr) * * BringWindowForward -- * - * Bring this background window to the front. We also set state + * Bring this background window to the front. We also set state * so Tk thinks the button is currently up. * * Results: @@ -533,21 +526,20 @@ GeneratePollingEvents(MouseEventData * medPtr) */ static void -BringWindowForward(WindowRef wRef, Boolean isFrontProcess) +BringWindowForward( + WindowRef wRef, + Boolean isFrontProcess) { if (!isFrontProcess) { ProcessSerialNumber ourPsn = {0, kCurrentProcess}; - OSStatus status = SetFrontProcess(&ourPsn); - if (status != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"SetFrontProcess failed, %d\n", (int) status); -#endif - } + + ChkErr(SetFrontProcess, &ourPsn); } - + if (!TkpIsWindowFloating(wRef)) { - if (IsValidWindowPtr(wRef)) + if (IsValidWindowPtr(wRef)) { SelectWindow(wRef); + } } } @@ -570,12 +562,12 @@ BringWindowForward(WindowRef wRef, Boolean isFrontProcess) static int GenerateMouseWheelEvent(MouseEventData * medPtr) { - Tk_Window tkwin, rootwin, grabWin; + Tk_Window tkwin, rootwin; TkDisplay *dispPtr; TkWindow *winPtr; - XEvent xEvent; + XEvent xEvent; - if ((!TkpIsWindowFloating(medPtr->whichWin) + if ((!TkpIsWindowFloating(medPtr->whichWin) && (medPtr->activeNonFloating != medPtr->whichWin))) { tkwin = NULL; } else { @@ -584,24 +576,22 @@ GenerateMouseWheelEvent(MouseEventData * medPtr) if (rootwin == NULL) { tkwin = NULL; } else { - tkwin = Tk_TopCoordsToWindow(rootwin, - medPtr->local.h, medPtr->local.v, + tkwin = Tk_TopCoordsToWindow(rootwin, + medPtr->local.h, medPtr->local.v, &xEvent.xbutton.x, &xEvent.xbutton.y); } } - + /* * The following call will generate the appropiate X events and * adjust any state that Tk must remember. */ - grabWin = TkMacOSXGetCapture(); - - if ((tkwin == NULL) && (grabWin != NULL)) { - tkwin = grabWin; + if (!tkwin) { + tkwin = TkMacOSXGetCapture(); } if (!tkwin) { - return false; + return false; } winPtr = (TkWindow *) tkwin; xEvent.type = MouseWheelEvent; @@ -628,12 +618,12 @@ GenerateMouseWheelEvent(MouseEventData * medPtr) * next mouse up event * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -static int -TkMacOSXGetEatButtonUp() +int +TkMacOSXGetEatButtonUp(void) { return gEatButtonUp; } @@ -644,7 +634,7 @@ TkMacOSXGetEatButtonUp() * TkMacOSXSetEatButtonUp -- * * Results: - * None. + * None. * * Side effects: * Sets the flag indicating if we need to eat the @@ -652,7 +642,7 @@ TkMacOSXGetEatButtonUp() * *---------------------------------------------------------------------- */ -static void +void TkMacOSXSetEatButtonUp(int f) { gEatButtonUp = f; @@ -661,42 +651,78 @@ TkMacOSXSetEatButtonUp(int f) /* *---------------------------------------------------------------------- * + * TkMacOSXKeyModifiers -- + * + * Returns the current state of the modifier keys. + * + * Results: + * An OS Modifier state. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +EventModifiers +TkMacOSXModifierState(void) +{ + UInt32 keyModifiers; + Boolean isFrontProcess = false; + + if (GetCurrentEvent()) { + ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess}; + OSStatus err = ChkErr(GetFrontProcess, &frontPsn); + + if (err == noErr) { + ChkErr(SameProcess, &frontPsn, &ourPsn, &isFrontProcess); + } + } + keyModifiers = isFrontProcess ? GetCurrentEventKeyModifiers() : + GetCurrentKeyModifiers(); + + return (EventModifiers)(keyModifiers & USHRT_MAX); +} + +/* + *---------------------------------------------------------------------- + * * TkMacOSXButtonKeyState -- * - * Returns the current state of the button & modifier keys. + * Returns the current state of the button & modifier keys. * * Results: - * A bitwise inclusive OR of a subset of the following: - * Button1Mask, ShiftMask, LockMask, ControlMask, Mod?Mask, - * Mod?Mask. + * A bitwise inclusive OR of a subset of the following: + * Button1Mask, ShiftMask, LockMask, ControlMask, Mod*Mask. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ unsigned int -TkMacOSXButtonKeyState() +TkMacOSXButtonKeyState(void) { UInt32 buttonState = 0, keyModifiers; Boolean isFrontProcess = false; - + if (GetCurrentEvent()) { ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess}; - OSStatus status = GetFrontProcess(&frontPsn); - if (status == noErr) { - SameProcess(&frontPsn, &ourPsn, &isFrontProcess); + OSStatus err = ChkErr(GetFrontProcess, &frontPsn); + + if (err == noErr) { + ChkErr(SameProcess, &frontPsn, &ourPsn, &isFrontProcess); } } - - if (!gEatButtonUp) { + + if (!TkMacOSXGetEatButtonUp()) { buttonState = isFrontProcess ? GetCurrentEventButtonState() : GetCurrentButtonState(); } keyModifiers = isFrontProcess ? GetCurrentEventKeyModifiers() : GetCurrentKeyModifiers(); - + return ButtonModifiers2State(buttonState, keyModifiers); } @@ -721,11 +747,11 @@ static unsigned int ButtonModifiers2State(UInt32 buttonState, UInt32 keyModifiers) { unsigned int state; - + /* Tk supports at most 5 buttons */ state = (buttonState & ((1<<5) - 1)) << 8; - - if (keyModifiers & alphaLock) { + + if (keyModifiers & alphaLock) { state |= LockMask; } if (keyModifiers & shiftKey) { @@ -740,10 +766,10 @@ ButtonModifiers2State(UInt32 buttonState, UInt32 keyModifiers) if (keyModifiers & optionKey) { state |= Mod2Mask; /* option key */ } - if (keyModifiers & kEventKeyModifierNumLockMask) { + if (keyModifiers & kEventKeyModifierNumLockMask) { state |= Mod3Mask; } - if (keyModifiers & kEventKeyModifierFnMask) { + if (keyModifiers & kEventKeyModifierFnMask) { state |= Mod4Mask; } @@ -755,16 +781,16 @@ ButtonModifiers2State(UInt32 buttonState, UInt32 keyModifiers) * * XQueryPointer -- * - * Check the current state of the mouse. This is not a complete - * implementation of this function. It only computes the root - * coordinates and the current mask. + * Check the current state of the mouse. This is not a complete + * implementation of this function. It only computes the root + * coordinates and the current mask. * * Results: - * Sets root_x_return, root_y_return, and mask_return. Returns - * true on success. + * Sets root_x_return, root_y_return, and mask_return. Returns + * true on success. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -786,48 +812,41 @@ XQueryPointer( if (getGlobal || getLocal) { Point where, local; - OSStatus status; + OSStatus err = noErr; int gotMouseLoc = 0; EventRef ev = GetCurrentEvent(); if (ev && getLocal) { - status = GetEventParameter(ev, - kEventParamWindowMouseLocation, - typeQDPoint, NULL, - sizeof(Point), NULL, - &local); - gotMouseLoc = (status == noErr); + err = ChkErr(GetEventParameter, ev, kEventParamWindowMouseLocation, + typeQDPoint, NULL, sizeof(Point), NULL, &local); + gotMouseLoc = (err == noErr); } if (getGlobal || !gotMouseLoc) { if (ev) { - status = GetEventParameter(ev, - kEventParamMouseLocation, - typeQDPoint, NULL, - sizeof(Point), NULL, - &where); + err = ChkErr(GetEventParameter, ev, kEventParamMouseLocation, + typeQDPoint, NULL, sizeof(Point), NULL, &where); } - if (!ev || status != noErr) { + if (!ev || err != noErr) { GetGlobalMouse(&where); } } if (getLocal) { WindowRef whichWin; if (ev) { - status = GetEventParameter(ev, - kEventParamWindowRef, - typeWindowRef, NULL, - sizeof(WindowRef), NULL, + err = ChkErr(GetEventParameter, ev, kEventParamWindowRef, + typeWindowRef, NULL, sizeof(WindowRef), NULL, &whichWin); } - if (!ev || status != noErr) { + if (!ev || err != noErr) { FindWindow(where, &whichWin); } if (gotMouseLoc) { if (whichWin) { Rect widths; - GetWindowStructureWidths(whichWin, &widths); + + ChkErr(GetWindowStructureWidths, whichWin, &widths); local.h -= widths.left; - local.v -= widths.top; + local.v -= widths.top; } } else { local = where; @@ -856,15 +875,15 @@ XQueryPointer( * * TkGenerateButtonEventForXPointer -- * - * This procedure generates an X button event for the current - * pointer state as reported by XQueryPointer(). + * This procedure generates an X button event for the current + * pointer state as reported by XQueryPointer(). * * Results: - * True if event(s) are generated - false otherwise. + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. - * Grab state may also change. + * Additional events may be place on the Tk event queue. + * Grab state may also change. * *---------------------------------------------------------------------- */ @@ -875,7 +894,7 @@ TkGenerateButtonEventForXPointer( { MouseEventData med; int global_x, global_y, local_x, local_y; - + bzero(&med, sizeof(MouseEventData)); XQueryPointer(NULL, None, NULL, NULL, &global_x, &global_y, &local_x, &local_y, &med.state); @@ -894,16 +913,16 @@ TkGenerateButtonEventForXPointer( * * TkGenerateButtonEvent -- * - * Given a global x & y position and the button key status this - * procedure generates the appropiate X button event. It also - * handles the state changes needed to implement implicit grabs. + * Given a global x & y position and the button key status this + * procedure generates the appropiate X button event. It also + * handles the state changes needed to implement implicit grabs. * * Results: - * True if event(s) are generated - false otherwise. + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. - * Grab state may also change. + * Additional events may be place on the Tk event queue. + * Grab state may also change. * *---------------------------------------------------------------------- */ @@ -916,7 +935,7 @@ TkGenerateButtonEvent( unsigned int state) /* Button Key state suitable for X event */ { MouseEventData med; - + bzero(&med, sizeof(MouseEventData)); med.state = state; med.window = window; @@ -935,15 +954,15 @@ TkGenerateButtonEvent( * * GenerateButtonEvent -- * - * Generate an X button event from a MouseEventData structure. - * Handles the state changes needed to implement implicit grabs. + * Generate an X button event from a MouseEventData structure. + * Handles the state changes needed to implement implicit grabs. * * Results: - * True if event(s) are generated - false otherwise. + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. - * Grab state may also change. + * Additional events may be place on the Tk event queue. + * Grab state may also change. * *---------------------------------------------------------------------- */ @@ -955,29 +974,30 @@ GenerateButtonEvent(MouseEventData * medPtr) int dummy; TkDisplay *dispPtr; - /* +#if UNUSED + /* * ButtonDown events will always occur in the front - * window. ButtonUp events, however, may occur anywhere - * on the screen. ButtonUp events should only be sent + * window. ButtonUp events, however, may occur anywhere + * on the screen. ButtonUp events should only be sent * to Tk if in the front window or during an implicit grab. */ - if (0 - && ((medPtr->activeNonFloating == NULL) - || ((!(TkpIsWindowFloating(medPtr->whichWin)) + if ((medPtr->activeNonFloating == NULL) + || ((!(TkpIsWindowFloating(medPtr->whichWin)) && (medPtr->activeNonFloating != medPtr->whichWin)) - && TkMacOSXGetCapture() == NULL))) { + && TkMacOSXGetCapture() == NULL)) { return false; } +#endif dispPtr = TkGetDisplayList(); tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window); if (tkwin != NULL) { - tkwin = Tk_TopCoordsToWindow(tkwin, medPtr->local.h, medPtr->local.v, + tkwin = Tk_TopCoordsToWindow(tkwin, medPtr->local.h, medPtr->local.v, &dummy, &dummy); } - Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v, medPtr->state); + Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v, medPtr->state); return true; } @@ -1014,7 +1034,7 @@ GenerateToolbarButtonEvent(MouseEventData * medPtr) medPtr->local.h, medPtr->local.v, &event.x, &event.y); } if (!tkwin) { - return true; + return true; } winPtr = (TkWindow *)tkwin; diff --git a/macosx/tkMacOSXNotify.c b/macosx/tkMacOSXNotify.c index 3eb3a3f..ccafbf9 100644 --- a/macosx/tkMacOSXNotify.c +++ b/macosx/tkMacOSXNotify.c @@ -1,18 +1,17 @@ /* * tkMacOSXNotify.c -- * - * This file contains the implementation of a tcl event source + * This file contains the implementation of a tcl event source * for the Carbon event loop. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. - * Copyright 2005, Tcl Core Team. - * Copyright (c) 2005 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXNotify.c,v 1.17 2007/01/19 00:36:45 das Exp $ + * RCS: @(#) $Id: tkMacOSXNotify.c,v 1.18 2007/04/23 21:24:34 das Exp $ */ #include "tkMacOSXInt.h" @@ -51,37 +50,37 @@ static void CarbonEventsCheckProc(ClientData clientData, int flags); */ void -Tk_MacOSXSetupTkNotifier() +Tk_MacOSXSetupTkNotifier(void) { ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - + if (!tsdPtr->initialized) { - /* HACK ALERT: There is a bug in Jaguar where when it goes to make - * the event queue for the Main Event Loop, it stores the Current - * event loop rather than the Main Event Loop in the Queue structure. - * So we have to make sure that the Main Event Queue gets set up on - * the main thread. Calling GetMainEventQueue will force this to - * happen. - */ - GetMainEventQueue(); - - tsdPtr->initialized = 1; - /* Install Carbon events event source in main event loop thread. */ - if (GetCurrentEventLoop() == GetMainEventLoop()) { - if (!pthread_main_np()) { - /* - * Panic if the Carbon main event loop thread (i.e. the - * thread where HIToolbox was first loaded) is not the - * main application thread, as Carbon does not support - * this properly. - */ - Tcl_Panic("Tk_MacOSXSetupTkNotifier: %s", - "first [load] of TkAqua has to occur in the main thread!"); - } - Tcl_CreateEventSource(CarbonEventsSetupProc, - CarbonEventsCheckProc, GetMainEventQueue()); - TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL); + /* HACK ALERT: There is a bug in Jaguar where when it goes to make + * the event queue for the Main Event Loop, it stores the Current + * event loop rather than the Main Event Loop in the Queue structure. + * So we have to make sure that the Main Event Queue gets set up on + * the main thread. Calling GetMainEventQueue will force this to + * happen. + */ + GetMainEventQueue(); + + tsdPtr->initialized = 1; + /* Install Carbon events event source in main event loop thread. */ + if (GetCurrentEventLoop() == GetMainEventLoop()) { + if (!pthread_main_np()) { + /* + * Panic if the Carbon main event loop thread (i.e. the + * thread where HIToolbox was first loaded) is not the + * main application thread, as Carbon does not support + * this properly. + */ + Tcl_Panic("Tk_MacOSXSetupTkNotifier: %s", + "first [load] of TkAqua has to occur in the main thread!"); + } + Tcl_CreateEventSource(CarbonEventsSetupProc, + CarbonEventsCheckProc, GetMainEventQueue()); + TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL); } } } @@ -110,8 +109,8 @@ TkMacOSXNotifyExitHandler(clientData) ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - Tcl_DeleteEventSource(CarbonEventsSetupProc, - CarbonEventsCheckProc, GetMainEventQueue()); + Tcl_DeleteEventSource(CarbonEventsSetupProc, + CarbonEventsCheckProc, GetMainEventQueue()); tsdPtr->initialized = 0; } @@ -121,7 +120,7 @@ TkMacOSXNotifyExitHandler(clientData) * CarbonEventsSetupProc -- * * This procedure implements the setup part of the Carbon Events - * event source. It is invoked by Tcl_DoOneEvent before entering + * event source. It is invoked by Tcl_DoOneEvent before entering * the notifier to check for events. * * Results: @@ -146,7 +145,7 @@ CarbonEventsSetupProc(clientData, flags) } if (GetNumEventsInQueue((EventQueueRef)clientData)) { - Tcl_SetMaxBlockTime(&blockTime); + Tcl_SetMaxBlockTime(&blockTime); } } @@ -174,19 +173,19 @@ CarbonEventsCheckProc(clientData, flags) { int numFound; OSStatus err = noErr; - + if (!(flags & TCL_WINDOW_EVENTS)) { return; } numFound = GetNumEventsInQueue((EventQueueRef)clientData); - + /* Avoid starving other event sources: */ if (numFound > 4) { - numFound = 4; + numFound = 4; } while (numFound > 0 && err == noErr) { - err = TkMacOSXReceiveAndProcessEvent(); - numFound--; + err = TkMacOSXReceiveAndDispatchEvent(); + numFound--; } } diff --git a/macosx/tkMacOSXPort.h b/macosx/tkMacOSXPort.h index 25b6b7d..3d3c634 100644 --- a/macosx/tkMacOSXPort.h +++ b/macosx/tkMacOSXPort.h @@ -1,17 +1,18 @@ /* * tkMacOSXPort.h -- * - * This file is included by all of the Tk C files. It contains + * This file is included by all of the Tk C files. It contains * information that may be configuration-dependent, such as * #includes for system include files and a few other things. * * Copyright (c) 1994-1996 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXPort.h,v 1.10 2007/01/05 00:00:51 nijtmans Exp $ + * RCS: @(#) $Id: tkMacOSXPort.h,v 1.11 2007/04/23 21:24:34 das Exp $ */ #ifndef _TKMACPORT @@ -19,16 +20,16 @@ /* * Macro to use instead of "void" for arguments that must have - * type "void *" in ANSI C; maps them to type "char *" in - * non-ANSI systems. This macro may be used in some of the include + * type "void *" in ANSI C; maps them to type "char *" in + * non-ANSI systems. This macro may be used in some of the include * files below, which is why it is defined here. */ #ifndef VOID # ifdef __STDC__ -# define VOID void +# define VOID void # else -# define VOID char +# define VOID char # endif #endif @@ -54,9 +55,9 @@ # include <time.h> #else # if HAVE_SYS_TIME_H -# include <sys/time.h> +# include <sys/time.h> # else -# include <time.h> +# include <time.h> # endif #endif #include <unistd.h> @@ -114,20 +115,6 @@ #endif /* - * Declarations for various library procedures that may not be declared - * in any other header file. - */ - -#ifndef strcasecmp -extern int strcasecmp _ANSI_ARGS_((const char *s1, - const char *s2)); -#endif -#ifndef strncasecmp -extern int strncasecmp _ANSI_ARGS_((const char *s1, - const char *s2, size_t n)); -#endif - -/* * The following define causes Tk to use its internal keysym hash table */ @@ -176,7 +163,7 @@ extern int strncasecmp _ANSI_ARGS_((const char *s1, #define TkpPrintWindowId(buf,w) \ sprintf((buf), "0x%x", (unsigned int) (w)) - + /* * TkpScanWindowId is just an alias for Tcl_GetInt on Unix. */ @@ -185,9 +172,19 @@ extern int strncasecmp _ANSI_ARGS_((const char *s1, Tcl_GetInt((i),(s),(int *) (wp)) /* - * Magic pixel values for dynamic (or active) colors. + * Turn off Tk double-buffering as Aqua windows are already double-buffered. + */ + +#define TK_NO_DOUBLE_BUFFERING 1 + +/* + * Magic pixel code values for system colors. + * + * NOTE: values must be kept in sync with indices into the + * systemColorMap array in tkMacOSXColor.c ! */ +#define TRANSPARENT_PIXEL 30 #define HIGHLIGHT_PIXEL 31 #define HIGHLIGHT_SECONDARY_PIXEL 32 #define HIGHLIGHT_TEXT_PIXEL 33 diff --git a/macosx/tkMacOSXRegion.c b/macosx/tkMacOSXRegion.c index 62b3efe..1e51343 100644 --- a/macosx/tkMacOSXRegion.c +++ b/macosx/tkMacOSXRegion.c @@ -1,44 +1,40 @@ -/* +/* * tkMacOSXRegion.c -- * - * Implements X window calls for manipulating regions + * Implements X window calls for manipulating regions * * Copyright (c) 1995-1996 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.5 2006/03/24 14:58:01 das Exp $ + * RCS: @(#) $Id: tkMacOSXRegion.c,v 1.6 2007/04/23 21:24:34 das Exp $ */ #include "tkMacOSXInt.h" -/* - * Temporary region that can be reused. - */ -static RgnHandle tmpRgn = NULL; - /* *---------------------------------------------------------------------- * * TkCreateRegion -- * - * Implements the equivelent of the X window function - * XCreateRegion. See X window documentation for more details. + * Implements the equivelent of the X window function + * XCreateRegion. See X window documentation for more details. * * Results: - * Returns an allocated region handle. + * Returns an allocated region handle. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ TkRegion -TkCreateRegion() +TkCreateRegion(void) { RgnHandle rgn; rgn = NewRgn(); @@ -50,19 +46,19 @@ TkCreateRegion() * * TkDestroyRegion -- * - * Implements the equivelent of the X window function - * XDestroyRegion. See X window documentation for more details. + * Implements the equivelent of the X window function + * XDestroyRegion. See X window documentation for more details. * * Results: - * None. + * None. * * Side effects: - * Memory is freed. + * Memory is freed. * *---------------------------------------------------------------------- */ -void +void TkDestroyRegion( TkRegion r) { @@ -75,19 +71,19 @@ TkDestroyRegion( * * TkIntersectRegion -- * - * Implements the equivilent of the X window function - * XIntersectRegion. See X window documentation for more details. + * Implements the equivilent of the X window function + * XIntersectRegion. See X window documentation for more details. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -void +void TkIntersectRegion( TkRegion sra, TkRegion srb, @@ -104,20 +100,20 @@ TkIntersectRegion( * * TkUnionRectWithRegion -- * - * Implements the equivelent of the X window function - * XUnionRectWithRegion. See X window documentation for more - * details. + * Implements the equivelent of the X window function + * XUnionRectWithRegion. See X window documentation for more + * details. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -void +void TkUnionRectWithRegion( XRectangle* rectangle, TkRegion src_region, @@ -126,12 +122,11 @@ TkUnionRectWithRegion( RgnHandle srcRgn = (RgnHandle) src_region; RgnHandle destRgn = (RgnHandle) dest_region_return; - if (tmpRgn == NULL) { - tmpRgn = NewRgn(); - } - SetRectRgn(tmpRgn, rectangle->x, rectangle->y, + TkMacOSXCheckTmpRgnEmpty(1); + SetRectRgn(tkMacOSXtmpRgn1, rectangle->x, rectangle->y, rectangle->x + rectangle->width, rectangle->y + rectangle->height); - UnionRgn(srcRgn, tmpRgn, destRgn); + UnionRgn(srcRgn, tkMacOSXtmpRgn1, destRgn); + SetEmptyRgn(tkMacOSXtmpRgn1); } /* @@ -139,19 +134,19 @@ TkUnionRectWithRegion( * * TkRectInRegion -- * - * Implements the equivelent of the X window function - * XRectInRegion. See X window documentation for more details. + * Implements the equivelent of the X window function + * XRectInRegion. See X window documentation for more details. * * Results: - * Returns one of: RectangleOut, RectangleIn, RectanglePart. + * Returns one of: RectangleOut, RectangleIn, RectanglePart. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -int +int TkRectInRegion( TkRegion region, int x, @@ -160,22 +155,19 @@ TkRectInRegion( unsigned int height) { RgnHandle rgn = (RgnHandle) region; - RgnHandle rectRgn, destRgn; int result; - - rectRgn = NewRgn(); - destRgn = NewRgn(); - SetRectRgn(rectRgn, x, y, x + width, y + height); - SectRgn(rgn, rectRgn, destRgn); - if (EmptyRgn(destRgn)) { + + TkMacOSXCheckTmpRgnEmpty(1); + SetRectRgn(tkMacOSXtmpRgn1, x, y, x + width, y + height); + SectRgn(rgn, tkMacOSXtmpRgn1, tkMacOSXtmpRgn1); + if (EmptyRgn(tkMacOSXtmpRgn1)) { result = RectangleOut; - } else if (EqualRgn(rgn, destRgn)) { + } else if (EqualRgn(rgn, tkMacOSXtmpRgn1)) { result = RectangleIn; } else { result = RectanglePart; } - DisposeRgn(rectRgn); - DisposeRgn(destRgn); + SetEmptyRgn(tkMacOSXtmpRgn1); return result; } @@ -184,19 +176,19 @@ TkRectInRegion( * * TkClipBox -- * - * Implements the equivelent of the X window function XClipBox. - * See X window documentation for more details. + * Implements the equivelent of the X window function XClipBox. + * See X window documentation for more details. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -void +void TkClipBox( TkRegion r, XRectangle* rect_return) @@ -218,7 +210,7 @@ TkClipBox( * TkSubtractRegion -- * * Implements the equivilent of the X window function - * XSubtractRegion. See X window documentation for more details. + * XSubtractRegion. See X window documentation for more details. * * Results: * None. @@ -229,7 +221,7 @@ TkClipBox( *---------------------------------------------------------------------- */ -void +void TkSubtractRegion( TkRegion sra, TkRegion srb, @@ -301,3 +293,34 @@ TkpBuildRegionFromAlphaData( dataPtr += lineStride; } } + +#if 0 +int +XSetClipRectangles(Display *d, GC gc, int clip_x_origin, int clip_y_origin, + XRectangle* rectangles, int n, int ordering) +{ + RgnHandle clipRgn; + + if (gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type + == TKP_CLIP_REGION) { + clipRgn = (RgnHandle) ((TkpClipMask*)gc->clip_mask)->value.region; + SetEmptyRgn(clipRgn); + } else { + clipRgn = NewRgn(); /* LEAK! */ + } + + TkMacOSXCheckTmpRgnEmpty(1); + while (n--) { + int x = clip_x_origin + rectangles->x; + int y = clip_y_origin + rectangles->y; + + SetRectRgn(tkMacOSXtmpRgn1, x, y, x + rectangles->width, + y + rectangles->height); + UnionRgn(tkMacOSXtmpRgn1, clipRgn, clipRgn); + rectangles++; + } + SetEmptyRgn(tkMacOSXtmpRgn1); + TkSetRegion(d, gc, (TkRegion) clipRgn); + return 1; +} +#endif diff --git a/macosx/tkMacOSXScale.c b/macosx/tkMacOSXScale.c index 8aab83c..f0fca13 100644 --- a/macosx/tkMacOSXScale.c +++ b/macosx/tkMacOSXScale.c @@ -1,24 +1,32 @@ -/* +/* * tkMacOSXScale.c -- * - * This file implements the Macintosh specific portion of the + * This file implements the Macintosh specific portion of the * scale widget. * * Copyright (c) 1996 by Sun Microsystems, Inc. * Copyright (c) 1998-2000 by Scriptics Corporation. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXScale.c,v 1.10 2007/04/21 19:06:38 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXScale.c,v 1.11 2007/04/23 21:24:34 das Exp $ */ #include "tkMacOSXInt.h" #include "tkScale.h" /* +#ifdef TK_MAC_DEBUG +#define TK_MAC_DEBUG_SCALE +#endif +*/ + +/* * Defines used in this file. */ + #define slider 1110 #define inSlider 1 #define inInc 2 @@ -43,10 +51,10 @@ static ControlActionUPP scaleActionProc = NULL; /* Pointer to func. */ * Forward declarations for procedures defined later in this file: */ -static void MacScaleEventProc _ANSI_ARGS_((ClientData clientData, - XEvent *eventPtr)); -static pascal void ScaleActionProc _ANSI_ARGS_((ControlRef theControl, - ControlPartCode partCode)); +static void MacScaleEventProc(ClientData clientData, XEvent *eventPtr); +static pascal void ScaleActionProc(ControlRef theControl, + ControlPartCode partCode); + /* *---------------------------------------------------------------------- @@ -65,20 +73,19 @@ static pascal void ScaleActionProc _ANSI_ARGS_((ControlRef theControl, */ TkScale * -TkpCreateScale(tkwin) - Tk_Window tkwin; +TkpCreateScale( + Tk_Window tkwin) { - MacScale *macScalePtr; - - macScalePtr = (MacScale *) ckalloc(sizeof(MacScale)); + MacScale *macScalePtr = (MacScale *) ckalloc(sizeof(MacScale)); + macScalePtr->scaleHandle = NULL; if (scaleActionProc == NULL) { scaleActionProc = NewControlActionUPP(ScaleActionProc); } - + Tk_CreateEventHandler(tkwin, ButtonPressMask, MacScaleEventProc, (ClientData) macScalePtr); - + return (TkScale *) macScalePtr; } @@ -99,16 +106,17 @@ TkpCreateScale(tkwin) */ void -TkpDestroyScale(scalePtr) - TkScale *scalePtr; +TkpDestroyScale( + TkScale *scalePtr) { MacScale *macScalePtr = (MacScale *) scalePtr; - + /* * Free Macintosh control. */ + if (macScalePtr->scaleHandle != NULL) { - DisposeControl(macScalePtr->scaleHandle); + DisposeControl(macScalePtr->scaleHandle); } } @@ -130,8 +138,8 @@ TkpDestroyScale(scalePtr) */ void -TkpDisplayScale(clientData) - ClientData clientData; /* Widget record for scale. */ +TkpDisplayScale( + ClientData clientData) /* Widget record for scale. */ { TkScale *scalePtr = (TkScale *) clientData; Tk_Window tkwin = scalePtr->tkwin; @@ -141,18 +149,14 @@ TkpDisplayScale(clientData) MacScale *macScalePtr = (MacScale *) clientData; Rect r; WindowRef windowRef; - CGrafPtr destPort; - CGrafPtr saveWorld; - GDHandle saveDevice; + CGrafPtr destPort, savePort; + Boolean portChanged; MacDrawable *macDraw; - SInt32 initialValue; - SInt32 minValue; - SInt32 maxValue; - UInt16 numTicks; - + SInt32 initialValue, minValue, maxValue; + UInt16 numTicks; -#ifdef TK_MAC_DEBUG - fprintf(stderr,"TkpDisplayScale\n"); +#ifdef TK_MAC_DEBUG_SCALE + TkMacOSXDbgMsg("TkpDisplayScale"); #endif scalePtr->flags &= ~REDRAW_PENDING; if ((scalePtr->tkwin == NULL) || !Tk_IsMapped(scalePtr->tkwin)) { @@ -167,8 +171,7 @@ TkpDisplayScale(clientData) if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) { Tcl_Preserve((ClientData) interp); sprintf(string, scalePtr->format, scalePtr->value); - result = Tcl_VarEval(interp, scalePtr->command, " ", string, - (char *) NULL); + result = Tcl_VarEval(interp, scalePtr->command, " ", string, NULL); if (result != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (command executed by scale)"); Tcl_BackgroundError(interp); @@ -184,14 +187,13 @@ TkpDisplayScale(clientData) /* * Now handle the part of redisplay that is the same for - * horizontal and vertical scales: border and traversal + * horizontal and vertical scales: border and traversal * highlight. */ if (scalePtr->highlightWidth != 0) { - GC gc; - - gc = Tk_GCForColor(scalePtr->highlightColorPtr, Tk_WindowId(tkwin)); + GC gc = Tk_GCForColor(scalePtr->highlightColorPtr, Tk_WindowId(tkwin)); + Tk_DrawFocusHighlight(tkwin, gc, scalePtr->highlightWidth, Tk_WindowId(tkwin)); } @@ -204,11 +206,11 @@ TkpDisplayScale(clientData) /* * Set up port for drawing Macintosh control. */ + macDraw = (MacDrawable *) Tk_WindowId(tkwin); destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); windowRef = GetWindowFromPort(destPort); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); + portChanged = QDSwapPort(dstPort, &savePort); TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin)); /* @@ -218,78 +220,78 @@ TkpDisplayScale(clientData) #define MAC_OSX_SCROLL_WIDTH 10 if (scalePtr->orient == ORIENT_HORIZONTAL) { - int offset; - offset = (Tk_Height(tkwin) - MAC_OSX_SCROLL_WIDTH)/2; - if (offset < 0) { - offset = 0; - } - - r.left = macDraw->xOff + scalePtr->inset; - r.top = macDraw->yOff + offset; - r.right = macDraw->xOff+Tk_Width(tkwin) - scalePtr->inset; - r.bottom = macDraw->yOff + offset + MAC_OSX_SCROLL_WIDTH/2; + int offset = (Tk_Height(tkwin) - MAC_OSX_SCROLL_WIDTH)/2; + + if (offset < 0) { + offset = 0; + } + + r.left = macDraw->xOff + scalePtr->inset; + r.top = macDraw->yOff + offset; + r.right = macDraw->xOff+Tk_Width(tkwin) - scalePtr->inset; + r.bottom = macDraw->yOff + offset + MAC_OSX_SCROLL_WIDTH/2; } else { - int offset; - - offset = (Tk_Width(tkwin) - MAC_OSX_SCROLL_WIDTH)/2; - if (offset < 0) { - offset = 0; - } - - r.left = macDraw->xOff + offset; - r.top = macDraw->yOff + scalePtr->inset; - r.right = macDraw->xOff + offset + MAC_OSX_SCROLL_WIDTH/2; - r.bottom = macDraw->yOff+Tk_Height(tkwin) - scalePtr->inset; + int offset = (Tk_Width(tkwin) - MAC_OSX_SCROLL_WIDTH)/2; + + if (offset < 0) { + offset = 0; + } + + r.left = macDraw->xOff + offset; + r.top = macDraw->yOff + scalePtr->inset; + r.right = macDraw->xOff + offset + MAC_OSX_SCROLL_WIDTH/2; + r.bottom = macDraw->yOff+Tk_Height(tkwin) - scalePtr->inset; } if (macScalePtr->scaleHandle == NULL) { - -#ifdef TK_MAC_DEBUG - fprintf(stderr,"Initialising scale\n"); +#ifdef TK_MAC_DEBUG_SCALE + TkMacOSXDbgMsg("Initialising scale"); #endif + initialValue = scalePtr->value; + if (scalePtr->orient == ORIENT_HORIZONTAL) { + minValue = scalePtr->fromValue; + maxValue = scalePtr->toValue; + } else { + minValue = scalePtr->fromValue; + maxValue = scalePtr->toValue; + } - initialValue = scalePtr->value; - if (scalePtr->orient == ORIENT_HORIZONTAL) { - minValue = scalePtr->fromValue; - maxValue = scalePtr->toValue; - } else { - minValue = scalePtr->fromValue; - maxValue = scalePtr->toValue; - } - - if (scalePtr->tickInterval == 0) { - numTicks = 0; - } else { - numTicks = (maxValue - minValue)/scalePtr->tickInterval; - } - - CreateSliderControl(windowRef, &r, initialValue, minValue, maxValue, - kControlSliderPointsDownOrRight, numTicks, - 1, scaleActionProc, - &(macScalePtr->scaleHandle)); - SetControlReference(macScalePtr->scaleHandle, (UInt32) scalePtr); + if (scalePtr->tickInterval == 0) { + numTicks = 0; + } else { + numTicks = (maxValue - minValue)/scalePtr->tickInterval; + } + + CreateSliderControl(windowRef, &r, initialValue, minValue, maxValue, + kControlSliderPointsDownOrRight, numTicks, 1, scaleActionProc, + &(macScalePtr->scaleHandle)); + SetControlReference(macScalePtr->scaleHandle, (UInt32) scalePtr); /* * If we are foremost than make us active. */ + if (windowRef == FrontWindow()) { macScalePtr->flags |= ACTIVE; } } else { - SetControlBounds(macScalePtr->scaleHandle, &r); - SetControl32BitValue(macScalePtr->scaleHandle, scalePtr->value); - SetControl32BitMinimum(macScalePtr->scaleHandle, scalePtr->fromValue); - SetControl32BitMaximum(macScalePtr->scaleHandle, scalePtr->toValue); + SetControlBounds(macScalePtr->scaleHandle, &r); + SetControl32BitValue(macScalePtr->scaleHandle, scalePtr->value); + SetControl32BitMinimum(macScalePtr->scaleHandle, scalePtr->fromValue); + SetControl32BitMaximum(macScalePtr->scaleHandle, scalePtr->toValue); } /* * Finally draw the control. */ + SetControlVisibility(macScalePtr->scaleHandle,true,true); HiliteControl(macScalePtr->scaleHandle,0); Draw1Control(macScalePtr->scaleHandle); - SetGWorld(saveWorld, saveDevice); + if (portChanged) { + QDSwapPort(savePort, NULL); + } done: scalePtr->flags &= ~REDRAW_ALL; } @@ -314,57 +316,57 @@ done: */ int -TkpScaleElement(scalePtr, x, y) - TkScale *scalePtr; /* Widget record for scale. */ - int x, y; /* Coordinates within scalePtr's window. */ +TkpScaleElement( + TkScale *scalePtr, /* Widget record for scale. */ + int x, int y) /* Coordinates within scalePtr's window. */ { MacScale *macScalePtr = (MacScale *) scalePtr; ControlPartCode part; Point where; Rect bounds; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; -#ifdef TK_MAC_DEBUG - fprintf(stderr,"TkpScaleElement\n"); -#endif + CGrafPtr destPort, savePort; + Boolean portChanged; +#ifdef TK_MAC_DEBUG_SCALE + TkMacOSXDbgMsg("TkpScaleElement"); +#endif destPort = TkMacOSXGetDrawablePort(Tk_WindowId(scalePtr->tkwin)); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); + portChanged = QDSwapPort(dstPort, &savePort); /* * All of the calculations in this procedure mirror those in - * DisplayScrollbar. Be sure to keep the two consistent. + * DisplayScrollbar. Be sure to keep the two consistent. */ - TkMacOSXWinBounds((TkWindow *) scalePtr->tkwin, &bounds); + TkMacOSXWinBounds((TkWindow *) scalePtr->tkwin, &bounds); where.h = x + bounds.left; where.v = y + bounds.top; part = TestControl(macScalePtr->scaleHandle, where); - - SetGWorld(saveWorld, saveDevice); -#ifdef TK_MAC_DEBUG + if (portChanged) { + QDSwapPort(savePort, NULL); + } + +#ifdef TK_MAC_DEBUG_SCALE fprintf (stderr,"ScalePart %d, pos ( %d %d )\n", part, where.h, where.v ); #endif - + switch (part) { - case inSlider: + case inSlider: return SLIDER; - case inInc: + case inInc: if (scalePtr->orient == ORIENT_VERTICAL) { return TROUGH1; } else { return TROUGH2; } - case inDecr: + case inDecr: if (scalePtr->orient == ORIENT_VERTICAL) { return TROUGH2; } else { return TROUGH1; } - default: + default: return OTHER; } } @@ -374,7 +376,7 @@ TkpScaleElement(scalePtr, x, y) * * MacScaleEventProc -- * - * This procedure is invoked by the Tk dispatcher for + * This procedure is invoked by the Tk dispatcher for * ButtonPress events on scales. * * Results: @@ -382,63 +384,70 @@ TkpScaleElement(scalePtr, x, y) * * Side effects: * When the window gets deleted, internal structures get - * cleaned up. When it gets exposed, it is redisplayed. + * cleaned up. When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */ static void -MacScaleEventProc(clientData, eventPtr) - ClientData clientData; /* Information about window. */ - XEvent *eventPtr; /* Information about event. */ +MacScaleEventProc( + ClientData clientData, /* Information about window. */ + XEvent *eventPtr) /* Information about event. */ { MacScale *macScalePtr = (MacScale *) clientData; Point where; Rect bounds; int part; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + CGrafPtr destPort, savePort; + Boolean portChanged; -#ifdef TK_MAC_DEBUG +#ifdef TK_MAC_DEBUG_SCALE fprintf(stderr,"MacScaleEventProc\n" ); #endif + /* * To call Macintosh control routines we must have the port - * set to the window containing the control. We will then test + * set to the window containing the control. We will then test * which part of the control was hit and act accordingly. */ + destPort = TkMacOSXGetDrawablePort(Tk_WindowId(macScalePtr->info.tkwin)); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); + portChanged = QDSwapPort(dstPort, &savePort); TkMacOSXSetUpClippingRgn(Tk_WindowId(macScalePtr->info.tkwin)); - TkMacOSXWinBounds((TkWindow *) macScalePtr->info.tkwin, &bounds); + TkMacOSXWinBounds((TkWindow *) macScalePtr->info.tkwin, &bounds); where.h = eventPtr->xbutton.x + bounds.left; where.v = eventPtr->xbutton.y + bounds.top; -#ifdef TK_MAC_DEBUG - fprintf(stderr,"calling TestControl\n"); +#ifdef TK_MAC_DEBUG_SCALE + TkMacOSXDbgMsg("calling TestControl"); #endif part = TestControl(macScalePtr->scaleHandle, where); if (part == 0) { return; } - - part = TrackControl(macScalePtr->scaleHandle, where, scaleActionProc); - + + TkMacOSXTrackingLoop(1); + part = HandleControlClick(macScalePtr->scaleHandle, where, + TkMacOSXModifierState(), scaleActionProc); + TkMacOSXTrackingLoop(0); + /* * Update the value for the widget. */ + macScalePtr->info.value = GetControlValue(macScalePtr->scaleHandle); /* TkScaleSetValue(&macScalePtr->info, macScalePtr->info.value, 1, 0); */ /* - * The TrackControl call will "eat" the ButtonUp event. We now + * The HandleControlClick call will "eat" the ButtonUp event. We now * generate a ButtonUp event so Tk will unset implicit grabs etc. */ + TkGenerateButtonEventForXPointer(Tk_WindowId(macScalePtr->info.tkwin)); - SetGWorld(saveWorld, saveDevice); + if (portChanged) { + QDSwapPort(savePort, NULL); + } } /* @@ -447,8 +456,8 @@ MacScaleEventProc(clientData, eventPtr) * ScaleActionProc -- * * Callback procedure used by the Macintosh toolbox call - * TrackControl. This call will update the display while - * the scrollbar is being manipulated by the user. + * HandleControlClick. This call will update the display + * while the scrollbar is being manipulated by the user. * * Results: * None. @@ -467,13 +476,13 @@ ScaleActionProc( int value; TkScale *scalePtr = (TkScale *) GetControlReference(theControl); -#ifdef TK_MAC_DEBUG - fprintf(stderr,"ScaleActionProc\n"); +#ifdef TK_MAC_DEBUG_SCALE + TkMacOSXDbgMsg("ScaleActionProc"); #endif - value = GetControlValue(theControl); + value = GetControlValue(theControl); TkScaleSetValue(scalePtr, value, 1, 1); Tcl_Preserve((ClientData) scalePtr); - Tcl_DoOneEvent(TCL_IDLE_EVENTS); + TkMacOSXRunTclEventLoop(); Tcl_Release((ClientData) scalePtr); } diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c index d096c03..48d153a 100644 --- a/macosx/tkMacOSXScrlbr.c +++ b/macosx/tkMacOSXScrlbr.c @@ -1,172 +1,206 @@ -/* +/* * tkMacOSXScrollbar.c -- * - * This file implements the Macintosh specific portion of the scrollbar - * widget. The Macintosh scrollbar may also draw a windows grow - * region under certain cases. + * This file implements the Macintosh specific portion of the scrollbar + * widget. The Macintosh scrollbar may also draw a windows grow + * region under certain cases. * * Copyright (c) 1996 by Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXScrlbr.c,v 1.20 2006/08/24 05:22:27 das Exp $ + * RCS: @(#) $Id: tkMacOSXScrlbr.c,v 1.21 2007/04/23 21:24:34 das Exp $ */ #include "tkMacOSXInt.h" #include "tkScrollbar.h" #include "tkMacOSXDebug.h" -#include "tclInt.h" /* for TclServiceIdle() */ +#define MIN_SCROLLBAR_VALUE 0 +#define SCROLLBAR_SCALING_VALUE ((float)LONG_MAX) /* - * The following definitions should really be in MacOS - * header files. They are included here as this is the only - * file that needs the declarations. + * Declaration of Mac specific scrollbar structure. */ -typedef pascal void (*ThumbActionFunc)(void); - -typedef ThumbActionFunc ThumbActionUPP; - -enum { - uppThumbActionProcInfo = kPascalStackBased -}; -#define NewThumbActionProc(userRoutine) ((ThumbActionUPP) (userRoutine)) +typedef struct MacScrollbar { + TkScrollbar info; /* Generic scrollbar info */ + ControlRef sbHandle; /* Scrollbar control */ + int macFlags; /* Various flags; see below */ + Rect eraseRect; /* Rect to erase before drawing control */ +} MacScrollbar; /* - * Minimum slider length, in pixels (designed to make sure that the slider - * is always easy to grab with the mouse). + * Flag bits for scrollbars on the Mac: + * + * ALREADY_DEAD: Non-zero means this scrollbar has been + * destroyed, but has not been cleaned up. + * IN_MODAL_LOOP: Non-zero means this scrollbar is in the middle + * of a modal loop. + * ACTIVE: Non-zero means this window is currently + * active (in the foreground). */ -#define MIN_SLIDER_LENGTH 5 -#define MIN_SCROLLBAR_VALUE 0 -#define SCROLLBAR_SCALING_VALUE 100000 -#define SCROLLBAR_SCALING_DVALUE 100000.0 +#define ALREADY_DEAD 1 +#define IN_MODAL_LOOP 2 +#define ACTIVE 4 /* - * Declaration of Windows specific scrollbar structure. + * Globals uses locally in this file. */ - -typedef struct MacScrollbar { - TkScrollbar info; /* Generic scrollbar info */ - ControlRef sbHandle; /* Opaque handle to the Scrollbar contol struct */ - int macFlags; /* Various flags; see below */ -} MacScrollbar; - -/* Handle to the Scrollbar control structure */ - +static ControlActionUPP scrollActionProc = NULL; /* Pointer to func. */ +static ControlActionUPP thumbActionProc = NULL; /* Pointer to func. */ +static Point mouseDownPoint; /* Used to store the coordinates where the */ + /* mouse was first pressed to begin */ + /* dragging the thumb, because */ + /* ThumbActionProc can't take any args. */ + +typedef struct ScrollbarMetrics { + SInt32 width, minHeight, minThumbHeight; + short topArrowHeight, bottomArrowHeight; + ControlSize size; +} ScrollbarMetrics; + +static ScrollbarMetrics metrics[2] = { + {15, 54, 26, 14, 14, kControlSizeNormal}, /* kThemeScrollBarMedium */ + {11, 40, 20, 10, 10, kControlSizeSmall}, /* kThemeScrollBarSmall */ +}; /* - * Flag bits for scrollbars on the Mac: - * - * ALREADY_DEAD: Non-zero means this scrollbar has been - * destroyed, but has not been cleaned up. - * IN_MODAL_LOOP: Non-zero means this scrollbar is in the middle - * of a modal loop. - * ACTIVE: Non-zero means this window is currently - * active (in the foreground). - * FLUSH_TOP: Flush with top of Mac window. - * FLUSH_BOTTOM: Flush with bottom of Mac window. - * FLUSH_RIGHT: Flush with right of Mac window. - * FLUSH_LEFT: Flush with left of Mac window. - * SCROLLBAR_GROW: Non-zero means this window draws the grow - * region for the toplevel window. - * AUTO_ADJUST: Non-zero means we automatically adjust - * the size of the widget to align correctly - * along a Mac window. - * DRAW_GROW: Non-zero means we draw the grow region. + * This variable holds the default width for a scrollbar in string form for + * use in a Tk_ConfigSpec. */ -#define ALREADY_DEAD 1 -#define IN_MODAL_LOOP 2 -#define ACTIVE 4 -#define FLUSH_TOP 8 -#define FLUSH_BOTTOM 16 -#define FLUSH_RIGHT 32 -#define FLUSH_LEFT 64 -#define SCROLLBAR_GROW 128 -#define AUTO_ADJUST 256 -#define DRAW_GROW 512 +static char defWidth[TCL_INTEGER_SPACE]; /* - * Globals uses locally in this file. - */ -static ControlActionUPP scrollActionProc = NULL; /* Pointer to func. */ -static ThumbActionUPP thumbActionProc = NULL; /* Pointer to func. */ -static TkScrollbar *activeScrollPtr = NULL; /* Non-null when in thumb */ - /* proc. */ -static Point mouseDownPoint; /* Used when activeScrollPtr is non-NULL */ - /* to store the coordinates where the */ - /* mouse was first pressed to begin */ - /* dragging the thumb, because */ - /* ThumbActionProc can't take any args. */ - -/* * Forward declarations for procedures defined later in this file: */ -static pascal void ScrollbarActionProc _ANSI_ARGS_((ControlRef theControl, ControlPartCode partCode)); -static int ScrollbarBindProc _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, XEvent *eventPtr, - Tk_Window tkwin, KeySym keySym)); -static void ScrollbarEventProc _ANSI_ARGS_(( ClientData clientData, XEvent *eventPtr)); -static pascal void ThumbActionProc _ANSI_ARGS_((void)); -static void UpdateControlValues _ANSI_ARGS_((MacScrollbar *macScrollPtr)); - +static pascal void ScrollbarActionProc(ControlRef theControl, + ControlPartCode partCode); +static pascal void ThumbActionProc(ControlRef theControl, + ControlPartCode partCode); +static int ScrollbarBindProc(ClientData clientData, Tcl_Interp *interp, + XEvent *eventPtr, Tk_Window tkwin, KeySym keySym); +static void ScrollbarEventProc(ClientData clientData, XEvent *eventPtr); +static void UpdateControlValues(MacScrollbar *macScrollPtr); + /* - * The class procedure table for the scrollbar widget. Leave the proc fields + * The class procedure table for the scrollbar widget. Leave the proc fields * initialized to NULL, which should happen automatically because of the scope * at which the variable is declared. */ Tk_ClassProcs tkpScrollbarProcs = { - sizeof(Tk_ClassProcs) /* size */ + sizeof(Tk_ClassProcs) /* size */ }; + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXInitScrollbarMetrics -- + * + * This function initializes the current system metrics for a + * scrollbar. + * + * Results: + * None. + * + * Side effects: + * Updates the geometry cache info for all scrollbars. + * + *---------------------------------------------------------------------- + */ + +void +TkMacOSXInitScrollbarMetrics(void) +{ + const short height = 100, width = 50; + ThemeTrackDrawInfo info = {0, {0, 0, height, width}, 0, 1, 0, 0, + kThemeTrackShowThumb, kThemeTrackActive, 0, {{1, 0}}}; + Rect bounds; + Tk_ConfigSpec *specPtr; + + ChkErr(GetThemeMetric, kThemeMetricScrollBarWidth, &metrics[0].width); + ChkErr(GetThemeMetric, kThemeMetricScrollBarMinThumbHeight, + &metrics[0].minThumbHeight); + info.kind = kThemeScrollBarMedium; + ChkErr(GetThemeTrackDragRect, &info, &bounds); + metrics[0].topArrowHeight = bounds.top; + metrics[0].bottomArrowHeight = height - bounds.bottom; + metrics[0].minHeight = metrics[0].minThumbHeight + + metrics[0].topArrowHeight + metrics[0].bottomArrowHeight; + ChkErr(GetThemeMetric, kThemeMetricSmallScrollBarWidth, &metrics[1].width); + ChkErr(GetThemeMetric, kThemeMetricSmallScrollBarMinThumbHeight, + &metrics[1].minThumbHeight); + info.kind = kThemeScrollBarSmall; + ChkErr(GetThemeTrackDragRect, &info, &bounds); + metrics[1].topArrowHeight = bounds.top; + metrics[1].bottomArrowHeight = height - bounds.bottom; + metrics[1].minHeight = metrics[1].minThumbHeight + + metrics[1].topArrowHeight + metrics[1].bottomArrowHeight; + + sprintf(defWidth, "%ld", metrics[0].width); + for (specPtr = tkpScrollbarConfigSpecs; specPtr->type != TK_CONFIG_END; + specPtr++) { + if (specPtr->offset == Tk_Offset(TkScrollbar, width)) { + specPtr->defValue = defWidth; + } + } +} /* *---------------------------------------------------------------------- * * TkpCreateScrollbar -- * - * Allocate a new TkScrollbar structure. + * Allocate a new TkScrollbar structure. * * Results: - * Returns a newly allocated TkScrollbar structure. + * Returns a newly allocated TkScrollbar structure. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ TkScrollbar * TkpCreateScrollbar( - Tk_Window tkwin) /* New Tk Window. */ + Tk_Window tkwin) /* New Tk Window. */ { + static int initialized = 0; MacScrollbar * macScrollPtr; TkWindow *winPtr = (TkWindow *)tkwin; - + if (scrollActionProc == NULL) { - scrollActionProc = NewControlActionUPP (ScrollbarActionProc); - thumbActionProc = NewThumbActionProc(ThumbActionProc); + scrollActionProc = NewControlActionUPP(ScrollbarActionProc); + thumbActionProc = NewControlActionUPP(ThumbActionProc); + } + if (!initialized) { + TkMacOSXInitScrollbarMetrics(); + initialized = 1; } - macScrollPtr = (MacScrollbar *) ckalloc(sizeof(MacScrollbar)); macScrollPtr->sbHandle = NULL; macScrollPtr->macFlags = 0; + SetRect(&macScrollPtr->eraseRect, 0, 0, 0, 0); Tk_CreateEventHandler(tkwin, ActivateMask|ExposureMask| - StructureNotifyMask|FocusChangeMask, - ScrollbarEventProc, (ClientData) macScrollPtr); + StructureNotifyMask|FocusChangeMask, + ScrollbarEventProc, (ClientData) macScrollPtr); if (!Tcl_GetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL)) { - Tcl_SetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL, (ClientData)1); - TkCreateBindingProcedure(winPtr->mainPtr->interp, - winPtr->mainPtr->bindingTable, - (ClientData)Tk_GetUid("Scrollbar"), "<ButtonPress>", - ScrollbarBindProc, NULL, NULL); + Tcl_SetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL, + (ClientData)1); + TkCreateBindingProcedure(winPtr->mainPtr->interp, + winPtr->mainPtr->bindingTable, + (ClientData)Tk_GetUid("Scrollbar"), "<ButtonPress>", + ScrollbarBindProc, NULL, NULL); } return (TkScrollbar *) macScrollPtr; } @@ -176,142 +210,111 @@ TkpCreateScrollbar( * * TkpDisplayScrollbar -- * - * This procedure redraws the contents of a scrollbar window. - * It is invoked as a do-when-idle handler, so it only runs - * when there's nothing else for the application to do. + * This procedure redraws the contents of a scrollbar window. + * It is invoked as a do-when-idle handler, so it only runs + * when there's nothing else for the application to do. * * Results: - * None. + * None. * * Side effects: - * Information appears on the screen. + * Information appears on the screen. * *-------------------------------------------------------------- */ void TkpDisplayScrollbar( - ClientData clientData) /* Information about window. */ + ClientData clientData) /* Information about window. */ { TkScrollbar *scrollPtr = (TkScrollbar *) clientData; MacScrollbar *macScrollPtr = (MacScrollbar *) clientData; Tk_Window tkwin = scrollPtr->tkwin; - MacDrawable *macDraw; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + CGrafPtr destPort, savePort; + Boolean portChanged; WindowRef windowRef; - + if ((scrollPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { - goto done; + goto done; } /* * Draw the focus or any 3D relief we may have. */ if (scrollPtr->highlightWidth != 0) { - GC fgGC, bgGC; - - bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr, - Tk_WindowId(tkwin)); - - if (scrollPtr->flags & GOT_FOCUS) { - fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr, - Tk_WindowId(tkwin)); - TkpDrawHighlightBorder(tkwin, fgGC, bgGC, scrollPtr->highlightWidth, - Tk_WindowId(tkwin)); - } else { - TkpDrawHighlightBorder(tkwin, bgGC, bgGC, scrollPtr->highlightWidth, - Tk_WindowId(tkwin)); - } + GC fgGC, bgGC; + + bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr, + Tk_WindowId(tkwin)); + + if (scrollPtr->flags & GOT_FOCUS) { + fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr, + Tk_WindowId(tkwin)); + TkpDrawHighlightBorder(tkwin, fgGC, bgGC, scrollPtr->highlightWidth, + Tk_WindowId(tkwin)); + } else { + TkpDrawHighlightBorder(tkwin, bgGC, bgGC, scrollPtr->highlightWidth, + Tk_WindowId(tkwin)); + } } Tk_Draw3DRectangle(tkwin, Tk_WindowId(tkwin), scrollPtr->bgBorder, - scrollPtr->highlightWidth, scrollPtr->highlightWidth, - Tk_Width(tkwin) - 2*scrollPtr->highlightWidth, - Tk_Height(tkwin) - 2*scrollPtr->highlightWidth, - scrollPtr->borderWidth, scrollPtr->relief); + scrollPtr->highlightWidth, scrollPtr->highlightWidth, + Tk_Width(tkwin) - 2*scrollPtr->highlightWidth, + Tk_Height(tkwin) - 2*scrollPtr->highlightWidth, + scrollPtr->borderWidth, scrollPtr->relief); /* * Set up port for drawing Macintosh control. */ macDraw = (MacDrawable *) Tk_WindowId(tkwin); destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); + portChanged = QDSwapPort(destPort, &savePort); TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin)); if (macScrollPtr->sbHandle == NULL) { - Rect r; - SInt32 initialValue; - SInt32 minValue; - SInt32 maxValue; - SInt16 procID; - WindowRef frontNonFloating; - - r.left = r.top = 0; - r.right = r.bottom = 1; - - minValue = MIN_SCROLLBAR_VALUE; - maxValue = SCROLLBAR_SCALING_VALUE; - initialValue = (minValue + maxValue)/2; - procID = kControlScrollBarLiveProc; - - windowRef = GetWindowFromPort(destPort); - CreateScrollBarControl(windowRef, &r, initialValue, - minValue, maxValue, - maxValue - minValue, true, - NULL, &(macScrollPtr->sbHandle)); - SetControlReference(macScrollPtr->sbHandle, (SInt32) scrollPtr); - - /* - * If we are foremost then make us active. - */ - - frontNonFloating = ActiveNonFloatingWindow(); - - if ((windowRef == FrontWindow()) || TkpIsWindowFloating(windowRef)) { - macScrollPtr->macFlags |= ACTIVE; - } + Rect r = {0, 0, 1, 1}; + WindowRef frontNonFloating; + + windowRef = GetWindowFromPort(destPort); + CreateScrollBarControl(windowRef, &r, MIN_SCROLLBAR_VALUE + + SCROLLBAR_SCALING_VALUE/2, MIN_SCROLLBAR_VALUE, + SCROLLBAR_SCALING_VALUE, SCROLLBAR_SCALING_VALUE - + MIN_SCROLLBAR_VALUE, true, NULL, &(macScrollPtr->sbHandle)); + SetControlReference(macScrollPtr->sbHandle, (SInt32) scrollPtr); + + /* + * If we are foremost then make us active. + */ + + frontNonFloating = ActiveNonFloatingWindow(); + + if ((windowRef == FrontWindow()) || TkpIsWindowFloating(windowRef)) { + macScrollPtr->macFlags |= ACTIVE; + } } /* - * Adjust the control size based on its width... + * Update the control values before we draw. */ - if (macScrollPtr->info.width < 13) { - SetControlData(macScrollPtr->sbHandle, kControlNoPart, kControlSizeTag, - sizeof(kControlSizeSmall), (void *) kControlSizeSmall); - } else { - SetControlData(macScrollPtr->sbHandle, kControlNoPart, kControlSizeTag, - sizeof(kControlSizeSmall), (void *) kControlSizeLarge); - } - + UpdateControlValues(macScrollPtr); + /* - * Update the control values before we draw. + * Scrollbars do not erase the complete control bounds if they are wider + * than the standard width, so manually erase the extra space. */ - windowRef = GetControlOwner (macScrollPtr->sbHandle); - UpdateControlValues(macScrollPtr); - - if (macScrollPtr->macFlags & ACTIVE) { - Draw1Control(macScrollPtr->sbHandle); - if (macScrollPtr->macFlags & DRAW_GROW) { - DrawGrowIcon(windowRef); - } - } else { - HiliteControl (macScrollPtr->sbHandle, 255 ); - Draw1Control(macScrollPtr->sbHandle); - if (macScrollPtr->macFlags & DRAW_GROW) { - DrawGrowIcon(windowRef); - Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), scrollPtr->bgBorder, - Tk_Width(tkwin) - 13, Tk_Height(tkwin) - 13, - Tk_Width(tkwin), Tk_Height(tkwin), - 0, TK_RELIEF_FLAT); - } + + if (!EmptyRect(&macScrollPtr->eraseRect)) { + EraseRect(&macScrollPtr->eraseRect); + } + + Draw1Control(macScrollPtr->sbHandle); + + if (portChanged) { + QDSwapPort(savePort, NULL); } - - SetGWorld(saveWorld, saveDevice); - + done: scrollPtr->flags &= ~REDRAW_PENDING; } @@ -321,24 +324,24 @@ TkpDisplayScrollbar( * * TkpConfigureScrollbar -- * - * This procedure is called after the generic code has finished - * processing configuration options, in order to configure - * platform specific options. + * This procedure is called after the generic code has finished + * processing configuration options, in order to configure + * platform specific options. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ void TkpConfigureScrollbar(scrollPtr) - register TkScrollbar *scrollPtr; /* Information about widget; may or - * may not already have values for - * some fields. */ + register TkScrollbar *scrollPtr; /* Information about widget; may or + * may not already have values for + * some fields. */ { } @@ -347,39 +350,40 @@ TkpConfigureScrollbar(scrollPtr) * * TkpComputeScrollbarGeometry -- * - * After changes in a scrollbar's size or configuration, this - * procedure recomputes various geometry information used in - * displaying the scrollbar. + * After changes in a scrollbar's size or configuration, this + * procedure recomputes various geometry information used in + * displaying the scrollbar. * * Results: - * None. + * None. * * Side effects: - * The scrollbar will be displayed differently. + * The scrollbar will be displayed differently. * *---------------------------------------------------------------------- */ void TkpComputeScrollbarGeometry( - register TkScrollbar *scrollPtr) /* Scrollbar whose geometry may - * have changed. */ + register TkScrollbar *scrollPtr) /* Scrollbar whose geometry may + * have changed. */ { - MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr; - int width, fieldLength, adjust = 0; + int variant, fieldLength; if (scrollPtr->highlightWidth < 0) { - scrollPtr->highlightWidth = 0; + scrollPtr->highlightWidth = 0; } scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth; - width = (scrollPtr->vertical) ? Tk_Width(scrollPtr->tkwin) - : Tk_Height(scrollPtr->tkwin); - scrollPtr->arrowLength = width - 2*scrollPtr->inset + 1; + variant = ((scrollPtr->vertical ? Tk_Width(scrollPtr->tkwin) : + Tk_Height(scrollPtr->tkwin)) - 2 * scrollPtr->inset + < metrics[0].width) ? 1 : 0; + scrollPtr->arrowLength = (metrics[variant].topArrowHeight + + metrics[variant].bottomArrowHeight) / 2; fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin) - : Tk_Width(scrollPtr->tkwin)) - - 2*(scrollPtr->arrowLength + scrollPtr->inset); + : Tk_Width(scrollPtr->tkwin)) + - 2 * (scrollPtr->arrowLength + scrollPtr->inset); if (fieldLength < 0) { - fieldLength = 0; + fieldLength = 0; } scrollPtr->sliderFirst = fieldLength * scrollPtr->firstFraction; scrollPtr->sliderLast = fieldLength * scrollPtr->lastFraction; @@ -391,45 +395,41 @@ TkpComputeScrollbarGeometry( */ if (scrollPtr->sliderFirst > (fieldLength - 2*scrollPtr->borderWidth)) { - scrollPtr->sliderFirst = fieldLength - 2*scrollPtr->borderWidth; + scrollPtr->sliderFirst = fieldLength - 2*scrollPtr->borderWidth; } if (scrollPtr->sliderFirst < 0) { - scrollPtr->sliderFirst = 0; + scrollPtr->sliderFirst = 0; } - if (scrollPtr->sliderLast < (scrollPtr->sliderFirst - + MIN_SLIDER_LENGTH)) { - scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH; + if (scrollPtr->sliderLast < (scrollPtr->sliderFirst + + metrics[variant].minThumbHeight)) { + scrollPtr->sliderLast = scrollPtr->sliderFirst + + metrics[variant].minThumbHeight; } if (scrollPtr->sliderLast > fieldLength) { - scrollPtr->sliderLast = fieldLength; + scrollPtr->sliderLast = fieldLength; } - scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset; - scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset; + scrollPtr->sliderFirst += scrollPtr->inset + + metrics[variant].topArrowHeight; + scrollPtr->sliderLast += scrollPtr->inset + + metrics[variant].bottomArrowHeight; /* * Register the desired geometry for the window (leave enough space * for the two arrows plus a minimum-size slider, plus border around - * the whole window, if any). Then arrange for the window to be + * the whole window, if any). Then arrange for the window to be * redisplayed. */ if (scrollPtr->vertical) { - if ((macScrollPtr->macFlags & AUTO_ADJUST) && - (macScrollPtr->macFlags & (FLUSH_RIGHT|FLUSH_LEFT))) { - adjust--; - } - Tk_GeometryRequest(scrollPtr->tkwin, - scrollPtr->width + 2*scrollPtr->inset + adjust, - 2*(scrollPtr->arrowLength + scrollPtr->borderWidth - + scrollPtr->inset)); + Tk_GeometryRequest(scrollPtr->tkwin, scrollPtr->width + + 2 * scrollPtr->inset, 2 * (scrollPtr->arrowLength + + scrollPtr->borderWidth + scrollPtr->inset) + + metrics[variant].minThumbHeight); } else { - if ((macScrollPtr->macFlags & AUTO_ADJUST) && - (macScrollPtr->macFlags & (FLUSH_TOP|FLUSH_BOTTOM))) { - adjust--; - } - Tk_GeometryRequest(scrollPtr->tkwin, - 2*(scrollPtr->arrowLength + scrollPtr->borderWidth - + scrollPtr->inset), scrollPtr->width + 2*scrollPtr->inset + adjust); + Tk_GeometryRequest(scrollPtr->tkwin, 2 * (scrollPtr->arrowLength + + scrollPtr->borderWidth + scrollPtr->inset) + + metrics[variant].minThumbHeight, scrollPtr->width + + 2 * scrollPtr->inset); } Tk_SetInternalBorder(scrollPtr->tkwin, scrollPtr->inset); } @@ -439,28 +439,28 @@ TkpComputeScrollbarGeometry( * * TkpDestroyScrollbar -- * - * Free data structures associated with the scrollbar control. + * Free data structures associated with the scrollbar control. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ void TkpDestroyScrollbar( - TkScrollbar *scrollPtr) /* Scrollbar to destroy. */ + TkScrollbar *scrollPtr) /* Scrollbar to destroy. */ { MacScrollbar *macScrollPtr = (MacScrollbar *)scrollPtr; if (macScrollPtr->sbHandle != NULL) { - if (!(macScrollPtr->macFlags & IN_MODAL_LOOP)) { - DisposeControl(macScrollPtr->sbHandle); - macScrollPtr->sbHandle = NULL; - } + if (!(macScrollPtr->macFlags & IN_MODAL_LOOP)) { + DisposeControl(macScrollPtr->sbHandle); + macScrollPtr->sbHandle = NULL; + } } macScrollPtr->macFlags |= ALREADY_DEAD; } @@ -470,90 +470,79 @@ TkpDestroyScrollbar( * * TkpScrollbarPosition -- * - * Determine the scrollbar element corresponding to a - * given position. + * Determine the scrollbar element corresponding to a + * given position. * * Results: - * One of TOP_ARROW, TOP_GAP, etc., indicating which element - * of the scrollbar covers the position given by (x, y). If - * (x,y) is outside the scrollbar entirely, then OUTSIDE is - * returned. + * One of TOP_ARROW, TOP_GAP, etc., indicating which element + * of the scrollbar covers the position given by (x, y). If + * (x,y) is outside the scrollbar entirely, then OUTSIDE is + * returned. * * Side effects: - * None. + * None. * *-------------------------------------------------------------- */ int TkpScrollbarPosition( - TkScrollbar *scrollPtr, /* Scrollbar widget record. */ - int x, int y) /* Coordinates within scrollPtr's - * window. */ + TkScrollbar *scrollPtr, /* Scrollbar widget record. */ + int x, int y) /* Coordinates within scrollPtr's + * window. */ { MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr; - GWorldPtr destPort; - int length, width, tmp, inactive = false; + CGrafPtr destPort, savePort; + Boolean portChanged; + int inactive = 0; ControlPartCode part; - Point where; + Point where = {y, x}; Rect bounds; - int x0, y0; - - x0 = x; - y0 = y; - - if (scrollPtr->vertical) { - length = Tk_Height(scrollPtr->tkwin); - width = Tk_Width(scrollPtr->tkwin); - } else { - tmp = x; - x = y; - y = tmp; - length = Tk_Width(scrollPtr->tkwin); - width = Tk_Height(scrollPtr->tkwin); - } - if ((x < scrollPtr->inset) || (x >= (width - scrollPtr->inset)) - || (y < scrollPtr->inset) || (y >= (length - scrollPtr->inset))) { - return OUTSIDE; + if ((x < scrollPtr->inset) || (x >= (Tk_Width(scrollPtr->tkwin) - + scrollPtr->inset)) || (y < scrollPtr->inset) || + (y >= (Tk_Height(scrollPtr->tkwin) - scrollPtr->inset))) { + return OUTSIDE; } /* * All of the calculations in this procedure mirror those in - * DisplayScrollbar. Be sure to keep the two consistent. On the + * DisplayScrollbar. Be sure to keep the two consistent. On the * Macintosh we use the OS call TestControl to do this mapping. * For TestControl to work, the scrollbar must be active and must * be in the current port. */ destPort = TkMacOSXGetDrawablePort(Tk_WindowId(scrollPtr->tkwin)); - SetGWorld(destPort, NULL); + portChanged = QDSwapPort(destPort, &savePort); UpdateControlValues(macScrollPtr); - if ( GetControlHilite(macScrollPtr->sbHandle) == 255 ) { - inactive = true; - HiliteControl(macScrollPtr->sbHandle, 0 ); + if (!IsControlActive(macScrollPtr->sbHandle)) { + inactive = true; + ActivateControl(macScrollPtr->sbHandle); } - - TkMacOSXWinBounds((TkWindow *) scrollPtr->tkwin, &bounds); - where.h = x0 + bounds.left; - where.v = y0 + bounds.top; + TkMacOSXWinBounds((TkWindow *) scrollPtr->tkwin, &bounds); + where.h += bounds.left; + where.v += bounds.top; part = TestControl(((MacScrollbar *) scrollPtr)->sbHandle, where); if (inactive) { - HiliteControl(macScrollPtr->sbHandle, 255 ); + DeactivateControl(macScrollPtr->sbHandle); + } + if (portChanged) { + QDSwapPort(savePort, NULL); } switch (part) { - case kControlUpButtonPart: - return TOP_ARROW; - case kControlPageUpPart: - return TOP_GAP; - case kControlIndicatorPart: - return SLIDER; - case kControlPageDownPart: - return BOTTOM_GAP; - case kControlDownButtonPart: - return BOTTOM_ARROW; - default: - return OUTSIDE; + case kAppearancePartUpButton: + return TOP_ARROW; + case kAppearancePartPageUpArea: + return TOP_GAP; + case kAppearancePartIndicator: + return SLIDER; + case kAppearancePartPageDownArea: + return BOTTOM_GAP; + case kAppearancePartDownButton: + return BOTTOM_ARROW; + default: + return OUTSIDE; } } @@ -562,144 +551,132 @@ TkpScrollbarPosition( * * ThumbActionProc -- * - * Callback procedure used by the Macintosh toolbox call - * TrackControl. This call is used to track the thumb of - * the scrollbar. Unlike the ScrollbarActionProc function - * this function is called once and basically takes over - * tracking the scrollbar from the control. This is done - * to avoid conflicts with what the control plans to draw. + * Callback procedure used by the Macintosh toolbox call + * HandleControlClick. This call is used to track the + * thumb of the scrollbar. Unlike the + * ScrollbarActionProc function this function is called + * once and basically takes over tracking the scrollbar + * from the control. This is done to avoid conflicts with + * what the control plans to draw. * * Results: - * None. + * None. * * Side effects: - * May change the display. + * May change the display. * *-------------------------------------------------------------- */ static pascal void -ThumbActionProc() +ThumbActionProc(ControlRef theControl, ControlPartCode partCode) { - register TkScrollbar *scrollPtr = activeScrollPtr; - register MacScrollbar *macScrollPtr = (MacScrollbar *) activeScrollPtr; + TkScrollbar *scrollPtr = (TkScrollbar *)(intptr_t)GetControlReference( + theControl); + MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr; Tcl_DString cmdString; - int origValue; - double thumbWidth, oldFirstFraction, newFirstFraction, trackBarSize; + int origValue, variant; + short trackBarSize; + double oldFirstFraction, newFirstFraction; char valueString[40]; Point currentPoint = { 0, 0 }; Rect trackRect; Tcl_Interp *interp; MouseTrackingResult trackingResult; - OSErr err; - + OSStatus err; + if (scrollPtr == NULL) { - return; + return; } Tcl_DStringInit(&cmdString); - - /* - * First compute values that will remain constant during the tracking - * of the thumb. The variable trackBarSize is the length of the scrollbar - * minus the 2 arrows and half the width of the thumb on both sides - * (3 * arrowLength). The variable trackBarPin is the lower starting point - * of the drag region. - * - * Note: the arrowLength is equal to the thumb width of a Mac scrollbar. - */ - origValue = GetControl32BitValue(macScrollPtr->sbHandle); GetControlBounds(macScrollPtr->sbHandle, &trackRect); - - thumbWidth = scrollPtr->lastFraction - scrollPtr->firstFraction; - - if (scrollPtr->vertical == true) { - trackBarSize = (double) (trackRect.bottom - trackRect.top - - (scrollPtr->arrowLength * 3)); - InsetRect(&trackRect, -50, -226); - + + if (scrollPtr->vertical) { + variant = (trackRect.right - trackRect.left) < metrics[0].width ? 1 : 0; + trackBarSize = trackRect.bottom - trackRect.top - + metrics[variant].topArrowHeight - + metrics[variant].bottomArrowHeight; + InsetRect(&trackRect, -25, -113); } else { - trackBarSize = (double) (trackRect.right - trackRect.left - - (scrollPtr->arrowLength * 3)); - InsetRect(&trackRect, -226, -50); + variant = (trackRect.bottom - trackRect.top) < metrics[0].width ? 1 : 0; + trackBarSize = trackRect.right - trackRect.left - + metrics[variant].topArrowHeight - + metrics[variant].bottomArrowHeight; + InsetRect(&trackRect, -113, -25); } /* - * Track the mouse while the button is held down. If the mouse is moved, + * Track the mouse while the button is held down. If the mouse is moved, * we calculate the value that should be passed to the "command" part of - * the scrollbar. Since the mouse may move a distance too small to + * the scrollbar. Since the mouse may move a distance too small to * cause a change to the first fraction, each calculation must be done * versus what the first fraction was when the mouse button was - * initially pressed. Otherwise, moving the mouse too slowly will + * initially pressed. Otherwise, moving the mouse too slowly will * cause the calculated fraction delta to be zero and the scrollbar * won't respond. */ oldFirstFraction = scrollPtr->firstFraction; + TkMacOSXTrackingLoop(1); do { - err = TrackMouseLocationWithOptions(NULL, - kTrackMouseLocationOptionDontConsumeMouseUp, - kEventDurationForever, - ¤tPoint, - NULL, - &trackingResult); - - if ((err == noErr) - && ((trackingResult == kMouseTrackingMouseDragged) - || (trackingResult == kMouseTrackingMouseMoved))) { + err = ChkErr(TrackMouseLocationWithOptions, NULL, + kTrackMouseLocationOptionDontConsumeMouseUp, + kEventDurationForever, ¤tPoint, NULL, &trackingResult); + if ((err == noErr) && ((trackingResult == kMouseTrackingMouseDragged) + || (trackingResult == kMouseTrackingMouseMoved))) { /* - * Calculate where the scrollbar should move to, based on - * where the mouse button was pressed and where the scrollbar - * initially was at that time. Note that PtInRect() will + * Calculate where the scrollbar should move to, based on + * where the mouse button was pressed and where the scrollbar + * initially was at that time. Note that PtInRect() will * return false if currentPoint or trackRect are not in * is not in current graphics port, which may happen if any - * of the waiting idle events change the port (e.g. with + * of the waiting idle events change the port (e.g. with * SetPort()) but fail to restore it before returning and the * scrollbar will lock in place. - */ + */ newFirstFraction = oldFirstFraction; - if (PtInRect(currentPoint, &trackRect)) { - double pixDiff; - double fracDelta; - if (scrollPtr->vertical == true) { - pixDiff = (double)(currentPoint.v - mouseDownPoint.v); - } else { - pixDiff = (double)(currentPoint.h - mouseDownPoint.h); - } - fracDelta = pixDiff/(trackBarSize); - newFirstFraction += fracDelta; + if (PtInRect(currentPoint, &trackRect)) { + short pixDiff; + + if (scrollPtr->vertical) { + pixDiff = currentPoint.v - mouseDownPoint.v; + } else { + pixDiff = currentPoint.h - mouseDownPoint.h; + } + newFirstFraction += (double)pixDiff / trackBarSize; if (newFirstFraction > 1.0) { newFirstFraction = 1.0; } else if (newFirstFraction < 0.0) { newFirstFraction = 0.0; } } - + /* * Move the scrollbar thumb to the new first fraction given * its position when initially pressed and how far the mouse - * has moved. Process waiting idle tasks afterward to allow + * has moved. Process waiting idle tasks afterward to allow * for the display to update. */ - sprintf(valueString, "%g", newFirstFraction); - Tcl_DStringSetLength(&cmdString, 0); - Tcl_DStringAppend(&cmdString, scrollPtr->command, - scrollPtr->commandSize); - Tcl_DStringAppendElement(&cmdString, "moveto"); - Tcl_DStringAppendElement(&cmdString, valueString); - interp = scrollPtr->interp; - Tcl_Preserve((ClientData) interp); - Tcl_GlobalEval(interp, cmdString.string); - Tcl_Release((ClientData) interp); - - TclServiceIdle(); - } + sprintf(valueString, "%g", newFirstFraction); + Tcl_DStringSetLength(&cmdString, 0); + Tcl_DStringAppend(&cmdString, scrollPtr->command, + scrollPtr->commandSize); + Tcl_DStringAppendElement(&cmdString, "moveto"); + Tcl_DStringAppendElement(&cmdString, valueString); + interp = scrollPtr->interp; + Tcl_Preserve((ClientData) interp); + Tcl_EvalEx(interp, Tcl_DStringValue(&cmdString), + Tcl_DStringLength(&cmdString), TCL_EVAL_GLOBAL); + Tcl_Release((ClientData) interp); + TkMacOSXRunTclEventLoop(); + } } while ((err == noErr) && trackingResult != kMouseTrackingMouseReleased); - + TkMacOSXTrackingLoop(0); Tcl_DStringFree(&cmdString); return; } @@ -709,50 +686,60 @@ ThumbActionProc() * * ScrollbarActionProc -- * - * Callback procedure used by the Macintosh toolbox call - * TrackControl. This call will update the display while - * the scrollbar is being manipulated by the user. + * Callback procedure used by the Macintosh toolbox call + * HandleControlClick. This call will update the display + * while the scrollbar is being manipulated by the user. * * Results: - * None. + * None. * * Side effects: - * May change the display. + * May change the display. * *-------------------------------------------------------------- */ static pascal void ScrollbarActionProc( - ControlRef theControl, /* Handle to scrollbat control */ - ControlPartCode partCode) /* Part of scrollbar that was "hit" */ + ControlRef theControl, /* Handle to scrollbat control */ + ControlPartCode partCode) /* Part of scrollbar that was "hit" */ { - TkScrollbar *scrollPtr = (TkScrollbar *) GetControlReference(theControl); + TkScrollbar *scrollPtr = (TkScrollbar *)(intptr_t)GetControlReference( + theControl); + MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr; Tcl_DString cmdString; - + Tcl_DStringInit(&cmdString); Tcl_DStringAppend(&cmdString, scrollPtr->command, - scrollPtr->commandSize); - - if ( partCode == kControlUpButtonPart || - partCode == kControlDownButtonPart ) { - Tcl_DStringAppendElement(&cmdString, "scroll"); - Tcl_DStringAppendElement(&cmdString, - (partCode == kControlUpButtonPart ) ? "-1" : "1"); - Tcl_DStringAppendElement(&cmdString, "unit"); - } else if (partCode == kControlPageUpPart || partCode == kControlPageDownPart ) { - Tcl_DStringAppendElement(&cmdString, "scroll"); - Tcl_DStringAppendElement(&cmdString, - (partCode == kControlPageUpPart ) ? "-1" : "1"); - Tcl_DStringAppendElement(&cmdString, "page"); + scrollPtr->commandSize); + + if ( partCode == kAppearancePartUpButton || + partCode == kAppearancePartDownButton ) { + Tcl_DStringAppendElement(&cmdString, "scroll"); + Tcl_DStringAppendElement(&cmdString, + (partCode == kAppearancePartUpButton) ? "-1" : "1"); + Tcl_DStringAppendElement(&cmdString, "unit"); + } else if (partCode == kAppearancePartPageUpArea || + partCode == kAppearancePartPageDownArea ) { + Tcl_DStringAppendElement(&cmdString, "scroll"); + Tcl_DStringAppendElement(&cmdString, + (partCode == kAppearancePartPageUpArea) ? "-1" : "1"); + Tcl_DStringAppendElement(&cmdString, "page"); + } else if (partCode == kAppearancePartIndicator) { + char valueString[TCL_DOUBLE_SPACE]; + + sprintf(valueString, "%g", + (GetControl32BitValue(macScrollPtr->sbHandle) - + MIN_SCROLLBAR_VALUE) / SCROLLBAR_SCALING_VALUE); + Tcl_DStringAppendElement(&cmdString, "moveto"); + Tcl_DStringAppendElement(&cmdString, valueString); } Tcl_Preserve((ClientData) scrollPtr->interp); - Tcl_DStringAppend(&cmdString, "; update idletasks", - strlen("; update idletasks")); - Tcl_GlobalEval(scrollPtr->interp, cmdString.string); + Tcl_EvalEx(scrollPtr->interp, Tcl_DStringValue(&cmdString), + Tcl_DStringLength(&cmdString), TCL_EVAL_GLOBAL); Tcl_Release((ClientData) scrollPtr->interp); - Tcl_DStringFree(&cmdString); + TkMacOSXRunTclEventLoop(); } /* @@ -760,25 +747,25 @@ ScrollbarActionProc( * * ScrollbarBindProc -- * - * This procedure is invoked when the default <ButtonPress> - * binding on the Scrollbar bind tag fires. + * This procedure is invoked when the default <ButtonPress> + * binding on the Scrollbar bind tag fires. * * Results: - * None. + * None. * * Side effects: - * The event enters a modal loop. + * The event enters a modal loop. * *-------------------------------------------------------------- */ static int ScrollbarBindProc( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Interp with binding. */ - XEvent *eventPtr, /* X event that triggered binding. */ - Tk_Window tkwin, /* Target window for event. */ - KeySym keySym) /* The KeySym if a key event. */ + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Interp with binding. */ + XEvent *eventPtr, /* X event that triggered binding. */ + Tk_Window tkwin, /* Target window for event. */ + KeySym keySym) /* The KeySym if a key event. */ { TkWindow *winPtr = (TkWindow*)tkwin; TkScrollbar *scrollPtr = (TkScrollbar *) winPtr->instanceData; @@ -786,108 +773,103 @@ ScrollbarBindProc( Tcl_Preserve((ClientData)scrollPtr); macScrollPtr->macFlags |= IN_MODAL_LOOP; - + if (eventPtr->type == ButtonPress) { Point where; Rect bounds; int part; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; - Window window; - - /* - * To call Macintosh control routines we must have the port - * set to the window containing the control. We will then test - * which part of the control was hit and act accordingly. - */ - destPort = TkMacOSXGetDrawablePort(Tk_WindowId(scrollPtr->tkwin)); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(Tk_WindowId(scrollPtr->tkwin)); - - TkMacOSXWinBounds((TkWindow *) scrollPtr->tkwin, &bounds); + CGrafPtr destPort, savePort; + Boolean portChanged; + Window window; + + /* + * To call Macintosh control routines we must have the port + * set to the window containing the control. We will then test + * which part of the control was hit and act accordingly. + */ + destPort = TkMacOSXGetDrawablePort(Tk_WindowId(scrollPtr->tkwin)); + portChanged = QDSwapPort(destPort, &savePort); + TkMacOSXSetUpClippingRgn(Tk_WindowId(scrollPtr->tkwin)); + + TkMacOSXWinBounds((TkWindow *) scrollPtr->tkwin, &bounds); where.h = eventPtr->xbutton.x + bounds.left; where.v = eventPtr->xbutton.y + bounds.top; - part = TestControl(macScrollPtr->sbHandle, where); - if (part == kControlIndicatorPart && scrollPtr->jump == false) { - /* - * Case 1: In thumb, no jump scrolling. Call track control - * with the thumb action proc which will do most of the work. - * Set the global activeScrollPtr to the current control - * so the callback may have access to it. - */ - activeScrollPtr = scrollPtr; + part = TestControl(macScrollPtr->sbHandle, where); + TkMacOSXTrackingLoop(1); + if (part == kAppearancePartIndicator && scrollPtr->jump == false) { + /* + * Case 1: In thumb, no jump scrolling. Call track control + * with the thumb action proc which will do most of the work. + */ mouseDownPoint.h = where.h; mouseDownPoint.v = where.v; - part = TrackControl(macScrollPtr->sbHandle, where, - (ControlActionUPP) thumbActionProc); - activeScrollPtr = NULL; - } else if (part == kControlIndicatorPart) { - /* - * Case 2: in thumb with jump scrolling. Call TrackControl - * with a NULL action proc. Use the new value of the control - * to set update the control. - */ - part = TrackControl(macScrollPtr->sbHandle, where, NULL); - if (part == kControlIndicatorPart) { - double newFirstFraction, thumbWidth; - Tcl_DString cmdString; - char valueString[TCL_DOUBLE_SPACE]; - - /* - * The following calculation takes the new control - * value and maps it to what Tk needs for its variable - * thumb size representation. - */ - thumbWidth = scrollPtr->lastFraction - - scrollPtr->firstFraction; - newFirstFraction = (1.0 - thumbWidth) * - ((double) GetControl32BitValue(macScrollPtr->sbHandle) / SCROLLBAR_SCALING_DVALUE); - - sprintf(valueString, "%g", newFirstFraction); - - Tcl_DStringInit(&cmdString); - Tcl_DStringAppend(&cmdString, scrollPtr->command, - strlen(scrollPtr->command)); - Tcl_DStringAppendElement(&cmdString, "moveto"); - Tcl_DStringAppendElement(&cmdString, valueString); - Tcl_DStringAppend(&cmdString, "; update idletasks", - strlen("; update idletasks")); - - interp = scrollPtr->interp; - Tcl_Preserve((ClientData) interp); - Tcl_GlobalEval(interp, cmdString.string); - Tcl_Release((ClientData) interp); - Tcl_DStringFree(&cmdString); - } - } else if (part != 0) { - /* - * Case 3: in any other part of the scrollbar. We call - * TrackControl with the scrollActionProc which will do - * most all the work. - */ - TrackControl(macScrollPtr->sbHandle, where, scrollActionProc); - HiliteControl(macScrollPtr->sbHandle, 0); - } - - /* - * The TrackControl call will "eat" the ButtonUp event. We now - * generate a ButtonUp event so Tk will unset implicit grabs etc. - */ - window = Tk_WindowId(scrollPtr->tkwin); - TkGenerateButtonEventForXPointer(window); - - SetGWorld(saveWorld, saveDevice); + part = HandleControlClick(macScrollPtr->sbHandle, where, + TkMacOSXModifierState(), thumbActionProc); + } else if (part == kAppearancePartIndicator) { + /* + * Case 2: in thumb with jump scrolling. Call HandleControlClick + * with a NULL action proc. Use the new value of the control + * to set update the control. + */ + part = HandleControlClick(macScrollPtr->sbHandle, where, + TkMacOSXModifierState(), NULL); + if (part == kAppearancePartIndicator) { + Tcl_DString cmdString; + char valueString[TCL_DOUBLE_SPACE]; + + sprintf(valueString, "%g", + (GetControl32BitValue(macScrollPtr->sbHandle) - + MIN_SCROLLBAR_VALUE) / SCROLLBAR_SCALING_VALUE); + Tcl_DStringInit(&cmdString); + Tcl_DStringAppend(&cmdString, scrollPtr->command, + strlen(scrollPtr->command)); + Tcl_DStringAppendElement(&cmdString, "moveto"); + Tcl_DStringAppendElement(&cmdString, valueString); + + interp = scrollPtr->interp; + Tcl_Preserve((ClientData) interp); + Tcl_EvalEx(interp, Tcl_DStringValue(&cmdString), + Tcl_DStringLength(&cmdString), TCL_EVAL_GLOBAL); + Tcl_Release((ClientData) interp); + Tcl_DStringFree(&cmdString); + TkMacOSXRunTclEventLoop(); + } + } else if (part != 0) { + /* + * Case 3: in any other part of the scrollbar. We call + * HandleControlClick with the scrollActionProc which will do + * most all the work. + */ + HandleControlClick(macScrollPtr->sbHandle, where, + TkMacOSXModifierState(), scrollActionProc); + /* + * Workaround for Carbon bug where the scrollbar down arrow + * sometimes gets "stuck" after the mousebutton has been released. + */ + TkMacOSXSetUpClippingRgn(Tk_WindowId(scrollPtr->tkwin)); + Draw1Control(macScrollPtr->sbHandle); + } + TkMacOSXTrackingLoop(0); + + /* + * The HandleControlClick call will "eat" the ButtonUp event. We now + * generate a ButtonUp event so Tk will unset implicit grabs etc. + */ + window = Tk_WindowId(scrollPtr->tkwin); + TkGenerateButtonEventForXPointer(window); + + if (portChanged) { + QDSwapPort(savePort, NULL); + } } if (macScrollPtr->sbHandle && (macScrollPtr->macFlags & ALREADY_DEAD)) { - DisposeControl(macScrollPtr->sbHandle); - macScrollPtr->sbHandle = NULL; + DisposeControl(macScrollPtr->sbHandle); + macScrollPtr->sbHandle = NULL; } macScrollPtr->macFlags &= ~IN_MODAL_LOOP; Tcl_Release((ClientData)scrollPtr); - + return TCL_OK; } @@ -896,37 +878,37 @@ ScrollbarBindProc( * * ScrollbarEventProc -- * - * This procedure is invoked by the Tk dispatcher for various - * events on scrollbars. + * This procedure is invoked by the Tk dispatcher for various + * events on scrollbars. * * Results: - * None. + * None. * * Side effects: - * When the window gets deleted, internal structures get - * cleaned up. When it gets exposed, it is redisplayed. + * When the window gets deleted, internal structures get + * cleaned up. When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */ static void ScrollbarEventProc( - ClientData clientData, /* Information about window. */ - XEvent *eventPtr) /* Information about event. */ + ClientData clientData, /* Information about window. */ + XEvent *eventPtr) /* Information about event. */ { TkScrollbar *scrollPtr = (TkScrollbar *) clientData; MacScrollbar *macScrollPtr = (MacScrollbar *) clientData; if (eventPtr->type == UnmapNotify) { - TkMacOSXSetScrollbarGrow((TkWindow *) scrollPtr->tkwin, false); + TkMacOSXSetScrollbarGrow((TkWindow *) scrollPtr->tkwin, false); } else if (eventPtr->type == ActivateNotify) { - macScrollPtr->macFlags |= ACTIVE; - TkScrollbarEventuallyRedraw((ClientData) scrollPtr); + macScrollPtr->macFlags |= ACTIVE; + TkScrollbarEventuallyRedraw((ClientData) scrollPtr); } else if (eventPtr->type == DeactivateNotify) { - macScrollPtr->macFlags &= ~ACTIVE; - TkScrollbarEventuallyRedraw((ClientData) scrollPtr); + macScrollPtr->macFlags &= ~ACTIVE; + TkScrollbarEventuallyRedraw((ClientData) scrollPtr); } else { - TkScrollbarEventProc(clientData, eventPtr); + TkScrollbarEventProc(clientData, eventPtr); } } @@ -935,151 +917,91 @@ ScrollbarEventProc( * * UpdateControlValues -- * - * This procedure updates the Macintosh scrollbar control - * to display the values defined by the Tk scrollbar. + * This procedure updates the Macintosh scrollbar control + * to display the values defined by the Tk scrollbar. * * Results: - * None. + * None. * * Side effects: - * The Macintosh control is updated. + * The Macintosh control is updated. * *-------------------------------------------------------------- */ static void UpdateControlValues( - MacScrollbar *macScrollPtr) /* Scrollbar data struct. */ + MacScrollbar *macScrollPtr) /* Scrollbar data struct. */ { TkScrollbar *scrollPtr = (TkScrollbar *) macScrollPtr; Tk_Window tkwin = scrollPtr->tkwin; MacDrawable * macDraw = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin); - WindowRef windowRef = GetControlOwner(macScrollPtr->sbHandle); double dViewSize; - SInt32 viewSize, controlMax, controlValue; - int flushRight = false; - int flushBottom = false; Rect contrlRect, portRect; - UInt8 contrlHilite; - - /* - * We can't use the Macintosh commands SizeControl and MoveControl as these - * calls will also cause a redraw which in our case will also cause - * flicker. To avoid this we adjust the control record directly. The - * Draw1Control command appears to just draw where ever the control says to - * draw so this seems right. - */ + int variant, active; + short width, height; contrlRect.left = macDraw->xOff + scrollPtr->inset; contrlRect.top = macDraw->yOff + scrollPtr->inset; contrlRect.right = macDraw->xOff + Tk_Width(tkwin) - scrollPtr->inset; contrlRect.bottom = macDraw->yOff + Tk_Height(tkwin) - scrollPtr->inset; + GetPortBounds (GetWindowPort(GetControlOwner(macScrollPtr->sbHandle)), + &portRect); + /* - * To make Tk applications look more like Macintosh applications without - * requiring additional work by the Tk developer we do some cute tricks. - * The first trick plays with the size of the widget to get it to overlap - * with the side of the window by one pixel (we don't do this if the placer - * is the geometry manager). The second trick shrinks the scrollbar if it - * it covers the area of the grow region ao the scrollbar can also draw - * the grow region if need be. + * If the scrollbar is flush against the bottom right hand corner then + * we leave space to draw the grow region for the window. */ - if ((macDraw->winPtr->geomMgrPtr != NULL) - && !strcmp(macDraw->winPtr->geomMgrPtr->name, "place")) { - macScrollPtr->macFlags &= ~AUTO_ADJUST; + if (portRect.bottom == contrlRect.bottom && + portRect.right == contrlRect.right) { + TkMacOSXSetScrollbarGrow((TkWindow *) tkwin, true); + if (TkMacOSXResizable(macDraw->toplevel->winPtr)) { + int growSize; + + switch (TkMacOSXWindowClass(macDraw->toplevel->winPtr)) { + case kFloatingWindowClass: + case kUtilityWindowClass: + growSize = metrics[1].width - 1; + break; + case kDocumentWindowClass: + case kMovableAlertWindowClass: + case kMovableModalWindowClass: + default: + growSize = metrics[0].width - 1; + break; + } + if (scrollPtr->vertical) { + contrlRect.bottom -= growSize; + } else { + contrlRect.right -= growSize; + } + } } else { - macScrollPtr->macFlags |= AUTO_ADJUST; - } - GetPortBounds ( GetWindowPort ( windowRef ), &portRect ); - if ( portRect.left == contrlRect.left ) { - if (macScrollPtr->macFlags & AUTO_ADJUST) { - contrlRect.left--; - } - if (!(macScrollPtr->macFlags & FLUSH_LEFT)) { - macScrollPtr->macFlags |= FLUSH_LEFT; - if (scrollPtr->vertical) { - TkpComputeScrollbarGeometry(scrollPtr); - } - } - } else if (macScrollPtr->macFlags & FLUSH_LEFT) { - macScrollPtr->macFlags &= ~FLUSH_LEFT; - if (scrollPtr->vertical) { - TkpComputeScrollbarGeometry(scrollPtr); - } + TkMacOSXSetScrollbarGrow((TkWindow *) tkwin, false); } - if (portRect.top == contrlRect.top) { - if (macScrollPtr->macFlags & AUTO_ADJUST) { - contrlRect.top--; - } - if (!(macScrollPtr->macFlags & FLUSH_TOP)) { - macScrollPtr->macFlags |= FLUSH_TOP; - if (! scrollPtr->vertical) { - TkpComputeScrollbarGeometry(scrollPtr); - } - } - } else if (macScrollPtr->macFlags & FLUSH_TOP) { - macScrollPtr->macFlags &= ~FLUSH_TOP; - if (! scrollPtr->vertical) { - TkpComputeScrollbarGeometry(scrollPtr); - } + if (IsControlVisible (macScrollPtr->sbHandle)) { + SetControlVisibility(macScrollPtr->sbHandle, false, false); } - if (portRect.right == contrlRect.right) { - flushRight = true; - if (macScrollPtr->macFlags & AUTO_ADJUST) { - contrlRect.right++; - } - if (!(macScrollPtr->macFlags & FLUSH_RIGHT)) { - macScrollPtr->macFlags |= FLUSH_RIGHT; - if (scrollPtr->vertical) { - TkpComputeScrollbarGeometry(scrollPtr); - } - } - } else if (macScrollPtr->macFlags & FLUSH_RIGHT) { - macScrollPtr->macFlags &= ~FLUSH_RIGHT; - if (scrollPtr->vertical) { - TkpComputeScrollbarGeometry(scrollPtr); - } - } - - if (portRect.bottom == contrlRect.bottom) { - flushBottom = true; - if (macScrollPtr->macFlags & AUTO_ADJUST) { - contrlRect.bottom++; - } - if (!(macScrollPtr->macFlags & FLUSH_BOTTOM)) { - macScrollPtr->macFlags |= FLUSH_BOTTOM; - if (! scrollPtr->vertical) { - TkpComputeScrollbarGeometry(scrollPtr); - } - } - } else if (macScrollPtr->macFlags & FLUSH_BOTTOM) { - macScrollPtr->macFlags &= ~FLUSH_BOTTOM; - if (! scrollPtr->vertical) { - TkpComputeScrollbarGeometry(scrollPtr); - } + if (scrollPtr->vertical) { + width = contrlRect.right - contrlRect.left; + height = contrlRect.bottom - contrlRect.top; + } else { + width = contrlRect.bottom - contrlRect.top; + height = contrlRect.right - contrlRect.left; } + variant = width < metrics[0].width ? 1 : 0; + SetControlData(macScrollPtr->sbHandle, kControlEntireControl, + kControlSizeTag, sizeof(ControlSize), + &(metrics[variant].size)); - /* - * If the scrollbar is flush against the bottom right hand corner then - * it may need to draw the grow region for the window so we let the - * wm code know about this scrollbar. We don't actually draw the grow - * region, however, unless we are currently resizable. - */ - macScrollPtr->macFlags &= ~DRAW_GROW; - if (flushBottom && flushRight) { - TkMacOSXSetScrollbarGrow((TkWindow *) tkwin, true); - if (TkMacOSXResizable(macDraw->toplevel->winPtr)) { - if (scrollPtr->vertical) { - contrlRect.bottom -= 14; - } else { - contrlRect.right -= 14; - } - macScrollPtr->macFlags |= DRAW_GROW; - } + macScrollPtr->eraseRect = contrlRect; + if (scrollPtr->vertical) { + macScrollPtr->eraseRect.left += metrics[variant].width; } else { - TkMacOSXSetScrollbarGrow((TkWindow *) tkwin, false); + macScrollPtr->eraseRect.top += metrics[variant].width; } /* @@ -1092,50 +1014,37 @@ UpdateControlValues( /* * Given the Tk parameters for the fractions of the start and * end of the thumb, the following calculation determines the - * location for the Macintosh thumb. + * location for the Macintosh thumb. * The Aqua scroll control works as follows. - * The scrollbar's value is the position of the left (or top) side of - * the view area in the content area being scrolled. - * The maximum value of the control is therefore the dimension of + * The scrollbar's value is the position of the left (or top) side of + * the view area in the content area being scrolled. + * The maximum value of the control is therefore the dimension of * the content area less the size of the view area. * Since these values are all integers, and Tk gives the thumb position * as fractions, we have introduced a scaling factor. */ - dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction) - * SCROLLBAR_SCALING_DVALUE; - - viewSize = (SInt32) dViewSize; - controlMax = (SInt32) (SCROLLBAR_SCALING_DVALUE - dViewSize); - controlValue = (SInt32) (SCROLLBAR_SCALING_DVALUE * scrollPtr->firstFraction); - - SetControlViewSize(macScrollPtr->sbHandle,viewSize); - SetControl32BitMaximum(macScrollPtr->sbHandle, controlMax); - -#if 0 - middle = scrollPtr->firstFraction / - (1.0 - (scrollPtr->lastFraction - scrollPtr->firstFraction)); - - viewSize = (SInt32) ((scrollPtr->lastFraction - scrollPtr->firstFraction) - * SCROLLBAR_SCALING_DVALUE - / (1.0 - (scrollPtr->lastFraction - scrollPtr->firstFraction))); - - SetControlViewSize(macScrollPtr->sbHandle,viewSize); - SetControl32BitValue(macScrollPtr->sbHandle, - (middle) ); -#endif - contrlHilite = GetControlHilite(macScrollPtr->sbHandle); - SetControl32BitMinimum(macScrollPtr->sbHandle, 0); - if ( contrlHilite == 0 || contrlHilite == 255) { - if (scrollPtr->firstFraction == 0.0 && - scrollPtr->lastFraction == 1.0) { - SetControl32BitMinimum(macScrollPtr->sbHandle, SCROLLBAR_SCALING_VALUE); - } else { - HiliteControl(macScrollPtr->sbHandle, 0); - } - } - SetControl32BitValue(macScrollPtr->sbHandle, controlValue); - if ( !IsControlVisible (macScrollPtr -> sbHandle) ) { - SetControlVisibility(macScrollPtr->sbHandle,TRUE,FALSE); + dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction) + * SCROLLBAR_SCALING_VALUE; + SetControlViewSize(macScrollPtr->sbHandle, dViewSize); + SetControl32BitMinimum(macScrollPtr->sbHandle, MIN_SCROLLBAR_VALUE); + SetControl32BitMaximum(macScrollPtr->sbHandle, MIN_SCROLLBAR_VALUE + + SCROLLBAR_SCALING_VALUE - dViewSize); + SetControl32BitValue(macScrollPtr->sbHandle, MIN_SCROLLBAR_VALUE + + SCROLLBAR_SCALING_VALUE * scrollPtr->firstFraction); + + if((scrollPtr->firstFraction <= 0.0 && scrollPtr->lastFraction >= 1.0) + || height <= metrics[variant].minHeight) { + /* Disable scrollbar */ + SetControl32BitMaximum(macScrollPtr->sbHandle, MIN_SCROLLBAR_VALUE); + } + active = ((macScrollPtr->macFlags & ACTIVE) != 0); + if (active != IsControlActive(macScrollPtr->sbHandle)) { + if (active) { + ActivateControl(macScrollPtr->sbHandle); + } else { + DeactivateControl(macScrollPtr->sbHandle); + } } + SetControlVisibility(macScrollPtr->sbHandle, true, false); } diff --git a/macosx/tkMacOSXSend.c b/macosx/tkMacOSXSend.c index c9ef484..179beb6 100644 --- a/macosx/tkMacOSXSend.c +++ b/macosx/tkMacOSXSend.c @@ -1,49 +1,47 @@ -/* +/* * tkMacOSXSend.c -- * * This file provides procedures that implement the "send" * command, allowing commands to be passed from interpreter - * to interpreter. This current implementation for the Mac + * to interpreter. This current implementation for the Mac * has most functionality stubed out. * * The current plan, which we have not had time to implement, is * for the first Wish app to create a gestalt of type 'WIsH'. * This gestalt will point to a table, in system memory, of - * Tk apps. Each Tk app, when it starts up, will register their - * name, and process ID, in this table. This will allow us to + * Tk apps. Each Tk app, when it starts up, will register their + * name, and process ID, in this table. This will allow us to * implement "tk appname". * * Then the send command will look up the process id of the target - * app in this table, and send an AppleEvent to that process. The + * app in this table, and send an AppleEvent to that process. The * AppleEvent handler is much like the do script handler, except that - * you have to specify the name of the tk app as well, since there may + * you have to specify the name of the tk app as well, since there may * be many interps in one wish app, and you need to send it to the * right one. * * Implementing this has been on our list of things to do, but what - * with the demise of Tcl at Sun, and the lack of resources at - * Scriptics it may not get done for awhile. So this sketch is + * with the demise of Tcl at Sun, and the lack of resources at + * Scriptics it may not get done for awhile. So this sketch is * offered for the brave to attempt if they need the functionality... * * Copyright (c) 1989-1994 The Regents of the University of California. * Copyright (c) 1994-1998 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXSend.c,v 1.5 2006/03/24 14:58:01 das Exp $ + * RCS: @(#) $Id: tkMacOSXSend.c,v 1.6 2007/04/23 21:24:34 das Exp $ */ #include "tkMacOSXInt.h" -MODULE_SCOPE int Tk_SendObjCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); - - /* - * The following structure is used to keep track of the - * interpreters registered by this process. - */ +/* + * The following structure is used to keep track of the + * interpreters registered by this process. + */ typedef struct RegisteredInterp { char *name; /* Interpreter's name (malloc-ed). */ @@ -60,7 +58,7 @@ typedef struct RegisteredInterp { * property "InterpRegistry" on the root window of the display. * It is organized as a series of zero or more concatenated strings * (in no particular order), each of the form - * window space name '\0' + * window space name '\0' * where "window" is the hex id of the comm. window to use to talk * to an interpreter named "name". * @@ -79,14 +77,14 @@ typedef struct NameRegistry { * out when the NameRegistry is closed. */ unsigned long propLength; /* Length of the property, in bytes. */ char *property; /* The contents of the property, or NULL - * if none. See format description above; + * if none. See format description above; * this is *not* terminated by the first - * null character. Dynamically allocated. */ + * null character. Dynamically allocated. */ int allocedByX; /* Non-zero means must free property with - * XFree; zero means use ckfree. */ + * XFree; zero means use ckfree. */ } NameRegistry; -static int initialized = false; /* A flag to denote if we have initialized yet. */ +static int initialized = false; /* A flag to denote if we have initialized yet. */ static RegisteredInterp *interpListPtr = NULL; /* List of all interpreters @@ -94,78 +92,78 @@ static RegisteredInterp *interpListPtr = NULL; /* * The information below is used for communication between processes - * during "send" commands. Each process keeps a private window, never - * even mapped, with one property, "Comm". When a command is sent to + * during "send" commands. Each process keeps a private window, never + * even mapped, with one property, "Comm". When a command is sent to * an interpreter, the command is appended to the comm property of the - * communication window associated with the interp's process. Similarly, + * communication window associated with the interp's process. Similarly, * when a result is returned from a sent command, it is also appended * to the comm property. * - * Each command and each result takes the form of ASCII text. For a + * Each command and each result takes the form of ASCII text. For a * command, the text consists of a zero character followed by several - * null-terminated ASCII strings. The first string consists of the - * single letter "c". Subsequent strings have the form "option value" + * null-terminated ASCII strings. The first string consists of the + * single letter "c". Subsequent strings have the form "option value" * where the following options are supported: * * -r commWindow serial * - * This option means that a response should be sent to the window - * whose X identifier is "commWindow" (in hex), and the response should - * be identified with the serial number given by "serial" (in decimal). - * If this option isn't specified then the send is asynchronous and - * no response is sent. + * This option means that a response should be sent to the window + * whose X identifier is "commWindow" (in hex), and the response should + * be identified with the serial number given by "serial" (in decimal). + * If this option isn't specified then the send is asynchronous and + * no response is sent. * * -n name - * "Name" gives the name of the application for which the command is - * intended. This option must be present. + * "Name" gives the name of the application for which the command is + * intended. This option must be present. * * -s script * - * "Script" is the script to be executed. This option must be present. + * "Script" is the script to be executed. This option must be present. * - * The options may appear in any order. The -n and -s options must be - * present, but -r may be omitted for asynchronous RPCs. For compatibility + * The options may appear in any order. The -n and -s options must be + * present, but -r may be omitted for asynchronous RPCs. For compatibility * with future releases that may add new features, there may be additional - * options present; as long as they start with a "-" character, they will + * options present; as long as they start with a "-" character, they will * be ignored. * * A result also consists of a zero character followed by several null- - * terminated ASCII strings. The first string consists of the single - * letter "r". Subsequent strings have the form "option value" where + * terminated ASCII strings. The first string consists of the single + * letter "r". Subsequent strings have the form "option value" where * the following options are supported: * * -s serial * - * Identifies the command for which this is the result. It is the - * same as the "serial" field from the -s option in the command. This - * option must be present. + * Identifies the command for which this is the result. It is the + * same as the "serial" field from the -s option in the command. This + * option must be present. * * -c code * - * "Code" is the completion code for the script, in decimal. If the - * code is omitted it defaults to TCL_OK. + * "Code" is the completion code for the script, in decimal. If the + * code is omitted it defaults to TCL_OK. * * -r result * - * "Result" is the result string for the script, which may be either - * a result or an error message. If this field is omitted then it - * defaults to an empty string. + * "Result" is the result string for the script, which may be either + * a result or an error message. If this field is omitted then it + * defaults to an empty string. * * -i errorInfo * - * "ErrorInfo" gives a string with which to initialize the errorInfo - * variable. This option may be omitted; it is ignored unless the - * completion code is TCL_ERROR. + * "ErrorInfo" gives a string with which to initialize the errorInfo + * variable. This option may be omitted; it is ignored unless the + * completion code is TCL_ERROR. * * -e errorCode * - * "ErrorCode" gives a string with with to initialize the errorCode - * variable. This option may be omitted; it is ignored unless the - * completion code is TCL_ERROR. + * "ErrorCode" gives a string with with to initialize the errorCode + * variable. This option may be omitted; it is ignored unless the + * completion code is TCL_ERROR. * * Options may appear in any order, and only the -s option must be - * present. As with commands, there may be additional options besides - * these; unknown options are ignored. + * present. As with commands, there may be additional options besides + * these; unknown options are ignored. */ /* @@ -179,29 +177,8 @@ static RegisteredInterp *interpListPtr = NULL; * Forward declarations for procedures defined later in this file: */ -static int SendInit _ANSI_ARGS_((Tcl_Interp *interp)); -/* -static int AppendErrorProc _ANSI_ARGS_((ClientData clientData, - XErrorEvent *errorPtr)); -static void DeleteProc _ANSI_ARGS_((ClientData clientData)); -static void RegAddName _ANSI_ARGS_((NameRegistry *regPtr, - char *name, Window commWindow)); -static void RegClose _ANSI_ARGS_((NameRegistry *regPtr)); -static void RegDeleteName _ANSI_ARGS_((NameRegistry *regPtr, - char *name)); -static Window RegFindName _ANSI_ARGS_((NameRegistry *regPtr, - char *name)); -static NameRegistry * RegOpen _ANSI_ARGS_((Tcl_Interp *interp, - TkWindow *winPtr, int lock)); -static void SendEventProc _ANSI_ARGS_((ClientData clientData, - XEvent *eventPtr)); -static Bool SendRestrictProc _ANSI_ARGS_((Display *display, - XEvent *eventPtr, char *arg)); -static int ServerSecure _ANSI_ARGS_((TkDisplay *dispPtr)); -static void TimeoutProc _ANSI_ARGS_((ClientData clientData)); -static int ValidateName _ANSI_ARGS_((TkDisplay *dispPtr, - char *name, Window commWindow, int oldOK)); -*/ +static int SendInit(Tcl_Interp *interp); + /* *-------------------------------------------------------------- @@ -209,20 +186,20 @@ static int ValidateName _ANSI_ARGS_((TkDisplay *dispPtr, * Tk_SetAppName -- * * This procedure is called to associate an ASCII name with a Tk - * application. If the application has already been named, the + * application. If the application has already been named, the * name replaces the old one. * * Results: * The return value is the name actually given to the application. * This will normally be the same as name, but if name was already * in use for an application then a name of the form "name #2" will - * be chosen, with a high enough number to make the name unique. + * be chosen, with a high enough number to make the name unique. * * Side effects: * Registration info is saved, thereby allowing the "send" command - * to be used later to invoke commands in the application. In + * to be used later to invoke commands in the application. In * addition, the "send" command is created in the application's - * interpreter. The registration will be removed automatically + * interpreter. The registration will be removed automatically * if the interpreter is deleted or the "send" command is removed. * *-------------------------------------------------------------- @@ -231,18 +208,18 @@ static int ValidateName _ANSI_ARGS_((TkDisplay *dispPtr, CONST char * Tk_SetAppName( Tk_Window tkwin, /* Token for any window in the application - * to be named: it is just used to identify - * the application and the display. */ + * to be named: it is just used to identify + * the application and the display. */ CONST char *name) /* The name that will be used to * refer to the interpreter in later - * "send" commands. Must be globally + * "send" commands. Must be globally * unique. */ { TkWindow *winPtr = (TkWindow *) tkwin; Tcl_Interp *interp = winPtr->mainPtr->interp; int i, suffix, offset, result; RegisteredInterp *riPtr, *prevPtr; - CONST char *actualName; + const char *actualName; Tcl_DString dString; Tcl_Obj *resultObjPtr, *interpNamePtr; char *interpName; @@ -257,7 +234,7 @@ Tk_SetAppName( * will take care of disposing of this entry. */ - for (riPtr = interpListPtr, prevPtr = NULL; riPtr != NULL; + for (riPtr = interpListPtr, prevPtr = NULL; riPtr != NULL; prevPtr = riPtr, riPtr = riPtr->nextPtr) { if (riPtr->interp == interp) { if (prevPtr == NULL) { @@ -270,8 +247,8 @@ Tk_SetAppName( } /* - * Pick a name to use for the application. Use "name" if it's not - * already in use. Otherwise add a suffix such as " #2", trying + * Pick a name to use for the application. Use "name" if it's not + * already in use. Otherwise add a suffix such as " #2", trying * larger and larger numbers until we eventually find one that is * unique. */ @@ -289,7 +266,7 @@ Tk_SetAppName( if (interpNamePtr == NULL) { break; } - interpName = Tcl_GetStringFromObj(interpNamePtr, NULL); + interpName = Tcl_GetString(interpNamePtr); if (strcmp(actualName, interpName) == 0) { if (suffix == 1) { Tcl_DStringAppend(&dString, name, -1); @@ -320,7 +297,7 @@ Tk_SetAppName( interpListPtr = riPtr; strcpy(riPtr->name, actualName); - Tcl_CreateObjCommand(interp, "send", Tk_SendObjCmd, + Tcl_CreateObjCommand(interp, "send", Tk_SendObjCmd, (ClientData) riPtr, NULL /* TODO: DeleteProc */); if (Tcl_IsSafe(interp)) { Tcl_HideCommand(interp, "send", "send"); @@ -354,7 +331,7 @@ Tk_SendObjCmd( int objc, /* Number of arguments */ Tcl_Obj *CONST objv[]) /* The arguments */ { - CONST char *sendOptions[] = {"-async", "-displayof", "-", (char *) NULL}; + const char *sendOptions[] = {"-async", "-displayof", "-", NULL}; char *stringRep, *destName; int async = 0; int i, index, firstArg; @@ -363,7 +340,7 @@ Tk_SendObjCmd( int result = TCL_OK; for (i = 1; i < (objc - 1); ) { - stringRep = Tcl_GetStringFromObj(objv[i], NULL); + stringRep = Tcl_GetString(objv[i]); if (stringRep[0] == '-') { if (Tcl_GetIndexFromObj(interp, objv[i], sendOptions, "option", 0, &index) != TCL_OK) { @@ -381,32 +358,32 @@ Tk_SendObjCmd( break; } } - + if (objc < (i + 2)) { Tcl_WrongNumArgs(interp, 1, objv, "?options? interpName arg ?arg ...?"); return TCL_ERROR; } - destName = Tcl_GetStringFromObj(objv[i], NULL); + destName = Tcl_GetString(objv[i]); firstArg = i + 1; resultPtr = Tcl_GetObjResult(interp); /* - * See if the target interpreter is local. If so, execute + * See if the target interpreter is local. If so, execute * the command directly without going through the DDE server. * The only tricky thing is passing the result from the target - * interpreter to the invoking interpreter. Watch out: they + * interpreter to the invoking interpreter. Watch out: they * could be the same! */ - for (riPtr = interpListPtr; (riPtr != NULL) + for (riPtr = interpListPtr; (riPtr != NULL) && (strcmp(destName, riPtr->name)); riPtr = riPtr->nextPtr) { /* * Empty loop body. */ - + } if (riPtr != NULL) { @@ -442,16 +419,16 @@ Tk_SendObjCmd( /* * An error occurred, so transfer error information from the - * destination interpreter back to our interpreter. Must clear + * destination interpreter back to our interpreter. Must clear * interp's result before calling Tcl_AddErrorInfo, since * Tcl_AddErrorInfo will store the interp's result in errorInfo - * before appending riPtr's $errorInfo; we've already got + * before appending riPtr's $errorInfo; we've already got * everything we need in riPtr's $errorInfo. */ Tcl_ResetResult(interp); Tcl_AddErrorInfo(interp, Tcl_GetVar2(localInterp, - "errorInfo", (char *) NULL, TCL_GLOBAL_ONLY)); + "errorInfo", NULL, TCL_GLOBAL_ONLY)); /* errorObjPtr = Tcl_GetObjVar2(localInterp, "errorCode", NULL, TCL_GLOBAL_ONLY); Tcl_SetObjErrorCode(interp, errorObjPtr); */ @@ -480,9 +457,9 @@ Tk_SendObjCmd( * of a particular window. * * Results: - * A standard Tcl return value. Interp->result will be set + * A standard Tcl return value. Interp->result will be set * to hold a list of all the interpreter names defined for - * tkwin's display. If an error occurs, then TCL_ERROR + * tkwin's display. If an error occurs, then TCL_ERROR * is returned and interp->result will hold an error message. * * Side effects: @@ -503,11 +480,11 @@ TkGetInterpNames( listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); riPtr = interpListPtr; while (riPtr != NULL) { - Tcl_ListObjAppendElement(interp, listObjPtr, + Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(riPtr->name, -1)); riPtr = riPtr->nextPtr; } - + Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c index a471e6f..377e528 100644 --- a/macosx/tkMacOSXSubwindows.c +++ b/macosx/tkMacOSXSubwindows.c @@ -1,16 +1,16 @@ -/* +/* * tkMacOSXSubwindows.c -- * * Implements subwindows for the macintosh version of Tk. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. - * Copyright (c) 2006 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.16 2006/10/31 22:33:34 das Exp $ + * RCS: @(#) $Id: tkMacOSXSubwindows.c,v 1.17 2007/04/23 21:24:34 das Exp $ */ #include "tkMacOSXInt.h" @@ -18,23 +18,19 @@ #include "tkMacOSXWm.h" /* -#ifdef TK_MAC_DEBUG +#ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_CLIP_REGIONS #endif */ /* - * Temporary region that can be reused. - */ -static RgnHandle tmpRgn = NULL; - -/* * Prototypes for functions used only in this file. */ static void GenerateConfigureNotify (TkWindow *winPtr, int includeWin); static void UpdateOffsets (TkWindow *winPtr, int deltaX, int deltaY); + /* *---------------------------------------------------------------------- * @@ -51,13 +47,13 @@ static void UpdateOffsets (TkWindow *winPtr, int deltaX, int deltaY); *---------------------------------------------------------------------- */ -void +void XDestroyWindow( Display* display, /* Display. */ Window window) /* Window. */ { MacDrawable *macWin = (MacDrawable *) window; - CGrafPtr destPort; + CGrafPtr destPort; /* * Remove any dangling pointers that may exist if * the window we are deleting is being tracked by @@ -68,68 +64,69 @@ XDestroyWindow( macWin->toplevel->referenceCount--; if (Tk_IsTopLevel(macWin->winPtr)) { - WindowRef winRef; - /* - * We are relying on the Activate Mac OS event to pass the - * focus away from a window that is getting Destroyed to the - * Front non-floating window. BUT we don't get activate events - * when a floating window is destroyed - since the front non-floating - * window doesn't in fact get activated... So maybe we can check here - * and if we are destroying a floating window, we can pass the focus - * back to the front non-floating window... - */ - - if (macWin->grafPtr != NULL) { - TkWindow *focusPtr = TkGetFocusWin(macWin->winPtr); - if (focusPtr == NULL || (focusPtr->mainPtr->winPtr == macWin->winPtr)) { - winRef = GetWindowFromPort(macWin->grafPtr); - if (TkpIsWindowFloating (winRef)) { - Window window; - - window = TkMacOSXGetXWindow(ActiveNonFloatingWindow()); - if (window != None) { - TkMacOSXGenerateFocusEvent(window, 1); - } - } - } - } + WindowRef winRef; + /* + * We are relying on the Activate Mac OS event to pass the + * focus away from a window that is getting Destroyed to the + * Front non-floating window. BUT we don't get activate events + * when a floating window is destroyed - since the front non-floating + * window doesn't in fact get activated... So maybe we can check here + * and if we are destroying a floating window, we can pass the focus + * back to the front non-floating window... + */ + + if (macWin->grafPtr != NULL) { + TkWindow *focusPtr = TkGetFocusWin(macWin->winPtr); + if (focusPtr == NULL || (focusPtr->mainPtr->winPtr == macWin->winPtr)) { + winRef = GetWindowFromPort(macWin->grafPtr); + if (TkpIsWindowFloating (winRef)) { + Window window; + + window = TkMacOSXGetXWindow(ActiveNonFloatingWindow()); + if (window != None) { + TkMacOSXGenerateFocusEvent(window, 1); + } + } + } + } DisposeRgn(macWin->clipRgn); DisposeRgn(macWin->aboveClipRgn); - + DisposeRgn(macWin->drawRgn); + /* * Delete the Mac window and remove it from the windowTable. * The window could be NULL if the window was never mapped. * However, we don't do this for embedded windows, they don't * go in the window list, and they do not own their portPtr's. */ - + if (!(Tk_IsEmbedded(macWin->winPtr))) { - destPort = TkMacOSXGetDrawablePort(window); + destPort = TkMacOSXGetDrawablePort(window); if (destPort != NULL) { - TkMacOSXWindowList *listPtr, *prevPtr; - WindowRef winRef; - winRef = GetWindowFromPort(destPort); - TkMacOSXUnregisterMacWindow(winRef); - DisposeWindow(winRef); - - for (listPtr = tkMacOSXWindowListPtr, prevPtr = NULL; - tkMacOSXWindowListPtr != NULL; - prevPtr = listPtr, listPtr = listPtr->nextPtr) { - if (listPtr->winPtr == macWin->winPtr) { - if (prevPtr == NULL) { - tkMacOSXWindowListPtr = listPtr->nextPtr; - } else { - prevPtr->nextPtr = listPtr->nextPtr; - } - ckfree((char *) listPtr); - break; - } - } + TkMacOSXWindowList *listPtr, *prevPtr; + WindowRef winRef; + winRef = GetWindowFromPort(destPort); + TkMacOSXUnregisterMacWindow(winRef); + DisposeWindow(winRef); + + for (listPtr = tkMacOSXWindowListPtr, prevPtr = NULL; + tkMacOSXWindowListPtr != NULL; + prevPtr = listPtr, listPtr = listPtr->nextPtr) { + if (listPtr->winPtr == macWin->winPtr) { + if (prevPtr == NULL) { + tkMacOSXWindowListPtr = listPtr->nextPtr; + } else { + prevPtr->nextPtr = listPtr->nextPtr; + } + ckfree((char *) listPtr); + break; + } + } } } - + macWin->grafPtr = NULL; - + /* * Delay deletion of a toplevel data structure untill all * children have been deleted. @@ -138,18 +135,14 @@ XDestroyWindow( ckfree((char *) macWin->toplevel); } } else { - CGrafPtr destPort; - destPort = TkMacOSXGetDrawablePort(window); - if (destPort != NULL) { - SetGWorld(destPort, NULL); - TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); - } + TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); if (macWin->winPtr->parentPtr != NULL) { TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr); } DisposeRgn(macWin->clipRgn); DisposeRgn(macWin->aboveClipRgn); - + DisposeRgn(macWin->drawRgn); + if (macWin->toplevel->referenceCount == 0) { ckfree((char *) macWin->toplevel); } @@ -162,7 +155,7 @@ XDestroyWindow( * * XMapWindow -- * - * Map the given X Window to the screen. See X window documentation + * Map the given X Window to the screen. See X window documentation * for more details. * * Results: @@ -174,7 +167,7 @@ XDestroyWindow( *---------------------------------------------------------------------- */ -void +void XMapWindow( Display* display, /* Display. */ Window window) /* Window. */ @@ -186,7 +179,7 @@ XMapWindow( /* * Under certain situations it's possible for this function to be * called before the toplevel window it's associated with has actually - * been mapped. In that case we need to create the real Macintosh + * been mapped. In that case we need to create the real Macintosh * window now as this function as well as other X functions assume that * the portPtr is valid. */ @@ -204,7 +197,7 @@ XMapWindow( * XXX windows that have a wmPtr->master parent set. */ WindowRef wRef = GetWindowFromPort(destPort); - if ((TkMacOSXWindowClass(macWin->winPtr) == kSheetWindowClass) + if ((macWin->winPtr->wmInfoPtr->macClass == kSheetWindowClass) && (macWin->winPtr->wmInfoPtr->master != None)) { ShowSheetWindow(wRef, GetWindowFromPort(TkMacOSXGetDrawablePort(macWin->winPtr->wmInfoPtr->master))); @@ -212,25 +205,25 @@ XMapWindow( ShowWindow(wRef); } } + TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr); - /* + /* * We only need to send the MapNotify event * for toplevel windows. */ event.xany.serial = display->request; event.xany.send_event = False; event.xany.display = display; - + event.xmap.window = window; event.xmap.type = MapNotify; event.xmap.event = window; event.xmap.override_redirect = macWin->winPtr->atts.override_redirect; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); } else { - /* - * Generate damage for that area of the window + /* + * Generate damage for that area of the window */ - SetGWorld(destPort, NULL); TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr); TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); } @@ -241,7 +234,7 @@ XMapWindow( * * XUnmapWindow -- * - * Unmap the given X Window to the screen. See X window + * Unmap the given X Window to the screen. See X window * documentation for more details. * * Results: @@ -253,7 +246,7 @@ XMapWindow( *---------------------------------------------------------------------- */ -void +void XUnmapWindow( Display* display, /* Display. */ Window window) /* Window. */ @@ -273,15 +266,16 @@ XUnmapWindow( * XXX windows that have a wmPtr->master parent set. */ WindowRef wref = GetWindowFromPort(destPort); - if ((TkMacOSXWindowClass(macWin->winPtr) == kSheetWindowClass) + if ((macWin->winPtr->wmInfoPtr->macClass == kSheetWindowClass) && (macWin->winPtr->wmInfoPtr->master != None)) { HideSheetWindow(wref); } else { HideWindow(wref); } } + TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr); - /* + /* * We only need to send the UnmapNotify event * for toplevel windows. */ @@ -295,10 +289,9 @@ XUnmapWindow( event.xunmap.from_configure = false; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); } else { - /* + /* * Generate damage for that area of the window. */ - SetGWorld(destPort, NULL); TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr); } @@ -309,7 +302,7 @@ XUnmapWindow( * * XResizeWindow -- * - * Resize a given X window. See X windows documentation for + * Resize a given X window. See X windows documentation for * further details. * * Results: @@ -321,104 +314,99 @@ XUnmapWindow( *---------------------------------------------------------------------- */ -void +void XResizeWindow( Display* display, /* Display. */ - Window window, /* Window. */ + Window window, /* Window. */ unsigned int width, unsigned int height) { MacDrawable *macWin = (MacDrawable *) window; - CGrafPtr destPort; - int havePort = 1; + CGrafPtr destPort; destPort = TkMacOSXGetDrawablePort(window); - if (destPort == NULL) { - havePort = 0; - } - display->request++; if (Tk_IsTopLevel(macWin->winPtr)) { if (!Tk_IsEmbedded(macWin->winPtr)) { - /* + /* * NOTE: we are not adding the new space to the update - * region. It is currently assumed that Tk will need + * region. It is currently assumed that Tk will need * to completely redraw anway. */ - if (havePort) { - SetPort(destPort); - SizeWindow(GetWindowFromPort(destPort), - (short) width, (short) height, false); - TkMacOSXInvalidateWindow(macWin, TK_WINDOW_ONLY); - TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr); - } + if (destPort) { + WindowRef w = GetWindowFromPort(destPort); + Rect bounds; + + ChkErr(GetWindowBounds, w, kWindowContentRgn, &bounds); + bounds.right = bounds.left + width; + bounds.bottom = bounds.top + height; + ChkErr(SetWindowBounds, w, kWindowContentRgn, &bounds); + TkMacOSXInvalidateWindow(macWin, TK_WINDOW_ONLY); + } } else { int deltaX, deltaY; - + /* * Find the Parent window - - * For an embedded window this will be its container. + * For an embedded window this will be its container. */ TkWindow *contWinPtr; - + contWinPtr = TkpGetOtherWindow(macWin->winPtr); - + if (contWinPtr != NULL) { - MacDrawable *macParent = contWinPtr->privatePtr; + MacDrawable *macParent = contWinPtr->privatePtr; - if (havePort) { - SetPort(destPort); + if (destPort) { TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); - TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr); + TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr); } deltaX = macParent->xOff + macWin->winPtr->changes.x - macWin->xOff; deltaY = macParent->yOff + macWin->winPtr->changes.y - macWin->yOff; - + UpdateOffsets(macWin->winPtr, deltaX, deltaY); } else { - /* - * This is the case where we are embedded in - * another app. At this point, we are assuming that - * the changes.x,y is not maintained, if you need + /* + * This is the case where we are embedded in + * another app. At this point, we are assuming that + * the changes.x,y is not maintained, if you need * the info get it from Tk_GetRootCoords, - * and that the toplevel sits at 0,0 when it is drawn. - */ - + * and that the toplevel sits at 0,0 when it is drawn. + */ + TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); UpdateOffsets(macWin->winPtr, 0, 0); } - - } + + } } else { /* TODO: update all xOff & yOffs */ int deltaX, deltaY, parentBorderwidth; MacDrawable *macParent = macWin->winPtr->parentPtr->privatePtr; - + if (macParent == NULL) { return; /* TODO: Probably should be a panic */ } - - if (havePort) { - SetPort(destPort); + + if (destPort) { TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); - TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr); - } + TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr); + } deltaX = - macWin->xOff; deltaY = - macWin->yOff; parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width; - + deltaX += macParent->xOff + parentBorderwidth + macWin->winPtr->changes.x; deltaY += macParent->yOff + parentBorderwidth + macWin->winPtr->changes.y; - + UpdateOffsets(macWin->winPtr, deltaX, deltaY); } } - /* *---------------------------------------------------------------------- @@ -426,9 +414,9 @@ XResizeWindow( * GenerateConfigureNotify -- * * Generates ConfigureNotify events for all the child widgets - * of the widget passed in the winPtr parameter. If includeWin - * is true, also generates ConfigureNotify event for the - * widget itself. + * of the widget passed in the winPtr parameter. If includeWin + * is true, also generates ConfigureNotify event for the + * widget itself. * * Results: * None. @@ -445,24 +433,23 @@ GenerateConfigureNotify (TkWindow *winPtr, int includeWin) TkWindow *childPtr; for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { - if (!Tk_IsMapped(childPtr) || Tk_IsTopLevel(childPtr)) { - continue; - } - GenerateConfigureNotify(childPtr, 1); + childPtr = childPtr->nextPtr) { + if (!Tk_IsMapped(childPtr) || Tk_IsTopLevel(childPtr)) { + continue; + } + GenerateConfigureNotify(childPtr, 1); } if (includeWin) { - TkDoConfigureNotify(winPtr); + TkDoConfigureNotify(winPtr); } -} - - +} + /* *---------------------------------------------------------------------- * * XMoveResizeWindow -- * - * Move or resize a given X window. See X windows documentation + * Move or resize a given X window. See X windows documentation * for further details. * * Results: @@ -474,83 +461,79 @@ GenerateConfigureNotify (TkWindow *winPtr, int includeWin) *---------------------------------------------------------------------- */ -void +void XMoveResizeWindow( Display* display, /* Display. */ - Window window, /* Window. */ + Window window, /* Window. */ int x, int y, unsigned int width, unsigned int height) -{ +{ MacDrawable * macWin = (MacDrawable *) window; - CGrafPtr destPort; - int havePort = 1; + CGrafPtr destPort; destPort = TkMacOSXGetDrawablePort(window); - if (destPort == NULL) { - havePort = 0; - } - - if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { - /* + if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { + /* * NOTE: we are not adding the new space to the update - * region. It is currently assumed that Tk will need + * region. It is currently assumed that Tk will need * to completely redraw anway. */ - if (havePort) { - SetPort( destPort); - SizeWindow(GetWindowFromPort(destPort), - (short) width, (short) height, false); - MoveWindowStructure(GetWindowFromPort(destPort), x, y); - + if (destPort) { + Rect bounds; + + bounds.left = x + macWin->winPtr->wmInfoPtr->xInParent; + bounds.right = bounds.left + width; + bounds.top = y + macWin->winPtr->wmInfoPtr->yInParent; + bounds.bottom = bounds.top + height; + ChkErr(SetWindowBounds, GetWindowFromPort(destPort), + kWindowContentRgn, &bounds); TkMacOSXInvalidateWindow(macWin, TK_WINDOW_ONLY); - TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr); - } + } } else { int deltaX, deltaY, parentBorderwidth; Rect bounds; MacDrawable *macParent; - - /* - * Find the Parent window - - * For an embedded window this will be its container. - */ - + + /* + * Find the Parent window - + * For an embedded window this will be its container. + */ + if (Tk_IsEmbedded(macWin->winPtr)) { TkWindow *contWinPtr; - + contWinPtr = TkpGetOtherWindow(macWin->winPtr); if (contWinPtr == NULL) { Tcl_Panic("XMoveResizeWindow could not find container"); } macParent = contWinPtr->privatePtr; - + /* * NOTE: Here we should handle out of process embedding. */ - - + + } else { - macParent = macWin->winPtr->parentPtr->privatePtr; + macParent = macWin->winPtr->parentPtr->privatePtr; if (macParent == NULL) { - return; /* TODO: Probably should be a panic */ + return; /* TODO: Probably should be a panic */ } } - if (havePort) { - SetPort( destPort); + if (destPort) { TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr); } deltaX = - macWin->xOff; deltaY = - macWin->yOff; - - /* + + /* * If macWin->winPtr is an embedded window, don't offset by its * parent's borderwidth... */ - + if (!Tk_IsEmbedded(macWin->winPtr)) { parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width; } else { @@ -560,13 +543,13 @@ XMoveResizeWindow( macWin->winPtr->changes.x; deltaY += macParent->yOff + parentBorderwidth + macWin->winPtr->changes.y; - + UpdateOffsets(macWin->winPtr, deltaX, deltaY); - if (havePort) { + if (destPort) { TkMacOSXWinBounds(macWin->winPtr, &bounds); InvalWindowRect(GetWindowFromPort(destPort),&bounds); - } - GenerateConfigureNotify(macWin->winPtr, 0); + } + GenerateConfigureNotify(macWin->winPtr, 0); } } @@ -575,7 +558,7 @@ XMoveResizeWindow( * * XMoveWindow -- * - * Move a given X window. See X windows documentation for further + * Move a given X window. See X windows documentation for further * details. * * Results: @@ -587,7 +570,7 @@ XMoveResizeWindow( *---------------------------------------------------------------------- */ -void +void XMoveWindow( Display* display, /* Display. */ Window window, /* Window. */ @@ -596,70 +579,64 @@ XMoveWindow( { MacDrawable *macWin = (MacDrawable *) window; CGrafPtr destPort; - int havePort = 1; destPort = TkMacOSXGetDrawablePort(window); - if (destPort == NULL) { - havePort = 0; - } if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { - /* + /* * NOTE: we are not adding the new space to the update - * region. It is currently assumed that Tk will need + * region. It is currently assumed that Tk will need * to completely redraw anway. */ - if (havePort) { - SetPort(destPort); - MoveWindowStructure( GetWindowFromPort(destPort), x, y); + if (destPort) { + WindowRef w = GetWindowFromPort(destPort); + MoveWindowStructure(w, x, y); TkMacOSXInvalidateWindow(macWin, TK_WINDOW_ONLY); - TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr); - } + } } else { int deltaX, deltaY, parentBorderwidth; Rect bounds; MacDrawable *macParent; - - /* - * Find the Parent window - - * For an embedded window this will be its container. - */ - + + /* + * Find the Parent window - + * For an embedded window this will be its container. + */ + if (Tk_IsEmbedded(macWin->winPtr)) { TkWindow *contWinPtr; - + contWinPtr = TkpGetOtherWindow(macWin->winPtr); if (contWinPtr == NULL) { Tcl_Panic("XMoveWindow could not find container"); } macParent = contWinPtr->privatePtr; - + /* * NOTE: Here we should handle out of process embedding. */ - + } else { - macParent = macWin->winPtr->parentPtr->privatePtr; + macParent = macWin->winPtr->parentPtr->privatePtr; if (macParent == NULL) { - return; /* TODO: Probably should be a panic */ + return; /* TODO: Probably should be a panic */ } } - if (havePort) { - SetPort(destPort); + if (destPort) { TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr); - } - + } + deltaX = - macWin->xOff; deltaY = - macWin->yOff; - - /* + + /* * If macWin->winPtr is an embedded window, don't offset by its * parent's borderwidth... */ - + if (!Tk_IsEmbedded(macWin->winPtr)) { parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width; } else { @@ -669,12 +646,12 @@ XMoveWindow( macWin->winPtr->changes.x; deltaY += macParent->yOff + parentBorderwidth + macWin->winPtr->changes.y; - + UpdateOffsets(macWin->winPtr, deltaX, deltaY); - if (havePort) { - TkMacOSXWinBounds(macWin->winPtr, &bounds); + if (destPort) { + TkMacOSXWinBounds(macWin->winPtr, &bounds); InvalWindowRect(GetWindowFromPort(destPort),&bounds); - } + } GenerateConfigureNotify(macWin->winPtr, 0); } } @@ -695,18 +672,18 @@ XMoveWindow( *---------------------------------------------------------------------- */ -void +void XRaiseWindow( Display* display, /* Display. */ Window window) /* Window. */ { MacDrawable *macWin = (MacDrawable *) window; - + display->request++; if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { TkWmRestackToplevel(macWin->winPtr, Above, NULL); } else { - /* TODO: this should generate damage */ + /* TODO: this should generate damage */ } } @@ -727,18 +704,18 @@ XRaiseWindow( *---------------------------------------------------------------------- */ -void +void XLowerWindow( Display* display, /* Display. */ Window window) /* Window. */ { MacDrawable *macWin = (MacDrawable *) window; - + display->request++; if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { TkWmRestackToplevel(macWin->winPtr, Below, NULL); } else { - /* TODO: this should generate damage */ + /* TODO: this should generate damage */ } } #endif @@ -755,7 +732,7 @@ XLowerWindow( * None. * * Side effects: - * Changes the attributes of the specified window. Note that we + * Changes the attributes of the specified window. Note that we * ignore the passed in values and use the values stored in the * TkWindow data structure. * @@ -784,8 +761,8 @@ XConfigureWindow( } /* - * Change the stacking order of the window. Tk actuall keeps all - * the information we need for stacking order. All we need to do + * Change the stacking order of the window. Tk actuall keeps all + * the information we need for stacking order. All we need to do * is make sure the clipping regions get updated and generate damage * that will ensure things get drawn correctly. */ @@ -793,28 +770,27 @@ XConfigureWindow( if (value_mask & CWStackMode) { Rect bounds; CGrafPtr destPort; - + destPort = TkMacOSXGetDrawablePort(w); if (destPort != NULL) { - SetPort( destPort); TkMacOSXInvalClipRgns((Tk_Window) winPtr->parentPtr); TkMacOSXWinBounds(winPtr, &bounds); InvalWindowRect(GetWindowFromPort(destPort),&bounds); } - } + } - /* TkGenWMMoveRequestEvent(macWin->winPtr, + /* TkGenWMMoveRequestEvent(macWin->winPtr, macWin->winPtr->changes.x, macWin->winPtr->changes.y); */ } /* *---------------------------------------------------------------------- * - * TkMacOSXUpdateClipRgn -- + * TkMacOSXUpdateClipRgn -- * * This function updates the cliping regions for a given window - * and all of its children. Once updated the TK_CLIP_INVALID flag - * in the subwindow data structure is unset. The TK_CLIP_INVALID + * and all of its children. Once updated the TK_CLIP_INVALID flag + * in the subwindow data structure is unset. The TK_CLIP_INVALID * flag should always be unset before any drawing is attempted. * * Results: @@ -841,21 +817,18 @@ TkMacOSXUpdateClipRgn( if (winPtr->privatePtr && winPtr->privatePtr->flags & TK_CLIP_INVALID) { if (Tk_IsMapped(winPtr)) { rgn = winPtr->privatePtr->aboveClipRgn; - if (tmpRgn == NULL) { - tmpRgn = NewRgn(); - } - /* + /* * Start with a region defined by the window bounds. */ x = winPtr->privatePtr->xOff; y = winPtr->privatePtr->yOff; SetRectRgn(rgn, (short) x, (short) y, - (short) (winPtr->changes.width + x), + (short) (winPtr->changes.width + x), (short) (winPtr->changes.height + y)); - /* + /* * Clip away the area of any windows that may obscure this * window. * For a non-toplevel window, first, clip to the parents visible @@ -863,14 +836,15 @@ TkMacOSXUpdateClipRgn( * Second, clip away any siblings that are higher in the * stacking order. * For an embedded toplevel, just clip to the container's visible - * clip region. Remember, we only allow one contained window + * clip region. Remember, we only allow one contained window * in a frame, and don't support any other widgets in the frame * either. This is not currently enforced, however. */ - if (!Tk_IsTopLevel(winPtr)) { + if (!Tk_IsTopLevel(winPtr)) { TkMacOSXUpdateClipRgn(winPtr->parentPtr); - SectRgn(rgn, + TkMacOSXCheckTmpRgnEmpty(1); + SectRgn(rgn, winPtr->parentPtr->privatePtr->aboveClipRgn, rgn); win2Ptr = winPtr->nextPtr; @@ -881,10 +855,10 @@ TkMacOSXUpdateClipRgn( } x = win2Ptr->privatePtr->xOff; y = win2Ptr->privatePtr->yOff; - SetRectRgn(tmpRgn, (short) x, (short) y, - (short) (win2Ptr->changes.width + x), + SetRectRgn(tkMacOSXtmpRgn1, (short) x, (short) y, + (short) (win2Ptr->changes.width + x), (short) (win2Ptr->changes.height + y)); - DiffRgn(rgn, tmpRgn, rgn); + DiffRgn(rgn, tkMacOSXtmpRgn1, rgn); win2Ptr = win2Ptr->nextPtr; } @@ -893,11 +867,14 @@ TkMacOSXUpdateClipRgn( if (contWinPtr != NULL) { TkMacOSXUpdateClipRgn(contWinPtr); - SectRgn(rgn, + TkMacOSXCheckTmpRgnEmpty(1); + SectRgn(rgn, contWinPtr->privatePtr->aboveClipRgn, rgn); } else if (tkMacOSXEmbedHandler != NULL) { - tkMacOSXEmbedHandler->getClipProc((Tk_Window) winPtr, tmpRgn); - SectRgn(rgn, tmpRgn, rgn); + TkMacOSXCheckTmpRgnEmpty(1); + tkMacOSXEmbedHandler->getClipProc((Tk_Window) winPtr, + tkMacOSXtmpRgn1); + SectRgn(rgn, tkMacOSXtmpRgn1, rgn); } /* @@ -906,10 +883,10 @@ TkMacOSXUpdateClipRgn( } - /* + /* * The final clip region is the aboveClip region (or visible * region) minus all the children of this window. - * Alternatively, if the window is a container, we must also + * Alternatively, if the window is a container, we must also * subtract the region of the embedded window. */ @@ -924,10 +901,10 @@ TkMacOSXUpdateClipRgn( } x = win2Ptr->privatePtr->xOff; y = win2Ptr->privatePtr->yOff; - SetRectRgn(tmpRgn, (short) x, (short) y, - (short) (win2Ptr->changes.width + x), + SetRectRgn(tkMacOSXtmpRgn1, (short) x, (short) y, + (short) (win2Ptr->changes.width + x), (short) (win2Ptr->changes.height + y)); - DiffRgn(rgn, tmpRgn, rgn); + DiffRgn(rgn, tkMacOSXtmpRgn1, rgn); win2Ptr = win2Ptr->nextPtr; } @@ -938,18 +915,19 @@ TkMacOSXUpdateClipRgn( if (Tk_IsMapped(win2Ptr)) { x = win2Ptr->privatePtr->xOff; y = win2Ptr->privatePtr->yOff; - SetRectRgn(tmpRgn, (short) x, (short) y, - (short) (win2Ptr->changes.width + x), + SetRectRgn(tkMacOSXtmpRgn1, (short) x, (short) y, + (short) (win2Ptr->changes.width + x), (short) (win2Ptr->changes.height + y)); - DiffRgn(rgn, tmpRgn, rgn); + DiffRgn(rgn, tkMacOSXtmpRgn1, rgn); } - } + } /* * NOTE: Here we should handle out of process embedding. */ } + SetEmptyRgn(tkMacOSXtmpRgn1); } else { /* * An unmapped window has empty clip regions to prevent any @@ -957,7 +935,7 @@ TkMacOSXUpdateClipRgn( * visible. [Bug 940117] */ - if (!Tk_IsTopLevel(winPtr)) { + if (!Tk_IsTopLevel(winPtr)) { TkMacOSXUpdateClipRgn(winPtr->parentPtr); } else if (Tk_IsEmbedded(winPtr)) { TkWindow *contWinPtr = TkpGetOtherWindow(winPtr); @@ -972,7 +950,7 @@ TkMacOSXUpdateClipRgn( winPtr->privatePtr->flags &= ~TK_CLIP_INVALID; -#if defined(TK_MAC_DEBUG) && defined(TK_MAC_DEBUG_CLIP_REGIONS) +#ifdef TK_MAC_DEBUG_CLIP_REGIONS TkMacOSXInitNamedDebugSymbol(HIToolbox, int, QDDebugFlashRegion, CGrafPtr port, RgnHandle region); if (QDDebugFlashRegion) { @@ -991,8 +969,8 @@ TkMacOSXUpdateClipRgn( * * TkMacOSXVisableClipRgn -- * - * This function returnd the Macintosh cliping region for the - * given window. A NULL Rgn means the window is not visible. + * This function returnd the Macintosh cliping region for the + * given window. A NULL Rgn means the window is not visible. * * Results: * The region. @@ -1033,7 +1011,7 @@ TkMacOSXVisableClipRgn( void TkMacOSXInvalidateWindow( - MacDrawable *macWin, /* Make window that's causing damage. */ + MacDrawable *macWin, /* Make window that's causing damage. */ int flag) /* Should be TK_WINDOW_ONLY or * TK_PARENT_WINDOW */ { @@ -1053,7 +1031,7 @@ TkMacOSXInvalidateWindow( InvalWindowRgn(windowRef, macWin->aboveClipRgn); } -#if defined(TK_MAC_DEBUG) && defined(TK_MAC_DEBUG_CLIP_REGIONS) +#ifdef TK_MAC_DEBUG_CLIP_REGIONS TkMacOSXInitNamedDebugSymbol(HIToolbox, int, QDDebugFlashRegion, CGrafPtr port, RgnHandle region); if (QDDebugFlashRegion) { @@ -1073,7 +1051,7 @@ TkMacOSXInvalidateWindow( * This function returns the Graphics Port for a given X drawable. * * Results: - * A CGrafPort . Either an off screen pixmap or a Window. + * A CGrafPort . Either an off screen pixmap or a Window. * * Side effects: * None. @@ -1086,68 +1064,65 @@ TkMacOSXGetDrawablePort( Drawable drawable) { MacDrawable *macWin = (MacDrawable *) drawable; - GWorldPtr resultPort = NULL; - + CGrafPtr resultPort = NULL; + if (macWin == NULL) { - return NULL; + return NULL; } - + /* - * This is NULL for off-screen pixmaps. Then the portPtr + * This is NULL for off-screen pixmaps. Then the portPtr * always points to the off-screen port, and we don't * have to worry about containment */ - + if (macWin->clipRgn == NULL) { return macWin->grafPtr; } - + /* * If the Drawable is in an embedded window, use the Port of its container. - * + * * TRICKY POINT: we can have cases when a toplevel is being destroyed - * where the winPtr for the toplevel has been freed, but the children - * are not all the way destroyed. The children will call this function + * where the winPtr for the toplevel has been freed, but the children + * are not all the way destroyed. The children will call this function * as they are being destroyed, but Tk_IsEmbedded will return garbage. - * So we check the copy of the TK_EMBEDDED flag we put into the + * So we check the copy of the TK_EMBEDDED flag we put into the * toplevel's macWin flags. */ - - - - + if (!(macWin->toplevel->flags & TK_EMBEDDED)) { - return macWin->toplevel->grafPtr; + return macWin->toplevel->grafPtr; } else { - TkWindow *contWinPtr; + TkWindow *contWinPtr; contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr); - - if (contWinPtr != NULL) { - resultPort = TkMacOSXGetDrawablePort( + + if (contWinPtr != NULL) { + resultPort = TkMacOSXGetDrawablePort( (Drawable) contWinPtr->privatePtr); - } else if (tkMacOSXEmbedHandler != NULL) { + } else if (tkMacOSXEmbedHandler != NULL) { resultPort = tkMacOSXEmbedHandler->getPortProc( - (Tk_Window) macWin->winPtr); - } - + (Tk_Window) macWin->winPtr); + } + if (resultPort == NULL) { /* * FIXME: * * So far as I can tell, the only time that this happens is when * we are tearing down an embedded child interpreter, and most - * of the time, this is harmless... However, we really need to + * of the time, this is harmless... However, we really need to * find why the embedding loses. */ DebugStr("\pTkMacOSXGetDrawablePort couldn't find container"); - return NULL; - } - + return NULL; + } + /* * NOTE: Here we should handle out of process embedding. */ - + } return resultPort; } @@ -1177,23 +1152,23 @@ TkMacOSXGetRootControl( */ MacDrawable *macWin = (MacDrawable *) drawable; ControlRef result = NULL; - + if (macWin == NULL) { - return NULL; + return NULL; } if (!(macWin->toplevel->flags & TK_EMBEDDED)) { - return macWin->toplevel->rootControl; + return macWin->toplevel->rootControl; } else { - TkWindow *contWinPtr; + TkWindow *contWinPtr; - contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr); + contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr); - if (contWinPtr != NULL) { - result = TkMacOSXGetRootControl( - (Drawable) contWinPtr->privatePtr); - } else if (tkMacOSXEmbedHandler != NULL) { - result = NULL; - } + if (contWinPtr != NULL) { + result = TkMacOSXGetRootControl( + (Drawable) contWinPtr->privatePtr); + } else if (tkMacOSXEmbedHandler != NULL) { + result = NULL; + } } return result; } @@ -1204,7 +1179,7 @@ TkMacOSXGetRootControl( * TkMacOSXInvalClipRgns -- * * This function invalidates the clipping regions for a given - * window and all of its children. This function should be + * window and all of its children. This function should be * called whenever changes are made to subwindows that would * affect the size or position of windows. * @@ -1213,7 +1188,7 @@ TkMacOSXGetRootControl( * * Side effects: * The cliping regions for the window and its children are - * mark invalid. (Make sure they are valid before drawing.) + * mark invalid. (Make sure they are valid before drawing.) * *---------------------------------------------------------------------- */ @@ -1225,8 +1200,8 @@ TkMacOSXInvalClipRgns( TkWindow *winPtr = (TkWindow *) tkwin; TkWindow *childPtr; - /* - * If already marked we can stop because all + /* + * If already marked we can stop because all * decendants will also already be marked. */ if (!winPtr->privatePtr || winPtr->privatePtr->flags & TK_CLIP_INVALID) { @@ -1237,8 +1212,8 @@ TkMacOSXInvalClipRgns( SetEmptyRgn(winPtr->privatePtr->aboveClipRgn); SetEmptyRgn(winPtr->privatePtr->clipRgn); - /* - * Invalidate clip regions for all children & + /* + * Invalidate clip regions for all children & * their decendants - unless the child is a toplevel. */ childPtr = winPtr->childList; @@ -1274,7 +1249,7 @@ TkMacOSXInvalClipRgns( * * 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 + * system. This is also the same coordinate system as the * Tk toplevel window in which this window is contained. * * Results: @@ -1327,14 +1302,14 @@ UpdateOffsets( if (winPtr->privatePtr == NULL) { /* - * We havn't called Tk_MakeWindowExist for this window yet. The - * offset information will be postponed and calulated at that - * time. (This will usually only happen when a mapped parent is + * We havn't called Tk_MakeWindowExist for this window yet. The + * offset information will be postponed and calulated at that + * time. (This will usually only happen when a mapped parent is * being moved but has child windows that have yet to be mapped.) */ return; } - + winPtr->privatePtr->xOff += deltaX; winPtr->privatePtr->yOff += deltaY; @@ -1345,17 +1320,17 @@ UpdateOffsets( } childPtr = childPtr->nextPtr; } - + if (Tk_IsContainer(winPtr)) { childPtr = TkpGetOtherWindow(winPtr); if (childPtr != NULL) { UpdateOffsets(childPtr,deltaX,deltaY); } - + /* * NOTE: Here we should handle out of process embedding. */ - + } } @@ -1387,8 +1362,7 @@ Tk_GetPixmap( GWorldPtr gWorld; Rect bounds; MacDrawable *macPix; - PixMapHandle pixels; - + if (display != NULL) { display->request++; } @@ -1398,6 +1372,7 @@ Tk_GetPixmap( macPix->yOff = 0; macPix->clipRgn = NULL; macPix->aboveClipRgn = NULL; + macPix->drawRgn = NULL; macPix->referenceCount = 0; macPix->toplevel = NULL; macPix->flags = 0; @@ -1409,24 +1384,20 @@ Tk_GetPixmap( depth = 0; } /* - * Allocate memory for the off screen pixmap. If we fail - * try again from system memory. Eventually, we may have + * Allocate memory for the off screen pixmap. If we fail + * try again from system memory. Eventually, we may have * to panic. */ - err = NewGWorld(&gWorld, depth, &bounds, NULL, NULL, 0); - if (err != noErr) { - err = NewGWorld(&gWorld, depth, &bounds, NULL, NULL, useTempMem); - } + err = ChkErr(NewGWorld, &gWorld, depth, &bounds, NULL, NULL, 0 +#ifdef __LITTLE_ENDIAN__ + | kNativeEndianPixMap +#endif + ); if (err != noErr) { - Tcl_Panic("Out of memory: NewGWorld failed in Tk_GetPixmap"); + Tcl_Panic("Out of memory: NewGWorld failed in Tk_GetPixmap"); } - - /* - * Lock down the pixels so they don't move out from under us. - */ - pixels = GetGWorldPixMap(gWorld); - LockPixels(pixels); macPix->grafPtr = gWorld; + macPix->context = NULL; return (Pixmap) macPix; } @@ -1447,17 +1418,14 @@ Tk_GetPixmap( *---------------------------------------------------------------------- */ -void +void Tk_FreePixmap( Display *display, /* Display. */ - Pixmap pixmap) /* Pixmap to destroy */ + Pixmap pixmap) /* Pixmap to destroy */ { MacDrawable *macPix = (MacDrawable *) pixmap; - PixMapHandle pixels; display->request++; - pixels = GetGWorldPixMap(macPix->grafPtr); - UnlockPixels(pixels); DisposeGWorld(macPix->grafPtr); ckfree((char *) macPix); } diff --git a/macosx/tkMacOSXTest.c b/macosx/tkMacOSXTest.c index 51189eb..50e2ca7 100644 --- a/macosx/tkMacOSXTest.c +++ b/macosx/tkMacOSXTest.c @@ -1,4 +1,4 @@ -/* +/* * tkMacOSXTest.c -- * * Contains commands for platform specific tests for @@ -6,11 +6,12 @@ * * Copyright (c) 1996 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXTest.c,v 1.5 2005/12/09 00:48:54 das Exp $ + * RCS: @(#) $Id: tkMacOSXTest.c,v 1.6 2007/04/23 21:24:34 das Exp $ */ #include "tkMacOSXInt.h" @@ -20,7 +21,7 @@ */ static int DebuggerCmd (ClientData dummy, Tcl_Interp *interp, - int argc, CONST char **argv); + int argc, const char **argv); MODULE_SCOPE int TkplatformtestInit(Tcl_Interp *interp); /* @@ -47,9 +48,9 @@ TkplatformtestInit( /* * Add commands for platform specific tests on MacOS here. */ - + Tcl_CreateCommand(interp, "debugger", DebuggerCmd, - (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); return TCL_OK; } @@ -75,7 +76,7 @@ DebuggerCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ int argc, /* Not used. */ - CONST char **argv) /* Not used. */ + const char **argv) /* Not used. */ { Debugger(); return TCL_OK; diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c index 1c8901a..41a9cb1 100644 --- a/macosx/tkMacOSXWindowEvent.c +++ b/macosx/tkMacOSXWindowEvent.c @@ -2,59 +2,59 @@ * tkMacOSXWindowEvent.c -- * * This file defines the routines for both creating and handling - * Window Manager class events for Tk. + * Window Manager class events for Tk. * * Copyright 2001, Apple Computer, Inc. - * Copyright (c) 2005 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * The following terms apply to all files originating from Apple - * Computer, Inc. ("Apple") and associated with the software - * unless explicitly disclaimed in individual files. - * - * - * Apple hereby grants permission to use, copy, modify, - * distribute, and license this software and its documentation - * for any purpose, provided that existing copyright notices are - * retained in all copies and that this notice is included - * verbatim in any distributions. No written agreement, license, - * or royalty fee is required for any of the authorized - * uses. Modifications to this software may be copyrighted by - * their authors and need not follow the licensing terms - * described here, provided that the new terms are clearly - * indicated on the first page of each file where they apply. - * - * - * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE - * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, - * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF - * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, - * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND - * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS - * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE - * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * GOVERNMENT USE: If you are acquiring this software on behalf - * of the U.S. government, the Government shall have only - * "Restricted Rights" in the software and related documentation - * as defined in the Federal Acquisition Regulations (FARs) in - * Clause 52.227.19 (c) (2). If you are acquiring the software - * on behalf of the Department of Defense, the software shall be - * classified as "Commercial Computer Software" and the - * Government shall have only "Restricted Rights" as defined in - * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the - * foregoing, the authors grant the U.S. Government and others - * acting in its behalf permission to use and distribute the - * software in accordance with the terms specified in this - * license. - * - * RCS: @(#) $Id: tkMacOSXWindowEvent.c,v 1.20 2007/04/21 19:06:38 hobbs Exp $ + * The following terms apply to all files originating from Apple + * Computer, Inc. ("Apple") and associated with the software + * unless explicitly disclaimed in individual files. + * + * + * Apple hereby grants permission to use, copy, modify, + * distribute, and license this software and its documentation + * for any purpose, provided that existing copyright notices are + * retained in all copies and that this notice is included + * verbatim in any distributions. No written agreement, license, + * or royalty fee is required for any of the authorized + * uses. Modifications to this software may be copyrighted by + * their authors and need not follow the licensing terms + * described here, provided that the new terms are clearly + * indicated on the first page of each file where they apply. + * + * + * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE + * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, + * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF + * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, + * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND + * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS + * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE + * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * GOVERNMENT USE: If you are acquiring this software on behalf + * of the U.S. government, the Government shall have only + * "Restricted Rights" in the software and related documentation + * as defined in the Federal Acquisition Regulations (FARs) in + * Clause 52.227.19 (c) (2). If you are acquiring the software + * on behalf of the Department of Defense, the software shall be + * classified as "Commercial Computer Software" and the + * Government shall have only "Restricted Rights" as defined in + * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the + * foregoing, the authors grant the U.S. Government and others + * acting in its behalf permission to use and distribute the + * software in accordance with the terms specified in this + * license. + * + * RCS: @(#) $Id: tkMacOSXWindowEvent.c,v 1.21 2007/04/23 21:24:34 das Exp $ */ #include "tkMacOSXInt.h" @@ -63,11 +63,17 @@ #include "tkMacOSXDebug.h" /* +#ifdef TK_MAC_DEBUG +#define TK_MAC_DEBUG_CLIP_REGIONS +#endif +*/ + +/* * Declarations of global variables defined in this file. */ -static int tkMacOSXAppInFront = true; /* Boolean variable for determining if - * we are the frontmost app. Only set +static int tkMacOSXAppInFront = true; /* Boolean variable for determining if + * we are the frontmost app. Only set * in TkMacOSXProcessApplicationEvent */ static RgnHandle gDamageRgn = NULL; @@ -75,167 +81,342 @@ static RgnHandle gDamageRgn = NULL; /* * Declaration of functions used only in this file */ - + static int GenerateUpdateEvent( Window window); static int GenerateUpdates( RgnHandle updateRgn, TkWindow *winPtr); static int GenerateActivateEvents( Window window, int activeFlag); +static void ClearPort(CGrafPtr port); - + /* *---------------------------------------------------------------------- * * TkMacOSXProcessApplicationEvent -- * - * This processes Application level events, mainly activate - * and deactivate. + * This processes Application level events, mainly activate + * and deactivate. * * Results: - * o. + * 0. * * Side effects: - * Hide or reveal floating windows, and set tkMacOSXAppInFront. + * Hide or reveal floating windows, and set tkMacOSXAppInFront. * *---------------------------------------------------------------------- */ - + MODULE_SCOPE int TkMacOSXProcessApplicationEvent( - TkMacOSXEvent *eventPtr, - MacEventStatus *statusPtr) + TkMacOSXEvent *eventPtr, + MacEventStatus *statusPtr) { Tcl_CmdInfo dummy; /* - * This is a bit of a hack. We get "show" events both when we come back - * from being hidden, and whenever we are activated. I only want to run + * This is a bit of a hack. We get "show" events both when we come back + * from being hidden, and whenever we are activated. I only want to run * the "show" proc when we have been hidden already, not as a substitute - * for <Activate>. So I use this toggle... + * for <Activate>. So I use this toggle... */ static int toggleHide = 0; switch (eventPtr->eKind) { - case kEventAppActivated: - tkMacOSXAppInFront = true; - ShowFloatingWindows(); - break; - case kEventAppDeactivated: - TkSuspendClipboard(); - tkMacOSXAppInFront = false; - HideFloatingWindows(); - break; - case kEventAppQuit: - statusPtr->stopProcessing = 1; - break; - case kEventAppHidden: - if (toggleHide == 0) { - toggleHide = 1; - if (eventPtr->interp && Tcl_GetCommandInfo(eventPtr->interp, - "::tk::mac::OnHide", &dummy)) { - Tcl_GlobalEval(eventPtr->interp, "::tk::mac::OnHide"); - } - } - statusPtr->stopProcessing = 1; - break; - case kEventAppShown: - if (toggleHide == 1) { - toggleHide = 0; - if (eventPtr->interp && Tcl_GetCommandInfo(eventPtr->interp, - "::tk::mac::OnShow", &dummy)) { - Tcl_GlobalEval(eventPtr->interp, "::tk::mac::OnShow"); - } - } - statusPtr->stopProcessing = 1; - break; + case kEventAppActivated: + tkMacOSXAppInFront = true; + ShowFloatingWindows(); + break; + case kEventAppDeactivated: + TkSuspendClipboard(); + tkMacOSXAppInFront = false; + HideFloatingWindows(); + break; + case kEventAppQuit: + statusPtr->stopProcessing = 1; + break; + case kEventAppHidden: + if (toggleHide == 0) { + toggleHide = 1; + if (eventPtr->interp && Tcl_GetCommandInfo(eventPtr->interp, + "::tk::mac::OnHide", &dummy)) { + Tcl_GlobalEval(eventPtr->interp, "::tk::mac::OnHide"); + } + } + statusPtr->stopProcessing = 1; + break; + case kEventAppShown: + if (toggleHide == 1) { + toggleHide = 0; + if (eventPtr->interp && Tcl_GetCommandInfo(eventPtr->interp, + "::tk::mac::OnShow", &dummy)) { + Tcl_GlobalEval(eventPtr->interp, "::tk::mac::OnShow"); + } + } + statusPtr->stopProcessing = 1; + break; case kEventAppAvailableWindowBoundsChanged: { - TkDisplay *dispPtr = TkGetDisplayList(); - TkMacOSXDisplayChanged(dispPtr->display); + static UInt32 prevId = 0; + UInt32 id; + OSStatus err; + + err = ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamTransactionID, typeUInt32, + NULL, sizeof(id), NULL, &id); + if (err != noErr || id != prevId) { + TkDisplay *dispPtr = TkGetDisplayList(); + + prevId = id; + TkMacOSXDisplayChanged(dispPtr->display); + } /* * Should we call ::tk::mac::OnDisplayChanged? */ break; } - default: - break; + default: + break; } return 0; } -/* + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXProcessAppearanceEvent -- + * + * This processes Appearance events. + * + * Results: + * 0. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +MODULE_SCOPE int +TkMacOSXProcessAppearanceEvent( + TkMacOSXEvent *eventPtr, + MacEventStatus *statusPtr) +{ + switch (eventPtr->eKind) { + case kEventAppearanceScrollBarVariantChanged: + TkMacOSXInitScrollbarMetrics(); + break; + default: + break; + } + return 0; +} + +/* *---------------------------------------------------------------------- * * TkMacOSXProcessWindowEvent -- * - * This processes Window level events, mainly activate - * and deactivate. + * This processes Window level events, mainly activate + * and deactivate. * * Results: - * 0. + * 0. * * Side effects: - * Cause Windows to be moved forward or backward in the - * window stack. + * Cause Windows to be moved forward or backward in the + * window stack. * *---------------------------------------------------------------------- */ MODULE_SCOPE int TkMacOSXProcessWindowEvent( - TkMacOSXEvent * eventPtr, - MacEventStatus * statusPtr) -{ - OSStatus status; + TkMacOSXEvent * eventPtr, + MacEventStatus * statusPtr) +{ + OSStatus err; WindowRef whichWindow; - Window window; - int eventFound = false; - - switch (eventPtr->eKind) { - case kEventWindowActivated: - case kEventWindowDeactivated: - case kEventWindowUpdate: - case kEventWindowExpanded: - break; - default: - return 0; - break; + Window window; + int eventFound = false; + TkDisplay *dispPtr; + TkWindow *winPtr; + + switch (eventPtr->eKind) { + case kEventWindowActivated: + case kEventWindowDeactivated: + case kEventWindowUpdate: + case kEventWindowExpanded: + case kEventWindowBoundsChanged: + case kEventWindowDragStarted: + case kEventWindowDragCompleted: + case kEventWindowConstrain: + case kEventWindowGetRegion: + case kEventWindowDrawContent: + break; + default: + return 0; + break; } - status = GetEventParameter(eventPtr->eventRef, - kEventParamDirectObject, - typeWindowRef, NULL, - sizeof(whichWindow), NULL, - &whichWindow); - if (status != noErr) { -#ifdef TK_MAC_DEBUG - fprintf ( stderr, "TkMacOSXHandleWindowEvent:Failed to retrieve window" ); -#endif - return 0; + err = ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamDirectObject, typeWindowRef, NULL, sizeof(whichWindow), + NULL, &whichWindow); + if (err != noErr) { + return 0; } - + window = TkMacOSXGetXWindow(whichWindow); + dispPtr = TkGetDisplayList(); + winPtr = (TkWindow *)Tk_IdToWindow(dispPtr->display, window); - switch (eventPtr->eKind) { - case kEventWindowActivated: - eventFound |= GenerateActivateEvents(window, 1); - eventFound |= TkMacOSXGenerateFocusEvent(window, 1); - break; - case kEventWindowDeactivated: - eventFound |= GenerateActivateEvents(window, 0); - eventFound |= TkMacOSXGenerateFocusEvent(window, 0); - break; - case kEventWindowUpdate: - if (GenerateUpdateEvent(window)) { - eventFound = true; - } - break; - case kEventWindowExpanded: { - TkDisplay *dispPtr; - TkWindow *winPtr; - dispPtr = TkGetDisplayList(); - winPtr = (TkWindow *)Tk_IdToWindow(dispPtr->display, window); - if (winPtr) { - TkpWmSetState(winPtr, TkMacOSXIsWindowZoomed(winPtr) ? - ZoomState : NormalState); - } - break; - } + if (window != None) { + switch (eventPtr->eKind) { + case kEventWindowActivated: + case kEventWindowDeactivated: { + int activate = (eventPtr->eKind == kEventWindowActivated); + + eventFound |= GenerateActivateEvents(window, activate); + eventFound |= TkMacOSXGenerateFocusEvent(window, activate); + if (winPtr) { + TkMacOSXEnterExitFullscreen(winPtr, activate); + } + statusPtr->stopProcessing = 1; + break; + } + case kEventWindowUpdate: + if (GenerateUpdateEvent(window)) { + eventFound = true; + statusPtr->stopProcessing = 1; + } + break; + case kEventWindowExpanded: + if (winPtr) { + TkpWmSetState(winPtr, TkMacOSXIsWindowZoomed(winPtr) ? + ZoomState : NormalState); + } + break; + case kEventWindowBoundsChanged: + if (winPtr) { + WmInfo *wmPtr = winPtr->wmInfoPtr; + UInt32 attr; + Rect bounds; + int x = -1, y = -1, width = -1, height = -1, flags = 0; + + ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamAttributes, typeUInt32, + NULL, sizeof(attr), NULL, &attr); + ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamCurrentBounds, typeQDRectangle, + NULL, sizeof(bounds), NULL, &bounds); + if (attr & kWindowBoundsChangeOriginChanged) { + x = bounds.left - wmPtr->xInParent; + y = bounds.top - wmPtr->yInParent; + flags |= TK_LOCATION_CHANGED; + } + if (attr & kWindowBoundsChangeSizeChanged) { + width = bounds.right - bounds.left; + height = bounds.bottom - bounds.top; + flags |= TK_SIZE_CHANGED; + } + TkGenWMConfigureEvent((Tk_Window)winPtr, x, y, width, + height, flags); + if (attr & kWindowBoundsChangeUserResize || + attr & kWindowBoundsChangeUserDrag) { + TkMacOSXRunTclEventLoop(); + } + if (wmPtr->attributes & kWindowResizableAttribute) { + HIViewRef growBoxView; + + err = HIViewFindByID(HIViewGetRoot(whichWindow), + kHIViewWindowGrowBoxID, &growBoxView); + if (err == noErr) { + ChkErr(HIViewSetNeedsDisplay, growBoxView, true); + } + } + } + break; + case kEventWindowDragStarted: + if (winPtr) { + TkMacOSXTrackingLoop(1); + } + break; + case kEventWindowDragCompleted: + if (winPtr) { + Rect maxBounds, bounds, strWidths; + int h = 0, v = 0; + + TkMacOSXTrackingLoop(0); + ChkErr(GetWindowGreatestAreaDevice, whichWindow, + kWindowDragRgn, NULL, &maxBounds); + ChkErr(GetWindowBounds, whichWindow, kWindowStructureRgn, + &bounds); + ChkErr(GetWindowStructureWidths, whichWindow, &strWidths); + if (bounds.left > maxBounds.right - strWidths.left) { + h = maxBounds.right + - (strWidths.left ? strWidths.left : 40) + - bounds.left; + } else if (bounds.right < maxBounds.left + + strWidths.right) { + h = maxBounds.left + + (strWidths.right ? strWidths.right : 40) + - bounds.right; + } + if (bounds.top > maxBounds.bottom - strWidths.top) { + v = maxBounds.bottom + - (strWidths.top ? strWidths.top : 40) + - bounds.top; + } else if (bounds.bottom < maxBounds.top + + strWidths.bottom) { + v = maxBounds.top + + (strWidths.bottom ? strWidths.bottom : 40) + - bounds.bottom; + } else if (strWidths.top && bounds.top < maxBounds.top) { + v = maxBounds.top - bounds.top; + } + if (h || v) { + OffsetRect(&bounds, h, v); + ChkErr(SetWindowBounds, whichWindow, + kWindowStructureRgn, &bounds); + } + } + break; + case kEventWindowConstrain: + if (winPtr) { + if (winPtr->wmInfoPtr->flags & WM_FULLSCREEN && + TkMacOSXMakeFullscreen(winPtr, whichWindow, 1, + NULL) == TCL_OK) { + statusPtr->stopProcessing = 1; + } + } + break; + case kEventWindowGetRegion: + if (winPtr && (winPtr->wmInfoPtr->flags & WM_TRANSPARENT)) { + WindowRegionCode code; + + statusPtr->stopProcessing = (CallNextEventHandler( + eventPtr->callRef, eventPtr->eventRef) == noErr); + err = ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamWindowRegionCode, typeWindowRegionCode, + NULL, sizeof(code), NULL, &code); + if (err == noErr && code == kWindowOpaqueRgn) { + RgnHandle rgn; + + err = ChkErr(GetEventParameter, eventPtr->eventRef, + kEventParamRgnHandle, typeQDRgnHandle, NULL, + sizeof(rgn), NULL, &rgn); + if (err == noErr) { + SetEmptyRgn(rgn); + statusPtr->stopProcessing = 1; + } + } + } + break; + case kEventWindowDrawContent: + if (winPtr && (winPtr->wmInfoPtr->flags & WM_TRANSPARENT)) { + CGrafPtr port; + + GetPort(&port); + ClearPort(port); + } + break; + } } return 0; } @@ -245,60 +426,56 @@ TkMacOSXProcessWindowEvent( * * GenerateUpdateEvent -- * - * Given a Macintosh window update event this function generates - * all the Expose XEvents needed by Tk. + * Given a Macintosh window update event this function generates + * all the Expose XEvents needed by Tk. * - * Results: - * True if event(s) are generated - false otherwise. + * Results: + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. - * + * Additional events may be place on the Tk event queue. + * *---------------------------------------------------------------------- - */ + */ static int GenerateUpdateEvent(Window window) { - CGrafPtr destPort; - WindowRef macWindow; + CGrafPtr destPort; + WindowRef macWindow; TkDisplay * dispPtr; TkWindow * winPtr; - int result = 0; - static RgnHandle updtRgn = NULL, visRgn = NULL; - + int result = 0; + dispPtr = TkGetDisplayList(); winPtr = (TkWindow *)Tk_IdToWindow(dispPtr->display, window); - + if (winPtr ==NULL ){ - return result; + return result; } if (gDamageRgn == NULL) { - gDamageRgn = NewRgn(); - } - if (updtRgn == NULL) { - updtRgn = NewRgn(); - } - if (visRgn == NULL) { - visRgn = NewRgn(); + gDamageRgn = NewRgn(); } + TkMacOSXCheckTmpRgnEmpty(1); destPort = TkMacOSXGetDrawablePort(window); macWindow = GetWindowFromPort(destPort); - GetWindowRegion(macWindow, kWindowUpdateRgn, updtRgn); - visRgn = QDGlobalToLocalRegion(destPort, updtRgn); - SectRegionWithPortVisibleRegion(destPort, visRgn); -#if defined(TK_MAC_DEBUG) && defined(TK_MAC_DEBUG_CLIP_REGIONS) + GetWindowRegion(macWindow, kWindowUpdateRgn, tkMacOSXtmpRgn1); + QDGlobalToLocalRegion(destPort, tkMacOSXtmpRgn1); + SectRegionWithPortVisibleRegion(destPort, tkMacOSXtmpRgn1); +#ifdef TK_MAC_DEBUG_CLIP_REGIONS TkMacOSXInitNamedDebugSymbol(HIToolbox, int, QDDebugFlashRegion, - CGrafPtr port, RgnHandle region); + CGrafPtr port, RgnHandle region); if (QDDebugFlashRegion) { /* Carbon-internal region flashing SPI (c.f. Technote 2124) */ - QDDebugFlashRegion(destPort, visRgn); + QDDebugFlashRegion(destPort, tkMacOSXtmpRgn1); } #endif /* TK_MAC_DEBUG_CLIP_REGIONS */ BeginUpdate(macWindow); - result = GenerateUpdates(visRgn, winPtr); + if (winPtr->wmInfoPtr->flags & WM_TRANSPARENT) { + ClearPort(destPort); + } + result = GenerateUpdates(tkMacOSXtmpRgn1, winPtr); EndUpdate(macWindow); - SetEmptyRgn(visRgn); - SetEmptyRgn(updtRgn); + SetEmptyRgn(tkMacOSXtmpRgn1); SetEmptyRgn(gDamageRgn); return result; } @@ -308,16 +485,16 @@ GenerateUpdateEvent(Window window) * * GenerateUpdates -- * - * Given a Macintosh update region and a Tk window this function - * geneates a X Expose event for the window if it is within the - * update region. The function will then recursivly have each - * damaged window generate Expose events for its child windows. + * Given a Macintosh update region and a Tk window this function + * geneates a X Expose event for the window if it is within the + * update region. The function will then recursivly have each + * damaged window generate Expose events for its child windows. * * Results: - * True if event(s) are generated - false otherwise. + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. + * Additional events may be place on the Tk event queue. * *---------------------------------------------------------------------- */ @@ -333,26 +510,26 @@ GenerateUpdates( TkMacOSXWinBounds(winPtr, &bounds); GetRegionBounds(updateRgn,&updateBounds); - + if (bounds.top > updateBounds.bottom || - updateBounds.top > bounds.bottom || - bounds.left > updateBounds.right || - updateBounds.left > bounds.right || - !RectInRgn(&bounds, updateRgn)) { - return 0; + updateBounds.top > bounds.bottom || + bounds.left > updateBounds.right || + updateBounds.left > bounds.right || + !RectInRgn(&bounds, updateRgn)) { + return 0; } if (!RectInRgn(&bounds, updateRgn)) { - return 0; + return 0; } 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; - /* + /* * Compute the bounding box of the area that the damage occured in. */ @@ -369,97 +546,97 @@ GenerateUpdates( event.xexpose.width = damageBounds.right-damageBounds.left; event.xexpose.height = damageBounds.bottom-damageBounds.top; event.xexpose.count = 0; - + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); /* * Generate updates for the children of this window */ - + for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { - if (!Tk_IsMapped(childPtr) || Tk_IsTopLevel(childPtr)) { - continue; - } + childPtr = childPtr->nextPtr) { + if (!Tk_IsMapped(childPtr) || Tk_IsTopLevel(childPtr)) { + continue; + } - GenerateUpdates(updateRgn, childPtr); + GenerateUpdates(updateRgn, childPtr); } - + /* * Generate updates for any contained windows */ if (Tk_IsContainer(winPtr)) { - childPtr = TkpGetOtherWindow(winPtr); - if (childPtr != NULL && Tk_IsMapped(childPtr)) { - GenerateUpdates(updateRgn, childPtr); - } - - /* - * NOTE: Here we should handle out of process embedding. - */ - - } + childPtr = TkpGetOtherWindow(winPtr); + if (childPtr != NULL && Tk_IsMapped(childPtr)) { + GenerateUpdates(updateRgn, childPtr); + } + + /* + * NOTE: Here we should handle out of process embedding. + */ + + } return 1; } -/* +/* *---------------------------------------------------------------------- - * + * * GenerateActivateEvents -- - * - * Given a Macintosh window activate event this function generates all the - * X Activate events needed by Tk. * - * Results: - * True if event(s) are generated - false otherwise. + * Given a Macintosh window activate event this function generates all the + * X Activate events needed by Tk. + * + * Results: + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. - * + * Additional events may be place on the Tk event queue. + * *---------------------------------------------------------------------- */ - + int GenerateActivateEvents( - Window window, /* Root X window for event. */ - int activeFlag ) + Window window, /* Root X window for event. */ + int activeFlag ) { TkWindow *winPtr; TkDisplay *dispPtr; - + dispPtr = TkGetDisplayList(); winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window); if (winPtr == NULL || winPtr->window == None) { - return false; + return false; } TkGenerateActivateEvents(winPtr,activeFlag); return true; } -/* +/* *---------------------------------------------------------------------- - * + * * TkMacOSXGenerateFocusEvent -- - * - * Given a Macintosh window activate event this function generates all the - * X Focus events needed by Tk. * - * Results: - * True if event(s) are generated - false otherwise. + * Given a Macintosh window activate event this function generates all the + * X Focus events needed by Tk. + * + * Results: + * True if event(s) are generated - false otherwise. * * Side effects: - * Additional events may be place on the Tk event queue. - * + * Additional events may be place on the Tk event queue. + * *---------------------------------------------------------------------- - */ + */ MODULE_SCOPE int TkMacOSXGenerateFocusEvent( - Window window, /* Root X window for event. */ - int activeFlag ) + Window window, /* Root X window for event. */ + int activeFlag ) { XEvent event; Tk_Window tkwin; @@ -468,7 +645,7 @@ TkMacOSXGenerateFocusEvent( dispPtr = TkGetDisplayList(); tkwin = Tk_IdToWindow(dispPtr->display, window); if (tkwin == NULL) { - return false; + return false; } /* @@ -482,14 +659,14 @@ TkMacOSXGenerateFocusEvent( } /* - * Generate FocusIn and FocusOut events. This event + * Generate FocusIn and FocusOut events. This event * is only sent to the toplevel window. */ if (activeFlag) { - event.xany.type = FocusIn; + event.xany.type = FocusIn; } else { - event.xany.type = FocusOut; + event.xany.type = FocusOut; } event.xany.serial = dispPtr->display->request; @@ -502,13 +679,13 @@ TkMacOSXGenerateFocusEvent( Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); return true; } - + /* *---------------------------------------------------------------------- * * TkGenWMConfigureEvent -- * - * Generate a ConfigureNotify event for Tk. Depending on the + * Generate a ConfigureNotify event for Tk. Depending on the * value of flag the values of width/height, x/y, or both may * be changed. * @@ -533,11 +710,11 @@ TkGenWMConfigureEvent( XEvent event; WmInfo *wmPtr; TkWindow *winPtr = (TkWindow *) tkwin; - + if (tkwin == NULL) { return; } - + event.type = ConfigureNotify; event.xconfigure.serial = Tk_Display(tkwin)->request; event.xconfigure.send_event = False; @@ -552,27 +729,21 @@ TkGenWMConfigureEvent( event.xconfigure.above = None; } - if (flags & TK_LOCATION_CHANGED) { - event.xconfigure.x = x; - event.xconfigure.y = y; - } else { - event.xconfigure.x = Tk_X(tkwin); - event.xconfigure.y = Tk_Y(tkwin); + if (!(flags & TK_LOCATION_CHANGED)) { x = Tk_X(tkwin); y = Tk_Y(tkwin); } - if (flags & TK_SIZE_CHANGED) { - event.xconfigure.width = width; - event.xconfigure.height = height; - } else { - event.xconfigure.width = Tk_Width(tkwin); - event.xconfigure.height = Tk_Height(tkwin); + if (!(flags & TK_SIZE_CHANGED)) { width = Tk_Width(tkwin); height = Tk_Height(tkwin); } - + event.xconfigure.x = x; + event.xconfigure.y = y; + event.xconfigure.width = width; + event.xconfigure.height = height; + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - + /* * Update window manager information. */ @@ -583,7 +754,7 @@ TkGenWMConfigureEvent( wmPtr->y = y; wmPtr->flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y); } - if ((flags & TK_SIZE_CHANGED) && + if ((flags & TK_SIZE_CHANGED) && !(wmPtr->flags & WM_SYNC_PENDING) && ((width != Tk_Width(tkwin)) || (height != Tk_Height(tkwin)))) { if ((wmPtr->width == -1) && (width == winPtr->reqWidth)) { /* @@ -621,11 +792,11 @@ TkGenWMConfigureEvent( wmPtr->configHeight = height; } } - + /* - * Now set up the changes structure. Under X we wait for the - * ConfigureNotify to set these values. On the Mac we know imediatly that - * this is what we want - so we just set them. However, we need to + * Now set up the changes structure. Under X we wait for the + * ConfigureNotify to set these values. On the Mac we know imediatly that + * this is what we want - so we just set them. However, we need to * make sure the windows clipping region is marked invalid so the * change is visible to the subwindow. */ @@ -635,13 +806,14 @@ TkGenWMConfigureEvent( winPtr->changes.height = height; TkMacOSXInvalClipRgns(tkwin); } - + /* *---------------------------------------------------------------------- * * TkGenWMDestroyEvent -- * - * Generate a WM Destroy event for Tk. * + * Generate a WM Destroy event for Tk. + * * Results: * None. * @@ -656,11 +828,11 @@ TkGenWMDestroyEvent( Tk_Window tkwin) { XEvent event; - + event.xany.serial = Tk_Display(tkwin)->request; event.xany.send_event = False; event.xany.display = Tk_Display(tkwin); - + event.xclient.window = Tk_WindowId(tkwin); event.xclient.type = ClientMessage; event.xclient.message_type = Tk_InternAtom(tkwin, "WM_PROTOCOLS"); @@ -668,7 +840,7 @@ TkGenWMDestroyEvent( event.xclient.data.l[0] = Tk_InternAtom(tkwin, "WM_DELETE_WINDOW"); Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); } - + /* *---------------------------------------------------------------------- * @@ -706,11 +878,11 @@ TkWmProtocolEventProc( } protocol = (Atom) eventPtr->xclient.data.l[0]; for (protPtr = wmPtr->protPtr; protPtr != NULL; - protPtr = protPtr->nextPtr) { + protPtr = protPtr->nextPtr) { if (protocol == protPtr->protocol) { Tcl_Preserve((ClientData) protPtr); - interp = protPtr->interp; - Tcl_Preserve((ClientData) interp); + interp = protPtr->interp; + Tcl_Preserve((ClientData) interp); result = Tcl_GlobalEval(interp, protPtr->command); if (result != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (command for \""); @@ -719,14 +891,14 @@ TkWmProtocolEventProc( Tcl_AddErrorInfo(interp, "\" window manager protocol)"); Tk_BackgroundError(interp); } - Tcl_Release((ClientData) interp); + Tcl_Release((ClientData) interp); Tcl_Release((ClientData) protPtr); return; } } /* - * No handler was present for this protocol. If this is a + * No handler was present for this protocol. If this is a * WM_DELETE_WINDOW message then just destroy the window. */ @@ -734,13 +906,13 @@ TkWmProtocolEventProc( Tk_DestroyWindow((Tk_Window) winPtr); } } - + /* *---------------------------------------------------------------------- * * Tk_MacOSXIsAppInFront -- * - * Returns 1 if this app is the foreground app. + * Returns 1 if this app is the foreground app. * * Results: * 1 if app is in front, 0 otherwise. @@ -756,3 +928,31 @@ Tk_MacOSXIsAppInFront (void) { return tkMacOSXAppInFront; } + +/* + *---------------------------------------------------------------------- + * + * ClearPort -- + * + * Clear (i.e. fill with transparent color) the given port. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +static void +ClearPort(CGrafPtr port) { + CGContextRef context; + Rect bounds; + CGRect rect; + + GetPortBounds(port, &bounds); + QDBeginCGContext(port, &context); + rect = CGRectMake(0, 0, bounds.right, bounds.bottom); + CGContextClearRect(context, rect); + QDEndCGContext(port, &context); +} diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index c16f287..b344f04 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -1,36 +1,47 @@ -/* +/* * tkMacOSXWm.c -- * * This module takes care of the interactions between a Tk-based - * application and the window manager. Among other things, it + * application and the window manager. Among other things, it * implements the "wm" command and passes geometry information * to the window manager. * * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. - * Copyright (c) 2006 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.48 2007/04/21 19:06:38 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXWm.c,v 1.49 2007/04/23 21:24:34 das Exp $ */ #include "tkMacOSXInt.h" #include "tkScrollbar.h" #include "tkMacOSXWm.h" #include "tkMacOSXEvent.h" +#include "tkMacOSXDebug.h" -/* Define constants only available on Mac OS X 10.3 or later */ -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 - #define kSimpleWindowClass 18 - #define kWindowDoesNotCycleAttribute (1L << 15) -#endif -/* Define constants only available on Mac OS X 10.4 or later */ -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1040 - #define kWindowNoTitleBarAttribute (1L << 9) - #define kWindowMetalNoContentSeparatorAttribute (1L << 11) +/* +#ifdef TK_MAC_DEBUG +#define TK_MAC_DEBUG_WINDOWS #endif +*/ + +/* + * Data for [wm attributes] command: + */ +typedef enum { + WMATT_ALPHA, WMATT_FULLSCREEN, WMATT_MODIFIED, WMATT_NOTIFY, + WMATT_TITLEPATH, WMATT_TOPMOST, WMATT_TRANSPARENT, + _WMATT_LAST_ATTRIBUTE +} WmAttribute; + +static const char *WmAttributeNames[] = { + "-alpha", "-fullscreen", "-modified", "-notify", + "-titlepath", "-topmost", "-transparent", + NULL +}; /* * This is a list of all of the toplevels that have been mapped so far. It is @@ -42,7 +53,7 @@ TkMacOSXWindowList *tkMacOSXWindowListPtr = NULL; /* * The variable below is used to enable or disable tracing in this - * module. If tracing is enabled, then information is printed on + * module. If tracing is enabled, then information is printed on * standard output about interesting interactions with the window * manager. */ @@ -54,8 +65,7 @@ static int wmTracing = 0; * management of top-level windows. */ -static void TopLevelReqProc _ANSI_ARGS_((ClientData dummy, - Tk_Window tkwin)); +static void TopLevelReqProc(ClientData dummy, Tk_Window tkwin); static const Tk_GeomMgr wmMgrType = { "wm", /* name */ @@ -80,133 +90,93 @@ static int windowHashInit = false; * Forward declarations for procedures defined in this file: */ -static void InitialWindowBounds _ANSI_ARGS_((TkWindow *winPtr, - Rect *geometry)); -static int ParseGeometry _ANSI_ARGS_((Tcl_Interp *interp, - char *string, TkWindow *winPtr)); -static void TopLevelEventProc _ANSI_ARGS_((ClientData clientData, - XEvent *eventPtr)); -static void WmStackorderToplevelWrapperMap _ANSI_ARGS_(( - TkWindow *winPtr, - Display *display, - Tcl_HashTable *table)); -static void TopLevelReqProc _ANSI_ARGS_((ClientData dummy, - Tk_Window tkwin)); -static void UpdateGeometryInfo _ANSI_ARGS_(( - ClientData clientData)); -static void UpdateSizeHints _ANSI_ARGS_((TkWindow *winPtr)); -static void UpdateVRootGeometry _ANSI_ARGS_((WmInfo *wmPtr)); -static int WmAspectCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmAttributesCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static Tcl_Obj * WmAttrGetModifiedStatus(WindowRef macWindow); -static Tcl_Obj * WmAttrGetTitlePath(WindowRef macWindow); -static Tcl_Obj * WmAttrGetAlpha(WindowRef macWindow); -static Tcl_Obj * WmAttrGetNotifyStatus(void); -static void WmAttrSetNotifyStatus(int state); -static int WmClientCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmColormapwindowsCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmCommandCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmDeiconifyCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmFocusmodelCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmFrameCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmGeometryCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmGridCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmGroupCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmIconbitmapCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmIconifyCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmIconmaskCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmIconnameCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmIconphotoCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmIconpositionCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmIconwindowCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmMaxsizeCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmMinsizeCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmOverrideredirectCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmPositionfromCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmProtocolCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmResizableCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmSizefromCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmStackorderCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmStateCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmTitleCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmTransientCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int WmWithdrawCmd _ANSI_ARGS_((Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static void WmUpdateGeom _ANSI_ARGS_((WmInfo *wmPtr, - TkWindow *winPtr)); -static int WmWinStyle _ANSI_ARGS_((Tcl_Interp *interp, - TkWindow *winPtr, int objc, - Tcl_Obj * CONST objv[])); -static void ApplyWindowAttributeChanges _ANSI_ARGS_(( - TkWindow *winPtr, int newAttributes, - int oldAttributes, int create)); +static void InitialWindowBounds(TkWindow *winPtr, WindowRef macWindow, + Rect *geometry); +static int ParseGeometry(Tcl_Interp *interp, char *string, TkWindow *winPtr); +static void TopLevelEventProc(ClientData clientData, XEvent *eventPtr); +static void WmStackorderToplevelWrapperMap(TkWindow *winPtr, Display *display, + Tcl_HashTable *table); +static void UpdateGeometryInfo(ClientData clientData); +static void UpdateSizeHints(TkWindow *winPtr); +static void UpdateVRootGeometry(WmInfo *wmPtr); +static int WmAspectCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int WmAttributesCmd(Tk_Window tkwin, TkWindow *winPtr, + Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int WmClientCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int WmColormapwindowsCmd(Tk_Window tkwin, TkWindow *winPtr, + Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int WmCommandCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +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[]); +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, + int objc, Tcl_Obj *const objv[]); +static int WmGridCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int WmGroupCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int WmIconbitmapCmd(Tk_Window tkwin, TkWindow *winPtr, + Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int WmIconifyCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int WmIconmaskCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int WmIconnameCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int WmIconphotoCmd(Tk_Window tkwin, TkWindow *winPtr, + Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +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[]); +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, + int objc, Tcl_Obj *const objv[]); +static int WmOverrideredirectCmd(Tk_Window tkwin, TkWindow *winPtr, + Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int WmPositionfromCmd(Tk_Window tkwin, TkWindow *winPtr, + Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int WmProtocolCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int WmResizableCmd(Tk_Window tkwin, TkWindow *winPtr, + Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int WmSizefromCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int WmStackorderCmd(Tk_Window tkwin, TkWindow *winPtr, + Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int WmStateCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int WmTitleCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int WmTransientCmd(Tk_Window tkwin, TkWindow *winPtr, + Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int WmWithdrawCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static void WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr); +static int WmWinStyle(Tcl_Interp *interp, TkWindow *winPtr, int objc, + Tcl_Obj * const objv[]); +static void ApplyWindowClassAttributeChanges(TkWindow *winPtr, + WindowRef macWindow, WindowClass oldClass, + WindowAttributes oldAttributes, int create); +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); + /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * TkWmNewWindow -- * * This procedure is invoked whenever a new top-level - * window is created. Its job is to initialize the WmInfo + * window is created. Its job is to initialize the WmInfo * structure for the window. * * Results: @@ -215,7 +185,7 @@ static void ApplyWindowAttributeChanges _ANSI_ARGS_(( * Side effects: * A WmInfo structure gets allocated and initialized. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ void @@ -244,14 +214,8 @@ TkWmNewWindow( wmPtr->iconFor = NULL; wmPtr->sizeHintsFlags = 0; wmPtr->minWidth = wmPtr->minHeight = 1; - - /* - * Default the maximum dimensions to the size of the display, minus - * a guess about how space is needed for window manager decorations. - */ - - wmPtr->maxWidth = DisplayWidth(winPtr->display, winPtr->screenNum) - 15; - wmPtr->maxHeight = DisplayHeight(winPtr->display, winPtr->screenNum) - 30; + wmPtr->maxWidth = 0; + wmPtr->maxHeight = 0; wmPtr->gridWin = NULL; wmPtr->widthInc = wmPtr->heightInc = 1; wmPtr->minAspect.x = wmPtr->minAspect.y = 1; @@ -270,6 +234,8 @@ TkWmNewWindow( wmPtr->yInParent = 0; wmPtr->cmapList = NULL; wmPtr->cmapCount = 0; + wmPtr->configX = 0; + wmPtr->configY = 0; wmPtr->configWidth = -1; wmPtr->configHeight = -1; wmPtr->vRoot = None; @@ -279,7 +245,8 @@ TkWmNewWindow( wmPtr->flags = WM_NEVER_MAPPED; wmPtr->style = -1; wmPtr->macClass = kDocumentWindowClass; - wmPtr->attributes = kWindowStandardDocumentAttributes; + wmPtr->attributes = kWindowStandardDocumentAttributes + | kWindowLiveResizeAttribute; wmPtr->scrollWinPtr = NULL; winPtr->wmInfoPtr = wmPtr; @@ -302,14 +269,14 @@ TkWmNewWindow( } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * TkWmMapWindow -- * - * This procedure is invoked to map a top-level window. This + * This procedure is invoked to map a top-level window. This * module gets a chance to update all window-manager-related * information in properties before the window manager sees - * the map event and checks the properties. It also gets to + * the map event and checks the properties. It also gets to * decide whether or not to even map the window after all. * * Results: @@ -317,11 +284,11 @@ TkWmNewWindow( * * Side effects: * Properties of winPtr may get updated to provide up-to-date - * information to the window manager. The window may also get + * information to the window manager. The window may also get * mapped, but it may not be if this procedure decides that * isn't appropriate (e.g. because the window is withdrawn). * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ void @@ -330,7 +297,6 @@ TkWmMapWindow( * be mapped. */ { WmInfo *wmPtr = winPtr->wmInfoPtr; - Rect widths; if (wmPtr->flags & WM_NEVER_MAPPED) { wmPtr->flags &= ~WM_NEVER_MAPPED; @@ -373,7 +339,7 @@ TkWmMapWindow( if (wmPtr->hints.initial_state == WithdrawnState) { return; } - + /* * TODO: we need to display a window if it's iconic on creation. */ @@ -381,7 +347,7 @@ TkWmMapWindow( if (wmPtr->hints.initial_state == IconicState) { return; } - + /* * Update geometry information. */ @@ -397,22 +363,10 @@ TkWmMapWindow( */ XMapWindow(winPtr->display, winPtr->window); - - /* - * Now that the window is visible we can determine the offset - * from the window's content orgin to the window's decorative - * orgin (structure orgin). - */ - GetWindowStructureWidths(GetWindowFromPort(TkMacOSXGetDrawablePort( - Tk_WindowId(winPtr))), &widths); - wmPtr->xInParent = widths.left; - wmPtr->yInParent = widths.top; - wmPtr->parentWidth = winPtr->changes.width + widths.left + widths.right; - wmPtr->parentHeight = winPtr->changes.height + widths.top + widths.bottom; } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * TkWmUnmapWindow -- * @@ -425,7 +379,7 @@ TkWmMapWindow( * Side effects: * Unmaps the window. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ void @@ -437,12 +391,12 @@ TkWmUnmapWindow( } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * TkWmDeadWindow -- * * This procedure is invoked when a top-level window is - * about to be deleted. It cleans up the wm-related data + * about to be deleted. It cleans up the wm-related data * structures for the window. * * Results: @@ -451,12 +405,12 @@ TkWmUnmapWindow( * Side effects: * The WmInfo structure for winPtr gets freed up. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ void -TkWmDeadWindow(winPtr) - TkWindow *winPtr; /* Top-level window that's being deleted. */ +TkWmDeadWindow( + TkWindow *winPtr) /* Top-level window that's being deleted. */ { WmInfo *wmPtr = winPtr->wmInfoPtr; WmInfo *wmPtr2; @@ -506,14 +460,14 @@ TkWmDeadWindow(winPtr) } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * TkWmSetClass -- * * This procedure is invoked whenever a top-level window's - * class is changed. If the window has been mapped then this + * class is changed. If the window has been mapped then this * procedure updates the window manager property for the - * class. If the window hasn't been mapped, the update is + * class. If the window hasn't been mapped, the update is * deferred until just before the first mapping. * * Results: @@ -522,7 +476,7 @@ TkWmDeadWindow(winPtr) * Side effects: * A window property may get updated. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ void @@ -531,6 +485,7 @@ TkWmSetClass( { return; } + /* *---------------------------------------------------------------------- * @@ -551,143 +506,142 @@ TkWmSetClass( /* ARGSUSED */ int Tk_WmObjCmd( - ClientData clientData, /* Main window associated with - * interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ - { + ClientData clientData, /* Main window associated with interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ Tk_Window tkwin = (Tk_Window) clientData; - static CONST char *optionStrings[] = { - "aspect", "attributes", "client", "colormapwindows", - "command", "deiconify", "focusmodel", "frame", - "geometry", "grid", "group", "iconbitmap", - "iconify", "iconmask", "iconname", + static const char *optionStrings[] = { + "aspect", "attributes", "client", "colormapwindows", + "command", "deiconify", "focusmodel", "frame", + "geometry", "grid", "group", "iconbitmap", + "iconify", "iconmask", "iconname", "iconphoto", "iconposition", - "iconwindow", "maxsize", "minsize", "overrideredirect", - "positionfrom", "protocol", "resizable", "sizefrom", - "stackorder", "state", "title", "transient", - "withdraw", (char *) NULL }; + "iconwindow", "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_FRAME, - WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP, - WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME, + WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS, + WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, 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_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM, - WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT, - WMOPT_WITHDRAW }; + WMOPT_ICONWINDOW, WMOPT_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT, + WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM, + WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT, + WMOPT_WITHDRAW }; int index, length; char *argv1; TkWindow *winPtr; if (objc < 2) { wrongNumArgs: - Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?"); + return TCL_ERROR; } argv1 = Tcl_GetStringFromObj(objv[1], &length); if ((argv1[0] == 't') && (strncmp(argv1, "tracing", length) == 0) - && (length >= 3)) { - if ((objc != 2) && (objc != 3)) { - Tcl_WrongNumArgs(interp, 2, objv, "?boolean?"); - return TCL_ERROR; - } - if (objc == 2) { - Tcl_SetResult(interp, ((wmTracing) ? "on" : "off"), TCL_STATIC); - return TCL_OK; - } - return Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing); + && (length >= 3)) { + if ((objc != 2) && (objc != 3)) { + Tcl_WrongNumArgs(interp, 2, objv, "?boolean?"); + return TCL_ERROR; + } + if (objc == 2) { + Tcl_SetResult(interp, ((wmTracing) ? "on" : "off"), TCL_STATIC); + return TCL_OK; + } + return Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing); } if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, - &index) != TCL_OK) { - return TCL_ERROR; + &index) != TCL_OK) { + return TCL_ERROR; } if (objc < 3) { - goto wrongNumArgs; + goto wrongNumArgs; } if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) &winPtr) - != TCL_OK) { - return TCL_ERROR; + != TCL_OK) { + return TCL_ERROR; } if (!Tk_IsTopLevel(winPtr)) { - Tcl_AppendResult(interp, "window \"", winPtr->pathName, - "\" isn't a top-level window", (char *) NULL); - return TCL_ERROR; + Tcl_AppendResult(interp, "window \"", winPtr->pathName, + "\" isn't a top-level window", NULL); + return TCL_ERROR; } switch ((enum options) index) { - case WMOPT_ASPECT: - return WmAspectCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ATTRIBUTES: - return WmAttributesCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_CLIENT: - return WmClientCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_COLORMAPWINDOWS: - return WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_COMMAND: - return WmCommandCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_DEICONIFY: - return WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_FOCUSMODEL: - return WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_FRAME: - return WmFrameCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_GEOMETRY: - return WmGeometryCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_GRID: - return WmGridCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_GROUP: - return WmGroupCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONBITMAP: - return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONIFY: - return WmIconifyCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONMASK: - return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONNAME: - return WmIconnameCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_ASPECT: + return WmAspectCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_ATTRIBUTES: + return WmAttributesCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_CLIENT: + return WmClientCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_COLORMAPWINDOWS: + return WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_COMMAND: + return WmCommandCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_DEICONIFY: + return WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_FOCUSMODEL: + return WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_FRAME: + return WmFrameCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_GEOMETRY: + return WmGeometryCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_GRID: + return WmGridCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_GROUP: + return WmGroupCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_ICONBITMAP: + return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_ICONIFY: + return WmIconifyCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_ICONMASK: + return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_ICONNAME: + return WmIconnameCmd(tkwin, winPtr, interp, objc, objv); case WMOPT_ICONPHOTO: return WmIconphotoCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONPOSITION: - return WmIconpositionCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONWINDOW: - return WmIconwindowCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_MAXSIZE: - return WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_MINSIZE: - return WmMinsizeCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_OVERRIDEREDIRECT: - return WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_POSITIONFROM: - return WmPositionfromCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_PROTOCOL: - return WmProtocolCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_RESIZABLE: - return WmResizableCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_SIZEFROM: - return WmSizefromCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_STACKORDER: - return WmStackorderCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_STATE: - return WmStateCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_TITLE: - return WmTitleCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_TRANSIENT: - return WmTransientCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_WITHDRAW: - return WmWithdrawCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_ICONPOSITION: + return WmIconpositionCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_ICONWINDOW: + return WmIconwindowCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_MAXSIZE: + return WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_MINSIZE: + return WmMinsizeCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_OVERRIDEREDIRECT: + return WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_POSITIONFROM: + return WmPositionfromCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_PROTOCOL: + return WmProtocolCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_RESIZABLE: + return WmResizableCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_SIZEFROM: + return WmSizefromCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_STACKORDER: + return WmStackorderCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_STATE: + return WmStateCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_TITLE: + return WmTitleCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_TRANSIENT: + return WmTransientCmd(tkwin, winPtr, interp, objc, objv); + case WMOPT_WITHDRAW: + return WmWithdrawCmd(tkwin, winPtr, interp, objc, objv); } /* This should not happen */ return TCL_ERROR; } - + /* *---------------------------------------------------------------------- * @@ -706,402 +660,407 @@ wrongNumArgs: */ static int -WmAspectCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmAspectCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; int numer1, denom1, numer2, denom2; if ((objc != 3) && (objc != 7)) { - Tcl_WrongNumArgs(interp, 2, objv, - "window ?minNumer minDenom maxNumer maxDenom?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, + "window ?minNumer minDenom maxNumer maxDenom?"); + return TCL_ERROR; } if (objc == 3) { - if (wmPtr->sizeHintsFlags & PAspect) { - char buf[TCL_INTEGER_SPACE * 4]; + if (wmPtr->sizeHintsFlags & PAspect) { + char buf[TCL_INTEGER_SPACE * 4]; - sprintf(buf, "%d %d %d %d", wmPtr->minAspect.x, - wmPtr->minAspect.y, wmPtr->maxAspect.x, - wmPtr->maxAspect.y); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - } - return TCL_OK; + sprintf(buf, "%d %d %d %d", wmPtr->minAspect.x, + wmPtr->minAspect.y, wmPtr->maxAspect.x, + wmPtr->maxAspect.y); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + } + return TCL_OK; } if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->sizeHintsFlags &= ~PAspect; + wmPtr->sizeHintsFlags &= ~PAspect; } else { - if ((Tcl_GetIntFromObj(interp, objv[3], &numer1) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) { - return TCL_ERROR; - } - if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) || - (denom2 <= 0)) { - Tcl_SetResult(interp, "aspect number can't be <= 0", - TCL_STATIC); - return TCL_ERROR; - } - wmPtr->minAspect.x = numer1; - wmPtr->minAspect.y = denom1; - wmPtr->maxAspect.x = numer2; - wmPtr->maxAspect.y = denom2; - wmPtr->sizeHintsFlags |= PAspect; + if ((Tcl_GetIntFromObj(interp, objv[3], &numer1) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) { + return TCL_ERROR; + } + if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) || + (denom2 <= 0)) { + Tcl_SetResult(interp, "aspect number can't be <= 0", + TCL_STATIC); + return TCL_ERROR; + } + wmPtr->minAspect.x = numer1; + wmPtr->minAspect.y = denom1; + wmPtr->maxAspect.x = numer2; + wmPtr->maxAspect.y = denom2; + wmPtr->sizeHintsFlags |= PAspect; } wmPtr->flags |= WM_UPDATE_SIZE_HINTS; WmUpdateGeom(wmPtr, winPtr); return TCL_OK; } - + /* *---------------------------------------------------------------------- * - * WmAttributesCmd -- + * WmSetAttribute -- * - * This procedure is invoked to process the "wm attributes" Tcl command. - * See the user documentation for details on what it does. + * Helper routine for WmAttributesCmd. Sets the value + * of the specified attribute. * - * Results: - * A standard Tcl result. + * Returns: * - * Side effects: - * See the user documentation. + * TCL_OK if successful, TCL_ERROR otherwise. In case of an + * error, leaves a message in the interpreter's result. * *---------------------------------------------------------------------- */ - -static int -WmAttributesCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +static int WmSetAttribute( + TkWindow *winPtr, /* Toplevel to work with */ + WindowRef macWindow, + Tcl_Interp *interp, /* Current interpreter */ + WmAttribute attribute, /* Code of attribute to set */ + Tcl_Obj *value) /* New value */ { - int i; - int index; - WindowRef macWindow; - Tcl_Obj *objPtr = NULL; - const char *optionTable[] = { - "-alpha", - "-modified", - "-notify", - "-titlepath", - (char *)NULL - }; - enum optionIdx { - WmAttrAlphaIdx, - WmAttrModifiedIdx, - WmAttrNotifyIdx, - WmAttrTitlePathIdx, - }; - - /* Must have objc >= 3 at this point. */ - if (objc < 3) { - Tcl_WrongNumArgs(interp, 1, objv, - "attributes window ?-modified ?bool?? ?-titlepath ?path?? ?-alpha ?double?? ?-notify ?bool??"); - return TCL_ERROR; - } - - if (winPtr->window == None) { - Tk_MakeWindowExist((Tk_Window) winPtr); - } - if (!TkMacOSXHostToplevelExists(winPtr)) { - TkMacOSXMakeRealWindowExist(winPtr); - } - macWindow = GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window)); - - if (objc == 3) { - objPtr = Tcl_NewObj(); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewStringObj("-alpha", -1)); - Tcl_ListObjAppendElement(NULL, objPtr, WmAttrGetAlpha(macWindow)); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewStringObj("-modified", -1)); - Tcl_ListObjAppendElement(NULL, objPtr, - WmAttrGetModifiedStatus(macWindow)); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewStringObj("-notify", -1)); - Tcl_ListObjAppendElement(NULL, objPtr, WmAttrGetNotifyStatus()); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewStringObj("-titlepath", -1)); - Tcl_ListObjAppendElement(NULL, objPtr, WmAttrGetTitlePath(macWindow)); - Tcl_SetObjResult(interp, objPtr); - return TCL_OK; - } - if (objc == 4) { - if (Tcl_GetIndexFromObj(interp, objv[3], optionTable, "attribute", 0, - &index) != TCL_OK) { - return TCL_ERROR; - } - switch (index) { - case WmAttrModifiedIdx: - objPtr = WmAttrGetModifiedStatus(macWindow); - break; - case WmAttrTitlePathIdx: - objPtr = WmAttrGetTitlePath(macWindow); - break; - case WmAttrAlphaIdx: - objPtr = WmAttrGetAlpha(macWindow); - break; - case WmAttrNotifyIdx: - objPtr = WmAttrGetNotifyStatus(); - break; - } - Tcl_SetObjResult(interp, objPtr); - return TCL_OK; - } + WmInfo *wmPtr = winPtr->wmInfoPtr; + int boolean; - if ( (objc - 3) % 2 != 0 ) { - Tcl_WrongNumArgs(interp, 3, objv, - "?-modified ?bool?? ?-titlepath ?path?? ?-alpha ?double??"); - return TCL_ERROR; - } - for (i = 3; i < objc; i += 2) { - int boolean; - const char *path; - OSErr err; - double dval; + switch (attribute) { + case WMATT_ALPHA: { + double dval; - if (Tcl_GetIndexFromObj(interp, objv[i], optionTable, "attribute", 0, - &index) != TCL_OK) { - return TCL_ERROR; + if (Tcl_GetDoubleFromObj(interp, value, &dval) != TCL_OK) { + return TCL_ERROR; + } + /* + * The user should give (transparent) 0 .. 1.0 (opaque) + */ + if (dval < 0.0) { + dval = 0.0; + } else if (dval > 1.0) { + dval = 1.0; + } + ChkErr(SetWindowAlpha, macWindow, dval); + break; } - switch (index) { - case WmAttrModifiedIdx: - if (Tcl_GetBooleanFromObj(interp, objv[i+1], &boolean) != - TCL_OK) { + case WMATT_FULLSCREEN: + if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) { + return TCL_ERROR; + } + if (boolean != ((wmPtr->flags & WM_FULLSCREEN) != 0)) { + if(TkMacOSXMakeFullscreen(winPtr, macWindow, boolean, interp) + != TCL_OK) { return TCL_ERROR; } - objPtr = objv[i+1]; - SetWindowModified(macWindow, boolean); - break; - case WmAttrTitlePathIdx: - path = Tcl_FSGetNativePath(objv[i+1]); - if (path && *path) { - FSRef ref; - Boolean d; - err = FSPathMakeRef((unsigned char*) path, &ref, &d); - if (err == noErr) { + } + break; + case WMATT_MODIFIED: + if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) { + return TCL_ERROR; + } + if (boolean != IsWindowModified(macWindow)) { + ChkErr(SetWindowModified, macWindow, boolean); + } + break; + case WMATT_NOTIFY: + if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) { + return TCL_ERROR; + } + if (boolean == !tkMacOSXWmAttrNotifyVal) { + static NMRec notifyRec; + + if (boolean) { + bzero(¬ifyRec, sizeof(notifyRec)); + notifyRec.qType = nmType; + notifyRec.nmMark = 1; + ChkErr(NMInstall, ¬ifyRec); + } else { + ChkErr(NMRemove, ¬ifyRec); + } + tkMacOSXWmAttrNotifyVal = boolean; + } + break; + case WMATT_TITLEPATH: { + const char *path; + OSStatus err; + + path = Tcl_FSGetNativePath(value); + if (path && *path) { + FSRef ref; + Boolean d; + + err = ChkErr(FSPathMakeRef, (const unsigned char*) path, &ref, + &d); + if (err == noErr) { #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 - if (HIWindowSetProxyFSRef != NULL) { - err = HIWindowSetProxyFSRef(macWindow, &ref); - } else + if (1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + && HIWindowSetProxyFSRef != NULL +#endif + ) { + err = ChkErr(HIWindowSetProxyFSRef, macWindow, &ref); + } else #endif - { - AliasHandle alias; - err = FSNewAlias(NULL, &ref, &alias); - if (err == noErr) { - err = SetWindowProxyAlias(macWindow, alias); - DisposeHandle((Handle) alias); - } + { +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + AliasHandle alias; + + err = ChkErr(FSNewAlias, NULL, &ref, &alias); + if (err == noErr) { + err = ChkErr(SetWindowProxyAlias, macWindow, + alias); + DisposeHandle((Handle) alias); } - } - } else { - int len; - Tcl_GetStringFromObj(objv[i+1], &len); - if (len == 0) { - err = RemoveWindowProxy(macWindow); - } else { - err = fnfErr; +#endif } } - if (err != noErr) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("couldn't set window proxy title path", - -1)); - return TCL_ERROR; + } else { + int len; + + Tcl_GetStringFromObj(value, &len); + if (!len) { + err = ChkErr(RemoveWindowProxy, macWindow); } else { - objPtr = objv[i+1]; + err = fnfErr; } - break; - case WmAttrAlphaIdx: - if (Tcl_GetDoubleFromObj(interp, objv[i+1], &dval) != - TCL_OK) { - return TCL_ERROR; - } - /* - * The user should give (transparent) 0 .. 1.0 (opaque) - */ - if (dval < 0.0) { - dval = 0.0; - } else if (dval > 1.0) { - dval = 1.0; + } + if (err != noErr) { + return TCL_ERROR; + } + break; + } + case WMATT_TOPMOST: { + if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) { + return TCL_ERROR; + } + if (boolean != ((wmPtr->flags & WM_TOPMOST) != 0)) { + WindowGroupRef group; + + if (boolean) { + wmPtr->flags |= WM_TOPMOST; + group = GetWindowGroupOfClass(kUtilityWindowClass); + } else { + wmPtr->flags &= ~WM_TOPMOST; + group = GetWindowGroupOfClass(wmPtr->macClass); } - objPtr = Tcl_NewDoubleObj(dval); - SetWindowAlpha(macWindow, dval); - break; - case WmAttrNotifyIdx: - if (Tcl_GetBooleanFromObj(interp, objv[i+1], &boolean) != - TCL_OK) { - return TCL_ERROR; + if (group && group != GetWindowGroup(macWindow)) { + ChkErr(SetWindowGroup, macWindow, group); } - objPtr = Tcl_NewBooleanObj(boolean); - WmAttrSetNotifyStatus(boolean); - break; + } + break; } + case WMATT_TRANSPARENT: + if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) { + return TCL_ERROR; + } + if (boolean != ((wmPtr->flags & WM_TRANSPARENT) != 0)) { + WindowAttributes oldAttributes = wmPtr->attributes; + + if (boolean) { + wmPtr->flags |= WM_TRANSPARENT; + wmPtr->attributes |= kWindowNoShadowAttribute; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + if (1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1030 + && HIWindowChangeFeatures != NULL +#endif + ) { + UInt32 features; + + ChkErr(GetWindowFeatures, macWindow, &features); + if (features & kWindowIsOpaque) { + ChkErr(HIWindowChangeFeatures, macWindow, 0, + kWindowIsOpaque); + } + } +#endif + } else { + wmPtr->flags &= ~WM_TRANSPARENT; + wmPtr->attributes &= ~kWindowNoShadowAttribute; + } + ApplyWindowClassAttributeChanges(winPtr, macWindow, + wmPtr->macClass, oldAttributes, 1); + ChkErr(ReshapeCustomWindow, macWindow); + TkMacOSXInvalidateWindow((MacDrawable *)(winPtr->window), + TK_WINDOW_ONLY); + } + break; + case _WMATT_LAST_ATTRIBUTE: + default: + return TCL_ERROR; } - Tcl_SetObjResult(interp, objPtr); return TCL_OK; } /* *---------------------------------------------------------------------- - * WmAttrGetModifiedStatus -- - * - * Helper procedure to retrieve the -modified option for the wm - * attributes command. - * - * Results: - * Returns value in unrefcounted Tcl_Obj. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ -static Tcl_Obj * -WmAttrGetModifiedStatus(WindowRef macWindow) -{ - return Tcl_NewBooleanObj((IsWindowModified(macWindow) == true)); -} - -/* - *---------------------------------------------------------------------- - * WmAttrGetTitlePath -- - * - * Helper procedure to retrieve the -titlepath option for the wm - * attributes command. * - * Results: - * Returns value in unrefcounted Tcl_Obj. + * WmGetAttribute -- * - * Side effects: - * None. + * Helper routine for WmAttributesCmd. Returns the current value + * of the specified attribute. * *---------------------------------------------------------------------- */ -static Tcl_Obj * -WmAttrGetTitlePath(WindowRef macWindow) +static Tcl_Obj *WmGetAttribute( + TkWindow *winPtr, /* Toplevel to work with */ + WindowRef macWindow, + WmAttribute attribute) /* Code of attribute to get */ { - FSRef ref; - Boolean wasChanged; - UInt8 path[2048]; - OSStatus err = fnfErr; + WmInfo *wmPtr = winPtr->wmInfoPtr; + Tcl_Obj *result = NULL; + + switch (attribute) { + case WMATT_ALPHA: { + float fval = 1.0; + + ChkErr(GetWindowAlpha, macWindow, &fval); + result = Tcl_NewDoubleObj(fval); + break; + } + case WMATT_FULLSCREEN: + result = Tcl_NewBooleanObj(wmPtr->flags & WM_FULLSCREEN); + break; + case WMATT_MODIFIED: + result = Tcl_NewBooleanObj(IsWindowModified(macWindow)); + break; + case WMATT_NOTIFY: + result = Tcl_NewBooleanObj(tkMacOSXWmAttrNotifyVal); + break; + case WMATT_TITLEPATH: { + FSRef ref; + UInt8 path[PATH_MAX+1]; + OSStatus err; #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 - if (HIWindowGetProxyFSRef != NULL) { - err = HIWindowGetProxyFSRef(macWindow, &ref); - } + if (1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + && HIWindowSetProxyFSRef != NULL #endif - if (err != noErr) { - AliasHandle alias; - err = GetWindowProxyAlias(macWindow, &alias); - if (err == noErr) { - err = FSResolveAlias(NULL, alias, &ref, &wasChanged); + ) { + err = ChkErr(HIWindowGetProxyFSRef, macWindow, &ref); + } else +#endif +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + { + Boolean wasChanged; + AliasHandle alias; + + err = ChkErr(GetWindowProxyAlias, macWindow, &alias); + if (err == noErr) { + err = ChkErr(FSResolveAlias, NULL, alias, &ref, + &wasChanged); + } + } +#endif + if (err == noErr) { + err = ChkErr(FSRefMakePath, &ref, path, PATH_MAX); + } + if (err != noErr) { + *path = 0; + } + result = Tcl_NewStringObj((char*) path, -1); + break; } + case WMATT_TOPMOST: + result = Tcl_NewBooleanObj(wmPtr->flags & WM_TOPMOST); + break; + case WMATT_TRANSPARENT: + result = Tcl_NewBooleanObj(wmPtr->flags & WM_TRANSPARENT); + break; + case _WMATT_LAST_ATTRIBUTE: + default: + break; } - if (err == noErr) { - err = FSRefMakePath(&ref, path, 2048); - } - if (err == noErr) { - return Tcl_NewStringObj((char*) path, -1); - } else { - return Tcl_NewStringObj("", 0); - } + return result; } /* *---------------------------------------------------------------------- - * WmAttrGetAlpha -- - * - * Helper procedure to retrieve the -alpha option for the wm - * attributes command. - * - * Results: - * Returns value in unrefcounted Tcl_Obj. - * - * Side effects: - * None. * - *---------------------------------------------------------------------- - */ -static Tcl_Obj * -WmAttrGetAlpha(WindowRef macWindow) -{ - float fval; - if (GetWindowAlpha(macWindow, &fval) != noErr) { - fval = 1.0; - } - return Tcl_NewDoubleObj(fval); -} - -/* - *---------------------------------------------------------------------- - * WmAttrGetNotifyStatus -- + * WmAttributesCmd -- * - * Helper procedure to retrieve the -notify option for the wm - * attributes command. + * This procedure is invoked to process the "wm attributes" Tcl command. + * See the user documentation for details on what it does. * * Results: - * Returns value in unrefcounted Tcl_Obj. + * A standard Tcl result. * * Side effects: - * None. + * See the user documentation. * *---------------------------------------------------------------------- */ -static Tcl_Obj * -WmAttrGetNotifyStatus() + +static int +WmAttributesCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - return Tcl_NewBooleanObj((tkMacOSXWmAttrNotifyVal != 0)); + int attribute = 0; + WindowRef macWindow; + + if (winPtr->window == None) { + Tk_MakeWindowExist((Tk_Window) winPtr); + } + if (!TkMacOSXHostToplevelExists(winPtr)) { + TkMacOSXMakeRealWindowExist(winPtr); + } + macWindow = GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window)); + + if (objc == 3) { /* wm attributes $win */ + Tcl_Obj *result = Tcl_NewListObj(0,0); + + for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) { + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(WmAttributeNames[attribute], -1)); + Tcl_ListObjAppendElement(interp, result, + WmGetAttribute(winPtr, macWindow, attribute)); + } + Tcl_SetObjResult(interp, result); + } else if (objc == 4) { /* wm attributes $win -attribute */ + if (Tcl_GetIndexFromObj(interp, objv[3], WmAttributeNames, + "attribute", 0, &attribute) != TCL_OK) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, WmGetAttribute(winPtr, macWindow, attribute)); + } else if ((objc - 3) % 2 == 0) { /* wm attributes $win -att value... */ + int i; + + for (i = 3; i < objc; i += 2) { + if (Tcl_GetIndexFromObj(interp, objv[i], WmAttributeNames, + "attribute", 0, &attribute) != TCL_OK) { + return TCL_ERROR; + } + if (WmSetAttribute(winPtr, macWindow, interp, attribute, objv[i+1]) + != TCL_OK) { + return TCL_ERROR; + } + } + } else { + Tcl_WrongNumArgs(interp, 2, objv, "window ?-attribute ?value ...??"); + return TCL_ERROR; + } + return TCL_OK; } /* *---------------------------------------------------------------------- - * WmAttrGetNotifyStatus -- - * - * Helper procedure to set the -notify option for the wm - * attributes command. - * - * Results: - * Nothing. - * - * Side effects: - * Sets the notify status. - * - *---------------------------------------------------------------------- - */ -static void -WmAttrSetNotifyStatus(int state) -{ - static NMRec notifyRec; - - if (state) { - if (tkMacOSXWmAttrNotifyVal == 0) { - notifyRec.qType = nmType; - notifyRec.nmMark = 1; - notifyRec.nmSound = NULL; - notifyRec.nmStr = NULL; - notifyRec.nmResp = NULL; - notifyRec.nmRefCon = 0; - NMInstall(¬ifyRec); - tkMacOSXWmAttrNotifyVal = 1; - } - } else { - if (tkMacOSXWmAttrNotifyVal != 0) { - NMRemove(¬ifyRec); - tkMacOSXWmAttrNotifyVal = 0; - } - } -} -/* - *---------------------------------------------------------------------- * * WmClientCmd -- * @@ -1118,44 +1077,44 @@ WmAttrSetNotifyStatus(int state) */ static int -WmClientCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmClientCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; char *argv3; int length; if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?name?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?name?"); + return TCL_ERROR; } if (objc == 3) { - if (wmPtr->clientMachine != NULL) { - Tcl_SetResult(interp, wmPtr->clientMachine, TCL_STATIC); - } - return TCL_OK; + if (wmPtr->clientMachine != NULL) { + Tcl_SetResult(interp, wmPtr->clientMachine, TCL_STATIC); + } + return TCL_OK; } argv3 = Tcl_GetStringFromObj(objv[3], &length); if (argv3[0] == 0) { - if (wmPtr->clientMachine != NULL) { - ckfree((char *) wmPtr->clientMachine); - wmPtr->clientMachine = NULL; - } - return TCL_OK; + if (wmPtr->clientMachine != NULL) { + ckfree((char *) wmPtr->clientMachine); + wmPtr->clientMachine = NULL; + } + return TCL_OK; } if (wmPtr->clientMachine != NULL) { - ckfree((char *) wmPtr->clientMachine); + ckfree((char *) wmPtr->clientMachine); } wmPtr->clientMachine = (char *) - ckalloc((unsigned) (length + 1)); + ckalloc((unsigned) (length + 1)); strcpy(wmPtr->clientMachine, argv3); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -1175,12 +1134,12 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmColormapwindowsCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; TkWindow **cmapList; @@ -1189,64 +1148,64 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ Tcl_Obj **windowObjv; if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?"); + return TCL_ERROR; } if (objc == 3) { - Tk_MakeWindowExist((Tk_Window) winPtr); - for (i = 0; i < wmPtr->cmapCount; i++) { - if ((i == (wmPtr->cmapCount-1)) - && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) { - break; - } - Tcl_AppendElement(interp, wmPtr->cmapList[i]->pathName); - } - return TCL_OK; + Tk_MakeWindowExist((Tk_Window) winPtr); + for (i = 0; i < wmPtr->cmapCount; i++) { + if ((i == (wmPtr->cmapCount-1)) + && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) { + break; + } + Tcl_AppendElement(interp, wmPtr->cmapList[i]->pathName); + } + return TCL_OK; } if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv) - != TCL_OK) { - return TCL_ERROR; + != TCL_OK) { + return TCL_ERROR; } cmapList = (TkWindow **) ckalloc((unsigned) - ((windowObjc+1)*sizeof(TkWindow*))); + ((windowObjc+1)*sizeof(TkWindow*))); for (i = 0; i < windowObjc; i++) { - if (TkGetWindowFromObj(interp, tkwin, windowObjv[i], - (Tk_Window *) &winPtr2) != TCL_OK) - { - ckfree((char *) cmapList); - return TCL_ERROR; - } - if (winPtr2 == winPtr) { - gotToplevel = 1; - } - if (winPtr2->window == None) { - Tk_MakeWindowExist((Tk_Window) winPtr2); - } - cmapList[i] = winPtr2; + if (TkGetWindowFromObj(interp, tkwin, windowObjv[i], + (Tk_Window *) &winPtr2) != TCL_OK) + { + ckfree((char *) cmapList); + return TCL_ERROR; + } + if (winPtr2 == winPtr) { + gotToplevel = 1; + } + if (winPtr2->window == None) { + Tk_MakeWindowExist((Tk_Window) winPtr2); + } + cmapList[i] = winPtr2; } if (!gotToplevel) { - wmPtr->flags |= WM_ADDED_TOPLEVEL_COLORMAP; - cmapList[windowObjc] = winPtr; - windowObjc++; + wmPtr->flags |= WM_ADDED_TOPLEVEL_COLORMAP; + cmapList[windowObjc] = winPtr; + windowObjc++; } else { - wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP; + wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP; } wmPtr->flags |= WM_COLORMAPS_EXPLICIT; if (wmPtr->cmapList != NULL) { - ckfree((char *)wmPtr->cmapList); + ckfree((char *)wmPtr->cmapList); } wmPtr->cmapList = cmapList; wmPtr->cmapCount = windowObjc; /* * On the Macintosh all of this is just an excercise - * in compatability as we don't support colormaps. If + * in compatability as we don't support colormaps. If * we did they would be installed here. */ return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -1265,49 +1224,49 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmCommandCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmCommandCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; char *argv3; int cmdArgc; - CONST char **cmdArgv; + const char **cmdArgv; if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?value?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?value?"); + return TCL_ERROR; } if (objc == 3) { - if (wmPtr->cmdArgv != NULL) { - Tcl_SetResult(interp, - Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv), - TCL_DYNAMIC); - } - return TCL_OK; + if (wmPtr->cmdArgv != NULL) { + Tcl_SetResult(interp, + Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv), + TCL_DYNAMIC); + } + return TCL_OK; } argv3 = Tcl_GetString(objv[3]); if (argv3[0] == 0) { - if (wmPtr->cmdArgv != NULL) { - ckfree((char *) wmPtr->cmdArgv); - wmPtr->cmdArgv = NULL; - } - return TCL_OK; + if (wmPtr->cmdArgv != NULL) { + ckfree((char *) wmPtr->cmdArgv); + wmPtr->cmdArgv = NULL; + } + return TCL_OK; } if (Tcl_SplitList(interp, argv3, &cmdArgc, &cmdArgv) != TCL_OK) { - return TCL_ERROR; + return TCL_ERROR; } if (wmPtr->cmdArgv != NULL) { - ckfree((char *) wmPtr->cmdArgv); + ckfree((char *) wmPtr->cmdArgv); } wmPtr->cmdArgc = cmdArgc; wmPtr->cmdArgv = cmdArgv; return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -1326,34 +1285,33 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmDeiconifyCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window"); + return TCL_ERROR; } if (wmPtr->iconFor != NULL) { - Tcl_AppendResult(interp, "can't deiconify ", Tcl_GetString(objv[2]), - ": it is an icon for ", Tk_PathName(wmPtr->iconFor), - (char *) NULL); - return TCL_ERROR; + Tcl_AppendResult(interp, "can't deiconify ", Tcl_GetString(objv[2]), + ": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL); + return TCL_ERROR; } if (winPtr->flags & TK_EMBEDDED) { - Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName, - ": it is an embedded window", (char *) NULL); - return TCL_ERROR; + Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName, + ": it is an embedded window", NULL); + return TCL_ERROR; } TkpWmSetState(winPtr, TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -1372,42 +1330,42 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmFocusmodelCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - static CONST char *optionStrings[] = { - "active", "passive", (char *) NULL }; + static const char *optionStrings[] = { + "active", "passive", NULL }; enum options { - OPT_ACTIVE, OPT_PASSIVE }; + OPT_ACTIVE, OPT_PASSIVE }; int index; if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?"); + return TCL_ERROR; } if (objc == 3) { - Tcl_SetResult(interp, (wmPtr->hints.input ? "passive" : "active"), - TCL_STATIC); - return TCL_OK; + Tcl_SetResult(interp, (wmPtr->hints.input ? "passive" : "active"), + TCL_STATIC); + return TCL_OK; } if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, - &index) != TCL_OK) { - return TCL_ERROR; + &index) != TCL_OK) { + return TCL_ERROR; } if (index == OPT_ACTIVE) { - wmPtr->hints.input = False; + wmPtr->hints.input = False; } else { /* OPT_PASSIVE */ - wmPtr->hints.input = True; + wmPtr->hints.input = True; } return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -1426,30 +1384,30 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmFrameCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmFrameCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; Window window; char buf[TCL_INTEGER_SPACE]; if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window"); + return TCL_ERROR; } window = wmPtr->reparent; if (window == None) { - window = Tk_WindowId((Tk_Window) winPtr); + window = Tk_WindowId((Tk_Window) winPtr); } sprintf(buf, "0x%x", (unsigned int) window); Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -1468,12 +1426,12 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmGeometryCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmGeometryCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; char xSign, ySign; @@ -1481,38 +1439,38 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ char *argv3; if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?"); + return TCL_ERROR; } if (objc == 3) { - char buf[16 + TCL_INTEGER_SPACE * 4]; - - xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+'; - ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+'; - if (wmPtr->gridWin != NULL) { - width = wmPtr->reqGridWidth + (winPtr->changes.width - - winPtr->reqWidth)/wmPtr->widthInc; - height = wmPtr->reqGridHeight + (winPtr->changes.height - - winPtr->reqHeight)/wmPtr->heightInc; - } else { - width = winPtr->changes.width; - height = winPtr->changes.height; - } - sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, wmPtr->x, - ySign, wmPtr->y); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - return TCL_OK; + char buf[16 + TCL_INTEGER_SPACE * 4]; + + xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+'; + ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+'; + if (wmPtr->gridWin != NULL) { + width = wmPtr->reqGridWidth + (winPtr->changes.width + - winPtr->reqWidth)/wmPtr->widthInc; + height = wmPtr->reqGridHeight + (winPtr->changes.height + - winPtr->reqHeight)/wmPtr->heightInc; + } else { + width = winPtr->changes.width; + height = winPtr->changes.height; + } + sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, wmPtr->x, + ySign, wmPtr->y); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + return TCL_OK; } argv3 = Tcl_GetString(objv[3]); if (*argv3 == '\0') { - wmPtr->width = -1; - wmPtr->height = -1; - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; + wmPtr->width = -1; + wmPtr->height = -1; + WmUpdateGeom(wmPtr, winPtr); + return TCL_OK; } return ParseGeometry(interp, argv3, winPtr); } - + /* *---------------------------------------------------------------------- * @@ -1531,78 +1489,78 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmGridCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmGridCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; int reqWidth, reqHeight, widthInc, heightInc; if ((objc != 3) && (objc != 7)) { - Tcl_WrongNumArgs(interp, 2, objv, - "window ?baseWidth baseHeight widthInc heightInc?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, + "window ?baseWidth baseHeight widthInc heightInc?"); + return TCL_ERROR; } if (objc == 3) { - if (wmPtr->sizeHintsFlags & PBaseSize) { - char buf[TCL_INTEGER_SPACE * 4]; + if (wmPtr->sizeHintsFlags & PBaseSize) { + char buf[TCL_INTEGER_SPACE * 4]; - sprintf(buf, "%d %d %d %d", wmPtr->reqGridWidth, - wmPtr->reqGridHeight, wmPtr->widthInc, - wmPtr->heightInc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - } - return TCL_OK; + sprintf(buf, "%d %d %d %d", wmPtr->reqGridWidth, + wmPtr->reqGridHeight, wmPtr->widthInc, + wmPtr->heightInc); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + } + return TCL_OK; } if (*Tcl_GetString(objv[3]) == '\0') { - /* - * Turn off gridding and reset the width and height - * to make sense as ungridded numbers. - */ - - wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc); - if (wmPtr->width != -1) { - wmPtr->width = winPtr->reqWidth + (wmPtr->width - - wmPtr->reqGridWidth)*wmPtr->widthInc; - wmPtr->height = winPtr->reqHeight + (wmPtr->height - - wmPtr->reqGridHeight)*wmPtr->heightInc; - } - wmPtr->widthInc = 1; - wmPtr->heightInc = 1; + /* + * Turn off gridding and reset the width and height + * to make sense as ungridded numbers. + */ + + wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc); + if (wmPtr->width != -1) { + wmPtr->width = winPtr->reqWidth + (wmPtr->width + - wmPtr->reqGridWidth)*wmPtr->widthInc; + wmPtr->height = winPtr->reqHeight + (wmPtr->height + - wmPtr->reqGridHeight)*wmPtr->heightInc; + } + wmPtr->widthInc = 1; + wmPtr->heightInc = 1; } else { - if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[6], &heightInc) != TCL_OK)) { - return TCL_ERROR; - } - if (reqWidth < 0) { - Tcl_SetResult(interp, "baseWidth can't be < 0", TCL_STATIC); - return TCL_ERROR; - } - if (reqHeight < 0) { - Tcl_SetResult(interp, "baseHeight can't be < 0", TCL_STATIC); - return TCL_ERROR; - } - if (widthInc <= 0) { - Tcl_SetResult(interp, "widthInc can't be <= 0", TCL_STATIC); - return TCL_ERROR; - } - if (heightInc <= 0) { - Tcl_SetResult(interp, "heightInc can't be <= 0", TCL_STATIC); - return TCL_ERROR; - } - Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc, - heightInc); + if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[6], &heightInc) != TCL_OK)) { + return TCL_ERROR; + } + if (reqWidth < 0) { + Tcl_SetResult(interp, "baseWidth can't be < 0", TCL_STATIC); + return TCL_ERROR; + } + if (reqHeight < 0) { + Tcl_SetResult(interp, "baseHeight can't be < 0", TCL_STATIC); + return TCL_ERROR; + } + if (widthInc <= 0) { + Tcl_SetResult(interp, "widthInc can't be <= 0", TCL_STATIC); + return TCL_ERROR; + } + if (heightInc <= 0) { + Tcl_SetResult(interp, "heightInc can't be <= 0", TCL_STATIC); + return TCL_ERROR; + } + Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc, + heightInc); } wmPtr->flags |= WM_UPDATE_SIZE_HINTS; WmUpdateGeom(wmPtr, winPtr); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -1621,12 +1579,12 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmGroupCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmGroupCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; Tk_Window tkwin2; @@ -1634,38 +1592,38 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ int length; if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?"); + return TCL_ERROR; } if (objc == 3) { - if (wmPtr->hints.flags & WindowGroupHint) { - Tcl_SetResult(interp, wmPtr->leaderName, TCL_STATIC); - } - return TCL_OK; + if (wmPtr->hints.flags & WindowGroupHint) { + Tcl_SetResult(interp, wmPtr->leaderName, TCL_STATIC); + } + return TCL_OK; } argv3 = Tcl_GetStringFromObj(objv[3], &length); if (*argv3 == '\0') { - wmPtr->hints.flags &= ~WindowGroupHint; - if (wmPtr->leaderName != NULL) { - ckfree(wmPtr->leaderName); - } - wmPtr->leaderName = NULL; + wmPtr->hints.flags &= ~WindowGroupHint; + if (wmPtr->leaderName != NULL) { + ckfree(wmPtr->leaderName); + } + wmPtr->leaderName = NULL; } else { - if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) { - return TCL_ERROR; - } - Tk_MakeWindowExist(tkwin2); - if (wmPtr->leaderName != NULL) { - ckfree(wmPtr->leaderName); - } - wmPtr->hints.window_group = Tk_WindowId(tkwin2); - wmPtr->hints.flags |= WindowGroupHint; - wmPtr->leaderName = ckalloc((unsigned) (length + 1)); - strcpy(wmPtr->leaderName, argv3); + if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) { + return TCL_ERROR; + } + Tk_MakeWindowExist(tkwin2); + if (wmPtr->leaderName != NULL) { + ckfree(wmPtr->leaderName); + } + wmPtr->hints.window_group = Tk_WindowId(tkwin2); + wmPtr->hints.flags |= WindowGroupHint; + wmPtr->leaderName = ckalloc((unsigned) (length + 1)); + strcpy(wmPtr->leaderName, argv3); } return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -1684,64 +1642,39 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmIconbitmapCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; Pixmap pixmap; - const char *path; - int len = -1; - OSErr err = fnfErr; - FSRef ref; + char *str; + int len; if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?"); + return TCL_ERROR; } if (objc == 3) { - if (wmPtr->hints.flags & IconPixmapHint) { - Tcl_SetResult(interp, - (char *) Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_pixmap), - TCL_STATIC); - } - return TCL_OK; - } - path = Tcl_FSGetNativePath(objv[3]); - if (path && *path) { - Boolean d; - err = FSPathMakeRef((unsigned char*) path, &ref, &d); - } else { - Tcl_GetStringFromObj(objv[3], &len); - } - if (err == noErr || len == 0) { - WindowRef macWindow; - if (winPtr->window == None) { - Tk_MakeWindowExist((Tk_Window) winPtr); + if (wmPtr->hints.flags & IconPixmapHint) { + Tcl_SetResult(interp, (char*)Tk_NameOfBitmap(winPtr->display, + wmPtr->hints.icon_pixmap), TCL_STATIC); } - if (!TkMacOSXHostToplevelExists(winPtr)) { - TkMacOSXMakeRealWindowExist(winPtr); - } - macWindow = GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window)); - if (len) { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 - if (HIWindowSetProxyFSRef != NULL) { - err = HIWindowSetProxyFSRef(macWindow, &ref); - } else -#endif - { - AliasHandle alias; - err = FSNewAlias(NULL, &ref, &alias); - if (err == noErr) { - err = SetWindowProxyAlias(macWindow, alias); - DisposeHandle((Handle) alias); - } - } - } else { - err = RemoveWindowProxy(macWindow); + return TCL_OK; + } + str = Tcl_GetStringFromObj(objv[3], &len); + if (winPtr->window == None) { + Tk_MakeWindowExist((Tk_Window) winPtr); + } + if (!TkMacOSXHostToplevelExists(winPtr)) { + TkMacOSXMakeRealWindowExist(winPtr); + } + if (WmSetAttribute(winPtr, GetWindowFromPort(TkMacOSXGetDrawablePort( + winPtr->window)), interp, WMATT_TITLEPATH, objv[3]) == TCL_OK) { + if (!len) { if (wmPtr->hints.icon_pixmap != None) { Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap); wmPtr->hints.icon_pixmap = None; @@ -1749,18 +1682,16 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ wmPtr->hints.flags &= ~IconPixmapHint; } } else { - pixmap = Tk_GetBitmap(interp, (Tk_Window) winPtr, - Tk_GetUid(Tcl_GetStringFromObj(objv[3], NULL))); - if (pixmap == None) { - return TCL_ERROR; - } - wmPtr->hints.icon_pixmap = pixmap; - wmPtr->hints.flags |= IconPixmapHint; - } - + pixmap = Tk_GetBitmap(interp, (Tk_Window) winPtr, Tk_GetUid(str)); + if (pixmap == None) { + return TCL_ERROR; + } + wmPtr->hints.icon_pixmap = pixmap; + wmPtr->hints.flags |= IconPixmapHint; + } return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -1779,43 +1710,42 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmIconifyCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmIconifyCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window"); + return TCL_ERROR; } if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) { - Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName, - "\": override-redirect flag is set", (char *) NULL); - return TCL_ERROR; + Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName, + "\": override-redirect flag is set", NULL); + return TCL_ERROR; } if (wmPtr->master != None) { - Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName, - "\": it is a transient", (char *) NULL); - return TCL_ERROR; + Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName, + "\": it is a transient", NULL); + return TCL_ERROR; } if (wmPtr->iconFor != NULL) { - Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName, - ": it is an icon for ", Tk_PathName(wmPtr->iconFor), - (char *) NULL); - return TCL_ERROR; + Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName, + ": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL); + return TCL_ERROR; } if (winPtr->flags & TK_EMBEDDED) { - Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName, - ": it is an embedded window", (char *) NULL); - return TCL_ERROR; + Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName, + ": it is an embedded window", NULL); + return TCL_ERROR; } TkpWmSetState(winPtr, IconicState); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -1834,46 +1764,46 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmIconmaskCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmIconmaskCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; Pixmap pixmap; char *argv3; if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?"); + return TCL_ERROR; } if (objc == 3) { - if (wmPtr->hints.flags & IconMaskHint) { - Tcl_SetResult(interp, - (char *) Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask), - TCL_STATIC); - } - return TCL_OK; + if (wmPtr->hints.flags & IconMaskHint) { + Tcl_SetResult(interp, + (char*)Tk_NameOfBitmap(winPtr->display, + wmPtr->hints.icon_mask), TCL_STATIC); + } + return TCL_OK; } argv3 = Tcl_GetString(objv[3]); if (*argv3 == '\0') { - if (wmPtr->hints.icon_mask != None) { - Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask); - } - wmPtr->hints.flags &= ~IconMaskHint; + if (wmPtr->hints.icon_mask != None) { + Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask); + } + wmPtr->hints.flags &= ~IconMaskHint; } else { - pixmap = Tk_GetBitmap(interp, tkwin, argv3); - if (pixmap == None) { - return TCL_ERROR; - } - wmPtr->hints.icon_mask = pixmap; - wmPtr->hints.flags |= IconMaskHint; + pixmap = Tk_GetBitmap(interp, tkwin, argv3); + if (pixmap == None) { + return TCL_ERROR; + } + wmPtr->hints.icon_mask = pixmap; + wmPtr->hints.flags |= IconMaskHint; } return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -1892,40 +1822,40 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmIconnameCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmIconnameCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - CONST char *argv3; + const char *argv3; int length; if (objc > 4) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?"); + return TCL_ERROR; } if (objc == 3) { - Tcl_SetResult(interp, - (char *) ((wmPtr->iconName != NULL) ? wmPtr->iconName : ""), - TCL_STATIC); - return TCL_OK; + Tcl_SetResult(interp, + (char*)((wmPtr->iconName != NULL) ? + wmPtr->iconName : ""), TCL_STATIC); + return TCL_OK; } else { - if (wmPtr->iconName != NULL) { - ckfree((char *) wmPtr->iconName); - } - argv3 = Tcl_GetStringFromObj(objv[3], &length); - wmPtr->iconName = ckalloc((unsigned) (length + 1)); - strcpy(wmPtr->iconName, argv3); - if (!(wmPtr->flags & WM_NEVER_MAPPED)) { - XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName); - } + if (wmPtr->iconName != NULL) { + ckfree((char *) wmPtr->iconName); + } + argv3 = Tcl_GetStringFromObj(objv[3], &length); + wmPtr->iconName = ckalloc((unsigned) (length + 1)); + strcpy(wmPtr->iconName, argv3); + if (!(wmPtr->flags & WM_NEVER_MAPPED)) { + XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName); + } } return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -1946,12 +1876,12 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmIconphotoCmd(tkwin, winPtr, interp, objc, objv) - Tk_Window tkwin; /* Main window of the application. */ - TkWindow *winPtr; /* Toplevel to work with */ - Tcl_Interp *interp; /* Current interpreter. */ - int objc; /* Number of arguments. */ - Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmIconphotoCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_PhotoHandle photo; int i, width, height, isDefault = 0; @@ -1977,7 +1907,7 @@ WmIconphotoCmd(tkwin, winPtr, interp, objc, objv) photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i])); if (photo == NULL) { Tcl_AppendResult(interp, "can't use \"", Tcl_GetString(objv[i]), - "\" as iconphoto: not a photo image", (char *) NULL); + "\" as iconphoto: not a photo image", NULL); return TCL_ERROR; } Tk_PhotoGetSize(photo, &width, &height); @@ -1988,7 +1918,7 @@ WmIconphotoCmd(tkwin, winPtr, interp, objc, objv) */ return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2008,44 +1938,44 @@ WmIconphotoCmd(tkwin, winPtr, interp, objc, objv) */ static int -WmIconpositionCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmIconpositionCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; int x, y; if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?"); + return TCL_ERROR; } if (objc == 3) { - if (wmPtr->hints.flags & IconPositionHint) { - char buf[TCL_INTEGER_SPACE * 2]; + if (wmPtr->hints.flags & IconPositionHint) { + char buf[TCL_INTEGER_SPACE * 2]; - sprintf(buf, "%d %d", wmPtr->hints.icon_x, - wmPtr->hints.icon_y); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - } - return TCL_OK; + sprintf(buf, "%d %d", wmPtr->hints.icon_x, + wmPtr->hints.icon_y); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + } + return TCL_OK; } if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->hints.flags &= ~IconPositionHint; + wmPtr->hints.flags &= ~IconPositionHint; } else { - if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){ - return TCL_ERROR; - } - wmPtr->hints.icon_x = x; - wmPtr->hints.icon_y = y; - wmPtr->hints.flags |= IconPositionHint; + if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){ + return TCL_ERROR; + } + wmPtr->hints.icon_x = x; + wmPtr->hints.icon_y = y; + wmPtr->hints.flags |= IconPositionHint; } return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2064,71 +1994,71 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmIconwindowCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmIconwindowCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; Tk_Window tkwin2; WmInfo *wmPtr2; if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?"); + return TCL_ERROR; } if (objc == 3) { - if (wmPtr->icon != NULL) { - Tcl_SetResult(interp, Tk_PathName(wmPtr->icon), TCL_STATIC); - } - return TCL_OK; + if (wmPtr->icon != NULL) { + Tcl_SetResult(interp, Tk_PathName(wmPtr->icon), TCL_STATIC); + } + return TCL_OK; } if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->hints.flags &= ~IconWindowHint; - if (wmPtr->icon != NULL) { - wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr; - wmPtr2->iconFor = NULL; - wmPtr2->hints.initial_state = WithdrawnState; - } - wmPtr->icon = NULL; + wmPtr->hints.flags &= ~IconWindowHint; + if (wmPtr->icon != NULL) { + wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr; + wmPtr2->iconFor = NULL; + wmPtr2->hints.initial_state = WithdrawnState; + } + wmPtr->icon = NULL; } else { - if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) { - return TCL_ERROR; - } - if (!Tk_IsTopLevel(tkwin2)) { - Tcl_AppendResult(interp, "can't use ", Tcl_GetString(objv[3]), - " as icon window: not at top level", (char *) NULL); - return TCL_ERROR; - } - wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr; - if (wmPtr2->iconFor != NULL) { - Tcl_AppendResult(interp, Tcl_GetString(objv[3]), - " is already an icon for ", - Tk_PathName(wmPtr2->iconFor), (char *) NULL); - return TCL_ERROR; - } - if (wmPtr->icon != NULL) { - WmInfo *wmPtr3 = ((TkWindow *) wmPtr->icon)->wmInfoPtr; - wmPtr3->iconFor = NULL; - } - Tk_MakeWindowExist(tkwin2); - wmPtr->hints.icon_window = Tk_WindowId(tkwin2); - wmPtr->hints.flags |= IconWindowHint; - wmPtr->icon = tkwin2; - wmPtr2->iconFor = (Tk_Window) winPtr; - if (!(wmPtr2->flags & WM_NEVER_MAPPED)) { - /* - * Don't have iconwindows on the Mac. We just withdraw. - */ - - Tk_UnmapWindow(tkwin2); - } + if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) { + return TCL_ERROR; + } + if (!Tk_IsTopLevel(tkwin2)) { + Tcl_AppendResult(interp, "can't use ", Tcl_GetString(objv[3]), + " as icon window: not at top level", NULL); + return TCL_ERROR; + } + wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr; + if (wmPtr2->iconFor != NULL) { + Tcl_AppendResult(interp, Tcl_GetString(objv[3]), + " is already an icon for ", + Tk_PathName(wmPtr2->iconFor), NULL); + return TCL_ERROR; + } + if (wmPtr->icon != NULL) { + WmInfo *wmPtr3 = ((TkWindow *) wmPtr->icon)->wmInfoPtr; + wmPtr3->iconFor = NULL; + } + Tk_MakeWindowExist(tkwin2); + wmPtr->hints.icon_window = Tk_WindowId(tkwin2); + wmPtr->hints.flags |= IconWindowHint; + wmPtr->icon = tkwin2; + wmPtr2->iconFor = (Tk_Window) winPtr; + if (!(wmPtr2->flags & WM_NEVER_MAPPED)) { + /* + * Don't have iconwindows on the Mac. We just withdraw. + */ + + Tk_UnmapWindow(tkwin2); + } } return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2147,30 +2077,31 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmMaxsizeCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; int width, height; if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?"); + return TCL_ERROR; } if (objc == 3) { - char buf[TCL_INTEGER_SPACE * 2]; + char buf[TCL_INTEGER_SPACE * 2]; - sprintf(buf, "%d %d", wmPtr->maxWidth, wmPtr->maxHeight); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - return TCL_OK; + GetMaxSize(winPtr, &width, &height); + sprintf(buf, "%d %d", width, height); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + return TCL_OK; } if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) { - return TCL_ERROR; + || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) { + return TCL_ERROR; } wmPtr->maxWidth = width; wmPtr->maxHeight = height; @@ -2178,7 +2109,7 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ WmUpdateGeom(wmPtr, winPtr); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2197,30 +2128,31 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmMinsizeCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmMinsizeCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; int width, height; if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?"); + return TCL_ERROR; } if (objc == 3) { - char buf[TCL_INTEGER_SPACE * 2]; + char buf[TCL_INTEGER_SPACE * 2]; - sprintf(buf, "%d %d", wmPtr->minWidth, wmPtr->minHeight); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - return TCL_OK; + GetMinSize(winPtr, &width, &height); + sprintf(buf, "%d %d", width, height); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + return TCL_OK; } if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) { - return TCL_ERROR; + || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) { + return TCL_ERROR; } wmPtr->minWidth = width; wmPtr->minHeight = height; @@ -2228,7 +2160,7 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ WmUpdateGeom(wmPtr, winPtr); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2248,59 +2180,34 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmOverrideredirectCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - register WmInfo *wmPtr = winPtr->wmInfoPtr; int boolean; XSetWindowAttributes atts; - int oldAttributes = wmPtr->attributes; if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?"); + return TCL_ERROR; } if (objc == 3) { - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), - Tk_Attributes((Tk_Window) winPtr)->override_redirect); - return TCL_OK; + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), + Tk_Attributes((Tk_Window) winPtr)->override_redirect); + return TCL_OK; } if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) { - return TCL_ERROR; + return TCL_ERROR; } atts.override_redirect = (boolean) ? True : False; - Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect, - &atts); - /* - * FIX: We need an UpdateWrapper equivalent to make this 100% correct - */ - if (boolean) { - if (wmPtr->macClass == kDocumentWindowClass || (wmPtr->master != None && - wmPtr->macClass == kFloatingWindowClass)) { - wmPtr->macClass = kSimpleWindowClass; - wmPtr->attributes = kWindowNoAttributes; - } - wmPtr->attributes |= kWindowNoActivatesAttribute; - } else { - wmPtr->attributes &= ~kWindowNoActivatesAttribute; - if (wmPtr->macClass == kSimpleWindowClass) { - if (wmPtr->master != None) { - wmPtr->macClass = kFloatingWindowClass; // override && transient - wmPtr->attributes = kWindowStandardFloatingAttributes; - } else { - wmPtr->macClass = kDocumentWindowClass; - wmPtr->attributes = kWindowStandardDocumentAttributes; - } - } - } - ApplyWindowAttributeChanges(winPtr, wmPtr->attributes, oldAttributes, 0); + Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect, &atts); + ApplyMasterOverrideChanges(winPtr, NULL); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2320,52 +2227,52 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmPositionfromCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmPositionfromCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - static CONST char *optionStrings[] = { - "program", "user", (char *) NULL }; + static const char *optionStrings[] = { + "program", "user", NULL }; enum options { - OPT_PROGRAM, OPT_USER }; + OPT_PROGRAM, OPT_USER }; int index; if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?"); + return TCL_ERROR; } if (objc == 3) { - if (wmPtr->sizeHintsFlags & USPosition) { - Tcl_SetResult(interp, "user", TCL_STATIC); - } else if (wmPtr->sizeHintsFlags & PPosition) { - Tcl_SetResult(interp, "program", TCL_STATIC); - } - return TCL_OK; + if (wmPtr->sizeHintsFlags & USPosition) { + Tcl_SetResult(interp, "user", TCL_STATIC); + } else if (wmPtr->sizeHintsFlags & PPosition) { + Tcl_SetResult(interp, "program", TCL_STATIC); + } + return TCL_OK; } if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->sizeHintsFlags &= ~(USPosition|PPosition); + wmPtr->sizeHintsFlags &= ~(USPosition|PPosition); } else { - if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, - &index) != TCL_OK) { - return TCL_ERROR; - } - if (index == OPT_USER) { - wmPtr->sizeHintsFlags &= ~PPosition; - wmPtr->sizeHintsFlags |= USPosition; - } else { - wmPtr->sizeHintsFlags &= ~USPosition; - wmPtr->sizeHintsFlags |= PPosition; - } + if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, + &index) != TCL_OK) { + return TCL_ERROR; + } + if (index == OPT_USER) { + wmPtr->sizeHintsFlags &= ~PPosition; + wmPtr->sizeHintsFlags |= USPosition; + } else { + wmPtr->sizeHintsFlags &= ~USPosition; + wmPtr->sizeHintsFlags |= PPosition; + } } wmPtr->flags |= WM_UPDATE_SIZE_HINTS; WmUpdateGeom(wmPtr, winPtr); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2384,12 +2291,12 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmProtocolCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmProtocolCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; register ProtocolHandler *protPtr, *prevPtr; @@ -2398,33 +2305,34 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ int cmdLength; if ((objc < 3) || (objc > 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?"); + return TCL_ERROR; } if (objc == 3) { - /* - * Return a list of all defined protocols for the window. - */ - for (protPtr = wmPtr->protPtr; protPtr != NULL; - protPtr = protPtr->nextPtr) { - Tcl_AppendElement(interp, - Tk_GetAtomName((Tk_Window) winPtr, protPtr->protocol)); - } - return TCL_OK; + /* + * Return a list of all defined protocols for the window. + */ + for (protPtr = wmPtr->protPtr; protPtr != NULL; + protPtr = protPtr->nextPtr) { + Tcl_AppendElement(interp, + Tk_GetAtomName((Tk_Window) winPtr, protPtr->protocol)); + } + return TCL_OK; } protocol = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3])); if (objc == 4) { - /* - * Return the command to handle a given protocol. - */ - for (protPtr = wmPtr->protPtr; protPtr != NULL; - protPtr = protPtr->nextPtr) { - if (protPtr->protocol == protocol) { - Tcl_SetResult(interp, protPtr->command, TCL_STATIC); - return TCL_OK; - } - } - return TCL_OK; + /* + * Return the command to handle a given protocol. + */ + + for (protPtr = wmPtr->protPtr; protPtr != NULL; + protPtr = protPtr->nextPtr) { + if (protPtr->protocol == protocol) { + Tcl_SetResult(interp, protPtr->command, TCL_STATIC); + return TCL_OK; + } + } + return TCL_OK; } /* @@ -2434,29 +2342,29 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ for (protPtr = wmPtr->protPtr, prevPtr = NULL; protPtr != NULL; - prevPtr = protPtr, protPtr = protPtr->nextPtr) { - if (protPtr->protocol == protocol) { - if (prevPtr == NULL) { - wmPtr->protPtr = protPtr->nextPtr; - } else { - prevPtr->nextPtr = protPtr->nextPtr; - } - Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC); - break; - } + prevPtr = protPtr, protPtr = protPtr->nextPtr) { + if (protPtr->protocol == protocol) { + if (prevPtr == NULL) { + wmPtr->protPtr = protPtr->nextPtr; + } else { + prevPtr->nextPtr = protPtr->nextPtr; + } + Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC); + break; + } } cmd = Tcl_GetStringFromObj(objv[4], &cmdLength); if (cmdLength > 0) { - protPtr = (ProtocolHandler *) ckalloc(HANDLER_SIZE(cmdLength)); - protPtr->protocol = protocol; - protPtr->nextPtr = wmPtr->protPtr; - wmPtr->protPtr = protPtr; - protPtr->interp = interp; - strcpy(protPtr->command, cmd); + protPtr = (ProtocolHandler *) ckalloc(HANDLER_SIZE(cmdLength)); + protPtr->protocol = protocol; + protPtr->nextPtr = wmPtr->protPtr; + wmPtr->protPtr = protPtr; + protPtr->interp = interp; + strcpy(protPtr->command, cmd); } return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2475,63 +2383,64 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmResizableCmd(tkwin, winPtr, interp, objc, objv) - Tk_Window tkwin; /* Main window of the application. */ - TkWindow *winPtr; /* Toplevel to work with */ - Tcl_Interp *interp; /* Current interpreter. */ - int objc; /* Number of arguments. */ - Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmResizableCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; int width, height; - int oldAttributes = wmPtr->attributes; + WindowAttributes oldAttributes = wmPtr->attributes; if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?"); + return TCL_ERROR; } if (objc == 3) { - char buf[TCL_INTEGER_SPACE * 2]; + char buf[TCL_INTEGER_SPACE * 2]; - sprintf(buf, "%d %d", - (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1, - (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - return TCL_OK; + sprintf(buf, "%d %d", + (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1, + (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + return TCL_OK; } if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK) - || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) { - return TCL_ERROR; + || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) { + return TCL_ERROR; } if (width) { - wmPtr->flags &= ~WM_WIDTH_NOT_RESIZABLE; - wmPtr->attributes |= kWindowHorizontalZoomAttribute; + wmPtr->flags &= ~WM_WIDTH_NOT_RESIZABLE; + wmPtr->attributes |= kWindowHorizontalZoomAttribute; } else { - wmPtr->flags |= WM_WIDTH_NOT_RESIZABLE; - wmPtr->attributes &= ~kWindowHorizontalZoomAttribute; + wmPtr->flags |= WM_WIDTH_NOT_RESIZABLE; + wmPtr->attributes &= ~kWindowHorizontalZoomAttribute; } if (height) { - wmPtr->flags &= ~WM_HEIGHT_NOT_RESIZABLE; - wmPtr->attributes |= kWindowVerticalZoomAttribute; + wmPtr->flags &= ~WM_HEIGHT_NOT_RESIZABLE; + wmPtr->attributes |= kWindowVerticalZoomAttribute; } else { - wmPtr->flags |= WM_HEIGHT_NOT_RESIZABLE; - wmPtr->attributes &= ~kWindowVerticalZoomAttribute; + wmPtr->flags |= WM_HEIGHT_NOT_RESIZABLE; + wmPtr->attributes &= ~kWindowVerticalZoomAttribute; } if (width || height) { - wmPtr->attributes |= kWindowResizableAttribute; + wmPtr->attributes |= kWindowResizableAttribute; } else { - wmPtr->attributes &= ~kWindowResizableAttribute; + wmPtr->attributes &= ~kWindowResizableAttribute; } wmPtr->flags |= WM_UPDATE_SIZE_HINTS; if (wmPtr->scrollWinPtr != NULL) { - TkScrollbarEventuallyRedraw((TkScrollbar *) + TkScrollbarEventuallyRedraw((TkScrollbar *) wmPtr->scrollWinPtr->instanceData); } WmUpdateGeom(wmPtr, winPtr); - ApplyWindowAttributeChanges(winPtr, wmPtr->attributes, oldAttributes, 1); + ApplyWindowClassAttributeChanges(winPtr, NULL, wmPtr->macClass, + oldAttributes, 1); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2550,53 +2459,53 @@ WmResizableCmd(tkwin, winPtr, interp, objc, objv) */ static int -WmSizefromCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmSizefromCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - static CONST char *optionStrings[] = { - "program", "user", (char *) NULL }; + static const char *optionStrings[] = { + "program", "user", NULL }; enum options { - OPT_PROGRAM, OPT_USER }; + OPT_PROGRAM, OPT_USER }; int index; if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?"); + return TCL_ERROR; } if (objc == 3) { - if (wmPtr->sizeHintsFlags & USSize) { - Tcl_SetResult(interp, "user", TCL_STATIC); - } else if (wmPtr->sizeHintsFlags & PSize) { - Tcl_SetResult(interp, "program", TCL_STATIC); - } - return TCL_OK; + if (wmPtr->sizeHintsFlags & USSize) { + Tcl_SetResult(interp, "user", TCL_STATIC); + } else if (wmPtr->sizeHintsFlags & PSize) { + Tcl_SetResult(interp, "program", TCL_STATIC); + } + return TCL_OK; } if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->sizeHintsFlags &= ~(USSize|PSize); + wmPtr->sizeHintsFlags &= ~(USSize|PSize); } else { - if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, - &index) != TCL_OK) { - return TCL_ERROR; - } - if (index == OPT_USER) { - wmPtr->sizeHintsFlags &= ~PSize; - wmPtr->sizeHintsFlags |= USSize; - } else { /* OPT_PROGRAM */ - wmPtr->sizeHintsFlags &= ~USSize; - wmPtr->sizeHintsFlags |= PSize; - } + if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, + &index) != TCL_OK) { + return TCL_ERROR; + } + if (index == OPT_USER) { + wmPtr->sizeHintsFlags &= ~PSize; + wmPtr->sizeHintsFlags |= USSize; + } else { /* OPT_PROGRAM */ + wmPtr->sizeHintsFlags &= ~USSize; + wmPtr->sizeHintsFlags |= PSize; + } } wmPtr->flags |= WM_UPDATE_SIZE_HINTS; WmUpdateGeom(wmPtr, winPtr); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2615,105 +2524,104 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmStackorderCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmStackorderCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { TkWindow **windows, **window_ptr; - static CONST char *optionStrings[] = { - "isabove", "isbelow", (char *) NULL }; + static const char *optionStrings[] = { + "isabove", "isbelow", NULL }; enum options { - OPT_ISABOVE, OPT_ISBELOW }; + OPT_ISABOVE, OPT_ISBELOW }; int index; if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?isabove|isbelow window?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?isabove|isbelow window?"); + return TCL_ERROR; } if (objc == 3) { - windows = TkWmStackorderToplevel(winPtr); - if (windows == NULL) { - Tcl_Panic("TkWmStackorderToplevel failed"); - } else { - for (window_ptr = windows; *window_ptr ; window_ptr++) { - Tcl_AppendElement(interp, (*window_ptr)->pathName); - } - ckfree((char *) windows); - return TCL_OK; - } + windows = TkWmStackorderToplevel(winPtr); + if (windows == NULL) { + Tcl_Panic("TkWmStackorderToplevel failed"); + } else { + for (window_ptr = windows; *window_ptr ; window_ptr++) { + Tcl_AppendElement(interp, (*window_ptr)->pathName); + } + ckfree((char *) windows); + return TCL_OK; + } } else { - TkWindow *winPtr2; - int index1=-1, index2=-1, result; - - if (TkGetWindowFromObj(interp, tkwin, objv[4], (Tk_Window *) &winPtr2) - != TCL_OK) { - return TCL_ERROR; - } - - if (!Tk_IsTopLevel(winPtr2)) { - Tcl_AppendResult(interp, "window \"", winPtr2->pathName, - "\" isn't a top-level window", (char *) NULL); - return TCL_ERROR; - } - - if (!Tk_IsMapped(winPtr)) { - Tcl_AppendResult(interp, "window \"", winPtr->pathName, - "\" isn't mapped", (char *) NULL); - return TCL_ERROR; - } - - if (!Tk_IsMapped(winPtr2)) { - Tcl_AppendResult(interp, "window \"", winPtr2->pathName, - "\" isn't mapped", (char *) NULL); - return TCL_ERROR; - } - - /* - * Lookup stacking order of all toplevels that are children - * of "." and find the position of winPtr and winPtr2 - * in the stacking order. - */ - - windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr); - - if (windows == NULL) { - Tcl_AppendResult(interp, "TkWmStackorderToplevel failed", - (char *) NULL); - return TCL_ERROR; - } else { - for (window_ptr = windows; *window_ptr ; window_ptr++) { - if (*window_ptr == winPtr) - index1 = (window_ptr - windows); - if (*window_ptr == winPtr2) - index2 = (window_ptr - windows); - } - if (index1 == -1) - Tcl_Panic("winPtr window not found"); - if (index2 == -1) - Tcl_Panic("winPtr2 window not found"); - - ckfree((char *) windows); - } - - if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, - &index) != TCL_OK) { - return TCL_ERROR; - } - if (index == OPT_ISABOVE) { - result = index1 > index2; - } else { /* OPT_ISBELOW */ - result = index1 < index2; - } - Tcl_SetIntObj(Tcl_GetObjResult(interp), result); - return TCL_OK; + TkWindow *winPtr2; + int index1=-1, index2=-1, result; + + if (TkGetWindowFromObj(interp, tkwin, objv[4], (Tk_Window *) &winPtr2) + != TCL_OK) { + return TCL_ERROR; + } + + if (!Tk_IsTopLevel(winPtr2)) { + Tcl_AppendResult(interp, "window \"", winPtr2->pathName, + "\" isn't a top-level window", NULL); + return TCL_ERROR; + } + + if (!Tk_IsMapped(winPtr)) { + Tcl_AppendResult(interp, "window \"", winPtr->pathName, + "\" isn't mapped", NULL); + return TCL_ERROR; + } + + if (!Tk_IsMapped(winPtr2)) { + Tcl_AppendResult(interp, "window \"", winPtr2->pathName, + "\" isn't mapped", NULL); + return TCL_ERROR; + } + + /* + * Lookup stacking order of all toplevels that are children + * of "." and find the position of winPtr and winPtr2 + * in the stacking order. + */ + + windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr); + + if (windows == NULL) { + Tcl_AppendResult(interp, "TkWmStackorderToplevel failed", NULL); + return TCL_ERROR; + } else { + for (window_ptr = windows; *window_ptr ; window_ptr++) { + if (*window_ptr == winPtr) + index1 = (window_ptr - windows); + if (*window_ptr == winPtr2) + index2 = (window_ptr - windows); + } + if (index1 == -1) + Tcl_Panic("winPtr window not found"); + if (index2 == -1) + Tcl_Panic("winPtr2 window not found"); + + ckfree((char *) windows); + } + + if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, + &index) != TCL_OK) { + return TCL_ERROR; + } + if (index == OPT_ISABOVE) { + result = index1 > index2; + } else { /* OPT_ISBELOW */ + result = index1 < index2; + } + Tcl_SetIntObj(Tcl_GetObjResult(interp), result); + return TCL_OK; } return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2732,98 +2640,93 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmStateCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmStateCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - static CONST char *optionStrings[] = { - "normal", "iconic", "withdrawn", "zoomed", (char *) NULL }; + static const char *optionStrings[] = { + "normal", "iconic", "withdrawn", "zoomed", NULL }; enum options { - OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED }; + OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED }; int index; if ((objc < 3) || (objc > 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?state?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?state?"); + return TCL_ERROR; } if (objc == 4) { - if (wmPtr->iconFor != NULL) { - Tcl_AppendResult(interp, "can't change state of ", - Tcl_GetString(objv[2]), - ": it is an icon for ", Tk_PathName(wmPtr->iconFor), - (char *) NULL); - return TCL_ERROR; - } - if (winPtr->flags & TK_EMBEDDED) { - Tcl_AppendResult(interp, "can't change state of ", - winPtr->pathName, ": it is an embedded window", - (char *) NULL); - return TCL_ERROR; - } - - if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, - &index) != TCL_OK) { - return TCL_ERROR; - } - - if (index == OPT_NORMAL) { - TkpWmSetState(winPtr, NormalState); - /* - * This varies from 'wm deiconify' because it does not - * force the window to be raised and receive focus - */ - } else if (index == OPT_ICONIC) { - if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) { - Tcl_AppendResult(interp, "can't iconify \"", - winPtr->pathName, - "\": override-redirect flag is set", - (char *) NULL); - return TCL_ERROR; - } - if (wmPtr->master != None) { - Tcl_AppendResult(interp, "can't iconify \"", - winPtr->pathName, - "\": it is a transient", (char *) NULL); - return TCL_ERROR; - } - TkpWmSetState(winPtr, IconicState); - } else if (index == OPT_WITHDRAWN) { - TkpWmSetState(winPtr, WithdrawnState); - } else { /* OPT_ZOOMED */ - TkpWmSetState(winPtr, ZoomState); - } + if (wmPtr->iconFor != NULL) { + Tcl_AppendResult(interp, "can't change state of ", + Tcl_GetString(objv[2]), ": it is an icon for ", + Tk_PathName(wmPtr->iconFor), NULL); + return TCL_ERROR; + } + if (winPtr->flags & TK_EMBEDDED) { + Tcl_AppendResult(interp, "can't change state of ", + winPtr->pathName, ": it is an embedded window", NULL); + return TCL_ERROR; + } + + if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, + &index) != TCL_OK) { + return TCL_ERROR; + } + + if (index == OPT_NORMAL) { + TkpWmSetState(winPtr, NormalState); + /* + * This varies from 'wm deiconify' because it does not + * force the window to be raised and receive focus + */ + } else if (index == OPT_ICONIC) { + if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) { + Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName, + "\": override-redirect flag is set", NULL); + return TCL_ERROR; + } + if (wmPtr->master != None) { + Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName, + "\": it is a transient", NULL); + return TCL_ERROR; + } + TkpWmSetState(winPtr, IconicState); + } else if (index == OPT_WITHDRAWN) { + TkpWmSetState(winPtr, WithdrawnState); + } else { /* OPT_ZOOMED */ + TkpWmSetState(winPtr, ZoomState); + } } else { - if (wmPtr->iconFor != NULL) { - Tcl_SetResult(interp, "icon", TCL_STATIC); - } else { + if (wmPtr->iconFor != NULL) { + Tcl_SetResult(interp, "icon", TCL_STATIC); + } else { if (wmPtr->hints.initial_state == NormalState || wmPtr->hints.initial_state == ZoomState) { wmPtr->hints.initial_state = (TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState); } - switch (wmPtr->hints.initial_state) { - case NormalState: - Tcl_SetResult(interp, "normal", TCL_STATIC); - break; - case IconicState: - Tcl_SetResult(interp, "iconic", TCL_STATIC); - break; - case WithdrawnState: - Tcl_SetResult(interp, "withdrawn", TCL_STATIC); - break; - case ZoomState: - Tcl_SetResult(interp, "zoomed", TCL_STATIC); - break; - } - } + switch (wmPtr->hints.initial_state) { + case NormalState: + Tcl_SetResult(interp, "normal", TCL_STATIC); + break; + case IconicState: + Tcl_SetResult(interp, "iconic", TCL_STATIC); + break; + case WithdrawnState: + Tcl_SetResult(interp, "withdrawn", TCL_STATIC); + break; + case ZoomState: + Tcl_SetResult(interp, "zoomed", TCL_STATIC); + break; + } + } } return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2842,36 +2745,34 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmTitleCmd(tkwin, winPtr, interp, objc, objv) -Tk_Window tkwin; /* Main window of the application. */ -TkWindow *winPtr; /* Toplevel to work with */ -Tcl_Interp *interp; /* Current interpreter. */ -int objc; /* Number of arguments. */ -Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmTitleCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; char *argv3; int length; if (objc > 4) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?"); + return TCL_ERROR; } if (objc == 3) { - Tcl_SetResult(interp, - (char *) ((wmPtr->titleUid != NULL) ? wmPtr->titleUid : winPtr->nameUid), - TCL_STATIC); - return TCL_OK; - } else { - argv3 = Tcl_GetStringFromObj(objv[3], &length); - wmPtr->titleUid = Tk_GetUid(argv3); - if (!(wmPtr->flags & WM_NEVER_MAPPED) && !Tk_IsEmbedded(winPtr)) { - TkSetWMName(winPtr, wmPtr->titleUid); - } + Tcl_SetResult(interp, (char *)((wmPtr->titleUid != NULL) ? + wmPtr->titleUid : winPtr->nameUid), TCL_STATIC); + return TCL_OK; + } + argv3 = Tcl_GetStringFromObj(objv[3], &length); + wmPtr->titleUid = Tk_GetUid(argv3); + if (!(wmPtr->flags & WM_NEVER_MAPPED) && !Tk_IsEmbedded(winPtr)) { + TkSetWMName(winPtr, wmPtr->titleUid); } return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2890,94 +2791,73 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ */ static int -WmTransientCmd(tkwin, winPtr, interp, objc, objv) - Tk_Window tkwin; /* Main window of the application. */ - TkWindow *winPtr; /* Toplevel to work with */ - Tcl_Interp *interp; /* Current interpreter. */ - int objc; /* Number of arguments. */ - Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmTransientCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; Tk_Window master; WmInfo *wmPtr2; char *argv3; int length; - int oldAttributes = wmPtr->attributes; if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?master?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window ?master?"); + return TCL_ERROR; } if (objc == 3) { - if (wmPtr->master != None) { - Tcl_SetResult(interp, wmPtr->masterWindowName, TCL_STATIC); - } - return TCL_OK; + if (wmPtr->master != None) { + Tcl_SetResult(interp, wmPtr->masterWindowName, TCL_STATIC); + } + return TCL_OK; } if (Tcl_GetString(objv[3])[0] == '\0') { - wmPtr->master = None; - if (wmPtr->masterWindowName != NULL) { - ckfree(wmPtr->masterWindowName); - } - wmPtr->masterWindowName = NULL; - /* XXX UpdateWrapper */ - if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) { - wmPtr->macClass = kSimpleWindowClass; - wmPtr->attributes = kWindowNoActivatesAttribute; - } else { - wmPtr->macClass = kDocumentWindowClass; - wmPtr->attributes = kWindowStandardDocumentAttributes; + wmPtr->master = None; + if (wmPtr->masterWindowName != NULL) { + ckfree(wmPtr->masterWindowName); } + wmPtr->masterWindowName = NULL; } else { - if (TkGetWindowFromObj(interp, tkwin, objv[3], &master) != TCL_OK) { - return TCL_ERROR; - } - Tk_MakeWindowExist(master); - - if (wmPtr->iconFor != NULL) { - Tcl_AppendResult(interp, "can't make \"", - Tcl_GetString(objv[2]), - "\" a transient: it is an icon for ", - Tk_PathName(wmPtr->iconFor), - (char *) NULL); - return TCL_ERROR; - } - - wmPtr2 = ((TkWindow *) master)->wmInfoPtr; - - /* Under some circumstances, wmPtr2 is NULL here */ - if (wmPtr2 != NULL && wmPtr2->iconFor != NULL) { - Tcl_AppendResult(interp, "can't make \"", - Tcl_GetString(objv[3]), - "\" a master: it is an icon for ", - Tk_PathName(wmPtr2->iconFor), - (char *) NULL); - return TCL_ERROR; - } + if (TkGetWindowFromObj(interp, tkwin, objv[3], &master) != TCL_OK) { + return TCL_ERROR; + } + Tk_MakeWindowExist(master); + + if (wmPtr->iconFor != NULL) { + Tcl_AppendResult(interp, "can't make \"", Tcl_GetString(objv[2]), + "\" a transient: it is an icon for ", + Tk_PathName(wmPtr->iconFor), NULL); + return TCL_ERROR; + } + + wmPtr2 = ((TkWindow *) master)->wmInfoPtr; + + /* Under some circumstances, wmPtr2 is NULL here */ + if (wmPtr2 != NULL && wmPtr2->iconFor != NULL) { + Tcl_AppendResult(interp, "can't make \"", Tcl_GetString(objv[3]), + "\" a master: it is an icon for ", + Tk_PathName(wmPtr2->iconFor), NULL); + return TCL_ERROR; + } if ((TkWindow *) master == winPtr) { Tcl_AppendResult(interp, "can't make \"", Tk_PathName(winPtr), "\" its own master", NULL); return TCL_ERROR; } - - argv3 = Tcl_GetStringFromObj(objv[3], &length); - wmPtr->master = Tk_WindowId(master); - wmPtr->masterWindowName = ckalloc((unsigned) length+1); - strcpy(wmPtr->masterWindowName, argv3); - /* XXX UpdateWrapper */ - if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) { - wmPtr->macClass = kSimpleWindowClass; - wmPtr->attributes = kWindowNoActivatesAttribute; - } else { - wmPtr->macClass = kFloatingWindowClass; - wmPtr->attributes = kWindowStandardFloatingAttributes; - } + + argv3 = Tcl_GetStringFromObj(objv[3], &length); + wmPtr->master = Tk_WindowId(master); + wmPtr->masterWindowName = ckalloc((unsigned) length+1); + strcpy(wmPtr->masterWindowName, argv3); } - ApplyWindowAttributeChanges(winPtr, wmPtr->attributes, oldAttributes, 0); + ApplyMasterOverrideChanges(winPtr, NULL); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2996,24 +2876,23 @@ WmTransientCmd(tkwin, winPtr, interp, objc, objv) */ static int -WmWithdrawCmd(tkwin, winPtr, interp, objc, objv) - Tk_Window tkwin; /* Main window of the application. */ - TkWindow *winPtr; /* Toplevel to work with */ - Tcl_Interp *interp; /* Current interpreter. */ - int objc; /* Number of arguments. */ - Tcl_Obj *CONST objv[]; /* Argument objects. */ +WmWithdrawCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 2, objv, "window"); + return TCL_ERROR; } if (wmPtr->iconFor != NULL) { - Tcl_AppendResult(interp, "can't withdraw ", Tcl_GetString(objv[2]), - ": it is an icon for ", Tk_PathName(wmPtr->iconFor), - (char *) NULL); - return TCL_ERROR; + Tcl_AppendResult(interp, "can't withdraw ", Tcl_GetString(objv[2]), + ": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL); + return TCL_ERROR; } TkpWmSetState(winPtr, WithdrawnState); return TCL_OK; @@ -3029,10 +2908,11 @@ WmInfo *wmPtr; TkWindow *winPtr; { if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr); - wmPtr->flags |= WM_UPDATE_PENDING; + Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr); + wmPtr->flags |= WM_UPDATE_PENDING; } -} +} + /* *---------------------------------------------------------------------- * @@ -3049,7 +2929,7 @@ TkWindow *winPtr; * Side effects: * Grid-related information will be passed to the window manager, so * that the top-level window associated with tkwin will resize on - * even grid units. If some other window already controls gridding + * even grid units. If some other window already controls gridding * for the top-level window then this procedure call has no effect. * *---------------------------------------------------------------------- @@ -3057,7 +2937,7 @@ TkWindow *winPtr; void Tk_SetGrid( - Tk_Window tkwin, /* Token for window. New window mgr info + Tk_Window tkwin, /* Token for window. New window mgr info * will be posted for the top-level window * associated with this window. */ int reqWidth, /* Width (in grid units) corresponding to @@ -3073,6 +2953,7 @@ Tk_SetGrid( /* * Ensure widthInc and heightInc are greater than 0 */ + if (widthInc <= 0) { widthInc = 1; } @@ -3109,7 +2990,7 @@ Tk_SetGrid( * in pixel units and there's no easy way to translate them to * grid units since the new requested size of the top-level window in * pixels may not yet have been registered yet (it may filter up - * the hierarchy in DoWhenIdle handlers). However, if the window + * the hierarchy in DoWhenIdle handlers). However, if the window * has never been mapped yet then just leave the window size alone: * assume that it is intended to be in grid units but just happened * to have been specified before this procedure was called. @@ -3120,7 +3001,7 @@ Tk_SetGrid( wmPtr->height = -1; } - /* + /* * Set the new gridding information, and start the process of passing * all of this information to the window manager. */ @@ -3151,7 +3032,7 @@ Tk_SetGrid( * * Side effects: * If tkwin currently controls gridding for its top-level window, - * gridding is cancelled for that top-level window; if some other + * gridding is cancelled for that top-level window; if some other * window controls gridding then this procedure has no effect. * *---------------------------------------------------------------------- @@ -3216,31 +3097,29 @@ Tk_UnsetGrid( static void TopLevelEventProc( - ClientData clientData, /* Window for which event occurred. */ - XEvent *eventPtr) /* Event that just happened. */ + ClientData clientData, /* Window for which event occurred. */ + XEvent *eventPtr) /* Event that just happened. */ { TkWindow *winPtr = (TkWindow *) clientData; winPtr->wmInfoPtr->flags |= WM_VROOT_OFFSET_STALE; if (eventPtr->type == DestroyNotify) { - Tk_ErrorHandler handler; - if (!(winPtr->flags & TK_ALREADY_DEAD)) { /* * A top-level window was deleted externally (e.g., by the window - * manager). This is probably not a good thing, but cleanup as - * best we can. The error handler is needed because + * manager). This is probably not a good thing, but cleanup as + * best we can. The error handler is needed because * Tk_DestroyWindow will try to destroy the window, but of course * it's already gone. */ - - handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1, - (Tk_ErrorProc *) NULL, (ClientData) NULL); + + Tk_ErrorHandler handler = Tk_CreateErrorHandler(winPtr->display, + -1, -1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL); Tk_DestroyWindow((Tk_Window) winPtr); Tk_DeleteErrorHandler(handler); } if (wmTracing) { - printf("TopLevelEventProc: %s deleted\n", winPtr->pathName); + TkMacOSXDbgMsg("TopLevelEventProc: %s deleted", winPtr->pathName); } } else if (eventPtr->type == ReparentNotify) { Tcl_Panic("recieved unwanted reparent event"); @@ -3268,8 +3147,8 @@ TopLevelEventProc( /* ARGSUSED */ static void TopLevelReqProc( - ClientData dummy, /* Not used. */ - Tk_Window tkwin) /* Information about window. */ + ClientData dummy, /* Not used. */ + Tk_Window tkwin) /* Information about window. */ { TkWindow *winPtr = (TkWindow *) tkwin; WmInfo *wmPtr; @@ -3306,24 +3185,27 @@ TopLevelReqProc( static void UpdateGeometryInfo( - ClientData clientData) /* Pointer to the window's record. */ + ClientData clientData) /* Pointer to the window's record. */ { TkWindow *winPtr = (TkWindow *) clientData; WmInfo *wmPtr = winPtr->wmInfoPtr; - int x, y, width, height; - int min, max; + int x, y, width, height, min, max; unsigned long serial; wmPtr->flags &= ~WM_UPDATE_PENDING; + if (wmPtr->flags & WM_FULLSCREEN) { + return; + } + /* - * Compute the new size for the top-level window. See the + * Compute the new size for the top-level window. See the * user documentation for details on this, but the size * requested depends on (a) the size requested internally * by the window's widgets, (b) the size requested by the * user in a "wm geometry" command or via wm-based interactive * resizing (if any), and (c) whether or not the window is - * gridded. Don't permit sizes <= 0 because this upsets + * gridded. Don't permit sizes <= 0 because this upsets * the X server. */ @@ -3399,7 +3281,7 @@ UpdateGeometryInfo( /* * Compute the new position for the upper-left pixel of the window's - * decorative frame. This is tricky, because we need to include the + * decorative frame. This is tricky, because we need to include the * border widths supplied by a reparented parent in this calculation, * but can't use the parent's current overall size since that may * change as a result of this code. @@ -3421,7 +3303,7 @@ UpdateGeometryInfo( /* * If the window's size is going to change and the window is * supposed to not be resizable by the user, then we have to - * update the size hints. There may also be a size-hint-update + * update the size hints. There may also be a size-hint-update * request pending from somewhere else, too. */ @@ -3441,41 +3323,39 @@ UpdateGeometryInfo( * * 1. If the window is embedded and the container is also in this * process, don't actually reconfigure the window; just pass the - * desired size on to the container. Also, zero out any position + * desired size on to the container. Also, zero out any position * information, since embedded windows are not allowed to move. * 2. Sometimes the window manager will give us a different size * than we asked for (e.g. mwm has a minimum size for windows), so * base the size check on what we *asked for* last time, not what we * got. * 3. Don't move window unless a new position has been requested for - * it. This is because of "features" in some window managers (e.g. + * it. This is because of "features" in some window managers (e.g. * twm, as of 4/24/91) where they don't interpret coordinates - * according to ICCCM. Moving a window to its current location may + * according to ICCCM. Moving a window to its current location may * cause it to shift position on the screen. */ if (Tk_IsEmbedded(winPtr)) { - TkWindow *contWinPtr; + TkWindow *contWinPtr = TkpGetOtherWindow(winPtr); - contWinPtr = TkpGetOtherWindow(winPtr); - /* * NOTE: Here we should handle out of process embedding. */ - if (contWinPtr != NULL) { + if (contWinPtr != NULL) { /* * This window is embedded and the container is also in this * process, so we don't need to do anything special about the * geometry, except to make sure that the desired size is known - * by the container. Also, zero out any position information, + * by the container. Also, zero out any position information, * since embedded windows are not allowed to move. */ wmPtr->x = wmPtr->y = 0; wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y); Tk_GeometryRequest((Tk_Window) contWinPtr, width, height); - } + } return; } serial = NextRequest(winPtr->display); @@ -3483,28 +3363,29 @@ UpdateGeometryInfo( wmPtr->configWidth = width; wmPtr->configHeight = height; if (wmTracing) { - printf( - "UpdateGeometryInfo moving to %d %d, resizing to %d x %d,\n", - x, y, width, height); + TkMacOSXDbgMsg("Moving to %d %d, resizing to %d x %d", x, y, + width, height); } - Tk_MoveResizeWindow((Tk_Window) winPtr, x, y, (unsigned) width, - (unsigned) height); + wmPtr->flags |= WM_SYNC_PENDING; + XMoveResizeWindow(winPtr->display, winPtr->window, x, y, + (unsigned) width, (unsigned) height); + wmPtr->flags &= ~WM_SYNC_PENDING; } else if ((width != wmPtr->configWidth) || (height != wmPtr->configHeight)) { wmPtr->configWidth = width; wmPtr->configHeight = height; if (wmTracing) { - printf("UpdateGeometryInfo resizing to %d x %d\n", width, height); + TkMacOSXDbgMsg("Resizing to %d x %d\n", width, height); } - Tk_ResizeWindow((Tk_Window) winPtr, (unsigned) width, + wmPtr->flags |= WM_SYNC_PENDING; + XResizeWindow(winPtr->display, winPtr->window, (unsigned) width, (unsigned) height); - } else { - return; + wmPtr->flags &= ~WM_SYNC_PENDING; } } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * UpdateSizeHints -- * @@ -3518,7 +3399,7 @@ UpdateGeometryInfo( * Side effects: * Properties get changed for winPtr. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ static void @@ -3533,7 +3414,7 @@ UpdateSizeHints( } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * ParseGeometry -- * @@ -3548,13 +3429,13 @@ UpdateSizeHints( * Side effects: * The size and/or location of winPtr may change. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ static int ParseGeometry( Tcl_Interp *interp, /* Used for error reporting. */ - char *string, /* String containing new geometry. Has the + char *string, /* String containing new geometry. Has the * standard form "=wxh+x+y". */ TkWindow *winPtr) /* Pointer to top-level window whose * geometry is to be changed. */ @@ -3573,7 +3454,7 @@ ParseGeometry( } /* - * Parse the width and height, if they are present. Don't + * Parse the width and height, if they are present. Don't * actually update any of the fields of wmPtr until we've * successfully parsed the entire geometry string. */ @@ -3630,7 +3511,7 @@ ParseGeometry( /* * Assume that the geometry information came from the user, - * unless an explicit source has been specified. Otherwise + * unless an explicit source has been specified. Otherwise * most window managers assume that the size hints were * program-specified and they ignore them. */ @@ -3642,7 +3523,7 @@ ParseGeometry( } /* - * Everything was parsed OK. Update the fields of *wmPtr and + * Everything was parsed OK. Update the fields of *wmPtr and * arrange for the appropriate information to be percolated out * to the window manager at the next idle moment. */ @@ -3652,8 +3533,13 @@ ParseGeometry( if ((x != wmPtr->x) || (y != wmPtr->y) || ((flags & (WM_NEGATIVE_X|WM_NEGATIVE_Y)) != (wmPtr->flags & (WM_NEGATIVE_X|WM_NEGATIVE_Y)))) { - wmPtr->x = x; - wmPtr->y = y; + if (wmPtr->flags & WM_FULLSCREEN) { + wmPtr->configX = x; + wmPtr->configY = y; + } else { + wmPtr->x = x; + wmPtr->y = y; + } flags |= WM_MOVE_PENDING; } wmPtr->flags = flags; @@ -3664,7 +3550,7 @@ ParseGeometry( } return TCL_OK; - error: +error: Tcl_AppendResult(interp, "bad geometry specifier \"", string, "\"", NULL); return TCL_ERROR; } @@ -3680,7 +3566,7 @@ ParseGeometry( * * Results: * The locations pointed to by xPtr and yPtr are filled in with - * the root coordinates of the (0,0) point in tkwin. If a virtual + * the root coordinates of the (0,0) point in tkwin. If a virtual * root window is in effect for the window, then the coordinates * in the virtual root are returned. * @@ -3711,49 +3597,49 @@ Tk_GetRootCoords( y += winPtr->changes.y + winPtr->changes.border_width; if (winPtr->flags & TK_TOP_LEVEL) { if (!(Tk_IsEmbedded(winPtr))) { - x += winPtr->wmInfoPtr->xInParent; - y += winPtr->wmInfoPtr->yInParent; - break; + x += winPtr->wmInfoPtr->xInParent; + y += winPtr->wmInfoPtr->yInParent; + break; } else { - TkWindow *otherPtr; - - otherPtr = TkpGetOtherWindow(winPtr); + TkWindow *otherPtr = TkpGetOtherWindow(winPtr); + if (otherPtr != NULL) { /* * The container window is in the same application. * Query its coordinates. */ winPtr = otherPtr; - + /* * Remember to offset by the container window here, * since at the end of this if branch, we will * pop out to the container's parent... */ - - x += winPtr->changes.x + winPtr->changes.border_width; - y += winPtr->changes.y + winPtr->changes.border_width; - + + x += winPtr->changes.x + winPtr->changes.border_width; + y += winPtr->changes.y + winPtr->changes.border_width; + } else { Point theOffset; - + if (tkMacOSXEmbedHandler->getOffsetProc != NULL) { - /* - * We do not require that the changes.x & changes.y for - * a non-Tk master window be kept up to date. So we - * first subtract off the possibly bogus values that have - * been added on at the top of this pass through the loop, - * and then call out to the getOffsetProc to give us - * the correct offset. - */ - - x -= winPtr->changes.x + winPtr->changes.border_width; - y -= winPtr->changes.y + winPtr->changes.border_width; - - tkMacOSXEmbedHandler->getOffsetProc((Tk_Window) winPtr, &theOffset); - - x += theOffset.h; - y += theOffset.v; + /* + * We do not require that the changes.x & changes.y for + * a non-Tk master window be kept up to date. So we + * first subtract off the possibly bogus values that + * have been added on at the top of this pass through + * the loop, and then call out to the getOffsetProc to + * give us the correct offset. + */ + + x -= winPtr->changes.x + winPtr->changes.border_width; + y -= winPtr->changes.y + winPtr->changes.border_width; + + tkMacOSXEmbedHandler->getOffsetProc((Tk_Window) winPtr, + &theOffset); + + x += theOffset.h; + y += theOffset.v; } break; } @@ -3788,7 +3674,7 @@ Tk_GetRootCoords( Tk_Window Tk_CoordsToWindow( - int rootX, int rootY, /* Coordinates of point in root window. If + int rootX, int rootY, /* Coordinates of point in root window. If * a virtual-root window manager is in use, * these coordinates refer to the virtual * root, not the real root. */ @@ -3808,7 +3694,7 @@ Tk_CoordsToWindow( /* * Step 1: find the top-level window that contains the desired point. */ - + where.h = rootX; where.v = rootY; FindWindow(where, &whichWin); @@ -3819,13 +3705,13 @@ Tk_CoordsToWindow( dispPtr = TkGetDisplayList(); winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, rootChild); if (winPtr == NULL) { - return NULL; + return NULL; } /* * Step 2: work down through the hierarchy underneath this window. * At each level, scan through all the children to find the highest - * one in the stacking order that contains the point. Then repeat + * one in the stacking order that contains the point. Then repeat * the whole process on that child. */ @@ -3835,48 +3721,48 @@ Tk_CoordsToWindow( x -= winPtr->changes.x; y -= winPtr->changes.y; nextPtr = NULL; - + /* - * Container windows cannot have children. So if it is a container, + * Container windows cannot have children. So if it is a container, * look there, otherwise inspect the children. */ - + if (Tk_IsContainer(winPtr)) { childPtr = TkpGetOtherWindow(winPtr); if (childPtr != NULL) { if (Tk_IsMapped(childPtr)) { - tmpx = x - childPtr->changes.x; - tmpy = y - childPtr->changes.y; - bd = childPtr->changes.border_width; - - if ((tmpx >= -bd) && (tmpy >= -bd) - && (tmpx < (childPtr->changes.width + bd)) - && (tmpy < (childPtr->changes.height + bd))) { - nextPtr = childPtr; - } - } + tmpx = x - childPtr->changes.x; + tmpy = y - childPtr->changes.y; + bd = childPtr->changes.border_width; + + if ((tmpx >= -bd) && (tmpy >= -bd) + && (tmpx < (childPtr->changes.width + bd)) + && (tmpy < (childPtr->changes.height + bd))) { + nextPtr = childPtr; + } + } } - + /* * NOTE: Here we should handle out of process embedding. */ - + } else { for (childPtr = winPtr->childList; childPtr != NULL; childPtr = childPtr->nextPtr) { - if (!Tk_IsMapped(childPtr) || + if (!Tk_IsMapped(childPtr) || (childPtr->flags & TK_TOP_LEVEL)) { continue; - } - tmpx = x - childPtr->changes.x; - tmpy = y - childPtr->changes.y; - bd = childPtr->changes.border_width; - if ((tmpx >= -bd) && (tmpy >= -bd) - && (tmpx < (childPtr->changes.width + bd)) - && (tmpy < (childPtr->changes.height + bd))) { + } + tmpx = x - childPtr->changes.x; + tmpy = y - childPtr->changes.y; + bd = childPtr->changes.border_width; + if ((tmpx >= -bd) && (tmpy >= -bd) + && (tmpx < (childPtr->changes.width + bd)) + && (tmpy < (childPtr->changes.height + bd))) { nextPtr = childPtr; - } + } } } if (nextPtr == NULL) { @@ -3893,17 +3779,17 @@ Tk_CoordsToWindow( * Tk_TopCoordsToWindow -- * * Given a Tk Window, and coordinates of a point relative to that window - * this procedure returns the top-most child of the window (excluding - * toplevels) covering that point, if there exists such a window in this + * this procedure returns the top-most child of the window (excluding + * toplevels) covering that point, if there exists such a window in this * application. * It also sets newX, and newY to the coords of the point relative to the - * window returned. + * window returned. * * Results: * The return result is either a token for the window corresponding * to rootX and rootY, or else NULL to indicate that there is no such - * window. newX and newY are also set to the coords of the point relative - * to the returned window. + * window. newX and newY are also set to the coords of the point relative + * to the returned window. * * Side effects: * None. @@ -3916,8 +3802,8 @@ Tk_TopCoordsToWindow( Tk_Window tkwin, /* Token for a Tk Window which defines the; * coordinates for rootX & rootY */ int rootX, int rootY, /* Coordinates of a point in tkWin. */ - int *newX, int *newY) /* Coordinates of point in the upperMost child of - * tkWin containing (rootX,rootY) */ + int *newX, int *newY) /* Coordinates of point in the upperMost child + * of tkWin containing (rootX,rootY) */ { TkWindow *winPtr, *childPtr; TkWindow *nextPtr; /* Coordinates of highest child found so @@ -3933,22 +3819,20 @@ Tk_TopCoordsToWindow( children = NULL; /* - * Container windows cannot have children. So if it is a container, + * Container windows cannot have children. So if it is a container, * look there, otherwise inspect the children. */ if (Tk_IsContainer(winPtr)) { childPtr = TkpGetOtherWindow(winPtr); if (childPtr != NULL) { - if (Tk_IsMapped(childPtr) && - (x > childPtr->changes.x && - x < childPtr->changes.x + - childPtr->changes.width) && - (y > childPtr->changes.y && - y < childPtr->changes.y + - childPtr->changes.height)) { - nextPtr = childPtr; - } + if (Tk_IsMapped(childPtr) && + x > childPtr->changes.x && + x < childPtr->changes.x + childPtr->changes.width && + y > childPtr->changes.y && + y < childPtr->changes.y + childPtr->changes.height) { + nextPtr = childPtr; + } } /* @@ -3956,19 +3840,19 @@ Tk_TopCoordsToWindow( */ } else { for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { - if (!Tk_IsMapped(childPtr) || + childPtr = childPtr->nextPtr) { + if (!Tk_IsMapped(childPtr) || (childPtr->flags & TK_TOP_LEVEL)) { continue; - } - if (x < childPtr->changes.x || y < childPtr->changes.y) { + } + if (x < childPtr->changes.x || y < childPtr->changes.y) { continue; - } - if (x > childPtr->changes.x + childPtr->changes.width || - y > childPtr->changes.y + childPtr->changes.height) { + } + if (x > childPtr->changes.x + childPtr->changes.width || + y > childPtr->changes.y + childPtr->changes.height) { continue; - } - nextPtr = childPtr; + } + nextPtr = childPtr; } } if (nextPtr == NULL) { @@ -4004,7 +3888,7 @@ Tk_TopCoordsToWindow( static void UpdateVRootGeometry( WmInfo *wmPtr) /* Window manager information to be - * updated. The wmPtr->vRoot field must + * updated. The wmPtr->vRoot field must * be valid. */ { TkWindow *winPtr = wmPtr->winPtr; @@ -4037,9 +3921,9 @@ UpdateVRootGeometry( &dummy2, &wmPtr->vRootX, &wmPtr->vRootY, &wmPtr->vRootWidth, &wmPtr->vRootHeight, &bd, &dummy); if (wmTracing) { - printf("UpdateVRootGeometry: x = %d, y = %d, width = %d, ", - wmPtr->vRootX, wmPtr->vRootY, wmPtr->vRootWidth); - printf("height = %d, status = %d\n", wmPtr->vRootHeight, status); + TkMacOSXDbgMsg("x = %d, y = %d, width = %d, height = %d, status = %d", + wmPtr->vRootX, wmPtr->vRootY, wmPtr->vRootWidth, + wmPtr->vRootHeight, status); } Tk_DeleteErrorHandler(handler); if (status == 0) { @@ -4063,9 +3947,9 @@ UpdateVRootGeometry( * Results: * The values at xPtr, yPtr, widthPtr, and heightPtr are set * with the offset and dimensions of the root window corresponding - * to tkwin. If tkwin is being managed by a virtual root window + * to tkwin. If tkwin is being managed by a virtual root window * manager these values correspond to the virtual root window being - * used for tkwin; otherwise the offsets will be 0 and the + * used for tkwin; otherwise the offsets will be 0 and the * dimensions will be those of the screen. * * Side effects: @@ -4116,7 +4000,7 @@ Tk_GetVRootGeometry( * Tk_MoveToplevelWindow -- * * This procedure is called instead of Tk_MoveWindow to adjust - * the x-y location of a top-level window. It delays the actual + * the x-y location of a top-level window. It delays the actual * move to a later time and keeps window-manager information * up-to-date with the move * @@ -4165,7 +4049,8 @@ Tk_MoveToplevelWindow( } UpdateGeometryInfo((ClientData) winPtr); } -} +} + /* *---------------------------------------------------------------------- * @@ -4200,7 +4085,7 @@ TkWmRestackToplevel( wmPtr = winPtr->wmInfoPtr; /* - * Get the mac window. Make sure it exists & is mapped. + * Get the mac window. Make sure it exists & is mapped. */ if (winPtr->window == None) { Tk_MakeWindowExist((Tk_Window) winPtr); @@ -4227,7 +4112,8 @@ TkWmRestackToplevel( if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) { TkWmMapWindow(otherPtr); } - otherMacWindow = GetWindowFromPort(TkMacOSXGetDrawablePort(otherPtr->window)); + otherMacWindow = GetWindowFromPort(TkMacOSXGetDrawablePort( + otherPtr->window)); } else { otherMacWindow = NULL; } @@ -4236,12 +4122,12 @@ TkWmRestackToplevel( if (aboveBelow == Above) { if (macWindow == frontWindow) { - /* + /* * Do nothing - it's already at the top. */ } else if (otherMacWindow == frontWindow || otherMacWindow == NULL) { /* - * Raise the window to the top. If the window is visible then + * Raise the window to the top. If the window is visible then * we also make it the active window. */ @@ -4252,11 +4138,12 @@ TkWmRestackToplevel( } } else { /* - * Find the window to be above. (Front window will actually be the - * window to be behind.) Front window is NULL if no other windows. + * Find the window to be above. (Front window will actually be the + * window to be behind.) Front window is NULL if no other windows. */ + while (frontWindow != NULL && - ( tmpWindow = GetNextWindow (frontWindow) ) != otherMacWindow) { + (tmpWindow=GetNextWindow(frontWindow)) != otherMacWindow) { frontWindow = tmpWindow; } if (frontWindow != NULL) { @@ -4265,10 +4152,12 @@ TkWmRestackToplevel( } } else { /* - * Send behind. If it was in front find another window to make active. + * Send behind. If it was in front find another window to make active. */ + if (macWindow == frontWindow) { - if ( ( tmpWindow = GetNextWindow ( macWindow )) != NULL) { + tmpWindow = GetNextWindow(macWindow); + if (tmpWindow != NULL) { SelectWindow(tmpWindow); } } @@ -4283,7 +4172,7 @@ TkWmRestackToplevel( * * This procedure is called to add a given window to the * WM_COLORMAP_WINDOWS property for its top-level, if it - * isn't already there. It is invoked by the Tk code that + * isn't already there. It is invoked by the Tk code that * creates a new colormap, in order to make sure that colormap * information is propagated to the window manager by default. * @@ -4315,7 +4204,7 @@ TkWmAddToColormapWindows( for (topPtr = winPtr->parentPtr; ; topPtr = topPtr->parentPtr) { if (topPtr == NULL) { /* - * Window is being deleted. Skip the whole operation. + * Window is being deleted. Skip the whole operation. */ return; @@ -4365,7 +4254,7 @@ TkWmAddToColormapWindows( /* * On the Macintosh all of this is just an excercise - * in compatability as we don't support colormaps. If + * in compatability as we don't support colormaps. If * we did they would be installed here. */ } @@ -4376,7 +4265,7 @@ TkWmAddToColormapWindows( * TkWmRemoveFromColormapWindows -- * * This procedure is called to remove a given window from the - * WM_COLORMAP_WINDOWS property for its top-level. It is invoked + * WM_COLORMAP_WINDOWS property for its top-level. It is invoked * when windows are deleted. * * Results: @@ -4394,11 +4283,10 @@ void TkWmRemoveFromColormapWindows( TkWindow *winPtr) /* Window that may be present in * WM_COLORMAP_WINDOWS property for its - * top-level. Should not be a top-level + * top-level. Should not be a top-level * window. */ { - TkWindow *topPtr; - TkWindow **oldPtr; + TkWindow *topPtr, **oldPtr; int count, i, j; for (topPtr = winPtr->parentPtr; ; topPtr = topPtr->parentPtr) { @@ -4450,9 +4338,9 @@ TkWmRemoveFromColormapWindows( * * Results: * *xPtr and *yPtr are filled in with the (virtual) root coordinates - * of the mouse pointer for tkwin's display. If the pointer isn't + * of the mouse pointer for tkwin's display. If the pointer isn't * on tkwin's screen, then -1 values are returned for both - * coordinates. The argument tkwin must be a toplevel window. + * coordinates. The argument tkwin must be a toplevel window. * * Side effects: * None. @@ -4475,7 +4363,7 @@ TkGetPointerCoords( * InitialWindowBounds -- * * This function calculates the initial bounds for a new Mac - * toplevel window. Unless the geometry is specified by the user + * toplevel window. Unless the geometry is specified by the user * this code will auto place the windows in a cascade diagonially * across the main monitor of the Mac. * @@ -4491,28 +4379,35 @@ TkGetPointerCoords( static void InitialWindowBounds( TkWindow *winPtr, /* Window to get initial bounds for. */ + WindowRef macWindow, Rect *geometry) /* On return the initial bounds. */ { WmInfo *wmPtr = winPtr->wmInfoPtr; - static int defaultX = 5; - static int defaultY = 45; if (!(wmPtr->sizeHintsFlags & (USPosition | PPosition))) { - /* - * We will override the program & hopefully place the - * window in a "better" location. - */ - BitMap screenBits; - GetQDGlobalsScreenBits(&screenBits); - if (((screenBits.bounds.right - defaultX) < 30) || - ((screenBits.bounds.bottom - defaultY) < 30)) { - defaultX = 5; - defaultY = 45; + WindowRef parent; + + parent = GetFrontWindowOfClass(wmPtr->macClass, false); + if (parent && parent == macWindow) { + parent = GetNextWindowOfClass(parent, wmPtr->macClass, false); + } + if (parent && parent != macWindow) { + Rect bounds; + + ChkErr(RepositionWindow, macWindow, parent, + kWindowCascadeOnParentWindowScreen); + ChkErr(GetWindowBounds, macWindow, kWindowStructureRgn, &bounds); + wmPtr->x = bounds.left; + wmPtr->y = bounds.top; + } else { + static SInt16 menuBarHeight = 0; + + if (!menuBarHeight) { + ChkErr(GetThemeMenuBarHeight, &menuBarHeight); + } + wmPtr->x = 5; + wmPtr->y = menuBarHeight + 5; } - wmPtr->x = defaultX; - wmPtr->y = defaultY; - defaultX += 20; - defaultY += 20; } geometry->left = wmPtr->x; @@ -4527,7 +4422,7 @@ InitialWindowBounds( * TkMacOSXResizable -- * * This function determines if the passed in window is part of - * a toplevel window that is resizable. If the window is + * a toplevel window that is resizable. If the window is * resizable in the x, y or both directions, true is returned. * * Results: @@ -4551,7 +4446,7 @@ TkMacOSXResizable( while (winPtr->wmInfoPtr == NULL) { winPtr = winPtr->parentPtr; } - + wmPtr = winPtr->wmInfoPtr; if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) && (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) { @@ -4567,8 +4462,8 @@ TkMacOSXResizable( * TkMacOSXGrowToplevel -- * * The function is invoked when the user clicks in the grow region - * of a Tk window. The function will handle the dragging - * procedure and not return until completed. Finally, the function + * of a Tk window. The function will handle the dragging + * procedure and not return until completed. Finally, the function * may place information Tk's event queue is the window was resized. * * Results: @@ -4587,55 +4482,86 @@ TkMacOSXGrowToplevel( { Point where = start; TkDisplay *dispPtr; - Rect portRect; + Rect portRect; + CGrafPtr destPort = GetWindowPort(whichWindow); - SetPort(GetWindowPort(whichWindow)); - GlobalToLocal(&where); - GetPortBounds(GetWindowPort(whichWindow), &portRect); + QDGlobalToLocalPoint(destPort, &where); + GetPortBounds(destPort, &portRect); if (where.h > (portRect.right - 16) && where.v > (portRect.bottom - 16)) { Window window; TkWindow *winPtr; WmInfo *wmPtr; - Rect bounds; - long growResult; + int minWidth, minHeight, maxWidth, maxHeight; + Rect limits, bounds, *maxBounds; + Boolean resizeResult; window = TkMacOSXGetXWindow(whichWindow); dispPtr = TkGetDisplayList(); winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window); wmPtr = winPtr->wmInfoPtr; + maxBounds = (Rect*)(dispPtr->display->screens->ext_data); - /* TODO: handle grid size options. */ if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) && (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) { return false; } - if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) { - bounds.left = bounds.right = winPtr->changes.width; + GetMinSize(winPtr, &minWidth, &minHeight); + GetMaxSize(winPtr, &maxWidth, &maxHeight); + if (wmPtr->gridWin != NULL) { + int base = winPtr->reqWidth - (wmPtr->reqGridWidth + * wmPtr->widthInc); + if (base < 0) { + base = 0; + } + limits.left = base + (minWidth * wmPtr->widthInc); + limits.right = base + (maxWidth * wmPtr->widthInc); + base = winPtr->reqHeight - (wmPtr->reqGridHeight + * wmPtr->heightInc); + if (base < 0) { + base = 0; + } + limits.top = base + (minHeight * wmPtr->heightInc); + limits.bottom = base + (maxHeight * wmPtr->heightInc); } else { - bounds.left = (wmPtr->minWidth < 64) ? 64 : wmPtr->minWidth; - bounds.right = (wmPtr->maxWidth < 64) ? 64 : wmPtr->maxWidth; + limits.left = minWidth; + limits.right = maxWidth; + limits.top = minHeight; + limits.bottom = maxHeight; + } + if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) { + limits.left = limits.right = winPtr->changes.width; } if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) { - bounds.top = bounds.bottom = winPtr->changes.height; - } else { - bounds.top = (wmPtr->minHeight < 64) ? 64 : wmPtr->minHeight; - bounds.bottom = (wmPtr->maxHeight < 64) ? 64 : wmPtr->maxHeight; + limits.top = limits.bottom = winPtr->changes.height; } - - growResult = GrowWindow(whichWindow, start, &bounds); - - if (growResult != 0) { - SizeWindow(whichWindow, - LoWord(growResult), HiWord(growResult), true); - InvalWindowRect(whichWindow, &portRect); /* TODO: may not be needed */ - TkMacOSXInvalClipRgns((Tk_Window) winPtr); - TkGenWMConfigureEvent((Tk_Window) winPtr, -1, -1, - (int) LoWord(growResult), (int) HiWord(growResult), - TK_SIZE_CHANGED); + if (PtInRect(start, maxBounds)) { + Rect strBounds, strWidths, limitBounds; + + ChkErr(GetWindowBounds, whichWindow, kWindowStructureRgn, + &strBounds); + ChkErr(GetWindowStructureWidths, whichWindow, &strWidths); + + limitBounds.left = limits.left + (strBounds.left + strWidths.left); + limitBounds.right = limits.right + + (strBounds.left + strWidths.left + strWidths.right); + limitBounds.top = limits.top + (strBounds.top + strWidths.top); + limitBounds.bottom = limits.bottom + + (strBounds.top + strWidths.top + strWidths.bottom); + SectRect(&limitBounds, maxBounds, &limitBounds); + limits.left = limitBounds.left - (strBounds.left + strWidths.left); + limits.right = limitBounds.right - + (strBounds.left + strWidths.left + strWidths.right); + limits.top = limitBounds.top - (strBounds.top + strWidths.top); + limits.bottom = limitBounds.bottom - + (strBounds.top + strWidths.top + strWidths.bottom); + } + TkMacOSXTrackingLoop(1); + resizeResult = ResizeWindow(whichWindow, start, &limits, &bounds); + TkMacOSXTrackingLoop(0); + if (resizeResult) { return true; } - return false; } return false; } @@ -4645,7 +4571,7 @@ TkMacOSXGrowToplevel( * * TkSetWMName -- * - * Set the title for a toplevel window. If the window is embedded, + * Set the title for a toplevel window. If the window is embedded, * do not change the window title. * * Results: @@ -4662,33 +4588,33 @@ TkSetWMName( TkWindow *winPtr, Tk_Uid titleUid) { - CFStringRef title; - WindowRef macWin; - + CFStringRef title; + if (Tk_IsEmbedded(winPtr)) { - return; + return; } - - title = CFStringCreateWithBytes(NULL, (unsigned char*) titleUid, - strlen(titleUid), kCFStringEncodingUTF8, false); + + title = CFStringCreateWithBytes(NULL, (const unsigned char*) titleUid, + strlen(titleUid), kCFStringEncodingUTF8, false); if (title) { - macWin = GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window)); + WindowRef macWin = GetWindowFromPort( + TkMacOSXGetDrawablePort(winPtr->window)); + SetWindowTitleWithCFString(macWin, title); CFRelease(title); } } - /* *---------------------------------------------------------------------- * * TkGetTransientMaster -- * * If the passed window has the TRANSIENT_FOR property set this - * will return the master window. Otherwise it will return None. + * will return the master window. Otherwise it will return None. * * Results: - * The master window or None. + * The master window or None. * * Side effects: * None. @@ -4714,7 +4640,7 @@ TkGetTransientMaster( * Returns the X window Id associated with the given WindowRef. * * Results: - * The window id is returned. None is returned if not a Tk window. + * The window id is returned. None is returned if not a Tk window. * * Side effects: * None. @@ -4762,21 +4688,23 @@ TkMacOSXIsWindowZoomed( TkWindow *winPtr) { WmInfo *wmPtr = winPtr->wmInfoPtr; + int maxWidth, maxHeight; Point idealSize; - + if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) && (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) { return false; } + GetMaxSize(winPtr, &maxWidth, &maxHeight); if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) { idealSize.h = winPtr->changes.width; } else { - idealSize.h = wmPtr->maxWidth; + idealSize.h = maxWidth; } if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) { idealSize.v = winPtr->changes.height; } else { - idealSize.v = wmPtr->maxHeight; + idealSize.v = maxHeight; } return IsWindowInStandardState( @@ -4813,53 +4741,45 @@ TkMacOSXZoomToplevel( TkDisplay *dispPtr; TkWindow *winPtr; WmInfo *wmPtr; - Point location = {0, 0}, idealSize; + Point idealSize; + int maxWidth, maxHeight; Rect portRect; - int xOffset, yOffset; - OSStatus status; + OSStatus err; + CGrafPtr destPort = GetWindowPort(whichWindow); window = TkMacOSXGetXWindow(whichWindow); dispPtr = TkGetDisplayList(); winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window); wmPtr = winPtr->wmInfoPtr; - + if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) && (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) { return false; } + GetMaxSize(winPtr, &maxWidth, &maxHeight); if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) { idealSize.h = winPtr->changes.width; } else { - idealSize.h = wmPtr->maxWidth; + idealSize.h = maxWidth; } if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) { idealSize.v = winPtr->changes.height; } else { - idealSize.v = wmPtr->maxHeight; + idealSize.v = maxHeight; } /* Do nothing if already in desired zoom state */ - if (!IsWindowInStandardState(whichWindow, &idealSize, NULL) == + if (!IsWindowInStandardState(whichWindow, &idealSize, NULL) == (zoomPart == inZoomIn)) { return false; } - SetPort(GetWindowPort(whichWindow)); - GetPortBounds(GetWindowPort(whichWindow), &portRect); - status = ZoomWindowIdeal(whichWindow, zoomPart, &idealSize); - if (status == noErr) { + GetPortBounds(destPort, &portRect); + err = ChkErr(ZoomWindowIdeal, whichWindow, zoomPart, &idealSize); + if (err == noErr) { wmPtr->hints.initial_state = (zoomPart == inZoomIn ? NormalState : ZoomState); InvalWindowRect(whichWindow, &portRect); - TkMacOSXInvalClipRgns((Tk_Window) winPtr); - LocalToGlobal(&location); - TkMacOSXWindowOffset(whichWindow, &xOffset, &yOffset); - location.h -= xOffset; - location.v -= yOffset; - GetPortBounds(GetWindowPort(whichWindow), &portRect); - TkGenWMConfigureEvent((Tk_Window) winPtr, location.h, location.v, - portRect.right - portRect.left, portRect.bottom - portRect.top, - TK_BOTH_CHANGED); return true; } else { return false; @@ -4871,7 +4791,7 @@ TkMacOSXZoomToplevel( * * TkUnsupported1Cmd -- * - * This procedure is invoked to process the + * This procedure is invoked to process the * "::tk::unsupported::MacWindowStyle" Tcl command. * This command allows you to set the style of decoration * for a Macintosh window. @@ -4892,9 +4812,9 @@ TkUnsupported1ObjCmd( * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj * CONST objv[]) /* Argument objects. */ + Tcl_Obj * const objv[]) /* Argument objects. */ { - static CONST char *subcmds[] = { + static const char *subcmds[] = { "style", NULL }; enum SubCmds { @@ -4917,7 +4837,7 @@ TkUnsupported1ObjCmd( if (!(winPtr->flags & TK_TOP_LEVEL)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "window \"", winPtr->pathName, - "\" isn't a top-level window", (char *) NULL); + "\" isn't a top-level window", NULL); return TCL_ERROR; } @@ -4941,7 +4861,7 @@ TkUnsupported1ObjCmd( * * WmWinStyle -- * - * This procedure is invoked to process the + * This procedure is invoked to process the * "::tk::unsupported::MacWindowStyle style" subcommand. * This command allows you to set the style of decoration * for a Macintosh window. @@ -4959,83 +4879,82 @@ WmWinStyle( Tcl_Interp *interp, /* Current interpreter. */ TkWindow *winPtr, /* Window to be manipulated. */ int objc, /* Number of arguments. */ - Tcl_Obj * CONST objv[]) /* Argument objects. */ + Tcl_Obj * const objv[]) /* Argument objects. */ { struct StrIntMap { - char *strValue; - int intValue; + const char *strValue; + UInt32 intValue; }; - static CONST struct StrIntMap styleMap[] = { - { "documentProc", documentProc }, - { "noGrowDocProc", documentProc }, - { "dBoxProc", dBoxProc }, - { "plainDBox", plainDBox }, - { "altDBoxProc", altDBoxProc }, - { "movableDBoxProc", movableDBoxProc }, - { "zoomDocProc", zoomDocProc }, - { "zoomNoGrow", zoomNoGrow }, - { "floatProc", floatGrowProc }, - { "floatGrowProc", floatGrowProc }, - { "floatZoomProc", floatZoomGrowProc }, - { "floatZoomGrowProc", floatZoomGrowProc }, - { "floatSideProc", floatSideGrowProc }, - { "floatSideGrowProc", floatSideGrowProc }, - { "floatSideZoomProc", floatSideZoomGrowProc }, - { "floatSideZoomGrowProc", floatSideZoomGrowProc }, - { NULL, 0 } + static const struct StrIntMap styleMap[] = { + { "documentProc", documentProc }, + { "noGrowDocProc", documentProc }, + { "dBoxProc", dBoxProc }, + { "plainDBox", plainDBox }, + { "altDBoxProc", altDBoxProc }, + { "movableDBoxProc", movableDBoxProc }, + { "zoomDocProc", zoomDocProc }, + { "zoomNoGrow", zoomNoGrow }, + { "floatProc", floatGrowProc }, + { "floatGrowProc", floatGrowProc }, + { "floatZoomProc", floatZoomGrowProc }, + { "floatZoomGrowProc", floatZoomGrowProc }, + { "floatSideProc", floatSideGrowProc }, + { "floatSideGrowProc", floatSideGrowProc }, + { "floatSideZoomProc", floatSideZoomGrowProc }, + { "floatSideZoomGrowProc", floatSideZoomGrowProc }, + { NULL, 0 } }; - static CONST struct StrIntMap classMap[] = { - { "alert", kAlertWindowClass }, - { "moveableAlert", kMovableAlertWindowClass }, - { "modal", kModalWindowClass }, - { "moveableModal", kMovableModalWindowClass }, - { "floating", kFloatingWindowClass }, - { "document", kDocumentWindowClass }, - { "utility", kUtilityWindowClass }, - { "help", kHelpWindowClass }, - { "sheet", kSheetWindowClass }, - { "toolbar", kToolbarWindowClass }, - { "plain", kPlainWindowClass }, - { "overlay", kOverlayWindowClass }, - { "sheetAlert", kSheetAlertWindowClass }, - { "altPlain", kAltPlainWindowClass }, - { "simple", kSimpleWindowClass }, - { "drawer", kDrawerWindowClass }, - { NULL, 0 } + static const struct StrIntMap classMap[] = { + { "alert", kAlertWindowClass }, + { "moveableAlert", kMovableAlertWindowClass }, + { "modal", kModalWindowClass }, + { "moveableModal", kMovableModalWindowClass }, + { "floating", kFloatingWindowClass }, + { "document", kDocumentWindowClass }, + { "utility", kUtilityWindowClass }, + { "help", kHelpWindowClass }, + { "sheet", kSheetWindowClass }, + { "toolbar", kToolbarWindowClass }, + { "plain", kPlainWindowClass }, + { "overlay", kOverlayWindowClass }, + { "sheetAlert", kSheetAlertWindowClass }, + { "altPlain", kAltPlainWindowClass }, + { "simple", kSimpleWindowClass }, + { "drawer", kDrawerWindowClass }, + { NULL, 0 } }; - static CONST struct StrIntMap compositeAttrMap[] = { - { "none", kWindowNoAttributes }, - { "standardDocument", kWindowStandardDocumentAttributes }, - { "standardFloating", kWindowStandardFloatingAttributes }, - { NULL, 0 } + static const struct StrIntMap compositeAttrMap[] = { + { "none", kWindowNoAttributes }, + { "standardDocument", kWindowStandardDocumentAttributes }, + { "standardFloating", kWindowStandardFloatingAttributes }, + { "fullZoom", kWindowFullZoomAttribute }, + { NULL, 0 } }; - static CONST struct StrIntMap attrMap[] = { - { "closeBox", kWindowCloseBoxAttribute }, - { "horizontalZoom", kWindowHorizontalZoomAttribute }, - { "verticalZoom", kWindowVerticalZoomAttribute }, - { "fullZoom", kWindowFullZoomAttribute }, - { "collapseBox", kWindowCollapseBoxAttribute }, - { "resizable", kWindowResizableAttribute }, - { "sideTitlebar", kWindowSideTitlebarAttribute }, - { "toolbarButton", kWindowToolbarButtonAttribute }, - { "metal", kWindowMetalAttribute }, - { "noTitleBar", kWindowNoTitleBarAttribute }, + static const struct StrIntMap attrMap[] = { + { "closeBox", kWindowCloseBoxAttribute }, + { "horizontalZoom", kWindowHorizontalZoomAttribute }, + { "verticalZoom", kWindowVerticalZoomAttribute }, + { "collapseBox", kWindowCollapseBoxAttribute }, + { "resizable", kWindowResizableAttribute }, + { "sideTitlebar", kWindowSideTitlebarAttribute }, + { "toolbarButton", kWindowToolbarButtonAttribute }, + { "unifiedTitleAndToolbar", kWindowUnifiedTitleAndToolbarAttribute }, + { "metal", kWindowMetalAttribute }, + { "noTitleBar", kWindowNoTitleBarAttribute }, + { "texturedSquareCorners", kWindowTexturedSquareCornersAttribute }, { "metalNoContentSeparator", kWindowMetalNoContentSeparatorAttribute }, - { "doesNotCycle", kWindowDoesNotCycleAttribute }, - { "noUpdates", kWindowNoUpdatesAttribute }, - { "noActivates", kWindowNoActivatesAttribute }, - { "opaqueForEvents", kWindowOpaqueForEventsAttribute }, - { "compositing", kWindowCompositingAttribute }, - { "noShadow", kWindowNoShadowAttribute }, - { "hideOnSuspend", kWindowHideOnSuspendAttribute }, - { "standardHandler", kWindowStandardHandlerAttribute }, - { "hideOnFullScreen", kWindowHideOnFullScreenAttribute }, - { "inWindowMenu", kWindowInWindowMenuAttribute }, - { "ignoreClicks", kWindowIgnoreClicksAttribute }, - { "noConstrain", kWindowNoConstrainAttribute }, - { "standardDocument", kWindowStandardDocumentAttributes }, - { "standardFloating", kWindowStandardFloatingAttributes }, - { NULL, 0 } + { "doesNotCycle", kWindowDoesNotCycleAttribute }, + { "noUpdates", kWindowNoUpdatesAttribute }, + { "noActivates", kWindowNoActivatesAttribute }, + { "opaqueForEvents", kWindowOpaqueForEventsAttribute }, + { "noShadow", kWindowNoShadowAttribute }, + { "hideOnSuspend", kWindowHideOnSuspendAttribute }, + { "hideOnFullScreen", kWindowHideOnFullScreenAttribute }, + { "inWindowMenu", kWindowInWindowMenuAttribute }, + { "liveResize", kWindowLiveResizeAttribute }, + { "ignoreClicks", kWindowIgnoreClicksAttribute }, + { "noConstrain", kWindowNoConstrainAttribute }, + { NULL, 0 } }; int index, i; WmInfo *wmPtr = winPtr->wmInfoPtr; @@ -5043,8 +4962,8 @@ WmWinStyle( if (objc == 3) { if (wmPtr->style != -1) { for (i = 0; styleMap[i].strValue != NULL; i++) { - if (wmPtr->style == styleMap[i].intValue) { - Tcl_SetObjResult(interp, + if (wmPtr->style == (short)(styleMap[i].intValue)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj(styleMap[i].strValue, -1)); return TCL_OK; } @@ -5052,7 +4971,7 @@ WmWinStyle( Tcl_Panic("invalid style"); } else { Tcl_Obj *attributeList, *newResult = NULL; - int usesComposite; + WindowAttributes attributes; for (i = 0; classMap[i].strValue != NULL; i++) { if (wmPtr->macClass == classMap[i].intValue) { @@ -5065,22 +4984,23 @@ WmWinStyle( } attributeList = Tcl_NewListObj(0, NULL); - usesComposite = 0; + attributes = wmPtr->attributes; for (i = 0; compositeAttrMap[i].strValue != NULL; i++) { - if (wmPtr->attributes == compositeAttrMap[i].intValue) { + UInt32 intValue = compositeAttrMap[i].intValue; + + if (intValue && (attributes & intValue) == intValue) { Tcl_ListObjAppendElement(interp, attributeList, - Tcl_NewStringObj(compositeAttrMap[i].strValue, -1)); - usesComposite = 1; + Tcl_NewStringObj(compositeAttrMap[i].strValue, + -1)); + attributes &= ~intValue; break; } } - if (!usesComposite) { - for (i = 0; attrMap[i].strValue != NULL; i++) { - if (wmPtr->attributes & attrMap[i].intValue) { - Tcl_ListObjAppendElement(interp, attributeList, - Tcl_NewStringObj(attrMap[i].strValue, -1)); - } + for (i = 0; attrMap[i].strValue != NULL; i++) { + if (attributes & attrMap[i].intValue) { + Tcl_ListObjAppendElement(interp, attributeList, + Tcl_NewStringObj(attrMap[i].strValue, -1)); } } Tcl_ListObjAppendElement(interp, newResult, attributeList); @@ -5088,47 +5008,53 @@ WmWinStyle( } } else if (objc == 4) { if (Tcl_GetIndexFromObjStruct(interp, objv[3], styleMap, - sizeof(struct StrIntMap), "style", 0, &index) != TCL_OK) { + sizeof(struct StrIntMap), "style", 0, &index) != TCL_OK) { return TCL_ERROR; } wmPtr->style = styleMap[index].intValue; } else if (objc == 5) { int attrObjc; Tcl_Obj **attrObjv = NULL; - int oldClass = wmPtr->macClass; - int oldAttributes = wmPtr->attributes; + WindowClass oldClass = wmPtr->macClass; + WindowAttributes oldAttributes = wmPtr->attributes; if (Tcl_GetIndexFromObjStruct(interp, objv[3], classMap, - sizeof(struct StrIntMap), "class", 0, &index) != TCL_OK) { - return TCL_ERROR; + sizeof(struct StrIntMap), "class", 0, &index) != TCL_OK) { + goto badClassAttrs; + } + wmPtr->macClass = classMap[index].intValue; + if (!IsValidWindowClass(wmPtr->macClass)) { + goto badClassAttrs; } if (Tcl_ListObjGetElements(interp, objv[4], &attrObjc, &attrObjv) != TCL_OK) { - return TCL_ERROR; + goto badClassAttrs; } - wmPtr->macClass = classMap[index].intValue; wmPtr->attributes = kWindowNoAttributes; for (i = 0; i < attrObjc; i++) { if (Tcl_GetIndexFromObjStruct(interp, attrObjv[i], - compositeAttrMap, sizeof(struct StrIntMap), - "attribute", 0, &index) == TCL_OK) { + compositeAttrMap, sizeof(struct StrIntMap), + "attribute", 0, &index) == TCL_OK) { wmPtr->attributes |= compositeAttrMap[index].intValue; } else if (Tcl_GetIndexFromObjStruct(interp, attrObjv[i], - attrMap, sizeof(struct StrIntMap), - "attribute", 0, &index) == TCL_OK) { - Tcl_ResetResult (interp); + attrMap, sizeof(struct StrIntMap), + "attribute", 0, &index) == TCL_OK) { + Tcl_ResetResult(interp); wmPtr->attributes |= attrMap[index].intValue; } else { - wmPtr->macClass = oldClass; - wmPtr->attributes = oldAttributes; - return TCL_ERROR; + goto badClassAttrs; } } - ApplyWindowAttributeChanges(winPtr, wmPtr->attributes, - oldAttributes, 0); + ApplyWindowClassAttributeChanges(winPtr, NULL, oldClass, oldAttributes, + 0); wmPtr->style = -1; - } + return TCL_OK; + badClassAttrs: + wmPtr->macClass = oldClass; + wmPtr->attributes = oldAttributes; + return TCL_ERROR; + } return TCL_OK; } @@ -5137,7 +5063,7 @@ WmWinStyle( * * TkpMakeMenuWindow -- * - * Configure the window to be either a undecorated pull-down + * Configure the window to be either a undecorated pull-down * (or pop-up) menu, or as a toplevel floating menu (palette). * * Results: @@ -5153,18 +5079,20 @@ void TkpMakeMenuWindow( Tk_Window tkwin, /* New window. */ int transient) /* 1 means menu is only posted briefly as - * a popup or pulldown or cascade. 0 means - * menu is always visible, e.g. as a + * a popup or pulldown or cascade. 0 means + * menu is always visible, e.g. as a * floating menu. */ { + TkWindow *winPtr = (TkWindow *) tkwin; + if (transient) { - ((TkWindow *) tkwin)->wmInfoPtr->macClass = kSimpleWindowClass; - ((TkWindow *) tkwin)->wmInfoPtr->attributes = kWindowNoActivatesAttribute; + winPtr->wmInfoPtr->macClass = kSimpleWindowClass; + winPtr->wmInfoPtr->attributes = kWindowNoActivatesAttribute; } else { - ((TkWindow *) tkwin)->wmInfoPtr->macClass = kFloatingWindowClass; - ((TkWindow *) tkwin)->wmInfoPtr->attributes = kWindowStandardFloatingAttributes; - ((TkWindow *) tkwin)->wmInfoPtr->flags |= WM_WIDTH_NOT_RESIZABLE; - ((TkWindow *) tkwin)->wmInfoPtr->flags |= WM_HEIGHT_NOT_RESIZABLE; + winPtr->wmInfoPtr->macClass = kFloatingWindowClass; + winPtr->wmInfoPtr->attributes = kWindowStandardFloatingAttributes; + winPtr->wmInfoPtr->flags |= WM_WIDTH_NOT_RESIZABLE; + winPtr->wmInfoPtr->flags |= WM_HEIGHT_NOT_RESIZABLE; } } @@ -5187,16 +5115,16 @@ TkpMakeMenuWindow( void TkMacOSXMakeRealWindowExist( - TkWindow *winPtr) /* Tk window. */ + TkWindow *winPtr) /* Tk window. */ { WmInfo *wmPtr = winPtr->wmInfoPtr; - WindowRef newWindow = NULL; + WindowRef newWindow = NULL; ControlRef rootControl = NULL; MacDrawable *macWin; - Rect geometry = {0,0,0,0}; - Tcl_HashEntry *valueHashPtr; - int new; + Rect initialBounds = {42, 0, 43, 1}, geometry, strWidths; + short structureW, structureH; TkMacOSXWindowList *listPtr; + OSStatus err; if (TkMacOSXHostToplevelExists(winPtr)) { return; @@ -5206,64 +5134,88 @@ TkMacOSXMakeRealWindowExist( /* * If this is embedded, make sure its container's toplevel exists, - * then return... + * then return... */ if (Tk_IsEmbedded(winPtr)) { - TkWindow *contWinPtr; + TkWindow *contWinPtr = TkpGetOtherWindow(winPtr); - contWinPtr = TkpGetOtherWindow(winPtr); if (contWinPtr != NULL) { - TkMacOSXMakeRealWindowExist(contWinPtr->privatePtr->toplevel->winPtr); + TkMacOSXMakeRealWindowExist( + contWinPtr->privatePtr->toplevel->winPtr); macWin->flags |= TK_HOST_EXISTS; return; - } else if (tkMacOSXEmbedHandler != NULL) { - if (tkMacOSXEmbedHandler->containerExistProc != NULL) { - if (tkMacOSXEmbedHandler->containerExistProc((Tk_Window) winPtr) != TCL_OK) { - Tcl_Panic("ContainerExistProc could not make container"); - } - } - return; - } else { + } + + if (tkMacOSXEmbedHandler == NULL) { Tcl_Panic("TkMacOSXMakeRealWindowExist could not find container"); } + if (tkMacOSXEmbedHandler->containerExistProc && + tkMacOSXEmbedHandler->containerExistProc((Tk_Window) winPtr) != + TCL_OK) { + Tcl_Panic("ContainerExistProc could not make container"); + } + return; /* * NOTE: Here we should handle out of process embedding. */ - } - InitialWindowBounds(winPtr, &geometry); - if (wmPtr->style == -1) { - OSStatus err; - /* - * There seems to be a bug in CreateNewWindow: If I set the - * window geometry to be the too small for the structure region, - * then the whole window is positioned incorrectly. - * Adding this here makes the positioning work, and the size will - * get overwritten when you actually map the contents of the window. - */ - - geometry.right += 64; - geometry.bottom += 24; - err = CreateNewWindow(wmPtr->macClass, wmPtr->attributes, - &geometry, &newWindow); + if (!IsValidWindowClass(wmPtr->macClass)) { + TkMacOSXDbgMsg("Invalid window class: %ld", wmPtr->macClass); + wmPtr->macClass = kPlainWindowClass; + } + wmPtr->attributes = (wmPtr->attributes | kWindowAsyncDragAttribute) & + GetAvailableWindowAttributes(wmPtr->macClass); + err = ChkErr(CreateNewWindow, wmPtr->macClass, wmPtr->attributes, + &initialBounds, &newWindow); if (err != noErr) { newWindow = NULL; } - } else { - newWindow = NewCWindow(NULL, &geometry, "\p", false, - (short) wmPtr->style, (WindowRef) -1, true, 0); + TkMacOSXDbgMsg("Window creation via NewCWindow API is deprecated, " + "use a window class instead of style %d", wmPtr->style); + newWindow = NewCWindow(NULL, &initialBounds, "\p", false, + wmPtr->style, (WindowRef) -1, true, 0); } if (newWindow == NULL) { Tcl_Panic("couldn't allocate new Mac window"); } - if (CreateRootControl(newWindow,&rootControl) != noErr ) { - Tcl_Panic("couldn't create root control for new Mac window"); + + ChkErr(GetWindowStructureWidths, newWindow, &strWidths); + if (wmPtr->macClass == kFloatingWindowClass) { + /* + * Workaround GetWindowStructureWidths() Carbon bug: + */ + + strWidths.top = 16; + } + wmPtr->xInParent = strWidths.left; + wmPtr->yInParent = strWidths.top; + structureW = strWidths.left + strWidths.right; + structureH = strWidths.top + strWidths.bottom; + wmPtr->parentWidth = winPtr->changes.width + structureW; + wmPtr->parentHeight = winPtr->changes.height + structureH; + InitialWindowBounds(winPtr, newWindow, &geometry); + geometry.right += structureW; + geometry.bottom += structureH; + ChkErr(SetWindowBounds, newWindow, kWindowStructureRgn, &geometry); + + TkMacOSXInstallWindowCarbonEventHandler(NULL, newWindow); + if (ChkErr(CreateRootControl, newWindow, &rootControl) != noErr ) { + Tcl_Panic("couldn't create root control for new Mac window"); + } + if (wmPtr->attributes & kWindowResizableAttribute) { + HIViewRef growBoxView; + + err = ChkErr(HIViewFindByID, HIViewGetRoot(newWindow), + kHIViewWindowGrowBoxID, &growBoxView); + if (err == noErr && !HIGrowBoxViewIsTransparent(growBoxView)) { + ChkErr(HIGrowBoxViewSetTransparent, growBoxView, true); + } } /* @@ -5277,33 +5229,22 @@ TkMacOSXMakeRealWindowExist( macWin->grafPtr = GetWindowPort(newWindow); macWin->rootControl = rootControl; - MoveWindowStructure(newWindow, geometry.left, geometry.top); - SetPort(GetWindowPort(newWindow)); - if ((wmPtr->master != None) && winPtr->atts.override_redirect) { - /* - * If we are transient and overrideredirect, use the utility class - * to ensure we are topmost (for dropdowns). - */ - WindowGroupRef group = GetWindowGroupOfClass(kUtilityWindowClass); - if (group != NULL) { - SetWindowGroup(newWindow, group); - } + if (wmPtr->master != None && winPtr->atts.override_redirect) { + ApplyMasterOverrideChanges(winPtr, newWindow); } SetWindowModified(newWindow, false); + TkMacOSXRegisterOffScreenWindow((Window) macWin, (GWorldPtr) newWindow); + macWin->flags |= TK_HOST_EXISTS; + ChkErr(GetWindowClass, newWindow, &(wmPtr->macClass)); + ChkErr(GetWindowAttributes, newWindow, &(wmPtr->attributes)); - if (!windowHashInit) { - Tcl_InitHashTable(&windowTable, TCL_ONE_WORD_KEYS); - windowHashInit = true; - } - valueHashPtr = Tcl_CreateHashEntry(&windowTable, - (char *) newWindow, &new); - if (!new) { - Tcl_Panic("same macintosh window allocated twice!"); +#ifdef TK_MAC_DEBUG_WINDOWS + TkMacOSXInitNamedDebugSymbol(HIToolbox, void, DebugPrintWindow, WindowRef); + if (DebugPrintWindow) { + DebugPrintWindow(newWindow); } - Tcl_SetHashValue(valueHashPtr, macWin); - - macWin->flags |= TK_HOST_EXISTS; +#endif /* TK_MAC_DEBUG_WINDOWS */ } /* @@ -5312,10 +5253,7 @@ TkMacOSXMakeRealWindowExist( * TkMacOSXRegisterOffScreenWindow -- * * This function adds the passed in Off Screen Port to the - * hash table that maps Mac windows to root X windows. - * - * FIXME: This is not currently used. Is there any reason - * to keep it? + * hash table that maps Mac windows to root X windows. * * Results: * None. @@ -5326,26 +5264,23 @@ TkMacOSXMakeRealWindowExist( *---------------------------------------------------------------------- */ -void +void TkMacOSXRegisterOffScreenWindow( - Window window, /* Window structure. */ - GWorldPtr portPtr) /* Pointer to a Mac GWorld. */ + Window window, /* Window structure. */ + GWorldPtr portPtr) /* Pointer to a Mac GWorld. */ { - MacDrawable *macWin; Tcl_HashEntry *valueHashPtr; - int new; + int isNew; - macWin = (MacDrawable *) window; if (!windowHashInit) { Tcl_InitHashTable(&windowTable, TCL_ONE_WORD_KEYS); windowHashInit = true; } - valueHashPtr = Tcl_CreateHashEntry(&windowTable, - (char *) portPtr, &new); - if (!new) { - Tcl_Panic("same macintosh window allocated twice!"); + valueHashPtr = Tcl_CreateHashEntry(&windowTable, (char *) portPtr, &isNew); + if (!isNew) { + Tcl_Panic("Same macintosh window allocated twice!"); } - Tcl_SetHashValue(valueHashPtr, macWin); + Tcl_SetHashValue(valueHashPtr, window); } /* @@ -5353,7 +5288,7 @@ TkMacOSXRegisterOffScreenWindow( * * TkMacOSXUnregisterMacWindow -- * - * Given a macintosh port window, this function removes the + * Given a macintosh port window, this function removes the * association between this window and the root X window that * Tk cares about. * @@ -5366,23 +5301,20 @@ TkMacOSXRegisterOffScreenWindow( *---------------------------------------------------------------------- */ -void +void TkMacOSXUnregisterMacWindow( WindowRef macWinPtr) /* Reference to a Mac Window */ { Tcl_HashEntry *entryPtr; + if (!windowHashInit) { Tcl_Panic("TkMacOSXUnregisterMacWindow: unmapping before inited"); } entryPtr = Tcl_FindHashEntry(&windowTable,(char *) macWinPtr); if (!entryPtr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"Unregister:failed to find window %08x\n", - (int) macWinPtr ); -#endif - } - else { - Tcl_DeleteHashEntry(entryPtr); + TkMacOSXDbgMsg("Failed to find window %08x", (int) macWinPtr); + } else { + Tcl_DeleteHashEntry(entryPtr); } } @@ -5392,7 +5324,7 @@ TkMacOSXUnregisterMacWindow( * TkMacOSXSetScrollbarGrow -- * * Sets a flag for a toplevel window indicating that the passed - * Tk scrollbar window will display the grow region for the + * Tk scrollbar window will display the grow region for the * toplevel window. * * Results: @@ -5404,7 +5336,7 @@ TkMacOSXUnregisterMacWindow( *---------------------------------------------------------------------- */ -void +void TkMacOSXSetScrollbarGrow( TkWindow *winPtr, /* Tk scrollbar window. */ int flag) /* Boolean value true or false. */ @@ -5418,7 +5350,7 @@ TkMacOSXSetScrollbarGrow( winPtr->privatePtr->toplevel->winPtr->wmInfoPtr->scrollWinPtr = NULL; } } - + /* *---------------------------------------------------------------------- * @@ -5427,8 +5359,8 @@ TkMacOSXSetScrollbarGrow( * This is a utility procedure invoked by focus-management code. It * exists because of the extra wrapper windows that exist under * Unix; its job is to map from wrapper windows to the - * corresponding toplevel windows. On PCs and Macs there are no - * wrapper windows so no mapping is necessary; this procedure just + * corresponding toplevel windows. On PCs and Macs there are no + * wrapper windows so no mapping is necessary; this procedure just * determines whether a window is a toplevel or not. * * Results: @@ -5501,13 +5433,13 @@ TkpGetWrapperWindow( void TkpWmSetState(winPtr, state) - TkWindow *winPtr; /* Toplevel window to operate on. */ - int state; /* One of IconicState, ZoomState, NormalState, + TkWindow *winPtr; /* Toplevel window to operate on. */ + int state; /* One of IconicState, ZoomState, NormalState, * or WithdrawnState. */ { WmInfo *wmPtr = winPtr->wmInfoPtr; WindowRef macWin; - + wmPtr->hints.initial_state = state; if (wmPtr->flags & WM_NEVER_MAPPED) { return; @@ -5519,7 +5451,7 @@ TkpWmSetState(winPtr, state) Tk_UnmapWindow((Tk_Window) winPtr); } else if (state == IconicState) { /* - * The window always gets unmapped. If we can show the + * The window always gets unmapped. If we can show the * icon version of the window we also collapse it. */ if (IsWindowCollapsable(macWin) && !IsWindowCollapsed(macWin)) { @@ -5540,84 +5472,74 @@ TkpWmSetState(winPtr, state) TkMacOSXZoomToplevel(macWin, inZoomOut); } } - + /* *---------------------------------------------------------------------- * * TkpIsWindowFloating -- * - * Returns 1 if a window is floating, 0 otherwise. + * Returns 1 if a window is floating, 0 otherwise. * * Results: - * 1 or 0 depending on window's floating attribute. + * 1 or 0 depending on window's floating attribute. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ int -TkpIsWindowFloating(WindowRef wRef) +TkpIsWindowFloating( + WindowRef wRef) { WindowClass class; if (wRef == NULL) { - return 0; + return 0; } - + GetWindowClass(wRef, &class); return (class == kFloatingWindowClass); } - + /* *---------------------------------------------------------------------- * * TkMacOSXWindowClass -- * - * Returns OS X window class of window + * Returns OS X window class of window * * Results: - * 1 or 0 depending on window's floating attribute. + * 1 or 0 depending on window's floating attribute. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ MODULE_SCOPE WindowClass -TkMacOSXWindowClass(TkWindow *winPtr) +TkMacOSXWindowClass( + TkWindow *winPtr) { - WindowRef wRef; - WindowClass class; - - if (winPtr == NULL) { - return 0; - } - wRef = GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window)); - if (wRef == NULL) { - return 0; - } - - GetWindowClass(wRef, &class); - return class; + return winPtr->wmInfoPtr->macClass; } - + /* - *---------------------------------------------------------------------- + *-------------------------------------------------------------- * * TkMacOSXWindowOffset -- * - * Determines the x and y offset from the orgin of the toplevel - * window dressing (the structure region, ie. title bar) and the - * orgin of the content area. + * Determines the x and y offset from the orgin of the toplevel + * window dressing (the structure region, ie. title bar) and the + * orgin of the content area. * * Results: - * The x & y offset in pixels. + * The x & y offset in pixels. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -5628,62 +5550,55 @@ TkMacOSXWindowOffset( int *xOffset, int *yOffset) { - Rect widths; + Window window; + TkDisplay *dispPtr; + TkWindow *winPtr; - GetWindowStructureWidths(wRef, &widths); - *xOffset = widths.left; - *yOffset = widths.top; - return; + window = TkMacOSXGetXWindow(wRef); + dispPtr = TkGetDisplayList(); + winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window); + *xOffset = winPtr->wmInfoPtr->xInParent; + *yOffset = winPtr->wmInfoPtr->yInParent; } - + /* *---------------------------------------------------------------------- * * TkpGetMS -- * - * Return a relative time in milliseconds. It doesn't matter - * when the epoch was. + * Return a relative time in milliseconds. It doesn't matter + * when the epoch was. * * Results: - * Number of milliseconds. + * Number of milliseconds. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ unsigned long -TkpGetMS() +TkpGetMS(void) { - long long * int64Ptr; - UnsignedWide micros; - - Microseconds(µs); - int64Ptr = (long long *) µs; - - /* - * We need 64 bit math to do this. This is available in CW 11 - * and on. Other's will need to use a different scheme. - */ + Tcl_Time now; - *int64Ptr /= 1000; - - return (long) *int64Ptr; + Tcl_GetTime(&now); + return (long) now.sec * 1000 + now.usec / 1000; } - + /* *---------------------------------------------------------------------- * * XSetInputFocus -- * - * Change the focus window for the application. + * Change the focus window for the application. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -5696,7 +5611,7 @@ XSetInputFocus( Time time) { /* - * Don't need to do a thing. Tk manages the focus for us. + * Don't need to do a thing. Tk manages the focus for us. */ } @@ -5705,48 +5620,47 @@ XSetInputFocus( * * TkpChangeFocus -- * - * This procedure is a stub on the Mac because we always own the - * focus if we are a front most application. + * This procedure is a stub on the Mac because we always own the + * focus if we are a front most application. * * Results: - * The return value is the serial number of the command that - * changed the focus. It may be needed by the caller to filter - * out focus change events that were queued before the command. - * If the procedure doesn't actually change the focus then - * it returns 0. + * The return value is the serial number of the command that + * changed the focus. It may be needed by the caller to filter + * out focus change events that were queued before the command. + * If the procedure doesn't actually change the focus then + * it returns 0. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ int TkpChangeFocus(winPtr, force) - TkWindow *winPtr; /* Window that is to receive the X focus. */ - int force; /* Non-zero means claim the focus even - * if it didn't originally belong to - * topLevelPtr's application. */ + TkWindow *winPtr; /* Window that is to receive the X focus. */ + int force; /* Non-zero means claim the focus even + * if it didn't originally belong to + * topLevelPtr's application. */ { /* - * We don't really need to do anything on the Mac. Tk will + * We don't really need to do anything on the Mac. Tk will * keep all this state for us. */ if (winPtr->atts.override_redirect) { - return 0; + return 0; } /* * Remember the current serial number for the X server and issue - * a dummy server request. This marks the position at which we + * a dummy server request. This marks the position at which we * changed the focus, so we can distinguish FocusIn and FocusOut * events on either side of the mark. */ return NextRequest(winPtr->display); } - /* *---------------------------------------------------------------------- @@ -5769,28 +5683,30 @@ TkpChangeFocus(winPtr, force) * *---------------------------------------------------------------------- */ + static void -WmStackorderToplevelWrapperMap(winPtr, display, table) - TkWindow *winPtr; /* TkWindow to recurse on */ - Display *display; /* X display of parent window */ - Tcl_HashTable *table; /* Maps mac window to TkWindow */ +WmStackorderToplevelWrapperMap( + TkWindow *winPtr, /* TkWindow to recurse on */ + Display *display, /* X display of parent window */ + Tcl_HashTable *table) /* Maps mac window to TkWindow */ { TkWindow *childPtr; Tcl_HashEntry *hPtr; WindowRef macWindow; int newEntry; - if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) && (winPtr->display == display)) { - macWindow = GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window)); + if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) + && (winPtr->display == display)) { + macWindow = GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window)); - hPtr = Tcl_CreateHashEntry(table, - (const char *) macWindow, &newEntry); - Tcl_SetHashValue(hPtr, winPtr); + hPtr = Tcl_CreateHashEntry(table, + (const char *) macWindow, &newEntry); + Tcl_SetHashValue(hPtr, winPtr); } for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { - WmStackorderToplevelWrapperMap(childPtr, display, table); + childPtr = childPtr->nextPtr) { + WmStackorderToplevelWrapperMap(childPtr, display, table); } } @@ -5813,7 +5729,7 @@ WmStackorderToplevelWrapperMap(winPtr, display, table) TkWindow ** TkWmStackorderToplevel(parentPtr) - TkWindow *parentPtr; /* Parent toplevel window. */ + TkWindow *parentPtr; /* Parent toplevel window. */ { WindowRef frontWindow; TkWindow *childWinPtr, **windows, **window_ptr; @@ -5829,7 +5745,7 @@ TkWmStackorderToplevel(parentPtr) WmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table); windows = (TkWindow **) ckalloc((table.numEntries+1) - * sizeof(TkWindow *)); + * sizeof(TkWindow *)); /* * Special cases: If zero or one toplevels were mapped @@ -5838,33 +5754,34 @@ TkWmStackorderToplevel(parentPtr) switch (table.numEntries) { case 0: - windows[0] = NULL; - goto done; + windows[0] = NULL; + goto done; case 1: - hPtr = Tcl_FirstHashEntry(&table, &search); - windows[0] = (TkWindow *) Tcl_GetHashValue(hPtr); - windows[1] = NULL; - goto done; + hPtr = Tcl_FirstHashEntry(&table, &search); + windows[0] = (TkWindow *) Tcl_GetHashValue(hPtr); + windows[1] = NULL; + goto done; } frontWindow = (WindowRef) FrontWindow(); if (frontWindow == NULL) { - ckfree((char *) windows); - windows = NULL; + ckfree((char *) windows); + windows = NULL; } else { - window_ptr = windows + table.numEntries; - *window_ptr-- = NULL; + window_ptr = windows + table.numEntries; + *window_ptr-- = NULL; while (frontWindow != NULL) { hPtr = Tcl_FindHashEntry(&table, (char *) frontWindow); - if (hPtr != NULL) { - childWinPtr = (TkWindow *) Tcl_GetHashValue(hPtr); - *window_ptr-- = childWinPtr; - } - frontWindow = GetNextWindow(frontWindow); + if (hPtr != NULL) { + childWinPtr = (TkWindow *) Tcl_GetHashValue(hPtr); + *window_ptr-- = childWinPtr; + } + frontWindow = GetNextWindow(frontWindow); } - if (window_ptr != (windows-1)) - Tcl_Panic("num matched toplevel windows does not equal num children"); + if (window_ptr != (windows-1)) + Tcl_Panic("num matched toplevel windows does not equal num " + "children"); } done: @@ -5875,9 +5792,9 @@ TkWmStackorderToplevel(parentPtr) /* *---------------------------------------------------------------------- * - * ApplyWindowAttributeChanges -- + * ApplyWindowClassAttributeChanges -- * - * This procedure applies carbon window attribute changes. + * This procedure applies carbon window class and attribute changes. * * Results: * None. @@ -5889,27 +5806,440 @@ TkWmStackorderToplevel(parentPtr) */ static void -ApplyWindowAttributeChanges(TkWindow *winPtr, int newAttributes, - int oldAttributes, int create) +ApplyWindowClassAttributeChanges( + TkWindow *winPtr, + WindowRef macWindow, + WindowClass oldClass, + WindowAttributes oldAttributes, + int create) { - if (newAttributes != oldAttributes) { - if (winPtr->window == None) { - if (create) { - Tk_MakeWindowExist((Tk_Window) winPtr); + WmInfo *wmPtr = winPtr->wmInfoPtr; + WindowAttributes newAttributes = wmPtr->attributes | + kWindowAsyncDragAttribute; + + if (wmPtr->macClass != oldClass || newAttributes != oldAttributes) { + Rect strWidths; + + if (!macWindow) { + if (winPtr->window == None) { + if (create) { + Tk_MakeWindowExist((Tk_Window) winPtr); + } else { + return; + } + } + if (!TkMacOSXHostToplevelExists(winPtr)) { + if (create) { + TkMacOSXMakeRealWindowExist(winPtr); + } else { + return; + } + } + macWindow = GetWindowFromPort(TkMacOSXGetDrawablePort( + winPtr->window)); + } +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + if (wmPtr->macClass != oldClass +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1030 + && HIWindowChangeClass != NULL +#endif + ) { + ChkErr(HIWindowChangeClass, macWindow, wmPtr->macClass); + ChkErr(GetWindowClass, macWindow, &(wmPtr->macClass)); + } +#endif + if (newAttributes != oldAttributes) { + newAttributes &= GetAvailableWindowAttributes(wmPtr->macClass); + ChkErr(ChangeWindowAttributes, macWindow, + newAttributes & (newAttributes ^ oldAttributes), + oldAttributes & (newAttributes ^ oldAttributes)); + } + ChkErr(GetWindowAttributes, macWindow, &(wmPtr->attributes)); + if (wmPtr->attributes & kWindowResizableAttribute) { + OSStatus err; + HIViewRef growBoxView; + + err = ChkErr(HIViewFindByID, HIViewGetRoot(macWindow), + kHIViewWindowGrowBoxID, &growBoxView); + if (err == noErr && !HIGrowBoxViewIsTransparent(growBoxView)) { + ChkErr(HIGrowBoxViewSetTransparent, growBoxView, true); + } + } + + /* + * The change of window class/attributes might have changed the window + * structure widths: + */ + GetWindowStructureWidths(macWindow, &strWidths); + wmPtr->xInParent = strWidths.left; + wmPtr->yInParent = strWidths.top; + wmPtr->parentWidth = winPtr->changes.width + strWidths.left + + strWidths.right; + wmPtr->parentHeight = winPtr->changes.height + strWidths.top + + strWidths.bottom; + } +} + +/* + *---------------------------------------------------------------------- + * + * ApplyMasterOverrideChanges -- + * + * This procedure applies changes to override_redirect or master. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +ApplyMasterOverrideChanges( + TkWindow *winPtr, + WindowRef macWindow) +{ + WmInfo *wmPtr = winPtr->wmInfoPtr; + WindowClass oldClass = wmPtr->macClass; + WindowAttributes oldAttributes = wmPtr->attributes; + int frontmost = 0; + + /* + * FIX: We need an UpdateWrapper equivalent to make this 100% correct + */ + if (winPtr->atts.override_redirect) { + if (wmPtr->macClass == kDocumentWindowClass || (wmPtr->master != None + && wmPtr->macClass == kFloatingWindowClass)) { + wmPtr->macClass = kSimpleWindowClass; + wmPtr->attributes = kWindowNoAttributes; + } + if (wmPtr->master != None) { + frontmost = 1; + } + wmPtr->attributes |= kWindowNoActivatesAttribute; + } else { + if (wmPtr->macClass == kSimpleWindowClass) { + if (wmPtr->master != None) { + wmPtr->macClass = kFloatingWindowClass; + wmPtr->attributes = kWindowStandardFloatingAttributes; } else { - return; + wmPtr->macClass = kDocumentWindowClass; + wmPtr->attributes = kWindowStandardDocumentAttributes + | kWindowLiveResizeAttribute; } } + wmPtr->attributes &= ~kWindowNoActivatesAttribute; + } + if (!macWindow) { + if (winPtr->window == None) { + return; + } if (!TkMacOSXHostToplevelExists(winPtr)) { - if (create) { - TkMacOSXMakeRealWindowExist(winPtr); - } else { - return; + return; + } + macWindow = GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window)); + } + if (macWindow) { + Tcl_Obj *val; + + ApplyWindowClassAttributeChanges(winPtr, macWindow, oldClass, + oldAttributes, 0); + val = Tcl_NewBooleanObj(frontmost); + WmSetAttribute(winPtr, macWindow, NULL, WMATT_TOPMOST, val); + Tcl_DecrRefCount(val); + } +} + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXMakeFullscreen -- + * + * This procedure sets a fullscreen window to the size of the screen. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TkMacOSXMakeFullscreen( + TkWindow *winPtr, + WindowRef window, + int fullscreen, + Tcl_Interp *interp) +{ + WmInfo *wmPtr = winPtr->wmInfoPtr; + int result = TCL_OK, wasFullscreen = (wmPtr->flags & WM_FULLSCREEN); + + if (fullscreen) { + int screenWidth = WidthOfScreen(Tk_Screen(winPtr)); + int screenHeight = HeightOfScreen(Tk_Screen(winPtr)); + /* + * Check max width and height if set by the user. + */ + if ((wmPtr->maxWidth > 0 && wmPtr->maxWidth < screenWidth) + || (wmPtr->maxHeight > 0 && wmPtr->maxHeight < screenHeight)) { + if (interp) { + Tcl_AppendResult(interp, + "can't set fullscreen attribute for \"", + winPtr->pathName, + "\": max width/height is too small", NULL); + } + result = TCL_ERROR; + wmPtr->flags &= ~WM_FULLSCREEN; + } else { + Rect bounds, screenBounds = {0, 0, screenHeight, screenWidth}; + + ChkErr(GetWindowBounds, window, kWindowContentRgn, &bounds); + if (!EqualRect(&bounds, &screenBounds)) { + if (!wasFullscreen) { + wmPtr->configX = wmPtr->x; + wmPtr->configY = wmPtr->y; + wmPtr->configAttributes = wmPtr->attributes; + wmPtr->attributes &= ~kWindowResizableAttribute; + ApplyWindowClassAttributeChanges(winPtr, window, + wmPtr->macClass, wmPtr->configAttributes, 0); + } + wmPtr->flags |= WM_SYNC_PENDING; + ChkErr(SetWindowBounds, window, kWindowContentRgn, + &screenBounds); + wmPtr->flags &= ~WM_SYNC_PENDING; + TkMacOSXInvalidateWindow((MacDrawable*)winPtr->window, + TK_WINDOW_ONLY); } + wmPtr->flags |= WM_FULLSCREEN; + } + } else { + wmPtr->flags &= ~WM_FULLSCREEN; + } + if (wasFullscreen && !(wmPtr->flags & WM_FULLSCREEN)) { + WindowAttributes oldAttributes = wmPtr->attributes; + Rect bounds = {wmPtr->configY, wmPtr->configX, + wmPtr->configY + wmPtr->yInParent + wmPtr->configHeight, + wmPtr->configX + wmPtr->xInParent + wmPtr->configWidth}; + + wmPtr->attributes |= wmPtr->configAttributes & + kWindowResizableAttribute; + ApplyWindowClassAttributeChanges(winPtr, window, wmPtr->macClass, + oldAttributes, 0); + wmPtr->flags |= WM_SYNC_PENDING; + ChkErr(SetWindowBounds, window, kWindowStructureRgn, &bounds); + wmPtr->flags &= ~WM_SYNC_PENDING; + TkMacOSXInvalidateWindow((MacDrawable*)winPtr->window, + TK_WINDOW_ONLY); + } + TkMacOSXEnterExitFullscreen(winPtr, IsWindowActive(window)); + return result; +} + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXEnterExitFullscreen -- + * + * This procedure enters or exits fullscreen mode if required. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TkMacOSXEnterExitFullscreen( + TkWindow *winPtr, + int active) +{ + WmInfo *wmPtr = winPtr->wmInfoPtr; + SystemUIMode mode; + SystemUIOptions options; + + GetSystemUIMode(&mode, &options); + if (wmPtr->flags & WM_FULLSCREEN && active) { + static SystemUIMode fullscreenMode = 0; + static SystemUIOptions fullscreenOptions = 0; + + if (!fullscreenMode) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + if (1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1030 + && &kHIToolboxVersionNumber != NULL + && kHIToolboxVersionNumber >= kHIToolboxVersionNumber10_3 +#endif + ) { + fullscreenMode = kUIModeAllSuppressed; + } else +#endif + { + fullscreenMode = kUIModeAllHidden; + fullscreenOptions = kUIOptionAutoShowMenuBar; + } + } + if (mode != fullscreenMode) { + ChkErr(SetSystemUIMode, fullscreenMode, fullscreenOptions); + } + } else { + if (mode != kUIModeNormal) { + ChkErr(SetSystemUIMode, kUIModeNormal, 0); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * GetMinSize -- + * + * This function computes the current minWidth and minHeight values for + * a window, taking into account the possibility that they may be + * defaulted. + * + * Results: + * The values at *minWidthPtr and *minHeightPtr are filled in with the + * minimum allowable dimensions of wmPtr's window, in grid units. If the + * requested minimum is smaller than the system required minimum, then + * this function computes the smallest size that will satisfy both the + * system and the grid constraints. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +GetMinSize( + TkWindow *winPtr, /* Toplevel window to operate on. */ + int *minWidthPtr, /* Where to store the current minimum width of + * the window. */ + int *minHeightPtr) /* Where to store the current minimum height + * of the window. */ +{ + WmInfo *wmPtr = winPtr->wmInfoPtr; + int minWidth = 1, minHeight = 1; + + /* + * Compute the minimum width & height by taking the default client size and + * rounding it up to the nearest grid unit. Return the greater of the + * default minimum and the specified minimum. + */ + + switch (wmPtr->macClass) { + case kDocumentWindowClass: + case kMovableAlertWindowClass: + case kMovableModalWindowClass: + minWidth = 72; + if (wmPtr->attributes & kWindowResizableAttribute) { + minHeight = 15; + } + if (wmPtr->attributes & kWindowToolbarButtonAttribute) { + minWidth += 29; + } + break; + case kFloatingWindowClass: + case kUtilityWindowClass: + minWidth = 59; + if (wmPtr->attributes & kWindowResizableAttribute) { + minHeight = 11; + } + if (wmPtr->attributes & kWindowSideTitlebarAttribute) { + int tmp = minWidth; + minWidth = minHeight; + minHeight = tmp; + } else if (wmPtr->attributes & kWindowToolbarButtonAttribute) { + minWidth += 29; + } + break; + default: + if (wmPtr->attributes & kWindowResizableAttribute) { + minWidth = 15; + minHeight = 15; + } + break; + } + + if (wmPtr->gridWin != NULL) { + int base = winPtr->reqWidth - (wmPtr->reqGridWidth * wmPtr->widthInc); + if (base < 0) { + base = 0; + } + minWidth = ((minWidth - base) + wmPtr->widthInc-1)/wmPtr->widthInc; + base = winPtr->reqHeight - (wmPtr->reqGridHeight * wmPtr->heightInc); + if (base < 0) { + base = 0; + } + minHeight = ((minHeight - base) + wmPtr->heightInc-1)/wmPtr->heightInc; + } + if (minWidth < wmPtr->minWidth) { + minWidth = wmPtr->minWidth; + } + if (minHeight < wmPtr->minHeight) { + minHeight = wmPtr->minHeight; + } + *minWidthPtr = minWidth; + *minHeightPtr = minHeight; +} + +/* + *---------------------------------------------------------------------- + * + * GetMaxSize -- + * + * This function computes the current maxWidth and maxHeight values for + * a window, taking into account the possibility that they may be + * defaulted. + * + * Results: + * The values at *maxWidthPtr and *maxHeightPtr are filled in with the + * maximum allowable dimensions of wmPtr's window, in grid units. If no + * maximum has been specified for the window, then this function computes + * the largest sizes that will fit on the screen. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +GetMaxSize( + TkWindow *winPtr, /* Toplevel window to operate on. */ + int *maxWidthPtr, /* Where to store the current maximum width of + * the window. */ + int *maxHeightPtr) /* Where to store the current maximum height + * of the window. */ +{ + WmInfo *wmPtr = winPtr->wmInfoPtr; + Rect *maxBounds = (Rect*)(winPtr->display->screens->ext_data); + + if (wmPtr->maxWidth > 0) { + *maxWidthPtr = wmPtr->maxWidth; + } else { + int maxWidth = maxBounds->right - maxBounds->left - wmPtr->xInParent; + if (wmPtr->gridWin != NULL) { + maxWidth = wmPtr->reqGridWidth + + (maxWidth - winPtr->reqWidth)/wmPtr->widthInc; + } + *maxWidthPtr = maxWidth; + } + if (wmPtr->maxHeight > 0) { + *maxHeightPtr = wmPtr->maxHeight; + } else { + int maxHeight = maxBounds->bottom - maxBounds->top - wmPtr->yInParent; + if (wmPtr->gridWin != NULL) { + maxHeight = wmPtr->reqGridHeight + + (maxHeight - winPtr->reqHeight)/wmPtr->heightInc; } - ChangeWindowAttributes( - GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window)), - newAttributes & (newAttributes ^ oldAttributes), - oldAttributes & (newAttributes ^ oldAttributes)); + *maxHeightPtr = maxHeight; } } diff --git a/macosx/tkMacOSXWm.h b/macosx/tkMacOSXWm.h index 9e45a84..e16e7c1 100644 --- a/macosx/tkMacOSXWm.h +++ b/macosx/tkMacOSXWm.h @@ -1,58 +1,61 @@ /* * tkMacOSXWm.h -- * - * Declarations of Macintosh specific functions for implementing the - * Mac OS X Notifier. + * Declarations of Macintosh specific window manager structures. * - * Copyright 2001, Apple Computer, Inc. + * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * - * The following terms apply to all files originating from Apple - * Computer, Inc. ("Apple") and associated with the software - * unless explicitly disclaimed in individual files. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * + * The following terms apply to all files originating from Apple + * Computer, Inc. ("Apple") and associated with the software + * unless explicitly disclaimed in individual files. * - * Apple hereby grants permission to use, copy, modify, - * distribute, and license this software and its documentation - * for any purpose, provided that existing copyright notices are - * retained in all copies and that this notice is included - * verbatim in any distributions. No written agreement, license, - * or royalty fee is required for any of the authorized - * uses. Modifications to this software may be copyrighted by - * their authors and need not follow the licensing terms - * described here, provided that the new terms are clearly - * indicated on the first page of each file where they apply. * + * Apple hereby grants permission to use, copy, modify, + * distribute, and license this software and its documentation + * for any purpose, provided that existing copyright notices are + * retained in all copies and that this notice is included + * verbatim in any distributions. No written agreement, license, + * or royalty fee is required for any of the authorized + * uses. Modifications to this software may be copyrighted by + * their authors and need not follow the licensing terms + * described here, provided that the new terms are clearly + * indicated on the first page of each file where they apply. * - * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE - * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, - * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF - * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, - * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND - * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS - * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE - * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * - * GOVERNMENT USE: If you are acquiring this software on behalf - * of the U.S. government, the Government shall have only - * "Restricted Rights" in the software and related documentation - * as defined in the Federal Acquisition Regulations (FARs) in - * Clause 52.227.19 (c) (2). If you are acquiring the software - * on behalf of the Department of Defense, the software shall be - * classified as "Commercial Computer Software" and the - * Government shall have only "Restricted Rights" as defined in - * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the - * foregoing, the authors grant the U.S. Government and others - * acting in its behalf permission to use and distribute the - * software in accordance with the terms specified in this - * license. + * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE + * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, + * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF + * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, + * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND + * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS + * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE + * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * - * RCS: @(#) $Id: tkMacOSXWm.h,v 1.7 2007/01/05 00:00:51 nijtmans Exp $ + * GOVERNMENT USE: If you are acquiring this software on behalf + * of the U.S. government, the Government shall have only + * "Restricted Rights" in the software and related documentation + * as defined in the Federal Acquisition Regulations (FARs) in + * Clause 52.227.19 (c) (2). If you are acquiring the software + * on behalf of the Department of Defense, the software shall be + * classified as "Commercial Computer Software" and the + * Government shall have only "Restricted Rights" as defined in + * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the + * foregoing, the authors grant the U.S. Government and others + * acting in its behalf permission to use and distribute the + * software in accordance with the terms specified in this + * license. + * + * RCS: @(#) $Id: tkMacOSXWm.h,v 1.8 2007/04/23 21:24:34 das Exp $ */ - + #ifndef _TKMACWM #define _TKMACWM @@ -73,7 +76,7 @@ typedef struct ProtocolHandler { * end of list. */ Tcl_Interp *interp; /* Interpreter in which to invoke command. */ char command[4]; /* Tcl command to invoke when a client - * message for this protocol arrives. + * message for this protocol arrives. * The actual size of the structure varies * to accommodate the needs of the actual * command. THIS MUST BE THE LAST FIELD OF @@ -94,10 +97,10 @@ typedef struct TkWmInfo { Window reparent; /* If the window has been reparented, this * gives the ID of the ancestor of the window * that is a child of the root window (may - * not be window's immediate parent). If + * not be window's immediate parent). If * the window isn't reparented, this has the * value None. */ - Tk_Uid titleUid; /* Title to display in window caption. If + Tk_Uid titleUid; /* Title to display in window caption. If * NULL, use name of widget. */ char *iconName; /* Name to display in icon. */ Window master; /* Master window for TRANSIENT_FOR property, @@ -106,7 +109,7 @@ typedef struct TkWmInfo { * window manager. */ char *leaderName; /* Path name of leader of window group * (corresponds to hints.window_group). - * Malloc-ed. Note: this field doesn't + * Malloc-ed. Note: this field doesn't * get updated if leader is destroyed. */ char *masterWindowName; /* Path name of window specified as master * in "wm transient" command, or NULL. @@ -125,7 +128,7 @@ typedef struct TkWmInfo { int sizeHintsFlags; /* Flags word for XSizeHints structure. * If the PBaseSize flag is set then the - * window is gridded; otherwise it isn't + * window is gridded; otherwise it isn't * gridded. */ int minWidth, minHeight; /* Minimum dimensions of window, in * grid units, not pixels. */ @@ -137,8 +140,8 @@ typedef struct TkWmInfo { int widthInc, heightInc; /* Increments for size changes (# pixels * per step). */ struct { - int x; /* numerator */ - int y; /* denominator */ + int x; /* numerator */ + int y; /* denominator */ } minAspect, maxAspect; /* Min/max aspect ratios for window. */ int reqGridWidth, reqGridHeight; /* The dimensions of the window (in @@ -151,15 +154,15 @@ typedef struct TkWmInfo { */ int width, height; /* Desired dimensions of window, specified - * in grid units. These values are + * in grid units. These values are * set by the "wm geometry" command and by * ConfigureNotify events (for when wm - * resizes window). -1 means user hasn't + * resizes window). -1 means user hasn't * requested dimensions. */ int x, y; /* Desired X and Y coordinates for window. * These values are set by "wm geometry", * plus by ConfigureNotify events (when wm - * moves window). These numbers are + * moves window). These numbers are * different than the numbers stored in * winPtr->changes because (a) they could be * measured from the right or bottom edge @@ -169,18 +172,20 @@ typedef struct TkWmInfo { * parent rather than the window itself. */ int parentWidth, parentHeight; /* Width and height of reparent, in pixels - * *including border*. If window hasn't been + * *including border*. If window hasn't been * reparented then these will be the outer * dimensions of the window, including * border. */ - int xInParent, yInParent; /* Offset of window within reparent, measured + int xInParent, yInParent; /* Offset of window within reparent, measured * from upper-left outer corner of parent's * border to upper-left outer corner of child's - * border. If not reparented then these are + * border. If not reparented then these are * zero. */ + int configX, configY; /* x,y position of toplevel when window is + * switched into fullscreen state, */ int configWidth, configHeight; /* Dimensions passed to last request that we - * issued to change geometry of window. Used + * issued to change geometry of window. Used * to eliminate redundant resize operations. */ /* @@ -192,15 +197,15 @@ typedef struct TkWmInfo { * or None if there is no virtual root * window (i.e. just use the screen's root). */ int vRootX, vRootY; /* Position of the virtual root inside the - * root window. If the WM_VROOT_OFFSET_STALE + * root window. If the WM_VROOT_OFFSET_STALE * flag is set then this information may be * incorrect and needs to be refreshed from - * the X server. If vRoot is None then these + * the X server. If vRoot is None then these * values are both 0. */ unsigned int vRootWidth, vRootHeight; /* Dimensions of the virtual root window. * If vRoot is None, gives the dimensions - * of the containing screen. This information + * of the containing screen. This information * is never stale, even though vRootX and * vRootY can be. */ @@ -219,7 +224,7 @@ typedef struct TkWmInfo { * this window (NULL means none). */ int cmdArgc; /* Number of elements in cmdArgv below. */ const char **cmdArgv; /* Array of strings to store in the - * WM_COMMAND property. NULL means nothing + * WM_COMMAND property. NULL means nothing * available. */ char *clientMachine; /* String to store in WM_CLIENT_MACHINE * property, or NULL. */ @@ -228,10 +233,10 @@ typedef struct TkWmInfo { /* * Macintosh information. */ - int style; /* Native window style. */ - int macClass; - int attributes; + WindowClass macClass; + WindowAttributes attributes, configAttributes; TkWindow *scrollWinPtr; /* Ptr to scrollbar handling grow widget. */ + short style; /* Legacy window style. */ } WmInfo; @@ -239,11 +244,11 @@ typedef struct TkWmInfo { * Flag values for WmInfo structures: * * WM_NEVER_MAPPED - non-zero means window has never been - * mapped; need to update all info when + * mapped; need to update all info when * window is first mapped. * WM_UPDATE_PENDING - non-zero means a call to UpdateGeometryInfo * has already been scheduled for this - * window; no need to schedule another one. + * window; no need to schedule another one. * WM_NEGATIVE_X - non-zero means x-coordinate is measured in * pixels from right edge of screen, rather * than from left edge. @@ -258,7 +263,7 @@ typedef struct TkWmInfo { * about the virtual root window is stale and * needs to be fetched fresh from the X server. * WM_ABOUT_TO_MAP - non-zero means that the window is about to - * be mapped by TkWmMapWindow. This is used + * be mapped by TkWmMapWindow. This is used * by UpdateGeometryInfo to modify its behavior. * WM_MOVE_PENDING - non-zero means the application has requested * a new position for the window, but it hasn't @@ -280,19 +285,22 @@ typedef struct TkWmInfo { * command). */ -#define WM_NEVER_MAPPED 1 -#define WM_UPDATE_PENDING 2 -#define WM_NEGATIVE_X 4 -#define WM_NEGATIVE_Y 8 -#define WM_UPDATE_SIZE_HINTS 0x10 -#define WM_SYNC_PENDING 0x20 -#define WM_VROOT_OFFSET_STALE 0x40 -#define WM_ABOUT_TO_MAP 0x100 -#define WM_MOVE_PENDING 0x200 -#define WM_COLORMAPS_EXPLICIT 0x400 -#define WM_ADDED_TOPLEVEL_COLORMAP 0x800 -#define WM_WIDTH_NOT_RESIZABLE 0x1000 -#define WM_HEIGHT_NOT_RESIZABLE 0x2000 +#define WM_NEVER_MAPPED 0x0001 +#define WM_UPDATE_PENDING 0x0002 +#define WM_NEGATIVE_X 0x0004 +#define WM_NEGATIVE_Y 0x0008 +#define WM_UPDATE_SIZE_HINTS 0x0010 +#define WM_SYNC_PENDING 0x0020 +#define WM_VROOT_OFFSET_STALE 0x0040 +#define WM_ABOUT_TO_MAP 0x0080 +#define WM_MOVE_PENDING 0x0100 +#define WM_COLORMAPS_EXPLICIT 0x0200 +#define WM_ADDED_TOPLEVEL_COLORMAP 0x0400 +#define WM_WIDTH_NOT_RESIZABLE 0x0800 +#define WM_HEIGHT_NOT_RESIZABLE 0x1000 +#define WM_TOPMOST 0x2000 +#define WM_FULLSCREEN 0x4000 +#define WM_TRANSPARENT 0x8000 #endif diff --git a/macosx/tkMacOSXXCursors.r b/macosx/tkMacOSXXCursors.r index fd2a61c..8513b07 100644 --- a/macosx/tkMacOSXXCursors.r +++ b/macosx/tkMacOSXXCursors.r @@ -1,22 +1,21 @@ -/* +/* * tkMacOSXXCursors.r -- * * This file defines a set of Macintosh cursor resources that - * emulate the X cursor set. All of these cursors were + * emulate the X cursor set. All of these cursors were * constructed and donated by Grant Neufeld. (gneufeld@ccs.carleton.ca) - * * * Copyright (c) 1995-1996 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXXCursors.r,v 1.2 2002/08/31 06:12:31 das Exp $ + * RCS: @(#) $Id: tkMacOSXXCursors.r,v 1.3 2007/04/23 21:24:34 das Exp $ */ /* - * All of the X cursors are defined as 'CURS' resources. However, a - * subset of the X cursors are also defined as 'crsr' resources. Tk + * All of the X cursors are defined as 'CURS' resources. However, a + * subset of the X cursors are also defined as 'crsr' resources. Tk * will attempt to first use the color cursors ('crsr') if it doesn't * exist it will attempt to use the black & white cursor ('CURS'). */ @@ -26,7 +25,7 @@ data 'CURS' (3000, "X_cursor") { $"07E0 0FF0 1FF8 3E7C 7C3E F81F F00F E007" $"0000 6006 700E 381C 1C38 0E70 07E0 03C0" $"03C0 07E0 0E70 1C38 381C 700E 6006 0000" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3001, "arrow") { @@ -34,7 +33,7 @@ data 'CURS' (3001, "arrow") { $"03B0 0720 0E20 1C00 3800 7000 2000 0000" $"0007 001F 007F 01FE 07FE 1FFC 7FFC 03F8" $"07F8 0FF0 1F70 3E60 7C60 F840 7040 2000" - $"0001 000E" + $"0001 000E" }; data 'CURS' (3002, "based_arrow_down") { @@ -42,7 +41,7 @@ data 'CURS' (3002, "based_arrow_down") { $"0300 0B40 0780 0300 0000 0000 0000 0000" $"0000 0000 0000 1FE0 0000 1FE0 0780 0780" $"3FF0 1FE0 0FC0 0780 0300 0000 0000 0000" - $"000B 0006" + $"000B 0006" }; data 'CURS' (3003, "based_arrow_up") { @@ -50,7 +49,7 @@ data 'CURS' (3003, "based_arrow_up") { $"0300 0300 1FE0 0000 1FE0 0000 0000 0000" $"0000 0000 0000 0300 0780 0FC0 1FE0 3FF0" $"0780 0780 1FE0 0000 1FE0 0000 0000 0000" - $"0004 0006" + $"0004 0006" }; data 'CURS' (3004, "boat") { @@ -58,7 +57,7 @@ data 'CURS' (3004, "boat") { $"0018 0020 0040 FFC0 0000 0000 0000 0000" $"0000 0000 0000 0000 0100 03C0 87E0 FFFF" $"FFF8 FFE0 FFC0 FFC0 0000 0000 0000 0000" - $"0007 000F" + $"0007 000F" }; data 'CURS' (3005, "bogosity") { @@ -66,7 +65,7 @@ data 'CURS' (3005, "bogosity") { $"5114 5114 7FFC 1110 1110 1110 711C 0000" $"0000 0000 0000 0000 0000 7FFC 7FFC 7FFC" $"7FFC 7FFC 7FFC 0000 0000 0000 0000 0000" - $"0001 0007" + $"0001 0007" }; data 'CURS' (3006, "bottom_left_corner") { @@ -74,7 +73,7 @@ data 'CURS' (3006, "bottom_left_corner") { $"C900 CA00 CC00 CFC0 C000 C000 FFF0 FFF0" $"0000 0000 0000 0000 0000 0020 0840 0880" $"0900 0A00 0C00 0FC0 0000 0000 0000 0000" - $"000F 0000" + $"000F 0000" }; data 'CURS' (3007, "bottom_right_corner") { @@ -82,7 +81,7 @@ data 'CURS' (3007, "bottom_right_corner") { $"0093 0053 0033 03F3 0003 0003 0FFF 0FFF" $"0000 0000 0000 0000 0000 0400 0210 0110" $"0090 0050 0030 03F0 0000 0000 0000 0000" - $"000F 000F" + $"000F 000F" }; data 'CURS' (3008, "bottom_side") { @@ -90,7 +89,7 @@ data 'CURS' (3008, "bottom_side") { $"0920 0540 0380 0100 0000 7FFC 7FFC 0000" $"0000 0000 0100 0100 0100 0100 0100 1110" $"0920 0540 0380 0100 0000 0000 0000 0000" - $"000B 0007" + $"000B 0007" }; data 'CURS' (3009, "bottom_tee") { @@ -98,7 +97,7 @@ data 'CURS' (3009, "bottom_tee") { $"0180 0180 7FFE 7FFE 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" - $"000B 0007" + $"000B 0007" }; data 'CURS' (3010, "box_spiral") { @@ -106,7 +105,7 @@ data 'CURS' (3010, "box_spiral") { $"AAAA ABAA A82A AFEA A00A BFFA 8002 FFFE" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" - $"0008 0008" + $"0008 0008" }; data 'CURS' (3011, "center_ptr") { @@ -114,7 +113,7 @@ data 'CURS' (3011, "center_ptr") { $"1FE0 3330 2310 0300 0300 0300 0300 0000" $"0300 0780 0780 0FC0 0FC0 1FE0 1FE0 3FF0" $"3FF0 7FF8 77B8 6798 0780 0780 0780 0780" - $"0001 0006" + $"0001 0006" }; data 'CURS' (3012, "circle") { @@ -122,7 +121,7 @@ data 'CURS' (3012, "circle") { $"700E 700E 381C 3C3C 1FF8 0FF0 03C0 0000" $"03C0 0FF0 1FF8 3FFC 7FFE 7C3E F81F F81F" $"F81F F81F 7C3E 7FFE 3FFC 1FF8 0FF0 03C0" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3013, "clock") { @@ -130,7 +129,7 @@ data 'CURS' (3013, "clock") { $"2994 2994 2994 2BD4 6996 781E 7FFE 7FFE" $"1FF8 3FFC 7FFE 7FFE 7FFE 7FFE 7FFE 3FFC" $"3FFC 3FFC 3FFC 3FFC 7FFE 7FFE 7FFE 7FFE" - $"0004 0008" + $"0004 0008" }; data 'CURS' (3014, "coffee_mug") { @@ -138,7 +137,7 @@ data 'CURS' (3014, "coffee_mug") { $"960D DA55 7A55 36ED 10A1 1001 0802 07FC" $"03F8 0FFE 1FFF 1FFF 3FFF 7FFF FFFF FFFF" $"FFFF FFFF 7FFF 3FFF 1FFF 1FFF 0FFE 07FC" - $"0004 0003" + $"0004 0003" }; data 'CURS' (3015, "cross") { @@ -146,7 +145,7 @@ data 'CURS' (3015, "cross") { $"FEFE 0280 0280 0280 0280 0280 0280 0000" $"0380 0380 0380 0380 0380 0380 FFFE FFFE" $"FFFE 0380 0380 0380 0380 0380 0380 0000" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3016, "cross_reverse") { @@ -154,7 +153,7 @@ data 'CURS' (3016, "cross_reverse") { $"FD7E 0AA0 16D0 2AA8 5294 A28A 4284 0000" $"4384 E38E 739C 3BB8 1FF0 0FE0 FFFE FFFE" $"FFFE 0FE0 1FF0 3BB8 739C E38E 4384 0000" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3017, "crosshair") { @@ -162,7 +161,7 @@ data 'CURS' (3017, "crosshair") { $"0100 0100 0100 0100 0100 0100 0100 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3018, "diamond_cross") { @@ -170,7 +169,7 @@ data 'CURS' (3018, "diamond_cross") { $"FEFE 4284 2288 1290 0AA0 06C0 0280 0000" $"0280 06C0 0EE0 1EF0 3EF8 7EFC FEFE 0000" $"FEFE 7EFC 3EF8 1EF0 0EE0 06C0 0280 0000" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3019, "dot") { @@ -178,7 +177,7 @@ data 'CURS' (3019, "dot") { $"3FF0 1FE0 1FE0 0780 0000 0000 0000 0000" $"0000 0780 1FE0 3FF0 3FF0 7FF8 7FF8 7FF8" $"7FF8 3FF0 3FF0 1FE0 0780 0000 0000 0000" - $"0006 0006" + $"0006 0006" }; data 'CURS' (3020, "dotbox") { @@ -186,7 +185,7 @@ data 'CURS' (3020, "dotbox") { $"2184 2004 2004 2004 2004 3FFC 0000 0000" $"0000 0000 3FFC 3FFC 300C 300C 318C 33CC" $"33CC 318C 300C 300C 3FFC 3FFC 0000 0000" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3021, "double_arrow") { @@ -194,7 +193,7 @@ data 'CURS' (3021, "double_arrow") { $"0180 0180 1998 0DB0 07E0 03C0 0180 0000" $"0180 03C0 07E0 0FF0 1FF8 3FFC 3BDC 03C0" $"03C0 3BDC 3FFC 1FF8 0FF0 07E0 03C0 0180" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3022, "draft_large") { @@ -202,7 +201,7 @@ data 'CURS' (3022, "draft_large") { $"0160 0260 0440 0840 1000 2000 4000 0000" $"0003 000F 003E 00FE 03FC 0FFC 3FF8 FFF8" $"03F0 07F0 0EE0 1CE0 38C0 70C0 E080 4080" - $"0001 000E" + $"0001 000E" }; data 'CURS' (3023, "draft_small") { @@ -210,7 +209,7 @@ data 'CURS' (3023, "draft_small") { $"0120 0220 0400 0800 1000 2000 4000 0000" $"0003 000F 003E 00FE 03FC 0FFC 3FF8 01F8" $"03F0 0770 0E60 1C60 3840 7040 E000 4000" - $"0001 000E" + $"0001 000E" }; data 'CURS' (3024, "draped_box") { @@ -218,7 +217,7 @@ data 'CURS' (3024, "draped_box") { $"2184 381C 2C34 2664 2244 3FFC 0000 0000" $"0000 0000 3FFC 3E7C 3E7C 3C3C 399C 23C4" $"23C4 399C 3C3C 3E7C 3E7C 3FFC 0000 0000" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3025, "exchange") { @@ -226,7 +225,7 @@ data 'CURS' (3025, "exchange") { $"0000 00FC 0064 1024 187C 0FEC 07C4 0000" $"C7C0 EFE0 FFF0 FFF8 FC38 FE10 FF00 FF80" $"03FE 01FE 10FE 387E 3FFE 1FFE 0FEE 07C6" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3026, "fleur") { @@ -234,7 +233,7 @@ data 'CURS' (3026, "fleur") { $"7FFE 318C 1188 0180 07E0 03C0 0180 0000" $"0180 03C0 07E0 0FF0 17E8 3BDC 7FFE FFFF" $"FFFF 7FFE 3BDC 17E8 0FF0 07E0 03C0 0180" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3027, "gobbler") { @@ -242,7 +241,7 @@ data 'CURS' (3027, "gobbler") { $"3038 00F0 0FE0 0400 0400 0400 0F00 0000" $"00FC 00FC E0FF FFFF FFFF FFF8 FFF8 FFF8" $"FFFC 7FFC 3FF8 1FF0 0E00 1F80 1F80 1F80" - $"0003 000E" + $"0003 000E" }; data 'CURS' (3028, "gumby") { @@ -250,7 +249,7 @@ data 'CURS' (3028, "gumby") { $"0826 0826 092E 0926 0920 1110 2108 3EF8" $"3F00 1FC0 CFE0 EFE0 CFE0 CFE0 FFF8 3FFE" $"0FE6 0FE6 0FEE 0FE6 0FE0 1FF0 3FF8 3EF8" - $"0000 0002" + $"0000 0002" }; data 'CURS' (3029, "hand1") { @@ -258,7 +257,7 @@ data 'CURS' (3029, "hand1") { $"7FF0 5FF0 07E0 07C0 4A00 6200 3400 1800" $"000C 003C 00F0 01E0 03C0 07E0 0FF0 2FE0" $"7FF0 7FF0 7FE0 7FC0 7E00 7E00 3C00 1800" - $"0000 000D" + $"0000 000D" }; data 'CURS' (3030, "hand2") { @@ -266,7 +265,7 @@ data 'CURS' (3030, "hand2") { $"0822 0641 0182 0124 0088 0050 0020 0000" $"0000 3FC0 7FE0 3FF0 0FF8 07F8 0FF8 07FC" $"0FFE 07FF 01FE 01FC 00F8 0070 0020 0000" - $"0002 0001" + $"0002 0001" }; data 'CURS' (3031, "heart") { @@ -274,7 +273,7 @@ data 'CURS' (3031, "heart") { $"C006 600C 3018 1830 0C60 06C0 0380 0000" $"0000 3EF8 7FFC FFFE FFFE FFFE FFFE FFFE" $"FFFE 7FFC 3FF8 1FF0 0FE0 07C0 0380 0000" - $"0003 0007" + $"0003 0007" }; data 'CURS' (3032, "icon") { @@ -282,7 +281,7 @@ data 'CURS' (3032, "icon") { $"A00B D005 A00B D005 AAAB D555 AAAB FFFF" $"FFFF FFFF FFFF FFFF F00F F00F F00F F00F" $"F00F F00F F00F F00F FFFF FFFF FFFF FFFF" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3033, "iron_cross") { @@ -290,7 +289,7 @@ data 'CURS' (3033, "iron_cross") { $"7FFE 799E 73CE 67E6 4FF2 1FF8 3FFC 0000" $"7FFE 7FFE FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF 7FFE 7FFE" - $"0007 0006" + $"0007 0006" }; data 'CURS' (3034, "left_ptr") { @@ -298,7 +297,7 @@ data 'CURS' (3034, "left_ptr") { $"0FF0 0F80 0D80 08C0 00C0 0060 0060 0000" $"1800 1C00 1E00 1F00 1F80 1FC0 1FE0 1FF0" $"1FF8 1FFC 1FC0 1DE0 19E0 10F0 00F0 0070" - $"0001 0004" + $"0001 0004" }; data 'CURS' (3035, "left_side") { @@ -306,7 +305,7 @@ data 'CURS' (3035, "left_side") { $"6400 6200 6100 6080 6000 6000 0000 0000" $"0000 0000 0000 0080 0100 0200 0400 0FFC" $"0400 0200 0100 0080 0000 0000 0000 0000" - $"0007 0004" + $"0007 0004" }; data 'CURS' (3036, "left_tee") { @@ -314,7 +313,7 @@ data 'CURS' (3036, "left_tee") { $"0FF8 0C00 0C00 0C00 0C00 0C00 0C00 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" - $"0007 0004" + $"0007 0004" }; data 'CURS' (3037, "leftbutton") { @@ -322,7 +321,7 @@ data 'CURS' (3037, "leftbutton") { $"4444 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 8002" $"FFFE FFFE FFFE FFFE FFFE FFFE FFFE FFFE" $"FFFE FFFE FFFE FFFE FFFE FFFE FFFE FFFE" - $"0004 0003" + $"0004 0003" }; data 'CURS' (3038, "ll_angle") { @@ -330,7 +329,7 @@ data 'CURS' (3038, "ll_angle") { $"0C00 0C00 0FF8 0FF8 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" - $"000B 0004" + $"000B 0004" }; data 'CURS' (3039, "lr_angle") { @@ -338,7 +337,7 @@ data 'CURS' (3039, "lr_angle") { $"0030 0030 1FF0 1FF0 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" - $"000B 000B" + $"000B 000B" }; data 'CURS' (3040, "man") { @@ -346,7 +345,7 @@ data 'CURS' (3040, "man") { $"0440 0280 0440 0920 1290 1450 783C F83F" $"0380 1FF0 0380 8100 4387 27CB 1FF0 07C0" $"07C0 0380 07C0 0FE0 1EF0 1C70 783C F83F" - $"0001 0007" + $"0001 0007" }; data 'CURS' (3041, "middlebutton") { @@ -354,7 +353,7 @@ data 'CURS' (3041, "middlebutton") { $"4444 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 8002" $"FFFE FFFE FFFE FFFE FFFE FFFE FFFE FFFE" $"FFFE FFFE FFFE FFFE FFFE FFFE FFFE FFFE" - $"0004 0007" + $"0004 0007" }; data 'CURS' (3042, "mouse") { @@ -362,7 +361,7 @@ data 'CURS' (3042, "mouse") { $"17E8 1008 1008 1008 1008 1008 1008 0FF0" $"0600 0100 0180 0FF0 1FF8 1FF8 1FF8 1FF8" $"1FF8 1FF8 1FF8 1FF8 1FF8 1FF8 1FF8 0FF0" - $"0000 0000" + $"0000 0000" }; data 'CURS' (3043, "pencil") { @@ -370,7 +369,7 @@ data 'CURS' (3043, "pencil") { $"0440 0880 0880 1100 1E00 1C00 1800 1000" $"0000 00F0 00F8 01F8 01F0 03F0 03E0 07C0" $"07C0 0F80 0F80 1F00 1E00 1C00 1800 1000" - $"000F 0003" + $"000F 0003" }; data 'CURS' (3044, "pirate") { @@ -378,7 +377,7 @@ data 'CURS' (3044, "pirate") { $"43C2 43C3 2184 1C38 03C0 0FF1 781F 4002" $"07E0 0FF0 1FF8 3FFC 3FFC 1FF8 0FF0 47E2" $"E7E7 E7E7 7FFF 3FFC 1FF9 7FFF FFFF F81F" - $"000A 0007" + $"000A 0007" }; data 'CURS' (3045, "plus") { @@ -386,7 +385,7 @@ data 'CURS' (3045, "plus") { $"1FF8 0180 0180 0180 0180 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3046, "question_arrow") { @@ -394,7 +393,7 @@ data 'CURS' (3046, "question_arrow") { $"0380 0280 0280 0EE0 06C0 0380 0100 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 3FF8 1FF0 0FE0 07C0 0380 0100" - $"000E 0007" + $"000E 0007" }; data 'CURS' (3047, "right_ptr") { @@ -402,7 +401,7 @@ data 'CURS' (3047, "right_ptr") { $"0FF0 01F0 01B0 0310 0300 0600 0600 0000" $"0018 0038 0078 00F8 01F8 03F8 07F8 0FF8" $"1FF8 3FF8 03F8 07B8 0798 0F08 0F00 0E00" - $"0001 000B" + $"0001 000B" }; data 'CURS' (3048, "right_side") { @@ -410,7 +409,7 @@ data 'CURS' (3048, "right_side") { $"3FF6 0026 0046 0086 0106 0006 0006 0000" $"0000 0000 0000 0000 0100 0080 0040 0020" $"3FF0 0020 0040 0080 0100 0000 0000 0000" - $"0008 000B" + $"0008 000B" }; data 'CURS' (3049, "right_tee") { @@ -418,7 +417,7 @@ data 'CURS' (3049, "right_tee") { $"1FF0 0030 0030 0030 0030 0030 0030 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" - $"0007 000A" + $"0007 000A" }; data 'CURS' (3050, "rightbutton") { @@ -426,7 +425,7 @@ data 'CURS' (3050, "rightbutton") { $"4444 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 8002" $"FFFE FFFE FFFE FFFE FFFE FFFE FFFE FFFE" $"FFFE FFFE FFFE FFFE FFFE FFFE FFFE FFFE" - $"0004 0003" + $"0004 0003" }; data 'CURS' (3051, "rtl_logo") { @@ -434,7 +433,7 @@ data 'CURS' (3051, "rtl_logo") { $"4422 4422 47FE 4402 4402 4402 7FFE 0000" $"0000 7FFE 7FFE 6076 7FF6 7FF6 7C36 6C36" $"6C36 6C3E 6FFE 6FFE 6E06 7FFE 7FFE 0000" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3052, "sailboat") { @@ -442,7 +441,7 @@ data 'CURS' (3052, "sailboat") { $"0770 0F78 0F78 1F78 1F7C 3E38 0000 0000" $"0040 00E0 01E0 03F0 03F0 07F0 07F8 0FF8" $"0FF8 1FFC 1FFC 3FFC 3FFE 7F7C 7E38 0000" - $"000C 0008" + $"000C 0008" }; data 'CURS' (3053, "sb_down_arrow") { @@ -450,7 +449,7 @@ data 'CURS' (3053, "sb_down_arrow") { $"0280 0280 0280 0FE0 07C0 0380 0100 0000" $"0380 0380 0380 0380 0380 0380 0380 0380" $"0380 0380 0380 1FF0 0FE0 07C0 0380 0100" - $"000E 0007" + $"000E 0007" }; data 'CURS' (3054, "sb_h_double_arrow") { @@ -458,7 +457,7 @@ data 'CURS' (3054, "sb_h_double_arrow") { $"3FFC 1818 0810 0000 0000 0000 0000 0000" $"0000 0000 0000 0810 1818 381C 7FFE FFFF" $"7FFE 381C 1818 0810 0000 0000 0000 0000" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3055, "sb_left_arrow") { @@ -466,7 +465,7 @@ data 'CURS' (3055, "sb_left_arrow") { $"3FFF 1800 0800 0000 0000 0000 0000 0000" $"0000 0000 0000 0800 1800 3800 7FFF FFFF" $"7FFF 3800 1800 0800 0000 0000 0000 0000" - $"0007 0001" + $"0007 0001" }; data 'CURS' (3056, "sb_right_arrow") { @@ -474,7 +473,7 @@ data 'CURS' (3056, "sb_right_arrow") { $"001E FFFC 0018 0010 0000 0000 0000 0000" $"0000 0000 0000 0000 0010 0018 001C FFFE" $"FFFF FFFE 001C 0018 0010 0000 0000 0000" - $"0008 000E" + $"0008 000E" }; data 'CURS' (3057, "sb_up_arrow") { @@ -482,7 +481,7 @@ data 'CURS' (3057, "sb_up_arrow") { $"0140 0140 0140 0140 0140 0140 0140 0140" $"0080 01C0 03E0 07F0 0FF8 01C0 01C0 01C0" $"01C0 01C0 01C0 01C0 01C0 01C0 01C0 01C0" - $"0001 0008" + $"0001 0008" }; data 'CURS' (3058, "sb_v_double_arrow") { @@ -490,7 +489,7 @@ data 'CURS' (3058, "sb_v_double_arrow") { $"0280 0280 0280 0FE0 07C0 0380 0100 0000" $"0100 0380 07C0 0FE0 1FF0 0380 0380 0380" $"0380 0380 0380 1FF0 0FE0 07C0 0380 0100" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3059, "shuttle") { @@ -498,7 +497,7 @@ data 'CURS' (3059, "shuttle") { $"11DE 11DE 31DE 71DE FDDE 1888 0078 0030" $"0020 0070 00F8 01FE 07FE 0FFE 1FFE 1FFE" $"1FFE 1FFE 3FFE 7FFE FFFE 18F8 0078 0030" - $"0000 000A" + $"0000 000A" }; data 'CURS' (3060, "sizing") { @@ -506,7 +505,7 @@ data 'CURS' (3060, "sizing") { $"4422 0422 07E2 0012 000A 0006 01FE 0000" $"FFC0 FFC0 FFC0 E000 EFF0 EFF0 EC37 EC37" $"EC37 EC37 0FF7 0FFF 001F 03FF 03FF 03FF" - $"000E 000E" + $"000E 000E" }; data 'CURS' (3061, "spider") { @@ -514,7 +513,7 @@ data 'CURS' (3061, "spider") { $"1FE0 6798 8787 0840 0840 1020 1020 2010" $"7038 3870 3870 1CE0 9FE7 EFDF FFFF 7FF8" $"7FF8 FFFF EFDF 9FE7 1CE0 3870 3870 7038" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3062, "spraycan") { @@ -522,7 +521,7 @@ data 'CURS' (3062, "spraycan") { $"2900 3900 2900 3900 3900 2100 2100 3F00" $"0000 0000 0C00 1E00 1E00 3F00 3F00 3F00" $"3F00 3F00 3F00 3F00 3F00 3F00 3F00 3F00" - $"0002 0007" + $"0002 0007" }; data 'CURS' (3063, "star") { @@ -530,7 +529,7 @@ data 'CURS' (3063, "star") { $"C006 3838 0920 1290 2448 2828 3018 2008" $"0100 0380 0380 0380 07C0 07C0 07C0 3FF8" $"FFFE 3FF8 0FE0 1EF0 3C78 3838 3018 2008" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3064, "target") { @@ -538,7 +537,7 @@ data 'CURS' (3064, "target") { $"C106 600C 3018 1C70 0FE0 0380 0000 0000" $"0000 0380 0FE0 1FF0 3C78 701C E38E E38E" $"E38E 701C 3C78 1FF0 0FE0 0380 0000 0000" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3065, "tcross") { @@ -546,7 +545,7 @@ data 'CURS' (3065, "tcross") { $"0100 0100 0100 0100 0100 0100 0100 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" - $"0007 0007" + $"0007 0007" }; data 'CURS' (3066, "top_left_arrow") { @@ -554,7 +553,7 @@ data 'CURS' (3066, "top_left_arrow") { $"0C80 0440 0420 0010 0008 0004 0000 0000" $"E000 F800 FE00 7F80 7FE0 3FF8 3FFE 1F80" $"1FC0 0EE0 0E70 0638 061C 020E 0204 0000" - $"0001 0001" + $"0001 0001" }; data 'CURS' (3067, "top_left_corner") { @@ -562,7 +561,7 @@ data 'CURS' (3067, "top_left_corner") { $"C880 C840 C020 C000 0000 0000 0000 0000" $"0000 0000 0000 0000 0FC0 0C00 0A00 0900" $"0880 0840 0020 0000 0000 0000 0000 0000" - $"0000 0000" + $"0000 0000" }; data 'CURS' (3068, "top_right_corner") { @@ -570,7 +569,7 @@ data 'CURS' (3068, "top_right_corner") { $"0113 0213 0403 0003 0000 0000 0000 0000" $"0000 0000 0000 0000 03F0 0030 0050 0090" $"0110 0210 0400 0000 0000 0000 0000 0000" - $"0000 000F" + $"0000 000F" }; data 'CURS' (3069, "top_side") { @@ -578,7 +577,7 @@ data 'CURS' (3069, "top_side") { $"1110 0100 0100 0100 0100 0100 0000 0000" $"0000 0000 0000 0000 0100 0380 0540 0920" $"1110 0100 0100 0100 0100 0100 0000 0000" - $"0004 0007" + $"0004 0007" }; data 'CURS' (3070, "top_tee") { @@ -586,7 +585,7 @@ data 'CURS' (3070, "top_tee") { $"0180 0180 0180 0180 0180 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" - $"0004 0007" + $"0004 0007" }; data 'CURS' (3071, "trek") { @@ -594,7 +593,7 @@ data 'CURS' (3071, "trek") { $"0380 0100 0BA0 0D60 0920 0820 0820 0000" $"0000 0380 07C0 0FE0 1FF0 1FF0 1FF0 0FE0" $"07C0 0BA0 1FF0 1FF0 1FF0 1D70 1C70 0820" - $"0000 0007" + $"0000 0007" }; data 'CURS' (3072, "ul_angle") { @@ -602,7 +601,7 @@ data 'CURS' (3072, "ul_angle") { $"0C00 0C00 0C00 0C00 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" - $"0003 0004" + $"0003 0004" }; data 'CURS' (3073, "umbrella") { @@ -610,7 +609,7 @@ data 'CURS' (3073, "umbrella") { $"0100 0100 0100 0100 0140 0140 0080 0000" $"0000 0FF0 1FF8 7FFE 7FFC FFFE FBBE E38E" $"0380 0380 0380 03C0 03E0 03E0 01C0 0080" - $"0004 0007" + $"0004 0007" }; data 'CURS' (3074, "ur_angle") { @@ -618,7 +617,7 @@ data 'CURS' (3074, "ur_angle") { $"0030 0030 0030 0030 0030 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" - $"0004 000B" + $"0004 000B" }; data 'CURS' (3075, "watch") { @@ -626,7 +625,7 @@ data 'CURS' (3075, "watch") { $"138C 1008 1008 0810 07E0 07E0 07E0 07E0" $"07E0 07E0 07E0 07E0 0FF0 1FF8 1FF8 1FFC" $"1FFC 1FF8 1FF8 0FF0 07E0 07E0 07E0 07E0" - $"0008 000D" + $"0008 000D" }; data 'CURS' (3076, "xterm") { @@ -634,12 +633,12 @@ data 'CURS' (3076, "xterm") { $"0100 0100 0100 0100 0100 0100 0280 0C60" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" - $"000B 0007" + $"000B 0007" }; /* - * The following are color versions of some of the - * cursors defined above. The color cursors will be + * The following are color versions of some of the + * cursors defined above. The color cursors will be * used if the exist in preference to the black & white * cursors. */ @@ -666,7 +665,7 @@ data 'crsr' (3004, "boat", purgeable) { $"FFFF 0001 BBBB BBBB BBBB 0002 EEEE EEEE" $"EEEE 0003 DDDD DDDD DDDD 0004 CCCC CCCC" $"CCCC 0005 4444 4444 4444 0006 1111 1111" - $"1111 000F 0000 0000 0000" + $"1111 000F 0000 0000 0000" }; data 'crsr' (3013, "clock") { @@ -691,7 +690,7 @@ data 'crsr' (3013, "clock") { $"FFFF 0001 4444 4444 4444 0002 AAAA AAAA" $"AAAA 0003 EEEE EEEE EEEE 0004 5555 5555" $"5555 0005 DDDD DDDD DDDD 0006 7777 7777" - $"7777 000F 0000 0000 0000" + $"7777 000F 0000 0000 0000" }; data 'crsr' (3014, "coffee_mug") { @@ -716,7 +715,7 @@ data 'crsr' (3014, "coffee_mug") { $"FFFF 0001 CCCC 9999 6666 0002 CCCC CCCC" $"FFFF 0003 3333 3333 6666 0004 9999 9999" $"FFFF 0005 6666 6666 CCCC 000F 0000 0000" - $"0000" + $"0000" }; data 'crsr' (3027, "gobbler") { @@ -741,7 +740,7 @@ data 'crsr' (3027, "gobbler") { $"FFFF 0001 CCCC 9999 6666 0002 DDDD 0000" $"0000 0003 FFFF 6666 3333 0004 CCCC CCCC" $"CCCC 0005 8888 8888 8888 0006 FFFF CCCC" - $"9999" + $"9999" }; data 'crsr' (3028, "gumby") { @@ -765,7 +764,7 @@ data 'crsr' (3028, "gumby") { $"F000 0000 0000 0000 0005 0000 FFFF FFFF" $"FFFF 0001 0000 BBBB 0000 0002 CCCC CCCC" $"CCCC 0003 AAAA AAAA AAAA 0004 4444 4444" - $"4444 000F 0000 0000 0000" + $"4444 000F 0000 0000 0000" }; data 'crsr' (3031, "heart") { @@ -784,7 +783,7 @@ data 'crsr' (3031, "heart") { $"9700 00D6 5C00 0035 7000 000F C000 0000" $"0000 0000 0000 0000 0003 0000 FFFF FFFF" $"FFFF 0001 DDDD 0000 0000 0002 FFFF 6666" - $"CCCC 0003 0000 0000 0000" + $"CCCC 0003 0000 0000 0000" }; data 'crsr' (3042, "mouse", purgeable) { @@ -811,7 +810,7 @@ data 'crsr' (3042, "mouse", purgeable) { $"4444 0005 2222 2222 2222 0006 5555 5555" $"5555 0007 AAAA AAAA AAAA 0008 BBBB BBBB" $"BBBB 0009 7777 7777 7777 000A 1111 1111" - $"1111 000F 0000 0000 0000" + $"1111 000F 0000 0000 0000" }; data 'crsr' (3043, "pencil", purgeable) { @@ -836,7 +835,7 @@ data 'crsr' (3043, "pencil", purgeable) { $"FFFF 0001 CCCC CCCC CCCC 0002 8888 8888" $"8888 0003 FFFF FFFF 0000 0004 DDDD 0000" $"0000 0005 FFFF 6666 3333 000F 0000 0000" - $"0000" + $"0000" }; data 'crsr' (3059, "shuttle") { @@ -861,7 +860,7 @@ data 'crsr' (3059, "shuttle") { $"FFFF 0001 FFFF 6666 3333 0002 DDDD 0000" $"0000 0003 4444 4444 4444 0004 8888 8888" $"8888 0005 DDDD DDDD DDDD 000F 0000 0000" - $"0000" + $"0000" }; data 'crsr' (3062, "spraycan") { @@ -888,7 +887,7 @@ data 'crsr' (3062, "spraycan") { $"2222 0005 4444 4444 4444 0006 BBBB BBBB" $"BBBB 0007 DDDD DDDD DDDD 0008 EEEE EEEE" $"EEEE 0009 6666 6666 CCCC 000A CCCC CCCC" - $"FFFF 000F 0000 0000 0000" + $"FFFF 000F 0000 0000 0000" }; data 'crsr' (3063, "star") { @@ -907,7 +906,7 @@ data 'crsr' (3063, "star") { $"D700 0D70 35C0 0DC0 0DC0 0F00 03C0 0C00" $"00C0 0000 0000 0000 0002 0000 FFFF FFFF" $"FFFF 0001 FFFF FFFF 0000 0003 0000 0000" - $"0000" + $"0000" }; data 'crsr' (3071, "trek") { @@ -932,7 +931,7 @@ data 'crsr' (3071, "trek") { $"FFFF 0001 EEEE EEEE EEEE 0002 9999 9999" $"FFFF 0003 DDDD DDDD DDDD 0004 3333 3333" $"6666 0005 DDDD 0000 0000 000F 0000 0000" - $"0000" + $"0000" }; data 'crsr' (3075, "watch", purgeable) { @@ -956,6 +955,6 @@ data 'crsr' (3075, "watch", purgeable) { $"0000 0000 0000 0000 0004 0000 FFFF FFFF" $"FFFF 0001 CCCC CCCC CCCC 0002 EEEE EEEE" $"EEEE 0003 BBBB BBBB BBBB 000F 0000 0000" - $"0000" + $"0000" }; diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c index ab81fb3..32886ce 100644 --- a/macosx/tkMacOSXXStubs.c +++ b/macosx/tkMacOSXXStubs.c @@ -1,18 +1,19 @@ -/* +/* * tkMacOSXXStubs.c -- * - * This file contains most of the X calls called by Tk. Many of - * these calls are just stubs and either don't make sense on the - * Macintosh or thier implamentation just doesn't do anything. Other - * calls will eventually be moved into other files. + * This file contains most of the X calls called by Tk. Many of + * these calls are just stubs and either don't make sense on the + * Macintosh or thier implamentation just doesn't do anything. Other + * calls will eventually be moved into other files. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net> * * 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.16 2006/09/10 17:06:32 das Exp $ + * RCS: @(#) $Id: tkMacOSXXStubs.c,v 1.17 2007/04/23 21:24:34 das Exp $ */ #include "tkMacOSXInt.h" @@ -22,14 +23,14 @@ /* * Because this file is still under major development Debugger statements are - * used through out this file. The define TCL_DEBUG will decide whether + * used through out this file. The define TCL_DEBUG will decide whether * the debugger statements actually call the debugger or not. */ #ifndef TCL_DEBUG # define Debugger() #endif - + #define ROOT_ID 10 /* @@ -37,30 +38,27 @@ */ static TkDisplay *gMacDisplay = NULL; /* Macintosh display. */ -static char *macScreenName = ":0"; /* Default name of macintosh display. */ +static const char *macScreenName = ":0"; /* Default name of macintosh display. */ /* * Forward declarations of procedures used in this file. */ -static XID MacXIdAlloc _ANSI_ARGS_((Display *display)); -static int DefaultErrorHandler _ANSI_ARGS_((Display* display, - XErrorEvent* err_evt)); +static XID MacXIdAlloc(Display *display); +static int DefaultErrorHandler(Display* display, XErrorEvent* err_evt); /* * Other declarations */ -static int TkMacOSXXDestroyImage _ANSI_ARGS_((XImage *image)); -static unsigned long TkMacOSXXGetPixel _ANSI_ARGS_((XImage *image, int x, int y)); -static int TkMacOSXXPutPixel _ANSI_ARGS_((XImage *image, int x, int y, - unsigned long pixel)); -static XImage *TkMacOSXXSubImage _ANSI_ARGS_((XImage *image, int x, int y, - unsigned int width, unsigned int height)); -static int TkMacOSXXAddPixel _ANSI_ARGS_((XImage *image, long value)); -int _XInitImageFuncPtrs _ANSI_ARGS_((XImage *image)); - +static int TkMacOSXXDestroyImage(XImage *image); +static unsigned long TkMacOSXXGetPixel(XImage *image, int x, int y); +static int TkMacOSXXPutPixel(XImage *image, int x, int y, unsigned long pixel); +static XImage *TkMacOSXXSubImage(XImage *image, int x, int y, + unsigned int width, unsigned int height); +static int TkMacOSXXAddPixel(XImage *image, long value); + /* *---------------------------------------------------------------------- * @@ -83,6 +81,7 @@ TkMacOSXDisplayChanged(Display *display) { GDHandle graphicsDevice; Screen *screen; + Rect bounds = {0, 0, 0, 0}, *maxBounds; if (display == NULL || display->screens == NULL) { return; @@ -90,15 +89,29 @@ TkMacOSXDisplayChanged(Display *display) screen = display->screens; graphicsDevice = GetMainDevice(); - screen->root_depth = (*(*graphicsDevice)->gdPMap)->cmpSize * - (*(*graphicsDevice)->gdPMap)->cmpCount; - screen->height = (*graphicsDevice)->gdRect.bottom - + screen->root_depth = (*(*graphicsDevice)->gdPMap)->cmpSize * + (*(*graphicsDevice)->gdPMap)->cmpCount; + screen->height = (*graphicsDevice)->gdRect.bottom - (*graphicsDevice)->gdRect.top; - screen->width = (*graphicsDevice)->gdRect.right - + screen->width = (*graphicsDevice)->gdRect.right - (*graphicsDevice)->gdRect.left; - screen->mwidth = (screen->width * 254 + 360) / 720; - screen->mheight = (screen->height * 254 + 360) / 720; + screen->mwidth = (screen->width * 254 + 360) / 720; + screen->mheight = (screen->height * 254 + 360) / 720; + + maxBounds = (Rect*) screen->ext_data; + *maxBounds = bounds; + graphicsDevice = GetDeviceList(); + while (graphicsDevice) { + OSStatus err; + + err = ChkErr(GetAvailableWindowPositioningBounds, graphicsDevice, + &bounds); + if (err == noErr) { + UnionRect(&bounds, maxBounds, maxBounds); + } + graphicsDevice = GetNextDevice(graphicsDevice); + } } /* @@ -124,7 +137,8 @@ TkpOpenDisplay( { Display *display; Screen *screen; - int fd = 0; + int fd = 0; + static Rect maxBounds = {0, 0, 0, 0}; if (gMacDisplay != NULL) { if (strcmp(gMacDisplay->display->display_name, display_name) == 0) { @@ -133,7 +147,6 @@ TkpOpenDisplay( return NULL; } } - InitCursor(); display = (Display *) ckalloc(sizeof(Display)); screen = (Screen *) ckalloc(sizeof(Screen)); @@ -141,13 +154,13 @@ TkpOpenDisplay( bzero(screen, sizeof(Screen)); display->resource_alloc = MacXIdAlloc; - display->request = 0; - display->qlen = 0; - display->fd = fd; - display->screens = screen; - display->nscreens = 1; + display->request = 0; + display->qlen = 0; + display->fd = fd; + display->screens = screen; + display->nscreens = 1; display->default_screen = 0; - display->display_name = macScreenName; + display->display_name = (char*)macScreenName; Gestalt(gestaltQuickdrawVersion, (long*)&display->proto_minor_version); display->proto_major_version = 10; @@ -158,14 +171,15 @@ TkpOpenDisplay( /* * These screen bits never change */ - screen->root = ROOT_ID; - screen->display = display; - screen->black_pixel = 0x00000000; - screen->white_pixel = 0x00FFFFFF; + screen->root = ROOT_ID; + screen->display = display; + screen->black_pixel = 0x00000000 | PIXEL_MAGIC << 24; + screen->white_pixel = 0x00FFFFFF | PIXEL_MAGIC << 24; + screen->ext_data = (XExtData*) &maxBounds; screen->root_visual = (Visual *) ckalloc(sizeof(Visual)); screen->root_visual->visualid = 0; - screen->root_visual->class = TrueColor; + screen->root_visual->class = TrueColor; screen->root_visual->red_mask = 0x00FF0000; screen->root_visual->green_mask = 0x0000FF00; screen->root_visual->blue_mask = 0x000000FF; @@ -211,15 +225,15 @@ TkpCloseDisplay( { Display *display = displayPtr->display; if (gMacDisplay != displayPtr) { - Tcl_Panic("TkpCloseDisplay: tried to call TkpCloseDisplay on bad display"); + Tcl_Panic("TkpCloseDisplay: tried to call TkpCloseDisplay on bad display"); } gMacDisplay = NULL; if (display->screens != (Screen *) NULL) { - if (display->screens->root_visual != (Visual *) NULL) { - ckfree((char *) display->screens->root_visual); - } - ckfree((char *) display->screens); + if (display->screens->root_visual != (Visual *) NULL) { + ckfree((char *) display->screens->root_visual); + } + ckfree((char *) display->screens); } ckfree((char *) display); } @@ -231,7 +245,7 @@ TkpCloseDisplay( * * This procedure is called to cleanup resources associated with * claiming clipboard ownership and for receiving selection get - * results. This function is called in tkWindow.c. This has to be + * results. This function is called in tkWindow.c. This has to be * called by the display cleanup function because we still need the * access display elements. * @@ -246,7 +260,7 @@ TkpCloseDisplay( void TkClipCleanup(dispPtr) - TkDisplay *dispPtr; /* display associated with clipboard */ + TkDisplay *dispPtr; /* display associated with clipboard */ { /* * Make sure that the local scrap is transfered to the global @@ -331,7 +345,7 @@ TkpWindowWasRecentlyDeleted( * * DefaultErrorHandler -- * - * This procedure is the default X error handler. Tk uses it's + * This procedure is the default X error handler. Tk uses it's * own error handler so this call should never be called. * * Results: @@ -349,7 +363,7 @@ DefaultErrorHandler( XErrorEvent* err_evt) { /* - * This call should never be called. Tk replaces + * This call should never be called. Tk replaces * it with its own error handler. */ Tcl_Panic("Warning hit bogus error handler!"); @@ -396,45 +410,45 @@ XGetImage(display, d, x, y, width, height, plane_mask, format) unsigned int height; unsigned long plane_mask; int format; -{ +{ XImage * imagePtr = NULL; Pixmap pixmap = (Pixmap) NULL; Tk_Window win = (Tk_Window) ((MacDrawable *) d)->winPtr; - GC gc; - int depth = 32; - int offset = 0; - int bitmap_pad = 32; - int bytes_per_line = 0; - + GC gc; + int depth = 32; + int offset = 0; + int bitmap_pad = 32; + int bytes_per_line = 0; + if (TkMacOSXGetDrawablePort(d)) { - if (format == ZPixmap) { - if (width > 0 && height > 0) { - /* Tk_GetPixmap fails for zero width or height */ - pixmap = Tk_GetPixmap(display, d, width, height, depth); - } - if (win) { - XGCValues values; - gc = Tk_GetGC(win, 0, &values); - } else { - gc = XCreateGC(display, pixmap, 0, NULL); - } - if (pixmap) { - XCopyArea(display, d, pixmap, gc, x, y, width, height, 0, 0); - } - imagePtr = XCreateImage(display, NULL, depth, format, offset, - (char*)TkMacOSXGetDrawablePort(pixmap), - width, height, bitmap_pad, bytes_per_line); - /* Track Pixmap underlying the XImage in the unused obdata field * - * so that we can treat XImages coming from XGetImage specially. */ - imagePtr->obdata = (XPointer) pixmap; - if (!win) { - XFreeGC(display, gc); - } - } else { - TkpDisplayWarning( - "XGetImage: only ZPixmap types are implemented", - "XGetImage Failure"); - } + if (format == ZPixmap) { + if (width > 0 && height > 0) { + /* Tk_GetPixmap fails for zero width or height */ + pixmap = Tk_GetPixmap(display, d, width, height, depth); + } + if (win) { + XGCValues values; + gc = Tk_GetGC(win, 0, &values); + } else { + gc = XCreateGC(display, pixmap, 0, NULL); + } + if (pixmap) { + XCopyArea(display, d, pixmap, gc, x, y, width, height, 0, 0); + } + imagePtr = XCreateImage(display, NULL, depth, format, offset, + (char*)TkMacOSXGetDrawablePort(pixmap), + width, height, bitmap_pad, bytes_per_line); + /* Track Pixmap underlying the XImage in the unused obdata field * + * so that we can treat XImages coming from XGetImage specially. */ + imagePtr->obdata = (XPointer) pixmap; + if (!win) { + XFreeGC(display, gc); + } + } else { + TkpDisplayWarning( + "XGetImage: only ZPixmap types are implemented", + "XGetImage Failure"); + } } return imagePtr; } @@ -462,17 +476,18 @@ XGetGeometry(display, d, root_return, x_return, y_return, width_return, *width_return = Tk_Width(winPtr); *height_return = Tk_Height(winPtr); *border_width_return = winPtr->changes.border_width; - *depth_return = Tk_Depth(winPtr); + *depth_return = Tk_Depth(winPtr); } else { Rect boundsRect; CGrafPtr destPort = TkMacOSXGetDrawablePort(d); - GetPortBounds(destPort,&boundsRect); + + GetPortBounds(destPort, &boundsRect); *x_return = boundsRect.left; *y_return = boundsRect.top; *width_return = boundsRect.right - boundsRect.left; *height_return = boundsRect.bottom - boundsRect.top; - *border_width_return = 0; - *depth_return = 32; + *border_width_return = 0; + *depth_return = 32; } return 1; } @@ -516,23 +531,23 @@ XSetWMNormalHints( XSizeHints* hints) { /* - * Do nothing. Shouldn't even be called. + * Do nothing. Shouldn't even be called. */ } XSizeHints * -XAllocSizeHints() +XAllocSizeHints(void) { /* - * Always return NULL. Tk code checks to see if NULL + * Always return NULL. Tk code checks to see if NULL * is returned & does nothing if it is. */ - + return NULL; } #endif -XImage * +XImage * XCreateImage( Display* display, Visual* visual, @@ -544,7 +559,7 @@ XCreateImage( unsigned int height, int bitmap_pad, int bytes_per_line) -{ +{ XImage *ximage; display->request++; @@ -660,15 +675,15 @@ XQueryColor( unsigned char r, g, b; XColor *d = def_in_out; - p = d->pixel; - r = (p & 0x00FF0000) >> 16; - g = (p & 0x0000FF00) >> 8; - b = (p & 0x000000FF); - d->red = (r << 8) | r; + p = d->pixel; + r = (p & 0x00FF0000) >> 16; + g = (p & 0x0000FF00) >> 8; + b = (p & 0x000000FF); + d->red = (r << 8) | r; d->green = (g << 8) | g; - d->blue = (b << 8) | b; + d->blue = (b << 8) | b; d->flags = DoRed|DoGreen|DoBlue; - d->pad = 0; + d->pad = 0; } void @@ -684,21 +699,21 @@ XQueryColors( XColor *d = defs_in_out; for (i = 0; i < ncolors; i++, d++) { - p = d->pixel; - r = (p & 0x00FF0000) >> 16; - g = (p & 0x0000FF00) >> 8; - b = (p & 0x000000FF); - d->red = (r << 8) | r; + p = d->pixel; + r = (p & 0x00FF0000) >> 16; + g = (p & 0x0000FF00) >> 8; + b = (p & 0x000000FF); + d->red = (r << 8) | r; d->green = (g << 8) | g; - d->blue = (b << 8) | b; + d->blue = (b << 8) | b; d->flags = DoRed|DoGreen|DoBlue; - d->pad = 0; + d->pad = 0; } } -int +int XQueryTree(display, w, root_return, parent_return, children_return, - nchildren_return) + nchildren_return) Display* display; Window w; Window* root_return; @@ -739,7 +754,7 @@ XRefreshKeyboardMapping( XMappingEvent* x) Debugger(); } -void +void XSetIconName( Display* display, Window w, @@ -751,15 +766,15 @@ XSetIconName( display->request++; } -void +void XForceScreenSaver( Display* display, int mode) { - /* - * This function is just a no-op. It is defined to - * reset the screen saver. However, there is no real - * way to do this on a Mac. Let me know if there is! + /* + * This function is just a no-op. It is defined to + * reset the screen saver. However, there is no real + * way to do this on a Mac. Let me know if there is! */ display->request++; } @@ -786,7 +801,7 @@ XSync (Display *display, Bool flag) * TkGetServerInfo -- * * Given a window, this procedure returns information about - * the window server for that window. This procedure provides + * the window server for that window. This procedure provides * the guts of the "winfo server" command. * * Results: @@ -802,7 +817,7 @@ void TkGetServerInfo( Tcl_Interp *interp, /* The server information is returned in * this interpreter's result. */ - Tk_Window tkwin) /* Token for window; this selects a + Tk_Window tkwin) /* Token for window; this selects a * particular display and server. */ { char buffer[8 + TCL_INTEGER_SPACE * 2]; @@ -812,77 +827,83 @@ TkGetServerInfo( ProtocolRevision(Tk_Display(tkwin))); sprintf(buffer2, " %x", VendorRelease(Tk_Display(tkwin))); Tcl_AppendResult(interp, buffer, ServerVendor(Tk_Display(tkwin)), - buffer2, (char *) NULL); + buffer2, NULL); } /* - * Image stuff + * Image stuff */ -static int +static int TkMacOSXXDestroyImage( XImage *image) { if (image->obdata) - Tk_FreePixmap((Display*)gMacDisplay,(Pixmap)image->obdata); + Tk_FreePixmap((Display*)gMacDisplay,(Pixmap)image->obdata); return 0; } -static unsigned long +static unsigned long TkMacOSXXGetPixel( XImage *image, int x, int y) { - CGrafPtr grafPtr, oldPort; + CGrafPtr destPort, savePort; + Boolean portChanged; RGBColor cPix; unsigned long r, g, b, c; - grafPtr = (CGrafPtr)image->data; - GetPort(&oldPort); - SetPort(grafPtr); - GetCPixel(x,y,&cPix); + + destPort = (CGrafPtr)image->data; + portChanged = QDSwapPort(destPort, &savePort); + GetCPixel(x, y, &cPix); if (image->obdata) { - /* Image from XGetImage, 16 bit color values */ - r = (cPix . red) >> 8; - g = (cPix . green) >> 8; - b = (cPix . blue) >> 8; + /* Image from XGetImage, 16 bit color values */ + r = (cPix . red) >> 8; + g = (cPix . green) >> 8; + b = (cPix . blue) >> 8; } else { - r = cPix . red; - g = cPix . green; - b = cPix . blue; + r = cPix . red; + g = cPix . green; + b = cPix . blue; } c = (r<<16)|(g<<8)|(b); - SetPort(oldPort); + if (portChanged) { + QDSwapPort(savePort, NULL); + } return c; } -static int +static int TkMacOSXXPutPixel( XImage *image, int x, int y, unsigned long pixel) { - CGrafPtr grafPtr, oldPort; + CGrafPtr destPort, savePort; + Boolean portChanged; RGBColor cPix; unsigned long r, g, b; - grafPtr = (CGrafPtr)image->data; - GetPort(&oldPort); - SetPort(grafPtr); + + destPort = (CGrafPtr)image->data; + portChanged = QDSwapPort(destPort, &savePort); r = (pixel & image->red_mask)>>16; g = (pixel & image->green_mask)>>8; b = (pixel & image->blue_mask); if (image->obdata) { - /* Image from XGetImage, 16 bit color values */ - cPix . red = r << 8; - cPix . green = g << 8; - cPix . blue = b << 8; + /* Image from XGetImage, 16 bit color values */ + cPix . red = r << 8; + cPix . green = g << 8; + cPix . blue = b << 8; } else { - cPix . red = r; - cPix . green = g; - cPix . blue = b; + cPix . red = r; + cPix . green = g; + cPix . blue = b; + } + SetCPixel(x, y, &cPix); + if (portChanged) { + QDSwapPort(savePort, NULL); } - SetCPixel(x,y,&cPix); - SetPort(oldPort); return 0; } @@ -898,7 +919,7 @@ TkMacOSXXSubImage( return NULL; } -static int +static int TkMacOSXXAddPixel( XImage *image, long value) @@ -914,7 +935,7 @@ TkMacOSXXAddPixel( * XSetWindowBackgroundPixmap, XSetWindowBorder, XSetWindowBorderPixmap, * XSetWindowBorderWidth, XSetWindowColormap * - * These functions are all no-ops. They all have equivilent + * These functions are all no-ops. They all have equivilent * Tk calls that should always be used instead. * * Results: @@ -935,7 +956,7 @@ XChangeWindowAttributes( { } -void +void XSetWindowBackground( Display *display, Window window, @@ -986,8 +1007,8 @@ XSetWindowColormap( Status XStringListToTextProperty( - char** list, - int count, + char** list, + int count, XTextProperty* text_prop_return) { Debugger(); @@ -995,8 +1016,8 @@ XStringListToTextProperty( } void XSetWMClientMachine( - Display* display, - Window w, + Display* display, + Window w, XTextProperty* text_prop) { Debugger(); @@ -1042,7 +1063,7 @@ TkGetDefaultScreenName( /* *---------------------------------------------------------------------- - * + * * Tk_GetUserInactiveTime -- * * Return the number of milliseconds the user was inactive. diff --git a/macosx/ttkMacOSXTheme.c b/macosx/ttkMacOSXTheme.c index e2bd709..31e3668 100644 --- a/macosx/ttkMacOSXTheme.c +++ b/macosx/ttkMacOSXTheme.c @@ -1,10 +1,11 @@ /* - * $Id: ttkMacOSXTheme.c,v 1.5 2006/12/30 23:23:26 cc_benny Exp $ + * ttkMacOSXTheme.c -- * - * Tk theme engine for Mac OSX, using the Appearance Manager API. + * Tk theme engine for Mac OSX, using the Appearance Manager API. * * Copyright (c) 2004 Joe English * Copyright (c) 2005 Neil Madden + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -12,30 +13,27 @@ * See also: * * <URL: http://developer.apple.com/documentation/Carbon/Reference/ - * Appearance_Manager/appearance_manager/APIIndex.html > + * Appearance_Manager/appearance_manager/APIIndex.html > * * Notes: - * "Active" means different things in Mac and Tk terminology -- + * "Active" means different things in Mac and Tk terminology -- * On Aqua, widgets are "Active" if they belong to the foreground window, * "Inactive" if they are in a background window. * Tk/ttk uses the term "active" to mean that the mouse cursor * is over a widget; aka "hover", "prelight", or "hot-tracked". * (Aqua doesn't use this kind of feedback). * - * The QuickDraw/Carbon coordinate system is relative to the - * top-level window, *not* to the Tk_Window. However, + * The QuickDraw/Carbon coordinate system is relative to the + * top-level window, *not* to the Tk_Window. However, * since we're drawing into an off-screen port (Tk "Pixmap), * we don't need to account for this. + * + * RCS: @(#) $Id: ttkMacOSXTheme.c,v 1.6 2007/04/23 21:24:34 das Exp $ */ #include "tkMacOSXInt.h" #include "ttk/ttkTheme.h" -/* Define a constant that was renamed for Mac OS X 10.4 */ -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1040 -#define kThemeDisclosureTriangle kThemeDisclosureButton -#endif - /*---------------------------------------------------------------------- * +++ Utilities. */ @@ -44,6 +42,7 @@ static Rect BoxToRect(Ttk_Box b) { Rect rect; + rect.top = b.y; rect.left = b.x; rect.bottom = b.y + b.height; @@ -52,18 +51,24 @@ Rect BoxToRect(Ttk_Box b) } /* DontErase -- - * No-op ThemeEraseProc, can be passed to DrawThemeButton &c. + * No-op ThemeEraseProc, can be passed to DrawThemeButton &c. */ static void DontErase( const Rect *bounds, UInt32 eraseData, SInt16 depth, Boolean isColorDev) { } -#define BEGIN_DRAWING(d) { \ - CGrafPtr saveWorld; GDHandle saveDevice; \ - GetGWorld(&saveWorld, &saveDevice); \ - SetGWorld(TkMacOSXGetDrawablePort(d), 0) ; -#define END_DRAWING \ - SetGWorld(saveWorld,saveDevice); } +#define BEGIN_DRAWING(d) do { \ + TkMacOSXDrawingContext dc; \ + TkMacOSXSetupDrawingContext((d), NULL, 0, &dc) +#define END_DRAWING() \ + TkMacOSXRestoreDrawingContext(&dc); \ + } while (0) +#define OFFSET_RECT(d, r) do { \ + OffsetRect(&(r), ((MacDrawable*)(d))->xOff, ((MacDrawable*)(d))->yOff);\ + } while (0) +#define OFFSET_POINT(d, p) do { \ + (p).h += ((MacDrawable*)(d))->xOff; (p).v += ((MacDrawable*)(d))->yOff;\ + } while (0) /* Table mapping Tk states to Appearance manager ThemeStates */ @@ -86,7 +91,7 @@ static Ttk_StateTable ThemeStateTable[] = { }; /*---------------------------------------------------------------------- - * +++ Button element: Used for elements drawn with DrawThemeButton. + * +++ Button element: Used for elements drawn with DrawThemeButton. */ /* Extra margins to account for drop shadow. @@ -96,8 +101,8 @@ static Ttk_Padding ButtonMargins = {2,2,2,2}; #define NoThemeMetric 0xFFFFFFFF typedef struct { - ThemeButtonKind kind; - ThemeMetric heightMetric; + ThemeButtonKind kind; + ThemeMetric heightMetric; } ThemeButtonParms; static ThemeButtonParms @@ -130,6 +135,7 @@ static ThemeButtonDrawInfo computeButtonDrawInfo( ThemeButtonParms *parms, Ttk_State state) { ThemeButtonDrawInfo info; + info.state = Ttk_StateTableLookup(ThemeStateTable, state); info.value = Ttk_StateTableLookup(ButtonValueTable, state); info.adornment = Ttk_StateTableLookup(ButtonAdornmentTable, state); @@ -144,6 +150,7 @@ static void ButtonElementGeometryNoPadding( if (parms->heightMetric != NoThemeMetric) { SInt32 gratuitouslyOverspecifiedType; + GetThemeMetric(parms->heightMetric, &gratuitouslyOverspecifiedType); *heightPtr = gratuitouslyOverspecifiedType; } @@ -158,9 +165,8 @@ static void ButtonElementGeometry( Rect scratchRect, contentsRect; const int scratchSize = 100; - ButtonElementGeometryNoPadding( - clientData, elementRecord, tkwin, - widthPtr, heightPtr, paddingPtr); + ButtonElementGeometryNoPadding(clientData, elementRecord, tkwin, widthPtr, + heightPtr, paddingPtr); /* To compute internal padding, query the appearance manager * for the content bounds of a dummy rectangle, then use @@ -192,14 +198,14 @@ static void ButtonElementDraw( ThemeButtonParms *parms = clientData; ThemeButtonDrawInfo info = computeButtonDrawInfo(parms, state); - BEGIN_DRAWING(d) + OFFSET_RECT(d, bounds); + BEGIN_DRAWING(d); DrawThemeButton(&bounds, parms->kind, &info, NULL/*prevInfo*/,NULL/*eraseProc*/,NULL/*labelProc*/,0/*userData*/); - END_DRAWING + END_DRAWING(); } -static Ttk_ElementSpec ButtonElementSpec = -{ +static Ttk_ElementSpec ButtonElementSpec = { TK_STYLE_VERSION_2, sizeof(NullElement), TtkNullElementOptions, @@ -214,7 +220,7 @@ static Ttk_ElementSpec ButtonElementSpec = static Ttk_StateTable TabStyleTable[] = { { kThemeTabFrontInactive, TTK_STATE_SELECTED|TTK_STATE_BACKGROUND, 0 }, { kThemeTabNonFrontInactive, TTK_STATE_BACKGROUND, 0 }, - { kThemeTabFrontUnavailable, TTK_STATE_DISABLED|TTK_STATE_SELECTED, 0 }, + { kThemeTabFrontUnavailable, TTK_STATE_DISABLED|TTK_STATE_SELECTED, 0 }, { kThemeTabNonFrontUnavailable, TTK_STATE_DISABLED, 0 }, { kThemeTabFront, TTK_STATE_SELECTED, 0 }, { kThemeTabNonFrontPressed, TTK_STATE_PRESSED, 0 }, @@ -243,16 +249,17 @@ static void TabElementDraw( Drawable d, Ttk_Box b, Ttk_State state) { Rect bounds = BoxToRect(b); + bounds.bottom += TAB_OVERLAP; - BEGIN_DRAWING(d) + OFFSET_RECT(d, bounds); + BEGIN_DRAWING(d); DrawThemeTab( - &bounds, Ttk_StateTableLookup(TabStyleTable, state), kThemeTabNorth, + &bounds, Ttk_StateTableLookup(TabStyleTable, state), kThemeTabNorth, 0/*labelProc*/,0/*userData*/); - END_DRAWING + END_DRAWING(); } -static Ttk_ElementSpec TabElementSpec = -{ +static Ttk_ElementSpec TabElementSpec = { TK_STYLE_VERSION_2, sizeof(NullElement), TtkNullElementOptions, @@ -275,14 +282,15 @@ static void PaneElementDraw( Drawable d, Ttk_Box b, Ttk_State state) { Rect bounds = BoxToRect(b); - BEGIN_DRAWING(d) + + OFFSET_RECT(d, bounds); + BEGIN_DRAWING(d); DrawThemeTabPane( - &bounds, Ttk_StateTableLookup(ThemeStateTable, state)); - END_DRAWING + &bounds, Ttk_StateTableLookup(ThemeStateTable, state)); + END_DRAWING(); } -static Ttk_ElementSpec PaneElementSpec = -{ +static Ttk_ElementSpec PaneElementSpec = { TK_STYLE_VERSION_2, sizeof(NullElement), TtkNullElementOptions, @@ -311,14 +319,14 @@ static void GroupElementDraw( Drawable d, Ttk_Box b, Ttk_State state) { Rect bounds = BoxToRect(b); - BEGIN_DRAWING(d) + OFFSET_RECT(d, bounds); + BEGIN_DRAWING(d); DrawThemePrimaryGroup( - &bounds, Ttk_StateTableLookup(ThemeStateTable, state)); - END_DRAWING + &bounds, Ttk_StateTableLookup(ThemeStateTable, state)); + END_DRAWING(); } -static Ttk_ElementSpec GroupElementSpec = -{ +static Ttk_ElementSpec GroupElementSpec = { TK_STYLE_VERSION_2, sizeof(NullElement), TtkNullElementOptions, @@ -327,9 +335,9 @@ static Ttk_ElementSpec GroupElementSpec = }; /*---------------------------------------------------------------------- - * +++ Entry element -- - * 3 pixels padding for focus rectangle - * 2 pixels padding for EditTextFrame + * +++ Entry element -- + * 3 pixels padding for focus rectangle + * 2 pixels padding for EditTextFrame */ typedef struct { @@ -358,29 +366,27 @@ static void EntryElementDraw( Ttk_Box inner = Ttk_PadBox(b, Ttk_UniformPadding(3)); Rect bounds = BoxToRect(inner); - BEGIN_DRAWING(d) - /* Erase w/background color: */ XFillRectangle(Tk_Display(tkwin), d, Tk_3DBorderGC(tkwin, backgroundPtr, TK_3D_FLAT_GC), inner.x,inner.y, inner.width, inner.height); + OFFSET_RECT(d, bounds); + BEGIN_DRAWING(d); /* Draw border: */ DrawThemeEditTextFrame( - &bounds, Ttk_StateTableLookup(ThemeStateTable, state)); + &bounds, Ttk_StateTableLookup(ThemeStateTable, state)); /* Draw focus highlight: */ if (state & TTK_STATE_FOCUS) DrawThemeFocusRect(&bounds, 1); - - END_DRAWING + END_DRAWING(); } -static Ttk_ElementSpec EntryElementSpec = -{ +static Ttk_ElementSpec EntryElementSpec = { TK_STYLE_VERSION_2, sizeof(EntryElement), EntryElementOptions, @@ -395,7 +401,7 @@ static Ttk_ElementSpec EntryElementSpec = */ static void PopupArrowElementGeometry( - void *clientData, void *elementRecord, Tk_Window tkwin, + void *clientData, void *elementRecord, Tk_Window tkwin, int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) { *widthPtr = 12; /* wild-assed guess */ @@ -403,11 +409,10 @@ static void PopupArrowElementGeometry( } static void PopupArrowElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, + void *clientData, void *elementRecord, Tk_Window tkwin, Drawable d, Ttk_Box b, Ttk_State state) { Rect bounds = BoxToRect(b); - ThemeButtonParms *parms = clientData; ThemeButtonDrawInfo info = computeButtonDrawInfo(parms, state); @@ -416,7 +421,8 @@ static void PopupArrowElementDraw( bounds.right -= 6; bounds.bottom -= 2; - BEGIN_DRAWING(d) + OFFSET_RECT(d, bounds); + BEGIN_DRAWING(d); DrawThemeButton(&bounds, kThemeArrowButton, &info, NULL/*prevInfo*/,NULL/*eraseProc*/,NULL/*labelProc*/,0/*userData*/); @@ -426,16 +432,16 @@ static void PopupArrowElementDraw( bounds.left -= 2; bounds.right -= 2; + OFFSET_RECT(d, bounds); DrawThemePopupArrow(&bounds, - kThemeArrowDown, + kThemeArrowDown, kThemeArrow9pt, /* ??? */ Ttk_StateTableLookup(ThemeStateTable, state), NULL /*eraseProc*/,0/*eraseData*/); - END_DRAWING + END_DRAWING(); } -static Ttk_ElementSpec PopupArrowElementSpec = -{ +static Ttk_ElementSpec PopupArrowElementSpec = { TK_STYLE_VERSION_2, sizeof(NullElement), TtkNullElementOptions, @@ -445,7 +451,7 @@ static Ttk_ElementSpec PopupArrowElementSpec = /*---------------------------------------------------------------------- * +++ DrawThemeTrack-based elements -- - * Progress bars and scales. (See also: <<NOTE-TRACKS>>) + * Progress bars and scales. (See also: <<NOTE-TRACKS>>) */ static Ttk_StateTable ThemeTrackEnableTable[] = { @@ -460,14 +466,15 @@ typedef struct { /* TrackElement client data */ SInt32 thicknessMetric; } TrackElementData; -static TrackElementData ScaleData = - { kThemeSlider, kThemeMetricHSliderHeight }; +static TrackElementData ScaleData = { + kThemeSlider, kThemeMetricHSliderHeight +}; typedef struct { Tcl_Obj *fromObj; /* minimum value */ Tcl_Obj *toObj; /* maximum value */ Tcl_Obj *valueObj; /* current value */ - Tcl_Obj *orientObj; /* horizontal / vertical */ + Tcl_Obj *orientObj; /* horizontal / vertical */ } TrackElement; static Ttk_ElementOptionSpec TrackElementOptions[] = { @@ -484,6 +491,7 @@ static void TrackElementGeometry( { TrackElementData *data = clientData; SInt32 size = 24; /* reasonable default ... */ + GetThemeMetric(data->thicknessMetric, &size); *widthPtr = *heightPtr = size; } @@ -518,20 +526,21 @@ static void TrackElementDraw( drawInfo.enableState = Ttk_StateTableLookup(ThemeTrackEnableTable, state); switch (data->kind) { - case kThemeProgressBar: - drawInfo.trackInfo.progress.phase = 0; /* 1-4: animation phase */ - break; - case kThemeSlider: - drawInfo.trackInfo.slider.pressState = 0; /* @@@ fill this in */ - drawInfo.trackInfo.slider.thumbDir = kThemeThumbPlain; - /* kThemeThumbUpward, kThemeThumbDownward, kThemeThumbPlain */ - break; + case kThemeProgressBar: + drawInfo.trackInfo.progress.phase = 0; /* 1-4: animation phase */ + break; + case kThemeSlider: + drawInfo.trackInfo.slider.pressState = 0; /* @@@ fill this in */ + drawInfo.trackInfo.slider.thumbDir = kThemeThumbPlain; + /* kThemeThumbUpward, kThemeThumbDownward, kThemeThumbPlain */ + break; } - BEGIN_DRAWING(d) + OFFSET_RECT(d, drawInfo.bounds); + BEGIN_DRAWING(d); DrawThemeTrack(&drawInfo, - NULL/*rgnGhost*/,NULL/*eraseProc*/,0/*eraseData*/); - END_DRAWING + NULL/*rgnGhost*/,NULL/*eraseProc*/,0/*eraseData*/); + END_DRAWING(); } static Ttk_ElementSpec TrackElementSpec = { @@ -544,8 +553,8 @@ static Ttk_ElementSpec TrackElementSpec = { /* Slider element -- <<NOTE-TRACKS>> - * Has geometry only. The Scale widget adjusts the position of this element, - * and uses it for hit detection. In the Aqua theme, the slider is actually + * Has geometry only. The Scale widget adjusts the position of this element, + * and uses it for hit detection. In the Aqua theme, the slider is actually * drawn as part of the trough element. * * Also buggy: The geometry here is a Wild-Assed-Guess; I can't @@ -569,14 +578,14 @@ static Ttk_ElementSpec SliderElementSpec = { /*---------------------------------------------------------------------- * +++ Progress bar element (new): - * + * * @@@ NOTE: According to an older revision of the Aqua reference docs, - * @@@ the 'phase' field is between 0 and 4. Newer revisions say + * @@@ the 'phase' field is between 0 and 4. Newer revisions say * @@@ that it can be any UInt8 value. */ typedef struct { - Tcl_Obj *orientObj; /* horizontal / vertical */ + Tcl_Obj *orientObj; /* horizontal / vertical */ Tcl_Obj *valueObj; /* current value */ Tcl_Obj *maximumObj; /* maximum value */ Tcl_Obj *phaseObj; /* animation phase */ @@ -584,16 +593,16 @@ typedef struct { } PbarElement; static Ttk_ElementOptionSpec PbarElementOptions[] = { - { "-orient", TK_OPTION_STRING, + { "-orient", TK_OPTION_STRING, Tk_Offset(PbarElement,orientObj), "horizontal" }, { "-value", TK_OPTION_DOUBLE, - Tk_Offset(PbarElement,valueObj), "0" }, + Tk_Offset(PbarElement,valueObj), "0" }, { "-maximum", TK_OPTION_DOUBLE, - Tk_Offset(PbarElement,maximumObj), "100" }, + Tk_Offset(PbarElement,maximumObj), "100" }, { "-phase", TK_OPTION_INT, - Tk_Offset(PbarElement,phaseObj), "0" }, - { "-mode", TK_OPTION_STRING, - Tk_Offset(PbarElement,modeObj), "determinate" }, + Tk_Offset(PbarElement,phaseObj), "0" }, + { "-mode", TK_OPTION_STRING, + Tk_Offset(PbarElement,modeObj), "determinate" }, {0,0,0,0} }; @@ -602,6 +611,7 @@ static void PbarElementGeometry( int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) { SInt32 size = 24; /* @@@ Check HIG for correct default */ + GetThemeMetric(kThemeMetricLargeProgressBarThickness, &size); *widthPtr = *heightPtr = size; } @@ -636,10 +646,11 @@ static void PbarElementDraw( drawInfo.enableState = Ttk_StateTableLookup(ThemeTrackEnableTable, state); drawInfo.trackInfo.progress.phase = phase; - BEGIN_DRAWING(d) + OFFSET_RECT(d, drawInfo.bounds); + BEGIN_DRAWING(d); DrawThemeTrack(&drawInfo, - NULL/*rgnGhost*/,NULL/*eraseProc*/,0/*eraseData*/); - END_DRAWING + NULL/*rgnGhost*/,NULL/*eraseProc*/,0/*eraseData*/); + END_DRAWING(); } static Ttk_ElementSpec PbarElementSpec = { @@ -674,13 +685,13 @@ static void SeparatorElementDraw( /* DrawThemeSeparator only supports kThemeStateActive / kThemeStateInactive */ state &= TTK_STATE_BACKGROUND; - BEGIN_DRAWING(d) + OFFSET_RECT(d, bounds); + BEGIN_DRAWING(d); DrawThemeSeparator(&bounds, Ttk_StateTableLookup(ThemeStateTable, state)); - END_DRAWING + END_DRAWING(); } -static Ttk_ElementSpec SeparatorElementSpec = -{ +static Ttk_ElementSpec SeparatorElementSpec = { TK_STYLE_VERSION_2, sizeof(NullElement), TtkNullElementOptions, @@ -691,19 +702,18 @@ static Ttk_ElementSpec SeparatorElementSpec = /*---------------------------------------------------------------------- * +++ Size grip element. */ -static const ThemeGrowDirection sizegripGrowDirection +static const ThemeGrowDirection sizegripGrowDirection = kThemeGrowRight|kThemeGrowDown; static void SizegripElementSize( void *clientData, void *elementRecord, Tk_Window tkwin, int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) { - Point origin; + Point origin = {0, 0}; Rect bounds; - origin.h = origin.v = 0; GetThemeStandaloneGrowBoxBounds( - origin, sizegripGrowDirection, false, &bounds); + origin, sizegripGrowDirection, false, &bounds); *widthPtr = bounds.right - bounds.left; *heightPtr = bounds.bottom - bounds.top; } @@ -713,20 +723,21 @@ static void SizegripElementDraw( Drawable d, Ttk_Box b, unsigned int state) { Point origin; + origin.h = b.x; origin.v = b.y; /* Grow box only supports kThemeStateActive, kThemeStateInactive */ state &= TTK_STATE_BACKGROUND; - BEGIN_DRAWING(d) + OFFSET_POINT(d, origin); + BEGIN_DRAWING(d); DrawThemeStandaloneGrowBox( - origin, sizegripGrowDirection, false, + origin, sizegripGrowDirection, false, Ttk_StateTableLookup(ThemeStateTable, state)); - END_DRAWING + END_DRAWING(); } -static Ttk_ElementSpec SizegripElementSpec = -{ +static Ttk_ElementSpec SizegripElementSpec = { TK_STYLE_VERSION_2, sizeof(NullElement), TtkNullElementOptions, @@ -743,18 +754,18 @@ static Ttk_ElementSpec SizegripElementSpec = * and the type of the top-level window. * * Also: patterned backgrounds should be aligned with the coordinate - * system of the top-level window. Since we're drawing into an - * off-screen graphics port with its own coordinate system, + * system of the top-level window. Since we're drawing into an + * off-screen graphics port with its own coordinate system, * this leads to alignment glitches. * * Available kTheme constants: - * kThemeBackgroundTabPane, - * kThemeBackgroundPlacard, - * kThemeBackgroundWindowHeader, - * kThemeBackgroundListViewWindowHeader, - * kThemeBackgroundSecondaryGroupBox, + * kThemeBackgroundTabPane, + * kThemeBackgroundPlacard, + * kThemeBackgroundWindowHeader, + * kThemeBackgroundListViewWindowHeader, + * kThemeBackgroundSecondaryGroupBox, * - * GetThemeBrush() and SetThemeBackground() offer more choices. + * GetThemeBrush() and SetThemeBackground() offer more choices. * */ @@ -781,17 +792,18 @@ static void BackgroundElementDraw( bounds.right = Tk_Width(tkwin); bounds.bottom = Tk_Height(tkwin); - BEGIN_DRAWING(d) + OFFSET_POINT(d, origin); + OFFSET_RECT(d, bounds); + BEGIN_DRAWING(d); ApplyThemeBackground(kind, &bounds, - Ttk_StateTableLookup(ThemeStateTable, state), + Ttk_StateTableLookup(ThemeStateTable, state), depth, inColor); QDSetPatternOrigin(origin); EraseRect(&bounds); - END_DRAWING + END_DRAWING(); } -static Ttk_ElementSpec BackgroundElementSpec = -{ +static Ttk_ElementSpec BackgroundElementSpec = { TK_STYLE_VERSION_2, sizeof(NullElement), TtkNullElementOptions, @@ -802,14 +814,14 @@ static Ttk_ElementSpec BackgroundElementSpec = /*---------------------------------------------------------------------- * +++ ToolbarBackground element -- toolbar style for frames. * - * This is very similar to the normal background element, but uses a - * different ThemeBrush in order to get the lighter pinstripe effect - * used in toolbars. We use SetThemeBackground() rather than - * ApplyThemeBackground() in order to get the right style. + * This is very similar to the normal background element, but uses a + * different ThemeBrush in order to get the lighter pinstripe effect + * used in toolbars. We use SetThemeBackground() rather than + * ApplyThemeBackground() in order to get the right style. * * <URL: http://developer.apple.com/documentation/Carbon/Reference/ - * Appearance_Manager/appearance_manager/constant_7.html#/ - * /apple_ref/doc/uid/TP30000243/C005321> + * Appearance_Manager/appearance_manager/constant_7.html#/ + * /apple_ref/doc/uid/TP30000243/C005321> * */ static void ToolbarBackgroundElementDraw( @@ -825,15 +837,15 @@ static void ToolbarBackgroundElementDraw( bounds.right = Tk_Width(tkwin); bounds.bottom = Tk_Height(tkwin); - BEGIN_DRAWING(d) + OFFSET_RECT(d, bounds); + BEGIN_DRAWING(d); SetThemeBackground(brush, depth, inColor); EraseRect(&bounds); - END_DRAWING + END_DRAWING(); } -static Ttk_ElementSpec ToolbarBackgroundElementSpec = -{ +static Ttk_ElementSpec ToolbarBackgroundElementSpec = { TK_STYLE_VERSION_2, sizeof(NullElement), TtkNullElementOptions, @@ -864,14 +876,14 @@ static void TreeHeaderElementDraw( info.value = Ttk_StateTableLookup(ButtonValueTable, state); info.adornment = Ttk_StateTableLookup(TreeHeaderAdornmentTable, state); - BEGIN_DRAWING(d) + OFFSET_RECT(d, bounds); + BEGIN_DRAWING(d); DrawThemeButton(&bounds, parms->kind, &info, NULL/*prevInfo*/,NULL/*eraseProc*/,NULL/*labelProc*/,0/*userData*/); - END_DRAWING + END_DRAWING(); } -static Ttk_ElementSpec TreeHeaderElementSpec = -{ +static Ttk_ElementSpec TreeHeaderElementSpec = { TK_STYLE_VERSION_2, sizeof(NullElement), TtkNullElementOptions, @@ -904,21 +916,22 @@ static void DisclosureElementDraw( Rect bounds = BoxToRect(b); ThemeButtonDrawInfo info; - if (state & TTK_TREEVIEW_STATE_LEAF) + if (state & TTK_TREEVIEW_STATE_LEAF) { return; + } info.state = Ttk_StateTableLookup(ThemeStateTable, state); info.value = Ttk_StateTableLookup(DisclosureValueTable, state); info.adornment = kThemeAdornmentDrawIndicatorOnly; - BEGIN_DRAWING(d) + OFFSET_RECT(d, bounds); + BEGIN_DRAWING(d); DrawThemeButton(&bounds, kThemeDisclosureTriangle, &info, NULL/*prevInfo*/,DontErase,NULL/*labelProc*/,0/*userData*/); - END_DRAWING + END_DRAWING(); } -static Ttk_ElementSpec DisclosureElementSpec = -{ +static Ttk_ElementSpec DisclosureElementSpec = { TK_STYLE_VERSION_2, sizeof(NullElement), TtkNullElementOptions, @@ -995,19 +1008,19 @@ static int AquaTheme_Init(Tcl_Interp *interp) &ToolbarBackgroundElementSpec, 0); Ttk_RegisterElementSpec(themePtr, "Button.button", - &ButtonElementSpec, &PushButtonParms); + &ButtonElementSpec, &PushButtonParms); Ttk_RegisterElementSpec(themePtr, "Checkbutton.button", - &ButtonElementSpec, &CheckBoxParms); + &ButtonElementSpec, &CheckBoxParms); Ttk_RegisterElementSpec(themePtr, "Radiobutton.button", - &ButtonElementSpec, &RadioButtonParms); + &ButtonElementSpec, &RadioButtonParms); Ttk_RegisterElementSpec(themePtr, "Toolbutton.border", - &ButtonElementSpec, &BevelButtonParms); + &ButtonElementSpec, &BevelButtonParms); Ttk_RegisterElementSpec(themePtr, "Menubutton.button", - &ButtonElementSpec, &PopupButtonParms); + &ButtonElementSpec, &PopupButtonParms); Ttk_RegisterElementSpec(themePtr, "Treeitem.indicator", - &DisclosureElementSpec, &DisclosureParms); + &DisclosureElementSpec, &DisclosureParms); Ttk_RegisterElementSpec(themePtr, "Treeheading.cell", - &TreeHeaderElementSpec, &ListHeaderParms); + &TreeHeaderElementSpec, &ListHeaderParms); Ttk_RegisterElementSpec(themePtr, "Notebook.tab", &TabElementSpec, 0); Ttk_RegisterElementSpec(themePtr, "Notebook.client", &PaneElementSpec, 0); @@ -1017,7 +1030,7 @@ static int AquaTheme_Init(Tcl_Interp *interp) Ttk_RegisterElementSpec(themePtr, "Combobox.field",&EntryElementSpec,0); Ttk_RegisterElementSpec(themePtr, "Combobox.downarrow", - &PopupArrowElementSpec, 0); + &PopupArrowElementSpec, 0); Ttk_RegisterElementSpec(themePtr, "separator",&SeparatorElementSpec,0); Ttk_RegisterElementSpec(themePtr, "hseparator",&SeparatorElementSpec,0); @@ -1031,7 +1044,7 @@ static int AquaTheme_Init(Tcl_Interp *interp) * we do all the drawing in the ".track" element and leave the .pbar out. */ Ttk_RegisterElementSpec(themePtr,"Scale.trough", - &TrackElementSpec, &ScaleData); + &TrackElementSpec, &ScaleData); Ttk_RegisterElementSpec(themePtr,"Scale.slider",&SliderElementSpec,0); Ttk_RegisterElementSpec(themePtr,"Progressbar.track", &PbarElementSpec, 0); diff --git a/unix/Makefile.in b/unix/Makefile.in index a522a7a..91045b8 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -5,7 +5,7 @@ # "autoconf" program (constructs like "@foo@" will get replaced in the # actual Makefile. # -# RCS: @(#) $Id: Makefile.in,v 1.121 2007/03/07 23:46:33 das Exp $ +# RCS: @(#) $Id: Makefile.in,v 1.122 2007/04/23 21:24:35 das Exp $ # Current Tk version; used in various names. @@ -526,7 +526,7 @@ SRCS = $(GENERIC_SRCS) $(@TK_WINDOWINGSYSTEM@_SRCS) @PLAT_SRCS@ AQUA_RESOURCES = \ $(MAC_OSX_DIR)/tkAboutDlg.r $(MAC_OSX_DIR)/tkMacOSXCursors.r \ - $(MAC_OSX_DIR)/tkMacOSXMenu.r $(MAC_OSX_DIR)/tkMacOSXXCursors.r + $(MAC_OSX_DIR)/tkMacOSXXCursors.r AQUA_WISH_RESOURCES = $(MAC_OSX_DIR)/tkMacOSXAETE.r |