diff options
author | das <das> | 2007-04-29 02:26:47 (GMT) |
---|---|---|
committer | das <das> | 2007-04-29 02:26:47 (GMT) |
commit | 0537d1c70efd92c5bd39a4047c02524d70ad7a58 (patch) | |
tree | d8296fa62af852c5f2e743159973d854366b69fa | |
parent | 9025e3c799817de9b380db2644dd47a61924c5eb (diff) | |
download | tk-0537d1c70efd92c5bd39a4047c02524d70ad7a58.zip tk-0537d1c70efd92c5bd39a4047c02524d70ad7a58.tar.gz tk-0537d1c70efd92c5bd39a4047c02524d70ad7a58.tar.bz2 |
* macosx/tkMacOSXCarbonEvents.c: add window event target carbon event
* macosx/tkMacOSXEvent.c: handler for all kEventClassWindow and
* macosx/tkMacOSXEvent.h: kEventClassMouse events; move all
* macosx/tkMacOSXNotify.c: 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
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
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; disable broken QD stippling.
* macosx/tkMacOSXMenu.c: large-scale rewrite of custom
* macosx/tkMacOSXMenu.r (removed): MDEF and related code that
* unix/Makefile.in: restores many longtime-MIA
features to working order (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/tkMacOSXFont.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/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/tkMacOSXAETE.r: fix whitespace.
* macosx/tkMacOSXConfig.c:
* macosx/tkMacOSXCursors.r:
* macosx/tkMacOSXKeyboard.c:
* macosx/tkMacOSXSend.c:
* macosx/tkMacOSXXCursors.r:
* macosx/README:
* macosx/Makefile: fix/add copyright and license refs.
* macosx/Tk-Info.plist.in:
* macosx/Wish-Info.plist.in:
* macosx/tkMacOSX.h:
50 files changed, 16321 insertions, 15232 deletions
@@ -1,3 +1,318 @@ +2007-04-29 Daniel Steffen <das@users.sourceforge.net> + + * 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 + * macosx/tkMacOSXPort.h: platforms would only require implementation + * unix/tkUnixScale.c: of TkpClipDrawableToRect()). + + * 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/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. + + * macosx/tkMacOSXCarbonEvents.c: add window event target carbon event + * macosx/tkMacOSXEvent.c: handler for all kEventClassWindow and + * macosx/tkMacOSXEvent.h: kEventClassMouse events; move all + * macosx/tkMacOSXNotify.c: 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 + 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 + 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; disable broken QD stippling. + + * macosx/tkMacOSXMenu.c: large-scale rewrite of custom + * macosx/tkMacOSXMenu.r (removed): MDEF and related code that + * unix/Makefile.in: restores many longtime-MIA + features to working order (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/tkMacOSXFont.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/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/tkMacOSXAETE.r: fix whitespace. + * macosx/tkMacOSXConfig.c: + * macosx/tkMacOSXCursors.r: + * macosx/tkMacOSXKeyboard.c: + * macosx/tkMacOSXSend.c: + * macosx/tkMacOSXXCursors.r: + * macosx/README: + + * macosx/Makefile: fix/add copyright and license refs. + * macosx/Tk-Info.plist.in: + * macosx/Wish-Info.plist.in: + * macosx/tkMacOSX.h: + + * unix/Makefile.in (dist): copy license.terms to dist macosx dir. + * unix/configure.in: install license.terms into Tk.framework; fix tk + debug build detection. + * unix/configure: autoconf-2.13 + + * 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]. + 2007-03-07 Daniel Steffen <das@users.sourceforge.net> * generic/tkMain.c (Tk_MainEx): replicate macosx-specific code from diff --git a/macosx/Makefile b/macosx/Makefile index 14f7644..b138a2f 100644 --- a/macosx/Makefile +++ b/macosx/Makefile @@ -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: Makefile,v 1.7.2.16 2006/10/16 17:35:20 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: Makefile,v 1.7.2.17 2007/04/29 02:26:47 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 @@ -165,7 +170,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 \ --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} \ @@ -290,7 +295,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 4e72d67..d40fb55 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.6.2.14 2006/10/16 15:57:13 das Exp $ +RCS: @(#) $Id: README,v 1.6.2.15 2007/04/29 02:26:47 das Exp $ This is the README file for the Mac OS X/Darwin version of Tcl/Tk. @@ -91,14 +91,14 @@ framework directories: "-psn_XXXX" argument. This is the Wish's carbon process serial number, you may need to filter it out for cross platform compatibility of your scripts. -- the env array is different when Wish is started from the Finder than when it -(or tclsh) is invoked from the Terminal, in particular PATH may not be what you -expect. (Wish started from the Finder inherits the Finder's environment -variables, which are essentially those set in $HOME/.MacOSX/environment.plist -and not those set by your shell configuration files). +- the env array is different when Wish is started from the Finder (i.e. via +LaunchServices) than when it (or tclsh) is invoked from the Terminal, in +particular PATH may not be what you expect. (Wish started by LaunchServices +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 @@ -110,14 +110,14 @@ control whether a line/shape is drawn antialiased. The antialiasing threshold is 0 by default (i.e. antialias everything), it can be changed by setting set tk::mac::CGAntialiasLimit <limit> in your script before drawing, in which case lines (or shapes with outlines) -thinner that <limit> pixels will not be antialiased. +thinner than <limit> pixels will not be antialiased. - Quickdraw text antialiasing is enabled by default when available (from 10.1.5 onwards). Changing the global boolean variable '::tk::mac::antialiasedtext' allows to dis/enable antialiasing on the fly from Tcl (even for existing text). - Scrollbars: There are two scrollbar variants in Aqua, normal & small. The -normal scrollbar has a small dimension of 16, the small variant 12. Access to +normal scrollbar has a small dimension of 15, the small variant 11. Access to the small variant was added in Tk 8.4.2. - Cursors: You can now put up and spin the Classic MacOS spinner, and the @@ -131,8 +131,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 @@ -159,16 +159,16 @@ select based notifier). Note that --enable-aqua is incompatible with --disable-corefoundation (for both Tcl and Tk configure). - It is also possible to build with Apple's IDE via the tk/macosx/Wish.pbproj -project, this simply calls through to the tk/macosx/GNUMakefile. It requires a +project, this simply calls through to the tk/macosx/Makefile. It requires a build of the tcl/macosx/Tcl.pbproj project. - To build universal binaries, set CFLAGS as follows: export CFLAGS="-arch ppc -arch i386 \ -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4" This requires Mac OS X 10.4 and Xcode 2.2 (_not_ Xcode 2.1) and will work on any -of the architectures (on intel Macs, the -isysroot may not be required). Note -that it is not possible to configure universal builds correctly if the current -architecture is not present in CFLAGS (i.e. -arch `arch` must be there). +of the architectures (the -isysroot flag is only required on PowerPC Tiger). +Note that configure requires CFLAGS to contain a least one architecture that can +be run on the build machine (i.e. ppc on PowerPC, ppc or i386 on Intel). Universal builds of Tk TEA extensions are also possible with CFLAGS set as above, they will be [load]able by universal as well as thin binaries of Tk. Note that while Tcl can be built for 64-bit architectures, neither TkAqua nor @@ -194,7 +194,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. ] @@ -203,12 +203,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..39784f3 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.1.2.3 2007/04/29 02:26:47 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-Info.plist.in b/macosx/Wish-Info.plist.in index 08fff5a..3ca0705 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.1.2.3 2007/04/29 02:26:47 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/tkAboutDlg.r b/macosx/tkAboutDlg.r index d606220..f573a67 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.3.2.4 2006/04/28 06:02:58 das Exp $ + * RCS: @(#) $Id: tkAboutDlg.r,v 1.3.2.5 2007/04/29 02:26:47 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 3f75f6f..b0d166a 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.2.2.2 2006/03/28 02:44:12 das Exp $ + * RCS: @(#) $Id: tkMacOSX.h,v 1.2.2.3 2007/04/29 02:26:47 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..3588e43 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.1.2.1 2007/04/29 02:26:47 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 eecb6f1..7227ce6 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.2.2.2 2006/03/28 02:44:12 das Exp $ + * RCS: @(#) $Id: tkMacOSXBitmap.c,v 1.2.2.3 2007/04/29 02:26:47 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 0878819..65e1043 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.2.2.14 2006/05/26 21:43:05 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXButton.c,v 1.2.2.15 2007/04/29 02:26:47 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,301 +173,292 @@ 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 { - 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 { - 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 { + 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 { + 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), @@ -477,24 +468,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); } } @@ -503,60 +498,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); } /* @@ -567,172 +560,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); @@ -743,13 +730,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. * *---------------------------------------------------------------------- */ @@ -758,10 +745,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; } } @@ -770,244 +758,212 @@ 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 { - SetControlValue(mbPtr->control, 0); + SetControlValue(mbPtr->control, 0); } if (!Tk_MacOSXIsAppInFront() || butPtr->state == STATE_DISABLED) { @@ -1017,6 +973,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) { @@ -1025,7 +982,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); @@ -1039,31 +996,29 @@ 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) { - } + if (butPtr->type == TYPE_BUTTON && !mbPtr->params.isBevel) { + 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); } } @@ -1072,147 +1027,128 @@ 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); + + if (butPtr->selectImage != NULL && (butPtr->flags & SELECTED)) { + Tk_RedrawImage(butPtr->selectImage, 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); } } @@ -1221,28 +1157,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); } /* @@ -1250,28 +1188,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); } /* @@ -1279,28 +1219,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); } /* @@ -1308,14 +1249,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. * *-------------------------------------------------------------- */ @@ -1325,10 +1266,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); } } @@ -1337,82 +1278,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; + } } } @@ -1421,143 +1364,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 = 1; - paramsPtr->procID = kControlRadioButtonProc; - } else { - paramsPtr->initialValue = 0; - paramsPtr->minValue = kControlBehaviorOffsetContents| - kControlBehaviorSticky| - 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_CHECK_BUTTON: - if (((butPtr->image == None) - && (butPtr->bitmap == None)) - || (butPtr->indicatorOn)) { - paramsPtr->initialValue = 1; - paramsPtr->minValue = 0; - paramsPtr->maxValue = 1; - paramsPtr->procID = kControlCheckBoxProc; - } else { - paramsPtr->initialValue = 0; - paramsPtr->minValue = kControlBehaviorOffsetContents - | kControlBehaviorSticky - | 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_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 = 1; + paramsPtr->procID = kControlRadioButtonProc; + } else { + paramsPtr->initialValue = 0; + paramsPtr->minValue = kControlBehaviorOffsetContents | + kControlBehaviorSticky | 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_CHECK_BUTTON: + if (((butPtr->image == None) && (butPtr->bitmap == None)) + || (butPtr->indicatorOn)) { + paramsPtr->initialValue = 1; + paramsPtr->minValue = 0; + paramsPtr->maxValue = 1; + paramsPtr->procID = kControlCheckBoxProc; + } else { + paramsPtr->initialValue = 0; + paramsPtr->minValue = kControlBehaviorOffsetContents | + kControlBehaviorSticky | 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; } -} +} + /* *---------------------------------------------------------------------- * * 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. @@ -1568,69 +1509,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 7808b01..f95dec2 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.3.2.15 2006/10/31 22:33:38 das 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.3.2.16 2007/04/29 02:26:48 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 e40312d..8009173 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.2.2.5 2007/01/19 00:41:33 das Exp $ + * RCS: @(#) $Id: tkMacOSXClipboard.c,v 1.2.2.6 2007/04/29 02:26:48 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 33e39a7..c3a5bc7 100644 --- a/macosx/tkMacOSXColor.c +++ b/macosx/tkMacOSXColor.c @@ -1,197 +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.2.2.4 2006/09/11 14:41:16 das Exp $ + * RCS: @(#) $Id: tkMacOSXColor.c,v 1.2.2.5 2007/04/29 02:26:48 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 ! */ + +#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 + /* - * Stubbed out for OS X -static AuxCtlHandle defaultAuxCtlHandle = NULL; -*/ + *---------------------------------------------------------------------- + * + * 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 +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; + } +} + /* - * Forward declarations for procedures defined later in this file: + *---------------------------------------------------------------------- + * + * GetThemeColor -- + * + * Get RGB color for a given system color or pixel value. + * + * Results: + * OSStatus + * + * 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 OSStatus +GetThemeColor(unsigned long pixel, ThemeBrush brush, ThemeTextColor textColor, + ThemeBackgroundKind background, RGBColor *c) +{ + OSStatus err = noErr; + + 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; +} /* *---------------------------------------------------------------------- * * TkSetMacColor -- * - * Populates a Macintosh RGBColor structure from a X style - * pixel value. + * Populates a Macintosh RGBColor structure from a X style + * pixel value. * * Results: - * Returns false if not a real pixel, true otherwise. + * Returns false if not a real pixel, true otherwise. * * Side effects: - * The variable macColor is updated to the pixels value. + * The variable macColor is updated to the pixels value. * *---------------------------------------------------------------------- */ int TkSetMacColor( - unsigned long pixel, /* Pixel value to convert. */ - RGBColor *macColor) /* Mac color struct to modify. */ + unsigned long pixel, /* Pixel value to convert. */ + RGBColor *macColor) /* Mac color struct to modify. */ { - OSStatus err; + OSStatus err = -1; + ThemeBrush brush; + ThemeTextColor textColor; + ThemeBackgroundKind background; - 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 (GetThemeFromPixelCode((pixel >> 24) & 0xff, &brush, &textColor, + &background)) { + err = ChkErr(GetThemeColor, pixel, brush, textColor, background, + macColor); } + return (err == noErr); } /* *---------------------------------------------------------------------- * - * 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); + } } /* @@ -199,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); @@ -224,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; @@ -345,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)); @@ -380,120 +637,64 @@ TkpGetColorByValue( /* *---------------------------------------------------------------------- * - * GetControlPartColor -- + * Stub functions -- * - * 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. + * 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 -GetControlPartColor( - 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. */ { - 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; + display->request++; + colorPtr->pixel = TkpGetPixel(colorPtr); + return 1; } - -/* - *---------------------------------------------------------------------- - * - * GetWindowPartColor -- - * - * 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. - * - * 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 -GetWindowPartColor( - short part, /* Part code. */ - RGBColor *macColor) /* Pointer to Mac color. */ +Colormap +XCreateColormap( + Display *display, /* Display. */ + Window window, /* X window. */ + Visual *visual, /* Not used. */ + int alloc) /* Not used. */ { - short index; - WCTabHandle wcTab; + static Colormap index = 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; - } + /* + * 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 8f4df57..818925e 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.2.2.1 2006/03/28 02:44:13 das Exp $ + * RCS: @(#) $Id: tkMacOSXConfig.c,v 1.2.2.2 2007/04/29 02:26:48 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 e72bbae..81fe11d 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.4.2.4 2006/07/20 06:26:45 das Exp $ + * RCS: @(#) $Id: tkMacOSXCursor.c,v 1.4.2.5 2007/04/29 02:26:48 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..6ce82a2 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.2.2.1 2007/04/29 02:26:48 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 a0e1fe0..9f53276 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.2.2.10 2007/03/07 23:48:13 das Exp $ + * RCS: @(#) $Id: tkMacOSXDebug.c,v 1.2.2.11 2007/04/29 02:26:48 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 008a70d..56a9631 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.2.2.7 2006/10/31 22:33:38 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.2.2.8 2007/04/29 02:26:48 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 a2fc1a6..c11c92c 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.2.2.4 2006/09/10 17:07:36 das Exp $ + * RCS: @(#) $Id: tkMacOSXDefault.h,v 1.2.2.5 2007/04/29 02:26:48 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" @@ -126,7 +125,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" @@ -138,14 +137,14 @@ /* * Defaults for entries: */ - -/* - * I test the following three values in TkpDrawEntryBorderAndFocus - * to determine whether to use the native entry widget. So if + +/* + * I test the following two values in TkpDrawEntryBorderAndFocus + * 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 @@ -288,29 +287,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 "" @@ -333,7 +332,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 @@ -480,8 +479,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: @@ -505,7 +503,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" @@ -523,7 +521,7 @@ #define DEF_TEXT_STATE "normal" #define DEF_TEXT_TABS "" #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 350f1fe..538056a 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.4.2.12 2006/12/01 07:13:14 das Exp $ + * RCS: @(#) $Id: tkMacOSXDialog.c,v 1.4.2.13 2007/04/29 02:26:48 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; + char *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: - choice = Tcl_GetStringFromObj(objv[i + 1], NULL); - if (TkGetFileFilters(interp, &ofd.fl, choice, 0) != TCL_OK) { - result = TCL_ERROR; + types = Tcl_GetString(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. + * + *---------------------------------------------------------------------- + */ -static pascal Boolean +pascal void +OpenEventProc( + NavEventCallbackMessage callBackSelector, + NavCBRecPtr callBackParams, + NavCallBackUserData callBackUD) +{ + NavHandlerUserData *data = (NavHandlerUserData*) callBackUD; + + 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,139 +1377,139 @@ 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; } } @@ -1518,22 +1520,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; @@ -1541,89 +1543,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; } - + /* *---------------------------------------------------------------------- * @@ -1640,31 +1636,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 aca5ee0..2f8464b 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.2.2.20 2006/10/31 22:26:10 das Exp $ + * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.2.2.21 2007/04/29 02:26:48 das Exp $ */ #include "tkMacOSXInt.h" @@ -26,10 +26,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 @@ -41,8 +38,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; @@ -56,32 +54,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; @@ -106,15 +101,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; } @@ -123,41 +132,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; @@ -166,8 +171,7 @@ XCopyArea( srcPort = TkMacOSXGetDrawablePort(src); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(dstPort, NULL); + portChanged = QDSwapPort(dstPort, &savePort); GetForeColor(&origForeColor); GetBackColor(&origBackColor); whiteColor.red = 0; @@ -179,9 +183,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), @@ -197,18 +198,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); */ @@ -217,23 +220,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); } @@ -245,8 +247,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); + } } /* @@ -254,45 +259,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; @@ -300,8 +297,7 @@ XCopyPlane( dstPort = TkMacOSXGetDrawablePort(dst); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(dstPort, NULL); + portChanged = QDSwapPort(dstPort, &savePort); TkMacOSXSetUpClippingRgn(dst); srcBit = GetPortBitMapForCopyBits(srcPort); @@ -316,7 +312,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; @@ -333,24 +329,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. */ @@ -373,8 +366,9 @@ XCopyPlane( srcPtr, srcPtr, dstPtr, tmode, NULL); } } - - SetGWorld(saveWorld, saveDevice); + if (portChanged) { + QDSwapPort(savePort, NULL); + } } /* @@ -382,14 +376,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. * *---------------------------------------------------------------------- */ @@ -409,9 +403,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; @@ -422,9 +415,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); @@ -435,10 +427,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; @@ -449,14 +442,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; @@ -489,7 +485,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++) { @@ -514,6 +510,7 @@ TkPutImage( /* * Color image */ + const int maxRowBytes = 0x3ffc; PixMap pixmap; @@ -521,7 +518,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; @@ -582,8 +579,9 @@ TkPutImage( if (newData != NULL) { ckfree(newData); } - - SetGWorld(saveWorld, saveDevice); + if (portChanged) { + QDSwapPort(savePort, NULL); + } } /* @@ -591,74 +589,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++) { @@ -669,10 +655,8 @@ XDrawLines( Line((short) points[i].x, (short) points[i].y); } } - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } /* @@ -680,71 +664,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); } /* @@ -752,13 +723,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. * *---------------------------------------------------------------------- */ @@ -774,45 +745,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)); @@ -825,11 +784,10 @@ XFillPolygon( } } ClosePoly(); - FillCPoly(polygon, gPenPat); + FillCPoly(polygon, dc.penPat); KillPoly(polygon); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } /* @@ -837,71 +795,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 @@ -910,27 +852,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, @@ -940,24 +882,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; @@ -966,16 +899,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); @@ -983,10 +912,8 @@ XDrawRectangles( theRect.bottom = (short) (theRect.top + rectPtr->height + lw); FrameRect(&theRect); } - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #endif @@ -995,42 +922,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; @@ -1039,23 +958,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); } /* @@ -1063,98 +979,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 @@ -1163,23 +1066,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, @@ -1190,24 +1094,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) { @@ -1219,41 +1114,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); @@ -1263,10 +1157,8 @@ XDrawArcs( extent = (short) (-(arcPtr->angle2/64)); FrameArc(&theRect, start, extent); } - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #endif @@ -1275,71 +1167,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); @@ -1351,11 +1236,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; @@ -1365,10 +1249,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)); @@ -1394,19 +1277,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 @@ -1415,16 +1293,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, @@ -1434,28 +1313,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) { @@ -1467,22 +1337,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); @@ -1492,12 +1365,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; @@ -1507,7 +1379,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); @@ -1538,20 +1409,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 @@ -1563,8 +1429,10 @@ XFillArcs( * *---------------------------------------------------------------------- */ + long -XMaxRequestSize(Display *display) +XMaxRequestSize( + Display *display) { return (SHRT_MAX / 4); } @@ -1575,51 +1443,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. */ @@ -1644,45 +1506,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. */ @@ -1698,220 +1542,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 */ } /* @@ -1919,21 +1843,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; @@ -1942,43 +1866,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; } } } @@ -1988,48 +1941,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; @@ -2039,9 +1989,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; @@ -2052,20 +2001,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; @@ -2084,32 +2033,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); @@ -2127,7 +2076,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: @@ -2140,52 +2089,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 b98ec45..4c6c69c 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.2.2.4 2006/10/31 22:33:38 das Exp $ + * RCS: @(#) $Id: tkMacOSXEmbed.c,v 1.2.2.5 2007/04/29 02:26:48 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,18 +73,19 @@ 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. * *---------------------------------------------------------------------- */ + void Tk_MacOSXSetEmbedHandler( Tk_MacOSXEmbedRegisterWinProc *registerWinProc, @@ -99,28 +95,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 +133,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 +195,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 +228,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 +242,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 +255,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 +416,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 +453,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 +479,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 +513,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 +554,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 +605,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 +631,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 +682,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 +713,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 +740,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. */ +EmbeddedEventProc( + ClientData clientData, /* Token for container window. */ + XEvent *eventPtr) /* ResizeRequest event. */ { TkWindow *winPtr = (TkWindow *) clientData; if (eventPtr->type == DestroyNotify) { - EmbedWindowDeleted(winPtr); + EmbedWindowDeleted(winPtr); } } @@ -794,28 +790,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. */ +ContainerEventProc( + ClientData clientData, /* Token for container window. */ + XEvent *eventPtr) /* ResizeRequest event. */ { TkWindow *winPtr = (TkWindow *) clientData; Container *containerPtr; @@ -828,67 +824,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 +894,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. */ +EmbedStructureProc( + 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 +943,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. */ +EmbedActivateProc( + 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 +978,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. */ +EmbedFocusProc( + ClientData clientData, /* Token for container window. */ + XEvent *eventPtr) /* ResizeRequest event. */ { Container *containerPtr = (Container *) clientData; Display *display; @@ -1008,34 +1004,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 +1039,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. */ +EmbedGeometryRequest( + Container *containerPtr, /* Information about the embedding. */ + int width, int 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 +1078,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 +1091,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. */ +EmbedSendConfigure( + Container *containerPtr) /* Information about the embedding. */ { } @@ -1123,28 +1119,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. */ +EmbedWindowDeleted( + 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 +1148,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 f231937..1f12cf5 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.2.2.7 2006/09/10 17:07:36 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.2.2.8 2007/04/29 02:26:49 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 2427155..960c676 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.3.2.9 2006/10/31 22:33:38 das Exp $ + * RCS: @(#) $Id: tkMacOSXEvent.c,v 1.3.2.10 2007/04/29 02:26:49 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 10eba80..6e15649 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.3.2.7 2006/07/20 06:27: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: tkMacOSXEvent.h,v 1.3.2.8 2007/04/29 02:26:49 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 45da327..2cd3dda 100644 --- a/macosx/tkMacOSXFont.c +++ b/macosx/tkMacOSXFont.c @@ -1,17 +1,18 @@ /* * tkMacOSXFont.c -- * - * Contains the Macintosh implementation of the platform-independant - * font package interface. + * Contains the Macintosh implementation of the platform-independant + * font package interface. * * 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.c,v 1.3.2.8 2006/03/28 02:44:13 das Exp $ + * RCS: @(#) $Id: tkMacOSXFont.c,v 1.3.2.9 2007/04/29 02:26:49 das Exp $ */ #include "tkMacOSXInt.h" @@ -20,8 +21,7 @@ #include "tclInt.h" /* for Tcl_CreateNamespace() */ /* - * For doing things with Mac strings and Fixed numbers. This probably should move - * the mac header file. + * Dealing with pascal strings. */ #ifndef StrLength @@ -33,76 +33,71 @@ #define pstrcmp(s1, s2) RelString((s1), (s2), 1, 1) #define pstrcasecmp(s1, s2) RelString((s1), (s2), 0, 1) -#ifndef Fixed2Int -#define Fixed2Int(f) ((f) >> 16) -#define Int2Fixed(i) ((i) << 16) -#endif - /* * The preferred font encodings. */ -static CONST char *encodingList[] = { +static const char *encodingList[] = { "macRoman", "macJapan", NULL }; /* - * The following structures are used to map the script/language codes of a + * The following structures are used to map the script/language codes of a * font to the name that should be passed to Tcl_GetTextEncoding() 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. */ - + static TkStateMap scriptMap[] = { - {smRoman, "macRoman"}, - {smJapanese, "macJapan"}, - {smTradChinese, "macChinese"}, - {smKorean, "macKorean"}, - {smArabic, "macArabic"}, - {smHebrew, "macHebrew"}, - {smGreek, "macGreek"}, - {smCyrillic, "macCyrillic"}, - {smRSymbol, "macRSymbol"}, - {smDevanagari, "macDevanagari"}, - {smGurmukhi, "macGurmukhi"}, - {smGujarati, "macGujarati"}, - {smOriya, "macOriya"}, - {smBengali, "macBengali"}, - {smTamil, "macTamil"}, - {smTelugu, "macTelugu"}, - {smKannada, "macKannada"}, - {smMalayalam, "macMalayalam"}, - {smSinhalese, "macSinhalese"}, - {smBurmese, "macBurmese"}, - {smKhmer, "macKhmer"}, - {smThai, "macThailand"}, - {smLaotian, "macLaos"}, - {smGeorgian, "macGeorgia"}, - {smArmenian, "macArmenia"}, - {smSimpChinese, "macSimpChinese"}, - {smTibetan, "macTIbet"}, - {smMongolian, "macMongolia"}, - {smGeez, "macEthiopia"}, - {smEastEurRoman, "macCentEuro"}, - {smVietnamese, "macVietnam"}, - {smExtArabic, "macSindhi"}, - {0, NULL} -}; + {smRoman, "macRoman"}, + {smJapanese, "macJapan"}, + {smTradChinese, "macChinese"}, + {smKorean, "macKorean"}, + {smArabic, "macArabic"}, + {smHebrew, "macHebrew"}, + {smGreek, "macGreek"}, + {smCyrillic, "macCyrillic"}, + {smRSymbol, "macRSymbol"}, + {smDevanagari, "macDevanagari"}, + {smGurmukhi, "macGurmukhi"}, + {smGujarati, "macGujarati"}, + {smOriya, "macOriya"}, + {smBengali, "macBengali"}, + {smTamil, "macTamil"}, + {smTelugu, "macTelugu"}, + {smKannada, "macKannada"}, + {smMalayalam, "macMalayalam"}, + {smSinhalese, "macSinhalese"}, + {smBurmese, "macBurmese"}, + {smKhmer, "macKhmer"}, + {smThai, "macThailand"}, + {smLaotian, "macLaos"}, + {smGeorgian, "macGeorgia"}, + {smArmenian, "macArmenia"}, + {smSimpChinese, "macSimpChinese"}, + {smTibetan, "macTIbet"}, + {smMongolian, "macMongolia"}, + {smGeez, "macEthiopia"}, + {smEastEurRoman, "macCentEuro"}, + {smVietnamese, "macVietnam"}, + {smExtArabic, "macSindhi"}, + {0, NULL} +}; static TkStateMap romanMap[] = { - {langCroatian, "macCroatian"}, - {langSlovenian, "macCroatian"}, - {langIcelandic, "macIceland"}, - {langRomanian, "macRomania"}, - {langTurkish, "macTurkish"}, - {langGreek, "macGreek"}, - {0, NULL} + {langCroatian, "macCroatian"}, + {langSlovenian, "macCroatian"}, + {langIcelandic, "macIceland"}, + {langRomanian, "macRomania"}, + {langTurkish, "macTurkish"}, + {langGreek, "macGreek"}, + {0, NULL} }; static TkStateMap cyrillicMap[] = { - {langUkrainian, "macUkraine"}, - {langBulgarian, "macBulgaria"}, - {0, NULL} + {langUkrainian, "macUkraine"}, + {langBulgarian, "macBulgaria"}, + {0, NULL} }; /* @@ -117,47 +112,47 @@ static TkStateMap cyrillicMap[] = { */ -#define FONTMAP_SHIFT 10 +#define FONTMAP_SHIFT 10 -#define FONTMAP_PAGES (1 << (sizeof(Tcl_UniChar) * 8 - FONTMAP_SHIFT)) -#define FONTMAP_BITSPERPAGE (1 << FONTMAP_SHIFT) +#define FONTMAP_PAGES (1 << (sizeof(Tcl_UniChar) * 8 - FONTMAP_SHIFT)) +#define FONTMAP_BITSPERPAGE (1 << FONTMAP_SHIFT) typedef struct FontFamily { - struct FontFamily *nextPtr; /* Next in list of all known font families. */ - int refCount; /* How many SubFonts are referring to this - * FontFamily. When the refCount drops to - * zero, this FontFamily may be freed. */ + struct FontFamily *nextPtr; /* Next in list of all known font families. */ + int refCount; /* How many SubFonts are referring to this + * FontFamily. When the refCount drops to + * zero, this FontFamily may be freed. */ /* * Key. */ - FMFontFamily faceNum; /* Unique face number key for this FontFamily. */ - + FMFontFamily faceNum; /* Unique face number key for this FontFamily. */ + /* * Derived properties. */ - - Tcl_Encoding encoding; /* Encoding for this font family. */ - int isSymbolFont; /* Non-zero if this is a symbol family. */ - int isMultiByteFont; /* Non-zero if this is a multi-byte family. */ - char typeTable[256]; /* Table that identfies all lead bytes for a - * multi-byte family, used when measuring chars. - * If a byte is a lead byte, the value at the - * corresponding position in the typeTable is 1, - * otherwise 0. If this is a single-byte font, - * all entries are 0. */ + + Tcl_Encoding encoding; /* Encoding for this font family. */ + int isSymbolFont; /* Non-zero if this is a symbol family. */ + int isMultiByteFont; /* Non-zero if this is a multi-byte family. */ + char typeTable[256]; /* Table that identfies all lead bytes for a + * multi-byte family, used when measuring chars. + * If a byte is a lead byte, the value at the + * corresponding position in the typeTable is 1, + * otherwise 0. If this is a single-byte font, + * all entries are 0. */ char *fontMap[FONTMAP_PAGES]; - /* Two-level sparse table used to determine - * quickly if the specified character exists. - * As characters are encountered, more pages - * in this table are dynamically added. The - * contents of each page is a bitmask - * consisting of FONTMAP_BITSPERPAGE bits, - * representing whether this font can be used - * to display the given character at the - * corresponding bit position. The high bits - * of the character are used to pick which - * page of the table is used. */ + /* Two-level sparse table used to determine + * quickly if the specified character exists. + * As characters are encountered, more pages + * in this table are dynamically added. The + * contents of each page is a bitmask + * consisting of FONTMAP_BITSPERPAGE bits, + * representing whether this font can be used + * to display the given character at the + * corresponding bit position. The high bits + * of the character are used to pick which + * page of the table is used. */ } FontFamily; /* @@ -167,9 +162,9 @@ typedef struct FontFamily { */ typedef struct SubFont { - char **fontMap; /* Pointer to font map from the FontFamily, - * cached here to save a dereference. */ - FontFamily *familyPtr; /* The FontFamily for this SubFont. */ + char **fontMap; /* Pointer to font map from the FontFamily, + * cached here to save a dereference. */ + FontFamily *familyPtr; /* The FontFamily for this SubFont. */ } SubFont; /* @@ -177,45 +172,45 @@ typedef struct SubFont { * object. */ -#define SUBFONT_SPACE 3 +#define SUBFONT_SPACE 3 typedef struct MacFont { - TkFont font; /* Stuff used by generic font package. Must - * be first in structure. */ + TkFont font; /* Stuff used by generic font package. Must + * be first in structure. */ SubFont staticSubFonts[SUBFONT_SPACE]; - /* Builtin space for a limited number of - * SubFonts. */ - int numSubFonts; /* Length of following array. */ - SubFont *subFontArray; /* Array of SubFonts that have been loaded - * in order to draw/measure all the characters - * encountered by this font so far. All fonts - * start off with one SubFont initialized by - * AllocFont() from the original set of font - * attributes. Usually points to - * staticSubFonts, but may point to malloced - * space if there are lots of SubFonts. */ - - short size; /* Font size in pixels, constructed from - * font attributes. */ - short style; /* Style bits, constructed from font - * attributes. */ + /* Builtin space for a limited number of + * SubFonts. */ + int numSubFonts; /* Length of following array. */ + SubFont *subFontArray; /* Array of SubFonts that have been loaded + * in order to draw/measure all the characters + * encountered by this font so far. All fonts + * start off with one SubFont initialized by + * AllocFont() from the original set of font + * attributes. Usually points to + * staticSubFonts, but may point to malloced + * space if there are lots of SubFonts. */ + + short size; /* Font size in pixels, constructed from + * font attributes. */ + short style; /* Style bits, constructed from font + * attributes. */ } MacFont; /* * The following structure is used to map between the UTF-8 name for a font and * the name that the Macintosh uses to refer to the font, in order to determine - * if a font exists. The Macintosh names for fonts are stored in the encoding + * if a font exists. The Macintosh names for fonts are stored in the encoding * of the font itself. */ - + typedef struct FontNameMap { - Tk_Uid utfName; /* The name of the font in UTF-8. */ - StringPtr nativeName; /* The name of the font in the font's encoding. */ - FMFontFamily faceNum; /* Unique face number for this font. */ + Tk_Uid utfName; /* The name of the font in UTF-8. */ + StringPtr nativeName; /* The name of the font in the font's encoding. */ + FMFontFamily faceNum; /* Unique face number for this font. */ } FontNameMap; /* - * The list of font families that are currently loaded. As screen fonts + * The list of font families that are currently loaded. As screen fonts * are loaded, this list grows to hold information about what characters * exist in each font family. */ @@ -225,299 +220,357 @@ static FontFamily *fontFamilyList = NULL; /* * Information cached about the system at startup time. */ - + static FontNameMap *gFontNameMap = NULL; static GWorldPtr gWorld = NULL; /* + * The names for our "native" fonts. + */ + +#define SYSTEMFONT_NAME "system" +#define APPLFONT_NAME "application" +#define MENUITEMFONT_NAME "menu" + +/* * Procedures used only in this file. */ -static FontFamily * AllocFontFamily(CONST MacFont *fontPtr, int family); -static SubFont * CanUseFallback(MacFont *fontPtr, CONST char *fallbackName, int ch, SubFont **fixSubFontPtrPtr); -static SubFont * CanUseFallbackWithAliases(MacFont *fontPtr, CONST char *faceName, int ch, Tcl_DString *nameTriedPtr, SubFont **fixSubFontPtrPtr); +static FontFamily * AllocFontFamily(const MacFont *fontPtr, int family); +static SubFont * CanUseFallback(MacFont *fontPtr, const char *fallbackName, int ch, SubFont **fixSubFontPtrPtr); +static SubFont * CanUseFallbackWithAliases(MacFont *fontPtr, const char *faceName, int ch, Tcl_DString *nameTriedPtr, SubFont **fixSubFontPtrPtr); static SubFont * FindSubFontForChar(MacFont *fontPtr, int ch, SubFont **fixSubFontPtrPtr); static void FontMapInsert(SubFont *subFontPtr, int ch); static void FontMapLoadPage(SubFont *subFontPtr, int row); static int FontMapLookup(SubFont *subFontPtr, int ch); static void FreeFontFamily(FontFamily *familyPtr); -static void InitFont(Tk_Window tkwin, int family, int size, int style, MacFont *fontPtr); -static void InitSubFont(CONST MacFont *fontPtr, int family, SubFont *subFontPtr); -static void MultiFontDrawText(MacFont *fontPtr, CONST char *source, int numBytes, int x, int y); +static void InitFont(Tk_Window tkwin, int family, unsigned char *familyName, int size, int style, MacFont *fontPtr); +static void InitSubFont(const MacFont *fontPtr, int family, SubFont *subFontPtr); +static void MultiFontDrawText(MacFont *fontPtr, const char *source, int numBytes, int x, int y); static void ReleaseFont(MacFont *fontPtr); static void ReleaseSubFont(SubFont *subFontPtr); -static int SeenName(CONST char *name, Tcl_DString *dsPtr); +static int SeenName(const char *name, Tcl_DString *dsPtr); -static CONST char * BreakLine(FontFamily *familyPtr, int flags, CONST char *source, int numBytes, int *widthPtr); -static int GetFamilyNum(CONST char *faceName, short *familyPtr); -static int GetFamilyOrAliasNum(CONST char *faceName, short *familyPtr); +static const char * BreakLine(FontFamily *familyPtr, int flags, const char *source, int numBytes, int *widthPtr); +static int GetFamilyNum(const char *faceName, short *familyPtr); +static int GetFamilyOrAliasNum(const char *faceName, short *familyPtr); static Tcl_Encoding GetFontEncoding(int faceNum, int allowSymbol, int *isSymbolPtr); static Tk_Uid GetUtfFaceName(StringPtr faceNameStr); +static OSStatus GetThemeFontAndFamily(const ThemeFontID themeFontId, + FMFontFamily* fontFamily, unsigned char *fontName, SInt16 *fontSize, + Style *fontStyle); + /* *------------------------------------------------------------------------- - * + * * 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: - * See comments below. + * See comments below. * *------------------------------------------------------------------------- */ void -TkpFontPkgInit(mainPtr) - TkMainInfo *mainPtr; /* The application being created. */ +TkpFontPkgInit( + TkMainInfo *mainPtr) /* The application being created. */ { FMFontFamilyIterator fontFamilyIterator; - FMFontFamily fontFamily; + FMFontFamily fontFamily; FontNameMap *tmpFontNameMap, *newFontNameMap, *mapPtr; int i, j, numFonts, fontMapOffset, isSymbol; Str255 nativeName; Tcl_DString ds; Tcl_Encoding encoding; Tcl_Encoding *encodings; - + if (gWorld == NULL) { - Rect rect = {0, 0, 1, 1}; - SetFractEnable(0); - /* - * Used for saving and restoring state while drawing and measuring. - */ - if (NewGWorld(&gWorld, 0, &rect, NULL, NULL, 0) != noErr) { - Tcl_Panic("TkpFontPkgInit: NewGWorld failed"); - } - /* - * The name of each font is stored in the encoding of that font. - * How would we translate a name from UTF-8 into the native encoding - * of the font unless we knew the encoding of that font? We can't. - * So, precompute the UTF-8 and native names of all fonts on the - * system. The when the user asks for font by its UTF-8 name, we - * lookup the name in that table and really ask for the font by its - * native name. Any unknown UTF-8 names will be mapped to the system - * font. - */ - FMCreateFontFamilyIterator (NULL, NULL, kFMDefaultOptions, &fontFamilyIterator); - numFonts = 0; - while (FMGetNextFontFamily(&fontFamilyIterator, &fontFamily) != kFMIterationCompleted) { - numFonts++; - } - tmpFontNameMap = (FontNameMap *) ckalloc(sizeof(FontNameMap) * numFonts); - encodings = (Tcl_Encoding *) ckalloc(sizeof(Tcl_Encoding) * numFonts); - mapPtr = tmpFontNameMap; - FMResetFontFamilyIterator(NULL, NULL, kFMDefaultOptions, &fontFamilyIterator); - i = 0; - while (FMGetNextFontFamily(&fontFamilyIterator, &fontFamily) != kFMIterationCompleted) { - mapPtr->faceNum = fontFamily; - encodings[i] = GetFontEncoding(mapPtr->faceNum, 0, &isSymbol); - FMGetFontFamilyName(fontFamily, nativeName ); - Tcl_ExternalToUtfDString(encodings[i], StrBody(nativeName), StrLength(nativeName), &ds); - mapPtr->utfName = Tk_GetUid(Tcl_DStringValue(&ds)); - mapPtr->nativeName = (StringPtr) ckalloc(StrLength(nativeName) + 1); - memcpy(mapPtr->nativeName, nativeName, StrLength(nativeName) + 1); - Tcl_DStringFree(&ds); - mapPtr++; - i++; - } - FMDisposeFontFamilyIterator (&fontFamilyIterator); - - /* - * Reorder FontNameMap so fonts with the preferred encodings are at - * the front of the list. The relative order of fonts that all have - * the same encoding is preserved. Fonts with unknown encodings get - * stuck at the end. - */ - newFontNameMap = (FontNameMap *) ckalloc(sizeof(FontNameMap) * (numFonts + 1)); - fontMapOffset = 0; - for (i = 0; encodingList[i] != NULL; i++) { - encoding = Tcl_GetEncoding(NULL, encodingList[i]); - if (encoding == NULL) { - continue; - } - for (j = 0; j < numFonts; j++) { - if (encodings[j] == encoding) { - newFontNameMap[fontMapOffset] = tmpFontNameMap[j]; - fontMapOffset++; - Tcl_FreeEncoding(encodings[j]); - tmpFontNameMap[j].utfName = NULL; - } - } - Tcl_FreeEncoding(encoding); - } - for (i = 0; i < numFonts; i++) { - if (tmpFontNameMap[i].utfName != NULL) { - newFontNameMap[fontMapOffset] = tmpFontNameMap[i]; - fontMapOffset++; - Tcl_FreeEncoding(encodings[i]); - } - } - if (fontMapOffset != numFonts) { - Tcl_Panic("TkpFontPkgInit: unexpected number of fonts"); - } - - mapPtr = &newFontNameMap[numFonts]; - mapPtr->utfName = NULL; - mapPtr->nativeName = NULL; - mapPtr->faceNum = 0; - - ckfree((char *) tmpFontNameMap); - ckfree((char *) encodings); - - gFontNameMap = newFontNameMap; + Rect rect = {0, 0, 1, 1}; + + SetFractEnable(0); + /* + * Used for saving and restoring state while drawing and measuring. + */ + if (ChkErr(NewGWorld, &gWorld, 32, &rect, NULL, NULL, 0 +#ifdef __LITTLE_ENDIAN__ + | kNativeEndianPixMap +#endif + ) != noErr) { + Tcl_Panic("TkpFontPkgInit: NewGWorld failed"); + } + /* + * The name of each font is stored in the encoding of that font. + * How would we translate a name from UTF-8 into the native encoding + * of the font unless we knew the encoding of that font? We can't. + * So, precompute the UTF-8 and native names of all fonts on the + * system. The when the user asks for font by its UTF-8 name, we + * lookup the name in that table and really ask for the font by its + * native name. Any unknown UTF-8 names will be mapped to the system + * font. + */ + FMCreateFontFamilyIterator(NULL, NULL, kFMDefaultOptions, &fontFamilyIterator); + numFonts = 0; + while (FMGetNextFontFamily(&fontFamilyIterator, &fontFamily) != kFMIterationCompleted) { + numFonts++; + } + tmpFontNameMap = (FontNameMap *) ckalloc(sizeof(FontNameMap) * numFonts); + encodings = (Tcl_Encoding *) ckalloc(sizeof(Tcl_Encoding) * numFonts); + mapPtr = tmpFontNameMap; + FMResetFontFamilyIterator(NULL, NULL, kFMDefaultOptions, &fontFamilyIterator); + i = 0; + while (FMGetNextFontFamily(&fontFamilyIterator, &fontFamily) != kFMIterationCompleted) { + mapPtr->faceNum = fontFamily; + encodings[i] = GetFontEncoding(mapPtr->faceNum, 0, &isSymbol); + FMGetFontFamilyName(fontFamily, nativeName ); + Tcl_ExternalToUtfDString(encodings[i], StrBody(nativeName), StrLength(nativeName), &ds); + mapPtr->utfName = Tk_GetUid(Tcl_DStringValue(&ds)); + mapPtr->nativeName = (StringPtr) ckalloc(StrLength(nativeName) + 1); + memcpy(mapPtr->nativeName, nativeName, StrLength(nativeName) + 1); + Tcl_DStringFree(&ds); + mapPtr++; + i++; + } + FMDisposeFontFamilyIterator(&fontFamilyIterator); + + /* + * Reorder FontNameMap so fonts with the preferred encodings are at + * the front of the list. The relative order of fonts that all have + * the same encoding is preserved. Fonts with unknown encodings get + * stuck at the end. + */ + newFontNameMap = (FontNameMap *) ckalloc(sizeof(FontNameMap) * (numFonts + 1)); + fontMapOffset = 0; + for (i = 0; encodingList[i] != NULL; i++) { + encoding = Tcl_GetEncoding(NULL, encodingList[i]); + if (encoding == NULL) { + continue; + } + for (j = 0; j < numFonts; j++) { + if (encodings[j] == encoding) { + newFontNameMap[fontMapOffset] = tmpFontNameMap[j]; + fontMapOffset++; + Tcl_FreeEncoding(encodings[j]); + tmpFontNameMap[j].utfName = NULL; + } + } + Tcl_FreeEncoding(encoding); + } + for (i = 0; i < numFonts; i++) { + if (tmpFontNameMap[i].utfName != NULL) { + newFontNameMap[fontMapOffset] = tmpFontNameMap[i]; + fontMapOffset++; + Tcl_FreeEncoding(encodings[i]); + } + } + if (fontMapOffset != numFonts) { + Tcl_Panic("TkpFontPkgInit: unexpected number of fonts"); + } + + mapPtr = &newFontNameMap[numFonts]; + mapPtr->utfName = NULL; + mapPtr->nativeName = NULL; + mapPtr->faceNum = 0; + + ckfree((char *) tmpFontNameMap); + ckfree((char *) encodings); + + gFontNameMap = newFontNameMap; } } /* *--------------------------------------------------------------------------- * + * GetThemeFontAndFamily -- + * + * Wrapper around the GetThemeFont and FMGetFontFamilyFromName APIs. + * + *--------------------------------------------------------------------------- + */ + +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; +} + +/* + *--------------------------------------------------------------------------- + * * 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. */ { - SInt16 family; - MacFont *fontPtr; - - if (strcmp(name, "system") == 0) { - family = GetSysFont(); - } else if (strcmp(name, "application") == 0) { - family = GetAppFont(); + ThemeFontID themeFontId; + FMFontFamily fontFamily; + Str255 fontName; + SInt16 fontSize; + Style fontStyle; + MacFont * fontPtr; + + if (strcmp(name, SYSTEMFONT_NAME) == 0) { + themeFontId = kThemeSystemFont; + } else if (strcmp(name, APPLFONT_NAME) == 0) { + 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; } - + fontPtr = (MacFont *) ckalloc(sizeof(MacFont)); - InitFont(tkwin, family, 0, 0, fontPtr); - + InitFont(tkwin, fontFamily, fontName, fontSize, fontStyle, fontPtr); + return (TkFont *) fontPtr; } /* *--------------------------------------------------------------------------- * - * TkpGetFontFromAttributes -- + * 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. */ + 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. */ + /* Set of attributes to match. */ { short faceNum, style; int i, j; - CONST char *faceName, *fallback; + const char *faceName, *fallback; char ***fallbacks; MacFont *fontPtr; - + /* * Algorithm to get the closest font to the one requested. * * try fontname * try all aliases for fontname * foreach fallback for fontname - * try the fallback - * try all aliases for the fallback + * try the fallback + * try all aliases for the fallback */ - + faceNum = 0; faceName = faPtr->family; if (faceName != NULL) { - if (GetFamilyOrAliasNum(faceName, &faceNum) != 0) { - goto found; - } - fallbacks = TkFontGetFallbacks(); - for (i = 0; fallbacks[i] != NULL; i++) { - for (j = 0; (fallback = fallbacks[i][j]) != NULL; j++) { - if (strcasecmp(faceName, fallback) == 0) { - for (j = 0; (fallback = fallbacks[i][j]) != NULL; j++) { - if (GetFamilyOrAliasNum(fallback, &faceNum)) { - goto found; - } - } - } - break; - } - } + if (GetFamilyOrAliasNum(faceName, &faceNum) != 0) { + goto found; + } + fallbacks = TkFontGetFallbacks(); + for (i = 0; fallbacks[i] != NULL; i++) { + for (j = 0; (fallback = fallbacks[i][j]) != NULL; j++) { + if (strcasecmp(faceName, fallback) == 0) { + for (j = 0; (fallback = fallbacks[i][j]) != NULL; j++) { + if (GetFamilyOrAliasNum(fallback, &faceNum)) { + goto found; + } + } + } + break; + } + } } - - found: + +found: style = 0; if (faPtr->weight != TK_FW_NORMAL) { - style |= bold; + style |= bold; } if (faPtr->slant != TK_FS_ROMAN) { - style |= italic; + style |= italic; } if (faPtr->underline) { - style |= underline; + style |= 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, faceNum, faPtr->size, style, fontPtr); - + InitFont(tkwin, faceNum, NULL, faPtr->size, style, fontPtr); + return (TkFont *) fontPtr; } @@ -526,26 +579,26 @@ 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: - * None. + * None. * * Side effects: - * TkFont is deallocated. + * TkFont is deallocated. * *--------------------------------------------------------------------------- */ void TkpDeleteFont( - TkFont *tkFontPtr) /* Token of font to be deleted. */ + TkFont *tkFontPtr) /* Token of font to be deleted. */ { MacFont *fontPtr; - + fontPtr = (MacFont *) tkFontPtr; ReleaseFont(fontPtr); } @@ -555,31 +608,31 @@ 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. */ +{ FontNameMap *mapPtr; Tcl_Obj *resultPtr, *strPtr; - + resultPtr = Tcl_GetObjResult(interp); for (mapPtr = gFontNameMap; mapPtr->utfName != NULL; mapPtr++) { - strPtr = Tcl_NewStringObj(mapPtr->utfName, -1); - Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); + strPtr = Tcl_NewStringObj(mapPtr->utfName, -1); + Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); } } @@ -588,23 +641,23 @@ 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(interp, tkfont) - Tcl_Interp *interp; /* Interp to hold result. */ - Tk_Font tkfont; /* Font object to query. */ +TkpGetSubFonts( + Tcl_Interp *interp, /* Interp to hold result. */ + Tk_Font tkfont) /* Font object to query. */ { int i; Tcl_Obj *resultPtr, *strPtr; @@ -612,13 +665,13 @@ TkpGetSubFonts(interp, tkfont) FontFamily *familyPtr; Str255 nativeName; - resultPtr = Tcl_GetObjResult(interp); + resultPtr = Tcl_GetObjResult(interp); fontPtr = (MacFont *) tkfont; for (i = 0; i < fontPtr->numSubFonts; i++) { - familyPtr = fontPtr->subFontArray[i].familyPtr; - GetFontName(familyPtr->faceNum, nativeName); - strPtr = Tcl_NewStringObj(GetUtfFaceName(nativeName), -1); - Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); + familyPtr = fontPtr->subFontArray[i].familyPtr; + GetFontName(familyPtr->faceNum, nativeName); + strPtr = Tcl_NewStringObj(GetUtfFaceName(nativeName), -1); + Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); } } @@ -627,50 +680,50 @@ TkpGetSubFonts(interp, tkfont) * * 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. * * 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 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. */ { MacFont *fontPtr; SubFont *thisSubFontPtr, *lastSubFontPtr; - CGrafPtr saveWorld; - GDHandle saveDevice; + CGrafPtr savePort; + Boolean portChanged; int curX, curByte; /* @@ -684,109 +737,110 @@ Tk_MeasureChars( * where a word or line break would occur, then can we map that * number back to UTF-8? */ - + fontPtr = (MacFont *) tkfont; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(gWorld, NULL); - + portChanged = QDSwapPort(gWorld, &savePort); + TextSize(fontPtr->size); TextFace(fontPtr->style); lastSubFontPtr = &fontPtr->subFontArray[0]; - + if (numBytes == 0) { - curX = 0; - curByte = 0; + curX = 0; + curByte = 0; } else if (maxLength < 0) { - CONST char *p, *end, *next; - Tcl_UniChar ch; - FontFamily *familyPtr; - Tcl_DString runString; - - /* - * A three step process: - * 1. Find a contiguous range of characters that can all be - * represented by a single screen font. - * 2. Convert those chars to the encoding of that font. - * 3. Measure converted chars. - */ - - curX = 0; - end = source + numBytes; - for (p = source; p < end; ) { - next = p + Tcl_UtfToUniChar(p, &ch); - thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); - if (thisSubFontPtr != lastSubFontPtr) { - familyPtr = lastSubFontPtr->familyPtr; - TextFont(familyPtr->faceNum); - Tcl_UtfToExternalDString(familyPtr->encoding, source, - p - source, &runString); - curX += TextWidth(Tcl_DStringValue(&runString), 0, - Tcl_DStringLength(&runString)); - Tcl_DStringFree(&runString); + const char *p, *end, *next; + Tcl_UniChar ch; + FontFamily *familyPtr; + Tcl_DString runString; + + /* + * A three step process: + * 1. Find a contiguous range of characters that can all be + * represented by a single screen font. + * 2. Convert those chars to the encoding of that font. + * 3. Measure converted chars. + */ + + curX = 0; + end = source + numBytes; + for (p = source; p < end; ) { + next = p + Tcl_UtfToUniChar(p, &ch); + thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); + if (thisSubFontPtr != lastSubFontPtr) { + familyPtr = lastSubFontPtr->familyPtr; + TextFont(familyPtr->faceNum); + Tcl_UtfToExternalDString(familyPtr->encoding, source, + p - source, &runString); + curX += TextWidth(Tcl_DStringValue(&runString), 0, + Tcl_DStringLength(&runString)); + Tcl_DStringFree(&runString); lastSubFontPtr = thisSubFontPtr; - source = p; - } - p = next; - } - familyPtr = lastSubFontPtr->familyPtr; - TextFont(familyPtr->faceNum); - Tcl_UtfToExternalDString(familyPtr->encoding, source, p - source, - &runString); - curX += TextWidth(Tcl_DStringValue(&runString), 0, - Tcl_DStringLength(&runString)); - Tcl_DStringFree(&runString); - curByte = numBytes; + source = p; + } + p = next; + } + familyPtr = lastSubFontPtr->familyPtr; + TextFont(familyPtr->faceNum); + Tcl_UtfToExternalDString(familyPtr->encoding, source, p - source, + &runString); + curX += TextWidth(Tcl_DStringValue(&runString), 0, + Tcl_DStringLength(&runString)); + Tcl_DStringFree(&runString); + curByte = numBytes; } else { - CONST char *p, *end, *next, *sourceOrig; - int widthLeft; - Tcl_UniChar ch; - CONST char *rest = NULL; - - /* - * How many chars will fit in the space allotted? - */ - - if (maxLength > 32767) { - maxLength = 32767; - } - - widthLeft = maxLength; - sourceOrig = source; - end = source + numBytes; - for (p = source; p < end; p = next) { - next = p + Tcl_UtfToUniChar(p, &ch); - thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); - if (thisSubFontPtr != lastSubFontPtr) { - if (p > source) { - rest = BreakLine(lastSubFontPtr->familyPtr, flags, source, - p - source, &widthLeft); - flags &= ~TK_AT_LEAST_ONE; - if (rest != NULL) { - p = source; - break; - } - } + const char *p, *end, *next, *sourceOrig; + int widthLeft; + Tcl_UniChar ch; + const char *rest = NULL; + + /* + * How many chars will fit in the space allotted? + */ + + if (maxLength > 32767) { + maxLength = 32767; + } + + widthLeft = maxLength; + sourceOrig = source; + end = source + numBytes; + for (p = source; p < end; p = next) { + next = p + Tcl_UtfToUniChar(p, &ch); + thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); + if (thisSubFontPtr != lastSubFontPtr) { + if (p > source) { + rest = BreakLine(lastSubFontPtr->familyPtr, flags, source, + p - source, &widthLeft); + flags &= ~TK_AT_LEAST_ONE; + if (rest != NULL) { + p = source; + break; + } + } lastSubFontPtr = thisSubFontPtr; - source = p; - } - } - - if (p > source) { - rest = BreakLine(lastSubFontPtr->familyPtr, flags, source, p - source, - &widthLeft); - } - - if (rest == NULL) { - curByte = numBytes; - } else { - curByte = rest - sourceOrig; - } - curX = maxLength - widthLeft; + source = p; + } + } + + if (p > source) { + rest = BreakLine(lastSubFontPtr->familyPtr, flags, source, p - source, + &widthLeft); + } + + if (rest == NULL) { + curByte = numBytes; + } else { + curByte = rest - sourceOrig; + } + curX = maxLength - widthLeft; } - SetGWorld(saveWorld, saveDevice); + if (portChanged) { + QDSwapPort(savePort, NULL); + } *lengthPtr = curX; return curByte; @@ -797,48 +851,48 @@ Tk_MeasureChars( * * BreakLine -- * - * Determine where the given line of text should be broken so that it - * fits in the specified range. Before calling this function, the - * font values and graphics port must be set. + * Determine where the given line of text should be broken so that it + * fits in the specified range. Before calling this function, the + * font values and graphics port must be set. * * Results: - * The return value is NULL if the specified range is larger that the - * space the text needs, and *widthLeftPtr is filled with how much - * space is left in the range after measuring the whole text buffer. - * Otherwise, the return value is a pointer into the text buffer that - * indicates where the line should be broken (up to, but not including - * that character), and *widthLeftPtr is filled with how much space is - * left in the range after measuring up to that character. + * The return value is NULL if the specified range is larger that the + * space the text needs, and *widthLeftPtr is filled with how much + * space is left in the range after measuring the whole text buffer. + * Otherwise, the return value is a pointer into the text buffer that + * indicates where the line should be broken (up to, but not including + * that character), and *widthLeftPtr is filled with how much space is + * left in the range after measuring up to that character. * * Side effects: - * None. + * None. * *--------------------------------------------------------------------------- */ - -static CONST char * + +static const char * BreakLine( - FontFamily *familyPtr, /* FontFamily that describes the font values - * that are already selected into the graphics - * port. */ - 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. */ - 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 *widthLeftPtr) /* On input, specifies size of range into - * which characters from source buffer should - * be fit. On output, filled with how much - * space is left after fitting as many - * characters as possible into the range. - * Result may be negative if TK_AT_LEAST_ONE - * was specified in the flags argument. */ + FontFamily *familyPtr, /* FontFamily that describes the font values + * that are already selected into the graphics + * port. */ + 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. */ + 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 *widthLeftPtr) /* On input, specifies size of range into + * which characters from source buffer should + * be fit. On output, filled with how much + * space is left after fitting as many + * characters as possible into the range. + * Result may be negative if TK_AT_LEAST_ONE + * was specified in the flags argument. */ { Fixed pixelWidth, widthLeft; StyledLineBreakCode breakCode; @@ -848,37 +902,37 @@ BreakLine( Point point; int charOffset, thisCharWasDoubleByte; char *p, *end, *typeTable; - + TextFont(familyPtr->faceNum); Tcl_UtfToExternalDString(familyPtr->encoding, source, numBytes, - &runString); - pixelWidth = Int2Fixed(*widthLeftPtr) + 1; + &runString); + pixelWidth = IntToFixed(*widthLeftPtr) + 1; if (flags & TK_WHOLE_WORDS) { - textOffset = (flags & TK_AT_LEAST_ONE); - widthLeft = pixelWidth; - breakCode = StyledLineBreak(Tcl_DStringValue(&runString), - Tcl_DStringLength(&runString), 0, Tcl_DStringLength(&runString), - 0, &widthLeft, &textOffset); - if (breakCode != smBreakOverflow) { - /* - * StyledLineBreak includes all the space characters at the end of - * line that we want to suppress. - */ - - textOffset = VisibleLength(Tcl_DStringValue(&runString), textOffset); - goto getoffset; - } + textOffset = (flags & TK_AT_LEAST_ONE); + widthLeft = pixelWidth; + breakCode = StyledLineBreak(Tcl_DStringValue(&runString), + Tcl_DStringLength(&runString), 0, Tcl_DStringLength(&runString), + 0, &widthLeft, &textOffset); + if (breakCode != smBreakOverflow) { + /* + * StyledLineBreak includes all the space characters at the end of + * line that we want to suppress. + */ + + textOffset = VisibleLength(Tcl_DStringValue(&runString), textOffset); + goto getoffset; + } } else { - point.v = 1; - point.h = 1; - textOffset = PixelToChar(Tcl_DStringValue(&runString), - Tcl_DStringLength(&runString), 0, pixelWidth, &leadingEdge, - &widthLeft, smOnlyStyleRun, point, point); - if (Fixed2Int(widthLeft) < 0) { - goto getoffset; - } + point.v = 1; + point.h = 1; + textOffset = PixelToChar(Tcl_DStringValue(&runString), + Tcl_DStringLength(&runString), 0, pixelWidth, &leadingEdge, + &widthLeft, smOnlyStyleRun, point, point); + if (FixedToInt(widthLeft) < 0) { + goto getoffset; + } } - *widthLeftPtr = Fixed2Int(widthLeft); + *widthLeftPtr = FixedToInt(widthLeft); Tcl_DStringFree(&runString); return NULL; @@ -886,50 +940,50 @@ BreakLine( * The conversion routine that converts UTF-8 to the target encoding * must map one UTF-8 character to exactly one encoding-specific * character, so that the following algorithm works: - * + * * 1. Get byte offset of where line should be broken. * 2. Get char offset corresponding to that byte offset. * 3. Map that char offset to byte offset in UTF-8 string. - */ + */ getoffset: thisCharWasDoubleByte = 0; if (familyPtr->isMultiByteFont == 0) { - charOffset = textOffset; + charOffset = textOffset; } else { - charOffset = 0; - typeTable = familyPtr->typeTable; - - p = Tcl_DStringValue(&runString); - end = p + textOffset; - thisCharWasDoubleByte = typeTable[*((unsigned char *) p)]; - for ( ; p < end; p++) { - thisCharWasDoubleByte = typeTable[*((unsigned char *) p)]; - p += thisCharWasDoubleByte; - charOffset++; - } + charOffset = 0; + typeTable = familyPtr->typeTable; + + p = Tcl_DStringValue(&runString); + end = p + textOffset; + thisCharWasDoubleByte = typeTable[*((unsigned char *) p)]; + for ( ; p < end; p++) { + thisCharWasDoubleByte = typeTable[*((unsigned char *) p)]; + p += thisCharWasDoubleByte; + charOffset++; + } } - + if ((flags & TK_WHOLE_WORDS) == 0) { - if ((flags & TK_PARTIAL_OK) && (leadingEdge != 0)) { - textOffset += thisCharWasDoubleByte; - textOffset++; - charOffset++; - } else if (((flags & TK_PARTIAL_OK) == 0) && (leadingEdge == 0)) { - textOffset -= thisCharWasDoubleByte; - textOffset--; - charOffset--; - } + if ((flags & TK_PARTIAL_OK) && (leadingEdge != 0)) { + textOffset += thisCharWasDoubleByte; + textOffset++; + charOffset++; + } else if (((flags & TK_PARTIAL_OK) == 0) && (leadingEdge == 0)) { + textOffset -= thisCharWasDoubleByte; + textOffset--; + charOffset--; + } } - if ((textOffset == 0) && (Tcl_DStringLength(&runString) > 0) - && (flags & TK_AT_LEAST_ONE)) { - p = Tcl_DStringValue(&runString); - textOffset += familyPtr->typeTable[*((unsigned char *) p)]; - textOffset++; - charOffset++; + if ((textOffset == 0) && (Tcl_DStringLength(&runString) > 0) + && (flags & TK_AT_LEAST_ONE)) { + p = Tcl_DStringValue(&runString); + textOffset += familyPtr->typeTable[*((unsigned char *) p)]; + textOffset++; + charOffset++; } - *widthLeftPtr = Fixed2Int(pixelWidth) - - TextWidth(Tcl_DStringValue(&runString), 0, textOffset); + *widthLeftPtr = FixedToInt(pixelWidth) + - TextWidth(Tcl_DStringValue(&runString), 0, textOffset); Tcl_DStringFree(&runString); return Tcl_UtfAtIndex(source, charOffset); } @@ -939,113 +993,82 @@ BreakLine( * * Tk_DrawChars -- * - * Draw a string of characters on the screen. + * Draw a string of characters on the screen. * * 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 - * 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 + * string when drawing. */ { - MacFont *fontPtr; - MacDrawable *macWin; - RGBColor macColor, origColor; - GWorldPtr destPort; - CGrafPtr saveWorld; - GDHandle saveDevice; - short txFont, txFace, txSize; - BitMapPtr stippleMap; - Rect portRect; + MacDrawable *macWin = (MacDrawable *) drawable; + MacFont *fontPtr = (MacFont *) tkfont; + TkMacOSXDrawingContext drawingContext; - fontPtr = (MacFont *) tkfont; - macWin = (MacDrawable *) drawable; - - destPort = TkMacOSXGetDrawablePort(drawable); - GetPortBounds(destPort, &portRect); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - - TkMacOSXSetUpClippingRgn(drawable); - TkMacOSXSetUpGraphicsPort(gc, destPort); - - txFont = GetPortTextFont(destPort); - txFace = GetPortTextFace(destPort); - txSize = GetPortTextSize(destPort); - GetForeColor(&origColor); - + TkMacOSXSetupDrawingContext(drawable, gc, 0, &drawingContext); +#if 0 + /* + * Stippled QD text drawing only kind of works and is ugly, so disable it + * for now: + */ 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) == true) { - RGBForeColor(&macColor); - } - GetQDGlobalsWhite(&white); - ShowPen(); - FillRect(&stippleMap->bounds, &white); - MultiFontDrawText(fontPtr, source, numBytes, 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) == true) { - RGBForeColor(&macColor); - } - ShowPen(); - MultiFontDrawText(fontPtr, source, numBytes, macWin->xOff + x, - macWin->yOff + y); - HidePen(); + || gc->fill_style == FillOpaqueStippled) + && gc->stipple != None) { + TkMacOSXDrawingContext pixmapDrawingContext; + BitMapPtr stippleMap; + Pixmap pixmap; + Pattern white; + Rect bounds = drawingContext.portBounds; + + OffsetRect(&bounds, macWin->xOff + x, 0); + stippleMap = TkMacOSXMakeStippleMap(drawable, gc->stipple); + pixmap = Tk_GetPixmap(display, drawable, + stippleMap->bounds.right, stippleMap->bounds.bottom, 0); + TkMacOSXSetupDrawingContext(pixmap, gc, 0, &pixmapDrawingContext); + GetQDGlobalsWhite(&white); + FillRect(&stippleMap->bounds, &white); + MultiFontDrawText(fontPtr, source, numBytes, 0, macWin->yOff + y); + TkMacOSXRestoreDrawingContext(&pixmapDrawingContext); + CopyDeepMask(GetPortBitMapForCopyBits(TkMacOSXGetDrawablePort(pixmap)), + stippleMap, GetPortBitMapForCopyBits( + TkMacOSXGetDrawablePort(drawable)), &stippleMap->bounds, + &stippleMap->bounds, &bounds, 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 +#endif + { + MultiFontDrawText(fontPtr, source, numBytes, macWin->xOff + x, + macWin->yOff + y); } - - TextFont(txFont); - TextSize(txSize); - TextFace(txFace); - RGBForeColor(&origColor); - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&drawingContext); } /* @@ -1053,37 +1076,37 @@ Tk_DrawChars( * * MultiFontDrawText -- * - * Helper function for Tk_DrawChars. Draws characters, using the - * various screen fonts in fontPtr to draw multilingual characters. - * Note: No bidirectional support. + * Helper function for Tk_DrawChars. Draws characters, using the + * various screen fonts in fontPtr to draw multilingual characters. + * Note: No bidirectional support. * * Results: - * None. + * None. * * Side effects: - * Information gets drawn on the screen. - * Contents of fontPtr may be modified if more subfonts were loaded - * in order to draw all the multilingual characters in the given - * string. + * Information gets drawn on the screen. + * Contents of fontPtr may be modified if more subfonts were loaded + * in order to draw all the multilingual characters in the given + * string. * *------------------------------------------------------------------------- */ static void MultiFontDrawText( - MacFont *fontPtr, /* Contains set of fonts to use when drawing - * following string. */ - CONST char *source, /* Potentially multilingual UTF-8 string. */ - int numBytes, /* Length of string in bytes. */ - int x, int y) /* Coordinates at which to place origin * - * of string when drawing. */ + MacFont *fontPtr, /* Contains set of fonts to use when drawing + * following string. */ + const char *source, /* Potentially multilingual UTF-8 string. */ + int numBytes, /* Length of string in bytes. */ + int x, int y) /* Coordinates at which to place origin * + * of string when drawing. */ { SubFont *thisSubFontPtr, *lastSubFontPtr; FontFamily *familyPtr; Tcl_DString runString; - CONST char *p, *end, *next; + const char *p, *end, *next; Tcl_UniChar ch; - + TextSize(fontPtr->size); TextFace(fontPtr->style); @@ -1091,35 +1114,35 @@ MultiFontDrawText( end = source + numBytes; for (p = source; p < end; ) { - next = p + Tcl_UtfToUniChar(p, &ch); - thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); - if (thisSubFontPtr != lastSubFontPtr) { - if (p > source) { - familyPtr = lastSubFontPtr->familyPtr; - TextFont(familyPtr->faceNum); - Tcl_UtfToExternalDString(familyPtr->encoding, source, - p - source, &runString); - MoveTo((short) x, (short) y); - DrawText(Tcl_DStringValue(&runString), 0, - Tcl_DStringLength(&runString)); - x += TextWidth(Tcl_DStringValue(&runString), 0, - Tcl_DStringLength(&runString)); - Tcl_DStringFree(&runString); - source = p; - } - lastSubFontPtr = thisSubFontPtr; - } - p = next; + next = p + Tcl_UtfToUniChar(p, &ch); + thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); + if (thisSubFontPtr != lastSubFontPtr) { + if (p > source) { + familyPtr = lastSubFontPtr->familyPtr; + TextFont(familyPtr->faceNum); + Tcl_UtfToExternalDString(familyPtr->encoding, source, + p - source, &runString); + MoveTo((short) x, (short) y); + DrawText(Tcl_DStringValue(&runString), 0, + Tcl_DStringLength(&runString)); + x += TextWidth(Tcl_DStringValue(&runString), 0, + Tcl_DStringLength(&runString)); + Tcl_DStringFree(&runString); + source = p; + } + lastSubFontPtr = thisSubFontPtr; + } + p = next; } if (p > source) { - familyPtr = lastSubFontPtr->familyPtr; - TextFont(familyPtr->faceNum); - Tcl_UtfToExternalDString(familyPtr->encoding, source, - p - source, &runString); - MoveTo((short) x, (short) y); - DrawText(Tcl_DStringValue(&runString), 0, - Tcl_DStringLength(&runString)); - Tcl_DStringFree(&runString); + familyPtr = lastSubFontPtr->familyPtr; + TextFont(familyPtr->faceNum); + Tcl_UtfToExternalDString(familyPtr->encoding, source, + p - source, &runString); + MoveTo((short) x, (short) y); + DrawText(Tcl_DStringValue(&runString), 0, + Tcl_DStringLength(&runString)); + Tcl_DStringFree(&runString); } } @@ -1128,58 +1151,32 @@ MultiFontDrawText( * * TkMacOSXIsCharacterMissing -- * - * Given a tkFont and a character determines whether the character has - * a glyph defined in the font or not. Note that this is potentially - * not compatible with Mac OS 8 as it looks at the font handle - * structure directly. Looks into the character array of the font - * handle to determine whether the glyph is defined or not. + * Given a tkFont and a character determines whether the character has + * a glyph defined in the font or not. Note that this is potentially + * not compatible with Mac OS 8 as it looks at the font handle + * structure directly. Looks into the character array of the font + * handle to determine whether the glyph is defined 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. */ { -/* - * For some reason, FMSwapFont always returns a NULL font handle under OS X - * Until we figure this one out, return 0; - */ -#ifdef MAC_OSX_TK + /* + * For some reason, FMSwapFont always returns a NULL font handle under OS X + * Until we figure this one out, return 0; + */ + return 0; -#else - MacFont *fontPtr = (MacFont *) tkfont; - FMInput fm; - FontRec **fontRecHandle; - FMOutPtr fmOutPtr; - - - fm.family = fontPtr->subFontArray[0].familyPtr->faceNum; - fm.size = fontPtr->size; - fm.face = fontPtr->style; - fm.needBits = 0; - fm.device = 0; - fm.numer.h = fm.numer.v = fm.denom.h = fm.denom.v = 1; - - fmOutPtr = FMSwapFont(&fm); - fprintf(stderr,"fmOut %08x, handle %08x\n", (int)fmOutPtr, fmOutPtr->fontHandle); - -#if !defined(UNIVERSAL_INTERFACES_VERSION) || (UNIVERSAL_INTERFACES_VERSION < 0x0300) - fontRecHandle = (FontRec **) FMSwapFont(&fm)->fontResult; -#else - fontRecHandle = (FontRec **) FMSwapFont(&fm)->fontHandle; -#endif - return *(short *) ((long) &(*fontRecHandle)->owTLoc - + ((long)((*fontRecHandle)->owTLoc + searchChar - - (*fontRecHandle)->firstChar) * sizeof(short))) == -1; -#endif } /* @@ -1187,110 +1184,113 @@ TkMacOSXIsCharacterMissing( * * 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. */ - int faceNum, /* Macintosh font number. */ - int size, /* Point size for Macintosh font. */ - int style, /* Macintosh style bits. */ - MacFont *fontPtr) /* Filled with information constructed from - * the above arguments. */ + Tk_Window tkwin, /* For display where font will be used. */ + int faceNum, /* Macintosh font number. */ + unsigned char *familyName, /* The font family name or NULL. */ + int size, /* Point size for Macintosh font. */ + int style, /* Macintosh style bits. */ + MacFont *fontPtr) /* Filled with information constructed from + * the above arguments. */ { Str255 nativeName; FontInfo fi; TkFontAttributes *faPtr; TkFontMetrics *fmPtr; - CGrafPtr saveWorld; - GDHandle saveDevice; + CGrafPtr savePort; + Boolean portChanged; short pixels; if (size == 0) { - size = -GetDefFontSize(); + size = -GetDefFontSize(); } pixels = (short) TkFontGetPixels(tkwin, size); - - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(gWorld, NULL); + + portChanged = QDSwapPort(gWorld, &savePort); TextFont(faceNum); - - TextSize(pixels); TextFace(style); GetFontInfo(&fi); - GetFontName(faceNum, nativeName); - fontPtr->font.fid = (Font) fontPtr; - + if (!familyName) { + GetFontName(faceNum, nativeName); + familyName = nativeName; + } + fontPtr->font.fid = (Font) fontPtr; + faPtr = &fontPtr->font.fa; - faPtr->family = GetUtfFaceName(nativeName); + faPtr->family = GetUtfFaceName(familyName); faPtr->size = TkFontGetPoints(tkwin, size); faPtr->weight = (style & bold) ? TK_FW_BOLD : TK_FW_NORMAL; faPtr->slant = (style & italic) ? TK_FS_ITALIC : TK_FS_ROMAN; faPtr->underline = ((style & underline) != 0); faPtr->overstrike = 0; - + fmPtr = &fontPtr->font.fm; - fmPtr->ascent = fi.ascent; - fmPtr->descent = fi.descent; + fmPtr->ascent = fi.ascent; + fmPtr->descent = fi.descent; fmPtr->maxWidth = fi.widMax; fmPtr->fixed = (CharWidth('i') == CharWidth('w')); - + fontPtr->size = pixels; fontPtr->style = (short) style; - + fontPtr->numSubFonts = 1; fontPtr->subFontArray = fontPtr->staticSubFonts; InitSubFont(fontPtr, faceNum, &fontPtr->subFontArray[0]); - SetGWorld(saveWorld, saveDevice); + if (portChanged) { + QDSwapPort(savePort, NULL); + } } /* *------------------------------------------------------------------------- * * 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. */ { int i; for (i = 0; i < fontPtr->numSubFonts; i++) { - ReleaseSubFont(&fontPtr->subFontArray[i]); + ReleaseSubFont(&fontPtr->subFontArray[i]); } if (fontPtr->subFontArray != fontPtr->staticSubFonts) { - ckfree((char *) fontPtr->subFontArray); + ckfree((char *) fontPtr->subFontArray); } } @@ -1299,26 +1299,26 @@ ReleaseFont( * * InitSubFont -- * - * Wrap a screen font and load the FontFamily that represents - * it. Used to prepare a SubFont so that characters can be mapped - * from UTF-8 to the charset of the font. + * Wrap a screen font and load the FontFamily that represents + * it. Used to prepare a SubFont so that characters can be mapped + * from UTF-8 to the charset of the font. * * Results: - * The subFontPtr is filled with information about the font. + * The subFontPtr is filled with information about the font. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static void InitSubFont( - CONST MacFont *fontPtr, /* Font object in which the SubFont will be - * used. */ - int faceNum, /* The font number. */ - SubFont *subFontPtr) /* Filled with SubFont constructed from - * above attributes. */ + const MacFont *fontPtr, /* Font object in which the SubFont will be + * used. */ + int faceNum, /* The font number. */ + SubFont *subFontPtr) /* Filled with SubFont constructed from + * above attributes. */ { subFontPtr->familyPtr = AllocFontFamily(fontPtr, faceNum); subFontPtr->fontMap = subFontPtr->familyPtr->fontMap; @@ -1329,21 +1329,21 @@ InitSubFont( * * ReleaseSubFont -- * - * Called to release the contents of a SubFont. The caller is - * responsible for freeing the memory used by the SubFont itself. + * Called to release the contents of a SubFont. The caller is + * responsible for freeing the memory used by the SubFont itself. * * Results: - * None. + * None. * * Side effects: - * Memory and resources are freed. + * Memory and resources are freed. * *--------------------------------------------------------------------------- */ static void ReleaseSubFont( - SubFont *subFontPtr) /* The SubFont to delete. */ + SubFont *subFontPtr) /* The SubFont to delete. */ { FreeFontFamily(subFontPtr->familyPtr); } @@ -1353,39 +1353,39 @@ ReleaseSubFont( * * AllocFontFamily -- * - * Find the FontFamily structure associated with the given font - * family. The information should be stored by the caller in a - * SubFont and used when determining if that SubFont supports a - * character. + * Find the FontFamily structure associated with the given font + * family. The information should be stored by the caller in a + * SubFont and used when determining if that SubFont supports a + * character. * * Results: - * A pointer to a FontFamily. The reference count in the FontFamily - * is automatically incremented. When the SubFont is released, the - * reference count is decremented. When no SubFont is using this - * FontFamily, it may be deleted. + * A pointer to a FontFamily. The reference count in the FontFamily + * is automatically incremented. When the SubFont is released, the + * reference count is decremented. When no SubFont is using this + * FontFamily, it may be deleted. * * Side effects: - * A new FontFamily structure will be allocated if this font family - * has not been seen. + * A new FontFamily structure will be allocated if this font family + * has not been seen. * *------------------------------------------------------------------------- */ static FontFamily * AllocFontFamily( - CONST MacFont *fontPtr, /* Font object in which the FontFamily will - * be used. */ - int faceNum) /* The font number. */ + const MacFont *fontPtr, /* Font object in which the FontFamily will + * be used. */ + int faceNum) /* The font number. */ { FontFamily *familyPtr; int i; - + familyPtr = fontFamilyList; for (; familyPtr != NULL; familyPtr = familyPtr->nextPtr) { - if (familyPtr->faceNum == faceNum) { - familyPtr->refCount++; - return familyPtr; - } + if (familyPtr->faceNum == faceNum) { + familyPtr->refCount++; + return familyPtr; + } } familyPtr = (FontFamily *) ckalloc(sizeof(FontFamily)); @@ -1393,27 +1393,27 @@ AllocFontFamily( familyPtr->nextPtr = fontFamilyList; fontFamilyList = familyPtr; - /* - * Set key for this FontFamily. + /* + * Set key for this FontFamily. */ - + familyPtr->faceNum = faceNum; - /* + /* * An initial refCount of 2 means that FontFamily information will * persist even when the SubFont that loaded the FontFamily is released. * Change it to 1 to cause FontFamilies to be unloaded when not in use. */ - + familyPtr->refCount = 2; familyPtr->encoding = GetFontEncoding(faceNum, 1, &familyPtr->isSymbolFont); familyPtr->isMultiByteFont = 0; FillParseTable(familyPtr->typeTable, FontToScript(faceNum)); for (i = 0; i < 256; i++) { - if (familyPtr->typeTable[i] != 0) { - familyPtr->isMultiByteFont = 1; - break; - } + if (familyPtr->typeTable[i] != 0) { + familyPtr->isMultiByteFont = 1; + break; + } } return familyPtr; } @@ -1423,52 +1423,52 @@ AllocFontFamily( * * FreeFontFamily -- * - * Called to free a FontFamily when the SubFont is finished using it. - * Frees the contents of the FontFamily and the memory used by the - * FontFamily itself. + * Called to free a FontFamily when the SubFont is finished using it. + * Frees the contents of the FontFamily and the memory used by the + * FontFamily itself. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ - + static void FreeFontFamily( - FontFamily *familyPtr) /* The FontFamily to delete. */ + FontFamily *familyPtr) /* The FontFamily to delete. */ { FontFamily **familyPtrPtr; int i; if (familyPtr == NULL) { - return; + return; } familyPtr->refCount--; if (familyPtr->refCount > 0) { - return; + return; } Tcl_FreeEncoding(familyPtr->encoding); for (i = 0; i < FONTMAP_PAGES; i++) { - if (familyPtr->fontMap[i] != NULL) { - ckfree((char *) familyPtr->fontMap[i]); - } + if (familyPtr->fontMap[i] != NULL) { + ckfree((char *) familyPtr->fontMap[i]); + } } - - /* - * Delete from list. + + /* + * Delete from list. */ - + for (familyPtrPtr = &fontFamilyList; ; ) { - if (*familyPtrPtr == familyPtr) { - *familyPtrPtr = familyPtr->nextPtr; - break; - } - familyPtrPtr = &(*familyPtrPtr)->nextPtr; + if (*familyPtrPtr == familyPtr) { + *familyPtrPtr = familyPtr->nextPtr; + break; + } + familyPtrPtr = &(*familyPtrPtr)->nextPtr; } - + ckfree((char *) familyPtr); } @@ -1477,115 +1477,115 @@ FreeFontFamily( * * FindSubFontForChar -- * - * Determine which physical screen font is necessary to use to - * display the given character. If the font object does not have - * a screen font that can display the character, another screen font - * may be loaded into the font object, following a set of preferred - * fallback rules. + * Determine which physical screen font is necessary to use to + * display the given character. If the font object does not have + * a screen font that can display the character, another screen font + * may be loaded into the font object, following a set of preferred + * fallback rules. * * Results: - * The return value is the SubFont to use to display the given - * character. + * The return value is the SubFont to use to display the given + * character. * * Side effects: - * The contents of fontPtr are modified to cache the results - * of the lookup and remember any SubFonts that were dynamically - * loaded. The table of SubFonts might be extended, and if a non-NULL - * reference to a subfont pointer is available, it is updated if it - * previously pointed into the old subfont table. + * The contents of fontPtr are modified to cache the results + * of the lookup and remember any SubFonts that were dynamically + * loaded. The table of SubFonts might be extended, and if a non-NULL + * reference to a subfont pointer is available, it is updated if it + * previously pointed into the old subfont table. * *------------------------------------------------------------------------- */ static SubFont * FindSubFontForChar( - MacFont *fontPtr, /* The font object with which the character - * will be displayed. */ - int ch, /* The Unicode character to be displayed. */ - SubFont **fixSubFontPtrPtr) /* Subfont reference to fix up if we + MacFont *fontPtr, /* The font object with which the character + * will be displayed. */ + int ch, /* The Unicode character to be displayed. */ + SubFont **fixSubFontPtrPtr) /* Subfont reference to fix up if we * reallocate our subfont table. */ { int i, j, k; - CONST char *fallbackName; + const char *fallbackName; char **aliases; SubFont *subFontPtr; FontNameMap *mapPtr; Tcl_DString faceNames; char ***fontFallbacks; char **anyFallbacks; - + if (FontMapLookup(&fontPtr->subFontArray[0], ch)) { - return &fontPtr->subFontArray[0]; + return &fontPtr->subFontArray[0]; } for (i = 1; i < fontPtr->numSubFonts; i++) { - if (FontMapLookup(&fontPtr->subFontArray[i], ch)) { - return &fontPtr->subFontArray[i]; - } + if (FontMapLookup(&fontPtr->subFontArray[i], ch)) { + return &fontPtr->subFontArray[i]; + } } /* * Keep track of all face names that we check, so we don't check some * name multiple times if it can be reached by multiple paths. */ - + Tcl_DStringInit(&faceNames); - + aliases = TkFontGetAliasList(fontPtr->font.fa.family); subFontPtr = NULL; fontFallbacks = TkFontGetFallbacks(); for (i = 0; fontFallbacks[i] != NULL; i++) { - for (j = 0; fontFallbacks[i][j] != NULL; j++) { - fallbackName = fontFallbacks[i][j]; - if (strcasecmp(fallbackName, fontPtr->font.fa.family) == 0) { - /* - * If the base font has a fallback... - */ - - goto tryfallbacks; - } else if (aliases != NULL) { - /* - * Or if an alias for the base font has a fallback... - */ - - for (k = 0; aliases[k] != NULL; k++) { - if (strcasecmp(aliases[k], fallbackName) == 0) { - goto tryfallbacks; - } - } - } - } - continue; - - /* - * ...then see if we can use one of the fallbacks, or an - * alias for one of the fallbacks. - */ - - tryfallbacks: - for (j = 0; fontFallbacks[i][j] != NULL; j++) { - fallbackName = fontFallbacks[i][j]; - subFontPtr = CanUseFallbackWithAliases(fontPtr, fallbackName, - ch, &faceNames, fixSubFontPtrPtr); - if (subFontPtr != NULL) { - goto end; - } - } + for (j = 0; fontFallbacks[i][j] != NULL; j++) { + fallbackName = fontFallbacks[i][j]; + if (strcasecmp(fallbackName, fontPtr->font.fa.family) == 0) { + /* + * If the base font has a fallback... + */ + + goto tryfallbacks; + } else if (aliases != NULL) { + /* + * Or if an alias for the base font has a fallback... + */ + + for (k = 0; aliases[k] != NULL; k++) { + if (strcasecmp(aliases[k], fallbackName) == 0) { + goto tryfallbacks; + } + } + } + } + continue; + + /* + * ...then see if we can use one of the fallbacks, or an + * alias for one of the fallbacks. + */ + + tryfallbacks: + for (j = 0; fontFallbacks[i][j] != NULL; j++) { + fallbackName = fontFallbacks[i][j]; + subFontPtr = CanUseFallbackWithAliases(fontPtr, fallbackName, + ch, &faceNames, fixSubFontPtrPtr); + if (subFontPtr != NULL) { + goto end; + } + } } - + /* - * See if we can use something from the global fallback list. + * See if we can use something from the global fallback list. */ anyFallbacks = TkFontGetGlobalClass(); for (i = 0; anyFallbacks[i] != NULL; i++) { - fallbackName = anyFallbacks[i]; - subFontPtr = CanUseFallbackWithAliases(fontPtr, fallbackName, ch, - &faceNames, fixSubFontPtrPtr); - if (subFontPtr != NULL) { - goto end; - } + fallbackName = anyFallbacks[i]; + subFontPtr = CanUseFallbackWithAliases(fontPtr, fallbackName, ch, + &faceNames, fixSubFontPtrPtr); + if (subFontPtr != NULL) { + goto end; + } } /* @@ -1594,27 +1594,27 @@ FindSubFontForChar( */ for (mapPtr = gFontNameMap; mapPtr->utfName != NULL; mapPtr++) { - fallbackName = mapPtr->utfName; - if (SeenName(fallbackName, &faceNames) == 0) { + fallbackName = mapPtr->utfName; + if (SeenName(fallbackName, &faceNames) == 0) { subFontPtr = CanUseFallback(fontPtr, fallbackName, ch, fixSubFontPtrPtr); - if (subFontPtr != NULL) { - goto end; - } - } + if (subFontPtr != NULL) { + goto end; + } + } } - + end: Tcl_DStringFree(&faceNames); - + if (subFontPtr == NULL) { - /* - * No font can display this character. We will use the base font - * and have it display the "unknown" character. - */ + /* + * No font can display this character. We will use the base font + * and have it display the "unknown" character. + */ - subFontPtr = &fontPtr->subFontArray[0]; - FontMapInsert(subFontPtr, ch); + subFontPtr = &fontPtr->subFontArray[0]; + FontMapInsert(subFontPtr, ch); } return subFontPtr; } @@ -1624,33 +1624,33 @@ FindSubFontForChar( * * FontMapLookup -- * - * See if the screen font can display the given character. + * See if the screen font can display the given character. * * Results: - * The return value is 0 if the screen font cannot display the - * character, non-zero otherwise. + * The return value is 0 if the screen font cannot display the + * character, non-zero otherwise. * * Side effects: - * New pages are added to the font mapping cache whenever the - * character belongs to a page that hasn't been seen before. - * When a page is loaded, information about all the characters on - * that page is stored, not just for the single character in - * question. + * New pages are added to the font mapping cache whenever the + * character belongs to a page that hasn't been seen before. + * When a page is loaded, information about all the characters on + * that page is stored, not just for the single character in + * question. * *------------------------------------------------------------------------- */ static int FontMapLookup( - SubFont *subFontPtr, /* Contains font mapping cache to be queried - * and possibly updated. */ - int ch) /* Character to be tested. */ + SubFont *subFontPtr, /* Contains font mapping cache to be queried + * and possibly updated. */ + int ch) /* Character to be tested. */ { int row, bitOffset; row = ch >> FONTMAP_SHIFT; if (subFontPtr->fontMap[row] == NULL) { - FontMapLoadPage(subFontPtr, row); + FontMapLoadPage(subFontPtr, row); } bitOffset = ch & (FONTMAP_BITSPERPAGE - 1); return (subFontPtr->fontMap[row][bitOffset >> 3] >> (bitOffset & 7)) & 1; @@ -1661,37 +1661,37 @@ FontMapLookup( * * FontMapInsert -- * - * Tell the font mapping cache that the given screen font should be - * used to display the specified character. This is called when no - * font on the system can be be found that can display that - * character; we lie to the font and tell it that it can display - * the character, otherwise we would end up re-searching the entire - * fallback hierarchy every time that character was seen. + * Tell the font mapping cache that the given screen font should be + * used to display the specified character. This is called when no + * font on the system can be be found that can display that + * character; we lie to the font and tell it that it can display + * the character, otherwise we would end up re-searching the entire + * fallback hierarchy every time that character was seen. * * Results: - * None. + * None. * * Side effects: - * New pages are added to the font mapping cache whenever the - * character belongs to a page that hasn't been seen before. - * When a page is loaded, information about all the characters on - * that page is stored, not just for the single character in - * question. + * New pages are added to the font mapping cache whenever the + * character belongs to a page that hasn't been seen before. + * When a page is loaded, information about all the characters on + * that page is stored, not just for the single character in + * question. * *------------------------------------------------------------------------- */ static void FontMapInsert( - SubFont *subFontPtr, /* Contains font mapping cache to be - * updated. */ - int ch) /* Character to be added to cache. */ + SubFont *subFontPtr, /* Contains font mapping cache to be + * updated. */ + int ch) /* Character to be added to cache. */ { int row, bitOffset; row = ch >> FONTMAP_SHIFT; if (subFontPtr->fontMap[row] == NULL) { - FontMapLoadPage(subFontPtr, row); + FontMapLoadPage(subFontPtr, row); } bitOffset = ch & (FONTMAP_BITSPERPAGE - 1); subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7); @@ -1702,25 +1702,25 @@ FontMapInsert( * * FontMapLoadPage -- * - * Load information about all the characters on a given page. - * This information consists of one bit per character that indicates - * whether the associated HFONT can (1) or cannot (0) display the - * characters on the page. + * Load information about all the characters on a given page. + * This information consists of one bit per character that indicates + * whether the associated HFONT can (1) or cannot (0) display the + * characters on the page. * * Results: - * None. + * None. * * Side effects: - * Mempry allocated. + * Mempry allocated. * *------------------------------------------------------------------------- */ -static void +static void FontMapLoadPage( - SubFont *subFontPtr, /* Contains font mapping cache to be - * updated. */ - int row) /* Index of the page to be loaded into - * the cache. */ + SubFont *subFontPtr, /* Contains font mapping cache to be + * updated. */ + int row) /* Index of the page to be loaded into + * the cache. */ { FMInput fm; FMOutPtr fmOut; @@ -1733,9 +1733,9 @@ FontMapLoadPage( subFontPtr->fontMap[row] = (char *) ckalloc(FONTMAP_BITSPERPAGE / 8); memset(subFontPtr->fontMap[row], 0, FONTMAP_BITSPERPAGE / 8); - + encoding = subFontPtr->familyPtr->encoding; - + fm.family = subFontPtr->familyPtr->faceNum; fm.size = 12; fm.face = 0; @@ -1745,82 +1745,33 @@ FontMapLoadPage( fm.numer.v = 1; fm.denom.h = 1; fm.denom.v = 1; - /* -#if !defined(UNIVERSAL_INTERFACES_VERSION) || (UNIVERSAL_INTERFACES_VERSION < 0x0300) - fHandle = FMSwapFont(&fm)->fontHandle; -#else - fHandle = FMSwapFont(&fm)->fontHandle; -#endif -*/ + /* * For some reason, FMSwapFont alywas returns a structure where the returned font handle * is NULL. Until we figure this one out, assume all characters are allowed */ + fmOut = FMSwapFont(&fm); fHandle = fmOut->fontHandle; isMultiByteFont = subFontPtr->familyPtr->isMultiByteFont; -#ifndef MAC_OSX_TK - GetResInfo(fHandle, &theID, &theType, theName); - fprintf ( stderr, "ResError() %d, %x\n", ResError (), fHandle ); - if (theType == 'sfnt') { -#endif - /* - * Found an outline font which has very complex font record. - * Let's just assume *ALL* the characters are allowed. - */ - - end = (row + 1) << FONTMAP_SHIFT; - for (i = row << FONTMAP_SHIFT; i < end; i++) { - if (Tcl_UtfToExternal(NULL, encoding, src, Tcl_UniCharToUtf(i, - src), - TCL_ENCODING_STOPONERROR, NULL, (char *) buf, - sizeof(buf), - &srcRead, &dstWrote, NULL) == TCL_OK) { - bitOffset = i & (FONTMAP_BITSPERPAGE - 1); - subFontPtr->fontMap[row][bitOffset >> 3] |= 1 - << (bitOffset & 7); - } - } -#ifndef MAC_OSX_TK - } else { - /* - * Found an old bitmap font which has a well-defined record. - * We can check the width table to see which characters exist. - */ - - fontRecPtr = *((FontRec **) fHandle ); - widths = (short *) ((long) &fontRecPtr->owTLoc - + ((long) (fontRecPtr->owTLoc - fontRecPtr->firstChar) - * sizeof(short))); - - end = (row + 1) << FONTMAP_SHIFT; - for (i = row << FONTMAP_SHIFT; i < end; i++) { - if (Tcl_UtfToExternal(NULL, encoding, src, - Tcl_UniCharToUtf(i, src), - TCL_ENCODING_STOPONERROR, NULL, (char *) buf, sizeof(buf), - &srcRead, &dstWrote, NULL) == TCL_OK) { - - if (((isMultiByteFont != 0) && (buf[0] > 31)) - || (widths[buf[0]] != -1)) { - if ((buf[0] == 0x11) && (widths[0x12] == -1)) { - continue; - } - - /* - * Mac's char existence metrics are only for one-byte - * characters. If we have a double-byte char, just - * assume that the font supports that char if the font's - * encoding supports that char. - */ - - bitOffset = i & (FONTMAP_BITSPERPAGE - 1); - subFontPtr->fontMap[row][bitOffset >> 3] |= 1 - << (bitOffset & 7); - } - } - } - } -#endif + + /* + * Found an outline font which has very complex font record. + * Let's just assume *ALL* the characters are allowed. + */ + + end = (row + 1) << FONTMAP_SHIFT; + for (i = row << FONTMAP_SHIFT; i < end; i++) { + if (Tcl_UtfToExternal(NULL, encoding, src, Tcl_UniCharToUtf(i, + src), + TCL_ENCODING_STOPONERROR, NULL, (char *) buf, + sizeof(buf), + &srcRead, &dstWrote, NULL) == TCL_OK) { + bitOffset = i & (FONTMAP_BITSPERPAGE - 1); + subFontPtr->fontMap[row][bitOffset >> 3] |= 1 + << (bitOffset & 7); + } + } } /* @@ -1828,59 +1779,59 @@ FontMapLoadPage( * * CanUseFallbackWithAliases -- * - * Helper function for FindSubFontForChar. Determine if the - * specified face name (or an alias of the specified face name) - * can be used to construct a screen font that can display the - * given character. + * Helper function for FindSubFontForChar. Determine if the + * specified face name (or an alias of the specified face name) + * can be used to construct a screen font that can display the + * given character. * * Results: - * See CanUseFallback(). + * See CanUseFallback(). * * Side effects: - * If the name and/or one of its aliases was rejected, the - * rejected string is recorded in nameTriedPtr so that it won't - * be tried again. The table of SubFonts might be extended, and if - * a non-NULL reference to a subfont pointer is available, it is - * updated if it previously pointed into the old subfont table. + * If the name and/or one of its aliases was rejected, the + * rejected string is recorded in nameTriedPtr so that it won't + * be tried again. The table of SubFonts might be extended, and if + * a non-NULL reference to a subfont pointer is available, it is + * updated if it previously pointed into the old subfont table. * *--------------------------------------------------------------------------- */ static SubFont * CanUseFallbackWithAliases( - MacFont *fontPtr, /* The font object that will own the new - * screen font. */ - CONST char *faceName, /* Desired face name for new screen font. */ - int ch, /* The Unicode character that the new - * screen font must be able to display. */ - Tcl_DString *nameTriedPtr, /* Records face names that have already - * been tried. It is possible for the same - * face name to be queried multiple times when - * trying to find a suitable screen font. */ - SubFont **fixSubFontPtrPtr) /* Subfont reference to fix up if we + MacFont *fontPtr, /* The font object that will own the new + * screen font. */ + const char *faceName, /* Desired face name for new screen font. */ + int ch, /* The Unicode character that the new + * screen font must be able to display. */ + Tcl_DString *nameTriedPtr, /* Records face names that have already + * been tried. It is possible for the same + * face name to be queried multiple times when + * trying to find a suitable screen font. */ + SubFont **fixSubFontPtrPtr) /* Subfont reference to fix up if we * reallocate our subfont table. */ { SubFont *subFontPtr; char **aliases; int i; - + if (SeenName(faceName, nameTriedPtr) == 0) { subFontPtr = CanUseFallback(fontPtr, faceName, ch, fixSubFontPtrPtr); - if (subFontPtr != NULL) { - return subFontPtr; - } + if (subFontPtr != NULL) { + return subFontPtr; + } } aliases = TkFontGetAliasList(faceName); if (aliases != NULL) { - for (i = 0; aliases[i] != NULL; i++) { - if (SeenName(aliases[i], nameTriedPtr) == 0) { + for (i = 0; aliases[i] != NULL; i++) { + if (SeenName(aliases[i], nameTriedPtr) == 0) { subFontPtr = CanUseFallback(fontPtr, aliases[i], ch, fixSubFontPtrPtr); - if (subFontPtr != NULL) { - return subFontPtr; - } - } - } + if (subFontPtr != NULL) { + return subFontPtr; + } + } + } } return NULL; } @@ -1890,35 +1841,35 @@ CanUseFallbackWithAliases( * * SeenName -- * - * Used to determine we have already tried and rejected the given - * face name when looking for a screen font that can support some - * Unicode character. + * Used to determine we have already tried and rejected the given + * face name when looking for a screen font that can support some + * Unicode character. * * Results: - * The return value is 0 if this face name has not already been seen, - * non-zero otherwise. + * The return value is 0 if this face name has not already been seen, + * non-zero otherwise. * * Side effects: - * None. + * None. * *--------------------------------------------------------------------------- */ static int SeenName( - CONST char *name, /* The name to check. */ - Tcl_DString *dsPtr) /* Contains names that have already been - * seen. */ + const char *name, /* The name to check. */ + Tcl_DString *dsPtr) /* Contains names that have already been + * seen. */ { - CONST char *seen, *end; + const char *seen, *end; seen = Tcl_DStringValue(dsPtr); end = seen + Tcl_DStringLength(dsPtr); while (seen < end) { - if (strcasecmp(seen, name) == 0) { - return 1; - } - seen += strlen(seen) + 1; + if (strcasecmp(seen, name) == 0) { + return 1; + } + seen += strlen(seen) + 1; } Tcl_DStringAppend(dsPtr, (char *) name, (int) (strlen(name) + 1)); return 0; @@ -1929,37 +1880,37 @@ SeenName( * * CanUseFallback -- * - * If the specified physical screen font has not already been loaded - * into the font object, determine if the specified physical screen - * font can display the given character. + * If the specified physical screen font has not already been loaded + * into the font object, determine if the specified physical screen + * font can display the given character. * * Results: - * The return value is a pointer to a newly allocated SubFont, owned - * by the font object. This SubFont can be used to display the given - * character. The SubFont represents the screen font with the base set - * of font attributes from the font object, but using the specified - * font name. NULL is returned if the font object already holds - * a reference to the specified physical font or if the specified - * physical font cannot display the given character. - * - * Side effects: - * The font object's subFontArray is updated to contain a reference - * to the newly allocated SubFont. The table of SubFonts might be - * extended, and if a non-NULL reference to a subfont pointer is - * available, it is updated if it previously pointed into the old - * subfont table. + * The return value is a pointer to a newly allocated SubFont, owned + * by the font object. This SubFont can be used to display the given + * character. The SubFont represents the screen font with the base set + * of font attributes from the font object, but using the specified + * font name. NULL is returned if the font object already holds + * a reference to the specified physical font or if the specified + * physical font cannot display the given character. + * + * Side effects: + * The font object's subFontArray is updated to contain a reference + * to the newly allocated SubFont. The table of SubFonts might be + * extended, and if a non-NULL reference to a subfont pointer is + * available, it is updated if it previously pointed into the old + * subfont table. * *------------------------------------------------------------------------- */ static SubFont * CanUseFallback( - MacFont *fontPtr, /* The font object that will own the new - * screen font. */ - CONST char *faceName, /* Desired face name for new screen font. */ - int ch, /* The Unicode character that the new - * screen font must be able to display. */ - SubFont **fixSubFontPtrPtr) /* Subfont reference to fix up if we + MacFont *fontPtr, /* The font object that will own the new + * screen font. */ + const char *faceName, /* Desired face name for new screen font. */ + int ch, /* The Unicode character that the new + * screen font must be able to display. */ + SubFont **fixSubFontPtrPtr) /* Subfont reference to fix up if we * reallocate our subfont table. */ { int i; @@ -1967,48 +1918,48 @@ CanUseFallback( short faceNum; if (GetFamilyNum(faceName, &faceNum) == 0) { - return NULL; + return NULL; } - - /* + + /* * Skip all fonts we've already used. */ - + for (i = 0; i < fontPtr->numSubFonts; i++) { - if (faceNum == fontPtr->subFontArray[i].familyPtr->faceNum) { - return NULL; - } + if (faceNum == fontPtr->subFontArray[i].familyPtr->faceNum) { + return NULL; + } } - + /* * Load this font and see if it has the desired character. */ - + InitSubFont(fontPtr, faceNum, &subFont); - if (((ch < 256) && (subFont.familyPtr->isSymbolFont)) - || (FontMapLookup(&subFont, ch) == 0)) { - ReleaseSubFont(&subFont); - return NULL; + if (((ch < 256) && (subFont.familyPtr->isSymbolFont)) + || (FontMapLookup(&subFont, ch) == 0)) { + ReleaseSubFont(&subFont); + return NULL; } - + if (fontPtr->numSubFonts >= SUBFONT_SPACE) { - SubFont *newPtr; - newPtr = (SubFont *) ckalloc(sizeof(SubFont) - * (fontPtr->numSubFonts + 1)); - memcpy((char *) newPtr, fontPtr->subFontArray, - fontPtr->numSubFonts * sizeof(SubFont)); + SubFont *newPtr = (SubFont *) ckalloc(sizeof(SubFont) + * (fontPtr->numSubFonts + 1)); + memcpy((char *) newPtr, fontPtr->subFontArray, + fontPtr->numSubFonts * sizeof(SubFont)); if (fixSubFontPtrPtr != NULL) { - /* - * Fix up the variable pointed to by fixSubFontPtrPtr so it - * still points into the live array. [Bug 618872] - */ - *fixSubFontPtrPtr = - newPtr + (*fixSubFontPtrPtr - fontPtr->subFontArray); + /* + * Fix up the variable pointed to by fixSubFontPtrPtr so it + * still points into the live array. [Bug 618872] + */ + + *fixSubFontPtrPtr = + newPtr + (*fixSubFontPtrPtr - fontPtr->subFontArray); } - if (fontPtr->subFontArray != fontPtr->staticSubFonts) { - ckfree((char *) fontPtr->subFontArray); - } - fontPtr->subFontArray = newPtr; + if (fontPtr->subFontArray != fontPtr->staticSubFonts) { + ckfree((char *) fontPtr->subFontArray); + } + fontPtr->subFontArray = newPtr; } fontPtr->subFontArray[fontPtr->numSubFonts] = subFont; fontPtr->numSubFonts++; @@ -2020,60 +1971,60 @@ CanUseFallback( * * GetFamilyNum -- * - * Determines 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. + * Determines 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. * * Results: - * The return value is 0 if the specified font family does not exist, - * non-zero otherwise. *faceNumPtr is filled with the unique face - * number that identifies the screen font, or 0 if the font family - * did not exist. + * The return value is 0 if the specified font family does not exist, + * non-zero otherwise. *faceNumPtr is filled with the unique face + * number that identifies the screen font, or 0 if the font family + * did not exist. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int GetFamilyNum( - CONST char *faceName, /* UTF-8 name of font family to query. */ - short *faceNumPtr) /* Filled with font number for above family. */ + const char *faceName, /* UTF-8 name of font family to query. */ + short *faceNumPtr) /* Filled with font number for above family. */ { FontNameMap *mapPtr; - + if (faceName != NULL) { - for (mapPtr = gFontNameMap; mapPtr->utfName != NULL; mapPtr++) { - if (strcasecmp(faceName, mapPtr->utfName) == 0) { - *faceNumPtr = mapPtr->faceNum; - return 1; - } - } + for (mapPtr = gFontNameMap; mapPtr->utfName != NULL; mapPtr++) { + if (strcasecmp(faceName, mapPtr->utfName) == 0) { + *faceNumPtr = mapPtr->faceNum; + return 1; + } + } } - *faceNumPtr = 0; + *faceNumPtr = 0; return 0; } static int GetFamilyOrAliasNum( - CONST char *faceName, /* UTF-8 name of font family to query. */ - short *faceNumPtr) /* Filled with font number for above family. */ + const char *faceName, /* UTF-8 name of font family to query. */ + short *faceNumPtr) /* Filled with font number for above family. */ { char **aliases; int i; - + if (GetFamilyNum(faceName, faceNumPtr) != 0) { - return 1; + return 1; } aliases = TkFontGetAliasList(faceName); if (aliases != NULL) { - for (i = 0; aliases[i] != NULL; i++) { - if (GetFamilyNum(aliases[i], faceNumPtr) != 0) { - return 1; - } - } + for (i = 0; aliases[i] != NULL; i++) { + if (GetFamilyNum(aliases[i], faceNumPtr) != 0) { + return 1; + } + } } return 0; } @@ -2083,33 +2034,33 @@ GetFamilyOrAliasNum( * * GetUtfFaceName -- * - * Given the native name for a Macintosh font (in which the name of - * the font is in the encoding of the font itself), return the UTF-8 - * name that corresponds to that font. The specified font name must - * refer to a font that actually exists on the machine. + * Given the native name for a Macintosh font (in which the name of + * the font is in the encoding of the font itself), return the UTF-8 + * name that corresponds to that font. The specified font name must + * refer to a font that actually exists on the machine. * - * This function is used to obtain the UTF-8 name when querying the - * properties of a Macintosh font object. + * This function is used to obtain the UTF-8 name when querying the + * properties of a Macintosh font object. * * Results: - * The return value is a pointer to the UTF-8 of the specified font. + * The return value is a pointer to the UTF-8 of the specified font. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------ */ - + static Tk_Uid GetUtfFaceName( - StringPtr nativeName) /* Pascal name for font in native encoding. */ + StringPtr nativeName) /* Pascal name for font in native encoding. */ { FontNameMap *mapPtr; - + for (mapPtr = gFontNameMap; mapPtr->utfName != NULL; mapPtr++) { - if (pstrcmp(nativeName, mapPtr->nativeName) == 0) { - return mapPtr->utfName; - } + if (pstrcmp(nativeName, mapPtr->nativeName) == 0) { + return mapPtr->utfName; + } } Tcl_Panic("GetUtfFaceName: unexpected nativeName"); return NULL; @@ -2120,64 +2071,64 @@ GetUtfFaceName( * * GetFontEncoding -- * - * Return a string that can be passed to Tcl_GetTextEncoding() and - * used to convert bytes from UTF-8 into the encoding of the - * specified font. + * Return a string that can be passed to Tcl_GetTextEncoding() and + * used to convert bytes from UTF-8 into the encoding of the + * specified font. * - * The desired encoding to use to convert the name of a symbolic - * font into UTF-8 is macRoman, while the desired encoding to use - * to convert bytes in a symbolic font to UTF-8 is the corresponding - * symbolic encoding. Due to this dual interpretatation of symbolic - * fonts, the caller can specify what type of encoding to return - * should the specified font be symbolic. + * The desired encoding to use to convert the name of a symbolic + * font into UTF-8 is macRoman, while the desired encoding to use + * to convert bytes in a symbolic font to UTF-8 is the corresponding + * symbolic encoding. Due to this dual interpretatation of symbolic + * fonts, the caller can specify what type of encoding to return + * should the specified font be symbolic. * * Results: - * The return value is a string that specifies the font's encoding. - * If the font's encoding could not be identified, NULL is returned. + * The return value is a string that specifies the font's encoding. + * If the font's encoding could not be identified, NULL is returned. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------ */ - + static Tcl_Encoding GetFontEncoding( - int faceNum, /* Macintosh font number. */ - int allowSymbol, /* If non-zero, then the encoding string - * for symbol fonts will be the corresponding - * symbol encoding. Otherwise, the encoding - * string for symbol fonts will be - * "macRoman". */ - int *isSymbolPtr) /* Filled with non-zero if this font is a - * symbol font, 0 otherwise. */ + int faceNum, /* Macintosh font number. */ + int allowSymbol, /* If non-zero, then the encoding string + * for symbol fonts will be the corresponding + * symbol encoding. Otherwise, the encoding + * string for symbol fonts will be + * "macRoman". */ + int *isSymbolPtr) /* Filled with non-zero if this font is a + * symbol font, 0 otherwise. */ { Str255 faceName; int script, lang; - char *name; - + char *name; + if (allowSymbol != 0) { - GetFontName(faceNum, faceName); - if (pstrcasecmp(faceName, "\psymbol") == 0) { - *isSymbolPtr = 1; - return Tcl_GetEncoding(NULL, "symbol"); - } - if (pstrcasecmp(faceName, "\pzapf dingbats") == 0) { - *isSymbolPtr = 1; - return Tcl_GetEncoding(NULL, "macDingbats"); - } + GetFontName(faceNum, faceName); + if (pstrcasecmp(faceName, "\psymbol") == 0) { + *isSymbolPtr = 1; + return Tcl_GetEncoding(NULL, "symbol"); + } + if (pstrcasecmp(faceName, "\pzapf dingbats") == 0) { + *isSymbolPtr = 1; + return Tcl_GetEncoding(NULL, "macDingbats"); + } } *isSymbolPtr = 0; script = FontToScript(faceNum); lang = GetScriptVariable(script, smScriptLang); name = NULL; if (script == smRoman) { - name = TkFindStateString(romanMap, lang); + name = TkFindStateString(romanMap, lang); } else if (script == smCyrillic) { - name = TkFindStateString(cyrillicMap, lang); + name = TkFindStateString(cyrillicMap, lang); } if (name == NULL) { - name = TkFindStateString(scriptMap, script); + name = TkFindStateString(scriptMap, script); } return Tcl_GetEncoding(NULL, name); } @@ -2200,17 +2151,18 @@ GetFontEncoding( */ void -TkMacOSXInitControlFontStyle(Tk_Font tkfont, ControlFontStylePtr fsPtr) +TkMacOSXInitControlFontStyle( + Tk_Font tkfont, + ControlFontStylePtr fsPtr) { - MacFont *fontPtr; - FontFamily *lastFamilyPtr; - fontPtr = (MacFont *) tkfont; - lastFamilyPtr = fontPtr->subFontArray[0].familyPtr; + MacFont *fontPtr = (MacFont *) tkfont; + FontFamily *lastFamilyPtr = fontPtr->subFontArray[0].familyPtr; + fsPtr->flags = - kControlUseFontMask| - kControlUseSizeMask| - kControlUseFaceMask| - kControlUseJustMask; + kControlUseFontMask| + kControlUseSizeMask| + kControlUseFaceMask| + kControlUseJustMask; fsPtr->font = lastFamilyPtr->faceNum; fsPtr->size = fontPtr->size; fsPtr->style = fontPtr->style; @@ -2222,77 +2174,72 @@ TkMacOSXInitControlFontStyle(Tk_Font tkfont, ControlFontStylePtr fsPtr) * * TkMacOSXUseAntialiasedText -- * - * Enables or disables application-wide use of quickdraw - * antialiased text (where available). - * Sets up a linked tcl global boolean variable with write trace - * to allow disabling of antialiased text from tcl. + * Enables or disables application-wide use of quickdraw + * antialiased text (where available). + * Sets up a linked tcl global boolean variable with write trace + * to allow disabling of antialiased text from tcl. * * Results: - * TCL_OK if facility was sucessfully enabled/disabled. - * TCL_ERROR if an error occurred or if facility is not available. + * TCL_OK if facility was sucessfully enabled/disabled. + * TCL_ERROR if an error occurred or if facility is not available. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -/* define constants from 10.2 Quickdraw.h to enable compilation in 10.1 */ -#define kQDUseTrueTypeScalerGlyphs (1 << 0) -#define kQDUseCGTextRendering (1 << 1) -#define kQDUseCGTextMetrics (1 << 2) - static int TkMacOSXAntialiasedTextEnabled = FALSE; static char * -TkMacOSXAntialiasedTextVariableProc(clientData, interp, name1, name2, flags) - ClientData clientData; - Tcl_Interp *interp; - CONST char *name1; - CONST char *name2; - int flags; +TkMacOSXAntialiasedTextVariableProc( + ClientData clientData, + Tcl_Interp *interp, + const char *name1, + const char *name2, + int flags) { TkMacOSXUseAntialiasedText(interp, TkMacOSXAntialiasedTextEnabled); return (char *) NULL; } int -TkMacOSXUseAntialiasedText(interp, enable) - Tcl_Interp *interp; - int enable; +TkMacOSXUseAntialiasedText( + Tcl_Interp *interp, + int enable) { static Boolean initialized = FALSE; static UInt32 (*swaptextflags)(UInt32) = NULL; - + if(!initialized) { - swaptextflags = TkMacOSXGetNamedSymbol("QD", "_QDSwapTextFlags"); - if (!swaptextflags) { - swaptextflags = TkMacOSXGetNamedSymbol("QD", "_SwapQDTextFlags"); - } - initialized = TRUE; - - TkMacOSXAntialiasedTextEnabled = (swaptextflags ? enable : FALSE); - if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) { - Tcl_ResetResult(interp); - } - if (Tcl_TraceVar(interp, "::tk::mac::antialiasedtext", - TCL_GLOBAL_ONLY | TCL_TRACE_WRITES, - TkMacOSXAntialiasedTextVariableProc, NULL) != TCL_OK) { - Tcl_ResetResult(interp); - } - if (Tcl_LinkVar(interp, "::tk::mac::antialiasedtext", - (char *) &TkMacOSXAntialiasedTextEnabled, - TCL_LINK_BOOLEAN) != TCL_OK) { - Tcl_ResetResult(interp); - } + swaptextflags = TkMacOSXGetNamedSymbol("QD", "_QDSwapTextFlags"); + if (!swaptextflags) { + swaptextflags = TkMacOSXGetNamedSymbol("QD", "_SwapQDTextFlags"); + } + initialized = TRUE; + + TkMacOSXAntialiasedTextEnabled = (swaptextflags ? enable : FALSE); + if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) { + Tcl_ResetResult(interp); + } + if (Tcl_TraceVar(interp, "::tk::mac::antialiasedtext", + TCL_GLOBAL_ONLY | TCL_TRACE_WRITES, + TkMacOSXAntialiasedTextVariableProc, NULL) != TCL_OK) { + Tcl_ResetResult(interp); + } + if (Tcl_LinkVar(interp, "::tk::mac::antialiasedtext", + (char *) &TkMacOSXAntialiasedTextEnabled, + TCL_LINK_BOOLEAN) != TCL_OK) { + Tcl_ResetResult(interp); + } } if (swaptextflags) { - swaptextflags(enable ? kQDUseCGTextRendering | kQDUseCGTextMetrics - : kQDUseTrueTypeScalerGlyphs); - TkMacOSXAntialiasedTextEnabled = enable; - return TCL_OK; + swaptextflags(enable ? kQDUseCGTextRendering | kQDUseCGTextMetrics + : kQDUseTrueTypeScalerGlyphs); + TkMacOSXAntialiasedTextEnabled = enable; + return TCL_OK; } else { - TkMacOSXAntialiasedTextEnabled = FALSE; - return TCL_ERROR; + TkMacOSXAntialiasedTextEnabled = FALSE; + return TCL_ERROR; } } diff --git a/macosx/tkMacOSXFont.h b/macosx/tkMacOSXFont.h index 9709cd1..fc8abc6 100644 --- a/macosx/tkMacOSXFont.h +++ b/macosx/tkMacOSXFont.h @@ -1,21 +1,22 @@ /* * tkMacOSXFont.h -- * - * Contains the Macintosh implementation of the platform-independant - * font package interface. + * Contains the Macintosh implementation of the platform-independant + * font package interface. * * 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.3.2.3 2006/04/28 06:02:59 das Exp $ + * RCS: @(#) $Id: tkMacOSXFont.h,v 1.3.2.4 2007/04/29 02:26:49 das Exp $ */ -#ifndef TKMACOSXFONT_H -#define TKMACOSXFONT_H 1 +#ifndef TKMACOSXFONT_H +#define TKMACOSXFONT_H 1 #include "tkFont.h" @@ -27,7 +28,7 @@ * Function prototypes */ -MODULE_SCOPE void TkMacOSXInitControlFontStyle(Tk_Font tkfont, - ControlFontStylePtr fsPtr); +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 155febb..0fc7a6e 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.5.2.9 2006/05/12 18:18:52 das Exp $ + * RCS: @(#) $Id: tkMacOSXHLEvents.c,v 1.5.2.10 2007/04/29 02:26:49 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 85d4aa5..524306e 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.3.2.20 2006/11/24 19:04:07 hobbs Exp $ + * RCS: @(#) $Id: tkMacOSXInit.c,v 1.3.2.21 2007/04/29 02:26:49 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, TRUE); - 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) { @@ -225,6 +213,100 @@ 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: */ + 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, TRUE); + 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); + } + + /* * If we don't have a TTY and stdin is a special character file of * length 0, (e.g. /dev/null, which is what Finder sets when double * clicking Wish) then use the Tk based console interpreter. @@ -232,18 +314,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 (TclGetStartupScriptFileName() == 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); @@ -254,74 +340,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,25 +359,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)) { @@ -378,22 +396,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) { @@ -410,18 +428,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: - * TclSetStartupScriptFileName() called when AppMain.tcl found. + * TclSetStartupScriptFileName() called when AppMain.tcl found. * *---------------------------------------------------------------------- */ @@ -435,9 +453,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) { @@ -450,7 +468,7 @@ TkMacOSXDefaultStartupScript(void) scriptFldrURL = CFURLCreateCopyDeletingLastPathComponent( NULL, appMainURL); if (scriptFldrURL != NULL) { - CFURLGetFileSystemRepresentation(scriptFldrURL, + CFURLGetFileSystemRepresentation(scriptFldrURL, true, (unsigned char*) scriptPath, PATH_MAX); CFRelease(scriptFldrURL); } @@ -466,23 +484,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) { diff --git a/macosx/tkMacOSXInt.h b/macosx/tkMacOSXInt.h index 96df487..538157a 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.3.2.15 2006/10/31 22:33:38 das Exp $ + * RCS: @(#) $Id: tkMacOSXInt.h,v 1.3.2.16 2007/04/29 02:26:49 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 @@ -117,10 +195,49 @@ MODULE_SCOPE TkMacOSXEmbedHandler *tkMacOSXEmbedHandler; #define TK_BOTH_CHANGED 3 /* + * 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 */ @@ -129,13 +246,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 @@ -147,30 +257,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 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 b8d3828..945256b4 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.6.2.12 2006/09/11 14:41:17 das 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.6.2.13 2007/04/29 02:26:49 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 6a15e44..6206116 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.5.2.6 2006/07/21 06:26:54 das Exp $ + * RCS: @(#) $Id: tkMacOSXKeyboard.c,v 1.5.2.7 2007/04/29 02:26:49 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 47f1927..9c79ffc 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.6.2.23 2006/09/11 14:41:17 das Exp $ + * RCS: @(#) $Id: tkMacOSXMenu.c,v 1.6.2.24 2007/04/29 02:26:49 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 d5ae817..acf507a 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.2.2.9 2006/07/20 06:27:34 das Exp $ + * RCS: @(#) $Id: tkMacOSXMenubutton.c,v 1.2.2.10 2007/04/29 02:26:49 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 f5c2e1d..d12bdb3 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.2.2.12 2006/08/18 07:47:25 das Exp $ + * RCS: @(#) $Id: tkMacOSXMenus.c,v 1.2.2.13 2007/04/29 02:26:49 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 2f0a7df..bc8dff8 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.6.2.17 2006/09/10 17:07:36 das 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.6.2.18 2007/04/29 02:26:49 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 0ed72ee..ae2504c 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.5.2.10 2007/01/19 00:41:33 das Exp $ + * RCS: @(#) $Id: tkMacOSXNotify.c,v 1.5.2.11 2007/04/29 02:26:49 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 e922acd..4e48896 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.3.2.6 2006/09/10 17:07:36 das Exp $ + * RCS: @(#) $Id: tkMacOSXPort.h,v 1.3.2.7 2007/04/29 02:26:50 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 803d144..c64a45d 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.2.2.2 2006/03/28 02:44:14 das Exp $ + * RCS: @(#) $Id: tkMacOSXRegion.c,v 1.2.2.3 2007/04/29 02:26:50 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, @@ -241,3 +233,34 @@ TkSubtractRegion( DiffRgn(srcRgnA, srcRgnB, destRgn); } + +#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 a94b499..283255f 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.2.2.5 2006/04/28 06:03:00 das Exp $ + * RCS: @(#) $Id: tkMacOSXScale.c,v 1.2.2.6 2007/04/29 02:26:50 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 011b565..0fa6561 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.5.2.10 2006/08/24 05:22:33 das Exp $ + * RCS: @(#) $Id: tkMacOSXScrlbr.c,v 1.5.2.11 2007/04/29 02:26:50 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 09a5829..22afde4 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.2.2.2 2006/04/28 06:03:00 das Exp $ + * RCS: @(#) $Id: tkMacOSXSend.c,v 1.2.2.3 2007/04/29 02:26:50 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 d536a1b..18dc2ec 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.2.2.13 2006/10/31 22:33:38 das Exp $ + * RCS: @(#) $Id: tkMacOSXSubwindows.c,v 1.2.2.14 2007/04/29 02:26:50 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 271e895..edaf05d 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.2.2.4 2006/04/28 06:03:00 das Exp $ + * RCS: @(#) $Id: tkMacOSXTest.c,v 1.2.2.5 2007/04/29 02:26:50 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 b4a7845..86fc381 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.3.2.17 2006/11/02 15:18:26 das 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.3.2.18 2007/04/29 02:26:50 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 d8815bc..799af66 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.7.2.35 2006/10/31 22:33:38 das Exp $ + * RCS: @(#) $Id: tkMacOSXWm.c,v 1.7.2.36 2007/04/29 02:26:50 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 Tk_GeomMgr wmMgrType = { "wm", /* name */ @@ -64,6 +74,14 @@ static Tk_GeomMgr wmMgrType = { }; /* + * The following keeps state for Aqua dock icon bounce notification. + */ + +/* +static int tkMacOSXWmAttrNotifyVal = 0; +*/ + +/* * Hash table for Mac Window -> TkWindow mapping. */ @@ -74,131 +92,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 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: @@ -207,7 +187,7 @@ static void ApplyWindowAttributeChanges _ANSI_ARGS_(( * Side effects: * A WmInfo structure gets allocated and initialized. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ void @@ -236,14 +216,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; @@ -262,6 +236,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; @@ -271,7 +247,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; @@ -294,14 +271,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: @@ -309,11 +286,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 @@ -322,7 +299,6 @@ TkWmMapWindow( * be mapped. */ { WmInfo *wmPtr = winPtr->wmInfoPtr; - Rect widths; if (wmPtr->flags & WM_NEVER_MAPPED) { wmPtr->flags &= ~WM_NEVER_MAPPED; @@ -365,7 +341,7 @@ TkWmMapWindow( if (wmPtr->hints.initial_state == WithdrawnState) { return; } - + /* * TODO: we need to display a window if it's iconic on creation. */ @@ -373,7 +349,7 @@ TkWmMapWindow( if (wmPtr->hints.initial_state == IconicState) { return; } - + /* * Update geometry information. */ @@ -389,22 +365,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 -- * @@ -417,7 +381,7 @@ TkWmMapWindow( * Side effects: * Unmaps the window. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ void @@ -429,12 +393,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: @@ -443,12 +407,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; @@ -498,14 +462,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: @@ -514,7 +478,7 @@ TkWmDeadWindow(winPtr) * Side effects: * A window property may get updated. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ void @@ -523,6 +487,7 @@ TkWmSetClass( { return; } + /* *---------------------------------------------------------------------- * @@ -543,143 +508,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; } - + /* *---------------------------------------------------------------------- * @@ -698,323 +662,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", - "-titlepath", - (char *)NULL - }; - enum optionIdx { - WmAttrAlphaIdx, - WmAttrModifiedIdx, - WmAttrTitlePathIdx, - }; - - /* Must have objc >= 3 at this point. */ - if (objc < 3) { - Tcl_WrongNumArgs(interp, 1, objv, - "attributes window ?-modified ?bool?? ?-titlepath ?path?? ?-alpha ?double??"); - 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("-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; - } - 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; + } + 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); } - /* - * 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 (group && group != GetWindowGroup(macWindow)) { + ChkErr(SetWindowGroup, macWindow, group); } - objPtr = Tcl_NewDoubleObj(dval); - SetWindowAlpha(macWindow, dval); - 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. + * WmGetAttribute -- * - * Side effects: - * None. + * Helper routine for WmAttributesCmd. Returns the current value + * of the specified attribute. * *---------------------------------------------------------------------- */ -static Tcl_Obj * -WmAttrGetModifiedStatus(WindowRef macWindow) +static Tcl_Obj *WmGetAttribute( + TkWindow *winPtr, /* Toplevel to work with */ + WindowRef macWindow, + WmAttribute attribute) /* Code of attribute to get */ { - return Tcl_NewBooleanObj((IsWindowModified(macWindow) == true)); -} - + 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; /* - *---------------------------------------------------------------------- - * WmAttrGetTitlePath -- - * - * Helper procedure to retrieve the -titlepath option for the wm - * attributes command. - * - * Results: - * Returns value in unrefcounted Tcl_Obj. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ -static Tcl_Obj * -WmAttrGetTitlePath(WindowRef macWindow) -{ - FSRef ref; - Boolean wasChanged; - UInt8 path[2048]; - OSStatus err = fnfErr; + 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 + ) { + 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) { - AliasHandle alias; - err = GetWindowProxyAlias(macWindow, &alias); - if (err == noErr) { - err = FSResolveAlias(NULL, alias, &ref, &wasChanged); + 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. + * WmAttributesCmd -- + * + * 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 * -WmAttrGetAlpha(WindowRef macWindow) + +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. */ { - float fval; - if (GetWindowAlpha(macWindow, &fval) != noErr) { - fval = 1.0; + int attribute = 0; + WindowRef macWindow; + + if (winPtr->window == None) { + Tk_MakeWindowExist((Tk_Window) winPtr); + } + if (!TkMacOSXHostToplevelExists(winPtr)) { + TkMacOSXMakeRealWindowExist(winPtr); } - return Tcl_NewDoubleObj(fval); + 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; } /* @@ -1035,44 +1083,44 @@ WmAttrGetAlpha(WindowRef macWindow) */ 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; } - + /* *---------------------------------------------------------------------- * @@ -1092,12 +1140,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; @@ -1106,64 +1154,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; } - + /* *---------------------------------------------------------------------- * @@ -1182,49 +1230,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; } - + /* *---------------------------------------------------------------------- * @@ -1243,34 +1291,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; } - + /* *---------------------------------------------------------------------- * @@ -1289,42 +1336,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; } - + /* *---------------------------------------------------------------------- * @@ -1343,30 +1390,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; } - + /* *---------------------------------------------------------------------- * @@ -1385,12 +1432,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; @@ -1398,38 +1445,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); } - + /* *---------------------------------------------------------------------- * @@ -1448,78 +1495,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; } - + /* *---------------------------------------------------------------------- * @@ -1538,12 +1585,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; @@ -1551,38 +1598,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; } - + /* *---------------------------------------------------------------------- * @@ -1601,64 +1648,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; @@ -1666,18 +1688,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; } - + /* *---------------------------------------------------------------------- * @@ -1696,43 +1716,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; } - + /* *---------------------------------------------------------------------- * @@ -1751,46 +1770,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; } - + /* *---------------------------------------------------------------------- * @@ -1809,40 +1828,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; } - + /* *---------------------------------------------------------------------- * @@ -1863,12 +1882,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; @@ -1894,7 +1913,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); @@ -1905,7 +1924,7 @@ WmIconphotoCmd(tkwin, winPtr, interp, objc, objv) */ return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -1925,44 +1944,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; } - + /* *---------------------------------------------------------------------- * @@ -1981,71 +2000,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; } - + /* *---------------------------------------------------------------------- * @@ -2064,30 +2083,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; @@ -2095,7 +2115,7 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ WmUpdateGeom(wmPtr, winPtr); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2114,30 +2134,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; @@ -2145,7 +2166,7 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */ WmUpdateGeom(wmPtr, winPtr); return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -2165,59 +2186,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; } - + /* *---------------------------------------------------------------------- * @@ -2237,52 +2233,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; } - + /* *---------------------------------------------------------------------- * @@ -2301,12 +2297,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; @@ -2315,33 +2311,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; } /* @@ -2351,29 +2348,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; } - + /* *---------------------------------------------------------------------- * @@ -2392,63 +2389,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; } - + /* *---------------------------------------------------------------------- * @@ -2467,53 +2465,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; } - + /* *---------------------------------------------------------------------- * @@ -2532,105 +2530,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; } - + /* *---------------------------------------------------------------------- * @@ -2649,98 +2646,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; } - + /* *---------------------------------------------------------------------- * @@ -2759,36 +2751,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; } - + /* *---------------------------------------------------------------------- * @@ -2807,94 +2797,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; } - + /* *---------------------------------------------------------------------- * @@ -2913,24 +2882,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; @@ -2946,10 +2914,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; } -} +} + /* *---------------------------------------------------------------------- * @@ -2966,7 +2935,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. * *---------------------------------------------------------------------- @@ -2974,7 +2943,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 @@ -2988,6 +2957,17 @@ Tk_SetGrid( WmInfo *wmPtr; /* + * Ensure widthInc and heightInc are greater than 0 + */ + + if (widthInc <= 0) { + widthInc = 1; + } + if (heightInc <= 0) { + heightInc = 1; + } + + /* * Find the top-level window for tkwin, plus the window manager * information. */ @@ -3016,7 +2996,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. @@ -3027,7 +3007,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. */ @@ -3058,7 +3038,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. * *---------------------------------------------------------------------- @@ -3123,31 +3103,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"); @@ -3175,8 +3153,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; @@ -3213,24 +3191,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. */ @@ -3306,7 +3287,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. @@ -3328,7 +3309,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. */ @@ -3348,41 +3329,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); @@ -3390,28 +3369,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 -- * @@ -3425,7 +3405,7 @@ UpdateGeometryInfo( * Side effects: * Properties get changed for winPtr. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ static void @@ -3440,7 +3420,7 @@ UpdateSizeHints( } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * ParseGeometry -- * @@ -3455,13 +3435,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. */ @@ -3480,7 +3460,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. */ @@ -3537,7 +3517,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. */ @@ -3549,7 +3529,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. */ @@ -3559,8 +3539,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; @@ -3571,7 +3556,7 @@ ParseGeometry( } return TCL_OK; - error: +error: Tcl_AppendResult(interp, "bad geometry specifier \"", string, "\"", NULL); return TCL_ERROR; } @@ -3587,7 +3572,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. * @@ -3618,49 +3603,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; } @@ -3695,7 +3680,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. */ @@ -3715,7 +3700,7 @@ Tk_CoordsToWindow( /* * Step 1: find the top-level window that contains the desired point. */ - + where.h = rootX; where.v = rootY; FindWindow(where, &whichWin); @@ -3726,13 +3711,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. */ @@ -3742,48 +3727,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) { @@ -3800,17 +3785,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. @@ -3823,8 +3808,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 @@ -3840,22 +3825,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; + } } /* @@ -3863,19 +3846,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) { @@ -3911,7 +3894,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; @@ -3944,9 +3927,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) { @@ -3970,9 +3953,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: @@ -4023,7 +4006,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 * @@ -4072,7 +4055,8 @@ Tk_MoveToplevelWindow( } UpdateGeometryInfo((ClientData) winPtr); } -} +} + /* *---------------------------------------------------------------------- * @@ -4107,7 +4091,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); @@ -4134,7 +4118,8 @@ TkWmRestackToplevel( if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) { TkWmMapWindow(otherPtr); } - otherMacWindow = GetWindowFromPort(TkMacOSXGetDrawablePort(otherPtr->window)); + otherMacWindow = GetWindowFromPort(TkMacOSXGetDrawablePort( + otherPtr->window)); } else { otherMacWindow = NULL; } @@ -4143,12 +4128,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. */ @@ -4159,11 +4144,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) { @@ -4172,10 +4158,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); } } @@ -4190,7 +4178,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. * @@ -4222,7 +4210,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; @@ -4272,7 +4260,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. */ } @@ -4283,7 +4271,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: @@ -4301,11 +4289,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) { @@ -4357,9 +4344,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. @@ -4382,7 +4369,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. * @@ -4398,28 +4385,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; @@ -4434,7 +4428,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: @@ -4458,7 +4452,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)) { @@ -4474,8 +4468,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: @@ -4494,55 +4488,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; } @@ -4552,7 +4577,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: @@ -4569,33 +4594,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. @@ -4621,7 +4646,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. @@ -4669,21 +4694,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( @@ -4720,53 +4747,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; @@ -4778,7 +4797,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. @@ -4799,9 +4818,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 { @@ -4824,7 +4843,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; } @@ -4848,7 +4867,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. @@ -4866,83 +4885,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; @@ -4950,8 +4968,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; } @@ -4959,7 +4977,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) { @@ -4972,22 +4990,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); @@ -4995,47 +5014,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; } @@ -5044,7 +5069,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: @@ -5060,18 +5085,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; } } @@ -5094,16 +5121,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; @@ -5113,64 +5140,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); + } } /* @@ -5184,33 +5235,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; +#ifdef TK_MAC_DEBUG_WINDOWS + TkMacOSXInitNamedDebugSymbol(HIToolbox, void, DebugPrintWindow, WindowRef); + if (DebugPrintWindow) { + DebugPrintWindow(newWindow); } - valueHashPtr = Tcl_CreateHashEntry(&windowTable, - (char *) newWindow, &new); - if (!new) { - Tcl_Panic("same macintosh window allocated twice!"); - } - Tcl_SetHashValue(valueHashPtr, macWin); - - macWin->flags |= TK_HOST_EXISTS; +#endif /* TK_MAC_DEBUG_WINDOWS */ } /* @@ -5219,10 +5259,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. @@ -5233,26 +5270,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); } /* @@ -5260,7 +5294,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. * @@ -5273,23 +5307,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); } } @@ -5299,7 +5330,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: @@ -5311,7 +5342,7 @@ TkMacOSXUnregisterMacWindow( *---------------------------------------------------------------------- */ -void +void TkMacOSXSetScrollbarGrow( TkWindow *winPtr, /* Tk scrollbar window. */ int flag) /* Boolean value true or false. */ @@ -5325,7 +5356,7 @@ TkMacOSXSetScrollbarGrow( winPtr->privatePtr->toplevel->winPtr->wmInfoPtr->scrollWinPtr = NULL; } } - + /* *---------------------------------------------------------------------- * @@ -5334,8 +5365,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: @@ -5408,13 +5439,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; @@ -5426,7 +5457,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)) { @@ -5447,84 +5478,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. * *---------------------------------------------------------------------- */ @@ -5535,62 +5556,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; + Tcl_Time now; - /* - * 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. - */ - - *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. * *---------------------------------------------------------------------- */ @@ -5603,7 +5617,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. */ } @@ -5612,48 +5626,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); } - /* *---------------------------------------------------------------------- @@ -5676,28 +5689,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); } } @@ -5720,7 +5735,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; @@ -5736,7 +5751,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 @@ -5745,33 +5760,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; } - if (window_ptr != (windows-1)) - Tcl_Panic("num matched toplevel windows does not equal num children"); + frontWindow = GetNextWindow(frontWindow); + } + if (window_ptr != (windows-1)) + Tcl_Panic("num matched toplevel windows does not equal num " + "children"); } done: @@ -5782,9 +5798,9 @@ TkWmStackorderToplevel(parentPtr) /* *---------------------------------------------------------------------- * - * ApplyWindowAttributeChanges -- + * ApplyWindowClassAttributeChanges -- * - * This procedure applies carbon window attribute changes. + * This procedure applies carbon window class and attribute changes. * * Results: * None. @@ -5796,27 +5812,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 037ccdc..4b18477 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.2.2.4 2006/03/28 02:44:14 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: tkMacOSXWm.h,v 1.2.2.5 2007/04/29 02:26:51 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. */ @@ -218,8 +223,8 @@ typedef struct TkWmInfo { ProtocolHandler *protPtr; /* First in list of protocol handlers for * 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 + const char **cmdArgv; /* Array of strings to store in the + * 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..1e4be4e 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.2.2.1 2007/04/29 02:26:51 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 2ebf2b1..6891a3d 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.2.2.13 2006/09/10 17:07:36 das Exp $ + * RCS: @(#) $Id: tkMacOSXXStubs.c,v 1.2.2.14 2007/04/29 02:26:51 das Exp $ */ #include "tkMacOSXInt.h" @@ -20,14 +21,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 /* @@ -35,30 +36,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); + /* *---------------------------------------------------------------------- * @@ -81,6 +79,7 @@ TkMacOSXDisplayChanged(Display *display) { GDHandle graphicsDevice; Screen *screen; + Rect bounds = {0, 0, 0, 0}, *maxBounds; if (display == NULL || display->screens == NULL) { return; @@ -88,15 +87,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); + } } /* @@ -122,7 +135,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) { @@ -131,7 +145,6 @@ TkpOpenDisplay( return NULL; } } - InitCursor(); display = (Display *) ckalloc(sizeof(Display)); screen = (Screen *) ckalloc(sizeof(Screen)); @@ -139,13 +152,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; @@ -156,14 +169,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; @@ -209,15 +223,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); } @@ -229,7 +243,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. * @@ -244,7 +258,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 @@ -329,7 +343,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: @@ -347,7 +361,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!"); @@ -394,45 +408,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; } @@ -460,17 +474,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; } @@ -514,23 +529,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, @@ -542,7 +557,7 @@ XCreateImage( unsigned int height, int bitmap_pad, int bytes_per_line) -{ +{ XImage *ximage; display->request++; @@ -658,15 +673,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 @@ -682,21 +697,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; @@ -737,7 +752,7 @@ XRefreshKeyboardMapping( XMappingEvent* x) Debugger(); } -void +void XSetIconName( Display* display, Window w, @@ -749,15 +764,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++; } @@ -784,7 +799,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: @@ -800,7 +815,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]; @@ -810,77 +825,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; } @@ -896,7 +917,7 @@ TkMacOSXXSubImage( return NULL; } -static int +static int TkMacOSXXAddPixel( XImage *image, long value) @@ -912,7 +933,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: @@ -933,7 +954,7 @@ XChangeWindowAttributes( { } -void +void XSetWindowBackground( Display *display, Window window, @@ -984,8 +1005,8 @@ XSetWindowColormap( Status XStringListToTextProperty( - char** list, - int count, + char** list, + int count, XTextProperty* text_prop_return) { Debugger(); @@ -993,8 +1014,8 @@ XStringListToTextProperty( } void XSetWMClientMachine( - Display* display, - Window w, + Display* display, + Window w, XTextProperty* text_prop) { Debugger(); |