From 3d653839d0082e663196cd7d34738a73d9b99bca Mon Sep 17 00:00:00 2001 From: das Date: Sun, 29 Apr 2007 02:26:47 +0000 Subject: * 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 <> 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 <> 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: --- ChangeLog | 315 +++ macosx/Makefile | 23 +- macosx/README | 40 +- macosx/Tk-Info.plist.in | 17 +- macosx/Wish-Info.plist.in | 29 +- macosx/tkAboutDlg.r | 34 +- macosx/tkMacOSX.h | 13 +- macosx/tkMacOSXAETE.r | 17 +- macosx/tkMacOSXBitmap.c | 277 ++- macosx/tkMacOSXButton.c | 1876 ++++++++------- macosx/tkMacOSXCarbonEvents.c | 649 ++++-- macosx/tkMacOSXClipboard.c | 331 ++- macosx/tkMacOSXColor.c | 905 +++++--- macosx/tkMacOSXConfig.c | 26 +- macosx/tkMacOSXCursor.c | 467 ++-- macosx/tkMacOSXCursors.r | 32 +- macosx/tkMacOSXDebug.c | 303 ++- macosx/tkMacOSXDebug.h | 93 +- macosx/tkMacOSXDefault.h | 66 +- macosx/tkMacOSXDialog.c | 1444 ++++++------ macosx/tkMacOSXDraw.c | 1508 ++++++------ macosx/tkMacOSXEmbed.c | 1085 +++++---- macosx/tkMacOSXEntry.c | 328 ++- macosx/tkMacOSXEvent.c | 300 ++- macosx/tkMacOSXEvent.h | 125 +- macosx/tkMacOSXFont.c | 2453 ++++++++++---------- macosx/tkMacOSXFont.h | 17 +- macosx/tkMacOSXHLEvents.c | 511 ++-- macosx/tkMacOSXInit.c | 350 +-- macosx/tkMacOSXInt.h | 230 +- macosx/tkMacOSXKeyEvent.c | 1359 +++++------ macosx/tkMacOSXKeyboard.c | 691 +++--- macosx/tkMacOSXMenu.c | 5142 ++++++++++++++++++++--------------------- macosx/tkMacOSXMenu.r | 47 - macosx/tkMacOSXMenubutton.c | 970 ++++---- macosx/tkMacOSXMenus.c | 250 +- macosx/tkMacOSXMouseEvent.c | 660 +++--- macosx/tkMacOSXNotify.c | 79 +- macosx/tkMacOSXPort.h | 45 +- macosx/tkMacOSXRegion.c | 135 +- macosx/tkMacOSXScale.c | 277 +-- macosx/tkMacOSXScrlbr.c | 1253 +++++----- macosx/tkMacOSXSend.c | 191 +- macosx/tkMacOSXSubwindows.c | 642 +++-- macosx/tkMacOSXTest.c | 13 +- macosx/tkMacOSXWindowEvent.c | 766 +++--- macosx/tkMacOSXWm.c | 4471 +++++++++++++++++++---------------- macosx/tkMacOSXWm.h | 170 +- macosx/tkMacOSXXCursors.r | 195 +- macosx/tkMacOSXXStubs.c | 335 +-- 50 files changed, 16322 insertions(+), 15233 deletions(-) delete mode 100644 macosx/tkMacOSXMenu.r diff --git a/ChangeLog b/ChangeLog index 735a4b9..55e2991 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,318 @@ +2007-04-29 Daniel Steffen + + * 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 <> 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 <> 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 * 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 +# +# 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 in your script before drawing, in which case lines (or shapes with outlines) -thinner that pixels will not be antialiased. +thinner than 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 @@ + CFBundleDevelopmentRegion @@ -7,14 +15,17 @@ CFBundleExecutable @TK_LIB_FILE@ CFBundleGetInfoString - 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. + 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. CFBundleIdentifier com.tcltk.tklibrary CFBundleInfoDictionaryVersion 6.0 CFBundleName - Tk @TK_WINDOWINGSYSTEM@ Library @TK_VERSION@ + Tk @TK_WINDOWINGSYSTEM@ @TK_VERSION@ CFBundlePackageType FMWK CFBundleShortVersionString 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 @@ + CFBundleDevelopmentRegion @@ -9,13 +17,21 @@ CFBundleTypeExtensions + tcl + TCL * + CFBundleTypeMIMETypes + + application/x-tcl + text/plain + CFBundleTypeName NSStringPboardType CFBundleTypeOSTypes TEXT + **** CFBundleTypeRole Viewer @@ -24,8 +40,11 @@ CFBundleExecutable Wish CFBundleGetInfoString - 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. + 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. CFBundleIconFile Wish.icns CFBundleIdentifier @@ -42,5 +61,11 @@ Initial MacOS X Port by Jim Ingham <jingham@apple.com> & Ian Reid, Cop WiSH CFBundleVersion @TK_VERSION@@TK_PATCH_LEVEL@ + LSMinimumSystemVersion + 10.2.0 + LSRequiresCarbon + + NSAppleScriptEnabled + 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 * * 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 * * 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 * * 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 * * 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 + * Copyright (c) 2005-2007 Daniel A. Steffen * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * 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 * * 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 * * 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 * * 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 @@ -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 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 * - * 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 * * 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 * * 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 + * Copyright (c) 2006-2007 Daniel A. Steffen * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: 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;ixOff + 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 * * 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 * - * 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 + * Copyright (c) 2005-2007 Daniel A. Steffen * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: 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 * - * 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 * * 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 * * 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 + * Copyright (c) 2005-2007 Daniel A. Steffen * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: 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 * * 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 #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 + * Copyright (c) 2006-2007 Daniel A. Steffen * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * 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 ) 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 . - * - * 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 . + * + * 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 * * 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, and become synonyms for and