summaryrefslogtreecommitdiffstats
path: root/macosx
diff options
context:
space:
mode:
Diffstat (limited to 'macosx')
-rw-r--r--macosx/Makefile56
-rw-r--r--macosx/Wish.icnsbin0 -> 35960 bytes
-rw-r--r--macosx/Wish.pbproj/jingham.pbxuser1502
-rw-r--r--macosx/Wish.pbproj/project.pbxproj3593
-rw-r--r--macosx/tclets.r172
-rw-r--r--macosx/tkAboutDlg.r393
-rw-r--r--macosx/tkMacOSX.h34
-rw-r--r--macosx/tkMacOSXAppInit.c241
-rw-r--r--macosx/tkMacOSXApplication.r276
-rw-r--r--macosx/tkMacOSXBitmap.c283
-rw-r--r--macosx/tkMacOSXButton.c1580
-rw-r--r--macosx/tkMacOSXClipboard.c321
-rw-r--r--macosx/tkMacOSXColor.c448
-rw-r--r--macosx/tkMacOSXConfig.c46
-rw-r--r--macosx/tkMacOSXCursor.c406
-rw-r--r--macosx/tkMacOSXCursors.r130
-rw-r--r--macosx/tkMacOSXDebug.c439
-rw-r--r--macosx/tkMacOSXDebug.h69
-rw-r--r--macosx/tkMacOSXDefault.h531
-rw-r--r--macosx/tkMacOSXDialog.c1229
-rw-r--r--macosx/tkMacOSXDraw.c1714
-rw-r--r--macosx/tkMacOSXEmbed.c1193
-rw-r--r--macosx/tkMacOSXEvent.c276
-rw-r--r--macosx/tkMacOSXEvent.h86
-rw-r--r--macosx/tkMacOSXFont.c2191
-rw-r--r--macosx/tkMacOSXHLEvents.c447
-rw-r--r--macosx/tkMacOSXInit.c221
-rw-r--r--macosx/tkMacOSXInt.h155
-rw-r--r--macosx/tkMacOSXKeyEvent.c420
-rw-r--r--macosx/tkMacOSXKeyboard.c650
-rw-r--r--macosx/tkMacOSXLibrary.r510
-rw-r--r--macosx/tkMacOSXMenu.c4686
-rw-r--r--macosx/tkMacOSXMenu.r47
-rw-r--r--macosx/tkMacOSXMenubutton.c861
-rw-r--r--macosx/tkMacOSXMenus.c325
-rw-r--r--macosx/tkMacOSXMouseEvent.c704
-rw-r--r--macosx/tkMacOSXNotify.c1145
-rw-r--r--macosx/tkMacOSXPort.h154
-rw-r--r--macosx/tkMacOSXRegion.c252
-rw-r--r--macosx/tkMacOSXResource.r502
-rw-r--r--macosx/tkMacOSXScale.c431
-rw-r--r--macosx/tkMacOSXScrlbr.c1076
-rw-r--r--macosx/tkMacOSXSend.c552
-rw-r--r--macosx/tkMacOSXSubwindows.c1304
-rw-r--r--macosx/tkMacOSXTest.c82
-rw-r--r--macosx/tkMacOSXUtil.c330
-rw-r--r--macosx/tkMacOSXUtil.h65
-rw-r--r--macosx/tkMacOSXWindowEvent.c693
-rw-r--r--macosx/tkMacOSXWm.c5506
-rw-r--r--macosx/tkMacOSXWm.h302
-rw-r--r--macosx/tkMacOSXXCursors.r961
-rw-r--r--macosx/tkMacOSXXStubs.c862
52 files changed, 40452 insertions, 0 deletions
diff --git a/macosx/Makefile b/macosx/Makefile
new file mode 100644
index 0000000..dc4f77f
--- /dev/null
+++ b/macosx/Makefile
@@ -0,0 +1,56 @@
+################################################################################
+#
+# Simple makefile for building on Mac OS X with the
+# Project Builder command line tool 'pbxbuild'
+#
+# RCS: @(#) $Id: Makefile,v 1.2 2002/08/31 06:12:29 das Exp $
+#
+################################################################################
+
+INSTALL_ROOT =
+
+BUILD_DIR = ../../build
+
+TARGET = Wish
+
+DEVBUILDSTYLE = Development
+DEPBUILDSTYLE = Deployment
+
+PBXBUILD = /usr/bin/pbxbuild
+
+BUILD = ${PBXBUILD} SYMROOT="${BUILD_DIR}" -target "${TARGET}"
+
+DEVBUILD = ${BUILD} -buildstyle "${DEVBUILDSTYLE}"
+DEPBUILD = ${BUILD} -buildstyle "${DEPBUILDSTYLE}"
+
+INSTALLOPTS = INSTALL_ROOT="${INSTALL_ROOT}"
+
+################################################################################
+
+all: develop deploy
+
+install: install-develop install-deploy
+
+clean: clean-develop clean-deploy
+
+################################################################################
+
+develop:
+ ${DEVBUILD}
+
+deploy:
+ ${DEPBUILD}
+
+install-develop:
+ ${DEVBUILD} install ${INSTALLOPTS}
+
+install-deploy:
+ ${DEPBUILD} install ${INSTALLOPTS}
+
+clean-develop:
+ ${DEVBUILD} clean
+
+clean-deploy:
+ ${DEPBUILD} clean
+
+################################################################################
diff --git a/macosx/Wish.icns b/macosx/Wish.icns
new file mode 100644
index 0000000..060bfbd
--- /dev/null
+++ b/macosx/Wish.icns
Binary files differ
diff --git a/macosx/Wish.pbproj/jingham.pbxuser b/macosx/Wish.pbproj/jingham.pbxuser
new file mode 100644
index 0000000..72932e7
--- /dev/null
+++ b/macosx/Wish.pbproj/jingham.pbxuser
@@ -0,0 +1,1502 @@
+// !$*UTF8*$!
+{
+ 005751A902FB00920AC916F0 = {
+ fRef = F5375568016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXXStubs.c: TkpCloseDisplay";
+ rLen = 0;
+ rLoc = 5311;
+ rType = 0;
+ vrLen = 417;
+ vrLoc = 4894;
+ };
+ F50D961501961F0201DC9062 = {
+ fileReference = F5375551016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 902;
+ state = 2;
+ };
+ F537552A016C352C01DC9062 = {
+ activeBuildStyle = F537552C016C352C01DC9062;
+ activeExecutable = F53756AB016C4DD401DC9062;
+ activeTarget = F53756A0016C4DD401DC9062;
+ addToTargets = (
+ F53755DF016C38D201DC9062,
+ );
+ breakpoints = (
+ F5B2CDC10175829501DC9062,
+ F571FE470179562E01DC9062,
+ F571FE4A0179695001DC9062,
+ F571FE4C01796B1101DC9062,
+ F571FE4D01796CAF01DC9062,
+ F571FE4E01796F9201DC9062,
+ F571FE4F0179702301DC9062,
+ F571FE500179702301DC9062,
+ F583DC0E018D092D01DC9062,
+ F583DC0F018D0CB501DC9062,
+ F583DC13018D2B4A01DC9062,
+ F58907BE018DCE8F01DC9062,
+ F58907C5018DD1C301DC9062,
+ F50D961501961F0201DC9062,
+ F566083B0197283B01DC9062,
+ F566083C0197823801DC9062,
+ F5A5146F01D05DC201DC9062,
+ F5A5147001D0758C01DC9062,
+ F5A852D6020F6C6C01DC9062,
+ F5A439C0029B609C01DC9064,
+ F5A439C2029B60ED01DC9064,
+ F5A439CA029B620901DC9064,
+ F55BC4B602B2DFB901DC9062,
+ F5978FD602B3190701DC9062,
+ );
+ executables = (
+ F53756AB016C4DD401DC9062,
+ );
+ perUserDictionary = {
+ PBXPerProjectTemplateStateSaveDate = 49921092;
+ "PBXTemplateGeometry-F5314676015831810DCA290F" = {
+ ContentSize = "{716, 618}";
+ LeftSlideOut = {
+ Collapsed = NO;
+ Frame = "{{0, 23}, {716, 595}}";
+ Split0 = {
+ ActiveTab = 2;
+ Collapsed = NO;
+ Frame = "{{0, 0}, {716, 595}}";
+ Split0 = {
+ Frame = "{{0, 249}, {716, 346}}";
+ };
+ SplitCount = 1;
+ Tab0 = {
+ Debugger = {
+ Collapsed = NO;
+ Frame = "{{0, 0}, {952, 321}}";
+ Split0 = {
+ Frame = "{{0, 24}, {952, 297}}";
+ Split0 = {
+ Frame = "{{0, 0}, {468, 297}}";
+ };
+ Split1 = {
+ DebugVariablesTableConfiguration = (
+ Name,
+ 126.803,
+ Value,
+ 150.074,
+ Summary,
+ 172.123,
+ );
+ Frame = "{{477, 0}, {475, 297}}";
+ };
+ SplitCount = 2;
+ };
+ SplitCount = 1;
+ Tab0 = {
+ Frame = "{{0, 0}, {100, 50}}";
+ };
+ Tab1 = {
+ Frame = "{{0, 0}, {100, 50}}";
+ };
+ TabCount = 2;
+ TabsVisible = YES;
+ };
+ Frame = "{{0, 0}, {952, 321}}";
+ LauncherConfigVersion = 7;
+ };
+ Tab1 = {
+ Frame = "{{0, 0}, {781, 452}}";
+ LauncherConfigVersion = 3;
+ Runner = {
+ Frame = "{{0, 0}, {781, 452}}";
+ };
+ };
+ Tab2 = {
+ BuildMessageFrame = "{{0, 0}, {718, 0}}";
+ BuildTranscriptFrame = "{{0, 9}, {718, 236}}";
+ Frame = "{{0, 0}, {716, 243}}";
+ };
+ Tab3 = {
+ Frame = "{{0, 0}, {612, 295}}";
+ };
+ TabCount = 4;
+ TabsVisible = NO;
+ };
+ SplitCount = 1;
+ Tab0 = {
+ Frame = "{{0, 0}, {300, 533}}";
+ GroupTreeTableConfiguration = (
+ SCMStatusColumn,
+ 22,
+ TargetStatusColumn,
+ 18,
+ MainColumn,
+ 245,
+ );
+ };
+ Tab1 = {
+ ClassesFrame = "{{0, 0}, {280, 398}}";
+ ClassesTreeTableConfiguration = (
+ PBXBookColumnIdentifier,
+ 20,
+ PBXClassColumnIdentifier,
+ 237,
+ );
+ Frame = "{{0, 0}, {278, 659}}";
+ MembersFrame = "{{0, 407}, {280, 252}}";
+ MembersTreeTableConfiguration = (
+ PBXBookColumnIdentifier,
+ 20,
+ PBXMethodColumnIdentifier,
+ 236,
+ );
+ };
+ Tab2 = {
+ Frame = "{{0, 0}, {200, 100}}";
+ };
+ Tab3 = {
+ Frame = "{{0, 0}, {200, 100}}";
+ TargetTableConfiguration = (
+ ActiveObject,
+ 16,
+ ObjectNames,
+ 202.296,
+ );
+ };
+ Tab4 = {
+ BreakpointsTreeTableConfiguration = (
+ breakpointColumn,
+ 197,
+ enabledColumn,
+ 31,
+ );
+ Frame = "{{0, 0}, {250, 100}}";
+ };
+ TabCount = 5;
+ TabsVisible = NO;
+ };
+ StatusViewVisible = YES;
+ Template = F5314676015831810DCA290F;
+ ToolbarVisible = YES;
+ WindowLocation = "{49, 213}";
+ };
+ "PBXTemplateGeometry-F5CA7ECB015C094F0DCA290F" = {
+ ContentSize = "{690, 721}";
+ LeftSlideOut = {
+ Collapsed = NO;
+ Frame = "{{0, 0}, {690, 721}}";
+ Split0 = {
+ Collapsed = NO;
+ Frame = "{{0, 0}, {690, 721}}";
+ Split0 = {
+ Frame = "{{0, 0}, {690, 721}}";
+ };
+ SplitCount = 1;
+ Tab0 = {
+ Debugger = {
+ Collapsed = NO;
+ Frame = "{{0, 0}, {484, 208}}";
+ Split0 = {
+ Frame = "{{0, 24}, {484, 184}}";
+ Split0 = {
+ Frame = "{{0, 0}, {236, 184}}";
+ };
+ Split1 = {
+ DebugVariablesTableConfiguration = (
+ Name,
+ 123,
+ Value,
+ 85,
+ Summary,
+ 62.123,
+ );
+ Frame = "{{245, 0}, {239, 184}}";
+ };
+ SplitCount = 2;
+ };
+ SplitCount = 1;
+ Tab0 = {
+ Frame = "{{0, 0}, {100, 50}}";
+ };
+ Tab1 = {
+ Frame = "{{0, 0}, {100, 50}}";
+ };
+ TabCount = 2;
+ TabsVisible = YES;
+ };
+ Frame = "{{0, 0}, {484, 208}}";
+ LauncherConfigVersion = 7;
+ };
+ Tab1 = {
+ Frame = "{{0, 0}, {664, 208}}";
+ LauncherConfigVersion = 3;
+ Runner = {
+ Frame = "{{0, 0}, {664, 208}}";
+ };
+ };
+ Tab2 = {
+ BuildMessageFrame = "{{0, 0}, {666, 43}}";
+ BuildTranscriptFrame = "{{0, 52}, {666, 0}}";
+ Frame = "{{0, 0}, {664, 50}}";
+ };
+ Tab3 = {
+ Frame = "{{0, 0}, {612, 295}}";
+ };
+ TabCount = 4;
+ TabsVisible = NO;
+ };
+ SplitCount = 1;
+ Tab0 = {
+ Frame = "{{0, 0}, {313, 531}}";
+ GroupTreeTableConfiguration = (
+ SCMStatusColumn,
+ 22,
+ TargetStatusColumn,
+ 18,
+ MainColumn,
+ 258,
+ );
+ };
+ Tab1 = {
+ ClassesFrame = "{{0, 0}, {280, 398}}";
+ ClassesTreeTableConfiguration = (
+ PBXBookColumnIdentifier,
+ 20,
+ PBXClassColumnIdentifier,
+ 237,
+ );
+ Frame = "{{0, 0}, {278, 659}}";
+ MembersFrame = "{{0, 407}, {280, 252}}";
+ MembersTreeTableConfiguration = (
+ PBXBookColumnIdentifier,
+ 20,
+ PBXMethodColumnIdentifier,
+ 236,
+ );
+ };
+ Tab2 = {
+ Frame = "{{0, 0}, {200, 100}}";
+ };
+ Tab3 = {
+ Frame = "{{0, 0}, {200, 557}}";
+ TargetTableConfiguration = (
+ ActiveObject,
+ 16,
+ ObjectNames,
+ 202.296,
+ );
+ };
+ Tab4 = {
+ BreakpointsTreeTableConfiguration = (
+ breakpointColumn,
+ 197,
+ enabledColumn,
+ 31,
+ );
+ Frame = "{{0, 0}, {250, 100}}";
+ };
+ TabCount = 5;
+ TabsVisible = NO;
+ };
+ StatusViewVisible = NO;
+ Template = F5CA7ECB015C094F0DCA290F;
+ ToolbarVisible = NO;
+ WindowLocation = "{48, 3}";
+ };
+ PBXWorkspaceContents = (
+ {
+ LeftSlideOut = {
+ Split0 = {
+ Split0 = {
+ NavContent0 = {
+ history = (
+ F5A439D1029B6B5501DC9064,
+ F5A439D2029B6B5501DC9064,
+ F5A439D3029B6B5501DC9064,
+ F5A439D4029B6B5501DC9064,
+ F5A439D5029B6B5501DC9064,
+ F5A439D6029B6B5501DC9064,
+ F5A439D7029B6B5501DC9064,
+ F5BE671E029B6FEE01DC9064,
+ F55BC4B902B2E09101DC9062,
+ F55BC4BA02B2E09101DC9062,
+ F55BC4BD02B2E09101DC9062,
+ F5BFE59402F984FA01DC9062,
+ F5BFE59502F984FA01DC9062,
+ F5BFE59602F984FA01DC9062,
+ F5BFE59702F984FA01DC9062,
+ F5BFE59802F984FA01DC9062,
+ F5BFE59902F984FA01DC9062,
+ F5BFE59B02F984FA01DC9062,
+ F5BFE59C02F984FA01DC9062,
+ F5BFE59D02F984FA01DC9062,
+ F5BFE59E02F984FA01DC9062,
+ F5BFE59F02F984FA01DC9062,
+ F5BFE5A002F984FA01DC9062,
+ F5BFE5A102F984FA01DC9062,
+ F5BFE5A202F984FA01DC9062,
+ F5BFE5A402F984FA01DC9062,
+ F5BFE5A502F984FA01DC9062,
+ F5BFE5A602F984FA01DC9062,
+ F5BFE5A702F984FA01DC9062,
+ F5BFE5A802F984FA01DC9062,
+ );
+ prevStack = (
+ F5A439DA029B6B5501DC9064,
+ F5A439DB029B6B5501DC9064,
+ F5A439DE029B6B5501DC9064,
+ F5A439DF029B6B5501DC9064,
+ F5A439E0029B6B5501DC9064,
+ F5A439E1029B6B5501DC9064,
+ F5A439E2029B6B5501DC9064,
+ F5A439E3029B6B5501DC9064,
+ F5A439E4029B6B5501DC9064,
+ F5A439E5029B6B5501DC9064,
+ F5A439E6029B6B5501DC9064,
+ F5A439E7029B6B5501DC9064,
+ F5A439E8029B6B5501DC9064,
+ F5BE671F029B6FEE01DC9064,
+ F55BC4BF02B2E09101DC9062,
+ F55BC4C002B2E09101DC9062,
+ F55BC4C102B2E09101DC9062,
+ F55BC4C202B2E09101DC9062,
+ F55BC4C302B2E09101DC9062,
+ F55BC4C402B2E09101DC9062,
+ F55BC4C702B2E09101DC9062,
+ F5BFE5AA02F984FA01DC9062,
+ F5BFE5AB02F984FA01DC9062,
+ F5BFE5AC02F984FA01DC9062,
+ F5BFE5AD02F984FA01DC9062,
+ F5BFE5AE02F984FA01DC9062,
+ F5BFE5AF02F984FA01DC9062,
+ F5BFE5B002F984FA01DC9062,
+ F5BFE5B202F984FA01DC9062,
+ F5BFE5B302F984FA01DC9062,
+ F5BFE5B402F984FA01DC9062,
+ F5BFE5B502F984FA01DC9062,
+ F5BFE5B702F984FA01DC9062,
+ F5BFE5B802F984FA01DC9062,
+ F5BFE5B902F984FA01DC9062,
+ F5BFE5BB02F984FA01DC9062,
+ F5BFE5BC02F984FA01DC9062,
+ F5BFE5BD02F984FA01DC9062,
+ F5BFE5BE02F984FA01DC9062,
+ F5BFE5BF02F984FA01DC9062,
+ F5BFE5C002F984FA01DC9062,
+ F5BFE5C102F984FA01DC9062,
+ );
+ };
+ NavContent1 = {
+ bookmark = 005751A902FB00920AC916F0;
+ history = (
+ F5BFE5C402F984FA01DC9062,
+ );
+ };
+ NavCount = 2;
+ NavGeometry0 = {
+ Frame = "{{0, 0}, {645, 321}}";
+ NavBarVisible = YES;
+ };
+ NavGeometry1 = {
+ Frame = "{{0, 330}, {645, 321}}";
+ NavBarVisible = YES;
+ };
+ };
+ SplitCount = 1;
+ Tab0 = {
+ Debugger = {
+ Split0 = {
+ SplitCount = 2;
+ };
+ SplitCount = 1;
+ TabCount = 2;
+ };
+ LauncherConfigVersion = 7;
+ };
+ Tab1 = {
+ LauncherConfigVersion = 3;
+ Runner = {
+ };
+ };
+ TabCount = 4;
+ };
+ SplitCount = 1;
+ Tab1 = {
+ OptionsSetName = "Default Options";
+ };
+ TabCount = 5;
+ };
+ },
+ );
+ PBXWorkspaceGeometries = (
+ {
+ ContentSize = "{929, 674}";
+ LeftSlideOut = {
+ ActiveTab = 0;
+ Collapsed = NO;
+ Frame = "{{0, 23}, {929, 651}}";
+ Split0 = {
+ Collapsed = NO;
+ Frame = "{{284, 0}, {645, 651}}";
+ Split0 = {
+ Frame = "{{0, 0}, {645, 651}}";
+ };
+ SplitCount = 1;
+ Tab0 = {
+ Debugger = {
+ Collapsed = NO;
+ Frame = "{{0, 0}, {681, 289}}";
+ Split0 = {
+ Frame = "{{0, 24}, {681, 265}}";
+ Split0 = {
+ Frame = "{{0, 0}, {333, 265}}";
+ };
+ Split1 = {
+ DebugVariablesTableConfiguration = (
+ Name,
+ 82.80298,
+ Value,
+ 104.074,
+ Summary,
+ 126.123,
+ );
+ Frame = "{{342, 0}, {339, 265}}";
+ };
+ SplitCount = 2;
+ };
+ SplitCount = 1;
+ Tab0 = {
+ Frame = "{{0, 0}, {100, 50}}";
+ };
+ Tab1 = {
+ Frame = "{{0, 0}, {100, 50}}";
+ };
+ TabCount = 2;
+ TabsVisible = YES;
+ };
+ Frame = "{{0, 0}, {681, 289}}";
+ LauncherConfigVersion = 7;
+ };
+ Tab1 = {
+ Frame = "{{0, 0}, {681, 120}}";
+ LauncherConfigVersion = 3;
+ Runner = {
+ Frame = "{{0, 0}, {681, 120}}";
+ };
+ };
+ Tab2 = {
+ BuildMessageFrame = "{{0, 0}, {683, 127}}";
+ BuildTranscriptFrame = "{{0, 136}, {683, 100}}";
+ Frame = "{{0, 0}, {681, 234}}";
+ };
+ Tab3 = {
+ Frame = "{{0, 0}, {681, 238}}";
+ };
+ TabCount = 4;
+ TabsVisible = NO;
+ };
+ SplitCount = 1;
+ Tab0 = {
+ Frame = "{{0, 0}, {260, 651}}";
+ GroupTreeTableConfiguration = (
+ SCMStatusColumn,
+ 22,
+ TargetStatusColumn,
+ 18,
+ MainColumn,
+ 205,
+ );
+ };
+ Tab1 = {
+ ClassesFrame = "{{0, 0}, {250, 333}}";
+ ClassesTreeTableConfiguration = (
+ PBXBookColumnIdentifier,
+ 20,
+ PBXClassColumnIdentifier,
+ 207,
+ );
+ Frame = "{{0, 0}, {248, 554}}";
+ MembersFrame = "{{0, 342}, {250, 212}}";
+ MembersTreeTableConfiguration = (
+ PBXBookColumnIdentifier,
+ 20,
+ PBXMethodColumnIdentifier,
+ 206,
+ );
+ };
+ Tab2 = {
+ Frame = "{{0, 0}, {217, 554}}";
+ };
+ Tab3 = {
+ Frame = "{{0, 0}, {239, 651}}";
+ TargetTableConfiguration = (
+ ActiveObject,
+ 16,
+ ObjectNames,
+ 206.296,
+ );
+ };
+ Tab4 = {
+ BreakpointsTreeTableConfiguration = (
+ breakpointColumn,
+ 197,
+ enabledColumn,
+ 31,
+ );
+ Frame = "{{0, 0}, {250, 554}}";
+ };
+ TabCount = 5;
+ TabsVisible = YES;
+ };
+ StatusViewVisible = YES;
+ Template = 64ABBB4501FA494900185B06;
+ ToolbarVisible = YES;
+ WindowLocation = "{165, 176}";
+ },
+ );
+ PBXWorkspaceStateSaveDate = 49921092;
+ };
+ perUserProjectItems = {
+ 005751A902FB00920AC916F0 = 005751A902FB00920AC916F0;
+ F55BC4B902B2E09101DC9062 = F55BC4B902B2E09101DC9062;
+ F55BC4BA02B2E09101DC9062 = F55BC4BA02B2E09101DC9062;
+ F55BC4BD02B2E09101DC9062 = F55BC4BD02B2E09101DC9062;
+ F55BC4BF02B2E09101DC9062 = F55BC4BF02B2E09101DC9062;
+ F55BC4C002B2E09101DC9062 = F55BC4C002B2E09101DC9062;
+ F55BC4C102B2E09101DC9062 = F55BC4C102B2E09101DC9062;
+ F55BC4C202B2E09101DC9062 = F55BC4C202B2E09101DC9062;
+ F55BC4C302B2E09101DC9062 = F55BC4C302B2E09101DC9062;
+ F55BC4C402B2E09101DC9062 = F55BC4C402B2E09101DC9062;
+ F55BC4C702B2E09101DC9062 = F55BC4C702B2E09101DC9062;
+ F5A439D1029B6B5501DC9064 = F5A439D1029B6B5501DC9064;
+ F5A439D2029B6B5501DC9064 = F5A439D2029B6B5501DC9064;
+ F5A439D3029B6B5501DC9064 = F5A439D3029B6B5501DC9064;
+ F5A439D4029B6B5501DC9064 = F5A439D4029B6B5501DC9064;
+ F5A439D5029B6B5501DC9064 = F5A439D5029B6B5501DC9064;
+ F5A439D6029B6B5501DC9064 = F5A439D6029B6B5501DC9064;
+ F5A439D7029B6B5501DC9064 = F5A439D7029B6B5501DC9064;
+ F5A439DA029B6B5501DC9064 = F5A439DA029B6B5501DC9064;
+ F5A439DB029B6B5501DC9064 = F5A439DB029B6B5501DC9064;
+ F5A439DE029B6B5501DC9064 = F5A439DE029B6B5501DC9064;
+ F5A439DF029B6B5501DC9064 = F5A439DF029B6B5501DC9064;
+ F5A439E0029B6B5501DC9064 = F5A439E0029B6B5501DC9064;
+ F5A439E1029B6B5501DC9064 = F5A439E1029B6B5501DC9064;
+ F5A439E2029B6B5501DC9064 = F5A439E2029B6B5501DC9064;
+ F5A439E3029B6B5501DC9064 = F5A439E3029B6B5501DC9064;
+ F5A439E4029B6B5501DC9064 = F5A439E4029B6B5501DC9064;
+ F5A439E5029B6B5501DC9064 = F5A439E5029B6B5501DC9064;
+ F5A439E6029B6B5501DC9064 = F5A439E6029B6B5501DC9064;
+ F5A439E7029B6B5501DC9064 = F5A439E7029B6B5501DC9064;
+ F5A439E8029B6B5501DC9064 = F5A439E8029B6B5501DC9064;
+ F5BE671E029B6FEE01DC9064 = F5BE671E029B6FEE01DC9064;
+ F5BE671F029B6FEE01DC9064 = F5BE671F029B6FEE01DC9064;
+ F5BFE59402F984FA01DC9062 = F5BFE59402F984FA01DC9062;
+ F5BFE59502F984FA01DC9062 = F5BFE59502F984FA01DC9062;
+ F5BFE59602F984FA01DC9062 = F5BFE59602F984FA01DC9062;
+ F5BFE59702F984FA01DC9062 = F5BFE59702F984FA01DC9062;
+ F5BFE59802F984FA01DC9062 = F5BFE59802F984FA01DC9062;
+ F5BFE59902F984FA01DC9062 = F5BFE59902F984FA01DC9062;
+ F5BFE59B02F984FA01DC9062 = F5BFE59B02F984FA01DC9062;
+ F5BFE59C02F984FA01DC9062 = F5BFE59C02F984FA01DC9062;
+ F5BFE59D02F984FA01DC9062 = F5BFE59D02F984FA01DC9062;
+ F5BFE59E02F984FA01DC9062 = F5BFE59E02F984FA01DC9062;
+ F5BFE59F02F984FA01DC9062 = F5BFE59F02F984FA01DC9062;
+ F5BFE5A002F984FA01DC9062 = F5BFE5A002F984FA01DC9062;
+ F5BFE5A102F984FA01DC9062 = F5BFE5A102F984FA01DC9062;
+ F5BFE5A202F984FA01DC9062 = F5BFE5A202F984FA01DC9062;
+ F5BFE5A402F984FA01DC9062 = F5BFE5A402F984FA01DC9062;
+ F5BFE5A502F984FA01DC9062 = F5BFE5A502F984FA01DC9062;
+ F5BFE5A602F984FA01DC9062 = F5BFE5A602F984FA01DC9062;
+ F5BFE5A702F984FA01DC9062 = F5BFE5A702F984FA01DC9062;
+ F5BFE5A802F984FA01DC9062 = F5BFE5A802F984FA01DC9062;
+ F5BFE5AA02F984FA01DC9062 = F5BFE5AA02F984FA01DC9062;
+ F5BFE5AB02F984FA01DC9062 = F5BFE5AB02F984FA01DC9062;
+ F5BFE5AC02F984FA01DC9062 = F5BFE5AC02F984FA01DC9062;
+ F5BFE5AD02F984FA01DC9062 = F5BFE5AD02F984FA01DC9062;
+ F5BFE5AE02F984FA01DC9062 = F5BFE5AE02F984FA01DC9062;
+ F5BFE5AF02F984FA01DC9062 = F5BFE5AF02F984FA01DC9062;
+ F5BFE5B002F984FA01DC9062 = F5BFE5B002F984FA01DC9062;
+ F5BFE5B202F984FA01DC9062 = F5BFE5B202F984FA01DC9062;
+ F5BFE5B302F984FA01DC9062 = F5BFE5B302F984FA01DC9062;
+ F5BFE5B402F984FA01DC9062 = F5BFE5B402F984FA01DC9062;
+ F5BFE5B502F984FA01DC9062 = F5BFE5B502F984FA01DC9062;
+ F5BFE5B702F984FA01DC9062 = F5BFE5B702F984FA01DC9062;
+ F5BFE5B802F984FA01DC9062 = F5BFE5B802F984FA01DC9062;
+ F5BFE5B902F984FA01DC9062 = F5BFE5B902F984FA01DC9062;
+ F5BFE5BB02F984FA01DC9062 = F5BFE5BB02F984FA01DC9062;
+ F5BFE5BC02F984FA01DC9062 = F5BFE5BC02F984FA01DC9062;
+ F5BFE5BD02F984FA01DC9062 = F5BFE5BD02F984FA01DC9062;
+ F5BFE5BE02F984FA01DC9062 = F5BFE5BE02F984FA01DC9062;
+ F5BFE5BF02F984FA01DC9062 = F5BFE5BF02F984FA01DC9062;
+ F5BFE5C002F984FA01DC9062 = F5BFE5C002F984FA01DC9062;
+ F5BFE5C102F984FA01DC9062 = F5BFE5C102F984FA01DC9062;
+ F5BFE5C402F984FA01DC9062 = F5BFE5C402F984FA01DC9062;
+ };
+ projectwideBuildSettings = {
+ OBJROOT = "/Volumes/TheCloset/jingham/tcl-tk/source/tcl-merge/Objects";
+ SYMROOT = "/Volumes/TheCloset/jingham/tcl-tk/source/tcl-merge/Products";
+ };
+ wantsIndex = 1;
+ wantsSCM = -1;
+ };
+ F53755DF016C38D201DC9062 = {
+ activeExec = 0;
+ };
+ F53756A0016C4DD401DC9062 = {
+ activeExec = 0;
+ executables = (
+ F53756AB016C4DD401DC9062,
+ );
+ };
+ F53756AB016C4DD401DC9062 = {
+ activeArgIndex = 2147483647;
+ argumentStrings = (
+ );
+ debuggerPlugin = GDBDebugging;
+ dylibVariantSuffix = "";
+ enableDebugStr = 1;
+ environmentEntries = (
+ );
+ isa = PBXExecutable;
+ name = "Wish Shell";
+ shlibInfoDictList = (
+ );
+ sourceDirectories = (
+ );
+ };
+ F55BC4B602B2DFB901DC9062 = {
+ fileReference = F5375580016C389901DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 201;
+ state = 2;
+ };
+ F55BC4B902B2E09101DC9062 = {
+ fRef = F5375553016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXEvent.c: 242";
+ rLen = 0;
+ rLoc = 6185;
+ rType = 0;
+ vrLen = 1438;
+ vrLoc = 5937;
+ };
+ F55BC4BA02B2E09101DC9062 = {
+ fRef = F55BC46A02B2D3F301DC9062;
+ isa = PBXTextBookmark;
+ name = "panedwindow.tcl: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 1395;
+ vrLoc = 0;
+ };
+ F55BC4BD02B2E09101DC9062 = {
+ bstl = F537552C016C352C01DC9062;
+ isa = PBXBuildStyleBookmark;
+ };
+ F55BC4BF02B2E09101DC9062 = {
+ fRef = F5375553016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXEvent.c: 242";
+ rLen = 0;
+ rLoc = 6185;
+ rType = 0;
+ vrLen = 1438;
+ vrLoc = 5937;
+ };
+ F55BC4C002B2E09101DC9062 = {
+ isa = PBXTargetBookmark;
+ trg = F53755DF016C38D201DC9062;
+ };
+ F55BC4C102B2E09101DC9062 = {
+ fRef = F55BC46A02B2D3F301DC9062;
+ isa = PBXTextBookmark;
+ name = "panedwindow.tcl: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 1395;
+ vrLoc = 0;
+ };
+ F55BC4C202B2E09101DC9062 = {
+ isa = PBXTargetBookmark;
+ trg = F53755DF016C38D201DC9062;
+ };
+ F55BC4C302B2E09101DC9062 = {
+ fRef = F55BC46A02B2D3F301DC9062;
+ isa = PBXTextBookmark;
+ name = "panedwindow.tcl: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 1395;
+ vrLoc = 0;
+ };
+ F55BC4C402B2E09101DC9062 = {
+ isa = PBXTargetBookmark;
+ trg = F53755DF016C38D201DC9062;
+ };
+ F55BC4C702B2E09101DC9062 = {
+ bstl = F537552C016C352C01DC9062;
+ isa = PBXBuildStyleBookmark;
+ };
+ F566083B0197283B01DC9062 = {
+ fileReference = F5375548016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 214;
+ state = 2;
+ };
+ F566083C0197823801DC9062 = {
+ isa = PBXSymbolicBreakpoint;
+ state = 2;
+ symbolName = Tcl_CreateObjCommand;
+ };
+ F571FE470179562E01DC9062 = {
+ fileReference = F5375583016C389901DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 1711;
+ state = 2;
+ };
+ F571FE4A0179695001DC9062 = {
+ fileReference = F5375558016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 175;
+ state = 2;
+ };
+ F571FE4C01796B1101DC9062 = {
+ fileReference = F5375558016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 172;
+ state = 2;
+ };
+ F571FE4D01796CAF01DC9062 = {
+ fileReference = F5375558016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 229;
+ state = 2;
+ };
+ F571FE4E01796F9201DC9062 = {
+ fileReference = F53755C8016C389901DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 408;
+ state = 2;
+ };
+ F571FE4F0179702301DC9062 = {
+ fileReference = F537559A016C389901DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 444;
+ state = 2;
+ };
+ F571FE500179702301DC9062 = {
+ fileReference = F537559A016C389901DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 469;
+ state = 2;
+ };
+ F583DC0E018D092D01DC9062 = {
+ fileReference = F5375551016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 531;
+ state = 2;
+ };
+ F583DC0F018D0CB501DC9062 = {
+ fileReference = F5375551016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 547;
+ state = 2;
+ };
+ F583DC13018D2B4A01DC9062 = {
+ fileReference = F5375551016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 1478;
+ state = 2;
+ };
+ F58907BE018DCE8F01DC9062 = {
+ fileReference = F5375548016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 196;
+ state = 2;
+ };
+ F58907C5018DD1C301DC9062 = {
+ fileReference = F5375551016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 502;
+ state = 2;
+ };
+ F5978FD602B3190701DC9062 = {
+ fileReference = F5375580016C389901DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 224;
+ state = 2;
+ };
+ F5A439C0029B609C01DC9064 = {
+ fileReference = F5375548016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 74;
+ state = 1;
+ };
+ F5A439C2029B60ED01DC9064 = {
+ fileReference = F5375548016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 155;
+ state = 1;
+ };
+ F5A439CA029B620901DC9064 = {
+ fileReference = F5375548016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 306;
+ state = 1;
+ };
+ F5A439D1029B6B5501DC9064 = {
+ fRef = F5A439F3029B6B5601DC9064;
+ isa = PBXTextBookmark;
+ name = "CarbonEvents.h: 4483";
+ rLen = 19;
+ rLoc = 173576;
+ rType = 0;
+ vrLen = 804;
+ vrLoc = 173125;
+ };
+ F5A439D2029B6B5501DC9064 = {
+ fRef = F5375548016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXAppInit.c: Tcl_AppInit";
+ rLen = 0;
+ rLoc = 9908;
+ rType = 0;
+ vrLen = 1370;
+ vrLoc = 8362;
+ };
+ F5A439D3029B6B5501DC9064 = {
+ fRef = F5A439F4029B6B5601DC9064;
+ isa = PBXTextBookmark;
+ name = "MacWindows.h: 1410";
+ rLen = 105;
+ rLoc = 57285;
+ rType = 0;
+ vrLen = 1155;
+ vrLoc = 56795;
+ };
+ F5A439D4029B6B5501DC9064 = {
+ fRef = F5A439F5029B6B5601DC9064;
+ isa = PBXBookmark;
+ };
+ F5A439D5029B6B5501DC9064 = {
+ fRef = F5A439F6029B6B5601DC9064;
+ isa = PBXBookmark;
+ };
+ F5A439D6029B6B5501DC9064 = {
+ fRef = F5A439F7029B6B5601DC9064;
+ isa = PBXBookmark;
+ };
+ F5A439D7029B6B5501DC9064 = {
+ fRef = F5A439F8029B6B5601DC9064;
+ isa = PBXBookmark;
+ };
+ F5A439DA029B6B5501DC9064 = {
+ fRef = F5375553016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXEvent.c: TkMacOSXProcessEvent";
+ rLen = 25;
+ rLoc = 4656;
+ rType = 0;
+ vrLen = 1260;
+ vrLoc = 4407;
+ };
+ F5A439DB029B6B5501DC9064 = {
+ fRef = F537555C016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXMouseEvent.c: TkMacOSXProcessMouseEvent";
+ rLen = 0;
+ rLoc = 6037;
+ rType = 0;
+ vrLen = 1438;
+ vrLoc = 5075;
+ };
+ F5A439DE029B6B5501DC9064 = {
+ fRef = F5375553016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXEvent.c: ReceiveAndProcessEvent";
+ rLen = 0;
+ rLoc = 7098;
+ rType = 0;
+ vrLen = 1455;
+ vrLoc = 5920;
+ };
+ F5A439DF029B6B5501DC9064 = {
+ fRef = F5375548016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXAppInit.c: Tcl_AppInit";
+ rLen = 0;
+ rLoc = 9908;
+ rType = 0;
+ vrLen = 673;
+ vrLoc = 7806;
+ };
+ F5A439E0029B6B5501DC9064 = {
+ fRef = F5375567016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXWm.c: TkMacOSXMakeRealWindowExist";
+ rLen = 15;
+ rLoc = 148454;
+ rType = 0;
+ vrLen = 695;
+ vrLoc = 112860;
+ };
+ F5A439E1029B6B5501DC9064 = {
+ fRef = F5A439FB029B6B5601DC9064;
+ isa = PBXTextBookmark;
+ name = "MacWindows.h: 1410";
+ rLen = 0;
+ rLoc = 57304;
+ rType = 0;
+ vrLen = 659;
+ vrLoc = 56953;
+ };
+ F5A439E2029B6B5501DC9064 = {
+ fRef = F5375548016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXAppInit.c: Tcl_AppInit";
+ rLen = 0;
+ rLoc = 9908;
+ rType = 0;
+ vrLen = 1370;
+ vrLoc = 8362;
+ };
+ F5A439E3029B6B5501DC9064 = {
+ fRef = F5A439EF029B6B5601DC9064;
+ isa = PBXTextBookmark;
+ name = "MacWindows.h: 1410";
+ rLen = 105;
+ rLoc = 57285;
+ rType = 0;
+ vrLen = 1155;
+ vrLoc = 56795;
+ };
+ F5A439E4029B6B5501DC9064 = {
+ fRef = F5A439F1029B6B5601DC9064;
+ isa = PBXBookmark;
+ };
+ F5A439E5029B6B5501DC9064 = {
+ fRef = F5A439FD029B6B5601DC9064;
+ isa = PBXBookmark;
+ };
+ F5A439E6029B6B5501DC9064 = {
+ fRef = F5A439FE029B6B5601DC9064;
+ isa = PBXBookmark;
+ };
+ F5A439E7029B6B5501DC9064 = {
+ fRef = F5A439EE029B6B5601DC9064;
+ isa = PBXBookmark;
+ };
+ F5A439E8029B6B5501DC9064 = {
+ fRef = F5A439F2029B6B5601DC9064;
+ isa = PBXBookmark;
+ };
+ F5A439EE029B6B5601DC9064 = {
+ isa = PBXFileReference;
+ name = Carbon.html;
+ path = /Developer/Documentation/Carbon/Carbon.html;
+ refType = 0;
+ };
+ F5A439EF029B6B5601DC9064 = {
+ isa = PBXFileReference;
+ name = MacWindows.h;
+ path = /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/MacWindows.h;
+ refType = 0;
+ };
+ F5A439F1029B6B5601DC9064 = {
+ isa = PBXFileReference;
+ name = Carbon.html;
+ path = /Developer/Documentation/Carbon/Carbon.html;
+ refType = 0;
+ };
+ F5A439F2029B6B5601DC9064 = {
+ isa = PBXFileReference;
+ name = carboneventmanager.html;
+ path = /Developer/Documentation/Carbon/oss/CarbonEventManager/carboneventmanager.html;
+ refType = 0;
+ };
+ F5A439F3029B6B5601DC9064 = {
+ isa = PBXFileReference;
+ name = CarbonEvents.h;
+ path = /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/CarbonEvents.h;
+ refType = 0;
+ };
+ F5A439F4029B6B5601DC9064 = {
+ isa = PBXFileReference;
+ name = MacWindows.h;
+ path = /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/MacWindows.h;
+ refType = 0;
+ };
+ F5A439F5029B6B5601DC9064 = {
+ isa = PBXFileReference;
+ name = windowmanager.html;
+ path = /Developer/Documentation/Carbon/HumanInterfaceToolbox/WindowManager/windowmanager.html;
+ refType = 0;
+ };
+ F5A439F6029B6B5601DC9064 = {
+ isa = PBXFileReference;
+ name = index.html;
+ path = /Developer/Documentation/Carbon/HumanInterfaceToolbox/WindowManager/Window_Manager/index.html;
+ refType = 0;
+ };
+ F5A439F7029B6B5601DC9064 = {
+ isa = PBXFileReference;
+ name = Carbon.html;
+ path = /Developer/Documentation/Carbon/Carbon.html;
+ refType = 0;
+ };
+ F5A439F8029B6B5601DC9064 = {
+ isa = PBXFileReference;
+ name = carboneventmanager.html;
+ path = /Developer/Documentation/Carbon/oss/CarbonEventManager/carboneventmanager.html;
+ refType = 0;
+ };
+ F5A439FB029B6B5601DC9064 = {
+ isa = PBXFileReference;
+ name = MacWindows.h;
+ path = /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/MacWindows.h;
+ refType = 0;
+ };
+ F5A439FD029B6B5601DC9064 = {
+ isa = PBXFileReference;
+ name = windowmanager.html;
+ path = /Developer/Documentation/Carbon/HumanInterfaceToolbox/WindowManager/windowmanager.html;
+ refType = 0;
+ };
+ F5A439FE029B6B5601DC9064 = {
+ isa = PBXFileReference;
+ name = index.html;
+ path = /Developer/Documentation/Carbon/HumanInterfaceToolbox/WindowManager/Window_Manager/index.html;
+ refType = 0;
+ };
+ F5A5146F01D05DC201DC9062 = {
+ fileReference = F5375550016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 651;
+ state = 1;
+ };
+ F5A5147001D0758C01DC9062 = {
+ fileReference = F5375550016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 838;
+ state = 1;
+ };
+ F5A852D6020F6C6C01DC9062 = {
+ fileReference = F5375550016C376E01DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 277;
+ state = 1;
+ };
+ F5B2CDC10175829501DC9062 = {
+ fileReference = F5375583016C389901DC9062;
+ isa = PBXFileBreakpoint;
+ lineNumber = 2584;
+ state = 2;
+ };
+ F5BE671E029B6FEE01DC9064 = {
+ fRef = F5BE6723029B6FEE01DC9064;
+ isa = PBXBookmark;
+ };
+ F5BE671F029B6FEE01DC9064 = {
+ fRef = F5BE6722029B6FEE01DC9064;
+ isa = PBXBookmark;
+ };
+ F5BE6722029B6FEE01DC9064 = {
+ isa = PBXFileReference;
+ name = index.html;
+ path = /Developer/Documentation/Carbon/oss/CarbonEventManager/Carbon_Event_Manager_Ref/index.html;
+ refType = 0;
+ };
+ F5BE6723029B6FEE01DC9064 = {
+ isa = PBXFileReference;
+ name = index.html;
+ path = /Developer/Documentation/Carbon/oss/CarbonEventManager/Carbon_Event_Manager_Ref/index.html;
+ refType = 0;
+ };
+ F5BFE59402F984FA01DC9062 = {
+ isa = PBXTargetBookmark;
+ trg = F53755DF016C38D201DC9062;
+ };
+ F5BFE59502F984FA01DC9062 = {
+ fRef = F53755BC016C389901DC9062;
+ isa = PBXTextBookmark;
+ name = "tkTest.c: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 1168;
+ vrLoc = 0;
+ };
+ F5BFE59602F984FA01DC9062 = {
+ fRef = F5BFE58C02F8C41501DC9062;
+ isa = PBXTextBookmark;
+ name = "tkUndo.c: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 723;
+ vrLoc = 0;
+ };
+ F5BFE59702F984FA01DC9062 = {
+ fRef = F5BFE58F02F8C45B01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkUndo.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 1028;
+ vrLoc = 0;
+ };
+ F5BFE59802F984FA01DC9062 = {
+ fRef = F5375575016C37A601DC9062;
+ isa = PBXTextBookmark;
+ name = "tkIntDecls.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 959;
+ vrLoc = 52384;
+ };
+ F5BFE59902F984FA01DC9062 = {
+ fRef = F537556A016C37A601DC9062;
+ isa = PBXTextBookmark;
+ name = "ks_names.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 963;
+ vrLoc = 0;
+ };
+ F5BFE59B02F984FA01DC9062 = {
+ fRef = F537559F016C389901DC9062;
+ isa = PBXTextBookmark;
+ name = "tkGet.c: Tk_GetUid";
+ rLen = 50;
+ rLoc = 13445;
+ rType = 0;
+ vrLen = 1360;
+ vrLoc = 12671;
+ };
+ F5BFE59C02F984FA01DC9062 = {
+ fRef = F5375545016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXWm.h: 104";
+ rLen = 6;
+ rLoc = 4294;
+ rType = 0;
+ vrLen = 1558;
+ vrLoc = 8742;
+ };
+ F5BFE59D02F984FA01DC9062 = {
+ fRef = F537556B016C37A601DC9062;
+ isa = PBXTextBookmark;
+ name = "tk.h: 1606";
+ rLen = 0;
+ rLoc = 56812;
+ rType = 0;
+ vrLen = 897;
+ vrLoc = 55983;
+ };
+ F5BFE59E02F984FA01DC9062 = {
+ exec = F53756AB016C4DD401DC9062;
+ isa = PBXExecutableBookmark;
+ };
+ F5BFE59F02F984FA01DC9062 = {
+ fRef = F5BFE5E102F984FA01DC9062;
+ isa = PBXBookmark;
+ };
+ F5BFE5A002F984FA01DC9062 = {
+ fRef = F5BFE5DA02F984FA01DC9062;
+ isa = PBXBookmark;
+ };
+ F5BFE5A102F984FA01DC9062 = {
+ fRef = F5BFE5DC02F984FA01DC9062;
+ isa = PBXBookmark;
+ };
+ F5BFE5A202F984FA01DC9062 = {
+ fRef = F5BFE5DB02F984FA01DC9062;
+ isa = PBXBookmark;
+ };
+ F5BFE5A402F984FA01DC9062 = {
+ fRef = F5BFE5DD02F984FA01DC9062;
+ isa = PBXBookmark;
+ };
+ F5BFE5A502F984FA01DC9062 = {
+ fRef = F5375567016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXWm.c: TkUnsupported1Cmd";
+ rLen = 15;
+ rLoc = 148454;
+ rType = 0;
+ vrLen = 1386;
+ vrLoc = 112609;
+ };
+ F5BFE5A602F984FA01DC9062 = {
+ fRef = F5375568016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXXStubs.c: TkpCloseDisplay";
+ rLen = 0;
+ rLoc = 5311;
+ rType = 0;
+ vrLen = 437;
+ vrLoc = 4370;
+ };
+ F5BFE5A702F984FA01DC9062 = {
+ fRef = F53755C8016C389901DC9062;
+ isa = PBXTextBookmark;
+ name = "tkWindow.c: TkCloseDisplay";
+ rLen = 0;
+ rLoc = 9153;
+ rType = 0;
+ vrLen = 453;
+ vrLoc = 8833;
+ };
+ F5BFE5A802F984FA01DC9062 = {
+ fRef = F537555C016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXMouseEvent.c: TkMacOSXProcessMouseEvent";
+ rLen = 0;
+ rLoc = 6187;
+ rType = 0;
+ vrLen = 742;
+ vrLoc = 11312;
+ };
+ F5BFE5AA02F984FA01DC9062 = {
+ isa = PBXTargetBookmark;
+ trg = F53755DF016C38D201DC9062;
+ };
+ F5BFE5AB02F984FA01DC9062 = {
+ fRef = F53755BC016C389901DC9062;
+ isa = PBXTextBookmark;
+ name = "tkTest.c: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 1168;
+ vrLoc = 0;
+ };
+ F5BFE5AC02F984FA01DC9062 = {
+ fRef = F5BFE58C02F8C41501DC9062;
+ isa = PBXTextBookmark;
+ name = "tkUndo.c: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 723;
+ vrLoc = 0;
+ };
+ F5BFE5AD02F984FA01DC9062 = {
+ fRef = F5BFE58F02F8C45B01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkUndo.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 1028;
+ vrLoc = 0;
+ };
+ F5BFE5AE02F984FA01DC9062 = {
+ fRef = F5375575016C37A601DC9062;
+ isa = PBXTextBookmark;
+ name = "tkIntDecls.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 959;
+ vrLoc = 52384;
+ };
+ F5BFE5AF02F984FA01DC9062 = {
+ fRef = F537556A016C37A601DC9062;
+ isa = PBXTextBookmark;
+ name = "ks_names.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 963;
+ vrLoc = 0;
+ };
+ F5BFE5B002F984FA01DC9062 = {
+ fRef = F537556B016C37A601DC9062;
+ isa = PBXTextBookmark;
+ name = "tk.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 882;
+ vrLoc = 55769;
+ };
+ F5BFE5B202F984FA01DC9062 = {
+ fRef = F537559F016C389901DC9062;
+ isa = PBXTextBookmark;
+ name = "tkGet.c: Tk_GetUid";
+ rLen = 50;
+ rLoc = 13445;
+ rType = 0;
+ vrLen = 1360;
+ vrLoc = 12671;
+ };
+ F5BFE5B302F984FA01DC9062 = {
+ fRef = F5375545016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXWm.h: 104";
+ rLen = 6;
+ rLoc = 4294;
+ rType = 0;
+ vrLen = 1558;
+ vrLoc = 8742;
+ };
+ F5BFE5B402F984FA01DC9062 = {
+ fRef = F537556B016C37A601DC9062;
+ isa = PBXTextBookmark;
+ name = "tk.h: 1606";
+ rLen = 0;
+ rLoc = 56812;
+ rType = 0;
+ vrLen = 897;
+ vrLoc = 55983;
+ };
+ F5BFE5B502F984FA01DC9062 = {
+ exec = F53756AB016C4DD401DC9062;
+ isa = PBXExecutableBookmark;
+ };
+ F5BFE5B702F984FA01DC9062 = {
+ fRef = F5BFE5DF02F984FA01DC9062;
+ isa = PBXBookmark;
+ };
+ F5BFE5B802F984FA01DC9062 = {
+ fRef = F5BFE5D902F984FA01DC9062;
+ isa = PBXBookmark;
+ };
+ F5BFE5B902F984FA01DC9062 = {
+ fRef = F5BFE5E502F984FA01DC9062;
+ isa = PBXBookmark;
+ };
+ F5BFE5BB02F984FA01DC9062 = {
+ fRef = F5BFE5D802F984FA01DC9062;
+ isa = PBXBookmark;
+ };
+ F5BFE5BC02F984FA01DC9062 = {
+ fRef = F5375567016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXWm.c: TkUnsupported1Cmd";
+ rLen = 15;
+ rLoc = 148454;
+ rType = 0;
+ vrLen = 1386;
+ vrLoc = 112609;
+ };
+ F5BFE5BD02F984FA01DC9062 = {
+ fRef = F5375568016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXXStubs.c: 92";
+ rLen = 14;
+ rLoc = 2403;
+ rType = 0;
+ vrLen = 1501;
+ vrLoc = 2945;
+ };
+ F5BFE5BE02F984FA01DC9062 = {
+ fRef = F53755C8016C389901DC9062;
+ isa = PBXTextBookmark;
+ name = "tkWindow.c: DeleteWindowsExitProc";
+ rLen = 0;
+ rLoc = 79080;
+ rType = 0;
+ vrLen = 1549;
+ vrLoc = 78212;
+ };
+ F5BFE5BF02F984FA01DC9062 = {
+ fRef = F5375568016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXXStubs.c: TkpCloseDisplay";
+ rLen = 0;
+ rLoc = 5311;
+ rType = 0;
+ vrLen = 437;
+ vrLoc = 4370;
+ };
+ F5BFE5C002F984FA01DC9062 = {
+ fRef = F53755C8016C389901DC9062;
+ isa = PBXTextBookmark;
+ name = "tkWindow.c: TkCloseDisplay";
+ rLen = 0;
+ rLoc = 9153;
+ rType = 0;
+ vrLen = 453;
+ vrLoc = 8833;
+ };
+ F5BFE5C102F984FA01DC9062 = {
+ fRef = F537555C016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXMouseEvent.c: TkMacOSXProcessMouseEvent";
+ rLen = 0;
+ rLoc = 6187;
+ rType = 0;
+ vrLen = 742;
+ vrLoc = 11312;
+ };
+ F5BFE5C402F984FA01DC9062 = {
+ fRef = F5375568016C376E01DC9062;
+ isa = PBXTextBookmark;
+ name = "tkMacOSXXStubs.c: TkpCloseDisplay";
+ rLen = 0;
+ rLoc = 5311;
+ rType = 0;
+ vrLen = 500;
+ vrLoc = 4894;
+ };
+ F5BFE5D802F984FA01DC9062 = {
+ isa = PBXFileReference;
+ name = README.html;
+ path = /Developer/Documentation/Help/README/README.html;
+ refType = 0;
+ };
+ F5BFE5D902F984FA01DC9062 = {
+ isa = PBXFileReference;
+ name = index.html;
+ path = /Developer/Documentation/ReleaseNotes/index.html;
+ refType = 0;
+ };
+ F5BFE5DA02F984FA01DC9062 = {
+ isa = PBXFileReference;
+ name = devessentials.html;
+ path = /Developer/Documentation/Essentials/devessentials.html;
+ refType = 0;
+ };
+ F5BFE5DB02F984FA01DC9062 = {
+ isa = PBXFileReference;
+ name = index.html;
+ path = /Developer/Documentation/ReleaseNotes/index.html;
+ refType = 0;
+ };
+ F5BFE5DC02F984FA01DC9062 = {
+ isa = PBXFileReference;
+ name = MallocOptions.html;
+ path = /Developer/Documentation/ReleaseNotes/MallocOptions.html;
+ refType = 0;
+ };
+ F5BFE5DD02F984FA01DC9062 = {
+ isa = PBXFileReference;
+ name = README.html;
+ path = /Developer/Documentation/Help/README/README.html;
+ refType = 0;
+ };
+ F5BFE5DF02F984FA01DC9062 = {
+ isa = PBXFileReference;
+ name = devessentials.html;
+ path = /Developer/Documentation/Essentials/devessentials.html;
+ refType = 0;
+ };
+ F5BFE5E102F984FA01DC9062 = {
+ isa = PBXFileReference;
+ name = devtools.html;
+ path = /Developer/Documentation/DeveloperTools/devtools.html;
+ refType = 0;
+ };
+ F5BFE5E502F984FA01DC9062 = {
+ isa = PBXFileReference;
+ name = README.html;
+ path = /Developer/Documentation/Help/README/README.html;
+ refType = 0;
+ };
+}
diff --git a/macosx/Wish.pbproj/project.pbxproj b/macosx/Wish.pbproj/project.pbxproj
new file mode 100644
index 0000000..b3a7b98
--- /dev/null
+++ b/macosx/Wish.pbproj/project.pbxproj
@@ -0,0 +1,3593 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 38;
+ objects = {
+ F50D96120196176E01DC9062 = {
+ isa = PBXFrameworkReference;
+ name = ApplicationServices.framework;
+ path = /System/Library/Frameworks/ApplicationServices.framework;
+ refType = 0;
+ };
+ F50D96130196176E01DC9062 = {
+ fileRef = F50D96120196176E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F50D96140196176E01DC9062 = {
+ fileRef = F50D96120196176E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F51D903E0181474301DC9062 = {
+ fileRef = F5875C7B016FEF1D01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F51D903F018149BD01DC9062 = {
+ buildActionMask = 2147483647;
+ dstPath = "Versions/$(FRAMEWORK_VERSION)/Headers/X11";
+ dstSubfolderSpec = 1;
+ files = (
+ F51D9040018149FD01DC9062,
+ F51D9041018149FD01DC9062,
+ F51D9042018149FD01DC9062,
+ F51D9043018149FD01DC9062,
+ F51D9044018149FD01DC9062,
+ F51D9045018149FD01DC9062,
+ F51D9046018149FD01DC9062,
+ F51D9047018149FD01DC9062,
+ F51D9048018149FD01DC9062,
+ );
+ isa = PBXCopyFilesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F51D9040018149FD01DC9062 = {
+ fileRef = F53755CE016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F51D9041018149FD01DC9062 = {
+ fileRef = F53755CF016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F51D9042018149FD01DC9062 = {
+ fileRef = F53755D0016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F51D9043018149FD01DC9062 = {
+ fileRef = F53755D1016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F51D9044018149FD01DC9062 = {
+ fileRef = F53755D2016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F51D9045018149FD01DC9062 = {
+ fileRef = F53755D3016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F51D9046018149FD01DC9062 = {
+ fileRef = F53755D4016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F51D9047018149FD01DC9062 = {
+ fileRef = F53755D5016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F51D9048018149FD01DC9062 = {
+ fileRef = F53755D6016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F52D38C5031F4259016F146B = {
+ buildActionMask = 2147483647;
+ files = (
+ );
+ generatedFileNames = (
+ );
+ isa = PBXShellScriptBuildPhase;
+ neededFileNames = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "if [ \"${BUILD_STYLE}\" = \"Development\" ]; then\n\t# keep copy of debug library around, so that\n\t# Deployment build can be installed on top\n\t# of Development build without overwriting it\n\tcd \"${TARGET_BUILD_DIR}/${PRODUCT_NAME}.${WRAPPER_EXTENSION}/Versions/${FRAMEWORK_VERSION}\"\n\tcp -fp \"${PRODUCT_NAME}\" \"${PRODUCT_NAME}_debug\"\n\n\t# force Deployment build to be relinked next time\n\tif [ -f \"${OBJROOT}/Deployment.build/${PROJECT_NAME}.build/${TARGET_NAME}.build/Objects-normal/LinkFileList\" ]; then\n\t touch -t `date -r \\`expr \\\\\\`date +\"%s\"\\\\\\` + 30\\` +\"%G%m%d%H%M.%S\"` \"${OBJROOT}/Deployment.build/${PROJECT_NAME}.build/${TARGET_NAME}.build/Objects-normal/LinkFileList\"\n\tfi\nelse\n\t# force Development build to be relinked next time\n\tif [ -f \"${OBJROOT}/Development.build/${PROJECT_NAME}.build/${TARGET_NAME}.build/Objects-normal/LinkFileList\" ]; then\n\t touch -t `date -r \\`expr \\\\\\`date +\"%s\"\\\\\\` + 30\\` +\"%G%m%d%H%M.%S\"` \"${OBJROOT}/Development.build/${PROJECT_NAME}.build/${TARGET_NAME}.build/Objects-normal/LinkFileList\"\n\tfi\nfi";
+ };
+ F537552A016C352C01DC9062 = {
+ buildStyles = (
+ F537552C016C352C01DC9062,
+ F537552D016C352C01DC9062,
+ );
+ isa = PBXProject;
+ mainGroup = F537552B016C352C01DC9062;
+ productRefGroup = F53755DD016C38D201DC9062;
+ projectDirPath = "";
+ targets = (
+ F53756A0016C4DD401DC9062,
+ F53755DF016C38D201DC9062,
+ F548F8CE0313CEF0016F146B,
+ );
+ };
+ F537552B016C352C01DC9062 = {
+ children = (
+ F5C88659017D625C01DC9062,
+ F5DF07A7016CD03801DC9062,
+ F5375688016C3F1001DC9062,
+ F5375531016C376E01DC9062,
+ F537552E016C376E01DC9062,
+ F537553C016C376E01DC9062,
+ F53755C9016C389901DC9062,
+ F53755CC016C389901DC9062,
+ F537567C016C3ADB01DC9062,
+ F53755DD016C38D201DC9062,
+ );
+ isa = PBXGroup;
+ refType = 4;
+ };
+ F537552C016C352C01DC9062 = {
+ buildRules = (
+ );
+ buildSettings = {
+ TEMP_DIR = "${OBJROOT}/Development.build/$(PROJECT_NAME).build/$(TARGET_NAME).build";
+ UNSTRIPPED_PRODUCT = YES;
+ };
+ isa = PBXBuildStyle;
+ name = Development;
+ };
+ F537552D016C352C01DC9062 = {
+ buildRules = (
+ );
+ buildSettings = {
+ DEBUGGING_SYMBOLS = NO;
+ OPTIMIZATION_CFLAGS = "-Os";
+ TEMP_DIR = "${OBJROOT}/Deployment.build/$(PROJECT_NAME).build/$(TARGET_NAME).build";
+ };
+ isa = PBXBuildStyle;
+ name = Deployment;
+ };
+ F537552E016C376E01DC9062 = {
+ children = (
+ F537552F016C376E01DC9062,
+ F5375530016C376E01DC9062,
+ );
+ isa = PBXGroup;
+ name = Generic;
+ refType = 4;
+ };
+ F537552F016C376E01DC9062 = {
+ children = (
+ F5375569016C37A601DC9062,
+ F537556A016C37A601DC9062,
+ F537556B016C37A601DC9062,
+ F537556C016C37A601DC9062,
+ F537556D016C37A601DC9062,
+ F537556E016C37A601DC9062,
+ F537556F016C37A601DC9062,
+ F5375570016C37A601DC9062,
+ F5375571016C37A601DC9062,
+ F5375572016C37A601DC9062,
+ F5375573016C37A601DC9062,
+ F5375574016C37A601DC9062,
+ F5375575016C37A601DC9062,
+ F5375576016C37A601DC9062,
+ F5375577016C37A601DC9062,
+ F5375578016C37A601DC9062,
+ F5375579016C37A601DC9062,
+ F537557A016C37A601DC9062,
+ F537557B016C37A601DC9062,
+ F537557C016C37A601DC9062,
+ F537557D016C37A601DC9062,
+ F537557E016C37A601DC9062,
+ F537557F016C37A601DC9062,
+ F5BFE58F02F8C45B01DC9062,
+ );
+ isa = PBXGroup;
+ name = Headers;
+ refType = 4;
+ };
+ F5375530016C376E01DC9062 = {
+ children = (
+ F5375580016C389901DC9062,
+ F5375581016C389901DC9062,
+ F5375582016C389901DC9062,
+ F5375583016C389901DC9062,
+ F5375584016C389901DC9062,
+ F5375585016C389901DC9062,
+ F5375586016C389901DC9062,
+ F5375587016C389901DC9062,
+ F5375588016C389901DC9062,
+ F5375589016C389901DC9062,
+ F537558A016C389901DC9062,
+ F537558B016C389901DC9062,
+ F537558C016C389901DC9062,
+ F537558D016C389901DC9062,
+ F537558E016C389901DC9062,
+ F537558F016C389901DC9062,
+ F5375590016C389901DC9062,
+ F5375591016C389901DC9062,
+ F5375592016C389901DC9062,
+ F5375593016C389901DC9062,
+ F5375594016C389901DC9062,
+ F5375595016C389901DC9062,
+ F5375596016C389901DC9062,
+ F5375597016C389901DC9062,
+ F5375598016C389901DC9062,
+ F5375599016C389901DC9062,
+ F537559A016C389901DC9062,
+ F537559B016C389901DC9062,
+ F537559C016C389901DC9062,
+ F537559D016C389901DC9062,
+ F537559E016C389901DC9062,
+ F537559F016C389901DC9062,
+ F53755A0016C389901DC9062,
+ F53755A1016C389901DC9062,
+ F53755A2016C389901DC9062,
+ F53755A3016C389901DC9062,
+ F53755A4016C389901DC9062,
+ F53755A5016C389901DC9062,
+ F53755A6016C389901DC9062,
+ F53755A7016C389901DC9062,
+ F53755A8016C389901DC9062,
+ F53755A9016C389901DC9062,
+ F53755AA016C389901DC9062,
+ F53755AB016C389901DC9062,
+ F53755AC016C389901DC9062,
+ F53755AD016C389901DC9062,
+ F53755AE016C389901DC9062,
+ F53755AF016C389901DC9062,
+ F53755B0016C389901DC9062,
+ F53755B1016C389901DC9062,
+ F53755B2016C389901DC9062,
+ F55BC46802B2D38B01DC9062,
+ F53755B3016C389901DC9062,
+ F53755B4016C389901DC9062,
+ F53755B5016C389901DC9062,
+ F53755B6016C389901DC9062,
+ F53755B7016C389901DC9062,
+ F53755B8016C389901DC9062,
+ F53755B9016C389901DC9062,
+ F53755BA016C389901DC9062,
+ F53755BB016C389901DC9062,
+ F5BFE58B02F8C41501DC9062,
+ F53755BC016C389901DC9062,
+ F53755BD016C389901DC9062,
+ F53755BE016C389901DC9062,
+ F53755BF016C389901DC9062,
+ F53755C0016C389901DC9062,
+ F53755C1016C389901DC9062,
+ F53755C2016C389901DC9062,
+ F53755C3016C389901DC9062,
+ F53755C4016C389901DC9062,
+ F53755C5016C389901DC9062,
+ F5BFE58C02F8C41501DC9062,
+ F53755C6016C389901DC9062,
+ F53755C7016C389901DC9062,
+ F53755C8016C389901DC9062,
+ );
+ isa = PBXGroup;
+ name = Source;
+ refType = 4;
+ };
+ F5375531016C376E01DC9062 = {
+ children = (
+ F5375532016C376E01DC9062,
+ F537553B016C376E01DC9062,
+ );
+ isa = PBXGroup;
+ name = Resources;
+ refType = 4;
+ };
+ F5375532016C376E01DC9062 = {
+ children = (
+ F5375533016C376E01DC9062,
+ F5375534016C376E01DC9062,
+ F5375535016C376E01DC9062,
+ F5375536016C376E01DC9062,
+ F5375538016C376E01DC9062,
+ F5375539016C376E01DC9062,
+ F537553A016C376E01DC9062,
+ );
+ isa = PBXGroup;
+ name = "Resource Manager Resources";
+ refType = 4;
+ };
+ F5375533016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkAboutDlg.r;
+ refType = 4;
+ };
+ F5375534016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXApplication.r;
+ refType = 4;
+ };
+ F5375535016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXCursors.r;
+ refType = 4;
+ };
+ F5375536016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXLibrary.r;
+ refType = 4;
+ };
+ F5375538016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXMenu.r;
+ refType = 4;
+ };
+ F5375539016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXResource.r;
+ refType = 4;
+ };
+ F537553A016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXXCursors.r;
+ refType = 4;
+ };
+ F537553B016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = Wish.icns;
+ refType = 4;
+ };
+ F537553C016C376E01DC9062 = {
+ children = (
+ F537553D016C376E01DC9062,
+ F5375546016C376E01DC9062,
+ );
+ isa = PBXGroup;
+ name = "MacOS X";
+ refType = 4;
+ };
+ F537553D016C376E01DC9062 = {
+ children = (
+ F537553E016C376E01DC9062,
+ F537553F016C376E01DC9062,
+ F5375540016C376E01DC9062,
+ F5375541016C376E01DC9062,
+ F5375542016C376E01DC9062,
+ F5375543016C376E01DC9062,
+ F5375544016C376E01DC9062,
+ F5375545016C376E01DC9062,
+ );
+ isa = PBXGroup;
+ name = Headers;
+ refType = 4;
+ };
+ F537553E016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSX.h;
+ refType = 2;
+ };
+ F537553F016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXDebug.h;
+ refType = 2;
+ };
+ F5375540016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXDefault.h;
+ refType = 2;
+ };
+ F5375541016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXEvent.h;
+ refType = 2;
+ };
+ F5375542016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXInt.h;
+ refType = 2;
+ };
+ F5375543016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXPort.h;
+ refType = 2;
+ };
+ F5375544016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXUtil.h;
+ refType = 2;
+ };
+ F5375545016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXWm.h;
+ refType = 2;
+ };
+ F5375546016C376E01DC9062 = {
+ children = (
+ F5375548016C376E01DC9062,
+ F5375549016C376E01DC9062,
+ F537554A016C376E01DC9062,
+ F537554B016C376E01DC9062,
+ F537554C016C376E01DC9062,
+ F537554D016C376E01DC9062,
+ F537554E016C376E01DC9062,
+ F537554F016C376E01DC9062,
+ F5375550016C376E01DC9062,
+ F5375551016C376E01DC9062,
+ F5375552016C376E01DC9062,
+ F5375553016C376E01DC9062,
+ F5375554016C376E01DC9062,
+ F5375555016C376E01DC9062,
+ F5375556016C376E01DC9062,
+ F5375557016C376E01DC9062,
+ F5375558016C376E01DC9062,
+ F5375559016C376E01DC9062,
+ F537555A016C376E01DC9062,
+ F537555B016C376E01DC9062,
+ F537555C016C376E01DC9062,
+ F537555D016C376E01DC9062,
+ F537555E016C376E01DC9062,
+ F5375560016C376E01DC9062,
+ F5375561016C376E01DC9062,
+ F5375562016C376E01DC9062,
+ F5375563016C376E01DC9062,
+ F5375564016C376E01DC9062,
+ F5375565016C376E01DC9062,
+ F5375567016C376E01DC9062,
+ F5375568016C376E01DC9062,
+ );
+ isa = PBXGroup;
+ name = Source;
+ refType = 4;
+ };
+ F5375548016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXAppInit.c;
+ refType = 4;
+ };
+ F5375549016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXBitmap.c;
+ refType = 4;
+ };
+ F537554A016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXButton.c;
+ refType = 4;
+ };
+ F537554B016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXClipboard.c;
+ refType = 4;
+ };
+ F537554C016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXColor.c;
+ refType = 4;
+ };
+ F537554D016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXConfig.c;
+ refType = 4;
+ };
+ F537554E016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXCursor.c;
+ refType = 4;
+ };
+ F537554F016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXDebug.c;
+ refType = 4;
+ };
+ F5375550016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXDialog.c;
+ refType = 4;
+ };
+ F5375551016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXDraw.c;
+ refType = 4;
+ };
+ F5375552016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXEmbed.c;
+ refType = 4;
+ };
+ F5375553016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXEvent.c;
+ refType = 4;
+ };
+ F5375554016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXFont.c;
+ refType = 4;
+ };
+ F5375555016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXHLEvents.c;
+ refType = 4;
+ };
+ F5375556016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXInit.c;
+ refType = 4;
+ };
+ F5375557016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXKeyboard.c;
+ refType = 4;
+ };
+ F5375558016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXKeyEvent.c;
+ refType = 4;
+ };
+ F5375559016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXMenu.c;
+ refType = 4;
+ };
+ F537555A016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXMenubutton.c;
+ refType = 4;
+ };
+ F537555B016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXMenus.c;
+ refType = 4;
+ };
+ F537555C016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXMouseEvent.c;
+ refType = 4;
+ };
+ F537555D016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXNotify.c;
+ refType = 4;
+ };
+ F537555E016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXRegion.c;
+ refType = 4;
+ };
+ F5375560016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXScrlbr.c;
+ refType = 4;
+ };
+ F5375561016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXSend.c;
+ refType = 4;
+ };
+ F5375562016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXSubwindows.c;
+ refType = 4;
+ };
+ F5375563016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXTest.c;
+ refType = 4;
+ };
+ F5375564016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXUtil.c;
+ refType = 4;
+ };
+ F5375565016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXWindowEvent.c;
+ refType = 4;
+ };
+ F5375567016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXWm.c;
+ refType = 4;
+ };
+ F5375568016C376E01DC9062 = {
+ isa = PBXFileReference;
+ path = tkMacOSXXStubs.c;
+ refType = 4;
+ };
+ F5375569016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = default.h;
+ path = ../generic/default.h;
+ refType = 2;
+ };
+ F537556A016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = ks_names.h;
+ path = ../generic/ks_names.h;
+ refType = 2;
+ };
+ F537556B016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tk.h;
+ path = ../generic/tk.h;
+ refType = 2;
+ };
+ F537556C016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tk3d.h;
+ path = ../generic/tk3d.h;
+ refType = 2;
+ };
+ F537556D016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkButton.h;
+ path = ../generic/tkButton.h;
+ refType = 2;
+ };
+ F537556E016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkCanvas.h;
+ path = ../generic/tkCanvas.h;
+ refType = 2;
+ };
+ F537556F016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkColor.h;
+ path = ../generic/tkColor.h;
+ refType = 2;
+ };
+ F5375570016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkDecls.h;
+ path = ../generic/tkDecls.h;
+ refType = 2;
+ };
+ F5375571016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkFileFilter.h;
+ path = ../generic/tkFileFilter.h;
+ refType = 2;
+ };
+ F5375572016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkFont.h;
+ path = ../generic/tkFont.h;
+ refType = 2;
+ };
+ F5375573016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkInitScript.h;
+ path = ../generic/tkInitScript.h;
+ refType = 2;
+ };
+ F5375574016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkInt.h;
+ path = ../generic/tkInt.h;
+ refType = 2;
+ };
+ F5375575016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkIntDecls.h;
+ path = ../generic/tkIntDecls.h;
+ refType = 2;
+ };
+ F5375576016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkIntPlatDecls.h;
+ path = ../generic/tkIntPlatDecls.h;
+ refType = 2;
+ };
+ F5375577016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkIntXlibDecls.h;
+ path = ../generic/tkIntXlibDecls.h;
+ refType = 2;
+ };
+ F5375578016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkMenu.h;
+ path = ../generic/tkMenu.h;
+ refType = 2;
+ };
+ F5375579016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkMenubutton.h;
+ path = ../generic/tkMenubutton.h;
+ refType = 2;
+ };
+ F537557A016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkPlatDecls.h;
+ path = ../generic/tkPlatDecls.h;
+ refType = 2;
+ };
+ F537557B016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkPort.h;
+ path = ../generic/tkPort.h;
+ refType = 2;
+ };
+ F537557C016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkScale.h;
+ path = ../generic/tkScale.h;
+ refType = 2;
+ };
+ F537557D016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkScrollbar.h;
+ path = ../generic/tkScrollbar.h;
+ refType = 2;
+ };
+ F537557E016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkSelect.h;
+ path = ../generic/tkSelect.h;
+ refType = 2;
+ };
+ F537557F016C37A601DC9062 = {
+ isa = PBXFileReference;
+ name = tkText.h;
+ path = ../generic/tkText.h;
+ refType = 2;
+ };
+ F5375580016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tk3d.c;
+ path = ../generic/tk3d.c;
+ refType = 2;
+ };
+ F5375581016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkArgv.c;
+ path = ../generic/tkArgv.c;
+ refType = 2;
+ };
+ F5375582016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkAtom.c;
+ path = ../generic/tkAtom.c;
+ refType = 2;
+ };
+ F5375583016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkBind.c;
+ path = ../generic/tkBind.c;
+ refType = 2;
+ };
+ F5375584016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkBitmap.c;
+ path = ../generic/tkBitmap.c;
+ refType = 2;
+ };
+ F5375585016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkButton.c;
+ path = ../generic/tkButton.c;
+ refType = 2;
+ };
+ F5375586016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkCanvArc.c;
+ path = ../generic/tkCanvArc.c;
+ refType = 2;
+ };
+ F5375587016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkCanvas.c;
+ path = ../generic/tkCanvas.c;
+ refType = 2;
+ };
+ F5375588016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkCanvBmap.c;
+ path = ../generic/tkCanvBmap.c;
+ refType = 2;
+ };
+ F5375589016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkCanvImg.c;
+ path = ../generic/tkCanvImg.c;
+ refType = 2;
+ };
+ F537558A016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkCanvLine.c;
+ path = ../generic/tkCanvLine.c;
+ refType = 2;
+ };
+ F537558B016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkCanvPoly.c;
+ path = ../generic/tkCanvPoly.c;
+ refType = 2;
+ };
+ F537558C016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkCanvPs.c;
+ path = ../generic/tkCanvPs.c;
+ refType = 2;
+ };
+ F537558D016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkCanvText.c;
+ path = ../generic/tkCanvText.c;
+ refType = 2;
+ };
+ F537558E016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkCanvUtil.c;
+ path = ../generic/tkCanvUtil.c;
+ refType = 2;
+ };
+ F537558F016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkCanvWind.c;
+ path = ../generic/tkCanvWind.c;
+ refType = 2;
+ };
+ F5375590016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkClipboard.c;
+ path = ../generic/tkClipboard.c;
+ refType = 2;
+ };
+ F5375591016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkCmds.c;
+ path = ../generic/tkCmds.c;
+ refType = 2;
+ };
+ F5375592016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkColor.c;
+ path = ../generic/tkColor.c;
+ refType = 2;
+ };
+ F5375593016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkConfig.c;
+ path = ../generic/tkConfig.c;
+ refType = 2;
+ };
+ F5375594016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkConsole.c;
+ path = ../generic/tkConsole.c;
+ refType = 2;
+ };
+ F5375595016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkCursor.c;
+ path = ../generic/tkCursor.c;
+ refType = 2;
+ };
+ F5375596016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkEntry.c;
+ path = ../generic/tkEntry.c;
+ refType = 2;
+ };
+ F5375597016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkError.c;
+ path = ../generic/tkError.c;
+ refType = 2;
+ };
+ F5375598016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkEvent.c;
+ path = ../generic/tkEvent.c;
+ refType = 2;
+ };
+ F5375599016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkFileFilter.c;
+ path = ../generic/tkFileFilter.c;
+ refType = 2;
+ };
+ F537559A016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkFocus.c;
+ path = ../generic/tkFocus.c;
+ refType = 2;
+ };
+ F537559B016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkFont.c;
+ path = ../generic/tkFont.c;
+ refType = 2;
+ };
+ F537559C016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkFrame.c;
+ path = ../generic/tkFrame.c;
+ refType = 2;
+ };
+ F537559D016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkGC.c;
+ path = ../generic/tkGC.c;
+ refType = 2;
+ };
+ F537559E016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkGeometry.c;
+ path = ../generic/tkGeometry.c;
+ refType = 2;
+ };
+ F537559F016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkGet.c;
+ path = ../generic/tkGet.c;
+ refType = 2;
+ };
+ F53755A0016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkGrab.c;
+ path = ../generic/tkGrab.c;
+ refType = 2;
+ };
+ F53755A1016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkGrid.c;
+ path = ../generic/tkGrid.c;
+ refType = 2;
+ };
+ F53755A2016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkImage.c;
+ path = ../generic/tkImage.c;
+ refType = 2;
+ };
+ F53755A3016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkImgBmap.c;
+ path = ../generic/tkImgBmap.c;
+ refType = 2;
+ };
+ F53755A4016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkImgGIF.c;
+ path = ../generic/tkImgGIF.c;
+ refType = 2;
+ };
+ F53755A5016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkImgPhoto.c;
+ path = ../generic/tkImgPhoto.c;
+ refType = 2;
+ };
+ F53755A6016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkImgPPM.c;
+ path = ../generic/tkImgPPM.c;
+ refType = 2;
+ };
+ F53755A7016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkImgUtil.c;
+ path = ../generic/tkImgUtil.c;
+ refType = 2;
+ };
+ F53755A8016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkListbox.c;
+ path = ../generic/tkListbox.c;
+ refType = 2;
+ };
+ F53755A9016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkMacWinMenu.c;
+ path = ../generic/tkMacWinMenu.c;
+ refType = 2;
+ };
+ F53755AA016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkMain.c;
+ path = ../generic/tkMain.c;
+ refType = 2;
+ };
+ F53755AB016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkMenu.c;
+ path = ../generic/tkMenu.c;
+ refType = 2;
+ };
+ F53755AC016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkMenubutton.c;
+ path = ../generic/tkMenubutton.c;
+ refType = 2;
+ };
+ F53755AD016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkMenuDraw.c;
+ path = ../generic/tkMenuDraw.c;
+ refType = 2;
+ };
+ F53755AE016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkMessage.c;
+ path = ../generic/tkMessage.c;
+ refType = 2;
+ };
+ F53755AF016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkObj.c;
+ path = ../generic/tkObj.c;
+ refType = 2;
+ };
+ F53755B0016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkOldConfig.c;
+ path = ../generic/tkOldConfig.c;
+ refType = 2;
+ };
+ F53755B1016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkOption.c;
+ path = ../generic/tkOption.c;
+ refType = 2;
+ };
+ F53755B2016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkPack.c;
+ path = ../generic/tkPack.c;
+ refType = 2;
+ };
+ F53755B3016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkPlace.c;
+ path = ../generic/tkPlace.c;
+ refType = 2;
+ };
+ F53755B4016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkPointer.c;
+ path = ../generic/tkPointer.c;
+ refType = 2;
+ };
+ F53755B5016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkRectOval.c;
+ path = ../generic/tkRectOval.c;
+ refType = 2;
+ };
+ F53755B6016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkScale.c;
+ path = ../generic/tkScale.c;
+ refType = 2;
+ };
+ F53755B7016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkScrollbar.c;
+ path = ../generic/tkScrollbar.c;
+ refType = 2;
+ };
+ F53755B8016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkSelect.c;
+ path = ../generic/tkSelect.c;
+ refType = 2;
+ };
+ F53755B9016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkStubImg.c;
+ path = ../generic/tkStubImg.c;
+ refType = 2;
+ };
+ F53755BA016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkStubInit.c;
+ path = ../generic/tkStubInit.c;
+ refType = 2;
+ };
+ F53755BB016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkStubLib.c;
+ path = ../generic/tkStubLib.c;
+ refType = 2;
+ };
+ F53755BC016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkTest.c;
+ path = ../generic/tkTest.c;
+ refType = 2;
+ };
+ F53755BD016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkText.c;
+ path = ../generic/tkText.c;
+ refType = 2;
+ };
+ F53755BE016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkTextBTree.c;
+ path = ../generic/tkTextBTree.c;
+ refType = 2;
+ };
+ F53755BF016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkTextDisp.c;
+ path = ../generic/tkTextDisp.c;
+ refType = 2;
+ };
+ F53755C0016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkTextImage.c;
+ path = ../generic/tkTextImage.c;
+ refType = 2;
+ };
+ F53755C1016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkTextIndex.c;
+ path = ../generic/tkTextIndex.c;
+ refType = 2;
+ };
+ F53755C2016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkTextMark.c;
+ path = ../generic/tkTextMark.c;
+ refType = 2;
+ };
+ F53755C3016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkTextTag.c;
+ path = ../generic/tkTextTag.c;
+ refType = 2;
+ };
+ F53755C4016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkTextWind.c;
+ path = ../generic/tkTextWind.c;
+ refType = 2;
+ };
+ F53755C5016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkTrig.c;
+ path = ../generic/tkTrig.c;
+ refType = 2;
+ };
+ F53755C6016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkUtil.c;
+ path = ../generic/tkUtil.c;
+ refType = 2;
+ };
+ F53755C7016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkVisual.c;
+ path = ../generic/tkVisual.c;
+ refType = 2;
+ };
+ F53755C8016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkWindow.c;
+ path = ../generic/tkWindow.c;
+ refType = 2;
+ };
+ F53755C9016C389901DC9062 = {
+ children = (
+ F53755CA016C389901DC9062,
+ F53755CB016C389901DC9062,
+ );
+ isa = PBXGroup;
+ name = Unix;
+ refType = 4;
+ };
+ F53755CA016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkUnix3d.c;
+ path = ../unix/tkUnix3d.c;
+ refType = 2;
+ };
+ F53755CB016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = tkUnixScale.c;
+ path = ../unix/tkUnixScale.c;
+ refType = 2;
+ };
+ F53755CC016C389901DC9062 = {
+ children = (
+ F53755CD016C389901DC9062,
+ F53755D7016C389901DC9062,
+ );
+ isa = PBXGroup;
+ name = "X Emulation";
+ refType = 4;
+ };
+ F53755CD016C389901DC9062 = {
+ children = (
+ F53755CE016C389901DC9062,
+ F53755CF016C389901DC9062,
+ F53755D0016C389901DC9062,
+ F53755D1016C389901DC9062,
+ F53755D2016C389901DC9062,
+ F53755D3016C389901DC9062,
+ F53755D4016C389901DC9062,
+ F53755D5016C389901DC9062,
+ F53755D6016C389901DC9062,
+ );
+ isa = PBXGroup;
+ name = Headers;
+ refType = 4;
+ };
+ F53755CE016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = xbytes.h;
+ path = ../xlib/xbytes.h;
+ refType = 2;
+ };
+ F53755CF016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = cursorfont.h;
+ path = ../xlib/X11/cursorfont.h;
+ refType = 2;
+ };
+ F53755D0016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = keysym.h;
+ path = ../xlib/X11/keysym.h;
+ refType = 2;
+ };
+ F53755D1016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = keysymdef.h;
+ path = ../xlib/X11/keysymdef.h;
+ refType = 2;
+ };
+ F53755D2016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = X.h;
+ path = ../xlib/X11/X.h;
+ refType = 2;
+ };
+ F53755D3016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = Xatom.h;
+ path = ../xlib/X11/Xatom.h;
+ refType = 2;
+ };
+ F53755D4016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = Xfuncproto.h;
+ path = ../xlib/X11/Xfuncproto.h;
+ refType = 2;
+ };
+ F53755D5016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = Xlib.h;
+ path = ../xlib/X11/Xlib.h;
+ refType = 2;
+ };
+ F53755D6016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = Xutil.h;
+ path = ../xlib/X11/Xutil.h;
+ refType = 2;
+ };
+ F53755D7016C389901DC9062 = {
+ children = (
+ F53755D8016C389901DC9062,
+ F53755D9016C389901DC9062,
+ F53755DA016C389901DC9062,
+ F53755DB016C389901DC9062,
+ F53755DC016C389901DC9062,
+ );
+ isa = PBXGroup;
+ name = Source;
+ refType = 4;
+ };
+ F53755D8016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = xcolors.c;
+ path = ../xlib/xcolors.c;
+ refType = 2;
+ };
+ F53755D9016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = xdraw.c;
+ path = ../xlib/xdraw.c;
+ refType = 2;
+ };
+ F53755DA016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = xgc.c;
+ path = ../xlib/xgc.c;
+ refType = 2;
+ };
+ F53755DB016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = ximage.c;
+ path = ../xlib/ximage.c;
+ refType = 2;
+ };
+ F53755DC016C389901DC9062 = {
+ isa = PBXFileReference;
+ name = xutil.c;
+ path = ../xlib/xutil.c;
+ refType = 2;
+ };
+ F53755DD016C38D201DC9062 = {
+ children = (
+ F53755DE016C38D201DC9062,
+ F537569F016C4DD401DC9062,
+ F548F8CF0313CEF0016F146B,
+ );
+ isa = PBXGroup;
+ name = Products;
+ refType = 4;
+ };
+ F53755DE016C38D201DC9062 = {
+ isa = PBXFrameworkReference;
+ path = Tk.framework;
+ refType = 3;
+ };
+ F53755DF016C38D201DC9062 = {
+ buildPhases = (
+ F5877FB7031F97ED016F146B,
+ F53755E0016C38D201DC9062,
+ F53755E1016C38D301DC9062,
+ F53755E2016C38D301DC9062,
+ F53755E3016C38D301DC9062,
+ F53755E4016C38D301DC9062,
+ F5B1FC08016FFE3501DC9062,
+ F51D903F018149BD01DC9062,
+ F548F8C80313C9E0016F146B,
+ F52D38C5031F4259016F146B,
+ F5877FBC031FA968016F146B,
+ F5C1D51901B88F9A01DC9062,
+ );
+ buildSettings = {
+ DYLIB_COMPATIBILITY_VERSION = 8.4;
+ DYLIB_CURRENT_VERSION = 8.4;
+ FRAMEWORK_SEARCH_PATHS = "\"$(SYMROOT)\"";
+ FRAMEWORK_VERSION = 8.4;
+ GLOBAL_CFLAGS = "`source \"${SYMROOT}/Tcl.framework/Resources/tclConfig.sh\"; echo $${}{TCL_EXTRA_CFLAGS} $${}{TCL_DEFS} | sed -e 's|\\\\\\\\\\\\\\\"|\\\"|g' | sed -e 's| -DTCL_WIDE_INT_TYPE=long. long||'` -U_REENTRANT";
+ HEADER_SEARCH_PATHS = "../../tcl/generic ../../tcl/unix ../bitmaps ../generic ../xlib";
+ INSTALL_PATH = /Library/Frameworks;
+ LIBRARY_SEARCH_PATHS = "";
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "-DMAC_OSX_TK -DTCL_WIDE_INT_TYPE=\"long long\"";
+ OTHER_LDFLAGS = "-seg1addr 0xb000000";
+ OTHER_LIBTOOL_FLAGS = "";
+ OTHER_REZFLAGS = "-i \"../../tcl/generic\" -i \"../generic\"";
+ PRINCIPAL_CLASS = "";
+ PRODUCT_NAME = Tk;
+ SECTORDER_FLAGS = "";
+ TK_MAJOR_VERSION = 8;
+ TK_MINOR_VERSION = 4;
+ TK_PATCH_LEVEL = b3;
+ USE_GCC3_PFE_SUPPORT = NO;
+ WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas -Wno-unused-variable";
+ WRAPPER_EXTENSION = framework;
+ };
+ dependencies = (
+ F548F8D20313CF93016F146B,
+ );
+ isa = PBXFrameworkTarget;
+ name = TkLibrary;
+ productInstallPath = /Library/Frameworks;
+ productName = TkLibrary;
+ productReference = F53755DE016C38D201DC9062;
+ productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>Tk</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Tk Library 8.4b3
+MacOS X Port by Jim Ingham &amp; Ian Reid
+jingham@apple.com
+Copyright Apple Computer, Inc 2001</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.tcltk.tklibrary</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>Tk Library 8.4b3</string>
+ <key>CFBundlePackageType</key>
+ <string>FMWK</string>
+ <key>CFBundleShortVersionString</key>
+ <string>libtk8.4b3</string>
+ <key>CFBundleSignature</key>
+ <string>WiSH</string>
+ <key>CFBundleVersion</key>
+ <string>8.4b3</string>
+</dict>
+</plist>
+";
+ shouldUseHeadermap = 0;
+ };
+ F53755E0016C38D201DC9062 = {
+ buildActionMask = 2147483647;
+ files = (
+ F53755E5016C390401DC9062,
+ F53755E6016C390401DC9062,
+ F53755E7016C390401DC9062,
+ F53755E8016C390401DC9062,
+ F53755E9016C390401DC9062,
+ F53755EA016C390401DC9062,
+ F53755EB016C390401DC9062,
+ F53755EC016C390401DC9062,
+ F53755ED016C390401DC9062,
+ F53755EE016C390401DC9062,
+ F53755EF016C390401DC9062,
+ F53755F0016C390401DC9062,
+ F53755F1016C390401DC9062,
+ F53755F2016C390401DC9062,
+ F53755F3016C390401DC9062,
+ F53755F4016C390401DC9062,
+ F53755F5016C390401DC9062,
+ F53755F6016C390401DC9062,
+ F53755F7016C390401DC9062,
+ F53755F8016C390401DC9062,
+ F53755F9016C390401DC9062,
+ F53755FA016C390401DC9062,
+ F53755FB016C390401DC9062,
+ F53755FC016C397D01DC9062,
+ F53755FD016C397D01DC9062,
+ F53755FE016C397D01DC9062,
+ F53755FF016C397D01DC9062,
+ F5375600016C397D01DC9062,
+ F5375601016C397D01DC9062,
+ F5375602016C397D01DC9062,
+ F5375603016C397D01DC9062,
+ F537566E016C3A1F01DC9062,
+ F537566F016C3A1F01DC9062,
+ F5375670016C3A1F01DC9062,
+ F5375671016C3A1F01DC9062,
+ F5375672016C3A1F01DC9062,
+ F5375673016C3A1F01DC9062,
+ F5375674016C3A1F01DC9062,
+ F5375675016C3A1F01DC9062,
+ F5375676016C3A1F01DC9062,
+ F5375693016C3F1001DC9062,
+ F5375694016C3F1001DC9062,
+ F5375695016C3F1001DC9062,
+ F5375696016C3F1001DC9062,
+ F5375697016C3F1001DC9062,
+ F5375698016C3F1001DC9062,
+ F5375699016C3F1001DC9062,
+ F537569A016C3F1001DC9062,
+ F537569B016C3F1001DC9062,
+ F537569C016C3F1001DC9062,
+ F5BFE59002F8C45B01DC9062,
+ );
+ isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F53755E1016C38D301DC9062 = {
+ buildActionMask = 2147483647;
+ files = (
+ );
+ isa = PBXResourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F53755E2016C38D301DC9062 = {
+ buildActionMask = 2147483647;
+ files = (
+ F5375604016C397D01DC9062,
+ F5375605016C397D01DC9062,
+ F5375606016C397D01DC9062,
+ F5375607016C397D01DC9062,
+ F5375608016C397D01DC9062,
+ F5375609016C397D01DC9062,
+ F537560A016C397D01DC9062,
+ F537560B016C397D01DC9062,
+ F537560C016C397D01DC9062,
+ F537560D016C397D01DC9062,
+ F537560E016C397D01DC9062,
+ F537560F016C397D01DC9062,
+ F5375610016C397D01DC9062,
+ F5375611016C397D01DC9062,
+ F5375612016C397D01DC9062,
+ F5375613016C397D01DC9062,
+ F5375614016C397D01DC9062,
+ F5375615016C397D01DC9062,
+ F5375616016C397D01DC9062,
+ F5375617016C397D01DC9062,
+ F5375618016C397D01DC9062,
+ F5375619016C397D01DC9062,
+ F537561A016C397D01DC9062,
+ F537561B016C397D01DC9062,
+ F537561C016C397D01DC9062,
+ F537561D016C397D01DC9062,
+ F537561E016C397D01DC9062,
+ F537561F016C397D01DC9062,
+ F5375620016C397D01DC9062,
+ F5375621016C397D01DC9062,
+ F5375622016C397D01DC9062,
+ F5375623016C397D01DC9062,
+ F5375624016C397D01DC9062,
+ F5375625016C397D01DC9062,
+ F5375626016C397D01DC9062,
+ F5375627016C397D01DC9062,
+ F5375628016C397D01DC9062,
+ F5375629016C397D01DC9062,
+ F537562A016C397D01DC9062,
+ F537562B016C397D01DC9062,
+ F537562C016C397D01DC9062,
+ F537562D016C397D01DC9062,
+ F537562E016C397D01DC9062,
+ F537562F016C397D01DC9062,
+ F5375630016C397D01DC9062,
+ F5375631016C397D01DC9062,
+ F5375632016C397D01DC9062,
+ F5375633016C397D01DC9062,
+ F5375634016C397D01DC9062,
+ F5375635016C397D01DC9062,
+ F5375636016C397D01DC9062,
+ F5375637016C397D01DC9062,
+ F5375638016C397D01DC9062,
+ F5375639016C397D01DC9062,
+ F537563A016C397D01DC9062,
+ F537563B016C397D01DC9062,
+ F537563C016C397D01DC9062,
+ F537563D016C397D01DC9062,
+ F537563F016C397D01DC9062,
+ F5375640016C397D01DC9062,
+ F5375641016C397D01DC9062,
+ F5375642016C397D01DC9062,
+ F5375643016C397D01DC9062,
+ F5375644016C397D01DC9062,
+ F5375645016C397D01DC9062,
+ F5375646016C397D01DC9062,
+ F5375647016C397D01DC9062,
+ F5375648016C397D01DC9062,
+ F5375649016C397D01DC9062,
+ F537564A016C397D01DC9062,
+ F537564D016C39A101DC9062,
+ F537564E016C39A101DC9062,
+ F537564F016C39A101DC9062,
+ F5375650016C39A101DC9062,
+ F5375651016C39A101DC9062,
+ F5375652016C39A101DC9062,
+ F5375653016C39A101DC9062,
+ F5375654016C39A101DC9062,
+ F5375655016C39A101DC9062,
+ F5375656016C39A101DC9062,
+ F5375657016C39A101DC9062,
+ F5375658016C39A101DC9062,
+ F5375659016C39A101DC9062,
+ F537565A016C39A101DC9062,
+ F537565B016C39A101DC9062,
+ F537565C016C39A101DC9062,
+ F537565D016C39A101DC9062,
+ F537565E016C39A101DC9062,
+ F537565F016C39A101DC9062,
+ F5375660016C39A101DC9062,
+ F5375661016C39A101DC9062,
+ F5375662016C39A101DC9062,
+ F5375664016C39A101DC9062,
+ F5375665016C39A101DC9062,
+ F5375666016C39A101DC9062,
+ F5375667016C39A101DC9062,
+ F5375668016C39A101DC9062,
+ F537566A016C39A101DC9062,
+ F537566B016C39A101DC9062,
+ F537566C016C39F201DC9062,
+ F537566D016C39F201DC9062,
+ F5375677016C3A6D01DC9062,
+ F5375678016C3A6D01DC9062,
+ F5375679016C3A6D01DC9062,
+ F537567A016C3A6D01DC9062,
+ F537567B016C3A6D01DC9062,
+ F537569E016C49C301DC9062,
+ F55BC46902B2D38B01DC9062,
+ F5BFE58D02F8C41501DC9062,
+ F5BFE58E02F8C41501DC9062,
+ );
+ isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F53755E3016C38D301DC9062 = {
+ buildActionMask = 2147483647;
+ files = (
+ F51D903E0181474301DC9062,
+ F537567E016C3ADB01DC9062,
+ F50D96130196176E01DC9062,
+ );
+ isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F53755E4016C38D301DC9062 = {
+ buildActionMask = 2147483647;
+ files = (
+ F537567F016C3ADB01DC9062,
+ F5375680016C3ADB01DC9062,
+ F5375681016C3ADB01DC9062,
+ F5375682016C3ADB01DC9062,
+ );
+ isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F53755E5016C390401DC9062 = {
+ fileRef = F5375569016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755E6016C390401DC9062 = {
+ fileRef = F537556A016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755E7016C390401DC9062 = {
+ fileRef = F537556B016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ Public,
+ );
+ };
+ };
+ F53755E8016C390401DC9062 = {
+ fileRef = F537556C016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755E9016C390401DC9062 = {
+ fileRef = F537556D016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755EA016C390401DC9062 = {
+ fileRef = F537556E016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755EB016C390401DC9062 = {
+ fileRef = F537556F016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755EC016C390401DC9062 = {
+ fileRef = F5375570016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ Public,
+ );
+ };
+ };
+ F53755ED016C390401DC9062 = {
+ fileRef = F5375571016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755EE016C390401DC9062 = {
+ fileRef = F5375572016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755EF016C390401DC9062 = {
+ fileRef = F5375573016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755F0016C390401DC9062 = {
+ fileRef = F5375574016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ Private,
+ );
+ };
+ };
+ F53755F1016C390401DC9062 = {
+ fileRef = F5375575016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ Private,
+ );
+ };
+ };
+ F53755F2016C390401DC9062 = {
+ fileRef = F5375576016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ Private,
+ );
+ };
+ };
+ F53755F3016C390401DC9062 = {
+ fileRef = F5375577016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ Private,
+ );
+ };
+ };
+ F53755F4016C390401DC9062 = {
+ fileRef = F5375578016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755F5016C390401DC9062 = {
+ fileRef = F5375579016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755F6016C390401DC9062 = {
+ fileRef = F537557A016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ Public,
+ );
+ };
+ };
+ F53755F7016C390401DC9062 = {
+ fileRef = F537557B016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755F8016C390401DC9062 = {
+ fileRef = F537557C016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755F9016C390401DC9062 = {
+ fileRef = F537557D016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755FA016C390401DC9062 = {
+ fileRef = F537557E016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755FB016C390401DC9062 = {
+ fileRef = F537557F016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755FC016C397D01DC9062 = {
+ fileRef = F537553E016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ Public,
+ );
+ };
+ };
+ F53755FD016C397D01DC9062 = {
+ fileRef = F537553F016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755FE016C397D01DC9062 = {
+ fileRef = F5375540016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53755FF016C397D01DC9062 = {
+ fileRef = F5375541016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375600016C397D01DC9062 = {
+ fileRef = F5375542016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ Private,
+ );
+ };
+ };
+ F5375601016C397D01DC9062 = {
+ fileRef = F5375543016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375602016C397D01DC9062 = {
+ fileRef = F5375544016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375603016C397D01DC9062 = {
+ fileRef = F5375545016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375604016C397D01DC9062 = {
+ fileRef = F5375580016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375605016C397D01DC9062 = {
+ fileRef = F5375581016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375606016C397D01DC9062 = {
+ fileRef = F5375582016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375607016C397D01DC9062 = {
+ fileRef = F5375583016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375608016C397D01DC9062 = {
+ fileRef = F5375584016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375609016C397D01DC9062 = {
+ fileRef = F5375585016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537560A016C397D01DC9062 = {
+ fileRef = F5375586016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537560B016C397D01DC9062 = {
+ fileRef = F5375587016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537560C016C397D01DC9062 = {
+ fileRef = F5375588016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537560D016C397D01DC9062 = {
+ fileRef = F5375589016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537560E016C397D01DC9062 = {
+ fileRef = F537558A016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537560F016C397D01DC9062 = {
+ fileRef = F537558B016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375610016C397D01DC9062 = {
+ fileRef = F537558C016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375611016C397D01DC9062 = {
+ fileRef = F537558D016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375612016C397D01DC9062 = {
+ fileRef = F537558E016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375613016C397D01DC9062 = {
+ fileRef = F537558F016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375614016C397D01DC9062 = {
+ fileRef = F5375590016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375615016C397D01DC9062 = {
+ fileRef = F5375591016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375616016C397D01DC9062 = {
+ fileRef = F5375592016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375617016C397D01DC9062 = {
+ fileRef = F5375593016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375618016C397D01DC9062 = {
+ fileRef = F5375594016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375619016C397D01DC9062 = {
+ fileRef = F5375595016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537561A016C397D01DC9062 = {
+ fileRef = F5375596016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537561B016C397D01DC9062 = {
+ fileRef = F5375597016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537561C016C397D01DC9062 = {
+ fileRef = F5375598016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537561D016C397D01DC9062 = {
+ fileRef = F5375599016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537561E016C397D01DC9062 = {
+ fileRef = F537559A016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537561F016C397D01DC9062 = {
+ fileRef = F537559B016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375620016C397D01DC9062 = {
+ fileRef = F537559C016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375621016C397D01DC9062 = {
+ fileRef = F537559D016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375622016C397D01DC9062 = {
+ fileRef = F537559E016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375623016C397D01DC9062 = {
+ fileRef = F537559F016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375624016C397D01DC9062 = {
+ fileRef = F53755A0016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375625016C397D01DC9062 = {
+ fileRef = F53755A1016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375626016C397D01DC9062 = {
+ fileRef = F53755A2016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375627016C397D01DC9062 = {
+ fileRef = F53755A3016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375628016C397D01DC9062 = {
+ fileRef = F53755A4016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375629016C397D01DC9062 = {
+ fileRef = F53755A5016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537562A016C397D01DC9062 = {
+ fileRef = F53755A6016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537562B016C397D01DC9062 = {
+ fileRef = F53755A7016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537562C016C397D01DC9062 = {
+ fileRef = F53755A8016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537562D016C397D01DC9062 = {
+ fileRef = F53755A9016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537562E016C397D01DC9062 = {
+ fileRef = F53755AA016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537562F016C397D01DC9062 = {
+ fileRef = F53755AB016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375630016C397D01DC9062 = {
+ fileRef = F53755AC016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375631016C397D01DC9062 = {
+ fileRef = F53755AD016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375632016C397D01DC9062 = {
+ fileRef = F53755AE016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375633016C397D01DC9062 = {
+ fileRef = F53755AF016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375634016C397D01DC9062 = {
+ fileRef = F53755B0016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375635016C397D01DC9062 = {
+ fileRef = F53755B1016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375636016C397D01DC9062 = {
+ fileRef = F53755B2016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375637016C397D01DC9062 = {
+ fileRef = F53755B3016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375638016C397D01DC9062 = {
+ fileRef = F53755B4016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375639016C397D01DC9062 = {
+ fileRef = F53755B5016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537563A016C397D01DC9062 = {
+ fileRef = F53755B6016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537563B016C397D01DC9062 = {
+ fileRef = F53755B7016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537563C016C397D01DC9062 = {
+ fileRef = F53755B8016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537563D016C397D01DC9062 = {
+ fileRef = F53755BA016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537563F016C397D01DC9062 = {
+ fileRef = F53755BD016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375640016C397D01DC9062 = {
+ fileRef = F53755BE016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375641016C397D01DC9062 = {
+ fileRef = F53755BF016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375642016C397D01DC9062 = {
+ fileRef = F53755C0016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375643016C397D01DC9062 = {
+ fileRef = F53755C1016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375644016C397D01DC9062 = {
+ fileRef = F53755C2016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375645016C397D01DC9062 = {
+ fileRef = F53755C3016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375646016C397D01DC9062 = {
+ fileRef = F53755C4016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375647016C397D01DC9062 = {
+ fileRef = F53755C5016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375648016C397D01DC9062 = {
+ fileRef = F53755C6016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375649016C397D01DC9062 = {
+ fileRef = F53755C7016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537564A016C397D01DC9062 = {
+ fileRef = F53755C8016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537564D016C39A101DC9062 = {
+ fileRef = F5375549016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537564E016C39A101DC9062 = {
+ fileRef = F537554A016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537564F016C39A101DC9062 = {
+ fileRef = F537554B016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375650016C39A101DC9062 = {
+ fileRef = F537554C016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375651016C39A101DC9062 = {
+ fileRef = F537554D016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375652016C39A101DC9062 = {
+ fileRef = F537554E016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375653016C39A101DC9062 = {
+ fileRef = F537554F016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375654016C39A101DC9062 = {
+ fileRef = F5375550016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375655016C39A101DC9062 = {
+ fileRef = F5375551016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375656016C39A101DC9062 = {
+ fileRef = F5375552016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375657016C39A101DC9062 = {
+ fileRef = F5375553016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375658016C39A101DC9062 = {
+ fileRef = F5375554016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375659016C39A101DC9062 = {
+ fileRef = F5375555016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537565A016C39A101DC9062 = {
+ fileRef = F5375556016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537565B016C39A101DC9062 = {
+ fileRef = F5375557016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537565C016C39A101DC9062 = {
+ fileRef = F5375558016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537565D016C39A101DC9062 = {
+ fileRef = F5375559016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537565E016C39A101DC9062 = {
+ fileRef = F537555A016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537565F016C39A101DC9062 = {
+ fileRef = F537555B016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375660016C39A101DC9062 = {
+ fileRef = F537555C016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375661016C39A101DC9062 = {
+ fileRef = F537555D016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375662016C39A101DC9062 = {
+ fileRef = F537555E016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375664016C39A101DC9062 = {
+ fileRef = F5375560016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375665016C39A101DC9062 = {
+ fileRef = F5375561016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375666016C39A101DC9062 = {
+ fileRef = F5375562016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375667016C39A101DC9062 = {
+ fileRef = F5375564016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375668016C39A101DC9062 = {
+ fileRef = F5375565016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537566A016C39A101DC9062 = {
+ fileRef = F5375567016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537566B016C39A101DC9062 = {
+ fileRef = F5375568016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537566C016C39F201DC9062 = {
+ fileRef = F53755CA016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537566D016C39F201DC9062 = {
+ fileRef = F53755CB016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537566E016C3A1F01DC9062 = {
+ fileRef = F53755CE016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ );
+ };
+ };
+ F537566F016C3A1F01DC9062 = {
+ fileRef = F53755CF016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ );
+ };
+ };
+ F5375670016C3A1F01DC9062 = {
+ fileRef = F53755D0016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ ATTRIBUTES = (
+ );
+ };
+ };
+ F5375671016C3A1F01DC9062 = {
+ fileRef = F53755D1016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375672016C3A1F01DC9062 = {
+ fileRef = F53755D2016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375673016C3A1F01DC9062 = {
+ fileRef = F53755D3016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375674016C3A1F01DC9062 = {
+ fileRef = F53755D4016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375675016C3A1F01DC9062 = {
+ fileRef = F53755D5016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375676016C3A1F01DC9062 = {
+ fileRef = F53755D6016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375677016C3A6D01DC9062 = {
+ fileRef = F53755D8016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375678016C3A6D01DC9062 = {
+ fileRef = F53755D9016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375679016C3A6D01DC9062 = {
+ fileRef = F53755DA016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537567A016C3A6D01DC9062 = {
+ fileRef = F53755DB016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537567B016C3A6D01DC9062 = {
+ fileRef = F53755DC016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537567C016C3ADB01DC9062 = {
+ children = (
+ F50D96120196176E01DC9062,
+ F5875C7B016FEF1D01DC9062,
+ F537567D016C3ADB01DC9062,
+ );
+ isa = PBXGroup;
+ name = "External Frameworks";
+ refType = 4;
+ };
+ F537567D016C3ADB01DC9062 = {
+ isa = PBXFrameworkReference;
+ name = Carbon.framework;
+ path = /System/Library/Frameworks/Carbon.framework;
+ refType = 0;
+ };
+ F537567E016C3ADB01DC9062 = {
+ fileRef = F537567D016C3ADB01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537567F016C3ADB01DC9062 = {
+ fileRef = F5375533016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375680016C3ADB01DC9062 = {
+ fileRef = F5375535016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375681016C3ADB01DC9062 = {
+ fileRef = F5375538016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375682016C3ADB01DC9062 = {
+ fileRef = F537553A016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375688016C3F1001DC9062 = {
+ children = (
+ F5375689016C3F1001DC9062,
+ F537568A016C3F1001DC9062,
+ F537568B016C3F1001DC9062,
+ F537568C016C3F1001DC9062,
+ F537568D016C3F1001DC9062,
+ F537568E016C3F1001DC9062,
+ F537568F016C3F1001DC9062,
+ F5375690016C3F1001DC9062,
+ F5375691016C3F1001DC9062,
+ F5375692016C3F1001DC9062,
+ );
+ isa = PBXGroup;
+ name = Bitmaps;
+ refType = 4;
+ };
+ F5375689016C3F1001DC9062 = {
+ isa = PBXFileReference;
+ name = error.bmp;
+ path = ../bitmaps/error.bmp;
+ refType = 2;
+ };
+ F537568A016C3F1001DC9062 = {
+ isa = PBXFileReference;
+ name = gray12.bmp;
+ path = ../bitmaps/gray12.bmp;
+ refType = 2;
+ };
+ F537568B016C3F1001DC9062 = {
+ isa = PBXFileReference;
+ name = gray25.bmp;
+ path = ../bitmaps/gray25.bmp;
+ refType = 2;
+ };
+ F537568C016C3F1001DC9062 = {
+ isa = PBXFileReference;
+ name = gray50.bmp;
+ path = ../bitmaps/gray50.bmp;
+ refType = 2;
+ };
+ F537568D016C3F1001DC9062 = {
+ isa = PBXFileReference;
+ name = gray75.bmp;
+ path = ../bitmaps/gray75.bmp;
+ refType = 2;
+ };
+ F537568E016C3F1001DC9062 = {
+ isa = PBXFileReference;
+ name = hourglass.bmp;
+ path = ../bitmaps/hourglass.bmp;
+ refType = 2;
+ };
+ F537568F016C3F1001DC9062 = {
+ isa = PBXFileReference;
+ name = info.bmp;
+ path = ../bitmaps/info.bmp;
+ refType = 2;
+ };
+ F5375690016C3F1001DC9062 = {
+ isa = PBXFileReference;
+ name = questhead.bmp;
+ path = ../bitmaps/questhead.bmp;
+ refType = 2;
+ };
+ F5375691016C3F1001DC9062 = {
+ isa = PBXFileReference;
+ name = question.bmp;
+ path = ../bitmaps/question.bmp;
+ refType = 2;
+ };
+ F5375692016C3F1001DC9062 = {
+ isa = PBXFileReference;
+ name = warning.bmp;
+ path = ../bitmaps/warning.bmp;
+ refType = 2;
+ };
+ F5375693016C3F1001DC9062 = {
+ fileRef = F5375689016C3F1001DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375694016C3F1001DC9062 = {
+ fileRef = F537568A016C3F1001DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375695016C3F1001DC9062 = {
+ fileRef = F537568B016C3F1001DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375696016C3F1001DC9062 = {
+ fileRef = F537568C016C3F1001DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375697016C3F1001DC9062 = {
+ fileRef = F537568D016C3F1001DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375698016C3F1001DC9062 = {
+ fileRef = F537568E016C3F1001DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5375699016C3F1001DC9062 = {
+ fileRef = F537568F016C3F1001DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537569A016C3F1001DC9062 = {
+ fileRef = F5375690016C3F1001DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537569B016C3F1001DC9062 = {
+ fileRef = F5375691016C3F1001DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537569C016C3F1001DC9062 = {
+ fileRef = F5375692016C3F1001DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537569E016C49C301DC9062 = {
+ fileRef = F53755BB016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F537569F016C4DD401DC9062 = {
+ isa = PBXApplicationReference;
+ path = "Wish Shell.app";
+ refType = 3;
+ };
+ F53756A0016C4DD401DC9062 = {
+ buildPhases = (
+ F5877FB8031F982D016F146B,
+ F53756A1016C4DD401DC9062,
+ F53756A2016C4DD401DC9062,
+ F53756A4016C4DD401DC9062,
+ F53756A6016C4DD401DC9062,
+ F53756AA016C4DD401DC9062,
+ F5877FBD031FAC6A016F146B,
+ );
+ buildSettings = {
+ FRAMEWORK_SEARCH_PATHS = "\"$(SYMROOT)\"";
+ GLOBAL_CFLAGS = "`source \"${SYMROOT}/Tcl.framework/Resources/tclConfig.sh\"; echo $${}{TCL_EXTRA_CFLAGS} $${}{TCL_DEFS} | sed -e 's|\\\\\\\\\\\\\\\"|\\\"|g' | sed -e 's| -DTCL_WIDE_INT_TYPE=long. long||'` -U_REENTRANT";
+ HEADER_SEARCH_PATHS = "../../tcl/generic ../../tcl/unix ../generic ../xlib";
+ INSTALL_PATH = /Applications/Utilities;
+ LIBRARY_SEARCH_PATHS = "";
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "-DMAC_OSX_TK -DTCL_WIDE_INT_TYPE=\"long long\"";
+ OTHER_LDFLAGS = "-sectcreate __TEXT __info_plist \"$TEMP_DIR/Info.plist\"";
+ OTHER_REZFLAGS = "-i \"../../tcl/generic\" -i \"../generic\"";
+ PRODUCT_NAME = "Wish Shell";
+ SECTORDER_FLAGS = "";
+ USE_GCC3_PFE_SUPPORT = NO;
+ WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+ WRAPPER_EXTENSION = app;
+ };
+ dependencies = (
+ F53756B2016C525F01DC9062,
+ );
+ isa = PBXApplicationTarget;
+ name = Wish;
+ productInstallPath = /Applications/Utilities;
+ productName = "Wish Shell";
+ productReference = F537569F016C4DD401DC9062;
+ productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>Wish Shell</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Wish Shell 8.4b3
+MacOS X Port by Jim Ingham &amp; Ian Reid
+jingham@apple.com
+Copyright Apple Computer, Inc 2002</string>
+ <key>CFBundleIconFile</key>
+ <string>Wish.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.wish</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>Wish</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>Wish8.4b3</string>
+ <key>CFBundleSignature</key>
+ <string>WiSH</string>
+ <key>CFBundleVersion</key>
+ <string>8.4b3</string>
+</dict>
+</plist>
+";
+ shouldUseHeadermap = 0;
+ };
+ F53756A1016C4DD401DC9062 = {
+ buildActionMask = 2147483647;
+ files = (
+ F53756AC016C4E1D01DC9062,
+ F53756AD016C4E1D01DC9062,
+ F53756AE016C4E1D01DC9062,
+ );
+ isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F53756A2016C4DD401DC9062 = {
+ buildActionMask = 2147483647;
+ files = (
+ F53756A3016C4DD401DC9062,
+ );
+ isa = PBXResourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F53756A3016C4DD401DC9062 = {
+ fileRef = F537553B016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53756A4016C4DD401DC9062 = {
+ buildActionMask = 2147483647;
+ files = (
+ F53756A5016C4DD401DC9062,
+ );
+ isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F53756A5016C4DD401DC9062 = {
+ fileRef = F5375548016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53756A6016C4DD401DC9062 = {
+ buildActionMask = 2147483647;
+ files = (
+ F53756A8016C4DD401DC9062,
+ F5875C7D016FEF1D01DC9062,
+ F53756A7016C4DD401DC9062,
+ F50D96140196176E01DC9062,
+ F5877FB9031F9F49016F146B,
+ );
+ isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F53756A7016C4DD401DC9062 = {
+ fileRef = F53755DE016C38D201DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53756A8016C4DD401DC9062 = {
+ fileRef = F537567D016C3ADB01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53756AA016C4DD401DC9062 = {
+ buildActionMask = 2147483647;
+ files = (
+ );
+ isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F53756AC016C4E1D01DC9062 = {
+ fileRef = F537556B016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53756AD016C4E1D01DC9062 = {
+ fileRef = F5375570016C37A601DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53756AE016C4E1D01DC9062 = {
+ fileRef = F537553E016C376E01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F53756B2016C525F01DC9062 = {
+ isa = PBXTargetDependency;
+ target = F53755DF016C38D201DC9062;
+ };
+ F548F8C80313C9E0016F146B = {
+ buildActionMask = 2147483647;
+ dstPath = "Versions/$(FRAMEWORK_VERSION)";
+ dstSubfolderSpec = 1;
+ files = (
+ F5877FBA031F9F4B016F146B,
+ );
+ isa = PBXCopyFilesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F548F8CA0313CEF0016F146B = {
+ buildActionMask = 2147483647;
+ files = (
+ );
+ isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F548F8CB0313CEF0016F146B = {
+ buildActionMask = 2147483647;
+ files = (
+ F548F8D10313CF14016F146B,
+ F548F8D00313CF11016F146B,
+ );
+ isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F548F8CC0313CEF0016F146B = {
+ buildActionMask = 2147483647;
+ files = (
+ );
+ isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F548F8CD0313CEF0016F146B = {
+ buildActionMask = 2147483647;
+ files = (
+ );
+ isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F548F8CE0313CEF0016F146B = {
+ buildPhases = (
+ F548F8CA0313CEF0016F146B,
+ F548F8CB0313CEF0016F146B,
+ F548F8CC0313CEF0016F146B,
+ F548F8CD0313CEF0016F146B,
+ );
+ buildSettings = {
+ GLOBAL_CFLAGS = "`source \"${SYMROOT}/Tcl.framework/Resources/tclConfig.sh\"; echo $${}{TCL_EXTRA_CFLAGS} $${}{TCL_DEFS} | sed -e 's|\\\\\\\\\\\\\\\"|\\\"|g' | sed -e 's| -DTCL_WIDE_INT_TYPE=long. long||'` -U_REENTRANT";
+ HEADER_SEARCH_PATHS = "../../tcl/generic ../../tcl/unix ../generic ../xlib";
+ LIBRARY_STYLE = STATIC;
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "-DMAC_OSX_TK -DTCL_WIDE_INT_TYPE=\"long long\"";
+ OTHER_LDFLAGS = "";
+ OTHER_LIBTOOL_FLAGS = "";
+ PRODUCT_NAME = libtkstub8.4.a;
+ REZ_EXECUTABLE = YES;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+ };
+ dependencies = (
+ );
+ isa = PBXLibraryTarget;
+ name = TkStubLibrary;
+ productInstallPath = /usr/local/lib;
+ productName = TkStub;
+ productReference = F548F8CF0313CEF0016F146B;
+ shouldUseHeadermap = 0;
+ };
+ F548F8CF0313CEF0016F146B = {
+ isa = PBXLibraryReference;
+ path = libtkstub8.4.a;
+ refType = 3;
+ };
+ F548F8D00313CF11016F146B = {
+ fileRef = F53755B9016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F548F8D10313CF14016F146B = {
+ fileRef = F53755BB016C389901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F548F8D20313CF93016F146B = {
+ isa = PBXTargetDependency;
+ target = F548F8CE0313CEF0016F146B;
+ };
+ F55BC46802B2D38B01DC9062 = {
+ isa = PBXFileReference;
+ name = tkPanedWindow.c;
+ path = ../generic/tkPanedWindow.c;
+ refType = 2;
+ };
+ F55BC46902B2D38B01DC9062 = {
+ fileRef = F55BC46802B2D38B01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F55BC46A02B2D3F301DC9062 = {
+ isa = PBXFileReference;
+ name = panedwindow.tcl;
+ path = ../library/panedwindow.tcl;
+ refType = 2;
+ };
+ F55BC46B02B2D3F301DC9062 = {
+ fileRef = F55BC46A02B2D3F301DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5875C7B016FEF1D01DC9062 = {
+ isa = PBXFrameworkReference;
+ path = Tcl.framework;
+ refType = 3;
+ };
+ F5875C7D016FEF1D01DC9062 = {
+ fileRef = F5875C7B016FEF1D01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5877FB7031F97ED016F146B = {
+ buildActionMask = 8;
+ files = (
+ );
+ generatedFileNames = (
+ );
+ isa = PBXShellScriptBuildPhase;
+ neededFileNames = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ shellPath = /bin/sh;
+ shellScript = "# ensure we can overwrite a previous install\nif [ -d \"${INSTALL_ROOT}${INSTALL_PATH}/${PRODUCT_NAME}.${WRAPPER_EXTENSION}\" ]; then\n chmod -RH u+w \"${INSTALL_ROOT}${INSTALL_PATH}/${PRODUCT_NAME}.${WRAPPER_EXTENSION}\"\nfi";
+ };
+ F5877FB8031F982D016F146B = {
+ buildActionMask = 8;
+ files = (
+ );
+ generatedFileNames = (
+ );
+ isa = PBXShellScriptBuildPhase;
+ neededFileNames = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ shellPath = /bin/sh;
+ shellScript = "# ensure we can overwrite a previous install\nif [ -d \"${INSTALL_ROOT}${INSTALL_PATH}/${PRODUCT_NAME}.${WRAPPER_EXTENSION}\" ]; then\n chmod -RH u+w \"${INSTALL_ROOT}${INSTALL_PATH}/${PRODUCT_NAME}.${WRAPPER_EXTENSION}\"\nfi";
+ };
+ F5877FB9031F9F49016F146B = {
+ fileRef = F548F8CF0313CEF0016F146B;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5877FBA031F9F4B016F146B = {
+ fileRef = F548F8CF0313CEF0016F146B;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5877FBC031FA968016F146B = {
+ buildActionMask = 8;
+ files = (
+ );
+ generatedFileNames = (
+ );
+ isa = PBXShellScriptBuildPhase;
+ neededFileNames = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ shellPath = /bin/sh;
+ shellScript = "# redo prebinding\nif [ ! -d \"${INSTALL_ROOT}/usr/lib\" ]; then ln -fs /usr/lib \"${INSTALL_ROOT}/usr/\"; RM_USRLIB=1; fi\nif [ ! -d \"${INSTALL_ROOT}/System\" ]; then ln -fs /System \"${INSTALL_ROOT}/\"; RM_SYSTEM=1; fi\nredo_prebinding -r \"${INSTALL_ROOT}\" \"${INSTALL_ROOT}${INSTALL_PATH}/${PRODUCT_NAME}.${WRAPPER_EXTENSION}/Versions/${FRAMEWORK_VERSION}/${PRODUCT_NAME}\"\nif [ -n \"${RM_USRLIB:-}\" ]; then rm -f \"${INSTALL_ROOT}/usr/lib\"; fi\nif [ -n \"${RM_SYSTEM:-}\" ]; then rm -f ${INSTALL_ROOT}/System; fi";
+ };
+ F5877FBD031FAC6A016F146B = {
+ buildActionMask = 8;
+ files = (
+ );
+ generatedFileNames = (
+ );
+ isa = PBXShellScriptBuildPhase;
+ neededFileNames = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ shellPath = /bin/sh;
+ shellScript = "# redo prebinding\nif [ ! -d \"${INSTALL_ROOT}/usr/lib\" ]; then ln -fs /usr/lib \"${INSTALL_ROOT}/usr/\"; RM_USRLIB=1; fi\nif [ ! -d \"${INSTALL_ROOT}/System\" ]; then ln -fs /System \"${INSTALL_ROOT}/\"; RM_SYSTEM=1; fi\nredo_prebinding -r \"${INSTALL_ROOT}\" \"${INSTALL_ROOT}${INSTALL_PATH}/${PRODUCT_NAME}.${WRAPPER_EXTENSION}/Contents/MacOS/${PRODUCT_NAME}\"\nif [ -n \"${RM_USRLIB:-}\" ]; then rm -f \"${INSTALL_ROOT}/usr/lib\"; fi\nif [ -n \"${RM_SYSTEM:-}\" ]; then rm -f ${INSTALL_ROOT}/System; fi";
+ };
+ F5B1FC08016FFE3501DC9062 = {
+ buildActionMask = 2147483647;
+ dstPath = "Versions/$(FRAMEWORK_VERSION)/Resources/Scripts";
+ dstSubfolderSpec = 1;
+ files = (
+ F5B1FC09016FFE3501DC9062,
+ F5B1FC0A016FFE3501DC9062,
+ F5B1FC0B016FFE3501DC9062,
+ F5B1FC0C016FFE3501DC9062,
+ F5B1FC0D016FFE3501DC9062,
+ F5B1FC0E016FFE3501DC9062,
+ F5B1FC0F016FFE3501DC9062,
+ F5B1FC10016FFE3501DC9062,
+ F5B1FC11016FFE3501DC9062,
+ F5B1FC12016FFE3501DC9062,
+ F5B1FC13016FFE3501DC9062,
+ F5B1FC14016FFE3501DC9062,
+ F5B1FC15016FFE3501DC9062,
+ F5B1FC16016FFE3501DC9062,
+ F5B1FC17016FFE3501DC9062,
+ F5B1FC18016FFE3501DC9062,
+ F5B1FC19016FFE3501DC9062,
+ F5B1FC1A016FFE3501DC9062,
+ F55BC46B02B2D3F301DC9062,
+ F5B1FC1B016FFE3501DC9062,
+ F5B1FC1C016FFE3501DC9062,
+ F5B1FC1D016FFE3501DC9062,
+ F5B1FC1E016FFE3501DC9062,
+ F5B1FC1F016FFE3501DC9062,
+ F5B1FC20016FFE3501DC9062,
+ F5B1FC21016FFE3501DC9062,
+ F5B1FC22016FFE3501DC9062,
+ F5B1FC23016FFE3501DC9062,
+ F5B1FC24016FFE3501DC9062,
+ F5B1FC25016FFE3501DC9062,
+ F5B1FC26016FFE3501DC9062,
+ );
+ isa = PBXCopyFilesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5B1FC09016FFE3501DC9062 = {
+ fileRef = F5DF0928016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC0A016FFE3501DC9062 = {
+ fileRef = F5DF0929016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC0B016FFE3501DC9062 = {
+ fileRef = F5DF092A016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC0C016FFE3501DC9062 = {
+ fileRef = F5DF092B016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC0D016FFE3501DC9062 = {
+ fileRef = F5DF092C016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC0E016FFE3501DC9062 = {
+ fileRef = F5DF092D016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC0F016FFE3501DC9062 = {
+ fileRef = F5DF092E016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC10016FFE3501DC9062 = {
+ fileRef = F5DF092F016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC11016FFE3501DC9062 = {
+ fileRef = F5DF0930016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC12016FFE3501DC9062 = {
+ fileRef = F5DF0931016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC13016FFE3501DC9062 = {
+ fileRef = F5DF0932016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC14016FFE3501DC9062 = {
+ fileRef = F5DF0933016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC15016FFE3501DC9062 = {
+ fileRef = F5DF0934016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC16016FFE3501DC9062 = {
+ fileRef = F5DF0935016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC17016FFE3501DC9062 = {
+ fileRef = F5DF0936016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC18016FFE3501DC9062 = {
+ fileRef = F5DF0937016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC19016FFE3501DC9062 = {
+ fileRef = F5DF0938016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC1A016FFE3501DC9062 = {
+ fileRef = F5DF0939016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC1B016FFE3501DC9062 = {
+ fileRef = F5DF093A016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC1C016FFE3501DC9062 = {
+ fileRef = F5DF093B016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC1D016FFE3501DC9062 = {
+ fileRef = F5DF093C016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC1E016FFE3501DC9062 = {
+ fileRef = F5DF093D016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC1F016FFE3501DC9062 = {
+ fileRef = F5DF093E016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC20016FFE3501DC9062 = {
+ fileRef = F5DF093F016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC21016FFE3501DC9062 = {
+ fileRef = F5DF0940016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC22016FFE3501DC9062 = {
+ fileRef = F5DF0941016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC23016FFE3501DC9062 = {
+ fileRef = F5DF0942016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC24016FFE3501DC9062 = {
+ fileRef = F5DF0943016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC25016FFE3501DC9062 = {
+ fileRef = F5DF0944016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5B1FC26016FFE3501DC9062 = {
+ fileRef = F5DF0945016CD3F901DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5BFE58B02F8C41501DC9062 = {
+ isa = PBXFileReference;
+ name = tkStyle.c;
+ path = ../generic/tkStyle.c;
+ refType = 2;
+ };
+ F5BFE58C02F8C41501DC9062 = {
+ isa = PBXFileReference;
+ name = tkUndo.c;
+ path = ../generic/tkUndo.c;
+ refType = 2;
+ };
+ F5BFE58D02F8C41501DC9062 = {
+ fileRef = F5BFE58B02F8C41501DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5BFE58E02F8C41501DC9062 = {
+ fileRef = F5BFE58C02F8C41501DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5BFE58F02F8C45B01DC9062 = {
+ isa = PBXFileReference;
+ name = tkUndo.h;
+ path = ../generic/tkUndo.h;
+ refType = 2;
+ };
+ F5BFE59002F8C45B01DC9062 = {
+ fileRef = F5BFE58F02F8C45B01DC9062;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ F5C1D51901B88F9A01DC9062 = {
+ buildActionMask = 8;
+ files = (
+ );
+ generatedFileNames = (
+ );
+ isa = PBXShellScriptBuildPhase;
+ neededFileNames = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ shellPath = /bin/sh;
+ shellScript = "#source buildConfig";
+ };
+ F5C88659017D625C01DC9062 = {
+ children = (
+ F5C8865A017D625C01DC9062,
+ F5C8865B017D625C01DC9062,
+ );
+ isa = PBXGroup;
+ name = "Header Tools";
+ refType = 4;
+ };
+ F5C8865A017D625C01DC9062 = {
+ isa = PBXFileReference;
+ name = tk.decls;
+ path = ../generic/tk.decls;
+ refType = 2;
+ };
+ F5C8865B017D625C01DC9062 = {
+ isa = PBXFileReference;
+ name = tkInt.decls;
+ path = ../generic/tkInt.decls;
+ refType = 2;
+ };
+ F5DF07A7016CD03801DC9062 = {
+ children = (
+ F5DF0928016CD3F901DC9062,
+ F5DF0929016CD3F901DC9062,
+ F5DF092A016CD3F901DC9062,
+ F5DF092B016CD3F901DC9062,
+ F5DF092C016CD3F901DC9062,
+ F5DF092D016CD3F901DC9062,
+ F5DF092E016CD3F901DC9062,
+ F5DF092F016CD3F901DC9062,
+ F5DF0930016CD3F901DC9062,
+ F5DF0931016CD3F901DC9062,
+ F5DF0932016CD3F901DC9062,
+ F5DF0933016CD3F901DC9062,
+ F5DF0934016CD3F901DC9062,
+ F5DF0935016CD3F901DC9062,
+ F5DF0936016CD3F901DC9062,
+ F5DF0937016CD3F901DC9062,
+ F5DF0938016CD3F901DC9062,
+ F5DF0939016CD3F901DC9062,
+ F55BC46A02B2D3F301DC9062,
+ F5DF093A016CD3F901DC9062,
+ F5DF093B016CD3F901DC9062,
+ F5DF093C016CD3F901DC9062,
+ F5DF093D016CD3F901DC9062,
+ F5DF093E016CD3F901DC9062,
+ F5DF093F016CD3F901DC9062,
+ F5DF0940016CD3F901DC9062,
+ F5DF0941016CD3F901DC9062,
+ F5DF0942016CD3F901DC9062,
+ F5DF0943016CD3F901DC9062,
+ F5DF0944016CD3F901DC9062,
+ F5DF0945016CD3F901DC9062,
+ );
+ isa = PBXGroup;
+ name = Scripts;
+ refType = 4;
+ };
+ F5DF0928016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = bgerror.tcl;
+ path = ../library/bgerror.tcl;
+ refType = 2;
+ };
+ F5DF0929016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = button.tcl;
+ path = ../library/button.tcl;
+ refType = 2;
+ };
+ F5DF092A016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = choosedir.tcl;
+ path = ../library/choosedir.tcl;
+ refType = 2;
+ };
+ F5DF092B016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = clrpick.tcl;
+ path = ../library/clrpick.tcl;
+ refType = 2;
+ };
+ F5DF092C016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = comdlg.tcl;
+ path = ../library/comdlg.tcl;
+ refType = 2;
+ };
+ F5DF092D016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = console.tcl;
+ path = ../library/console.tcl;
+ refType = 2;
+ };
+ F5DF092E016CD3F901DC9062 = {
+ includeInIndex = 0;
+ isa = PBXFolderReference;
+ name = demos;
+ path = ../library/demos;
+ refType = 2;
+ };
+ F5DF092F016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = dialog.tcl;
+ path = ../library/dialog.tcl;
+ refType = 2;
+ };
+ F5DF0930016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = entry.tcl;
+ path = ../library/entry.tcl;
+ refType = 2;
+ };
+ F5DF0931016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = focus.tcl;
+ path = ../library/focus.tcl;
+ refType = 2;
+ };
+ F5DF0932016CD3F901DC9062 = {
+ includeInIndex = 0;
+ isa = PBXFolderReference;
+ name = images;
+ path = ../library/images;
+ refType = 2;
+ };
+ F5DF0933016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = listbox.tcl;
+ path = ../library/listbox.tcl;
+ refType = 2;
+ };
+ F5DF0934016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = menu.tcl;
+ path = ../library/menu.tcl;
+ refType = 2;
+ };
+ F5DF0935016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = msgbox.tcl;
+ path = ../library/msgbox.tcl;
+ refType = 2;
+ };
+ F5DF0936016CD3F901DC9062 = {
+ includeInIndex = 0;
+ isa = PBXFolderReference;
+ name = msgs;
+ path = ../library/msgs;
+ refType = 2;
+ };
+ F5DF0937016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = obsolete.tcl;
+ path = ../library/obsolete.tcl;
+ refType = 2;
+ };
+ F5DF0938016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = optMenu.tcl;
+ path = ../library/optMenu.tcl;
+ refType = 2;
+ };
+ F5DF0939016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = palette.tcl;
+ path = ../library/palette.tcl;
+ refType = 2;
+ };
+ F5DF093A016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = prolog.ps;
+ path = ../library/prolog.ps;
+ refType = 2;
+ };
+ F5DF093B016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = safetk.tcl;
+ path = ../library/safetk.tcl;
+ refType = 2;
+ };
+ F5DF093C016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = scale.tcl;
+ path = ../library/scale.tcl;
+ refType = 2;
+ };
+ F5DF093D016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = scrlbar.tcl;
+ path = ../library/scrlbar.tcl;
+ refType = 2;
+ };
+ F5DF093E016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = spinbox.tcl;
+ path = ../library/spinbox.tcl;
+ refType = 2;
+ };
+ F5DF093F016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = tclIndex;
+ path = ../library/tclIndex;
+ refType = 2;
+ };
+ F5DF0940016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = tearoff.tcl;
+ path = ../library/tearoff.tcl;
+ refType = 2;
+ };
+ F5DF0941016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = text.tcl;
+ path = ../library/text.tcl;
+ refType = 2;
+ };
+ F5DF0942016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = tk.tcl;
+ path = ../library/tk.tcl;
+ refType = 2;
+ };
+ F5DF0943016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = tkfbox.tcl;
+ path = ../library/tkfbox.tcl;
+ refType = 2;
+ };
+ F5DF0944016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = unsupported.tcl;
+ path = ../library/unsupported.tcl;
+ refType = 2;
+ };
+ F5DF0945016CD3F901DC9062 = {
+ isa = PBXFileReference;
+ name = xmfbox.tcl;
+ path = ../library/xmfbox.tcl;
+ refType = 2;
+ };
+ };
+ rootObject = F537552A016C352C01DC9062;
+}
diff --git a/macosx/tclets.r b/macosx/tclets.r
new file mode 100644
index 0000000..ce68db4
--- /dev/null
+++ b/macosx/tclets.r
@@ -0,0 +1,172 @@
+/*
+ * tclets.r --
+ *
+ */
+
+/*
+ * New style DLOG templates have an extra field for the positioning
+ * options for the Dialog Box. We will not use this, for now, so we
+ * turn it off here.
+ */
+
+#define DLOG_RezTemplateVersion 0
+
+#include <Types.r>
+#include <SysTypes.r>
+#include <AEUserTermTypes.r>
+
+/*
+ * We now load the Tclets code into the resource fork
+ */
+
+#define TK_LIBRARY_RESOURCES 3000
+
+read 'TEXT' (TK_LIBRARY_RESOURCES+114, "tclshrc", purgeable)
+ "::mac:tclets.tcl";
+
+data 'icns' (-16455) {
+ $"6963 6E73 0000 08F8 6963 7323 0000 0048" /* icns...øics#...H */
+ $"0100 02EE 05CE 09EE 13DE 23FF 47CE 86C6" /* ...î.ÎÆî.Þ#ÿG렮 */
+ $"4681 22C2 12C4 0888 0410 0220 0140 0080" /* F"Â.Ä.ˆ... .@.€ */
+ $"0100 03EE 07CE 0FEE 1FFE 3FFF 7FFE FFFE" /* ...î.Î.î.þ?ÿ.þÿþ */
+ $"7FFF 3FFE 1FFC 0FF8 07F0 03E0 01C0 0080" /* .ÿ?þ.ü.ø.ð.à.À.€ */
+ $"6963 7334 0000 0088 0000 000F 0000 0000" /* ics4...ˆ........ */
+ $"0000 00FC F6D0 FFF0 0000 0FC5 DD00 F6F0" /* ...üöÐÿð...ÅÝ.öð */
+ $"0000 FCCD 66F0 F6F0 000F CC6E 66CE F6F0" /* ..üÍfðöð..ÌnfÎöð */
+ $"00FC CC6E 67EF F6FF 0FCC CD66 66CC F6F0" /* .üÌngïöÿ.ÌÍffÌöð */
+ $"FCCC CDDC 66CC CFA0 0FCC CD6C EDCC CC0F" /* üÌÍÜfÌÏ .ÌÍlíÌÌ. */
+ $"00FC CC6C E6CC CCF0 000F CC6C 66CC CF00" /* .üÌlæÌÌð..ÌlfÌÏ. */
+ $"0000 FCCC 6CCC F000 0000 0FCC DCCF 0000" /* ..üÌlÌð....ÌÜÏ.. */
+ $"0000 00FD DCF0 0000 0000 000F CF00 0000" /* ...ýÜð......Ï... */
+ $"0000 0000 F000 0000 6963 7338 0000 0108" /* ....ð...ics8.... */
+ $"0000 0000 0000 00FF 0000 0000 0000 0000" /* .......ÿ........ */
+ $"0000 0000 0000 FF2B FFEC 7F00 FFFF FF00" /* ......ÿ+ÿì..ÿÿÿ. */
+ $"0000 0000 00FF 2BB0 7F7F 0000 FFEC FF00" /* .....ÿ+°....ÿìÿ. */
+ $"0000 0000 FF2B 2B7F ECEC FF00 FFEC FF00" /* ....ÿ++.ììÿ.ÿìÿ. */
+ $"0000 00FF 2B2B ECFC ECEC 2BFB FFEC FF00" /* ...ÿ++ìüìì+ûÿìÿ. */
+ $"0000 FF2B 2B2B ECFC ECC0 FBFF FFEC FFFF" /* ..ÿ+++ìüìÀûÿÿìÿÿ */
+ $"00FF 2B2B 2B7F ECEC ECEC 2B2B FFEC FF00" /* .ÿ+++.ìììì++ÿìÿ. */
+ $"FF2B 2B2B 2B7F 7FF6 ECEC 2B2B 2BFF FD00" /* ÿ++++..öìì+++ÿý. */
+ $"00FF 2B2B 2B7F ECF6 FCF9 2B2B 2B2B 00FF" /* .ÿ+++.ìöüù++++.ÿ */
+ $"0000 FF2B 2B2B ECF6 FCEC 2B2B 2B2B FF00" /* ..ÿ+++ìöüì++++ÿ. */
+ $"0000 00FF 2B2B ECF6 ECEC 2B2B 2BFF 0000" /* ...ÿ++ìöìì+++ÿ.. */
+ $"0000 0000 FF2B 2BF6 EC2B 2B2B FF00 0000" /* ....ÿ++öì+++ÿ... */
+ $"0000 0000 00FF 2BF6 F92B 2BFF 0000 0000" /* .....ÿ+öù++ÿ.... */
+ $"0000 0000 0000 FFF9 F92B FF00 0000 0000" /* ......ÿùù+ÿ..... */
+ $"0000 0000 0000 00FF 2BFF 0000 0000 0000" /* .......ÿ+ÿ...... */
+ $"0000 0000 0000 0000 FF00 0000 0000 0000" /* ........ÿ....... */
+ $"4943 4E23 0000 0108 0001 0000 0002 8000" /* ICN#..........€. */
+ $"0004 78F8 0008 70F8 0010 F0F8 0021 E8F8" /* ..xø..pø..ðø.!èø */
+ $"0043 C4F8 0081 FAF8 0107 F1F8 0207 F0F8" /* .CÄø.úø..ñø..ðø */
+ $"0407 F7FF 0807 E3FE 1007 E1FC 200E E0F8" /* ..÷ÿ..ãþ..áü .àø */
+ $"4002 E074 800E E022 400E E001 200E C002" /* @.àt€.à"@.à. .À. */
+ $"1006 E004 0806 C008 0406 E010 0202 C020" /* ..à...À...à...À */
+ $"0102 C040 0080 8080 0040 0100 0020 0200" /* ..À@.€€€.@... .. */
+ $"0010 0400 0008 0800 0004 1000 0002 2000" /* .............. . */
+ $"0001 4000 0000 8000 0001 0000 0003 8000" /* ..@...€.......€. */
+ $"0007 F8F8 000F F0F8 001F F0F8 003F F8F8" /* ..øø..ðø..ðø.?øø */
+ $"007F FCF8 00FF FEF8 01FF FFF8 03FF FFF8" /* ..üø.ÿþø.ÿÿø.ÿÿø */
+ $"07FF FFFF 0FFF FFFE 1FFF FFFC 3FFF FFF8" /* .ÿÿÿ.ÿÿþ.ÿÿü?ÿÿø */
+ $"7FFF FFFC FFFF FFFE 7FFF FFFF 3FFF FFFE" /* .ÿÿüÿÿÿþ.ÿÿÿ?ÿÿþ */
+ $"1FFF FFFC 0FFF FFF8 07FF FFF0 03FF FFE0" /* .ÿÿü.ÿÿø.ÿÿð.ÿÿà */
+ $"01FF FFC0 00FF FF80 007F FF00 003F FE00" /* .ÿÿÀ.ÿÿ€..ÿ..?þ. */
+ $"001F FC00 000F F800 0007 F000 0003 E000" /* ..ü...ø...ð...à. */
+ $"0001 C000 0000 8000 6963 6C34 0000 0208" /* ..À...€.icl4.... */
+ $"0000 0000 0000 000F 0000 0000 0000 0000" /* ................ */
+ $"0000 0000 0000 00FC F000 0000 0000 0000" /* .......üð....... */
+ $"0000 0000 0000 0FCC CFD6 D000 FFFF F000" /* .......ÌÏÖÐ.ÿÿð. */
+ $"0000 0000 0000 FCCC C556 0000 F767 F000" /* ......üÌÅV..÷gð. */
+ $"0000 0000 000F CCCC 566F 0000 F676 F000" /* ......ÌÌVo..övð. */
+ $"0000 0000 00FC CCC5 6F5C F000 F767 F000" /* .....üÌÅo\ð.÷gð. */
+ $"0000 0000 0FCC CC66 66CC 0F00 F676 F000" /* .....ÌÌffÌ..övð. */
+ $"0000 0000 FCCC CCD5 5666 FCF0 F767 F000" /* ....üÌÌÕVfüð÷gð. */
+ $"0000 000F CCCC C656 5667 CCCF F676 F000" /* ....ÌÌÆVVgÌÏövð. */
+ $"0000 00FC CCCC C6E5 5566 CCCC F767 F000" /* ...üÌÌÆåUfÌÌ÷gð. */
+ $"0000 0FCC CCCC C656 5657 CFFF F676 FFFF" /* ...ÌÌÌÆVVWÏÿövÿÿ */
+ $"0000 FCCC CCCC C6E5 565C CCF7 6767 67F0" /* ..üÌÌÌÆåV\Ì÷gggð */
+ $"000F CCCC CCCC C655 565C CCCF 7676 7F00" /* ..ÌÌÌÌÆUV\ÌÏvv.. */
+ $"00FC CCCC CCCC 7660 556C CCCC F767 F000" /* .üÌÌÌÌv`UlÌÌ÷gð. */
+ $"0FCC CCCC CCCC CD5D 567C CCCC CF7F CF00" /* .ÌÌÌÌÌÍ]V|ÌÌÏ.Ï. */
+ $"FCCC CCCC CCCC 6660 556C CCCC CCFC CCF0" /* üÌÌÌÌÌf`UlÌÌÌüÌð */
+ $"0FCC CCCC CCCC 665C 565C CCCC CCCC CCCF" /* .ÌÌÌÌÌf\V\ÌÌÌÌÌÏ */
+ $"00FC CCCC CCCC 6660 E6DC CCCC CCCC CCF0" /* .üÌÌÌÌf`æÜÌÌÌÌÌð */
+ $"000F CCCC CCCC C650 656C CCCC CCCC CF00" /* ..ÌÌÌÌÆPelÌÌÌÌÏ. */
+ $"0000 FCCC CCCC C6EC 5ECC CCCC CCCC F000" /* ..üÌÌÌÆì^ÌÌÌÌÌð. */
+ $"0000 0FCC CCCC C650 566C CCCC CCCF 0000" /* ...ÌÌÌÆPVlÌÌÌÏ.. */
+ $"0000 00FC CCCC CC50 D5CC CCCC CCF0 0000" /* ...üÌÌÌPÕÌÌÌÌð.. */
+ $"0000 000F CCCC CC50 56CC CCCC CF00 0000" /* ....ÌÌÌPVÌÌÌÏ... */
+ $"0000 0000 FCCC CCD0 5CCC CCCC F000 0000" /* ....üÌÌÐ\ÌÌÌð... */
+ $"0000 0000 0FCC CCD0 DCCC CCCF 0000 0000" /* .....ÌÌÐÜÌÌÏ.... */
+ $"0000 0000 00FC CCD0 DCCC CCF0 0000 0000" /* .....üÌÐÜÌÌð.... */
+ $"0000 0000 000F CCD0 DCCC CF00 0000 0000" /* ......ÌÐÜÌÏ..... */
+ $"0000 0000 0000 FCC0 CCCC F000 0000 0000" /* ......üÀÌÌð..... */
+ $"0000 0000 0000 0FCD CCCF 0000 0000 0000" /* .......ÍÌÏ...... */
+ $"0000 0000 0000 00FC CCF0 0000 0000 0000" /* .......üÌð...... */
+ $"0000 0000 0000 000F CF00 0000 0000 0000" /* ........Ï....... */
+ $"0000 0000 0000 0000 F000 0000 0000 0000" /* ........ð....... */
+ $"6963 6C38 0000 0408 0000 0000 0000 0000" /* icl8............ */
+ $"0000 0000 0000 00FF 0000 0000 0000 0000" /* .......ÿ........ */
+ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */
+ $"0000 0000 0000 FF2B FF00 0000 0000 0000" /* ......ÿ+ÿ....... */
+ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */
+ $"0000 0000 00FF 2B2B 2BFF 7FEC 7F00 0000" /* .....ÿ+++ÿ.ì.... */
+ $"FFFF FFFF FF00 0000 0000 0000 0000 0000" /* ÿÿÿÿÿ........... */
+ $"0000 0000 FF2B 2B2B 2BB0 B0EC 0000 0000" /* ....ÿ++++°°ì.... */
+ $"FFC0 ECC0 FF00 0000 0000 0000 0000 0000" /* ÿÀìÀÿ........... */
+ $"0000 00FF 2B2B 2B2B B0EC ECFF 0000 0000" /* ...ÿ++++°ììÿ.... */
+ $"FFEC C0EC FF00 0000 0000 0000 0000 0000" /* ÿìÀìÿ........... */
+ $"0000 FF2B 2B2B 2BB0 ECFF B02B FF00 0000" /* ..ÿ++++°ìÿ°+ÿ... */
+ $"FFC0 ECC0 FF00 0000 0000 0000 0000 0000" /* ÿÀìÀÿ........... */
+ $"00FF 2B2B 2B2B ECEC ECEC 2B2B 00FF 0000" /* .ÿ++++ìììì++.ÿ.. */
+ $"FFEC C0EC FF00 0000 0000 0000 0000 0000" /* ÿìÀìÿ........... */
+ $"FF2B 2B2B 2B2B F9B0 B0EC ECEC FF2B FF00" /* ÿ+++++ù°°ìììÿ+ÿ. */
+ $"FFC0 ECC0 FF00 0000 0000 0000 0000 00FF" /* ÿÀìÀÿ..........ÿ */
+ $"2B2B 2B2B 2BEC B0EC B0EC ECC0 2B2B 2BFF" /* +++++ì°ì°ììÀ+++ÿ */
+ $"FFEC C0EC FF00 0000 0000 0000 0000 FF2B" /* ÿìÀìÿ.........ÿ+ */
+ $"2B2B 2B2B 2BEC FCB0 B0B0 ECEC 2B2B 2B2B" /* +++++ìü°°°ìì++++ */
+ $"FFC0 ECC0 FF00 0000 0000 0000 00FF 2B2B" /* ÿÀìÀÿ........ÿ++ */
+ $"2B2B 2B2B 2BEC B0EC B0EC B0C0 2BFF FFFF" /* +++++ì°ì°ì°À+ÿÿÿ */
+ $"FFEC C0EC FFFF FFFF 0000 0000 FF2B 2B2B" /* ÿìÀìÿÿÿÿ....ÿ+++ */
+ $"2B2B 2B2B 2BEC FCB0 B0EC B02B 2B2B FFC0" /* +++++ìü°°ì°+++ÿÀ */
+ $"ECC0 ECC0 ECC0 FF00 0000 00FF 2B2B 2B2B" /* ìÀìÀìÀÿ....ÿ++++ */
+ $"2B2B 2B2B 2BEC B0B0 B0EC B02B 2B2B 2BFF" /* +++++ì°°°ì°++++ÿ */
+ $"C0EC C0EC C0FF 0000 0000 FF2B 2B2B 2B2B" /* ÀìÀìÀÿ....ÿ+++++ */
+ $"2B2B 2B2B C0EC EC00 B0B0 EC2B 2B2B 2B2B" /* ++++Àìì.°°ì+++++ */
+ $"FFC0 ECC0 FF00 0000 00FF 2B2B 2B2B 2B2B" /* ÿÀìÀÿ....ÿ++++++ */
+ $"2B2B 2B2B 2BF9 B0F9 B0EC C02B 2B2B 2B2B" /* +++++ù°ù°ìÀ+++++ */
+ $"2BFF C0FF 2BFF 0000 FF2B 2B2B 2B2B 2B2B" /* +ÿÀÿ+ÿ..ÿ+++++++ */
+ $"2B2B 2B2B ECEC EC00 B0B0 EC2B 2B2B 2B2B" /* ++++ììì.°°ì+++++ */
+ $"2B2B FF2B 2B2B FF00 00FF 2B2B 2B2B 2B2B" /* ++ÿ+++ÿ..ÿ++++++ */
+ $"2B2B 2B2B ECEC B02B B0EC B02B 2B2B 2B2B" /* ++++ìì°+°ì°+++++ */
+ $"2B2B 2B2B 2B2B 2BFF 0000 FF2B 2B2B 2B2B" /* +++++++ÿ..ÿ+++++ */
+ $"2B2B 2B2B ECEC EC00 FCEC F92B 2B2B 2B2B" /* ++++ììì.üìù+++++ */
+ $"2B2B 2B2B 2B2B FF00 0000 00FF 2B2B 2B2B" /* ++++++ÿ....ÿ++++ */
+ $"2B2B 2B2B 2BEC B000 ECB0 EC2B 2B2B 2B2B" /* +++++ì°.ì°ì+++++ */
+ $"2B2B 2B2B 2BFF 0000 0000 0000 FF2B 2B2B" /* +++++ÿ......ÿ+++ */
+ $"2B2B 2B2B 2BEC FC2B B0FC 2B2B 2B2B 2B2B" /* +++++ìü+°ü++++++ */
+ $"2B2B 2B2B FF00 0000 0000 0000 00FF 2B2B" /* ++++ÿ........ÿ++ */
+ $"2B2B 2B2B 2BEC B000 B0EC EC2B 2B2B 2B2B" /* +++++ì°.°ìì+++++ */
+ $"2B2B 2BFF 0000 0000 0000 0000 0000 FF2B" /* +++ÿ..........ÿ+ */
+ $"2B2B 2B2B 2B2B B000 7FB0 2B2B 2B2B 2B2B" /* ++++++°..°++++++ */
+ $"2B2B FF00 0000 0000 0000 0000 0000 00FF" /* ++ÿ............ÿ */
+ $"2B2B 2B2B 2B2B B000 B0EC 2B2B 2B2B 2B2B" /* ++++++°.°ì++++++ */
+ $"2BFF 0000 0000 0000 0000 0000 0000 0000" /* +ÿ.............. */
+ $"FF2B 2B2B 2B2B F900 B02B 2B2B 2B2B 2B2B" /* ÿ+++++ù.°+++++++ */
+ $"FF00 0000 0000 0000 0000 0000 0000 0000" /* ÿ............... */
+ $"00FF 2B2B 2B2B F900 F92B 2B2B 2B2B 2BFF" /* .ÿ++++ù.ù++++++ÿ */
+ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */
+ $"0000 FF2B 2B2B F900 F92B 2B2B 2B2B FF00" /* ..ÿ+++ù.ù+++++ÿ. */
+ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */
+ $"0000 00FF 2B2B F900 F92B 2B2B 2BFF 0000" /* ...ÿ++ù.ù++++ÿ.. */
+ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */
+ $"0000 0000 FF2B 2B00 2B2B 2B2B FF00 0000" /* ....ÿ++.++++ÿ... */
+ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */
+ $"0000 0000 00FF 2BF9 2B2B 2BFF 0000 0000" /* .....ÿ+ù+++ÿ.... */
+ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */
+ $"0000 0000 0000 FF2B 2B2B FF00 0000 0000" /* ......ÿ+++ÿ..... */
+ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */
+ $"0000 0000 0000 00FF 2BFF 0000 0000 0000" /* .......ÿ+ÿ...... */
+ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */
+ $"0000 0000 0000 0000 FF00 0000 0000 0000" /* ........ÿ....... */
+ $"0000 0000 0000 0000" /* ........ */
+};
diff --git a/macosx/tkAboutDlg.r b/macosx/tkAboutDlg.r
new file mode 100644
index 0000000..13f0679
--- /dev/null
+++ b/macosx/tkAboutDlg.r
@@ -0,0 +1,393 @@
+/*
+ * 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.
+ *
+ * Copyright (c) 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: tkAboutDlg.r,v 1.2 2002/08/31 06:12:29 das Exp $
+ */
+
+
+
+/*
+ * New style DLOG templates have an extra field for the positioning
+ * options for the Dialog Box. We will not use this, for now, so we
+ * turn it off here.
+ */
+
+#define DLOG_RezTemplateVersion 0
+
+/*
+ * The folowing include and defines help construct
+ * the version string for Tcl.
+ */
+
+#define RESOURCE_INCLUDED
+#include <Carbon.r>
+#include <tcl.h>
+#include "tk.h"
+
+#if (TK_RELEASE_LEVEL == 0)
+# define RELEASE_LEVEL alpha
+#elif (TK_RELEASE_LEVEL == 1)
+# define RELEASE_LEVEL beta
+#elif (TK_RELEASE_LEVEL == 2)
+# define RELEASE_LEVEL final
+#endif
+
+#if (TK_RELEASE_LEVEL == 2)
+# define MINOR_VERSION (TK_MINOR_VERSION * 16) + TK_RELEASE_SERIAL
+#else
+# define MINOR_VERSION TK_MINOR_VERSION * 16
+#endif
+
+#define RELEASE_CODE 0x00
+
+/*
+ * 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
+ * default dialog will not be shown and the Tcl procedure is expected to
+ * create and manage an About Dialog box.
+ */
+
+data 'DLOG' (128, "Default About Box", purgeable) {
+ $"0055 006B 00F3 0196 0001 0100 0100 0000"
+ $"0000 0081 0000 280A"
+};
+
+resource 'DITL' (129, "About Box", purgeable) {
+ {
+ {128, 128, 148, 186}, Button {enabled, "Ok"},
+ { 14, 108, 117, 298}, StaticText {disabled,
+ "Wish - Windowing Shell" "\n" "based on Tcl "
+ TCL_PATCH_LEVEL " & Tk " TK_PATCH_LEVEL "\n\n" "Jim Ingham & Ray Johnson"
+ "Scriptics Inc." "\n" "jingham@cygnus.com"},
+ { 11, 24, 111, 92}, Picture {enabled, 128}
+ }
+};
+
+data 'PICT' (128, purgeable) {
+ $"13A4 0000 0000 0064 0044 0011 02FF 0C00"
+ $"FFFE 0000 0048 0000 0048 0000 0000 0000"
+ $"0064 0044 0000 0000 0001 000A 0000 0000"
+ $"0064 0044 0099 8044 0000 0000 0064 0044"
+ $"0000 0000 0000 0000 0048 0000 0048 0000"
+ $"0000 0008 0001 0008 0000 0000 0108 00D8"
+ $"0000 0000 0001 5A5A 8000 00FF 3736 FF00"
+ $"FF00 FF00 3535 FF00 FF00 CC00 3434 FF00"
+ $"FF00 9900 3333 FF00 FF00 6600 3736 FF00"
+ $"FF00 3300 3535 FF00 FF00 0000 3434 FF00"
+ $"CC00 FF00 3333 FF00 CC00 CC00 3736 FF00"
+ $"CC00 9900 3535 FF00 CC00 6600 FAFA FF00"
+ $"CC00 3300 3333 FF00 CC00 0000 3130 FF00"
+ $"9900 FF00 2F2F FF00 9900 CC00 FAFA FF00"
+ $"9900 9900 F9F9 FF00 9900 6600 3130 FF00"
+ $"9900 3300 2F2F FF00 9900 0000 2E2E FF00"
+ $"6600 FF00 F9F9 FF00 6600 CC00 3130 FF00"
+ $"6600 9900 2F2F FF00 6600 6600 2E2E FF00"
+ $"6600 3300 2D2D FF00 6600 0000 3130 FF00"
+ $"3300 FF00 2F2F FF00 3300 CC00 2E2E FF00"
+ $"3300 9900 2D2D FF00 3300 6600 3130 FF00"
+ $"3300 3300 2F2F FF00 3300 0000 2E2E FF00"
+ $"0000 FF00 2D2D FF00 0000 CC00 3130 FF00"
+ $"0000 9900 2F2F FF00 0000 6600 2E2E FF00"
+ $"0000 3300 2DF8 FF00 0000 0000 2B2A CC00"
+ $"FF00 FF00 2929 CC00 FF00 CC00 2828 CC00"
+ $"FF00 9900 27F8 CC00 FF00 6600 2B2A CC00"
+ $"FF00 3300 2929 CC00 FF00 0000 2828 CC00"
+ $"CC00 FF00 2727 CC00 CC00 CC00 2B2A CC00"
+ $"CC00 9900 2929 CC00 CC00 6600 2828 CC00"
+ $"CC00 3300 2727 CC00 CC00 0000 2B2A CC00"
+ $"9900 FF00 2929 CC00 9900 CC00 2828 CC00"
+ $"9900 9900 2727 CC00 9900 6600 DBDB CC00"
+ $"9900 3300 4747 CC00 9900 0000 4646 CC00"
+ $"6600 FF00 4545 CC00 6600 CC00 DBDB CC00"
+ $"6600 9900 4747 CC00 6600 6600 4646 CC00"
+ $"6600 3300 4545 CC00 6600 0000 DBDB CC00"
+ $"3300 FF00 4747 CC00 3300 CC00 4646 CC00"
+ $"3300 9900 4545 CC00 3300 6600 DBDB CC00"
+ $"3300 3300 4141 CC00 3300 0000 4040 CC00"
+ $"0000 FF00 3F3F CC00 0000 CC00 4342 CC00"
+ $"0000 9900 4141 CC00 0000 6600 4040 CC00"
+ $"0000 3300 3F3F CC00 0000 0000 4342 9900"
+ $"FF00 FF00 4141 9900 FF00 CC00 4040 9900"
+ $"FF00 9900 3F3F 9900 FF00 6600 4342 9900"
+ $"FF00 3300 4141 9900 FF00 0000 4040 9900"
+ $"CC00 FF00 3F3F 9900 CC00 CC00 4342 9900"
+ $"CC00 9900 4141 9900 CC00 6600 4040 9900"
+ $"CC00 3300 3F3F 9900 CC00 0000 4342 9900"
+ $"9900 FF00 4141 9900 9900 CC00 4040 9900"
+ $"9900 9900 3F3F 9900 9900 6600 3D3C 9900"
+ $"9900 3300 3B3B 9900 9900 0000 3A3A 9900"
+ $"6600 FF00 3939 9900 6600 CC00 3D3C 9900"
+ $"6600 9900 3B3B 9900 6600 6600 3A3A 9900"
+ $"6600 3300 3939 9900 6600 0000 3D3C 9900"
+ $"3300 FF00 3B3B 9900 3300 CC00 3A3A 9900"
+ $"3300 9900 3939 9900 3300 6600 3D3C 9900"
+ $"3300 3300 3B3B 9900 3300 0000 3A3A 9900"
+ $"0000 FF00 3939 9900 0000 CC00 3D3C 9900"
+ $"0000 9900 3B3B 9900 0000 6600 3A3A 9900"
+ $"0000 3300 3939 9900 0000 0000 3D3C 6600"
+ $"FF00 FF00 3B3B 6600 FF00 CC00 3A3A 6600"
+ $"FF00 9900 3939 6600 FF00 6600 3D3C 6600"
+ $"FF00 3300 3B3B 6600 FF00 0000 3A3A 6600"
+ $"CC00 FF00 3939 6600 CC00 CC00 3736 6600"
+ $"CC00 9900 3535 6600 CC00 6600 3434 6600"
+ $"CC00 3300 3333 6600 CC00 0000 3736 6600"
+ $"9900 FF00 3535 6600 9900 CC00 3434 6600"
+ $"9900 9900 3333 6600 9900 6600 3736 6600"
+ $"9900 3300 3535 6600 9900 0000 3434 6600"
+ $"6600 FF00 3333 6600 6600 CC00 3736 6600"
+ $"6600 9900 3535 6600 6600 6600 3434 6600"
+ $"6600 3300 3333 6600 6600 0000 3736 6600"
+ $"3300 FF00 3535 6600 3300 CC00 3434 6600"
+ $"3300 9900 3333 6600 3300 6600 3736 6600"
+ $"3300 3300 3535 6600 3300 0000 3434 6600"
+ $"0000 FF00 3333 6600 0000 CC00 3130 6600"
+ $"0000 9900 2F2F 6600 0000 6600 2E2E 6600"
+ $"0000 3300 F9F9 6600 0000 0000 3130 3300"
+ $"FF00 FF00 2F2F 3300 FF00 CC00 2E2E 3300"
+ $"FF00 9900 F9F9 3300 FF00 6600 3130 3300"
+ $"FF00 3300 2F2F 3300 FF00 0000 2E2E 3300"
+ $"CC00 FF00 2D2D 3300 CC00 CC00 3130 3300"
+ $"CC00 9900 2F2F 3300 CC00 6600 2E2E 3300"
+ $"CC00 3300 2D2D 3300 CC00 0000 3130 3300"
+ $"9900 FF00 2F2F 3300 9900 CC00 2E2E 3300"
+ $"9900 9900 2D2D 3300 9900 6600 3130 3300"
+ $"9900 3300 2F2F 3300 9900 0000 2E2E 3300"
+ $"6600 FF00 2DF8 3300 6600 CC00 2B2A 3300"
+ $"6600 9900 2929 3300 6600 6600 2828 3300"
+ $"6600 3300 27F8 3300 6600 0000 2B2A 3300"
+ $"3300 FF00 2929 3300 3300 CC00 2828 3300"
+ $"3300 9900 2727 3300 3300 6600 2B2A 3300"
+ $"3300 3300 2929 3300 3300 0000 2828 3300"
+ $"0000 FF00 2727 3300 0000 CC00 2B2A 3300"
+ $"0000 9900 2929 3300 0000 6600 2828 3300"
+ $"0000 3300 2727 3300 0000 0000 4948 0000"
+ $"FF00 FF00 4747 0000 FF00 CC00 4646 0000"
+ $"FF00 9900 4545 0000 FF00 6600 4948 0000"
+ $"FF00 3300 4747 0000 FF00 0000 4646 0000"
+ $"CC00 FF00 4545 0000 CC00 CC00 4948 0000"
+ $"CC00 9900 4747 0000 CC00 6600 4646 0000"
+ $"CC00 3300 4545 0000 CC00 0000 4342 0000"
+ $"9900 FF00 4141 0000 9900 CC00 4040 0000"
+ $"9900 9900 3F3F 0000 9900 6600 4342 0000"
+ $"9900 3300 4141 0000 9900 0000 4040 0000"
+ $"6600 FF00 3F3F 0000 6600 CC00 4342 0000"
+ $"6600 9900 4141 0000 6600 6600 4040 0000"
+ $"6600 3300 3F3F 0000 6600 0000 4342 0000"
+ $"3300 FF00 4141 0000 3300 CC00 4040 0000"
+ $"3300 9900 3F3F 0000 3300 6600 4342 0000"
+ $"3300 3300 4141 0000 3300 0000 4040 0000"
+ $"0000 FF00 3F3F 0000 0000 CC00 4342 0000"
+ $"0000 9900 4141 0000 0000 6600 4040 0000"
+ $"0000 3300 3F3F EE00 0000 0000 3D3C DD00"
+ $"0000 0000 3B3B BB00 0000 0000 3A3A AA00"
+ $"0000 0000 3939 8800 0000 0000 3D3C 7700"
+ $"0000 0000 3B3B 5500 0000 0000 3A3A 4400"
+ $"0000 0000 3939 2200 0000 0000 3D3C 1100"
+ $"0000 0000 3B3B 0000 EE00 0000 3A3A 0000"
+ $"DD00 0000 3939 0000 BB00 0000 3D3C 0000"
+ $"AA00 0000 3B3B 0000 8800 0000 3A3A 0000"
+ $"7700 0000 3939 0000 5500 0000 3D3C 0000"
+ $"4400 0000 3B3B 0000 2200 0000 3A3A 0000"
+ $"1100 0000 3939 0000 0000 EE00 3D3C 0000"
+ $"0000 DD00 3B3B 0000 0000 BB00 3A3A 0000"
+ $"0000 AA00 3939 0000 0000 8800 3D3C 0000"
+ $"0000 7700 3B3B 0000 0000 5500 3A3A 0000"
+ $"0000 4400 3939 0000 0000 2200 3736 0000"
+ $"0000 1100 3535 EE00 EE00 EE00 3434 DD00"
+ $"DD00 DD00 3333 BB00 BB00 BB00 3736 AA00"
+ $"AA00 AA00 3535 8800 8800 8800 3434 7700"
+ $"7700 7700 3333 5500 5500 5500 3736 4400"
+ $"4400 4400 3535 2200 2200 2200 3434 1100"
+ $"1100 1100 3333 0000 0000 0000 0000 0000"
+ $"0064 0044 0000 0000 0064 0044 0000 000A"
+ $"0000 0000 0064 0044 02BD 0013 E800 01F5"
+ $"F6FE 07FE 0E02 3232 33FD 3900 0EE6 001D"
+ $"FC00 01F5 F5FE 0700 08FE 0E02 3232 33FE"
+ $"3900 3AFC 40F2 4102 4033 07E9 0017 0100"
+ $"0EFC 40DC 4102 390E F5F5 0002 F5F5 F6FE"
+ $"0702 0E07 0016 0100 32D5 4104 4039 0E32"
+ $"33FD 3900 3AFC 40FC 4101 3200 0801 000E"
+ $"C141 010E 0008 0100 0EC1 4101 0800 0801"
+ $"000E C141 0107 0008 0100 0EC1 4101 0700"
+ $"0901 0007 C241 0240 F500 0E01 0007 E841"
+ $"0147 47DD 4102 4000 0012 0100 07F0 4100"
+ $"47FA 4101 3B3B DD41 0240 0000 1901 0007"
+ $"F141 0C47 3B0B 3B47 4141 4711 0505 3B47"
+ $"DF41 023A 0000 1701 00F6 F041 010B 0BFE"
+ $"4105 473B 0505 113B DE41 0239 0000 1A02"
+ $"00F5 40F3 410C 473B 053B 4741 4741 0B0B"
+ $"3B47 47DE 4102 3900 0018 0200 F540 F341"
+ $"0247 110B FE41 0447 1105 4147 DC41 0233"
+ $"0000 1B02 0000 40F3 4103 4711 1147 FE41"
+ $"0205 3547 F741 FD47 E941 0232 0000 1E02"
+ $"0000 40F2 4106 113B 4741 4735 0BF7 4106"
+ $"4741 390E 0E40 47EA 4102 0E00 0021 0200"
+ $"0040 F241 0711 3B47 4141 0B35 47F9 4102"
+ $"4740 07FE 0002 F640 47EB 4102 0E00 0023"
+ $"0200 0040 F341 0847 3541 4147 3B05 4147"
+ $"FA41 0947 3AF6 00F5 4F55 F50E 47EB 4102"
+ $"0700 0022 0200 003A F341 0147 3BFE 4101"
+ $"0B0B F941 0547 3AF5 0055 C8FE CE01 5640"
+ $"EB41 0207 0000 1F02 0000 39F0 4104 4741"
+ $"053B 47FB 4104 4740 F5F5 A4FC CE01 C85D"
+ $"EB41 02F6 0000 1F02 0000 39F0 4104 473B"
+ $"0541 47FC 4104 4740 07F6 C8FA CE00 64EC"
+ $"4103 40F5 0000 1C02 0000 39F0 4102 4711"
+ $"0BFA 4103 4708 2AC8 FACE 0164 D8EC 4100"
+ $"40FE 0025 0200 0039 EF41 020B 3B47 FC41"
+ $"0347 0FF5 A4FB CE02 C887 D8FC 41FE 47FC"
+ $"4100 47F9 4100 3AFE 0028 0200 0039 EF41"
+ $"020B 3B47 FD41 0347 3900 A4FA CE00 ABFA"
+ $"4109 3B11 3B41 4147 3B0B 3B47 FA41 0039"
+ $"FE00 2402 0000 33F1 4102 4741 0BFA 4101"
+ $"0779 F9CE 0064 FA41 0235 050B FD41 010B"
+ $"0BF9 4100 39FE 0028 0200 0032 F141 0247"
+ $"3B0B FC41 0247 39F6 F9CE 0187 D8FB 4103"
+ $"4741 050B FE41 0247 110B F941 0039 FE00"
+ $"2C02 0000 32F1 4102 473B 11FB 4101 0879"
+ $"FACE 05AA 4041 4147 47FE 410A 4741 0511"
+ $"4741 4147 3511 47FA 4100 32FE 002F 0200"
+ $"000E F141 0347 3B11 47FE 4103 4740 F6C8"
+ $"FACE 0564 D841 4039 39FE 4104 473B 053B"
+ $"47FE 4102 3541 47FA 4100 0EFE 0027 0200"
+ $"000E F141 0347 3B3B 47FE 4102 470F 79FA"
+ $"CE0C 8741 4032 F500 003A 4741 473B 05F2"
+ $"4100 0EFE 0027 0200 000E F141 0347 3B3B"
+ $"47FD 4101 0EA4 FACE 01AB AAFE C808 7900"
+ $"3947 4147 110B 47F3 4100 07FE 001C 0200"
+ $"000E EA41 0240 2BC8 F5CE 0881 0033 4741"
+ $"410B 3B47 F341 0007 FE00 1A02 0000 08EB"
+ $"4102 473A 55F4 CE06 5D00 3947 4741 0BF1"
+ $"4100 F6FE 001C 0200 0007 EB41 0247 3979"
+ $"F4CE 0739 0039 4747 3511 47F3 4101 40F5"
+ $"FE00 1C02 0000 07EB 4102 4739 A4F5 CE08"
+ $"AB0E 0040 4741 1141 47F3 4100 40FD 001B"
+ $"0200 0007 EB41 0247 39A4 F5CE 0787 0707"
+ $"4147 4111 47F2 4100 40FD 001B 0200 0007"
+ $"EB41 0247 39C8 F5CE 0763 F532 4747 3B3B"
+ $"47F2 4100 3AFD 001A 0300 00F6 40EC 4102"
+ $"4739 C8F5 CE05 39F5 4047 413B F041 0039"
+ $"FD00 1C03 0000 F540 EB41 0140 C8FD CE01"
+ $"C8A4 FCCE 03AB 080E 47ED 4100 39FD 001A"
+ $"FE00 0040 EB41 0040 FCCE 01A4 C8FC CE03"
+ $"FA07 4047 ED41 0032 FD00 1AFE 0000 40EA"
+ $"4100 AAFE CE02 87F9 C8FC CE02 560F 47EC"
+ $"4100 32FD 0019 FE00 0040 EA41 00AB FECE"
+ $"0264 56C8 FDCE 01C8 32EA 4100 0EFD 001B"
+ $"FE00 0040 ED41 030E 4047 87FE CE01 4055"
+ $"FCCE 01FA 40EA 4100 08FD 001A FE00 003A"
+ $"ED41 0807 0740 FBCE CEAB 3979 FDCE 00AB"
+ $"E841 0007 FD00 1CFE 0000 3AED 4108 0700"
+ $"F6A4 CECE 8733 79FD CE02 4147 47EA 4100"
+ $"07FD 001E FE00 0039 ED41 0807 2AA4 C8CE"
+ $"CE88 0E9D FECE 0364 1C39 39EB 4101 40F5"
+ $"FD00 1CFE 0000 39ED 4101 074F FDCE 0264"
+ $"F7A4 FECE 03AB 80F6 07EB 4100 40FC 001C"
+ $"FE00 0039 ED41 0108 79FE CE03 AB40 2BA4"
+ $"FCCE 02F7 0E47 EC41 0040 FC00 1CFE 0000"
+ $"39ED 4101 0879 FECE 03AB 40F6 C8FC CE02"
+ $"F615 47EC 4100 40FC 001E FE00 003A EE41"
+ $"0247 0E79 FECE 03AB 40F5 C8FD CE03 A4F5"
+ $"3A47 EC41 0040 FC00 1EFE 0000 3AEE 4102"
+ $"470E 56FE CE03 FB3A F6C8 FDCE 0280 F540"
+ $"EB41 0140 F5FD 001E FE00 0040 EE41 0947"
+ $"0F56 CECE C888 39F6 C8FD CE02 5601 40EB"
+ $"4101 40F5 FD00 1CFE 0000 40EE 4109 4739"
+ $"32CE CEC8 8839 2AC8 FDCE 0156 07E9 4100"
+ $"F6FD 001B FE00 0040 EE41 0847 3A32 CECE"
+ $"C864 152A FCCE 0132 07E9 4100 07FD 001A"
+ $"FE00 0040 ED41 0740 32AB CEC8 6439 4EFC"
+ $"CE01 3A07 E941 0007 FD00 1D03 0000 F540"
+ $"ED41 0740 0EAB CECE 640F 4EFD CE03 AB40"
+ $"0840 EA41 0007 FD00 1B03 0000 F540 EC41"
+ $"060F 81CE CE64 334E FDCE 02AB 400E E941"
+ $"000E FD00 1C02 0000 F6EC 4107 4715 FACE"
+ $"CE64 334E FDCE 0387 0F0E 47EA 4100 0EFD"
+ $"001C 0200 0007 EC41 0747 16F9 CEC8 6433"
+ $"4EFD CE03 6308 4047 EA41 000E FD00 1A02"
+ $"0000 07EB 4106 40F9 CEC8 6439 4EFD CE02"
+ $"3940 47E9 4100 32FD 001B 0200 0007 EA41"
+ $"0539 CECE 8839 F6FE CE04 AB41 4139 40EA"
+ $"4100 32FD 001C 0200 0007 EB41 0E47 3AC8"
+ $"CE88 39F6 C8CE CE64 15F6 F540 EA41 0033"
+ $"FD00 1A02 0000 07EA 410C 40A4 CE87 392A"
+ $"C8CE AB41 40F8 F6E9 4100 39FD 001B 0200"
+ $"000E EB41 0D47 41AB C887 39F5 C8CE ABAB"
+ $"CEA4 07E9 4100 39FD 001C 0200 000E ED41"
+ $"0947 3939 4787 C8AB 40F5 C8FD CE01 A40E"
+ $"E941 0039 FD00 1D02 0000 0EED 4109 473A"
+ $"0007 80CE AB40 F5C8 FDCE 0255 0E47 EA41"
+ $"0039 FD00 1B02 0000 0EEB 4107 0779 C8CE"
+ $"CE40 F6A4 FDCE 022B 3947 EA41 003A FD00"
+ $"1C02 0000 0EEC 4102 4739 79FE CE02 6407"
+ $"A4FE CE02 A407 40E9 4100 40FD 001A 0200"
+ $"0032 EA41 0632 A4CE CE88 0879 FECE 02F9"
+ $"0F47 E941 0040 FD00 1A02 0000 32EB 4107"
+ $"4740 F7C8 CE87 0E79 FECE 0132 40E8 4100"
+ $"40FD 0019 0200 0033 EA41 0B47 40F8 C8AB"
+ $"0E55 CECE 8015 47E8 4100 40FD 0017 0200"
+ $"0033 E941 0847 40F9 A439 4FCE CE5D E641"
+ $"0140 F5FE 0014 0200 0039 E841 0647 64FB"
+ $"392B C8AB E441 00F6 FE00 1102 0000 39E5"
+ $"4103 40F6 8764 E441 0007 FE00 1E02 0000"
+ $"39EB 4102 3A0E 0EFD 4102 0740 47F6 4104"
+ $"400F 0839 47F4 4100 07FE 0027 0200 0039"
+ $"FB41 0147 47F2 4102 0800 40FE 4102 0839"
+ $"47FC 4101 4747 FC41 0339 0039 47F4 4100"
+ $"07FE 0029 0200 0039 FB41 0140 39F3 4109"
+ $"470E F540 4141 470E 3347 FC41 0139 3AFD"
+ $"4104 4739 0039 47F4 4100 08FE 0036 0200"
+ $"003A FC41 0347 0E00 40FC 4102 4741 40FC"
+ $"4109 470E F540 4141 4733 0E47 FE41 0447"
+ $"4000 0E47 FE41 0447 3900 3941 FE40 F741"
+ $"000E FE00 3A02 0000 3AFD 410E 4740 0700"
+ $"0E40 4741 4147 390E 390E 40FE 4108 470E"
+ $"F540 4141 4739 0EFC 4103 0F00 0739 FE41"
+ $"0747 3900 3940 080F 39F7 4100 0EFE 0035"
+ $"0200 0040 FB41 020E 0040 FE41 0D47 4000"
+ $"3941 0032 4741 4147 0EF5 40FE 4101 4008"
+ $"FC41 023A 000E FD41 0547 3900 3939 33F5"
+ $"4100 0EFE 0039 0200 0040 FC41 0347 0E00"
+ $"40FE 4106 4732 0040 4139 40FE 4103 470E"
+ $"F540 FD41 0108 40FE 4104 4740 000E 47FE"
+ $"4106 4739 0007 F540 47F6 4100 32FE 003A"
+ $"0200 0040 FC41 0C47 0E00 4047 4141 470E"
+ $"0040 4747 FD41 0347 0EF5 40FE 410A 470E"
+ $"3947 4141 4740 000E 47FE 4107 4739 000E"
+ $"0007 4147 F741 0032 FE00 3802 0000 40FC"
+ $"4102 470E 00FD 4106 4739 003A 4740 39FE"
+ $"4102 470E F5FD 410A 4733 3347 4141 4740"
+ $"000E 47FE 4106 4739 0039 3900 0EF6 4100"
+ $"33FE 003A 0200 F540 FC41 0447 3200 0E39"
+ $"FD41 0B0E 0E40 333A 4741 413A 07F5 39FE"
+ $"4102 473A 0EFD 410F 40F5 0733 4041 4140"
+ $"0E00 0E40 0700 0E40 F841 0039 FE00 2902"
+ $"00F5 40FA 4101 3939 FB41 023A 3A40 FD41"
+ $"FD40 FD41 0240 0E40 FD41 0240 3940 FD41"
+ $"FA40 F741 0039 FE00 2A01 00F6 F941 0147"
+ $"47FB 4101 4747 FB41 0147 47FB 4101 3940"
+ $"FD41 0147 47FB 4100 47FE 4100 47F6 4100"
+ $"39FE 000D 0100 07E1 4100 40E4 4100 3AFE"
+ $"0009 0100 07C3 4100 3AFE 0009 0100 07C3"
+ $"4100 40FE 0009 0100 07C3 4100 40FE 0009"
+ $"0100 07C3 4100 40FE 000A 0100 0EC3 4103"
+ $"40F5 0000 0901 000E C241 02F6 0000 0901"
+ $"000E C241 0207 0000 0901 000E C241 0207"
+ $"0000 1101 000E ED41 FE40 003A F940 E241"
+ $"0207 0000 2B01 0032 F941 FE40 FE39 0632"
+ $"0E0E 0707 F6F5 F800 02F5 F5F6 FB07 FB0E"
+ $"0332 3233 33FB 3901 3A3A FB40 0207 0000"
+ $"0E0A 000E 3939 320E 0E07 07F6 F5C8 0002"
+ $"BD00 00FF"
+};
diff --git a/macosx/tkMacOSX.h b/macosx/tkMacOSX.h
new file mode 100644
index 0000000..45bbf7b
--- /dev/null
+++ b/macosx/tkMacOSX.h
@@ -0,0 +1,34 @@
+/*
+ * tkMacOSXInt.h --
+ *
+ * Declarations of Macintosh specific exported variables and procedures.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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 2002/08/31 06:12:29 das Exp $
+ */
+
+#ifndef _TKMAC
+#define _TKMAC
+
+#include <Carbon/Carbon.h>
+#include "tkInt.h"
+
+/*
+ * 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 void (Tk_MacOSXEmbedGetOffsetInParentProc) (Tk_Window window, Point *ulCorner);
+
+#include "tkPlatDecls.h"
+
+#endif /* _TKMAC */
diff --git a/macosx/tkMacOSXAppInit.c b/macosx/tkMacOSXAppInit.c
new file mode 100644
index 0000000..422546b
--- /dev/null
+++ b/macosx/tkMacOSXAppInit.c
@@ -0,0 +1,241 @@
+/*
+ * tkAppInit.c --
+ *
+ * Provides a default version of the Tcl_AppInit procedure for
+ * use in wish and similar Tk-based applications.
+ *
+ * Copyright (c) 1993 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXAppInit.c,v 1.2 2002/08/31 06:12:29 das Exp $
+ */
+#include <pthread.h>
+#include "tk.h"
+#include "tclInt.h"
+#include "locale.h"
+
+#include <Carbon/Carbon.h>
+#include "tkMacOSX.h"
+#include "tkMacOSXEvent.h"
+
+#ifndef MAX_PATH_LEN
+ #define MAX_PATH_LEN 1024
+#endif
+
+/*
+ * If the App is in an App package, then we want to add the Scripts
+ * directory to the auto_path. But we have to wait till after the
+ * Tcl_Init is run, or it gets blown away. This stores what we
+ * figured out in main.
+ */
+
+char scriptPath[MAX_PATH_LEN + 1];
+
+extern Tcl_Interp *gStdoutInterp;
+
+#ifdef TK_TEST
+extern int Tktest_Init _ANSI_ARGS_((Tcl_Interp *interp));
+#endif /* TK_TEST */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * main --
+ *
+ * This is the main program for the application.
+ *
+ * Results:
+ * None: Tk_Main never returns here, so this procedure never
+ * returns either.
+ *
+ * Side effects:
+ * Whatever the application does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+main(argc, argv)
+ int argc; /* Number of command-line arguments. */
+ char **argv; /* Values of command-line arguments. */
+{
+ int textEncoding; /*
+ * Variable used to take care of
+ * lazy font initialization
+ */
+ CFBundleRef bundleRef;
+
+ /*
+ * The following #if block allows you to change the AppInit
+ * function by using a #define of TCL_LOCAL_APPINIT instead
+ * of rewriting this entire file. The #if checks for that
+ * #define and uses Tcl_AppInit if it doesn't exist.
+ */
+
+#ifndef TK_LOCAL_APPINIT
+#define TK_LOCAL_APPINIT Tcl_AppInit
+#endif
+ extern int TK_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp));
+
+ scriptPath[0] = '\0';
+
+ /*
+ * The following #if block allows you to change how Tcl finds the startup
+ * script, prime the library or encoding paths, fiddle with the argv,
+ * etc., without needing to rewrite Tk_Main(). Note, if you use this
+ * hook, then I won't do the CFBundle lookup, since if you are messing
+ * around at this level, you probably don't want me to do this for you...
+ */
+
+#ifdef TK_LOCAL_MAIN_HOOK
+ extern int TK_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));
+ TK_LOCAL_MAIN_HOOK(&argc, &argv);
+#else
+
+ /*
+ * 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.
+ */
+
+ bundleRef = CFBundleGetMainBundle();
+
+ if (bundleRef != NULL) {
+ CFURLRef appMainURL;
+ appMainURL = CFBundleCopyResourceURL(bundleRef,
+ CFSTR("AppMain"),
+ CFSTR("tcl"),
+ CFSTR("Scripts"));
+
+ if (appMainURL != NULL) {
+ CFURLRef scriptFldrURL;
+ char *startupScript = malloc(MAX_PATH_LEN + 1);
+
+ if (CFURLGetFileSystemRepresentation (appMainURL, true,
+ startupScript, MAX_PATH_LEN)) {
+ TclSetStartupScriptFileName(startupScript);
+ scriptFldrURL = CFBundleCopyResourceURL(bundleRef,
+ CFSTR("Scripts"),
+ NULL,
+ NULL);
+ CFURLGetFileSystemRepresentation(scriptFldrURL,
+ true, scriptPath, MAX_PATH_LEN);
+ CFRelease(scriptFldrURL);
+ } else {
+ free(startupScript);
+ }
+ CFRelease(appMainURL);
+ }
+ }
+
+#endif
+ textEncoding=GetApplicationTextEncoding();
+
+ /*
+ * Now add the scripts folder to the auto_path.
+ */
+
+ Tk_Main(argc,argv,TK_LOCAL_APPINIT);
+ return 0; /* Needed only to prevent compiler warning. */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppInit --
+ *
+ * This procedure performs application-specific initialization.
+ * Most applications, especially those that incorporate additional
+ * packages, will have their own version of this procedure.
+ *
+ * Results:
+ * Returns a standard Tcl completion code, and leaves an error
+ * message in the interp's result if an error occurs.
+ *
+ * Side effects:
+ * Depends on the startup script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_AppInit(interp)
+ Tcl_Interp *interp; /* Interpreter for application. */
+{
+ if (Tcl_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+ if (Tk_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+ Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);
+
+ if (scriptPath[0] != '\0') {
+ Tcl_SetVar(interp, "auto_path", scriptPath,
+ TCL_GLOBAL_ONLY|TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
+ }
+
+#ifdef TK_TEST
+ if (Tktest_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+ Tcl_StaticPackage(interp, "Tktest", Tktest_Init,
+ (Tcl_PackageInitProc *) NULL);
+#endif /* TK_TEST */
+
+ /*
+ * If we don't have a TTY, then use the Tk based console
+ * interpreter instead.
+ */
+
+ if (ttyname(0) == NULL) {
+ Tk_InitConsoleChannels(interp);
+ Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDIN));
+ Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDOUT));
+ Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDERR));
+ if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
+ goto error;
+ }
+ /* Only show the console if we don't have a startup script */
+ if (TclGetStartupScriptPath() == NULL) {
+ Tcl_Eval(interp, "console show");
+ }
+ }
+
+ /*
+ * Call the init procedures for included packages. Each call should
+ * look like this:
+ *
+ * if (Mod_Init(interp) == TCL_ERROR) {
+ * return TCL_ERROR;
+ * }
+ *
+ * where "Mod" is the name of the module.
+ */
+
+ /*
+ * Call Tcl_CreateCommand for application-specific commands, if
+ * they weren't already created by the init procedures called above.
+ */
+
+
+ /*
+ * Specify a user-specific startup file to invoke if the application
+ * is run interactively. Typically the startup file is "~/.apprc"
+ * where "app" is the name of the application. If this line is deleted
+ * then no user-specific startup file will be run under any conditions.
+ */
+
+ Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY);
+
+ return TCL_OK;
+
+ error:
+ return TCL_ERROR;
+}
diff --git a/macosx/tkMacOSXApplication.r b/macosx/tkMacOSXApplication.r
new file mode 100644
index 0000000..0012f29
--- /dev/null
+++ b/macosx/tkMacOSXApplication.r
@@ -0,0 +1,276 @@
+/*
+ * tkMacOSXApplication.r --
+ *
+ * This file creates resources for use in the Wish application.
+ *
+ * Copyright (c) 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: tkMacOSXApplication.r,v 1.2 2002/08/31 06:12:29 das Exp $
+ */
+
+#include <Carbon/Carbon.r>
+
+/*
+ * The folowing include and defines help construct
+ * the version string for Tcl.
+ */
+
+#define RESOURCE_INCLUDED
+#include "tk.h"
+
+#if (TK_RELEASE_LEVEL == 0)
+# define RELEASE_LEVEL alpha
+#elif (TK_RELEASE_LEVEL == 1)
+# define RELEASE_LEVEL beta
+#elif (TK_RELEASE_LEVEL == 2)
+# define RELEASE_LEVEL final
+#endif
+
+#if (TK_RELEASE_LEVEL == 2)
+# define MINOR_VERSION (TK_MINOR_VERSION * 16) + TK_RELEASE_SERIAL
+#else
+# define MINOR_VERSION TK_MINOR_VERSION * 16
+#endif
+
+#define RELEASE_CODE 0x00
+
+resource 'vers' (1) {
+ TK_MAJOR_VERSION, MINOR_VERSION,
+ RELEASE_LEVEL, 0x00, verUS,
+ TK_PATCH_LEVEL,
+ TK_PATCH_LEVEL ", by Jim Ingham & Ian Reid" "\n" "© 2001 Apple Computer, Inc" "\n" "1998-2000 Scriptics Inc." "\n" "1996-1997 Sun Microsystems Inc."
+};
+
+resource 'vers' (2) {
+ TK_MAJOR_VERSION, MINOR_VERSION,
+ RELEASE_LEVEL, 0x00, verUS,
+ TK_PATCH_LEVEL,
+ "Wish " TK_PATCH_LEVEL " © 1993-1999"
+};
+
+#define TK_APP_RESOURCES 128
+#define TK_APP_CREATOR 'WIsH'
+
+/*
+ * The 'BNDL' resource is the primary link between a file's
+ * creator/type and its icon. This resource acts for all Tcl shared
+ * libraries; other libraries will not need one and ought to use
+ * custom icons rather than new file types for a different appearance.
+ */
+
+resource 'BNDL' (TK_APP_RESOURCES, "Tk app bundle", purgeable)
+{
+ TK_APP_CREATOR,
+ 0,
+ {
+ 'FREF',
+ {
+ 0, TK_APP_RESOURCES,
+ 1, TK_APP_RESOURCES+1
+ },
+ 'ICN#',
+ {
+ 0, TK_APP_RESOURCES,
+ 1, TK_APP_RESOURCES+1
+ }
+ }
+};
+
+resource 'FREF' (TK_APP_RESOURCES, purgeable)
+{
+ 'APPL', 0, ""
+};
+resource 'FREF' (TK_APP_RESOURCES+1, purgeable)
+{
+ 'TEXT', 1, ""
+};
+
+type TK_APP_CREATOR as 'STR ';
+resource TK_APP_CREATOR (0, purgeable) {
+ "Wish " TK_PATCH_LEVEL " © 1996"
+};
+
+/*
+ * The 'kind' resource works with a 'BNDL' in Macintosh Easy Open
+ * to affect the text the Finder displays in the "kind" column and
+ * file info dialog. This information will be applied to all files
+ * with the listed creator and type.
+ */
+resource 'kind' (TK_APP_RESOURCES, "Tcl kind", purgeable) {
+ TK_APP_CREATOR,
+ 0, /* region = USA */
+ {
+ 'APPL', "Wish",
+ 'TEXT', "Tcl/Tk Script"
+ }
+};
+
+#define kIconHelpString 256
+
+resource 'hfdr' (-5696, purgeable) {
+ HelpMgrVersion, hmDefaultOptions, 0, 0,
+ {HMSTRResItem {kIconHelpString}}
+};
+resource 'STR ' (kIconHelpString, purgeable) {
+ "This is the interpreter for Tcl & Tk scripts"
+ " running on Macintosh computers."
+};
+
+/*
+ * The following resource define the icon used by Tcl scripts. Any
+ * TEXT file with the creator of WIsH will get this icon.
+ */
+
+data 'icl4' (TK_APP_RESOURCES + 1, "Tk Doc", purgeable) {
+ $"000F FFFF FFFF FFFF FFFF FFF0 0000 0000"
+ $"000F 3333 3333 3333 3333 33FF 0000 0000"
+ $"000F 3333 3333 3333 3433 33F2 F000 0000"
+ $"000F 3333 3333 3333 7D43 33F2 2F00 0000"
+ $"000F 3333 3333 3335 5623 33F2 22F0 0000"
+ $"000F 3333 3333 3356 6343 33FF FFFF 0000"
+ $"000F 3333 3333 256F 5223 3333 333F 0000"
+ $"000F 3333 3333 D666 2433 3333 333F 0000"
+ $"000F 3333 3333 D5F6 6633 3333 333F 0000"
+ $"000F 3333 3332 5666 6733 3333 333F 0000"
+ $"000F 3333 3336 E56F 6633 3333 333F 0000"
+ $"000F 3333 3336 5656 5733 3333 333F 0000"
+ $"000F 3333 3336 E5B6 5233 3333 333F 0000"
+ $"000F 3333 3336 5ED6 3333 3333 333F 0000"
+ $"000F 3333 3376 6475 6233 3333 333F 0000"
+ $"000F 3333 333D 5D56 7333 3333 333F 0000"
+ $"000F 3333 3336 6C55 6333 3333 333F 0000"
+ $"000F 3333 3336 5C56 7333 3333 333F 0000"
+ $"000F 3333 3362 6CE6 D333 3333 333F 0000"
+ $"000F 3333 3336 5C65 6333 3333 333F 0000"
+ $"000F 3333 3336 EC5E 3333 3333 333F 0000"
+ $"000F 3333 3336 5C56 6333 3333 333F 0000"
+ $"000F 3333 3333 5C75 3333 3333 333F 0000"
+ $"000F 3333 3333 5DD6 3333 3333 333F 0000"
+ $"000F 3333 3333 3CDD 3333 3333 333F 0000"
+ $"000F 3333 3333 3303 3333 3333 333F 0000"
+ $"000F 3333 3333 3C33 3333 3333 333F 0000"
+ $"000F 3333 3333 3C33 3333 3333 333F 0000"
+ $"000F 3333 3333 3C33 3333 3333 333F 0000"
+ $"000F 3333 3333 3333 3333 3333 333F 0000"
+ $"000F 3333 3333 3333 3333 3333 333F 0000"
+ $"000F FFFF FFFF FFFF FFFF FFFF FFFF 0000"
+};
+
+data 'ICN#' (TK_APP_RESOURCES + 1, "Tk Doc", purgeable) {
+ $"1FFF FE00 1000 0300 1000 F280 1003 F240"
+ $"1003 E220 1007 E3F0 100F C010 100F C010"
+ $"100F C010 101F F010 101F F010 101F F010"
+ $"101F F010 101F F010 101D E010 101D E010"
+ $"101D E010 101D C010 101D C010 101D C010"
+ $"101D C010 100D 8010 100D 8010 100D 8010"
+ $"1005 8010 1002 0010 1002 0010 1002 0010"
+ $"1002 0010 1002 0010 1000 0010 1FFF FFF0"
+ $"1FFF FE00 1FFF FF00 1FFF FF80 1FFF FFC0"
+ $"1FFF FFE0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+};
+
+data 'ics#' (TK_APP_RESOURCES + 1, "Tk Doc", purgeable) {
+ $"7FF0 41D8 419C 4384 43C4 47C4 47C4 4784"
+ $"4684 4684 4284 4284 4104 4104 4104 7FFC"
+ $"7FE0 7FF0 7FF8 7FFC 7FFC 7FFC 7FFC 7FFC"
+ $"7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC"
+};
+
+data 'ics4' (TK_APP_RESOURCES + 1, "Tk Doc", purgeable) {
+ $"0FFF FFFF FFFF 0000 0F33 3333 53F2 F000"
+ $"0F33 3335 52FF FF00 0F33 33E6 3333 3F00"
+ $"0F33 3256 6333 3F00 0F33 3556 6333 3F00"
+ $"0F33 3A5E 3333 3F00 0F33 65D6 D333 3F00"
+ $"0F33 3655 5333 3F00 0F33 65C6 3333 3F00"
+ $"0F33 3EC5 E333 3F00 0F33 36C6 3333 3F00"
+ $"0F33 33CD 3333 3F00 0F33 33C3 3333 3F00"
+ $"0F33 33C3 3333 3F00 0FFF FFFF FFFF FF00"
+};
+
+/*
+ * The following resources define the icons for the Wish
+ * application.
+ */
+
+data 'icl4' (TK_APP_RESOURCES, "Tk App", purgeable) {
+ $"0000 0000 0000 000F 0000 0000 0000 0000"
+ $"0000 0000 0000 00FC F000 0000 0000 0000"
+ $"0000 0000 0000 0FCC CF66 0000 0000 0000"
+ $"0000 0000 0000 FCCC C556 0000 0000 0000"
+ $"0000 0000 000F CCCC 566F 0000 0000 0000"
+ $"0000 0000 00FC CCC5 6F5C F000 0000 0000"
+ $"0000 0000 0FCC CC66 66CC CF00 0000 0000"
+ $"0000 0000 FCCC CCD5 5666 CCF0 0000 0000"
+ $"0000 000F CCCC C656 5667 CCCF 0000 0000"
+ $"0000 00FC CCCC C6E5 5566 CCCC F000 0000"
+ $"0000 0FCC CCCC C656 5657 CCCC CF00 0000"
+ $"0000 FCCC CCCC C6E5 565C CCCC CCF0 0000"
+ $"000F CCCC CCCC C655 565C CCCC CCCF 0000"
+ $"00FC CCCC CCCC 7660 556C CCCC CCCC F000"
+ $"0FCC CCCC CCCC CD5D 567C CCCC CCCC CF00"
+ $"FCCC CCCC CCCC 6660 556C CCCC CCCC CCF0"
+ $"0FCC CCCC CCCC 665C 565C CCCC CCCC C0CF"
+ $"00FC CCCC CCCC 6660 E6DC CCCC CCCC CCF0"
+ $"000F CCCC CCCC C650 656C CCCC CCCC CF00"
+ $"0000 FCCC CCCC C6EC 5ECC CCCC CCCC F000"
+ $"0000 0FCC CCCC C650 566C CCCC CCCF 0000"
+ $"0000 00FC CCCC CC50 75CC CCCC CCF0 0000"
+ $"0000 000F CCCC CC50 56CC CCCC CF00 0000"
+ $"0000 0000 FCCC CCC0 5CCC CCCC F000 0000"
+ $"0000 0000 0FCC CCC0 CCCC CCCF 0000 0000"
+ $"0000 0000 00FC CCC0 CCCC CCF0 0000 0000"
+ $"0000 0000 000F CCC0 CCCC CF00 0000 0000"
+ $"0000 0000 0000 FCCC CCCC F000 0000 0000"
+ $"0000 0000 0000 0FCC CCCF 0000 0000 0000"
+ $"0000 0000 0000 00FC CCF0 0000 0000 0000"
+ $"0000 0000 0000 000F CF00 0000 0000 0000"
+ $"0000 0000 0000 0000 F000 0000 0000 0000"
+};
+
+data 'ICN#' (TK_APP_RESOURCES, "Tk App", purgeable) {
+ $"0001 0000 0002 8000 0004 7000 0008 7000"
+ $"0010 F000 0021 E800 0043 C400 0081 F200"
+ $"0107 F100 0207 F080 0407 F040 0807 E020"
+ $"1007 E010 200E E008 4002 E004 800E E002"
+ $"400E E001 200E C002 1006 E004 0806 C008"
+ $"0406 E010 0202 C020 0102 C040 0080 8080"
+ $"0041 0100 0021 0200 0011 0400 0009 0800"
+ $"0004 1000 0002 2000 0001 4000 0000 8000"
+ $"0001 0000 0003 8000 0007 F000 000F F000"
+ $"001F F000 003F F800 007F FC00 00FF FE00"
+ $"01FF FF00 03FF FF80 07FF FFC0 0FFF FFE0"
+ $"1FFF FFF0 3FFF FFF8 7FFF FFFC FFFF FFFE"
+ $"7FFF FFFF 3FFF FFFE 1FFF FFFC 0FFF FFF8"
+ $"07FF FFF0 03FF FFE0 01FF FFC0 00FF FF80"
+ $"007F FF00 003F FE00 001F FC00 000F F800"
+ $"0007 F000 0003 E000 0001 C000 0000 8000"
+};
+
+data 'ics#' (TK_APP_RESOURCES, "Tk App", purgeable) {
+ $"01C0 0260 04E0 09D0 1388 23C4 43C2 8281"
+ $"8282 4284 2188 1190 0920 0540 0280 0100"
+ $"01C0 03E0 07E0 0FF0 1FF8 3FFC 7FFE FFFF"
+ $"FFFE 7FFC 3FF8 1FF0 0FE0 07C0 0380 0100"
+};
+
+data 'ics4' (TK_APP_RESOURCES, "Tk App", purgeable) {
+ $"0000 000F C000 0000 0000 00FC 6600 0000"
+ $"0000 0FCC 6600 0000 0000 FCC6 66F0 0000"
+ $"000F CCD5 56CF 0000 00FC CC66 57CC F000"
+ $"0FCC CC65 56CC CF00 FCCC CC56 57CC CCF0"
+ $"0FCC CCC6 6CCC CCCF 00FC CCC6 5CCC CCF0"
+ $"000F CCC6 6CCC CF00 0000 FCCC 5CCC F000"
+ $"0000 0FCC CCCF 0000 0000 00FC CCF0 0000"
+ $"0000 000F CF00 0000 0000 0000 F000 0000"
+};
+
+
diff --git a/macosx/tkMacOSXBitmap.c b/macosx/tkMacOSXBitmap.c
new file mode 100644
index 0000000..9f930aa
--- /dev/null
+++ b/macosx/tkMacOSXBitmap.c
@@ -0,0 +1,283 @@
+/*
+ * tkMacOSXBitmap.c --
+ *
+ * This file handles the implementation of native bitmaps.
+ *
+ * Copyright (c) 1996-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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 2002/08/31 06:12:29 das Exp $
+ */
+
+#include "tkPort.h"
+#include "tk.h"
+#include "tkMacOSXInt.h"
+
+#include <Carbon/Carbon.h>
+/*
+#include <Icons.h>
+#include <Dialogs.h>
+#include <Resources.h>
+#include <Strings.h>
+*/
+
+/*
+ * 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. */
+
+/*
+ * 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. */
+} NativeIcon;
+
+/*
+ * This structure holds information about native bitmaps.
+ */
+
+typedef struct {
+ char *name; /* Name of icon. */
+ long int type; /* Type of icon. */
+ int id; /* Id of icon. */
+ int size; /* Size of icon. */
+} BuiltInIcon;
+
+/*
+ * This array mapps a string name to the supported builtin icons
+ * on the Macintosh.
+ */
+
+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}
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDefineNativeBitmaps --
+ *
+ * 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.
+ *
+ * Side effects:
+ * "Name" is entered into the bitmap table and may be used from
+ * here on to refer to the given bitmap.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpDefineNativeBitmaps()
+{
+ int new;
+ Tcl_HashEntry *predefHashPtr;
+ TkPredefBitmap *predefPtr;
+ CONST char * name;
+ 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);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpCreateNativeBitmap --
+ *
+ * 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.
+ *
+ * Side effects:
+ * "Name" is entered into the bitmap table and may be used from
+ * here on to refer to the given bitmap.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Pixmap
+TkpCreateNativeBitmap(
+ Display *display,
+ 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);
+
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ nativeIconPtr = (NativeIcon *) source;
+ SetRect(&destRect, 0, 0, 32, 32);
+ if (nativeIconPtr->type == TYPE1) {
+ RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};
+
+ 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);
+ }
+ }
+
+ SetGWorld(saveWorld, saveDevice);
+ return pix;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetNativeAppBitmap --
+ *
+ * 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.
+ *
+ * Side effects:
+ * "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. */
+ int *height)
+{
+ Pixmap pix;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ Rect destRect;
+ Handle resource;
+ int type = -1, destWrote;
+ Str255 nativeName;
+
+ /*
+ * 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 */
+ nativeName[0] = destWrote;
+
+ resource = GetNamedResource('cicn', nativeName);
+ if (resource != NULL) {
+ type = TYPE3;
+ } else {
+ resource = GetNamedResource('ICON', nativeName);
+ if (resource != NULL) {
+ type = TYPE2;
+ }
+ }
+
+ if (resource == NULL) {
+ return NULL;
+ }
+
+ pix = Tk_GetPixmap(display, None, 32, 32, 0);
+ destPort = TkMacOSXGetDrawablePort(pix);
+
+ 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);
+ } 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);
+ }
+
+ *width = 32;
+ *height = 32;
+ SetGWorld(saveWorld, saveDevice);
+ return pix;
+}
diff --git a/macosx/tkMacOSXButton.c b/macosx/tkMacOSXButton.c
new file mode 100644
index 0000000..6314535
--- /dev/null
+++ b/macosx/tkMacOSXButton.c
@@ -0,0 +1,1580 @@
+/*
+ * tkMacOSXButton.c --
+ *
+ * This file implements the Macintosh specific portion of the
+ * button widgets.
+ *
+ * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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 2002/08/31 06:12:29 das Exp $
+ */
+
+#include "tkButton.h"
+#include "tkMacOSXInt.h"
+#include "tkMacOSXDebug.h"
+
+#define DEFAULT_USE_TK_TEXT 0
+
+/*
+ * Default insets for controls
+ */
+#define DEF_INSET_LEFT 2
+#define DEF_INSET_RIGHT 2
+#define DEF_INSET_TOP 2
+#define DEF_INSET_BOTTOM 4
+
+#include <Carbon/Carbon.h>
+
+/*
+ * Some defines used to control what type of control is drawn.
+ */
+
+#define DRAW_LABEL 0 /* Labels are treated genericly. */
+#define DRAW_CONTROL 1 /* Draw using the Native control. */
+#define DRAW_CUSTOM 2 /* Make our own button drawing. */
+#define DRAW_BEVEL 3
+
+/*
+ * Declaration of Mac specific button structure.
+ */
+
+typedef struct {
+ SInt16 initialValue;
+ SInt16 minValue;
+ SInt16 maxValue;
+ SInt16 procID;
+ int isBevel;
+} MacControlParams;
+
+typedef struct {
+ int drawType;
+ Tk_3DBorder border;
+ int relief;
+ 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;
+ 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.
+ */
+ CCTabHandle tabHandle;
+ ControlButtonContentInfo bevelButtonContent;
+ OpenCPicParams picParams;
+ Pixmap picPixmap;
+} MacButton;
+
+/*
+ * Forward declarations for procedures defined later in this file:
+ */
+
+
+static OSErr SetUserPaneDrawProc(ControlRef control,
+ ControlUserPaneDrawProcPtr upp);
+static OSErr 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));
+
+extern int TkFontGetFirstTextLayout(Tk_TextLayout layout, Tk_Font * font, char * dst);
+extern void TkMacOSXInitControlFontStyle(Tk_Font tkfont,ControlFontStylePtr fsPtr);
+
+/*
+ * The class procedure table for the button widgets.
+ */
+
+Tk_ClassProcs tkpButtonProcs = {
+ sizeof(Tk_ClassProcs), /* size */
+ TkButtonWorldChanged, /* worldChangedProc */
+};
+
+static int bCount;
+
+int tkPictureIsOpen;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpCreateButton --
+ *
+ * Allocate a new TkButton structure.
+ *
+ * Results:
+ * Returns a newly allocated TkButton structure.
+ *
+ * Side effects:
+ * Registers an event handler for the widget.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkButton *
+TkpCreateButton(
+ Tk_Window tkwin)
+{
+ MacButton *macButtonPtr;
+ macButtonPtr = (MacButton *) ckalloc(sizeof(MacButton));
+ Tk_CreateEventHandler(tkwin, ActivateMask,
+ 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->userPane=NULL;
+ macButtonPtr->control=NULL;
+ macButtonPtr->controlTitle[0]=
+ macButtonPtr->controlTitle[1]=0;
+ macButtonPtr->picParams.version = -2;
+ macButtonPtr->picParams.hRes = 0x00480000;
+ macButtonPtr->picParams.vRes = 0x00480000;
+ macButtonPtr->picParams.srcRect.top = 0;
+ macButtonPtr->picParams.srcRect.left = 0;
+ macButtonPtr->picParams.reserved1 = 0;
+ macButtonPtr->picParams.reserved2 = 0;
+ macButtonPtr->bevelButtonContent.contentType = kControlContentPictHandle;
+ bzero(&macButtonPtr->params, sizeof(macButtonPtr->params));
+ bzero(&macButtonPtr->fontStyle,sizeof(macButtonPtr->fontStyle));
+ return (TkButton *)macButtonPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDisplayButton --
+ *
+ * This procedure is invoked to display a button widget. It is
+ * normally invoked as an idle handler.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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. */
+{
+ MacButton *macButtonPtr = (MacButton *)clientData;
+ TkButton *butPtr = (TkButton *) clientData;
+ Tk_Window tkwin = butPtr->tkwin;
+ int x = 0; /* Initialization only needed to stop
+ * compiler warning. */
+ int y;
+ int width, height, fullWidth, fullHeight;
+ int imageXOffset, imageYOffset, textXOffset, textYOffset;
+ int haveImage = 0, haveText = 0;
+ GWorldPtr destPort;
+ int borderWidth;
+ Pixmap pixmap;
+ int wasUsingControl;
+ DrawParams drawParams, * dpPtr = &drawParams;
+
+ butPtr->flags &= ~REDRAW_PENDING;
+ if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
+ return;
+ }
+
+ pixmap = (Pixmap) Tk_WindowId(tkwin);
+ wasUsingControl = macButtonPtr->usingControl;
+
+ if (TkMacOSXComputeDrawParams(butPtr, &drawParams) ) {
+ macButtonPtr->usingControl=1;
+ macButtonPtr->useTkText=DEFAULT_USE_TK_TEXT;
+ } else {
+ macButtonPtr->usingControl=0;
+ macButtonPtr->useTkText=1;
+ }
+
+ /*
+ * set up clipping region
+ */
+
+ TkMacOSXSetUpClippingRgn(pixmap);
+
+ /*
+ * 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);
+ }
+ }
+
+ /*
+ * 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 (macButtonPtr->usingControl) {
+ borderWidth = 0;
+ /*
+ * This part uses Macintosh rather than Tk calls to draw
+ * to the screen. Make sure the ports etc. are set correctly.
+ */
+
+ destPort = TkMacOSXGetDrawablePort(pixmap);
+ SetGWorld(destPort, NULL);
+ 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;
+ }
+
+ /*
+ * 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;
+ }
+ haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
+ if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
+ imageXOffset = 0;
+ imageYOffset = 0;
+ 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;
+ }
+
+ if (butPtr->image != NULL) {
+ if ((butPtr->selectImage != NULL) &&
+ (butPtr->flags & SELECTED)) {
+ Tk_RedrawImage(butPtr->selectImage, 0, 0,
+ width, height, pixmap, x + imageXOffset,
+ y + imageYOffset);
+ } else {
+ Tk_RedrawImage(butPtr->image, 0, 0, width,
+ height, pixmap, x + imageXOffset,
+ y + imageYOffset);
+ }
+ } else {
+ XSetClipOrigin(butPtr->display, dpPtr->gc, x + imageXOffset,
+ y + imageYOffset);
+ XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
+ 0, 0, (unsigned int) width,
+ (unsigned int) height, x + imageXOffset,
+ y + 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) {
+ 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;
+ }
+ if (butPtr->image != NULL) {
+ if ((butPtr->selectImage != NULL) &&
+ (butPtr->flags & SELECTED)) {
+ Tk_RedrawImage(butPtr->selectImage, 0, 0, width,
+ height, pixmap, x, y);
+ } else {
+ Tk_RedrawImage(butPtr->image, 0, 0, width, height,
+ pixmap, x, y);
+ }
+ } 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 {
+ TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX,
+ butPtr->padY,
+ butPtr->indicatorSpace + butPtr->textWidth,
+ butPtr->textHeight, &x, &y);
+
+ x += butPtr->indicatorSpace;
+
+ if (macButtonPtr->useTkText) {
+ Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
+ butPtr->textLayout, x, y, 0, -1);
+ }
+ y += butPtr->textHeight/2;
+ }
+ }
+ }
+
+ /*
+ * If the button is disabled with a stipple rather than a special
+ * 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.
+ */
+
+ if (macButtonPtr->useTkText) {
+ if ((butPtr->state == STATE_DISABLED)
+ && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) {
+ if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
+ && (butPtr->selectBorder != NULL)) {
+ XSetForeground(butPtr->display, butPtr->disabledGC,
+ Tk_3DBorderColor(butPtr->selectBorder)->pixel);
+ }
+ XFillRectangle(butPtr->display, pixmap, butPtr->disabledGC,
+ butPtr->inset, butPtr->inset,
+ (unsigned) (Tk_Width(tkwin) - 2*butPtr->inset),
+ (unsigned) (Tk_Height(tkwin) - 2*butPtr->inset));
+ if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
+ && (butPtr->selectBorder != NULL)) {
+ XSetForeground(butPtr->display, butPtr->disabledGC,
+ 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);
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The button's window may change size.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpComputeButtonGeometry(
+ TkButton *butPtr) /* Button whose geometry may have changed. */
+{
+ int width, height, avgWidth, haveImage = 0, haveText = 0;
+ int xInset, yInset;
+ int 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;
+ } else if (butPtr->bitmap != None) {
+ 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);
+ }
+
+ /*
+ * If the button is compound (ie, it shows both an image and text),
+ * the new geometry is a combination of the image and text geometry.
+ * We only honor the compound bit if the button has both text and an
+ * image, because otherwise it is not really a compound button.
+ */
+
+ 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;
+
+ } 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;
+ }
+ }
+ }
+
+ /*
+ * Now figure out the size of the border decorations for the button.
+ */
+
+ if (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,
+ * 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,
+ * 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
+ * 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
+ * highlight width as there is also one pixel of spacing.
+ * 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;
+ }
+
+ 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;
+ }
+ }
+ } 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;
+ } else {
+ xInset = butPtr->indicatorSpace+butPtr->inset*2;
+ yInset = butPtr->inset*2;
+ }
+ Tk_GeometryRequest(butPtr->tkwin, width + xInset, height + yInset);
+ Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDestroyButton --
+ *
+ * Free data structures associated with the button control.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Restores the default control state.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpDestroyButton(
+ TkButton *butPtr)
+{
+ MacButton *mbPtr = ( MacButton *) butPtr; /* Mac button. */
+ if (mbPtr->userPane) {
+ DisposeControl(mbPtr->userPane);
+ mbPtr->userPane = NULL;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXInitControl --
+ *
+ * This procedure initialises a Carbon control
+ *
+ * Results:
+ * 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
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkMacOSXInitControl (
+ MacButton *mbPtr, /* Mac button. */
+ GWorldPtr destPort,
+ GC gc,
+ Pixmap pixmap,
+ Rect *paneRect,
+ Rect *cntrRect
+)
+{
+ OSErr status;
+ TkButton * butPtr = ( TkButton * )mbPtr;
+ ControlRef rootControl;
+ SInt16 procID;
+ Boolean initiallyVisible;
+ SInt16 initialValue;
+ SInt16 minValue;
+ SInt16 maxValue;
+ SInt32 controlReference;
+
+ rootControl = TkMacOSXGetRootControl(Tk_WindowId(butPtr->tkwin));
+ mbPtr->windowRef
+ = GetWindowFromPort(TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin)));
+
+ /*
+ * Set up the user pane
+ */
+
+ initiallyVisible=false;
+ 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 );
+
+ if (!mbPtr->userPane) {
+ fprintf(stderr,"Failed to create user pane control\n");
+ return 1;
+ }
+
+ if ((status=EmbedControl(mbPtr->userPane,rootControl))!=noErr) {
+ fprintf(stderr,"Failed to embed user pane control %d\n", status);
+ return 1;
+ }
+
+ SetUserPaneSetUpSpecialBackgroundProc(mbPtr->userPane,
+ 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 );
+
+ if (!mbPtr->control) {
+ fprintf(stderr,"failed to create control of type %d\n",procID);
+ return 1;
+ }
+
+ if (EmbedControl(mbPtr->control,mbPtr->userPane) != noErr ) {
+ fprintf(stderr,"failed to embed control of type %d\n",procID);
+ 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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 */
+
+{
+ TkButton * butPtr = ( TkButton *)mbPtr;
+ int err;
+ TkWindow * winPtr;
+ Rect paneRect;
+ Rect cntrRect;
+ int hilitePart = -1;
+
+
+ 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.bottom-=butPtr->inset;
+*/
+ 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
+ */
+
+ if (mbPtr->flags) {
+ MacControlParams params;
+ TkMacOSXComputeControlParams(butPtr, &params);
+ if (bcmp(&params, &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;
+ }
+ }
+ SetControlBounds(mbPtr->userPane, &paneRect);
+ SetControlBounds(mbPtr->control, &cntrRect);
+
+ if (!mbPtr->useTkText) {
+ Str255 controlTitle;
+ ControlFontStyleRec fontStyle;
+ Tk_Font font;
+ int len;
+
+ len = TkFontGetFirstTextLayout(butPtr->textLayout,
+ &font, controlTitle);
+ controlTitle[len] = 0;
+ if (bcmp(mbPtr->controlTitle, controlTitle, len+1)) {
+ CFStringRef cf;
+ cf = CFStringCreateWithCString(NULL,
+ 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) {
+ fprintf(stderr,"SetControlFontStyle failed\n");
+ }
+ bcopy(&fontStyle, &mbPtr->fontStyle,
+ sizeof(fontStyle));
+ }
+ }
+ }
+ if (mbPtr->params.isBevel) {
+ /* Initialiase the image/button parameters */
+ SetupBevelButton(mbPtr, mbPtr->control, destPort,
+ gc, pixmap);
+ }
+
+ if (butPtr->flags & SELECTED) {
+ SetControlValue(mbPtr->control, 1);
+ } else {
+ SetControlValue(mbPtr->control, 0);
+ }
+
+ if (!Tk_MacOSXIsAppInFront() || butPtr->state == STATE_DISABLED) {
+ HiliteControl(mbPtr->control, kControlInactivePart);
+ } else if (butPtr->state == STATE_ACTIVE) {
+ if (mbPtr->params.isBevel) {
+ HiliteControl(mbPtr->control, kControlButtonPart);
+ } else {
+ switch (butPtr->type) {
+ case TYPE_BUTTON:
+ HiliteControl(mbPtr->control, kControlButtonPart);
+ break;
+ case TYPE_RADIO_BUTTON:
+ HiliteControl(mbPtr->control, kControlRadioButtonPart);
+ break;
+ case TYPE_CHECK_BUTTON:
+ HiliteControl(mbPtr->control, kControlCheckBoxPart);
+ break;
+ }
+ }
+ } else {
+ HiliteControl(mbPtr->control, kControlNoPart);
+ }
+ 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 (mbPtr->flags&2) {
+ ShowControl(mbPtr->control);
+ ShowControl(mbPtr->userPane);
+ mbPtr->flags ^= 2;
+ } else {
+ Draw1Control(mbPtr->userPane);
+ SetControlVisibility(mbPtr->control, true, true);
+ }
+
+ if (mbPtr->params.isBevel) {
+ KillPicture(mbPtr->bevelButtonContent.u.picture);
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * SetupBevelButton --
+ *
+ * Sets up the Bevel Button with image by copying the
+ * source image onto the PicHandle for the button.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * 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 */
+ )
+{
+ int err;
+ TkButton *butPtr = ( TkButton *)mbPtr;
+ int height, width;
+ ControlButtonGraphicAlignment theAlignment;
+
+ SetPort(destPort);
+
+ if (butPtr->image != None) {
+ Tk_SizeOfImage(butPtr->image,
+ &width, &height);
+ } else {
+ Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap,
+ &width, &height);
+ }
+
+ if ((butPtr->width > 0) && (butPtr->width < width)) {
+ width = butPtr->width;
+ }
+ if ((butPtr->height > 0) && (butPtr->height < 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
+ */
+
+ if (!(mbPtr->bevelButtonContent.u.picture
+ = OpenCPicture(&mbPtr->picParams)) ) {
+ fprintf(stderr,"OpenCPicture failed\n");
+ }
+ tkPictureIsOpen = 1;
+
+ /*
+ * TO DO - There is one case where XCopyPlane calls CopyDeepMask,
+ * which does not get recorded in the picture. So the bitmap code
+ * will fail in that case.
+ */
+
+ if ((butPtr->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);
+ }
+
+ ClosePicture();
+ tkPictureIsOpen = 0;
+
+ if ( (err=SetControlData(controlHandle, kControlButtonPart,
+ kControlBevelButtonContentTag,
+ sizeof(ControlButtonContentInfo),
+ (char *) &mbPtr->bevelButtonContent)) != noErr ) {
+ fprintf(stderr,
+ "SetControlData BevelButtonContent failed, %d\n", err );
+ }
+
+ 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;
+ } else if (butPtr->anchor == TK_ANCHOR_SE) {
+ theAlignment = kControlBevelButtonAlignBottomRight;
+ } else if (butPtr->anchor == TK_ANCHOR_S) {
+ theAlignment = kControlBevelButtonAlignBottom;
+ } else if (butPtr->anchor == TK_ANCHOR_SW) {
+ theAlignment = kControlBevelButtonAlignBottomLeft;
+ } else if (butPtr->anchor == TK_ANCHOR_W) {
+ theAlignment = kControlBevelButtonAlignLeft;
+ } else if (butPtr->anchor == TK_ANCHOR_NW) {
+ theAlignment = kControlBevelButtonAlignTopLeft;
+ } else if (butPtr->anchor == TK_ANCHOR_CENTER) {
+ theAlignment = kControlBevelButtonAlignCenter;
+ }
+
+ if ((err=SetControlData(controlHandle, kControlButtonPart,
+ kControlBevelButtonGraphicAlignTag,
+ sizeof(ControlButtonGraphicAlignment),
+ (char *) &theAlignment)) != noErr ) {
+ fprintf(stderr,
+ "SetControlData BevelButtonGraphicAlign failed, %d\n", err );
+ }
+
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * SetUserPaneDrawProc --
+ *
+ * Utility function to add a UserPaneDrawProc
+ * to a userPane control. From MoreControls code
+ * from Apple DTS.
+ *
+ * Results:
+ * MacOS system error.
+ *
+ * Side effects:
+ * The user pane gets a new UserPaneDrawProc.
+ *
+ *--------------------------------------------------------------
+ */
+OSErr SetUserPaneDrawProc (
+ ControlRef control,
+ ControlUserPaneDrawProcPtr upp)
+{
+ ControlUserPaneDrawUPP myControlUserPaneDrawUPP;
+ myControlUserPaneDrawUPP = NewControlUserPaneDrawUPP(upp);
+ return SetControlData (control,
+ kControlNoPart, kControlUserPaneDrawProcTag,
+ sizeof(myControlUserPaneDrawUPP),
+ (Ptr) &myControlUserPaneDrawUPP);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * SetUserPaneSetUpSpecialBackgroundProc --
+ *
+ * Utility function to add a UserPaneBackgroundProc
+ * to a userPane control
+ *
+ * Results:
+ * MacOS system error.
+ *
+ * Side effects:
+ * The user pane gets a new UserPaneBackgroundProc.
+ *
+ *--------------------------------------------------------------
+ */
+OSErr
+SetUserPaneSetUpSpecialBackgroundProc(
+ ControlRef control,
+ ControlUserPaneBackgroundProcPtr upp)
+{
+ ControlUserPaneBackgroundUPP myControlUserPaneBackgroundUPP;
+ myControlUserPaneBackgroundUPP = NewControlUserPaneBackgroundUPP(upp);
+ return SetControlData (control, kControlNoPart,
+ kControlUserPaneBackgroundProcTag,
+ sizeof(myControlUserPaneBackgroundUPP),
+ (Ptr) &myControlUserPaneBackgroundUPP);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * UserPaneDraw --
+ *
+ * This function draws the background of the user pane that will
+ * lie under checkboxes and radiobuttons.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The user pane gets updated to the current color.
+ *
+ *--------------------------------------------------------------
+ */
+void
+UserPaneDraw(
+ ControlRef control,
+ ControlPartCode cpc)
+{
+ Rect contrlRect;
+ MacButton * mbPtr;
+ mbPtr = ( MacButton *)GetControlReference(control);
+ GetControlBounds(control,&contrlRect);
+ RGBBackColor (&mbPtr->userPaneBackground);
+ EraseRect (&contrlRect);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * UserPaneBackgroundProc --
+ *
+ * This function sets up the background of the user pane that will
+ * lie under checkboxes and radiobuttons.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The user pane background gets set to the current color.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+UserPaneBackgroundProc(
+ ControlHandle control,
+ ControlBackgroundPtr info)
+{
+ MacButton * mbPtr;
+ mbPtr = ( MacButton *)GetControlReference(control);
+ if (info->colorDevice) {
+ RGBBackColor (&mbPtr->userPaneBackground);
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * UpdateControlColors --
+ *
+ * This function will review the colors used to display
+ * a Macintosh button. If any non-standard colors are
+ * used we create a custom palette for the button, populate
+ * with the colors for the button and install the palette.
+ *
+ * Under Appearance, we just set the pointer that will be
+ * used by the UserPaneDrawProc.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The Macintosh control may get a custom palette installed.
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+UpdateControlColors(MacButton * mbPtr)
+{
+ XColor *xcolor;
+ 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.
+ * 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);
+ } else {
+ xcolor = Tk_3DBorderColor(butPtr->normalBorder);
+ }
+ TkSetMacColor(xcolor->pixel, &mbPtr->userPaneBackground);
+
+ return false;
+}
+/*
+ *--------------------------------------------------------------
+ *
+ * ButtonEventProc --
+ *
+ * This procedure is invoked by the Tk dispatcher for various
+ * events on buttons.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * When it gets exposed, it is redisplayed.
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+ButtonEventProc(
+ 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;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXComputeControlParams --
+ *
+ * This procedure computes the various parameters used
+ * when creating a Carbon control (NewControl)
+ * These are determined by the various tk button parameters
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Sets the control initialisation parameters
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TkMacOSXComputeControlParams(TkButton * butPtr, MacControlParams * paramsPtr )
+{
+ paramsPtr->isBevel = 0;
+
+ /*
+ * 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;
+ }
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXComputeDrawParams --
+ *
+ * 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.
+ *
+ * Side effects:
+ * Sets the button draw parameters
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TkMacOSXComputeDrawParams(TkButton * butPtr, DrawParams * dpPtr)
+{
+ 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;
+ } else {
+ dpPtr->gc = butPtr->normalTextGC;
+ }
+
+ 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.
+ * However, don't do this in the presence of Appearance, since
+ * then the bevel button will take care of the relief.
+ */
+
+ 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;
+ }
+ }
+
+ /*
+ * Determine the draw type
+ */
+ if (butPtr->type == TYPE_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;
+ }
+ }
+ }
+ } 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;
+ }
+ }
+
+ if ((dpPtr->drawType == DRAW_CONTROL) || (dpPtr->drawType == DRAW_BEVEL)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
diff --git a/macosx/tkMacOSXClipboard.c b/macosx/tkMacOSXClipboard.c
new file mode 100644
index 0000000..7bfa7ce
--- /dev/null
+++ b/macosx/tkMacOSXClipboard.c
@@ -0,0 +1,321 @@
+/*
+ * tkMacOSXClipboard.c --
+ *
+ * This file manages the clipboard for the Tk toolkit.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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 2002/08/31 06:12:29 das Exp $
+ */
+
+#include "tkInt.h"
+#include "tkPort.h"
+#include "tkMacOSXInt.h"
+#include "tkSelect.h"
+
+#include <Carbon/Carbon.h>
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkSelGetSelection --
+ *
+ * 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.
+ *
+ * Side effects:
+ * 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. */
+{
+ int result;
+ int err;
+ long length;
+ ScrapRef scrapRef;
+ 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;
+ }
+
+ 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;
+
+ 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_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);
+ return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkSetSelectionOwner --
+ *
+ * This function claims ownership of the specified selection.
+ * If the selection is CLIPBOARD, then we empty the system
+ * clipboard.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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? */
+{
+ Tk_Window tkwin;
+ TkDisplay *dispPtr;
+
+ /*
+ * This is a gross hack because the Tk_InternAtom interface is broken.
+ * It expects a Tk_Window, even though it only needs a Tk_Display.
+ */
+
+ 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.
+ */
+
+ dispPtr = TkGetMainInfoList()->winPtr->dispPtr;
+ if (dispPtr->clipboardActive) {
+ return;
+ }
+ ClearCurrentScrap();
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkSelUpdateClipboard(
+ TkWindow *winPtr, /* Window associated with clipboard. */
+ TkClipboardTarget *targetPtr) /* Info about the content. */
+{
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkSelEventProc --
+ *
+ * This procedure is invoked whenever a selection-related
+ * event occurs.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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. */
+{
+ if (eventPtr->type == SelectionClear) {
+ TkSelClearSelection(tkwin, eventPtr);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkSelPropProc --
+ *
+ * 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.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkSelPropProc(
+ register XEvent *eventPtr) /* X PropertyChange event. */
+{
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkSuspendClipboard --
+ *
+ * Handle clipboard conversion as required by the suppend event.
+ * This function is also called on exit.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The local scrap is moved to the global scrap.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkSuspendClipboard()
+{
+ TkClipboardTarget *targetPtr;
+ TkClipboardBuffer *cbPtr;
+ TkDisplay *dispPtr;
+ char *buffer, *p, *endPtr, *buffPtr;
+ long length;
+ ScrapRef scrapRef;
+
+ dispPtr = TkGetDisplayList();
+ if ((dispPtr == NULL) || !dispPtr->clipboardActive) {
+ return;
+ }
+
+ for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
+ targetPtr = targetPtr->nextPtr) {
+ if (targetPtr->type == XA_STRING)
+ break;
+ }
+ if (targetPtr != NULL) {
+ Tcl_DString encodedText;
+
+ 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);
+ ckfree(buffer);
+ }
+
+ /*
+ * 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.)
+ */
+
+ if (TkGetMainInfoList() != NULL) {
+ Tk_ClearSelection((Tk_Window) TkGetMainInfoList()->winPtr,
+ Tk_InternAtom((Tk_Window) TkGetMainInfoList()->winPtr,
+ "CLIPBOARD"));
+ }
+
+ return;
+}
diff --git a/macosx/tkMacOSXColor.c b/macosx/tkMacOSXColor.c
new file mode 100644
index 0000000..492f098
--- /dev/null
+++ b/macosx/tkMacOSXColor.c
@@ -0,0 +1,448 @@
+/*
+ * 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.
+ *
+ * Copyright (c) 1990-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1996 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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 2002/08/31 06:12:29 das Exp $
+ */
+
+#include <tkColor.h>
+#include "tkMacOSXInt.h"
+#include <Carbon/Carbon.h>
+
+/*
+ * 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.
+ */
+/*
+ * Stubbed out for OS X
+static AuxCtlHandle defaultAuxCtlHandle = NULL;
+*/
+
+/*
+ * Forward declarations for procedures defined later in this file:
+ */
+
+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));
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkSetMacColor --
+ *
+ * Populates a Macintosh RGBColor structure from a X style
+ * pixel value.
+ *
+ * Results:
+ * Returns false if not a real pixel, true otherwise.
+ *
+ * Side effects:
+ * 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. */
+{
+ switch (pixel >> 24) {
+ case HIGHLIGHT_PIXEL:
+ LMGetHiliteRGB(macColor);
+ return true;
+ case HIGHLIGHT_TEXT_PIXEL:
+ 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;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Stub functions --
+ *
+ * These functions are just stubs for functions that either
+ * don't make sense on the Mac or have yet to be implemented.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * These calls do nothing - which may not be expected.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Status
+XAllocColor(
+ Display *display, /* Display. */
+ Colormap map, /* Not used. */
+ XColor *colorPtr) /* XColor struct to modify. */
+{
+ display->request++;
+ colorPtr->pixel = TkpGetPixel(colorPtr);
+ return 1;
+}
+
+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++;
+}
+
+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. */
+{
+ /*
+ * 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.
+ */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetColor --
+ *
+ * Allocate a new TkColor for the color with the given name.
+ *
+ * Results:
+ * 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.
+ *
+ *----------------------------------------------------------------------
+ */
+
+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). */
+{
+ Display *display = Tk_Display(tkwin);
+ Colormap colormap = Tk_Colormap(tkwin);
+ TkColor *tkColPtr;
+ XColor color;
+
+ /*
+ * Check to see if this is a system color. Otherwise, XParseColor
+ * will do all the work.
+ */
+ if (strncasecmp(name, "system", 6) == 0) {
+ int foundSystemColor = false;
+ RGBColor rgbValue;
+ char pixelCode = 0;
+
+ if (!strcasecmp(name+6, "Highlight")) {
+ LMGetHiliteRGB(&rgbValue);
+ pixelCode = HIGHLIGHT_PIXEL;
+ foundSystemColor = true;
+ } else if (!strcasecmp(name+6, "HighlightText")) {
+ LMGetHiliteRGB(&rgbValue);
+ 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;
+ }
+
+ tkColPtr = (TkColor *) ckalloc(sizeof(TkColor));
+ tkColPtr->color = color;
+
+ return tkColPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * Side effects:
+ * 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. */
+{
+ TkColor *tkColPtr = (TkColor *) ckalloc(sizeof(TkColor));
+
+ tkColPtr->color.red = colorPtr->red;
+ tkColPtr->color.green = colorPtr->green;
+ tkColPtr->color.blue = colorPtr->blue;
+ tkColPtr->color.pixel = TkpGetPixel(&tkColPtr->color);
+ return tkColPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetControlPartColor --
+ *
+ * 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 'cctb' 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
+GetControlPartColor(
+ short part, /* Part code. */
+ RGBColor *macColor) /* Pointer to Mac color. */
+{
+/* Stubbed out for OS X
+ short index;
+ CCTabHandle ccTab;
+
+ if (defaultAuxCtlHandle == NULL) {
+ GetAuxiliaryControlRecord(NULL, &defaultAuxCtlHandle);
+ }
+ ccTab = (**defaultAuxCtlHandle).acCTable;
+ if(ccTab && (ResError() == noErr)) {
+ for(index = 0; index <= (**ccTab).ctSize; index++) {
+ if((**ccTab).ctTable[index].value == part) {
+ *macColor = (**ccTab).ctTable[index].rgb;
+ return true;
+ }
+ }
+ }
+*/
+ return false;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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. */
+{
+ short index;
+ WCTabHandle wcTab;
+
+ 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;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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 */
+{
+
+ /* 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;
+}
diff --git a/macosx/tkMacOSXConfig.c b/macosx/tkMacOSXConfig.c
new file mode 100644
index 0000000..a89d51f
--- /dev/null
+++ b/macosx/tkMacOSXConfig.c
@@ -0,0 +1,46 @@
+/*
+ * tkMacOSXConfig.c --
+ *
+ * This module implements the Macintosh system defaults for
+ * the configuration package.
+ *
+ * Copyright (c) 1997 by Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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 2002/08/31 06:12:29 das Exp $
+ */
+
+#include "tk.h"
+#include "tkInt.h"
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetSystemDefault --
+ *
+ * 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.
+ *
+ * Side effects:
+ * 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. */
+{
+ return NULL;
+}
diff --git a/macosx/tkMacOSXCursor.c b/macosx/tkMacOSXCursor.c
new file mode 100644
index 0000000..a1bbbb4
--- /dev/null
+++ b/macosx/tkMacOSXCursor.c
@@ -0,0 +1,406 @@
+/*
+ * tkMacOSXCursor.c --
+ *
+ * This file contains Macintosh specific cursor related routines.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.2 2002/08/31 06:12:29 das Exp $
+ */
+
+#include "tkPort.h"
+#include "tkInt.h"
+#include "tkMacOSXInt.h"
+
+#include <Carbon/Carbon.h>
+
+/*
+ * There are three different ways to set the cursor on the Mac.
+ */
+#define ARROW 0 /* The arrow cursor. */
+#define COLOR 1 /* Cursors of type crsr. */
+#define NORMAL 2 /* Cursors of type CURS. */
+
+/*
+ * The following data structure contains the system specific data
+ * necessary to control Windows cursors.
+ */
+
+typedef struct {
+ TkCursor info; /* Generic cursor info used by tkCursor.c */
+ Handle macCursor; /* Resource containing Macintosh cursor. */
+ int type; /* Type of Mac cursor: arrow, crsr, CURS */
+} TkMacOSXCursor;
+
+/*
+ * The table below is used to map from the name of a predefined cursor
+ * to its resource identifier.
+ */
+
+static struct CursorName {
+ char *name;
+ int id;
+} cursorNames[] = {
+ {"ibeam", 1},
+ {"text", 1},
+ {"xterm", 1},
+ {"cross", 2},
+ {"crosshair", 2},
+ {"cross-hair", 2},
+ {"plus", 3},
+ {"watch", 4},
+ {"arrow", 5},
+ {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 */
+
+/*
+ * Declarations of procedures local to this file
+ */
+
+static void FindCursorByName _ANSI_ARGS_ ((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.
+ *
+ * Results:
+ * Fills the macCursorPtr record.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+FindCursorByName(
+ TkMacOSXCursor *macCursorPtr,
+ CONST char *string)
+{
+ Handle resource;
+ Str255 curName;
+ int destWrote, inCurLen;
+
+ inCurLen = strlen(string);
+ if (inCurLen > 255) {
+ 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 */
+ curName[0] = destWrote;
+
+ 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;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkGetCursorByName --
+ *
+ * Retrieve a system cursor by name.
+ *
+ * Results:
+ * Returns a new cursor, or NULL on errors.
+ *
+ * Side effects:
+ * 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. */
+{
+ struct CursorName *namePtr;
+ TkMacOSXCursor *macCursorPtr;
+
+ macCursorPtr = (TkMacOSXCursor *) ckalloc(sizeof(TkMacOSXCursor));
+ macCursorPtr->info.cursor = (Tk_Cursor) macCursorPtr;
+
+ /*
+ * To find a cursor we must first determine if it is one of the
+ * builtin cursors or the standard arrow cursor. Otherwise, we
+ * attempt to load the cursor as a named Mac resource.
+ */
+
+ for (namePtr = cursorNames; namePtr->name != NULL; namePtr++) {
+ if (strcmp(namePtr->name, string) == 0) {
+ break;
+ }
+ }
+
+
+ if (namePtr->name != NULL) {
+ if (namePtr->id == 5) {
+ macCursorPtr->macCursor = (Handle) -1;
+ macCursorPtr->type = ARROW;
+ } else {
+ macCursorPtr->macCursor = (Handle) GetCursor(namePtr->id);
+ macCursorPtr->type = NORMAL;
+ }
+ } else {
+ 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 (macCursorPtr->macCursor == NULL) {
+ ckfree((char *)macCursorPtr);
+ Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"",
+ (char *) NULL);
+ return NULL;
+ } else {
+ return (TkCursor *) macCursorPtr;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkCreateCursorFromData --
+ *
+ * Creates a cursor from the source and mask bits.
+ *
+ * Results:
+ * Returns a new cursor, or NULL on errors.
+ *
+ * Side effects:
+ * 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. */
+{
+ return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpFreeCursor --
+ *
+ * This procedure is called to release a cursor allocated by
+ * TkGetCursorByName.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The cursor data structure is deallocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpFreeCursor(
+ TkCursor *cursorPtr)
+{
+ TkMacOSXCursor *macCursorPtr = (TkMacOSXCursor *) cursorPtr;
+
+ switch (macCursorPtr->type) {
+ case COLOR:
+ DisposeCCursor((CCrsrHandle) macCursorPtr->macCursor);
+ break;
+ case NORMAL:
+ ReleaseResource(macCursorPtr->macCursor);
+ break;
+ }
+
+ if (macCursorPtr == gCurrentCursor) {
+ gCurrentCursor = NULL;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXInstallCursor --
+ *
+ * Installs either the current cursor as defined by TkpSetCursor
+ * or a resize cursor as the cursor the Macintosh should currently
+ * display.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes the Macintosh mouse cursor.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXInstallCursor(
+ int resizeOverride)
+{
+ TkMacOSXCursor *macCursorPtr = gCurrentCursor;
+ CCrsrHandle ccursor;
+ CursHandle cursor;
+
+ gResizeOverride = resizeOverride;
+
+ if (resizeOverride) {
+ cursor = (CursHandle) GetNamedResource('CURS', "\presize");
+ if (cursor) {
+ SetCursor(*cursor);
+ } else {
+ /*
+ fprintf(stderr,"Resize cursor failed, %d\n", ResError());
+ */
+ }
+ } else if (macCursorPtr == NULL || macCursorPtr->type == ARROW) {
+ SetThemeCursor(kThemeArrowCursor);
+ } else {
+ switch (macCursorPtr->type) {
+ case COLOR:
+ ccursor = (CCrsrHandle) macCursorPtr->macCursor;
+ SetCCursor(ccursor);
+ break;
+ case NORMAL:
+ cursor = (CursHandle) macCursorPtr->macCursor;
+ SetCursor(*cursor);
+ break;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpSetCursor --
+ *
+ * Set the current cursor and install it.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes the current cursor.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpSetCursor(
+ TkpCursor cursor)
+{
+ if (!gTkOwnsCursor) {
+ return;
+ }
+ if (cursor == None) {
+ gCurrentCursor = NULL;
+ } else {
+ gCurrentCursor = (TkMacOSXCursor *) cursor;
+ }
+
+ if (Tk_MacOSXIsAppInFront()) {
+ TkMacOSXInstallCursor(gResizeOverride);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_MacOSXTkOwnsCursor --
+ *
+ * Sets whether Tk has the right to adjust the cursor.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May keep Tk from changing the cursor.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_MacOSXTkOwnsCursor(
+ int tkOwnsIt)
+{
+ gTkOwnsCursor = tkOwnsIt;
+}
diff --git a/macosx/tkMacOSXCursors.r b/macosx/tkMacOSXCursors.r
new file mode 100644
index 0000000..51abc74
--- /dev/null
+++ b/macosx/tkMacOSXCursors.r
@@ -0,0 +1,130 @@
+/*
+ * tkMacOSXCursors.r --
+ *
+ * This file defines a set of Macintosh cursor resources that
+ * 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 $
+ */
+
+/*
+ * These are resource definitions for Macintosh cursors.
+ * The are identified and loaded by the "name" of the
+ * cursor. However, the ids must be unique.
+ */
+
+data 'CURS' (1000, "hand") {
+ $"0180 1A70 2648 264A 124D 1249 6809 9801"
+ $"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"
+};
+
+data 'CURS' (1002, "bucket") {
+ $"0000 0000 0600 0980 0940 0B30 0D18 090C"
+ $"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"
+};
+
+data 'CURS' (1003, "cancel") {
+ $"0000 0000 0000 0000 3180 4A40 4A40 3F80"
+ $"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"
+};
+
+data 'CURS' (1004, "resize") {
+ $"FFFF 8001 BF01 A181 A1F9 A18D A18D BF8D"
+ $"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"
+};
+
+data 'CURS' (1005, "eyedrop") {
+ $"000E 001F 001F 00FF 007E 00B8 0118 0228"
+ $"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"
+};
+
+data 'CURS' (1006, "eyedrop-full") {
+ $"000E 001F 001F 00FF 007E 00B8 0118 0328"
+ $"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"
+};
+
+data 'CURS' (1007, "zoom-in") {
+ $"0780 1860 2790 5868 5028 A014 AFD4 AFD4"
+ $"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"
+};
+
+data 'CURS' (1008, "zoom-out") {
+ $"0780 1860 2790 5868 5328 A314 AFD4 AFD4"
+ $"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"
+};
+
+/*
+ * 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
+ * same name preference will be given to the color
+ * cursors.
+ */
+
+data 'crsr' (1000, "hand") {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 0180 1A70 2648 264A 124D 1249"
+ $"6809 9801 8802 4002 2002 2004 1004 0808"
+ $"0408 0408 0180 1BF0 3FF8 3FFA 1FFF 1FFF"
+ $"6FFF FFFF FFFE 7FFE 3FFE 3FFC 1FFC 0FF8"
+ $"07F8 07F8 0008 0008 0000 0000 0000 0000"
+ $"0000 0000 8004 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0002 0001 0002 0000 0000 0000 00D2 0000"
+ $"0000 0003 C000 03CD 7F00 0D7D 75C0 0D7D"
+ $"75CC 035D 75F7 035D 75D7 3CD5 55D7 D7D5"
+ $"5557 D5D5 555C 3555 555C 0D55 555C 0D55"
+ $"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"
+};
+
+data 'crsr' (1001, "fist") {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0DB0 124C"
+ $"100A 0802 1802 2002 2002 2004 1004 0808"
+ $"0408 0408 0000 0000 0000 0000 0DB0 1FFC"
+ $"1FFE 0FFE 1FFE 3FFE 3FFE 3FFC 1FFC 0FF8"
+ $"07F8 07F8 0008 0008 0000 0000 0000 0000"
+ $"0000 0000 8004 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0002 0001 0002 0000 0000 0000 00D2 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 00F3 CF00 035D 75F0 0355 55DC 00D5"
+ $"555C 03D5 555C 0D55 555C 0D55 555C 0D55"
+ $"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"
+};
+
diff --git a/macosx/tkMacOSXDebug.c b/macosx/tkMacOSXDebug.c
new file mode 100644
index 0000000..53997e8
--- /dev/null
+++ b/macosx/tkMacOSXDebug.c
@@ -0,0 +1,439 @@
+/*
+ * tkMacOSXDebug.c --
+ *
+ * Implementation of Macintosh specific functions for debugging MacOS events,
+ * regions, etc...
+ *
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.
+ */
+
+#include "tkMacOSXDebug.h"
+
+typedef struct {
+ EventKind kind;
+ char * name;
+} MyEventName;
+
+typedef struct {
+ EventClass c;
+ MyEventName * names;
+} MyEventNameList;
+
+static MyEventName windowEventNames [] = {
+ { kEventWindowUpdate,"Update"},
+ { kEventWindowDrawContent,"DrawContent"},
+ { kEventWindowActivated,"Activated"},
+ { kEventWindowDeactivated,"Deactivated"},
+ { kEventWindowGetClickActivation,"GetClickActivation"},
+ { kEventWindowShowing,"Showing"},
+ { kEventWindowHiding,"Hiding"},
+ { kEventWindowShown,"Shown"},
+ { kEventWindowHidden,"Hidden"},
+ { kEventWindowBoundsChanging,"BoundsChanging"},
+ { kEventWindowBoundsChanged,"BoundsChanged"},
+ { kEventWindowResizeStarted,"ResizeStarted"},
+ { kEventWindowResizeCompleted,"ResizeCompleted"},
+ { kEventWindowDragStarted,"DragStarted"},
+ { kEventWindowDragCompleted,"DragCompleted"},
+ { kEventWindowClickDragRgn,"ClickDragRgn"},
+ { kEventWindowClickResizeRgn,"ClickResizeRgn"},
+ { kEventWindowClickCollapseRgn,"ClickCollapseRgn"},
+ { kEventWindowClickCloseRgn,"ClickCloseRgn"},
+ { kEventWindowClickZoomRgn,"ClickZoomRgn"},
+ { kEventWindowClickContentRgn,"ClickContentRgn"},
+ { kEventWindowClickProxyIconRgn,"ClickProxyIconRgn"},
+ { kEventWindowCursorChange,"CursorChange" },
+ { kEventWindowCollapse,"Collapse"},
+ { kEventWindowCollapsed,"Collapsed"},
+ { kEventWindowCollapseAll,"CollapseAll"},
+ { kEventWindowExpand,"Expand"},
+ { kEventWindowExpanded,"Expanded"},
+ { kEventWindowExpandAll,"ExpandAll"},
+ { kEventWindowCollapse,"Collapse"},
+ { kEventWindowClose,"Close"},
+ { kEventWindowClosed,"Closed"},
+ { kEventWindowCloseAll,"CloseAll"},
+ { kEventWindowZoom,"Zoom"},
+ { kEventWindowZoomed,"Zoomed"},
+ { kEventWindowZoomAll,"ZoomAll"},
+ { kEventWindowContextualMenuSelect,"ContextualMenuSelect"},
+ { kEventWindowPathSelect,"PathSelect"},
+ { kEventWindowGetIdealSize,"GetIdealSize"},
+ { kEventWindowGetMinimumSize,"GetMinimumSize"},
+ { kEventWindowGetMaximumSize,"GetMaximumSize"},
+ { kEventWindowConstrain,"Constrain"},
+ { kEventWindowHandleContentClick,"HandleContentClick"},
+ { kEventWindowProxyBeginDrag,"ProxyBeginDra}"},
+ { kEventWindowProxyEndDrag,"ProxyEndDrag"},
+ { kEventWindowFocusAcquired,"FocusAcquired"},
+ { kEventWindowFocusRelinquish,"FocusRelinquish"},
+ { kEventWindowDrawFrame,"DrawFrame"},
+ { kEventWindowDrawPart,"DrawPart"},
+ { kEventWindowGetRegion,"GetRegion"},
+ { kEventWindowHitTest,"HitTest"},
+ { kEventWindowInit,"Init"},
+ { kEventWindowDispose,"Dispose"},
+ { kEventWindowDragHilite,"DragHilite"},
+ { kEventWindowModified,"Modified"},
+ { kEventWindowSetupProxyDragImage,"SetupProxyDragImage"},
+ { kEventWindowStateChanged,"StateChanged"},
+ { kEventWindowMeasureTitle,"MeasureTitle"},
+ { kEventWindowDrawGrowBox,"DrawGrowBox"},
+ { kEventWindowGetGrowImageRegion,"GetGrowImageRegion"},
+ { kEventWindowPaint,"Paint"},
+ { 0, NULL },
+};
+
+static MyEventName mouseEventNames [] = {
+ { kEventMouseMoved, "Moved"},
+ { kEventMouseUp, "Up"},
+ { kEventMouseDown, "Down"},
+ { kEventMouseDragged, "Dragged"},
+ { kEventMouseWheelMoved, "WheelMoved"},
+ { 0, NULL}
+};
+
+static MyEventName keyboardEventNames [] = {
+ { kEventRawKeyDown, "Down"},
+ { kEventRawKeyRepeat, "Repeat"},
+ { kEventRawKeyUp, "Up"},
+ { kEventRawKeyModifiersChanged, "ModifiersChanged"},
+ { kEventHotKeyPressed, "HotKeyPressed"},
+ { kEventHotKeyReleased, "HotKeyReleased"},
+ { 0, NULL}
+};
+
+static MyEventName appEventNames [] = {
+ { kEventAppActivated, "Activated"},
+ { kEventAppDeactivated, "Deactivated"},
+ { kEventAppQuit, "Quit"},
+ { kEventAppLaunchNotification, "LaunchNotification"},
+ { kEventAppLaunched, "Launched"},
+ { kEventAppTerminated, "Terminated"},
+ { kEventAppFrontSwitched, "FrontSwitched"},
+ { 0, NULL}
+};
+
+static MyEventName menuEventNames [] = {
+ { kEventMenuBeginTracking, "BeginTracking"},
+ { kEventMenuEndTracking, "EndTracking"},
+ { kEventMenuChangeTrackingMode, "ChangeTrackingMode"},
+ { kEventMenuOpening, "Opening"},
+ { kEventMenuClosed, "Closed"},
+ { kEventMenuTargetItem, "TargetItem"},
+ { kEventMenuMatchKey, "MatchKey"},
+ { kEventMenuEnableItems, "EnableItems"},
+ { kEventMenuDispose, "Dispose"},
+ { 0, NULL }
+};
+
+static MyEventName controlEventNames [] = {
+ { kEventControlInitialize, "Initialize" },
+ { kEventControlDispose, "Dispose" },
+ { kEventControlGetOptimalBounds, "GetOptimalBounds" },
+ { kEventControlHit, "Hit" },
+ { kEventControlSimulateHit, "SimulateHit" },
+ { kEventControlHitTest, "HitTest" },
+ { kEventControlDraw, "Draw" },
+ { kEventControlApplyBackground, "ApplyBackground" },
+ { kEventControlApplyTextColor, "ApplyTextColor" },
+ { kEventControlSetFocusPart, "SetFocusPart" },
+ { kEventControlGetFocusPart, "GetFocusPart" },
+ { kEventControlActivate, "Activate" },
+ { kEventControlDeactivate, "Deactivate" },
+ { kEventControlSetCursor, "SetCursor" },
+ { kEventControlContextualMenuClick, "ContextualMenuClick" },
+ { kEventControlClick, "Click" },
+ { kEventControlTrack, "Track" },
+ { kEventControlGetScrollToHereStartPoint, "GetScrollToHereStartPoint" },
+ { kEventControlGetIndicatorDragConstraint, "GetIndicatorDragConstraint" },
+ { kEventControlIndicatorMoved, "IndicatorMoved" },
+ { kEventControlGhostingFinished, "GhostingFinished" },
+ { kEventControlGetActionProcPart, "GetActionProcPart" },
+ { kEventControlGetPartRegion, "GetPartRegion" },
+ { kEventControlGetPartBounds, "GetPartBounds" },
+ { kEventControlSetData, "SetData" },
+ { kEventControlGetData, "GetData" },
+ { kEventControlValueFieldChanged, "ValueFieldChanged" },
+ { kEventControlAddedSubControl, "AddedSubControl" },
+ { kEventControlRemovingSubControl, "RemovingSubControl" },
+ { kEventControlBoundsChanged, "BoundsChanged" },
+ { kEventControlOwningWindowChanged, "OwningWindowChanged" },
+ { kEventControlArbitraryMessage, "ArbitraryMessage" },
+ { 0, NULL }
+};
+
+
+static MyEventName commandEventNames [] = {
+ { kEventCommandProcess, "Process" },
+ { kEventCommandUpdateStatus, "UpdateStatus" },
+ { 0, NULL }
+};
+
+static MyEventNameList eventNameList [] = {
+ { kEventClassWindow, windowEventNames },
+ { kEventClassMouse, mouseEventNames },
+ { kEventClassKeyboard, keyboardEventNames },
+ { kEventClassApplication, appEventNames },
+ { kEventClassMenu, menuEventNames },
+ { kEventClassControl, controlEventNames },
+ { kEventClassCommand, commandEventNames },
+ { 0, NULL}
+};
+
+
+MyEventName classicEventNames [] = {
+ { nullEvent,"nullEvent" },
+ { mouseDown,"mouseDown" },
+ { mouseUp,"mouseUp" },
+ { keyDown,"keyDown" },
+ { keyUp,"keyUp" },
+ { autoKey,"autoKey" },
+ { updateEvt,"updateEvt" },
+ { diskEvt,"diskEvt" },
+ { activateEvt,"activateEvt" },
+ { osEvt,"osEvt" },
+ { kHighLevelEvent,"kHighLevelEvent" },
+ { 0, NULL }
+};
+
+char *
+CarbonEventToAscii(EventRef eventRef, char * buf)
+{
+ EventClass eventClass;
+ EventKind eventKind;
+ MyEventNameList * list = eventNameList;
+ MyEventName * names = NULL;
+ int * iPtr = ( int * )buf;
+ char * iBuf = buf;
+ int found = 0;
+
+ eventClass = GetEventClass(eventRef);
+ eventKind = GetEventKind(eventRef);
+
+ *iPtr = eventClass;
+ buf [ 4 ] = 0;
+ strcat(buf, " ");
+ buf += strlen(buf);
+ while (list->names && (!names) ) {
+ 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 );
+ }
+ return iBuf;
+}
+
+char * CarbonEventKindToAscii(EventRef eventRef, char * buf )
+{
+ EventClass eventClass;
+ EventKind eventKind;
+ MyEventNameList * list = eventNameList;
+ MyEventName * names = NULL;
+ int found = 0;
+ eventClass = GetEventClass(eventRef);
+ eventKind = GetEventKind(eventRef);
+ while (list->names && (!names) ) {
+ if (eventClass == list -> c) {
+ names = list -> names;
+ } else {
+ list++;
+ }
+ }
+ if (names) {
+ found=0;
+ while ( names->name && !found ) {
+ if (eventKind==names->kind) {
+ sprintf(buf,"%s",names->name);
+ found=1;
+ } else {
+ names++;
+ }
+ }
+ }
+ if (!found) {
+ sprintf ( buf,"%d", eventKind );
+ } else {
+ sprintf ( buf,"%d", eventKind );
+ }
+ return buf;
+}
+
+char * ClassicEventToAscii(EventRecord * eventPtr, char * buf )
+{
+ 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 (!found) {
+ sprintf(buf,"%-16d %08x %08x, %s",
+ eventPtr->what, (int) eventPtr->message,
+ eventPtr->modifiers, buf);
+ }
+ return buf;
+
+}
+
+void printPoint(char * tag, Point * p )
+{
+ fprintf(stderr,"%s %4d %4d\n",
+ tag,p->h,p->v );
+}
+
+void printRect(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 );
+}
+
+void printRegion(char * tag, RgnHandle rgn )
+{
+ Rect r;
+ GetRegionBounds(rgn,&r);
+ printRect(tag,&r);
+}
+
+void printWindowTitle(char * tag, WindowRef window )
+{
+ Str255 title;
+ GetWTitle(window,title);
+ title [ title[0] + 1 ] = 0;
+ fprintf(stderr, "%s %s\n", tag, title +1 );
+}
+
+typedef struct {
+ int msg;
+ char * name;
+} MsgName;
+
+MsgName msgNames [] = {
+ { kMenuDrawMsg, "Draw"},
+ { kMenuSizeMsg, "Size"},
+ { kMenuPopUpMsg, "PopUp"},
+ { kMenuCalcItemMsg, "CalcItem" },
+ { kMenuThemeSavvyMsg, "ThemeSavvy"},
+ { kMenuInitMsg, "Init" },
+ { kMenuDisposeMsg, "Dispose" },
+ { kMenuFindItemMsg, "FindItem" },
+ { kMenuHiliteItemMsg, "HiliteItem" },
+ { kMenuDrawItemsMsg, "DrawItems" },
+ { -1, NULL }
+};
+
+
+char *
+TkMacOSXMenuMessageToAscii(int msg, char * s)
+{
+ MsgName * msgNamePtr;
+ for (msgNamePtr = msgNames;msgNamePtr->name;) {
+ if (msgNamePtr->msg==msg) {
+ strcpy(s,msgNamePtr->name);
+ return s;
+ } else {
+ msgNamePtr++;
+ }
+ }
+ sprintf(s,"unknown : %d", msg );
+ return s;
+}
+
+
+char * MouseTrackingResultToAscii(MouseTrackingResult r, char * buf)
+{
+ MsgName trackingNames [] = {
+ { kMouseTrackingMousePressed , "MousePressed " },
+ { kMouseTrackingMouseReleased , "MouseReleased " },
+ { kMouseTrackingMouseExited , "MouseExited " },
+ { kMouseTrackingMouseEntered , "MouseEntered " },
+ { kMouseTrackingMouseMoved , "MouseMoved " },
+ { kMouseTrackingKeyModifiersChanged, "KeyModifiersChanged" },
+ { kMouseTrackingUserCancelled , "UserCancelled " },
+ { kMouseTrackingTimedOut , "TimedOut " },
+ { -1, NULL }
+ };
+ MsgName * namePtr;
+ for (namePtr=trackingNames;namePtr->name;namePtr++) {
+ if (namePtr->msg==r) {
+ strcpy(buf,namePtr->name);
+ return buf;
+ }
+ }
+ sprintf(buf, "Unknown mouse tracking result : %d", r);
+ return buf;
+}
diff --git a/macosx/tkMacOSXDebug.h b/macosx/tkMacOSXDebug.h
new file mode 100644
index 0000000..0b3185d
--- /dev/null
+++ b/macosx/tkMacOSXDebug.h
@@ -0,0 +1,69 @@
+/*
+ * tkMacOSXDebug.h --
+ *
+ * Declarations of Macintosh specific functions for debugging MacOS events,
+ * regions, etc...
+ *
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _TKMACDEBUG
+#define _TKMACDEBUG
+#include <Carbon/Carbon.h>
+
+char * CarbonEventToAscii(EventRef eventRef, char * buf );
+char * ClassicEventToAscii(EventRecord * eventPtr, char * buf );
+
+void printRect(char * tag, Rect * r );
+void printPoint(char * tag, Point * p );
+
+void printRegion(char * tag, RgnHandle rgn );
+void printWindowTitle(char * tag, WindowRef window );
+char * TkMacOSXMenuMessageToAscii(int msg, char * s);
+
+char * MouseTrackingResultToAscii(MouseTrackingResult r, char * buf );
+#endif
diff --git a/macosx/tkMacOSXDefault.h b/macosx/tkMacOSXDefault.h
new file mode 100644
index 0000000..13a05ce
--- /dev/null
+++ b/macosx/tkMacOSXDefault.h
@@ -0,0 +1,531 @@
+/*
+ * tkMacOSXDefault.h --
+ *
+ * This file defines the defaults for all options for all of
+ * the Tk widgets.
+ *
+ * Copyright (c) 1991-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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 2002/08/31 06:12:29 das Exp $
+ */
+
+#ifndef _TKMACDEFAULT
+#define _TKMACDEFAULT
+
+/*
+ * The definitions below provide symbolic names for the default colors.
+ * NORMAL_BG - Normal background color.
+ * ACTIVE_BG - Background color when widget is active.
+ * SELECT_BG - Background color for selected text.
+ * SELECT_FG - Foreground color for selected text.
+ * TROUGH - Background color for troughs in scales and scrollbars.
+ * INDICATOR - Color for indicator when button is selected.
+ * 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 TROUGH "#c3c3c3"
+#define INDICATOR "#b03060"
+#define DISABLED "#a3a3a3"
+
+/*
+ * Defaults for labels, buttons, checkbuttons, and radiobuttons:
+ */
+
+#define DEF_BUTTON_ANCHOR "center"
+#define DEF_BUTTON_ACTIVE_BG_COLOR "systemButtonText"
+#define DEF_BUTTON_ACTIVE_BG_MONO BLACK
+#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 WHITE
+#define DEF_BUTTON_BG_MONO WHITE
+#define DEF_BUTTON_BITMAP ""
+#define DEF_BUTTON_BORDER_WIDTH "2"
+#define DEF_BUTTON_CURSOR ""
+#define DEF_BUTTON_COMMAND ""
+#define DEF_BUTTON_COMPOUND "none"
+#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_CHKRAD_FG DEF_BUTTON_FG
+#define DEF_BUTTON_FONT "system"
+#define DEF_BUTTON_HEIGHT "0"
+#define DEF_BUTTON_HIGHLIGHT_BG_COLOR DEF_BUTTON_BG_COLOR
+#define DEF_BUTTON_HIGHLIGHT_BG_MONO DEF_BUTTON_BG_MONO
+#define DEF_BUTTON_HIGHLIGHT "systemButtonFrame"
+#define DEF_LABEL_HIGHLIGHT_WIDTH "0"
+#define DEF_BUTTON_HIGHLIGHT_WIDTH "4"
+#define DEF_BUTTON_IMAGE (char *) NULL
+#define DEF_BUTTON_INDICATOR "1"
+#define DEF_BUTTON_JUSTIFY "center"
+#define DEF_BUTTON_OFF_VALUE "0"
+#define DEF_BUTTON_ON_VALUE "1"
+#define DEF_BUTTON_OVER_RELIEF ""
+#define DEF_BUTTON_PADX "12"
+#define DEF_LABCHKRAD_PADX "1"
+#define DEF_BUTTON_PADY "3"
+#define DEF_LABCHKRAD_PADY "1"
+#define DEF_BUTTON_RELIEF "flat"
+#define DEF_LABCHKRAD_RELIEF "flat"
+#define DEF_BUTTON_REPEAT_DELAY "0"
+#define DEF_BUTTON_REPEAT_INTERVAL "0"
+#define DEF_BUTTON_SELECT_COLOR INDICATOR
+#define DEF_BUTTON_SELECT_MONO BLACK
+#define DEF_BUTTON_SELECT_IMAGE (char *) NULL
+#define DEF_BUTTON_STATE "normal"
+#define DEF_LABEL_TAKE_FOCUS "0"
+#define DEF_BUTTON_TAKE_FOCUS (char *) NULL
+#define DEF_BUTTON_TEXT ""
+#define DEF_BUTTON_TEXT_VARIABLE ""
+#define DEF_BUTTON_UNDERLINE "-1"
+#define DEF_BUTTON_VALUE ""
+#define DEF_BUTTON_WIDTH "0"
+#define DEF_BUTTON_WRAP_LENGTH "0"
+#define DEF_RADIOBUTTON_VARIABLE "selectedButton"
+#define DEF_CHECKBUTTON_VARIABLE ""
+
+/*
+ * Defaults for canvases:
+ */
+
+#define DEF_CANVAS_BG_COLOR NORMAL_BG
+#define DEF_CANVAS_BG_MONO WHITE
+#define DEF_CANVAS_BORDER_WIDTH "0"
+#define DEF_CANVAS_CLOSE_ENOUGH "1"
+#define DEF_CANVAS_CONFINE "1"
+#define DEF_CANVAS_CURSOR ""
+#define DEF_CANVAS_HEIGHT "7c"
+#define DEF_CANVAS_HIGHLIGHT_BG NORMAL_BG
+#define DEF_CANVAS_HIGHLIGHT BLACK
+#define DEF_CANVAS_HIGHLIGHT_WIDTH "3"
+#define DEF_CANVAS_INSERT_BG BLACK
+#define DEF_CANVAS_INSERT_BD_COLOR "0"
+#define DEF_CANVAS_INSERT_BD_MONO "0"
+#define DEF_CANVAS_INSERT_OFF_TIME "300"
+#define DEF_CANVAS_INSERT_ON_TIME "600"
+#define DEF_CANVAS_INSERT_WIDTH "2"
+#define DEF_CANVAS_RELIEF "flat"
+#define DEF_CANVAS_SCROLL_REGION ""
+#define DEF_CANVAS_SELECT_COLOR SELECT_BG
+#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_MONO WHITE
+#define DEF_CANVAS_TAKE_FOCUS (char *) NULL
+#define DEF_CANVAS_WIDTH "10c"
+#define DEF_CANVAS_X_SCROLL_CMD ""
+#define DEF_CANVAS_X_SCROLL_INCREMENT "0"
+#define DEF_CANVAS_Y_SCROLL_CMD ""
+#define DEF_CANVAS_Y_SCROLL_INCREMENT "0"
+
+/*
+ * Defaults for entries:
+ */
+
+#define DEF_ENTRY_BG_COLOR NORMAL_BG
+#define DEF_ENTRY_BG_MONO WHITE
+/* #define DEF_ENTRY_BORDER_WIDTH "2" */
+#define DEF_ENTRY_BORDER_WIDTH "1"
+#define DEF_ENTRY_CURSOR "xterm"
+#define DEF_ENTRY_DISABLED_BG_COLOR NORMAL_BG
+#define DEF_ENTRY_DISABLED_BG_MONO WHITE
+#define DEF_ENTRY_DISABLED_FG DISABLED
+#define DEF_ENTRY_EXPORT_SELECTION "1"
+#define DEF_ENTRY_FONT "Helvetica 12"
+#define DEF_ENTRY_FG BLACK
+#define DEF_ENTRY_HIGHLIGHT_BG NORMAL_BG
+#define DEF_ENTRY_HIGHLIGHT BLACK
+/* #define DEF_ENTRY_HIGHLIGHT_WIDTH "3" */
+#define DEF_ENTRY_HIGHLIGHT_WIDTH "0"
+#define DEF_ENTRY_INSERT_BG BLACK
+#define DEF_ENTRY_INSERT_BD_COLOR "0"
+#define DEF_ENTRY_INSERT_BD_MONO "0"
+#define DEF_ENTRY_INSERT_OFF_TIME "300"
+#define DEF_ENTRY_INSERT_ON_TIME "600"
+/* #define DEF_ENTRY_INSERT_WIDTH "2" */
+#define DEF_ENTRY_INSERT_WIDTH "1"
+#define DEF_ENTRY_JUSTIFY "left"
+#define DEF_ENTRY_READONLY_BG_COLOR NORMAL_BG
+#define DEF_ENTRY_READONLY_BG_MONO WHITE
+/* #define DEF_ENTRY_RELIEF "sunken" */
+#define DEF_ENTRY_RELIEF "solid"
+#define DEF_ENTRY_SCROLL_COMMAND ""
+#define DEF_ENTRY_SELECT_COLOR SELECT_BG
+#define DEF_ENTRY_SELECT_MONO BLACK
+#define DEF_ENTRY_SELECT_BD_COLOR "1"
+#define DEF_ENTRY_SELECT_BD_MONO "0"
+#define DEF_ENTRY_SELECT_FG_COLOR SELECT_FG
+#define DEF_ENTRY_SELECT_FG_MONO WHITE
+#define DEF_ENTRY_SHOW (char *) NULL
+#define DEF_ENTRY_STATE "normal"
+#define DEF_ENTRY_TAKE_FOCUS (char *) NULL
+#define DEF_ENTRY_TEXT_VARIABLE ""
+#define DEF_ENTRY_WIDTH "20"
+
+/*
+ * Defaults for frames:
+ */
+
+#define DEF_FRAME_BG_COLOR NORMAL_BG
+#define DEF_FRAME_BG_MONO WHITE
+#define DEF_FRAME_BORDER_WIDTH "0"
+#define DEF_FRAME_CLASS "Frame"
+#define DEF_FRAME_COLORMAP ""
+#define DEF_FRAME_CONTAINER "0"
+#define DEF_FRAME_CURSOR ""
+#define DEF_FRAME_HEIGHT "0"
+#define DEF_FRAME_HIGHLIGHT_BG NORMAL_BG
+#define DEF_FRAME_HIGHLIGHT BLACK
+#define DEF_FRAME_HIGHLIGHT_WIDTH "0"
+#define DEF_FRAME_PADX "0"
+#define DEF_FRAME_PADY "0"
+#define DEF_FRAME_RELIEF "flat"
+#define DEF_FRAME_TAKE_FOCUS "0"
+#define DEF_FRAME_VISUAL ""
+#define DEF_FRAME_WIDTH "0"
+
+/*
+ * Defaults for labelframes:
+ */
+
+#define DEF_LABELFRAME_BORDER_WIDTH "2"
+#define DEF_LABELFRAME_CLASS "Labelframe"
+#define DEF_LABELFRAME_RELIEF "groove"
+#define DEF_LABELFRAME_FG "systemButtonText"
+#define DEF_LABELFRAME_FONT "system"
+#define DEF_LABELFRAME_TEXT ""
+#define DEF_LABELFRAME_LABELANCHOR "nw"
+
+/*
+ * Defaults for listboxes:
+ */
+
+#define DEF_LISTBOX_ACTIVE_STYLE "underline"
+#define DEF_LISTBOX_BG_COLOR NORMAL_BG
+#define DEF_LISTBOX_BG_MONO WHITE
+#define DEF_LISTBOX_BORDER_WIDTH "1"
+#define DEF_LISTBOX_CURSOR ""
+#define DEF_LISTBOX_DISABLED_FG DISABLED
+#define DEF_LISTBOX_EXPORT_SELECTION "1"
+#define DEF_LISTBOX_FONT "application"
+#define DEF_LISTBOX_FG BLACK
+#define DEF_LISTBOX_HEIGHT "10"
+#define DEF_LISTBOX_HIGHLIGHT_BG NORMAL_BG
+#define DEF_LISTBOX_HIGHLIGHT BLACK
+#define DEF_LISTBOX_HIGHLIGHT_WIDTH "0"
+#define DEF_LISTBOX_RELIEF "solid"
+#define DEF_LISTBOX_SCROLL_COMMAND ""
+#define DEF_LISTBOX_LIST_VARIABLE ""
+#define DEF_LISTBOX_SELECT_COLOR SELECT_BG
+#define DEF_LISTBOX_SELECT_MONO BLACK
+#define DEF_LISTBOX_SELECT_BD "0"
+#define DEF_LISTBOX_SELECT_FG_COLOR SELECT_FG
+#define DEF_LISTBOX_SELECT_FG_MONO WHITE
+#define DEF_LISTBOX_SELECT_MODE "browse"
+#define DEF_LISTBOX_SET_GRID "0"
+#define DEF_LISTBOX_STATE "normal"
+#define DEF_LISTBOX_TAKE_FOCUS (char *) NULL
+#define DEF_LISTBOX_WIDTH "20"
+
+/*
+ * Defaults for individual entries of menus:
+ */
+
+#define DEF_MENU_ENTRY_ACTIVE_BG (char *) NULL
+#define DEF_MENU_ENTRY_ACTIVE_FG (char *) NULL
+#define DEF_MENU_ENTRY_ACCELERATOR (char *) NULL
+#define DEF_MENU_ENTRY_BG (char *) NULL
+#define DEF_MENU_ENTRY_BITMAP None
+#define DEF_MENU_ENTRY_COLUMN_BREAK "0"
+#define DEF_MENU_ENTRY_COMMAND (char *) NULL
+#define DEF_MENU_ENTRY_COMPOUND "none"
+#define DEF_MENU_ENTRY_FG (char *) NULL
+#define DEF_MENU_ENTRY_FONT (char *) NULL
+#define DEF_MENU_ENTRY_HIDE_MARGIN "0"
+#define DEF_MENU_ENTRY_IMAGE (char *) NULL
+#define DEF_MENU_ENTRY_INDICATOR "1"
+#define DEF_MENU_ENTRY_LABEL (char *) NULL
+#define DEF_MENU_ENTRY_MENU (char *) NULL
+#define DEF_MENU_ENTRY_OFF_VALUE "0"
+#define DEF_MENU_ENTRY_ON_VALUE "1"
+#define DEF_MENU_ENTRY_SELECT_IMAGE (char *) NULL
+#define DEF_MENU_ENTRY_STATE "normal"
+#define DEF_MENU_ENTRY_VALUE (char *) NULL
+#define DEF_MENU_ENTRY_CHECK_VARIABLE (char *) NULL
+#define DEF_MENU_ENTRY_RADIO_VARIABLE "selectedButton"
+#define DEF_MENU_ENTRY_SELECT (char *) NULL
+#define DEF_MENU_ENTRY_UNDERLINE "-1"
+
+/*
+ * Defaults for menus overall:
+ */
+
+#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_MONO WHITE
+#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_MONO ""
+#define DEF_MENU_FONT "system"
+#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_MONO BLACK
+#define DEF_MENU_TAKE_FOCUS "0"
+#define DEF_MENU_TEAROFF "1"
+#define DEF_MENU_TEAROFF_CMD (char *) NULL
+#define DEF_MENU_TITLE ""
+#define DEF_MENU_TYPE "normal"
+
+/*
+ * Defaults for menubuttons:
+ */
+
+#define DEF_MENUBUTTON_ANCHOR "center"
+#define DEF_MENUBUTTON_ACTIVE_BG_COLOR ACTIVE_BG
+#define DEF_MENUBUTTON_ACTIVE_BG_MONO BLACK
+#define DEF_MENUBUTTON_ACTIVE_FG_COLOR BLACK
+#define DEF_MENUBUTTON_ACTIVE_FG_MONO WHITE
+#define DEF_MENUBUTTON_BG_COLOR NORMAL_BG
+#define DEF_MENUBUTTON_BG_MONO WHITE
+#define DEF_MENUBUTTON_BITMAP ""
+#define DEF_MENUBUTTON_BORDER_WIDTH "2"
+#define DEF_MENUBUTTON_CURSOR ""
+#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_FG BLACK
+#define DEF_MENUBUTTON_HEIGHT "0"
+#define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR
+#define DEF_MENUBUTTON_HIGHLIGHT_BG_MONO DEF_MENUBUTTON_BG_MONO
+#define DEF_MENUBUTTON_HIGHLIGHT BLACK
+#define DEF_MENUBUTTON_HIGHLIGHT_WIDTH "0"
+#define DEF_MENUBUTTON_IMAGE (char *) NULL
+#define DEF_MENUBUTTON_INDICATOR "0"
+/* #define DEF_MENUBUTTON_JUSTIFY "center" */
+#define DEF_MENUBUTTON_JUSTIFY "left"
+#define DEF_MENUBUTTON_MENU ""
+#define DEF_MENUBUTTON_PADX "4p"
+#define DEF_MENUBUTTON_PADY "3p"
+#define DEF_MENUBUTTON_RELIEF "flat"
+#define DEF_MENUBUTTON_STATE "normal"
+#define DEF_MENUBUTTON_TAKE_FOCUS "0"
+#define DEF_MENUBUTTON_TEXT ""
+#define DEF_MENUBUTTON_TEXT_VARIABLE ""
+#define DEF_MENUBUTTON_UNDERLINE "-1"
+#define DEF_MENUBUTTON_WIDTH "0"
+#define DEF_MENUBUTTON_WRAP_LENGTH "0"
+
+/*
+ * Defaults for messages:
+ */
+
+#define DEF_MESSAGE_ANCHOR "center"
+#define DEF_MESSAGE_ASPECT "150"
+#define DEF_MESSAGE_BG_COLOR NORMAL_BG
+#define DEF_MESSAGE_BG_MONO WHITE
+#define DEF_MESSAGE_BORDER_WIDTH "2"
+#define DEF_MESSAGE_CURSOR ""
+#define DEF_MESSAGE_FG BLACK
+#define DEF_MESSAGE_FONT "system"
+#define DEF_MESSAGE_HIGHLIGHT_BG NORMAL_BG
+#define DEF_MESSAGE_HIGHLIGHT BLACK
+#define DEF_MESSAGE_HIGHLIGHT_WIDTH "0"
+#define DEF_MESSAGE_JUSTIFY "left"
+#define DEF_MESSAGE_PADX "-1"
+#define DEF_MESSAGE_PADY "-1"
+#define DEF_MESSAGE_RELIEF "flat"
+#define DEF_MESSAGE_TAKE_FOCUS "0"
+#define DEF_MESSAGE_TEXT ""
+#define DEF_MESSAGE_TEXT_VARIABLE ""
+#define DEF_MESSAGE_WIDTH "0"
+/*
+ * Defaults for panedwindows
+ */
+
+#define DEF_PANEDWINDOW_BG_COLOR NORMAL_BG
+#define DEF_PANEDWINDOW_BG_MONO WHITE
+#define DEF_PANEDWINDOW_BORDERWIDTH "2"
+#define DEF_PANEDWINDOW_CURSOR ""
+#define DEF_PANEDWINDOW_HANDLEPAD "8"
+#define DEF_PANEDWINDOW_HANDLESIZE "8"
+#define DEF_PANEDWINDOW_HEIGHT ""
+#define DEF_PANEDWINDOW_OPAQUERESIZE "0"
+#define DEF_PANEDWINDOW_ORIENT "horizontal"
+#define DEF_PANEDWINDOW_RELIEF "flat"
+#define DEF_PANEDWINDOW_SASHCURSOR ""
+#define DEF_PANEDWINDOW_SASHPAD "2"
+#define DEF_PANEDWINDOW_SASHRELIEF "raised"
+#define DEF_PANEDWINDOW_SASHWIDTH "2"
+#define DEF_PANEDWINDOW_SHOWHANDLE "1"
+#define DEF_PANEDWINDOW_WIDTH ""
+
+/*
+ * Defaults for panedwindow panes
+ */
+
+#define DEF_PANEDWINDOW_PANE_AFTER ""
+#define DEF_PANEDWINDOW_PANE_BEFORE ""
+#define DEF_PANEDWINDOW_PANE_HEIGHT ""
+#define DEF_PANEDWINDOW_PANE_MINSIZE "0"
+#define DEF_PANEDWINDOW_PANE_PADX "0"
+#define DEF_PANEDWINDOW_PANE_PADY "0"
+#define DEF_PANEDWINDOW_PANE_STICKY "nsew"
+#define DEF_PANEDWINDOW_PANE_WIDTH ""
+
+/*
+ * Defaults for scales:
+ */
+
+#define DEF_SCALE_ACTIVE_BG_COLOR ACTIVE_BG
+#define DEF_SCALE_ACTIVE_BG_MONO BLACK
+#define DEF_SCALE_BG_COLOR NORMAL_BG
+#define DEF_SCALE_BG_MONO WHITE
+#define DEF_SCALE_BIG_INCREMENT "0"
+#define DEF_SCALE_BORDER_WIDTH "2"
+#define DEF_SCALE_COMMAND ""
+#define DEF_SCALE_CURSOR ""
+#define DEF_SCALE_DIGITS "0"
+#define DEF_SCALE_FONT "system"
+#define DEF_SCALE_FG_COLOR BLACK
+#define DEF_SCALE_FG_MONO BLACK
+#define DEF_SCALE_FROM "0"
+#define DEF_SCALE_HIGHLIGHT_BG_COLOR DEF_SCALE_BG_COLOR
+#define DEF_SCALE_HIGHLIGHT_BG_MONO DEF_SCALE_BG_MONO
+#define DEF_SCALE_HIGHLIGHT BLACK
+#define DEF_SCALE_HIGHLIGHT_WIDTH "0"
+#define DEF_SCALE_LABEL ""
+#define DEF_SCALE_LENGTH "100"
+#define DEF_SCALE_ORIENT "vertical"
+#define DEF_SCALE_RELIEF "flat"
+#define DEF_SCALE_REPEAT_DELAY "300"
+#define DEF_SCALE_REPEAT_INTERVAL "100"
+#define DEF_SCALE_RESOLUTION "1"
+#define DEF_SCALE_TROUGH_COLOR TROUGH
+#define DEF_SCALE_TROUGH_MONO WHITE
+#define DEF_SCALE_SHOW_VALUE "1"
+#define DEF_SCALE_SLIDER_LENGTH "30"
+#define DEF_SCALE_SLIDER_RELIEF "raised"
+#define DEF_SCALE_STATE "normal"
+#define DEF_SCALE_TAKE_FOCUS (char *) NULL
+#define DEF_SCALE_TICK_INTERVAL "0"
+#define DEF_SCALE_TO "100"
+#define DEF_SCALE_VARIABLE ""
+#define DEF_SCALE_WIDTH "15"
+
+/*
+ * Defaults for scrollbars:
+ */
+
+#define DEF_SCROLLBAR_ACTIVE_BG_COLOR ACTIVE_BG
+#define DEF_SCROLLBAR_ACTIVE_BG_MONO BLACK
+#define DEF_SCROLLBAR_ACTIVE_RELIEF "raised"
+#define DEF_SCROLLBAR_BG_COLOR NORMAL_BG
+#define DEF_SCROLLBAR_BG_MONO WHITE
+/* #define DEF_SCROLLBAR_BORDER_WIDTH "2" */
+#define DEF_SCROLLBAR_BORDER_WIDTH "0"
+#define DEF_SCROLLBAR_COMMAND ""
+#define DEF_SCROLLBAR_CURSOR ""
+#define DEF_SCROLLBAR_EL_BORDER_WIDTH "-1"
+#define DEF_SCROLLBAR_HIGHLIGHT_BG NORMAL_BG
+#define DEF_SCROLLBAR_HIGHLIGHT BLACK
+/* #define DEF_SCROLLBAR_HIGHLIGHT_WIDTH "2" */
+#define DEF_SCROLLBAR_HIGHLIGHT_WIDTH "0"
+#define DEF_SCROLLBAR_JUMP "0"
+#define DEF_SCROLLBAR_ORIENT "vertical"
+/*#define DEF_SCROLLBAR_RELIEF "sunken" */
+#define DEF_SCROLLBAR_RELIEF "flat"
+#define DEF_SCROLLBAR_REPEAT_DELAY "300"
+#define DEF_SCROLLBAR_REPEAT_INTERVAL "100"
+#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"
+
+/*
+ * Defaults for texts:
+ */
+
+#define DEF_TEXT_AUTO_SEPARATORS "1"
+#define DEF_TEXT_BG_COLOR NORMAL_BG
+#define DEF_TEXT_BG_MONO WHITE
+#define DEF_TEXT_BORDER_WIDTH "0"
+#define DEF_TEXT_CURSOR "xterm"
+#define DEF_TEXT_FG BLACK
+#define DEF_TEXT_EXPORT_SELECTION "1"
+#define DEF_TEXT_FONT "Courier 12"
+#define DEF_TEXT_HEIGHT "24"
+#define DEF_TEXT_HIGHLIGHT_BG NORMAL_BG
+#define DEF_TEXT_HIGHLIGHT BLACK
+#define DEF_TEXT_HIGHLIGHT_WIDTH "3"
+#define DEF_TEXT_INSERT_BG BLACK
+#define DEF_TEXT_INSERT_BD_COLOR "0"
+#define DEF_TEXT_INSERT_BD_MONO "0"
+#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_PADX "1"
+#define DEF_TEXT_PADY "1"
+#define DEF_TEXT_RELIEF "flat"
+#define DEF_TEXT_SELECT_COLOR SELECT_BG
+#define DEF_TEXT_SELECT_MONO BLACK
+#define DEF_TEXT_SELECT_BD_COLOR "1"
+#define DEF_TEXT_SELECT_BD_MONO "0"
+#define DEF_TEXT_SELECT_FG_COLOR SELECT_FG
+#define DEF_TEXT_SELECT_FG_MONO WHITE
+#define DEF_TEXT_SELECT_RELIEF "solid"
+#define DEF_TEXT_SET_GRID "0"
+#define DEF_TEXT_SPACING1 "0"
+#define DEF_TEXT_SPACING2 "0"
+#define DEF_TEXT_SPACING3 "0"
+#define DEF_TEXT_STATE "normal"
+#define DEF_TEXT_TABS ""
+#define DEF_TEXT_TAKE_FOCUS (char *) NULL
+#define DEF_TEXT_UNDO "0"
+#define DEF_TEXT_WIDTH "80"
+#define DEF_TEXT_WRAP "char"
+#define DEF_TEXT_XSCROLL_COMMAND ""
+#define DEF_TEXT_YSCROLL_COMMAND ""
+
+/*
+ * Defaults for canvas text:
+ */
+
+#define DEF_CANVTEXT_FONT "Helvetica 12"
+
+/*
+ * Defaults for toplevels (most of the defaults for frames also apply
+ * to toplevels):
+ */
+
+#define DEF_TOPLEVEL_CLASS "Toplevel"
+#define DEF_TOPLEVEL_MENU ""
+#define DEF_TOPLEVEL_SCREEN ""
+#define DEF_TOPLEVEL_USE ""
+
+#endif /* _TKMACDEFAULT */
diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c
new file mode 100644
index 0000000..3decc8a
--- /dev/null
+++ b/macosx/tkMacOSXDialog.c
@@ -0,0 +1,1229 @@
+/*
+ * tkMacOSXDialog.c --
+ *
+ * Contains the Mac implementation of the common dialog boxes.
+ *
+ * Copyright (c) 1996-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.2 2002/08/31 06:12:29 das Exp $
+ */
+#include <Carbon/Carbon.h>
+
+#include "tkPort.h"
+#include "tkInt.h"
+#include "tkMacOSXUtil.h"
+#include "tkMacOSXInt.h"
+#include "tkFileFilter.h"
+
+#ifndef StrLength
+#define StrLength(s) (*((unsigned char *) (s)))
+#endif
+#ifndef StrBody
+#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 MATCHED 0
+#define UNMATCHED 1
+
+#define TK_DEFAULT_ABOUT 128
+
+/*
+ * The following structure is used in the GetFileName() function. It stored
+ * information about the file dialog and the file filters.
+ */
+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. */
+ int usePopup; /* True if we show the popup menu (this
+ * is an open operation and the
+ * -filetypes option is set). */
+} OpenFileData;
+
+
+static Boolean MatchOneType _ANSI_ARGS_((StringPtr fileNamePtr, OSType fileType,
+ OpenFileData *myofdPtr, FileFilter *filterPtr));
+static pascal Boolean OpenFileFilterProc(AEDesc* theItem, void* info,
+ NavCallBackUserData callBackUD,
+ NavFilterModes filterMode );
+pascal void OpenEventProc(NavEventCallbackMessage callBackSelector,
+ NavCBRecPtr callBackParms,
+ NavCallBackUserData callBackUD );
+static void InitFileDialogs();
+static int NavServicesGetFile(Tcl_Interp *interp, OpenFileData *ofd,
+ AEDesc *initialDescPtr,
+ unsigned char *initialFile, AEDescList *selectDescPtr,
+ StringPtr title, StringPtr message, int multiple, int isOpen);
+static int HandleInitialDirectory (Tcl_Interp *interp,
+ char *initialFile, char *initialDir,
+ FSRef *dirRef,
+ AEDescList *selectDescPtr,
+ AEDesc *dirDescPtr);
+
+/*
+ * Have we initialized the file dialog subsystem
+ */
+
+static int fileDlgInited = 0;
+
+/*
+ * Filter and hook functions used by the tk_getOpenFile and tk_getSaveFile
+ * commands.
+ */
+
+NavObjectFilterUPP openFileFilterUPP;
+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.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * 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. */
+{
+ Tk_Window parent;
+ char *title;
+ int i, picked, srcRead, dstWrote;
+ ColorPickerInfo cpinfo;
+ static int inited = 0;
+ static RGBColor in;
+ static CONST char *optionStrings[] = {
+ "-initialcolor", "-parent", "-title", NULL
+ };
+ enum options {
+ 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.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;
+
+ 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);
+ Tcl_AppendResult(interp, "value for \"", option, "\" missing",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ value = Tcl_GetStringFromObj(objv[i + 1], NULL);
+
+ switch ((enum options) index) {
+ case COLOR_INITIAL: {
+ XColor *colorPtr;
+
+ colorPtr = Tk_GetColor(interp, parent, value);
+ if (colorPtr == NULL) {
+ return TCL_ERROR;
+ }
+ in.red = colorPtr->red;
+ in.green = colorPtr->green;
+ in.blue = colorPtr->blue;
+ Tk_FreeColor(colorPtr);
+ break;
+ }
+ case COLOR_PARENT: {
+ parent = Tk_NameToWindow(interp, value, parent);
+ if (parent == NULL) {
+ return TCL_ERROR;
+ }
+ break;
+ }
+ case COLOR_TITLE: {
+ title = value;
+ break;
+ }
+ }
+ }
+
+
+ cpinfo.theColor.profile = 0L;
+ 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 = NULL;
+
+ /* This doesn't seem to actually set the title! */
+ Tcl_UtfToExternal(NULL, NULL, 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;
+ picked = 1;
+ }
+
+ if (picked != 0) {
+ char result[32];
+
+ sprintf(result, "#%02x%02x%02x", in.red >> 8, in.green >> 8,
+ in.blue >> 8);
+ Tcl_AppendResult(interp, result, NULL);
+ }
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_GetOpenFileObjCmd --
+ *
+ * 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.
+ *
+ * Side effects:
+ * 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. */
+{
+ int i, result, multiple;
+ OpenFileData ofd;
+ Tk_Window parent;
+ Str255 message, title;
+ 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
+ };
+ enum openOptions {
+ 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[0] = 0;
+ message[0] = 0;
+
+ TkInitFileFilters(&ofd.fl);
+
+ 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;
+ int srcRead, dstWrote;
+
+ 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);
+ Tcl_AppendResult(interp, "value for \"", string, "\" missing",
+ (char *) NULL);
+ result = TCL_ERROR;
+ goto end;
+ }
+
+ switch (index) {
+ 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;
+ goto end;
+ }
+ break;
+ case OPEN_INITDIR:
+ initialDir = Tcl_GetStringFromObj(objv[i + 1], NULL);
+ break;
+ case OPEN_INITFILE:
+ initialFile = Tcl_GetStringFromObj(objv[i + 1], NULL);
+ break;
+ case OPEN_MESSAGE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ Tcl_UtfToExternal(NULL, TkMacOSXCarbonEncoding, choice, choiceLen,
+ 0, NULL, StrBody(message), 255,
+ &srcRead, &dstWrote, NULL);
+ message[0] = dstWrote;
+ 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);
+ if (parent == NULL) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ break;
+ case OPEN_TITLE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ Tcl_UtfToExternal(NULL, TkMacOSXCarbonEncoding, choice, choiceLen,
+ 0, NULL, StrBody(title), 255,
+ &srcRead, &dstWrote, NULL);
+ title[0] = dstWrote;
+ break;
+ }
+ }
+
+ if (HandleInitialDirectory(interp, initialFile, initialDir, &dirRef,
+ &selectDesc, &initialDesc) != TCL_OK) {
+ result = TCL_ERROR;
+ goto end;
+ }
+
+ if (initialDesc.descriptorType == typeFSRef) {
+ initialPtr = &initialDesc;
+ }
+ result = NavServicesGetFile(interp, &ofd, initialPtr,
+ NULL, &selectDesc,
+ title, message, multiple, OPEN_FILE);
+
+ end:
+ TkFreeFileFilters(&ofd.fl);
+ AEDisposeDesc(&initialDesc);
+ AEDisposeDesc(&selectDesc);
+
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_GetSaveFileObjCmd --
+ *
+ * Same as Tk_GetOpenFileCmd but opens a "save file" dialog box
+ * instead
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * 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. */
+{
+ int i, result;
+ Str255 initialFile;
+ Tk_Window parent;
+ AEDesc initialDesc = {typeNull, NULL};
+ AEDesc *initialPtr = NULL;
+ FSRef dirRef;
+ Str255 title, message;
+ OpenFileData ofd;
+ 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
+ };
+
+ if (!fileDlgInited) {
+ InitFileDialogs();
+ }
+
+ result = TCL_ERROR;
+ parent = (Tk_Window) clientData;
+ StrLength(initialFile) = 0;
+ title[0] = 0;
+ message[0] = 0;
+
+ for (i = 1; i < objc; i += 2) {
+ char *choice;
+ int index, choiceLen;
+ char *string;
+ Tcl_DString ds;
+ int srcRead, dstWrote;
+
+ if (Tcl_GetIndexFromObj(interp, objv[i], saveOptionStrings, "option",
+ TCL_EXACT, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (i + 1 == objc) {
+ string = Tcl_GetStringFromObj(objv[i], NULL);
+ Tcl_AppendResult(interp, "value for \"", string, "\" missing",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ switch (index) {
+ case SAVE_DEFAULT:
+ break;
+ case SAVE_FILETYPES:
+ /* Currently unimplemented - what would we do here anyway? */
+ break;
+ case SAVE_INITDIR:
+ choice = Tcl_GetStringFromObj(objv[i + 1], NULL);
+ if (HandleInitialDirectory(interp, NULL, choice, &dirRef,
+ NULL, &initialDesc) != TCL_OK) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ break;
+ case SAVE_INITFILE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ if (Tcl_TranslateFileName(interp, choice, &ds) == NULL) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ Tcl_UtfToExternal(NULL, TkMacOSXCarbonEncoding, Tcl_DStringValue(&ds),
+ Tcl_DStringLength(&ds), 0, NULL,
+ StrBody(initialFile), 255, &srcRead, &dstWrote, NULL);
+ StrLength(initialFile) = (unsigned char) dstWrote;
+ Tcl_DStringFree(&ds);
+ break;
+ case SAVE_MESSAGE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ Tcl_UtfToExternal(NULL, TkMacOSXCarbonEncoding, choice, choiceLen,
+ 0, NULL, StrBody(message), 255,
+ &srcRead, &dstWrote, NULL);
+ StrLength(message) = (unsigned char) dstWrote;
+ break;
+ case SAVE_PARENT:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ parent = Tk_NameToWindow(interp, choice, parent);
+ if (parent == NULL) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ break;
+ case SAVE_TITLE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ Tcl_UtfToExternal(NULL, TkMacOSXCarbonEncoding, choice, choiceLen,
+ 0, NULL, StrBody(title), 255,
+ &srcRead, &dstWrote, NULL);
+ StrLength(title) = (unsigned char) dstWrote;
+ 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);
+
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_ChooseDirectoryObjCmd --
+ *
+ * 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.
+ *
+ * Side effects:
+ * A modal dialog window is created. Tcl_SetServiceMode() is
+ * called to allow background events to be processed
+ *
+ *----------------------------------------------------------------------
+ */
+
+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. */
+{
+ int i, result;
+ Tk_Window parent;
+ AEDesc initialDesc = {typeNull, NULL};
+ AEDesc *initialPtr = NULL;
+ FSRef dirRef;
+ Str255 message, title;
+ int srcRead, dstWrote;
+ OpenFileData ofd;
+ static CONST char *chooseOptionStrings[] = {
+ "-initialdir", "-message", "-mustexist", "-parent", "-title", NULL
+ };
+ enum chooseOptions {
+ 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[0] = 0;
+ message[0] = 0;
+
+ for (i = 1; i < objc; i += 2) {
+ char *choice;
+ int index, choiceLen;
+ char *string;
+
+ if (Tcl_GetIndexFromObj(interp, objv[i], chooseOptionStrings, "option",
+ TCL_EXACT, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (i + 1 == objc) {
+ string = Tcl_GetStringFromObj(objv[i], NULL);
+ Tcl_AppendResult(interp, "value for \"", string, "\" missing",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ switch (index) {
+ case CHOOSE_INITDIR:
+ choice = Tcl_GetStringFromObj(objv[i + 1], NULL);
+ if (HandleInitialDirectory(interp, NULL, choice, &dirRef,
+ NULL, &initialDesc) != TCL_OK) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ break;
+ case CHOOSE_MESSAGE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ Tcl_UtfToExternal(NULL, TkMacOSXCarbonEncoding, choice, choiceLen,
+ 0, NULL, StrBody(message), 255,
+ &srcRead, &dstWrote, NULL);
+ StrLength(message) = (unsigned char) dstWrote;
+ break;
+ case CHOOSE_PARENT:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ parent = Tk_NameToWindow(interp, choice, parent);
+ if (parent == NULL) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ break;
+ case CHOOSE_TITLE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ Tcl_UtfToExternal(NULL, TkMacOSXCarbonEncoding, choice, choiceLen,
+ 0, NULL, StrBody(title), 255,
+ &srcRead, &dstWrote, NULL);
+ StrLength(title) = (unsigned char) dstWrote;
+ 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);
+
+ return result;
+}
+
+int
+HandleInitialDirectory (
+ Tcl_Interp *interp,
+ char *initialFile,
+ char *initialDir,
+ FSRef *dirRef,
+ AEDescList *selectDescPtr,
+ AEDesc *dirDescPtr)
+{
+ Tcl_DString ds;
+ OSErr err;
+ Boolean isDirectory;
+ char *dirName = NULL;
+ int result = TCL_OK;
+
+ if (initialDir != NULL) {
+ dirName = Tcl_TranslateFileName(interp, initialDir, &ds);
+ if (dirName == NULL) {
+ return TCL_ERROR;
+ }
+
+ err = FSPathMakeRef(dirName,
+ dirRef, &isDirectory);
+
+ if (err != noErr) {
+ Tcl_AppendResult(interp, "bad directory \"",
+ initialDir, "\"", NULL);
+ result = TCL_ERROR;
+ 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);
+ }
+
+ if (initialFile != NULL && selectDescPtr != NULL) {
+ FSRef fileRef;
+ AEDesc fileDesc;
+ char *namePtr;
+
+ if (initialDir != NULL) {
+ Tcl_DStringAppend(&ds, "/", 1);
+ Tcl_DStringAppend(&ds, initialFile, -1);
+ namePtr = Tcl_DStringValue(&ds);
+ } else {
+ namePtr = initialFile;
+ }
+
+ AECreateList(NULL, 0, false, selectDescPtr);
+
+ err = FSPathMakeRef(namePtr, &fileRef, &isDirectory);
+ if (err != noErr) {
+ Tcl_AppendResult(interp, "bad initialfile \"", initialFile,
+ "\" file does not exist.", NULL);
+ return TCL_ERROR;
+ }
+ AECreateDesc(typeFSRef, &fileRef, sizeof(fileRef), &fileDesc);
+ AEPutDesc(selectDescPtr, 1, &fileDesc);
+ AEDisposeDesc(&fileDesc);
+ }
+
+end:
+ if (dirName != NULL) {
+ Tcl_DStringFree(&ds);
+ }
+ return result;
+}
+
+static void
+InitFileDialogs()
+{
+ fileDlgInited = 1;
+ openFileFilterUPP = NewNavObjectFilterUPP(OpenFileFilterProc);
+ openFileEventUPP = NewNavEventUPP(OpenEventProc);
+}
+
+static int
+NavServicesGetFile(
+ Tcl_Interp *interp,
+ OpenFileData *ofdPtr,
+ AEDesc *initialDescPtr,
+ unsigned char *initialFile,
+ AEDescList *selectDescPtr,
+ StringPtr title,
+ StringPtr message,
+ int multiple,
+ int isOpen)
+{
+ NavReplyRecord theReply;
+ NavDialogCreationOptions diagOptions;
+ NavDialogRef dialogRef = NULL;
+ CFStringRef * menuItemNames = NULL;
+ OSErr err;
+ Tcl_Obj *theResult = NULL;
+ int result;
+ TextEncoding encoding;
+
+ encoding = GetApplicationTextEncoding();
+ err = NavGetDefaultDialogCreationOptions(&diagOptions);
+ if (err!=noErr) {
+ return TCL_ERROR;
+ }
+ diagOptions.location.h = -1;
+ diagOptions.location.v = -1;
+ diagOptions.optionFlags = kNavDontAutoTranslate
+ + kNavDontAddTranslateItems;
+
+ if (multiple) {
+ diagOptions.optionFlags += kNavAllowMultipleFiles;
+ }
+
+ if (ofdPtr != NULL && ofdPtr->usePopup) {
+ FileFilter *filterPtr;
+
+ filterPtr = ofdPtr->fl.filters;
+ if (filterPtr == NULL) {
+ ofdPtr->usePopup = 0;
+ }
+ }
+
+ if (ofdPtr != NULL && ofdPtr->usePopup) {
+ FileFilter *filterPtr;
+ int index = 0;
+ ofdPtr->curType = 0;
+
+ menuItemNames = (CFStringRef *)ckalloc(ofdPtr->fl.numFilters
+ * sizeof(CFStringRef));
+
+ for (filterPtr = ofdPtr->fl.filters; filterPtr != NULL;
+ filterPtr = filterPtr->next, index++) {
+ menuItemNames[index] = CFStringCreateWithCString(NULL,
+ filterPtr->name, encoding);
+ }
+ diagOptions.popupExtension = CFArrayCreate(NULL,
+ (const void **)menuItemNames, ofdPtr->fl.numFilters, NULL);;
+ } else {
+ diagOptions.optionFlags += kNavNoTypePopup;
+ diagOptions.popupExtension = NULL;
+ }
+
+ /*
+ * This is required to allow App packages to be selectable in the
+ * file dialogs...
+ */
+
+ diagOptions.optionFlags += kNavSupportPackages;
+
+ diagOptions.clientName = CFStringCreateWithCString(NULL, "Wish", encoding);
+ if (message == NULL) {
+ diagOptions.message = NULL;
+ } else {
+ diagOptions.message = CFStringCreateWithPascalString(NULL, message, encoding);
+ }
+ if ((initialFile != NULL) && (initialFile[0] != 0)) {
+ diagOptions.saveFileName = CFStringCreateWithPascalString(NULL,
+ initialFile, encoding);
+ } else {
+ diagOptions.saveFileName = NULL;
+ }
+ if (title == NULL) {
+ diagOptions.windowTitle = NULL;
+ } else {
+ diagOptions.windowTitle = CFStringCreateWithPascalString(NULL, title, encoding);
+ }
+
+ 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){
+ fprintf(stderr,"NavCreateGetFileDialog failed, %d\n", err );
+ dialogRef = NULL;
+ }
+ } else if (isOpen == SAVE_FILE) {
+ err = NavCreatePutFileDialog(&diagOptions, 'TEXT', 'WIsH',
+ openFileEventUPP, NULL, &dialogRef);
+ if (err!=noErr){
+ fprintf(stderr,"NavCreatePutFileDialog failed, %d\n", err );
+ dialogRef = NULL;
+ }
+ } else if (isOpen == CHOOSE_FOLDER) {
+ err = NavCreateChooseFolderDialog(&diagOptions, openFileEventUPP,
+ openFileFilterUPP, NULL, &dialogRef);
+ if (err!=noErr){
+ fprintf(stderr,"NavCreateChooseFolderDialog failed, %d\n", err );
+ dialogRef = NULL;
+ }
+ }
+
+ if (dialogRef) {
+ if (initialDescPtr != NULL) {
+ NavCustomControl (dialogRef, kNavCtlSetLocation, initialDescPtr);
+ }
+ if ((selectDescPtr != NULL)
+ && (selectDescPtr->descriptorType != typeNull)) {
+ NavCustomControl(dialogRef, kNavCtlSetSelection, &selectDescPtr);
+ }
+
+ if ((err = NavDialogRun(dialogRef)) != noErr ){
+ fprintf(stderr,"NavDialogRun failed, %d\n", err );
+ } else {
+ if ((err = NavDialogGetReply(dialogRef, &theReply)) != noErr) {
+ fprintf(stderr,"NavGetReply failed, %d\n", err );
+ }
+ }
+ }
+
+ /*
+ * Most commands assume that the file dialogs return a single
+ * item, not a list. So only build a list if multiple is true...
+ */
+ if (err==noErr) {
+ if (multiple) {
+ theResult = Tcl_NewListObj(0, NULL);
+ } else {
+ theResult = Tcl_NewObj();
+ }
+ if (!theResult) {
+ err = memFullErr;
+ }
+ }
+ if (theReply.validRecord && err==noErr) {
+ AEDesc resultDesc;
+ long count;
+ Tcl_DString fileName;
+ FSRef fsRef;
+ char pathPtr[1024];
+ int pathValid = 0;
+ err = AECountItems(&theReply.selection, &count);
+ if (err == noErr) {
+ long i;
+ for (i = 1; i <= count; i++ ) {
+ err = AEGetNthDesc(&theReply.selection,
+ i, typeFSRef, NULL, &resultDesc);
+ pathValid = 0;
+ if (err == noErr) {
+ if ((err = AEGetDescData(&resultDesc, &fsRef, sizeof(fsRef)))
+ != noErr ) {
+ fprintf(stderr,"AEGetDescData failed %d\n", err );
+ } else {
+ if (err = FSRefMakePath(&fsRef, pathPtr, 1024) ) {
+ fprintf(stderr,"FSRefMakePath failed, %d\n", err );
+ } else {
+ if (isOpen == SAVE_FILE) {
+ CFStringRef saveNameRef;
+ char saveName [1024];
+ if (saveNameRef = NavDialogGetSaveFileName(dialogRef)) {
+ if (CFStringGetCString(saveNameRef, saveName,
+ 1024, encoding)) {
+ strcat(pathPtr, "/");
+ strcat(pathPtr, saveName);
+ pathValid = 1;
+ } else {
+ fprintf(stderr, "CFStringGetCString failed\n");
+ }
+ } else {
+ fprintf(stderr, "NavDialogGetSaveFileName failed\n");
+ }
+ } else {
+ pathValid = 1;
+ }
+ if (pathValid) {
+ /*
+ * Tested this and NULL=utf-8 encoding is
+ * good here
+ */
+ Tcl_ExternalToUtfDString(NULL, pathPtr, -1,
+ &fileName);
+ if (multiple) {
+ Tcl_ListObjAppendElement(interp, theResult,
+ Tcl_NewStringObj(Tcl_DStringValue(&fileName),
+ Tcl_DStringLength(&fileName)));
+ } else {
+ Tcl_SetStringObj(theResult, Tcl_DStringValue(&fileName),
+ Tcl_DStringLength(&fileName));
+ }
+ Tcl_DStringFree(&fileName);
+ }
+ }
+ }
+ AEDisposeDesc(&resultDesc);
+ }
+ }
+ }
+ err = NavDisposeReply(&theReply);
+ 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
+ */
+
+ if (diagOptions.windowTitle) {
+ CFRelease(diagOptions.windowTitle);
+ }
+ if (diagOptions.saveFileName) {
+ CFRelease(diagOptions.saveFileName);
+ }
+ if (diagOptions.message) {
+ CFRelease(diagOptions.message);
+ }
+ if (diagOptions.clientName) {
+ CFRelease(diagOptions.clientName);
+ }
+ /*
+ * dispose of the CFArray diagOptions.popupExtension
+ */
+
+ if (menuItemNames) {
+ int i;
+ for (i=0;i < ofdPtr->fl.numFilters;i++) {
+ CFRelease(menuItemNames[i]);
+ }
+ ckfree((void *)menuItemNames);
+ }
+ if (diagOptions.popupExtension != NULL) {
+ CFRelease(diagOptions.popupExtension);
+ }
+
+ return result;
+}
+
+static pascal Boolean
+OpenFileFilterProc(
+ AEDesc* theItem, void* info,
+ NavCallBackUserData callBackUD,
+ NavFilterModes filterMode )
+{
+ OpenFileData *ofdPtr = (OpenFileData *) callBackUD;
+ if (!ofdPtr || !ofdPtr->usePopup) {
+ return true;
+ } else {
+ if (ofdPtr->fl.numFilters == 0) {
+ return true;
+ } else {
+
+ if ( theItem->descriptorType == typeFSS ) {
+ NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*)info;
+ int result;
+
+ if ( !theInfo->isFolder ) {
+ OSType fileType;
+ StringPtr fileNamePtr;
+ int i;
+ FileFilter *filterPtr;
+
+ fileType = theInfo->fileAndFolder.fileInfo.finderInfo.fdType;
+ HLock((Handle)theItem->dataHandle);
+ fileNamePtr = (((FSSpec *) *theItem->dataHandle)->name);
+
+ if (ofdPtr->usePopup) {
+ i = ofdPtr->curType;
+ for (filterPtr = ofdPtr->fl.filters; filterPtr && i > 0; i--) {
+ filterPtr = filterPtr->next;
+ }
+ if (filterPtr) {
+ result = MatchOneType(fileNamePtr, fileType,
+ ofdPtr, filterPtr);
+ } else {
+ result = false;
+ }
+ } else {
+ /*
+ * We are not using the popup menu. In this case, the file is
+ * considered matched if it matches any of the file filters.
+ */
+ result = UNMATCHED;
+ for (filterPtr = ofdPtr->fl.filters; filterPtr;
+ filterPtr = filterPtr->next) {
+ if (MatchOneType(fileNamePtr, fileType,
+ ofdPtr, filterPtr) == MATCHED) {
+ result = MATCHED;
+ break;
+ }
+ }
+ }
+
+ HUnlock((Handle)theItem->dataHandle);
+ 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 */
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MatchOneType --
+ *
+ * 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.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Boolean
+MatchOneType(
+ StringPtr fileNamePtr, /* Name of the file */
+ OSType fileType, /* Type of the file */
+ OpenFileData * ofdPtr, /* Information about this file dialog */
+ FileFilter * filterPtr) /* Match the file described by pb against
+ * this filter */
+{
+ FileFilterClause * clausePtr;
+
+ /*
+ * A file matches with a file type if it matches with at least one
+ * clause of the type.
+ *
+ * If the clause has both glob patterns and ostypes, the file must
+ * match with at least one pattern AND at least one ostype.
+ *
+ * If the clause has glob patterns only, the file must match with at least
+ * one pattern.
+ *
+ * If the clause has mac types only, the file must match with at least
+ * one mac type.
+ *
+ * If the clause has neither glob patterns nor mac types, it's
+ * considered an error.
+ */
+
+ for (clausePtr=filterPtr->clauses; clausePtr; clausePtr=clausePtr->next) {
+ int macMatched = 0;
+ int globMatched = 0;
+ GlobPattern * globPtr;
+ MacFileType * mfPtr;
+
+ if (clausePtr->patterns == NULL) {
+ globMatched = 1;
+ }
+ if (clausePtr->macTypes == NULL) {
+ macMatched = 1;
+ }
+
+ for (globPtr=clausePtr->patterns; globPtr; globPtr=globPtr->next) {
+ char filename[256];
+ int len;
+ char * p, *q, *ext;
+
+ if (fileNamePtr == NULL) {
+ continue;
+ }
+ p = (char*)(fileNamePtr);
+ len = p[0];
+ strncpy(filename, p+1, len);
+ filename[len] = '\0';
+ ext = globPtr->pattern;
+
+ if (ext[0] == '\0') {
+ /*
+ * We don't want any extensions: OK if the filename doesn't
+ * have "." in it
+ */
+ for (q=filename; *q; q++) {
+ if (*q == '.') {
+ goto glob_unmatched;
+ }
+ }
+ goto glob_matched;
+ }
+
+ if (Tcl_StringMatch(filename, ext)) {
+ goto glob_matched;
+ } else {
+ goto glob_unmatched;
+ }
+
+ glob_unmatched:
+ continue;
+
+ glob_matched:
+ globMatched = 1;
+ break;
+ }
+
+ for (mfPtr=clausePtr->macTypes; mfPtr; mfPtr=mfPtr->next) {
+ if (fileType == mfPtr->type) {
+ macMatched = 1;
+ break;
+ }
+ }
+
+ if (globMatched && macMatched) {
+ return MATCHED;
+ }
+ }
+
+ return UNMATCHED;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkAboutDlg --
+ *
+ * Displays the default Tk About box. This code uses Macintosh
+ * resources to define the content of the About Box.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkAboutDlg()
+{
+ DialogPtr aboutDlog;
+ WindowRef windowRef;
+ short itemHit = -9;
+
+ aboutDlog = GetNewDialog(128, NULL, (void *) (-1));
+
+ if (!aboutDlog) {
+ return;
+ }
+
+ windowRef=GetDialogWindow(aboutDlog);
+ SelectWindow(windowRef);
+
+ while (itemHit != 1) {
+ ModalDialog( NULL, &itemHit);
+ }
+ DisposeDialog(aboutDlog);
+ aboutDlog = NULL;
+
+ SelectWindow(FrontNonFloatingWindow());
+
+ return;
+}
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
new file mode 100644
index 0000000..3edcfe9
--- /dev/null
+++ b/macosx/tkMacOSXDraw.c
@@ -0,0 +1,1714 @@
+/*
+ * tkMacOSXDraw.c --
+ *
+ * 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.
+ *
+ * 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 2002/08/31 06:12:29 das Exp $
+ */
+
+#include "tkInt.h"
+#include "X11/X.h"
+#include "X11/Xlib.h"
+#include <stdio.h>
+
+#include <Carbon/Carbon.h>
+#include "tkMacOSXInt.h"
+#include "tkPort.h"
+#include "tkMacOSXDebug.h"
+
+#ifndef PI
+# define PI 3.14159265358979323846
+#endif
+#define RGBFLOATRED( c ) (float)((float)(c.red) / 65535.0)
+#define RGBFLOATGREEN( c ) (float)((float)(c.green) / 65535.0)
+#define RGBFLOATBLUE( c ) (float)((float)(c.blue) / 65535.0)
+
+/*
+ * Temporary regions that can be reused.
+ */
+
+static RgnHandle tmpRgn = NULL;
+static RgnHandle tmpRgn2 = NULL;
+
+static PixPatHandle gPenPat = NULL;
+
+static int useCGDrawing = 0;
+
+/*
+ * Prototypes for functions used only in this file.
+ */
+static unsigned char InvertByte _ANSI_ARGS_((unsigned char data));
+
+void TkMacOSXSetUpCGContext(MacDrawable *macWin,
+ CGrafPtr destPort, GC gc, CGContextRef *contextPtr);
+void TkMacOSXReleaseCGContext(MacDrawable *macWin, CGrafPtr destPort,
+ CGContextRef *context);
+/*
+ *----------------------------------------------------------------------
+ *
+ * XCopyArea --
+ *
+ * Copies data from one drawable to another using block transfer
+ * routines.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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. */
+ unsigned int height,
+ 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;
+ short tmode;
+ RGBColor origForeColor, origBackColor, whiteColor, blackColor;
+ Rect clpRect;
+
+ dstPort = TkMacOSXGetDrawablePort(dst);
+ srcPort = TkMacOSXGetDrawablePort(src);
+
+ display->request++;
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(dstPort, NULL);
+ GetForeColor(&origForeColor);
+ GetBackColor(&origBackColor);
+ whiteColor.red = 0;
+ whiteColor.blue = 0;
+ whiteColor.green = 0;
+ RGBForeColor(&whiteColor);
+ blackColor.red = 0xFFFF;
+ blackColor.blue = 0xFFFF;
+ blackColor.green = 0xFFFF;
+ RGBBackColor(&blackColor);
+
+ if (tmpRgn2 == NULL) {
+ tmpRgn2 = NewRgn();
+ }
+ srcPtr = &srcRect;
+ SetRect(&srcRect, (short) (srcDraw->xOff + src_x),
+ (short) (srcDraw->yOff + src_y),
+ (short) (srcDraw->xOff + src_x + width ),
+ (short) (srcDraw->yOff + src_y + height));
+ if (tkPictureIsOpen ) {
+ dstPtr = &srcRect;
+ } else {
+ dstPtr = &dstRect;
+ SetRect(&dstRect, (short) (dstDraw->xOff + dest_x),
+ (short) (dstDraw->yOff + dest_y),
+ (short) (dstDraw->xOff + dest_x + width ),
+ (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.
+ */
+
+ GetClip(tmpRgn2);
+ 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
+ * In this case, would have also clipped to the srcRect
+ * ClipRect(&srcRect);
+ */
+ GetPortBounds(dstPort,&clpRect);
+ dstPtr = &srcRect;
+ ClipRect(&clpRect);
+ }
+ if (!gc->clip_mask ) {
+ } else if (((TkpClipMask*)gc->clip_mask)->type == TKP_CLIP_REGION) {
+ RgnHandle clipRgn = (RgnHandle)
+ ((TkpClipMask*)gc->clip_mask)->value.region;
+
+ int xOffset, yOffset;
+ 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);
+ if (!tkPictureIsOpen) {
+ OffsetRgn(clipRgn, -xOffset, -yOffset);
+ }
+ }
+ srcBit = GetPortBitMapForCopyBits( srcPort );
+ dstBit = GetPortBitMapForCopyBits( dstPort );
+ tmode = srcCopy;
+
+ CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL);
+ RGBForeColor(&origForeColor);
+ RGBBackColor(&origBackColor);
+ SetClip(tmpRgn2);
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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. */
+{
+ 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;
+ TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask;
+ short tmode;
+
+ srcPort = TkMacOSXGetDrawablePort(src);
+ dstPort = TkMacOSXGetDrawablePort(dst);
+
+ if (tmpRgn == NULL) {
+ tmpRgn = NewRgn();
+ }
+ display->request++;
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(dstPort, NULL);
+
+ TkMacOSXSetUpClippingRgn(dst);
+
+
+ srcBit = GetPortBitMapForCopyBits ( srcPort );
+ dstBit = GetPortBitMapForCopyBits ( dstPort );
+ SetRect(&srcRect, (short) (srcDraw->xOff + src_x),
+ (short) (srcDraw->yOff + src_y),
+ (short) (srcDraw->xOff + src_x + width),
+ (short) (srcDraw->yOff + src_y + height));
+ srcPtr = &srcRect;
+ if (tkPictureIsOpen) {
+ /*
+ * 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
+ */
+ Rect clpRect;
+ GetPortBounds(dstPort,&clpRect);
+ ClipRect(&clpRect);
+ dstPtr = &srcRect;
+ } else {
+ dstPtr = &dstRect;
+ SetRect(&dstRect, (short) (dstDraw->xOff + dest_x),
+ (short) (dstDraw->yOff + dest_y),
+ (short) (dstDraw->xOff + dest_x + width),
+ (short) (dstDraw->yOff + dest_y + height));
+ }
+ tmode = srcOr;
+ tmode = srcCopy + transparent;
+
+ if (TkSetMacColor(gc->foreground, &macColor) == true) {
+ RGBForeColor(&macColor);
+ }
+
+ if (clipPtr == NULL || clipPtr->type == TKP_CLIP_REGION) {
+
+ /*
+ * Case 1: opaque bitmaps.
+ */
+ TkSetMacColor(gc->background, &macColor);
+ RGBBackColor(&macColor);
+ 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
+ * the forecolor.
+ */
+ pm=GetPortPixMap(srcPort);
+ if (GetPixDepth(pm)== 1) {
+ tmode = srcOr;
+ } else {
+ tmode = transparent;
+ }
+ CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL);
+ } else {
+ /*
+ * Case 3: two arbitrary bitmaps.
+ */
+ tmode = srcCopy;
+ mskPort = TkMacOSXGetDrawablePort(clipPtr->value.pixmap);
+ mskBit = GetPortBitMapForCopyBits ( mskPort );
+ CopyDeepMask(srcBit, mskBit, dstBit,
+ srcPtr, srcPtr, dstPtr, tmode, NULL);
+ }
+ }
+
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkPutImage --
+ *
+ * Copies a subimage from an in-memory image to a rectangle of
+ * of the specified drawable.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Draws the image on the specified drawable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkPutImage(
+ unsigned long *colors, /* Unused on Macintosh. */
+ int ncolors, /* Unused on Macintosh. */
+ Display* display, /* Display. */
+ Drawable d, /* Drawable to place image on. */
+ GC gc, /* GC to use. */
+ XImage* image, /* Image to place. */
+ int src_x, /* Source X & Y. */
+ int src_y,
+ int dest_x, /* Destination X & Y. */
+ int dest_y,
+ unsigned int width, /* Same width & height for both */
+ unsigned int height) /* distination and source. */
+{
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ const BitMap * destBits;
+ int i, j;
+ BitMap bitmap;
+ char *newData = NULL;
+ Rect destRect, srcRect;
+
+ destPort = TkMacOSXGetDrawablePort(d);
+ SetRect(&destRect, dest_x, dest_y, dest_x + width, dest_y + height);
+ SetRect(&srcRect, src_x, src_y, src_x + width, src_y + height);
+
+ display->request++;
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ TkMacOSXSetUpClippingRgn(d);
+
+ if (image->depth == 1) {
+
+ /*
+ * This code assumes a pixel depth of 1
+ */
+
+ bitmap.bounds.top = bitmap.bounds.left = 0;
+ bitmap.bounds.right = (short) image->width;
+ bitmap.bounds.bottom = (short) image->height;
+ if ((image->bytes_per_line % 2) == 1) {
+ char *newPtr, *oldPtr;
+ newData = (char *) ckalloc(image->height *
+ (image->bytes_per_line + 1));
+ newPtr = newData;
+ oldPtr = image->data;
+ for (i = 0; i < image->height; i++) {
+ for (j = 0; j < image->bytes_per_line; j++) {
+ *newPtr = InvertByte((unsigned char) *oldPtr);
+ newPtr++, oldPtr++;
+ }
+ *newPtr = 0;
+ newPtr++;
+ }
+ bitmap.baseAddr = newData;
+ bitmap.rowBytes = image->bytes_per_line + 1;
+ } else {
+ newData = (char *) ckalloc(image->height * image->bytes_per_line);
+ for (i = 0; i < image->height * image->bytes_per_line; i++) {
+ newData[i] = InvertByte((unsigned char) image->data[i]);
+ }
+ bitmap.baseAddr = newData;
+ bitmap.rowBytes = image->bytes_per_line;
+ }
+ destBits = GetPortBitMapForCopyBits ( destPort );
+ CopyBits(&bitmap, destBits,
+ &srcRect, &destRect, srcCopy, NULL);
+
+ } else {
+ /* Color image */
+ PixMap pixmap;
+
+ pixmap.bounds.left = 0;
+ pixmap.bounds.top = 0;
+ pixmap.bounds.right = (short) image->width;
+ pixmap.bounds.bottom = (short) image->height;
+ pixmap.pixelType = RGBDirect;
+ pixmap.pmVersion = 4; /* 32bit clean */
+ pixmap.packType = 0;
+ pixmap.packSize = 0;
+ pixmap.hRes = 0x00480000;
+ pixmap.vRes = 0x00480000;
+ pixmap.pixelSize = 32;
+ pixmap.cmpCount = 3;
+ pixmap.cmpSize = 8;
+ pixmap.pixelFormat = 0;
+ pixmap.pmTable = NULL;
+ pixmap.pmExt = 0;
+ pixmap.baseAddr = image->data;
+ pixmap.rowBytes = image->bytes_per_line | 0x8000;
+
+ CopyBits((BitMap *) &pixmap, GetPortBitMapForCopyBits ( destPort ),
+ &srcRect, &destRect, srcCopy, NULL);
+ }
+
+ if (newData != NULL) {
+ ckfree(newData);
+ }
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XFillRectangles --
+ *
+ * Fill multiple rectangular areas in the given drawable.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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_rectangels) /* Number of rectangles. */
+{
+ MacDrawable *macWin = (MacDrawable *) d;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ Rect theRect;
+ int i;
+
+ destPort = TkMacOSXGetDrawablePort(d);
+
+ display->request++;
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ TkMacOSXSetUpClippingRgn(d);
+
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
+
+ for (i=0; i<n_rectangels; i++) {
+ theRect.left = (short) (macWin->xOff + rectangles[i].x);
+ theRect.top = (short) (macWin->yOff + rectangles[i].y);
+ theRect.right = (short) (theRect.left + rectangles[i].width);
+ theRect.bottom = (short) (theRect.top + rectangles[i].height);
+ FillCRect(&theRect, gPenPat);
+ }
+
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XDrawLines --
+ *
+ * Draw connected lines.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Renders a series of connected lines.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XDrawLines(
+ Display* display, /* Display. */
+ Drawable d, /* Draw on this. */
+ GC gc, /* Use this GC. */
+ 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;
+ int i;
+
+ destPort = TkMacOSXGetDrawablePort(d);
+
+ display->request++;
+ if (npoints < 2) {
+ return; /* TODO: generate BadValue error. */
+ }
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ TkMacOSXSetUpClippingRgn(d);
+
+ if (useCGDrawing) {
+ CGContextRef outContext;
+
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
+
+ CGContextBeginPath(outContext);
+ CGContextMoveToPoint(outContext, (float) points[0].x,
+ (float) points[0].y);
+ if (mode == CoordModeOrigin) {
+ for (i = 1; i < npoints; i++) {
+ CGContextAddLineToPoint(outContext,
+ (float) points[i].x,
+ (float) points[i].y);
+ }
+ }
+
+ CGContextStrokePath(outContext);
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
+
+ ShowPen();
+
+ PenPixPat(gPenPat);
+ MoveTo((short) (macWin->xOff + points[0].x),
+ (short) (macWin->yOff + points[0].y));
+ for (i = 1; i < npoints; i++) {
+ if (mode == CoordModeOrigin) {
+ LineTo((short) (macWin->xOff + points[i].x),
+ (short) (macWin->yOff + points[i].y));
+ } else {
+ Line((short) (macWin->xOff + points[i].x),
+ (short) (macWin->yOff + points[i].y));
+ }
+ }
+ HidePen();
+
+ }
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XDrawSegments --
+ *
+ * Draw unconnected lines.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Renders a series of connected lines.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void XDrawSegments(
+ Display *display,
+ Drawable d,
+ GC gc,
+ XSegment *segments,
+ int nsegments)
+{
+ MacDrawable *macWin = (MacDrawable *) d;
+ CGrafPtr saveWorld;
+ GWorldPtr destPort;
+ GDHandle saveDevice;
+ int i;
+
+ destPort = TkMacOSXGetDrawablePort(d);
+
+ display->request++;
+
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ TkMacOSXSetUpClippingRgn(d);
+
+ if (useCGDrawing) {
+ CGContextRef outContext;
+
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
+
+ CGContextBeginPath(outContext);
+ for (i = 0; i < nsegments; i++) {
+ CGContextMoveToPoint(outContext,
+ (float) segments[i].x1,
+ (float) segments[i].y1);
+ CGContextAddLineToPoint (outContext,
+ (float) segments[i].x2,
+ (float) segments[i].y2);
+ }
+ CGContextStrokePath(outContext);
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
+
+ ShowPen();
+
+ PenPixPat(gPenPat);
+ for (i = 0; i < nsegments; i++) {
+ MoveTo((short) (macWin->xOff + segments[i].x1),
+ (short) (macWin->yOff + segments[i].y1));
+ LineTo((short) (macWin->xOff + segments[i].x2),
+ (short) (macWin->yOff + segments[i].y2));
+ }
+ HidePen();
+ }
+
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XFillPolygon --
+ *
+ * Draws a filled polygon.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Draws a filled polygon on the specified drawable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XFillPolygon(
+ Display* display, /* Display. */
+ Drawable d, /* Draw on this. */
+ GC gc, /* Use this GC. */
+ XPoint* points, /* Array of points. */
+ int npoints, /* Number of points. */
+ int shape, /* Shape to draw. */
+ int mode) /* Drawing mode. */
+{
+ MacDrawable *macWin = (MacDrawable *) d;
+ PolyHandle polygon;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ int i;
+
+ destPort = TkMacOSXGetDrawablePort(d);
+
+ display->request++;
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ TkMacOSXSetUpClippingRgn(d);
+
+ if (useCGDrawing) {
+ CGContextRef outContext;
+
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
+
+ CGContextBeginPath(outContext);
+ CGContextMoveToPoint(outContext, (float) (points[0].x),
+ (float) (points[0].y));
+ for (i = 1; i < npoints; i++) {
+
+ if (mode == CoordModePrevious) {
+ CGContextAddLineToPoint(outContext, (float) points[i].x,
+ (float) points[i].y);
+ } else {
+ }
+ }
+ //CGContextStrokePath(outContext);
+ CGContextFillPath(outContext);
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
+
+ PenNormal();
+ polygon = OpenPoly();
+
+ MoveTo((short) (macWin->xOff + points[0].x),
+ (short) (macWin->yOff + points[0].y));
+ for (i = 1; i < npoints; i++) {
+ if (mode == CoordModePrevious) {
+ Line((short) (macWin->xOff + points[i].x),
+ (short) (macWin->yOff + points[i].y));
+ } else {
+ LineTo((short) (macWin->xOff + points[i].x),
+ (short) (macWin->yOff + points[i].y));
+ }
+ }
+
+ ClosePoly();
+
+ FillCPoly(polygon, gPenPat);
+
+ KillPoly(polygon);
+ }
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XDrawRectangle --
+ *
+ * Draws a rectangle.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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. */
+ unsigned int height)
+{
+ MacDrawable *macWin = (MacDrawable *) d;
+ Rect theRect;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+
+ destPort = TkMacOSXGetDrawablePort(d);
+
+ display->request++;
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ TkMacOSXSetUpClippingRgn(d);
+
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
+
+ theRect.left = (short) (macWin->xOff + x);
+ theRect.top = (short) (macWin->yOff + y);
+ theRect.right = (short) (theRect.left + width);
+ theRect.bottom = (short) (theRect.top + height);
+
+ ShowPen();
+ PenPixPat(gPenPat);
+ FrameRect(&theRect);
+ HidePen();
+
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XDrawRectangles --
+ *
+ * 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]
+ *
+ * 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.
+ *
+ * Side effects:
+ * Draws rectangles on the specified drawable.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+XDrawRectangles(
+ Display *display,
+ Drawable drawable,
+ GC gc,
+ XRectangle *rectArr,
+ int nRects)
+{
+ MacDrawable *macWin = (MacDrawable *) drawable;
+ Rect rect;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ XRectangle * rectPtr;
+ int i;
+
+ destPort = TkMacOSXGetDrawablePort(drawable);
+
+ display->request++;
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ TkMacOSXSetUpClippingRgn(drawable);
+
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
+
+
+ ShowPen();
+ PenPixPat(gPenPat);
+
+ for (i = 0, rectPtr = rectArr; i < nRects;i++, rectPtr++ ) {
+ rect.left = (short) (macWin->xOff + rectPtr->x);
+ rect.top = (short) (macWin->yOff + rectPtr->y);
+ rect.right = (short) (rect.left + rectPtr->width);
+ rect.bottom = (short) (rect.top + rectPtr->height);
+ FrameRect(&rect);
+ }
+ HidePen();
+
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XDrawArc --
+ *
+ * Draw an arc.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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. */
+ unsigned int height,
+ int angle1, /* Staring angle of arc. */
+ int angle2) /* Ending angle of arc. */
+{
+ MacDrawable *macWin = (MacDrawable *) d;
+ Rect theRect;
+ short start, extent;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ float fX = (float) x,
+ fY = (float) y,
+ fWidth = (float) width,
+ fHeight = (float) height;
+
+ if (width == 0 || height == 0) {
+ return;
+ }
+
+ destPort = TkMacOSXGetDrawablePort(d);
+
+ display->request++;
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ TkMacOSXSetUpClippingRgn(d);
+
+ if (useCGDrawing) {
+ CGContextRef outContext;
+ CGAffineTransform transform;
+ int clockwise = angle1 ? 0 : 1;
+
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
+
+ CGContextBeginPath(outContext);
+
+ /*
+ * If we are drawing an oval, we have to squash the coordinate
+ * system before drawing, since CGContextAddArcToPoint only draws
+ * circles.
+ */
+
+ CGContextSaveGState(outContext);
+ transform = CGAffineTransformMakeTranslation((float) (x + width/2),
+ (float) (y + height/2));
+ transform = CGAffineTransformScale(transform, 1.0, fHeight/fWidth);
+ CGContextConcatCTM(outContext, transform);
+
+ CGContextAddArc(outContext, 0.0, 0.0,
+ (float) width/2,
+ (float) angle1, (float) angle2, clockwise);
+
+ CGContextRestoreGState(outContext);
+
+ CGContextStrokePath(outContext);
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
+
+
+ theRect.left = (short) (macWin->xOff + x);
+ theRect.top = (short) (macWin->yOff + y);
+ theRect.right = (short) (theRect.left + width);
+ theRect.bottom = (short) (theRect.top + height);
+ start = (short) (90 - (angle1 / 64));
+ extent = (short) (-(angle2 / 64));
+
+ ShowPen();
+ PenPixPat(gPenPat);
+ FrameArc(&theRect, start, extent);
+ HidePen();
+ }
+
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Draws an arc for each array element on the specified drawable.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+XDrawArcs(
+ Display *display,
+ Drawable d,
+ GC gc,
+ XArc *arcArr,
+ int nArcs)
+{
+
+ MacDrawable *macWin = (MacDrawable *) d;
+ Rect rect;
+ short start, extent;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ XArc * arcPtr;
+ int i;
+
+ destPort = TkMacOSXGetDrawablePort(d);
+
+ display->request++;
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ TkMacOSXSetUpClippingRgn(d);
+
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
+
+
+ ShowPen();
+ PenPixPat(gPenPat);
+ for (i = 0, arcPtr = arcArr;i < nArcs;i++, arcPtr++ ) {
+ rect.left = (short) (macWin->xOff + arcPtr->x);
+ rect.top = (short) (macWin->yOff + arcPtr->y);
+ rect.right = (short) (rect.left + arcPtr->width);
+ rect.bottom = (short) (rect.top + arcPtr->height);
+ start = (short) (90 - (arcPtr->angle1 / 64));
+ extent = (short) (-(arcPtr->angle2 / 64));
+ FrameArc(&rect, start, extent);
+ }
+ HidePen();
+
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XFillArc --
+ *
+ * Draw a filled arc.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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. */
+ unsigned int height,
+ int angle1, /* Staring angle of arc. */
+ int angle2) /* Ending angle of arc. */
+{
+ MacDrawable *macWin = (MacDrawable *) d;
+ Rect theRect;
+ short start, extent;
+ PolyHandle polygon;
+ double sin1, cos1, sin2, cos2, angle;
+ double boxWidth, boxHeight;
+ double vertex[2], center1[2], center2[2];
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+
+ destPort = TkMacOSXGetDrawablePort(d);
+
+ display->request++;
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ TkMacOSXSetUpClippingRgn(d);
+
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
+
+ theRect.left = (short) (macWin->xOff + x);
+ theRect.top = (short) (macWin->yOff + y);
+ theRect.right = (short) (theRect.left + width);
+ theRect.bottom = (short) (theRect.top + height);
+ start = (short) (90 - (angle1 / 64));
+ extent = (short) (- (angle2 / 64));
+
+ if (gc->arc_mode == ArcChord) {
+ boxWidth = theRect.right - theRect.left;
+ boxHeight = theRect.bottom - theRect.top;
+ angle = -(angle1/64.0)*PI/180.0;
+ sin1 = sin(angle);
+ cos1 = cos(angle);
+ angle -= (angle2/64.0)*PI/180.0;
+ sin2 = sin(angle);
+ cos2 = cos(angle);
+ vertex[0] = (theRect.left + theRect.right)/2.0;
+ vertex[1] = (theRect.top + theRect.bottom)/2.0;
+ center1[0] = vertex[0] + cos1*boxWidth/2.0;
+ center1[1] = vertex[1] + sin1*boxHeight/2.0;
+ center2[0] = vertex[0] + cos2*boxWidth/2.0;
+ center2[1] = vertex[1] + sin2*boxHeight/2.0;
+
+ polygon = OpenPoly();
+ MoveTo((short) ((theRect.left + theRect.right)/2),
+ (short) ((theRect.top + theRect.bottom)/2));
+
+ LineTo((short) (center1[0] + 0.5), (short) (center1[1] + 0.5));
+ LineTo((short) (center2[0] + 0.5), (short) (center2[1] + 0.5));
+ ClosePoly();
+
+ ShowPen();
+ FillCArc(&theRect, start, extent, gPenPat);
+ FillCPoly(polygon, gPenPat);
+ HidePen();
+
+ KillPoly(polygon);
+ } else {
+ ShowPen();
+ FillCArc(&theRect, start, extent, gPenPat);
+ HidePen();
+ }
+
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XFillArcs --
+ *
+ * Draw a filled arc.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Draws a filled arc for each array element on the specified drawable.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+XFillArcs(
+ Display *display,
+ Drawable d,
+ GC gc,
+ XArc *arcArr,
+ int nArcs)
+{
+ MacDrawable *macWin = (MacDrawable *) d;
+ Rect rect;
+ short start, extent;
+ PolyHandle polygon;
+ double sin1, cos1, sin2, cos2, angle;
+ double boxWidth, boxHeight;
+ double vertex[2], center1[2], center2[2];
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ int i;
+ XArc * arcPtr;
+
+ destPort = TkMacOSXGetDrawablePort(d);
+
+ display->request++;
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ TkMacOSXSetUpClippingRgn(d);
+
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
+
+ for (i = 0, arcPtr = arcArr;i<nArcs;i++, arcPtr++ ) {
+ rect.left = (short) (macWin->xOff + arcPtr->x);
+ rect.top = (short) (macWin->yOff + arcPtr->y);
+ rect.right = (short) (rect.left + arcPtr->width);
+ rect.bottom = (short) (rect.top + arcPtr->height);
+ start = (short) (90 - (arcPtr->angle1 / 64));
+ extent = (short) (- (arcPtr->angle2 / 64));
+
+ if (gc->arc_mode == ArcChord) {
+ boxWidth = rect.right - rect.left;
+ boxHeight = rect.bottom - rect.top;
+ angle = -(arcPtr->angle1/64.0)*PI/180.0;
+ sin1 = sin(angle);
+ cos1 = cos(angle);
+ angle -= (arcPtr->angle2/64.0)*PI/180.0;
+ sin2 = sin(angle);
+ cos2 = cos(angle);
+ vertex[0] = (rect.left + rect.right)/2.0;
+ vertex[1] = (rect.top + rect.bottom)/2.0;
+ center1[0] = vertex[0] + cos1*boxWidth/2.0;
+ center1[1] = vertex[1] + sin1*boxHeight/2.0;
+ center2[0] = vertex[0] + cos2*boxWidth/2.0;
+ center2[1] = vertex[1] + sin2*boxHeight/2.0;
+
+ polygon = OpenPoly();
+ MoveTo((short) ((rect.left + rect.right)/2),
+ (short) ((rect.top + rect.bottom)/2));
+
+ LineTo((short) (center1[0] + 0.5), (short) (center1[1] + 0.5));
+ LineTo((short) (center2[0] + 0.5), (short) (center2[1] + 0.5));
+ ClosePoly();
+
+ ShowPen();
+ FillCArc(&rect, start, extent, gPenPat);
+ FillCPoly(polygon, gPenPat);
+ HidePen();
+
+ KillPoly(polygon);
+ } else {
+ ShowPen();
+ FillCArc(&rect, start, extent, gPenPat);
+ HidePen();
+ }
+ }
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XMaxRequestSize --
+ *
+ *----------------------------------------------------------------------
+ */
+long
+XMaxRequestSize(Display *display)
+{
+ return (SHRT_MAX / 4);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkScrollWindow --
+ *
+ * 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.
+ *
+ * Side effects:
+ * 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. */
+{
+ MacDrawable *destDraw = (MacDrawable *) Tk_WindowId(tkwin);
+ RgnHandle rgn = (RgnHandle) damageRgn;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ Rect srcRect, scrollRect;
+ RgnHandle visRgn, clipRgn;
+
+ destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin));
+
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ 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
+ * 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
+ * to "skip" over an area if the offset makes the source and
+ * destination rects disjoint and non-aligned.
+ */
+
+ SetRect(&srcRect, (short) (destDraw->xOff + x),
+ (short) (destDraw->yOff + y),
+ (short) (destDraw->xOff + x + width),
+ (short) (destDraw->yOff + y + height));
+ scrollRect = srcRect;
+ if (dx < 0) {
+ scrollRect.left += dx;
+ } else {
+ scrollRect.right += dx;
+ }
+ if (dy < 0) {
+ scrollRect.top += dy;
+ } else {
+ scrollRect.bottom += dy;
+ }
+
+ /*
+ * Adjust clip region so that we don't copy any windows
+ * that may overlap us.
+ */
+ visRgn = NewRgn();
+ clipRgn = NewRgn();
+ RectRgn(rgn, &srcRect);
+ GetPortVisibleRegion(destPort,visRgn);
+ DiffRgn(rgn, visRgn, rgn);
+ OffsetRgn(rgn, dx, dy);
+ GetPortClipRegion(destPort, clipRgn);
+ DiffRgn(clipRgn, rgn, clipRgn);
+ SetPortClipRegion(destPort, clipRgn);
+ 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);
+ /*
+ * Fortunantly, the region returned by ScrollRect is symanticlly
+ * 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.
+ */
+ if (EmptyRgn(rgn)) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXSetUpGraphicsPort --
+ *
+ * Set up the graphics port from the given GC.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The current port is adjusted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXSetUpGraphicsPort(
+ GC gc,
+ GWorldPtr destPort) /* GC to apply to current port. */
+{
+ 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) {
+ unsigned char *p = (unsigned char *) &(gc->dashes);
+ /*
+ * 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, we either
+ * have to convert all line drawings to regions, or, on Mac OS X
+ * we can use CG to draw our lines instead of QuickDraw.
+ */
+ }
+}
+ /*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXSetUpGraphicsPort --
+ *
+ * Set up the graphics port from the given GC.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The current port is adjusted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXSetUpCGContext(
+ MacDrawable *macWin,
+ CGrafPtr destPort,
+ GC gc,
+ CGContextRef *contextPtr) /* GC to apply to current port. */
+{
+ RGBColor macColor;
+ CGContextRef outContext;
+ OSStatus err;
+ Rect boundsRect;
+ CGAffineTransform coordsTransform;
+
+ err = QDBeginCGContext(destPort, contextPtr);
+ outContext = *contextPtr;
+
+ CGContextSaveGState(outContext);
+
+ GetPortBounds(destPort, &boundsRect);
+
+ CGContextResetCTM(outContext);
+ coordsTransform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0,
+ (float)(boundsRect.bottom - boundsRect.top));
+ CGContextConcatCTM(outContext, coordsTransform);
+
+ if (macWin->clipRgn != NULL) {
+ ClipCGContextToRegion(outContext, &boundsRect, macWin->clipRgn);
+ } else {
+ RgnHandle clipRgn = NewRgn();
+ GetPortClipRegion(destPort, clipRgn);
+ ClipCGContextToRegion(outContext, &boundsRect,
+ clipRgn);
+ DisposeRgn(clipRgn);
+ }
+
+ /* Now offset the CTM to the subwindow offset */
+
+ CGContextTranslateCTM(outContext, macWin->xOff, macWin->yOff);
+
+ if (TkSetMacColor(gc->foreground, &macColor) == true) {
+ CGContextSetRGBStrokeColor(outContext, RGBFLOATRED(macColor),
+ RGBFLOATGREEN(macColor),
+ RGBFLOATBLUE(macColor), 1.0);
+ }
+ if (TkSetMacColor(gc->background, &macColor) == true) {
+ CGContextSetRGBFillColor(outContext, RGBFLOATRED(macColor),
+ RGBFLOATGREEN(macColor),
+ RGBFLOATBLUE(macColor), 1.0);
+ }
+
+ if(gc->function == GXxor) {
+ }
+
+ CGContextSetLineWidth(outContext, (float) gc->line_width);
+
+ if (gc->line_style != LineSolid) {
+ unsigned char *p = (unsigned char *) &(gc->dashes);
+ /*
+ * 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, we either
+ * have to convert all line drawings to regions, or, on Mac OS X
+ * we can use CG to draw our lines instead of QuickDraw.
+ */
+ }
+}
+
+void
+TkMacOSXReleaseCGContext(
+ MacDrawable *macWin,
+ CGrafPtr destPort,
+ CGContextRef *outContext)
+{
+ CGContextResetCTM(*outContext);
+ CGContextRestoreGState(*outContext);
+ QDEndCGContext(destPort, outContext);
+
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXSetUpClippingRgn --
+ *
+ * Set up the clipping region so that drawing only occurs on the
+ * specified X subwindow.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The clipping region in the current port is changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXSetUpClippingRgn(
+ Drawable drawable) /* Drawable to update. */
+{
+ MacDrawable *macDraw = (MacDrawable *) drawable;
+
+ if (macDraw->winPtr != NULL) {
+ if (macDraw->flags & TK_CLIP_INVALID) {
+ TkMacOSXUpdateClipRgn(macDraw->winPtr);
+ }
+
+ /*
+ * 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 (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);
+ }
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * A BitMap data structure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+BitMapPtr
+TkMacOSXMakeStippleMap(
+ Drawable drawable, /* Window to apply stipple. */
+ Drawable stipple) /* The stipple pattern. */
+{
+ GWorldPtr destPort;
+ BitMapPtr bitmapPtr;
+ Rect portRect;
+ int width, height, stippleHeight, stippleWidth;
+ int i, j;
+ char * data;
+ Rect bounds;
+
+ destPort = TkMacOSXGetDrawablePort(drawable);
+
+ GetPortBounds ( destPort, &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;
+
+ destPort = TkMacOSXGetDrawablePort(stipple);
+ stippleWidth = portRect.right - portRect.left;
+ stippleHeight = portRect.bottom - portRect.top;
+
+ for (i = 0; i < height; i += stippleHeight) {
+ for (j = 0; j < width; j += stippleWidth) {
+ bounds.left = j;
+ bounds.top = i;
+ bounds.right = j + stippleWidth;
+ bounds.bottom = i + stippleHeight;
+
+ CopyBits(GetPortBitMapForCopyBits ( destPort ), bitmapPtr,
+ &portRect, &bounds, srcCopy, NULL);
+ }
+ }
+ return bitmapPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InvertByte --
+ *
+ * This function reverses the bits in the passed in Byte of data.
+ *
+ * Results:
+ * The incoming byte in reverse bit order.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static unsigned char
+InvertByte(
+ unsigned char data) /* Byte of data. */
+{
+ unsigned char i;
+ unsigned char mask = 1, result = 0;
+
+ for (i = (1 << 7); i != 0; i /= 2) {
+ if (data & mask) {
+ result |= i;
+ }
+ mask = mask << 1;
+ }
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDrawpHighlightBorder --
+ *
+ * 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.
+ *
+ * For proper Mac L&F, use highlightWidth of 3.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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)
+{
+ if (highlightWidth == 1) {
+ TkDrawInsetFocusHighlight (tkwin, fgGC, highlightWidth, drawable, 0);
+ } else {
+ TkDrawInsetFocusHighlight (tkwin, bgGC, highlightWidth, drawable, 0);
+ if (fgGC != bgGC) {
+ TkDrawInsetFocusHighlight (tkwin, fgGC, highlightWidth - 1, drawable, 0);
+ }
+ }
+}
diff --git a/macosx/tkMacOSXEmbed.c b/macosx/tkMacOSXEmbed.c
new file mode 100644
index 0000000..3405014
--- /dev/null
+++ b/macosx/tkMacOSXEmbed.c
@@ -0,0 +1,1193 @@
+/*
+ * 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.
+ *
+ * Copyright (c) 1996-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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 2002/08/31 06:12:29 das Exp $
+ */
+
+#include "tkInt.h"
+#include "tkPort.h"
+#include "X11/X.h"
+#include "X11/Xlib.h"
+#include <stdio.h>
+
+#include <Carbon/Carbon.h>
+#include "tkMacOSXInt.h"
+
+/*
+ * One of the following structures exists for each container in this
+ * 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. */
+} Container;
+
+static Container *firstContainerPtr = NULL;
+ /* First in list of all containers
+ * managed by this process. */
+/*
+ * Globals defined in this file
+ */
+
+TkMacOSXEmbedHandler *gMacEmbedHandler = 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));
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * The embed handler is set.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+Tk_MacOSXSetEmbedHandler(
+ Tk_MacOSXEmbedRegisterWinProc *registerWinProc,
+ Tk_MacOSXEmbedGetGrafPortProc *getPortProc,
+ Tk_MacOSXEmbedMakeContainerExistProc *containerExistProc,
+ Tk_MacOSXEmbedGetClipProc *getClipProc,
+ Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc)
+{
+ if (gMacEmbedHandler == NULL) {
+ gMacEmbedHandler = (TkMacOSXEmbedHandler *) ckalloc(sizeof(TkMacOSXEmbedHandler));
+ }
+ gMacEmbedHandler->registerWinProc = registerWinProc;
+ gMacEmbedHandler->getPortProc = getPortProc;
+ gMacEmbedHandler->containerExistProc = containerExistProc;
+ gMacEmbedHandler->getClipProc = getClipProc;
+ gMacEmbedHandler->getOffsetProc = getOffsetProc;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpMakeWindow --
+ *
+ * Creates an X Window (Mac subwindow).
+ *
+ * Results:
+ * The window id is returned.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Window
+TkpMakeWindow(
+ TkWindow *winPtr,
+ Window parent)
+{
+ MacDrawable *macWin;
+ XEvent event;
+
+ /*
+ * If this window is marked as embedded then
+ * the window structure should have already been
+ * created in the TkpUseWindow function.
+ */
+
+ if (Tk_IsEmbedded(winPtr)) {
+ return (Window) winPtr->privatePtr;
+ }
+
+ /*
+ * Allocate sub window
+ */
+
+ macWin = (MacDrawable *) ckalloc(sizeof(MacDrawable));
+ if (macWin == NULL) {
+ winPtr->privatePtr = NULL;
+ return None;
+ }
+ macWin->winPtr = winPtr;
+ winPtr->privatePtr = macWin;
+ macWin->clipRgn = NewRgn();
+ macWin->aboveClipRgn = NewRgn();
+ macWin->referenceCount = 0;
+ macWin->flags = TK_CLIP_INVALID;
+
+ 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;
+ } 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->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;
+ Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
+
+ return (Window) macWin;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * Side effects:
+ * 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. */
+{
+ TkWindow *winPtr = (TkWindow *) tkwin;
+ MacDrawable *parent, *macWin;
+ Container *containerPtr;
+ XEvent event;
+ int result;
+
+ if (winPtr->window != None) {
+ panic("TkpUseWindow: X window already assigned");
+ }
+
+ /*
+ * 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
+ * application as tkwin, since otherwise they would not be in our list
+ * of containers.
+ *
+ */
+
+ if (Tcl_GetInt(interp, string, &result) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ parent = (MacDrawable *) result;
+
+ /*
+ * 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
+ * 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;
+ }
+ }
+
+ /*
+ * Make the embedded window.
+ */
+
+ macWin = (MacDrawable *) ckalloc(sizeof(MacDrawable));
+ if (macWin == NULL) {
+ 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.
+ */
+
+ macWin->grafPtr = NULL;
+
+ macWin->clipRgn = NewRgn();
+ macWin->aboveClipRgn = 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
+ * 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 (gMacEmbedHandler == NULL ||
+ gMacEmbedHandler->registerWinProc(result, (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;
+
+ }
+ } 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);
+
+ }
+
+ /*
+ * 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;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpMakeContainer(
+ Tk_Window tkwin) /* Token for a window that is about to
+ * become a container. */
+{
+ TkWindow *winPtr = (TkWindow *) tkwin;
+ Container *containerPtr;
+
+ /*
+ * Register the window as a container so that, for example, we can
+ * make sure the argument to -use is valid.
+ */
+
+
+ Tk_MakeWindowExist(tkwin);
+ containerPtr = (Container *) ckalloc(sizeof(Container));
+ containerPtr->parent = Tk_WindowId(tkwin);
+ containerPtr->parentPtr = winPtr;
+ containerPtr->embedded = None;
+ containerPtr->embeddedPtr = NULL;
+ 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
+ * the container down to the embedded toplevel.
+ */
+
+ Tk_CreateEventHandler(tkwin,
+ SubstructureNotifyMask|SubstructureRedirectMask,
+ ContainerEventProc, (ClientData) winPtr);
+ Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbedStructureProc,
+ (ClientData) containerPtr);
+ Tk_CreateEventHandler(tkwin, ActivateMask, EmbedActivateProc,
+ (ClientData) containerPtr);
+ Tk_CreateEventHandler(tkwin, FocusChangeMask, EmbedFocusProc,
+ (ClientData) containerPtr);
+
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXContainerId --
+ *
+ * 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.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+MacDrawable *
+TkMacOSXContainerId(winPtr)
+ 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;
+ }
+ }
+ panic("TkMacOSXContainerId couldn't find window");
+ return None;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXGetHostToplevel --
+ *
+ * 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
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+MacDrawable *
+TkMacOSXGetHostToplevel(
+ TkWindow *winPtr) /* Tk's structure for a window. */
+{
+ TkWindow *contWinPtr, *topWinPtr;
+
+ topWinPtr = winPtr->privatePtr->toplevel->winPtr;
+ if (!Tk_IsEmbedded(topWinPtr)) {
+ 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;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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. */
+{
+ XEvent event;
+ Container *containerPtr;
+
+ if (!(topLevelPtr->flags & TK_EMBEDDED)) {
+ return;
+ }
+
+ for (containerPtr = firstContainerPtr;
+ containerPtr->embeddedPtr != topLevelPtr;
+ containerPtr = containerPtr->nextPtr) {
+ /* Empty loop body. */
+ }
+
+
+ event.xfocus.type = FocusIn;
+ event.xfocus.serial = LastKnownRequestProcessed(topLevelPtr->display);
+ event.xfocus.send_event = 1;
+ event.xfocus.display = topLevelPtr->display;
+ event.xfocus.window = containerPtr->parent;
+ event.xfocus.mode = EMBEDDED_APP_WANTS_FOCUS;
+ event.xfocus.detail = force;
+ Tk_QueueWindowEvent(&event,TCL_QUEUE_TAIL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpTestembedCmd --
+ *
+ * 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.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpTestembedCmd(
+ 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;
+ Tcl_DString dString;
+ char buffer[50];
+
+ if ((argc > 1) && (strcmp(argv[1], "all") == 0)) {
+ all = 1;
+ } else {
+ 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);
+ }
+ Tcl_DStringResult(interp, &dString);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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). */
+{
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetOtherWindow --
+ *
+ * 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.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkWindow *
+TkpGetOtherWindow(
+ TkWindow *winPtr) /* Tk's structure for a container or
+ * embedded window. */
+{
+ Container *containerPtr;
+
+ /*
+ * TkpGetOtherWindow returns NULL if both windows are not
+ * in the same process...
+ */
+
+ if (!(winPtr->flags & TK_BOTH_HALVES)) {
+ 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;
+ }
+ }
+ 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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. */
+{
+ TkWindow *winPtr = (TkWindow *) clientData;
+
+ if (eventPtr->type == DestroyNotify) {
+ EmbedWindowDeleted(winPtr);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * NOTE: on the Mac, only the DestroyNotify branch is ever taken.
+ * We don't synthesize the other events.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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. */
+{
+ TkWindow *winPtr = (TkWindow *) clientData;
+ Container *containerPtr;
+ Tk_ErrorHandler errHandler;
+
+ /*
+ * Ignore any X protocol errors that happen in this procedure
+ * (almost any operation could fail, for example, if the embedded
+ * application has deleted its window).
+ */
+
+ errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
+ -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) {
+ 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;
+ } 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);
+ } 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);
+ } else if (eventPtr->type == DestroyNotify) {
+ /*
+ * The embedded application is gone. Destroy the container window.
+ */
+
+ Tk_DestroyWindow((Tk_Window) winPtr);
+ }
+ Tk_DeleteErrorHandler(errHandler);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The embedded window gets resized to match the container.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+EmbedStructureProc(clientData, eventPtr)
+ 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);
+ }
+ } else if (eventPtr->type == DestroyNotify) {
+ EmbedWindowDeleted(containerPtr->parentPtr);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The X focus may change.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+EmbedActivateProc(clientData, eventPtr)
+ 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);
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The X focus may change.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+EmbedFocusProc(clientData, eventPtr)
+ ClientData clientData; /* Token for container window. */
+ XEvent *eventPtr; /* ResizeRequest event. */
+{
+ Container *containerPtr = (Container *) clientData;
+ Display *display;
+ XEvent event;
+
+ 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;
+
+ 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);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * NOTE: On the Mac, this is a stub, since we don't synthesize
+ * ConfigureRequest events.
+ *
+ * Results:
+ * 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.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+EmbedGeometryRequest(containerPtr, width, height)
+ Container *containerPtr; /* Information about the embedding. */
+ int width, height; /* Size that the child has requested. */
+{
+ TkWindow *winPtr = containerPtr->parentPtr;
+
+ /*
+ * Forward the requested size into our geometry management hierarchy
+ * via the container window. We need to send a Configure event back
+ * 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
+ * chance to do whatever they want to do), and if the window's size
+ * didn't change then generate a configure event.
+ */
+
+ Tk_GeometryRequest((Tk_Window) winPtr, width, height);
+ while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {
+ /* Empty loop body. */
+ }
+ if ((winPtr->changes.width != width)
+ || (winPtr->changes.height != height)) {
+ EmbedSendConfigure(containerPtr);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+EmbedSendConfigure(containerPtr)
+ Container *containerPtr; /* Information about the embedding. */
+{
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * A Container structure may be freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+EmbedWindowDeleted(winPtr)
+ TkWindow *winPtr; /* Tk's information about window that
+ * was deleted. */
+{
+ Container *containerPtr, *prevPtr;
+
+ /*
+ * Find the Container structure for this window. Delete the
+ * information about the embedded application and free the container's
+ * record.
+ */
+
+ 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 == NULL)
+ && (containerPtr->parentPtr == NULL)) {
+ if (prevPtr == NULL) {
+ firstContainerPtr = containerPtr->nextPtr;
+ } else {
+ prevPtr->nextPtr = containerPtr->nextPtr;
+ }
+ ckfree((char *) containerPtr);
+ }
+}
+
diff --git a/macosx/tkMacOSXEvent.c b/macosx/tkMacOSXEvent.c
new file mode 100644
index 0000000..a55d0fd
--- /dev/null
+++ b/macosx/tkMacOSXEvent.c
@@ -0,0 +1,276 @@
+/*
+ * tkMacOSXEvent.c --
+ *
+ * This file contains most of the X calls called by Tk. Many of
+ * these calls are just stubs and either don't make sense on the
+ * Macintosh or thier implamentation just doesn't do anything. Other
+ * calls will eventually be moved into other files.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.2 2002/08/31 06:12:29 das Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include "tkMacOSXInt.h"
+#include "tkMacOSXEvent.h"
+#include "tkMacOSXDebug.h"
+
+#define TK_MAC_DEBUG 1
+
+/*
+ * The following are undocumented event classes
+ *
+ */
+enum {
+ kEventClassUser = 'user',
+ kEventClassCgs = 'cgs ',
+};
+
+/*
+ * The following are undocumented event kinds
+ *
+ */
+enum {
+ kEventMouse8 = 8,
+ kEventMouse9 = 9,
+ kEventApp103 = 103
+};
+
+EventRef TkMacOSXCreateFakeEvent ();
+
+/*
+ * Forward declarations of procedures used in this file.
+ */
+static int ReceiveAndProcessEvent _ANSI_ARGS_(());
+
+static EventTargetRef targetRef;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * tkMacOSXFlushWindows --
+ *
+ * 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.
+ *
+ * Side effects:
+ * Flushes all Carbon windows
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+tkMacOSXFlushWindows ()
+{
+ WindowRef wRef = GetWindowList();
+
+ while (wRef) {
+ CGrafPtr portPtr = GetWindowPort(wRef);
+ if (QDIsPortBuffered(portPtr)) {
+ QDFlushPortBuffer(portPtr, NULL);
+ }
+ wRef=GetNextWindow(wRef);
+ }
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXCountAndProcessMacEvents --
+ *
+ * This routine receives any Carbon events that aare in the
+ * queue and converts them to tk events
+ * It is called by the event set-up and check routines
+ * Results:
+ * The number of events in the queue.
+ *
+ * Side effects:
+ * Tells the Window Manager to deliver events to the event
+ * queue of the current thread.
+ * Receives any Carbon events on the queue and converts them to tk events
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkMacOSXCountAndProcessMacEvents()
+{
+ EventQueueRef qPtr;
+ int eventCount;
+ qPtr = GetMainEventQueue();
+ eventCount = GetNumEventsInQueue(qPtr);
+ if (eventCount) {
+ int n, err;
+ for (n = 0, err = 0;n<eventCount && !err;n++) {
+ err = ReceiveAndProcessEvent();
+ }
+ }
+ return eventCount;
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXProcessAppleEvent --
+ *
+ * This processes Apple events
+ *
+ * Results:
+ * 0 on success
+ * -1 on failure
+ *
+ * Side effects:
+ * Calls the Tk high-level event handler
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TkMacOSXProcessAppleEvent(TkMacOSXEvent * eventPtr, MacEventStatus * statusPtr)
+{
+ int err;
+ EventRecord eventRecord;
+ if (ConvertEventRefToEventRecord(eventPtr->eventRef,
+ &eventRecord )) {
+ err=TkMacOSXDoHLEvent(&eventRecord);
+ if (err!=noErr) {
+ char buf1 [ 256 ];
+ char buf2 [ 256 ];
+ fprintf(stderr,
+ "TkMacOSXDoHLEvent failed : %s,%s,%d\n",
+ CarbonEventToAscii(eventPtr->eventRef, buf1),
+ ClassicEventToAscii(&eventRecord,buf2), err);
+ statusPtr->err = 1;
+ } else {
+ statusPtr->handledByTk = 1;
+ }
+ } else {
+ statusPtr->err = 1;
+ fprintf(stderr,"ConvertEventRefToEventRecord failed\n");
+ }
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXProcessEvent --
+ *
+ * This dispatches a filtered Carbon event to the appropriate handler
+ *
+ * Results:
+ * 0 on success
+ * -1 on failure
+ *
+ * Side effects:
+ * Converts a Carbon event to a Tk event
+ *
+ *----------------------------------------------------------------------
+ */
+
+static 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 kEventClassAppleEvent:
+ TkMacOSXProcessAppleEvent(eventPtr, statusPtr);
+ break;
+ case kEventClassCgs:
+ case kEventClassUser:
+ case kEventClassWish:
+ statusPtr->handledByTk = 1;
+ break;
+ default:
+#ifdef TK_MAC_DEBUG
+ if (0)
+ {
+ char buf [ 256 ];
+ fprintf(stderr,
+ "Unrecognised event : %s\n",
+ CarbonEventToAscii(eventPtr->eventRef, buf));
+ }
+#endif
+ break;
+ }
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReceiveAndProcessEvent --
+ *
+ * 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
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReceiveAndProcessEvent()
+{
+ TkMacOSXEvent macEvent;
+ MacEventStatus eventStatus;
+ int err;
+ char buf [ 256 ];
+
+ /*
+ * 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, &macEvent.eventRef);
+ if (err != noErr) {
+ return err;
+ } else {
+ macEvent.eClass = GetEventClass(macEvent.eventRef);
+ macEvent.eKind = GetEventKind(macEvent.eventRef);
+ bzero(&eventStatus, sizeof(eventStatus));
+ TkMacOSXProcessEvent(&macEvent,&eventStatus);
+ if (!eventStatus.handledByTk) {
+ if (!targetRef) {
+ targetRef=GetEventDispatcherTarget();
+ }
+
+ err= SendEventToEventTarget(macEvent.eventRef,targetRef);
+ if (err != noErr /* && err != eventNotHandledErr */) {
+ fprintf(stderr,
+ "RCNE SendEventToEventTarget (%s) failed, %d\n",
+ CarbonEventToAscii(macEvent.eventRef,buf ),err);
+ }
+ }
+ ReleaseEvent(macEvent.eventRef);
+ return 0;
+ }
+}
diff --git a/macosx/tkMacOSXEvent.h b/macosx/tkMacOSXEvent.h
new file mode 100644
index 0000000..2ce339b
--- /dev/null
+++ b/macosx/tkMacOSXEvent.h
@@ -0,0 +1,86 @@
+/*
+ * tkMacOSXEvent.h --
+ *
+ * Declarations of Macintosh specific functions for implementing the
+ * Mac OS X Notifier.
+ *
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _TKMACEVENT
+#define _TKMACEVENT
+
+#include <Carbon/Carbon.h>
+#include <tcl.h>
+
+enum {
+ kEventClassWish = 'WiSH'
+};
+
+typedef struct {
+ int handledByTk;
+ int err;
+ char errMsg[1024];
+} MacEventStatus;
+
+/*
+ * The event information in passed in the following structures
+ */
+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 */
+} TkMacOSXEvent;
+
+int TkMacOSXCountAndProcessMacEvents _ANSI_ARGS_(());
+void tkMacOSXFlushWindows _ANSI_ARGS_(());
+int TkMacOSXProcessMouseEvent(TkMacOSXEvent * e, MacEventStatus * statusPtr);
+int TkMacOSXProcessWindowEvent(TkMacOSXEvent * e, MacEventStatus * statusPtr);
+int TkMacOSXProcessKeyboardEvent(TkMacOSXEvent * e, MacEventStatus * statusPtr);
+int TkMacOSXProcessApplicationEvent(TkMacOSXEvent * e, MacEventStatus * statusPtr);
+
+#endif
diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c
new file mode 100644
index 0000000..40e637d
--- /dev/null
+++ b/macosx/tkMacOSXFont.c
@@ -0,0 +1,2191 @@
+/*
+ * tkMacOSXFont.c --
+ *
+ * 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.
+ *
+ * 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.2 2002/08/31 06:12:29 das Exp $
+ */
+#include <Carbon/Carbon.h>
+
+#include "tkMacOSXInt.h"
+#include "tkFont.h"
+
+/*
+ * For doing things with Mac strings and Fixed numbers. This probably should move
+ * the mac header file.
+ */
+
+#ifndef StrLength
+#define StrLength(s) (*((unsigned char *) (s)))
+#endif
+#ifndef StrBody
+#define StrBody(s) ((char *) (s) + 1)
+#endif
+#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[] = {
+ "macRoman", "macJapan", NULL
+};
+
+/*
+ * 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
+ * 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"},
+ {NULL, NULL}
+};
+
+static TkStateMap romanMap[] = {
+ {langCroatian, "macCroatian"},
+ {langSlovenian, "macCroatian"},
+ {langIcelandic, "macIceland"},
+ {langRomanian, "macRomania"},
+ {langTurkish, "macTurkish"},
+ {langGreek, "macGreek"},
+ {NULL, NULL}
+};
+
+static TkStateMap cyrillicMap[] = {
+ {langUkrainian, "macUkraine"},
+ {langBulgarian, "macBulgaria"},
+ {NULL, NULL}
+};
+
+/*
+ * The following structure represents a font family. It is assumed that
+ * all screen fonts constructed from the same "font family" share certain
+ * properties; all screen fonts with the same "font family" point to a
+ * shared instance of this structure. The most important shared property
+ * is the character existence metrics, used to determine if a screen font
+ * can display a given Unicode character.
+ *
+ * Under Macintosh, a "font family" is uniquely identified by its face number.
+ */
+
+
+#define FONTMAP_SHIFT 10
+
+#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. */
+ /*
+ * Key.
+ */
+
+ 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. */
+ 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. */
+} FontFamily;
+
+/*
+ * The following structure encapsulates an individual screen font. A font
+ * object is made up of however many SubFonts are necessary to display a
+ * stream of multilingual characters.
+ */
+
+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. */
+} SubFont;
+
+/*
+ * The following structure represents Macintosh's implementation of a font
+ * object.
+ */
+
+#define SUBFONT_SPACE 3
+
+typedef struct MacFont {
+ 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. */
+} 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
+ * 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. */
+} FontNameMap;
+
+/*
+ * 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.
+ */
+
+static FontFamily *fontFamilyList = NULL;
+
+/*
+ * Information cached about the system at startup time.
+ */
+
+static FontNameMap *gFontNameMap = NULL;
+static GWorldPtr gWorld = NULL;
+
+/*
+ * Procedures used only in this file.
+ */
+
+static FontFamily * AllocFontFamily(CONST MacFont *fontPtr, int family);
+static SubFont * CanUseFallback(MacFont *fontPtr, CONST char *fallbackName, int ch);
+static SubFont * CanUseFallbackWithAliases(MacFont *fontPtr, CONST char *faceName, int ch, Tcl_DString *nameTriedPtr);
+static SubFont * FindSubFontForChar(MacFont *fontPtr, int ch);
+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 ReleaseFont(MacFont *fontPtr);
+static void ReleaseSubFont(SubFont *subFontPtr);
+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 Tcl_Encoding GetFontEncoding(int faceNum, int allowSymbol, int *isSymbolPtr);
+static Tk_Uid GetUtfFaceName(StringPtr faceNameStr);
+
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * See comments below.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+TkpFontPkgInit(mainPtr)
+ TkMainInfo *mainPtr; /* The application being created. */
+{
+ FMFontFamilyIterator fontFamilyIterator;
+ 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) {
+ 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) {
+ 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;
+ }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TkpGetNativeFont --
+ *
+ * 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.
+ *
+ * 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().
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+TkFont *
+TkpGetNativeFont(
+ 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();
+ } else {
+ return NULL;
+ }
+
+ fontPtr = (MacFont *) ckalloc(sizeof(MacFont));
+ InitFont(tkwin, family, 0, 0, fontPtr);
+
+ return (TkFont *) fontPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TkpGetFontFromAttributes --
+ *
+ * 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.
+ *
+ * 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().
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+TkFont *
+TkpGetFontFromAttributes(
+ TkFont *tkFontPtr, /* If non-NULL, store the information in
+ * this existing TkFont structure, rather than
+ * allocating a new structure to hold the
+ * font; the existing contents of the font
+ * will be released. If NULL, a new TkFont
+ * structure is allocated. */
+ Tk_Window tkwin, /* For display where font will be used. */
+ CONST TkFontAttributes *faPtr)
+ /* Set of attributes to match. */
+{
+ short faceNum, style;
+ int i, j;
+ 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
+ */
+
+ 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;
+ }
+ }
+ }
+
+ found:
+ style = 0;
+ if (faPtr->weight != TK_FW_NORMAL) {
+ style |= bold;
+ }
+ if (faPtr->slant != TK_FS_ROMAN) {
+ style |= italic;
+ }
+ if (faPtr->underline) {
+ style |= underline;
+ }
+ if (tkFontPtr == NULL) {
+ fontPtr = (MacFont *) ckalloc(sizeof(MacFont));
+ } else {
+ fontPtr = (MacFont *) tkFontPtr;
+ ReleaseFont(fontPtr);
+ }
+ InitFont(tkwin, faceNum, faPtr->size, style, fontPtr);
+
+ return (TkFont *) fontPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * TkFont is deallocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+TkpDeleteFont(
+ TkFont *tkFontPtr) /* Token of font to be deleted. */
+{
+ MacFont *fontPtr;
+
+ fontPtr = (MacFont *) tkFontPtr;
+ ReleaseFont(fontPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TkpGetFontFamilies --
+ *
+ * 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.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+TkpGetFontFamilies(
+ 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);
+ }
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * TkpGetSubFonts --
+ *
+ * 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.
+ *
+ * Side effects:
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+TkpGetSubFonts(interp, tkfont)
+ Tcl_Interp *interp; /* Interp to hold result. */
+ Tk_Font tkfont; /* Font object to query. */
+{
+ int i;
+ Tcl_Obj *resultPtr, *strPtr;
+ MacFont *fontPtr;
+ FontFamily *familyPtr;
+ Str255 nativeName;
+
+ 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);
+ }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * Side effects:
+ * 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. */
+{
+ MacFont *fontPtr;
+ FontFamily *lastFamilyPtr;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ int curX, curByte;
+
+ /*
+ * According to "Inside Macintosh: Text", the Macintosh may
+ * automatically substitute
+ * ligatures or context-sensitive presentation forms when
+ * measuring/displaying text within a font run. We cannot safely
+ * measure individual characters and add up the widths w/o errors.
+ * However, if we convert a range of text from UTF-8 to, say,
+ * Shift-JIS, and get the offset into the Shift-JIS string as to
+ * 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);
+
+ TextSize(fontPtr->size);
+ TextFace(fontPtr->style);
+
+ lastFamilyPtr = fontPtr->subFontArray[0].familyPtr;
+
+ if (numBytes == 0) {
+ curX = 0;
+ curByte = 0;
+ } else if (maxLength < 0) {
+ CONST char *p, *end, *next;
+ Tcl_UniChar ch;
+ FontFamily *thisFamilyPtr;
+ 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);
+ thisFamilyPtr = FindSubFontForChar(fontPtr, ch)->familyPtr;
+ if (thisFamilyPtr != lastFamilyPtr) {
+ TextFont(lastFamilyPtr->faceNum);
+ Tcl_UtfToExternalDString(lastFamilyPtr->encoding, source,
+ p - source, &runString);
+ curX += TextWidth(Tcl_DStringValue(&runString), 0,
+ Tcl_DStringLength(&runString));
+ Tcl_DStringFree(&runString);
+ lastFamilyPtr = thisFamilyPtr;
+ source = p;
+ }
+ p = next;
+ }
+ TextFont(lastFamilyPtr->faceNum);
+ Tcl_UtfToExternalDString(lastFamilyPtr->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;
+ FontFamily *thisFamilyPtr;
+ 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);
+ thisFamilyPtr = FindSubFontForChar(fontPtr, ch)->familyPtr;
+ if (thisFamilyPtr != lastFamilyPtr) {
+ if (p > source) {
+ rest = BreakLine(lastFamilyPtr, flags, source,
+ p - source, &widthLeft);
+ flags &= ~TK_AT_LEAST_ONE;
+ if (rest != NULL) {
+ p = source;
+ break;
+ }
+ }
+ lastFamilyPtr = thisFamilyPtr;
+ source = p;
+ }
+ }
+
+ if (p > source) {
+ rest = BreakLine(lastFamilyPtr, flags, source, p - source,
+ &widthLeft);
+ }
+
+ if (rest == NULL) {
+ curByte = numBytes;
+ } else {
+ curByte = rest - sourceOrig;
+ }
+ curX = maxLength - widthLeft;
+ }
+
+ SetGWorld(saveWorld, saveDevice);
+
+ *lengthPtr = curX;
+ return curByte;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+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. */
+{
+ Fixed pixelWidth, widthLeft;
+ StyledLineBreakCode breakCode;
+ Tcl_DString runString;
+ long textOffset;
+ Boolean leadingEdge;
+ Point point;
+ int charOffset, thisCharWasDoubleByte;
+ char *p, *end, *typeTable;
+
+ TextFont(familyPtr->faceNum);
+ Tcl_UtfToExternalDString(familyPtr->encoding, source, numBytes,
+ &runString);
+ pixelWidth = Int2Fixed(*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;
+ }
+ } 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;
+ }
+ }
+ *widthLeftPtr = Fixed2Int(widthLeft);
+ Tcl_DStringFree(&runString);
+ return NULL;
+
+ /*
+ * 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;
+ } 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++;
+ }
+ }
+
+ 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 ((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);
+ Tcl_DStringFree(&runString);
+ return Tcl_UtfAtIndex(source, charOffset);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tk_DrawChars --
+ *
+ * Draw a string of characters on the screen.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * 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. */
+{
+ MacFont *fontPtr;
+ MacDrawable *macWin;
+ RGBColor macColor, origColor;
+ GWorldPtr destPort;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ short txFont, txFace, txSize;
+ BitMapPtr stippleMap;
+ Rect portRect;
+
+ 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);
+
+ 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();
+ }
+
+ TextFont(txFont);
+ TextSize(txSize);
+ TextFace(txFace);
+ RGBForeColor(&origColor);
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * MultiFontDrawText --
+ *
+ * Helper function for Tk_DrawChars. Draws characters, using the
+ * various screen fonts in fontPtr to draw multilingual characters.
+ * Note: No bidirectional support.
+ *
+ * Results:
+ * 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.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+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. */
+{
+ FontFamily *lastFamilyPtr, *thisFamilyPtr = NULL;
+ Tcl_DString runString;
+ CONST char *p, *end, *next;
+ Tcl_UniChar ch;
+
+ TextSize(fontPtr->size);
+ TextFace(fontPtr->style);
+
+ lastFamilyPtr = fontPtr->subFontArray[0].familyPtr;
+
+ end = source + numBytes;
+ for (p = source; p < end; ) {
+ next = p + Tcl_UtfToUniChar(p, &ch);
+ thisFamilyPtr = FindSubFontForChar(fontPtr, ch)->familyPtr;
+ if (thisFamilyPtr != lastFamilyPtr) {
+ if (p > source) {
+ TextFont(lastFamilyPtr->faceNum);
+ Tcl_UtfToExternalDString(lastFamilyPtr->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;
+ }
+ lastFamilyPtr = thisFamilyPtr;
+ }
+ p = next;
+ }
+ if (p > source) {
+ TextFont(thisFamilyPtr->faceNum);
+ Tcl_UtfToExternalDString(lastFamilyPtr->encoding, source,
+ p - source, &runString);
+ MoveTo((short) x, (short) y);
+ DrawText(Tcl_DStringValue(&runString), 0,
+ Tcl_DStringLength(&runString));
+ Tcl_DStringFree(&runString);
+ }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * Returns a 1 if the character is missing, a 0 if it is not.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TkMacOSXIsCharacterMissing(
+ 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
+ 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
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * InitFont --
+ *
+ * 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().
+ *
+ * Results:
+ * Fills the MacFont structure.
+ *
+ * Side effects:
+ * 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. */
+{
+ Str255 nativeName;
+ FontInfo fi;
+ TkFontAttributes *faPtr;
+ TkFontMetrics *fmPtr;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ short pixels;
+
+ if (size == 0) {
+ size = -GetDefFontSize();
+ }
+ pixels = (short) TkFontGetPixels(tkwin, size);
+
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(gWorld, NULL);
+ TextFont(faceNum);
+
+
+ TextSize(pixels);
+ TextFace(style);
+
+ GetFontInfo(&fi);
+ GetFontName(faceNum, nativeName);
+ fontPtr->font.fid = (Font) fontPtr;
+
+ faPtr = &fontPtr->font.fa;
+ faPtr->family = GetUtfFaceName(nativeName);
+ 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->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);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * ReleaseFont --
+ *
+ * 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.
+ *
+ * Side effects:
+ * Memory is freed.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+ReleaseFont(
+ MacFont *fontPtr) /* The font to delete. */
+{
+ int i;
+
+ for (i = 0; i < fontPtr->numSubFonts; i++) {
+ ReleaseSubFont(&fontPtr->subFontArray[i]);
+ }
+ if (fontPtr->subFontArray != fontPtr->staticSubFonts) {
+ ckfree((char *) fontPtr->subFontArray);
+ }
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * The subFontPtr is filled with information about the font.
+ *
+ * Side effects:
+ * 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. */
+{
+ subFontPtr->familyPtr = AllocFontFamily(fontPtr, faceNum);
+ subFontPtr->fontMap = subFontPtr->familyPtr->fontMap;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * ReleaseSubFont --
+ *
+ * Called to release the contents of a SubFont. The caller is
+ * responsible for freeing the memory used by the SubFont itself.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Memory and resources are freed.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+ReleaseSubFont(
+ SubFont *subFontPtr) /* The SubFont to delete. */
+{
+ FreeFontFamily(subFontPtr->familyPtr);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * Side effects:
+ * 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. */
+{
+ FontFamily *familyPtr;
+ int i;
+
+ familyPtr = fontFamilyList;
+ for (; familyPtr != NULL; familyPtr = familyPtr->nextPtr) {
+ if (familyPtr->faceNum == faceNum) {
+ familyPtr->refCount++;
+ return familyPtr;
+ }
+ }
+
+ familyPtr = (FontFamily *) ckalloc(sizeof(FontFamily));
+ memset(familyPtr, 0, sizeof(FontFamily));
+ familyPtr->nextPtr = fontFamilyList;
+ fontFamilyList = familyPtr;
+
+ /*
+ * 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;
+ }
+ }
+ return familyPtr;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+FreeFontFamily(
+ FontFamily *familyPtr) /* The FontFamily to delete. */
+{
+ FontFamily **familyPtrPtr;
+ int i;
+
+ if (familyPtr == NULL) {
+ return;
+ }
+ familyPtr->refCount--;
+ if (familyPtr->refCount > 0) {
+ return;
+ }
+ Tcl_FreeEncoding(familyPtr->encoding);
+ for (i = 0; i < FONTMAP_PAGES; i++) {
+ if (familyPtr->fontMap[i] != NULL) {
+ ckfree((char *) familyPtr->fontMap[i]);
+ }
+ }
+
+ /*
+ * Delete from list.
+ */
+
+ for (familyPtrPtr = &fontFamilyList; ; ) {
+ if (*familyPtrPtr == familyPtr) {
+ *familyPtrPtr = familyPtr->nextPtr;
+ break;
+ }
+ familyPtrPtr = &(*familyPtrPtr)->nextPtr;
+ }
+
+ ckfree((char *) familyPtr);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * 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.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static SubFont *
+FindSubFontForChar(
+ MacFont *fontPtr, /* The font object with which the character
+ * will be displayed. */
+ int ch) /* The Unicode character to be displayed. */
+{
+ int i, j, k;
+ 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];
+ }
+
+ for (i = 1; i < fontPtr->numSubFonts; 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);
+ if (subFontPtr != NULL) {
+ goto end;
+ }
+ }
+ }
+
+ /*
+ * 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);
+ if (subFontPtr != NULL) {
+ goto end;
+ }
+ }
+
+ /*
+ * Try all face names available in the whole system until we
+ * find one that can be used.
+ */
+
+ for (mapPtr = gFontNameMap; mapPtr->utfName != NULL; mapPtr++) {
+ fallbackName = mapPtr->utfName;
+ if (SeenName(fallbackName, &faceNames) == 0) {
+ subFontPtr = CanUseFallback(fontPtr, fallbackName, ch);
+ 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.
+ */
+
+ subFontPtr = &fontPtr->subFontArray[0];
+ FontMapInsert(subFontPtr, ch);
+ }
+ return subFontPtr;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * FontMapLookup --
+ *
+ * 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.
+ *
+ * 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.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+FontMapLookup(
+ 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);
+ }
+ bitOffset = ch & (FONTMAP_BITSPERPAGE - 1);
+ return (subFontPtr->fontMap[row][bitOffset >> 3] >> (bitOffset & 7)) & 1;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * 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.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+FontMapInsert(
+ 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);
+ }
+ bitOffset = ch & (FONTMAP_BITSPERPAGE - 1);
+ subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Mempry allocated.
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+FontMapLoadPage(
+ 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;
+ int i, end, bitOffset, isMultiByteFont;
+ char src[TCL_UTF_MAX];
+ unsigned char buf[16];
+ int srcRead, dstWrote;
+ Tcl_Encoding encoding;
+ Handle fHandle = NULL;
+
+ 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;
+ fm.needBits = 0;
+ fm.device = 0;
+ fm.numer.h = 1;
+ 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
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * 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.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+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 *subFontPtr;
+ char **aliases;
+ int i;
+
+ if (SeenName(faceName, nameTriedPtr) == 0) {
+ subFontPtr = CanUseFallback(fontPtr, faceName, ch);
+ if (subFontPtr != NULL) {
+ return subFontPtr;
+ }
+ }
+ aliases = TkFontGetAliasList(faceName);
+ if (aliases != NULL) {
+ for (i = 0; aliases[i] != NULL; i++) {
+ if (SeenName(aliases[i], nameTriedPtr) == 0) {
+ subFontPtr = CanUseFallback(fontPtr, aliases[i], ch);
+ if (subFontPtr != NULL) {
+ return subFontPtr;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * The return value is 0 if this face name has not already been seen,
+ * non-zero otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+SeenName(
+ CONST char *name, /* The name to check. */
+ Tcl_DString *dsPtr) /* Contains names that have already been
+ * seen. */
+{
+ 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;
+ }
+ Tcl_DStringAppend(dsPtr, (char *) name, (int) (strlen(name) + 1));
+ return 0;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * 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.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+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. */
+{
+ int i;
+ SubFont subFont;
+ short faceNum;
+
+ if (GetFamilyNum(faceName, &faceNum) == 0) {
+ 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;
+ }
+ }
+
+ /*
+ * 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 (fontPtr->numSubFonts >= SUBFONT_SPACE) {
+ SubFont *newPtr;
+ newPtr = (SubFont *) ckalloc(sizeof(SubFont)
+ * (fontPtr->numSubFonts + 1));
+ memcpy((char *) newPtr, fontPtr->subFontArray,
+ fontPtr->numSubFonts * sizeof(SubFont));
+ if (fontPtr->subFontArray != fontPtr->staticSubFonts) {
+ ckfree((char *) fontPtr->subFontArray);
+ }
+ fontPtr->subFontArray = newPtr;
+ }
+ fontPtr->subFontArray[fontPtr->numSubFonts] = subFont;
+ fontPtr->numSubFonts++;
+ return &fontPtr->subFontArray[fontPtr->numSubFonts - 1];
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * Side effects:
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+GetFamilyNum(
+ 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;
+ }
+ }
+ }
+ *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. */
+{
+ char **aliases;
+ int i;
+
+ if (GetFamilyNum(faceName, faceNumPtr) != 0) {
+ return 1;
+ }
+ aliases = TkFontGetAliasList(faceName);
+ if (aliases != NULL) {
+ for (i = 0; aliases[i] != NULL; i++) {
+ if (GetFamilyNum(aliases[i], faceNumPtr) != 0) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * Side effects:
+ * None.
+ *
+ *------------------------------------------------------------------------
+ */
+
+static Tk_Uid
+GetUtfFaceName(
+ 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;
+ }
+ }
+ panic("GetUtfFaceName: unexpected nativeName");
+ return NULL;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * Side effects:
+ * 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. */
+{
+ Str255 faceName;
+ int script, lang;
+ 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");
+ }
+ }
+ *isSymbolPtr = 0;
+ script = FontToScript(faceNum);
+ lang = GetScriptVariable(script, smScriptLang);
+ name = NULL;
+ if (script == smRoman) {
+ name = TkFindStateString(romanMap, lang);
+ } else if (script == smCyrillic) {
+ name = TkFindStateString(cyrillicMap, lang);
+ }
+ if (name == NULL) {
+ name = TkFindStateString(scriptMap, script);
+ }
+ return Tcl_GetEncoding(NULL, name);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXInitControlFontStyle --
+ *
+ * This procedure sets up the appropriate ControlFontStyleRec
+ * for a Mac control.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXInitControlFontStyle(Tk_Font tkfont, ControlFontStylePtr fsPtr)
+{
+ MacFont *fontPtr;
+ FontFamily *lastFamilyPtr;
+ fontPtr = (MacFont *) tkfont;
+ lastFamilyPtr = fontPtr->subFontArray[0].familyPtr;
+ fsPtr->flags =
+ kControlUseFontMask|
+ kControlUseSizeMask|
+ kControlUseFaceMask|
+ kControlUseJustMask;
+ fsPtr->font = lastFamilyPtr->faceNum;
+ fsPtr->size = fontPtr->size;
+ fsPtr->style = fontPtr->style;
+ fsPtr->just = teCenter;
+}
diff --git a/macosx/tkMacOSXHLEvents.c b/macosx/tkMacOSXHLEvents.c
new file mode 100644
index 0000000..4a1d30c
--- /dev/null
+++ b/macosx/tkMacOSXHLEvents.c
@@ -0,0 +1,447 @@
+/*
+ * tkMacOSXHLEvents.c --
+ *
+ * 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.
+ *
+ * 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.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#include "tkMacOSXUtil.h"
+#include "tkMacOSXInt.h"
+
+#include <Carbon/Carbon.h>
+
+/*
+ * This is a Tcl_Event structure that the Quit AppleEvent handler
+ * uses to schedule the tkReallyKillMe 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 */
+} KillEvent;
+
+/*
+ * Static functions used only in this file.
+ */
+
+static OSErr QuitHandler (const AppleEvent * event, AppleEvent * reply, long handlerRefcon);
+static OSErr OappHandler (const AppleEvent * event, AppleEvent * reply, long handlerRefcon);
+static OSErr OdocHandler (const AppleEvent * event, AppleEvent * reply, long handlerRefcon);
+static OSErr PrintHandler (const AppleEvent * event, AppleEvent * reply, long handlerRefcon);
+static OSErr ScriptHandler (const AppleEvent * event, AppleEvent * reply, long handlerRefcon);
+static OSErr PrefsHandler (const AppleEvent * event, AppleEvent * reply, long handlerRefcon);
+
+static int MissedAnyParameters _ANSI_ARGS_((const AppleEvent *theEvent));
+static int ReallyKillMe _ANSI_ARGS_((Tcl_Event *eventPtr, int flags));
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXInitAppleEvents --
+ *
+ * Initilize the Apple Events on the Macintosh. This registers the
+ * core event handlers.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXInitAppleEvents(
+ Tcl_Interp *interp) /* Interp to handle basic events. */
+{
+ OSErr err;
+ AEEventHandlerUPP OappHandlerUPP, OdocHandlerUPP,
+ PrintHandlerUPP, QuitHandlerUPP, ScriptHandlerUPP,
+ PrefsHandlerUPP;
+
+ /*
+ * Install event handlers for the core apple events.
+ */
+ QuitHandlerUPP = NewAEEventHandlerUPP(QuitHandler);
+ err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
+ QuitHandlerUPP, (long) interp, false);
+
+ OappHandlerUPP = NewAEEventHandlerUPP(OappHandler);
+ err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
+ OappHandlerUPP, (long) interp, false);
+
+ OdocHandlerUPP = NewAEEventHandlerUPP(OdocHandler);
+ err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
+ OdocHandlerUPP, (long) interp, false);
+
+ PrintHandlerUPP = NewAEEventHandlerUPP(PrintHandler);
+ err = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
+ PrintHandlerUPP, (long) interp, false);
+
+ PrefsHandlerUPP = NewAEEventHandlerUPP(PrefsHandler);
+ err = AEInstallEventHandler(kCoreEventClass, kAEShowPreferences,
+ PrefsHandlerUPP, (long) interp, false);
+
+ if (interp != NULL) {
+ ScriptHandlerUPP = NewAEEventHandlerUPP(ScriptHandler);
+ err = AEInstallEventHandler('misc', 'dosc',
+ ScriptHandlerUPP, (long) interp, false);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXDoHLEvent --
+ *
+ * Dispatch incomming highlevel events.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Depends on the incoming event.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkMacOSXDoHLEvent(EventRecord *theEvent)
+{
+ return AEProcessAppleEvent(theEvent);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * QuitHandler, OappHandler, etc. --
+ *
+ * These are the core Apple event handlers. Only the Quit event does
+ * anything interesting.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+OSErr QuitHandler (const AppleEvent * event, AppleEvent * reply, long handlerRefcon)
+{
+ Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
+ KillEvent *eventPtr;
+
+ /*
+ * 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
+ * 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 (const AppleEvent * event, AppleEvent * reply, long handlerRefcon)
+{
+ return noErr;
+}
+
+/* Called when the user selects 'Preferences...' in MacOS X */
+static OSErr
+PrefsHandler (const AppleEvent * event, AppleEvent * reply, long handlerRefcon)
+{
+ Tcl_CmdInfo dummy;
+ Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
+ /*
+ * Don't bother if we don't have an interp or
+ * the show preferences procedure doesn't exist.
+ */
+
+ if ((interp == NULL) ||
+ (Tcl_GetCommandInfo(interp, "::tk::mac::ShowPreferences", &dummy)) == 0) {
+ return noErr;
+ }
+ Tcl_GlobalEval(interp, "::tk::mac::ShowPreferences");
+ return noErr;
+}
+
+static OSErr
+OdocHandler (const AppleEvent * event, AppleEvent * reply, long handlerRefcon)
+{
+ Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
+ AEDescList fileSpecList;
+ FSSpec file;
+ OSErr err;
+ DescType type;
+ Size actual;
+ long count;
+ AEKeyword keyword;
+ long index;
+ Tcl_DString command;
+ Tcl_DString pathName;
+ Tcl_CmdInfo dummy;
+
+ /*
+ * Don't bother if we don't have an interp or
+ * the open document procedure doesn't exist.
+ */
+
+ 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);
+ if (err != noErr) {
+ return noErr;
+ }
+
+ err = MissedAnyParameters(event);
+ if (err != noErr) {
+ return noErr;
+ }
+
+ err = AECountItems(&fileSpecList, &count);
+ if (err != noErr) {
+ return noErr;
+ }
+
+ Tcl_DStringInit(&command);
+ Tcl_DStringAppend(&command, "::tk::mac::OpenDocument", -1);
+ for (index = 1; index <= count; index++) {
+ int length;
+ Handle fullPath;
+
+ err = AEGetNthPtr(&fileSpecList, index, typeFSS,
+ &keyword, &type, (Ptr) &file, sizeof(FSSpec), &actual);
+ if ( err != noErr ) {
+ continue;
+ }
+
+ err = FSpPathFromLocation(&file, &length, &fullPath);
+ HLock(fullPath);
+ Tcl_ExternalToUtfDString(NULL, *fullPath, length, &pathName);
+ HUnlock(fullPath);
+ DisposeHandle(fullPath);
+
+ Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName));
+ Tcl_DStringFree(&pathName);
+ }
+
+ Tcl_GlobalEval(interp, Tcl_DStringValue(&command));
+
+ Tcl_DStringFree(&command);
+ return noErr;
+}
+
+static OSErr
+PrintHandler (const AppleEvent * event, AppleEvent * reply, long handlerRefcon)
+{
+ return noErr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ScriptHandler --
+ *
+ * This handler process the script event.
+ *
+ * Results:
+ * Schedules the given event to be processed.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static OSErr
+ScriptHandler (const AppleEvent * event, AppleEvent * reply, long handlerRefcon)
+{
+ OSErr theErr;
+ AEDescList theDesc;
+ int tclErr = -1;
+ Tcl_Interp *interp;
+ char errString[128];
+
+ interp = (Tcl_Interp *) handlerRefcon;
+
+ /*
+ * The do script event receives one parameter that should be data or a file.
+ */
+ theErr = AEGetParamDesc(event, keyDirectObject, typeWildCard,
+ &theDesc);
+ if (theErr != noErr) {
+ sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", 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;
+ } else {
+ if (theDesc.descriptorType == (DescType)'TEXT') {
+ 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)'alis') {
+ Boolean dummy;
+ FSSpec theFSS;
+ Handle fullPath;
+ int length;
+ AliasHandle aliasHandle;
+
+ AEGetDescData (&theDesc,&aliasHandle,sizeof(aliasHandle ) );
+
+ theErr = ResolveAlias(NULL, aliasHandle,
+ &theFSS, &dummy);
+ if (theErr == noErr) {
+ FSpPathFromLocation(&theFSS, &length, &fullPath);
+ HLock(fullPath);
+ Tcl_EvalFile(interp, *fullPath);
+ HUnlock(fullPath);
+ DisposeHandle(fullPath);
+ } 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));
+ }
+ }
+
+ AEDisposeDesc(&theDesc);
+
+ return theErr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReallyKillMe --
+ *
+ * This proc tries to kill the shell by running exit, and if that
+ * has not succeeded (e.g. because someone has renamed the exit
+ * command), calls Tcl_Exit to really kill the shell. Called from
+ * an event scheduled by the "Quit" AppleEvent handler.
+ *
+ * Results:
+ * Kills the shell.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReallyKillMe(Tcl_Event *eventPtr, int flags)
+{
+ Tcl_Interp *interp = ((KillEvent *) eventPtr)->interp;
+ if (interp != NULL) {
+ Tcl_GlobalEval(interp, "exit");
+ }
+ Tcl_Exit(0);
+
+ return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MissedAnyParameters --
+ *
+ * Checks to see if parameters are still left in the event.
+ *
+ * Results:
+ * True or false.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+MissedAnyParameters(
+ const AppleEvent *theEvent)
+{
+ DescType returnedType;
+ Size actualSize;
+ OSErr err;
+
+ err = AEGetAttributePtr(theEvent, keyMissedKeywordAttr, typeWildCard,
+ &returnedType, NULL, 0, &actualSize);
+
+ return (err != errAEDescNotFound);
+}
diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c
new file mode 100644
index 0000000..ffcab99
--- /dev/null
+++ b/macosx/tkMacOSXInit.c
@@ -0,0 +1,221 @@
+/*
+ * tkUnixInit.c --
+ *
+ * This file contains Unix-specific interpreter initialization
+ * functions.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#include "tkInt.h"
+#include "tkMacOSXInt.h"
+
+/*
+ * The Init script (common to Windows and Unix platforms) is
+ * defined in tkInitScript.h
+ */
+#include "tkInitScript.h"
+
+/*
+ * 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
+ * defined by Apple.
+ */
+
+typedef struct Map {
+ int numKey;
+ char *strKey;
+} Map;
+
+static Map 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"},
+ {NULL, NULL}
+};
+
+Tcl_Encoding TkMacOSXCarbonEncoding = NULL;
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpInit --
+ *
+ * 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.
+ *
+ * Side effects:
+ * Sets "tk_library" Tcl variable, runs "tk.tcl" script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpInit(interp)
+ Tcl_Interp *interp;
+{
+ char tkLibPath[1024];
+ int result;
+ static int menusInitialized = false;
+ static int carbonEncodingInitialized = false;
+
+ /*
+ * Since it is possible for TkInit to be called multiple times
+ * and we don't want to do the menu initialization multiple times
+ * we protect against doing it more than once.
+ */
+
+ if (menusInitialized == false) {
+ menusInitialized = true;
+ Tk_MacOSXSetupTkNotifier();
+ TkMacOSXInitAppleEvents(interp);
+ TkMacOSXInitMenus(interp);
+ }
+
+ if (carbonEncodingInitialized == false) {
+ CFStringEncoding encoding;
+ char *encodingStr = NULL;
+ int i;
+
+ 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);
+ }
+ }
+
+ /*
+ * 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?
+ */
+
+ result = Tcl_MacOSXOpenBundleResources(interp, "com.tcltk.tklibrary",
+ 1, 1024, tkLibPath);
+
+ if (result != TCL_ERROR) {
+ Tcl_SetVar(interp, "tk_library", tkLibPath, TCL_GLOBAL_ONLY);
+ }
+
+ return Tcl_Eval(interp, initScript);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * Returns the application name in the given Tcl_DString.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpGetAppName(interp, namePtr)
+ Tcl_Interp *interp;
+ Tcl_DString *namePtr; /* A previously initialized Tcl_DString. */
+{
+ CONST char *p, *name;
+
+ name = Tcl_GetVar(interp, "argv0", TCL_GLOBAL_ONLY);
+ if ((name == NULL) || (*name == 0)) {
+ name = "tk";
+ } else {
+ p = strrchr(name, '/');
+ if (p != NULL) {
+ name = p+1;
+ }
+ }
+ Tcl_DStringAppend(namePtr, name, -1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDisplayWarning --
+ *
+ * This routines is called from Tk_Main to display warning
+ * messages that occur during startup.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Generates messages on stdout.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpDisplayWarning(msg, title)
+ CONST char *msg; /* Message to be displayed. */
+ CONST char *title; /* Title of warning. */
+{
+ Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);
+ if (errChannel) {
+ Tcl_WriteChars(errChannel, title, -1);
+ Tcl_WriteChars(errChannel, ": ", 2);
+ Tcl_WriteChars(errChannel, msg, -1);
+ Tcl_WriteChars(errChannel, "\n", 1);
+ }
+}
diff --git a/macosx/tkMacOSXInt.h b/macosx/tkMacOSXInt.h
new file mode 100644
index 0000000..b609d6e
--- /dev/null
+++ b/macosx/tkMacOSXInt.h
@@ -0,0 +1,155 @@
+/*
+ * tkMacOSXInt.h --
+ *
+ * Declarations of Macintosh specific shared variables and procedures.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#ifndef _TKMACINT
+#define _TKMACINT
+
+#ifndef _TKINT
+#include "tkInt.h"
+#endif
+
+/*
+ * Include platform specific public interfaces.
+ */
+
+#ifndef _TKMAC
+#include "tkMacOSX.h"
+#endif
+
+#ifndef _TKPORT
+#include "tkPort.h"
+#endif
+
+#include <Carbon/Carbon.h>
+
+struct TkWindowPrivate {
+ TkWindow *winPtr; /* Ptr to tk window or NULL if Pixmap */
+ CGrafPtr grafPtr;
+ ControlRef rootControl;
+ int xOff; /* X offset from toplevel window */
+ int yOff; /* Y offset from toplevel window */
+ RgnHandle clipRgn; /* Visable region of window */
+ RgnHandle aboveClipRgn; /* Visable region of window & it's children */
+ int referenceCount; /* Don't delete toplevel until children are
+ * gone. */
+ struct TkWindowPrivate *toplevel; /* Pointer to the toplevel
+ * datastruct. */
+ int flags; /* Various state see defines below. */
+};
+typedef struct TkWindowPrivate MacDrawable;
+
+/*
+ * This list is used to keep track of toplevel windows that have a Mac
+ * window attached. This is useful for several things, not the least
+ * of which is maintaining floating windows.
+ */
+
+typedef struct TkMacOSXWindowList {
+ 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
+
+/*
+ * 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 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 Destroy of a child.
+ */
+
+/*
+ * This structure is for handling Netscape-type in process
+ * 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
+ * are in tclMac.h.
+ */
+
+typedef struct {
+ Tk_MacOSXEmbedRegisterWinProc *registerWinProc;
+ Tk_MacOSXEmbedGetGrafPortProc *getPortProc;
+ Tk_MacOSXEmbedMakeContainerExistProc *containerExistProc;
+ Tk_MacOSXEmbedGetClipProc *getClipProc;
+ Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc;
+} TkMacOSXEmbedHandler;
+
+extern TkMacOSXEmbedHandler *gMacEmbedHandler;
+
+/*
+ * Defines used for TkMacOSXInvalidateWindow
+ */
+
+#define TK_WINDOW_ONLY 0
+#define TK_PARENT_WINDOW 1
+
+/*
+ * Accessor for the privatePtr flags field for the TK_HOST_EXISTS field
+ */
+
+#define TkMacOSXHostToplevelExists(tkwin) \
+ (((TkWindow *) (tkwin))->privatePtr->toplevel->flags & TK_HOST_EXISTS)
+
+/*
+ * Defines use for the flags argument to TkGenWMConfigureEvent.
+ */
+
+#define TK_LOCATION_CHANGED 1
+#define TK_SIZE_CHANGED 2
+#define TK_BOTH_CHANGED 3
+
+/*
+ * Variables shared among various Mac Tk modules but are not
+ * exported to the outside world.
+ */
+
+/*
+ * Globals shared among Macintosh Tk
+ */
+
+extern MenuHandle tkAppleMenu; /* Handle to the Apple Menu */
+extern MenuHandle tkFileMenu; /* Handles to menus */
+extern MenuHandle tkEditMenu; /* Handles to menus */
+extern RgnHandle tkMenuCascadeRgn; /* A region to clip with. */
+extern 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. */
+extern int tkPictureIsOpen; /* If this is 1, we are drawing to a picture
+ * The clipping should then be done relative
+ * to the bounds of the picture rather than the window
+ * As of OS X.0.4, something is seriously wrong:
+ * The clipping bounds only seem to work if the
+ * top,left values are 0,0
+ * The destination rectangle for CopyBits
+ * should also have top,left values of 0,0
+ */
+extern TkMacOSXWindowList *tkMacOSXWindowListPtr;
+ /* The list of toplevels */
+
+extern Tcl_Encoding TkMacOSXCarbonEncoding;
+
+#include "tkIntPlatDecls.h"
+
+#endif /* _TKMACINT */
diff --git a/macosx/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c
new file mode 100644
index 0000000..7c3474c
--- /dev/null
+++ b/macosx/tkMacOSXKeyEvent.c
@@ -0,0 +1,420 @@
+/*
+ * tkMacOSXKeyEvent.c --
+ *
+ * This file implements functions that decode & handle keyboard events
+ * on MacOS X.
+ *
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.
+ */
+
+#include "tkMacOSXInt.h"
+#include "tkPort.h"
+#include "tkMacOSXEvent.h"
+
+typedef struct {
+ WindowRef whichWindow;
+ Point global;
+ Point local;
+ int state;
+ 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. */
+
+/*
+ * Declarations for functions used only in this file.
+ */
+
+static int GenerateKeyEvent _ANSI_ARGS_(( EventKind eKind,
+ KeyEventData * e,
+ Window window,
+ UInt32 savedKeyCode));
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXProcessKeyboardEvent --
+ *
+ * This routine processes the event in eventPtr, and
+ * generates the appropriate Tk events from it.
+ *
+ * Results:
+ * True if event(s) are generated - false otherwise.
+ *
+ * Side effects:
+ * Additional events may be place on the Tk event queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int TkMacOSXProcessKeyboardEvent(
+ TkMacOSXEvent * eventPtr,
+ MacEventStatus * statusPtr)
+{
+ static UInt32 savedKeyCode = 0;
+ OSStatus status;
+ KeyEventData keyEventData;
+ Window window;
+ MenuRef menuRef;
+ MenuItemIndex menuItemIndex;
+ int eventGenerated;
+
+ statusPtr->handledByTk = 1;
+ keyEventData.whichWindow = FrontNonFloatingWindow();
+ if (keyEventData.whichWindow == NULL) {
+ return 0;
+ }
+ GetMouse(&keyEventData.local);
+ keyEventData.global = keyEventData.local;
+ LocalToGlobal(&keyEventData.global);
+ keyEventData.state = TkMacOSXButtonKeyState();
+ if (IsMenuKeyEvent(NULL, eventPtr->eventRef,
+ kNilOptions, &menuRef, &menuItemIndex)) {
+ int oldMode;
+ MenuID menuID;
+ KeyMap theKeys;
+ int selection;
+
+ menuID = GetMenuID(menuRef);
+ selection = (menuID << 16 ) | menuItemIndex;
+
+ GetKeys(theKeys);
+ oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
+ TkMacOSXClearMenubarActive();
+
+ /*
+ * Handle -postcommand
+ */
+
+ TkMacOSXPreprocessMenu();
+ TkMacOSXHandleMenuSelect(selection, theKeys[1] & 4);
+ Tcl_SetServiceMode(oldMode);
+ return 0; /* TODO: may not be on event on queue. */
+ }
+
+ status = GetEventParameter(eventPtr->eventRef,
+ kEventParamKeyMacCharCodes,
+ typeChar, NULL,
+ sizeof(keyEventData.ch), NULL,
+ &keyEventData.ch);
+ if (status != noErr) {
+ fprintf(stderr, "Failed to retrieve KeyMacCharCodes\n" );
+ statusPtr->err = 1;
+ return 1;
+ }
+ status = GetEventParameter(eventPtr->eventRef,
+ kEventParamKeyCode,
+ typeUInt32, NULL,
+ sizeof(keyEventData.keyCode), NULL,
+ &keyEventData.keyCode);
+ if (status != noErr) {
+ fprintf(stderr, "Failed to retrieve KeyCode\n" );
+ statusPtr->err = 1;
+ return 1;
+ }
+ status = GetEventParameter(eventPtr->eventRef,
+ kEventParamKeyModifiers,
+ typeUInt32, NULL,
+ sizeof(keyEventData.keyModifiers), NULL,
+ &keyEventData.keyModifiers);
+ if (status != noErr) {
+ fprintf(stderr, "Failed to retrieve KeyModifiers\n" );
+ statusPtr->err = 1;
+ return 1;
+ }
+ keyEventData.message = keyEventData.ch|(keyEventData.keyCode << 8);
+
+ window = TkMacOSXGetXWindow(keyEventData.whichWindow);
+
+ eventGenerated = GenerateKeyEvent(eventPtr->eKind, &keyEventData,
+ window, savedKeyCode);
+
+ if (eventGenerated == 0) {
+ savedKeyCode = keyEventData.message;
+ return false;
+ } else if (eventGenerated == -1) {
+ savedKeyCode = 0;
+ return false;
+ } else {
+ savedKeyCode = 0;
+ return true;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GenerateKeyEvent --
+ *
+ * Given Macintosh keyUp, keyDown & autoKey events this function
+ * generates the appropiate X key events. The window that is passed
+ * should represent the frontmost window - which will recieve the
+ * event.
+ *
+ * Results:
+ * 1 if an event was generated, 0 if we are waiting for another
+ * byte of a multi-byte sequence, and -1 for any other error.
+ *
+ * Side effects:
+ * Additional events may be place on the Tk event queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+GenerateKeyEvent( EventKind eKind,
+ KeyEventData * e,
+ Window window,
+ UInt32 savedKeyCode )
+{
+ Tk_Window tkwin;
+ XEvent event;
+ unsigned char byte;
+ char buf[16];
+ TkDisplay *dispPtr;
+
+ /*
+ * The focus must be in the FrontWindow on the Macintosh.
+ * We then query Tk to determine the exact Tk window
+ * that owns the focus.
+ */
+
+ dispPtr = TkGetDisplayList();
+ tkwin = Tk_IdToWindow(dispPtr->display, window);
+
+ if (tkwin == NULL) {
+ fprintf(stderr,"tkwin == NULL, %d\n", __LINE__);
+ return -1;
+ }
+
+ tkwin = (Tk_Window) ((TkWindow *) tkwin)->dispPtr->focusPtr;
+ if (tkwin == NULL) {
+ fprintf(stderr,"tkwin == NULL, %d\n", __LINE__);
+ return -1;
+ }
+ byte = (e->message&charCodeMask);
+ if ((savedKeyCode == 0) &&
+ (Tcl_ExternalToUtf(NULL, TkMacOSXCarbonEncoding,
+ (char *) &byte, 1, 0, NULL,
+ buf, sizeof(buf), NULL, NULL, NULL) != TCL_OK)) {
+ /*
+ * This event specifies a lead byte. Wait for the second byte
+ * to come in before sending the XEvent.
+ */
+ fprintf(stderr,"Failed %02x\n", byte);
+ return 0;
+ }
+
+ event.xany.send_event = False;
+ event.xkey.same_screen = true;
+ event.xkey.subwindow = None;
+ event.xkey.time = TkpGetMS();
+
+ event.xkey.x_root = e->global.h;
+ event.xkey.y_root = e->global.v;
+ Tk_TopCoordsToWindow(tkwin, e->local.h, e->local.v,
+ &event.xkey.x, &event.xkey.y);
+
+ event.xkey.keycode = byte |
+ ((savedKeyCode & charCodeMask) << 8) |
+ ((e->message&keyCodeMask) << 8);
+
+ event.xany.serial = Tk_Display(tkwin)->request;
+ event.xkey.window = Tk_WindowId(tkwin);
+ event.xkey.display = Tk_Display(tkwin);
+ event.xkey.root = XRootWindow(Tk_Display(tkwin), 0);
+ event.xkey.state = e->state;
+
+ 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:
+ break;
+ }
+ return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XGrabKeyboard --
+ *
+ * Simulates a keyboard grab by setting the focus.
+ *
+ * Results:
+ * Always returns GrabSuccess.
+ *
+ * Side effects:
+ * Sets the keyboard focus to the specified window.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+XGrabKeyboard(
+ Display* display,
+ Window grab_window,
+ Bool owner_events,
+ int pointer_mode,
+ int keyboard_mode,
+ Time time)
+{
+ gKeyboardWinPtr = Tk_IdToWindow(display, grab_window);
+ return GrabSuccess;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XUngrabKeyboard --
+ *
+ * Releases the simulated keyboard grab.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Sets the keyboard focus back to the value before the grab.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XUngrabKeyboard(
+ Display* display,
+ Time time)
+{
+ gKeyboardWinPtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXGetCapture --
+ *
+ * Results:
+ * Returns the current grab window
+ * Side effects:
+ * None.
+ *
+ */
+Tk_Window
+TkMacOSXGetCapture()
+{
+ return gGrabWinPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Sets the capture flag and captures the mouse.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpSetCapture(
+ TkWindow *winPtr) /* Capture window, or NULL. */
+{
+ while ((winPtr != NULL) && !Tk_IsTopLevel(winPtr)) {
+ winPtr = winPtr->parentPtr;
+ }
+ gGrabWinPtr = (Tk_Window) winPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_SetCaretPos(tkwin, x, y, height)
+ Tk_Window tkwin;
+ int x;
+ int y;
+ int height;
+{
+}
diff --git a/macosx/tkMacOSXKeyboard.c b/macosx/tkMacOSXKeyboard.c
new file mode 100644
index 0000000..db5d679
--- /dev/null
+++ b/macosx/tkMacOSXKeyboard.c
@@ -0,0 +1,650 @@
+/*
+ * tkMacOSXKeyboard.c --
+ *
+ * Routines to support keyboard events on the Macintosh.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#include "tkInt.h"
+#include "X11/Xlib.h"
+#include "X11/keysym.h"
+#include <Carbon/Carbon.h>
+#include "tkMacOSXInt.h"
+
+typedef struct {
+ int keycode; /* Macintosh keycode */
+ KeySym keysym; /* X windows Keysym */
+} KeyInfo;
+
+static KeyInfo keyArray[] = {
+ {0x4C, XK_Return},
+ {0x24, XK_Return},
+ {0x33, XK_BackSpace},
+ {0x75, XK_Delete},
+ {0x30, XK_Tab},
+ {0x74, XK_Page_Up},
+ {0x79, XK_Page_Down},
+ {0x73, XK_Home},
+ {0x77, XK_End},
+ {0x7B, XK_Left},
+ {0x7C, XK_Right},
+ {0x7E, XK_Up},
+ {0x7D, XK_Down},
+ {0x72, XK_Help},
+ {0x35, XK_Escape},
+ {0x47, XK_Clear},
+ {0, 0}
+};
+
+static KeyInfo vituralkeyArray[] = {
+ {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; /* vituralkeyArray hashed by virtual
+ keycode value. */
+static Ptr KCHRPtr; /* Pointer to 'KCHR' resource. */
+
+/*
+ * Prototypes for static functions used in this file.
+ */
+static void InitKeyMaps _ANSI_ARGS_((void));
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InitKeyMaps --
+ *
+ * Creates hash tables used by some of the functions in this file.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Allocates memory & creates some hash tables.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+InitKeyMaps()
+{
+ 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);
+ }
+ Tcl_InitHashTable(&vkeyTable, TCL_ONE_WORD_KEYS);
+ for (kPtr = vituralkeyArray; kPtr->keycode != 0; kPtr++) {
+ hPtr = Tcl_CreateHashEntry(&vkeyTable, (char *) kPtr->keycode,
+ &dummy);
+ Tcl_SetHashValue(hPtr, kPtr->keysym);
+ }
+ KCHRPtr = (Ptr) GetScriptManagerVariable(smKCHRCache);
+ if (!KCHRPtr){
+ fprintf(stderr,"GetScriptManagerVariable failed\n");
+ }
+ initialized = 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XKeycodeToKeysym --
+ *
+ * Translate from a system-dependent keycode to a
+ * system-independent keysym.
+ *
+ * Results:
+ * Returns the translated keysym, or NoSymbol on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+KeySym
+XKeycodeToKeysym(
+ Display* display,
+ KeyCode keycode,
+ int index)
+{
+ register Tcl_HashEntry *hPtr;
+ int c;
+ int virtualKey;
+ int newKeycode;
+ unsigned long dummy, newChar;
+
+ if (!initialized) {
+ InitKeyMaps();
+ }
+ virtualKey = (char) (keycode >> 16);
+ c = (keycode) & 0xffff;
+ if (c > 255) {
+ return NoSymbol;
+ }
+
+ /*
+ * 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 ASCI chars.
+ */
+ if (c == 0x10) {
+ hPtr = Tcl_FindHashEntry(&vkeyTable, (char *) virtualKey);
+ if (hPtr != NULL) {
+ return (KeySym) Tcl_GetHashValue(hPtr);
+ }
+ }
+ hPtr = Tcl_FindHashEntry(&keycodeTable, (char *) virtualKey);
+ if (hPtr != NULL) {
+ return (KeySym) Tcl_GetHashValue(hPtr);
+ }
+
+ /*
+ * Recompute the character based on the Shift key only.
+ * TODO: The index may also specify the NUM_LOCK.
+ */
+ newKeycode = virtualKey;
+ if (index & 0x01) {
+ newKeycode += 0x0200;
+ }
+ dummy = 0;
+ newChar = KeyTranslate(KCHRPtr, (short) newKeycode, &dummy);
+ c = newChar & charCodeMask;
+
+ if (c >= XK_space && c < XK_asciitilde) {
+ return c;
+ }
+
+ return NoSymbol;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetString --
+ *
+ * Retrieve the string equivalent for the given keyboard event.
+ *
+ * Results:
+ * Returns the UTF string.
+ *
+ * Side effects:
+ * 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. */
+{
+ register Tcl_HashEntry *hPtr;
+ char string[3];
+ int virtualKey;
+ int c, len;
+
+ if (!initialized) {
+ InitKeyMaps();
+ }
+
+ Tcl_DStringInit(dsPtr);
+
+ virtualKey = (char) (eventPtr->xkey.keycode >> 16);
+ c = (eventPtr->xkey.keycode) & 0xffff;
+
+ if (c < 256) {
+ string[0] = (char) c;
+ len = 1;
+ } else {
+ string[0] = (char) (c >> 8);
+ string[1] = (char) c;
+ len = 2;
+ }
+ /*
+ * Just return NULL if the character is a function key or another
+ * non-printing key.
+ */
+ if (c == 0x10) {
+ len = 0;
+ } else {
+ hPtr = Tcl_FindHashEntry(&keycodeTable, (char *) virtualKey);
+ if (hPtr != NULL) {
+ len = 0;
+ }
+ }
+ return Tcl_ExternalToUtfDString(TkMacOSXCarbonEncoding, string,
+ len, dsPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XGetModifierMapping --
+ *
+ * Fetch the current keycodes used as modifiers.
+ *
+ * Results:
+ * Returns a new modifier map.
+ *
+ * Side effects:
+ * Allocates a new modifier map data structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+XModifierKeymap *
+XGetModifierMapping(
+ Display* display)
+{
+ XModifierKeymap * modmap;
+
+ modmap = (XModifierKeymap *) ckalloc(sizeof(XModifierKeymap));
+ modmap->max_keypermod = 0;
+ modmap->modifiermap = NULL;
+ return modmap;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XFreeModifiermap --
+ *
+ * Deallocate a modifier map that was created by
+ * XGetModifierMapping.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Frees the datastructure referenced by modmap.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XFreeModifiermap(
+ XModifierKeymap *modmap)
+{
+ if (modmap->modifiermap != NULL) {
+ ckfree((char *) modmap->modifiermap);
+ }
+ ckfree((char *) modmap);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XKeysymToString, XStringToKeysym --
+ *
+ * These X window functions map Keysyms to strings & strings to
+ * keysyms. However, Tk already does this for the most common keysyms.
+ * Therefor, these functions only need to support keysyms that will be
+ * specific to the Macintosh. Currently, there are none.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+XKeysymToString(
+ KeySym keysym)
+{
+ return NULL;
+}
+
+KeySym
+XStringToKeysym(
+ const char* string)
+{
+ return NoSymbol;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XKeysymToKeycode --
+ *
+ * The function XKeysymToKeycode is only used by tkTest.c and
+ * currently only implementes the support for keys used in the
+ * Tk test suite.
+ * FIXME - This is no longer true. This function is now used in
+ * "event generate" so we really should make it work.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+KeyCode
+XKeysymToKeycode(
+ Display* display,
+ KeySym keysym)
+{
+ KeyCode keycode = 0;
+ char virtualKeyCode = 0;
+
+ 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);
+ }
+
+ return keycode;
+}
+
+/*
+ * When mapping from a keysym to a keycode, need
+ * information about the modifier state that should be used
+ * so that when they call XKeycodeToKeysym taking into
+ * account the xkey.state, they will get back the original
+ * keysym.
+ */
+
+void
+TkpSetKeycodeAndState(tkwin, keySym, eventPtr)
+ Tk_Window tkwin;
+ KeySym keySym;
+ XEvent *eventPtr;
+{
+ Display *display;
+ int state;
+ KeyCode keycode;
+
+ display = Tk_Display(tkwin);
+
+ if (keySym == NoSymbol) {
+ keycode = 0;
+ } else {
+ keycode = XKeysymToKeycode(display, keySym);
+ }
+ if (keycode != 0) {
+ for (state = 0; state < 4; state++) {
+ if (XKeycodeToKeysym(display, keycode, state) == keySym) {
+ if (state & 1) {
+ eventPtr->xkey.state |= ShiftMask;
+ }
+ if (state & 2) {
+ TkDisplay *dispPtr;
+
+ dispPtr = ((TkWindow *) tkwin)->dispPtr;
+ eventPtr->xkey.state |= dispPtr->modeModMask;
+ }
+ break;
+ }
+ }
+ }
+ eventPtr->xkey.keycode = keycode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetKeySym --
+ *
+ * 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.
+ *
+ * Side effects:
+ * In the first call for a given display, keycode-to-
+ * KeySym maps get loaded.
+ *
+ *----------------------------------------------------------------------
+ */
+
+KeySym
+TkpGetKeySym(dispPtr, eventPtr)
+ TkDisplay *dispPtr; /* Display in which to
+ * map keycode. */
+ XEvent *eventPtr; /* Description of X event. */
+{
+ KeySym sym;
+ int index;
+
+ /*
+ * Refresh the mapping information if it's stale
+ */
+
+ if (dispPtr->bindInfoStale) {
+ TkpInitKeymapInfo(dispPtr);
+ }
+
+ /*
+ * 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.
+ */
+
+ index = 0;
+ if (eventPtr->xkey.state & dispPtr->modeModMask) {
+ index = 2;
+ }
+ if ((eventPtr->xkey.state & ShiftMask)
+ || ((dispPtr->lockUsage != LU_IGNORE)
+ && (eventPtr->xkey.state & LockMask))) {
+ index += 1;
+ }
+ sym = XKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode, index);
+
+ /*
+ * Special handling: if the key was shifted because of Lock, but
+ * lock is only caps lock, not shift lock, and the shifted keysym
+ * isn't upper-case alphabetic, then switch back to the unshifted
+ * keysym.
+ */
+
+ if ((index & 1) && !(eventPtr->xkey.state & ShiftMask)
+ && (dispPtr->lockUsage == LU_CAPS)) {
+ if (!(((sym >= XK_A) && (sym <= XK_Z))
+ || ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
+ || ((sym >= XK_Ooblique) && (sym <= XK_Thorn)))) {
+ index &= ~1;
+ sym = XKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode,
+ index);
+ }
+ }
+
+ /*
+ * Another bit of special handling: if this is a shifted key and there
+ * is no keysym defined, then use the keysym for the unshifted key.
+ */
+
+ if ((index & 1) && (sym == NoSymbol)) {
+ sym = XKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode,
+ index & ~1);
+ }
+ return sym;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * 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 "mode
+ * switch".
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Keymap-related information in dispPtr is updated.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TkpInitKeymapInfo(dispPtr)
+ TkDisplay *dispPtr; /* Display for which to recompute keymap
+ * information. */
+{
+ XModifierKeymap *modMapPtr;
+ KeyCode *codePtr;
+ KeySym keysym;
+ int count, i, j, max, arraySize;
+#define KEYCODE_ARRAY_SIZE 20
+
+ dispPtr->bindInfoStale = 0;
+ modMapPtr = XGetModifierMapping(dispPtr->display);
+
+ /*
+ * Check the keycodes associated with the Lock modifier. If
+ * any of them is associated with the XK_Shift_Lock modifier,
+ * then Lock has to be interpreted as Shift Lock, not Caps Lock.
+ */
+
+ dispPtr->lockUsage = LU_IGNORE;
+ codePtr = modMapPtr->modifiermap + modMapPtr->max_keypermod*LockMapIndex;
+ for (count = modMapPtr->max_keypermod; count > 0; count--, codePtr++) {
+ if (*codePtr == 0) {
+ continue;
+ }
+ keysym = XKeycodeToKeysym(dispPtr->display, *codePtr, 0);
+ if (keysym == XK_Shift_Lock) {
+ dispPtr->lockUsage = LU_SHIFT;
+ break;
+ }
+ if (keysym == XK_Caps_Lock) {
+ dispPtr->lockUsage = LU_CAPS;
+ break;
+ }
+ }
+
+ /*
+ * Look through the keycodes associated with modifiers to see if
+ * the the "mode switch", "meta", or "alt" keysyms are associated
+ * with any modifiers. If so, remember their modifier mask bits.
+ */
+
+ dispPtr->modeModMask = 0;
+ dispPtr->metaModMask = 0;
+ dispPtr->altModMask = 0;
+ codePtr = modMapPtr->modifiermap;
+ max = 8*modMapPtr->max_keypermod;
+ for (i = 0; i < max; i++, codePtr++) {
+ if (*codePtr == 0) {
+ continue;
+ }
+ keysym = XKeycodeToKeysym(dispPtr->display, *codePtr, 0);
+ if (keysym == XK_Mode_switch) {
+ dispPtr->modeModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
+ }
+ if ((keysym == XK_Meta_L) || (keysym == XK_Meta_R)) {
+ dispPtr->metaModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
+ }
+ if ((keysym == XK_Alt_L) || (keysym == XK_Alt_R)) {
+ dispPtr->altModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
+ }
+ }
+
+ /*
+ * Create an array of the keycodes for all modifier keys.
+ */
+
+ if (dispPtr->modKeyCodes != NULL) {
+ ckfree((char *) dispPtr->modKeyCodes);
+ }
+ dispPtr->numModKeyCodes = 0;
+ arraySize = KEYCODE_ARRAY_SIZE;
+ dispPtr->modKeyCodes = (KeyCode *) ckalloc((unsigned)
+ (KEYCODE_ARRAY_SIZE * sizeof(KeyCode)));
+ for (i = 0, codePtr = modMapPtr->modifiermap; i < max; i++, codePtr++) {
+ if (*codePtr == 0) {
+ continue;
+ }
+
+ /*
+ * Make sure that the keycode isn't already in the array.
+ */
+
+ for (j = 0; j < dispPtr->numModKeyCodes; j++) {
+ if (dispPtr->modKeyCodes[j] == *codePtr) {
+ goto nextModCode;
+ }
+ }
+ if (dispPtr->numModKeyCodes >= arraySize) {
+ KeyCode *new;
+
+ /*
+ * Ran out of space in the array; grow it.
+ */
+
+ arraySize *= 2;
+ new = (KeyCode *) ckalloc((unsigned)
+ (arraySize * sizeof(KeyCode)));
+ memcpy((VOID *) new, (VOID *) dispPtr->modKeyCodes,
+ (dispPtr->numModKeyCodes * sizeof(KeyCode)));
+ ckfree((char *) dispPtr->modKeyCodes);
+ dispPtr->modKeyCodes = new;
+ }
+ dispPtr->modKeyCodes[dispPtr->numModKeyCodes] = *codePtr;
+ dispPtr->numModKeyCodes++;
+ nextModCode: continue;
+ }
+ XFreeModifiermap(modMapPtr);
+}
diff --git a/macosx/tkMacOSXLibrary.r b/macosx/tkMacOSXLibrary.r
new file mode 100644
index 0000000..4baf9b5
--- /dev/null
+++ b/macosx/tkMacOSXLibrary.r
@@ -0,0 +1,510 @@
+/*
+ * tkMacOSXLibrary.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.
+ *
+ * Copyright (c) 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: tkMacOSXLibrary.r,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+
+/*
+ * New style DLOG templates have an extra field for the positioning
+ * options for the Dialog Box. We will not use this, for now, so we
+ * turn it off here.
+ */
+
+#define DLOG_RezTemplateVersion 0
+
+/*
+#include <Types.r>
+#include <SysTypes.r>
+#include <AEUserTermTypes.r>
+*/
+
+/*
+ * The folowing include and defines help construct
+ * the version string for Tcl.
+ */
+
+#define RESOURCE_INCLUDED
+#include <tcl.h>
+#include "tk.h"
+
+#if (TK_RELEASE_LEVEL == 0)
+# define RELEASE_LEVEL alpha
+#elif (TK_RELEASE_LEVEL == 1)
+# define RELEASE_LEVEL beta
+#elif (TK_RELEASE_LEVEL == 2)
+# define RELEASE_LEVEL final
+#endif
+
+#if (TK_RELEASE_LEVEL == 2)
+# define MINOR_VERSION (TK_MINOR_VERSION * 16) + TK_RELEASE_SERIAL
+#else
+# define MINOR_VERSION TK_MINOR_VERSION * 16
+#endif
+
+#define RELEASE_CODE 0x00
+
+resource 'vers' (1) {
+ TK_MAJOR_VERSION, MINOR_VERSION,
+ RELEASE_LEVEL, 0x00, verUS,
+ TK_PATCH_LEVEL,
+ TK_PATCH_LEVEL ",by Ray Johnson & Jim Ingham" "\n" "© 1993-1997 Sun Microsystems" "\n" "1998-2000 Scriptics Inc."
+};
+
+resource 'vers' (2) {
+ TK_MAJOR_VERSION, MINOR_VERSION,
+ RELEASE_LEVEL, 0x00, verUS,
+ TK_PATCH_LEVEL,
+ "Tk Library " TK_PATCH_LEVEL " © 1993-1999"
+};
+
+#define TK_LIBRARY_RESOURCES 3000
+/*
+ * The -16397 string will be displayed by Finder when a user
+ * tries to open the shared library. The string should
+ * give the user a little detail about the library's capabilities
+ * and enough information to install the library in the correct location.
+ * A similar string should be placed in all shared libraries.
+ */
+resource 'STR ' (-16397, purgeable) {
+ "Tk Library\n\n"
+ "This is the library needed to run Tcl/Tk programs. "
+ "To work properly, it should be placed in the Tool Command Language folder "
+ "within the Extensions folder."
+};
+
+
+/*
+ * We now load the Tk library into the resource fork of the library.
+ */
+
+read 'TEXT' (TK_LIBRARY_RESOURCES+1, "tk", purgeable)
+ "::library:tk.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+2, "button", purgeable)
+ "::library:button.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+3, "dialog", purgeable)
+ "::library:dialog.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+4, "entry", purgeable)
+ "::library:entry.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+5, "focus", purgeable)
+ "::library:focus.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+6, "listbox", purgeable)
+ "::library:listbox.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+7, "menu", purgeable)
+ "::library:menu.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+8, "optionMenu", purgeable)
+ "::library:optMenu.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+9, "palette", purgeable)
+ "::library:palette.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+10, "scale", purgeable)
+ "::library:scale.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+11, "scrollbar", purgeable)
+ "::library:scrlbar.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+12, "tearoff", purgeable)
+ "::library:tearoff.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+13, "text", purgeable)
+ "::library:text.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+14, "tkerror", purgeable)
+ "::library:bgerror.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+15, "Console", purgeable)
+ "::library:console.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+16, "msgbox", purgeable, preload)
+ "::library:msgbox.tcl";
+read 'TEXT' (TK_LIBRARY_RESOURCES+17, "comdlg", purgeable, preload)
+ "::library:comdlg.tcl";
+
+/*
+ * 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
+ * default dialog will not be shown and the Tcl procedure is expected to
+ * create and manage an About Dialog box.
+ */
+
+data 'DLOG' (128, "Default About Box", purgeable) {
+ $"0055 006B 00F3 0196 0001 0100 0100 0000"
+ $"0000 0081 0000 280A"
+};
+
+resource 'DITL' (129, "About Box", purgeable) {
+ {
+ {128, 128, 148, 186}, Button {enabled, "Ok"},
+ { 14, 108, 117, 298}, StaticText {disabled,
+ "Wish - Windowing Shell" "\n" "based on Tcl "
+ TCL_PATCH_LEVEL " & Tk " TK_PATCH_LEVEL "\n\n" "Jim Ingham & Ray Johnson"
+ "Scriptics Inc." "\n" "jingham@cygnus.com"},
+ { 11, 24, 111, 92}, Picture {enabled, 128}
+ }
+};
+
+data 'PICT' (128, purgeable) {
+ $"13A4 0000 0000 0064 0044 0011 02FF 0C00"
+ $"FFFE 0000 0048 0000 0048 0000 0000 0000"
+ $"0064 0044 0000 0000 0001 000A 0000 0000"
+ $"0064 0044 0099 8044 0000 0000 0064 0044"
+ $"0000 0000 0000 0000 0048 0000 0048 0000"
+ $"0000 0008 0001 0008 0000 0000 0108 00D8"
+ $"0000 0000 0001 5A5A 8000 00FF 3736 FF00"
+ $"FF00 FF00 3535 FF00 FF00 CC00 3434 FF00"
+ $"FF00 9900 3333 FF00 FF00 6600 3736 FF00"
+ $"FF00 3300 3535 FF00 FF00 0000 3434 FF00"
+ $"CC00 FF00 3333 FF00 CC00 CC00 3736 FF00"
+ $"CC00 9900 3535 FF00 CC00 6600 FAFA FF00"
+ $"CC00 3300 3333 FF00 CC00 0000 3130 FF00"
+ $"9900 FF00 2F2F FF00 9900 CC00 FAFA FF00"
+ $"9900 9900 F9F9 FF00 9900 6600 3130 FF00"
+ $"9900 3300 2F2F FF00 9900 0000 2E2E FF00"
+ $"6600 FF00 F9F9 FF00 6600 CC00 3130 FF00"
+ $"6600 9900 2F2F FF00 6600 6600 2E2E FF00"
+ $"6600 3300 2D2D FF00 6600 0000 3130 FF00"
+ $"3300 FF00 2F2F FF00 3300 CC00 2E2E FF00"
+ $"3300 9900 2D2D FF00 3300 6600 3130 FF00"
+ $"3300 3300 2F2F FF00 3300 0000 2E2E FF00"
+ $"0000 FF00 2D2D FF00 0000 CC00 3130 FF00"
+ $"0000 9900 2F2F FF00 0000 6600 2E2E FF00"
+ $"0000 3300 2DF8 FF00 0000 0000 2B2A CC00"
+ $"FF00 FF00 2929 CC00 FF00 CC00 2828 CC00"
+ $"FF00 9900 27F8 CC00 FF00 6600 2B2A CC00"
+ $"FF00 3300 2929 CC00 FF00 0000 2828 CC00"
+ $"CC00 FF00 2727 CC00 CC00 CC00 2B2A CC00"
+ $"CC00 9900 2929 CC00 CC00 6600 2828 CC00"
+ $"CC00 3300 2727 CC00 CC00 0000 2B2A CC00"
+ $"9900 FF00 2929 CC00 9900 CC00 2828 CC00"
+ $"9900 9900 2727 CC00 9900 6600 DBDB CC00"
+ $"9900 3300 4747 CC00 9900 0000 4646 CC00"
+ $"6600 FF00 4545 CC00 6600 CC00 DBDB CC00"
+ $"6600 9900 4747 CC00 6600 6600 4646 CC00"
+ $"6600 3300 4545 CC00 6600 0000 DBDB CC00"
+ $"3300 FF00 4747 CC00 3300 CC00 4646 CC00"
+ $"3300 9900 4545 CC00 3300 6600 DBDB CC00"
+ $"3300 3300 4141 CC00 3300 0000 4040 CC00"
+ $"0000 FF00 3F3F CC00 0000 CC00 4342 CC00"
+ $"0000 9900 4141 CC00 0000 6600 4040 CC00"
+ $"0000 3300 3F3F CC00 0000 0000 4342 9900"
+ $"FF00 FF00 4141 9900 FF00 CC00 4040 9900"
+ $"FF00 9900 3F3F 9900 FF00 6600 4342 9900"
+ $"FF00 3300 4141 9900 FF00 0000 4040 9900"
+ $"CC00 FF00 3F3F 9900 CC00 CC00 4342 9900"
+ $"CC00 9900 4141 9900 CC00 6600 4040 9900"
+ $"CC00 3300 3F3F 9900 CC00 0000 4342 9900"
+ $"9900 FF00 4141 9900 9900 CC00 4040 9900"
+ $"9900 9900 3F3F 9900 9900 6600 3D3C 9900"
+ $"9900 3300 3B3B 9900 9900 0000 3A3A 9900"
+ $"6600 FF00 3939 9900 6600 CC00 3D3C 9900"
+ $"6600 9900 3B3B 9900 6600 6600 3A3A 9900"
+ $"6600 3300 3939 9900 6600 0000 3D3C 9900"
+ $"3300 FF00 3B3B 9900 3300 CC00 3A3A 9900"
+ $"3300 9900 3939 9900 3300 6600 3D3C 9900"
+ $"3300 3300 3B3B 9900 3300 0000 3A3A 9900"
+ $"0000 FF00 3939 9900 0000 CC00 3D3C 9900"
+ $"0000 9900 3B3B 9900 0000 6600 3A3A 9900"
+ $"0000 3300 3939 9900 0000 0000 3D3C 6600"
+ $"FF00 FF00 3B3B 6600 FF00 CC00 3A3A 6600"
+ $"FF00 9900 3939 6600 FF00 6600 3D3C 6600"
+ $"FF00 3300 3B3B 6600 FF00 0000 3A3A 6600"
+ $"CC00 FF00 3939 6600 CC00 CC00 3736 6600"
+ $"CC00 9900 3535 6600 CC00 6600 3434 6600"
+ $"CC00 3300 3333 6600 CC00 0000 3736 6600"
+ $"9900 FF00 3535 6600 9900 CC00 3434 6600"
+ $"9900 9900 3333 6600 9900 6600 3736 6600"
+ $"9900 3300 3535 6600 9900 0000 3434 6600"
+ $"6600 FF00 3333 6600 6600 CC00 3736 6600"
+ $"6600 9900 3535 6600 6600 6600 3434 6600"
+ $"6600 3300 3333 6600 6600 0000 3736 6600"
+ $"3300 FF00 3535 6600 3300 CC00 3434 6600"
+ $"3300 9900 3333 6600 3300 6600 3736 6600"
+ $"3300 3300 3535 6600 3300 0000 3434 6600"
+ $"0000 FF00 3333 6600 0000 CC00 3130 6600"
+ $"0000 9900 2F2F 6600 0000 6600 2E2E 6600"
+ $"0000 3300 F9F9 6600 0000 0000 3130 3300"
+ $"FF00 FF00 2F2F 3300 FF00 CC00 2E2E 3300"
+ $"FF00 9900 F9F9 3300 FF00 6600 3130 3300"
+ $"FF00 3300 2F2F 3300 FF00 0000 2E2E 3300"
+ $"CC00 FF00 2D2D 3300 CC00 CC00 3130 3300"
+ $"CC00 9900 2F2F 3300 CC00 6600 2E2E 3300"
+ $"CC00 3300 2D2D 3300 CC00 0000 3130 3300"
+ $"9900 FF00 2F2F 3300 9900 CC00 2E2E 3300"
+ $"9900 9900 2D2D 3300 9900 6600 3130 3300"
+ $"9900 3300 2F2F 3300 9900 0000 2E2E 3300"
+ $"6600 FF00 2DF8 3300 6600 CC00 2B2A 3300"
+ $"6600 9900 2929 3300 6600 6600 2828 3300"
+ $"6600 3300 27F8 3300 6600 0000 2B2A 3300"
+ $"3300 FF00 2929 3300 3300 CC00 2828 3300"
+ $"3300 9900 2727 3300 3300 6600 2B2A 3300"
+ $"3300 3300 2929 3300 3300 0000 2828 3300"
+ $"0000 FF00 2727 3300 0000 CC00 2B2A 3300"
+ $"0000 9900 2929 3300 0000 6600 2828 3300"
+ $"0000 3300 2727 3300 0000 0000 4948 0000"
+ $"FF00 FF00 4747 0000 FF00 CC00 4646 0000"
+ $"FF00 9900 4545 0000 FF00 6600 4948 0000"
+ $"FF00 3300 4747 0000 FF00 0000 4646 0000"
+ $"CC00 FF00 4545 0000 CC00 CC00 4948 0000"
+ $"CC00 9900 4747 0000 CC00 6600 4646 0000"
+ $"CC00 3300 4545 0000 CC00 0000 4342 0000"
+ $"9900 FF00 4141 0000 9900 CC00 4040 0000"
+ $"9900 9900 3F3F 0000 9900 6600 4342 0000"
+ $"9900 3300 4141 0000 9900 0000 4040 0000"
+ $"6600 FF00 3F3F 0000 6600 CC00 4342 0000"
+ $"6600 9900 4141 0000 6600 6600 4040 0000"
+ $"6600 3300 3F3F 0000 6600 0000 4342 0000"
+ $"3300 FF00 4141 0000 3300 CC00 4040 0000"
+ $"3300 9900 3F3F 0000 3300 6600 4342 0000"
+ $"3300 3300 4141 0000 3300 0000 4040 0000"
+ $"0000 FF00 3F3F 0000 0000 CC00 4342 0000"
+ $"0000 9900 4141 0000 0000 6600 4040 0000"
+ $"0000 3300 3F3F EE00 0000 0000 3D3C DD00"
+ $"0000 0000 3B3B BB00 0000 0000 3A3A AA00"
+ $"0000 0000 3939 8800 0000 0000 3D3C 7700"
+ $"0000 0000 3B3B 5500 0000 0000 3A3A 4400"
+ $"0000 0000 3939 2200 0000 0000 3D3C 1100"
+ $"0000 0000 3B3B 0000 EE00 0000 3A3A 0000"
+ $"DD00 0000 3939 0000 BB00 0000 3D3C 0000"
+ $"AA00 0000 3B3B 0000 8800 0000 3A3A 0000"
+ $"7700 0000 3939 0000 5500 0000 3D3C 0000"
+ $"4400 0000 3B3B 0000 2200 0000 3A3A 0000"
+ $"1100 0000 3939 0000 0000 EE00 3D3C 0000"
+ $"0000 DD00 3B3B 0000 0000 BB00 3A3A 0000"
+ $"0000 AA00 3939 0000 0000 8800 3D3C 0000"
+ $"0000 7700 3B3B 0000 0000 5500 3A3A 0000"
+ $"0000 4400 3939 0000 0000 2200 3736 0000"
+ $"0000 1100 3535 EE00 EE00 EE00 3434 DD00"
+ $"DD00 DD00 3333 BB00 BB00 BB00 3736 AA00"
+ $"AA00 AA00 3535 8800 8800 8800 3434 7700"
+ $"7700 7700 3333 5500 5500 5500 3736 4400"
+ $"4400 4400 3535 2200 2200 2200 3434 1100"
+ $"1100 1100 3333 0000 0000 0000 0000 0000"
+ $"0064 0044 0000 0000 0064 0044 0000 000A"
+ $"0000 0000 0064 0044 02BD 0013 E800 01F5"
+ $"F6FE 07FE 0E02 3232 33FD 3900 0EE6 001D"
+ $"FC00 01F5 F5FE 0700 08FE 0E02 3232 33FE"
+ $"3900 3AFC 40F2 4102 4033 07E9 0017 0100"
+ $"0EFC 40DC 4102 390E F5F5 0002 F5F5 F6FE"
+ $"0702 0E07 0016 0100 32D5 4104 4039 0E32"
+ $"33FD 3900 3AFC 40FC 4101 3200 0801 000E"
+ $"C141 010E 0008 0100 0EC1 4101 0800 0801"
+ $"000E C141 0107 0008 0100 0EC1 4101 0700"
+ $"0901 0007 C241 0240 F500 0E01 0007 E841"
+ $"0147 47DD 4102 4000 0012 0100 07F0 4100"
+ $"47FA 4101 3B3B DD41 0240 0000 1901 0007"
+ $"F141 0C47 3B0B 3B47 4141 4711 0505 3B47"
+ $"DF41 023A 0000 1701 00F6 F041 010B 0BFE"
+ $"4105 473B 0505 113B DE41 0239 0000 1A02"
+ $"00F5 40F3 410C 473B 053B 4741 4741 0B0B"
+ $"3B47 47DE 4102 3900 0018 0200 F540 F341"
+ $"0247 110B FE41 0447 1105 4147 DC41 0233"
+ $"0000 1B02 0000 40F3 4103 4711 1147 FE41"
+ $"0205 3547 F741 FD47 E941 0232 0000 1E02"
+ $"0000 40F2 4106 113B 4741 4735 0BF7 4106"
+ $"4741 390E 0E40 47EA 4102 0E00 0021 0200"
+ $"0040 F241 0711 3B47 4141 0B35 47F9 4102"
+ $"4740 07FE 0002 F640 47EB 4102 0E00 0023"
+ $"0200 0040 F341 0847 3541 4147 3B05 4147"
+ $"FA41 0947 3AF6 00F5 4F55 F50E 47EB 4102"
+ $"0700 0022 0200 003A F341 0147 3BFE 4101"
+ $"0B0B F941 0547 3AF5 0055 C8FE CE01 5640"
+ $"EB41 0207 0000 1F02 0000 39F0 4104 4741"
+ $"053B 47FB 4104 4740 F5F5 A4FC CE01 C85D"
+ $"EB41 02F6 0000 1F02 0000 39F0 4104 473B"
+ $"0541 47FC 4104 4740 07F6 C8FA CE00 64EC"
+ $"4103 40F5 0000 1C02 0000 39F0 4102 4711"
+ $"0BFA 4103 4708 2AC8 FACE 0164 D8EC 4100"
+ $"40FE 0025 0200 0039 EF41 020B 3B47 FC41"
+ $"0347 0FF5 A4FB CE02 C887 D8FC 41FE 47FC"
+ $"4100 47F9 4100 3AFE 0028 0200 0039 EF41"
+ $"020B 3B47 FD41 0347 3900 A4FA CE00 ABFA"
+ $"4109 3B11 3B41 4147 3B0B 3B47 FA41 0039"
+ $"FE00 2402 0000 33F1 4102 4741 0BFA 4101"
+ $"0779 F9CE 0064 FA41 0235 050B FD41 010B"
+ $"0BF9 4100 39FE 0028 0200 0032 F141 0247"
+ $"3B0B FC41 0247 39F6 F9CE 0187 D8FB 4103"
+ $"4741 050B FE41 0247 110B F941 0039 FE00"
+ $"2C02 0000 32F1 4102 473B 11FB 4101 0879"
+ $"FACE 05AA 4041 4147 47FE 410A 4741 0511"
+ $"4741 4147 3511 47FA 4100 32FE 002F 0200"
+ $"000E F141 0347 3B11 47FE 4103 4740 F6C8"
+ $"FACE 0564 D841 4039 39FE 4104 473B 053B"
+ $"47FE 4102 3541 47FA 4100 0EFE 0027 0200"
+ $"000E F141 0347 3B3B 47FE 4102 470F 79FA"
+ $"CE0C 8741 4032 F500 003A 4741 473B 05F2"
+ $"4100 0EFE 0027 0200 000E F141 0347 3B3B"
+ $"47FD 4101 0EA4 FACE 01AB AAFE C808 7900"
+ $"3947 4147 110B 47F3 4100 07FE 001C 0200"
+ $"000E EA41 0240 2BC8 F5CE 0881 0033 4741"
+ $"410B 3B47 F341 0007 FE00 1A02 0000 08EB"
+ $"4102 473A 55F4 CE06 5D00 3947 4741 0BF1"
+ $"4100 F6FE 001C 0200 0007 EB41 0247 3979"
+ $"F4CE 0739 0039 4747 3511 47F3 4101 40F5"
+ $"FE00 1C02 0000 07EB 4102 4739 A4F5 CE08"
+ $"AB0E 0040 4741 1141 47F3 4100 40FD 001B"
+ $"0200 0007 EB41 0247 39A4 F5CE 0787 0707"
+ $"4147 4111 47F2 4100 40FD 001B 0200 0007"
+ $"EB41 0247 39C8 F5CE 0763 F532 4747 3B3B"
+ $"47F2 4100 3AFD 001A 0300 00F6 40EC 4102"
+ $"4739 C8F5 CE05 39F5 4047 413B F041 0039"
+ $"FD00 1C03 0000 F540 EB41 0140 C8FD CE01"
+ $"C8A4 FCCE 03AB 080E 47ED 4100 39FD 001A"
+ $"FE00 0040 EB41 0040 FCCE 01A4 C8FC CE03"
+ $"FA07 4047 ED41 0032 FD00 1AFE 0000 40EA"
+ $"4100 AAFE CE02 87F9 C8FC CE02 560F 47EC"
+ $"4100 32FD 0019 FE00 0040 EA41 00AB FECE"
+ $"0264 56C8 FDCE 01C8 32EA 4100 0EFD 001B"
+ $"FE00 0040 ED41 030E 4047 87FE CE01 4055"
+ $"FCCE 01FA 40EA 4100 08FD 001A FE00 003A"
+ $"ED41 0807 0740 FBCE CEAB 3979 FDCE 00AB"
+ $"E841 0007 FD00 1CFE 0000 3AED 4108 0700"
+ $"F6A4 CECE 8733 79FD CE02 4147 47EA 4100"
+ $"07FD 001E FE00 0039 ED41 0807 2AA4 C8CE"
+ $"CE88 0E9D FECE 0364 1C39 39EB 4101 40F5"
+ $"FD00 1CFE 0000 39ED 4101 074F FDCE 0264"
+ $"F7A4 FECE 03AB 80F6 07EB 4100 40FC 001C"
+ $"FE00 0039 ED41 0108 79FE CE03 AB40 2BA4"
+ $"FCCE 02F7 0E47 EC41 0040 FC00 1CFE 0000"
+ $"39ED 4101 0879 FECE 03AB 40F6 C8FC CE02"
+ $"F615 47EC 4100 40FC 001E FE00 003A EE41"
+ $"0247 0E79 FECE 03AB 40F5 C8FD CE03 A4F5"
+ $"3A47 EC41 0040 FC00 1EFE 0000 3AEE 4102"
+ $"470E 56FE CE03 FB3A F6C8 FDCE 0280 F540"
+ $"EB41 0140 F5FD 001E FE00 0040 EE41 0947"
+ $"0F56 CECE C888 39F6 C8FD CE02 5601 40EB"
+ $"4101 40F5 FD00 1CFE 0000 40EE 4109 4739"
+ $"32CE CEC8 8839 2AC8 FDCE 0156 07E9 4100"
+ $"F6FD 001B FE00 0040 EE41 0847 3A32 CECE"
+ $"C864 152A FCCE 0132 07E9 4100 07FD 001A"
+ $"FE00 0040 ED41 0740 32AB CEC8 6439 4EFC"
+ $"CE01 3A07 E941 0007 FD00 1D03 0000 F540"
+ $"ED41 0740 0EAB CECE 640F 4EFD CE03 AB40"
+ $"0840 EA41 0007 FD00 1B03 0000 F540 EC41"
+ $"060F 81CE CE64 334E FDCE 02AB 400E E941"
+ $"000E FD00 1C02 0000 F6EC 4107 4715 FACE"
+ $"CE64 334E FDCE 0387 0F0E 47EA 4100 0EFD"
+ $"001C 0200 0007 EC41 0747 16F9 CEC8 6433"
+ $"4EFD CE03 6308 4047 EA41 000E FD00 1A02"
+ $"0000 07EB 4106 40F9 CEC8 6439 4EFD CE02"
+ $"3940 47E9 4100 32FD 001B 0200 0007 EA41"
+ $"0539 CECE 8839 F6FE CE04 AB41 4139 40EA"
+ $"4100 32FD 001C 0200 0007 EB41 0E47 3AC8"
+ $"CE88 39F6 C8CE CE64 15F6 F540 EA41 0033"
+ $"FD00 1A02 0000 07EA 410C 40A4 CE87 392A"
+ $"C8CE AB41 40F8 F6E9 4100 39FD 001B 0200"
+ $"000E EB41 0D47 41AB C887 39F5 C8CE ABAB"
+ $"CEA4 07E9 4100 39FD 001C 0200 000E ED41"
+ $"0947 3939 4787 C8AB 40F5 C8FD CE01 A40E"
+ $"E941 0039 FD00 1D02 0000 0EED 4109 473A"
+ $"0007 80CE AB40 F5C8 FDCE 0255 0E47 EA41"
+ $"0039 FD00 1B02 0000 0EEB 4107 0779 C8CE"
+ $"CE40 F6A4 FDCE 022B 3947 EA41 003A FD00"
+ $"1C02 0000 0EEC 4102 4739 79FE CE02 6407"
+ $"A4FE CE02 A407 40E9 4100 40FD 001A 0200"
+ $"0032 EA41 0632 A4CE CE88 0879 FECE 02F9"
+ $"0F47 E941 0040 FD00 1A02 0000 32EB 4107"
+ $"4740 F7C8 CE87 0E79 FECE 0132 40E8 4100"
+ $"40FD 0019 0200 0033 EA41 0B47 40F8 C8AB"
+ $"0E55 CECE 8015 47E8 4100 40FD 0017 0200"
+ $"0033 E941 0847 40F9 A439 4FCE CE5D E641"
+ $"0140 F5FE 0014 0200 0039 E841 0647 64FB"
+ $"392B C8AB E441 00F6 FE00 1102 0000 39E5"
+ $"4103 40F6 8764 E441 0007 FE00 1E02 0000"
+ $"39EB 4102 3A0E 0EFD 4102 0740 47F6 4104"
+ $"400F 0839 47F4 4100 07FE 0027 0200 0039"
+ $"FB41 0147 47F2 4102 0800 40FE 4102 0839"
+ $"47FC 4101 4747 FC41 0339 0039 47F4 4100"
+ $"07FE 0029 0200 0039 FB41 0140 39F3 4109"
+ $"470E F540 4141 470E 3347 FC41 0139 3AFD"
+ $"4104 4739 0039 47F4 4100 08FE 0036 0200"
+ $"003A FC41 0347 0E00 40FC 4102 4741 40FC"
+ $"4109 470E F540 4141 4733 0E47 FE41 0447"
+ $"4000 0E47 FE41 0447 3900 3941 FE40 F741"
+ $"000E FE00 3A02 0000 3AFD 410E 4740 0700"
+ $"0E40 4741 4147 390E 390E 40FE 4108 470E"
+ $"F540 4141 4739 0EFC 4103 0F00 0739 FE41"
+ $"0747 3900 3940 080F 39F7 4100 0EFE 0035"
+ $"0200 0040 FB41 020E 0040 FE41 0D47 4000"
+ $"3941 0032 4741 4147 0EF5 40FE 4101 4008"
+ $"FC41 023A 000E FD41 0547 3900 3939 33F5"
+ $"4100 0EFE 0039 0200 0040 FC41 0347 0E00"
+ $"40FE 4106 4732 0040 4139 40FE 4103 470E"
+ $"F540 FD41 0108 40FE 4104 4740 000E 47FE"
+ $"4106 4739 0007 F540 47F6 4100 32FE 003A"
+ $"0200 0040 FC41 0C47 0E00 4047 4141 470E"
+ $"0040 4747 FD41 0347 0EF5 40FE 410A 470E"
+ $"3947 4141 4740 000E 47FE 4107 4739 000E"
+ $"0007 4147 F741 0032 FE00 3802 0000 40FC"
+ $"4102 470E 00FD 4106 4739 003A 4740 39FE"
+ $"4102 470E F5FD 410A 4733 3347 4141 4740"
+ $"000E 47FE 4106 4739 0039 3900 0EF6 4100"
+ $"33FE 003A 0200 F540 FC41 0447 3200 0E39"
+ $"FD41 0B0E 0E40 333A 4741 413A 07F5 39FE"
+ $"4102 473A 0EFD 410F 40F5 0733 4041 4140"
+ $"0E00 0E40 0700 0E40 F841 0039 FE00 2902"
+ $"00F5 40FA 4101 3939 FB41 023A 3A40 FD41"
+ $"FD40 FD41 0240 0E40 FD41 0240 3940 FD41"
+ $"FA40 F741 0039 FE00 2A01 00F6 F941 0147"
+ $"47FB 4101 4747 FB41 0147 47FB 4101 3940"
+ $"FD41 0147 47FB 4100 47FE 4100 47F6 4100"
+ $"39FE 000D 0100 07E1 4100 40E4 4100 3AFE"
+ $"0009 0100 07C3 4100 3AFE 0009 0100 07C3"
+ $"4100 40FE 0009 0100 07C3 4100 40FE 0009"
+ $"0100 07C3 4100 40FE 000A 0100 0EC3 4103"
+ $"40F5 0000 0901 000E C241 02F6 0000 0901"
+ $"000E C241 0207 0000 0901 000E C241 0207"
+ $"0000 1101 000E ED41 FE40 003A F940 E241"
+ $"0207 0000 2B01 0032 F941 FE40 FE39 0632"
+ $"0E0E 0707 F6F5 F800 02F5 F5F6 FB07 FB0E"
+ $"0332 3233 33FB 3901 3A3A FB40 0207 0000"
+ $"0E0A 000E 3939 320E 0E07 07F6 F5C8 0002"
+ $"BD00 00FF"
+};
+
+/*
+ * Here is the custom file open dialog. This dialog is used instead of
+ * the default file dialog if the -filetypes flag is specified.
+ */
+
+#define DLOG_RezTemplateVersion 0
+
+resource 'DLOG' (130, purgeable) {
+ {0, 0, 195, 344}, dBoxProc, invisible, noGoAway, 0,
+ 130, ""
+};
+
+resource 'DITL' (130, "File Open Box", purgeable) {
+ {
+ {135, 252, 155, 332}, Button {enabled, "Open"},
+ {104, 252, 124, 332}, Button {enabled, "Cancel"},
+ { 0, 0, 0, 0}, HelpItem {disabled, HMScanhdlg {130}},
+ { 8, 235, 24, 337}, UserItem {enabled},
+ { 32, 252, 52, 332}, Button {enabled, "Eject"},
+ { 60, 252, 80, 332}, Button {enabled, "Desktop"},
+ { 29, 12, 159, 230}, UserItem {enabled},
+ { 6, 12, 25, 230}, UserItem {enabled},
+ { 91, 251, 92, 333}, Picture {disabled, 11},
+ {168, 20, 187, 300}, Control {enabled, 131}
+ }
+};
+
+resource 'CNTL' (131, "File Types menu", purgeable) {
+ {168, 20, 187, 300},
+ popupTitleLeftJust,
+ visible,
+ 80,
+ 132,
+ popupMenuCDEFProc,
+ 0,
+ "File Type:"
+};
+
+
+resource 'MENU' (132, preload) {
+ 132,
+ textMenuProc,
+ 0xFFFF, enabled, "", {}
+};
diff --git a/macosx/tkMacOSXMenu.c b/macosx/tkMacOSXMenu.c
new file mode 100644
index 0000000..8578359
--- /dev/null
+++ b/macosx/tkMacOSXMenu.c
@@ -0,0 +1,4686 @@
+/*
+ * tkMacOSXMenu.c --
+ *
+ * This module implements the Mac-platform specific features of menus.
+ *
+ * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXMenu.c,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+#include "tkMacOSXInt.h"
+#include "tkMenuButton.h"
+#include "tkMenu.h"
+#include "tkColor.h"
+#include "tkMacOSXInt.h"
+#undef Status
+
+#define USE_TK_MDEF
+//#define USE_ATSU
+
+#include <Carbon/Carbon.h>
+#include "tkMacOSXDebug.h"
+#include <CoreFoundation/CFString.h>
+
+typedef struct MacMenu {
+ MenuRef menuHdl; /* The Menu Manager data structure. */
+ Rect menuRect; /* The rectangle as calculated in the
+ * MDEF. This is used to figure ou the
+ * clipping rgn before we push
+ * the <<MenuSelect>> virtual binding
+ * through. */
+} MacMenu;
+
+typedef struct MenuEntryUserData {
+ Drawable mdefDrawable;
+ TkMenuEntry *mePtr;
+ Tk_Font tkfont;
+ Tk_FontMetrics *fmPtr;
+} MenuEntryUserData;
+/*
+ * Various geometry definitions:
+ */
+
+#define CASCADE_ARROW_HEIGHT 10
+#define CASCADE_ARROW_WIDTH 8
+#define DECORATION_BORDER_WIDTH 2
+#define MAC_MARGIN_WIDTH 8
+
+/*
+ * The following are constants relating to the SICNs used for drawing the MDEF.
+ */
+
+#define SICN_RESOURCE_NUMBER 128
+
+#define SICN_HEIGHT 16
+#define SICN_ROWS 2
+#define CASCADE_ICON_WIDTH 7
+#define SHIFT_ICON_WIDTH 10
+#define OPTION_ICON_WIDTH 16
+#define CONTROL_ICON_WIDTH 12
+#define COMMAND_ICON_WIDTH 10
+
+#define CASCADE_ARROW 0
+#define SHIFT_ICON 1
+#define OPTION_ICON 2
+#define CONTROL_ICON 3
+#define COMMAND_ICON 4
+#define DOWN_ARROW 5
+#define UP_ARROW 6
+
+/*
+ * Platform specific flags for menu entries
+ *
+ * ENTRY_COMMAND_ACCEL Indicates the entry has the command key
+ * in its accelerator string.
+ * ENTRY_OPTION_ACCEL Indicates the entry has the option key
+ * in its accelerator string.
+ * ENTRY_SHIFT_ACCEL Indicates the entry has the shift key
+ * in its accelerator string.
+ * ENTRY_CONTROL_ACCEL Indicates the entry has the control key
+ * in its accelerator string.
+ */
+
+#define ENTRY_COMMAND_ACCEL ENTRY_PLATFORM_FLAG1
+#define ENTRY_OPTION_ACCEL ENTRY_PLATFORM_FLAG2
+#define ENTRY_SHIFT_ACCEL ENTRY_PLATFORM_FLAG3
+#define ENTRY_CONTROL_ACCEL ENTRY_PLATFORM_FLAG4
+#define ENTRY_ACCEL_MASK (ENTRY_COMMAND_ACCEL | ENTRY_OPTION_ACCEL \
+ | ENTRY_SHIFT_ACCEL | ENTRY_CONTROL_ACCEL)
+
+/*
+ * This structure is used to keep track of subfields within Macintosh menu
+ * items.
+ */
+
+typedef struct EntryGeometry {
+ int accelTextStart; /* Offset into the accel string where
+ * the text starts. Everything before
+ * this is modifier key descriptions.
+ */
+ int modifierWidth; /* Width of modifier symbols. */
+ int accelTextWidth; /* Width of the text after the modifier
+ * keys. */
+ int nonAccelMargin; /* The width of the margin for entries
+ * without accelerators. */
+} EntryGeometry;
+
+/*
+ * Structure to keep track of toplevel windows and their menubars.
+ */
+
+typedef struct TopLevelMenubarList {
+ struct TopLevelMenubarList *nextPtr;
+ /* The next window in the list. */
+ Tk_Window tkwin; /* The toplevel window. */
+ TkMenu *menuPtr; /* The menu associated with this
+ * toplevel. */
+} TopLevelMenubarList;
+
+/*
+ * Platform-specific flags for menus.
+ *
+ * MENU_APPLE_MENU 0 indicates a custom Apple menu has
+ * not been installed; 1 a custom Apple
+ * menu has been installed.
+ * MENU_HELP_MENU 0 indicates a custom Help menu has
+ * not been installed; 1 a custom Help
+ * menu has been installed.
+ * MENU_RECONFIGURE_PENDING 1 indicates that an idle handler has
+ * been scheduled to reconfigure the
+ * Macintosh MenuHandle.
+ */
+
+#define MENU_APPLE_MENU MENU_PLATFORM_FLAG1
+#define MENU_HELP_MENU MENU_PLATFORM_FLAG2
+#define MENU_RECONFIGURE_PENDING MENU_PLATFORM_FLAG3
+
+#define CASCADE_CMD (0x1b)
+ /* The special command char for cascade
+ * menus. */
+#define SEPARATOR_TEXT "\p(-"
+ /* The text for a menu separator. */
+
+#define MENUBAR_REDRAW_PENDING 1
+#define SCREEN_MARGIN 5
+
+static int gNoTkMenus = 0; /* This is used by Tk_MacOSXTurnOffMenus as the
+ * flag that Tk is not to draw any menus. */
+
+RgnHandle tkMenuCascadeRgn = NULL;
+ /* The region to clip drawing to when the
+ * MDEF is up. */
+int tkUseMenuCascadeRgn = 0; /* If this is 1, clipping code
+ * should intersect tkMenuCascadeRgn
+ * before drawing occurs.
+ * tkMenuCascadeRgn will only
+ * be valid when the value of this
+ * variable is 1. */
+
+static Tcl_HashTable commandTable;
+ /* The list of menuInstancePtrs associated with
+ * menu ids */
+static short currentAppleMenuID;
+ /* The id of the current Apple menu. 0 for
+ * none. */
+static short currentHelpMenuID; /* The id of the current Help menu. 0 for
+ * none. */
+static Tcl_Interp *currentMenuBarInterp;
+ /* The interpreter of the window that owns
+ * the current menubar. */
+static char *currentMenuBarName;
+ /* Malloced. Name of current menu in menu bar.
+ * NULL if no menu set. TO DO: make this a
+ * DString. */
+static Tk_Window currentMenuBarOwner;
+ /* Which window owns the current menu bar. */
+static char elipsisString[TCL_UTF_MAX + 1];
+ /* The UTF representation of the elipsis (...)
+ * character. */
+static int helpItemCount; /* The number of items in the help menu.
+ * -1 means that the help menu is
+ * unavailable. This does not include
+ * the automatically generated separator. */
+static int inPostMenu; /* We cannot be re-entrant like X
+ * windows. */
+static short lastMenuID; /* To pass to NewMenu; need to figure out
+ * a good way to do this. */
+static unsigned char lastCascadeID;
+ /* Cascades have to have ids that are
+ * less than 256. */
+static MacDrawable macMDEFDrawable;
+ /* Drawable for use by MDEF code */
+static int MDEFScrollFlag = 0; /* Used so that popups don't scroll too soon. */
+static int menuBarFlags; /* Used for whether the menu bar needs
+ * redrawing or not. */
+
+static struct TearoffSelect {
+ TkMenu *menuPtr; /* The menu that is torn off */
+ Point point; /* The point to place the new menu */
+ Rect excludeRect; /* We don't want to drag tearoff highlights
+ * when we are in this menu */
+} tearoffStruct;
+
+static RgnHandle totalMenuRgn = NULL;
+ /* Used to update windows which have been
+ * obscured by menus. */
+static RgnHandle utilRgn = NULL;/* Used when creating the region that is to
+ * be clipped out while the MDEF is active. */
+
+static TopLevelMenubarList *windowListPtr;
+ /* A list of windows that have menubars set. */
+static MenuItemDrawingUPP tkThemeMenuItemDrawingUPP;
+ /* Points to the UPP for theme Item drawing. */
+static Tcl_Obj *useMDEFVar;
+
+/*
+ * Forward declarations for procedures defined later in this file:
+ */
+
+int TkMacOSXGetNewMenuID _ANSI_ARGS_((Tcl_Interp *interp,
+ TkMenu *menuInstPtr,
+ int cascade,
+ short *menuIDPtr));
+void TkMacOSXFreeMenuID _ANSI_ARGS_((short menuID));
+
+static void CompleteIdlers _ANSI_ARGS_((TkMenu *menuPtr));
+static void DrawMenuBarWhenIdle _ANSI_ARGS_((
+ ClientData clientData));
+static void DrawMenuBackground _ANSI_ARGS_((
+ Rect *menuRectPtr, Drawable d, ThemeMenuType type));
+static void DrawMenuEntryAccelerator _ANSI_ARGS_((
+ TkMenu *menuPtr, TkMenuEntry *mePtr,
+ Drawable d, GC gc, Tk_Font tkfont,
+ CONST Tk_FontMetrics *fmPtr,
+ Tk_3DBorder activeBorder, int x, int y,
+ int width, int height, int drawArrow));
+static void DrawMenuEntryBackground _ANSI_ARGS_((
+ TkMenu *menuPtr, TkMenuEntry *mePtr,
+ Drawable d, Tk_3DBorder activeBorder,
+ Tk_3DBorder bgBorder, int x, int y,
+ int width, int heigth));
+static void DrawMenuEntryIndicator _ANSI_ARGS_((
+ TkMenu *menuPtr, TkMenuEntry *mePtr,
+ Drawable d, GC gc, GC indicatorGC,
+ Tk_Font tkfont,
+ CONST Tk_FontMetrics *fmPtr, int x, int y,
+ int width, int height));
+static void DrawMenuEntryLabel _ANSI_ARGS_((
+ TkMenu * menuPtr, TkMenuEntry *mePtr, Drawable d,
+ GC gc, Tk_Font tkfont,
+ CONST Tk_FontMetrics *fmPtr, int x, int y,
+ int width, int height));
+static void DrawMenuSeparator _ANSI_ARGS_((TkMenu *menuPtr,
+ TkMenuEntry *mePtr, Drawable d, GC gc,
+ Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
+ int x, int y, int width, int height));
+static void DrawTearoffEntry _ANSI_ARGS_((TkMenu *menuPtr,
+ TkMenuEntry *mePtr, Drawable d, GC gc,
+ Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
+ int x, int y, int width, int height));
+static void GetEntryText _ANSI_ARGS_((TkMenuEntry *mePtr,
+ Tcl_DString *dStringPtr));
+static void GetMenuAccelGeometry _ANSI_ARGS_((TkMenu *menuPtr,
+ TkMenuEntry *mePtr, Tk_Font tkfont,
+ CONST Tk_FontMetrics *fmPtr, int *modWidthPtr,
+ int *textWidthPtr, int *heightPtr));
+static void GetMenuLabelGeometry _ANSI_ARGS_((TkMenuEntry *mePtr,
+ Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
+ int *widthPtr, int *heightPtr));
+static void GetMenuIndicatorGeometry _ANSI_ARGS_((
+ TkMenu *menuPtr, TkMenuEntry *mePtr,
+ Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
+ int *widthPtr, int *heightPtr));
+static void GetMenuSeparatorGeometry _ANSI_ARGS_((
+ TkMenu *menuPtr, TkMenuEntry *mePtr,
+ Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
+ int *widthPtr, int *heightPtr));
+static void GetTearoffEntryGeometry _ANSI_ARGS_((TkMenu *menuPtr,
+ TkMenuEntry *mePtr, Tk_Font tkfont,
+ CONST Tk_FontMetrics *fmPtr, int *widthPtr,
+ int *heightPtr));
+static char FindMarkCharacter _ANSI_ARGS_((TkMenuEntry *mePtr));
+static void InvalidateMDEFRgns _ANSI_ARGS_((void));
+
+static void MenuDefProc _ANSI_ARGS_((short message,
+ MenuHandle menu, Rect *menuRectPtr,
+ Point hitPt, short *whichItem ));
+static void HandleMenuHiliteMsg (MenuRef menu,
+ Rect *menuRectPtr,
+ Point hitPt,
+ SInt16 *whichItem,
+ TkMenu *menuPtr);
+static void HandleMenuDrawMsg (MenuRef menu,
+ Rect *menuRectPtr,
+ Point hitPt,
+ SInt16 *whichItem,
+ TkMenu *menuPtr);
+static void HandleMenuFindItemsMsg (MenuRef menu,
+ Rect *menuRectPtr,
+ Point hitPt,
+ SInt16 *whichItem,
+ TkMenu *menuPtr);
+static void HandleMenuPopUpMsg (MenuRef menu,
+ Rect *menuRectPtr,
+ Point hitPt,
+ SInt16 *whichItem,
+ TkMenu *menuPtr);
+static void HandleMenuCalcItemMsg (MenuRef menu,
+ Rect *menuRectPtr,
+ Point hitPt,
+ SInt16 *whichItem,
+ TkMenu *menuPtr);
+
+static void MenuSelectEvent _ANSI_ARGS_((TkMenu *menuPtr));
+static void ReconfigureIndividualMenu _ANSI_ARGS_((
+ TkMenu *menuPtr, MenuHandle macMenuHdl,
+ int base));
+static void ReconfigureMacintoshMenu _ANSI_ARGS_ ((
+ ClientData clientData));
+static void RecursivelyClearActiveMenu _ANSI_ARGS_((
+ TkMenu *menuPtr));
+static void RecursivelyDeleteMenu _ANSI_ARGS_((
+ TkMenu *menuPtr));
+static void RecursivelyInsertMenu _ANSI_ARGS_((
+ TkMenu *menuPtr));
+static void SetDefaultMenubar _ANSI_ARGS_((void));
+static int SetMenuCascade _ANSI_ARGS_((TkMenu *menuPtr));
+static void mySetMenuTitle _ANSI_ARGS_((MenuHandle menuHdl,
+ Tcl_Obj *titlePtr));
+static void AppearanceEntryDrawWrapper _ANSI_ARGS_((TkMenuEntry *mePtr,
+ Rect * menuRectPtr, MenuTrackingData *mtdPtr,
+ Drawable d, Tk_FontMetrics *fmPtr, Tk_Font tkfont,
+ int x, int y, int width, int height));
+pascal void tkThemeMenuItemDrawingProc _ANSI_ARGS_ ((const Rect *inBounds,
+ SInt16 inDepth, Boolean inIsColorDevice,
+ SInt32 inUserData));
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXUseID --
+ *
+ * Take the ID out of the available list for new menus. Used by the
+ * default menu bar's menus so that they do not get created at the tk
+ * level. See TkMacOSXGetNewMenuID for more information.
+ *
+ * Results:
+ * Returns TCL_OK if the id was not in use. Returns TCL_ERROR if the
+ * id was in use.
+ *
+ * Side effects:
+ * A hash table entry in the command table is created with a NULL
+ * value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkMacOSXUseMenuID(
+ short macID) /* The id to take out of the table */
+{
+ Tcl_HashEntry *commandEntryPtr;
+ int newEntry;
+ int iMacID = macID; /* Do this to remove compiler warning */
+
+ TkMenuInit();
+ commandEntryPtr = Tcl_CreateHashEntry(&commandTable, (char *) iMacID,
+ &newEntry);
+ if (newEntry == 1) {
+ Tcl_SetHashValue(commandEntryPtr, NULL);
+ return TCL_OK;
+ } else {
+ return TCL_ERROR;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXGetNewMenuID --
+ *
+ * Allocates a new menu id and marks it in use. Each menu on the
+ * mac must be designated by a unique id, which is a short. In
+ * addition, some ids are reserved by the system. Since Tk uses
+ * mostly dynamic menus, we must allocate and free these ids on
+ * the fly. We use the id as a key into a hash table; if there
+ * is no hash entry, we know that we can use the id.
+ *
+ * Results:
+ * Returns TCL_OK if succesful; TCL_ERROR if there are no more
+ * ids of the appropriate type to allocate. menuIDPtr contains
+ * the new id if succesful.
+ *
+ * Side effects:
+ * An entry is created for the menu in the command hash table,
+ * and the hash entry is stored in the appropriate field in the
+ * menu data structure.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+ TkMacOSXGetNewMenuID(
+ Tcl_Interp *interp, /* Used for error reporting */
+ TkMenu *menuPtr, /* The menu we are working with */
+ int cascade, /* 0 if we are working with a normal menu;
+ 1 if we are working with a cascade */
+ short *menuIDPtr) /* The resulting id */
+{
+ int found = 0;
+ int newEntry;
+ Tcl_HashEntry *commandEntryPtr = NULL;
+ short returnID = *menuIDPtr;
+
+ /*
+ * The following code relies on shorts and unsigned chars wrapping
+ * when the highest value is incremented. Also, the values between
+ * 236 and 255 inclusive are reserved for DA's by the Mac OS.
+ */
+
+ if (!cascade) {
+ short curID = lastMenuID + 1;
+ if (curID == 236) {
+ curID = 256;
+ }
+
+ while (curID != lastMenuID) {
+ int iCurID = curID;
+ commandEntryPtr = Tcl_CreateHashEntry(&commandTable,
+ (char *) iCurID, &newEntry);
+ if (newEntry == 1) {
+ found = 1;
+ lastMenuID = returnID = curID;
+ break;
+ }
+ curID++;
+ if (curID == 236) {
+ curID = 256;
+ }
+ }
+ } else {
+
+ /*
+ * Cascade ids must be between 0 and 235 only, so they must be
+ * dealt with separately.
+ */
+
+ unsigned char curID = lastCascadeID + 1;
+ if (curID == 236) {
+ curID = 0;
+ }
+
+ while (curID != lastCascadeID) {
+ int iCurID = curID;
+ commandEntryPtr = Tcl_CreateHashEntry(&commandTable,
+ (char *) iCurID, &newEntry);
+ if (newEntry == 1) {
+ found = 1;
+ lastCascadeID = returnID = curID;
+ break;
+ }
+ curID++;
+ if (curID == 236) {
+ curID = 0;
+ }
+ }
+ }
+
+ if (found) {
+ Tcl_SetHashValue(commandEntryPtr, (char *) menuPtr);
+ *menuIDPtr = returnID;
+ return TCL_OK;
+ } else {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "No more menus can be allocated.",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXFreeMenuID --
+ *
+ * Marks the id as free.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The hash table entry for the ID is cleared.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXFreeMenuID(
+ short menuID) /* The id to free */
+{
+ Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&commandTable,
+ (char *) ((int)menuID));
+
+ if (entryPtr != NULL) {
+ Tcl_DeleteHashEntry(entryPtr);
+ }
+ if (menuID == currentAppleMenuID) {
+ currentAppleMenuID = 0;
+ }
+ if (menuID == currentHelpMenuID) {
+ currentHelpMenuID = 0;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpNewMenu --
+ *
+ * Gets a new blank menu. Only the platform specific options are filled
+ * in.
+ *
+ * Results:
+ * Returns a standard TCL error.
+ *
+ * Side effects:
+ * Allocates a Macintosh menu handle and puts in the platformData
+ * field of the menuPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpNewMenu(
+ TkMenu *menuPtr) /* The common structure we are making the
+ * platform structure for. */
+{
+ short menuID;
+ Str255 itemText;
+ int length;
+ MenuRef macMenuHdl;
+ MenuDefSpec menuDefSpec;
+ Tcl_Obj *useMDEFObjPtr;
+ int useMDEF;
+ int error = TCL_OK;
+ int err;
+
+
+ error = TkMacOSXGetNewMenuID(menuPtr->interp, menuPtr, 0, &menuID);
+ if (error != TCL_OK) {
+ return error;
+ }
+ length = strlen(Tk_PathName(menuPtr->tkwin));
+ memmove(&itemText[1], Tk_PathName(menuPtr->tkwin),
+ (length > 230) ? 230 : length);
+ itemText[0] = (length > 230) ? 230 : length;
+ macMenuHdl = NewMenu(menuID, itemText);
+
+ /*
+ * Check whether we want to use the custom mdef or not. For now
+ * the default is to use it unless the variable is explicitly
+ * set to no.
+ */
+
+ useMDEFObjPtr = Tcl_ObjGetVar2(menuPtr->interp, useMDEFVar, NULL, TCL_GLOBAL_ONLY);
+ if (useMDEFObjPtr == NULL
+ || Tcl_GetBooleanFromObj(NULL, useMDEFObjPtr, &useMDEF) == TCL_ERROR
+ || useMDEF) {
+ menuDefSpec.defType = kMenuDefProcPtr;
+ menuDefSpec.u.defProc = MenuDefProc;
+ if ((err = SetMenuDefinition(macMenuHdl, &menuDefSpec)) != noErr) {
+ fprintf(stderr, "SetMenuDefinition failed %d\n", err );
+ }
+ }
+ menuPtr->platformData = (TkMenuPlatformData) ckalloc(sizeof(MacMenu));
+ ((MacMenu *) menuPtr->platformData)->menuHdl = macMenuHdl;
+ SetRect(&((MacMenu *) menuPtr->platformData)->menuRect, 0, 0, 0, 0);
+
+ if ((currentMenuBarInterp == menuPtr->interp)
+ && (currentMenuBarName != NULL)) {
+ Tk_Window parentWin = Tk_Parent(menuPtr->tkwin);
+
+ if (strcmp(currentMenuBarName, Tk_PathName(parentWin)) == 0) {
+ if ((strcmp(Tk_PathName(menuPtr->tkwin)
+ + strlen(Tk_PathName(parentWin)), ".apple") == 0)
+ || (strcmp(Tk_PathName(menuPtr->tkwin)
+ + strlen(Tk_PathName(parentWin)), ".help") == 0)) {
+ if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) {
+ Tcl_DoWhenIdle(DrawMenuBarWhenIdle, (ClientData *) NULL);
+ menuBarFlags |= MENUBAR_REDRAW_PENDING;
+ }
+ }
+ }
+ }
+
+ menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
+ Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDestroyMenu --
+ *
+ * Destroys platform-specific menu structures.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * All platform-specific allocations are freed up.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpDestroyMenu(
+ TkMenu *menuPtr) /* The common menu structure */
+{
+ MenuRef macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl;
+
+ if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) {
+ Tcl_CancelIdleCall(ReconfigureMacintoshMenu, (ClientData) menuPtr);
+ menuPtr->menuFlags &= ~MENU_RECONFIGURE_PENDING;
+ }
+ if (GetMenuID(macMenuHdl) == currentHelpMenuID) {
+ MenuRef helpMenuHdl;
+ MenuItemIndex helpIndex;
+
+ if ((HMGetHelpMenu(&helpMenuHdl,&helpIndex) == noErr)
+ && (helpMenuHdl != NULL)) {
+ int i, count = CountMenuItems(helpMenuHdl);
+
+ for (i = helpItemCount; i <= count; i++) {
+ DeleteMenuItem(helpMenuHdl, helpItemCount);
+ }
+ }
+ currentHelpMenuID = 0;
+ }
+ if (menuPtr->platformData != NULL) {
+ MenuID menuID;
+ menuID = GetMenuID(macMenuHdl);
+ DeleteMenu(menuID);
+ TkMacOSXFreeMenuID(menuID);
+ DisposeMenu(macMenuHdl);
+ ckfree((char *) menuPtr->platformData);
+ menuPtr->platformData = NULL;
+ }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetMenuCascade --
+ *
+ * Does any cleanup to change a menu from a normal to a cascade.
+ *
+ * Results:
+ * Standard Tcl error.
+ *
+ * Side effects:
+ * The mac menu id is reset.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetMenuCascade(
+ TkMenu* menuPtr) /* The menu we are setting up to be a
+ * cascade. */
+{
+ MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl;
+ MenuID newMenuID, menuID = GetMenuID(macMenuHdl);
+ int error = TCL_OK;
+ if (menuID >= 256) {
+ error = TkMacOSXGetNewMenuID(menuPtr->interp, menuPtr, 1, &newMenuID);
+ if (error == TCL_OK) {
+ TkMacOSXFreeMenuID(menuID);
+ SetMenuID (macMenuHdl,newMenuID);
+ }
+ }
+ return error;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDestroyMenuEntry --
+ *
+ * Cleans up platform-specific menu entry items.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * All platform-specific allocations are freed up.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpDestroyMenuEntry(
+ TkMenuEntry *mePtr) /* The common structure for the menu
+ * entry. */
+{
+ TkMenu *menuPtr = mePtr->menuPtr;
+
+ ckfree((char *) mePtr->platformEntryData);
+ if ((menuPtr->platformData != NULL)
+ && !(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
+ menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
+ Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetEntryText --
+ *
+ * Given a menu entry, gives back the text that should go in it.
+ * Separators should be done by the caller, as they have to be
+ * handled specially. This is primarily used to do a substitution
+ * between "..." and the ellipsis character which looks nicer.
+ *
+ * Results:
+ * itemText points to the new text for the item.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetEntryText(
+ TkMenuEntry *mePtr, /* A pointer to the menu entry. */
+ Tcl_DString *dStringPtr) /* The DString to put the text into. This
+ * will be initialized by this routine. */
+{
+ Tcl_DStringInit(dStringPtr);
+ if (mePtr->type == TEAROFF_ENTRY) {
+ Tcl_DStringAppend(dStringPtr, "(Tear-off)", -1);
+ } else if (mePtr->imagePtr != NULL) {
+ Tcl_DStringAppend(dStringPtr, "(Image)", -1);
+ } else if (mePtr->bitmapPtr != NULL) {
+ Tcl_DStringAppend(dStringPtr, "(Pixmap)", -1);
+ } else if (mePtr->labelPtr == NULL || mePtr->labelLength == 0) {
+ /*
+ * The Mac menu manager does not like null strings.
+ */
+
+ Tcl_DStringAppend(dStringPtr, " ", -1);
+ } else {
+ int length;
+ char *text = Tcl_GetStringFromObj(mePtr->labelPtr, &length);
+ char *dStringText;
+ int i;
+
+ for (i = 0; *text; text++, i++) {
+ if ((*text == '.')
+ && (*(text + 1) != '\0') && (*(text + 1) == '.')
+ && (*(text + 2) != '\0') && (*(text + 2) == '.')) {
+ Tcl_DStringAppend(dStringPtr, elipsisString, -1);
+ i += strlen(elipsisString) - 1;
+ text += 2;
+ } else {
+ Tcl_DStringSetLength(dStringPtr,
+ Tcl_DStringLength(dStringPtr) + 1);
+ dStringText = Tcl_DStringValue(dStringPtr);
+ dStringText[i] = *text;
+ }
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FindMarkCharacter --
+ *
+ * Finds the Macintosh mark character based on the font of the
+ * item. We calculate a good mark character based on the font
+ * that this item is rendered in.
+ *
+ * We try the following special mac characters. If none of them
+ * are present, just use the check mark.
+ * '' - Check mark character (\022)
+ * 'Â¥' - Mac Bullet character (\245)
+ * '' - Filled diamond (\023)
+ * '—' - Hollow diamond (\327)
+ * '‘' = Mac Long dash ("em dash") (\321)
+ * '-' = short dash (minus, "en dash");
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * New item is added to platform menu
+ *
+ *----------------------------------------------------------------------
+ */
+
+static char
+FindMarkCharacter(
+ TkMenuEntry *mePtr) /* The entry we are finding the character
+ * for. */
+{
+ char markChar;
+ Tk_Font tkfont;
+
+ tkfont = Tk_GetFontFromObj(mePtr->menuPtr->tkwin,
+ (mePtr->fontPtr == NULL) ? mePtr->menuPtr->fontPtr
+ : mePtr->fontPtr);
+
+ if (!TkMacOSXIsCharacterMissing(tkfont, '\022')) {
+ markChar = '\022'; /* Check mark */
+ } else if (!TkMacOSXIsCharacterMissing(tkfont, '\245')) {
+ markChar = '\245'; /* Bullet */
+ } else if (!TkMacOSXIsCharacterMissing(tkfont, '\023')) {
+ markChar = '\023'; /* Filled Diamond */
+ } else if (!TkMacOSXIsCharacterMissing(tkfont, '\327')) {
+ markChar = '\327'; /* Hollow Diamond */
+ } else if (!TkMacOSXIsCharacterMissing(tkfont, '\321')) {
+ markChar = '\321'; /* Long Dash */
+ } else if (!TkMacOSXIsCharacterMissing(tkfont, '-')) {
+ markChar = '-'; /* Short Dash */
+ } else {
+ markChar = '\022'; /* Check mark */
+ }
+ return markChar;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetMenuTitle --
+ *
+ * Sets title of menu so that the text displays correctly in menubar.
+ * This code directly manipulates menu handle data. This code
+ * was originally part of an ancient Apple Developer Response mail.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The menu handle will change size depending on the length of the
+ * title
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+mySetMenuTitle(
+ MenuRef menuHdl, /* The menu we are setting the title of. */
+ Tcl_Obj *titlePtr) /* The C string to set the title to. */
+{
+ char *title = (titlePtr == NULL) ? ""
+ : Tcl_GetStringFromObj(titlePtr, NULL);
+ Str255 menuTitle;
+ menuTitle [ 0 ] = strlen ( title ) + 1;
+ strcpy ( menuTitle + 1, title );
+ SetMenuTitle ( menuHdl, menuTitle );
+}
+static int ParseAccelerators(char **accelStringPtr) {
+ char *accelString = *accelStringPtr;
+ int flags = 0;
+ while (1) {
+ if ((0 == strncasecmp("Control", accelString, 6))
+ && (('-' == accelString[6]) || ('+' == accelString[6]))) {
+ flags |= ENTRY_CONTROL_ACCEL;
+ accelString += 7;
+ } else if ((0 == strncasecmp("Ctrl", accelString, 4))
+ && (('-' == accelString[4]) || ('+' == accelString[4]))) {
+ flags |= ENTRY_CONTROL_ACCEL;
+ accelString += 5;
+ } else if ((0 == strncasecmp("Shift", accelString, 5))
+ && (('-' == accelString[5]) || ('+' == accelString[5]))) {
+ flags |= ENTRY_SHIFT_ACCEL;
+ accelString += 6;
+ } else if ((0 == strncasecmp("Option", accelString, 6))
+ && (('-' == accelString[6]) || ('+' == accelString[6]))) {
+ flags |= ENTRY_OPTION_ACCEL;
+ accelString += 7;
+ } else if ((0 == strncasecmp("Opt", accelString, 3))
+ && (('-' == accelString[3]) || ('+' == accelString[3]))) {
+ flags |= ENTRY_OPTION_ACCEL;
+ accelString += 4;
+ } else if ((0 == strncasecmp("Command", accelString, 7))
+ && (('-' == accelString[7]) || ('+' == accelString[7]))) {
+ flags |= ENTRY_COMMAND_ACCEL;
+ accelString += 8;
+ } else if ((0 == strncasecmp("Cmd", accelString, 3))
+ && (('-' == accelString[3]) || ('+' == accelString[3]))) {
+ flags |= ENTRY_COMMAND_ACCEL;
+ accelString += 4;
+ } else if ((0 == strncasecmp("Alt", accelString, 3))
+ && (('-' == accelString[3]) || ('+' == accelString[3]))) {
+ flags |= ENTRY_OPTION_ACCEL;
+ accelString += 4;
+ } else if ((0 == strncasecmp("Meta", accelString, 4))
+ && (('-' == accelString[4]) || ('+' == accelString[4]))) {
+ flags |= ENTRY_COMMAND_ACCEL;
+ accelString += 5;
+ } else {
+ break;
+ }
+ }
+ *accelStringPtr = accelString;
+ return flags;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpConfigureMenuEntry --
+ *
+ * Processes configurations for menu entries.
+ *
+ * Results:
+ * Returns standard TCL result. If TCL_ERROR is returned, then
+ * the interp's result contains an error message.
+ *
+ * Side effects:
+ * Configuration information get set for mePtr; old resources
+ * get freed, if any need it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpConfigureMenuEntry(
+ TkMenuEntry *mePtr) /* Information about menu entry; may
+ * or may not already have values for
+ * some fields. */
+{
+ TkMenu *menuPtr = mePtr->menuPtr;
+ int index = mePtr->index;
+ MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl;
+ MenuHandle helpMenuHdl = NULL;
+
+ /*
+ * Cascade menus have to have menu IDs of less than 256. So
+ * we need to change the child menu if this has been configured
+ * for a cascade item.
+ */
+
+ if (mePtr->type == CASCADE_ENTRY) {
+ if ((mePtr->childMenuRefPtr != NULL)
+ && (mePtr->childMenuRefPtr->menuPtr != NULL)) {
+ MenuHandle childMenuHdl = ((MacMenu *) mePtr
+ ->childMenuRefPtr->menuPtr->platformData)->menuHdl;
+
+ if (childMenuHdl != NULL) {
+ int error = SetMenuCascade(mePtr->childMenuRefPtr->menuPtr);
+
+ if (error != TCL_OK) {
+ return error;
+ }
+
+ if (menuPtr->menuType == MENUBAR) {
+ mySetMenuTitle(childMenuHdl, mePtr->labelPtr);
+ }
+ }
+ }
+ }
+
+ /*
+ * We need to parse the accelerator string. If it has the strings
+ * for Command, Control, Shift or Option, we need to flag it
+ * so we can draw the symbols for it. We also need to precalcuate
+ * the position of the first real character we are drawing.
+ */
+
+ if (0 == mePtr->accelLength) {
+ ((EntryGeometry *)mePtr->platformEntryData)->accelTextStart = -1;
+ } else {
+ char *accelString = (mePtr->accelPtr == NULL) ? ""
+ : Tcl_GetStringFromObj(mePtr->accelPtr, NULL);
+ char *accel = accelString;
+ mePtr->entryFlags |= ~ENTRY_ACCEL_MASK;
+
+ mePtr->entryFlags |= ParseAccelerators(&accelString);
+
+ ((EntryGeometry *)mePtr->platformEntryData)->accelTextStart
+ = ((long) accelString - (long) accel);
+ }
+
+ if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
+ menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
+ Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr);
+ }
+
+ return TCL_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReconfigureIndividualMenu --
+ *
+ * This routine redoes the guts of the menu. It works from
+ * a base item and offset, so that a regular menu will
+ * just have all of its items added, but the help menu will
+ * have all of its items appended after the apple-defined
+ * items.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The Macintosh menu handle is updated
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ReconfigureIndividualMenu(
+ TkMenu *menuPtr, /* The menu we are affecting. */
+ MenuHandle macMenuHdl, /* The macintosh menu we are affecting.
+ * Will not necessarily be
+ * menuPtr->platformData because this could
+ * be the help menu. */
+ int base) /* The last index that we do not want
+ * touched. 0 for normal menus;
+ * helpMenuItemCount for help menus. */
+{
+ int count;
+ int index;
+ TkMenuEntry *mePtr;
+ Str255 itemText;
+ int parentDisabled = 0;
+
+ for (mePtr = menuPtr->menuRefPtr->parentEntryPtr; mePtr != NULL;
+ mePtr = mePtr->nextCascadePtr) {
+ char *name = (mePtr->namePtr == NULL) ? ""
+ : Tcl_GetStringFromObj(mePtr->namePtr, NULL);
+
+ if (strcmp(Tk_PathName(menuPtr->tkwin), name) == 0) {
+ if (mePtr->state == ENTRY_DISABLED) {
+ parentDisabled = 1;
+ }
+ break;
+ }
+ }
+
+ /*
+ * First, we get rid of all of the old items.
+ */
+
+ count = CountMenuItems(macMenuHdl);
+ for (index = base; index < count; index++) {
+ DeleteMenuItem(macMenuHdl, base + 1);
+ }
+
+ count = menuPtr->numEntries;
+
+ for (index = 1; index <= count; index++) {
+ mePtr = menuPtr->entries[index - 1];
+
+ /*
+ * We have to do separators separately because SetMenuItemText
+ * does not parse meta-characters.
+ */
+
+ if (mePtr->type == SEPARATOR_ENTRY) {
+ AppendMenu(macMenuHdl, SEPARATOR_TEXT);
+ } else {
+ Tcl_DString itemTextDString;
+ int destWrote;
+ CFStringRef cf;
+ GetEntryText(mePtr, &itemTextDString);
+ cf = CFStringCreateWithCString(NULL,
+ Tcl_DStringValue(&itemTextDString), kCFStringEncodingUTF8);
+ AppendMenu(macMenuHdl, "\px");
+ if (cf != NULL) {
+ SetMenuItemTextWithCFString(macMenuHdl, base + index, cf);
+ CFRelease(cf);
+ } else {
+ cf = CFSTR ("<Error>");
+ SetMenuItemTextWithCFString(macMenuHdl, base + index, cf);
+ }
+ Tcl_DStringFree(&itemTextDString);
+
+ /*
+ * Set enabling and disabling correctly.
+ */
+
+ if (parentDisabled || (mePtr->state == ENTRY_DISABLED)) {
+ DisableMenuItem(macMenuHdl, base + index);
+ } else {
+ EnableMenuItem(macMenuHdl, base + index);
+ }
+
+ /*
+ * Set the check mark for check entries and radio entries.
+ */
+
+ SetItemMark(macMenuHdl, base + index, 0);
+ if ((mePtr->type == CHECK_BUTTON_ENTRY)
+ || (mePtr->type == RADIO_BUTTON_ENTRY)) {
+ CheckMenuItem(macMenuHdl, base + index, (mePtr->entryFlags
+ & ENTRY_SELECTED) && mePtr->indicatorOn);
+ if (mePtr->indicatorOn
+ && (mePtr->entryFlags & ENTRY_SELECTED)) {
+ SetItemMark(macMenuHdl, base + index,
+ FindMarkCharacter(mePtr));
+ }
+ }
+
+ if (mePtr->type == CASCADE_ENTRY) {
+ if ((mePtr->childMenuRefPtr != NULL)
+ && (mePtr->childMenuRefPtr->menuPtr != NULL)) {
+ MenuHandle childMenuHdl =
+ ((MacMenu *) mePtr->childMenuRefPtr
+ ->menuPtr->platformData)->menuHdl;
+
+ if (childMenuHdl == NULL) {
+ childMenuHdl = ((MacMenu *) mePtr->childMenuRefPtr
+ ->menuPtr->platformData)->menuHdl;
+ }
+ if (childMenuHdl != NULL) {
+ {
+ SetMenuItemHierarchicalID(macMenuHdl, base + index,
+ GetMenuID(childMenuHdl));
+ }
+ }
+ /*
+ * If we changed the highligthing of this menu, its
+ * children all have to be reconfigured so that
+ * their state will be reflected in the menubar.
+ */
+
+ if (!(mePtr->childMenuRefPtr->menuPtr->menuFlags
+ & MENU_RECONFIGURE_PENDING)) {
+ mePtr->childMenuRefPtr->menuPtr->menuFlags
+ |= MENU_RECONFIGURE_PENDING;
+ Tcl_DoWhenIdle(ReconfigureMacintoshMenu,
+ (ClientData) mePtr->childMenuRefPtr->menuPtr);
+ }
+ }
+ }
+
+ if ((mePtr->type != CASCADE_ENTRY) && (mePtr->accelPtr != NULL)) {
+ int accelLen;
+ int modifiers = 0;
+ int hasCmd = 0;
+ int offset = ((EntryGeometry *)mePtr->platformEntryData)->accelTextStart;
+ char *accel = Tcl_GetStringFromObj(mePtr->accelPtr, &accelLen);
+ accelLen -= offset;
+ accel+= offset;
+
+ if (mePtr->entryFlags & ENTRY_OPTION_ACCEL) {
+ modifiers |= kMenuOptionModifier;
+ }
+ if (mePtr->entryFlags & ENTRY_SHIFT_ACCEL) {
+ modifiers |= kMenuShiftModifier;
+ }
+ if (mePtr->entryFlags & ENTRY_CONTROL_ACCEL) {
+ modifiers |= kMenuControlModifier;
+ }
+ if (mePtr->entryFlags & ENTRY_COMMAND_ACCEL) {
+ hasCmd = 1;
+ }
+ if (accelLen == 1) {
+ if (hasCmd || (modifiers != 0 && modifiers != kMenuShiftModifier)) {
+ SetItemCmd(macMenuHdl, base + index, accel[0]);
+ if (!hasCmd) {
+ modifiers |= kMenuNoCommandModifier;
+ }
+ }
+ } else {
+ /*
+ * Now we need to convert from various textual names
+ * to Carbon codes
+ */
+ char glyph = 0x0;
+ char first = UCHAR(accel[0]);
+ if (first == 'F' && (accel[1] > '0' && accel[1] <= '9')) {
+ int fkey = accel[1] - '0';
+ if (accel[2] > '0' && accel[2] <= '9') {
+ fkey = 10*fkey + (accel[2] - '0');
+ }
+ if (fkey > 0 && fkey < 16) {
+ glyph = kMenuF1Glyph + fkey - 1;
+ }
+ } else if (first == 'P' && 0 ==strcasecmp(accel,"pageup")) {
+ glyph = kMenuPageUpGlyph;
+ } else if (first == 'P' && 0 ==strcasecmp(accel,"pagedown")) {
+ glyph = kMenuPageDownGlyph;
+ } else if (first == 'L' && 0 ==strcasecmp(accel,"left")) {
+ glyph = kMenuLeftArrowGlyph;
+ } else if (first == 'R' && 0 ==strcasecmp(accel,"right")) {
+ glyph = kMenuRightArrowGlyph;
+ } else if (first == 'U' && 0 ==strcasecmp(accel,"up")) {
+ glyph = kMenuUpArrowGlyph;
+ } else if (first == 'D' && 0 ==strcasecmp(accel,"down")) {
+ glyph = kMenuDownArrowGlyph;
+ } else if (first == 'E' && 0 ==strcasecmp(accel,"escape")) {
+ glyph = kMenuEscapeGlyph;
+ } else if (first == 'C' && 0 ==strcasecmp(accel,"clear")) {
+ glyph = kMenuClearGlyph;
+ } else if (first == 'E' && 0 ==strcasecmp(accel,"enter")) {
+ glyph = kMenuEnterGlyph;
+ } else if (first == 'D' && 0 ==strcasecmp(accel,"backspace")) {
+ glyph = kMenuDeleteLeftGlyph;
+ } else if (first == 'S' && 0 ==strcasecmp(accel,"space")) {
+ glyph = kMenuSpaceGlyph;
+ } else if (first == 'T' && 0 ==strcasecmp(accel,"tab")) {
+ glyph = kMenuTabRightGlyph;
+ } else if (first == 'F' && 0 ==strcasecmp(accel,"delete")) {
+ glyph = kMenuDeleteRightGlyph;
+ } else if (first == 'H' && 0 ==strcasecmp(accel,"home")) {
+ glyph = kMenuNorthwestArrowGlyph;
+ } else if (first == 'R' && 0 ==strcasecmp(accel,"return")) {
+ glyph = kMenuReturnGlyph;
+ } else if (first == 'H' && 0 ==strcasecmp(accel,"help")) {
+ glyph = kMenuHelpGlyph;
+ } else if (first == 'P' && 0 ==strcasecmp(accel,"power")) {
+ glyph = kMenuPowerGlyph;
+ }
+ if (glyph != 0x0) {
+ SetMenuItemKeyGlyph(macMenuHdl, base + index, glyph);
+ if (modifiers == 0) {
+ if (!hasCmd) {
+ modifiers |= kMenuNoCommandModifier;
+ }
+ }
+ }
+ }
+
+ SetMenuItemModifiers(macMenuHdl, base + index, modifiers);
+ }
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReconfigureMacintoshMenu --
+ *
+ * Rebuilds the Macintosh MenuHandle items from the menu. Called
+ * usually as an idle handler, but can be called synchronously
+ * if the menu is about to be posted.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Configuration information get set for mePtr; old resources
+ * get freed, if any need it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ReconfigureMacintoshMenu(
+ ClientData clientData) /* Information about menu entry; may
+ * or may not already have values for
+ * some fields. */
+{
+ TkMenu *menuPtr = (TkMenu *) clientData;
+ MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl;
+ MenuHandle helpMenuHdl = NULL;
+
+ menuPtr->menuFlags &= ~MENU_RECONFIGURE_PENDING;
+
+ if (NULL == macMenuHdl) {
+ return;
+ }
+
+ ReconfigureIndividualMenu(menuPtr, macMenuHdl, 0);
+
+ if (menuPtr->menuFlags & MENU_APPLE_MENU) {
+ AppendResMenu(macMenuHdl, 'DRVR');
+ }
+ if (GetMenuID(macMenuHdl) == currentHelpMenuID) {
+ MenuItemIndex helpIndex;
+ HMGetHelpMenu(&helpMenuHdl,&helpIndex);
+ if (helpMenuHdl != NULL) {
+ ReconfigureIndividualMenu(menuPtr, helpMenuHdl, helpItemCount);
+ }
+ }
+
+ if (menuPtr->menuType == MENUBAR) {
+ if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) {
+ Tcl_DoWhenIdle(DrawMenuBarWhenIdle, (ClientData *) NULL);
+ menuBarFlags |= MENUBAR_REDRAW_PENDING;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompleteIdlers --
+ *
+ * Completes all idle handling so that the menus are in sync when
+ * the user invokes them with the mouse.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The Macintosh menu handles are flushed out.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+CompleteIdlers(
+ TkMenu *menuPtr) /* The menu we are completing. */
+{
+ int i;
+
+ if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) {
+ Tcl_CancelIdleCall(ReconfigureMacintoshMenu, (ClientData) menuPtr);
+ ReconfigureMacintoshMenu((ClientData) menuPtr);
+ }
+
+ for (i = 0; i < menuPtr->numEntries; i++) {
+ if (menuPtr->entries[i]->type == CASCADE_ENTRY) {
+ if ((menuPtr->entries[i]->childMenuRefPtr != NULL)
+ && (menuPtr->entries[i]->childMenuRefPtr->menuPtr
+ != NULL)) {
+ CompleteIdlers(menuPtr->entries[i]->childMenuRefPtr
+ ->menuPtr);
+ }
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpPostMenu --
+ *
+ * Posts a menu on the screen
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The menu is posted and handled.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpPostMenu(
+ Tcl_Interp *interp, /* The interpreter this menu lives in */
+ TkMenu *menuPtr, /* The menu we are posting */
+ int x, /* The global x-coordinate of the top, left-
+ * hand corner of where the menu is supposed
+ * to be posted. */
+ int y) /* The global y-coordinate */
+{
+ MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl;
+ long popUpResult;
+ int result;
+ int oldMode;
+
+ if (inPostMenu) {
+ Tcl_AppendResult(interp,
+ "Cannot call post menu while already posting menu",
+ (char *) NULL);
+ result = TCL_ERROR;
+ } else {
+ Window dummyWin;
+ unsigned int state;
+ int dummy, mouseX, mouseY;
+ short menuID;
+ Window window;
+ int oldWidth = menuPtr->totalWidth;
+ Tk_Window parentWindow = Tk_Parent(menuPtr->tkwin);
+
+ inPostMenu++;
+
+ result = TkPreprocessMenu(menuPtr);
+ if (result != TCL_OK) {
+ inPostMenu--;
+ return result;
+ }
+
+ /*
+ * The post commands could have deleted the menu, which means
+ * we are dead and should go away.
+ */
+
+ if (menuPtr->tkwin == NULL) {
+ inPostMenu--;
+ return TCL_OK;
+ }
+
+ CompleteIdlers(menuPtr);
+ if (menuBarFlags & MENUBAR_REDRAW_PENDING) {
+ Tcl_CancelIdleCall(DrawMenuBarWhenIdle, (ClientData *) NULL);
+ DrawMenuBarWhenIdle((ClientData *) NULL);
+ }
+
+ if (NULL == parentWindow) {
+ tearoffStruct.excludeRect.top = tearoffStruct.excludeRect.left
+ = tearoffStruct.excludeRect.bottom
+ = tearoffStruct.excludeRect.right = SHRT_MAX;
+ } else {
+ int left, top;
+
+ Tk_GetRootCoords(parentWindow, &left, &top);
+ tearoffStruct.excludeRect.left = left;
+ tearoffStruct.excludeRect.top = top;
+ tearoffStruct.excludeRect.right = left + Tk_Width(parentWindow);
+ tearoffStruct.excludeRect.bottom = top + Tk_Height(parentWindow);
+ if (Tk_Class(parentWindow) == Tk_GetUid("Menubutton")) {
+ TkWindow *parentWinPtr = (TkWindow *) parentWindow;
+ TkMenuButton *mbPtr =
+ (TkMenuButton *) parentWinPtr->instanceData;
+ int menuButtonWidth = Tk_Width(parentWindow)
+ - 2 * (mbPtr->highlightWidth + mbPtr->borderWidth + 1);
+ menuPtr->totalWidth = menuButtonWidth > menuPtr->totalWidth
+ ? menuButtonWidth : menuPtr->totalWidth;
+ }
+ }
+
+ InsertMenu(macMenuHdl, -1);
+ RecursivelyInsertMenu(menuPtr);
+ CountMenuItems(macMenuHdl);
+
+ oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
+ popUpResult = PopUpMenuSelect(macMenuHdl, y, x, menuPtr->active);
+ Tcl_SetServiceMode(oldMode);
+
+ menuPtr->totalWidth = oldWidth;
+ RecursivelyDeleteMenu(menuPtr);
+ DeleteMenu(GetMenuID(macMenuHdl));
+
+ /*
+ * Simulate the mouse up.
+ */
+
+ XQueryPointer(NULL, None, &dummyWin, &dummyWin, &mouseX,
+ &mouseY, &dummy, &dummy, &state);
+ window = Tk_WindowId(menuPtr->tkwin);
+ TkGenerateButtonEvent(mouseX, mouseY, window, state);
+
+ /*
+ * Dispatch the command.
+ */
+
+ menuID = HiWord(popUpResult);
+ if (menuID != 0) {
+ result = TkMacOSXDispatchMenuEvent(menuID, LoWord(popUpResult));
+ } else {
+ TkMacOSXHandleTearoffMenu();
+ result = TCL_OK;
+ }
+
+ /*
+ * Be careful, here. The command executed in handling the menu event
+ * could destroy the window. Don't try to do anything with it then.
+ */
+
+ if (menuPtr->tkwin) {
+ InvalidateMDEFRgns();
+ RecursivelyClearActiveMenu(menuPtr);
+ }
+ inPostMenu--;
+ }
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpMenuNewEntry --
+ *
+ * Adds a pointer to a new menu entry structure with the platform-
+ * specific fields filled in. The Macintosh uses the
+ * platformEntryData field of the TkMenuEntry record to store
+ * geometry information.
+ *
+ * Results:
+ * Standard TCL error.
+ *
+ * Side effects:
+ * Storage gets allocated. New menu entry data is put into the
+ * platformEntryData field of the mePtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpMenuNewEntry(
+ TkMenuEntry *mePtr) /* The menu we are adding an entry to */
+{
+ EntryGeometry *geometryPtr =
+ (EntryGeometry *) ckalloc(sizeof(EntryGeometry));
+ TkMenu *menuPtr = mePtr->menuPtr;
+
+ geometryPtr->accelTextStart = 0;
+ geometryPtr->accelTextWidth = 0;
+ geometryPtr->nonAccelMargin = 0;
+ geometryPtr->modifierWidth = 0;
+ mePtr->platformEntryData = (TkMenuPlatformEntryData) geometryPtr;
+ if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
+ menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
+ Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr);
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ *
+ * Tk_MacOSXTurnOffMenus --
+ *
+ * Turns off all the menu drawing code. This is more than just disabling
+ * the "menu" command, this means that Tk will NEVER touch the menubar.
+ * It is needed in the Plugin, where Tk does not own the menubar.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * A flag is set which will disable all menu drawing.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_MacOSXTurnOffMenus()
+{
+ gNoTkMenus = 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ *
+ * DrawMenuBarWhenIdle --
+ *
+ * Update the menu bar next time there is an idle event.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Menu bar is redrawn.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DrawMenuBarWhenIdle(
+ ClientData clientData) /* ignored here */
+{
+ TkMenuReferences *menuRefPtr;
+ TkMenu *appleMenuPtr, *helpMenuPtr;
+ MenuHandle macMenuHdl;
+ Tcl_HashEntry *hashEntryPtr;
+
+ /*
+ * If we have been turned off, exit.
+ */
+
+ if (gNoTkMenus) {
+ return;
+ }
+
+ /*
+ * We need to clear the apple and help menus of any extra items.
+ */
+
+ if (currentAppleMenuID != 0) {
+ hashEntryPtr = Tcl_FindHashEntry(&commandTable,
+ (char *) ((int)currentAppleMenuID));
+ appleMenuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr);
+ TkpDestroyMenu(appleMenuPtr);
+ TkpNewMenu(appleMenuPtr);
+ appleMenuPtr->menuFlags &= ~MENU_APPLE_MENU;
+ appleMenuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
+ Tcl_DoWhenIdle(ReconfigureMacintoshMenu,
+ (ClientData) appleMenuPtr);
+ }
+
+ if (currentHelpMenuID != 0) {
+ hashEntryPtr = Tcl_FindHashEntry(&commandTable,
+ (char *) ((int)currentHelpMenuID));
+ helpMenuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr);
+ TkpDestroyMenu(helpMenuPtr);
+ TkpNewMenu(helpMenuPtr);
+ helpMenuPtr->menuFlags &= ~MENU_HELP_MENU;
+ helpMenuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
+ Tcl_DoWhenIdle(ReconfigureMacintoshMenu,
+ (ClientData) helpMenuPtr);
+ }
+
+ /*
+ * We need to find the clone of this menu that is the menubar.
+ * Once we do that, for every cascade in the menu, we need to
+ * insert the Mac menu in the Mac menubar. Finally, we need
+ * to redraw the menubar.
+ */
+
+ menuRefPtr = NULL;
+ if (currentMenuBarName != NULL) {
+ menuRefPtr = TkFindMenuReferences(currentMenuBarInterp,
+ currentMenuBarName);
+ }
+ if (menuRefPtr != NULL) {
+ TkMenu *menuPtr, *menuBarPtr;
+ TkMenu *cascadeMenuPtr;
+ char *appleMenuName, *helpMenuName;
+ int appleIndex = -1, helpIndex = -1;
+ int i;
+
+ menuPtr = menuRefPtr->menuPtr;
+ if (menuPtr != NULL) {
+ TkMenuReferences *specialMenuRefPtr;
+ TkMenuEntry *specialEntryPtr;
+
+ appleMenuName = ckalloc(strlen(currentMenuBarName)
+ + 1 + strlen(".apple") + 1);
+ sprintf(appleMenuName, "%s.apple",
+ Tk_PathName(menuPtr->tkwin));
+ specialMenuRefPtr = TkFindMenuReferences(currentMenuBarInterp,
+ appleMenuName);
+ if ((specialMenuRefPtr != NULL)
+ && (specialMenuRefPtr->menuPtr != NULL)) {
+ for (specialEntryPtr
+ = specialMenuRefPtr->parentEntryPtr;
+ specialEntryPtr != NULL;
+ specialEntryPtr
+ = specialEntryPtr->nextCascadePtr) {
+ if (specialEntryPtr->menuPtr == menuPtr) {
+ appleIndex = specialEntryPtr->index;
+ break;
+ }
+ }
+ }
+ ckfree(appleMenuName);
+
+ helpMenuName = ckalloc(strlen(currentMenuBarName)
+ + 1 + strlen(".help") + 1);
+ sprintf(helpMenuName, "%s.help",
+ Tk_PathName(menuPtr->tkwin));
+ specialMenuRefPtr = TkFindMenuReferences(currentMenuBarInterp,
+ helpMenuName);
+ if ((specialMenuRefPtr != NULL)
+ && (specialMenuRefPtr->menuPtr != NULL)) {
+ for (specialEntryPtr
+ = specialMenuRefPtr->parentEntryPtr;
+ specialEntryPtr != NULL;
+ specialEntryPtr
+ = specialEntryPtr->nextCascadePtr) {
+ if (specialEntryPtr->menuPtr == menuPtr) {
+ helpIndex = specialEntryPtr->index;
+ break;
+ }
+ }
+ }
+ ckfree(helpMenuName);
+
+ }
+
+ for (menuBarPtr = menuPtr;
+ (menuBarPtr != NULL)
+ && (menuBarPtr->menuType != MENUBAR);
+ menuBarPtr = menuBarPtr->nextInstancePtr) {
+
+ /*
+ * Null loop body.
+ */
+
+ }
+
+ if (menuBarPtr == NULL) {
+ SetDefaultMenubar();
+ } else {
+ if (menuBarPtr->tearoff != menuPtr->tearoff) {
+ if (menuBarPtr->tearoff) {
+ appleIndex = (-1 == appleIndex) ? appleIndex
+ : appleIndex + 1;
+ helpIndex = (-1 == helpIndex) ? helpIndex
+ : helpIndex + 1;
+ } else {
+ appleIndex = (-1 == appleIndex) ? appleIndex
+ : appleIndex - 1;
+ helpIndex = (-1 == helpIndex) ? helpIndex
+ : helpIndex - 1;
+ }
+ }
+ ClearMenuBar();
+
+ if (appleIndex == -1) {
+ InsertMenu(tkAppleMenu, 0);
+ currentAppleMenuID = 0;
+ } else {
+ short appleID;
+ appleMenuPtr = menuBarPtr->entries[appleIndex]
+ ->childMenuRefPtr->menuPtr;
+ TkpDestroyMenu(appleMenuPtr);
+ TkMacOSXGetNewMenuID(appleMenuPtr->interp, appleMenuPtr, 0,
+ &appleID);
+ macMenuHdl = NewMenu(appleID, "\p\024");
+ appleMenuPtr->platformData =
+ (TkMenuPlatformData) ckalloc(sizeof(MacMenu));
+ ((MacMenu *)appleMenuPtr->platformData)->menuHdl
+ = macMenuHdl;
+ SetRect(&((MacMenu *) appleMenuPtr->platformData)->menuRect,
+ 0, 0, 0, 0);
+ appleMenuPtr->menuFlags |= MENU_APPLE_MENU;
+ if (!(appleMenuPtr->menuFlags
+ & MENU_RECONFIGURE_PENDING)) {
+ appleMenuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
+ Tcl_DoWhenIdle(ReconfigureMacintoshMenu,
+ (ClientData) appleMenuPtr);
+ }
+ InsertMenu(macMenuHdl, 0);
+ RecursivelyInsertMenu(appleMenuPtr);
+ currentAppleMenuID = appleID;
+ }
+ if (helpIndex == -1) {
+ currentHelpMenuID = 0;
+ }
+
+ for (i = 0; i < menuBarPtr->numEntries; i++) {
+ if (i == appleIndex) {
+ if (menuBarPtr->entries[i]->state == ENTRY_DISABLED) {
+ DisableMenuItem(((MacMenu *) menuBarPtr->entries[i]
+ ->childMenuRefPtr->menuPtr
+ ->platformData)->menuHdl,
+ 0);
+ } else {
+ EnableMenuItem(((MacMenu *) menuBarPtr->entries[i]
+ ->childMenuRefPtr->menuPtr
+ ->platformData)->menuHdl,
+ 0);
+ }
+ continue;
+ } else if (i == helpIndex) {
+ TkMenu *helpMenuPtr = menuBarPtr->entries[i]
+ ->childMenuRefPtr->menuPtr;
+ MenuHandle helpMenuHdl = NULL;
+
+ if (helpMenuPtr == NULL) {
+ continue;
+ }
+ helpMenuPtr->menuFlags |= MENU_HELP_MENU;
+ if (!(helpMenuPtr->menuFlags
+ & MENU_RECONFIGURE_PENDING)) {
+ helpMenuPtr->menuFlags
+ |= MENU_RECONFIGURE_PENDING;
+ Tcl_DoWhenIdle(ReconfigureMacintoshMenu,
+ (ClientData) helpMenuPtr);
+ }
+ macMenuHdl =
+ ((MacMenu *) helpMenuPtr->platformData)->menuHdl;
+ currentHelpMenuID = GetMenuID(macMenuHdl);
+ } else if (menuBarPtr->entries[i]->type
+ == CASCADE_ENTRY) {
+ if ((menuBarPtr->entries[i]->childMenuRefPtr != NULL)
+ && menuBarPtr->entries[i]->childMenuRefPtr
+ ->menuPtr != NULL) {
+ cascadeMenuPtr = menuBarPtr->entries[i]
+ ->childMenuRefPtr->menuPtr;
+ macMenuHdl = ((MacMenu *) cascadeMenuPtr
+ ->platformData)->menuHdl;
+ DeleteMenu(GetMenuID(macMenuHdl));
+ InsertMenu(macMenuHdl, 0);
+ RecursivelyInsertMenu(cascadeMenuPtr);
+ if (menuBarPtr->entries[i]->state == ENTRY_DISABLED) {
+ DisableMenuItem(((MacMenu *) menuBarPtr->entries[i]
+ ->childMenuRefPtr->menuPtr
+ ->platformData)->menuHdl,
+ 0);
+ } else {
+ EnableMenuItem(((MacMenu *) menuBarPtr->entries[i]
+ ->childMenuRefPtr->menuPtr
+ ->platformData)->menuHdl,
+ 0);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ SetDefaultMenubar();
+ }
+ DrawMenuBar();
+ menuBarFlags &= ~MENUBAR_REDRAW_PENDING;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RecursivelyInsertMenu --
+ *
+ * Puts all of the cascades of this menu in the Mac hierarchical list.
+ *
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The menubar is changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RecursivelyInsertMenu(
+ TkMenu *menuPtr) /* All of the cascade items in this menu
+ * will be inserted into the mac menubar. */
+{
+ int i;
+ TkMenu *cascadeMenuPtr;
+ MenuHandle macMenuHdl;
+
+ for (i = 0; i < menuPtr->numEntries; i++) {
+ if (menuPtr->entries[i]->type == CASCADE_ENTRY) {
+ if ((menuPtr->entries[i]->childMenuRefPtr != NULL)
+ && (menuPtr->entries[i]->childMenuRefPtr->menuPtr
+ != NULL)) {
+ cascadeMenuPtr = menuPtr->entries[i]->childMenuRefPtr->menuPtr;
+ macMenuHdl =
+ ((MacMenu *) cascadeMenuPtr->platformData)->menuHdl;
+ InsertMenu(macMenuHdl, -1);
+ RecursivelyInsertMenu(cascadeMenuPtr);
+ }
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RecursivelyDeleteMenu --
+ *
+ * Takes all of the cascades of this menu out of the Mac hierarchical
+ * list.
+ *
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The menubar is changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RecursivelyDeleteMenu(
+ TkMenu *menuPtr) /* All of the cascade items in this menu
+ * will be inserted into the mac menubar. */
+{
+ int i;
+ TkMenu *cascadeMenuPtr;
+ MenuHandle macMenuHdl;
+
+ for (i = 0; i < menuPtr->numEntries; i++) {
+ if (menuPtr->entries[i]->type == CASCADE_ENTRY) {
+ if ((menuPtr->entries[i]->childMenuRefPtr != NULL)
+ && (menuPtr->entries[i]->childMenuRefPtr->menuPtr
+ != NULL)) {
+ cascadeMenuPtr = menuPtr->entries[i]->childMenuRefPtr->menuPtr;
+ macMenuHdl =
+ ((MacMenu *) cascadeMenuPtr->platformData)->menuHdl;
+ DeleteMenu(GetMenuID(macMenuHdl));
+ RecursivelyInsertMenu(cascadeMenuPtr);
+ }
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetDefaultMenubar --
+ *
+ * Puts the Apple, File and Edit menus into the Macintosh menubar.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The menubar is changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+SetDefaultMenubar()
+{
+ if (currentMenuBarName != NULL) {
+ ckfree(currentMenuBarName);
+ currentMenuBarName = NULL;
+ }
+ currentMenuBarOwner = NULL;
+ ClearMenuBar();
+ InsertMenu(tkAppleMenu, 0);
+ InsertMenu(tkFileMenu, 0);
+ InsertMenu(tkEditMenu, 0);
+ if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) {
+ Tcl_DoWhenIdle(DrawMenuBarWhenIdle, (ClientData *) NULL);
+ menuBarFlags |= MENUBAR_REDRAW_PENDING;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpSetMainMenubar --
+ *
+ * Puts the menu associated with a window into the menubar. Should
+ * only be called when the window is in front.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The menubar is changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpSetMainMenubar(
+ Tcl_Interp *interp, /* The interpreter of the application */
+ Tk_Window tkwin, /* The frame we are setting up */
+ char *menuName) /* The name of the menu to put in front.
+ * If NULL, use the default menu bar.
+ */
+{
+ TkWindow *winPtr = (TkWindow *) tkwin;
+ CGrafPtr winPort;
+ WindowRef macWindowPtr;
+ WindowRef frontNonFloating;
+
+ winPort=TkMacOSXGetDrawablePort(winPtr->window);
+ if (!winPort) {
+ return;
+ }
+ macWindowPtr = GetWindowFromPort(winPort);
+
+ frontNonFloating = FrontNonFloatingWindow();
+ if ((macWindowPtr == NULL) || (macWindowPtr != frontNonFloating)) {
+ return;
+ }
+
+ if ((currentMenuBarInterp != interp)
+ || (currentMenuBarOwner != tkwin)
+ || (currentMenuBarName == NULL)
+ || (menuName == NULL)
+ || (strcmp(menuName, currentMenuBarName) != 0)) {
+ Tk_Window searchWindow;
+ TopLevelMenubarList *listPtr;
+
+ if (currentMenuBarName != NULL) {
+ ckfree(currentMenuBarName);
+ }
+
+ if (menuName == NULL) {
+ searchWindow = tkwin;
+ if (strcmp(Tk_Class(searchWindow), "Menu") == 0) {
+ TkMenuReferences *menuRefPtr;
+
+ menuRefPtr = TkFindMenuReferences(interp, Tk_PathName(tkwin));
+ if (menuRefPtr != NULL) {
+ TkMenu *menuPtr = menuRefPtr->menuPtr;
+ if (menuPtr != NULL) {
+ menuPtr = menuPtr->masterMenuPtr;
+ searchWindow = menuPtr->tkwin;
+ }
+ }
+ }
+ for (; searchWindow != NULL;
+ searchWindow = Tk_Parent(searchWindow)) {
+
+ for (listPtr = windowListPtr; listPtr != NULL;
+ listPtr = listPtr->nextPtr) {
+ if (listPtr->tkwin == searchWindow) {
+ break;
+ }
+ }
+ if (listPtr != NULL) {
+ menuName = Tk_PathName(listPtr->menuPtr->masterMenuPtr
+ ->tkwin);
+ break;
+ }
+ }
+ }
+
+ if (menuName == NULL) {
+ currentMenuBarName = NULL;
+ } else {
+ currentMenuBarName = ckalloc(strlen(menuName) + 1);
+ strcpy(currentMenuBarName, menuName);
+ }
+ currentMenuBarOwner = tkwin;
+ currentMenuBarInterp = interp;
+ }
+ if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) {
+ Tcl_DoWhenIdle(DrawMenuBarWhenIdle, (ClientData *) NULL);
+ menuBarFlags |= MENUBAR_REDRAW_PENDING;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpSetWindowMenuBar --
+ *
+ * Associates a given menu with a window.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * On Windows and UNIX, associates the platform menu with the
+ * platform window.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpSetWindowMenuBar(
+ Tk_Window tkwin, /* The window we are setting the menu in */
+ TkMenu *menuPtr) /* The menu we are setting */
+{
+ TopLevelMenubarList *listPtr, *prevPtr;
+
+ /*
+ * Remove any existing reference to this window.
+ */
+
+ for (prevPtr = NULL, listPtr = windowListPtr;
+ listPtr != NULL;
+ prevPtr = listPtr, listPtr = listPtr->nextPtr) {
+ if (listPtr->tkwin == tkwin) {
+ break;
+ }
+ }
+
+ if (listPtr != NULL) {
+ if (prevPtr != NULL) {
+ prevPtr->nextPtr = listPtr->nextPtr;
+ } else {
+ windowListPtr = listPtr->nextPtr;
+ }
+ ckfree((char *) listPtr);
+ }
+
+ if (menuPtr != NULL) {
+ listPtr = (TopLevelMenubarList *) ckalloc(sizeof(TopLevelMenubarList));
+ listPtr->nextPtr = windowListPtr;
+ windowListPtr = listPtr;
+ listPtr->tkwin = tkwin;
+ listPtr->menuPtr = menuPtr;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXDispatchMenuEvent --
+ *
+ * Given a menu id and an item, dispatches the command associated
+ * with it.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Commands get executed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkMacOSXDispatchMenuEvent(
+ int menuID, /* The menu id of the menu we are invoking */
+ int index) /* The one-based index of the item that was
+ * selected. */
+{
+ int result = TCL_OK;
+ if (menuID != 0) {
+ if (menuID == kHMHelpMenuID) {
+ if (currentMenuBarOwner != NULL) {
+ TkMenuReferences *helpMenuRef;
+ char *helpMenuName = ckalloc(strlen(currentMenuBarName)
+ + strlen(".help") + 1);
+ sprintf(helpMenuName, "%s.help", currentMenuBarName);
+ helpMenuRef = TkFindMenuReferences(currentMenuBarInterp,
+ helpMenuName);
+ ckfree(helpMenuName);
+ if ((helpMenuRef != NULL) && (helpMenuRef->menuPtr != NULL)) {
+ int newIndex = index - helpItemCount - 1;
+ result = TkInvokeMenu(currentMenuBarInterp,
+ helpMenuRef->menuPtr, newIndex);
+ }
+ }
+ } else {
+ Tcl_HashEntry *commandEntryPtr =
+ Tcl_FindHashEntry(&commandTable, (char *) ((int)menuID));
+ if (commandEntryPtr != NULL) {
+ TkMenu *menuPtr = (TkMenu *) Tcl_GetHashValue(commandEntryPtr);
+ if ((currentAppleMenuID == menuID)
+ && (index > menuPtr->numEntries + 1)) {
+ Str255 itemText;
+
+ GetMenuItemText(GetMenuHandle(menuID), index, itemText);
+ result = TCL_OK;
+ } else {
+ result = TkInvokeMenu(menuPtr->interp, menuPtr, index - 1);
+ }
+ } else {
+ return TCL_ERROR;
+ }
+ }
+ }
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetMenuIndicatorGeometry --
+ *
+ * Gets the width and height of the indicator area of a menu.
+ *
+ * Results:
+ * widthPtr and heightPtr are set.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetMenuIndicatorGeometry (
+ TkMenu *menuPtr, /* The menu we are drawing */
+ TkMenuEntry *mePtr, /* The entry we are measuring */
+ Tk_Font tkfont, /* Precalculated font */
+ CONST Tk_FontMetrics *fmPtr, /* Precalculated font metrics */
+ int *widthPtr, /* The resulting width */
+ int *heightPtr) /* The resulting height */
+{
+ char markChar;
+
+ *heightPtr = fmPtr->linespace;
+
+ markChar = (char) FindMarkCharacter(mePtr);
+ *widthPtr = Tk_TextWidth(tkfont, &markChar, 1) + 4;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetMenuAccelGeometry --
+ *
+ * Gets the width and height of the accelerator area of a menu.
+ *
+ * Results:
+ * widthPtr and heightPtr are set.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetMenuAccelGeometry (
+ TkMenu *menuPtr, /* The menu we are measuring */
+ TkMenuEntry *mePtr, /* The entry we are measuring */
+ Tk_Font tkfont, /* The precalculated font */
+ CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */
+ int *modWidthPtr, /* The width of all of the key
+ * modifier symbols. */
+ int *textWidthPtr, /* The resulting width */
+ int *heightPtr) /* The resulting height */
+{
+ *heightPtr = fmPtr->linespace;
+ *modWidthPtr = 0;
+ if (mePtr->type == CASCADE_ENTRY) {
+ *textWidthPtr = SICN_HEIGHT;
+ *modWidthPtr = Tk_TextWidth(tkfont, "W", 1);
+ } else if (0 == mePtr->accelLength) {
+ *textWidthPtr = 0;
+ } else {
+ char *accel = (mePtr->accelPtr == NULL) ? ""
+ : Tcl_GetStringFromObj(mePtr->accelPtr, NULL);
+
+ if (NULL == GetResource('SICN', SICN_RESOURCE_NUMBER)) {
+ *textWidthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength);
+ } else {
+ int emWidth = Tk_TextWidth(tkfont, "W", 1) + 1;
+ if ((mePtr->entryFlags & ENTRY_ACCEL_MASK) == 0) {
+ int width = Tk_TextWidth(tkfont, accel, mePtr->accelLength);
+ *textWidthPtr = emWidth;
+ if (width < emWidth) {
+ *modWidthPtr = 0;
+ } else {
+ *modWidthPtr = width - emWidth;
+ }
+ } else {
+ int length = ((EntryGeometry *)mePtr->platformEntryData)
+ ->accelTextStart;
+ if (mePtr->entryFlags & ENTRY_CONTROL_ACCEL) {
+ *modWidthPtr += CONTROL_ICON_WIDTH;
+ }
+ if (mePtr->entryFlags & ENTRY_SHIFT_ACCEL) {
+ *modWidthPtr += SHIFT_ICON_WIDTH;
+ }
+ if (mePtr->entryFlags & ENTRY_OPTION_ACCEL) {
+ *modWidthPtr += OPTION_ICON_WIDTH;
+ }
+ if (mePtr->entryFlags & ENTRY_COMMAND_ACCEL) {
+ *modWidthPtr += COMMAND_ICON_WIDTH;
+ }
+ if (1 == (mePtr->accelLength - length)) {
+ *textWidthPtr = emWidth;
+ } else {
+ *textWidthPtr += Tk_TextWidth(tkfont, accel
+ + length, mePtr->accelLength - length);
+ }
+ }
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetTearoffEntryGeometry --
+ *
+ * Gets the width and height of of a tearoff entry.
+ *
+ * Results:
+ * widthPtr and heightPtr are set.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetTearoffEntryGeometry (
+ TkMenu *menuPtr, /* The menu we are drawing */
+ TkMenuEntry *mePtr, /* The entry we are measuring */
+ Tk_Font tkfont, /* The precalculated font */
+ CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */
+ int *widthPtr, /* The resulting width */
+ int *heightPtr) /* The resulting height */
+{
+ if ((GetResource('MDEF', 591) == NULL) &&
+ (menuPtr->menuType == MASTER_MENU)) {
+ *heightPtr = fmPtr->linespace;
+ *widthPtr = 0;
+ } else {
+ *widthPtr = *heightPtr = 0;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetMenuSeparatorGeometry --
+ *
+ * Gets the width and height of menu separator.
+ *
+ * Results:
+ * widthPtr and heightPtr are set.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetMenuSeparatorGeometry(
+ TkMenu *menuPtr, /* The menu we are drawing */
+ TkMenuEntry *mePtr, /* The entry we are measuring */
+ Tk_Font tkfont, /* The precalculated font */
+ CONST Tk_FontMetrics *fmPtr, /* The precalcualted font metrics */
+ int *widthPtr, /* The resulting width */
+ int *heightPtr) /* The resulting height */
+{
+ SInt16 outHeight;
+
+ GetThemeMenuSeparatorHeight(&outHeight);
+ *widthPtr = 0;
+ *heightPtr = outHeight;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DrawMenuEntryIndicator --
+ *
+ * This procedure draws the indicator part of a menu.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Commands are output to X to display the menu in its
+ * current mode.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DrawMenuEntryIndicator(
+ TkMenu *menuPtr, /* The menu we are drawing */
+ TkMenuEntry *mePtr, /* The entry we are drawing */
+ Drawable d, /* The drawable we are drawing */
+ GC gc, /* The GC we are drawing with */
+ GC indicatorGC, /* The GC to use for the indicator */
+ Tk_Font tkfont, /* The precalculated font */
+ CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */
+ int x, /* topleft hand corner of entry */
+ int y, /* topleft hand corner of entry */
+ int width, /* width of entry */
+ int height) /* height of entry */
+{
+ if ((mePtr->type == CHECK_BUTTON_ENTRY) ||
+ (mePtr->type == RADIO_BUTTON_ENTRY)) {
+ if (mePtr->indicatorOn
+ && (mePtr->entryFlags & ENTRY_SELECTED)) {
+ int baseline;
+ short markShort;
+
+ baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2;
+ GetItemMark(((MacMenu *) menuPtr->platformData)->menuHdl,
+ mePtr->index + 1, &markShort);
+ if (markShort != 0) {
+ char markChar;
+ char markCharUTF[TCL_UTF_MAX + 1];
+ int dstWrote;
+
+ markChar = (char) markShort;
+ /*
+ * Not sure if this is the correct encoding, but this function
+ * doesn't appear to be used at all in, since the Carbon Menus
+ * draw themselves
+ */
+ Tcl_ExternalToUtf(NULL, NULL, &markChar, 1, 0, NULL,
+ markCharUTF, TCL_UTF_MAX + 1, NULL, &dstWrote, NULL);
+ Tk_DrawChars(menuPtr->display, d, gc, tkfont, markCharUTF,
+ dstWrote, x + 2, baseline);
+ }
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DrawMenuBackground --
+ *
+ * If Appearance is present, draws the Appearance background
+ *
+ * Results:
+ * Nothing
+ *
+ * Side effects:
+ * Commands are output to X to display the menu in its
+ * current mode.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+DrawMenuBackground(
+ Rect *menuRectPtr, /* The menu rect */
+ Drawable d, /* What we are drawing into */
+ ThemeMenuType type /* Type of menu */
+ )
+{
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+
+ destPort = TkMacOSXGetDrawablePort(d);
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+ TkMacOSXSetUpClippingRgn(d);
+ DrawThemeMenuBackground (menuRectPtr, type);
+ SetGWorld(saveWorld, saveDevice);
+ return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DrawSICN --
+ *
+ * Given a resource id and an index, loads the appropriate SICN
+ * and draws it into a given drawable using the given gc.
+ *
+ * Results:
+ * Returns 1 if the SICN was found, 0 if not found.
+ *
+ * Side effects:
+ * Commands are output to X to display the menu in its
+ * current mode.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+DrawSICN(
+ int resourceID, /* The resource # of the SICN table */
+ int index, /* The index into the SICN table of the
+ * icon we want. */
+ Drawable d, /* What we are drawing into */
+ GC gc, /* The GC to draw with */
+ int x, /* The left hand coord of the SICN */
+ int y) /* The top coord of the SICN */
+{
+ Handle sicnHandle = (Handle) GetResource('SICN', SICN_RESOURCE_NUMBER);
+
+ if (NULL == sicnHandle) {
+ return 0;
+ } else {
+ BitMap sicnBitmap;
+ Rect destRect;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ const BitMap *destBitMap;
+ RGBColor origForeColor, origBackColor, foreColor, backColor;
+
+ HLock(sicnHandle);
+ destPort = TkMacOSXGetDrawablePort(d);
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+ TkMacOSXSetUpClippingRgn(d);
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
+ GetForeColor(&origForeColor);
+ GetBackColor(&origBackColor);
+
+ if (TkSetMacColor(gc->foreground, &foreColor)) {
+ RGBForeColor(&foreColor);
+ }
+
+ if (TkSetMacColor(gc->background, &backColor)) {
+ RGBBackColor(&backColor);
+ }
+
+ SetRect(&destRect, x, y, x + SICN_HEIGHT, y + SICN_HEIGHT);
+ sicnBitmap.baseAddr = (Ptr) (*sicnHandle) + index * SICN_HEIGHT
+ * SICN_ROWS;
+ sicnBitmap.rowBytes = SICN_ROWS;
+ SetRect(&sicnBitmap.bounds, 0, 0, 16, 16);
+ destBitMap = GetPortBitMapForCopyBits(destPort);
+ CopyBits(&sicnBitmap, destBitMap, &sicnBitmap.bounds, &destRect, GetPortTextMode(destPort), NULL);
+ HUnlock(sicnHandle);
+ RGBForeColor(&origForeColor);
+ RGBBackColor(&origBackColor);
+ SetGWorld(saveWorld, saveDevice);
+ return 1;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DrawMenuEntryAccelerator --
+ *
+ * This procedure draws the accelerator part of a menu. We
+ * need to decide what to draw here. Should we replace strings
+ * like "Control", "Command", etc?
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Commands are output to X to display the menu in its
+ * current mode.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DrawMenuEntryAccelerator(
+ TkMenu *menuPtr, /* The menu we are drawing */
+ TkMenuEntry *mePtr, /* The entry we are drawing */
+ Drawable d, /* The drawable we are drawing in */
+ GC gc, /* The gc to draw into */
+ Tk_Font tkfont, /* The precalculated font */
+ CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */
+ Tk_3DBorder activeBorder, /* border for menu background */
+ int x, /* The left side of the entry */
+ int y, /* The top of the entry */
+ int width, /* The width of the entry */
+ int height, /* The height of the entry */
+ int drawArrow) /* Whether or not to draw cascade arrow */
+{
+ int activeBorderWidth;
+
+ Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
+ &activeBorderWidth);
+ if (mePtr->type == CASCADE_ENTRY) {
+ /*
+ * Under Appearance, we let the Appearance Manager draw the icon
+ */
+
+ } else if (mePtr->accelLength != 0) {
+ int leftEdge = x + width;
+ int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2;
+ char *accel;
+
+ accel = Tcl_GetStringFromObj(mePtr->accelPtr, NULL);
+
+ if (NULL == GetResource('SICN', SICN_RESOURCE_NUMBER)) {
+ leftEdge -= ((EntryGeometry *) mePtr->platformEntryData)
+ ->accelTextWidth;
+ Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
+ mePtr->accelLength, leftEdge, baseline);
+ } else {
+ EntryGeometry *geometryPtr =
+ (EntryGeometry *) mePtr->platformEntryData;
+ int length = mePtr->accelLength - geometryPtr->accelTextStart;
+
+ leftEdge -= geometryPtr->accelTextWidth;
+ if ((mePtr->entryFlags & ENTRY_ACCEL_MASK) == 0) {
+ leftEdge -= geometryPtr->modifierWidth;
+ }
+
+ Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel
+ + geometryPtr->accelTextStart, length, leftEdge, baseline);
+
+ if (mePtr->entryFlags & ENTRY_COMMAND_ACCEL) {
+ leftEdge -= COMMAND_ICON_WIDTH;
+ DrawSICN(SICN_RESOURCE_NUMBER, COMMAND_ICON, d, gc,
+ leftEdge, (y + (height / 2)) - (SICN_HEIGHT / 2) - 1);
+ }
+
+ if (mePtr->entryFlags & ENTRY_OPTION_ACCEL) {
+ leftEdge -= OPTION_ICON_WIDTH;
+ DrawSICN(SICN_RESOURCE_NUMBER, OPTION_ICON, d, gc,
+ leftEdge, (y + (height / 2)) - (SICN_HEIGHT / 2) - 1);
+ }
+
+ if (mePtr->entryFlags & ENTRY_SHIFT_ACCEL) {
+ leftEdge -= SHIFT_ICON_WIDTH;
+ DrawSICN(SICN_RESOURCE_NUMBER, SHIFT_ICON, d, gc,
+ leftEdge, (y + (height / 2)) - (SICN_HEIGHT / 2) - 1);
+ }
+
+ if (mePtr->entryFlags & ENTRY_CONTROL_ACCEL) {
+ leftEdge -= CONTROL_ICON_WIDTH;
+ DrawSICN(SICN_RESOURCE_NUMBER, CONTROL_ICON, d, gc,
+ leftEdge, (y + (height / 2)) - (SICN_HEIGHT / 2) - 1);
+ }
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DrawMenuSeparator --
+ *
+ * The menu separator is drawn.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Commands are output to X to display the menu in its
+ * current mode.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DrawMenuSeparator(
+ TkMenu *menuPtr, /* The menu we are drawing */
+ TkMenuEntry *mePtr, /* The entry we are drawing */
+ Drawable d, /* The drawable we are drawing into */
+ GC gc, /* The gc we are drawing with */
+ Tk_Font tkfont, /* The precalculated font */
+ CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */
+ int x, /* left coordinate of entry */
+ int y, /* top coordinate of entry */
+ int width, /* width of entry */
+ int height) /* height of entry */
+{
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ Rect r;
+
+ destPort = TkMacOSXGetDrawablePort(d);
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+ TkMacOSXSetUpClippingRgn(d);
+ r.top = y;
+ r.left = x;
+ r.bottom = y + height;
+ r.right = x + width;
+
+ DrawThemeMenuSeparator(&r);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AppearanceEntryDrawWrapper --
+ *
+ * It routes to the Appearance Managers DrawThemeEntry, which will
+ * then call us back after setting up the drawing context.
+ *
+ * Results:
+ * A menu entry is drawn
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+AppearanceEntryDrawWrapper(
+ TkMenuEntry *mePtr,
+ Rect *menuRectPtr,
+ MenuTrackingData *mtdPtr,
+ Drawable d,
+ Tk_FontMetrics *fmPtr,
+ Tk_Font tkfont,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ MenuEntryUserData meData;
+ Rect itemRect;
+ ThemeMenuState theState;
+ ThemeMenuItemType theType;
+
+ meData.mePtr = mePtr;
+ meData.mdefDrawable = d;
+ meData.fmPtr = fmPtr;
+ meData.tkfont = tkfont;
+
+ itemRect.top = y;
+ itemRect.left = x;
+ itemRect.bottom = itemRect.top + height;
+ itemRect.right = itemRect.left + width;
+
+ if (mePtr->state == ENTRY_ACTIVE) {
+ theState = kThemeMenuSelected;
+ } else if (mePtr->state == ENTRY_DISABLED) {
+ theState = kThemeMenuDisabled;
+ } else {
+ theState = kThemeMenuActive;
+ }
+
+ if (mePtr->type == CASCADE_ENTRY) {
+ theType = kThemeMenuItemHierarchical;
+ } else {
+ theType = kThemeMenuItemPlain;
+ }
+
+ DrawThemeMenuItem (menuRectPtr, &itemRect,
+ mtdPtr->virtualMenuTop, mtdPtr->virtualMenuBottom, theState,
+ theType, tkThemeMenuItemDrawingUPP,
+ (unsigned long) &meData);
+
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * tkThemeMenuItemDrawingProc --
+ *
+ * This routine is called from the Appearance DrawThemeMenuEntry
+ *
+ * Results:
+ * A menu entry is drawn
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+pascal void
+tkThemeMenuItemDrawingProc (
+ const Rect *inBounds,
+ SInt16 inDepth,
+ Boolean inIsColorDevice,
+ SInt32 inUserData)
+{
+ MenuEntryUserData *meData = (MenuEntryUserData *) inUserData;
+ TkpDrawMenuEntry(meData->mePtr, meData->mdefDrawable,
+ meData->tkfont, meData->fmPtr, inBounds->left,
+ inBounds->top, inBounds->right - inBounds->left,
+ inBounds->bottom - inBounds->top, 0, 1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXHandleTearoffMenu() --
+ *
+ * This routine sees if the MDEF has set a menu and a mouse position
+ * for tearing off and makes a tearoff menu if it has.
+ *
+ * Results:
+ * menuPtr->interp will have the result of the tearoff command.
+ *
+ * Side effects:
+ * A new tearoff menu is created if it is supposed to be.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXHandleTearoffMenu(void)
+{
+ if (tearoffStruct.menuPtr != NULL) {
+ Tcl_DString tearoffCmdStr;
+ char intString[TCL_INTEGER_SPACE];
+ short windowPart;
+ WindowRef whichWindow;
+
+ windowPart = FindWindow(tearoffStruct.point, &whichWindow);
+
+ if (windowPart != inMenuBar) {
+ Tcl_DStringInit(&tearoffCmdStr);
+ Tcl_DStringAppendElement(&tearoffCmdStr, "tkTearOffMenu");
+ Tcl_DStringAppendElement(&tearoffCmdStr,
+ Tk_PathName(tearoffStruct.menuPtr->tkwin));
+ sprintf(intString, "%d", tearoffStruct.point.h);
+ Tcl_DStringAppendElement(&tearoffCmdStr, intString);
+ sprintf(intString, "%d", tearoffStruct.point.v);
+ Tcl_DStringAppendElement(&tearoffCmdStr, intString);
+ Tcl_Eval(tearoffStruct.menuPtr->interp,
+ Tcl_DStringValue(&tearoffCmdStr));
+ Tcl_DStringFree(&tearoffCmdStr);
+ tearoffStruct.menuPtr = NULL;
+ }
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkpInitializeMenuBindings --
+ *
+ * For every interp, initializes the bindings for Windows
+ * menus. Does nothing on Mac or XWindows.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * C-level bindings are setup for the interp which will
+ * handle Alt-key sequences for menus without beeping
+ * or interfering with user-defined Alt-key bindings.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TkpInitializeMenuBindings(interp, bindingTable)
+ Tcl_Interp *interp; /* The interpreter to set. */
+ Tk_BindingTable bindingTable; /* The table to add to. */
+{
+ /*
+ * Nothing to do.
+ */
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkpComputeMenubarGeometry --
+ *
+ * This procedure is invoked to recompute the size and
+ * layout of a menu that is a menubar clone.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Fields of menu entries are changed to reflect their
+ * current positions, and the size of the menu window
+ * itself may be changed.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TkpComputeMenubarGeometry(menuPtr)
+ TkMenu *menuPtr; /* Structure describing menu. */
+{
+ TkpComputeStandardMenuGeometry(menuPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DrawTearoffEntry --
+ *
+ * This procedure draws the background part of a menu.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Commands are output to X to display the menu in its
+ * current mode.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+DrawTearoffEntry(
+ TkMenu *menuPtr, /* The menu we are drawing */
+ TkMenuEntry *mePtr, /* The entry we are drawing */
+ Drawable d, /* The drawable we are drawing into */
+ GC gc, /* The gc we are drawing with */
+ Tk_Font tkfont, /* The font we are drawing with */
+ CONST Tk_FontMetrics *fmPtr, /* The metrics we are drawing with */
+ int x, /* Left edge of entry. */
+ int y, /* Top edge of entry. */
+ int width, /* Width of entry. */
+ int height) /* Height of entry. */
+{
+ XPoint points[2];
+ int margin, segmentWidth, maxX;
+ Tk_3DBorder border;
+
+ if (menuPtr->menuType != MASTER_MENU ) {
+ return;
+ }
+
+ margin = (fmPtr->ascent + fmPtr->descent)/2;
+ points[0].x = x;
+ points[0].y = y + height/2;
+ points[1].y = points[0].y;
+ segmentWidth = 6;
+ maxX = width - 1;
+ border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
+
+ while (points[0].x < maxX) {
+ points[1].x = points[0].x + segmentWidth;
+ if (points[1].x > maxX) {
+ points[1].x = maxX;
+ }
+ Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1,
+ TK_RELIEF_RAISED);
+ points[0].x += 2*segmentWidth;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXSetHelpMenuItemCount --
+ *
+ * Has to be called after the first call to InsertMenu. Sets
+ * up the global variable for the number of items in the
+ * unmodified help menu.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Sets the global helpItemCount.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXSetHelpMenuItemCount()
+{
+ MenuRef helpMenuHandle;
+ MenuItemIndex itemIndex;
+
+ if ((HMGetHelpMenu(&helpMenuHandle,&itemIndex) != noErr)
+ || (helpMenuHandle == NULL)) {
+ helpItemCount = -1;
+ } else {
+ helpItemCount = CountMenuItems(helpMenuHandle);
+ DeleteMenuItem(helpMenuHandle, helpItemCount);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXMenuClick --
+ *
+ * Prepares a menubar for MenuSelect or MenuKey.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Any pending configurations of the menubar are completed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXMenuClick()
+{
+ TkMenu *menuPtr;
+ TkMenuReferences *menuRefPtr;
+
+ if ((currentMenuBarInterp != NULL) && (currentMenuBarName != NULL)) {
+ menuRefPtr = TkFindMenuReferences(currentMenuBarInterp,
+ currentMenuBarName);
+ for (menuPtr = menuRefPtr->menuPtr->masterMenuPtr;
+ menuPtr != NULL; menuPtr = menuPtr->nextInstancePtr) {
+ if (menuPtr->menuType == MENUBAR) {
+ CompleteIdlers(menuPtr);
+ break;
+ }
+ }
+ }
+
+ if (menuBarFlags & MENUBAR_REDRAW_PENDING) {
+ Tcl_CancelIdleCall(DrawMenuBarWhenIdle, (ClientData *) NULL);
+ DrawMenuBarWhenIdle((ClientData *) NULL);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDrawMenuEntry --
+ *
+ * Draws the given menu entry at the given coordinates with the
+ * given attributes.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * X Server commands are executed to display the menu entry.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpDrawMenuEntry(
+ TkMenuEntry *mePtr, /* The entry to draw */
+ Drawable d, /* What to draw into */
+ Tk_Font tkfont, /* Precalculated font for menu */
+ CONST Tk_FontMetrics *menuMetricsPtr,
+ /* Precalculated metrics for menu */
+ int x, /* X-coordinate of topleft of entry */
+ int y, /* Y-coordinate of topleft of entry */
+ int width, /* Width of the entry rectangle */
+ int height, /* Height of the current rectangle */
+ int strictMotif, /* Boolean flag */
+ int drawArrow) /* Whether or not to draw the cascade
+ * arrow for cascade items. Only applies
+ * to Windows. */
+{
+ GC gc;
+ TkMenu *menuPtr = mePtr->menuPtr;
+ int padY = (menuPtr->menuType == MENUBAR) ? 3 : 0;
+ GC indicatorGC;
+ Tk_3DBorder bgBorder, activeBorder;
+ const Tk_FontMetrics *fmPtr;
+ Tk_FontMetrics entryMetrics;
+ int adjustedY = y + padY;
+ int adjustedHeight = height - 2 * padY;
+
+ /*
+ * Choose the gc for drawing the foreground part of the entry.
+ * Under Appearance, we pass a null (appearanceGC) to tell
+ * ourselves not to change whatever color the appearance manager has set.
+ */
+
+ if ((mePtr->state == ENTRY_ACTIVE) && !strictMotif) {
+ gc = mePtr->activeGC;
+ if (gc == NULL) {
+ gc = menuPtr->activeGC;
+ }
+ } else {
+ TkMenuEntry *cascadeEntryPtr;
+ int parentDisabled = 0;
+
+ for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
+ cascadeEntryPtr != NULL;
+ cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
+ char *name = (cascadeEntryPtr->namePtr == NULL) ? ""
+ : Tcl_GetStringFromObj(cascadeEntryPtr->namePtr, NULL);
+
+ if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) {
+ if (cascadeEntryPtr->state == ENTRY_DISABLED) {
+ parentDisabled = 1;
+ }
+ break;
+ }
+ }
+
+ if (((parentDisabled || (mePtr->state == ENTRY_DISABLED)))
+ && (menuPtr->disabledFgPtr != NULL)) {
+ gc = mePtr->disabledGC;
+ if (gc == NULL) {
+ gc = menuPtr->disabledGC;
+ }
+ } else {
+ gc = mePtr->textGC;
+ if (gc == NULL) {
+ gc = menuPtr->textGC;
+ }
+ }
+ }
+
+ indicatorGC = mePtr->indicatorGC;
+ if (indicatorGC == NULL) {
+ indicatorGC = menuPtr->indicatorGC;
+ }
+
+ bgBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin,
+ (mePtr->borderPtr == NULL)
+ ? menuPtr->borderPtr : mePtr->borderPtr);
+ if (strictMotif) {
+ activeBorder = bgBorder;
+ } else {
+ activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin,
+ (mePtr->activeBorderPtr == NULL)
+ ? menuPtr->activeBorderPtr : mePtr->activeBorderPtr);
+ }
+
+ if (mePtr->fontPtr == NULL) {
+ fmPtr = menuMetricsPtr;
+ } else {
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
+ Tk_GetFontMetrics(tkfont, &entryMetrics);
+ fmPtr = &entryMetrics;
+ }
+
+ /*
+ * Need to draw the entire background, including padding. On Unix,
+ * for menubars, we have to draw the rest of the entry taking
+ * into account the padding.
+ */
+
+ DrawMenuEntryBackground(menuPtr, mePtr, d, activeBorder,
+ bgBorder, x, y, width, height);
+
+ if (mePtr->type == SEPARATOR_ENTRY) {
+ DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont,
+ fmPtr, x, adjustedY, width, adjustedHeight);
+ } else if (mePtr->type == TEAROFF_ENTRY) {
+ DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
+ width, adjustedHeight);
+ } else {
+ DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x,
+ adjustedY, width, adjustedHeight);
+ DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
+ activeBorder, x, adjustedY, width, adjustedHeight, drawArrow);
+ if (!mePtr->hideMargin) {
+ DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont,
+ fmPtr, x, adjustedY, width, adjustedHeight);
+ }
+
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkpComputeStandardMenuGeometry --
+ *
+ * This procedure is invoked to recompute the size and
+ * layout of a menu that is not a menubar clone.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Fields of menu entries are changed to reflect their
+ * current positions, and the size of the menu window
+ * itself may be changed.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TkpComputeStandardMenuGeometry(
+ TkMenu *menuPtr) /* Structure describing menu. */
+{
+ Tk_Font tkfont, menuFont;
+ Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
+ int x, y, height, modifierWidth, labelWidth, indicatorSpace;
+ int windowWidth, windowHeight, accelWidth, maxAccelTextWidth;
+ int i, j, lastColumnBreak, maxModifierWidth, maxWidth, nonAccelMargin;
+ int maxNonAccelMargin, maxEntryWithAccelWidth, maxEntryWithoutAccelWidth;
+ int entryWidth, maxIndicatorSpace, borderWidth, activeBorderWidth;
+ TkMenuEntry *mePtr, *columnEntryPtr;
+ EntryGeometry *geometryPtr;
+
+ if (menuPtr->tkwin == NULL) {
+ return;
+ }
+
+ Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
+ &borderWidth);
+ Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
+ &activeBorderWidth);
+ x = y = borderWidth;
+ indicatorSpace = labelWidth = accelWidth = maxAccelTextWidth = 0;
+ windowHeight = windowWidth = maxWidth = lastColumnBreak = 0;
+ maxModifierWidth = nonAccelMargin = maxNonAccelMargin = 0;
+ maxEntryWithAccelWidth = maxEntryWithoutAccelWidth = 0;
+ maxIndicatorSpace = 0;
+
+ /*
+ * On the Mac especially, getting font metrics can be quite slow,
+ * so we want to do it intelligently. We are going to precalculate
+ * them and pass them down to all of the measuring and drawing
+ * routines. We will measure the font metrics of the menu once.
+ * If an entry does not have its own font set, then we give
+ * the geometry/drawing routines the menu's font and metrics.
+ * If an entry has its own font, we will measure that font and
+ * give all of the geometry/drawing the entry's font and metrics.
+ */
+
+ menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
+ Tk_GetFontMetrics(menuFont, &menuMetrics);
+
+ for (i = 0; i < menuPtr->numEntries; i++) {
+ mePtr = menuPtr->entries[i];
+ if (mePtr->fontPtr == NULL) {
+ tkfont = menuFont;
+ fmPtr = &menuMetrics;
+ } else {
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
+ Tk_GetFontMetrics(tkfont, &entryMetrics);
+ fmPtr = &entryMetrics;
+ }
+
+ if ((i > 0) && mePtr->columnBreak) {
+ if (maxIndicatorSpace != 0) {
+ maxIndicatorSpace += 2;
+ }
+ for (j = lastColumnBreak; j < i; j++) {
+ columnEntryPtr = menuPtr->entries[j];
+ geometryPtr =
+ (EntryGeometry *) columnEntryPtr->platformEntryData;
+
+ columnEntryPtr->indicatorSpace = maxIndicatorSpace;
+ columnEntryPtr->width = maxIndicatorSpace + maxWidth
+ + 2 * activeBorderWidth;
+ geometryPtr->accelTextWidth = maxAccelTextWidth;
+ geometryPtr->modifierWidth = maxModifierWidth;
+ columnEntryPtr->x = x;
+ columnEntryPtr->entryFlags &= ~ENTRY_LAST_COLUMN;
+ if (maxEntryWithoutAccelWidth > maxEntryWithAccelWidth) {
+ geometryPtr->nonAccelMargin = maxEntryWithoutAccelWidth
+ - maxEntryWithAccelWidth;
+ if (geometryPtr->nonAccelMargin > maxNonAccelMargin) {
+ geometryPtr->nonAccelMargin = maxNonAccelMargin;
+ }
+ } else {
+ geometryPtr->nonAccelMargin = 0;
+ }
+ }
+ x += maxIndicatorSpace + maxWidth + 2 * borderWidth;
+ windowWidth = x;
+ maxWidth = maxIndicatorSpace = maxAccelTextWidth = 0;
+ maxModifierWidth = maxNonAccelMargin = maxEntryWithAccelWidth = 0;
+ maxEntryWithoutAccelWidth = 0;
+ lastColumnBreak = i;
+ y = borderWidth;
+ }
+
+ if (mePtr->type == SEPARATOR_ENTRY) {
+ GetMenuSeparatorGeometry(menuPtr, mePtr, tkfont,
+ fmPtr, &entryWidth, &height);
+ mePtr->height = height;
+ } else if (mePtr->type == TEAROFF_ENTRY) {
+ GetTearoffEntryGeometry(menuPtr, mePtr, tkfont,
+ fmPtr, &entryWidth, &height);
+ mePtr->height = height;
+ } else {
+ /*
+ * For each entry, compute the height required by that
+ * particular entry, plus three widths: the width of the
+ * label, the width to allow for an indicator to be displayed
+ * to the left of the label (if any), and the width of the
+ * accelerator to be displayed to the right of the label
+ * (if any). These sizes depend, of course, on the type
+ * of the entry.
+ */
+
+ GetMenuLabelGeometry(mePtr, tkfont, fmPtr, &labelWidth,
+ &height);
+ mePtr->height = height;
+
+ if (mePtr->type == CASCADE_ENTRY) {
+ GetMenuAccelGeometry(menuPtr, mePtr, tkfont, fmPtr,
+ &modifierWidth, &accelWidth, &height);
+ nonAccelMargin = 0;
+ } else if (mePtr->accelLength == 0) {
+ nonAccelMargin = mePtr->hideMargin ? 0
+ : Tk_TextWidth(tkfont, "m", 1);
+ accelWidth = modifierWidth = 0;
+ } else {
+ labelWidth += Tk_TextWidth(tkfont, "m", 1);
+ GetMenuAccelGeometry(menuPtr, mePtr, tkfont,
+ fmPtr, &modifierWidth, &accelWidth, &height);
+ if (height > mePtr->height) {
+ mePtr->height = height;
+ }
+ nonAccelMargin = 0;
+ }
+
+ if (!(mePtr->hideMargin)) {
+ GetMenuIndicatorGeometry(menuPtr, mePtr, tkfont,
+ fmPtr, &indicatorSpace, &height);
+ if (height > mePtr->height) {
+ mePtr->height = height;
+ }
+ } else {
+ indicatorSpace = 0;
+ }
+
+ if (nonAccelMargin > maxNonAccelMargin) {
+ maxNonAccelMargin = nonAccelMargin;
+ }
+ if (accelWidth > maxAccelTextWidth) {
+ maxAccelTextWidth = accelWidth;
+ }
+ if (modifierWidth > maxModifierWidth) {
+ maxModifierWidth = modifierWidth;
+ }
+ if (indicatorSpace > maxIndicatorSpace) {
+ maxIndicatorSpace = indicatorSpace;
+ }
+
+ entryWidth = labelWidth + modifierWidth + accelWidth
+ + nonAccelMargin;
+
+ if (entryWidth > maxWidth) {
+ maxWidth = entryWidth;
+ }
+
+ if (mePtr->accelLength > 0) {
+ if (entryWidth > maxEntryWithAccelWidth) {
+ maxEntryWithAccelWidth = entryWidth;
+ }
+ } else {
+ if (entryWidth > maxEntryWithoutAccelWidth) {
+ maxEntryWithoutAccelWidth = entryWidth;
+ }
+ }
+
+ mePtr->height += 2 * activeBorderWidth;
+ }
+ mePtr->y = y;
+ y += menuPtr->entries[i]->height + borderWidth;
+ if (y > windowHeight) {
+ windowHeight = y;
+ }
+ }
+
+ for (j = lastColumnBreak; j < menuPtr->numEntries; j++) {
+ columnEntryPtr = menuPtr->entries[j];
+ geometryPtr = (EntryGeometry *) columnEntryPtr->platformEntryData;
+
+ columnEntryPtr->indicatorSpace = maxIndicatorSpace;
+ columnEntryPtr->width = maxIndicatorSpace + maxWidth
+ + 2 * activeBorderWidth;
+ geometryPtr->accelTextWidth = maxAccelTextWidth;
+ geometryPtr->modifierWidth = maxModifierWidth;
+ columnEntryPtr->x = x;
+ columnEntryPtr->entryFlags |= ENTRY_LAST_COLUMN;
+ if (maxEntryWithoutAccelWidth > maxEntryWithAccelWidth) {
+ geometryPtr->nonAccelMargin = maxEntryWithoutAccelWidth
+ - maxEntryWithAccelWidth;
+ if (geometryPtr->nonAccelMargin > maxNonAccelMargin) {
+ geometryPtr->nonAccelMargin = maxNonAccelMargin;
+ }
+ } else {
+ geometryPtr->nonAccelMargin = 0;
+ }
+ }
+ windowWidth = x + maxIndicatorSpace + maxWidth
+ + 2 * activeBorderWidth + borderWidth;
+ windowHeight += borderWidth;
+
+ /*
+ * The X server doesn't like zero dimensions, so round up to at least
+ * 1 (a zero-sized menu should never really occur, anyway).
+ */
+
+ if (windowWidth <= 0) {
+ windowWidth = 1;
+ }
+ if (windowHeight <= 0) {
+ windowHeight = 1;
+ }
+ menuPtr->totalWidth = windowWidth;
+ menuPtr->totalHeight = windowHeight;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DrawMenuEntryLabel --
+ *
+ * This procedure draws the label part of a menu.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Commands are output to X to display the menu in its
+ * current mode.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DrawMenuEntryLabel(
+ TkMenu *menuPtr, /* The menu we are drawing */
+ TkMenuEntry *mePtr, /* The entry we are drawing */
+ Drawable d, /* What we are drawing into */
+ GC gc, /* The gc we are drawing into */
+ Tk_Font tkfont, /* The precalculated font */
+ CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */
+ int x, /* left edge */
+ int y, /* right edge */
+ int width, /* width of entry */
+ int height) /* height of entry */
+{
+ int baseline;
+ int indicatorSpace = mePtr->indicatorSpace;
+ int leftEdge = x + indicatorSpace;
+ int imageHeight, imageWidth;
+
+ /*
+ * Draw label or bitmap or image for entry.
+ */
+
+ baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2;
+ if (mePtr->image != NULL) {
+ Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight);
+ if ((mePtr->selectImage != NULL)
+ && (mePtr->entryFlags & ENTRY_SELECTED)) {
+ Tk_RedrawImage(mePtr->selectImage, 0, 0,
+ imageWidth, imageHeight, d, leftEdge,
+ (int) (y + (mePtr->height - imageHeight)/2));
+ } else {
+ Tk_RedrawImage(mePtr->image, 0, 0, imageWidth,
+ imageHeight, d, leftEdge,
+ (int) (y + (mePtr->height - imageHeight)/2));
+ }
+ } else if (mePtr->bitmapPtr != NULL) {
+ int width, height;
+ Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);
+ Tk_SizeOfBitmap(menuPtr->display,
+ bitmap, &width, &height);
+ XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0,
+ (unsigned) width, (unsigned) height, leftEdge,
+ (int) (y + (mePtr->height - height)/2), 1);
+ } else {
+ if (mePtr->labelLength > 0) {
+ Tcl_DString itemTextDString, convertedTextDString;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+#ifdef USE_ATSU
+ int runLengths;
+ CFStringRef stringRef;
+ ATSUTextLayout textLayout;
+ UniCharCount runLength;
+ ATSUStyle style;
+ int length;
+ int err;
+ Str255 fontName;
+ SInt16 fontSize;
+ Style fontStyle;
+ ATSUAttributeValuePtr valuePtr;
+ ByteCount valueSize;
+ Fixed fixedSize;
+ short iFONDNumber;
+ ATSUFontID fontID;
+ ATSUAttributeTag tag;
+
+ GetThemeFont (kThemeMenuItemFont, smSystemScript, fontName, &fontSize, &fontStyle);
+ if ((err = ATSUCreateStyle(&style)) != noErr) {
+ fprintf(stderr,"ATSUCreateStyle failed, %d\n", err);
+ return;
+ }
+ fixedSize = fontSize<<16;
+ tag = kATSUSizeTag;
+ valueSize = sizeof(fixedSize);
+ valuePtr = &fixedSize;
+ if ((err=ATSUSetAttributes(style, 1, &tag, &valueSize, &valuePtr))!= noErr) {
+ fprintf(stderr,"ATSUSetAttributes failed,%d\n", err );
+ }
+
+ GetFNum(fontName, &iFONDNumber);
+ ATSUFONDtoFontID(iFONDNumber, NULL, &fontID);
+ tag = kATSUFontTag;
+ valueSize = sizeof(fontID);
+ valuePtr = &fontID;
+ if ((err=ATSUSetAttributes(style, 1, &tag, &valueSize, &valuePtr))!= noErr) {
+ fprintf(stderr,"ATSUSetAttributes failed,%d\n", err );
+ }
+
+#endif
+
+ GetEntryText(mePtr, &itemTextDString);
+#ifdef USE_ATSU
+ runLengths = 1;
+ length = Tcl_DStringLength(&itemTextDString);
+ stringRef = CFStringCreateWithCString(NULL, Tcl_DStringValue(&itemTextDString), GetApplicationTextEncoding());
+ if (!stringRef) {
+ fprintf(stderr,"CFStringCreateWithCString failed\n");
+ }
+ if ((err=ATSUCreateTextLayoutWithTextPtr(CFStringGetCharactersPtr(stringRef), 0, length, length,
+ 1, &runLengths, &style, &textLayout)) != noErr) {
+ fprintf(stderr,"ATSUCreateTextLayoutWithTextPtr failed, %d\n", err);
+ return;
+ }
+#endif
+
+ /* Somehow DrawChars is changing the colors, it is odd, since
+ it works for the Apple Platinum Appearance, but not for
+ some Kaleidoscope Themes... Untill I can figure out what
+ exactly is going on, this will have to do: */
+
+ destPort = TkMacOSXGetDrawablePort(d);
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
+
+ MoveTo((short) leftEdge, (short) baseline);
+ Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&itemTextDString),
+ Tcl_DStringLength(&itemTextDString), &convertedTextDString);
+#ifdef USE_ATSU
+ xLocation = leftEdge<<16;
+ yLocation = baseline<<16;
+ ATSUDrawText(textLayout,kATSUFromTextBeginning, kATSUToTextEnd, xLocation, yLocation);
+ ATSUDisposeTextLayout(textLayout);
+ CFRelease(stringRef);
+#else
+ DrawText(Tcl_DStringValue(&convertedTextDString), 0,
+ Tcl_DStringLength(&convertedTextDString));
+#endif
+
+ /* Tk_DrawChars(menuPtr->display, d, gc,
+ tkfont, Tcl_DStringValue(&itemTextDString),
+ Tcl_DStringLength(&itemTextDString),
+ leftEdge, baseline); */
+
+ Tcl_DStringFree(&itemTextDString);
+ }
+ }
+
+ if (mePtr->state == ENTRY_DISABLED) {
+ if (menuPtr->disabledFgPtr == NULL) {
+ } else if ((mePtr->image != NULL)
+ && (menuPtr->disabledImageGC != None)) {
+ XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC,
+ leftEdge,
+ (int) (y + (mePtr->height - imageHeight)/2),
+ (unsigned) imageWidth, (unsigned) imageHeight);
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DrawMenuEntryBackground --
+ *
+ * This procedure draws the background part of a menu entry.
+ * Under Appearance, we only draw the background if the entry's
+ * border is set, we DO NOT inherit it from the menu...
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Commands are output to X to display the menu in its
+ * current mode.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DrawMenuEntryBackground(
+ TkMenu *menuPtr, /* The menu we are drawing. */
+ TkMenuEntry *mePtr, /* The entry we are drawing. */
+ Drawable d, /* What we are drawing into */
+ Tk_3DBorder activeBorder, /* Border for active items */
+ Tk_3DBorder bgBorder, /* Border for the background */
+ int x, /* left edge */
+ int y, /* top edge */
+ int width, /* width of rectangle to draw */
+ int height) /* height of rectangle to draw */
+{
+ if ((menuPtr->menuType == TEAROFF_MENU)
+ || ((mePtr->state == ENTRY_ACTIVE)
+ && (mePtr->activeBorderPtr != None))
+ || ((mePtr->state != ENTRY_ACTIVE) && (mePtr->borderPtr != None))) {
+ if (mePtr->state == ENTRY_ACTIVE) {
+ bgBorder = activeBorder;
+ }
+ Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder,
+ x, y, width, height, 0, TK_RELIEF_FLAT);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetMenuLabelGeometry --
+ *
+ * Figures out the size of the label portion of a menu item.
+ *
+ * Results:
+ * widthPtr and heightPtr are filled in with the correct geometry
+ * information.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetMenuLabelGeometry(
+ TkMenuEntry *mePtr, /* The entry we are computing */
+ Tk_Font tkfont, /* The precalculated font */
+ CONST Tk_FontMetrics *fmPtr, /* The precalculated metrics */
+ int *widthPtr, /* The resulting width of the label
+ * portion */
+ int *heightPtr) /* The resulting height of the label
+ * portion */
+{
+ TkMenu *menuPtr = mePtr->menuPtr;
+
+ if (mePtr->image != NULL) {
+ Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr);
+ } else if (mePtr->bitmapPtr != NULL) {
+ Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);
+ Tk_SizeOfBitmap(menuPtr->display, bitmap, widthPtr, heightPtr);
+ } else {
+ *heightPtr = fmPtr->linespace;
+
+ if (mePtr->labelPtr != NULL) {
+ Tcl_DString itemTextDString;
+
+ GetEntryText(mePtr, &itemTextDString);
+ *widthPtr = Tk_TextWidth(tkfont,
+ Tcl_DStringValue(&itemTextDString),
+ Tcl_DStringLength(&itemTextDString));
+ Tcl_DStringFree(&itemTextDString);
+ } else {
+ *widthPtr = 0;
+ }
+ }
+ *heightPtr += 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MenuSelectEvent --
+ *
+ * Generates a "MenuSelect" virtual event. This can be used to
+ * do context-sensitive menu help.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Places a virtual event on the event queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+MenuSelectEvent(
+ TkMenu *menuPtr) /* the menu we have selected. */
+{
+ XVirtualEvent event;
+ Point where;
+ CGrafPtr port;
+ Rect bounds;
+
+ event.type = VirtualEvent;
+ event.serial = menuPtr->display->request;
+ event.send_event = false;
+ event.display = menuPtr->display;
+ Tk_MakeWindowExist(menuPtr->tkwin);
+ event.event = Tk_WindowId(menuPtr->tkwin);
+ event.root = XRootWindow(menuPtr->display, 0);
+ event.subwindow = None;
+ event.time = TkpGetMS();
+
+ GetMouse(&where);
+ GetPort(&port);
+ GetPortBounds(port,&bounds);
+ event.x_root = where.h + bounds.left;
+ event.y_root = where.v + bounds.top;
+ event.state = TkMacOSXButtonKeyState();
+ event.same_screen = true;
+ event.name = Tk_GetUid("MenuSelect");
+ Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RecursivelyClearActiveMenu --
+ *
+ * Recursively clears the active entry in the menu's cascade hierarchy.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Generates <<MenuSelect>> virtual events.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+RecursivelyClearActiveMenu(
+ TkMenu *menuPtr) /* The menu to reset. */
+{
+ int i;
+ TkMenuEntry *mePtr;
+
+ TkActivateMenuEntry(menuPtr, -1);
+ MenuSelectEvent(menuPtr);
+ for (i = 0; i < menuPtr->numEntries; i++) {
+ mePtr = menuPtr->entries[i];
+ if (mePtr->type == CASCADE_ENTRY) {
+ if ((mePtr->childMenuRefPtr != NULL)
+ && (mePtr->childMenuRefPtr->menuPtr != NULL)) {
+ RecursivelyClearActiveMenu(mePtr->childMenuRefPtr->menuPtr);
+ }
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InvalidateMDEFRgns --
+ *
+ * Invalidates the regions covered by menus that did redrawing and
+ * might be damaged.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Generates Mac update events for affected windows.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+InvalidateMDEFRgns(void)
+{
+ GDHandle saveDevice;
+ GWorldPtr saveWorld, destPort;
+ Point scratch;
+ MacDrawable *macDraw;
+ TkMacOSXWindowList *listPtr;
+
+ if (totalMenuRgn == NULL) {
+ return;
+ }
+
+ GetGWorld(&saveWorld, &saveDevice);
+ for (listPtr = tkMacOSXWindowListPtr ; listPtr != NULL;
+ listPtr = listPtr->nextPtr) {
+ macDraw = (MacDrawable *) Tk_WindowId(listPtr->winPtr);
+ if (macDraw->flags & TK_DRAWN_UNDER_MENU) {
+ destPort = TkMacOSXGetDrawablePort(Tk_WindowId(listPtr->winPtr));
+ SetGWorld(destPort, NULL);
+ scratch.h = scratch.v = 0;
+ GlobalToLocal(&scratch);
+ OffsetRgn(totalMenuRgn, scratch.v, scratch.h);
+ InvalWindowRgn(GetWindowFromPort(destPort),totalMenuRgn);
+ OffsetRgn(totalMenuRgn, -scratch.v, -scratch.h);
+ macDraw->flags &= ~TK_DRAWN_UNDER_MENU;
+ }
+ }
+
+ SetGWorld(saveWorld, saveDevice);
+ SetEmptyRgn(totalMenuRgn);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXClearMenubarActive --
+ *
+ * Recursively clears the active entry in the current menubar hierarchy.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Generates <<MenuSelect>> virtual events.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXClearMenubarActive(void)
+{
+ TkMenuReferences *menuBarRefPtr;
+
+ if (currentMenuBarName != NULL) {
+ menuBarRefPtr = TkFindMenuReferences(currentMenuBarInterp,
+ currentMenuBarName);
+ if ((menuBarRefPtr != NULL) && (menuBarRefPtr->menuPtr != NULL)) {
+ TkMenu *menuPtr;
+
+ for (menuPtr = menuBarRefPtr->menuPtr->masterMenuPtr; menuPtr != NULL;
+ menuPtr = menuPtr->nextInstancePtr) {
+ if (menuPtr->menuType == MENUBAR) {
+ RecursivelyClearActiveMenu(menuPtr);
+ }
+ }
+ }
+ }
+ InvalidateMDEFRgns();
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpMenuNotifyToplevelCreate --
+ *
+ * This routine reconfigures the menu and the clones indicated by
+ * menuName becuase a toplevel has been created and any system
+ * menus need to be created. Only applicable to Windows.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * An idle handler is set up to do the reconfiguration.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpMenuNotifyToplevelCreate(
+ Tcl_Interp *interp, /* The interp the menu lives in. */
+ char *menuName) /* The name of the menu to
+ * reconfigure. */
+{
+ /*
+ * Nothing to do.
+ */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpMenuInit --
+ *
+ * Initializes Mac-specific menu data.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Allocates a hash table.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpMenuInit(void)
+{
+ lastMenuID = 256;
+ Tcl_InitHashTable(&commandTable, TCL_ONE_WORD_KEYS);
+ currentMenuBarOwner = NULL;
+ tearoffStruct.menuPtr = NULL;
+ currentAppleMenuID = 0;
+ currentHelpMenuID = 0;
+ currentMenuBarInterp = NULL;
+ currentMenuBarName = NULL;
+ windowListPtr = NULL;
+
+ tkThemeMenuItemDrawingUPP
+ = NewMenuItemDrawingUPP(tkThemeMenuItemDrawingProc);
+
+ /*
+ * We should just hardcode the utf-8 ellipsis character into
+ * 'elipsisString' here
+ */
+ Tcl_ExternalToUtf(NULL, Tcl_GetEncoding(NULL, "macRoman"),
+ "\311", /* ellipsis character */
+ -1, 0, NULL, elipsisString,
+ TCL_UTF_MAX + 1, NULL, NULL, NULL);
+
+ useMDEFVar = Tcl_NewStringObj("::tk::mac::useCustomMDEF", -1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpMenuThreadInit --
+ *
+ * Does platform-specific initialization of thread-specific
+ * menu state.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpMenuThreadInit()
+{
+ /*
+ * Nothing to do.
+ */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpPreprocessMacMenu --
+ *
+ * Handle preprocessing of menubar if it exists.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * All post commands for the current menubar get executed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXPreprocessMenu()
+{
+ TkMenuReferences *mbRefPtr;
+ int code;
+
+ if ((currentMenuBarName != NULL) && (currentMenuBarInterp != NULL)) {
+ mbRefPtr = TkFindMenuReferences(currentMenuBarInterp,
+ currentMenuBarName);
+ if ((mbRefPtr != NULL) && (mbRefPtr->menuPtr != NULL)) {
+ Tcl_Preserve((ClientData)currentMenuBarInterp);
+ code = TkPreprocessMenu(mbRefPtr->menuPtr->masterMenuPtr);
+ if ((code != TCL_OK) && (code != TCL_CONTINUE)
+ && (code != TCL_BREAK)) {
+ Tcl_AddErrorInfo(currentMenuBarInterp,
+ "\n (menu preprocess)");
+ Tcl_BackgroundError(currentMenuBarInterp);
+ }
+ Tcl_Release((ClientData)currentMenuBarInterp);
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MenuDefProc --
+ *
+ * This routine is the MDEF handler for Tk. It receives all messages
+ * for the menu and dispatches them.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * This routine causes menus to be drawn and will certainly allocate
+ * memory as a result. Also, the menu can scroll up and down, and
+ * various other interface actions can take place.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+MenuDefProc(
+ SInt16 message, /* What action are we taking? */
+ MenuRef menu, /* The menu we are working with */
+ Rect *menuRectPtr, /* A pointer to the rect for the
+ * whole menu. */
+ Point hitPt, /* Where the mouse was clicked for
+ * the appropriate messages. */
+ SInt16 *whichItem) /* Output result. Which item was
+ * hit by the user? */
+{
+ TkMenu *menuPtr;
+ Tcl_HashEntry *commandEntryPtr;
+ int maxMenuHeight;
+ MenuID menuID;
+ BitMap screenBits;
+
+ menuID = GetMenuID(menu);
+ commandEntryPtr = Tcl_FindHashEntry(&commandTable, (char *) ((int)menuID));
+
+ if (commandEntryPtr) {
+ menuPtr = (TkMenu *) Tcl_GetHashValue(commandEntryPtr);
+ } else {
+ menuPtr = NULL;
+ }
+
+ switch (message) {
+ case kMenuInitMsg:
+ *whichItem = noErr;
+ break;
+ case kMenuDisposeMsg:
+ break;
+ case kMenuHiliteItemMsg: {
+ HandleMenuHiliteMsg (menu, menuRectPtr, hitPt, whichItem, menuPtr);
+ break;
+ }
+ case kMenuCalcItemMsg:
+ HandleMenuCalcItemMsg (menu, menuRectPtr, hitPt, whichItem, menuPtr);
+ break;
+ case kMenuDrawItemsMsg: {
+ /*
+ * We do nothing here, because we don't support the Menu Managers
+ * dynamic item groups
+ */
+
+ break;
+ }
+ case kMenuThemeSavvyMsg:
+ *whichItem = kThemeSavvyMenuResponse;
+ break;
+ case kMenuSizeMsg:
+ GetQDGlobalsScreenBits(&screenBits);
+ maxMenuHeight = screenBits.bounds.bottom
+ - screenBits.bounds.top
+ - GetMBarHeight() - SCREEN_MARGIN;
+ SetMenuWidth(menu, menuPtr->totalWidth );
+ SetMenuHeight(menu,maxMenuHeight < menuPtr->totalHeight ? maxMenuHeight : menuPtr->totalHeight );
+ break;
+ case kMenuDrawMsg:
+ HandleMenuDrawMsg (menu, menuRectPtr, hitPt, whichItem, menuPtr);
+ break;
+ case kMenuFindItemMsg:
+ HandleMenuFindItemsMsg (menu, menuRectPtr, hitPt, whichItem, menuPtr);
+ break;
+ case kMenuPopUpMsg:
+ HandleMenuPopUpMsg (menu, menuRectPtr, hitPt, whichItem, menuPtr);
+ break;
+ }
+}
+
+void
+HandleMenuHiliteMsg (MenuRef menu,
+ Rect *menuRectPtr,
+ Point hitPt,
+ SInt16 *whichItem,
+ TkMenu *menuPtr)
+{
+ TkMenuEntry *mePtr = NULL;
+ Tk_Font tkfont;
+ Tk_FontMetrics fontMetrics;
+ int oldItem;
+ int newItem = -1;
+ MDEFHiliteItemData * hidPtr = ( MDEFHiliteItemData *)whichItem;
+ MenuTrackingData mtd, *mtdPtr = &mtd;
+ int err;
+ oldItem = hidPtr->previousItem - 1;
+ newItem = hidPtr->newItem - 1;
+
+ err = GetMenuTrackingData(menu, mtdPtr);
+ if (err !=noErr) {
+ fprintf(stderr,"GetMenuTrackingData failed : %d\n", err );
+ return;
+ }
+
+ if (oldItem >= 0) {
+ Rect oldItemRect;
+ int width;
+
+ mePtr = menuPtr->entries[oldItem];
+ if (mePtr->fontPtr == NULL) {
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin,
+ menuPtr->fontPtr);
+ } else {
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin,
+ mePtr->fontPtr);
+ }
+ Tk_GetFontMetrics(tkfont, &fontMetrics);
+
+ width = (mePtr->entryFlags & ENTRY_LAST_COLUMN)
+ ? menuPtr->totalWidth - mePtr->x : mePtr->width;
+
+ /*
+ * In Aqua, have to call EraseMenuBackground when you overdraw
+ * a previously selected menu item, otherwise you will see the
+ * old select highlight under the transparency of the new menu item.
+ */
+
+ oldItemRect.left = menuRectPtr->left + mePtr->x;
+ oldItemRect.right = oldItemRect.left +width;
+ oldItemRect.top = mtdPtr->virtualMenuTop + mePtr->y;
+ oldItemRect.bottom = oldItemRect.top + mePtr->height;
+
+ EraseMenuBackground(menu, & oldItemRect, NULL);
+
+ AppearanceEntryDrawWrapper(mePtr, menuRectPtr, mtdPtr,
+ (Drawable) &macMDEFDrawable, &fontMetrics, tkfont,
+ oldItemRect.left,
+ oldItemRect.top,
+ width,
+ mePtr->height);
+ }
+ if (newItem != -1) {
+ mePtr = menuPtr->entries[newItem];
+ if (mePtr->state != ENTRY_DISABLED) {
+ TkActivateMenuEntry(menuPtr, newItem);
+ }
+ if (mePtr->fontPtr == NULL) {
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
+ } else {
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
+ }
+ Tk_GetFontMetrics(tkfont, &fontMetrics);
+ AppearanceEntryDrawWrapper(mePtr, menuRectPtr, mtdPtr,
+ (Drawable) &macMDEFDrawable, &fontMetrics, tkfont,
+ menuRectPtr->left + mePtr->x,
+ mtdPtr->virtualMenuTop + mePtr->y,
+ (mePtr->entryFlags & ENTRY_LAST_COLUMN) ?
+ menuPtr->totalWidth - mePtr->x : mePtr->width,
+ mePtr->height);
+ }
+ tkUseMenuCascadeRgn = 1;
+ MenuSelectEvent(menuPtr);
+ Tcl_ServiceAll();
+ tkUseMenuCascadeRgn = 0;
+ if (newItem!=-1 && mePtr->state != ENTRY_DISABLED) {
+ TkActivateMenuEntry(menuPtr, -1);
+ }
+
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HandleMenuDrawMsg --
+ *
+ * It handles the MenuDefProc's draw message.
+ *
+ * Results:
+ * A menu entry is drawn
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+void
+HandleMenuDrawMsg(MenuRef menu,
+ Rect *menuRectPtr,
+ Point hitPt,
+ SInt16 *whichItem,
+ TkMenu *menuPtr)
+{
+ Tk_Font tkfont, menuFont;
+ Tk_FontMetrics fontMetrics, entryMetrics;
+ Tk_FontMetrics *fmPtr;
+ TkMenuEntry *mePtr;
+ int i;
+ GDHandle device;
+ TkMenu *searchMenuPtr;
+ Rect menuClipRect;
+ ThemeMenuType menuType;
+ MenuTrackingData * mtdPtr = (MenuTrackingData *)whichItem;
+ /*
+ * Store away the menu rectangle so we can keep track of the
+ * different regions that the menu obscures.
+ */
+
+ ((MacMenu *) menuPtr->platformData)->menuRect = *menuRectPtr;
+ if (tkMenuCascadeRgn == NULL) {
+ tkMenuCascadeRgn = NewRgn();
+ }
+ if (utilRgn == NULL) {
+ utilRgn = NewRgn();
+ }
+ if (totalMenuRgn == NULL) {
+ totalMenuRgn = NewRgn();
+ }
+ SetEmptyRgn(tkMenuCascadeRgn);
+ for (searchMenuPtr = menuPtr; searchMenuPtr != NULL; ) {
+ RectRgn(utilRgn,
+ &((MacMenu *) searchMenuPtr->platformData)->menuRect);
+ InsetRgn(utilRgn, -1, -1);
+ UnionRgn(tkMenuCascadeRgn, utilRgn, tkMenuCascadeRgn);
+ OffsetRgn(utilRgn, 1, 1);
+ UnionRgn(tkMenuCascadeRgn, utilRgn, tkMenuCascadeRgn);
+
+ if (searchMenuPtr->menuRefPtr->parentEntryPtr != NULL) {
+ searchMenuPtr = searchMenuPtr->menuRefPtr
+ ->parentEntryPtr->menuPtr;
+ } else {
+ break;
+ }
+ if (searchMenuPtr->menuType == MENUBAR) {
+ break;
+ }
+ }
+ UnionRgn(totalMenuRgn, tkMenuCascadeRgn, totalMenuRgn);
+ SetEmptyRgn(utilRgn);
+
+ /*
+ * Now draw the background if Appearance is present...
+ */
+
+ GetGWorld(&macMDEFDrawable.grafPtr, &device);
+
+ if (menuPtr->menuRefPtr->topLevelListPtr != NULL) {
+ menuType = kThemeMenuTypePullDown;
+ } else if (menuPtr->menuRefPtr->parentEntryPtr != NULL) {
+ menuType = kThemeMenuTypeHierarchical;
+ } else {
+ menuType = kThemeMenuTypePopUp;
+ }
+
+ DrawMenuBackground(menuRectPtr, (Drawable) &macMDEFDrawable, menuType);
+
+ /*
+ * Next, figure out scrolling information.
+ */
+
+ menuClipRect = *menuRectPtr;
+ if ((menuClipRect.bottom - menuClipRect.top)
+ < menuPtr->totalHeight) {
+ if (mtdPtr->virtualMenuTop < menuRectPtr->top) {
+ DrawSICN(SICN_RESOURCE_NUMBER, UP_ARROW,
+ (Drawable) &macMDEFDrawable,
+ menuPtr->textGC,
+ menuRectPtr->left + menuPtr->entries[1]->indicatorSpace,
+ menuRectPtr->top);
+ menuClipRect.top += SICN_HEIGHT;
+ }
+ if ((mtdPtr->virtualMenuTop + menuPtr->totalHeight)
+ > menuRectPtr->bottom) {
+ DrawSICN(SICN_RESOURCE_NUMBER, DOWN_ARROW,
+ (Drawable) &macMDEFDrawable,
+ menuPtr->textGC,
+ menuRectPtr->left + menuPtr->entries[1]->indicatorSpace,
+ menuRectPtr->bottom - SICN_HEIGHT);
+ menuClipRect.bottom -= SICN_HEIGHT;
+ }
+ GetClip(utilRgn);
+ }
+
+ /*
+ * Now, actually draw the menu. Don't draw entries that
+ * are higher than the top arrow, and don't draw entries
+ * that are lower than the bottom.
+ */
+
+ menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
+ Tk_GetFontMetrics(menuFont, &fontMetrics);
+ for (i = 0; i < menuPtr->numEntries; i++) {
+ mePtr = menuPtr->entries[i];
+ if (mtdPtr->virtualMenuTop + mePtr->y + mePtr->height
+ < menuClipRect.top) {
+ continue;
+ } else if (mtdPtr->virtualMenuTop + mePtr->y
+ > menuClipRect.bottom) {
+ continue;
+ }
+ ClipRect(&menuClipRect);
+ if (mePtr->fontPtr == NULL) {
+ fmPtr = &fontMetrics;
+ tkfont = menuFont;
+ } else {
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
+ Tk_GetFontMetrics(tkfont, &entryMetrics);
+ fmPtr = &entryMetrics;
+ }
+ AppearanceEntryDrawWrapper(mePtr, menuRectPtr, mtdPtr,
+ (Drawable) &macMDEFDrawable, fmPtr, tkfont,
+ menuRectPtr->left + mePtr->x,
+ mtdPtr->virtualMenuTop + mePtr->y,
+ (mePtr->entryFlags & ENTRY_LAST_COLUMN) ?
+ menuPtr->totalWidth - mePtr->x : mePtr->width,
+ menuPtr->entries[i]->height);
+ }
+ mtdPtr->virtualMenuBottom = mtdPtr->virtualMenuTop
+ + menuPtr->totalHeight;
+ if (!EmptyRgn(utilRgn)) {
+ SetClip(utilRgn);
+ SetEmptyRgn(utilRgn);
+ }
+ MDEFScrollFlag = 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HandleMenuFindItemsMsg --
+ *
+ * It handles the MenuDefProc's FindItems message. We have to
+ * respond by filling in the itemSelected, itemUnderMouse and
+ * itemRect fields. This is also the time to scroll the menu if
+ * it is too long to fit on the screen.
+ *
+ * Results:
+ * The Menu system is informed of the selected item & the item
+ * under the mouse.
+ *
+ * Side effects:
+ * The menu might get scrolled.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+HandleMenuFindItemsMsg (MenuRef menu,
+ Rect *menuRectPtr,
+ Point hitPt,
+ SInt16 *whichItem,
+ TkMenu *menuPtr)
+{
+ TkMenuEntry *parentEntryPtr;
+ Tk_Font tkfont;
+ Tk_FontMetrics fontMetrics, entryMetrics;
+ Tk_FontMetrics *fmPtr;
+ TkMenuEntry *mePtr;
+ int i;
+ int newItem = -1;
+ GDHandle device;
+ Rect itemRect;
+ short windowPart;
+ WindowRef whichWindow;
+ RGBColor bgColor;
+ RGBColor fgColor;
+ RGBColor origFgColor;
+ PenState origPenState;
+ Rect dragRect;
+ Rect scratchRect = {-32768, -32768, 32767, 32767};
+ RgnHandle oldClipRgn;
+ TkMenuReferences *menuRefPtr;
+ Rect menuClipRect;
+
+ int hasTopScroll, hasBottomScroll;
+ MenuTrackingData * mtdPtr = (MenuTrackingData *)whichItem;
+ int itemUnderMouse = -1;
+ enum {
+ DONT_SCROLL, DOWN_SCROLL, UP_SCROLL
+ } scrollDirection;
+ Rect updateRect;
+ short scrollAmt = 0;
+ RGBColor origForeColor, origBackColor;
+
+ /*
+ * Find out which item was hit. If it is the same as the old item,
+ * we don't need to do anything.
+ */
+
+ if (PtInRect(hitPt, menuRectPtr)) {
+ for (i = 0; i < menuPtr->numEntries; i++) {
+ mePtr = menuPtr->entries[i];
+ itemRect.left = menuRectPtr->left + mePtr->x;
+ itemRect.top = mtdPtr->virtualMenuTop + mePtr->y;
+ if (mePtr->entryFlags & ENTRY_LAST_COLUMN) {
+ itemRect.right = itemRect.left + menuPtr->totalWidth
+ - mePtr->x;
+ } else {
+ itemRect.right = itemRect.left + mePtr->width;
+ }
+ itemRect.bottom = itemRect.top
+ + mePtr->height;
+ if (PtInRect(hitPt, &itemRect)) {
+ if ((mePtr->type == SEPARATOR_ENTRY)
+ || (mePtr->state == ENTRY_DISABLED)) {
+ newItem = -1;
+ itemUnderMouse = i;
+ } else {
+ TkMenuEntry *cascadeEntryPtr;
+ int parentDisabled = 0;
+
+ for (cascadeEntryPtr
+ = menuPtr->menuRefPtr->parentEntryPtr;
+ cascadeEntryPtr != NULL;
+ cascadeEntryPtr
+ = cascadeEntryPtr->nextCascadePtr) {
+ char *name;
+
+ name = Tcl_GetStringFromObj(
+ cascadeEntryPtr->namePtr, NULL);
+ if (strcmp(name, Tk_PathName(menuPtr->tkwin))
+ == 0) {
+ if (cascadeEntryPtr->state == ENTRY_DISABLED) {
+ parentDisabled = 1;
+ }
+ break;
+ }
+ }
+
+ if (parentDisabled) {
+ newItem = -1;
+ itemUnderMouse = i;
+ } else {
+ newItem = i;
+ itemUnderMouse = i;
+ }
+ }
+ break;
+ }
+ }
+ } else {
+ }
+
+ /*
+ * Now we need to take care of scrolling the menu.
+ */
+
+ hasTopScroll = mtdPtr->virtualMenuTop < menuRectPtr->top;
+ hasBottomScroll = mtdPtr->virtualMenuBottom > menuRectPtr->bottom;
+ scrollDirection = DONT_SCROLL;
+ if (hasTopScroll && (hitPt.v < menuRectPtr->top + SICN_HEIGHT)) {
+ newItem = -1;
+ scrollDirection = DOWN_SCROLL;
+ } else if (hasBottomScroll && (hitPt.v > (menuRectPtr->bottom - SICN_HEIGHT))) {
+ newItem = -1;
+ scrollDirection = UP_SCROLL;
+ }
+
+ menuClipRect = *menuRectPtr;
+ if (hasTopScroll) {
+ menuClipRect.top += SICN_HEIGHT;
+ }
+ if (hasBottomScroll) {
+ menuClipRect.bottom -= SICN_HEIGHT;
+ }
+ if (MDEFScrollFlag) {
+ scrollDirection = DONT_SCROLL;
+ MDEFScrollFlag = 0;
+ }
+ GetClip(utilRgn);
+ ClipRect(&menuClipRect);
+
+ mtdPtr->itemSelected = newItem + 1;
+ mtdPtr->itemUnderMouse = itemUnderMouse + 1;
+ mtdPtr->itemRect = itemRect;
+
+ GetGWorld(&macMDEFDrawable.grafPtr, &device);
+ GetForeColor(&origForeColor);
+ GetBackColor(&origBackColor);
+
+ if (scrollDirection == UP_SCROLL) {
+ scrollAmt = menuClipRect.bottom - hitPt.v;
+ if (scrollAmt < menuRectPtr->bottom
+ - mtdPtr->virtualMenuBottom) {
+ scrollAmt = menuRectPtr->bottom - mtdPtr->virtualMenuBottom;
+ }
+ if (!hasTopScroll && ((mtdPtr->virtualMenuTop + scrollAmt)
+ < menuRectPtr->top)) {
+ SetRect(&updateRect, menuRectPtr->left,
+ mtdPtr->virtualMenuTop, menuRectPtr->right,
+ mtdPtr->virtualMenuTop + SICN_HEIGHT);
+ EraseRect(&updateRect);
+ DrawSICN(SICN_RESOURCE_NUMBER, UP_ARROW,
+ (Drawable) &macMDEFDrawable,
+ menuPtr->textGC, menuRectPtr->left
+ + menuPtr->entries[1]->indicatorSpace,
+ menuRectPtr->top);
+ menuClipRect.top += SICN_HEIGHT;
+ }
+ } else if (scrollDirection == DOWN_SCROLL) {
+
+ scrollAmt = menuClipRect.top - hitPt.v;
+ if (scrollAmt > menuRectPtr->top - mtdPtr->virtualMenuTop) {
+ scrollAmt = menuRectPtr->top - mtdPtr->virtualMenuTop;
+ }
+
+ if (!hasBottomScroll && ((mtdPtr->virtualMenuBottom + scrollAmt)
+ > menuRectPtr->bottom)) {
+ SetRect(&updateRect, menuRectPtr->left,
+ mtdPtr->virtualMenuBottom - SICN_HEIGHT,
+ menuRectPtr->right, mtdPtr->virtualMenuBottom);
+ EraseRect(&updateRect);
+ DrawSICN(SICN_RESOURCE_NUMBER, DOWN_ARROW,
+ (Drawable) &macMDEFDrawable,
+ menuPtr->textGC, menuRectPtr->left
+ + menuPtr->entries[1]->indicatorSpace,
+ menuRectPtr->bottom - SICN_HEIGHT);
+ menuClipRect.bottom -= SICN_HEIGHT;
+ }
+ }
+
+ if (scrollDirection != DONT_SCROLL) {
+ Tk_Font menuFont;
+ RgnHandle updateRgn = NewRgn();
+
+ ScrollMenuImage(menu, menuRectPtr, 0, scrollAmt, NULL);
+ mtdPtr->virtualMenuTop += scrollAmt;
+ mtdPtr->virtualMenuBottom += scrollAmt;
+#if 0
+ GetRegionBounds(updateRgn,&updateRect);
+ DisposeRgn(updateRgn);
+ if (mtdPtr->virtualMenuTop == menuRectPtr->top) {
+ updateRect.top -= SICN_HEIGHT;
+ }
+ if (mtdPtr->virtualMenuBottom == menuRectPtr->bottom) {
+ updateRect.bottom += SICN_HEIGHT;
+ }
+ ClipRect(&updateRect);
+ EraseRect(&updateRect);
+ menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
+ Tk_GetFontMetrics(menuFont, &fontMetrics);
+ for (i = 0; i < menuPtr->numEntries; i++) {
+ mePtr = menuPtr->entries[i];
+ if (mtdPtr->virtualMenuTop + mePtr->y + mePtr->height
+ < updateRect.top) {
+ continue;
+ } else if (mtdPtr->virtualMenuTop + mePtr->y
+ > updateRect.bottom) {
+ continue;
+ }
+ if (mePtr->fontPtr == NULL) {
+ fmPtr = &fontMetrics;
+ tkfont = menuFont;
+ } else {
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin,
+ mePtr->fontPtr);
+ Tk_GetFontMetrics(tkfont, &entryMetrics);
+ fmPtr = &entryMetrics;
+ }
+ AppearanceEntryDrawWrapper(mePtr, menuRectPtr, mtdPtr,
+ (Drawable) &macMDEFDrawable, fmPtr, tkfont,
+ menuRectPtr->left + mePtr->x,
+ mtdPtr->virtualMenuTop + mePtr->y,
+ (mePtr->entryFlags & ENTRY_LAST_COLUMN) ?
+ menuPtr->totalWidth - mePtr->x : mePtr->width,
+ menuPtr->entries[i]->height);
+ }
+#endif
+ }
+
+ SetClip(utilRgn);
+ SetEmptyRgn(utilRgn);
+ RGBForeColor(&origForeColor);
+ RGBBackColor(&origBackColor);
+
+ /*
+ * If the menu is a tearoff, and the mouse is outside the menu,
+ * we need to draw the drag rectangle.
+ *
+ * In order for tearoffs to work properly, we need to set
+ * the active member of the containing menubar.
+ */
+
+ menuRefPtr = TkFindMenuReferences(menuPtr->interp,
+ Tk_PathName(menuPtr->tkwin));
+
+ if ((menuRefPtr != NULL) && (menuRefPtr->parentEntryPtr != NULL)) {
+ char *name;
+ for (parentEntryPtr = menuRefPtr->parentEntryPtr;
+ parentEntryPtr != NULL
+ ; parentEntryPtr = parentEntryPtr->nextCascadePtr) {
+ name = Tcl_GetStringFromObj(parentEntryPtr->namePtr,
+ NULL);
+ if (strcmp(name, Tk_PathName(menuPtr->tkwin)) != 0) {
+ break;
+ }
+ }
+ if (parentEntryPtr != NULL) {
+ TkActivateMenuEntry(parentEntryPtr->menuPtr,
+ parentEntryPtr->index);
+ }
+ }
+
+ if (menuPtr->tearoff) {
+ scratchRect = *menuRectPtr;
+ if (tearoffStruct.menuPtr == NULL) {
+ scratchRect.top -= 10;
+ scratchRect.bottom += 10;
+ scratchRect.left -= 10;
+ scratchRect.right += 10;
+ }
+
+ windowPart = FindWindow(hitPt, &whichWindow);
+ if ((windowPart != inMenuBar) && (newItem == -1)
+ && (hitPt.v != 0) && (hitPt.h != 0)
+ && (!PtInRect(hitPt, &scratchRect))
+ && (!PtInRect(hitPt, &tearoffStruct.excludeRect))) {
+ unsigned long dummy;
+ oldClipRgn = NewRgn();
+ GetClip(oldClipRgn);
+ GetForeColor(&origFgColor);
+ GetPenState(&origPenState);
+ GetForeColor(&fgColor);
+ GetBackColor(&bgColor);
+ GetGray(device, &bgColor, &fgColor);
+ RGBForeColor(&fgColor);
+ SetRect(&scratchRect, -32768, -32768, 32767, 32767);
+ ClipRect(&scratchRect);
+
+ dragRect = *menuRectPtr;
+ tearoffStruct.menuPtr = menuPtr;
+
+ PenMode(srcXor);
+ dragRect = *menuRectPtr;
+ OffsetRect(&dragRect, -dragRect.left, -dragRect.top);
+ OffsetRect(&dragRect, tearoffStruct.point.h,
+ tearoffStruct.point.v);
+ if ((dragRect.top != 0) && (dragRect.left != 0)) {
+ FrameRect(&dragRect);
+ Delay(1, &dummy);
+ FrameRect(&dragRect);
+ }
+ tearoffStruct.point = hitPt;
+
+ SetClip(oldClipRgn);
+ DisposeRgn(oldClipRgn);
+ RGBForeColor(&origFgColor);
+ SetPenState(&origPenState);
+ } else {
+ tearoffStruct.menuPtr = NULL;
+ tearoffStruct.point.h = tearoffStruct.point.v = 0;
+ }
+ } else {
+ tearoffStruct.menuPtr = NULL;
+ tearoffStruct.point.h = tearoffStruct.point.v = 0;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HandleMenuPopUpMsg --
+ *
+ * It handles the MenuDefProc's PopUp message. The menu is
+ * posted with the selected item at the point given in hitPt.
+ *
+ * Results:
+ * A menu is posted.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+HandleMenuPopUpMsg (MenuRef menu,
+ Rect *menuRectPtr,
+ Point hitPt,
+ SInt16 *whichItem,
+ TkMenu *menuPtr)
+{
+ int maxMenuHeight;
+ int oldItem;
+ Rect portRect;
+ BitMap screenBits;
+
+ /*
+ * Note that for some oddball reason, h and v are reversed in the
+ * point given to us by the MDEF.
+ */
+ GetQDGlobalsScreenBits(&screenBits);
+
+ oldItem = *whichItem;
+ if (oldItem >= menuPtr->numEntries) {
+ oldItem = -1;
+ }
+ portRect.top = 0;
+ portRect.bottom = 1280;
+ maxMenuHeight = screenBits.bounds.bottom
+ - screenBits.bounds.top
+ - GetMBarHeight() - SCREEN_MARGIN;
+ if (menuPtr->totalHeight > maxMenuHeight) {
+ menuRectPtr->top = GetMBarHeight();
+ } else {
+ int delta;
+ menuRectPtr->top = hitPt.h;
+ if (oldItem >= 0) {
+ menuRectPtr->top -= menuPtr->entries[oldItem]->y;
+ }
+
+ if (menuRectPtr->top < GetMBarHeight()) {
+ /* Displace downward if the menu would stick off the
+ * top of the screen.
+ */
+
+ menuRectPtr->top = GetMBarHeight() + SCREEN_MARGIN;
+ } else {
+ /*
+ * Or upward if the menu sticks off the
+ * bottom end...
+ */
+
+ delta = menuRectPtr->top + menuPtr->totalHeight
+ - maxMenuHeight;
+ if (delta > 0) {
+ menuRectPtr->top -= delta;
+ }
+ }
+ }
+ menuRectPtr->left = hitPt.v;
+ menuRectPtr->right = menuRectPtr->left + menuPtr->totalWidth;
+ menuRectPtr->bottom = menuRectPtr->top +
+ ((maxMenuHeight < menuPtr->totalHeight)
+ ? maxMenuHeight : menuPtr->totalHeight);
+ if (menuRectPtr->top == GetMBarHeight()) {
+ *whichItem = hitPt.h;
+ } else {
+ *whichItem = menuRectPtr->top;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HandleMenuCalcItemMsg --
+ *
+ * It handles the MenuDefProc's CalcItem message. It is supposed
+ * to calculate the Rect of the menu entry in whichItem in the
+ * menu, and put that in menuRectPtr. I assume this works, but I
+ * have never seen the MenuManager send this message.
+ *
+ * Results:
+ * The Menu Manager is informed of the bounding rect of a
+ * menu rect.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+HandleMenuCalcItemMsg(MenuRef menu,
+ Rect *menuRectPtr,
+ Point hitPt,
+ SInt16 *whichItem,
+ TkMenu *menuPtr)
+{
+ TkMenuEntry *mePtr;
+ MenuTrackingData mtd, *mtdPtr = &mtd;
+ int err, virtualTop;
+
+ err = GetMenuTrackingData(menu, mtdPtr);
+ if (err == noErr) {
+ virtualTop = mtdPtr->virtualMenuTop;
+ } else {
+ virtualTop = 0;
+ }
+
+ mePtr = menuPtr->entries[*whichItem];
+ menuRectPtr->left = mePtr->x;
+ menuRectPtr->top = mePtr->y - virtualTop;
+ if (mePtr->entryFlags & ENTRY_LAST_COLUMN) {
+ menuRectPtr->right = menuPtr->totalWidth;
+ } else {
+ menuRectPtr->right = mePtr->x + mePtr->width;
+ }
+ menuRectPtr->bottom = menuRectPtr->top
+ + mePtr->height;
+}
diff --git a/macosx/tkMacOSXMenu.r b/macosx/tkMacOSXMenu.r
new file mode 100644
index 0000000..3a71886
--- /dev/null
+++ b/macosx/tkMacOSXMenu.r
@@ -0,0 +1,47 @@
+/*
+ * tkMacOSXMenu.r --
+ *
+ * Resources needed by menus.
+ *
+ * This file also contains the icons 'SICN' used by the menu code
+ * in menu items.
+ *
+ * Copyright (c) 1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXMenu.r,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#include <Carbon.r>
+
+/*
+ * Icons used in menu items.
+ */
+
+resource 'SICN' (128, preload, locked) {
+ { /* array: 7 elements */
+ /* [1] */
+ $"0000 0000 8000 C000 E000 F000 F800 FC00"
+ $"F800 F000 E000 C000 80",
+ /* [2] */
+ $"0000 0000 0000 0800 1400 2200 4100 8080"
+ $"E380 2200 2200 2200 3E",
+ /* [3] */
+ $"0000 0000 0000 0000 0000 F8F0 C4F0 F270"
+ $"0900 0480 0270 0130 00F0",
+ /* [4] */
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 E4E0 CE60 1B00 3180",
+ /* [5] */
+ $"0000 0000 0000 0000 6300 9480 9480 7F00"
+ $"1400 7F00 9480 9480 63",
+ /* [6] */
+ $"0000 0000 0000 0000 0000 3FF8 1FF0 0FE0"
+ $"07C0 0380 01",
+ /* [7] */
+ $"0000 0000 0000 0000 0000 0100 0380 07C0"
+ $"0FE0 1FF0 3FF8"
+ }
+};
diff --git a/macosx/tkMacOSXMenubutton.c b/macosx/tkMacOSXMenubutton.c
new file mode 100644
index 0000000..52b239c
--- /dev/null
+++ b/macosx/tkMacOSXMenubutton.c
@@ -0,0 +1,861 @@
+/*
+ * tkMacOSXMenubutton.c --
+ *
+ * This file implements the Macintosh specific portion of the
+ * menubutton widget.
+ *
+ * Copyright (c) 1996 by Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXMenubutton.c,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#include <Carbon/Carbon.h>
+#include "tkMenu.h"
+#include "tkMenubutton.h"
+#include "tkMacOSXInt.h"
+#include "tkMacOSXDebug.h"
+
+#define kShadowOffset (3) /* amount to offset shadow from frame */
+#define kTriangleWidth (11) /* width of the triangle */
+#define kTriangleHeight (6) /* height of the triangle */
+#define kTriangleMargin (5) /* margin around triangle */
+
+#define TK_POPUP_OFFSET 32 /* size of popup marker */
+
+int TkMacOSXGetNewMenuID _ANSI_ARGS_((Tcl_Interp *interp, TkMenu *menuInstPtr, int cascade, short *menuIDPtr));
+void TkMacOSXFreeMenuID _ANSI_ARGS_((short menuID));
+
+typedef struct {
+ SInt16 initialValue;
+ SInt16 minValue;
+ SInt16 maxValue;
+ SInt16 procID;
+ int isBevel;
+} MenuButtonControlParams;
+
+typedef struct {
+ int len;
+ Str255 title;
+ ControlFontStyleRec style;
+} ControlTitleParams;
+
+/*
+ * Declaration of Mac specific button structure.
+ */
+
+typedef struct MacMenuButton {
+ TkMenuButton info; /* Generic button info. */
+ WindowRef windowRef;
+ ControlRef userPane;
+ ControlRef control;
+ MenuRef menuRef;
+ RGBColor userPaneBackground;
+ MenuButtonControlParams params;
+ ControlTitleParams titleParams;
+ ControlButtonContentInfo bevelButtonContent;
+ OpenCPicParams picParams;
+ int flags;
+} MacMenuButton;
+
+/*
+ * Forward declarations for procedures defined later in this file:
+ */
+
+static OSErr SetUserPaneDrawProc(ControlRef control,
+ ControlUserPaneDrawProcPtr upp);
+static OSErr SetUserPaneSetUpSpecialBackgroundProc(ControlRef control,
+ ControlUserPaneBackgroundProcPtr upp);
+static void UserPaneDraw(ControlRef control, ControlPartCode cpc);
+static void UserPaneBackgroundProc(ControlHandle,
+ ControlBackgroundPtr info);
+static int MenuButtonInitControl ( MacMenuButton *mbPtr, Rect *paneRect, Rect *cntrRect );
+
+static int UpdateControlColors _ANSI_ARGS_((MacMenuButton *mbPtr ));
+static void ComputeMenuButtonControlParams _ANSI_ARGS_((TkMenuButton * mbPtr, MenuButtonControlParams * paramsPtr));
+static void ComputeControlTitleParams _ANSI_ARGS_((TkMenuButton * mbPtr, ControlTitleParams * paramsPtr));
+static void CompareControlTitleParams(
+ ControlTitleParams * p1Ptr,
+ ControlTitleParams * p2Ptr,
+ int * titleChanged,
+ int * styleChanged
+);
+
+extern int TkFontGetFirstTextLayout(Tk_TextLayout layout, Tk_Font * font, char * dst);
+extern void TkMacOSXInitControlFontStyle(Tk_Font tkfont,ControlFontStylePtr fsPtr);
+
+extern int tkPictureIsOpen;
+
+/*
+ * The structure below defines menubutton class behavior by means of
+ * procedures that can be invoked from generic window code.
+ */
+
+Tk_ClassProcs tkpMenubuttonClass = {
+ sizeof(Tk_ClassProcs), /* size */
+ TkMenuButtonWorldChanged, /* worldChangedProc */
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpCreateMenuButton --
+ *
+ * Allocate a new TkMenuButton structure.
+ *
+ * Results:
+ * Returns a newly allocated TkMenuButton structure.
+ *
+ * Side effects:
+ * Registers an event handler for the widget.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkMenuButton *
+TkpCreateMenuButton(
+ Tk_Window tkwin)
+{
+ MacMenuButton *mbPtr = (MacMenuButton *) ckalloc(sizeof(MacMenuButton));
+ mbPtr->userPaneBackground.red = 0;
+ mbPtr->userPaneBackground.green = 0;
+ mbPtr->userPaneBackground.blue = ~0;
+ mbPtr->flags = 0;
+ mbPtr->userPane = NULL;
+ mbPtr->control = NULL;
+ mbPtr->picParams.version = -2;
+ mbPtr->picParams.hRes = 0x00480000;
+ mbPtr->picParams.vRes = 0x00480000;
+ mbPtr->picParams.srcRect.top = 0;
+ mbPtr->picParams.srcRect.left = 0;
+ mbPtr->picParams.reserved1 = 0;
+ mbPtr->picParams.reserved2 = 0;
+ mbPtr->bevelButtonContent.contentType = kControlContentPictHandle;
+ mbPtr->menuRef = NULL;
+
+ bzero(&mbPtr->params, sizeof(mbPtr->params));
+ bzero(&mbPtr->titleParams,sizeof(mbPtr->titleParams));
+ return (TkMenuButton *) mbPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDisplayMenuButton --
+ *
+ * This procedure is invoked to display a menubutton widget.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Commands are output to X to display the menubutton in its
+ * current mode.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpDisplayMenuButton(
+ ClientData clientData) /* Information about widget. */
+{
+ TkMenuButton *butPtr = (TkMenuButton *) clientData;
+ Tk_Window tkwin = butPtr->tkwin;
+ TkWindow * winPtr;
+ Pixmap pixmap;
+ MacMenuButton * mbPtr = (MacMenuButton *) butPtr;
+ GWorldPtr dstPort;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ int hasImageOrBitmap = 0;
+ int width, height;
+ int err;
+ ControlButtonGraphicAlignment theAlignment;
+
+ Rect paneRect, cntrRect;
+
+ butPtr->flags &= ~REDRAW_PENDING;
+ if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
+ return;
+ }
+ pixmap = ( Pixmap )Tk_WindowId(tkwin);
+ GetGWorld(&saveWorld, &saveDevice);
+ dstPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin));
+ SetGWorld(dstPort, NULL);
+ TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin));
+
+ winPtr=(TkWindow *)butPtr->tkwin;
+ paneRect.left=winPtr->privatePtr->xOff;
+ paneRect.top=winPtr->privatePtr->yOff;
+ paneRect.right=paneRect.left+Tk_Width(butPtr->tkwin)-1;
+ paneRect.bottom=paneRect.top+Tk_Height(butPtr->tkwin)-1;
+
+ cntrRect=paneRect;
+
+ cntrRect.left+=butPtr->inset;
+ cntrRect.top+=butPtr->inset;
+ cntrRect.right-=butPtr->inset;
+ cntrRect.bottom-=butPtr->inset;
+
+ if (mbPtr->userPane) {
+ MenuButtonControlParams params;
+ bzero(&params, sizeof(params));
+ ComputeMenuButtonControlParams(butPtr, &params );
+ if (bcmp(&params,&mbPtr->params,sizeof(params))) {
+ if (mbPtr->userPane) {
+ DisposeControl(mbPtr->userPane);
+ mbPtr->userPane = NULL;
+ mbPtr->control = NULL;
+ }
+ }
+ }
+ if (!mbPtr->userPane) {
+ if (MenuButtonInitControl(mbPtr,&paneRect,&cntrRect ) ) {
+ fprintf(stderr,"Init Control failed\n" );
+ return;
+ }
+ }
+ SetControlBounds(mbPtr->userPane,&paneRect);
+ SetControlBounds(mbPtr->control,&cntrRect);
+
+ /*
+ * We need to cache the title and its style
+ */
+ if (!(mbPtr->flags&2)) {
+ ControlTitleParams titleParams;
+ int titleChanged;
+ int styleChanged;
+ ComputeControlTitleParams(butPtr,&titleParams);
+ CompareControlTitleParams(&titleParams,&mbPtr->titleParams,
+ &titleChanged,&styleChanged);
+ if (titleChanged) {
+ CFStringRef cf;
+ cf = CFStringCreateWithCString(NULL,
+ titleParams.title, kCFStringEncodingUTF8);
+ if (hasImageOrBitmap) {
+ SetControlTitleWithCFString(mbPtr->control, cf);
+ } else {
+ SetMenuItemTextWithCFString(mbPtr->menuRef, 1, cf);
+ }
+ CFRelease(cf);
+ bcopy(titleParams.title,mbPtr->titleParams.title,titleParams.len+1);
+ mbPtr->titleParams.len = titleParams.len;
+ }
+ if ((titleChanged||styleChanged) && titleParams .len) {
+ if (hasImageOrBitmap) {
+ if ((err=SetControlFontStyle(mbPtr->control,&titleParams.style))!=noErr) {
+ fprintf(stderr,"SetControlFontStyle failed %d\n", err);
+ return;
+ }
+ }
+ bcopy(&titleParams.style,&mbPtr->titleParams.style,sizeof(titleParams.style));
+ }
+ }
+ if (butPtr->image != None) {
+ Tk_SizeOfImage(butPtr->image, &width, &height);
+ hasImageOrBitmap = 1;
+ } else if (butPtr->bitmap != None) {
+ Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
+ hasImageOrBitmap = 1;
+ }
+ if (hasImageOrBitmap) {
+ mbPtr->picParams.srcRect.right = width;
+ mbPtr->picParams.srcRect.bottom = height;
+ /* Set the flag to circumvent clipping and bounds problems with OS 10.0.4 */
+ tkPictureIsOpen = 1;
+ if (!(mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams)) ) {
+ fprintf(stderr,"OpenCPicture failed\n");
+ }
+ /*
+ * TO DO - There is one case where XCopyPlane calls CopyDeepMask,
+ * which does not get recorded in the picture. So the bitmap code
+ * will fail in that case.
+ */
+ if (butPtr->image != NULL) {
+ Tk_RedrawImage(butPtr->image, 0, 0, width,
+ height, pixmap, 0, 0);
+ } else {
+ XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, NULL, 0, 0,
+ (unsigned int) width, (unsigned int) height, 0, 0, 1);
+ }
+ ClosePicture();
+
+ tkPictureIsOpen = 0;
+ if ( (err=SetControlData(mbPtr->control, kControlButtonPart,
+ kControlBevelButtonContentTag,
+ sizeof(ControlButtonContentInfo),
+ (char *) &mbPtr->bevelButtonContent)) != noErr ) {
+ fprintf(stderr,"SetControlData BevelButtonContent failed, %d\n", err );
+ }
+ switch (butPtr->anchor) {
+ case TK_ANCHOR_N:
+ theAlignment = kControlBevelButtonAlignTop;
+ break;
+ case TK_ANCHOR_NE:
+ theAlignment = kControlBevelButtonAlignTopRight;
+ break;
+ case TK_ANCHOR_E:
+ theAlignment = kControlBevelButtonAlignRight;
+ break;
+ case TK_ANCHOR_SE:
+ theAlignment = kControlBevelButtonAlignBottomRight;
+ break;
+ case TK_ANCHOR_S:
+ theAlignment = kControlBevelButtonAlignBottom;
+ break;
+ case TK_ANCHOR_SW:
+ theAlignment = kControlBevelButtonAlignBottomLeft;
+ break;
+ case TK_ANCHOR_W:
+ theAlignment = kControlBevelButtonAlignLeft;
+ break;
+ case TK_ANCHOR_NW:
+ theAlignment = kControlBevelButtonAlignTopLeft;
+ break;
+ case TK_ANCHOR_CENTER:
+ theAlignment = kControlBevelButtonAlignCenter;
+ break;
+ }
+
+ if ((err=SetControlData(mbPtr->control, kControlButtonPart,
+ kControlBevelButtonGraphicAlignTag,
+ sizeof(ControlButtonGraphicAlignment),
+ (char *) &theAlignment)) != noErr ) {
+ fprintf(stderr,"SetControlData BevelButtonGraphicAlign failed, %d\n", err );
+ }
+ }
+ if (butPtr->flags & GOT_FOCUS) {
+ HiliteControl(mbPtr->control,kControlButtonPart);
+ } else {
+ HiliteControl(mbPtr->control,kControlNoPart);
+ }
+ UpdateControlColors(mbPtr);
+ if (mbPtr->flags&2) {
+ ShowControl(mbPtr->control);
+ ShowControl(mbPtr->userPane);
+ mbPtr->flags ^= 2;
+ } else {
+ Draw1Control(mbPtr->userPane);
+ SetControlVisibility(mbPtr->control, true, true);
+ }
+ if (hasImageOrBitmap) {
+ KillPicture(mbPtr->bevelButtonContent.u.picture);
+ }
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDestroyMenuButton --
+ *
+ * Free data structures associated with the menubutton control.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Restores the default control state.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpDestroyMenuButton(
+ TkMenuButton *mbPtr)
+{
+ MacMenuButton * macMbPtr = (MacMenuButton *)mbPtr;
+ if (macMbPtr->userPane) {
+ DisposeControl(macMbPtr->userPane);
+ macMbPtr->userPane = NULL;
+ }
+ if (macMbPtr->menuRef) {
+ short menuID;
+ menuID = GetMenuID(macMbPtr->menuRef);
+ TkMacOSXFreeMenuID(menuID);
+ DisposeMenu(macMbPtr->menuRef);
+ macMbPtr->menuRef = NULL;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpComputeMenuButtonGeometry --
+ *
+ * After changes in a menu button's text or bitmap, this procedure
+ * recomputes the menu button's geometry and passes this information
+ * along to the geometry manager for the window.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The menu button's window may change size.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpComputeMenuButtonGeometry(mbPtr)
+ register TkMenuButton *mbPtr; /* Widget record for menu button. */
+{
+ int width, height, mm, pixels;
+ int hasImageOrBitmap = 0;
+
+ mbPtr->inset = mbPtr->highlightWidth + mbPtr->borderWidth;
+ if (mbPtr->image != None) {
+ Tk_SizeOfImage(mbPtr->image, &width, &height);
+ if (mbPtr->width > 0) {
+ width = mbPtr->width;
+ }
+ if (mbPtr->height > 0) {
+ height = mbPtr->height;
+ }
+ hasImageOrBitmap = 1;
+ } else if (mbPtr->bitmap != None) {
+ Tk_SizeOfBitmap(mbPtr->display, mbPtr->bitmap, &width, &height);
+ if (mbPtr->width > 0) {
+ width = mbPtr->width;
+ }
+ if (mbPtr->height > 0) {
+ height = mbPtr->height;
+ }
+ hasImageOrBitmap = 1;
+ } else {
+ hasImageOrBitmap = 0;
+ Tk_FreeTextLayout(mbPtr->textLayout);
+ mbPtr->textLayout = Tk_ComputeTextLayout(mbPtr->tkfont, mbPtr->text,
+ -1, mbPtr->wrapLength, mbPtr->justify, 0, &mbPtr->textWidth,
+ &mbPtr->textHeight);
+ width = mbPtr->textWidth;
+ height = mbPtr->textHeight;
+ if (mbPtr->width > 0) {
+ width = mbPtr->width * Tk_TextWidth(mbPtr->tkfont, "0", 1);
+ }
+ if (mbPtr->height > 0) {
+ Tk_FontMetrics fm;
+
+ Tk_GetFontMetrics(mbPtr->tkfont, &fm);
+ height = mbPtr->height * fm.linespace;
+ }
+ width += 2*mbPtr->padX;
+ height += 2*mbPtr->padY;
+ }
+
+ if (mbPtr->indicatorOn) {
+ mm = WidthMMOfScreen(Tk_Screen(mbPtr->tkwin));
+ pixels = WidthOfScreen(Tk_Screen(mbPtr->tkwin));
+ mbPtr->indicatorHeight= kTriangleHeight;
+ mbPtr->indicatorWidth = kTriangleWidth + kTriangleMargin;
+ width += mbPtr->indicatorWidth;
+ } else {
+ mbPtr->indicatorHeight = 0;
+ mbPtr->indicatorWidth = 0;
+ }
+ if (!hasImageOrBitmap) {
+ width += TK_POPUP_OFFSET;
+ }
+
+ Tk_GeometryRequest(mbPtr->tkwin, (int) (width + 2*mbPtr->inset),
+ (int) (height + 2*mbPtr->inset));
+ Tk_SetInternalBorder(mbPtr->tkwin, mbPtr->inset);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ComputeMenuButtonControlParams --
+ *
+ * This procedure computes the various parameters used
+ * when creating a Carbon control (NewControl)
+ * These are determined by the various tk menu button parameters
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Sets the control initialisation parameters
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ComputeMenuButtonControlParams(TkMenuButton * mbPtr,
+ MenuButtonControlParams * paramsPtr )
+{
+ int fakeMenuID = 256;
+
+ /*
+ * Determine ProcID based on button type and dimensions
+ *
+ * We need to set minValue to some non-zero value,
+ * Otherwise, the markers do not show up
+ */
+
+ paramsPtr->minValue = kControlBehaviorMultiValueMenu;
+ paramsPtr->maxValue = 0;
+ if (mbPtr->image || mbPtr->bitmap) {
+ paramsPtr->isBevel = 1;
+ if (mbPtr->borderWidth <= 2) {
+ paramsPtr->procID = kControlBevelButtonSmallBevelProc;
+ } else if (mbPtr->borderWidth == 3) {
+ paramsPtr->procID = kControlBevelButtonNormalBevelProc;
+ } else {
+ paramsPtr->procID = kControlBevelButtonLargeBevelProc;
+ }
+ if (mbPtr->indicatorOn) {
+ paramsPtr->initialValue = fakeMenuID;
+ } else {
+ paramsPtr->initialValue = 0;
+ }
+ } else {
+ paramsPtr->isBevel = 0;
+ paramsPtr->procID = kControlPopupButtonProc
+ + kControlPopupVariableWidthVariant;
+ paramsPtr->minValue = -12345;
+ paramsPtr->maxValue = -1;
+ paramsPtr->initialValue = 0;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * returns 0 if same, 1 otherwise
+ *----------------------------------------------------------------------
+ */
+static void
+CompareControlTitleParams(
+ ControlTitleParams * p1Ptr,
+ ControlTitleParams * p2Ptr,
+ int * titleChanged,
+ int * styleChanged
+)
+{
+ if (p1Ptr->len != p2Ptr->len) {
+ *titleChanged = 1;
+ } else {
+ if (bcmp(p1Ptr->title,p2Ptr->title,p1Ptr->len)) {
+ *titleChanged = 1;
+ } else {
+ *titleChanged = 0;
+ }
+ }
+ if (p1Ptr->len && p2Ptr->len) {
+ *styleChanged = bcmp(&p1Ptr->style, &p2Ptr->style, sizeof(p2Ptr->style));
+ } else {
+ *styleChanged = p1Ptr->len||p2Ptr->len;
+ }
+}
+
+static void
+ComputeControlTitleParams(TkMenuButton * butPtr, ControlTitleParams * paramsPtr )
+{
+ Tk_Font font;
+ paramsPtr->len =TkFontGetFirstTextLayout(butPtr->textLayout,&font, paramsPtr->title);
+ paramsPtr->title [paramsPtr->len] = 0;
+ if (paramsPtr->len) {
+ TkMacOSXInitControlFontStyle(font,&paramsPtr->style);
+ }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MenuButtonInitControl --
+ *
+ * This procedure initialises a Carbon control
+ *
+ * Results:
+ * 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
+ *
+ *----------------------------------------------------------------------
+ */
+int
+MenuButtonInitControl (
+ MacMenuButton *mbPtr, /* Mac button. */
+ Rect *paneRect,
+ Rect *cntrRect
+)
+{
+ OSErr status;
+ TkMenuButton * butPtr = ( TkMenuButton * )mbPtr;
+ ControlRef rootControl;
+ SInt16 procID;
+ Boolean initiallyVisible;
+ SInt16 initialValue;
+ SInt16 minValue;
+ SInt16 maxValue;
+ SInt32 controlReference;
+ int err;
+ short menuID;
+ int length;
+ Str255 itemText;
+
+ rootControl=TkMacOSXGetRootControl(Tk_WindowId(butPtr->tkwin));
+ mbPtr->windowRef=GetWindowFromPort(TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin)));
+ /*
+ * Set up the user pane
+ */
+ initiallyVisible = false;
+ 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 );
+ if (!mbPtr->userPane) {
+ fprintf(stderr,"Failed to create user pane control\n");
+ return 1;
+ }
+ if ((status=EmbedControl(mbPtr->userPane,rootControl))!=noErr) {
+ fprintf(stderr,"Failed to embed user pane control %d\n", status);
+ return 1;
+ }
+ SetUserPaneSetUpSpecialBackgroundProc(mbPtr->userPane,
+ UserPaneBackgroundProc);
+ SetUserPaneDrawProc(mbPtr->userPane,UserPaneDraw);
+ initiallyVisible = false;
+ ComputeMenuButtonControlParams(butPtr,&mbPtr->params);
+ /* Do this only if we are using bevel buttons */
+ ComputeControlTitleParams(butPtr,&mbPtr->titleParams);
+ mbPtr->control = NewControl(mbPtr->windowRef,
+ cntrRect, "\p", //mbPtr->titleParams.title,
+ initiallyVisible,
+ mbPtr->params.initialValue,
+ mbPtr->params.minValue,
+ mbPtr->params.maxValue,
+ mbPtr->params.procID,
+ controlReference );
+ if (!mbPtr->control) {
+ fprintf(stderr,"failed to create control of type %d : line %d\n",mbPtr->params.procID, __LINE__);
+ return 1;
+ }
+ if ((err=EmbedControl(mbPtr->control,mbPtr->userPane)) != noErr ) {
+ fprintf(stderr,"failed to embed control of type %d,%d\n",procID, err);
+ return 1;
+ }
+ if (mbPtr->params.isBevel) {
+ CFStringRef cf;
+ cf = CFStringCreateWithCString(NULL,
+ mbPtr->titleParams.title, kCFStringEncodingUTF8);
+ SetControlTitleWithCFString(mbPtr->control, cf);
+ CFRelease(cf);
+ if (mbPtr->titleParams.len) {
+ if ((err=SetControlFontStyle(mbPtr->control,&mbPtr->titleParams.style))!=noErr) {
+ fprintf(stderr,"SetControlFontStyle failed %d\n", err);
+ return 1;
+ }
+ }
+ } else {
+ CFStringRef cf;
+ err = TkMacOSXGetNewMenuID(mbPtr->info.interp, (TkMenu *)mbPtr, 0, &menuID);
+ if (err != TCL_OK) {
+ return err;
+ }
+ length = strlen(Tk_PathName(mbPtr->info.tkwin));
+ memmove(&itemText[1], Tk_PathName(mbPtr->info.tkwin),
+ (length > 230) ? 230 : length);
+ itemText[0] = (length > 230) ? 230 : length;
+ if (!(mbPtr->menuRef = NewMenu(menuID,itemText))) {
+ return 1;
+ }
+ cf = CFStringCreateWithCString(NULL,
+ mbPtr->titleParams.title, kCFStringEncodingUTF8);
+ AppendMenuItemText(mbPtr->menuRef, "\px");
+ if (cf != NULL) {
+ SetMenuItemTextWithCFString(mbPtr->menuRef, 1, cf);
+ CFRelease(cf);
+ }
+ err = SetControlData(mbPtr->control,
+ kControlNoPart,
+ kControlPopupButtonMenuRefTag,
+ sizeof(mbPtr->menuRef), &mbPtr->menuRef);
+ SetControlMinimum(mbPtr->control, 1);
+ SetControlMaximum(mbPtr->control, 1);
+ SetControlValue(mbPtr->control, 1);
+ }
+ mbPtr->flags |= 2;
+ return 0;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * SetUserPane
+ *
+ * Utility function to add a UserPaneDrawProc
+ * to a userPane control. From MoreControls code
+ * from Apple DTS.
+ *
+ * Results:
+ * MacOS system error.
+ *
+ * Side effects:
+ * The user pane gets a new UserPaneDrawProc.
+ *
+ *--------------------------------------------------------------
+ */
+OSErr SetUserPaneDrawProc (
+ ControlRef control,
+ ControlUserPaneDrawProcPtr upp)
+{
+ ControlUserPaneDrawUPP myControlUserPaneDrawUPP;
+ myControlUserPaneDrawUPP = NewControlUserPaneDrawUPP(upp);
+ return SetControlData (control,
+ kControlNoPart, kControlUserPaneDrawProcTag,
+ sizeof(myControlUserPaneDrawUPP),
+ (Ptr) &myControlUserPaneDrawUPP);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * SetUserPaneSetUpSpecialBackgroundProc --
+ *
+ * Utility function to add a UserPaneBackgroundProc
+ * to a userPane control
+ *
+ * Results:
+ * MacOS system error.
+ *
+ * Side effects:
+ * The user pane gets a new UserPaneBackgroundProc.
+ *
+ *--------------------------------------------------------------
+ */
+OSErr
+SetUserPaneSetUpSpecialBackgroundProc(
+ ControlRef control,
+ ControlUserPaneBackgroundProcPtr upp)
+{
+ ControlUserPaneBackgroundUPP myControlUserPaneBackgroundUPP;
+ myControlUserPaneBackgroundUPP = NewControlUserPaneBackgroundUPP(upp);
+ return SetControlData (control, kControlNoPart,
+ kControlUserPaneBackgroundProcTag,
+ sizeof(myControlUserPaneBackgroundUPP),
+ (Ptr) &myControlUserPaneBackgroundUPP);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * UserPaneDraw --
+ *
+ * This function draws the background of the user pane that will
+ * lie under checkboxes and radiobuttons.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The user pane gets updated to the current color.
+ *
+ *--------------------------------------------------------------
+ */
+void
+UserPaneDraw(
+ ControlRef control,
+ ControlPartCode cpc)
+{
+ Rect contrlRect;
+ MacMenuButton * mbPtr;
+ mbPtr = ( MacMenuButton *)GetControlReference(control);
+ GetControlBounds(control,&contrlRect);
+ RGBBackColor (&mbPtr->userPaneBackground);
+ EraseRect (&contrlRect);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * UserPaneBackgroundProc --
+ *
+ * This function sets up the background of the user pane that will
+ * lie under checkboxes and radiobuttons.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The user pane background gets set to the current color.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+UserPaneBackgroundProc(
+ ControlHandle control,
+ ControlBackgroundPtr info)
+{
+ MacMenuButton * mbPtr;
+ mbPtr = (MacMenuButton *)GetControlReference(control);
+ if (info->colorDevice) {
+ RGBBackColor (&mbPtr->userPaneBackground);
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * UpdateControlColors --
+ *
+ * This function will review the colors used to display
+ * a Macintosh button. If any non-standard colors are
+ * used we create a custom palette for the button, populate
+ * with the colors for the button and install the palette.
+ *
+ * Under Appearance, we just set the pointer that will be
+ * used by the UserPaneDrawProc.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The Macintosh control may get a custom palette installed.
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+UpdateControlColors(MacMenuButton * mbPtr)
+{
+ XColor *xcolor;
+ TkMenuButton * butPtr = ( TkMenuButton * )mbPtr;
+
+ /*
+ * Under Appearance we cannot change the background of the
+ * button itself. However, the color we are setting is the color
+ * of the containing userPane. This will be the color that peeks
+ * 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.
+ */
+
+ xcolor = Tk_3DBorderColor(butPtr->normalBorder);
+ TkSetMacColor(xcolor->pixel, &mbPtr->userPaneBackground);
+
+ return false;
+}
diff --git a/macosx/tkMacOSXMenus.c b/macosx/tkMacOSXMenus.c
new file mode 100644
index 0000000..f3aa259
--- /dev/null
+++ b/macosx/tkMacOSXMenus.c
@@ -0,0 +1,325 @@
+/*
+ * tkMacOSXMenus.c --
+ *
+ * These calls set up and manage the menubar for the
+ * Macintosh version of Tk.
+ *
+ * Copyright (c) 1995-1996 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXMenus.c,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#include "tk.h"
+#include "tkInt.h"
+#include "tkMacOSXInt.h"
+
+/*
+ * The define Status defined by Xlib.h conflicts with the function Status
+ * defined by Devices.h. We undefine it here to compile.
+ */
+#undef Status
+#include <Carbon/Carbon.h>
+
+#define kAppleMenu 256
+#define kAppleAboutItem 1
+#define kFileMenu 2
+#define kEditMenu 3
+
+#define kSourceItem 1
+#define kCloseItem 2
+#define kQuitItem 4
+
+#define EDIT_CUT 1
+#define EDIT_COPY 2
+#define EDIT_PASTE 3
+#define EDIT_CLEAR 4
+
+MenuRef tkAppleMenu;
+MenuRef tkFileMenu;
+MenuRef tkEditMenu;
+
+static Tcl_Interp * gInterp; /* Interpreter for this application. */
+
+static void GenerateEditEvent _ANSI_ARGS_((int flag));
+static void SourceDialog _ANSI_ARGS_((void));
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXHandleMenuSelect --
+ *
+ * Handles events that occur in the Menu bar.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXHandleMenuSelect(
+ long mResult,
+ int optionKeyPressed)
+{
+ short theItem = LoWord(mResult);
+ short theMenu = HiWord(mResult);
+ Tk_Window tkwin;
+ Window window;
+ TkDisplay *dispPtr;
+
+ if (mResult == 0) {
+ TkMacOSXHandleTearoffMenu();
+ TkMacOSXClearMenubarActive();
+ return;
+ }
+
+ switch (theMenu) {
+ case kAppleMenu:
+ switch (theItem) {
+ case kAppleAboutItem:
+ {
+ Tcl_CmdInfo dummy;
+ if (optionKeyPressed || gInterp == NULL ||
+ Tcl_GetCommandInfo(gInterp,
+ "tkAboutDialog", &dummy) == 0) {
+ TkAboutDlg();
+ } else {
+ Tcl_Eval(gInterp, "tkAboutDialog");
+ }
+ break;
+ }
+ }
+ break;
+ case kFileMenu:
+ switch (theItem) {
+ case kSourceItem:
+ /* TODO: source script */
+ SourceDialog();
+ break;
+ case kCloseItem:
+ /* Send close event */
+ window = TkMacOSXGetXWindow(FrontNonFloatingWindow());
+ dispPtr = TkGetDisplayList();
+ tkwin = Tk_IdToWindow(dispPtr->display, window);
+ TkGenWMDestroyEvent(tkwin);
+ break;
+ case kQuitItem:
+ /* Exit */
+ if (optionKeyPressed || gInterp == NULL) {
+ Tcl_Exit(0);
+ } else {
+ Tcl_Eval(gInterp, "exit");
+ }
+ break;
+ }
+ break;
+ case kEditMenu:
+ /*
+ * This implementation just send keysyms
+ * the Tk thinks are associated with function keys that
+ * do Cut, Copy & Paste on a Sun keyboard.
+ */
+ GenerateEditEvent(theItem);
+ break;
+ default:
+ TkMacOSXDispatchMenuEvent(theMenu, theItem);
+ TkMacOSXClearMenubarActive();
+ break;
+ }
+ /*
+ * Finally we unhighlight the menu.
+ */
+ HiliteMenu(0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXInitMenus --
+ *
+ * This procedure initializes the Macintosh menu bar.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXInitMenus(
+ Tcl_Interp *interp)
+{
+ gInterp = interp;
+
+ /*
+ * At this point, InitMenus() should have already been called.
+ */
+
+ if (TkMacOSXUseMenuID(256) != TCL_OK) {
+ panic("Menu ID 256 is already in use!");
+ }
+ tkAppleMenu = NewMenu(256, "\p\024");
+ if (tkAppleMenu == NULL) {
+ panic("memory - menus");
+ }
+ InsertMenu(tkAppleMenu, 0);
+ AppendMenu(tkAppleMenu, "\pAbout Tcl & TkÉ");
+ AppendMenu(tkAppleMenu, "\p(-");
+ /* Not necessary in Carbon:
+ AppendResMenu(tkAppleMenu, 'DRVR');
+ */
+
+ if (TkMacOSXUseMenuID(kFileMenu) != TCL_OK) {
+ panic("Menu ID %d is already in use!", kFileMenu);
+ }
+ tkFileMenu = NewMenu(kFileMenu, "\pFile");
+ if (tkFileMenu == NULL) {
+ panic("memory - menus");
+ }
+ InsertMenu(tkFileMenu, 0);
+ AppendMenu(tkFileMenu, "\pSourceÉ");
+ AppendMenu(tkFileMenu, "\pClose/W");
+ AppendMenu(tkFileMenu, "\p(-");
+ AppendMenu(tkFileMenu, "\pQuit/Q");
+
+ if (TkMacOSXUseMenuID(kEditMenu) != TCL_OK) {
+ panic("Menu ID %d is already in use!", kEditMenu);
+ }
+ tkEditMenu = NewMenu(kEditMenu, "\pEdit");
+ if (tkEditMenu == NULL) {
+ panic("memory - menus");
+ }
+ InsertMenu(tkEditMenu, 0);
+ AppendMenu(tkEditMenu, "\pCut/X");
+ AppendMenu(tkEditMenu, "\pCopy/C");
+ AppendMenu(tkEditMenu, "\pPaste/V");
+ AppendMenu(tkEditMenu, "\pClear");
+ if (TkMacOSXUseMenuID(kHMHelpMenuID) != TCL_OK) {
+ panic("Help menu ID %s is already in use!", kHMHelpMenuID);
+ }
+
+ DrawMenuBar();
+ TkMacOSXSetHelpMenuItemCount();
+ return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GenerateEditEvent --
+ *
+ * Takes an edit menu item and posts the corasponding a virtual
+ * event to Tk's event queue.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May place events of queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GenerateEditEvent(
+ int flag)
+{
+ XVirtualEvent event;
+ Point where;
+ Tk_Window tkwin;
+ Window window;
+ TkDisplay *dispPtr;
+
+ window = TkMacOSXGetXWindow(FrontNonFloatingWindow());
+ dispPtr = TkGetDisplayList();
+ tkwin = Tk_IdToWindow(dispPtr->display, window);
+ tkwin = (Tk_Window) ((TkWindow *) tkwin)->dispPtr->focusPtr;
+ if (tkwin == NULL) {
+ return;
+ }
+
+ event.type = VirtualEvent;
+ event.serial = Tk_Display(tkwin)->request;
+ event.send_event = false;
+ event.display = Tk_Display(tkwin);
+ event.event = Tk_WindowId(tkwin);
+ event.root = XRootWindow(Tk_Display(tkwin), 0);
+ event.subwindow = None;
+ event.time = TkpGetMS();
+
+ GetMouse(&where);
+ tkwin = Tk_TopCoordsToWindow(tkwin, where.h, where.v,
+ &event.x, &event.y);
+ LocalToGlobal(&where);
+ event.x_root = where.h;
+ event.y_root = where.v;
+ event.state = TkMacOSXButtonKeyState();
+ event.same_screen = true;
+
+ switch (flag) {
+ case EDIT_CUT:
+ event.name = Tk_GetUid("Cut");
+ break;
+ case EDIT_COPY:
+ event.name = Tk_GetUid("Copy");
+ break;
+ case EDIT_PASTE:
+ event.name = Tk_GetUid("Paste");
+ break;
+ case EDIT_CLEAR:
+ event.name = Tk_GetUid("Clear");
+ break;
+ }
+ Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SourceDialog --
+ *
+ * Presents a dialog to the user for selecting a Tcl file. The
+ * selected file will be sourced into the main interpreter.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+SourceDialog()
+{
+ int result;
+ CONST char *path;
+ CONST char *openCmd = "tk_getOpenFile -filetypes {\
+ {{TCL Scripts} {.tcl} TEXT} {{Text Files} {} TEXT}}";
+
+ if (gInterp == NULL) {
+ return;
+ }
+ if (Tcl_Eval(gInterp, openCmd) != TCL_OK) {
+ return;
+ }
+ path = Tcl_GetStringResult(gInterp);
+ if (strlen(path) == 0) {
+ return;
+ }
+ result = Tcl_EvalFile(gInterp, path);
+ if (result == TCL_ERROR) {
+ Tcl_BackgroundError(gInterp);
+ }
+}
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
new file mode 100644
index 0000000..769472c
--- /dev/null
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -0,0 +1,704 @@
+/*
+ * tkMacOSXMouseEvent.c --
+ *
+ * This file implements functions that decode & handle mouse events
+ * on MacOS X.
+ *
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.
+ */
+
+#include "tkInt.h"
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include "tkMacOSXEvent.h"
+#include "tkMacOSXInt.h"
+#include "tkPort.h"
+#include "tkMacOSXDebug.h"
+
+typedef struct {
+ WindowRef whichWin;
+ WindowRef activeNonFloating;
+ WindowPartCode windowPart;
+ Point global;
+ Point local;
+ unsigned int state;
+ long delta;
+} MouseEventData;
+
+/*
+ * Declarations of static variables used in this file.
+ */
+
+static int gEatButtonUp = 0; /* 1 if we need to eat the next * up event */
+
+/*
+ * Declarations of functions used only in this file.
+ */
+
+static void BringWindowForward _ANSI_ARGS_((WindowRef wRef));
+static int GeneratePollingEvents(MouseEventData * medPtr);
+static int GenerateMouseWheelEvent(MouseEventData * medPtr);
+
+extern int TkMacOSXGetEatButtonUp();
+extern void TkMacOSXSetEatButtonUp(int f);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXProcessMouseEvent --
+ *
+ * This routine processes the event in eventPtr, and
+ * generates the appropriate Tk events from it.
+ *
+ * Results:
+ * True if event(s) are generated - false otherwise.
+ *
+ * Side effects:
+ * Additional events may be place on the Tk event queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr)
+{
+ WindowRef frontWindow;
+ Tk_Window tkwin;
+ Point where, where2;
+ int xOffset, yOffset;
+ TkDisplay * dispPtr;
+ Window window;
+ int status,err;
+ MouseEventData mouseEventData, * medPtr = &mouseEventData;
+ KeyMap keyMap;
+
+ switch (eventPtr->eKind) {
+ case kEventMouseUp:
+ case kEventMouseDown:
+ case kEventMouseMoved:
+ case kEventMouseDragged:
+ case kEventMouseWheelMoved:
+ break;
+ default:
+ statusPtr->handledByTk = 1;
+ return 0;
+ break;
+ }
+ statusPtr->handledByTk = 1;
+ status = GetEventParameter(eventPtr->eventRef,
+ kEventParamMouseLocation,
+ typeQDPoint, NULL,
+ sizeof(where), NULL,
+ &where);
+ if (status != noErr) {
+ fprintf (stderr, "Failed to retrieve mouse location,%d\n", status);
+ return 0;
+ }
+ medPtr->state = 0;
+ GetKeys(keyMap);
+ if (keyMap[1] & 2) {
+ medPtr->state |= LockMask;
+ }
+ if (keyMap[1] & 1) {
+ medPtr->state |= ShiftMask;
+ }
+ if (keyMap[1] & 8) {
+ medPtr->state |= ControlMask;
+ }
+ if (keyMap[1] & 32768) {
+ medPtr->state |= Mod1Mask; /* command key */
+ }
+ if (keyMap[1] & 4) {
+ medPtr->state |= Mod2Mask; /* option key */
+ }
+ if (eventPtr->eKind == kEventMouseDown
+ || eventPtr->eKind== kEventMouseDragged ) {
+ EventMouseButton mouseButton;
+ if ((status=GetEventParameter(eventPtr->eventRef,
+ kEventParamMouseButton,
+ typeMouseButton, NULL,
+ sizeof(mouseButton), NULL,&mouseButton)) != noErr ) {
+ fprintf (stderr, "Failed to retrieve mouse button, %d\n", status);
+ statusPtr->err = 1;
+ return 0;
+ }
+ medPtr->state |= 1 << ((mouseButton-1)+8);
+ }
+
+ medPtr->windowPart= FindWindow(where, &medPtr->whichWin);
+ window = TkMacOSXGetXWindow(medPtr->whichWin);
+ if (medPtr->whichWin != NULL && window == None) {
+ statusPtr->handledByTk = 0;
+ return 0;
+ }
+
+ frontWindow = FrontWindow();
+ medPtr->activeNonFloating = ActiveNonFloatingWindow();
+
+ /*
+ * The window manager only needs to know about mouse down events
+ * and sometimes we need to "eat" the mouse up. Otherwise, we
+ * just pass the event to Tk.
+
+ */
+ if (eventPtr->eKind == kEventMouseUp) {
+ if (TkMacOSXGetEatButtonUp()) {
+ TkMacOSXSetEatButtonUp(false);
+ return false;
+ }
+ return TkGenerateButtonEvent(where.h, where.v,
+ window, medPtr->state);
+ }
+ if (eventPtr->eKind == kEventMouseWheelMoved) {
+ if ((status=GetEventParameter(eventPtr->eventRef,
+ kEventParamMouseWheelDelta,
+ typeLongInteger, NULL,
+ sizeof(medPtr->delta), NULL,&medPtr->delta)) != noErr ) {
+ fprintf (stderr,
+ "Failed to retrieve mouse wheel delta, %d\n", status);
+ statusPtr->err = 1;
+ return false;
+ }
+ }
+
+ dispPtr = TkGetDisplayList();
+ tkwin = Tk_IdToWindow(dispPtr->display, window);
+
+ if (eventPtr->eKind != kEventMouseDown ) {
+ /*
+ * MouseMoved, MouseDragged or kEventMouseWheelMoved
+ */
+
+ medPtr->global = where;
+ medPtr->local = where;
+ SetPortWindowPort(frontWindow);
+ GlobalToLocal(&medPtr->local);
+ if (eventPtr->eKind == kEventMouseWheelMoved ) {
+ return GenerateMouseWheelEvent(medPtr);
+ } else {
+ return GeneratePollingEvents(medPtr);
+ }
+ }
+
+ if (medPtr->whichWin && eventPtr->eKind==kEventMouseDown) {
+ ProcessSerialNumber frontPsn, ourPsn;
+ Boolean flag;
+ if ((err=GetFrontProcess(&frontPsn))!=noErr) {
+ fprintf(stderr, "GetFrontProcess failed, %d\n", err);
+ statusPtr->err = 1;
+ return 1;
+ }
+
+ GetCurrentProcess(&ourPsn);
+ if ((err=SameProcess(&frontPsn, &ourPsn, &flag))!=noErr) {
+ fprintf(stderr, "SameProcess failed, %d\n", err);
+ statusPtr->err = 1;
+ return 1;
+ } else {
+ if (!flag) {
+ if ((err=SetFrontProcess(&ourPsn)) != noErr) {
+ fprintf(stderr,"SetFrontProcess failed,%d\n", err);
+ statusPtr->err = 1;
+ return 1;
+ }
+ }
+ }
+
+ }
+
+ if (medPtr->whichWin) {
+ /*
+ * We got a mouse down in a window
+ * See if this is the activate click
+ * This click moves the window forward. We don't want
+ * the corresponding mouse-up to be reported to the application
+ * or else it will mess up some Tk scripts.
+ */
+
+ if (!(TkpIsWindowFloating(medPtr->whichWin))
+ && (medPtr->whichWin != medPtr->activeNonFloating)) {
+ Tk_Window grabWin = TkMacOSXGetCapture();
+ if ((grabWin != NULL) && (grabWin != tkwin)) {
+ TkWindow * tkw, * grb;
+ tkw = (TkWindow *)tkwin;
+ grb = (TkWindow *)grabWin;
+ SysBeep(1);
+ return false;
+ }
+ TkMacOSXSetEatButtonUp(true);
+ BringWindowForward(medPtr->whichWin);
+ return false;
+ }
+ }
+
+ switch (medPtr->windowPart) {
+ case inDrag:
+ DragWindow(medPtr->whichWin, where, NULL);
+ where2.h = where2.v = 0;
+ LocalToGlobal(&where2);
+ if (EqualPt(where, where2)) {
+ return false;
+ }
+ TkMacOSXWindowOffset(medPtr->whichWin, &xOffset, &yOffset);
+ where2.h -= xOffset;
+ where2.v -= yOffset;
+ TkGenWMConfigureEvent(tkwin, where2.h, where2.v,
+ -1, -1, TK_LOCATION_CHANGED);
+ return true;
+ break;
+ case inContent:
+ return TkGenerateButtonEvent(where.h, where.v,
+ window, medPtr->state);
+ break;
+ case inGrow:
+ /*
+ * Generally the content region is the domain of Tk
+ * sub-windows. However, one exception is the grow
+ * region. A button down in this area will be handled
+ * by the window manager. Note: this means that Tk
+ * may not get button down events in this area!
+ */
+ if (TkMacOSXGrowToplevel(medPtr->whichWin, where) == true) {
+ return true;
+ } else {
+ return TkGenerateButtonEvent(where.h,
+ where.v, window, medPtr->state);
+ }
+ break;
+ case inGoAway:
+ if (TrackGoAway(medPtr->whichWin,where)) {
+ if (tkwin == NULL) {
+ return false;
+ }
+ TkGenWMDestroyEvent(tkwin);
+ return true;
+ }
+ return false;
+ break;
+ case inMenuBar:
+ {
+ int oldMode;
+ KeyMap theKeys;
+
+ GetKeys(theKeys);
+ oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
+ TkMacOSXClearMenubarActive();
+
+ /*
+ * Handle -postcommand
+ */
+
+ TkMacOSXPreprocessMenu();
+ TkMacOSXHandleMenuSelect(MenuSelect(where),
+ theKeys[1] & 4);
+ Tcl_SetServiceMode(oldMode);
+ return true; /* TODO: may not be on event on queue. */
+ }
+ break;
+ case inZoomIn:
+ case inZoomOut:
+ if (TkMacOSXZoomToplevel(medPtr->whichWin, where,
+ medPtr->windowPart) == true) {
+ return true;
+ } else {
+ return false;
+ }
+ break;
+ case inCollapseBox:
+ if ((err = CollapseWindow(medPtr->whichWin,
+ !IsWindowCollapsed(medPtr->whichWin)))!=noErr) {
+ fprintf(stderr,"CollapseWindow failed,%d\n", err);
+ statusPtr->err = 1;
+ }
+ break;
+ default:
+ return false;
+ break;
+ }
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GeneratePollingEvents --
+ *
+ * This function polls the mouse position and generates X Motion,
+ * Enter & Leave events. The cursor is also updated at this
+ * time.
+ *
+ * Results:
+ * True if event(s) are generated - false otherwise.
+ *
+ * Side effects:
+ * Additional events may be place on the Tk event queue.
+ * The cursor may be changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GeneratePollingEvents(MouseEventData * medPtr)
+{
+ Tk_Window tkwin, rootwin, grabWin;
+ Window window;
+ int local_x, local_y;
+ TkDisplay *dispPtr;
+
+
+ if ((!TkpIsWindowFloating(medPtr->whichWin)
+ && (medPtr->activeNonFloating != medPtr->whichWin))) {
+ tkwin = NULL;
+ } else {
+ window = TkMacOSXGetXWindow(medPtr->whichWin);
+ dispPtr = TkGetDisplayList();
+ rootwin = Tk_IdToWindow(dispPtr->display, window);
+ if (rootwin == NULL) {
+ tkwin = NULL;
+ } else {
+ tkwin = Tk_TopCoordsToWindow(rootwin,
+ medPtr->local.h, medPtr->local.v,
+ &local_x, &local_y);
+ }
+ }
+
+ /*
+ * The following call will generate the appropiate X events and
+ * adjust any state that Tk must remember.
+ */
+
+ grabWin = TkMacOSXGetCapture();
+
+ if ((tkwin == NULL) && (grabWin != NULL)) {
+ tkwin = grabWin;
+ }
+ Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v,
+ medPtr->state);
+
+
+ TkMacOSXInstallCursor(0);
+
+ return true;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BringWindowForward --
+ *
+ * Bring this background window to the front. We also set state
+ * so Tk thinks the button is currently up.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The window is brought forward.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+BringWindowForward(WindowRef wRef)
+{
+ if (!TkpIsWindowFloating(wRef)) {
+ if (IsValidWindowPtr(wRef))
+ SelectWindow(wRef);
+ }
+}
+
+static int
+GenerateMouseWheelEvent(MouseEventData * medPtr)
+{
+ Tk_Window tkwin, rootwin, grabWin;
+ Window window;
+ int local_x, local_y;
+ TkDisplay *dispPtr;
+ TkWindow *winPtr;
+ XEvent xEvent;
+
+ if ((!TkpIsWindowFloating(medPtr->whichWin)
+ && (medPtr->activeNonFloating != medPtr->whichWin))) {
+ tkwin = NULL;
+ } else {
+ window = TkMacOSXGetXWindow(medPtr->whichWin);
+ dispPtr = TkGetDisplayList();
+ rootwin = Tk_IdToWindow(dispPtr->display, window);
+ if (rootwin == NULL) {
+ tkwin = NULL;
+ } else {
+ tkwin = Tk_TopCoordsToWindow(rootwin,
+ medPtr->local.h, medPtr->local.v,
+ &local_x, &local_y);
+ }
+ }
+
+ /*
+ * The following call will generate the appropiate X events and
+ * adjust any state that Tk must remember.
+ */
+
+ grabWin = TkMacOSXGetCapture();
+
+ if ((tkwin == NULL) && (grabWin != NULL)) {
+ tkwin = grabWin;
+ }
+ if (!tkwin) {
+ return true;
+ }
+ winPtr = ( TkWindow *)tkwin;
+ xEvent.type = MouseWheelEvent;
+ xEvent.xkey.keycode = medPtr->delta;
+ xEvent.xany.serial = LastKnownRequestProcessed(winPtr->display);
+ xEvent.xany.send_event = false;
+ xEvent.xany.display = winPtr->display;
+ xEvent.xany.window = Tk_WindowId(winPtr);
+ Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
+
+ return true;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXGetEatButtonUp --
+ *
+ * Results:
+ * Returns the flag indicating if we need to eat the
+ * next mouse up event
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+TkMacOSXGetEatButtonUp()
+{
+ return gEatButtonUp;
+}
+
+/*
+ * TkMacOSXSetEatButtonUp --
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Sets the flag indicating if we need to eat the
+ * next mouse up event
+ *
+ */
+void
+TkMacOSXSetEatButtonUp(int f)
+{
+ gEatButtonUp = f;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXButtonKeyState --
+ *
+ * Returns the current state of the button & modifier keys.
+ *
+ * Results:
+ * A bitwise inclusive OR of a subset of the following:
+ * Button1Mask, ShiftMask, LockMask, ControlMask, Mod?Mask,
+ * Mod?Mask.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+unsigned int
+TkMacOSXButtonKeyState()
+{
+ unsigned int state = 0;
+ KeyMap theKeys;
+
+ if (Button() & !gEatButtonUp) {
+ state |= Button1Mask;
+ }
+
+ GetKeys(theKeys);
+
+ if (theKeys[1] & 2) {
+ state |= LockMask;
+ }
+
+ if (theKeys[1] & 1) {
+ state |= ShiftMask;
+ }
+
+ if (theKeys[1] & 8) {
+ state |= ControlMask;
+ }
+
+ if (theKeys[1] & 32768) {
+ state |= Mod1Mask; /* command key */
+ }
+
+ if (theKeys[1] & 4) {
+ state |= Mod2Mask; /* option key */
+ }
+
+ return state;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XQueryPointer --
+ *
+ * Check the current state of the mouse. This is not a complete
+ * implementation of this function. It only computes the root
+ * coordinates and the current mask.
+ *
+ * Results:
+ * Sets root_x_return, root_y_return, and mask_return. Returns
+ * true on success.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Bool
+XQueryPointer(
+ Display* display,
+ Window w,
+ Window* root_return,
+ Window* child_return,
+ int* root_x_return,
+ int* root_y_return,
+ int* win_x_return,
+ int* win_y_return,
+ unsigned int* mask_return)
+{
+ Point where;
+ CGrafPtr port;
+ GDHandle dev;
+
+ GetGWorld(&port,&dev);
+ GetMouse(&where);
+ LocalToGlobal(&where);
+
+ *root_x_return = where.h;
+ *root_y_return = where.v;
+ *mask_return = TkMacOSXButtonKeyState();
+ return True;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkGenerateButtonEvent --
+ *
+ * Given a global x & y position and the button key status this
+ * procedure generates the appropiate X button event. It also
+ * handles the state changes needed to implement implicit grabs.
+ *
+ * Results:
+ * True if event(s) are generated - false otherwise.
+ *
+ * Side effects:
+ * Additional events may be place on the Tk event queue.
+ * Grab state may also change.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkGenerateButtonEvent(
+ int x, /* X location of mouse */
+ int y, /* Y location of mouse */
+ Window window, /* X Window containing button event. */
+ unsigned int state) /* Button Key state suitable for X event */
+{
+ WindowRef whichWin, frontWin;
+ Point where;
+ Tk_Window tkwin;
+ int dummy;
+ TkDisplay *dispPtr;
+
+ /*
+ * ButtonDown events will always occur in the front
+ * window. ButtonUp events, however, may occur anywhere
+ * on the screen. ButtonUp events should only be sent
+ * to Tk if in the front window or during an implicit grab.
+ */
+
+ where.h = x;
+ where.v = y;
+ FindWindow(where, &whichWin);
+ frontWin = FrontNonFloatingWindow();
+
+ if ((frontWin == NULL) || ((!(TkpIsWindowFloating(whichWin))
+ && (frontWin != whichWin))
+ && TkMacOSXGetCapture() == NULL)) {
+ return false;
+ }
+
+ dispPtr = TkGetDisplayList();
+ tkwin = Tk_IdToWindow(dispPtr->display, window);
+
+ GlobalToLocal(&where);
+ if (tkwin != NULL) {
+ tkwin = Tk_TopCoordsToWindow(tkwin, where.h, where.v,
+ &dummy, &dummy);
+ }
+
+ Tk_UpdatePointer(tkwin, x, y, state);
+
+ return true;
+} \ No newline at end of file
diff --git a/macosx/tkMacOSXNotify.c b/macosx/tkMacOSXNotify.c
new file mode 100644
index 0000000..c8c5af9
--- /dev/null
+++ b/macosx/tkMacOSXNotify.c
@@ -0,0 +1,1145 @@
+/*
+ * tclMacOSXNotify.c --
+ *
+ * This file contains the implementation of a merged
+ * Carbon/select-based notifier, which is the lowest-level part
+ * of the Tcl event loop. This file works together with
+ * ../generic/tclNotify.c.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXNotify.c,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#include "tclInt.h"
+#include "tclPort.h"
+
+/* FIXME - Why do I need these here? */
+
+#undef environ
+#include "tkMacOSX.h"
+#include "tkMacOSXEvent.h"
+#include <signal.h>
+
+extern TclStubs tclStubs;
+
+/*
+ * This structure is used to keep track of the notifier info for a
+ * a registered file.
+ */
+
+typedef struct FileHandler {
+ int fd;
+ int mask; /* Mask of desired events: TCL_READABLE,
+ * etc. */
+ int readyMask; /* Mask of events that have been seen since the
+ * last time file handlers were invoked for
+ * this file. */
+ Tcl_FileProc *proc; /* Procedure to call, in the style of
+ * Tcl_CreateFileHandler. */
+ ClientData clientData; /* Argument to pass to proc. */
+ struct FileHandler *nextPtr;/* Next in list of all files we care about. */
+} FileHandler;
+
+/*
+ * The following structure is what is added to the Tcl event queue when
+ * file handlers are ready to fire.
+ */
+
+typedef struct FileHandlerEvent {
+ Tcl_Event header; /* Information that is standard for
+ * all events. */
+ int fd; /* File descriptor that is ready. Used
+ * to find the FileHandler structure for
+ * the file (can't point directly to the
+ * FileHandler structure because it could
+ * go away while the event is queued). */
+} FileHandlerEvent;
+
+/*
+ * The following static structure contains the state information for the
+ * select based implementation of the Tcl notifier. One of these structures
+ * is created for each thread that is using the notifier.
+ */
+
+typedef struct ThreadSpecificData {
+ FileHandler *firstFileHandlerPtr;
+ /* Pointer to head of file handler list. */
+ fd_mask checkMasks[3*MASK_SIZE];
+ /* This array is used to build up the masks
+ * to be used in the next call to select.
+ * Bits are set in response to calls to
+ * Tcl_CreateFileHandler. */
+ fd_mask readyMasks[3*MASK_SIZE];
+ /* This array reflects the readable/writable
+ * conditions that were found to exist by the
+ * last call to select. */
+ int numFdBits; /* Number of valid bits in checkMasks
+ * (one more than highest fd for which
+ * Tcl_WatchFile has been called). */
+ int isMainLoop; /* Is this the main Carbon Loop (in which case
+ * we will call RNE in the actual wait... */
+#ifdef TCL_THREADS
+ int onList; /* True if it is in this list */
+ unsigned int pollState; /* pollState is used to implement a polling
+ * handshake between each thread and the
+ * notifier thread. Bits defined below. */
+ struct ThreadSpecificData *nextPtr, *prevPtr;
+ /* All threads that are currently waiting on
+ * an event have their ThreadSpecificData
+ * structure on a doubly-linked listed formed
+ * from these pointers. You must hold the
+ * notifierMutex lock before accessing these
+ * fields. */
+ Tcl_Condition waitCV; /* Any other thread alerts a notifier
+ * that an event is ready to be processed
+ * by signaling this condition variable. */
+ int eventReady; /* True if an event is ready to be processed.
+ * Used as condition flag together with
+ * waitCV above. */
+#endif
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
+#ifdef TCL_THREADS
+/*
+ * The following static indicates the number of threads that have
+ * initialized notifiers.
+ *
+ * You must hold the notifierMutex lock before accessing this variable.
+ */
+
+static int notifierCount = 0;
+
+/*
+ * The following variable points to the head of a doubly-linked list of
+ * of ThreadSpecificData structures for all threads that are currently
+ * waiting on an event.
+ *
+ * You must hold the notifierMutex lock before accessing this list.
+ */
+
+static ThreadSpecificData *waitingListPtr = NULL;
+
+/*
+ * The notifier thread spends all its time in select() waiting for a
+ * file descriptor associated with one of the threads on the waitingListPtr
+ * list to do something interesting. But if the contents of the
+ * waitingListPtr list ever changes, we need to wake up and restart
+ * the select() system call. You can wake up the notifier thread by
+ * writing a single byte to the file descriptor defined below. This
+ * file descriptor is the input-end of a pipe and the notifier thread is
+ * listening for data on the output-end of the same pipe. Hence writing
+ * to this file descriptor will cause the select() system call to return
+ * and wake up the notifier thread.
+ *
+ * You must hold the notifierMutex lock before accessing this list.
+ */
+
+static int triggerPipe = -1;
+
+/*
+ * The notifierMutex locks access to all of the global notifier state.
+ */
+
+TCL_DECLARE_MUTEX(notifierMutex)
+
+/*
+ * The notifier thread signals the notifierCV when it has finished
+ * initializing the triggerPipe and right before the notifier
+ * thread terminates.
+ */
+
+static Tcl_Condition notifierCV;
+
+/*
+ * The pollState bits
+ * POLL_WANT is set by each thread before it waits on its condition
+ * variable. It is checked by the notifier before it does
+ * select.
+ * POLL_DONE is set by the notifier if it goes into select after
+ * seeing POLL_WANT. The idea is to ensure it tries a select
+ * with the same bits the initial thread had set.
+ */
+#define POLL_WANT 0x1
+#define POLL_DONE 0x2
+
+/*
+ * This is the thread ID of the notifier thread that does select.
+ */
+static Tcl_ThreadId notifierThread;
+
+#endif
+
+/*
+ * Static routines defined in this file.
+ */
+
+#ifdef TCL_THREADS
+static void NotifierThreadProc _ANSI_ARGS_((ClientData clientData));
+#endif
+static int FileHandlerEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
+ int flags));
+
+void TkMacOSXSetTimer(Tcl_Time *timePtr);
+void TkMacOSXCreateFileHandler(int fd, int mask, Tcl_FileProc *proc, ClientData clientData);
+void TkMacOSXDeleteFileHandler(int fd);
+int TkMacOSXWaitForEvent(Tcl_Time *timePtr);
+void TkMacOSXAlertNotifier(ClientData clientData);
+ClientData TkMacOSXInitNotifier();
+void TkMacOSXFinalizeNotifier(ClientData clientData);
+void TkMacOSXServiceModeHook(int mode);
+EventRef TkMacOSXCreateFakeEvent ();
+ /*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXSetupTkNotifier --
+ *
+ * Replaces the Tcl notifier (from tclUnixNotfy.c) with
+ * the Mac notifier that melds the Unix select based notifer
+ * with the Carbon event handling side of the Tk notifier.
+ *
+ * Results:
+ * Replaces the notifier callbacks with MacOS X specific ones.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_MacOSXSetupTkNotifier()
+{
+ Tcl_NotifierProcs macNotifierProcs = {
+ TkMacOSXSetTimer,
+ TkMacOSXWaitForEvent,
+ TkMacOSXCreateFileHandler,
+ TkMacOSXDeleteFileHandler,
+ TkMacOSXInitNotifier,
+ TkMacOSXFinalizeNotifier,
+ TkMacOSXAlertNotifier,
+ TkMacOSXServiceModeHook
+ };
+
+ Tcl_SetNotifier(&macNotifierProcs);
+
+ /*
+ * Tcl_SetNotifier doesn't call the TclInitNotifier
+ * so we call it now. If we don't do this the
+ * ThreadSpecificData will keep a pointer to the original
+ * InitNotifier. See tclNotify.c:TclInitNotifier().
+ */
+
+ TclInitNotifier();
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InitNotifier --
+ *
+ * Initializes the platform specific notifier state.
+ *
+ * Results:
+ * Returns a handle to the notifier state for this thread..
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ClientData
+TkMacOSXInitNotifier()
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+#ifdef TCL_THREADS
+ tsdPtr->eventReady = 0;
+
+ /*
+ * Start the Notifier thread if necessary.
+ */
+
+ Tcl_MutexLock(&notifierMutex);
+ if (notifierCount == 0) {
+ if (Tcl_CreateThread(&notifierThread, NotifierThreadProc, NULL,
+ TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS) != TCL_OK) {
+ panic("Tcl_InitNotifier: unable to start notifier thread");
+ }
+ }
+ notifierCount++;
+
+ if (GetCurrentEventLoop() == GetMainEventLoop()) {
+ tsdPtr->isMainLoop = 1;
+ } else {
+ tsdPtr->isMainLoop = 0;
+ }
+
+ /*
+ * Wait for the notifier pipe to be created.
+ */
+
+ while (triggerPipe < 0) {
+ Tcl_ConditionWait(&notifierCV, &notifierMutex, NULL);
+ }
+
+ Tcl_MutexUnlock(&notifierMutex);
+#endif
+ return (ClientData) tsdPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FinalizeNotifier --
+ *
+ * This function is called to cleanup the notifier state before
+ * a thread is terminated.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May terminate the background notifier thread if this is the
+ * last notifier instance.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXFinalizeNotifier(clientData)
+ ClientData clientData; /* Not used. */
+{
+#ifdef TCL_THREADS
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+ Tcl_MutexLock(&notifierMutex);
+ notifierCount--;
+
+ /*
+ * If this is the last thread to use the notifier, close the notifier
+ * pipe and wait for the background thread to terminate.
+ */
+
+ if (notifierCount == 0) {
+ if (triggerPipe < 0) {
+ panic("Tcl_FinalizeNotifier: notifier pipe not initialized");
+ }
+
+ /*
+ * Send "q" message to the notifier thread so that it will
+ * terminate. The notifier will return from its call to select()
+ * and notice that a "q" message has arrived, it will then close
+ * its side of the pipe and terminate its thread. Note the we can
+ * not just close the pipe and check for EOF in the notifier
+ * thread because if a background child process was created with
+ * exec, select() would not register the EOF on the pipe until the
+ * child processes had terminated. [Bug: 4139]
+ */
+ write(triggerPipe, "q", 1);
+ close(triggerPipe);
+
+ Tcl_ConditionWait(&notifierCV, &notifierMutex, NULL);
+ }
+
+ /*
+ * Clean up any synchronization objects in the thread local storage.
+ */
+
+ Tcl_ConditionFinalize(&(tsdPtr->waitCV));
+
+ Tcl_MutexUnlock(&notifierMutex);
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AlertNotifier --
+ *
+ * Wake up the specified notifier from any thread. This routine
+ * is called by the platform independent notifier code whenever
+ * the Tcl_ThreadAlert routine is called. This routine is
+ * guaranteed not to be called on a given notifier after
+ * Tcl_FinalizeNotifier is called for that notifier.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Signals the notifier condition variable for the specified
+ * notifier.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXAlertNotifier(clientData)
+ ClientData clientData;
+{
+#ifdef TCL_THREADS
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;
+ Tcl_MutexLock(&notifierMutex);
+ tsdPtr->eventReady = 1;
+ Tcl_ConditionNotify(&tsdPtr->waitCV);
+ Tcl_MutexUnlock(&notifierMutex);
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetTimer --
+ *
+ * This procedure sets the current notifier timer value. This
+ * interface is not implemented in this notifier because we are
+ * always running inside of Tcl_DoOneEvent.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXSetTimer(timePtr)
+ Tcl_Time *timePtr; /* Timeout value, may be NULL. */
+{
+ /*
+ * The interval timer doesn't do anything in this implementation,
+ * because the only event loop is via Tcl_DoOneEvent, which passes
+ * timeout values to Tcl_WaitForEvent.
+ */
+
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ServiceModeHook --
+ *
+ * This function is invoked whenever the service mode changes.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXServiceModeHook(mode)
+ int mode; /* Either TCL_SERVICE_ALL, or
+ * TCL_SERVICE_NONE. */
+{
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateFileHandler --
+ *
+ * This procedure registers a file handler with the select notifier.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Creates a new file handler structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXCreateFileHandler(fd, mask, proc, clientData)
+ int fd; /* Handle of stream to watch. */
+ int mask; /* OR'ed combination of TCL_READABLE,
+ * TCL_WRITABLE, and TCL_EXCEPTION:
+ * indicates conditions under which
+ * proc should be called. */
+ Tcl_FileProc *proc; /* Procedure to call for each
+ * selected event. */
+ ClientData clientData; /* Arbitrary data to pass to proc. */
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ FileHandler *filePtr;
+ int index, bit;
+
+ for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL;
+ filePtr = filePtr->nextPtr) {
+ if (filePtr->fd == fd) {
+ break;
+ }
+ }
+ if (filePtr == NULL) {
+ filePtr = (FileHandler*) ckalloc(sizeof(FileHandler));
+ filePtr->fd = fd;
+ filePtr->readyMask = 0;
+ filePtr->nextPtr = tsdPtr->firstFileHandlerPtr;
+ tsdPtr->firstFileHandlerPtr = filePtr;
+ }
+ filePtr->proc = proc;
+ filePtr->clientData = clientData;
+ filePtr->mask = mask;
+
+ /*
+ * Update the check masks for this file.
+ */
+
+ index = fd/(NBBY*sizeof(fd_mask));
+ bit = 1 << (fd%(NBBY*sizeof(fd_mask)));
+ if (mask & TCL_READABLE) {
+ tsdPtr->checkMasks[index] |= bit;
+ } else {
+ tsdPtr->checkMasks[index] &= ~bit;
+ }
+ if (mask & TCL_WRITABLE) {
+ (tsdPtr->checkMasks+MASK_SIZE)[index] |= bit;
+ } else {
+ (tsdPtr->checkMasks+MASK_SIZE)[index] &= ~bit;
+ }
+ if (mask & TCL_EXCEPTION) {
+ (tsdPtr->checkMasks+2*(MASK_SIZE))[index] |= bit;
+ } else {
+ (tsdPtr->checkMasks+2*(MASK_SIZE))[index] &= ~bit;
+ }
+ if (tsdPtr->numFdBits <= fd) {
+ tsdPtr->numFdBits = fd+1;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteFileHandler --
+ *
+ * Cancel a previously-arranged callback arrangement for
+ * a file.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * If a callback was previously registered on file, remove it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXDeleteFileHandler(fd)
+ int fd; /* Stream id for which to remove callback procedure. */
+{
+ FileHandler *filePtr, *prevPtr;
+ int index, bit, i;
+ unsigned long flags;
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+ /*
+ * Find the entry for the given file (and return if there isn't one).
+ */
+
+ for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ;
+ prevPtr = filePtr, filePtr = filePtr->nextPtr) {
+ if (filePtr == NULL) {
+ return;
+ }
+ if (filePtr->fd == fd) {
+ break;
+ }
+ }
+
+ /*
+ * Update the check masks for this file.
+ */
+
+ index = fd/(NBBY*sizeof(fd_mask));
+ bit = 1 << (fd%(NBBY*sizeof(fd_mask)));
+
+ if (filePtr->mask & TCL_READABLE) {
+ tsdPtr->checkMasks[index] &= ~bit;
+ }
+ if (filePtr->mask & TCL_WRITABLE) {
+ (tsdPtr->checkMasks+MASK_SIZE)[index] &= ~bit;
+ }
+ if (filePtr->mask & TCL_EXCEPTION) {
+ (tsdPtr->checkMasks+2*(MASK_SIZE))[index] &= ~bit;
+ }
+
+ /*
+ * Find current max fd.
+ */
+
+ if (fd+1 == tsdPtr->numFdBits) {
+ for (tsdPtr->numFdBits = 0; index >= 0; index--) {
+ flags = tsdPtr->checkMasks[index]
+ | (tsdPtr->checkMasks+MASK_SIZE)[index]
+ | (tsdPtr->checkMasks+2*(MASK_SIZE))[index];
+ if (flags) {
+ for (i = (NBBY*sizeof(fd_mask)); i > 0; i--) {
+ if (flags & (((unsigned long)1) << (i-1))) {
+ break;
+ }
+ }
+ tsdPtr->numFdBits = index * (NBBY*sizeof(fd_mask)) + i;
+ break;
+ }
+ }
+ }
+
+ /*
+ * Clean up information in the callback record.
+ */
+
+ if (prevPtr == NULL) {
+ tsdPtr->firstFileHandlerPtr = filePtr->nextPtr;
+ } else {
+ prevPtr->nextPtr = filePtr->nextPtr;
+ }
+ ckfree((char *) filePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileHandlerEventProc --
+ *
+ * This procedure is called by Tcl_ServiceEvent when a file event
+ * reaches the front of the event queue. This procedure is
+ * responsible for actually handling the event by invoking the
+ * callback for the file handler.
+ *
+ * Results:
+ * Returns 1 if the event was handled, meaning it should be removed
+ * from the queue. Returns 0 if the event was not handled, meaning
+ * it should stay on the queue. The only time the event isn't
+ * handled is if the TCL_FILE_EVENTS flag bit isn't set.
+ *
+ * Side effects:
+ * Whatever the file handler's callback procedure does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileHandlerEventProc(evPtr, flags)
+ Tcl_Event *evPtr; /* Event to service. */
+ int flags; /* Flags that indicate what events to
+ * handle, such as TCL_FILE_EVENTS. */
+{
+ int mask;
+ FileHandler *filePtr;
+ FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) evPtr;
+ ThreadSpecificData *tsdPtr;
+
+ if (!(flags & TCL_FILE_EVENTS)) {
+ return 0;
+ }
+
+ /*
+ * Search through the file handlers to find the one whose handle matches
+ * the event. We do this rather than keeping a pointer to the file
+ * handler directly in the event, so that the handler can be deleted
+ * while the event is queued without leaving a dangling pointer.
+ */
+
+ tsdPtr = TCL_TSD_INIT(&dataKey);
+ for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL;
+ filePtr = filePtr->nextPtr) {
+ if (filePtr->fd != fileEvPtr->fd) {
+ continue;
+ }
+
+ /*
+ * The code is tricky for two reasons:
+ * 1. The file handler's desired events could have changed
+ * since the time when the event was queued, so AND the
+ * ready mask with the desired mask.
+ * 2. The file could have been closed and re-opened since
+ * the time when the event was queued. This is why the
+ * ready mask is stored in the file handler rather than
+ * the queued event: it will be zeroed when a new
+ * file handler is created for the newly opened file.
+ */
+
+ mask = filePtr->readyMask & filePtr->mask;
+ filePtr->readyMask = 0;
+ if (mask != 0) {
+ (*filePtr->proc)(filePtr->clientData, mask);
+ }
+ break;
+ }
+ return 1;
+}
+
+void
+DoActualWait(timePtr)
+ Tcl_Time *timePtr; /* Maximum block time, or NULL. */
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+ if (!tsdPtr->isMainLoop) {
+ Tcl_ConditionWait(&tsdPtr->waitCV, &notifierMutex, timePtr);
+ } else {
+ EventRef eventRef;
+ EventTime waitTime;
+ Tcl_MutexUnlock(&notifierMutex);
+
+ if (timePtr == NULL) {
+ waitTime = kEventDurationForever;
+ } else {
+ waitTime = timePtr->sec * kEventDurationSecond
+ + timePtr->usec * kEventDurationMicrosecond;
+ }
+ ReceiveNextEvent(0, NULL, waitTime, false, &eventRef);
+ Tcl_MutexLock(&notifierMutex);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_WaitForEvent --
+ *
+ * This function is called by Tcl_DoOneEvent to wait for new
+ * events on the message queue. If the block time is 0, then
+ * Tcl_WaitForEvent just polls without blocking.
+ *
+ * Results:
+ * Returns -1 if the select would block forever, otherwise
+ * returns 0.
+ *
+ * Side effects:
+ * Queues file events that are detected by the select.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkMacOSXWaitForEvent(timePtr)
+ Tcl_Time *timePtr; /* Maximum block time, or NULL. */
+{
+ FileHandler *filePtr;
+ FileHandlerEvent *fileEvPtr;
+ struct timeval timeout, *timeoutPtr;
+ int bit, index, mask;
+#ifdef TCL_THREADS
+ int waitForFiles;
+#else
+ int numFound;
+#endif
+
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+ /*
+ * Set up the timeout structure. Note that if there are no events to
+ * check for, we return with a negative result rather than blocking
+ * forever.
+ */
+
+ if (timePtr) {
+ timeout.tv_sec = timePtr->sec;
+ timeout.tv_usec = timePtr->usec;
+ timeoutPtr = &timeout;
+#ifndef TCL_THREADS
+ } else if (tsdPtr->numFdBits == 0) {
+ /*
+ * If there are no threads, no timeout, and no fds registered,
+ * then there are no events possible and we must avoid deadlock.
+ * Note that this is not entirely correct because there might
+ * be a signal that could interrupt the select call, but we
+ * don't handle that case if we aren't using threads.
+ */
+
+ return -1;
+#endif
+ } else {
+ timeoutPtr = NULL;
+ }
+
+#ifdef TCL_THREADS
+ /*
+ * Place this thread on the list of interested threads, signal the
+ * notifier thread, and wait for a response or a timeout.
+ */
+
+ Tcl_MutexLock(&notifierMutex);
+
+ waitForFiles = (tsdPtr->numFdBits > 0);
+ if (timePtr != NULL && timePtr->sec == 0 && timePtr->usec == 0) {
+ /*
+ * Cannot emulate a polling select with a polling condition variable.
+ * Instead, pretend to wait for files and tell the notifier
+ * thread what we are doing. The notifier thread makes sure
+ * it goes through select with its select mask in the same state
+ * as ours currently is. We block until that happens.
+ */
+
+ waitForFiles = 1;
+ tsdPtr->pollState = POLL_WANT;
+ timePtr = NULL;
+ } else {
+ tsdPtr->pollState = 0;
+ }
+
+ if (waitForFiles) {
+ /*
+ * Add the ThreadSpecificData structure of this thread to the list
+ * of ThreadSpecificData structures of all threads that are waiting
+ * on file events.
+ */
+
+
+ tsdPtr->nextPtr = waitingListPtr;
+ if (waitingListPtr) {
+ waitingListPtr->prevPtr = tsdPtr;
+ }
+ tsdPtr->prevPtr = 0;
+ waitingListPtr = tsdPtr;
+ tsdPtr->onList = 1;
+
+ write(triggerPipe, "", 1);
+ }
+
+ memset((VOID *) tsdPtr->readyMasks, 0, 3*MASK_SIZE*sizeof(fd_mask));
+
+ if (!tsdPtr->eventReady) {
+ DoActualWait(timePtr);
+ }
+ tsdPtr->eventReady = 0;
+
+ if (waitForFiles && tsdPtr->onList) {
+ /*
+ * Remove the ThreadSpecificData structure of this thread from the
+ * waiting list. Alert the notifier thread to recompute its select
+ * masks - skipping this caused a hang when trying to close a pipe
+ * which the notifier thread was still doing a select on.
+ */
+
+ if (tsdPtr->prevPtr) {
+ tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
+ } else {
+ waitingListPtr = tsdPtr->nextPtr;
+ }
+ if (tsdPtr->nextPtr) {
+ tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
+ }
+ tsdPtr->nextPtr = tsdPtr->prevPtr = NULL;
+ tsdPtr->onList = 0;
+ write(triggerPipe, "", 1);
+ }
+
+
+#else
+ memcpy((VOID *) tsdPtr->readyMasks, (VOID *) tsdPtr->checkMasks,
+ 3*MASK_SIZE*sizeof(fd_mask));
+ numFound = select(tsdPtr->numFdBits,
+ (SELECT_MASK *) &tsdPtr->readyMasks[0],
+ (SELECT_MASK *) &tsdPtr->readyMasks[MASK_SIZE],
+ (SELECT_MASK *) &tsdPtr->readyMasks[2*MASK_SIZE], timeoutPtr);
+
+ /*
+ * Some systems don't clear the masks after an error, so
+ * we have to do it here.
+ */
+
+ if (numFound == -1) {
+ memset((VOID *) tsdPtr->readyMasks, 0, 3*MASK_SIZE*sizeof(fd_mask));
+ }
+#endif
+
+ /*
+ * Queue all detected file events before returning.
+ */
+
+ for (filePtr = tsdPtr->firstFileHandlerPtr; (filePtr != NULL);
+ filePtr = filePtr->nextPtr) {
+ index = filePtr->fd / (NBBY*sizeof(fd_mask));
+ bit = 1 << (filePtr->fd % (NBBY*sizeof(fd_mask)));
+ mask = 0;
+
+ if (tsdPtr->readyMasks[index] & bit) {
+ mask |= TCL_READABLE;
+ }
+ if ((tsdPtr->readyMasks+MASK_SIZE)[index] & bit) {
+ mask |= TCL_WRITABLE;
+ }
+ if ((tsdPtr->readyMasks+2*(MASK_SIZE))[index] & bit) {
+ mask |= TCL_EXCEPTION;
+ }
+
+ if (!mask) {
+ continue;
+ }
+
+ /*
+ * Don't bother to queue an event if the mask was previously
+ * non-zero since an event must still be on the queue.
+ */
+
+ if (filePtr->readyMask == 0) {
+ fileEvPtr = (FileHandlerEvent *) ckalloc(
+ sizeof(FileHandlerEvent));
+ fileEvPtr->header.proc = FileHandlerEventProc;
+ fileEvPtr->fd = filePtr->fd;
+ Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL);
+ }
+ filePtr->readyMask = mask;
+ }
+
+ /*
+ * Also queue the Mac Events found...
+ */
+
+#ifdef TCL_THREADS
+ Tcl_MutexUnlock(&notifierMutex);
+#endif
+
+ if (tsdPtr->isMainLoop) {
+ TkMacOSXCountAndProcessMacEvents();
+ }
+
+ return 0;
+}
+
+#ifdef TCL_THREADS
+/*
+ *----------------------------------------------------------------------
+ *
+ * NotifierThreadProc --
+ *
+ * This routine is the initial (and only) function executed by the
+ * special notifier thread. Its job is to wait for file descriptors
+ * to become readable or writable or to have an exception condition
+ * and then to notify other threads who are interested in this
+ * information by signalling a condition variable. Other threads
+ * can signal this notifier thread of a change in their interests
+ * by writing a single byte to a special pipe that the notifier
+ * thread is monitoring.
+ *
+ * Result:
+ * None. Once started, this routine never exits. It dies with
+ * the overall process.
+ *
+ * Side effects:
+ * The trigger pipe used to signal the notifier thread is created
+ * when the notifier thread first starts.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+NotifierThreadProc(clientData)
+ ClientData clientData; /* Not used. */
+{
+ ThreadSpecificData *tsdPtr;
+ fd_mask masks[3*MASK_SIZE];
+ long *maskPtr = (long *)masks; /* masks[] cast to type long[] */
+ int fds[2];
+ int i, status, index, bit, numFdBits, found, receivePipe, word;
+ struct timeval poll = {0., 0.}, *timePtr;
+ int maskSize = 3 * ((MASK_SIZE) / sizeof(long)) * sizeof(fd_mask);
+ char buf[2];
+
+ if (pipe(fds) != 0) {
+ panic("NotifierThreadProc: could not create trigger pipe.");
+ }
+
+ receivePipe = fds[0];
+
+#ifndef USE_FIONBIO
+ status = fcntl(receivePipe, F_GETFL);
+ status |= O_NONBLOCK;
+ if (fcntl(receivePipe, F_SETFL, status) < 0) {
+ panic("NotifierThreadProc: could not make receive pipe non blocking.");
+ }
+ status = fcntl(fds[1], F_GETFL);
+ status |= O_NONBLOCK;
+ if (fcntl(fds[1], F_SETFL, status) < 0) {
+ panic("NotifierThreadProc: could not make trigger pipe non blocking.");
+ }
+#else
+ if (ioctl(receivePipe, (int) FIONBIO, &status) < 0) {
+ panic("NotifierThreadProc: could not make receive pipe non blocking.");
+ }
+ if (ioctl(fds[1], (int) FIONBIO, &status) < 0) {
+ panic("NotifierThreadProc: could not make trigger pipe non blocking.");
+ }
+#endif
+
+ /*
+ * Install the write end of the pipe into the global variable.
+ */
+
+ Tcl_MutexLock(&notifierMutex);
+ triggerPipe = fds[1];
+
+ /*
+ * Signal any threads that are waiting.
+ */
+
+ Tcl_ConditionNotify(&notifierCV);
+ Tcl_MutexUnlock(&notifierMutex);
+
+ /*
+ * Look for file events and report them to interested threads.
+ */
+
+ while (1) {
+ /*
+ * Set up the select mask to include the receive pipe.
+ */
+
+ memset((VOID *)masks, 0, 3*MASK_SIZE*sizeof(fd_mask));
+ numFdBits = receivePipe + 1;
+ index = receivePipe / (NBBY*sizeof(fd_mask));
+ bit = 1 << (receivePipe % (NBBY*sizeof(fd_mask)));
+ masks[index] |= bit;
+
+ /*
+ * Add in the check masks from all of the waiting notifiers.
+ */
+
+ Tcl_MutexLock(&notifierMutex);
+ timePtr = NULL;
+ for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
+ for (i = 0; i < maskSize; i++) {
+ maskPtr[i] |= ((long*)tsdPtr->checkMasks)[i];
+ }
+ if (tsdPtr->numFdBits > numFdBits) {
+ numFdBits = tsdPtr->numFdBits;
+ }
+ if (tsdPtr->pollState & POLL_WANT) {
+ /*
+ * Here we make sure we go through select() with the same
+ * mask bits that were present when the thread tried to poll.
+ */
+
+ tsdPtr->pollState |= POLL_DONE;
+ timePtr = &poll;
+ }
+ }
+ Tcl_MutexUnlock(&notifierMutex);
+
+ maskSize = 3 * ((MASK_SIZE) / sizeof(long)) * sizeof(fd_mask);
+
+ if (select(numFdBits, (SELECT_MASK *) &masks[0],
+ (SELECT_MASK *) &masks[MASK_SIZE],
+ (SELECT_MASK *) &masks[2*MASK_SIZE], timePtr) == -1) {
+ /*
+ * Try again immediately on an error.
+ */
+
+ continue;
+ }
+
+ /*
+ * Alert any threads that are waiting on a ready file descriptor.
+ */
+
+ Tcl_MutexLock(&notifierMutex);
+ for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
+ found = 0;
+
+ for (i = 0; i < maskSize; i++) {
+ word = maskPtr[i] & ((long*)tsdPtr->checkMasks)[i];
+ found |= word;
+ (((long*)(tsdPtr->readyMasks))[i]) = word;
+ }
+ if (found || (tsdPtr->pollState & POLL_DONE)) {
+ if (tsdPtr->onList) {
+ /*
+ * Remove the ThreadSpecificData structure of this
+ * thread from the waiting list. This prevents us from
+ * continuously spining on select until the other
+ * threads runs and services the file event.
+ */
+
+ if (tsdPtr->prevPtr) {
+ tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
+ } else {
+ waitingListPtr = tsdPtr->nextPtr;
+ }
+ if (tsdPtr->nextPtr) {
+ tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
+ }
+ tsdPtr->nextPtr = tsdPtr->prevPtr = NULL;
+ tsdPtr->onList = 0;
+ tsdPtr->pollState = 0;
+ }
+ tsdPtr->eventReady = 1;
+ if (tsdPtr->isMainLoop) {
+ /* We need to wake up the main loop, and let it have the event. */
+ EventRef fakeEvent = TkMacOSXCreateFakeEvent();
+ PostEventToQueue(GetMainEventQueue(), fakeEvent, kEventPriorityHigh);
+ ReleaseEvent(fakeEvent);
+ } else {
+ Tcl_ConditionNotify(&tsdPtr->waitCV);
+ }
+ }
+ }
+ Tcl_MutexUnlock(&notifierMutex);
+
+ /*
+ * Consume the next byte from the notifier pipe if the pipe was
+ * readable. Note that there may be multiple bytes pending, but
+ * to avoid a race condition we only read one at a time.
+ */
+
+ if (masks[index] & bit) {
+ i = read(receivePipe, buf, 1);
+
+ if ((i == 0) || ((i == 1) && (buf[0] == 'q'))) {
+ /*
+ * Someone closed the write end of the pipe or sent us a
+ * Quit message [Bug: 4139] and then closed the write end
+ * of the pipe so we need to shut down the notifier thread.
+ */
+
+ break;
+ }
+ }
+ }
+
+ /*
+ * Clean up the read end of the pipe and signal any threads waiting on
+ * termination of the notifier thread.
+ */
+
+ close(receivePipe);
+ Tcl_MutexLock(&notifierMutex);
+ triggerPipe = -1;
+ Tcl_ConditionNotify(&notifierCV);
+ Tcl_MutexUnlock(&notifierMutex);
+}
+#endif
+
+EventRef
+TkMacOSXCreateFakeEvent ()
+{
+ EventKind eKind;
+ EventClass eClass;
+ EventTime eTime;
+ EventRef eventRef;
+ EventAttributes flags;
+ eClass=kEventClassWish;
+ eKind = 0xffff;
+ eTime =GetLastUserEventTime() + 0.001;
+ flags=kEventAttributeUserEvent;
+ if (CreateEvent(NULL,eClass,eKind,eTime,flags,&eventRef)!=noErr) {
+ fprintf(stderr,"CreateEvent failed\n");
+ return NULL;
+ }
+ return eventRef;
+}
diff --git a/macosx/tkMacOSXPort.h b/macosx/tkMacOSXPort.h
new file mode 100644
index 0000000..c59a005
--- /dev/null
+++ b/macosx/tkMacOSXPort.h
@@ -0,0 +1,154 @@
+/*
+ * tkMacOSXPort.h --
+ *
+ * This file is included by all of the Tk C files. It contains
+ * information that may be configuration-dependent, such as
+ * #includes for system include files and a few other things.
+ *
+ * Copyright (c) 1994-1996 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXPort.h,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#ifndef _TKMACPORT
+#define _TKMACPORT
+
+/*
+ * Macro to use instead of "void" for arguments that must have
+ * type "void *" in ANSI C; maps them to type "char *" in
+ * non-ANSI systems. This macro may be used in some of the include
+ * files below, which is why it is defined here.
+ */
+
+#ifndef VOID
+# ifdef __STDC__
+# define VOID void
+# else
+# define VOID char
+# endif
+#endif
+
+#ifndef _TCL
+# include <tcl.h>
+#endif
+
+#include <time.h>
+#include <stdlib.h>
+#include <string.h>
+#include "tclMath.h"
+#include <ctype.h>
+#include <limits.h>
+
+#include <X11/Xlib.h>
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+#include <X11/Xfuncproto.h>
+#include <X11/Xutil.h>
+#include "tkIntXlibDecls.h"
+
+/*
+ * Not all systems declare the errno variable in errno.h. so this
+ * file does it explicitly.
+ */
+
+extern int errno;
+
+/*
+ * Define "NBBY" (number of bits per byte) if it's not already defined.
+ */
+
+#ifndef NBBY
+# define NBBY 8
+#endif
+
+/*
+ * Declarations for various library procedures that may not be declared
+ * in any other header file.
+ */
+
+#ifndef panic /* In a stubs-aware setting, this could confuse the #define */
+extern void panic _ANSI_ARGS_(TCL_VARARGS(char *, string));
+#endif
+#ifndef strcasecmp
+extern int strcasecmp _ANSI_ARGS_((CONST char *s1,
+ CONST char *s2));
+#endif
+#ifndef strncasecmp
+extern int strncasecmp _ANSI_ARGS_((CONST char *s1,
+ CONST char *s2, size_t n));
+#endif
+/*
+ * Defines for X functions that are used by Tk but are treated as
+ * no-op functions on the Macintosh.
+ */
+
+#define XFlush(display)
+#define XFree(data) {if ((data) != NULL) ckfree((char *) (data));}
+#define XGrabServer(display)
+#define XNoOp(display) {display->request++;}
+#define XUngrabServer(display)
+#define XSynchronize(display, bool) {display->request++;}
+#define XSync(display, bool) {display->request++;}
+#define XVisualIDFromVisual(visual) (visual->visualid)
+
+/*
+ * The following functions are not used on the Mac, so we stub them out.
+ */
+
+#define TkFreeWindowId(dispPtr,w)
+#define TkInitXId(dispPtr)
+#define TkpButtonSetDefaults(specPtr) {}
+#define TkpCmapStressed(tkwin,colormap) (0)
+#define TkpFreeColor(tkColPtr)
+#define TkSetPixmapColormap(p,c) {}
+#define TkpSync(display)
+
+/*
+ * The following macro returns the pixel value that corresponds to the
+ * RGB values in the given XColor structure.
+ */
+
+#define PIXEL_MAGIC ((unsigned char) 0x69)
+#define TkpGetPixel(p) ((((((PIXEL_MAGIC << 8) \
+ | (((p)->red >> 8) & 0xff)) << 8) \
+ | (((p)->green >> 8) & 0xff)) << 8) \
+ | (((p)->blue >> 8) & 0xff))
+
+/*
+ * This macro stores a representation of the window handle in a string.
+ * This should perhaps use the real size of an XID.
+ */
+
+#define TkpPrintWindowId(buf,w) \
+ sprintf((buf), "0x%x", (unsigned int) (w))
+
+/*
+ * TkpScanWindowId is just an alias for Tcl_GetInt on Unix.
+ */
+
+#define TkpScanWindowId(i,s,wp) \
+ Tcl_GetInt((i),(s),(int *) (wp))
+
+/*
+ * Magic pixel values for dynamic (or active) colors.
+ */
+
+#define HIGHLIGHT_PIXEL 31
+#define HIGHLIGHT_TEXT_PIXEL 33
+#define CONTROL_TEXT_PIXEL 35
+#define CONTROL_BODY_PIXEL 37
+#define CONTROL_FRAME_PIXEL 39
+#define WINDOW_BODY_PIXEL 41
+#define MENU_ACTIVE_PIXEL 43
+#define MENU_ACTIVE_TEXT_PIXEL 45
+#define MENU_BACKGROUND_PIXEL 47
+#define MENU_DISABLED_PIXEL 49
+#define MENU_TEXT_PIXEL 51
+#define APPEARANCE_PIXEL 52
+
+#endif /* _TKMACPORT */
diff --git a/macosx/tkMacOSXRegion.c b/macosx/tkMacOSXRegion.c
new file mode 100644
index 0000000..0fce0c0
--- /dev/null
+++ b/macosx/tkMacOSXRegion.c
@@ -0,0 +1,252 @@
+/*
+ * tkMacOSXRegion.c --
+ *
+ * Implements X window calls for manipulating regions
+ *
+ * Copyright (c) 1995-1996 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXRegion.c,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#include "tkInt.h"
+#include "tkMacOSXInt.h"
+#include "X11/X.h"
+#include "X11/Xlib.h"
+
+#include <Carbon/Carbon.h>
+/*
+#include <Windows.h>
+#include <QDOffscreen.h>
+*/
+
+/*
+ * Temporary region that can be reused.
+ */
+static RgnHandle tmpRgn = NULL;
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkCreateRegion --
+ *
+ * Implements the equivelent of the X window function
+ * XCreateRegion. See X window documentation for more details.
+ *
+ * Results:
+ * Returns an allocated region handle.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkRegion
+TkCreateRegion()
+{
+ RgnHandle rgn;
+ rgn = NewRgn();
+ return (TkRegion) rgn;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkDestroyRegion --
+ *
+ * Implements the equivelent of the X window function
+ * XDestroyRegion. See X window documentation for more details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Memory is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkDestroyRegion(
+ TkRegion r)
+{
+ RgnHandle rgn = (RgnHandle) r;
+ DisposeRgn(rgn);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkIntersectRegion --
+ *
+ * Implements the equivilent of the X window function
+ * XIntersectRegion. See X window documentation for more details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkIntersectRegion(
+ TkRegion sra,
+ TkRegion srb,
+ TkRegion dr_return)
+{
+ RgnHandle srcRgnA = (RgnHandle) sra;
+ RgnHandle srcRgnB = (RgnHandle) srb;
+ RgnHandle destRgn = (RgnHandle) dr_return;
+ SectRgn(srcRgnA, srcRgnB, destRgn);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkUnionRectWithRegion --
+ *
+ * Implements the equivelent of the X window function
+ * XUnionRectWithRegion. See X window documentation for more
+ * details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkUnionRectWithRegion(
+ XRectangle* rectangle,
+ TkRegion src_region,
+ TkRegion dest_region_return)
+{
+ RgnHandle srcRgn = (RgnHandle) src_region;
+ RgnHandle destRgn = (RgnHandle) dest_region_return;
+
+ if (tmpRgn == NULL) {
+ tmpRgn = NewRgn();
+ }
+ SetRectRgn(tmpRgn, rectangle->x, rectangle->y,
+ rectangle->x + rectangle->width, rectangle->y + rectangle->height);
+ UnionRgn(srcRgn, tmpRgn, destRgn);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkRectInRegion --
+ *
+ * Implements the equivelent of the X window function
+ * XRectInRegion. See X window documentation for more details.
+ *
+ * Results:
+ * Returns one of: RectangleOut, RectangleIn, RectanglePart.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkRectInRegion(
+ TkRegion region,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height)
+{
+ RgnHandle rgn = (RgnHandle) region;
+ RgnHandle rectRgn, destRgn;
+ int result;
+
+ rectRgn = NewRgn();
+ destRgn = NewRgn();
+ SetRectRgn(rectRgn, x, y, x + width, y + height);
+ SectRgn(rgn, rectRgn, destRgn);
+ if (EmptyRgn(destRgn)) {
+ result = RectangleOut;
+ } else if (EqualRgn(rgn, destRgn)) {
+ result = RectangleIn;
+ } else {
+ result = RectanglePart;
+ }
+ DisposeRgn(rectRgn);
+ DisposeRgn(destRgn);
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkClipBox --
+ *
+ * Implements the equivelent of the X window function XClipBox.
+ * See X window documentation for more details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkClipBox(
+ TkRegion r,
+ XRectangle* rect_return)
+{
+ RgnHandle rgn = (RgnHandle) r;
+ Rect rect;
+
+ GetRegionBounds(rgn,&rect);
+
+ rect_return->x = rect.left;
+ rect_return->y = rect.top;
+ rect_return->width = rect.right-rect.left;
+ rect_return->height = rect.bottom-rect.top;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkSubtractRegion --
+ *
+ * Implements the equivilent of the X window function
+ * XSubtractRegion. See X window documentation for more details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkSubtractRegion(
+ TkRegion sra,
+ TkRegion srb,
+ TkRegion dr_return)
+{
+ RgnHandle srcRgnA = (RgnHandle) sra;
+ RgnHandle srcRgnB = (RgnHandle) srb;
+ RgnHandle destRgn = (RgnHandle) dr_return;
+
+ DiffRgn(srcRgnA, srcRgnB, destRgn);
+}
diff --git a/macosx/tkMacOSXResource.r b/macosx/tkMacOSXResource.r
new file mode 100644
index 0000000..51a19c1
--- /dev/null
+++ b/macosx/tkMacOSXResource.r
@@ -0,0 +1,502 @@
+/*
+ * tkMacOSXResources.r --
+ *
+ * This file creates resources for use in a simple shell.
+ * This is designed to be an example of using the Tcl/Tk
+ * libraries in a Macintosh Application.
+ *
+ * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
+ * Copyright (c) 1995-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: tkMacOSXResource.r,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+
+/*
+ * We define SystemSevenOrLater so that our dialogs may use the
+ * auto center feature.
+ */
+#define SystemSevenOrLater 1
+
+#include <Types.r>
+#include <SysTypes.r>
+
+/*
+ * The folowing include and defines help construct
+ * the version string for Tcl.
+ */
+
+#define RESOURCE_INCLUDED
+#include "tcl.h"
+#include "tk.h"
+
+#if (TK_RELEASE_LEVEL == 0)
+# define RELEASE_LEVEL alpha
+#elif (TK_RELEASE_LEVEL == 1)
+# define RELEASE_LEVEL beta
+#elif (TK_RELEASE_LEVEL == 2)
+# define RELEASE_LEVEL final
+#endif
+
+#if (TK_RELEASE_LEVEL == 2)
+# define MINOR_VERSION (TK_MINOR_VERSION * 16) + TK_RELEASE_SERIAL
+#else
+# define MINOR_VERSION TK_MINOR_VERSION * 16
+#endif
+
+resource 'vers' (1) {
+ TK_MAJOR_VERSION, MINOR_VERSION,
+ RELEASE_LEVEL, 0x00, verUS,
+ TK_PATCH_LEVEL,
+ TK_PATCH_LEVEL ", by Ray Johnson & Jim Ingham " "\n" "© 1993-1997 Sun Microsystems" "\n" "© 1998-1999 Scriptics Inc."
+};
+
+resource 'vers' (2) {
+ TK_MAJOR_VERSION, MINOR_VERSION,
+ RELEASE_LEVEL, 0x00, verUS,
+ TK_PATCH_LEVEL,
+ "Wish " TK_PATCH_LEVEL " © 1993-1999"
+};
+
+
+/*
+ * The mechanisim below loads Tcl source into the resource fork of the
+ * application. The example below creates a TEXT resource named
+ * "Init" from the file "init.tcl". This allows applications to use
+ * Tcl to define the behavior of the application without having to
+ * require some predetermined file structure - all needed Tcl "files"
+ * are located within the application. To source a file for the
+ * resource fork the source command has been modified to support
+ * sourcing from resources. In the below case "source -rsrc {Init}"
+ * will load the TEXT resource named "Init".
+ */
+
+#include "tclMacTclCode.r"
+
+read 'TEXT' (10, "tk", purgeable, preload) "::library:tk.tcl";
+read 'TEXT' (11, "button", purgeable, preload) "::library:button.tcl";
+read 'TEXT' (12, "dialog", purgeable, preload) "::library:dialog.tcl";
+read 'TEXT' (13, "entry", purgeable, preload) "::library:entry.tcl";
+read 'TEXT' (14, "focus", purgeable, preload) "::library:focus.tcl";
+read 'TEXT' (15, "listbox", purgeable, preload) "::library:listbox.tcl";
+read 'TEXT' (16, "menu", purgeable, preload) "::library:menu.tcl";
+read 'TEXT' (17, "optionMenu", purgeable, preload) "::library:optMenu.tcl";
+read 'TEXT' (18, "palette", purgeable, preload) "::library:palette.tcl";
+read 'TEXT' (19, "scale", purgeable, preload) "::library:scale.tcl";
+read 'TEXT' (20, "scrollbar", purgeable, preload) "::library:scrlbar.tcl";
+read 'TEXT' (21, "tearoff", purgeable, preload) "::library:tearoff.tcl";
+read 'TEXT' (22, "text", purgeable, preload) "::library:text.tcl";
+read 'TEXT' (23, "tkerror", purgeable, preload) "::library:bgerror.tcl";
+read 'TEXT' (24, "Console", purgeable, preload) "::library:console.tcl";
+read 'TEXT' (25, "msgbox", purgeable, preload) "::library:msgbox.tcl";
+read 'TEXT' (26, "comdlg", purgeable, preload) "::library:comdlg.tcl";
+
+/*
+ * The following resource is used when creating the 'env' variable in
+ * the Macintosh environment. The creation mechanisim looks for the
+ * 'STR#' resource named "Tcl Environment Variables" rather than a
+ * specific resource number. (In other words, feel free to change the
+ * resource id if it conflicts with your application.) Each string in
+ * the resource must be of the form "KEYWORD=SOME STRING". See Tcl
+ * documentation for futher information about the env variable.
+ */
+
+/* A good example of something you may want to set is:
+ * "TCL_LIBRARY=My disk:etc."
+ */
+
+resource 'STR#' (128, "Tcl Environment Variables") {
+ { "SCHEDULE_NAME=Agent Controller Schedule",
+ "SCHEDULE_PATH=Lozoya:System Folder:Tcl Lib:Tcl-Scheduler"
+ };
+};
+
+/*
+ * 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
+ * default dialog will not be shown and the Tcl procedure is expected to
+ * create and manage an About Dialog box.
+ */
+
+resource 'DLOG' (128, "Default About Box", purgeable) {
+ {85, 107, 260, 412}, dBoxProc, visible, goAway, 0,
+ 128, "", centerMainScreen
+};
+
+resource 'DITL' (128, "About Box", purgeable) {
+ {
+ {143, 147, 167, 201}, Button {enabled, "Ok"},
+ { 14, 108, 137, 314}, StaticText {disabled,
+ "Wish - Windowing Shell" "\n" "based on Tcl "
+ TCL_PATCH_LEVEL " & Tk " TK_PATCH_LEVEL "\n\n"
+ "Ray Johnson & Jim Ingham" "\n"
+ "Scriptics Inc." "\n"
+ "jim.ingham@cygnus.com"},
+ { 19, 24, 119, 92}, Picture {enabled, 128}
+ }
+};
+
+data 'PICT' (128) {
+ $"13A4 0000 0000 0064 0044 0011 02FF 0C00"
+ $"FFFE 0000 0048 0000 0048 0000 0000 0000"
+ $"0064 0044 0000 0000 0001 000A 0000 0000"
+ $"0064 0044 0099 8044 0000 0000 0064 0044"
+ $"0000 0000 0000 0000 0048 0000 0048 0000"
+ $"0000 0008 0001 0008 0000 0000 0108 00D8"
+ $"0000 0000 0001 5A5A 8000 00FF 3736 FF00"
+ $"FF00 FF00 3535 FF00 FF00 CC00 3434 FF00"
+ $"FF00 9900 3333 FF00 FF00 6600 3736 FF00"
+ $"FF00 3300 3535 FF00 FF00 0000 3434 FF00"
+ $"CC00 FF00 3333 FF00 CC00 CC00 3736 FF00"
+ $"CC00 9900 3535 FF00 CC00 6600 FAFA FF00"
+ $"CC00 3300 3333 FF00 CC00 0000 3130 FF00"
+ $"9900 FF00 2F2F FF00 9900 CC00 FAFA FF00"
+ $"9900 9900 F9F9 FF00 9900 6600 3130 FF00"
+ $"9900 3300 2F2F FF00 9900 0000 2E2E FF00"
+ $"6600 FF00 F9F9 FF00 6600 CC00 3130 FF00"
+ $"6600 9900 2F2F FF00 6600 6600 2E2E FF00"
+ $"6600 3300 2D2D FF00 6600 0000 3130 FF00"
+ $"3300 FF00 2F2F FF00 3300 CC00 2E2E FF00"
+ $"3300 9900 2D2D FF00 3300 6600 3130 FF00"
+ $"3300 3300 2F2F FF00 3300 0000 2E2E FF00"
+ $"0000 FF00 2D2D FF00 0000 CC00 3130 FF00"
+ $"0000 9900 2F2F FF00 0000 6600 2E2E FF00"
+ $"0000 3300 2DF8 FF00 0000 0000 2B2A CC00"
+ $"FF00 FF00 2929 CC00 FF00 CC00 2828 CC00"
+ $"FF00 9900 27F8 CC00 FF00 6600 2B2A CC00"
+ $"FF00 3300 2929 CC00 FF00 0000 2828 CC00"
+ $"CC00 FF00 2727 CC00 CC00 CC00 2B2A CC00"
+ $"CC00 9900 2929 CC00 CC00 6600 2828 CC00"
+ $"CC00 3300 2727 CC00 CC00 0000 2B2A CC00"
+ $"9900 FF00 2929 CC00 9900 CC00 2828 CC00"
+ $"9900 9900 2727 CC00 9900 6600 DBDB CC00"
+ $"9900 3300 4747 CC00 9900 0000 4646 CC00"
+ $"6600 FF00 4545 CC00 6600 CC00 DBDB CC00"
+ $"6600 9900 4747 CC00 6600 6600 4646 CC00"
+ $"6600 3300 4545 CC00 6600 0000 DBDB CC00"
+ $"3300 FF00 4747 CC00 3300 CC00 4646 CC00"
+ $"3300 9900 4545 CC00 3300 6600 DBDB CC00"
+ $"3300 3300 4141 CC00 3300 0000 4040 CC00"
+ $"0000 FF00 3F3F CC00 0000 CC00 4342 CC00"
+ $"0000 9900 4141 CC00 0000 6600 4040 CC00"
+ $"0000 3300 3F3F CC00 0000 0000 4342 9900"
+ $"FF00 FF00 4141 9900 FF00 CC00 4040 9900"
+ $"FF00 9900 3F3F 9900 FF00 6600 4342 9900"
+ $"FF00 3300 4141 9900 FF00 0000 4040 9900"
+ $"CC00 FF00 3F3F 9900 CC00 CC00 4342 9900"
+ $"CC00 9900 4141 9900 CC00 6600 4040 9900"
+ $"CC00 3300 3F3F 9900 CC00 0000 4342 9900"
+ $"9900 FF00 4141 9900 9900 CC00 4040 9900"
+ $"9900 9900 3F3F 9900 9900 6600 3D3C 9900"
+ $"9900 3300 3B3B 9900 9900 0000 3A3A 9900"
+ $"6600 FF00 3939 9900 6600 CC00 3D3C 9900"
+ $"6600 9900 3B3B 9900 6600 6600 3A3A 9900"
+ $"6600 3300 3939 9900 6600 0000 3D3C 9900"
+ $"3300 FF00 3B3B 9900 3300 CC00 3A3A 9900"
+ $"3300 9900 3939 9900 3300 6600 3D3C 9900"
+ $"3300 3300 3B3B 9900 3300 0000 3A3A 9900"
+ $"0000 FF00 3939 9900 0000 CC00 3D3C 9900"
+ $"0000 9900 3B3B 9900 0000 6600 3A3A 9900"
+ $"0000 3300 3939 9900 0000 0000 3D3C 6600"
+ $"FF00 FF00 3B3B 6600 FF00 CC00 3A3A 6600"
+ $"FF00 9900 3939 6600 FF00 6600 3D3C 6600"
+ $"FF00 3300 3B3B 6600 FF00 0000 3A3A 6600"
+ $"CC00 FF00 3939 6600 CC00 CC00 3736 6600"
+ $"CC00 9900 3535 6600 CC00 6600 3434 6600"
+ $"CC00 3300 3333 6600 CC00 0000 3736 6600"
+ $"9900 FF00 3535 6600 9900 CC00 3434 6600"
+ $"9900 9900 3333 6600 9900 6600 3736 6600"
+ $"9900 3300 3535 6600 9900 0000 3434 6600"
+ $"6600 FF00 3333 6600 6600 CC00 3736 6600"
+ $"6600 9900 3535 6600 6600 6600 3434 6600"
+ $"6600 3300 3333 6600 6600 0000 3736 6600"
+ $"3300 FF00 3535 6600 3300 CC00 3434 6600"
+ $"3300 9900 3333 6600 3300 6600 3736 6600"
+ $"3300 3300 3535 6600 3300 0000 3434 6600"
+ $"0000 FF00 3333 6600 0000 CC00 3130 6600"
+ $"0000 9900 2F2F 6600 0000 6600 2E2E 6600"
+ $"0000 3300 F9F9 6600 0000 0000 3130 3300"
+ $"FF00 FF00 2F2F 3300 FF00 CC00 2E2E 3300"
+ $"FF00 9900 F9F9 3300 FF00 6600 3130 3300"
+ $"FF00 3300 2F2F 3300 FF00 0000 2E2E 3300"
+ $"CC00 FF00 2D2D 3300 CC00 CC00 3130 3300"
+ $"CC00 9900 2F2F 3300 CC00 6600 2E2E 3300"
+ $"CC00 3300 2D2D 3300 CC00 0000 3130 3300"
+ $"9900 FF00 2F2F 3300 9900 CC00 2E2E 3300"
+ $"9900 9900 2D2D 3300 9900 6600 3130 3300"
+ $"9900 3300 2F2F 3300 9900 0000 2E2E 3300"
+ $"6600 FF00 2DF8 3300 6600 CC00 2B2A 3300"
+ $"6600 9900 2929 3300 6600 6600 2828 3300"
+ $"6600 3300 27F8 3300 6600 0000 2B2A 3300"
+ $"3300 FF00 2929 3300 3300 CC00 2828 3300"
+ $"3300 9900 2727 3300 3300 6600 2B2A 3300"
+ $"3300 3300 2929 3300 3300 0000 2828 3300"
+ $"0000 FF00 2727 3300 0000 CC00 2B2A 3300"
+ $"0000 9900 2929 3300 0000 6600 2828 3300"
+ $"0000 3300 2727 3300 0000 0000 4948 0000"
+ $"FF00 FF00 4747 0000 FF00 CC00 4646 0000"
+ $"FF00 9900 4545 0000 FF00 6600 4948 0000"
+ $"FF00 3300 4747 0000 FF00 0000 4646 0000"
+ $"CC00 FF00 4545 0000 CC00 CC00 4948 0000"
+ $"CC00 9900 4747 0000 CC00 6600 4646 0000"
+ $"CC00 3300 4545 0000 CC00 0000 4342 0000"
+ $"9900 FF00 4141 0000 9900 CC00 4040 0000"
+ $"9900 9900 3F3F 0000 9900 6600 4342 0000"
+ $"9900 3300 4141 0000 9900 0000 4040 0000"
+ $"6600 FF00 3F3F 0000 6600 CC00 4342 0000"
+ $"6600 9900 4141 0000 6600 6600 4040 0000"
+ $"6600 3300 3F3F 0000 6600 0000 4342 0000"
+ $"3300 FF00 4141 0000 3300 CC00 4040 0000"
+ $"3300 9900 3F3F 0000 3300 6600 4342 0000"
+ $"3300 3300 4141 0000 3300 0000 4040 0000"
+ $"0000 FF00 3F3F 0000 0000 CC00 4342 0000"
+ $"0000 9900 4141 0000 0000 6600 4040 0000"
+ $"0000 3300 3F3F EE00 0000 0000 3D3C DD00"
+ $"0000 0000 3B3B BB00 0000 0000 3A3A AA00"
+ $"0000 0000 3939 8800 0000 0000 3D3C 7700"
+ $"0000 0000 3B3B 5500 0000 0000 3A3A 4400"
+ $"0000 0000 3939 2200 0000 0000 3D3C 1100"
+ $"0000 0000 3B3B 0000 EE00 0000 3A3A 0000"
+ $"DD00 0000 3939 0000 BB00 0000 3D3C 0000"
+ $"AA00 0000 3B3B 0000 8800 0000 3A3A 0000"
+ $"7700 0000 3939 0000 5500 0000 3D3C 0000"
+ $"4400 0000 3B3B 0000 2200 0000 3A3A 0000"
+ $"1100 0000 3939 0000 0000 EE00 3D3C 0000"
+ $"0000 DD00 3B3B 0000 0000 BB00 3A3A 0000"
+ $"0000 AA00 3939 0000 0000 8800 3D3C 0000"
+ $"0000 7700 3B3B 0000 0000 5500 3A3A 0000"
+ $"0000 4400 3939 0000 0000 2200 3736 0000"
+ $"0000 1100 3535 EE00 EE00 EE00 3434 DD00"
+ $"DD00 DD00 3333 BB00 BB00 BB00 3736 AA00"
+ $"AA00 AA00 3535 8800 8800 8800 3434 7700"
+ $"7700 7700 3333 5500 5500 5500 3736 4400"
+ $"4400 4400 3535 2200 2200 2200 3434 1100"
+ $"1100 1100 3333 0000 0000 0000 0000 0000"
+ $"0064 0044 0000 0000 0064 0044 0000 000A"
+ $"0000 0000 0064 0044 02BD 0013 E800 01F5"
+ $"F6FE 07FE 0E02 3232 33FD 3900 0EE6 001D"
+ $"FC00 01F5 F5FE 0700 08FE 0E02 3232 33FE"
+ $"3900 3AFC 40F2 4102 4033 07E9 0017 0100"
+ $"0EFC 40DC 4102 390E F5F5 0002 F5F5 F6FE"
+ $"0702 0E07 0016 0100 32D5 4104 4039 0E32"
+ $"33FD 3900 3AFC 40FC 4101 3200 0801 000E"
+ $"C141 010E 0008 0100 0EC1 4101 0800 0801"
+ $"000E C141 0107 0008 0100 0EC1 4101 0700"
+ $"0901 0007 C241 0240 F500 0E01 0007 E841"
+ $"0147 47DD 4102 4000 0012 0100 07F0 4100"
+ $"47FA 4101 3B3B DD41 0240 0000 1901 0007"
+ $"F141 0C47 3B0B 3B47 4141 4711 0505 3B47"
+ $"DF41 023A 0000 1701 00F6 F041 010B 0BFE"
+ $"4105 473B 0505 113B DE41 0239 0000 1A02"
+ $"00F5 40F3 410C 473B 053B 4741 4741 0B0B"
+ $"3B47 47DE 4102 3900 0018 0200 F540 F341"
+ $"0247 110B FE41 0447 1105 4147 DC41 0233"
+ $"0000 1B02 0000 40F3 4103 4711 1147 FE41"
+ $"0205 3547 F741 FD47 E941 0232 0000 1E02"
+ $"0000 40F2 4106 113B 4741 4735 0BF7 4106"
+ $"4741 390E 0E40 47EA 4102 0E00 0021 0200"
+ $"0040 F241 0711 3B47 4141 0B35 47F9 4102"
+ $"4740 07FE 0002 F640 47EB 4102 0E00 0023"
+ $"0200 0040 F341 0847 3541 4147 3B05 4147"
+ $"FA41 0947 3AF6 00F5 4F55 F50E 47EB 4102"
+ $"0700 0022 0200 003A F341 0147 3BFE 4101"
+ $"0B0B F941 0547 3AF5 0055 C8FE CE01 5640"
+ $"EB41 0207 0000 1F02 0000 39F0 4104 4741"
+ $"053B 47FB 4104 4740 F5F5 A4FC CE01 C85D"
+ $"EB41 02F6 0000 1F02 0000 39F0 4104 473B"
+ $"0541 47FC 4104 4740 07F6 C8FA CE00 64EC"
+ $"4103 40F5 0000 1C02 0000 39F0 4102 4711"
+ $"0BFA 4103 4708 2AC8 FACE 0164 D8EC 4100"
+ $"40FE 0025 0200 0039 EF41 020B 3B47 FC41"
+ $"0347 0FF5 A4FB CE02 C887 D8FC 41FE 47FC"
+ $"4100 47F9 4100 3AFE 0028 0200 0039 EF41"
+ $"020B 3B47 FD41 0347 3900 A4FA CE00 ABFA"
+ $"4109 3B11 3B41 4147 3B0B 3B47 FA41 0039"
+ $"FE00 2402 0000 33F1 4102 4741 0BFA 4101"
+ $"0779 F9CE 0064 FA41 0235 050B FD41 010B"
+ $"0BF9 4100 39FE 0028 0200 0032 F141 0247"
+ $"3B0B FC41 0247 39F6 F9CE 0187 D8FB 4103"
+ $"4741 050B FE41 0247 110B F941 0039 FE00"
+ $"2C02 0000 32F1 4102 473B 11FB 4101 0879"
+ $"FACE 05AA 4041 4147 47FE 410A 4741 0511"
+ $"4741 4147 3511 47FA 4100 32FE 002F 0200"
+ $"000E F141 0347 3B11 47FE 4103 4740 F6C8"
+ $"FACE 0564 D841 4039 39FE 4104 473B 053B"
+ $"47FE 4102 3541 47FA 4100 0EFE 0027 0200"
+ $"000E F141 0347 3B3B 47FE 4102 470F 79FA"
+ $"CE0C 8741 4032 F500 003A 4741 473B 05F2"
+ $"4100 0EFE 0027 0200 000E F141 0347 3B3B"
+ $"47FD 4101 0EA4 FACE 01AB AAFE C808 7900"
+ $"3947 4147 110B 47F3 4100 07FE 001C 0200"
+ $"000E EA41 0240 2BC8 F5CE 0881 0033 4741"
+ $"410B 3B47 F341 0007 FE00 1A02 0000 08EB"
+ $"4102 473A 55F4 CE06 5D00 3947 4741 0BF1"
+ $"4100 F6FE 001C 0200 0007 EB41 0247 3979"
+ $"F4CE 0739 0039 4747 3511 47F3 4101 40F5"
+ $"FE00 1C02 0000 07EB 4102 4739 A4F5 CE08"
+ $"AB0E 0040 4741 1141 47F3 4100 40FD 001B"
+ $"0200 0007 EB41 0247 39A4 F5CE 0787 0707"
+ $"4147 4111 47F2 4100 40FD 001B 0200 0007"
+ $"EB41 0247 39C8 F5CE 0763 F532 4747 3B3B"
+ $"47F2 4100 3AFD 001A 0300 00F6 40EC 4102"
+ $"4739 C8F5 CE05 39F5 4047 413B F041 0039"
+ $"FD00 1C03 0000 F540 EB41 0140 C8FD CE01"
+ $"C8A4 FCCE 03AB 080E 47ED 4100 39FD 001A"
+ $"FE00 0040 EB41 0040 FCCE 01A4 C8FC CE03"
+ $"FA07 4047 ED41 0032 FD00 1AFE 0000 40EA"
+ $"4100 AAFE CE02 87F9 C8FC CE02 560F 47EC"
+ $"4100 32FD 0019 FE00 0040 EA41 00AB FECE"
+ $"0264 56C8 FDCE 01C8 32EA 4100 0EFD 001B"
+ $"FE00 0040 ED41 030E 4047 87FE CE01 4055"
+ $"FCCE 01FA 40EA 4100 08FD 001A FE00 003A"
+ $"ED41 0807 0740 FBCE CEAB 3979 FDCE 00AB"
+ $"E841 0007 FD00 1CFE 0000 3AED 4108 0700"
+ $"F6A4 CECE 8733 79FD CE02 4147 47EA 4100"
+ $"07FD 001E FE00 0039 ED41 0807 2AA4 C8CE"
+ $"CE88 0E9D FECE 0364 1C39 39EB 4101 40F5"
+ $"FD00 1CFE 0000 39ED 4101 074F FDCE 0264"
+ $"F7A4 FECE 03AB 80F6 07EB 4100 40FC 001C"
+ $"FE00 0039 ED41 0108 79FE CE03 AB40 2BA4"
+ $"FCCE 02F7 0E47 EC41 0040 FC00 1CFE 0000"
+ $"39ED 4101 0879 FECE 03AB 40F6 C8FC CE02"
+ $"F615 47EC 4100 40FC 001E FE00 003A EE41"
+ $"0247 0E79 FECE 03AB 40F5 C8FD CE03 A4F5"
+ $"3A47 EC41 0040 FC00 1EFE 0000 3AEE 4102"
+ $"470E 56FE CE03 FB3A F6C8 FDCE 0280 F540"
+ $"EB41 0140 F5FD 001E FE00 0040 EE41 0947"
+ $"0F56 CECE C888 39F6 C8FD CE02 5601 40EB"
+ $"4101 40F5 FD00 1CFE 0000 40EE 4109 4739"
+ $"32CE CEC8 8839 2AC8 FDCE 0156 07E9 4100"
+ $"F6FD 001B FE00 0040 EE41 0847 3A32 CECE"
+ $"C864 152A FCCE 0132 07E9 4100 07FD 001A"
+ $"FE00 0040 ED41 0740 32AB CEC8 6439 4EFC"
+ $"CE01 3A07 E941 0007 FD00 1D03 0000 F540"
+ $"ED41 0740 0EAB CECE 640F 4EFD CE03 AB40"
+ $"0840 EA41 0007 FD00 1B03 0000 F540 EC41"
+ $"060F 81CE CE64 334E FDCE 02AB 400E E941"
+ $"000E FD00 1C02 0000 F6EC 4107 4715 FACE"
+ $"CE64 334E FDCE 0387 0F0E 47EA 4100 0EFD"
+ $"001C 0200 0007 EC41 0747 16F9 CEC8 6433"
+ $"4EFD CE03 6308 4047 EA41 000E FD00 1A02"
+ $"0000 07EB 4106 40F9 CEC8 6439 4EFD CE02"
+ $"3940 47E9 4100 32FD 001B 0200 0007 EA41"
+ $"0539 CECE 8839 F6FE CE04 AB41 4139 40EA"
+ $"4100 32FD 001C 0200 0007 EB41 0E47 3AC8"
+ $"CE88 39F6 C8CE CE64 15F6 F540 EA41 0033"
+ $"FD00 1A02 0000 07EA 410C 40A4 CE87 392A"
+ $"C8CE AB41 40F8 F6E9 4100 39FD 001B 0200"
+ $"000E EB41 0D47 41AB C887 39F5 C8CE ABAB"
+ $"CEA4 07E9 4100 39FD 001C 0200 000E ED41"
+ $"0947 3939 4787 C8AB 40F5 C8FD CE01 A40E"
+ $"E941 0039 FD00 1D02 0000 0EED 4109 473A"
+ $"0007 80CE AB40 F5C8 FDCE 0255 0E47 EA41"
+ $"0039 FD00 1B02 0000 0EEB 4107 0779 C8CE"
+ $"CE40 F6A4 FDCE 022B 3947 EA41 003A FD00"
+ $"1C02 0000 0EEC 4102 4739 79FE CE02 6407"
+ $"A4FE CE02 A407 40E9 4100 40FD 001A 0200"
+ $"0032 EA41 0632 A4CE CE88 0879 FECE 02F9"
+ $"0F47 E941 0040 FD00 1A02 0000 32EB 4107"
+ $"4740 F7C8 CE87 0E79 FECE 0132 40E8 4100"
+ $"40FD 0019 0200 0033 EA41 0B47 40F8 C8AB"
+ $"0E55 CECE 8015 47E8 4100 40FD 0017 0200"
+ $"0033 E941 0847 40F9 A439 4FCE CE5D E641"
+ $"0140 F5FE 0014 0200 0039 E841 0647 64FB"
+ $"392B C8AB E441 00F6 FE00 1102 0000 39E5"
+ $"4103 40F6 8764 E441 0007 FE00 1E02 0000"
+ $"39EB 4102 3A0E 0EFD 4102 0740 47F6 4104"
+ $"400F 0839 47F4 4100 07FE 0027 0200 0039"
+ $"FB41 0147 47F2 4102 0800 40FE 4102 0839"
+ $"47FC 4101 4747 FC41 0339 0039 47F4 4100"
+ $"07FE 0029 0200 0039 FB41 0140 39F3 4109"
+ $"470E F540 4141 470E 3347 FC41 0139 3AFD"
+ $"4104 4739 0039 47F4 4100 08FE 0036 0200"
+ $"003A FC41 0347 0E00 40FC 4102 4741 40FC"
+ $"4109 470E F540 4141 4733 0E47 FE41 0447"
+ $"4000 0E47 FE41 0447 3900 3941 FE40 F741"
+ $"000E FE00 3A02 0000 3AFD 410E 4740 0700"
+ $"0E40 4741 4147 390E 390E 40FE 4108 470E"
+ $"F540 4141 4739 0EFC 4103 0F00 0739 FE41"
+ $"0747 3900 3940 080F 39F7 4100 0EFE 0035"
+ $"0200 0040 FB41 020E 0040 FE41 0D47 4000"
+ $"3941 0032 4741 4147 0EF5 40FE 4101 4008"
+ $"FC41 023A 000E FD41 0547 3900 3939 33F5"
+ $"4100 0EFE 0039 0200 0040 FC41 0347 0E00"
+ $"40FE 4106 4732 0040 4139 40FE 4103 470E"
+ $"F540 FD41 0108 40FE 4104 4740 000E 47FE"
+ $"4106 4739 0007 F540 47F6 4100 32FE 003A"
+ $"0200 0040 FC41 0C47 0E00 4047 4141 470E"
+ $"0040 4747 FD41 0347 0EF5 40FE 410A 470E"
+ $"3947 4141 4740 000E 47FE 4107 4739 000E"
+ $"0007 4147 F741 0032 FE00 3802 0000 40FC"
+ $"4102 470E 00FD 4106 4739 003A 4740 39FE"
+ $"4102 470E F5FD 410A 4733 3347 4141 4740"
+ $"000E 47FE 4106 4739 0039 3900 0EF6 4100"
+ $"33FE 003A 0200 F540 FC41 0447 3200 0E39"
+ $"FD41 0B0E 0E40 333A 4741 413A 07F5 39FE"
+ $"4102 473A 0EFD 410F 40F5 0733 4041 4140"
+ $"0E00 0E40 0700 0E40 F841 0039 FE00 2902"
+ $"00F5 40FA 4101 3939 FB41 023A 3A40 FD41"
+ $"FD40 FD41 0240 0E40 FD41 0240 3940 FD41"
+ $"FA40 F741 0039 FE00 2A01 00F6 F941 0147"
+ $"47FB 4101 4747 FB41 0147 47FB 4101 3940"
+ $"FD41 0147 47FB 4100 47FE 4100 47F6 4100"
+ $"39FE 000D 0100 07E1 4100 40E4 4100 3AFE"
+ $"0009 0100 07C3 4100 3AFE 0009 0100 07C3"
+ $"4100 40FE 0009 0100 07C3 4100 40FE 0009"
+ $"0100 07C3 4100 40FE 000A 0100 0EC3 4103"
+ $"40F5 0000 0901 000E C241 02F6 0000 0901"
+ $"000E C241 0207 0000 0901 000E C241 0207"
+ $"0000 1101 000E ED41 FE40 003A F940 E241"
+ $"0207 0000 2B01 0032 F941 FE40 FE39 0632"
+ $"0E0E 0707 F6F5 F800 02F5 F5F6 FB07 FB0E"
+ $"0332 3233 33FB 3901 3A3A FB40 0207 0000"
+ $"0E0A 000E 3939 320E 0E07 07F6 F5C8 0002"
+ $"BD00 00FF"
+};
+
+/*
+ * Here is the custom file open dialog. This dialog is used instead of
+ * the default file dialog if the -filetypes flag is specified.
+ */
+
+resource 'DLOG' (130, purgeable) {
+ {0, 0, 195, 344}, dBoxProc, invisible, noGoAway, 0,
+ 130, "", noAutoCenter
+};
+
+resource 'DITL' (130, "File Open Box", purgeable) {
+ {
+ {135, 252, 155, 332}, Button {enabled, "Open"},
+ {104, 252, 124, 332}, Button {enabled, "Cancel"},
+ { 0, 0, 0, 0}, HelpItem {disabled, HMScanhdlg {130}},
+ { 8, 235, 24, 337}, UserItem {enabled},
+ { 32, 252, 52, 332}, Button {enabled, "Eject"},
+ { 60, 252, 80, 332}, Button {enabled, "Desktop"},
+ { 29, 12, 159, 230}, UserItem {enabled},
+ { 6, 12, 25, 230}, UserItem {enabled},
+ { 91, 251, 92, 333}, Picture {disabled, 11},
+ {168, 20, 187, 300}, Control {enabled, 131}
+ }
+};
+
+resource 'CNTL' (131, "File Types menu", purgeable) {
+ {168, 20, 187, 300},
+ popupTitleLeftJust,
+ visible,
+ 80,
+ 132,
+ popupMenuCDEFProc,
+ 0,
+ "File Type:"
+};
+
+
+resource 'MENU' (132, preload) {
+ 132,
+ textMenuProc,
+ 0xFFFF, enabled, "", {}
+};
diff --git a/macosx/tkMacOSXScale.c b/macosx/tkMacOSXScale.c
new file mode 100644
index 0000000..3c00610
--- /dev/null
+++ b/macosx/tkMacOSXScale.c
@@ -0,0 +1,431 @@
+/*
+ * tkMacOSXScale.c --
+ *
+ * This file implements the Macintosh specific portion of the
+ * scale widget.
+ *
+ * Copyright (c) 1996 by Sun Microsystems, Inc.
+ * Copyright (c) 1998-2000 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXScale.c,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#include "tkScale.h"
+#include "tkInt.h"
+#include <Carbon/Carbon.h>
+#include "tkMacOSXInt.h"
+
+/*
+ * Defines used in this file.
+ */
+#define slider 1110
+#define inSlider 1
+#define inInc 2
+#define inDecr 3
+
+/*
+ * Declaration of Macintosh specific scale structure.
+ */
+
+typedef struct MacScale {
+ TkScale info; /* Generic scale info. */
+ int flags; /* Flags. */
+ ControlRef scaleHandle; /* Handle to the Scale control struct. */
+} MacScale;
+
+/*
+ * Globals uses locally in this file.
+ */
+static ControlActionUPP scaleActionProc = NULL; /* Pointer to func. */
+
+/*
+ * Forward declarations for procedures defined later in this file:
+ */
+
+static void MacScaleEventProc _ANSI_ARGS_((ClientData clientData,
+ XEvent *eventPtr));
+static pascal void ScaleActionProc _ANSI_ARGS_((ControlRef theControl,
+ ControlPartCode partCode));
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpCreateScale --
+ *
+ * Allocate a new TkScale structure.
+ *
+ * Results:
+ * Returns a newly allocated TkScale structure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkScale *
+TkpCreateScale(tkwin)
+ Tk_Window tkwin;
+{
+ MacScale *macScalePtr;
+
+ macScalePtr = (MacScale *) ckalloc(sizeof(MacScale));
+ macScalePtr->scaleHandle = NULL;
+ if (scaleActionProc == NULL) {
+ scaleActionProc = NewControlActionUPP(ScaleActionProc);
+ }
+
+ Tk_CreateEventHandler(tkwin, ButtonPressMask,
+ MacScaleEventProc, (ClientData) macScalePtr);
+
+ return (TkScale *) macScalePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDestroyScale --
+ *
+ * Free Macintosh specific resources.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * The slider control is destroyed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpDestroyScale(scalePtr)
+ TkScale *scalePtr;
+{
+ MacScale *macScalePtr = (MacScale *) scalePtr;
+
+ /*
+ * Free Macintosh control.
+ */
+ if (macScalePtr->scaleHandle != NULL) {
+ DisposeControl(macScalePtr->scaleHandle);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDisplayScale --
+ *
+ * This procedure is invoked as an idle handler to redisplay
+ * the contents of a scale widget.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The scale gets redisplayed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpDisplayScale(clientData)
+ ClientData clientData; /* Widget record for scale. */
+{
+ TkScale *scalePtr = (TkScale *) clientData;
+ Tk_Window tkwin = scalePtr->tkwin;
+ Tcl_Interp *interp = scalePtr->interp;
+ int result;
+ char string[PRINT_CHARS];
+ MacScale *macScalePtr = (MacScale *) clientData;
+ Rect r;
+ WindowRef windowRef;
+ CGrafPtr destPort;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ MacDrawable *macDraw;
+ SInt16 initialValue;
+ SInt16 minValue;
+ SInt16 maxValue;
+ SInt16 procID;
+ SInt32 controlReference;
+ Boolean initiallyVisible=true;
+
+ fprintf(stderr,"TkpDisplayScale\n");
+ scalePtr->flags &= ~REDRAW_PENDING;
+ if ((scalePtr->tkwin == NULL) || !Tk_IsMapped(scalePtr->tkwin)) {
+ goto done;
+ }
+
+ /*
+ * Invoke the scale's command if needed.
+ */
+
+ Tcl_Preserve((ClientData) scalePtr);
+ if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) {
+ Tcl_Preserve((ClientData) interp);
+ sprintf(string, scalePtr->format, scalePtr->value);
+ result = Tcl_VarEval(interp, scalePtr->command, " ", string,
+ (char *) NULL);
+ if (result != TCL_OK) {
+ Tcl_AddErrorInfo(interp, "\n (command executed by scale)");
+ Tcl_BackgroundError(interp);
+ }
+ Tcl_Release((ClientData) interp);
+ }
+ scalePtr->flags &= ~INVOKE_COMMAND;
+ if (scalePtr->flags & SCALE_DELETED) {
+ Tcl_Release((ClientData) scalePtr);
+ return;
+ }
+ Tcl_Release((ClientData) scalePtr);
+
+ /*
+ * Now handle the part of redisplay that is the same for
+ * horizontal and vertical scales: border and traversal
+ * highlight.
+ */
+
+ if (scalePtr->highlightWidth != 0) {
+ GC gc;
+
+ gc = Tk_GCForColor(scalePtr->highlightColorPtr, Tk_WindowId(tkwin));
+ Tk_DrawFocusHighlight(tkwin, gc, scalePtr->highlightWidth,
+ Tk_WindowId(tkwin));
+ }
+ Tk_Draw3DRectangle(tkwin, Tk_WindowId(tkwin), scalePtr->bgBorder,
+ scalePtr->highlightWidth, scalePtr->highlightWidth,
+ Tk_Width(tkwin) - 2*scalePtr->highlightWidth,
+ Tk_Height(tkwin) - 2*scalePtr->highlightWidth,
+ scalePtr->borderWidth, scalePtr->relief);
+
+ /*
+ * Set up port for drawing Macintosh control.
+ */
+ macDraw = (MacDrawable *) Tk_WindowId(tkwin);
+ destPort=TkMacOSXGetDrawablePort(Tk_WindowId(tkwin));
+ windowRef=GetWindowFromPort(destPort);
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+ TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin));
+
+ /*
+ * Create Macintosh control.
+ */
+ if (macScalePtr->scaleHandle == NULL) {
+ fprintf(stderr,"Initialising scale\n");
+ r.left=macDraw->xOff;
+ r.top=macDraw->yOff;
+ r.right=macDraw->xOff+Tk_Width(tkwin) - scalePtr->inset;
+ r.bottom=macDraw->yOff+Tk_Height(tkwin) - scalePtr->inset;
+
+ initialValue=scalePtr->value;
+ minValue=scalePtr->toValue;
+ maxValue=scalePtr->fromValue;
+ procID=kControlSliderProc;
+ controlReference=(SInt32) macScalePtr;
+ macScalePtr->scaleHandle = NewControl(windowRef,
+ &r, "\p", initiallyVisible, initialValue,minValue,maxValue,
+ procID, controlReference);
+
+ /*
+ * If we are foremost than make us active.
+ */
+ if (windowRef==FrontWindow()) {
+ macScalePtr->flags |= ACTIVE;
+ }
+ }
+
+ /*
+ * Finally draw the control.
+ */
+ SetControlVisibility(macScalePtr->scaleHandle,true,true);
+ HiliteControl(macScalePtr->scaleHandle,0);
+ Draw1Control(macScalePtr->scaleHandle);
+
+ SetGWorld(saveWorld, saveDevice);
+done:
+ scalePtr->flags &= ~REDRAW_ALL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpScaleElement --
+ *
+ * Determine which part of a scale widget lies under a given
+ * point.
+ *
+ * Results:
+ * The return value is either TROUGH1, SLIDER, TROUGH2, or
+ * OTHER, depending on which of the scale's active elements
+ * (if any) is under the point at (x,y).
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpScaleElement(scalePtr, x, y)
+ TkScale *scalePtr; /* Widget record for scale. */
+ int x, y; /* Coordinates within scalePtr's window. */
+{
+ MacScale *macScalePtr = (MacScale *) scalePtr;
+ ControlPartCode part;
+ Point where;
+ Rect bounds;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ fprintf(stderr,"TkpScaleElement\n");
+
+ destPort = TkMacOSXGetDrawablePort(Tk_WindowId(scalePtr->tkwin));
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+
+ /*
+ * All of the calculations in this procedure mirror those in
+ * DisplayScrollbar. Be sure to keep the two consistent.
+ */
+
+ TkMacOSXWinBounds((TkWindow *) scalePtr->tkwin, &bounds);
+ where.h = x + bounds.left;
+ where.v = y + bounds.top;
+ part = TestControl(macScalePtr->scaleHandle, where);
+
+ SetGWorld(saveWorld, saveDevice);
+
+ fprintf (stderr,"ScalePart %d, pos ( %d %d )\n", part, where.h, where.v );
+
+ switch (part) {
+ case inSlider:
+ return SLIDER;
+ case inInc:
+ if (scalePtr->orient == ORIENT_VERTICAL) {
+ return TROUGH1;
+ } else {
+ return TROUGH2;
+ }
+ case inDecr:
+ if (scalePtr->orient == ORIENT_VERTICAL) {
+ return TROUGH2;
+ } else {
+ return TROUGH1;
+ }
+ default:
+ return OTHER;
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * MacScaleEventProc --
+ *
+ * This procedure is invoked by the Tk dispatcher for
+ * ButtonPress events on scales.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * When the window gets deleted, internal structures get
+ * cleaned up. When it gets exposed, it is redisplayed.
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+MacScaleEventProc(clientData, eventPtr)
+ ClientData clientData; /* Information about window. */
+ XEvent *eventPtr; /* Information about event. */
+{
+ MacScale *macScalePtr = (MacScale *) clientData;
+ Point where;
+ Rect bounds;
+ int part, x, y, dummy;
+ unsigned int state;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ Window dummyWin;
+
+ fprintf(stderr,"MacScaleEventProc\n" );
+ /*
+ * To call Macintosh control routines we must have the port
+ * set to the window containing the control. We will then test
+ * which part of the control was hit and act accordingly.
+ */
+ destPort = TkMacOSXGetDrawablePort(Tk_WindowId(macScalePtr->info.tkwin));
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+ TkMacOSXSetUpClippingRgn(Tk_WindowId(macScalePtr->info.tkwin));
+
+ TkMacOSXWinBounds((TkWindow *) macScalePtr->info.tkwin, &bounds);
+ where.h = eventPtr->xbutton.x + bounds.left;
+ where.v = eventPtr->xbutton.y + bounds.top;
+ fprintf(stderr,"calling TestControl\n");
+ part = TestControl(macScalePtr->scaleHandle, where);
+ if (part == 0) {
+ return;
+ }
+
+ part = TrackControl(macScalePtr->scaleHandle, where, scaleActionProc);
+
+ /*
+ * Update the value for the widget.
+ */
+ macScalePtr->info.value = GetControlValue(macScalePtr->scaleHandle);
+ /* TkScaleSetValue(&macScalePtr->info, macScalePtr->info.value, 1, 0); */
+
+ /*
+ * The TrackControl call will "eat" the ButtonUp event. We now
+ * generate a ButtonUp event so Tk will unset implicit grabs etc.
+ */
+ GetMouse(&where);
+ XQueryPointer(NULL, None, &dummyWin, &dummyWin, &x,
+ &y, &dummy, &dummy, &state);
+ TkGenerateButtonEvent(x, y, Tk_WindowId(macScalePtr->info.tkwin), state);
+
+ SetGWorld(saveWorld, saveDevice);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ScaleActionProc --
+ *
+ * Callback procedure used by the Macintosh toolbox call
+ * TrackControl. This call will update the display while
+ * the scrollbar is being manipulated by the user.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May change the display.
+ *
+ *--------------------------------------------------------------
+ */
+
+static pascal void
+ScaleActionProc(ControlRef theControl, ControlPartCode partCode)
+ /* ControlRef theControl; /* Handle to scrollbat control */
+ /* ControlPartCode partCode; /* Part of scrollbar that was "hit" */
+{
+ int value;
+ TkScale *scalePtr = (TkScale *) GetControlReference(theControl);
+
+ fprintf(stderr,"ScaleActionProc\n");
+ value = GetControlValue(theControl);
+ TkScaleSetValue(scalePtr, value, 1, 1);
+ Tcl_Preserve((ClientData) scalePtr);
+ Tcl_DoOneEvent(TCL_IDLE_EVENTS);
+ Tcl_Release((ClientData) scalePtr);
+}
+
diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c
new file mode 100644
index 0000000..12b4443
--- /dev/null
+++ b/macosx/tkMacOSXScrlbr.c
@@ -0,0 +1,1076 @@
+/*
+ * tkMacOSXScrollbar.c --
+ *
+ * This file implements the Macintosh specific portion of the scrollbar
+ * widget. The Macintosh scrollbar may also draw a windows grow
+ * region under certain cases.
+ *
+ * Copyright (c) 1996 by Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXScrlbr.c,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#include "tkScrollbar.h"
+#include "tkMacOSXInt.h"
+
+#include <Carbon/Carbon.h>
+
+#include "tkMacOSXDebug.h"
+/*
+ * The following definitions should really be in MacOS
+ * header files. They are included here as this is the only
+ * file that needs the declarations.
+ */
+typedef pascal void (*ThumbActionFunc)(void);
+
+typedef ThumbActionFunc ThumbActionUPP;
+
+enum {
+ uppThumbActionProcInfo = kPascalStackBased
+};
+
+#define NewThumbActionProc(userRoutine) ((ThumbActionUPP) (userRoutine))
+
+/*
+ * Minimum slider length, in pixels (designed to make sure that the slider
+ * is always easy to grab with the mouse).
+ */
+
+#define MIN_SLIDER_LENGTH 5
+#define MIN_SCROLLBAR_VALUE 0
+#define MAX_SCROLLBAR_VALUE 1000
+#define MAX_SCROLLBAR_DVALUE 1000.0
+
+/*
+ * Declaration of Windows specific scrollbar structure.
+ */
+
+typedef struct MacScrollbar {
+ TkScrollbar info; /* Generic scrollbar info */
+ ControlRef sbHandle; /* Opaque handle to the Scrollbar contol struct */
+ int macFlags; /* Various flags; see below */
+} MacScrollbar;
+
+/* Handle to the Scrollbar control structure */
+
+
+/*
+ * Flag bits for scrollbars on the Mac:
+ *
+ * ALREADY_DEAD: Non-zero means this scrollbar has been
+ * destroyed, but has not been cleaned up.
+ * IN_MODAL_LOOP: Non-zero means this scrollbar is in the middle
+ * of a modal loop.
+ * ACTIVE: Non-zero means this window is currently
+ * active (in the foreground).
+ * FLUSH_TOP: Flush with top of Mac window.
+ * FLUSH_BOTTOM: Flush with bottom of Mac window.
+ * FLUSH_RIGHT: Flush with right of Mac window.
+ * FLUSH_LEFT: Flush with left of Mac window.
+ * SCROLLBAR_GROW: Non-zero means this window draws the grow
+ * region for the toplevel window.
+ * AUTO_ADJUST: Non-zero means we automatically adjust
+ * the size of the widget to align correctly
+ * along a Mac window.
+ * DRAW_GROW: Non-zero means we draw the grow region.
+ */
+
+#define ALREADY_DEAD 1
+#define IN_MODAL_LOOP 2
+#define ACTIVE 4
+#define FLUSH_TOP 8
+#define FLUSH_BOTTOM 16
+#define FLUSH_RIGHT 32
+#define FLUSH_LEFT 64
+#define SCROLLBAR_GROW 128
+#define AUTO_ADJUST 256
+#define DRAW_GROW 512
+
+/*
+ * Globals uses locally in this file.
+ */
+static ControlActionUPP scrollActionProc = NULL; /* Pointer to func. */
+static ThumbActionUPP thumbActionProc = NULL; /* Pointer to func. */
+static TkScrollbar *activeScrollPtr = NULL; /* Non-null when in thumb */
+ /* proc. */
+/*
+ * Forward declarations for procedures defined later in this file:
+ */
+
+static pascal void ScrollbarActionProc _ANSI_ARGS_((ControlRef theControl, ControlPartCode partCode));
+static int ScrollbarBindProc _ANSI_ARGS_((ClientData clientData,
+ Tcl_Interp *interp, XEvent *eventPtr,
+ Tk_Window tkwin, KeySym keySym));
+static void ScrollbarEventProc _ANSI_ARGS_(( ClientData clientData, XEvent *eventPtr));
+static pascal void ThumbActionProc _ANSI_ARGS_((void));
+static void UpdateControlValues _ANSI_ARGS_((MacScrollbar *macScrollPtr));
+
+/*
+ * The class procedure table for the scrollbar widget. Leave the proc fields
+ * initialized to NULL, which should happen automatically because of the scope
+ * at which the variable is declared.
+ */
+
+Tk_ClassProcs tkpScrollbarProcs = {
+ sizeof(Tk_ClassProcs) /* size */
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpCreateScrollbar --
+ *
+ * Allocate a new TkScrollbar structure.
+ *
+ * Results:
+ * Returns a newly allocated TkScrollbar structure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkScrollbar *
+TkpCreateScrollbar(
+ Tk_Window tkwin) /* New Tk Window. */
+{
+ MacScrollbar * macScrollPtr;
+ TkWindow *winPtr = (TkWindow *)tkwin;
+
+ if (scrollActionProc == NULL) {
+ scrollActionProc = NewControlActionUPP (ScrollbarActionProc);
+ thumbActionProc = NewThumbActionProc(ThumbActionProc);
+ }
+
+ macScrollPtr = (MacScrollbar *) ckalloc(sizeof(MacScrollbar));
+ macScrollPtr->sbHandle = NULL;
+ macScrollPtr->macFlags = 0;
+
+ Tk_CreateEventHandler(tkwin, ActivateMask|ExposureMask|
+ StructureNotifyMask|FocusChangeMask,
+ ScrollbarEventProc, (ClientData) macScrollPtr);
+
+ if (!Tcl_GetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL)) {
+ Tcl_SetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL, (ClientData)1);
+ TkCreateBindingProcedure(winPtr->mainPtr->interp,
+ winPtr->mainPtr->bindingTable,
+ (ClientData)Tk_GetUid("Scrollbar"), "<ButtonPress>",
+ ScrollbarBindProc, NULL, NULL);
+ }
+ return (TkScrollbar *) macScrollPtr;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkpDisplayScrollbar --
+ *
+ * This procedure redraws the contents of a scrollbar window.
+ * It is invoked as a do-when-idle handler, so it only runs
+ * when there's nothing else for the application to do.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Information appears on the screen.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TkpDisplayScrollbar(
+ ClientData clientData) /* Information about window. */
+{
+ TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
+ MacScrollbar *macScrollPtr = (MacScrollbar *) clientData;
+ Tk_Window tkwin = scrollPtr->tkwin;
+
+ MacDrawable *macDraw;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ WindowRef windowRef;
+
+ if ((scrollPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
+ goto done;
+ }
+
+ /*
+ * Draw the focus or any 3D relief we may have.
+ */
+ if (scrollPtr->highlightWidth != 0) {
+ GC fgGC, bgGC;
+
+ bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr,
+ Tk_WindowId(tkwin));
+
+ if (scrollPtr->flags & GOT_FOCUS) {
+ fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr,
+ Tk_WindowId(tkwin));
+ TkpDrawHighlightBorder(tkwin, fgGC, bgGC, scrollPtr->highlightWidth,
+ Tk_WindowId(tkwin));
+ } else {
+ TkpDrawHighlightBorder(tkwin, bgGC, bgGC, scrollPtr->highlightWidth,
+ Tk_WindowId(tkwin));
+ }
+ }
+ Tk_Draw3DRectangle(tkwin, Tk_WindowId(tkwin), scrollPtr->bgBorder,
+ scrollPtr->highlightWidth, scrollPtr->highlightWidth,
+ Tk_Width(tkwin) - 2*scrollPtr->highlightWidth,
+ Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,
+ scrollPtr->borderWidth, scrollPtr->relief);
+
+ /*
+ * Set up port for drawing Macintosh control.
+ */
+ macDraw = (MacDrawable *) Tk_WindowId(tkwin);
+ destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin));
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+ TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin));
+
+ if (macScrollPtr->sbHandle == NULL) {
+ Rect r;
+ SInt16 initialValue;
+ SInt16 minValue;
+ SInt16 maxValue;
+ SInt16 procID;
+ WindowRef frontNonFloating;
+
+ r.left = r.top = 0;
+ r.right = r.bottom = 1;
+
+ minValue = MIN_SCROLLBAR_VALUE;
+ maxValue = MAX_SCROLLBAR_VALUE;
+ initialValue = (minValue + maxValue)/2;
+ procID = kControlScrollBarLiveProc;
+
+ windowRef = GetWindowFromPort(destPort);
+ macScrollPtr->sbHandle = NewControl(windowRef, &r, "\p",
+ false, initialValue,minValue,maxValue,
+ procID, (SInt32) scrollPtr);
+
+ /*
+ * If we are foremost then make us active.
+ */
+
+ frontNonFloating = FrontNonFloatingWindow();
+
+ if ((windowRef == FrontWindow()) || TkpIsWindowFloating(windowRef)) {
+ macScrollPtr->macFlags |= ACTIVE;
+ }
+ }
+
+ /*
+ * Update the control values before we draw.
+ */
+ windowRef = GetControlOwner (macScrollPtr->sbHandle);
+ UpdateControlValues(macScrollPtr);
+
+ if (macScrollPtr->macFlags & ACTIVE) {
+ Draw1Control(macScrollPtr->sbHandle);
+ if (macScrollPtr->macFlags & DRAW_GROW) {
+ DrawGrowIcon(windowRef);
+ }
+ } else {
+ HiliteControl (macScrollPtr->sbHandle, 255 );
+ Draw1Control(macScrollPtr->sbHandle);
+ if (macScrollPtr->macFlags & DRAW_GROW) {
+ DrawGrowIcon(windowRef);
+ Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), scrollPtr->bgBorder,
+ Tk_Width(tkwin) - 13, Tk_Height(tkwin) - 13,
+ Tk_Width(tkwin), Tk_Height(tkwin),
+ 0, TK_RELIEF_FLAT);
+ }
+ }
+
+ SetGWorld(saveWorld, saveDevice);
+
+ done:
+ scrollPtr->flags &= ~REDRAW_PENDING;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpConfigureScrollbar --
+ *
+ * This procedure is called after the generic code has finished
+ * processing configuration options, in order to configure
+ * platform specific options.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpConfigureScrollbar(scrollPtr)
+ register TkScrollbar *scrollPtr; /* Information about widget; may or
+ * may not already have values for
+ * some fields. */
+{
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpComputeScrollbarGeometry --
+ *
+ * After changes in a scrollbar's size or configuration, this
+ * procedure recomputes various geometry information used in
+ * displaying the scrollbar.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The scrollbar will be displayed differently.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpComputeScrollbarGeometry(
+ register TkScrollbar *scrollPtr) /* Scrollbar whose geometry may
+ * have changed. */
+{
+ MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr;
+ int width, fieldLength, adjust = 0;
+
+ if (scrollPtr->highlightWidth < 0) {
+ scrollPtr->highlightWidth = 0;
+ }
+ scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;
+ width = (scrollPtr->vertical) ? Tk_Width(scrollPtr->tkwin)
+ : Tk_Height(scrollPtr->tkwin);
+ scrollPtr->arrowLength = width - 2*scrollPtr->inset + 1;
+ fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin)
+ : Tk_Width(scrollPtr->tkwin))
+ - 2*(scrollPtr->arrowLength + scrollPtr->inset);
+ if (fieldLength < 0) {
+ fieldLength = 0;
+ }
+ scrollPtr->sliderFirst = fieldLength*scrollPtr->firstFraction;
+ scrollPtr->sliderLast = fieldLength*scrollPtr->lastFraction;
+
+ /*
+ * Adjust the slider so that some piece of it is always
+ * displayed in the scrollbar and so that it has at least
+ * a minimal width (so it can be grabbed with the mouse).
+ */
+
+ if (scrollPtr->sliderFirst > (fieldLength - 2*scrollPtr->borderWidth)) {
+ scrollPtr->sliderFirst = fieldLength - 2*scrollPtr->borderWidth;
+ }
+ if (scrollPtr->sliderFirst < 0) {
+ scrollPtr->sliderFirst = 0;
+ }
+ if (scrollPtr->sliderLast < (scrollPtr->sliderFirst
+ + MIN_SLIDER_LENGTH)) {
+ scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH;
+ }
+ if (scrollPtr->sliderLast > fieldLength) {
+ scrollPtr->sliderLast = fieldLength;
+ }
+ scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset;
+ scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset;
+
+ /*
+ * Register the desired geometry for the window (leave enough space
+ * for the two arrows plus a minimum-size slider, plus border around
+ * the whole window, if any). Then arrange for the window to be
+ * redisplayed.
+ */
+
+ if (scrollPtr->vertical) {
+ if ((macScrollPtr->macFlags & AUTO_ADJUST) &&
+ (macScrollPtr->macFlags & (FLUSH_RIGHT|FLUSH_LEFT))) {
+ adjust--;
+ }
+ Tk_GeometryRequest(scrollPtr->tkwin,
+ scrollPtr->width + 2*scrollPtr->inset + adjust,
+ 2*(scrollPtr->arrowLength + scrollPtr->borderWidth
+ + scrollPtr->inset));
+ } else {
+ if ((macScrollPtr->macFlags & AUTO_ADJUST) &&
+ (macScrollPtr->macFlags & (FLUSH_TOP|FLUSH_BOTTOM))) {
+ adjust--;
+ }
+ Tk_GeometryRequest(scrollPtr->tkwin,
+ 2*(scrollPtr->arrowLength + scrollPtr->borderWidth
+ + scrollPtr->inset), scrollPtr->width + 2*scrollPtr->inset + adjust);
+ }
+ Tk_SetInternalBorder(scrollPtr->tkwin, scrollPtr->inset);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDestroyScrollbar --
+ *
+ * Free data structures associated with the scrollbar control.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpDestroyScrollbar(
+ TkScrollbar *scrollPtr) /* Scrollbar to destroy. */
+{
+ MacScrollbar *macScrollPtr = (MacScrollbar *)scrollPtr;
+
+ if (macScrollPtr->sbHandle != NULL) {
+ if (!(macScrollPtr->macFlags & IN_MODAL_LOOP)) {
+ DisposeControl(macScrollPtr->sbHandle);
+ macScrollPtr->sbHandle = NULL;
+ }
+ }
+ macScrollPtr->macFlags |= ALREADY_DEAD;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkpScrollbarPosition --
+ *
+ * Determine the scrollbar element corresponding to a
+ * given position.
+ *
+ * Results:
+ * One of TOP_ARROW, TOP_GAP, etc., indicating which element
+ * of the scrollbar covers the position given by (x, y). If
+ * (x,y) is outside the scrollbar entirely, then OUTSIDE is
+ * returned.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+int
+TkpScrollbarPosition(
+ TkScrollbar *scrollPtr, /* Scrollbar widget record. */
+ int x, int y) /* Coordinates within scrollPtr's
+ * window. */
+{
+ MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr;
+ GWorldPtr destPort;
+ int length, width, tmp, inactive = false;
+ ControlPartCode part;
+ Point where;
+ Rect bounds;
+ int x0, y0;
+
+ x0 = x;
+ y0 = y;
+
+ if (scrollPtr->vertical) {
+ length = Tk_Height(scrollPtr->tkwin);
+ width = Tk_Width(scrollPtr->tkwin);
+ } else {
+ tmp = x;
+ x = y;
+ y = tmp;
+ length = Tk_Width(scrollPtr->tkwin);
+ width = Tk_Height(scrollPtr->tkwin);
+ }
+
+ if ((x < scrollPtr->inset) || (x >= (width - scrollPtr->inset))
+ || (y < scrollPtr->inset) || (y >= (length - scrollPtr->inset))) {
+ return OUTSIDE;
+ }
+
+ /*
+ * All of the calculations in this procedure mirror those in
+ * DisplayScrollbar. Be sure to keep the two consistent. On the
+ * Macintosh we use the OS call TestControl to do this mapping.
+ * For TestControl to work, the scrollbar must be active and must
+ * be in the current port.
+ */
+
+ destPort = TkMacOSXGetDrawablePort(Tk_WindowId(scrollPtr->tkwin));
+ SetGWorld(destPort, NULL);
+ UpdateControlValues(macScrollPtr);
+ if ( GetControlHilite(macScrollPtr->sbHandle) == 255 ) {
+ inactive = true;
+ HiliteControl(macScrollPtr->sbHandle, 0 );
+ }
+
+ TkMacOSXWinBounds((TkWindow *) scrollPtr->tkwin, &bounds);
+ where.h = x0 + bounds.left;
+ where.v = y0 + bounds.top;
+ part = TestControl(((MacScrollbar *) scrollPtr)->sbHandle, where);
+ if (inactive) {
+ HiliteControl(macScrollPtr->sbHandle, 255 );
+ }
+ switch (part) {
+ case kControlUpButtonPart:
+ return TOP_ARROW;
+ case kControlPageUpPart:
+ return TOP_GAP;
+ case kControlIndicatorPart:
+ return SLIDER;
+ case kControlPageDownPart:
+ return BOTTOM_GAP;
+ case kControlDownButtonPart:
+ return BOTTOM_ARROW;
+ default:
+ return OUTSIDE;
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ThumbActionProc --
+ *
+ * Callback procedure used by the Macintosh toolbox call
+ * TrackControl. This call is used to track the thumb of
+ * the scrollbar. Unlike the ScrollbarActionProc function
+ * this function is called once and basically takes over
+ * tracking the scrollbar from the control. This is done
+ * to avoid conflicts with what the control plans to draw.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May change the display.
+ *
+ *--------------------------------------------------------------
+ */
+
+static pascal void
+ThumbActionProc()
+{
+ register TkScrollbar *scrollPtr = activeScrollPtr;
+ register MacScrollbar *macScrollPtr = (MacScrollbar *) activeScrollPtr;
+ Tcl_DString cmdString;
+ int origValue, trackBarPin;
+ double thumbWidth, newFirstFraction, trackBarSize;
+ char valueString[40];
+ Point currentPoint = { 0, 0 };
+ Rect trackRect;
+ Tcl_Interp *interp;
+ MouseTrackingResult trackingResult;
+ OSErr err;
+
+ if (scrollPtr == NULL) {
+ return;
+ }
+
+ Tcl_DStringInit(&cmdString);
+
+ /*
+ * First compute values that will remain constant during the tracking
+ * of the thumb. The variable trackBarSize is the length of the scrollbar
+ * minus the 2 arrows and half the width of the thumb on both sides
+ * (3 * arrowLength). The variable trackBarPin is the lower starting point
+ * of the drag region.
+ *
+ * Note: the arrowLength is equal to the thumb width of a Mac scrollbar.
+ */
+
+ origValue = GetControlValue(macScrollPtr->sbHandle);
+ GetControlBounds(macScrollPtr->sbHandle, &trackRect);
+ if (scrollPtr->vertical == true) {
+ trackBarSize = (double) (trackRect.bottom - trackRect.top
+ - (scrollPtr->arrowLength * 3));
+ trackBarPin = trackRect.top + scrollPtr->arrowLength
+ + (scrollPtr->arrowLength / 2);
+ InsetRect(&trackRect, -25, -113);
+
+ } else {
+ trackBarSize = (double) (trackRect.right - trackRect.left
+ - (scrollPtr->arrowLength * 3));
+ trackBarPin = trackRect.left + scrollPtr->arrowLength
+ + (scrollPtr->arrowLength / 2);
+ InsetRect(&trackRect, -113, -25);
+ }
+
+ /*
+ * Track the mouse while the button is held down. If the mouse is moved,
+ * we calculate the value that should be passed to the "command" part of
+ * the scrollbar.
+ */
+
+ do {
+ err = TrackMouseLocationWithOptions(NULL,
+ kTrackMouseLocationOptionDontConsumeMouseUp,
+ kEventDurationForever,
+ &currentPoint,
+ NULL,
+ &trackingResult);
+
+ if ((err==noErr)
+ && ((trackingResult == kMouseTrackingMouseDragged)
+ || (trackingResult == kMouseTrackingMouseMoved))) {
+ /*
+ * Calculating this value is a little tricky. We need to calculate a
+ * value for where the thumb would be in a Motif widget (variable
+ * thumb). This value is what the "command" expects and is what will
+ * be resent to the scrollbar to update its value.
+ */
+ thumbWidth = scrollPtr->lastFraction - scrollPtr->firstFraction;
+ if (PtInRect(currentPoint, &trackRect)) {
+ if (scrollPtr->vertical == true) {
+ newFirstFraction = (1.0 - thumbWidth) *
+ ((double) (currentPoint.v - trackBarPin) / trackBarSize);
+ } else {
+ newFirstFraction = (1.0 - thumbWidth) *
+ ((double) (currentPoint.h - trackBarPin) / trackBarSize);
+ }
+ } else {
+ newFirstFraction = ((double) origValue / MAX_SCROLLBAR_DVALUE)
+ * (1.0 - thumbWidth);
+ }
+ sprintf(valueString, "%g", newFirstFraction);
+ Tcl_DStringSetLength(&cmdString, 0);
+ Tcl_DStringAppend(&cmdString, scrollPtr->command,
+ scrollPtr->commandSize);
+ Tcl_DStringAppendElement(&cmdString, "moveto");
+ Tcl_DStringAppendElement(&cmdString, valueString);
+ interp = scrollPtr->interp;
+ Tcl_Preserve((ClientData) interp);
+ Tcl_GlobalEval(interp, cmdString.string);
+ Tcl_Release((ClientData) interp);
+ Tcl_DStringSetLength(&cmdString, 0);
+ Tcl_DStringAppend(&cmdString, "update idletasks",
+ strlen("update idletasks"));
+ Tcl_Preserve((ClientData) interp);
+ Tcl_GlobalEval(interp, cmdString.string);
+ Tcl_Release((ClientData) interp);
+ }
+ } while ((err==noErr) && trackingResult!=kMouseTrackingMouseReleased );
+
+ Tcl_DStringFree(&cmdString);
+ return;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ScrollbarActionProc --
+ *
+ * Callback procedure used by the Macintosh toolbox call
+ * TrackControl. This call will update the display while
+ * the scrollbar is being manipulated by the user.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May change the display.
+ *
+ *--------------------------------------------------------------
+ */
+
+static pascal void
+ScrollbarActionProc(
+ ControlRef theControl, /* Handle to scrollbat control */
+ ControlPartCode partCode) /* Part of scrollbar that was "hit" */
+{
+ TkScrollbar *scrollPtr = (TkScrollbar *) GetControlReference(theControl);
+ Tcl_DString cmdString;
+
+ Tcl_DStringInit(&cmdString);
+ Tcl_DStringAppend(&cmdString, scrollPtr->command,
+ scrollPtr->commandSize);
+
+ if ( partCode == kControlUpButtonPart ||
+ partCode == kControlDownButtonPart ) {
+ Tcl_DStringAppendElement(&cmdString, "scroll");
+ Tcl_DStringAppendElement(&cmdString,
+ (partCode == kControlUpButtonPart ) ? "-1" : "1");
+ Tcl_DStringAppendElement(&cmdString, "unit");
+ } else if (partCode == kControlPageUpPart || partCode == kControlPageDownPart ) {
+ Tcl_DStringAppendElement(&cmdString, "scroll");
+ Tcl_DStringAppendElement(&cmdString,
+ (partCode == kControlPageUpPart ) ? "-1" : "1");
+ Tcl_DStringAppendElement(&cmdString, "page");
+ }
+ Tcl_Preserve((ClientData) scrollPtr->interp);
+ Tcl_DStringAppend(&cmdString, "; update idletasks",
+ strlen("; update idletasks"));
+ Tcl_GlobalEval(scrollPtr->interp, cmdString.string);
+ Tcl_Release((ClientData) scrollPtr->interp);
+
+ Tcl_DStringFree(&cmdString);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ScrollbarBindProc --
+ *
+ * This procedure is invoked when the default <ButtonPress>
+ * binding on the Scrollbar bind tag fires.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The event enters a modal loop.
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+ScrollbarBindProc(
+ ClientData clientData, /* Not used. */
+ Tcl_Interp *interp, /* Interp with binding. */
+ XEvent *eventPtr, /* X event that triggered binding. */
+ Tk_Window tkwin, /* Target window for event. */
+ KeySym keySym) /* The KeySym if a key event. */
+{
+ TkWindow *winPtr = (TkWindow*)tkwin;
+ TkScrollbar *scrollPtr = (TkScrollbar *) winPtr->instanceData;
+ MacScrollbar *macScrollPtr = (MacScrollbar *) winPtr->instanceData;
+
+ Tcl_Preserve((ClientData)scrollPtr);
+ macScrollPtr->macFlags |= IN_MODAL_LOOP;
+
+ if (eventPtr->type == ButtonPress) {
+ Point where;
+ Rect bounds;
+ int part, x, y, dummy;
+ unsigned int state;
+ CGrafPtr saveWorld;
+ GDHandle saveDevice;
+ GWorldPtr destPort;
+ Window window;
+
+ /*
+ * To call Macintosh control routines we must have the port
+ * set to the window containing the control. We will then test
+ * which part of the control was hit and act accordingly.
+ */
+ destPort = TkMacOSXGetDrawablePort(Tk_WindowId(scrollPtr->tkwin));
+ GetGWorld(&saveWorld, &saveDevice);
+ SetGWorld(destPort, NULL);
+ TkMacOSXSetUpClippingRgn(Tk_WindowId(scrollPtr->tkwin));
+
+ TkMacOSXWinBounds((TkWindow *) scrollPtr->tkwin, &bounds);
+ where.h = eventPtr->xbutton.x + bounds.left;
+ where.v = eventPtr->xbutton.y + bounds.top;
+ part = TestControl(macScrollPtr->sbHandle, where);
+ if (part == kControlIndicatorPart && scrollPtr->jump == false) {
+ /*
+ * Case 1: In thumb, no jump scrolling. Call track control
+ * with the thumb action proc which will do most of the work.
+ * Set the global activeScrollPtr to the current control
+ * so the callback may have access to it.
+ */
+ activeScrollPtr = scrollPtr;
+ part = TrackControl(macScrollPtr->sbHandle, where,
+ (ControlActionUPP) thumbActionProc);
+ activeScrollPtr = NULL;
+ } else if (part == kControlIndicatorPart) {
+ /*
+ * Case 2: in thumb with jump scrolling. Call TrackControl
+ * with a NULL action proc. Use the new value of the control
+ * to set update the control.
+ */
+ part = TrackControl(macScrollPtr->sbHandle, where, NULL);
+ if (part == kControlIndicatorPart) {
+ double newFirstFraction, thumbWidth;
+ Tcl_DString cmdString;
+ char valueString[TCL_DOUBLE_SPACE];
+
+ /*
+ * The following calculation takes the new control
+ * value and maps it to what Tk needs for its variable
+ * thumb size representation.
+ */
+ thumbWidth = scrollPtr->lastFraction
+ - scrollPtr->firstFraction;
+ newFirstFraction = (1.0 - thumbWidth) *
+ ((double) GetControlValue(macScrollPtr->sbHandle) / MAX_SCROLLBAR_DVALUE);
+ sprintf(valueString, "%g", newFirstFraction);
+
+ Tcl_DStringInit(&cmdString);
+ Tcl_DStringAppend(&cmdString, scrollPtr->command,
+ strlen(scrollPtr->command));
+ Tcl_DStringAppendElement(&cmdString, "moveto");
+ Tcl_DStringAppendElement(&cmdString, valueString);
+ Tcl_DStringAppend(&cmdString, "; update idletasks",
+ strlen("; update idletasks"));
+
+ interp = scrollPtr->interp;
+ Tcl_Preserve((ClientData) interp);
+ Tcl_GlobalEval(interp, cmdString.string);
+ Tcl_Release((ClientData) interp);
+ Tcl_DStringFree(&cmdString);
+ }
+ } else if (part != 0) {
+ /*
+ * Case 3: in any other part of the scrollbar. We call
+ * TrackControl with the scrollActionProc which will do
+ * most all the work.
+ */
+ TrackControl(macScrollPtr->sbHandle, where, scrollActionProc);
+ HiliteControl(macScrollPtr->sbHandle, 0);
+ }
+
+ /*
+ * The TrackControl call will "eat" the ButtonUp event. We now
+ * generate a ButtonUp event so Tk will unset implicit grabs etc.
+ */
+ GetMouse(&where);
+ XQueryPointer(NULL, None, &window, &window, &x,
+ &y, &dummy, &dummy, &state);
+ window = Tk_WindowId(scrollPtr->tkwin);
+ TkGenerateButtonEvent(x, y, window, state);
+
+ SetGWorld(saveWorld, saveDevice);
+ }
+
+ if (macScrollPtr->sbHandle && (macScrollPtr->macFlags & ALREADY_DEAD)) {
+ DisposeControl(macScrollPtr->sbHandle);
+ macScrollPtr->sbHandle = NULL;
+ }
+ macScrollPtr->macFlags &= ~IN_MODAL_LOOP;
+ Tcl_Release((ClientData)scrollPtr);
+
+ return TCL_OK;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ScrollbarEventProc --
+ *
+ * This procedure is invoked by the Tk dispatcher for various
+ * events on scrollbars.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * When the window gets deleted, internal structures get
+ * cleaned up. When it gets exposed, it is redisplayed.
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+ScrollbarEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
+{
+ TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
+ MacScrollbar *macScrollPtr = (MacScrollbar *) clientData;
+
+ if (eventPtr->type == UnmapNotify) {
+ TkMacOSXSetScrollbarGrow((TkWindow *) scrollPtr->tkwin, false);
+ } else if (eventPtr->type == ActivateNotify) {
+ macScrollPtr->macFlags |= ACTIVE;
+ TkScrollbarEventuallyRedraw((ClientData) scrollPtr);
+ } else if (eventPtr->type == DeactivateNotify) {
+ macScrollPtr->macFlags &= ~ACTIVE;
+ TkScrollbarEventuallyRedraw((ClientData) scrollPtr);
+ } else {
+ TkScrollbarEventProc(clientData, eventPtr);
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * UpdateControlValues --
+ *
+ * This procedure updates the Macintosh scrollbar control
+ * to display the values defined by the Tk scrollbar.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The Macintosh control is updated.
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+UpdateControlValues(
+ MacScrollbar *macScrollPtr) /* Scrollbar data struct. */
+{
+ TkScrollbar *scrollPtr = (TkScrollbar *) macScrollPtr;
+ Tk_Window tkwin = scrollPtr->tkwin;
+ MacDrawable * macDraw = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin);
+ WindowRef windowRef = GetControlOwner(macScrollPtr->sbHandle);
+ double middle;
+ SInt32 viewSize;
+ int flushRight = false;
+ int flushBottom = false;
+ Rect contrlRect, portRect;
+ UInt8 contrlHilite;
+
+ /*
+ * We can't use the Macintosh commands SizeControl and MoveControl as these
+ * calls will also cause a redraw which in our case will also cause
+ * flicker. To avoid this we adjust the control record directly. The
+ * Draw1Control command appears to just draw where ever the control says to
+ * draw so this seems right.
+ *
+ * NOTE: changing the control record directly may not work when
+ * Apple releases the Copland version of the MacOS (or when hell is cold).
+ */
+
+ contrlRect.left = macDraw->xOff + scrollPtr->inset;
+ contrlRect.top = macDraw->yOff + scrollPtr->inset;
+ contrlRect.right = macDraw->xOff + Tk_Width(tkwin) - scrollPtr->inset;
+ contrlRect.bottom = macDraw->yOff + Tk_Height(tkwin) - scrollPtr->inset;
+
+ SetControlBounds(macScrollPtr->sbHandle, &contrlRect );
+
+ /*
+ * To make Tk applications look more like Macintosh applications without
+ * requiring additional work by the Tk developer we do some cute tricks.
+ * The first trick plays with the size of the widget to get it to overlap
+ * with the side of the window by one pixel (we don't do this if the placer
+ * is the geometry manager). The second trick shrinks the scrollbar if it
+ * it covers the area of the grow region ao the scrollbar can also draw
+ * the grow region if need be.
+ */
+ if (!strcmp(macDraw->winPtr->geomMgrPtr->name, "place")) {
+ macScrollPtr->macFlags &= AUTO_ADJUST;
+ } else {
+ macScrollPtr->macFlags |= AUTO_ADJUST;
+ }
+ GetPortBounds ( GetWindowPort ( windowRef ), &portRect );
+ if ( portRect.left == contrlRect.left ) {
+ if (macScrollPtr->macFlags & AUTO_ADJUST) {
+ contrlRect.left--;
+ SetControlBounds ( macScrollPtr->sbHandle, &contrlRect );
+ }
+ if (!(macScrollPtr->macFlags & FLUSH_LEFT)) {
+ macScrollPtr->macFlags |= FLUSH_LEFT;
+ if (scrollPtr->vertical) {
+ TkpComputeScrollbarGeometry(scrollPtr);
+ }
+ }
+ } else if (macScrollPtr->macFlags & FLUSH_LEFT) {
+ macScrollPtr->macFlags &= ~FLUSH_LEFT;
+ if (scrollPtr->vertical) {
+ TkpComputeScrollbarGeometry(scrollPtr);
+ }
+ }
+
+ if (portRect.top == contrlRect.top) {
+ if (macScrollPtr->macFlags & AUTO_ADJUST) {
+ contrlRect.top--;
+ }
+ if (!(macScrollPtr->macFlags & FLUSH_TOP)) {
+ macScrollPtr->macFlags |= FLUSH_TOP;
+ if (! scrollPtr->vertical) {
+ TkpComputeScrollbarGeometry(scrollPtr);
+ }
+ }
+ } else if (macScrollPtr->macFlags & FLUSH_TOP) {
+ macScrollPtr->macFlags &= ~FLUSH_TOP;
+ if (! scrollPtr->vertical) {
+ TkpComputeScrollbarGeometry(scrollPtr);
+ }
+ }
+
+ if (portRect.right == contrlRect.right) {
+ flushRight = true;
+ if (macScrollPtr->macFlags & AUTO_ADJUST) {
+ contrlRect.right++;
+ }
+ if (!(macScrollPtr->macFlags & FLUSH_RIGHT)) {
+ macScrollPtr->macFlags |= FLUSH_RIGHT;
+ if (scrollPtr->vertical) {
+ TkpComputeScrollbarGeometry(scrollPtr);
+ }
+ }
+ } else if (macScrollPtr->macFlags & FLUSH_RIGHT) {
+ macScrollPtr->macFlags &= ~FLUSH_RIGHT;
+ if (scrollPtr->vertical) {
+ TkpComputeScrollbarGeometry(scrollPtr);
+ }
+ }
+
+ if (portRect.bottom == contrlRect.bottom) {
+ flushBottom = true;
+ if (macScrollPtr->macFlags & AUTO_ADJUST) {
+ contrlRect.bottom++;
+ }
+ if (!(macScrollPtr->macFlags & FLUSH_BOTTOM)) {
+ macScrollPtr->macFlags |= FLUSH_BOTTOM;
+ if (! scrollPtr->vertical) {
+ TkpComputeScrollbarGeometry(scrollPtr);
+ }
+ }
+ } else if (macScrollPtr->macFlags & FLUSH_BOTTOM) {
+ macScrollPtr->macFlags &= ~FLUSH_BOTTOM;
+ if (! scrollPtr->vertical) {
+ TkpComputeScrollbarGeometry(scrollPtr);
+ }
+ }
+
+ /*
+ * If the scrollbar is flush against the bottom right hand corner then
+ * it may need to draw the grow region for the window so we let the
+ * wm code know about this scrollbar. We don't actually draw the grow
+ * region, however, unless we are currently resizable.
+ */
+ macScrollPtr->macFlags &= ~DRAW_GROW;
+ if (flushBottom && flushRight) {
+ TkMacOSXSetScrollbarGrow((TkWindow *) tkwin, true);
+ if (TkMacOSXResizable(macDraw->toplevel->winPtr)) {
+ if (scrollPtr->vertical) {
+ contrlRect.bottom -= 14;
+ } else {
+ contrlRect.right -= 14;
+ }
+ macScrollPtr->macFlags |= DRAW_GROW;
+ }
+ } else {
+ TkMacOSXSetScrollbarGrow((TkWindow *) tkwin, false);
+ }
+
+ /*
+ * Given the Tk parameters for the fractions of the start and
+ * end of the thumb, the following calculation determines the
+ * location for the fixed sized Macintosh thumb.
+ */
+ middle = scrollPtr->firstFraction / (scrollPtr->firstFraction +
+ (1.0 - scrollPtr->lastFraction));
+ viewSize = (SInt32)((scrollPtr->lastFraction-scrollPtr->firstFraction)
+ * MAX_SCROLLBAR_DVALUE);
+ SetControlViewSize(macScrollPtr->sbHandle,viewSize);
+ SetControlValue(macScrollPtr->sbHandle,
+ (short) (middle * MAX_SCROLLBAR_VALUE) );
+ contrlHilite=GetControlHilite(macScrollPtr->sbHandle);
+ if ( contrlHilite == 0 || contrlHilite == 255) {
+ if (scrollPtr->firstFraction == 0.0 &&
+ scrollPtr->lastFraction == 1.0) {
+ HiliteControl(macScrollPtr->sbHandle,255);
+ } else {
+ HiliteControl(macScrollPtr->sbHandle,0);
+ }
+ }
+ if ( !IsControlVisible (macScrollPtr -> sbHandle) ) {
+ SetControlVisibility(macScrollPtr->sbHandle,TRUE,FALSE);
+ }
+}
diff --git a/macosx/tkMacOSXSend.c b/macosx/tkMacOSXSend.c
new file mode 100644
index 0000000..1647f75
--- /dev/null
+++ b/macosx/tkMacOSXSend.c
@@ -0,0 +1,552 @@
+/*
+ * tkMacOSXSend.c --
+ *
+ * This file provides procedures that implement the "send"
+ * command, allowing commands to be passed from interpreter
+ * to interpreter. This current implementation for the Mac
+ * has most functionality stubed out.
+ *
+ * The current plan, which we have not had time to implement, is
+ * for the first Wish app to create a gestalt of type 'WIsH'.
+ * This gestalt will point to a table, in system memory, of
+ * Tk apps. Each Tk app, when it starts up, will register their
+ * name, and process ID, in this table. This will allow us to
+ * implement "tk appname".
+ *
+ * Then the send command will look up the process id of the target
+ * app in this table, and send an AppleEvent to that process. The
+ * AppleEvent handler is much like the do script handler, except that
+ * you have to specify the name of the tk app as well, since there may
+ * be many interps in one wish app, and you need to send it to the
+ * right one.
+ *
+ * Implementing this has been on our list of things to do, but what
+ * with the demise of Tcl at Sun, and the lack of resources at
+ * Scriptics it may not get done for awhile. So this sketch is
+ * offered for the brave to attempt if they need the functionality...
+ *
+ * Copyright (c) 1989-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1998 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXSend.c,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#include <Carbon/Carbon.h>
+/*
+#include <Gestalt.h>
+*/
+#include "tkPort.h"
+#include "tkInt.h"
+
+EXTERN int Tk_SendObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
+
+ /*
+ * The following structure is used to keep track of the
+ * interpreters registered by this process.
+ */
+
+typedef struct RegisteredInterp {
+ char *name; /* Interpreter's name (malloc-ed). */
+ Tcl_Interp *interp; /* Interpreter associated with
+ * name. */
+ struct RegisteredInterp *nextPtr;
+ /* Next in list of names associated
+ * with interps in this process.
+ * NULL means end of list. */
+} RegisteredInterp;
+
+/*
+ * A registry of all interpreters for a display is kept in a
+ * property "InterpRegistry" on the root window of the display.
+ * It is organized as a series of zero or more concatenated strings
+ * (in no particular order), each of the form
+ * window space name '\0'
+ * where "window" is the hex id of the comm. window to use to talk
+ * to an interpreter named "name".
+ *
+ * When the registry is being manipulated by an application (e.g. to
+ * add or remove an entry), it is loaded into memory using a structure
+ * of the following type:
+ */
+
+typedef struct NameRegistry {
+ TkDisplay *dispPtr; /* Display from which the registry was
+ * read. */
+ int locked; /* Non-zero means that the display was
+ * locked when the property was read in. */
+ int modified; /* Non-zero means that the property has
+ * been modified, so it needs to be written
+ * out when the NameRegistry is closed. */
+ unsigned long propLength; /* Length of the property, in bytes. */
+ char *property; /* The contents of the property, or NULL
+ * if none. See format description above;
+ * this is *not* terminated by the first
+ * null character. Dynamically allocated. */
+ int allocedByX; /* Non-zero means must free property with
+ * XFree; zero means use ckfree. */
+} NameRegistry;
+
+static int initialized = false; /* A flag to denote if we have initialized yet. */
+
+static RegisteredInterp *interpListPtr = NULL;
+/* List of all interpreters
+ * registered by this process. */
+
+ /*
+ * The information below is used for communication between processes
+ * during "send" commands. Each process keeps a private window, never
+ * even mapped, with one property, "Comm". When a command is sent to
+ * an interpreter, the command is appended to the comm property of the
+ * communication window associated with the interp's process. Similarly,
+ * when a result is returned from a sent command, it is also appended
+ * to the comm property.
+ *
+ * Each command and each result takes the form of ASCII text. For a
+ * command, the text consists of a zero character followed by several
+ * null-terminated ASCII strings. The first string consists of the
+ * single letter "c". Subsequent strings have the form "option value"
+ * where the following options are supported:
+ *
+ * -r commWindow serial
+ *
+ * This option means that a response should be sent to the window
+ * whose X identifier is "commWindow" (in hex), and the response should
+ * be identified with the serial number given by "serial" (in decimal).
+ * If this option isn't specified then the send is asynchronous and
+ * no response is sent.
+ *
+ * -n name
+ * "Name" gives the name of the application for which the command is
+ * intended. This option must be present.
+ *
+ * -s script
+ *
+ * "Script" is the script to be executed. This option must be present.
+ *
+ * The options may appear in any order. The -n and -s options must be
+ * present, but -r may be omitted for asynchronous RPCs. For compatibility
+ * with future releases that may add new features, there may be additional
+ * options present; as long as they start with a "-" character, they will
+ * be ignored.
+ *
+ * A result also consists of a zero character followed by several null-
+ * terminated ASCII strings. The first string consists of the single
+ * letter "r". Subsequent strings have the form "option value" where
+ * the following options are supported:
+ *
+ * -s serial
+ *
+ * Identifies the command for which this is the result. It is the
+ * same as the "serial" field from the -s option in the command. This
+ * option must be present.
+ *
+ * -c code
+ *
+ * "Code" is the completion code for the script, in decimal. If the
+ * code is omitted it defaults to TCL_OK.
+ *
+ * -r result
+ *
+ * "Result" is the result string for the script, which may be either
+ * a result or an error message. If this field is omitted then it
+ * defaults to an empty string.
+ *
+ * -i errorInfo
+ *
+ * "ErrorInfo" gives a string with which to initialize the errorInfo
+ * variable. This option may be omitted; it is ignored unless the
+ * completion code is TCL_ERROR.
+ *
+ * -e errorCode
+ *
+ * "ErrorCode" gives a string with with to initialize the errorCode
+ * variable. This option may be omitted; it is ignored unless the
+ * completion code is TCL_ERROR.
+ *
+ * Options may appear in any order, and only the -s option must be
+ * present. As with commands, there may be additional options besides
+ * these; unknown options are ignored.
+ */
+
+ /*
+ * The following variable is the serial number that was used in the
+ * last "send" command. It is exported only for testing purposes.
+ */
+
+int tkSendSerial = 0;
+
+ /*
+ * Maximum size property that can be read at one time by
+ * this module:
+ */
+
+#define MAX_PROP_WORDS 100000
+
+/*
+ * Forward declarations for procedures defined later in this file:
+ */
+
+static int SendInit _ANSI_ARGS_((Tcl_Interp *interp));
+/*
+static int AppendErrorProc _ANSI_ARGS_((ClientData clientData,
+ XErrorEvent *errorPtr));
+static void DeleteProc _ANSI_ARGS_((ClientData clientData));
+static void RegAddName _ANSI_ARGS_((NameRegistry *regPtr,
+ char *name, Window commWindow));
+static void RegClose _ANSI_ARGS_((NameRegistry *regPtr));
+static void RegDeleteName _ANSI_ARGS_((NameRegistry *regPtr,
+ char *name));
+static Window RegFindName _ANSI_ARGS_((NameRegistry *regPtr,
+ char *name));
+static NameRegistry * RegOpen _ANSI_ARGS_((Tcl_Interp *interp,
+ TkWindow *winPtr, int lock));
+static void SendEventProc _ANSI_ARGS_((ClientData clientData,
+ XEvent *eventPtr));
+static Bool SendRestrictProc _ANSI_ARGS_((Display *display,
+ XEvent *eventPtr, char *arg));
+static int ServerSecure _ANSI_ARGS_((TkDisplay *dispPtr));
+static void TimeoutProc _ANSI_ARGS_((ClientData clientData));
+static int ValidateName _ANSI_ARGS_((TkDisplay *dispPtr,
+ char *name, Window commWindow, int oldOK));
+*/
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Tk_SetAppName --
+ *
+ * This procedure is called to associate an ASCII name with a Tk
+ * application. If the application has already been named, the
+ * name replaces the old one.
+ *
+ * Results:
+ * The return value is the name actually given to the application.
+ * This will normally be the same as name, but if name was already
+ * in use for an application then a name of the form "name #2" will
+ * be chosen, with a high enough number to make the name unique.
+ *
+ * Side effects:
+ * Registration info is saved, thereby allowing the "send" command
+ * to be used later to invoke commands in the application. In
+ * addition, the "send" command is created in the application's
+ * interpreter. The registration will be removed automatically
+ * if the interpreter is deleted or the "send" command is removed.
+ *
+ *--------------------------------------------------------------
+ */
+
+CONST char *
+Tk_SetAppName(
+ Tk_Window tkwin, /* Token for any window in the application
+ * to be named: it is just used to identify
+ * the application and the display. */
+ CONST char *name) /* The name that will be used to
+ * refer to the interpreter in later
+ * "send" commands. Must be globally
+ * unique. */
+{
+ TkWindow *winPtr = (TkWindow *) tkwin;
+ Tcl_Interp *interp = winPtr->mainPtr->interp;
+ int i, suffix, offset, result;
+ RegisteredInterp *riPtr, *prevPtr;
+ CONST char *actualName;
+ Tcl_DString dString;
+ Tcl_Obj *resultObjPtr, *interpNamePtr;
+ char *interpName;
+
+ if (!initialized) {
+ SendInit(interp);
+ }
+
+ /*
+ * See if the application is already registered; if so, remove its
+ * current name from the registry. The deletion of the command
+ * will take care of disposing of this entry.
+ */
+
+ for (riPtr = interpListPtr, prevPtr = NULL; riPtr != NULL;
+ prevPtr = riPtr, riPtr = riPtr->nextPtr) {
+ if (riPtr->interp == interp) {
+ if (prevPtr == NULL) {
+ interpListPtr = interpListPtr->nextPtr;
+ } else {
+ prevPtr->nextPtr = riPtr->nextPtr;
+ }
+ break;
+ }
+ }
+
+ /*
+ * Pick a name to use for the application. Use "name" if it's not
+ * already in use. Otherwise add a suffix such as " #2", trying
+ * larger and larger numbers until we eventually find one that is
+ * unique.
+ */
+
+ actualName = name;
+ suffix = 1;
+ offset = 0;
+ Tcl_DStringInit(&dString);
+
+ TkGetInterpNames(interp, tkwin);
+ resultObjPtr = Tcl_GetObjResult(interp);
+ Tcl_IncrRefCount(resultObjPtr);
+ for (i = 0; ; ) {
+ result = Tcl_ListObjIndex(NULL, resultObjPtr, i, &interpNamePtr);
+ if (interpNamePtr == NULL) {
+ break;
+ }
+ interpName = Tcl_GetStringFromObj(interpNamePtr, NULL);
+ if (strcmp(actualName, interpName) == 0) {
+ if (suffix == 1) {
+ Tcl_DStringAppend(&dString, name, -1);
+ Tcl_DStringAppend(&dString, " #", 2);
+ offset = Tcl_DStringLength(&dString);
+ Tcl_DStringSetLength(&dString, offset + 10);
+ actualName = Tcl_DStringValue(&dString);
+ }
+ suffix++;
+ sprintf(Tcl_DStringValue(&dString) + offset, "%d", suffix);
+ i = 0;
+ } else {
+ i++;
+ }
+ }
+
+ Tcl_DecrRefCount(resultObjPtr);
+ Tcl_ResetResult(interp);
+
+ /*
+ * We have found a unique name. Now add it to the registry.
+ */
+
+ riPtr = (RegisteredInterp *) ckalloc(sizeof(RegisteredInterp));
+ riPtr->interp = interp;
+ riPtr->name = ckalloc(strlen(actualName) + 1);
+ riPtr->nextPtr = interpListPtr;
+ interpListPtr = riPtr;
+ strcpy(riPtr->name, actualName);
+
+ Tcl_CreateObjCommand(interp, "send", Tk_SendObjCmd,
+ (ClientData) riPtr, NULL /* TODO: DeleteProc */);
+ if (Tcl_IsSafe(interp)) {
+ Tcl_HideCommand(interp, "send", "send");
+ }
+ Tcl_DStringFree(&dString);
+
+ return riPtr->name;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Tk_SendObjCmd --
+ *
+ * This procedure is invoked to process the "send" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *--------------------------------------------------------------
+ */
+
+int
+Tk_SendObjCmd(
+ ClientData clientData, /* Used only for deletion */
+ Tcl_Interp *interp, /* The interp we are sending from */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[]) /* The arguments */
+{
+ CONST char *sendOptions[] = {"-async", "-displayof", "-", (char *) NULL};
+ char *stringRep, *destName;
+ int async = 0;
+ int i, index, firstArg;
+ RegisteredInterp *riPtr;
+ Tcl_Obj *resultPtr, *listObjPtr;
+ int result = TCL_OK;
+
+ for (i = 1; i < (objc - 1); ) {
+ stringRep = Tcl_GetStringFromObj(objv[i], NULL);
+ if (stringRep[0] == '-') {
+ if (Tcl_GetIndexFromObj(interp, objv[i], sendOptions, "option", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (index == 0) {
+ async = 1;
+ i++;
+ } else if (index == 1) {
+ i += 2;
+ } else {
+ i++;
+ }
+ } else {
+ break;
+ }
+ }
+
+ if (objc < (i + 2)) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "?options? interpName arg ?arg ...?");
+ return TCL_ERROR;
+ }
+
+ destName = Tcl_GetStringFromObj(objv[i], NULL);
+ firstArg = i + 1;
+
+ resultPtr = Tcl_GetObjResult(interp);
+
+ /*
+ * See if the target interpreter is local. If so, execute
+ * the command directly without going through the DDE server.
+ * The only tricky thing is passing the result from the target
+ * interpreter to the invoking interpreter. Watch out: they
+ * could be the same!
+ */
+
+ for (riPtr = interpListPtr; (riPtr != NULL)
+ && (strcmp(destName, riPtr->name)); riPtr = riPtr->nextPtr) {
+ /*
+ * Empty loop body.
+ */
+
+ }
+
+ if (riPtr != NULL) {
+ /*
+ * This command is to a local interp. No need to go through
+ * the server.
+ */
+
+ Tcl_Interp *localInterp;
+
+ Tcl_Preserve((ClientData) riPtr);
+ localInterp = riPtr->interp;
+ Tcl_Preserve((ClientData) localInterp);
+ if (firstArg == (objc - 1)) {
+ /*
+ * This might be one of those cases where the new
+ * parser is faster.
+ */
+
+ result = Tcl_EvalObjEx(localInterp, objv[firstArg], TCL_EVAL_DIRECT);
+ } else {
+ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
+ for (i = firstArg; i < objc; i++) {
+ Tcl_ListObjAppendList(interp, listObjPtr, objv[i]);
+ }
+ Tcl_IncrRefCount(listObjPtr);
+ result = Tcl_EvalObjEx(localInterp, listObjPtr, TCL_EVAL_DIRECT);
+ Tcl_DecrRefCount(listObjPtr);
+ }
+ if (interp != localInterp) {
+ if (result == TCL_ERROR) {
+ /* Tcl_Obj *errorObjPtr; */
+
+ /*
+ * An error occurred, so transfer error information from the
+ * destination interpreter back to our interpreter. Must clear
+ * interp's result before calling Tcl_AddErrorInfo, since
+ * Tcl_AddErrorInfo will store the interp's result in errorInfo
+ * before appending riPtr's $errorInfo; we've already got
+ * everything we need in riPtr's $errorInfo.
+ */
+
+ Tcl_ResetResult(interp);
+ Tcl_AddErrorInfo(interp, Tcl_GetVar2(localInterp,
+ "errorInfo", (char *) NULL, TCL_GLOBAL_ONLY));
+ /* errorObjPtr = Tcl_GetObjVar2(localInterp, "errorCode", NULL,
+ TCL_GLOBAL_ONLY);
+ Tcl_SetObjErrorCode(interp, errorObjPtr); */
+ }
+ Tcl_SetObjResult(interp, Tcl_GetObjResult(localInterp));
+ }
+ Tcl_Release((ClientData) riPtr);
+ Tcl_Release((ClientData) localInterp);
+ } else {
+ /*
+ * This is a non-local request. Send the script to the server and poll
+ * it for a result. TODO!!!
+ */
+ }
+
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkGetInterpNames --
+ *
+ * This procedure is invoked to fetch a list of all the
+ * interpreter names currently registered for the display
+ * of a particular window.
+ *
+ * Results:
+ * A standard Tcl return value. Interp->result will be set
+ * to hold a list of all the interpreter names defined for
+ * tkwin's display. If an error occurs, then TCL_ERROR
+ * is returned and interp->result will hold an error message.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkGetInterpNames(
+ Tcl_Interp *interp, /* Interpreter for returning a result. */
+ Tk_Window tkwin) /* Window whose display is to be used
+ * for the lookup. */
+{
+ Tcl_Obj *listObjPtr;
+ RegisteredInterp *riPtr;
+
+ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
+ riPtr = interpListPtr;
+ while (riPtr != NULL) {
+ Tcl_ListObjAppendElement(interp, listObjPtr,
+ Tcl_NewStringObj(riPtr->name, -1));
+ riPtr = riPtr->nextPtr;
+ }
+
+ Tcl_SetObjResult(interp, listObjPtr);
+ return TCL_OK;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * SendInit --
+ *
+ * This procedure is called to initialize the
+ * communication channels for sending commands and
+ * receiving results.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Sets up various data structures and windows.
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+SendInit(
+ Tcl_Interp *interp) /* Interpreter to use for error reporting
+ * (no errors are ever returned, but the
+ * interpreter is needed anyway). */
+{
+ return TCL_OK;
+}
diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c
new file mode 100644
index 0000000..380725f
--- /dev/null
+++ b/macosx/tkMacOSXSubwindows.c
@@ -0,0 +1,1304 @@
+/*
+ * tkMacOSXSubwindows.c --
+ *
+ * Implements subwindows for the macintosh version of Tk.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXSubwindows.c,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#include "tkInt.h"
+#include "X11/X.h"
+#include "X11/Xlib.h"
+#include <stdio.h>
+
+#include <Carbon/Carbon.h>
+#include "tkMacOSXInt.h"
+#include "tkMacOSXDebug.h"
+
+/*
+ * Temporary region that can be reused.
+ */
+static RgnHandle tmpRgn = NULL;
+
+static void UpdateOffsets _ANSI_ARGS_((TkWindow *winPtr, int deltaX, int deltaY));
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XDestroyWindow --
+ *
+ * Dealocates the given X Window.
+ *
+ * Results:
+ * The window id is returned.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XDestroyWindow(
+ Display* display, /* Display. */
+ Window window) /* Window. */
+{
+ MacDrawable *macWin = (MacDrawable *) window;
+ CGrafPtr destPort;
+ /*
+ * Remove any dangling pointers that may exist if
+ * the window we are deleting is being tracked by
+ * the grab code.
+ */
+
+ TkPointerDeadWindow(macWin->winPtr);
+ macWin->toplevel->referenceCount--;
+
+
+ if (Tk_IsTopLevel(macWin->winPtr)) {
+ DisposeRgn(macWin->clipRgn);
+ DisposeRgn(macWin->aboveClipRgn);
+
+ /*
+ * Delete the Mac window and remove it from the windowTable.
+ * The window could be NULL if the window was never mapped.
+ * However, we don't do this for embedded windows, they don't
+ * go in the window list, and they do not own their portPtr's.
+ */
+
+ if (!(Tk_IsEmbedded(macWin->winPtr))) {
+ destPort = TkMacOSXGetDrawablePort(window);
+ if (destPort != NULL) {
+ TkMacOSXWindowList *listPtr, *prevPtr;
+ WindowRef winRef;
+ winRef = GetWindowFromPort(destPort);
+ TkMacOSXUnregisterMacWindow(winRef);
+ DisposeWindow(winRef);
+
+ for (listPtr = tkMacOSXWindowListPtr, prevPtr = NULL;
+ tkMacOSXWindowListPtr != NULL;
+ prevPtr = listPtr, listPtr = listPtr->nextPtr) {
+ if (listPtr->winPtr == macWin->winPtr) {
+ if (prevPtr == NULL) {
+ tkMacOSXWindowListPtr = listPtr->nextPtr;
+ } else {
+ prevPtr->nextPtr = listPtr->nextPtr;
+ }
+ ckfree((char *) listPtr);
+ break;
+ }
+ }
+ }
+ }
+
+ macWin->grafPtr = NULL;
+
+ /*
+ * Delay deletion of a toplevel data structure untill all
+ * children have been deleted.
+ */
+ if (macWin->toplevel->referenceCount == 0) {
+ ckfree((char *) macWin->toplevel);
+ }
+ } else {
+ CGrafPtr destPort;
+ destPort = TkMacOSXGetDrawablePort(window);
+ if (destPort != NULL) {
+ SetGWorld(destPort, NULL);
+ TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
+ }
+ if (macWin->winPtr->parentPtr != NULL) {
+ TkMacOSXInvalClipRgns(macWin->winPtr->parentPtr);
+ }
+ DisposeRgn(macWin->clipRgn);
+ DisposeRgn(macWin->aboveClipRgn);
+
+ if (macWin->toplevel->referenceCount == 0) {
+ ckfree((char *) macWin->toplevel);
+ }
+ ckfree((char *) macWin);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XMapWindow --
+ *
+ * Map the given X Window to the screen. See X window documentation
+ * for more details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The subwindow or toplevel may appear on the screen.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XMapWindow(
+ Display* display, /* Display. */
+ Window window) /* Window. */
+{
+ MacDrawable *macWin = (MacDrawable *) window;
+ XEvent event;
+ CGrafPtr destPort;
+
+ /*
+ * Under certain situations it's possible for this function to be
+ * called before the toplevel window it's associated with has actually
+ * been mapped. In that case we need to create the real Macintosh
+ * window now as this function as well as other X functions assume that
+ * the portPtr is valid.
+ */
+ if (!TkMacOSXHostToplevelExists(macWin->toplevel->winPtr)) {
+ TkMacOSXMakeRealWindowExist(macWin->toplevel->winPtr);
+ }
+ destPort = TkMacOSXGetDrawablePort (window);
+
+ display->request++;
+ macWin->winPtr->flags |= TK_MAPPED;
+ if (Tk_IsTopLevel(macWin->winPtr)) {
+ if (!Tk_IsEmbedded(macWin->winPtr)) {
+ ShowWindow(GetWindowFromPort(destPort));
+ }
+
+ /*
+ * We only need to send the MapNotify event
+ * for toplevel windows.
+ */
+ event.xany.serial = display->request;
+ event.xany.send_event = False;
+ event.xany.display = display;
+
+ event.xmap.window = window;
+ event.xmap.type = MapNotify;
+ event.xmap.event = window;
+ event.xmap.override_redirect = macWin->winPtr->atts.override_redirect;
+ Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
+ } else {
+ TkMacOSXInvalClipRgns(macWin->winPtr->parentPtr);
+ }
+
+ /*
+ * Generate damage for that area of the window
+ */
+ SetGWorld (destPort, NULL);
+ TkMacOSXUpdateClipRgn(macWin->winPtr);
+ TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XUnmapWindow --
+ *
+ * Unmap the given X Window to the screen. See X window
+ * documentation for more details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The subwindow or toplevel may be removed from the screen.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XUnmapWindow(
+ Display* display, /* Display. */
+ Window window) /* Window. */
+{
+ MacDrawable *macWin = (MacDrawable *) window;
+ XEvent event;
+ CGrafPtr destPort;
+
+ destPort = TkMacOSXGetDrawablePort(window);
+
+ display->request++;
+ macWin->winPtr->flags &= ~TK_MAPPED;
+ if (Tk_IsTopLevel(macWin->winPtr)) {
+ if (!Tk_IsEmbedded(macWin->winPtr)) {
+ HideWindow(GetWindowFromPort(destPort));
+ }
+
+ /*
+ * We only need to send the UnmapNotify event
+ * for toplevel windows.
+ */
+ event.xany.serial = display->request;
+ event.xany.send_event = False;
+ event.xany.display = display;
+
+ event.xunmap.type = UnmapNotify;
+ event.xunmap.window = window;
+ event.xunmap.event = window;
+ event.xunmap.from_configure = false;
+ Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
+ } else {
+ /*
+ * Generate damage for that area of the window.
+ */
+ SetGWorld(destPort, NULL);
+ TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); /* TODO: may not be valid */
+ TkMacOSXInvalClipRgns(macWin->winPtr->parentPtr);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XResizeWindow --
+ *
+ * Resize a given X window. See X windows documentation for
+ * further details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XResizeWindow(
+ Display* display, /* Display. */
+ Window window, /* Window. */
+ unsigned int width,
+ unsigned int height)
+{
+ MacDrawable *macWin = (MacDrawable *) window;
+ CGrafPtr destPort;
+
+ destPort = TkMacOSXGetDrawablePort(window);
+ if (destPort == NULL) {
+ return;
+ }
+
+ display->request++;
+ SetPort( destPort);
+ if (Tk_IsTopLevel(macWin->winPtr)) {
+ if (!Tk_IsEmbedded(macWin->winPtr)) {
+ /*
+ * NOTE: we are not adding the new space to the update
+ * region. It is currently assumed that Tk will need
+ * to completely redraw anway.
+ */
+ SizeWindow(GetWindowFromPort(destPort),
+ (short) width, (short) height, false);
+ TkMacOSXInvalidateWindow(macWin, TK_WINDOW_ONLY);
+ TkMacOSXInvalClipRgns(macWin->winPtr);
+ } else {
+ int deltaX, deltaY;
+
+ /*
+ * Find the Parent window -
+ * For an embedded window this will be its container.
+ */
+ TkWindow *contWinPtr;
+
+ contWinPtr = TkpGetOtherWindow(macWin->winPtr);
+
+ if (contWinPtr != NULL) {
+ MacDrawable *macParent = contWinPtr->privatePtr;
+
+ TkMacOSXInvalClipRgns(macParent->winPtr);
+ TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
+
+ deltaX = macParent->xOff +
+ macWin->winPtr->changes.x - macWin->xOff;
+ deltaY = macParent->yOff +
+ macWin->winPtr->changes.y - macWin->yOff;
+
+ UpdateOffsets(macWin->winPtr, deltaX, deltaY);
+ } else {
+ /*
+ * This is the case where we are embedded in
+ * another app. At this point, we are assuming that
+ * the changes.x,y is not maintained, if you need
+ * the info get it from Tk_GetRootCoords,
+ * and that the toplevel sits at 0,0 when it is drawn.
+ */
+
+ TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
+ UpdateOffsets(macWin->winPtr, 0, 0);
+ }
+
+ }
+ } else {
+ /* TODO: update all xOff & yOffs */
+ int deltaX, deltaY, parentBorderwidth;
+ MacDrawable *macParent = macWin->winPtr->parentPtr->privatePtr;
+
+ if (macParent == NULL) {
+ return; /* TODO: Probably should be a panic */
+ }
+
+ TkMacOSXInvalClipRgns(macParent->winPtr);
+ TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
+
+ deltaX = - macWin->xOff;
+ deltaY = - macWin->yOff;
+
+ parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
+
+ deltaX += macParent->xOff + parentBorderwidth +
+ macWin->winPtr->changes.x;
+ deltaY += macParent->yOff + parentBorderwidth +
+ macWin->winPtr->changes.y;
+
+ UpdateOffsets(macWin->winPtr, deltaX, deltaY);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XMoveResizeWindow --
+ *
+ * Move or resize a given X window. See X windows documentation
+ * for further details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XMoveResizeWindow(
+ Display* display, /* Display. */
+ Window window, /* Window. */
+ int x, int y,
+ unsigned int width,
+ unsigned int height)
+{
+ MacDrawable * macWin = (MacDrawable *) window;
+ CGrafPtr destPort;
+
+ destPort = TkMacOSXGetDrawablePort(window);
+ if (destPort == NULL) {
+ return;
+ }
+
+ SetPort( destPort);
+ if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
+ /*
+ * NOTE: we are not adding the new space to the update
+ * region. It is currently assumed that Tk will need
+ * to completely redraw anway.
+ */
+
+ SizeWindow(GetWindowFromPort(destPort),
+ (short) width, (short) height, false);
+ MoveWindowStructure(GetWindowFromPort(destPort), x, y);
+
+ /* TODO: is the following right? */
+ TkMacOSXInvalidateWindow(macWin, TK_WINDOW_ONLY);
+ TkMacOSXInvalClipRgns(macWin->winPtr);
+ } else {
+ int deltaX, deltaY, parentBorderwidth;
+ Rect bounds;
+ MacDrawable *macParent;
+
+ /*
+ * Find the Parent window -
+ * For an embedded window this will be its container.
+ */
+
+ if (Tk_IsEmbedded(macWin->winPtr)) {
+ TkWindow *contWinPtr;
+
+ contWinPtr = TkpGetOtherWindow(macWin->winPtr);
+ if (contWinPtr == NULL) {
+ panic("XMoveResizeWindow could not find container");
+ }
+ macParent = contWinPtr->privatePtr;
+
+ /*
+ * NOTE: Here we should handle out of process embedding.
+ */
+
+
+ } else {
+ macParent = macWin->winPtr->parentPtr->privatePtr;
+ if (macParent == NULL) {
+ return; /* TODO: Probably should be a panic */
+ }
+ }
+
+ TkMacOSXInvalClipRgns(macParent->winPtr);
+ TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
+
+ deltaX = - macWin->xOff;
+ deltaY = - macWin->yOff;
+
+ /*
+ * If macWin->winPtr is an embedded window, don't offset by its
+ * parent's borderwidth...
+ */
+
+ if (!Tk_IsEmbedded(macWin->winPtr)) {
+ parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
+ } else {
+ parentBorderwidth = 0;
+ }
+ deltaX += macParent->xOff + parentBorderwidth +
+ macWin->winPtr->changes.x;
+ deltaY += macParent->yOff + parentBorderwidth +
+ macWin->winPtr->changes.y;
+
+ UpdateOffsets(macWin->winPtr, deltaX, deltaY);
+ TkMacOSXWinBounds(macWin->winPtr, &bounds);
+ InvalWindowRect(GetWindowFromPort(destPort),&bounds);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XMoveWindow --
+ *
+ * Move a given X window. See X windows documentation for further
+ * details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XMoveWindow(
+ Display* display, /* Display. */
+ Window window, /* Window. */
+ int x,
+ int y)
+{
+ MacDrawable *macWin = (MacDrawable *) window;
+ CGrafPtr destPort;
+
+ destPort = TkMacOSXGetDrawablePort(window);
+ if (destPort == NULL) {
+ return;
+ }
+
+ SetPort( destPort);
+ if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
+ /*
+ * NOTE: we are not adding the new space to the update
+ * region. It is currently assumed that Tk will need
+ * to completely redraw anway.
+ */
+ MoveWindowStructure( GetWindowFromPort(destPort), x, y);
+
+ /* TODO: is the following right? */
+ TkMacOSXInvalidateWindow(macWin, TK_WINDOW_ONLY);
+ TkMacOSXInvalClipRgns(macWin->winPtr);
+ } else {
+ int deltaX, deltaY, parentBorderwidth;
+ Rect bounds;
+ MacDrawable *macParent;
+
+ /*
+ * Find the Parent window -
+ * For an embedded window this will be its container.
+ */
+
+ if (Tk_IsEmbedded(macWin->winPtr)) {
+ TkWindow *contWinPtr;
+
+ contWinPtr = TkpGetOtherWindow(macWin->winPtr);
+ if (contWinPtr == NULL) {
+ panic("XMoveWindow could not find container");
+ }
+ macParent = contWinPtr->privatePtr;
+
+ /*
+ * NOTE: Here we should handle out of process embedding.
+ */
+
+ } else {
+ macParent = macWin->winPtr->parentPtr->privatePtr;
+ if (macParent == NULL) {
+ return; /* TODO: Probably should be a panic */
+ }
+ }
+
+ TkMacOSXInvalClipRgns(macParent->winPtr);
+ TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
+
+ deltaX = - macWin->xOff;
+ deltaY = - macWin->yOff;
+
+ /*
+ * If macWin->winPtr is an embedded window, don't offset by its
+ * parent's borderwidth...
+ */
+
+ if (!Tk_IsEmbedded(macWin->winPtr)) {
+ parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
+ } else {
+ parentBorderwidth = 0;
+ }
+ deltaX += macParent->xOff + parentBorderwidth +
+ macWin->winPtr->changes.x;
+ deltaY += macParent->yOff + parentBorderwidth +
+ macWin->winPtr->changes.y;
+
+ UpdateOffsets(macWin->winPtr, deltaX, deltaY);
+ TkMacOSXWinBounds(macWin->winPtr, &bounds);
+ InvalWindowRect(GetWindowFromPort(destPort),&bounds);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XRaiseWindow --
+ *
+ * Change the stacking order of a window.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes the stacking order of the specified window.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XRaiseWindow(
+ Display* display, /* Display. */
+ Window window) /* Window. */
+{
+ MacDrawable *macWin = (MacDrawable *) window;
+
+ display->request++;
+ if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
+ TkWmRestackToplevel(macWin->winPtr, Above, NULL);
+ } else {
+ /* TODO: this should generate damage */
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XLowerWindow --
+ *
+ * Change the stacking order of a window.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes the stacking order of the specified window.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XLowerWindow(
+ Display* display, /* Display. */
+ Window window) /* Window. */
+{
+ MacDrawable *macWin = (MacDrawable *) window;
+
+ display->request++;
+ if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
+ TkWmRestackToplevel(macWin->winPtr, Below, NULL);
+ } else {
+ /* TODO: this should generate damage */
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XConfigureWindow --
+ *
+ * Change the size, position, stacking, or border of the specified
+ * window.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes the attributes of the specified window. Note that we
+ * ignore the passed in values and use the values stored in the
+ * TkWindow data structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XConfigureWindow(
+ Display* display, /* Display. */
+ Window w, /* Window. */
+ unsigned int value_mask,
+ XWindowChanges* values)
+{
+ MacDrawable *macWin = (MacDrawable *) w;
+ TkWindow *winPtr = macWin->winPtr;
+
+ display->request++;
+
+ /*
+ * Change the shape and/or position of the window.
+ */
+
+ if (value_mask & (CWX|CWY|CWWidth|CWHeight)) {
+ XMoveResizeWindow(display, w, winPtr->changes.x, winPtr->changes.y,
+ winPtr->changes.width, winPtr->changes.height);
+ }
+
+ /*
+ * Change the stacking order of the window. Tk actuall keeps all
+ * the information we need for stacking order. All we need to do
+ * is make sure the clipping regions get updated and generate damage
+ * that will ensure things get drawn correctly.
+ */
+
+ if (value_mask & CWStackMode) {
+ Rect bounds;
+ CGrafPtr destPort;
+
+ destPort = TkMacOSXGetDrawablePort(w);
+ if (destPort != NULL) {
+ SetPort( destPort);
+ TkMacOSXInvalClipRgns(winPtr->parentPtr);
+ TkMacOSXWinBounds(winPtr, &bounds);
+ InvalWindowRect(GetWindowFromPort(destPort),&bounds);
+ }
+ }
+
+ /* TkGenWMMoveRequestEvent(macWin->winPtr,
+ macWin->winPtr->changes.x, macWin->winPtr->changes.y); */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXUpdateClipRgn --
+ *
+ * This function updates the cliping regions for a given window
+ * and all of its children. Once updated the TK_CLIP_INVALID flag
+ * in the subwindow data structure is unset. The TK_CLIP_INVALID
+ * flag should always be unset before any drawing is attempted.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The clip regions for the window and its children are updated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXUpdateClipRgn(
+ TkWindow *winPtr)
+{
+ RgnHandle rgn;
+ int x, y;
+ TkWindow *win2Ptr;
+
+ if (winPtr == NULL) {
+ return;
+ }
+
+ if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
+ rgn = winPtr->privatePtr->aboveClipRgn;
+ if (tmpRgn == NULL) {
+ tmpRgn = NewRgn();
+ }
+
+ /*
+ * Start with a region defined by the window bounds.
+ */
+
+ x = winPtr->privatePtr->xOff;
+ y = winPtr->privatePtr->yOff;
+ SetRectRgn(rgn, (short) x, (short) y,
+ (short) (winPtr->changes.width + x),
+ (short) (winPtr->changes.height + y));
+
+ /*
+ * Clip away the area of any windows that may obscure this
+ * window.
+ * For a non-toplevel window, first, clip to the parents visable
+ * clip region.
+ * Second, clip away any siblings that are higher in the
+ * stacking order.
+ * For an embedded toplevel, just clip to the container's visible
+ * clip region. Remember, we only allow one contained window
+ * in a frame, and don't support any other widgets in the frame either.
+ * This is not currently enforced, however.
+ */
+
+ if (!Tk_IsTopLevel(winPtr)) {
+ TkMacOSXUpdateClipRgn(winPtr->parentPtr);
+ SectRgn(rgn,
+ winPtr->parentPtr->privatePtr->aboveClipRgn, rgn);
+
+ win2Ptr = winPtr->nextPtr;
+ while (win2Ptr != NULL) {
+ if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
+ win2Ptr = win2Ptr->nextPtr;
+ continue;
+ }
+ x = win2Ptr->privatePtr->xOff;
+ y = win2Ptr->privatePtr->yOff;
+ SetRectRgn(tmpRgn, (short) x, (short) y,
+ (short) (win2Ptr->changes.width + x),
+ (short) (win2Ptr->changes.height + y));
+ DiffRgn(rgn, tmpRgn, rgn);
+
+ win2Ptr = win2Ptr->nextPtr;
+ }
+ } else if (Tk_IsEmbedded(winPtr)) {
+ TkWindow *contWinPtr;
+
+ contWinPtr = TkpGetOtherWindow(winPtr);
+
+ if (contWinPtr != NULL) {
+ TkMacOSXUpdateClipRgn(contWinPtr);
+ SectRgn(rgn,
+ contWinPtr->privatePtr->aboveClipRgn, rgn);
+ } else if (gMacEmbedHandler != NULL) {
+ gMacEmbedHandler->getClipProc((Tk_Window) winPtr, tmpRgn);
+ SectRgn(rgn, tmpRgn, rgn);
+ }
+
+ /*
+ * NOTE: Here we should handle out of process embedding.
+ */
+
+ }
+
+ /*
+ * The final clip region is the aboveClip region (or visable
+ * region) minus all the children of this window.
+ * Alternatively, if the window is a container, we must also
+ * subtract the region of the embedded window.
+ */
+
+ rgn = winPtr->privatePtr->clipRgn;
+ CopyRgn(winPtr->privatePtr->aboveClipRgn, rgn);
+
+ win2Ptr = winPtr->childList;
+ while (win2Ptr != NULL) {
+ if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
+ win2Ptr = win2Ptr->nextPtr;
+ continue;
+ }
+ x = win2Ptr->privatePtr->xOff;
+ y = win2Ptr->privatePtr->yOff;
+ SetRectRgn(tmpRgn, (short) x, (short) y,
+ (short) (win2Ptr->changes.width + x),
+ (short) (win2Ptr->changes.height + y));
+ DiffRgn(rgn, tmpRgn, rgn);
+
+ win2Ptr = win2Ptr->nextPtr;
+ }
+
+ if (Tk_IsContainer(winPtr)) {
+ win2Ptr = TkpGetOtherWindow(winPtr);
+ if (win2Ptr != NULL) {
+ if (Tk_IsMapped(win2Ptr)) {
+ x = win2Ptr->privatePtr->xOff;
+ y = win2Ptr->privatePtr->yOff;
+ SetRectRgn(tmpRgn, (short) x, (short) y,
+ (short) (win2Ptr->changes.width + x),
+ (short) (win2Ptr->changes.height + y));
+ DiffRgn(rgn, tmpRgn, rgn);
+ }
+ }
+
+ /*
+ * NOTE: Here we should handle out of process embedding.
+ */
+
+ }
+
+ winPtr->privatePtr->flags &= ~TK_CLIP_INVALID;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXVisableClipRgn --
+ *
+ * This function returnd the Macintosh cliping region for the
+ * given window. A NULL Rgn means the window is not visable.
+ *
+ * Results:
+ * The region.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+RgnHandle
+TkMacOSXVisableClipRgn(
+ TkWindow *winPtr)
+{
+ if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
+ TkMacOSXUpdateClipRgn(winPtr);
+ }
+
+ return winPtr->privatePtr->clipRgn;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXInvalidateWindow --
+ *
+ * This function makes the window as invalid will generate damage
+ * for the window.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Damage is created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXInvalidateWindow(
+ MacDrawable *macWin, /* Make window that's causing damage. */
+ int flag) /* Should be TK_WINDOW_ONLY or
+ * TK_PARENT_WINDOW */
+{
+ WindowRef windowRef;
+ CGrafPtr grafPtr;
+
+ grafPtr=TkMacOSXGetDrawablePort((Drawable)macWin);
+ windowRef=GetWindowFromPort(grafPtr);
+
+ if (flag == TK_WINDOW_ONLY) {
+ InvalWindowRgn(windowRef,macWin->clipRgn);
+ } else {
+ if (!EmptyRgn(macWin->aboveClipRgn)) {
+ InvalWindowRgn(windowRef,macWin->aboveClipRgn);
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXGetDrawablePort --
+ *
+ * This function returns the Graphics Port for a given X drawable.
+ *
+ * Results:
+ * A CGrafPort . Either an off screen pixmap or a Window.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+CGrafPtr
+TkMacOSXGetDrawablePort(
+ Drawable drawable)
+{
+ MacDrawable *macWin = (MacDrawable *) drawable;
+ GWorldPtr resultPort = NULL;
+
+ if (macWin == NULL) {
+ return NULL;
+ }
+
+ /*
+ * This is NULL for off-screen pixmaps. Then the portPtr
+ * always points to the off-screen port, and we don't
+ * have to worry about containment
+ */
+
+ if (macWin->clipRgn == NULL) {
+ return macWin->grafPtr;
+ }
+
+ /*
+ * If the Drawable is in an embedded window, use the Port of its container.
+ *
+ * TRICKY POINT: we can have cases when a toplevel is being destroyed
+ * where the winPtr for the toplevel has been freed, but the children
+ * are not all the way destroyed. The children will call this function
+ * as they are being destroyed, but Tk_IsEmbedded will return garbage.
+ * So we check the copy of the TK_EMBEDDED flag we put into the
+ * toplevel's macWin flags.
+ */
+
+
+
+
+ if (!(macWin->toplevel->flags & TK_EMBEDDED)) {
+ return macWin->toplevel->grafPtr;
+ } else {
+ TkWindow *contWinPtr;
+
+ contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);
+
+ if (contWinPtr != NULL) {
+ resultPort = TkMacOSXGetDrawablePort(
+ (Drawable) contWinPtr->privatePtr);
+ } else if (gMacEmbedHandler != NULL) {
+ resultPort = gMacEmbedHandler->getPortProc(
+ (Tk_Window) macWin->winPtr);
+ }
+
+ if (resultPort == NULL) {
+ /*
+ * FIXME:
+ *
+ * So far as I can tell, the only time that this happens is when
+ * we are tearing down an embedded child interpreter, and most
+ * of the time, this is harmless... However, we really need to
+ * find why the embedding loses.
+ */
+ DebugStr("\pTkMacOSXGetDrawablePort couldn't find container");
+ return NULL;
+ }
+
+ /*
+ * NOTE: Here we should handle out of process embedding.
+ */
+
+ }
+ return resultPort;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXGetRootControl --
+ *
+ * This function returns the Root Control for a given X drawable.
+ *
+ * Results:
+ * A ControlRef .
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ControlRef
+TkMacOSXGetRootControl(
+ Drawable drawable)
+{
+ /*
+ * will probably need to fix this up for embedding
+ */
+ MacDrawable *macWin = (MacDrawable *) drawable;
+ ControlRef result = NULL;
+
+ if (macWin == NULL) {
+ return NULL;
+ }
+ if (!(macWin->toplevel->flags & TK_EMBEDDED)) {
+ return macWin->toplevel->rootControl;
+ } else {
+ TkWindow *contWinPtr;
+
+ contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);
+
+ if (contWinPtr != NULL) {
+ result = TkMacOSXGetRootControl(
+ (Drawable) contWinPtr->privatePtr);
+ } else if (gMacEmbedHandler != NULL) {
+ result = NULL;
+ }
+ }
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXInvalClipRgns --
+ *
+ * This function invalidates the clipping regions for a given
+ * window and all of its children. This function should be
+ * called whenever changes are made to subwindows that would
+ * effect the size or position of windows.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The cliping regions for the window and its children are
+ * mark invalid. (Make sure they are valid before drawing.)
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXInvalClipRgns(
+ TkWindow *winPtr)
+{
+ TkWindow *childPtr;
+
+ /*
+ * If already marked we can stop because all
+ * decendants will also already be marked.
+ */
+ if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
+ return;
+ }
+
+ winPtr->privatePtr->flags |= TK_CLIP_INVALID;
+
+ /*
+ * Invalidate clip regions for all children &
+ * their decendants - unless the child is a toplevel.
+ */
+ childPtr = winPtr->childList;
+ while (childPtr != NULL) {
+ if (!Tk_IsTopLevel(childPtr) && Tk_IsMapped(childPtr)) {
+ TkMacOSXInvalClipRgns(childPtr);
+ }
+ childPtr = childPtr->nextPtr;
+ }
+
+ /*
+ * Also, if the window is a container, mark its embedded window
+ */
+
+ if (Tk_IsContainer(winPtr)) {
+ childPtr = TkpGetOtherWindow(winPtr);
+
+ if (childPtr != NULL && Tk_IsMapped(childPtr)) {
+ TkMacOSXInvalClipRgns(childPtr);
+ }
+
+ /*
+ * NOTE: Here we should handle out of process embedding.
+ */
+
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXWinBounds --
+ *
+ * Given a Tk window this function determines the windows
+ * bounds in relation to the Macintosh window's coordinate
+ * system. This is also the same coordinate system as the
+ * Tk toplevel window in which this window is contained.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXWinBounds(
+ TkWindow *winPtr,
+ Rect *bounds)
+{
+ bounds->left = (short) winPtr->privatePtr->xOff;
+ bounds->top = (short) winPtr->privatePtr->yOff;
+ bounds->right = (short) (winPtr->privatePtr->xOff +
+ winPtr->changes.width);
+ bounds->bottom = (short) (winPtr->privatePtr->yOff +
+ winPtr->changes.height);
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateOffsets --
+ *
+ * Updates the X & Y offsets of the given TkWindow from the
+ * TopLevel it is a decendant of.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The xOff & yOff fields for the Mac window datastructure
+ * is updated to the proper offset.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateOffsets(
+ TkWindow *winPtr,
+ int deltaX,
+ int deltaY)
+{
+ TkWindow *childPtr;
+
+ if (winPtr->privatePtr == NULL) {
+ /*
+ * We havn't called Tk_MakeWindowExist for this window yet. The
+ * offset information will be postponed and calulated at that
+ * time. (This will usually only happen when a mapped parent is
+ * being moved but has child windows that have yet to be mapped.)
+ */
+ return;
+ }
+
+ winPtr->privatePtr->xOff += deltaX;
+ winPtr->privatePtr->yOff += deltaY;
+
+ childPtr = winPtr->childList;
+ while (childPtr != NULL) {
+ if (!Tk_IsTopLevel(childPtr)) {
+ UpdateOffsets(childPtr, deltaX, deltaY);
+ }
+ childPtr = childPtr->nextPtr;
+ }
+
+ if (Tk_IsContainer(winPtr)) {
+ childPtr = TkpGetOtherWindow(winPtr);
+ if (childPtr != NULL) {
+ UpdateOffsets(childPtr,deltaX,deltaY);
+ }
+
+ /*
+ * NOTE: Here we should handle out of process embedding.
+ */
+
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_GetPixmap --
+ *
+ * Creates an in memory drawing surface.
+ *
+ * Results:
+ * Returns a handle to a new pixmap.
+ *
+ * Side effects:
+ * Allocates a new Macintosh GWorld.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Pixmap
+Tk_GetPixmap(
+ Display *display, /* Display for new pixmap (can be null). */
+ Drawable d, /* Drawable where pixmap will be used (ignored). */
+ int width, /* Dimensions of pixmap. */
+ int height,
+ int depth) /* Bits per pixel for pixmap. */
+{
+ QDErr err;
+ GWorldPtr gWorld;
+ Rect bounds;
+ MacDrawable *macPix;
+ PixMapHandle pixels;
+
+ if (display != NULL) {
+ display->request++;
+ }
+ macPix = (MacDrawable *) ckalloc(sizeof(MacDrawable));
+ macPix->winPtr = NULL;
+ macPix->xOff = 0;
+ macPix->yOff = 0;
+ macPix->clipRgn = NULL;
+ macPix->aboveClipRgn = NULL;
+ macPix->referenceCount = 0;
+ macPix->toplevel = NULL;
+ macPix->flags = 0;
+
+ bounds.top = bounds.left = 0;
+ bounds.right = (short) width;
+ bounds.bottom = (short) height;
+ if (depth != 1) {
+ depth = 0;
+ }
+ /*
+ * Allocate memory for the off screen pixmap. If we fail
+ * try again from system memory. Eventually, we may have
+ * to panic.
+ */
+ err = NewGWorld(&gWorld, depth, &bounds, NULL, NULL, 0);
+ if (err != noErr) {
+ err = NewGWorld(&gWorld, depth, &bounds, NULL, NULL, useTempMem);
+ }
+ if (err != noErr) {
+ panic("Out of memory: NewGWorld failed in Tk_GetPixmap");
+ }
+
+ /*
+ * Lock down the pixels so they don't move out from under us.
+ */
+ pixels = GetGWorldPixMap(gWorld);
+ LockPixels(pixels);
+ macPix->grafPtr = gWorld;
+
+ return (Pixmap) macPix;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_FreePixmap --
+ *
+ * Release the resources associated with a pixmap.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Deletes the Macintosh GWorld created by Tk_GetPixmap.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_FreePixmap(
+ Display *display, /* Display. */
+ Pixmap pixmap) /* Pixmap to destroy */
+{
+ MacDrawable *macPix = (MacDrawable *) pixmap;
+ PixMapHandle pixels;
+
+ display->request++;
+ pixels = GetGWorldPixMap(macPix->grafPtr);
+ UnlockPixels(pixels);
+ DisposeGWorld(macPix->grafPtr);
+ ckfree((char *) macPix);
+}
diff --git a/macosx/tkMacOSXTest.c b/macosx/tkMacOSXTest.c
new file mode 100644
index 0000000..02cad5f
--- /dev/null
+++ b/macosx/tkMacOSXTest.c
@@ -0,0 +1,82 @@
+/*
+ * tkMacOSXTest.c --
+ *
+ * Contains commands for platform specific tests for
+ * the Macintosh platform.
+ *
+ * Copyright (c) 1996 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXTest.c,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+
+#include <tcl.h>
+
+/*
+ * Forward declarations of procedures defined later in this file:
+ */
+
+int TkplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp));
+static int DebuggerCmd _ANSI_ARGS_((ClientData dummy,
+ Tcl_Interp *interp, int argc, char **argv));
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkplatformtestInit --
+ *
+ * Defines commands that test platform specific functionality for
+ * Unix platforms.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * Defines new commands.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkplatformtestInit(
+ Tcl_Interp *interp) /* Interpreter to add commands to. */
+{
+ /*
+ * Add commands for platform specific tests on MacOS here.
+ */
+
+ Tcl_CreateCommand(interp, "debugger", DebuggerCmd,
+ (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DebuggerCmd --
+ *
+ * This procedure simply calls the low level debugger.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DebuggerCmd(
+ ClientData clientData, /* Not used. */
+ Tcl_Interp *interp, /* Not used. */
+ int argc, /* Not used. */
+ char **argv) /* Not used. */
+{
+ Debugger();
+ return TCL_OK;
+}
diff --git a/macosx/tkMacOSXUtil.c b/macosx/tkMacOSXUtil.c
new file mode 100644
index 0000000..1e4e856
--- /dev/null
+++ b/macosx/tkMacOSXUtil.c
@@ -0,0 +1,330 @@
+#include <Carbon/Carbon.h>
+
+#include "tkMacOSXUtil.h"
+
+#define DIR_SEP_CHAR ':'
+
+/*****************************************************************************/
+pascal OSErr FSMakeFSSpecCompat(short vRefNum,
+ long dirID,
+ ConstStr255Param fileName,
+ FSSpec *spec)
+{
+ OSErr result;
+
+ {
+ /* Let the file system create the FSSpec if it can since it does the job */
+ /* much more efficiently than I can. */
+ result = FSMakeFSSpec(vRefNum, dirID, fileName, spec);
+ /* Fix a bug in Macintosh PC Exchange's MakeFSSpec code where 0 is */
+ /* returned in the parID field when making an FSSpec to the volume's */
+ /* root directory by passing a full pathname in MakeFSSpec's */
+ /* fileName parameter. Fixed in Mac OS 8.1 */
+ if ( (result == noErr) && (spec->parID == 0) )
+ spec->parID = fsRtParID;
+ }
+ return ( result );
+}
+
+
+/*****************************************************************************/
+pascal OSErr GetCatInfoNoName(short vRefNum,
+ long dirID,
+ ConstStr255Param name,
+ CInfoPBPtr pb)
+{
+ Str31 tempName;
+ OSErr error;
+
+ /* Protection against File Sharing problem */
+ if ( (name == NULL) || (name[0] == 0) )
+ {
+ tempName[0] = 0;
+ pb->dirInfo.ioNamePtr = tempName;
+ pb->dirInfo.ioFDirIndex = -1; /* use ioDirID */
+ }
+ else
+ {
+ pb->dirInfo.ioNamePtr = (StringPtr)name;
+ pb->dirInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */
+ }
+ pb->dirInfo.ioVRefNum = vRefNum;
+ pb->dirInfo.ioDrDirID = dirID;
+ error = PBGetCatInfoSync(pb);
+ pb->dirInfo.ioNamePtr = NULL;
+ return ( error );
+}
+/*****************************************************************************/
+pascal OSErr GetDirectoryID(short vRefNum,
+ long dirID,
+ ConstStr255Param name,
+ long *theDirID,
+ Boolean *isDirectory)
+{
+ CInfoPBRec pb;
+ OSErr error;
+ error = GetCatInfoNoName(vRefNum, dirID, name, &pb);
+ if ( error == noErr )
+ {
+ *isDirectory = (pb.hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0;
+ if ( *isDirectory )
+ {
+ *theDirID = pb.dirInfo.ioDrDirID;
+ }
+ else
+ {
+ *theDirID = pb.hFileInfo.ioFlParID;
+ }
+ }
+
+ return ( error );
+}
+
+/*****************************************************************************/
+pascal OSErr FSpGetDirectoryID(const FSSpec *spec,
+ long *theDirID,
+ Boolean *isDirectory)
+{
+ return ( GetDirectoryID(spec->vRefNum, spec->parID, spec->name,
+ theDirID, isDirectory) );
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FSpPathFromLocation --
+ *
+ * This function obtains a full path name for a given macintosh
+ * FSSpec. Unlike the More Files function FSpGetFullPath, this
+ * function will return a C string in the Handle. It also will
+ * create paths for FSSpec that do not yet exist.
+ *
+ * Results:
+ * OSErr code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+OSErr
+FSpPathFromLocation(
+ FSSpec *spec, /* The location we want a path for. */
+ int *length, /* Length of the resulting path. */
+ Handle *fullPath) /* Handle to path. */
+{
+ OSErr err;
+ FSSpec tempSpec;
+ CInfoPBRec pb;
+
+ *fullPath = NULL;
+
+ /*
+ * Make a copy of the input FSSpec that can be modified.
+ */
+ BlockMoveData(spec, &tempSpec, sizeof(FSSpec));
+
+ if (tempSpec.parID == fsRtParID) {
+ /*
+ * The object is a volume. Add a colon to make it a full
+ * pathname. Allocate a handle for it and we are done.
+ */
+ tempSpec.name[0] += 2;
+ tempSpec.name[tempSpec.name[0] - 1] = DIR_SEP_CHAR;
+ tempSpec.name[tempSpec.name[0]] = '\0';
+
+ err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]);
+ } else {
+ /*
+ * The object isn't a volume. Is the object a file or a directory?
+ */
+ pb.dirInfo.ioNamePtr = tempSpec.name;
+ pb.dirInfo.ioVRefNum = tempSpec.vRefNum;
+ pb.dirInfo.ioDrDirID = tempSpec.parID;
+ pb.dirInfo.ioFDirIndex = 0;
+ err = PBGetCatInfoSync(&pb);
+
+ if ((err == noErr) || (err == fnfErr)) {
+ /*
+ * If the file doesn't currently exist we start over. If the
+ * directory exists everything will work just fine. Otherwise we
+ * will just fail later. If the object is a directory, append a
+ * colon so full pathname ends with colon, but only if the name is
+ * not empty. NavServices returns FSSpec's with the parent ID set,
+ * but the name empty...
+ */
+ if (err == fnfErr) {
+ BlockMoveData(spec, &tempSpec, sizeof(FSSpec));
+ } else if ( (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) {
+ if (tempSpec.name[0] > 0) {
+ tempSpec.name[0] += 1;
+ tempSpec.name[tempSpec.name[0]] = DIR_SEP_CHAR;
+ }
+ }
+
+ /*
+ * Create a new Handle for the object - make it a C string.
+ */
+ tempSpec.name[0] += 1;
+ tempSpec.name[tempSpec.name[0]] = '\0';
+ err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]);
+ if (err == noErr) {
+ /*
+ * Get the ancestor directory names - loop until we have an
+ * error or find the root directory.
+ */
+ pb.dirInfo.ioNamePtr = tempSpec.name;
+ pb.dirInfo.ioVRefNum = tempSpec.vRefNum;
+ pb.dirInfo.ioDrParID = tempSpec.parID;
+ do {
+ pb.dirInfo.ioFDirIndex = -1;
+ pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
+ err = PBGetCatInfoSync(&pb);
+ if (err == noErr) {
+ /*
+ * Append colon to directory name and add
+ * directory name to beginning of fullPath.
+ */
+ ++tempSpec.name[0];
+ tempSpec.name[tempSpec.name[0]] = DIR_SEP_CHAR;
+
+ (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1],
+ tempSpec.name[0]);
+ fprintf(stderr,"mem\n");
+ err = MemError();
+ }
+ } while ( (err == noErr) &&
+ (pb.dirInfo.ioDrDirID != fsRtDirID) );
+ }
+ }
+ }
+
+ /*
+ * On error Dispose the handle, set it to NULL & return the err.
+ * Otherwise, set the length & return.
+ */
+ if (err == noErr) {
+ *length = GetHandleSize(*fullPath) - 1;
+ } else {
+ if ( *fullPath != NULL ) {
+ DisposeHandle(*fullPath);
+ }
+ *fullPath = NULL;
+ *length = 0;
+ }
+
+ return err;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FSpLocationFromPath --
+ *
+ * This function obtains an FSSpec for a given macintosh path.
+ * Unlike the More Files function FSpLocationFromFullPath, this
+ * function will also accept partial paths and resolve any aliases
+ * along the path.
+ *
+ * Results:
+ * OSErr code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+OSErr
+FSpLocationFromPath(
+ int length, /* Length of path. */
+ const char *path, /* The path to convert. */
+ FSSpecPtr fileSpecPtr) /* On return the spec for the path. */
+{
+ Str255 fileName;
+ OSErr err;
+ short vRefNum;
+ long dirID;
+ int pos, cur;
+ Boolean isDirectory;
+ Boolean wasAlias;
+
+ /*
+ * Check to see if this is a full path. If partial
+ * we assume that path starts with the current working
+ * directory. (Ie. volume & dir = 0)
+ */
+ vRefNum = 0;
+ dirID = 0;
+ cur = 0;
+ if (length == 0) {
+ return fnfErr;
+ }
+ if (path[cur] == DIR_SEP_CHAR) {
+ cur++;
+ if (cur >= length) {
+ /*
+ * If path = ":", just return current directory.
+ */
+ FSMakeFSSpecCompat(0, 0, NULL, fileSpecPtr);
+ return noErr;
+ }
+ } else {
+ while (path[cur] != DIR_SEP_CHAR && cur < length) {
+ cur++;
+ }
+ if (cur > 255) {
+ return bdNamErr;
+ }
+ if (cur < length) {
+ /*
+ * This is a full path
+ */
+ cur++;
+ strncpy((char *) fileName + 1, path, cur);
+ fileName[0] = cur;
+ err = FSMakeFSSpecCompat(0, 0, fileName, fileSpecPtr);
+ if (err != noErr) return err;
+ FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory);
+ vRefNum = fileSpecPtr->vRefNum;
+ } else {
+ cur = 0;
+ }
+ }
+
+ isDirectory = 1;
+ while (cur < length) {
+ if (!isDirectory) {
+ return dirNFErr;
+ }
+ pos = cur;
+ while (path[pos] != DIR_SEP_CHAR && pos < length) {
+ pos++;
+ }
+ if (pos == cur) {
+ /* Move up one dir */
+ /* cur++; */
+ fileName[1] = DIR_SEP_CHAR;
+ fileName[2] = DIR_SEP_CHAR;
+ fileName[0] = 2;
+ } else if (pos - cur > 255) {
+ return bdNamErr;
+ } else {
+ strncpy((char *) fileName + 1, &path[cur], pos - cur);
+ fileName[0] = pos - cur;
+ }
+ err = FSMakeFSSpecCompat(vRefNum, dirID, fileName, fileSpecPtr);
+ if (err != noErr) return err;
+ err = ResolveAliasFile(fileSpecPtr, true, &isDirectory, &wasAlias);
+ if (err != noErr) return err;
+ FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory);
+ vRefNum = fileSpecPtr->vRefNum;
+ cur = pos;
+ if (path[cur] == DIR_SEP_CHAR) {
+ cur++;
+ }
+ }
+
+ return noErr;
+}
diff --git a/macosx/tkMacOSXUtil.h b/macosx/tkMacOSXUtil.h
new file mode 100644
index 0000000..e38f8a5
--- /dev/null
+++ b/macosx/tkMacOSXUtil.h
@@ -0,0 +1,65 @@
+/*
+ * tkMacOSXUtil.h --
+ *
+ * Declarations of utility functions from the MoreFiles package.
+ *
+ * FIXME: We should be able to replace all these with FSRef calls
+ * much more simply.
+ *
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.
+ */
+
+#ifndef TK_MAC_UTIL_H
+#define TK_MAC_UTIL_H
+
+#include <Carbon/Carbon.h>
+
+OSErr FSpPathFromLocation(FSSpec *spec, int *length, Handle *fullPath);
+OSErr FSpLocationFromPath(int length, const char *path, FSSpecPtr fileSpecPtr);
+OSErr FSpGetDirectoryID(const FSSpec *spec, long *theDirID, Boolean *isDirectory);
+
+#endif
diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c
new file mode 100644
index 0000000..d21d1f1
--- /dev/null
+++ b/macosx/tkMacOSXWindowEvent.c
@@ -0,0 +1,693 @@
+/*
+ * tkMacOSXWindowEvent.c --
+ *
+ * This file defines the routines for both creating and handling
+ * Window Manager class events for Tk.
+ *
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.
+ */
+
+#include "tkMacOSXInt.h"
+#include "tkPort.h"
+#include "tkMacOSXWm.h"
+#include "tkMacOSXEvent.h"
+#include "tkMacOSXDebug.h"
+
+/*
+ * Declarations of global variables defined in this file.
+ */
+
+int tkMacOSXAppInFront = true; /* Boolean variable for determining if
+ * we are the frontmost app. Only set
+ * in TkMacOSXProcessApplicationEvent
+ */
+static RgnHandle gDamageRgn;
+static RgnHandle visRgn;
+
+/*
+ * Declaration of functions used only in this file
+ */
+
+static int GenerateUpdateEvent( Window window);
+static void GenerateUpdates( RgnHandle updateRgn, TkWindow *winPtr);
+static int GenerateActivateEvents( Window window, int activeFlag);
+static int GenerateFocusEvent( Window window, int activeFlag);
+
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXProcessApplicationEvent --
+ *
+ * This processes Application level events, mainly activate
+ * and deactivate.
+ *
+ * Results:
+ * o.
+ *
+ * Side effects:
+ * Hide or reveal floating windows, and set tkMacOSXAppInFront.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkMacOSXProcessApplicationEvent(
+ TkMacOSXEvent *eventPtr,
+ MacEventStatus *statusPtr)
+{
+ statusPtr->handledByTk = 1;
+ switch (eventPtr->eKind) {
+ case kEventAppActivated:
+ tkMacOSXAppInFront = true;
+ ShowFloatingWindows();
+ break;
+ case kEventAppDeactivated:
+ TkSuspendClipboard();
+ tkMacOSXAppInFront = false;
+ HideFloatingWindows();
+ break;
+ case kEventAppQuit:
+ case kEventAppLaunchNotification:
+ case kEventAppLaunched:
+ case kEventAppTerminated:
+ case kEventAppFrontSwitched:
+ break;
+ }
+ return 0;
+}
+ /*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXProcessWindowEvent --
+ *
+ * This processes Window level events, mainly activate
+ * and deactivate.
+ *
+ * Results:
+ * 0.
+ *
+ * Side effects:
+ * Cause Windows to be moved forward or backward in the
+ * window stack.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkMacOSXProcessWindowEvent(
+ TkMacOSXEvent * eventPtr,
+ MacEventStatus * statusPtr)
+{
+ OSStatus status;
+ WindowRef whichWindow;
+ Window window;
+ int eventFound;
+
+ switch (eventPtr->eKind) {
+ case kEventWindowActivated:
+ case kEventWindowDeactivated:
+ case kEventWindowUpdate:
+ break;
+ default:
+ statusPtr->handledByTk = 1;
+ return 0;
+ break;
+ }
+ statusPtr->handledByTk = 1;
+ status = GetEventParameter(eventPtr->eventRef,
+ kEventParamDirectObject,
+ typeWindowRef, NULL,
+ sizeof(whichWindow), NULL,
+ &whichWindow);
+ if (status != noErr) {
+ fprintf ( stderr, "TkMacOSXHandleWindowEvent:Failed to retrieve window" );
+ return 0;
+ }
+
+ window = TkMacOSXGetXWindow(whichWindow);
+
+ switch (eventPtr->eKind) {
+ case kEventWindowActivated:
+ eventFound |= GenerateActivateEvents(window, 1);
+ eventFound |= GenerateFocusEvent(window, 1);
+ break;
+ case kEventWindowDeactivated:
+ eventFound |= GenerateActivateEvents(window, 0);
+ eventFound |= GenerateFocusEvent(window, 0);
+ break;
+ case kEventWindowUpdate:
+ if (GenerateUpdateEvent(window)) {
+ eventFound = true;
+ } else {
+ statusPtr->handledByTk = 0;
+ }
+ break;
+ }
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GenerateUpdateEvent --
+ *
+ * Given a Macintosh window update event this function generates all the
+ * X update events needed by Tk.
+ *
+ * Results:
+ * True if event(s) are generated - false otherwise.
+ *
+ * Side effects:
+ * Additional events may be place on the Tk event queue.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+GenerateUpdateEvent(Window window)
+{
+ WindowRef macWindow;
+ TkDisplay * dispPtr;
+ TkWindow * winPtr;
+ Rect bounds;
+
+ dispPtr = TkGetDisplayList();
+ winPtr = (TkWindow *)Tk_IdToWindow(dispPtr->display, window);
+
+ if (winPtr ==NULL ){
+ return false;
+ }
+ if (gDamageRgn == NULL) {
+ gDamageRgn = NewRgn();
+ }
+ if (visRgn == NULL) {
+ visRgn = NewRgn();
+ }
+ macWindow = GetWindowFromPort(TkMacOSXGetDrawablePort(window));
+ BeginUpdate(macWindow);
+ /*
+ * In the Classic version of the code, this was the "visRgn" field of the WindowRec
+ * This no longer exists in OS X, so retrieve the content region instead
+ * Note that this is in screen coordinates
+ * We therefore convert it to window relative coordinates
+ */
+ GetWindowRegion (macWindow, kWindowContentRgn, visRgn );
+ GetRegionBounds(visRgn,&bounds);
+ bounds.right -= bounds.left;
+ bounds.bottom -= bounds.top;
+ bounds.left=
+ bounds.top=0;
+ RectRgn(visRgn, &bounds);
+ GenerateUpdates(visRgn, winPtr);
+ EndUpdate(macWindow);
+ return true;
+ }
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GenerateUpdates --
+ *
+ * Given a Macintosh update region and a Tk window this function
+ * geneates a X damage event for the window if it is within the
+ * update region. The function will then recursivly have each
+ * damaged window generate damage events for its child windows.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Additional events may be place on the Tk event queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GenerateUpdates(
+ RgnHandle updateRgn,
+ TkWindow *winPtr)
+{
+ TkWindow *childPtr;
+ XEvent event;
+ Rect bounds, updateBounds, damageBounds;
+
+ TkMacOSXWinBounds(winPtr, &bounds);
+ GetRegionBounds(updateRgn,&updateBounds);
+
+ if (bounds.top > updateBounds.bottom ||
+ updateBounds.top > bounds.bottom ||
+ bounds.left > updateBounds.right ||
+ updateBounds.left > bounds.right ||
+ !RectInRgn(&bounds, updateRgn)) {
+ return;
+ }
+ if (!RectInRgn(&bounds, updateRgn)) {
+ return;
+ }
+
+ event.xany.serial = Tk_Display(winPtr)->request;
+ event.xany.send_event = false;
+ event.xany.window = Tk_WindowId(winPtr);
+ event.xany.display = Tk_Display(winPtr);
+
+ event.type = Expose;
+
+ /*
+ * Compute the bounding box of the area that the damage occured in.
+ */
+
+ /*
+ * CopyRgn(TkMacOSXVisableClipRgn(winPtr), rgn);
+ * TODO: this call doesn't work doing resizes!!!
+ */
+ RectRgn(gDamageRgn, &bounds);
+ SectRgn(gDamageRgn, updateRgn, gDamageRgn);
+ OffsetRgn(gDamageRgn, -bounds.left, -bounds.top);
+ GetRegionBounds(gDamageRgn,&damageBounds);
+ event.xexpose.x = damageBounds.left;
+ event.xexpose.y = damageBounds.top;
+ event.xexpose.width = damageBounds.right-damageBounds.left;
+ event.xexpose.height = damageBounds.bottom-damageBounds.top;
+ event.xexpose.count = 0;
+
+ Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
+
+ /*
+ * Generate updates for the children of this window
+ */
+
+ for (childPtr = winPtr->childList; childPtr != NULL;
+ childPtr = childPtr->nextPtr) {
+ if (!Tk_IsMapped(childPtr) || Tk_IsTopLevel(childPtr)) {
+ continue;
+ }
+
+ GenerateUpdates(updateRgn, childPtr);
+ }
+
+ /*
+ * Generate updates for any contained windows
+ */
+
+ if (Tk_IsContainer(winPtr)) {
+ childPtr = TkpGetOtherWindow(winPtr);
+ if (childPtr != NULL && Tk_IsMapped(childPtr)) {
+ GenerateUpdates(updateRgn, childPtr);
+ }
+
+ /*
+ * NOTE: Here we should handle out of process embedding.
+ */
+
+ }
+
+ return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GenerateActivateEvents --
+ *
+ * Given a Macintosh window activate event this function generates all the
+ * X Activate events needed by Tk.
+ *
+ * Results:
+ * True if event(s) are generated - false otherwise.
+ *
+ * Side effects:
+ * Additional events may be place on the Tk event queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+GenerateActivateEvents(
+ Window window, /* Root X window for event. */
+ int activeFlag )
+{
+ TkWindow *winPtr;
+ TkDisplay *dispPtr;
+
+ dispPtr = TkGetDisplayList();
+ winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window);
+ if (winPtr == NULL || winPtr->window == None) {
+ return false;
+ }
+
+ TkGenerateActivateEvents(winPtr,activeFlag);
+ return true;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GenerateFocusEvent --
+ *
+ * Given a Macintosh window activate event this function generates all the
+ * X Focus events needed by Tk.
+ *
+ * Results:
+ * True if event(s) are generated - false otherwise.
+ *
+ * Side effects:
+ * Additional events may be place on the Tk event queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+GenerateFocusEvent(
+ Window window, /* Root X window for event. */
+ int activeFlag )
+{
+ XEvent event;
+ Tk_Window tkwin;
+ TkDisplay *dispPtr;
+
+ dispPtr = TkGetDisplayList();
+ tkwin = Tk_IdToWindow(dispPtr->display, window);
+ if (tkwin == NULL) {
+ return false;
+ }
+
+ /*
+ * Generate FocusIn and FocusOut events. This event
+ * is only sent to the toplevel window.
+ */
+
+ if (activeFlag) {
+ event.xany.type = FocusIn;
+ } else {
+ event.xany.type = FocusOut;
+ }
+
+ event.xany.serial = dispPtr->display->request;
+ event.xany.send_event = False;
+ event.xfocus.display = dispPtr->display;
+ event.xfocus.window = window;
+ event.xfocus.mode = NotifyNormal;
+ event.xfocus.detail = NotifyDetailNone;
+
+ Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
+ return true;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkGenWMConfigureEvent --
+ *
+ * Generate a ConfigureNotify event for Tk. Depending on the
+ * value of flag the values of width/height, x/y, or both may
+ * be changed.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * A ConfigureNotify event is sent to Tk.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkGenWMConfigureEvent(
+ Tk_Window tkwin,
+ int x,
+ int y,
+ int width,
+ int height,
+ int flags)
+{
+ XEvent event;
+ WmInfo *wmPtr;
+ TkWindow *winPtr = (TkWindow *) tkwin;
+
+ if (tkwin == NULL) {
+ return;
+ }
+
+ event.type = ConfigureNotify;
+ event.xconfigure.serial = Tk_Display(tkwin)->request;
+ event.xconfigure.send_event = False;
+ event.xconfigure.display = Tk_Display(tkwin);
+ event.xconfigure.event = Tk_WindowId(tkwin);
+ event.xconfigure.window = Tk_WindowId(tkwin);
+ event.xconfigure.border_width = winPtr->changes.border_width;
+ event.xconfigure.override_redirect = winPtr->atts.override_redirect;
+ if (winPtr->changes.stack_mode == Above) {
+ event.xconfigure.above = winPtr->changes.sibling;
+ } else {
+ event.xconfigure.above = None;
+ }
+
+ if (flags & TK_LOCATION_CHANGED) {
+ event.xconfigure.x = x;
+ event.xconfigure.y = y;
+ } else {
+ event.xconfigure.x = Tk_X(tkwin);
+ event.xconfigure.y = Tk_Y(tkwin);
+ x = Tk_X(tkwin);
+ y = Tk_Y(tkwin);
+ }
+ if (flags & TK_SIZE_CHANGED) {
+ event.xconfigure.width = width;
+ event.xconfigure.height = height;
+ } else {
+ event.xconfigure.width = Tk_Width(tkwin);
+ event.xconfigure.height = Tk_Height(tkwin);
+ width = Tk_Width(tkwin);
+ height = Tk_Height(tkwin);
+ }
+
+ Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
+
+ /*
+ * Update window manager information.
+ */
+ if (Tk_IsTopLevel(winPtr)) {
+ wmPtr = winPtr->wmInfoPtr;
+ if (flags & TK_LOCATION_CHANGED) {
+ wmPtr->x = x;
+ wmPtr->y = y;
+ wmPtr->flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y);
+ }
+ if ((flags & TK_SIZE_CHANGED) &&
+ ((width != Tk_Width(tkwin)) || (height != Tk_Height(tkwin)))) {
+ if ((wmPtr->width == -1) && (width == winPtr->reqWidth)) {
+ /*
+ * Don't set external width, since the user didn't change it
+ * from what the widgets asked for.
+ */
+ } else {
+ if (wmPtr->gridWin != NULL) {
+ wmPtr->width = wmPtr->reqGridWidth
+ + (width - winPtr->reqWidth)/wmPtr->widthInc;
+ if (wmPtr->width < 0) {
+ wmPtr->width = 0;
+ }
+ } else {
+ wmPtr->width = width;
+ }
+ }
+ if ((wmPtr->height == -1) && (height == winPtr->reqHeight)) {
+ /*
+ * Don't set external height, since the user didn't change it
+ * from what the widgets asked for.
+ */
+ } else {
+ if (wmPtr->gridWin != NULL) {
+ wmPtr->height = wmPtr->reqGridHeight
+ + (height - winPtr->reqHeight)/wmPtr->heightInc;
+ if (wmPtr->height < 0) {
+ wmPtr->height = 0;
+ }
+ } else {
+ wmPtr->height = height;
+ }
+ }
+ wmPtr->configWidth = width;
+ wmPtr->configHeight = height;
+ }
+ }
+
+ /*
+ * Now set up the changes structure. Under X we wait for the
+ * ConfigureNotify to set these values. On the Mac we know imediatly that
+ * this is what we want - so we just set them. However, we need to
+ * make sure the windows clipping region is marked invalid so the
+ * change is visable to the subwindow.
+ */
+ winPtr->changes.x = x;
+ winPtr->changes.y = y;
+ winPtr->changes.width = width;
+ winPtr->changes.height = height;
+ TkMacOSXInvalClipRgns(winPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkGenWMDestroyEvent --
+ *
+ * Generate a WM Destroy event for Tk. *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * A WM_PROTOCOL/WM_DELETE_WINDOW event is sent to Tk.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkGenWMDestroyEvent(
+ Tk_Window tkwin)
+{
+ XEvent event;
+
+ event.xany.serial = Tk_Display(tkwin)->request;
+ event.xany.send_event = False;
+ event.xany.display = Tk_Display(tkwin);
+
+ event.xclient.window = Tk_WindowId(tkwin);
+ event.xclient.type = ClientMessage;
+ event.xclient.message_type = Tk_InternAtom(tkwin, "WM_PROTOCOLS");
+ event.xclient.format = 32;
+ event.xclient.data.l[0] = Tk_InternAtom(tkwin, "WM_DELETE_WINDOW");
+ Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkWmProtocolEventProc --
+ *
+ * This procedure is called by the Tk_HandleEvent whenever a
+ * ClientMessage event arrives whose type is "WM_PROTOCOLS".
+ * This procedure handles the message from the window manager
+ * in an appropriate fashion.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Depends on what sort of handler, if any, was set up for the
+ * protocol.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkWmProtocolEventProc(
+ TkWindow *winPtr, /* Window to which the event was sent. */
+ XEvent *eventPtr) /* X event. */
+{
+ WmInfo *wmPtr;
+ ProtocolHandler *protPtr;
+ Tcl_Interp *interp;
+ Atom protocol;
+ int result;
+
+ wmPtr = winPtr->wmInfoPtr;
+ if (wmPtr == NULL) {
+ return;
+ }
+ protocol = (Atom) eventPtr->xclient.data.l[0];
+ for (protPtr = wmPtr->protPtr; protPtr != NULL;
+ protPtr = protPtr->nextPtr) {
+ if (protocol == protPtr->protocol) {
+ Tcl_Preserve((ClientData) protPtr);
+ interp = protPtr->interp;
+ Tcl_Preserve((ClientData) interp);
+ result = Tcl_GlobalEval(interp, protPtr->command);
+ if (result != TCL_OK) {
+ Tcl_AddErrorInfo(interp, "\n (command for \"");
+ Tcl_AddErrorInfo(interp,
+ Tk_GetAtomName((Tk_Window) winPtr, protocol));
+ Tcl_AddErrorInfo(interp, "\" window manager protocol)");
+ Tk_BackgroundError(interp);
+ }
+ Tcl_Release((ClientData) interp);
+ Tcl_Release((ClientData) protPtr);
+ return;
+ }
+ }
+
+ /*
+ * No handler was present for this protocol. If this is a
+ * WM_DELETE_WINDOW message then just destroy the window.
+ */
+
+ if (protocol == Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW")) {
+ Tk_DestroyWindow((Tk_Window) winPtr);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_MacOSXIsAppInFront --
+ *
+ * Returns 1 if this app is the foreground app.
+ *
+ * Results:
+ * 1 if app is in front, 0 otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tk_MacOSXIsAppInFront (void)
+{
+ return tkMacOSXAppInFront;
+} \ No newline at end of file
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
new file mode 100644
index 0000000..094ef30
--- /dev/null
+++ b/macosx/tkMacOSXWm.c
@@ -0,0 +1,5506 @@
+/*
+ * tkMacOSXWm.c --
+ *
+ * This module takes care of the interactions between a Tk-based
+ * application and the window manager. Among other things, it
+ * implements the "wm" command and passes geometry information
+ * to the window manager.
+ *
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXWm.c,v 1.2 2002/08/31 06:12:30 das Exp $
+ */
+#include <Carbon/Carbon.h>
+
+#include "tkPort.h"
+#include "tkInt.h"
+#include "tkMacOSXInt.h"
+#include <errno.h>
+#include "tkScrollbar.h"
+#include "tkMacOSXWm.h"
+#include "tkMacOSXEvent.h"
+#include "tkMacOSXUtil.h"
+
+/*
+ * This is a list of all of the toplevels that have been mapped so far. It is
+ * used by the menu code to inval windows that were damaged by menus, and will
+ * eventually also be used to keep track of floating windows.
+ */
+
+TkMacOSXWindowList *tkMacOSXWindowListPtr = NULL;
+
+/*
+ * The variable below is used to enable or disable tracing in this
+ * module. If tracing is enabled, then information is printed on
+ * standard output about interesting interactions with the window
+ * manager.
+ */
+
+static int wmTracing = 0;
+
+/*
+ * The following structure is the official type record for geometry
+ * management of top-level windows.
+ */
+
+static void TopLevelReqProc _ANSI_ARGS_((ClientData dummy,
+ Tk_Window tkwin));
+
+static Tk_GeomMgr wmMgrType = {
+ "wm", /* name */
+ TopLevelReqProc, /* requestProc */
+ (Tk_GeomLostSlaveProc *) NULL, /* lostSlaveProc */
+};
+
+/*
+ * Hash table for Mac Window -> TkWindow mapping.
+ */
+
+static Tcl_HashTable windowTable;
+static int windowHashInit = false;
+
+/*
+ * Forward declarations for procedures defined in this file:
+ */
+
+static void InitialWindowBounds _ANSI_ARGS_((TkWindow *winPtr,
+ Rect *geometry));
+static int ParseGeometry _ANSI_ARGS_((Tcl_Interp *interp,
+ char *string, TkWindow *winPtr));
+static void TopLevelEventProc _ANSI_ARGS_((ClientData clientData,
+ XEvent *eventPtr));
+static void TopLevelReqProc _ANSI_ARGS_((ClientData dummy,
+ Tk_Window tkwin));
+static void UpdateGeometryInfo _ANSI_ARGS_((
+ ClientData clientData));
+static void UpdateSizeHints _ANSI_ARGS_((TkWindow *winPtr));
+static void UpdateVRootGeometry _ANSI_ARGS_((WmInfo *wmPtr));
+static int WmAspectCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmAttributesCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmClientCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmColormapwindowsCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmCommandCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmDeiconifyCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmFocusmodelCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmFrameCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmGeometryCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmGridCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmGroupCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmIconbitmapCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmIconifyCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmIconmaskCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmIconnameCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmIconpositionCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmIconwindowCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmMaxsizeCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmMinsizeCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmOverrideredirectCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmPositionfromCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmProtocolCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmResizableCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmSizefromCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmStackorderCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmStateCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmTitleCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmTransientCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int WmWithdrawCmd _ANSI_ARGS_((Tk_Window tkwin,
+ TkWindow *winPtr, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static void WmUpdateGeom _ANSI_ARGS_((WmInfo *wmPtr,
+ TkWindow *winPtr));
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkWmNewWindow --
+ *
+ * This procedure is invoked whenever a new top-level
+ * window is created. Its job is to initialize the WmInfo
+ * structure for the window.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * A WmInfo structure gets allocated and initialized.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TkWmNewWindow(
+ TkWindow *winPtr) /* Newly-created top-level window. */
+{
+ WmInfo *wmPtr;
+
+ wmPtr = (WmInfo *) ckalloc(sizeof(WmInfo));
+ wmPtr->winPtr = winPtr;
+ wmPtr->reparent = None;
+ wmPtr->titleUid = NULL;
+ wmPtr->iconName = NULL;
+ wmPtr->master = None;
+ wmPtr->hints.flags = InputHint | StateHint;
+ wmPtr->hints.input = True;
+ wmPtr->hints.initial_state = NormalState;
+ wmPtr->hints.icon_pixmap = None;
+ wmPtr->hints.icon_window = None;
+ wmPtr->hints.icon_x = wmPtr->hints.icon_y = 0;
+ wmPtr->hints.icon_mask = None;
+ wmPtr->hints.window_group = None;
+ wmPtr->leaderName = NULL;
+ wmPtr->masterWindowName = NULL;
+ wmPtr->icon = NULL;
+ wmPtr->iconFor = NULL;
+ wmPtr->sizeHintsFlags = 0;
+ wmPtr->minWidth = wmPtr->minHeight = 1;
+
+ /*
+ * Default the maximum dimensions to the size of the display, minus
+ * a guess about how space is needed for window manager decorations.
+ */
+
+ wmPtr->maxWidth = DisplayWidth(winPtr->display, winPtr->screenNum) - 15;
+ wmPtr->maxHeight = DisplayHeight(winPtr->display, winPtr->screenNum) - 30;
+ wmPtr->gridWin = NULL;
+ wmPtr->widthInc = wmPtr->heightInc = 1;
+ wmPtr->minAspect.x = wmPtr->minAspect.y = 1;
+ wmPtr->maxAspect.x = wmPtr->maxAspect.y = 1;
+ wmPtr->reqGridWidth = wmPtr->reqGridHeight = -1;
+ wmPtr->gravity = NorthWestGravity;
+ wmPtr->width = -1;
+ wmPtr->height = -1;
+ wmPtr->x = winPtr->changes.x;
+ wmPtr->y = winPtr->changes.y;
+ wmPtr->parentWidth = winPtr->changes.width
+ + 2*winPtr->changes.border_width;
+ wmPtr->parentHeight = winPtr->changes.height
+ + 2*winPtr->changes.border_width;
+ wmPtr->xInParent = 0;
+ wmPtr->yInParent = 0;
+ wmPtr->cmapList = NULL;
+ wmPtr->cmapCount = 0;
+ wmPtr->configWidth = -1;
+ wmPtr->configHeight = -1;
+ wmPtr->vRoot = None;
+ wmPtr->protPtr = NULL;
+ wmPtr->cmdArgv = NULL;
+ wmPtr->clientMachine = NULL;
+ wmPtr->flags = WM_NEVER_MAPPED;
+ wmPtr->style = -1;
+ wmPtr->macClass = kDocumentWindowClass;
+ wmPtr->attributes = kWindowStandardDocumentAttributes;
+ wmPtr->scrollWinPtr = NULL;
+ winPtr->wmInfoPtr = wmPtr;
+
+ UpdateVRootGeometry(wmPtr);
+
+ /*
+ * Tk must monitor structure events for top-level windows, in order
+ * to detect size and position changes caused by window managers.
+ */
+
+ Tk_CreateEventHandler((Tk_Window) winPtr, StructureNotifyMask,
+ TopLevelEventProc, (ClientData) winPtr);
+
+ /*
+ * Arrange for geometry requests to be reflected from the window
+ * to the window manager.
+ */
+
+ Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, (ClientData) 0);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkWmMapWindow --
+ *
+ * This procedure is invoked to map a top-level window. This
+ * module gets a chance to update all window-manager-related
+ * information in properties before the window manager sees
+ * the map event and checks the properties. It also gets to
+ * decide whether or not to even map the window after all.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Properties of winPtr may get updated to provide up-to-date
+ * information to the window manager. The window may also get
+ * mapped, but it may not be if this procedure decides that
+ * isn't appropriate (e.g. because the window is withdrawn).
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TkWmMapWindow(
+ TkWindow *winPtr) /* Top-level window that's about to
+ * be mapped. */
+{
+ WmInfo *wmPtr = winPtr->wmInfoPtr;
+ Point where = {0, 0};
+ int xOffset, yOffset;
+ int firstMap = false;
+ MacDrawable *macWin;
+
+ if (wmPtr->flags & WM_NEVER_MAPPED) {
+ wmPtr->flags &= ~WM_NEVER_MAPPED;
+ firstMap = true;
+
+ /*
+ * Create the underlying Mac window for this Tk window.
+ */
+ macWin = (MacDrawable *) winPtr->window;
+ if (!TkMacOSXHostToplevelExists(winPtr)) {
+ TkMacOSXMakeRealWindowExist(winPtr);
+ }
+
+ /*
+ * Generate configure event when we first map the window.
+ */
+ LocalToGlobal(&where);
+ TkMacOSXWindowOffset( GetWindowFromPort(TkMacOSXGetDrawablePort((Drawable) macWin)),
+ &xOffset, &yOffset);
+ where.h -= xOffset;
+ where.v -= yOffset;
+ TkGenWMConfigureEvent((Tk_Window) winPtr,
+ where.h, where.v, -1, -1, TK_LOCATION_CHANGED);
+
+ /*
+ * This is the first time this window has ever been mapped.
+ * Store all the window-manager-related information for the
+ * window.
+ */
+
+ if (wmPtr->titleUid == NULL) {
+ wmPtr->titleUid = winPtr->nameUid;
+ }
+
+ if (!Tk_IsEmbedded(winPtr)) {
+ TkSetWMName(winPtr, wmPtr->titleUid);
+ }
+
+ TkWmSetClass(winPtr);
+
+ if (wmPtr->iconName != NULL) {
+ XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName);
+ }
+
+ wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
+ }
+ if (wmPtr->hints.initial_state == WithdrawnState) {
+ return;
+ }
+
+ /*
+ * TODO: we need to display a window if it's iconic on creation.
+ */
+
+ if (wmPtr->hints.initial_state == IconicState) {
+ return;
+ }
+
+ /*
+ * Update geometry information.
+ */
+ wmPtr->flags |= WM_ABOUT_TO_MAP;
+ if (wmPtr->flags & WM_UPDATE_PENDING) {
+ Tk_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
+ }
+ UpdateGeometryInfo((ClientData) winPtr);
+ wmPtr->flags &= ~WM_ABOUT_TO_MAP;
+
+ /*
+ * Map the window.
+ */
+
+ XMapWindow(winPtr->display, winPtr->window);
+
+ /*
+ * Now that the window is visable we can determine the offset
+ * from the window's content orgin to the window's decorative
+ * orgin (structure orgin).
+ */
+ TkMacOSXWindowOffset( GetWindowFromPort(TkMacOSXGetDrawablePort(Tk_WindowId(winPtr))),
+ &wmPtr->xInParent, &wmPtr->yInParent);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkWmUnmapWindow --
+ *
+ * This procedure is invoked to unmap a top-level window.
+ * On the Macintosh all we do is call XUnmapWindow.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Unmaps the window.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TkWmUnmapWindow(
+ TkWindow *winPtr) /* Top-level window that's about to
+ * be mapped. */
+{
+ XUnmapWindow(winPtr->display, winPtr->window);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkWmDeadWindow --
+ *
+ * This procedure is invoked when a top-level window is
+ * about to be deleted. It cleans up the wm-related data
+ * structures for the window.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The WmInfo structure for winPtr gets freed up.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TkWmDeadWindow(winPtr)
+ TkWindow *winPtr; /* Top-level window that's being deleted. */
+{
+ WmInfo *wmPtr = winPtr->wmInfoPtr;
+ WmInfo *wmPtr2;
+
+ if (wmPtr == NULL) {
+ return;
+ }
+ if (wmPtr->hints.flags & IconPixmapHint) {
+ Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
+ }
+ if (wmPtr->hints.flags & IconMaskHint) {
+ Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
+ }
+ if (wmPtr->leaderName != NULL) {
+ ckfree(wmPtr->leaderName);
+ }
+ if (wmPtr->masterWindowName != NULL) {
+ ckfree(wmPtr->masterWindowName);
+ }
+ if (wmPtr->icon != NULL) {
+ wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
+ wmPtr2->iconFor = NULL;
+ }
+ if (wmPtr->iconFor != NULL) {
+ wmPtr2 = ((TkWindow *) wmPtr->iconFor)->wmInfoPtr;
+ wmPtr2->icon = NULL;
+ wmPtr2->hints.flags &= ~IconWindowHint;
+ }
+ while (wmPtr->protPtr != NULL) {
+ ProtocolHandler *protPtr;
+
+ protPtr = wmPtr->protPtr;
+ wmPtr->protPtr = protPtr->nextPtr;
+ Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC);
+ }
+ if (wmPtr->cmdArgv != NULL) {
+ ckfree((char *) wmPtr->cmdArgv);
+ }
+ if (wmPtr->clientMachine != NULL) {
+ ckfree((char *) wmPtr->clientMachine);
+ }
+ if (wmPtr->flags & WM_UPDATE_PENDING) {
+ Tk_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
+ }
+ ckfree((char *) wmPtr);
+ winPtr->wmInfoPtr = NULL;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkWmSetClass --
+ *
+ * This procedure is invoked whenever a top-level window's
+ * class is changed. If the window has been mapped then this
+ * procedure updates the window manager property for the
+ * class. If the window hasn't been mapped, the update is
+ * deferred until just before the first mapping.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * A window property may get updated.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TkWmSetClass(
+ TkWindow *winPtr) /* Newly-created top-level window. */
+{
+ return;
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_WmObjCmd --
+ *
+ * This procedure is invoked to process the "wm" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+/* ARGSUSED */
+int
+Tk_WmObjCmd(
+ ClientData clientData, /* Main window associated with
+ * interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
+ {
+ Tk_Window tkwin = (Tk_Window) clientData;
+ static CONST char *optionStrings[] = {
+ "aspect", "attributes", "client", "colormapwindows",
+ "command", "deiconify", "focusmodel", "frame",
+ "geometry", "grid", "group", "iconbitmap",
+ "iconify", "iconmask", "iconname", "iconposition",
+ "iconwindow", "maxsize", "minsize", "overrideredirect",
+ "positionfrom", "protocol", "resizable", "sizefrom",
+ "stackorder", "state", "title", "transient",
+ "withdraw", (char *) NULL };
+ enum options {
+ WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
+ WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FRAME,
+ WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP,
+ WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME, WMOPT_ICONPOSITION,
+ WMOPT_ICONWINDOW, WMOPT_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT,
+ WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM,
+ WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT,
+ WMOPT_WITHDRAW };
+ int index, length;
+ char *argv1;
+ TkWindow *winPtr;
+
+ if (objc < 2) {
+wrongNumArgs:
+ Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
+ return TCL_ERROR;
+ }
+
+ argv1 = Tcl_GetStringFromObj(objv[1], &length);
+ if ((argv1[0] == 't') && (strncmp(argv1, "tracing", length) == 0)
+ && (length >= 3)) {
+ if ((objc != 2) && (objc != 3)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
+ return TCL_ERROR;
+ }
+ if (objc == 2) {
+ Tcl_SetResult(interp, ((wmTracing) ? "on" : "off"), TCL_STATIC);
+ return TCL_OK;
+ }
+ return Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing);
+ }
+
+ if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (objc < 3) {
+ goto wrongNumArgs;
+ }
+
+ if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) &winPtr)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (!Tk_IsTopLevel(winPtr)) {
+ Tcl_AppendResult(interp, "window \"", winPtr->pathName,
+ "\" isn't a top-level window", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ switch ((enum options) index) {
+ case WMOPT_ASPECT:
+ return WmAspectCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_ATTRIBUTES:
+ return WmAttributesCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_CLIENT:
+ return WmClientCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_COLORMAPWINDOWS:
+ return WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_COMMAND:
+ return WmCommandCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_DEICONIFY:
+ return WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_FOCUSMODEL:
+ return WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_FRAME:
+ return WmFrameCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_GEOMETRY:
+ return WmGeometryCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_GRID:
+ return WmGridCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_GROUP:
+ return WmGroupCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_ICONBITMAP:
+ return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_ICONIFY:
+ return WmIconifyCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_ICONMASK:
+ return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_ICONNAME:
+ return WmIconnameCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_ICONPOSITION:
+ return WmIconpositionCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_ICONWINDOW:
+ return WmIconwindowCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_MAXSIZE:
+ return WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_MINSIZE:
+ return WmMinsizeCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_OVERRIDEREDIRECT:
+ return WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_POSITIONFROM:
+ return WmPositionfromCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_PROTOCOL:
+ return WmProtocolCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_RESIZABLE:
+ return WmResizableCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_SIZEFROM:
+ return WmSizefromCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_STACKORDER:
+ return WmStackorderCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_STATE:
+ return WmStateCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_TITLE:
+ return WmTitleCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_TRANSIENT:
+ return WmTransientCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_WITHDRAW:
+ return WmWithdrawCmd(tkwin, winPtr, interp, objc, objv);
+ }
+
+ /* This should not happen */
+ return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmAspectCmd --
+ *
+ * This procedure is invoked to process the "wm aspect" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmAspectCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ int numer1, denom1, numer2, denom2;
+
+ if ((objc != 3) && (objc != 7)) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "window ?minNumer minDenom maxNumer maxDenom?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ if (wmPtr->sizeHintsFlags & PAspect) {
+ char buf[TCL_INTEGER_SPACE * 4];
+
+ sprintf(buf, "%d %d %d %d", wmPtr->minAspect.x,
+ wmPtr->minAspect.y, wmPtr->maxAspect.x,
+ wmPtr->maxAspect.y);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ return TCL_OK;
+ }
+ if (*Tcl_GetString(objv[3]) == '\0') {
+ wmPtr->sizeHintsFlags &= ~PAspect;
+ } else {
+ if ((Tcl_GetIntFromObj(interp, objv[3], &numer1) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
+ return TCL_ERROR;
+ }
+ if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
+ (denom2 <= 0)) {
+ Tcl_SetResult(interp, "aspect number can't be <= 0",
+ TCL_STATIC);
+ return TCL_ERROR;
+ }
+ wmPtr->minAspect.x = numer1;
+ wmPtr->minAspect.y = denom1;
+ wmPtr->maxAspect.x = numer2;
+ wmPtr->maxAspect.y = denom2;
+ wmPtr->sizeHintsFlags |= PAspect;
+ }
+ wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
+ WmUpdateGeom(wmPtr, winPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmAttributesCmd --
+ *
+ * This procedure is invoked to process the "wm attributes" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ char buf[TCL_INTEGER_SPACE];
+ int i;
+ WindowRef macWindow;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window");
+ return TCL_ERROR;
+ }
+ if (objc < 3) {
+configArgs:
+ Tcl_AppendResult(interp, "wrong # arguments: must be \"",
+ Tcl_GetStringFromObj (objv[0], NULL), " attributes window",
+ " ?-modified ?bool??",
+ "\"", (char *) NULL);
+ return TCL_ERROR;
+ }
+ macWindow = GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window));
+ if (objc == 3) {
+ FSSpec spec;
+ sprintf(buf, "%d", (IsWindowModified(macWindow) == true));
+ Tcl_AppendResult(interp, "-modified ", buf, (char *) NULL);
+ if (GetWindowProxyFSSpec(macWindow, &spec) == noErr) {
+ Tcl_AppendResult(interp, " -titlepath", (char *) NULL);
+ /* Need to get the path from the spec */
+ Tcl_AppendElement(interp, "<read_unimplemented>");
+ } else {
+ Tcl_AppendResult(interp, " -titlepath {}", (char *) NULL);
+ }
+ return TCL_OK;
+ }
+ for (i = 3; i < objc; i += 2) {
+ int length;
+ char *argPtr = Tcl_GetStringFromObj(objv[i], &length);
+ if ((length < 2) || (*argPtr != '-')) {
+ goto configArgs;
+ }
+ if (strncmp(argPtr, "-modified", length) == 0) {
+ int boolean;
+ if (i < objc - 1) {
+ if (Tcl_GetBooleanFromObj(interp, objv[i+1], &boolean) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ SetWindowModified(macWindow, boolean);
+ }
+ } else if (strncmp(argPtr, "-titlepath", length) == 0) {
+ if (i < objc - 1) {
+ OSErr err;
+ FSSpec spec;
+ FSRef ref;
+ Boolean isDirectory;
+ err = FSPathMakeRef(Tcl_GetStringFromObj(objv[i+1], NULL), &ref, &isDirectory);
+ if (err == noErr) {
+ err = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL,
+ &spec, NULL);
+ if (err == noErr) {
+ if (SetWindowProxyFSSpec(macWindow,&spec) != noErr) {
+ Tcl_AppendResult(interp, "couldn't set window proxy title path",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ }
+ }
+ }
+ } else {
+ goto configArgs;
+ }
+ if (i == objc - 2) {
+ /* Want to return last result */
+ Tcl_SetObjResult(interp, objv[i+1]);
+ }
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmClientCmd --
+ *
+ * This procedure is invoked to process the "wm client" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmClientCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ char *argv3;
+ int length;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ if (wmPtr->clientMachine != NULL) {
+ Tcl_SetResult(interp, wmPtr->clientMachine, TCL_STATIC);
+ }
+ return TCL_OK;
+ }
+ argv3 = Tcl_GetStringFromObj(objv[3], &length);
+ if (argv3[0] == 0) {
+ if (wmPtr->clientMachine != NULL) {
+ ckfree((char *) wmPtr->clientMachine);
+ wmPtr->clientMachine = NULL;
+ }
+ return TCL_OK;
+ }
+ if (wmPtr->clientMachine != NULL) {
+ ckfree((char *) wmPtr->clientMachine);
+ }
+ wmPtr->clientMachine = (char *)
+ ckalloc((unsigned) (length + 1));
+ strcpy(wmPtr->clientMachine, argv3);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmColormapwindowsCmd --
+ *
+ * This procedure is invoked to process the "wm colormapwindows"
+ * Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ TkWindow **cmapList;
+ TkWindow *winPtr2;
+ int i, windowObjc, gotToplevel = 0;
+ Tcl_Obj **windowObjv;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ Tk_MakeWindowExist((Tk_Window) winPtr);
+ for (i = 0; i < wmPtr->cmapCount; i++) {
+ if ((i == (wmPtr->cmapCount-1))
+ && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
+ break;
+ }
+ Tcl_AppendElement(interp, wmPtr->cmapList[i]->pathName);
+ }
+ return TCL_OK;
+ }
+ if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+ cmapList = (TkWindow **) ckalloc((unsigned)
+ ((windowObjc+1)*sizeof(TkWindow*)));
+ for (i = 0; i < windowObjc; i++) {
+ if (TkGetWindowFromObj(interp, tkwin, windowObjv[i],
+ (Tk_Window *) &winPtr2) != TCL_OK)
+ {
+ ckfree((char *) cmapList);
+ return TCL_ERROR;
+ }
+ if (winPtr2 == winPtr) {
+ gotToplevel = 1;
+ }
+ if (winPtr2->window == None) {
+ Tk_MakeWindowExist((Tk_Window) winPtr2);
+ }
+ cmapList[i] = winPtr2;
+ }
+ if (!gotToplevel) {
+ wmPtr->flags |= WM_ADDED_TOPLEVEL_COLORMAP;
+ cmapList[windowObjc] = winPtr;
+ windowObjc++;
+ } else {
+ wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP;
+ }
+ wmPtr->flags |= WM_COLORMAPS_EXPLICIT;
+ if (wmPtr->cmapList != NULL) {
+ ckfree((char *)wmPtr->cmapList);
+ }
+ wmPtr->cmapList = cmapList;
+ wmPtr->cmapCount = windowObjc;
+
+ /*
+ * On the Macintosh all of this is just an excercise
+ * in compatability as we don't support colormaps. If
+ * we did they would be installed here.
+ */
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmCommandCmd --
+ *
+ * This procedure is invoked to process the "wm command" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmCommandCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ char *argv3;
+ int cmdArgc;
+ CONST char **cmdArgv;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ if (wmPtr->cmdArgv != NULL) {
+ Tcl_SetResult(interp,
+ Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv),
+ TCL_DYNAMIC);
+ }
+ return TCL_OK;
+ }
+ argv3 = Tcl_GetString(objv[3]);
+ if (argv3[0] == 0) {
+ if (wmPtr->cmdArgv != NULL) {
+ ckfree((char *) wmPtr->cmdArgv);
+ wmPtr->cmdArgv = NULL;
+ }
+ return TCL_OK;
+ }
+ if (Tcl_SplitList(interp, argv3, &cmdArgc, &cmdArgv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (wmPtr->cmdArgv != NULL) {
+ ckfree((char *) wmPtr->cmdArgv);
+ }
+ wmPtr->cmdArgc = cmdArgc;
+ wmPtr->cmdArgv = cmdArgv;
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmDeiconifyCmd --
+ *
+ * This procedure is invoked to process the "wm deiconify" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window");
+ return TCL_ERROR;
+ }
+ if (wmPtr->iconFor != NULL) {
+ Tcl_AppendResult(interp, "can't deiconify ", Tcl_GetString(objv[2]),
+ ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ if (winPtr->flags & TK_EMBEDDED) {
+ Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
+ ": it is an embedded window", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * TODO: may not want to call this function - look at Map events gened.
+ */
+
+ TkpWmSetState(winPtr, NormalState);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmFocusmodelCmd --
+ *
+ * This procedure is invoked to process the "wm focusmodel" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ static CONST char *optionStrings[] = {
+ "active", "passive", (char *) NULL };
+ enum options {
+ OPT_ACTIVE, OPT_PASSIVE };
+ int index;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ Tcl_SetResult(interp, (wmPtr->hints.input ? "passive" : "active"),
+ TCL_STATIC);
+ return TCL_OK;
+ }
+
+ if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (index == OPT_ACTIVE) {
+ wmPtr->hints.input = False;
+ } else { /* OPT_PASSIVE */
+ wmPtr->hints.input = True;
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmFrameCmd --
+ *
+ * This procedure is invoked to process the "wm frame" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmFrameCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ Window window;
+ char buf[TCL_INTEGER_SPACE];
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window");
+ return TCL_ERROR;
+ }
+ window = wmPtr->reparent;
+ if (window == None) {
+ window = Tk_WindowId((Tk_Window) winPtr);
+ }
+ sprintf(buf, "0x%x", (unsigned int) window);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmGeometryCmd --
+ *
+ * This procedure is invoked to process the "wm geometry" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmGeometryCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ char xSign, ySign;
+ int width, height;
+ char *argv3;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ char buf[16 + TCL_INTEGER_SPACE * 4];
+
+ xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+';
+ ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+';
+ if (wmPtr->gridWin != NULL) {
+ width = wmPtr->reqGridWidth + (winPtr->changes.width
+ - winPtr->reqWidth)/wmPtr->widthInc;
+ height = wmPtr->reqGridHeight + (winPtr->changes.height
+ - winPtr->reqHeight)/wmPtr->heightInc;
+ } else {
+ width = winPtr->changes.width;
+ height = winPtr->changes.height;
+ }
+ sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, wmPtr->x,
+ ySign, wmPtr->y);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ return TCL_OK;
+ }
+ argv3 = Tcl_GetString(objv[3]);
+ if (*argv3 == '\0') {
+ wmPtr->width = -1;
+ wmPtr->height = -1;
+ WmUpdateGeom(wmPtr, winPtr);
+ return TCL_OK;
+ }
+ return ParseGeometry(interp, argv3, winPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmGridCmd --
+ *
+ * This procedure is invoked to process the "wm grid" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmGridCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ int reqWidth, reqHeight, widthInc, heightInc;
+
+ if ((objc != 3) && (objc != 7)) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "window ?baseWidth baseHeight widthInc heightInc?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ if (wmPtr->sizeHintsFlags & PBaseSize) {
+ char buf[TCL_INTEGER_SPACE * 4];
+
+ sprintf(buf, "%d %d %d %d", wmPtr->reqGridWidth,
+ wmPtr->reqGridHeight, wmPtr->widthInc,
+ wmPtr->heightInc);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ return TCL_OK;
+ }
+ if (*Tcl_GetString(objv[3]) == '\0') {
+ /*
+ * Turn off gridding and reset the width and height
+ * to make sense as ungridded numbers.
+ */
+
+ wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
+ if (wmPtr->width != -1) {
+ wmPtr->width = winPtr->reqWidth + (wmPtr->width
+ - wmPtr->reqGridWidth)*wmPtr->widthInc;
+ wmPtr->height = winPtr->reqHeight + (wmPtr->height
+ - wmPtr->reqGridHeight)*wmPtr->heightInc;
+ }
+ wmPtr->widthInc = 1;
+ wmPtr->heightInc = 1;
+ } else {
+ if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[6], &heightInc) != TCL_OK)) {
+ return TCL_ERROR;
+ }
+ if (reqWidth < 0) {
+ Tcl_SetResult(interp, "baseWidth can't be < 0", TCL_STATIC);
+ return TCL_ERROR;
+ }
+ if (reqHeight < 0) {
+ Tcl_SetResult(interp, "baseHeight can't be < 0", TCL_STATIC);
+ return TCL_ERROR;
+ }
+ if (widthInc < 0) {
+ Tcl_SetResult(interp, "widthInc can't be < 0", TCL_STATIC);
+ return TCL_ERROR;
+ }
+ if (heightInc < 0) {
+ Tcl_SetResult(interp, "heightInc can't be < 0", TCL_STATIC);
+ return TCL_ERROR;
+ }
+ Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
+ heightInc);
+ }
+ wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
+ WmUpdateGeom(wmPtr, winPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmGroupCmd --
+ *
+ * This procedure is invoked to process the "wm group" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmGroupCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ Tk_Window tkwin2;
+ char *argv3;
+ int length;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ if (wmPtr->hints.flags & WindowGroupHint) {
+ Tcl_SetResult(interp, wmPtr->leaderName, TCL_STATIC);
+ }
+ return TCL_OK;
+ }
+ argv3 = Tcl_GetStringFromObj(objv[3], &length);
+ if (*argv3 == '\0') {
+ wmPtr->hints.flags &= ~WindowGroupHint;
+ if (wmPtr->leaderName != NULL) {
+ ckfree(wmPtr->leaderName);
+ }
+ wmPtr->leaderName = NULL;
+ } else {
+ if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ Tk_MakeWindowExist(tkwin2);
+ if (wmPtr->leaderName != NULL) {
+ ckfree(wmPtr->leaderName);
+ }
+ wmPtr->hints.window_group = Tk_WindowId(tkwin2);
+ wmPtr->hints.flags |= WindowGroupHint;
+ wmPtr->leaderName = ckalloc((unsigned) (length + 1));
+ strcpy(wmPtr->leaderName, argv3);
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmIconbitmapCmd --
+ *
+ * This procedure is invoked to process the "wm iconbitmap" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ char *argv3;
+ Pixmap pixmap;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ if (wmPtr->hints.flags & IconPixmapHint) {
+ Tcl_SetResult(interp,
+ (char *) Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_pixmap),
+ TCL_STATIC);
+ }
+ return TCL_OK;
+ }
+ argv3 = Tcl_GetString(objv[3]);
+ if (*argv3 == '\0') {
+ if (wmPtr->hints.icon_pixmap != None) {
+ Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
+ wmPtr->hints.icon_pixmap = None;
+ }
+ wmPtr->hints.flags &= ~IconPixmapHint;
+ } else {
+ OSErr err;
+ FSSpec spec;
+ FSRef ref;
+ Boolean isDirectory;
+ err = FSPathMakeRef(Tcl_GetStringFromObj(objv[3], NULL), &ref, &isDirectory);
+ if (err == noErr) {
+ err = FSGetCatalogInfo (&ref, kFSCatInfoNone, NULL, NULL, &spec, NULL);
+ if (err == noErr) {
+ WindowRef macWin
+ = GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window));
+ SetWindowProxyFSSpec(macWin, &spec);
+ return TCL_OK;
+ }
+ }
+ pixmap = Tk_GetBitmap(interp, (Tk_Window) winPtr,
+ Tk_GetUid(Tcl_GetStringFromObj(objv[3], NULL)));
+ if (pixmap == None) {
+ return TCL_ERROR;
+ }
+ wmPtr->hints.icon_pixmap = pixmap;
+ wmPtr->hints.flags |= IconPixmapHint;
+ }
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmIconifyCmd --
+ *
+ * This procedure is invoked to process the "wm iconify" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmIconifyCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window");
+ return TCL_ERROR;
+ }
+ if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
+ Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
+ "\": override-redirect flag is set", (char *) NULL);
+ return TCL_ERROR;
+ }
+ if (wmPtr->master != None) {
+ Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
+ "\": it is a transient", (char *) NULL);
+ return TCL_ERROR;
+ }
+ if (wmPtr->iconFor != NULL) {
+ Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
+ ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ if (winPtr->flags & TK_EMBEDDED) {
+ Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
+ ": it is an embedded window", (char *) NULL);
+ return TCL_ERROR;
+ }
+ TkpWmSetState(winPtr, IconicState);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmIconmaskCmd --
+ *
+ * This procedure is invoked to process the "wm iconmask" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmIconmaskCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ Pixmap pixmap;
+ char *argv3;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ if (wmPtr->hints.flags & IconMaskHint) {
+ Tcl_SetResult(interp,
+ (char *) Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask),
+ TCL_STATIC);
+ }
+ return TCL_OK;
+ }
+ argv3 = Tcl_GetString(objv[3]);
+ if (*argv3 == '\0') {
+ if (wmPtr->hints.icon_mask != None) {
+ Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
+ }
+ wmPtr->hints.flags &= ~IconMaskHint;
+ } else {
+ pixmap = Tk_GetBitmap(interp, tkwin, argv3);
+ if (pixmap == None) {
+ return TCL_ERROR;
+ }
+ wmPtr->hints.icon_mask = pixmap;
+ wmPtr->hints.flags |= IconMaskHint;
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmIconnameCmd --
+ *
+ * This procedure is invoked to process the "wm iconname" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmIconnameCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ CONST char *argv3;
+ int length;
+
+ if (objc > 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ Tcl_SetResult(interp,
+ (char *) ((wmPtr->iconName != NULL) ? wmPtr->iconName : ""),
+ TCL_STATIC);
+ return TCL_OK;
+ } else {
+ if (wmPtr->iconName != NULL) {
+ ckfree((char *) wmPtr->iconName);
+ }
+ argv3 = Tcl_GetStringFromObj(objv[3], &length);
+ wmPtr->iconName = ckalloc((unsigned) (length + 1));
+ strcpy(wmPtr->iconName, argv3);
+ if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
+ XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName);
+ }
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmIconpositionCmd --
+ *
+ * This procedure is invoked to process the "wm iconposition"
+ * Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmIconpositionCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ int x, y;
+
+ if ((objc != 3) && (objc != 5)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ if (wmPtr->hints.flags & IconPositionHint) {
+ char buf[TCL_INTEGER_SPACE * 2];
+
+ sprintf(buf, "%d %d", wmPtr->hints.icon_x,
+ wmPtr->hints.icon_y);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ return TCL_OK;
+ }
+ if (*Tcl_GetString(objv[3]) == '\0') {
+ wmPtr->hints.flags &= ~IconPositionHint;
+ } else {
+ if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){
+ return TCL_ERROR;
+ }
+ wmPtr->hints.icon_x = x;
+ wmPtr->hints.icon_y = y;
+ wmPtr->hints.flags |= IconPositionHint;
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmIconwindowCmd --
+ *
+ * This procedure is invoked to process the "wm iconwindow" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmIconwindowCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ Tk_Window tkwin2;
+ WmInfo *wmPtr2;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ if (wmPtr->icon != NULL) {
+ Tcl_SetResult(interp, Tk_PathName(wmPtr->icon), TCL_STATIC);
+ }
+ return TCL_OK;
+ }
+ if (*Tcl_GetString(objv[3]) == '\0') {
+ wmPtr->hints.flags &= ~IconWindowHint;
+ if (wmPtr->icon != NULL) {
+ wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
+ wmPtr2->iconFor = NULL;
+ wmPtr2->hints.initial_state = WithdrawnState;
+ }
+ wmPtr->icon = NULL;
+ } else {
+ if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (!Tk_IsTopLevel(tkwin2)) {
+ Tcl_AppendResult(interp, "can't use ", Tcl_GetString(objv[3]),
+ " as icon window: not at top level", (char *) NULL);
+ return TCL_ERROR;
+ }
+ wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr;
+ if (wmPtr2->iconFor != NULL) {
+ Tcl_AppendResult(interp, Tcl_GetString(objv[3]),
+ " is already an icon for ",
+ Tk_PathName(wmPtr2->iconFor), (char *) NULL);
+ return TCL_ERROR;
+ }
+ if (wmPtr->icon != NULL) {
+ WmInfo *wmPtr3 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
+ wmPtr3->iconFor = NULL;
+ }
+ Tk_MakeWindowExist(tkwin2);
+ wmPtr->hints.icon_window = Tk_WindowId(tkwin2);
+ wmPtr->hints.flags |= IconWindowHint;
+ wmPtr->icon = tkwin2;
+ wmPtr2->iconFor = (Tk_Window) winPtr;
+ if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
+ /*
+ * Don't have iconwindows on the Mac. We just withdraw.
+ */
+
+ Tk_UnmapWindow(tkwin2);
+ }
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmMaxsizeCmd --
+ *
+ * This procedure is invoked to process the "wm maxsize" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ int width, height;
+
+ if ((objc != 3) && (objc != 5)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ char buf[TCL_INTEGER_SPACE * 2];
+
+ sprintf(buf, "%d %d", wmPtr->maxWidth, wmPtr->maxHeight);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ return TCL_OK;
+ }
+ if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
+ return TCL_ERROR;
+ }
+ wmPtr->maxWidth = width;
+ wmPtr->maxHeight = height;
+ wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
+ WmUpdateGeom(wmPtr, winPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmMinsizeCmd --
+ *
+ * This procedure is invoked to process the "wm minsize" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmMinsizeCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ int width, height;
+
+ if ((objc != 3) && (objc != 5)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ char buf[TCL_INTEGER_SPACE * 2];
+
+ sprintf(buf, "%d %d", wmPtr->minWidth, wmPtr->minHeight);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ return TCL_OK;
+ }
+ if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
+ return TCL_ERROR;
+ }
+ wmPtr->minWidth = width;
+ wmPtr->minHeight = height;
+ wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
+ WmUpdateGeom(wmPtr, winPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmOverrideredirectCmd --
+ *
+ * This procedure is invoked to process the "wm overrideredirect"
+ * Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ int boolean;
+ XSetWindowAttributes atts;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
+ Tk_Attributes((Tk_Window) winPtr)->override_redirect);
+ return TCL_OK;
+ }
+ if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ atts.override_redirect = (boolean) ? True : False;
+ Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect,
+ &atts);
+ wmPtr->style = (boolean) ? plainDBox : documentProc;
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmPositionfromCmd --
+ *
+ * This procedure is invoked to process the "wm positionfrom"
+ * Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmPositionfromCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ static CONST char *optionStrings[] = {
+ "program", "user", (char *) NULL };
+ enum options {
+ OPT_PROGRAM, OPT_USER };
+ int index;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ if (wmPtr->sizeHintsFlags & USPosition) {
+ Tcl_SetResult(interp, "user", TCL_STATIC);
+ } else if (wmPtr->sizeHintsFlags & PPosition) {
+ Tcl_SetResult(interp, "program", TCL_STATIC);
+ }
+ return TCL_OK;
+ }
+ if (*Tcl_GetString(objv[3]) == '\0') {
+ wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
+ } else {
+ if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (index == OPT_USER) {
+ wmPtr->sizeHintsFlags &= ~PPosition;
+ wmPtr->sizeHintsFlags |= USPosition;
+ } else {
+ wmPtr->sizeHintsFlags &= ~USPosition;
+ wmPtr->sizeHintsFlags |= PPosition;
+ }
+ }
+ wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
+ WmUpdateGeom(wmPtr, winPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmProtocolCmd --
+ *
+ * This procedure is invoked to process the "wm protocol" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmProtocolCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ register ProtocolHandler *protPtr, *prevPtr;
+ Atom protocol;
+ char *cmd;
+ int cmdLength;
+
+ if ((objc < 3) || (objc > 5)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Return a list of all defined protocols for the window.
+ */
+ for (protPtr = wmPtr->protPtr; protPtr != NULL;
+ protPtr = protPtr->nextPtr) {
+ Tcl_AppendElement(interp,
+ Tk_GetAtomName((Tk_Window) winPtr, protPtr->protocol));
+ }
+ return TCL_OK;
+ }
+ protocol = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3]));
+ if (objc == 4) {
+ /*
+ * Return the command to handle a given protocol.
+ */
+ for (protPtr = wmPtr->protPtr; protPtr != NULL;
+ protPtr = protPtr->nextPtr) {
+ if (protPtr->protocol == protocol) {
+ Tcl_SetResult(interp, protPtr->command, TCL_STATIC);
+ return TCL_OK;
+ }
+ }
+ return TCL_OK;
+ }
+
+ /*
+ * Delete any current protocol handler, then create a new
+ * one with the specified command, unless the command is
+ * empty.
+ */
+
+ for (protPtr = wmPtr->protPtr, prevPtr = NULL; protPtr != NULL;
+ prevPtr = protPtr, protPtr = protPtr->nextPtr) {
+ if (protPtr->protocol == protocol) {
+ if (prevPtr == NULL) {
+ wmPtr->protPtr = protPtr->nextPtr;
+ } else {
+ prevPtr->nextPtr = protPtr->nextPtr;
+ }
+ Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC);
+ break;
+ }
+ }
+ cmd = Tcl_GetStringFromObj(objv[4], &cmdLength);
+ if (cmdLength > 0) {
+ protPtr = (ProtocolHandler *) ckalloc(HANDLER_SIZE(cmdLength));
+ protPtr->protocol = protocol;
+ protPtr->nextPtr = wmPtr->protPtr;
+ wmPtr->protPtr = protPtr;
+ protPtr->interp = interp;
+ strcpy(protPtr->command, cmd);
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmResizableCmd --
+ *
+ * This procedure is invoked to process the "wm resizable" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmResizableCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ int width, height;
+
+ if ((objc != 3) && (objc != 5)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ char buf[TCL_INTEGER_SPACE * 2];
+
+ sprintf(buf, "%d %d",
+ (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1,
+ (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ return TCL_OK;
+ }
+ if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK)
+ || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) {
+ return TCL_ERROR;
+ }
+ if (width) {
+ wmPtr->flags &= ~WM_WIDTH_NOT_RESIZABLE;
+ } else {
+ wmPtr->flags |= WM_WIDTH_NOT_RESIZABLE;
+ }
+ if (height) {
+ wmPtr->flags &= ~WM_HEIGHT_NOT_RESIZABLE;
+ } else {
+ wmPtr->flags |= WM_HEIGHT_NOT_RESIZABLE;
+ }
+ wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
+ if (wmPtr->scrollWinPtr != NULL) {
+ TkScrollbarEventuallyRedraw(
+ (TkScrollbar *) wmPtr->scrollWinPtr->instanceData);
+ }
+ WmUpdateGeom(wmPtr, winPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmSizefromCmd --
+ *
+ * This procedure is invoked to process the "wm sizefrom" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmSizefromCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ static CONST char *optionStrings[] = {
+ "program", "user", (char *) NULL };
+ enum options {
+ OPT_PROGRAM, OPT_USER };
+ int index;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ if (wmPtr->sizeHintsFlags & USSize) {
+ Tcl_SetResult(interp, "user", TCL_STATIC);
+ } else if (wmPtr->sizeHintsFlags & PSize) {
+ Tcl_SetResult(interp, "program", TCL_STATIC);
+ }
+ return TCL_OK;
+ }
+
+ if (*Tcl_GetString(objv[3]) == '\0') {
+ wmPtr->sizeHintsFlags &= ~(USSize|PSize);
+ } else {
+ if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (index == OPT_USER) {
+ wmPtr->sizeHintsFlags &= ~PSize;
+ wmPtr->sizeHintsFlags |= USSize;
+ } else { /* OPT_PROGRAM */
+ wmPtr->sizeHintsFlags &= ~USSize;
+ wmPtr->sizeHintsFlags |= PSize;
+ }
+ }
+ wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
+ WmUpdateGeom(wmPtr, winPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmStackorderCmd --
+ *
+ * This procedure is invoked to process the "wm stackorder" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmStackorderCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ TkWindow **windows, **window_ptr;
+ static CONST char *optionStrings[] = {
+ "isabove", "isbelow", (char *) NULL };
+ enum options {
+ OPT_ISABOVE, OPT_ISBELOW };
+ int index;
+
+ if ((objc != 3) && (objc != 5)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?isabove|isbelow window?");
+ return TCL_ERROR;
+ }
+
+ if (objc == 3) {
+ windows = TkWmStackorderToplevel(winPtr);
+ if (windows == NULL) {
+ panic("TkWmStackorderToplevel failed");
+ } else {
+ for (window_ptr = windows; *window_ptr ; window_ptr++) {
+ Tcl_AppendElement(interp, (*window_ptr)->pathName);
+ }
+ ckfree((char *) windows);
+ return TCL_OK;
+ }
+ } else {
+ TkWindow *winPtr2;
+ int index1=-1, index2=-1, result;
+
+ if (TkGetWindowFromObj(interp, tkwin, objv[4], (Tk_Window *) &winPtr2)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (!Tk_IsTopLevel(winPtr2)) {
+ Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
+ "\" isn't a top-level window", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ if (!Tk_IsMapped(winPtr)) {
+ Tcl_AppendResult(interp, "window \"", winPtr->pathName,
+ "\" isn't mapped", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ if (!Tk_IsMapped(winPtr2)) {
+ Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
+ "\" isn't mapped", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Lookup stacking order of all toplevels that are children
+ * of "." and find the position of winPtr and winPtr2
+ * in the stacking order.
+ */
+
+ windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);
+
+ if (windows == NULL) {
+ Tcl_AppendResult(interp, "TkWmStackorderToplevel failed",
+ (char *) NULL);
+ return TCL_ERROR;
+ } else {
+ for (window_ptr = windows; *window_ptr ; window_ptr++) {
+ if (*window_ptr == winPtr)
+ index1 = (window_ptr - windows);
+ if (*window_ptr == winPtr2)
+ index2 = (window_ptr - windows);
+ }
+ if (index1 == -1)
+ panic("winPtr window not found");
+ if (index2 == -1)
+ panic("winPtr2 window not found");
+
+ ckfree((char *) windows);
+ }
+
+ if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (index == OPT_ISABOVE) {
+ result = index1 > index2;
+ } else { /* OPT_ISBELOW */
+ result = index1 < index2;
+ }
+ Tcl_SetIntObj(Tcl_GetObjResult(interp), result);
+ return TCL_OK;
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmStateCmd --
+ *
+ * This procedure is invoked to process the "wm state" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmStateCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ static CONST char *optionStrings[] = {
+ "normal", "iconic", "withdrawn", "zoomed", (char *) NULL };
+ enum options {
+ OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED };
+ int index;
+
+ if ((objc < 3) || (objc > 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
+ return TCL_ERROR;
+ }
+ if (objc == 4) {
+ if (wmPtr->iconFor != NULL) {
+ Tcl_AppendResult(interp, "can't change state of ",
+ Tcl_GetString(objv[2]),
+ ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ if (winPtr->flags & TK_EMBEDDED) {
+ Tcl_AppendResult(interp, "can't change state of ",
+ winPtr->pathName, ": it is an embedded window",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (index == OPT_NORMAL) {
+ TkpWmSetState(winPtr, NormalState);
+ /*
+ * This varies from 'wm deiconify' because it does not
+ * force the window to be raised and receive focus
+ */
+ } else if (index == OPT_ICONIC) {
+ if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
+ Tcl_AppendResult(interp, "can't iconify \"",
+ winPtr->pathName,
+ "\": override-redirect flag is set",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ if (wmPtr->master != NULL) {
+ Tcl_AppendResult(interp, "can't iconify \"",
+ winPtr->pathName,
+ "\": it is a transient", (char *) NULL);
+ return TCL_ERROR;
+ }
+ TkpWmSetState(winPtr, IconicState);
+ } else if (index == OPT_WITHDRAWN) {
+ TkpWmSetState(winPtr, WithdrawnState);
+ } else { /* OPT_ZOOMED */
+ TkpWmSetState(winPtr, ZoomState);
+ }
+ } else {
+ if (wmPtr->iconFor != NULL) {
+ Tcl_SetResult(interp, "icon", TCL_STATIC);
+ } else {
+ switch (wmPtr->hints.initial_state) {
+ case NormalState:
+ Tcl_SetResult(interp, "normal", TCL_STATIC);
+ break;
+ case IconicState:
+ Tcl_SetResult(interp, "iconic", TCL_STATIC);
+ break;
+ case WithdrawnState:
+ Tcl_SetResult(interp, "withdrawn", TCL_STATIC);
+ break;
+ case ZoomState:
+ Tcl_SetResult(interp, "zoomed", TCL_STATIC);
+ break;
+ }
+ }
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmTitleCmd --
+ *
+ * This procedure is invoked to process the "wm title" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmTitleCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ char *argv3;
+ int length;
+
+ if (objc > 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ Tcl_SetResult(interp,
+ (char *) ((wmPtr->titleUid != NULL) ? wmPtr->titleUid : winPtr->nameUid),
+ TCL_STATIC);
+ return TCL_OK;
+ } else {
+ argv3 = Tcl_GetStringFromObj(objv[3], &length);
+ wmPtr->titleUid = Tk_GetUid(argv3);
+ if (!(wmPtr->flags & WM_NEVER_MAPPED) && !Tk_IsEmbedded(winPtr)) {
+ TkSetWMName(winPtr, wmPtr->titleUid);
+ }
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmTransientCmd --
+ *
+ * This procedure is invoked to process the "wm transient" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmTransientCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+ Tk_Window master;
+ WmInfo *wmPtr2;
+ char *argv3;
+ int length;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ if (wmPtr->master != None) {
+ Tcl_SetResult(interp, wmPtr->masterWindowName, TCL_STATIC);
+ }
+ return TCL_OK;
+ }
+ if (Tcl_GetString(objv[3])[0] == '\0') {
+ wmPtr->master = None;
+ if (wmPtr->masterWindowName != NULL) {
+ ckfree(wmPtr->masterWindowName);
+ }
+ wmPtr->masterWindowName = NULL;
+ wmPtr->style = documentProc;
+ } else {
+ if (TkGetWindowFromObj(interp, tkwin, objv[3], &master) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ Tk_MakeWindowExist(master);
+
+ if (wmPtr->iconFor != NULL) {
+ Tcl_AppendResult(interp, "can't make \"",
+ Tcl_GetString(objv[2]),
+ "\" a transient: it is an icon for ",
+ Tk_PathName(wmPtr->iconFor),
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ wmPtr2 = ((TkWindow *) master)->wmInfoPtr;
+
+ if (wmPtr2->iconFor != NULL) {
+ Tcl_AppendResult(interp, "can't make \"",
+ Tcl_GetString(objv[3]),
+ "\" a master: it is an icon for ",
+ Tk_PathName(wmPtr2->iconFor),
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ argv3 = Tcl_GetStringFromObj(objv[3], &length);
+ wmPtr->master = Tk_WindowId(master);
+ wmPtr->masterWindowName = ckalloc((unsigned) length+1);
+ strcpy(wmPtr->masterWindowName, argv3);
+ wmPtr->style = plainDBox;
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmWithdrawCmd --
+ *
+ * This procedure is invoked to process the "wm withdraw" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WmWithdrawCmd(tkwin, winPtr, interp, objc, objv)
+Tk_Window tkwin; /* Main window of the application. */
+TkWindow *winPtr; /* Toplevel to work with */
+Tcl_Interp *interp; /* Current interpreter. */
+int objc; /* Number of arguments. */
+Tcl_Obj *CONST objv[]; /* Argument objects. */
+{
+ register WmInfo *wmPtr = winPtr->wmInfoPtr;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window");
+ return TCL_ERROR;
+ }
+ if (wmPtr->iconFor != NULL) {
+ Tcl_AppendResult(interp, "can't withdraw ", Tcl_GetString(objv[2]),
+ ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ TkpWmSetState(winPtr, WithdrawnState);
+ return TCL_OK;
+}
+
+/*
+ * Invoked by those wm subcommands that affect geometry.
+ * Schedules a geometry update.
+ */
+static void
+WmUpdateGeom(wmPtr, winPtr)
+WmInfo *wmPtr;
+TkWindow *winPtr;
+{
+ if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
+ Tk_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
+ wmPtr->flags |= WM_UPDATE_PENDING;
+ }
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_SetGrid --
+ *
+ * This procedure is invoked by a widget when it wishes to set a grid
+ * coordinate system that controls the size of a top-level window.
+ * It provides a C interface equivalent to the "wm grid" command and
+ * is usually asscoiated with the -setgrid option.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Grid-related information will be passed to the window manager, so
+ * that the top-level window associated with tkwin will resize on
+ * even grid units. If some other window already controls gridding
+ * for the top-level window then this procedure call has no effect.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_SetGrid(
+ Tk_Window tkwin, /* Token for window. New window mgr info
+ * will be posted for the top-level window
+ * associated with this window. */
+ int reqWidth, /* Width (in grid units) corresponding to
+ * the requested geometry for tkwin. */
+ int reqHeight, /* Height (in grid units) corresponding to
+ * the requested geometry for tkwin. */
+ int widthInc, int heightInc)/* Pixel increments corresponding to a
+ * change of one grid unit. */
+{
+ TkWindow *winPtr = (TkWindow *) tkwin;
+ WmInfo *wmPtr;
+
+ /*
+ * Find the top-level window for tkwin, plus the window manager
+ * information.
+ */
+
+ while (!(winPtr->flags & TK_TOP_LEVEL)) {
+ winPtr = winPtr->parentPtr;
+ }
+ wmPtr = winPtr->wmInfoPtr;
+
+ if ((wmPtr->gridWin != NULL) && (wmPtr->gridWin != tkwin)) {
+ return;
+ }
+
+ if ((wmPtr->reqGridWidth == reqWidth)
+ && (wmPtr->reqGridHeight == reqHeight)
+ && (wmPtr->widthInc == widthInc)
+ && (wmPtr->heightInc == heightInc)
+ && ((wmPtr->sizeHintsFlags & (PBaseSize|PResizeInc))
+ == PBaseSize|PResizeInc)) {
+ return;
+ }
+
+ /*
+ * If gridding was previously off, then forget about any window
+ * size requests made by the user or via "wm geometry": these are
+ * in pixel units and there's no easy way to translate them to
+ * grid units since the new requested size of the top-level window in
+ * pixels may not yet have been registered yet (it may filter up
+ * the hierarchy in DoWhenIdle handlers). However, if the window
+ * has never been mapped yet then just leave the window size alone:
+ * assume that it is intended to be in grid units but just happened
+ * to have been specified before this procedure was called.
+ */
+
+ if ((wmPtr->gridWin == NULL) && !(wmPtr->flags & WM_NEVER_MAPPED)) {
+ wmPtr->width = -1;
+ wmPtr->height = -1;
+ }
+
+ /*
+ * Set the new gridding information, and start the process of passing
+ * all of this information to the window manager.
+ */
+
+ wmPtr->gridWin = tkwin;
+ wmPtr->reqGridWidth = reqWidth;
+ wmPtr->reqGridHeight = reqHeight;
+ wmPtr->widthInc = widthInc;
+ wmPtr->heightInc = heightInc;
+ wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc;
+ wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
+ if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
+ Tk_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
+ wmPtr->flags |= WM_UPDATE_PENDING;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_UnsetGrid --
+ *
+ * This procedure cancels the effect of a previous call
+ * to Tk_SetGrid.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * If tkwin currently controls gridding for its top-level window,
+ * gridding is cancelled for that top-level window; if some other
+ * window controls gridding then this procedure has no effect.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_UnsetGrid(
+ Tk_Window tkwin) /* Token for window that is currently
+ * controlling gridding. */
+{
+ TkWindow *winPtr = (TkWindow *) tkwin;
+ WmInfo *wmPtr;
+
+ /*
+ * Find the top-level window for tkwin, plus the window manager
+ * information.
+ */
+
+ while (!(winPtr->flags & TK_TOP_LEVEL)) {
+ winPtr = winPtr->parentPtr;
+ }
+ wmPtr = winPtr->wmInfoPtr;
+ if (tkwin != wmPtr->gridWin) {
+ return;
+ }
+
+ wmPtr->gridWin = NULL;
+ wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
+ if (wmPtr->width != -1) {
+ wmPtr->width = winPtr->reqWidth + (wmPtr->width
+ - wmPtr->reqGridWidth)*wmPtr->widthInc;
+ wmPtr->height = winPtr->reqHeight + (wmPtr->height
+ - wmPtr->reqGridHeight)*wmPtr->heightInc;
+ }
+ wmPtr->widthInc = 1;
+ wmPtr->heightInc = 1;
+
+ wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
+ if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
+ Tk_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
+ wmPtr->flags |= WM_UPDATE_PENDING;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TopLevelEventProc --
+ *
+ * This procedure is invoked when a top-level (or other externally-
+ * managed window) is restructured in any way.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Tk's internal data structures for the window get modified to
+ * reflect the structural change.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TopLevelEventProc(
+ ClientData clientData, /* Window for which event occurred. */
+ XEvent *eventPtr) /* Event that just happened. */
+{
+ TkWindow *winPtr = (TkWindow *) clientData;
+
+ winPtr->wmInfoPtr->flags |= WM_VROOT_OFFSET_STALE;
+ if (eventPtr->type == DestroyNotify) {
+ Tk_ErrorHandler handler;
+
+ if (!(winPtr->flags & TK_ALREADY_DEAD)) {
+ /*
+ * A top-level window was deleted externally (e.g., by the window
+ * manager). This is probably not a good thing, but cleanup as
+ * best we can. The error handler is needed because
+ * Tk_DestroyWindow will try to destroy the window, but of course
+ * it's already gone.
+ */
+
+ handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
+ (Tk_ErrorProc *) NULL, (ClientData) NULL);
+ Tk_DestroyWindow((Tk_Window) winPtr);
+ Tk_DeleteErrorHandler(handler);
+ }
+ if (wmTracing) {
+ printf("TopLevelEventProc: %s deleted\n", winPtr->pathName);
+ }
+ } else if (eventPtr->type == ReparentNotify) {
+ panic("recieved unwanted reparent event");
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TopLevelReqProc --
+ *
+ * This procedure is invoked by the geometry manager whenever
+ * the requested size for a top-level window is changed.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Arrange for the window to be resized to satisfy the request
+ * (this happens as a when-idle action).
+ *
+ *----------------------------------------------------------------------
+ */
+
+ /* ARGSUSED */
+static void
+TopLevelReqProc(
+ ClientData dummy, /* Not used. */
+ Tk_Window tkwin) /* Information about window. */
+{
+ TkWindow *winPtr = (TkWindow *) tkwin;
+ WmInfo *wmPtr;
+
+ wmPtr = winPtr->wmInfoPtr;
+ wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
+ if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
+ Tk_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
+ wmPtr->flags |= WM_UPDATE_PENDING;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateGeometryInfo --
+ *
+ * This procedure is invoked when a top-level window is first
+ * mapped, and also as a when-idle procedure, to bring the
+ * geometry and/or position of a top-level window back into
+ * line with what has been requested by the user and/or widgets.
+ * This procedure doesn't return until the window manager has
+ * responded to the geometry change.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The window's size and location may change, unless the WM prevents
+ * that from happening.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateGeometryInfo(
+ ClientData clientData) /* Pointer to the window's record. */
+{
+ TkWindow *winPtr = (TkWindow *) clientData;
+ WmInfo *wmPtr = winPtr->wmInfoPtr;
+ int x, y, width, height;
+ unsigned long serial;
+
+ wmPtr->flags &= ~WM_UPDATE_PENDING;
+
+ /*
+ * Compute the new size for the top-level window. See the
+ * user documentation for details on this, but the size
+ * requested depends on (a) the size requested internally
+ * by the window's widgets, (b) the size requested by the
+ * user in a "wm geometry" command or via wm-based interactive
+ * resizing (if any), and (c) whether or not the window is
+ * gridded. Don't permit sizes <= 0 because this upsets
+ * the X server.
+ */
+
+ if (wmPtr->width == -1) {
+ width = winPtr->reqWidth;
+ } else if (wmPtr->gridWin != NULL) {
+ width = winPtr->reqWidth
+ + (wmPtr->width - wmPtr->reqGridWidth)*wmPtr->widthInc;
+ } else {
+ width = wmPtr->width;
+ }
+ if (width <= 0) {
+ width = 1;
+ }
+ if (wmPtr->height == -1) {
+ height = winPtr->reqHeight;
+ } else if (wmPtr->gridWin != NULL) {
+ height = winPtr->reqHeight
+ + (wmPtr->height - wmPtr->reqGridHeight)*wmPtr->heightInc;
+ } else {
+ height = wmPtr->height;
+ }
+ if (height <= 0) {
+ height = 1;
+ }
+
+ /*
+ * Compute the new position for the upper-left pixel of the window's
+ * decorative frame. This is tricky, because we need to include the
+ * border widths supplied by a reparented parent in this calculation,
+ * but can't use the parent's current overall size since that may
+ * change as a result of this code.
+ */
+
+ if (wmPtr->flags & WM_NEGATIVE_X) {
+ x = wmPtr->vRootWidth - wmPtr->x
+ - (width + (wmPtr->parentWidth - winPtr->changes.width));
+ } else {
+ x = wmPtr->x;
+ }
+ if (wmPtr->flags & WM_NEGATIVE_Y) {
+ y = wmPtr->vRootHeight - wmPtr->y
+ - (height + (wmPtr->parentHeight - winPtr->changes.height));
+ } else {
+ y = wmPtr->y;
+ }
+
+ /*
+ * If the window's size is going to change and the window is
+ * supposed to not be resizable by the user, then we have to
+ * update the size hints. There may also be a size-hint-update
+ * request pending from somewhere else, too.
+ */
+
+ if (((width != winPtr->changes.width)
+ || (height != winPtr->changes.height))
+ && (wmPtr->gridWin == NULL)
+ && ((wmPtr->sizeHintsFlags & (PMinSize|PMaxSize)) == 0)) {
+ wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
+ }
+ if (wmPtr->flags & WM_UPDATE_SIZE_HINTS) {
+ UpdateSizeHints(winPtr);
+ }
+
+ /*
+ * Reconfigure the window if it isn't already configured correctly.
+ * A few tricky points:
+ *
+ * 1. If the window is embedded and the container is also in this
+ * process, don't actually reconfigure the window; just pass the
+ * desired size on to the container. Also, zero out any position
+ * information, since embedded windows are not allowed to move.
+ * 2. Sometimes the window manager will give us a different size
+ * than we asked for (e.g. mwm has a minimum size for windows), so
+ * base the size check on what we *asked for* last time, not what we
+ * got.
+ * 3. Don't move window unless a new position has been requested for
+ * it. This is because of "features" in some window managers (e.g.
+ * twm, as of 4/24/91) where they don't interpret coordinates
+ * according to ICCCM. Moving a window to its current location may
+ * cause it to shift position on the screen.
+ */
+
+ if (Tk_IsEmbedded(winPtr)) {
+ TkWindow *contWinPtr;
+
+ contWinPtr = TkpGetOtherWindow(winPtr);
+
+ /*
+ * NOTE: Here we should handle out of process embedding.
+ */
+
+ if (contWinPtr != NULL) {
+ /*
+ * This window is embedded and the container is also in this
+ * process, so we don't need to do anything special about the
+ * geometry, except to make sure that the desired size is known
+ * by the container. Also, zero out any position information,
+ * since embedded windows are not allowed to move.
+ */
+
+ wmPtr->x = wmPtr->y = 0;
+ wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
+ Tk_GeometryRequest((Tk_Window) contWinPtr, width, height);
+ }
+ return;
+ }
+ serial = NextRequest(winPtr->display);
+ if (wmPtr->flags & WM_MOVE_PENDING) {
+ wmPtr->configWidth = width;
+ wmPtr->configHeight = height;
+ if (wmTracing) {
+ printf(
+ "UpdateGeometryInfo moving to %d %d, resizing to %d x %d,\n",
+ x, y, width, height);
+ }
+ Tk_MoveResizeWindow((Tk_Window) winPtr, x, y, (unsigned) width,
+ (unsigned) height);
+ } else if ((width != wmPtr->configWidth)
+ || (height != wmPtr->configHeight)) {
+ wmPtr->configWidth = width;
+ wmPtr->configHeight = height;
+ if (wmTracing) {
+ printf("UpdateGeometryInfo resizing to %d x %d\n", width, height);
+ }
+ Tk_ResizeWindow((Tk_Window) winPtr, (unsigned) width,
+ (unsigned) height);
+ } else {
+ return;
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * UpdateSizeHints --
+ *
+ * This procedure is called to update the window manager's
+ * size hints information from the information in a WmInfo
+ * structure.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Properties get changed for winPtr.
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+UpdateSizeHints(
+ TkWindow *winPtr)
+{
+ WmInfo *wmPtr = winPtr->wmInfoPtr;
+ XSizeHints *hintsPtr;
+
+ wmPtr->flags &= ~WM_UPDATE_SIZE_HINTS;
+
+ hintsPtr = XAllocSizeHints();
+ if (hintsPtr == NULL) {
+ return;
+ }
+
+ /*
+ * Compute the pixel-based sizes for the various fields in the
+ * size hints structure, based on the grid-based sizes in
+ * our structure.
+ */
+
+ if (wmPtr->gridWin != NULL) {
+ hintsPtr->base_width = winPtr->reqWidth
+ - (wmPtr->reqGridWidth * wmPtr->widthInc);
+ if (hintsPtr->base_width < 0) {
+ hintsPtr->base_width = 0;
+ }
+ hintsPtr->base_height = winPtr->reqHeight
+ - (wmPtr->reqGridHeight * wmPtr->heightInc);
+ if (hintsPtr->base_height < 0) {
+ hintsPtr->base_height = 0;
+ }
+ hintsPtr->min_width = hintsPtr->base_width
+ + (wmPtr->minWidth * wmPtr->widthInc);
+ hintsPtr->min_height = hintsPtr->base_height
+ + (wmPtr->minHeight * wmPtr->heightInc);
+ hintsPtr->max_width = hintsPtr->base_width
+ + (wmPtr->maxWidth * wmPtr->widthInc);
+ hintsPtr->max_height = hintsPtr->base_height
+ + (wmPtr->maxHeight * wmPtr->heightInc);
+ } else {
+ hintsPtr->min_width = wmPtr->minWidth;
+ hintsPtr->min_height = wmPtr->minHeight;
+ hintsPtr->max_width = wmPtr->maxWidth;
+ hintsPtr->max_height = wmPtr->maxHeight;
+ hintsPtr->base_width = 0;
+ hintsPtr->base_height = 0;
+ }
+ hintsPtr->width_inc = wmPtr->widthInc;
+ hintsPtr->height_inc = wmPtr->heightInc;
+ hintsPtr->min_aspect.x = wmPtr->minAspect.x;
+ hintsPtr->min_aspect.y = wmPtr->minAspect.y;
+ hintsPtr->max_aspect.x = wmPtr->maxAspect.x;
+ hintsPtr->max_aspect.y = wmPtr->maxAspect.y;
+ hintsPtr->win_gravity = wmPtr->gravity;
+ hintsPtr->flags = wmPtr->sizeHintsFlags | PMinSize | PMaxSize;
+
+ /*
+ * If the window isn't supposed to be resizable, then set the
+ * minimum and maximum dimensions to be the same.
+ */
+
+ if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) {
+ if (wmPtr->width >= 0) {
+ hintsPtr->min_width = wmPtr->width;
+ } else {
+ hintsPtr->min_width = winPtr->reqWidth;
+ }
+ hintsPtr->max_width = hintsPtr->min_width;
+ }
+ if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) {
+ if (wmPtr->height >= 0) {
+ hintsPtr->min_height = wmPtr->height;
+ } else {
+ hintsPtr->min_height = winPtr->reqHeight;
+ }
+ hintsPtr->max_height = hintsPtr->min_height;
+ }
+
+ XSetWMNormalHints(winPtr->display, winPtr->window, hintsPtr);
+
+ XFree((char *) hintsPtr);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ParseGeometry --
+ *
+ * This procedure parses a geometry string and updates
+ * information used to control the geometry of a top-level
+ * window.
+ *
+ * Results:
+ * A standard Tcl return value, plus an error message in
+ * the interp's result if an error occurs.
+ *
+ * Side effects:
+ * The size and/or location of winPtr may change.
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+ParseGeometry(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ char *string, /* String containing new geometry. Has the
+ * standard form "=wxh+x+y". */
+ TkWindow *winPtr) /* Pointer to top-level window whose
+ * geometry is to be changed. */
+{
+ WmInfo *wmPtr = winPtr->wmInfoPtr;
+ int x, y, width, height, flags;
+ char *end;
+ char *p = string;
+
+ /*
+ * The leading "=" is optional.
+ */
+
+ if (*p == '=') {
+ p++;
+ }
+
+ /*
+ * Parse the width and height, if they are present. Don't
+ * actually update any of the fields of wmPtr until we've
+ * successfully parsed the entire geometry string.
+ */
+
+ width = wmPtr->width;
+ height = wmPtr->height;
+ x = wmPtr->x;
+ y = wmPtr->y;
+ flags = wmPtr->flags;
+ if (isdigit(UCHAR(*p))) {
+ width = strtoul(p, &end, 10);
+ p = end;
+ if (*p != 'x') {
+ goto error;
+ }
+ p++;
+ if (!isdigit(UCHAR(*p))) {
+ goto error;
+ }
+ height = strtoul(p, &end, 10);
+ p = end;
+ }
+
+ /*
+ * Parse the X and Y coordinates, if they are present.
+ */
+
+ if (*p != '\0') {
+ flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y);
+ if (*p == '-') {
+ flags |= WM_NEGATIVE_X;
+ } else if (*p != '+') {
+ goto error;
+ }
+ x = strtol(p+1, &end, 10);
+ p = end;
+ if (*p == '-') {
+ flags |= WM_NEGATIVE_Y;
+ } else if (*p != '+') {
+ goto error;
+ }
+ y = strtol(p+1, &end, 10);
+ if (*end != '\0') {
+ goto error;
+ }
+
+ /*
+ * Assume that the geometry information came from the user,
+ * unless an explicit source has been specified. Otherwise
+ * most window managers assume that the size hints were
+ * program-specified and they ignore them.
+ */
+
+ if ((wmPtr->sizeHintsFlags & (USPosition|PPosition)) == 0) {
+ wmPtr->sizeHintsFlags |= USPosition;
+ flags |= WM_UPDATE_SIZE_HINTS;
+ }
+ }
+
+ /*
+ * Everything was parsed OK. Update the fields of *wmPtr and
+ * arrange for the appropriate information to be percolated out
+ * to the window manager at the next idle moment.
+ */
+
+ wmPtr->width = width;
+ wmPtr->height = height;
+ if ((x != wmPtr->x) || (y != wmPtr->y)
+ || ((flags & (WM_NEGATIVE_X|WM_NEGATIVE_Y))
+ != (wmPtr->flags & (WM_NEGATIVE_X|WM_NEGATIVE_Y)))) {
+ wmPtr->x = x;
+ wmPtr->y = y;
+ flags |= WM_MOVE_PENDING;
+ }
+ wmPtr->flags = flags;
+
+ if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
+ Tk_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
+ wmPtr->flags |= WM_UPDATE_PENDING;
+ }
+ return TCL_OK;
+
+ error:
+ Tcl_AppendResult(interp, "bad geometry specifier \"",
+ string, "\"", (char *) NULL);
+ return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_GetRootCoords --
+ *
+ * Given a token for a window, this procedure traces through the
+ * window's lineage to find the (virtual) root-window coordinates
+ * corresponding to point (0,0) in the window.
+ *
+ * Results:
+ * The locations pointed to by xPtr and yPtr are filled in with
+ * the root coordinates of the (0,0) point in tkwin. If a virtual
+ * root window is in effect for the window, then the coordinates
+ * in the virtual root are returned.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_GetRootCoords(
+ Tk_Window tkwin, /* Token for window. */
+ int *xPtr, /* Where to store x-displacement of (0,0). */
+ int *yPtr) /* Where to store y-displacement of (0,0). */
+{
+ int x, y;
+ TkWindow *winPtr = (TkWindow *) tkwin;
+
+ /*
+ * Search back through this window's parents all the way to a
+ * top-level window, combining the offsets of each window within
+ * its parent.
+ */
+
+ x = y = 0;
+ while (1) {
+ x += winPtr->changes.x + winPtr->changes.border_width;
+ y += winPtr->changes.y + winPtr->changes.border_width;
+ if (winPtr->flags & TK_TOP_LEVEL) {
+ if (!(Tk_IsEmbedded(winPtr))) {
+ x += winPtr->wmInfoPtr->xInParent;
+ y += winPtr->wmInfoPtr->yInParent;
+ break;
+ } else {
+ TkWindow *otherPtr;
+
+ otherPtr = TkpGetOtherWindow(winPtr);
+ if (otherPtr != NULL) {
+ /*
+ * The container window is in the same application.
+ * Query its coordinates.
+ */
+ winPtr = otherPtr;
+
+ /*
+ * Remember to offset by the container window here,
+ * since at the end of this if branch, we will
+ * pop out to the container's parent...
+ */
+
+ x += winPtr->changes.x + winPtr->changes.border_width;
+ y += winPtr->changes.y + winPtr->changes.border_width;
+
+ } else {
+ Point theOffset;
+
+ if (gMacEmbedHandler->getOffsetProc != NULL) {
+ /*
+ * We do not require that the changes.x & changes.y for
+ * a non-Tk master window be kept up to date. So we
+ * first subtract off the possibly bogus values that have
+ * been added on at the top of this pass through the loop,
+ * and then call out to the getOffsetProc to give us
+ * the correct offset.
+ */
+
+ x -= winPtr->changes.x + winPtr->changes.border_width;
+ y -= winPtr->changes.y + winPtr->changes.border_width;
+
+ gMacEmbedHandler->getOffsetProc((Tk_Window) winPtr, &theOffset);
+
+ x += theOffset.h;
+ y += theOffset.v;
+ }
+ break;
+ }
+ }
+ }
+ winPtr = winPtr->parentPtr;
+ }
+ *xPtr = x;
+ *yPtr = y;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_CoordsToWindow --
+ *
+ * This is a Macintosh specific implementation of this function.
+ * Given the root coordinates of a point, this procedure returns
+ * the token for the top-most window covering that point, if
+ * there exists such a window in this application.
+ *
+ * Results:
+ * The return result is either a token for the window corresponding
+ * to rootX and rootY, or else NULL to indicate that there is no such
+ * window.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tk_Window
+Tk_CoordsToWindow(
+ int rootX, int rootY, /* Coordinates of point in root window. If
+ * a virtual-root window manager is in use,
+ * these coordinates refer to the virtual
+ * root, not the real root. */
+ Tk_Window tkwin) /* Token for any window in application;
+ * used to identify the display. */
+{
+ WindowPtr whichWin;
+ Point where;
+ Window rootChild;
+ TkWindow *winPtr, *childPtr;
+ TkWindow *nextPtr; /* Coordinates of highest child found so
+ * far that contains point. */
+ int x, y; /* Coordinates in winPtr. */
+ int tmpx, tmpy, bd;
+ TkDisplay *dispPtr;
+
+ /*
+ * Step 1: find the top-level window that contains the desired point.
+ */
+
+ where.h = rootX;
+ where.v = rootY;
+ FindWindow(where, &whichWin);
+ if (whichWin == NULL) {
+ return NULL;
+ }
+ rootChild = TkMacOSXGetXWindow(whichWin);
+ dispPtr = TkGetDisplayList();
+ winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, rootChild);
+ if (winPtr == NULL) {
+ return NULL;
+ }
+
+ /*
+ * Step 2: work down through the hierarchy underneath this window.
+ * At each level, scan through all the children to find the highest
+ * one in the stacking order that contains the point. Then repeat
+ * the whole process on that child.
+ */
+
+ x = rootX - winPtr->wmInfoPtr->xInParent;
+ y = rootY - winPtr->wmInfoPtr->yInParent;
+ while (1) {
+ x -= winPtr->changes.x;
+ y -= winPtr->changes.y;
+ nextPtr = NULL;
+
+ /*
+ * Container windows cannot have children. So if it is a container,
+ * look there, otherwise inspect the children.
+ */
+
+ if (Tk_IsContainer(winPtr)) {
+ childPtr = TkpGetOtherWindow(winPtr);
+ if (childPtr != NULL) {
+ if (Tk_IsMapped(childPtr)) {
+ tmpx = x - childPtr->changes.x;
+ tmpy = y - childPtr->changes.y;
+ bd = childPtr->changes.border_width;
+
+ if ((tmpx >= -bd) && (tmpy >= -bd)
+ && (tmpx < (childPtr->changes.width + bd))
+ && (tmpy < (childPtr->changes.height + bd))) {
+ nextPtr = childPtr;
+ }
+ }
+ }
+
+
+ /*
+ * NOTE: Here we should handle out of process embedding.
+ */
+
+ } else {
+ for (childPtr = winPtr->childList; childPtr != NULL;
+ childPtr = childPtr->nextPtr) {
+ if (!Tk_IsMapped(childPtr) ||
+ (childPtr->flags & TK_TOP_LEVEL)) {
+ continue;
+ }
+ tmpx = x - childPtr->changes.x;
+ tmpy = y - childPtr->changes.y;
+ bd = childPtr->changes.border_width;
+ if ((tmpx >= -bd) && (tmpy >= -bd)
+ && (tmpx < (childPtr->changes.width + bd))
+ && (tmpy < (childPtr->changes.height + bd))) {
+ nextPtr = childPtr;
+ }
+ }
+ }
+ if (nextPtr == NULL) {
+ break;
+ }
+ winPtr = nextPtr;
+ }
+ return (Tk_Window) winPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_TopCoordsToWindow --
+ *
+ * Given a Tk Window, and coordinates of a point relative to that window
+ * this procedure returns the top-most child of the window (excluding
+ * toplevels) covering that point, if there exists such a window in this
+ * application.
+ * It also sets newX, and newY to the coords of the point relative to the
+ * window returned.
+ *
+ * Results:
+ * The return result is either a token for the window corresponding
+ * to rootX and rootY, or else NULL to indicate that there is no such
+ * window. newX and newY are also set to the coords of the point relative
+ * to the returned window.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tk_Window
+Tk_TopCoordsToWindow(
+ Tk_Window tkwin, /* Token for a Tk Window which defines the;
+ * coordinates for rootX & rootY */
+ int rootX, int rootY, /* Coordinates of a point in tkWin. */
+ int *newX, int *newY) /* Coordinates of point in the upperMost child of
+ * tkWin containing (rootX,rootY) */
+{
+ TkWindow *winPtr, *childPtr;
+ TkWindow *nextPtr; /* Coordinates of highest child found so
+ * far that contains point. */
+ int x, y; /* Coordinates in winPtr. */
+ Window *children; /* Children of winPtr, or NULL. */
+
+ winPtr = (TkWindow *) tkwin;
+ x = rootX;
+ y = rootY;
+ while (1) {
+ nextPtr = NULL;
+ children = NULL;
+
+ /*
+ * Container windows cannot have children. So if it is a container,
+ * look there, otherwise inspect the children.
+ */
+
+ if (Tk_IsContainer(winPtr)) {
+ childPtr = TkpGetOtherWindow(winPtr);
+ if (childPtr != NULL) {
+ if (Tk_IsMapped(childPtr) &&
+ (x > childPtr->changes.x &&
+ x < childPtr->changes.x +
+ childPtr->changes.width) &&
+ (y > childPtr->changes.y &&
+ y < childPtr->changes.y +
+ childPtr->changes.height)) {
+ nextPtr = childPtr;
+ }
+ }
+
+ /*
+ * NOTE: Here we should handle out of process embedding.
+ */
+
+ } else {
+
+ for (childPtr = winPtr->childList; childPtr != NULL;
+ childPtr = childPtr->nextPtr) {
+ if (!Tk_IsMapped(childPtr) ||
+ (childPtr->flags & TK_TOP_LEVEL)) {
+ continue;
+ }
+ if (x < childPtr->changes.x || y < childPtr->changes.y) {
+ continue;
+ }
+ if (x > childPtr->changes.x + childPtr->changes.width ||
+ y > childPtr->changes.y + childPtr->changes.height) {
+ continue;
+ }
+ nextPtr = childPtr;
+ }
+ }
+ if (nextPtr == NULL) {
+ break;
+ }
+ winPtr = nextPtr;
+ x -= winPtr->changes.x;
+ y -= winPtr->changes.y;
+ }
+ *newX = x;
+ *newY = y;
+ return (Tk_Window) winPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateVRootGeometry --
+ *
+ * This procedure is called to update all the virtual root
+ * geometry information in wmPtr.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The vRootX, vRootY, vRootWidth, and vRootHeight fields in
+ * wmPtr are filled with the most up-to-date information.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateVRootGeometry(
+ WmInfo *wmPtr) /* Window manager information to be
+ * updated. The wmPtr->vRoot field must
+ * be valid. */
+{
+ TkWindow *winPtr = wmPtr->winPtr;
+ unsigned int bd, dummy;
+ Window dummy2;
+ Status status;
+ Tk_ErrorHandler handler;
+
+ /*
+ * If this isn't a virtual-root window manager, just return information
+ * about the screen.
+ */
+
+ wmPtr->flags &= ~WM_VROOT_OFFSET_STALE;
+ if (wmPtr->vRoot == None) {
+ noVRoot:
+ wmPtr->vRootX = wmPtr->vRootY = 0;
+ wmPtr->vRootWidth = DisplayWidth(winPtr->display, winPtr->screenNum);
+ wmPtr->vRootHeight = DisplayHeight(winPtr->display, winPtr->screenNum);
+ return;
+ }
+
+ /*
+ * Refresh the virtual root information if it's out of date.
+ */
+
+ handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
+ (Tk_ErrorProc *) NULL, (ClientData) NULL);
+ status = XGetGeometry(winPtr->display, wmPtr->vRoot,
+ &dummy2, &wmPtr->vRootX, &wmPtr->vRootY,
+ &wmPtr->vRootWidth, &wmPtr->vRootHeight, &bd, &dummy);
+ if (wmTracing) {
+ printf("UpdateVRootGeometry: x = %d, y = %d, width = %d, ",
+ wmPtr->vRootX, wmPtr->vRootY, wmPtr->vRootWidth);
+ printf("height = %d, status = %d\n", wmPtr->vRootHeight, status);
+ }
+ Tk_DeleteErrorHandler(handler);
+ if (status == 0) {
+ /*
+ * The virtual root is gone! Pretend that it never existed.
+ */
+
+ wmPtr->vRoot = None;
+ goto noVRoot;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_GetVRootGeometry --
+ *
+ * This procedure returns information about the virtual root
+ * window corresponding to a particular Tk window.
+ *
+ * Results:
+ * The values at xPtr, yPtr, widthPtr, and heightPtr are set
+ * with the offset and dimensions of the root window corresponding
+ * to tkwin. If tkwin is being managed by a virtual root window
+ * manager these values correspond to the virtual root window being
+ * used for tkwin; otherwise the offsets will be 0 and the
+ * dimensions will be those of the screen.
+ *
+ * Side effects:
+ * Vroot window information is refreshed if it is out of date.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_GetVRootGeometry(
+ Tk_Window tkwin, /* Window whose virtual root is to be
+ * queried. */
+ int *xPtr, int *yPtr, /* Store x and y offsets of virtual root
+ * here. */
+ int *widthPtr, /* Store dimensions of virtual root here. */
+ int *heightPtr)
+{
+ WmInfo *wmPtr;
+ TkWindow *winPtr = (TkWindow *) tkwin;
+
+ /*
+ * Find the top-level window for tkwin, and locate the window manager
+ * information for that window.
+ */
+
+ while (!(winPtr->flags & TK_TOP_LEVEL)) {
+ winPtr = winPtr->parentPtr;
+ }
+ wmPtr = winPtr->wmInfoPtr;
+
+ /*
+ * Make sure that the geometry information is up-to-date, then copy
+ * it out to the caller.
+ */
+
+ if (wmPtr->flags & WM_VROOT_OFFSET_STALE) {
+ UpdateVRootGeometry(wmPtr);
+ }
+ *xPtr = wmPtr->vRootX;
+ *yPtr = wmPtr->vRootY;
+ *widthPtr = wmPtr->vRootWidth;
+ *heightPtr = wmPtr->vRootHeight;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_MoveToplevelWindow --
+ *
+ * This procedure is called instead of Tk_MoveWindow to adjust
+ * the x-y location of a top-level window. It delays the actual
+ * move to a later time and keeps window-manager information
+ * up-to-date with the move
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The window is eventually moved so that its upper-left corner
+ * (actually, the upper-left corner of the window's decorative
+ * frame, if there is one) is at (x,y).
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_MoveToplevelWindow(
+ Tk_Window tkwin, /* Window to move. */
+ int x, int y) /* New location for window (within
+ * parent). */
+{
+ TkWindow *winPtr = (TkWindow *) tkwin;
+ WmInfo *wmPtr = winPtr->wmInfoPtr;
+
+ if (!(winPtr->flags & TK_TOP_LEVEL)) {
+ panic("Tk_MoveToplevelWindow called with non-toplevel window");
+ }
+ wmPtr->x = x;
+ wmPtr->y = y;
+ wmPtr->flags |= WM_MOVE_PENDING;
+ wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
+ if ((wmPtr->sizeHintsFlags & (USPosition|PPosition)) == 0) {
+ wmPtr->sizeHintsFlags |= USPosition;
+ wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
+ }
+
+ /*
+ * If the window has already been mapped, must bring its geometry
+ * up-to-date immediately, otherwise an event might arrive from the
+ * server that would overwrite wmPtr->x and wmPtr->y and lose the
+ * new position.
+ */
+
+ if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
+ if (wmPtr->flags & WM_UPDATE_PENDING) {
+ Tk_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
+ }
+ UpdateGeometryInfo((ClientData) winPtr);
+ }
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkWmRestackToplevel --
+ *
+ * This procedure restacks a top-level window.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * WinPtr gets restacked as specified by aboveBelow and otherPtr.
+ * This procedure doesn't return until the restack has taken
+ * effect and the ConfigureNotify event for it has been received.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkWmRestackToplevel(
+ TkWindow *winPtr, /* Window to restack. */
+ int aboveBelow, /* Gives relative position for restacking;
+ * must be Above or Below. */
+ TkWindow *otherPtr) /* Window relative to which to restack;
+ * if NULL, then winPtr gets restacked
+ * above or below *all* siblings. */
+{
+ WmInfo *wmPtr;
+
+ WindowRef macWindow, otherMacWindow, frontWindow, tmpWindow;
+
+ wmPtr = winPtr->wmInfoPtr;
+
+ /*
+ * Get the mac window. Make sure it exists & is mapped.
+ */
+
+ if (winPtr->window == None) {
+ Tk_MakeWindowExist((Tk_Window) winPtr);
+ }
+ if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
+
+ /*
+ * Can't set stacking order properly until the window is on the
+ * screen (mapping it may give it a reparent window), so make sure
+ * it's on the screen.
+ */
+
+ TkWmMapWindow(winPtr);
+ }
+ macWindow = GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window));
+
+ /*
+ * Get the window in which a raise or lower is in relation to.
+ */
+ if (otherPtr != NULL) {
+ if (otherPtr->window == None) {
+ Tk_MakeWindowExist((Tk_Window) otherPtr);
+ }
+ if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
+ TkWmMapWindow(otherPtr);
+ }
+ otherMacWindow =GetWindowFromPort(TkMacOSXGetDrawablePort(otherPtr->window));
+ } else {
+ otherMacWindow = NULL;
+ }
+
+
+ frontWindow = FrontNonFloatingWindow();
+
+ if (aboveBelow == Above) {
+ if (macWindow == frontWindow) {
+ /*
+ * Do nothing - it's already at the top.
+ */
+ } else if (otherMacWindow == frontWindow || otherMacWindow == NULL) {
+ /*
+ * Raise the window to the top. If the window is visable then
+ * we also make it the active window.
+ */
+
+ if (wmPtr->hints.initial_state == WithdrawnState) {
+ BringToFront(macWindow);
+ } else {
+ SelectWindow(macWindow);
+ }
+ } else {
+ /*
+ * Find the window to be above. (Front window will actually be the
+ * window to be behind.) Front window is NULL if no other windows.
+ */
+ while (frontWindow != NULL &&
+ ( tmpWindow = GetNextWindow (frontWindow) ) != otherMacWindow) {
+ frontWindow = tmpWindow;
+ }
+ if (frontWindow != NULL) {
+ SendBehind(macWindow, frontWindow);
+ }
+ }
+ } else {
+ /*
+ * Send behind. If it was in front find another window to make active.
+ */
+ if (macWindow == frontWindow) {
+ if ( ( tmpWindow = GetNextWindow ( macWindow )) != NULL) {
+ SelectWindow(tmpWindow);
+ }
+ }
+ SendBehind(macWindow, otherMacWindow);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkWmAddToColormapWindows --
+ *
+ * This procedure is called to add a given window to the
+ * WM_COLORMAP_WINDOWS property for its top-level, if it
+ * isn't already there. It is invoked by the Tk code that
+ * creates a new colormap, in order to make sure that colormap
+ * information is propagated to the window manager by default.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * WinPtr's window gets added to the WM_COLORMAP_WINDOWS
+ * property of its nearest top-level ancestor, unless the
+ * colormaps have been set explicitly with the
+ * "wm colormapwindows" command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkWmAddToColormapWindows(
+ TkWindow *winPtr) /* Window with a non-default colormap.
+ * Should not be a top-level window. */
+{
+ TkWindow *topPtr;
+ TkWindow **oldPtr, **newPtr;
+ int count, i;
+
+ if (winPtr->window == None) {
+ return;
+ }
+
+ for (topPtr = winPtr->parentPtr; ; topPtr = topPtr->parentPtr) {
+ if (topPtr == NULL) {
+ /*
+ * Window is being deleted. Skip the whole operation.
+ */
+
+ return;
+ }
+ if (topPtr->flags & TK_TOP_LEVEL) {
+ break;
+ }
+ }
+ if (topPtr->wmInfoPtr->flags & WM_COLORMAPS_EXPLICIT) {
+ return;
+ }
+
+ /*
+ * Make sure that the window isn't already in the list.
+ */
+
+ count = topPtr->wmInfoPtr->cmapCount;
+ oldPtr = topPtr->wmInfoPtr->cmapList;
+
+ for (i = 0; i < count; i++) {
+ if (oldPtr[i] == winPtr) {
+ return;
+ }
+ }
+
+ /*
+ * Make a new bigger array and use it to reset the property.
+ * Automatically add the toplevel itself as the last element
+ * of the list.
+ */
+
+ newPtr = (TkWindow **) ckalloc((unsigned) ((count+2)*sizeof(TkWindow*)));
+ if (count > 0) {
+ memcpy(newPtr, oldPtr, count * sizeof(TkWindow*));
+ }
+ if (count == 0) {
+ count++;
+ }
+ newPtr[count-1] = winPtr;
+ newPtr[count] = topPtr;
+ if (oldPtr != NULL) {
+ ckfree((char *) oldPtr);
+ }
+
+ topPtr->wmInfoPtr->cmapList = newPtr;
+ topPtr->wmInfoPtr->cmapCount = count+1;
+
+ /*
+ * On the Macintosh all of this is just an excercise
+ * in compatability as we don't support colormaps. If
+ * we did they would be installed here.
+ */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkWmRemoveFromColormapWindows --
+ *
+ * This procedure is called to remove a given window from the
+ * WM_COLORMAP_WINDOWS property for its top-level. It is invoked
+ * when windows are deleted.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * WinPtr's window gets removed from the WM_COLORMAP_WINDOWS
+ * property of its nearest top-level ancestor, unless the
+ * top-level itself is being deleted too.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkWmRemoveFromColormapWindows(
+ TkWindow *winPtr) /* Window that may be present in
+ * WM_COLORMAP_WINDOWS property for its
+ * top-level. Should not be a top-level
+ * window. */
+{
+ TkWindow *topPtr;
+ TkWindow **oldPtr;
+ int count, i, j;
+
+ for (topPtr = winPtr->parentPtr; ; topPtr = topPtr->parentPtr) {
+ if (topPtr == NULL) {
+ /*
+ * Ancestors have been deleted, so skip the whole operation.
+ * Seems like this can't ever happen?
+ */
+
+ return;
+ }
+ if (topPtr->flags & TK_TOP_LEVEL) {
+ break;
+ }
+ }
+ if (topPtr->flags & TK_ALREADY_DEAD) {
+ /*
+ * Top-level is being deleted, so there's no need to cleanup
+ * the WM_COLORMAP_WINDOWS property.
+ */
+
+ return;
+ }
+
+ /*
+ * Find the window and slide the following ones down to cover
+ * it up.
+ */
+
+ count = topPtr->wmInfoPtr->cmapCount;
+ oldPtr = topPtr->wmInfoPtr->cmapList;
+ for (i = 0; i < count; i++) {
+ if (oldPtr[i] == winPtr) {
+ for (j = i ; j < count-1; j++) {
+ oldPtr[j] = oldPtr[j+1];
+ }
+ topPtr->wmInfoPtr->cmapCount = count - 1;
+ break;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkGetPointerCoords --
+ *
+ * Fetch the position of the mouse pointer.
+ *
+ * Results:
+ * *xPtr and *yPtr are filled in with the (virtual) root coordinates
+ * of the mouse pointer for tkwin's display. If the pointer isn't
+ * on tkwin's screen, then -1 values are returned for both
+ * coordinates. The argument tkwin must be a toplevel window.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkGetPointerCoords(
+ Tk_Window tkwin, /* Toplevel window that identifies screen
+ * on which lookup is to be done. */
+ int *xPtr, int *yPtr) /* Store pointer coordinates here. */
+{
+ Point where;
+
+ GetMouse(&where);
+ LocalToGlobal(&where);
+ *xPtr = where.h;
+ *yPtr = where.v;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InitialWindowBounds --
+ *
+ * This function calculates the initial bounds for a new Mac
+ * toplevel window. Unless the geometry is specified by the user
+ * this code will auto place the windows in a cascade diagonially
+ * across the main monitor of the Mac.
+ *
+ * Results:
+ * The bounds are returned in geometry.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+InitialWindowBounds(
+ TkWindow *winPtr, /* Window to get initial bounds for. */
+ Rect *geometry) /* On return the initial bounds. */
+{
+ int x, y;
+ static int defaultX = 5;
+ static int defaultY = 45;
+
+ if (!(winPtr->wmInfoPtr->sizeHintsFlags & (USPosition | PPosition))) {
+ /*
+ * We will override the program & hopefully place the
+ * window in a "better" location.
+ */
+ BitMap screenBits;
+ GetQDGlobalsScreenBits(&screenBits);
+ if (((screenBits.bounds.right - defaultX) < 30) ||
+ ((screenBits.bounds.bottom - defaultY) < 30)) {
+ defaultX = 5;
+ defaultY = 45;
+ }
+ x = defaultX;
+ y = defaultY;
+ defaultX += 20;
+ defaultY += 20;
+ } else {
+ x = winPtr->wmInfoPtr->x;
+ y = winPtr->wmInfoPtr->y;
+ }
+
+ geometry->left = x;
+ geometry->top = y;
+ geometry->right = x + winPtr->changes.width;
+ geometry->bottom = y + winPtr->changes.height;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXResizable --
+ *
+ * This function determines if the passed in window is part of
+ * a toplevel window that is resizable. If the window is
+ * resizable in the x, y or both directions, true is returned.
+ *
+ * Results:
+ * True if resizable, false otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkMacOSXResizable(
+ TkWindow *winPtr) /* Tk window or NULL. */
+{
+ WmInfo *wmPtr;
+
+ if (winPtr == NULL) {
+ return false;
+ }
+ while (winPtr->wmInfoPtr == NULL) {
+ winPtr = winPtr->parentPtr;
+ }
+
+ wmPtr = winPtr->wmInfoPtr;
+ if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) &&
+ (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXGrowToplevel --
+ *
+ * The function is invoked when the user clicks in the grow region
+ * of a Tk window. The function will handle the dragging
+ * procedure and not return until completed. Finally, the function
+ * may place information Tk's event queue is the window was resized.
+ *
+ * Results:
+ * True if events were placed on event queue, false otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkMacOSXGrowToplevel(
+ WindowRef whichWindow,
+ Point start)
+{
+ Point where = start;
+ TkDisplay *dispPtr;
+ Rect portRect;
+
+ GlobalToLocal(&where);
+ GetPortBounds(GetWindowPort(whichWindow), &portRect );
+ if (where.h > (portRect.right - 16) &&
+ where.v > (portRect.bottom - 16)) {
+
+ Window window;
+ TkWindow *winPtr;
+ WmInfo *wmPtr;
+ Rect bounds;
+ long growResult;
+
+ window = TkMacOSXGetXWindow(whichWindow);
+ dispPtr = TkGetDisplayList();
+ winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window);
+ wmPtr = winPtr->wmInfoPtr;
+
+ /* TODO: handle grid size options. */
+ if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) &&
+ (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) {
+ return false;
+ }
+ if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) {
+ bounds.left = bounds.right = winPtr->changes.width;
+ } else {
+ bounds.left = (wmPtr->minWidth < 64) ? 64 : wmPtr->minWidth;
+ bounds.right = (wmPtr->maxWidth < 64) ? 64 : wmPtr->maxWidth;
+ }
+ if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) {
+ bounds.top = bounds.bottom = winPtr->changes.height;
+ } else {
+ bounds.top = (wmPtr->minHeight < 64) ? 64 : wmPtr->minHeight;
+ bounds.bottom = (wmPtr->maxHeight < 64) ? 64 : wmPtr->maxHeight;
+ }
+
+ growResult = GrowWindow(whichWindow, start, &bounds);
+
+ if (growResult != 0) {
+ SizeWindow(whichWindow,
+ LoWord(growResult), HiWord(growResult), true);
+ SetPort( GetWindowPort(whichWindow));
+ InvalWindowRect(whichWindow,&portRect); /* TODO: may not be needed */
+ TkMacOSXInvalClipRgns(winPtr);
+ TkGenWMConfigureEvent((Tk_Window) winPtr, -1, -1,
+ (int) LoWord(growResult), (int) HiWord(growResult),
+ TK_SIZE_CHANGED);
+ return true;
+ }
+ return false;
+ }
+ return false;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkSetWMName --
+ *
+ * Set the title for a toplevel window. If the window is embedded,
+ * do not change the window title.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The title of the window is changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkSetWMName(
+ TkWindow *winPtr,
+ Tk_Uid titleUid)
+{
+ Str255 pTitle;
+ WindowRef macWin;
+ int destWrote;
+
+ if (Tk_IsEmbedded(winPtr)) {
+ return;
+ }
+ Tcl_UtfToExternal(NULL, TkMacOSXCarbonEncoding, titleUid,
+ strlen(titleUid), 0, NULL,
+ (char *) &pTitle[1],
+ 255, NULL, &destWrote, NULL); /* Internalize native */
+ pTitle[0] = destWrote;
+
+ macWin = GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window));
+
+ /*
+ * FIXME: Convert this to SetWindowTitleWithCFString, we should
+ * use CFStrings and not pascal strings wherever they are supported,
+ * since at some point there will be encodings that can't be supported
+ * with the pascal string interfaces.
+ */
+
+ SetWTitle( macWin, pTitle);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkGetTransientMaster --
+ *
+ * If the passed window has the TRANSIENT_FOR property set this
+ * will return the master window. Otherwise it will return None.
+ *
+ * Results:
+ * The master window or None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Window
+TkGetTransientMaster(
+ TkWindow *winPtr)
+{
+ if (winPtr->wmInfoPtr != NULL) {
+ return winPtr->wmInfoPtr->master;
+ }
+ return None;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXGetXWindow --
+ *
+ * Returns the X window Id associated with the given WindowRef.
+ *
+ * Results:
+ * The window id is returned. None is returned if not a Tk window.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Window
+TkMacOSXGetXWindow(
+ WindowRef macWinPtr)
+{
+ Tcl_HashEntry *hPtr;
+
+ if ((macWinPtr == NULL) || !windowHashInit) {
+ return None;
+ }
+ hPtr = Tcl_FindHashEntry(&windowTable, (char *) macWinPtr);
+ if (hPtr == NULL) {
+ return None;
+ }
+ return (Window) Tcl_GetHashValue(hPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXZoomToplevel --
+ *
+ * The function is invoked when the user clicks in the zoom region
+ * of a Tk window. The function will handle the mouse tracking
+ * for the interaction. If the window is to be zoomed the window
+ * size is changed and events are generated to let Tk know what
+ * happened.
+ *
+ * Results:
+ * True if events were placed on event queue, false otherwise.
+ *
+ * Side effects:
+ * The window may be resized & events placed on Tk's queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkMacOSXZoomToplevel(
+ WindowRef whichWindow, /* The Macintosh window to zoom. */
+ Point where, /* The current mouse position. */
+ short zoomPart) /* Either inZoomIn or inZoomOut */
+{
+ Window window;
+ Tk_Window tkwin;
+ Point location = {0, 0};
+ int xOffset, yOffset;
+ WmInfo *wmPtr;
+ TkDisplay *dispPtr;
+ Rect portRect;
+
+ SetPort( GetWindowPort(whichWindow));
+ if (!TrackBox(whichWindow, where, zoomPart)) {
+ return false;
+ }
+
+ /*
+ * We should now zoom the window (as long as it's one of ours). We
+ * also need to generate an event to let Tk know that the window size
+ * has changed.
+ */
+ window = TkMacOSXGetXWindow(whichWindow);
+ dispPtr = TkGetDisplayList();
+ tkwin = Tk_IdToWindow(dispPtr->display, window);
+ if (tkwin == NULL) {
+ return false;
+ }
+
+ /*
+ * The following block of code works around a bug in the window
+ * definition for Apple's floating windows. The zoom behavior is
+ * broken - we must manually set the standard state (by default
+ * it's something like 1x1) and we must swap the zoomPart manually
+ * otherwise we always get the same zoomPart and nothing happens.
+ */
+ wmPtr = ((TkWindow *) tkwin)->wmInfoPtr;
+ if (wmPtr->style >= floatProc && wmPtr->style <= floatSideZoomGrowProc) {
+ if (zoomPart == inZoomIn) {
+ BitMap screenBits;
+ Rect zoomRect;
+ GetQDGlobalsScreenBits(&screenBits);
+ zoomRect = screenBits.bounds;
+ InsetRect(&zoomRect, 60, 60);
+ SetWindowStandardState(whichWindow, &zoomRect);
+ zoomPart = inZoomOut;
+ } else {
+ zoomPart = inZoomIn;
+ }
+ } else {
+ zoomPart = inZoomIn;
+ }
+
+ ZoomWindow(whichWindow, zoomPart, false);
+ InvalWindowRect(whichWindow,&portRect);
+ TkMacOSXInvalClipRgns((TkWindow *) tkwin);
+
+ LocalToGlobal(&location);
+ TkMacOSXWindowOffset(whichWindow, &xOffset, &yOffset);
+ location.h -= xOffset;
+ location.v -= yOffset;
+ GetPortBounds ( GetWindowPort(whichWindow), &portRect );
+ TkGenWMConfigureEvent(tkwin, location.h, location.v,
+ portRect.right - portRect.left,
+ portRect.bottom - portRect.top,
+ TK_BOTH_CHANGED);
+ return true;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkUnsupported1Cmd --
+ *
+ * This procedure is invoked to process the
+ * "::tk::unsupported::MacWindowStyle" Tcl command.
+ * This command allows you to set the style of decoration
+ * for a Macintosh window.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * Changes the style of a new Mac window.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ /* ARGSUSED */
+int
+TkUnsupported1Cmd(
+ ClientData clientData, /* Main window associated with
+ * interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ CONST char **argv) /* Argument strings. */
+{
+ Tk_Window tkwin = (Tk_Window) clientData;
+ TkWindow *winPtr;
+ WmInfo *wmPtr;
+ int c;
+ size_t length;
+
+ if (argc < 3) {
+ Tcl_AppendResult(interp, "wrong # args: should be \"",
+ argv[0], " option window ?arg ...?\"", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin);
+ if (winPtr == NULL) {
+ return TCL_ERROR;
+ }
+ if (!(winPtr->flags & TK_TOP_LEVEL)) {
+ Tcl_AppendResult(interp, "window \"", winPtr->pathName,
+ "\" isn't a top-level window", (char *) NULL);
+ return TCL_ERROR;
+ }
+ wmPtr = winPtr->wmInfoPtr;
+ c = argv[1][0];
+ length = strlen(argv[1]);
+ if ((c == 's') && (strncmp(argv[1], "style", length) == 0)) {
+ if ((argc < 3) || (argc > 5)) {
+ Tcl_AppendResult(interp, "wrong # arguments: must be \"",
+ argv[0], " style window ?windowStyle?\"",
+ " or \"", argv[0], "style window ?class attributes?\"",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ if (argc == 3) {
+ int appearanceSpec = 0;
+
+ switch (wmPtr->style) {
+ case -1:
+ appearanceSpec = 1;
+ break;
+ case noGrowDocProc:
+ case documentProc:
+ Tcl_SetResult(interp, "documentProc", TCL_STATIC);
+ break;
+ case dBoxProc:
+ Tcl_SetResult(interp, "dBoxProc", TCL_STATIC);
+ break;
+ case plainDBox:
+ Tcl_SetResult(interp, "plainDBox", TCL_STATIC);
+ break;
+ case altDBoxProc:
+ Tcl_SetResult(interp, "altDBoxProc", TCL_STATIC);
+ break;
+ case movableDBoxProc:
+ Tcl_SetResult(interp, "movableDBoxProc", TCL_STATIC);
+ break;
+ case zoomDocProc:
+ case zoomNoGrow:
+ Tcl_SetResult(interp, "zoomDocProc", TCL_STATIC);
+ break;
+ /* Not supported in Carbon
+ case rDocProc:
+ Tcl_SetResult(interp, "rDocProc", TCL_STATIC);
+ break;
+ */
+ case floatProc:
+ case floatGrowProc:
+ Tcl_SetResult(interp, "floatProc", TCL_STATIC);
+ break;
+ case floatZoomProc:
+ case floatZoomGrowProc:
+ Tcl_SetResult(interp, "floatZoomProc", TCL_STATIC);
+ break;
+ case floatSideProc:
+ case floatSideGrowProc:
+ Tcl_SetResult(interp, "floatSideProc", TCL_STATIC);
+ break;
+ case floatSideZoomProc:
+ case floatSideZoomGrowProc:
+ Tcl_SetResult(interp, "floatSideZoomProc", TCL_STATIC);
+ break;
+ default:
+ panic("invalid style");
+ }
+ if (appearanceSpec) {
+ Tcl_Obj *attributeList, *newResult = NULL;
+
+ switch (wmPtr->macClass) {
+ case kAlertWindowClass:
+ newResult = Tcl_NewStringObj("alert", -1);
+ break;
+ case kMovableAlertWindowClass:
+ newResult = Tcl_NewStringObj("moveableAlert", -1);
+ break;
+ case kModalWindowClass:
+ newResult = Tcl_NewStringObj("modal", -1);
+ break;
+ case kMovableModalWindowClass:
+ newResult = Tcl_NewStringObj("moveableModal", -1);
+ break;
+ case kFloatingWindowClass:
+ newResult = Tcl_NewStringObj("floating", -1);
+ break;
+ case kDocumentWindowClass:
+ newResult = Tcl_NewStringObj("document", -1);
+ break;
+ case kHelpWindowClass:
+ newResult = Tcl_NewStringObj("help", -1);
+ break;
+ case kToolbarWindowClass:
+ newResult = Tcl_NewStringObj("toolbar", -1);
+ break;
+ default:
+ panic("invalid class");
+ }
+
+ attributeList = Tcl_NewListObj(0, NULL);
+ if (wmPtr->attributes == kWindowNoAttributes) {
+ Tcl_ListObjAppendElement(interp, attributeList,
+ Tcl_NewStringObj("none", -1));
+ } else if (wmPtr->attributes == kWindowStandardDocumentAttributes) {
+ Tcl_ListObjAppendElement(interp, attributeList,
+ Tcl_NewStringObj("standardDocument", -1));
+ } else if (wmPtr->attributes == kWindowStandardFloatingAttributes) {
+ Tcl_ListObjAppendElement(interp, attributeList,
+ Tcl_NewStringObj("standardFloating", -1));
+ } else {
+ if (wmPtr->attributes & kWindowCloseBoxAttribute) {
+ Tcl_ListObjAppendElement(interp, attributeList,
+ Tcl_NewStringObj("closeBox", -1));
+ }
+ if (wmPtr->attributes & kWindowHorizontalZoomAttribute) {
+ Tcl_ListObjAppendElement(interp, attributeList,
+ Tcl_NewStringObj("horizontalZoom", -1));
+ }
+ if (wmPtr->attributes & kWindowVerticalZoomAttribute) {
+ Tcl_ListObjAppendElement(interp, attributeList,
+ Tcl_NewStringObj("verticalZoom", -1));
+ }
+ if (wmPtr->attributes & kWindowCollapseBoxAttribute) {
+ Tcl_ListObjAppendElement(interp, attributeList,
+ Tcl_NewStringObj("collapseBox", -1));
+ }
+ if (wmPtr->attributes & kWindowResizableAttribute) {
+ Tcl_ListObjAppendElement(interp, attributeList,
+ Tcl_NewStringObj("resizable", -1));
+ }
+ if (wmPtr->attributes & kWindowSideTitlebarAttribute) {
+ Tcl_ListObjAppendElement(interp, attributeList,
+ Tcl_NewStringObj("sideTitlebar", -1));
+ }
+ if (wmPtr->attributes & kWindowNoUpdatesAttribute) {
+ Tcl_ListObjAppendElement(interp, attributeList,
+ Tcl_NewStringObj("noUpdates", -1));
+ }
+ if (wmPtr->attributes & kWindowNoActivatesAttribute) {
+ Tcl_ListObjAppendElement(interp, attributeList,
+ Tcl_NewStringObj("noActivates", -1));
+ }
+ }
+ Tcl_ListObjAppendElement(interp, newResult, attributeList);
+ Tcl_SetObjResult(interp, newResult);
+ }
+ return TCL_OK;
+ } else if (argc == 4) {
+ if (strcmp(argv[3], "documentProc") == 0) {
+ wmPtr->style = documentProc;
+ } else if (strcmp(argv[3], "noGrowDocProc") == 0) {
+ wmPtr->style = documentProc;
+ } else if (strcmp(argv[3], "dBoxProc") == 0) {
+ wmPtr->style = dBoxProc;
+ } else if (strcmp(argv[3], "plainDBox") == 0) {
+ wmPtr->style = plainDBox;
+ } else if (strcmp(argv[3], "altDBoxProc") == 0) {
+ wmPtr->style = altDBoxProc;
+ } else if (strcmp(argv[3], "movableDBoxProc") == 0) {
+ wmPtr->style = movableDBoxProc;
+ } else if (strcmp(argv[3], "zoomDocProc") == 0) {
+ wmPtr->style = zoomDocProc;
+ } else if (strcmp(argv[3], "zoomNoGrow") == 0) {
+ wmPtr->style = zoomNoGrow;
+ }
+ /*
+ else
+ if (strcmp(argv[3], "rDocProc") == 0) {
+ wmPtr->style = rDocProc;
+ }
+ */
+ else if (strcmp(argv[3], "floatProc") == 0) {
+ wmPtr->style = floatGrowProc;
+ } else if (strcmp(argv[3], "floatGrowProc") == 0) {
+ wmPtr->style = floatGrowProc;
+ } else if (strcmp(argv[3], "floatZoomProc") == 0) {
+ wmPtr->style = floatZoomGrowProc;
+ } else if (strcmp(argv[3], "floatZoomGrowProc") == 0) {
+ wmPtr->style = floatZoomGrowProc;
+ } else if (strcmp(argv[3], "floatSideProc") == 0) {
+ wmPtr->style = floatSideGrowProc;
+ } else if (strcmp(argv[3], "floatSideGrowProc") == 0) {
+ wmPtr->style = floatSideGrowProc;
+ } else if (strcmp(argv[3], "floatSideZoomProc") == 0) {
+ wmPtr->style = floatSideZoomGrowProc;
+ } else if (strcmp(argv[3], "floatSideZoomGrowProc") == 0) {
+ wmPtr->style = floatSideZoomGrowProc;
+ } else {
+ Tcl_AppendResult(interp, "bad style: should be documentProc, ",
+ "dBoxProc, plainDBox, altDBoxProc, movableDBoxProc, ",
+ "zoomDocProc, rDocProc, floatProc, floatZoomProc, ",
+ "floatSideProc, or floatSideZoomProc",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ } else if (argc == 5) {
+ int oldClass = wmPtr->macClass;
+ int oldAttributes = wmPtr->attributes;
+
+ if (strcmp(argv[3], "alert") == 0) {
+ wmPtr->macClass = kAlertWindowClass;
+ } else if (strcmp(argv[3], "moveableAlert") == 0) {
+ wmPtr->macClass = kMovableAlertWindowClass;
+ } else if (strcmp(argv[3], "modal") == 0) {
+ wmPtr->macClass = kModalWindowClass;
+ } else if (strcmp(argv[3], "moveableModal") == 0) {
+ wmPtr->macClass = kMovableModalWindowClass;
+ } else if (strcmp(argv[3], "floating") == 0) {
+ wmPtr->macClass = kFloatingWindowClass;
+ } else if (strcmp(argv[3], "document") == 0) {
+ wmPtr->macClass = kDocumentWindowClass;
+ } else if (strcmp(argv[3], "help") == 0) {
+ wmPtr->macClass = kHelpWindowClass;
+ } else if (strcmp(argv[3], "toolbar") == 0) {
+ wmPtr->macClass = kToolbarWindowClass;
+ } else {
+ wmPtr->macClass = oldClass;
+ Tcl_AppendResult(interp, "bad class: should be alert, ",
+ "moveableAlert, modal, moveableModal, floating, ",
+ "help, or document",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ if (strcmp(argv[4], "none") == 0) {
+ wmPtr->attributes = kWindowNoAttributes;
+ } else if (strcmp(argv[4], "standardDocument") == 0) {
+ wmPtr->attributes = kWindowStandardDocumentAttributes;
+ } else if (strcmp(argv[4], "standardFloating") == 0) {
+ wmPtr->attributes = kWindowStandardFloatingAttributes;
+ } else {
+ int foundOne = 0;
+ int attrArgc, i;
+ CONST char **attrArgv = NULL;
+
+ if (Tcl_SplitList(interp, argv[4], &attrArgc, &attrArgv) != TCL_OK) {
+ wmPtr->macClass = oldClass;
+ Tcl_AppendResult(interp, "Ill-formed attributes list: \"",
+ argv[4], "\".", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ wmPtr->attributes = kWindowNoAttributes;
+
+ for (i = 0; i < attrArgc; i++) {
+ if ((*attrArgv[i] == 'c')
+ && (strcmp(attrArgv[i], "closeBox") == 0)) {
+ wmPtr->attributes |= kWindowCloseBoxAttribute;
+ foundOne = 1;
+ } else if ((*attrArgv[i] == 'h')
+ && (strcmp(attrArgv[i], "horizontalZoom") == 0)) {
+ wmPtr->attributes |= kWindowHorizontalZoomAttribute;
+ foundOne = 1;
+ } else if ((*attrArgv[i] == 'v')
+ && (strcmp(attrArgv[i], "verticalZoom") == 0)) {
+ wmPtr->attributes |= kWindowVerticalZoomAttribute;
+ foundOne = 1;
+ } else if ((*attrArgv[i] == 'c')
+ && (strcmp(attrArgv[i], "collapseBox") == 0)) {
+ wmPtr->attributes |= kWindowCollapseBoxAttribute;
+ foundOne = 1;
+ } else if ((*attrArgv[i] == 'r')
+ && (strcmp(attrArgv[i], "resizable") == 0)) {
+ wmPtr->attributes |= kWindowResizableAttribute;
+ foundOne = 1;
+ } else if ((*attrArgv[i] == 's')
+ && (strcmp(attrArgv[i], "sideTitlebar") == 0)) {
+ wmPtr->attributes |= kWindowSideTitlebarAttribute;
+ foundOne = 1;
+ } else {
+ foundOne = 0;
+ break;
+ }
+ }
+
+ if (attrArgv != NULL) {
+ ckfree ((char *) attrArgv);
+ }
+
+ if (foundOne != 1) {
+ wmPtr->macClass = oldClass;
+ wmPtr->attributes = oldAttributes;
+
+ Tcl_AppendResult(interp, "bad attribute: \"", argv[4],
+ "\", should be standardDocument, ",
+ "standardFloating, or some combination of ",
+ "closeBox, horizontalZoom, verticalZoom, ",
+ "collapseBox, resizable, or sideTitlebar.",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ }
+
+ wmPtr->style = -1;
+ }
+ } else {
+ Tcl_AppendResult(interp, "unknown or ambiguous option \"", argv[1],
+ "\": must be style",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpMakeMenuWindow --
+ *
+ * Configure the window to be either a undecorated pull-down
+ * (or pop-up) menu, or as a toplevel floating menu (palette).
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes the style bit used to create a new Mac toplevel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpMakeMenuWindow(
+ Tk_Window tkwin, /* New window. */
+ int transient) /* 1 means menu is only posted briefly as
+ * a popup or pulldown or cascade. 0 means
+ * menu is always visible, e.g. as a
+ * floating menu. */
+{
+ if (transient) {
+ ((TkWindow *) tkwin)->wmInfoPtr->style = plainDBox;
+ } else {
+ ((TkWindow *) tkwin)->wmInfoPtr->style = floatProc;
+ ((TkWindow *) tkwin)->wmInfoPtr->flags |= WM_WIDTH_NOT_RESIZABLE;
+ ((TkWindow *) tkwin)->wmInfoPtr->flags |= WM_HEIGHT_NOT_RESIZABLE;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXMakeRealWindowExist --
+ *
+ * This function finally creates the real Macintosh window that
+ * the Mac actually understands.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * A new Macintosh toplevel is created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXMakeRealWindowExist(
+ TkWindow *winPtr) /* Tk window. */
+{
+ WmInfo *wmPtr = winPtr->wmInfoPtr;
+ WindowRef newWindow = NULL;
+ ControlRef rootControl = NULL;
+ MacDrawable *macWin;
+ Rect geometry = {0,0,0,0};
+ Tcl_HashEntry *valueHashPtr;
+ int new;
+ TkMacOSXWindowList *listPtr;
+
+ if (TkMacOSXHostToplevelExists(winPtr)) {
+ return;
+ }
+
+ macWin = (MacDrawable *) winPtr->window;
+
+ /*
+ * If this is embedded, make sure its container's toplevel exists,
+ * then return...
+ */
+
+ if (Tk_IsEmbedded(winPtr)) {
+ TkWindow *contWinPtr;
+
+ contWinPtr = TkpGetOtherWindow(winPtr);
+ if (contWinPtr != NULL) {
+ TkMacOSXMakeRealWindowExist(contWinPtr->privatePtr->toplevel->winPtr);
+ macWin->flags |= TK_HOST_EXISTS;
+ return;
+ } else if (gMacEmbedHandler != NULL) {
+ if (gMacEmbedHandler->containerExistProc != NULL) {
+ if (gMacEmbedHandler->containerExistProc((Tk_Window) winPtr) != TCL_OK) {
+ panic("ContainerExistProc could not make container");
+ }
+ }
+ return;
+ } else {
+ panic("TkMacOSXMakeRealWindowExist could not find container");
+ }
+
+ /*
+ * NOTE: Here we should handle out of process embedding.
+ */
+
+ }
+
+ InitialWindowBounds(winPtr, &geometry);
+
+ if (wmPtr->style == -1) {
+ OSStatus err;
+ /*
+ * There seems to be a bug in CreateNewWindow: If I set the
+ * window geometry to be the too small for the structure region,
+ * then the whole window is positioned incorrectly.
+ * Adding this here makes the positioning work, and the size will
+ * get overwritten when you actually map the contents of the window.
+ */
+
+ geometry.right += 64;
+ geometry.bottom += 24;
+ err = CreateNewWindow(wmPtr->macClass, wmPtr->attributes,
+ &geometry, &newWindow);
+ if (err != noErr) {
+ newWindow = NULL;
+ }
+
+ } else {
+ newWindow = NewCWindow(NULL, &geometry, "\ptemp", false,
+ (short) wmPtr->style, (WindowRef) -1, true, 0);
+ }
+
+ if (newWindow == NULL) {
+ panic("couldn't allocate new Mac window");
+ }
+ if (CreateRootControl(newWindow,&rootControl) != noErr ) {
+ panic("couldn't create root control for new Mac window");
+ }
+
+ /*
+ * Add this window to the list of toplevel windows.
+ */
+
+ listPtr = (TkMacOSXWindowList *) ckalloc(sizeof(TkMacOSXWindowList));
+ listPtr->nextPtr = tkMacOSXWindowListPtr;
+ listPtr->winPtr = winPtr;
+ tkMacOSXWindowListPtr = listPtr;
+
+ macWin->grafPtr = GetWindowPort ( newWindow );
+ macWin->rootControl = rootControl;
+ MoveWindowStructure(newWindow, geometry.left, geometry.top);
+ SetPort(GetWindowPort(newWindow));
+
+ if (!windowHashInit) {
+ Tcl_InitHashTable(&windowTable, TCL_ONE_WORD_KEYS);
+ windowHashInit = true;
+ }
+ valueHashPtr = Tcl_CreateHashEntry(&windowTable,
+ (char *) newWindow, &new);
+ if (!new) {
+ panic("same macintosh window allocated twice!");
+ }
+ Tcl_SetHashValue(valueHashPtr, macWin);
+
+ macWin->flags |= TK_HOST_EXISTS;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXRegisterOffScreenWindow --
+ *
+ * This function adds the passed in Off Screen Port to the
+ * hash table that maps Mac windows to root X windows.
+ *
+ * FIXME: This is not currently used. Is there any reason
+ * to keep it?
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * An entry is added to the windowTable hash table.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXRegisterOffScreenWindow(
+ Window window, /* Window structure. */
+ GWorldPtr portPtr) /* Pointer to a Mac GWorld. */
+{
+ MacDrawable *macWin;
+ Tcl_HashEntry *valueHashPtr;
+ int new;
+
+ macWin = (MacDrawable *) window;
+ if (!windowHashInit) {
+ Tcl_InitHashTable(&windowTable, TCL_ONE_WORD_KEYS);
+ windowHashInit = true;
+ }
+ valueHashPtr = Tcl_CreateHashEntry(&windowTable,
+ (char *) portPtr, &new);
+ if (!new) {
+ panic("same macintosh window allocated twice!");
+ }
+ Tcl_SetHashValue(valueHashPtr, macWin);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXUnregisterMacWindow --
+ *
+ * Given a macintosh port window, this function removes the
+ * association between this window and the root X window that
+ * Tk cares about.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * An entry is removed from the windowTable hash table.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXUnregisterMacWindow(
+ WindowRef macWinPtr) /* Reference to a Mac Window */
+{
+ Tcl_HashEntry *entryPtr;
+ if (!windowHashInit) {
+ panic("TkMacOSXUnregisterMacWindow: unmapping before inited");
+ }
+ entryPtr=Tcl_FindHashEntry(&windowTable,(char *) macWinPtr);
+ if (!entryPtr) {
+ fprintf(stderr,"Unregister:failed to find window %08x\n",
+ (int) macWinPtr );
+ }
+ else {
+ Tcl_DeleteHashEntry(entryPtr);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXSetScrollbarGrow --
+ *
+ * Sets a flag for a toplevel window indicating that the passed
+ * Tk scrollbar window will display the grow region for the
+ * toplevel window.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * A flag is set int windows toplevel parent.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXSetScrollbarGrow(
+ TkWindow *winPtr, /* Tk scrollbar window. */
+ int flag) /* Boolean value true or false. */
+{
+ if (flag) {
+ winPtr->privatePtr->toplevel->flags |= TK_SCROLLBAR_GROW;
+ winPtr->privatePtr->toplevel->winPtr->wmInfoPtr->scrollWinPtr = winPtr;
+ } else if (winPtr->privatePtr->toplevel->winPtr->wmInfoPtr->scrollWinPtr
+ == winPtr) {
+ winPtr->privatePtr->toplevel->flags &= ~TK_SCROLLBAR_GROW;
+ winPtr->privatePtr->toplevel->winPtr->wmInfoPtr->scrollWinPtr = NULL;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkWmFocusToplevel --
+ *
+ * This is a utility procedure invoked by focus-management code. It
+ * exists because of the extra wrapper windows that exist under
+ * Unix; its job is to map from wrapper windows to the
+ * corresponding toplevel windows. On PCs and Macs there are no
+ * wrapper windows so no mapping is necessary; this procedure just
+ * determines whether a window is a toplevel or not.
+ *
+ * Results:
+ * If winPtr is a toplevel window, returns the pointer to the
+ * window; otherwise returns NULL.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkWindow *
+TkWmFocusToplevel(
+ TkWindow *winPtr) /* Window that received a focus-related
+ * event. */
+{
+ if (!(winPtr->flags & TK_TOP_LEVEL)) {
+ return NULL;
+ }
+ return winPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetWrapperWindow --
+ *
+ * This is a utility procedure invoked by focus-management code. It
+ * maps to the wrapper for a top-level, which is just the same
+ * as the top-level on Macs and PCs.
+ *
+ * Results:
+ * If winPtr is a toplevel window, returns the pointer to the
+ * window; otherwise returns NULL.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkWindow *
+TkpGetWrapperWindow(
+ TkWindow *winPtr) /* Window that received a focus-related
+ * event. */
+{
+ if (!(winPtr->flags & TK_TOP_LEVEL)) {
+ return NULL;
+ }
+ return winPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpWmSetState --
+ *
+ * Sets the window manager state for the wrapper window of a
+ * given toplevel window.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May maximize, minimize, restore, or withdraw a window.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpWmSetState(winPtr, state)
+ TkWindow *winPtr; /* Toplevel window to operate on. */
+ int state; /* One of IconicState, ZoomState, NormalState,
+ * or WithdrawnState. */
+{
+ WmInfo *wmPtr = winPtr->wmInfoPtr;
+ WindowRef macWin;
+
+ wmPtr->hints.initial_state = state;
+ if (wmPtr->flags & WM_NEVER_MAPPED) {
+ return;
+ }
+
+ macWin = GetWindowFromPort(TkMacOSXGetDrawablePort (winPtr->window));
+
+ if (state == WithdrawnState) {
+ Tk_UnmapWindow((Tk_Window) winPtr);
+ } else if (state == IconicState) {
+ Tk_UnmapWindow((Tk_Window) winPtr);
+ /*
+ * The window always gets unmapped. However, if we can show the
+ * icon version of the window (collapsed) we make the window visable
+ * and then collapse it.
+ *
+ * TODO: This approach causes flashing!
+ */
+
+ if (IsWindowCollapsable(macWin)) {
+ ShowWindow(macWin);
+ CollapseWindow( macWin, true);
+ }
+
+ } else if (state == NormalState) {
+ Tk_MapWindow((Tk_Window) winPtr);
+ CollapseWindow((WindowPtr) macWin, false);
+ } else if (state == ZoomState) {
+ /* TODO: need to support zoomed windows */
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpIsWindowFloating --
+ *
+ * Returns 1 if a window is floating, 0 otherwise.
+ *
+ * Results:
+ * 1 or 0 depending on window's floating attribute.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpIsWindowFloating(WindowRef wRef)
+{
+ WindowClass class;
+ GetWindowClass(wRef, &class);
+ return (class == kFloatingWindowClass);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXWindowOffset --
+ *
+ * Determines the x and y offset from the orgin of the toplevel
+ * window dressing (the structure region, ie. title bar) and the
+ * orgin of the content area.
+ *
+ * Results:
+ * The x & y offset in pixels.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXWindowOffset(
+ WindowRef wRef,
+ int *xOffset,
+ int *yOffset)
+{
+ OSErr err = noErr;
+ static RgnHandle strucRgn = NULL;
+ static RgnHandle contRgn = NULL;
+ Rect strucRect, contRect;
+
+ if (!strucRgn) {
+ if(!(strucRgn = NewRgn())) {
+ err=MemError();
+ }
+ }
+ if (!contRgn) {
+ if(!(contRgn = NewRgn())) {
+ err=MemError();
+ }
+ }
+ if (err==noErr) {
+ GetWindowRegion(wRef, kWindowStructureRgn, strucRgn);
+ GetWindowRegion(wRef, kWindowContentRgn, contRgn);
+ GetRegionBounds(strucRgn,&strucRect);
+ GetRegionBounds(contRgn,&contRect);
+ *xOffset = contRect.left - strucRect.left;
+ *yOffset = contRect.top - strucRect.top;
+ } else {
+ *xOffset = 0;
+ *yOffset = 0;
+ }
+ return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetMS --
+ *
+ * Return a relative time in milliseconds. It doesn't matter
+ * when the epoch was.
+ *
+ * Results:
+ * Number of milliseconds.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+unsigned long
+TkpGetMS()
+{
+ long long * int64Ptr;
+ UnsignedWide micros;
+
+ Microseconds(&micros);
+ int64Ptr = (long long *) &micros;
+
+ /*
+ * We need 64 bit math to do this. This is available in CW 11
+ * and on. Other's will need to use a different scheme.
+ */
+
+ *int64Ptr /= 1000;
+
+ return (long) *int64Ptr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XSetInputFocus --
+ *
+ * Change the focus window for the application.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XSetInputFocus(
+ Display* display,
+ Window focus,
+ int revert_to,
+ Time time)
+{
+ /*
+ * Don't need to do a thing. Tk manages the focus for us.
+ */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpChangeFocus --
+ *
+ * This procedure is a stub on the Mac because we always own the
+ * focus if we are a front most application.
+ *
+ * Results:
+ * The return value is the serial number of the command that
+ * changed the focus. It may be needed by the caller to filter
+ * out focus change events that were queued before the command.
+ * If the procedure doesn't actually change the focus then
+ * it returns 0.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpChangeFocus(winPtr, force)
+ TkWindow *winPtr; /* Window that is to receive the X focus. */
+ int force; /* Non-zero means claim the focus even
+ * if it didn't originally belong to
+ * topLevelPtr's application. */
+{
+ /*
+ * We don't really need to do anything on the Mac. Tk will
+ * keep all this state for us.
+ */
+
+ if (winPtr->atts.override_redirect) {
+ return 0;
+ }
+
+ /*
+ * Remember the current serial number for the X server and issue
+ * a dummy server request. This marks the position at which we
+ * changed the focus, so we can distinguish FocusIn and FocusOut
+ * events on either side of the mark.
+ */
+
+ return NextRequest(winPtr->display);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkWmStackorderToplevelWrapperMap --
+ *
+ * This procedure will create a table that maps the reparent wrapper
+ * X id for a toplevel to the TkWindow structure that is wraps.
+ * Tk keeps track of a mapping from the window X id to the TkWindow
+ * structure but that does us no good here since we only get the X
+ * id of the wrapper window. Only those toplevel windows that are
+ * mapped have a position in the stacking order.
+ *
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Adds entries to the passed hashtable.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+TkWmStackorderToplevelWrapperMap(winPtr, table)
+ TkWindow *winPtr; /* TkWindow to recurse on */
+ Tcl_HashTable *table; /* Maps mac window to TkWindow */
+{
+ TkWindow *childPtr;
+ Tcl_HashEntry *hPtr;
+ void *wrapper;
+ int newEntry;
+
+ if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr)) {
+ wrapper = (void *) TkMacOSXGetDrawablePort(winPtr->window);
+
+ hPtr = Tcl_CreateHashEntry(table,
+ (char *) wrapper, &newEntry);
+ Tcl_SetHashValue(hPtr, winPtr);
+ }
+
+ for (childPtr = winPtr->childList; childPtr != NULL;
+ childPtr = childPtr->nextPtr) {
+ TkWmStackorderToplevelWrapperMap(childPtr, table);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkWmStackorderToplevel --
+ *
+ * This procedure returns the stack order of toplevel windows.
+ *
+ * Results:
+ * An array of pointers to tk window objects in stacking order
+ * or else NULL if there was an error.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkWindow **
+TkWmStackorderToplevel(parentPtr)
+ TkWindow *parentPtr; /* Parent toplevel window. */
+{
+ WindowRef frontWindow;
+ TkWindow *childWinPtr, **windows, **window_ptr;
+ Tcl_HashTable table;
+ Tcl_HashEntry *hPtr;
+ Tcl_HashSearch search;
+
+ /*
+ * Map mac windows to a TkWindow of the wrapped toplevel.
+ */
+
+ Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
+ TkWmStackorderToplevelWrapperMap(parentPtr, &table);
+
+ windows = (TkWindow **) ckalloc((table.numEntries+1)
+ * sizeof(TkWindow *));
+
+ /*
+ * Special cases: If zero or one toplevels were mapped
+ * there is no need to enumerate Windows.
+ */
+
+ switch (table.numEntries) {
+ case 0:
+ windows[0] = NULL;
+ goto done;
+ case 1:
+ hPtr = Tcl_FirstHashEntry(&table, &search);
+ windows[0] = (TkWindow *) Tcl_GetHashValue(hPtr);
+ windows[1] = NULL;
+ goto done;
+ }
+
+ frontWindow = (WindowRef) FrontWindow();
+
+ if (frontWindow == NULL) {
+ ckfree((char *) windows);
+ windows = NULL;
+ } else {
+ window_ptr = windows + table.numEntries;
+ *window_ptr-- = NULL;
+ while (frontWindow != NULL) {
+ hPtr = Tcl_FindHashEntry(&table, (char *) frontWindow);
+ if (hPtr != NULL) {
+ childWinPtr = (TkWindow *) Tcl_GetHashValue(hPtr);
+ *window_ptr-- = childWinPtr;
+ }
+ frontWindow = GetNextWindow(frontWindow);
+ }
+ if (window_ptr != (windows-1))
+ panic("num matched toplevel windows does not equal num children");
+ }
+
+ done:
+ Tcl_DeleteHashTable(&table);
+ return windows;
+}
+
+
+
+
+
diff --git a/macosx/tkMacOSXWm.h b/macosx/tkMacOSXWm.h
new file mode 100644
index 0000000..eaa0dd5
--- /dev/null
+++ b/macosx/tkMacOSXWm.h
@@ -0,0 +1,302 @@
+/*
+/*
+ * tkMacOSXWm.h --
+ *
+ * Declarations of Macintosh specific functions for implementing the
+ * Mac OS X Notifier.
+ *
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _TKMACWM
+#define _TKMACWM
+
+#include <Carbon/Carbon.h>
+#include "tkPort.h"
+#include "tkInt.h"
+#include "tkMacOSXInt.h"
+#include <errno.h>
+#include "tkScrollbar.h"
+
+/*
+ * A data structure of the following type holds information for
+ * each window manager protocol (such as WM_DELETE_WINDOW) for
+ * which a handler (i.e. a Tcl command) has been defined for a
+ * particular top-level window.
+ */
+
+typedef struct ProtocolHandler {
+ Atom protocol; /* Identifies the protocol. */
+ struct ProtocolHandler *nextPtr;
+ /* Next in list of protocol handlers for
+ * the same top-level window, or NULL for
+ * end of list. */
+ Tcl_Interp *interp; /* Interpreter in which to invoke command. */
+ char command[4]; /* Tcl command to invoke when a client
+ * message for this protocol arrives.
+ * The actual size of the structure varies
+ * to accommodate the needs of the actual
+ * command. THIS MUST BE THE LAST FIELD OF
+ * THE STRUCTURE. */
+} ProtocolHandler;
+
+#define HANDLER_SIZE(cmdLength) \
+((unsigned) (sizeof(ProtocolHandler) - 3 + cmdLength))
+
+/*
+ * A data structure of the following type holds window-manager-related
+ * information for each top-level window in an application.
+ */
+
+typedef struct TkWmInfo {
+ TkWindow *winPtr; /* Pointer to main Tk information for
+ * this window. */
+ Window reparent; /* If the window has been reparented, this
+ * gives the ID of the ancestor of the window
+ * that is a child of the root window (may
+ * not be window's immediate parent). If
+ * the window isn't reparented, this has the
+ * value None. */
+ Tk_Uid titleUid; /* Title to display in window caption. If
+ * NULL, use name of widget. */
+ char *iconName; /* Name to display in icon. */
+ Window master; /* Master window for TRANSIENT_FOR property,
+ * or None. */
+ XWMHints hints; /* Various pieces of information for
+ * window manager. */
+ char *leaderName; /* Path name of leader of window group
+ * (corresponds to hints.window_group).
+ * Malloc-ed. Note: this field doesn't
+ * get updated if leader is destroyed. */
+ char *masterWindowName; /* Path name of window specified as master
+ * in "wm transient" command, or NULL.
+ * Malloc-ed. Note: this field doesn't
+ * get updated if masterWindowName is
+ * destroyed. */
+ Tk_Window icon; /* Window to use as icon for this window,
+ * or NULL. */
+ Tk_Window iconFor; /* Window for which this window is icon, or
+ * NULL if this isn't an icon for anyone. */
+
+ /*
+ * Information used to construct an XSizeHints structure for
+ * the window manager:
+ */
+
+ int sizeHintsFlags; /* Flags word for XSizeHints structure.
+ * If the PBaseSize flag is set then the
+ * window is gridded; otherwise it isn't
+ * gridded. */
+ int minWidth, minHeight; /* Minimum dimensions of window, in
+ * grid units, not pixels. */
+ int maxWidth, maxHeight; /* Maximum dimensions of window, in
+ * grid units, not pixels. */
+ Tk_Window gridWin; /* Identifies the window that controls
+ * gridding for this top-level, or NULL if
+ * the top-level isn't currently gridded. */
+ int widthInc, heightInc; /* Increments for size changes (# pixels
+ * per step). */
+ struct {
+ int x; /* numerator */
+ int y; /* denominator */
+ } minAspect, maxAspect; /* Min/max aspect ratios for window. */
+ int reqGridWidth, reqGridHeight;
+ /* The dimensions of the window (in
+ * grid units) requested through
+ * the geometry manager. */
+ int gravity; /* Desired window gravity. */
+
+ /*
+ * Information used to manage the size and location of a window.
+ */
+
+ int width, height; /* Desired dimensions of window, specified
+ * in grid units. These values are
+ * set by the "wm geometry" command and by
+ * ConfigureNotify events (for when wm
+ * resizes window). -1 means user hasn't
+ * requested dimensions. */
+ int x, y; /* Desired X and Y coordinates for window.
+ * These values are set by "wm geometry",
+ * plus by ConfigureNotify events (when wm
+ * moves window). These numbers are
+ * different than the numbers stored in
+ * winPtr->changes because (a) they could be
+ * measured from the right or bottom edge
+ * of the screen (see WM_NEGATIVE_X and
+ * WM_NEGATIVE_Y flags) and (b) if the window
+ * has been reparented then they refer to the
+ * parent rather than the window itself. */
+ int parentWidth, parentHeight;
+ /* Width and height of reparent, in pixels
+ * *including border*. If window hasn't been
+ * reparented then these will be the outer
+ * dimensions of the window, including
+ * border. */
+ int xInParent, yInParent; /* Offset of window within reparent, measured
+ * from upper-left outer corner of parent's
+ * border to upper-left outer corner of child's
+ * border. If not reparented then these are
+ * zero. */
+ int configWidth, configHeight;
+ /* Dimensions passed to last request that we
+ * issued to change geometry of window. Used
+ * to eliminate redundant resize operations. */
+
+ /*
+ * Information about the virtual root window for this top-level,
+ * if there is one.
+ */
+
+ Window vRoot; /* Virtual root window for this top-level,
+ * or None if there is no virtual root
+ * window (i.e. just use the screen's root). */
+ int vRootX, vRootY; /* Position of the virtual root inside the
+ * root window. If the WM_VROOT_OFFSET_STALE
+ * flag is set then this information may be
+ * incorrect and needs to be refreshed from
+ * the X server. If vRoot is None then these
+ * values are both 0. */
+ unsigned int vRootWidth, vRootHeight;
+ /* Dimensions of the virtual root window.
+ * If vRoot is None, gives the dimensions
+ * of the containing screen. This information
+ * is never stale, even though vRootX and
+ * vRootY can be. */
+
+ /*
+ * List of children of the toplevel which have private colormaps.
+ */
+
+ TkWindow **cmapList; /* Array of window with private colormaps. */
+ int cmapCount; /* Number of windows in array. */
+
+ /*
+ * Miscellaneous information.
+ */
+
+ ProtocolHandler *protPtr; /* First in list of protocol handlers for
+ * this window (NULL means none). */
+ int cmdArgc; /* Number of elements in cmdArgv below. */
+ CONST char **cmdArgv; /* Array of strings to store in the
+ * WM_COMMAND property. NULL means nothing
+ * available. */
+ char *clientMachine; /* String to store in WM_CLIENT_MACHINE
+ * property, or NULL. */
+ int flags; /* Miscellaneous flags, defined below. */
+
+ /*
+ * Macintosh information.
+ */
+ int style; /* Native window style. */
+ int macClass;
+ int attributes;
+ TkWindow *scrollWinPtr; /* Ptr to scrollbar handling grow widget. */
+} WmInfo;
+
+
+/*
+ * Flag values for WmInfo structures:
+ *
+ * WM_NEVER_MAPPED - non-zero means window has never been
+ * mapped; need to update all info when
+ * window is first mapped.
+ * WM_UPDATE_PENDING - non-zero means a call to UpdateGeometryInfo
+ * has already been scheduled for this
+ * window; no need to schedule another one.
+ * WM_NEGATIVE_X - non-zero means x-coordinate is measured in
+ * pixels from right edge of screen, rather
+ * than from left edge.
+ * WM_NEGATIVE_Y - non-zero means y-coordinate is measured in
+ * pixels up from bottom of screen, rather than
+ * down from top.
+ * WM_UPDATE_SIZE_HINTS - non-zero means that new size hints need to be
+ * propagated to window manager.
+ * WM_SYNC_PENDING - set to non-zero while waiting for the window
+ * manager to respond to some state change.
+ * WM_VROOT_OFFSET_STALE - non-zero means that (x,y) offset information
+ * about the virtual root window is stale and
+ * needs to be fetched fresh from the X server.
+ * WM_ABOUT_TO_MAP - non-zero means that the window is about to
+ * be mapped by TkWmMapWindow. This is used
+ * by UpdateGeometryInfo to modify its behavior.
+ * WM_MOVE_PENDING - non-zero means the application has requested
+ * a new position for the window, but it hasn't
+ * been reflected through the window manager
+ * yet.
+ * WM_COLORMAPS_EXPLICIT - non-zero means the colormap windows were
+ * set explicitly via "wm colormapwindows".
+ * WM_ADDED_TOPLEVEL_COLORMAP - non-zero means that when "wm colormapwindows"
+ * was called the top-level itself wasn't
+ * specified, so we added it implicitly at
+ * the end of the list.
+ * WM_WIDTH_NOT_RESIZABLE - non-zero means that we're not supposed to
+ * allow the user to change the width of the
+ * window (controlled by "wm resizable"
+ * command).
+ * WM_HEIGHT_NOT_RESIZABLE - non-zero means that we're not supposed to
+ * allow the user to change the height of the
+ * window (controlled by "wm resizable"
+ * command).
+ */
+
+#define WM_NEVER_MAPPED 1
+#define WM_UPDATE_PENDING 2
+#define WM_NEGATIVE_X 4
+#define WM_NEGATIVE_Y 8
+#define WM_UPDATE_SIZE_HINTS 0x10
+#define WM_SYNC_PENDING 0x20
+#define WM_VROOT_OFFSET_STALE 0x40
+#define WM_ABOUT_TO_MAP 0x100
+#define WM_MOVE_PENDING 0x200
+#define WM_COLORMAPS_EXPLICIT 0x400
+#define WM_ADDED_TOPLEVEL_COLORMAP 0x800
+#define WM_WIDTH_NOT_RESIZABLE 0x1000
+#define WM_HEIGHT_NOT_RESIZABLE 0x2000
+
+#endif
+
diff --git a/macosx/tkMacOSXXCursors.r b/macosx/tkMacOSXXCursors.r
new file mode 100644
index 0000000..fd2a61c
--- /dev/null
+++ b/macosx/tkMacOSXXCursors.r
@@ -0,0 +1,961 @@
+/*
+ * tkMacOSXXCursors.r --
+ *
+ * This file defines a set of Macintosh cursor resources that
+ * emulate the X cursor set. All of these cursors were
+ * constructed and donated by Grant Neufeld. (gneufeld@ccs.carleton.ca)
+ *
+ *
+ * Copyright (c) 1995-1996 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXXCursors.r,v 1.2 2002/08/31 06:12:31 das Exp $
+ */
+
+/*
+ * All of the X cursors are defined as 'CURS' resources. However, a
+ * subset of the X cursors are also defined as 'crsr' resources. Tk
+ * will attempt to first use the color cursors ('crsr') if it doesn't
+ * exist it will attempt to use the black & white cursor ('CURS').
+ */
+
+data 'CURS' (3000, "X_cursor") {
+ $"E007 F00F F81F 7C3E 3E7C 1FF8 0FF0 07E0"
+ $"07E0 0FF0 1FF8 3E7C 7C3E F81F F00F E007"
+ $"0000 6006 700E 381C 1C38 0E70 07E0 03C0"
+ $"03C0 07E0 0E70 1C38 381C 700E 6006 0000"
+ $"0007 0007"
+};
+
+data 'CURS' (3001, "arrow") {
+ $"0000 0006 001E 007C 01FC 07F8 00F8 01F0"
+ $"03B0 0720 0E20 1C00 3800 7000 2000 0000"
+ $"0007 001F 007F 01FE 07FE 1FFC 7FFC 03F8"
+ $"07F8 0FF0 1F70 3E60 7C60 F840 7040 2000"
+ $"0001 000E"
+};
+
+data 'CURS' (3002, "based_arrow_down") {
+ $"0000 0000 0000 1FE0 0000 1FE0 0300 0300"
+ $"0300 0B40 0780 0300 0000 0000 0000 0000"
+ $"0000 0000 0000 1FE0 0000 1FE0 0780 0780"
+ $"3FF0 1FE0 0FC0 0780 0300 0000 0000 0000"
+ $"000B 0006"
+};
+
+data 'CURS' (3003, "based_arrow_up") {
+ $"0000 0000 0000 0000 0300 0780 0B40 0300"
+ $"0300 0300 1FE0 0000 1FE0 0000 0000 0000"
+ $"0000 0000 0000 0300 0780 0FC0 1FE0 3FF0"
+ $"0780 0780 1FE0 0000 1FE0 0000 0000 0000"
+ $"0004 0006"
+};
+
+data 'CURS' (3004, "boat") {
+ $"0000 0000 0000 0000 0100 03C0 8460 FFFF"
+ $"0018 0020 0040 FFC0 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0100 03C0 87E0 FFFF"
+ $"FFF8 FFE0 FFC0 FFC0 0000 0000 0000 0000"
+ $"0007 000F"
+};
+
+data 'CURS' (3005, "bogosity") {
+ $"0000 711C 1110 1110 1110 7FFC 5114 5114"
+ $"5114 5114 7FFC 1110 1110 1110 711C 0000"
+ $"0000 0000 0000 0000 0000 7FFC 7FFC 7FFC"
+ $"7FFC 7FFC 7FFC 0000 0000 0000 0000 0000"
+ $"0001 0007"
+};
+
+data 'CURS' (3006, "bottom_left_corner") {
+ $"0000 0000 0000 0000 C000 C020 C840 C880"
+ $"C900 CA00 CC00 CFC0 C000 C000 FFF0 FFF0"
+ $"0000 0000 0000 0000 0000 0020 0840 0880"
+ $"0900 0A00 0C00 0FC0 0000 0000 0000 0000"
+ $"000F 0000"
+};
+
+data 'CURS' (3007, "bottom_right_corner") {
+ $"0000 0000 0000 0000 0003 0403 0213 0113"
+ $"0093 0053 0033 03F3 0003 0003 0FFF 0FFF"
+ $"0000 0000 0000 0000 0000 0400 0210 0110"
+ $"0090 0050 0030 03F0 0000 0000 0000 0000"
+ $"000F 000F"
+};
+
+data 'CURS' (3008, "bottom_side") {
+ $"0000 0000 0100 0100 0100 0100 0100 1110"
+ $"0920 0540 0380 0100 0000 7FFC 7FFC 0000"
+ $"0000 0000 0100 0100 0100 0100 0100 1110"
+ $"0920 0540 0380 0100 0000 0000 0000 0000"
+ $"000B 0007"
+};
+
+data 'CURS' (3009, "bottom_tee") {
+ $"0000 0000 0000 0180 0180 0180 0180 0180"
+ $"0180 0180 7FFE 7FFE 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"000B 0007"
+};
+
+data 'CURS' (3010, "box_spiral") {
+ $"FFFE 8000 BFFE A002 AFFA A80A ABEA AA2A"
+ $"AAAA ABAA A82A AFEA A00A BFFA 8002 FFFE"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0008 0008"
+};
+
+data 'CURS' (3011, "center_ptr") {
+ $"0000 0300 0300 0780 0780 0FC0 0FC0 1FE0"
+ $"1FE0 3330 2310 0300 0300 0300 0300 0000"
+ $"0300 0780 0780 0FC0 0FC0 1FE0 1FE0 3FF0"
+ $"3FF0 7FF8 77B8 6798 0780 0780 0780 0780"
+ $"0001 0006"
+};
+
+data 'CURS' (3012, "circle") {
+ $"0000 03C0 0FF0 1FF8 3C3C 381C 700E 700E"
+ $"700E 700E 381C 3C3C 1FF8 0FF0 03C0 0000"
+ $"03C0 0FF0 1FF8 3FFC 7FFE 7C3E F81F F81F"
+ $"F81F F81F 7C3E 7FFE 3FFC 1FF8 0FF0 03C0"
+ $"0007 0007"
+};
+
+data 'CURS' (3013, "clock") {
+ $"1FF8 33CC 6466 4992 4F12 4422 63C6 3FFC"
+ $"2994 2994 2994 2BD4 6996 781E 7FFE 7FFE"
+ $"1FF8 3FFC 7FFE 7FFE 7FFE 7FFE 7FFE 3FFC"
+ $"3FFC 3FFC 3FFC 3FFC 7FFE 7FFE 7FFE 7FFE"
+ $"0004 0008"
+};
+
+data 'CURS' (3014, "coffee_mug") {
+ $"03F8 0C06 1001 1C07 33F9 7001 D001 9001"
+ $"960D DA55 7A55 36ED 10A1 1001 0802 07FC"
+ $"03F8 0FFE 1FFF 1FFF 3FFF 7FFF FFFF FFFF"
+ $"FFFF FFFF 7FFF 3FFF 1FFF 1FFF 0FFE 07FC"
+ $"0004 0003"
+};
+
+data 'CURS' (3015, "cross") {
+ $"0280 0280 0280 0280 0280 0280 FEFE 0000"
+ $"FEFE 0280 0280 0280 0280 0280 0280 0000"
+ $"0380 0380 0380 0380 0380 0380 FFFE FFFE"
+ $"FFFE 0380 0380 0380 0380 0380 0380 0000"
+ $"0007 0007"
+};
+
+data 'CURS' (3016, "cross_reverse") {
+ $"4284 A28A 5294 2AA8 16D0 0AA0 FD7E 0280"
+ $"FD7E 0AA0 16D0 2AA8 5294 A28A 4284 0000"
+ $"4384 E38E 739C 3BB8 1FF0 0FE0 FFFE FFFE"
+ $"FFFE 0FE0 1FF0 3BB8 739C E38E 4384 0000"
+ $"0007 0007"
+};
+
+data 'CURS' (3017, "crosshair") {
+ $"0100 0100 0100 0100 0100 0100 0100 FEFE"
+ $"0100 0100 0100 0100 0100 0100 0100 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0007 0007"
+};
+
+data 'CURS' (3018, "diamond_cross") {
+ $"0280 06C0 0AA0 1290 2288 4284 FEFE 0000"
+ $"FEFE 4284 2288 1290 0AA0 06C0 0280 0000"
+ $"0280 06C0 0EE0 1EF0 3EF8 7EFC FEFE 0000"
+ $"FEFE 7EFC 3EF8 1EF0 0EE0 06C0 0280 0000"
+ $"0007 0007"
+};
+
+data 'CURS' (3019, "dot") {
+ $"0000 0000 0780 1FE0 1FE0 3FF0 3FF0 3FF0"
+ $"3FF0 1FE0 1FE0 0780 0000 0000 0000 0000"
+ $"0000 0780 1FE0 3FF0 3FF0 7FF8 7FF8 7FF8"
+ $"7FF8 3FF0 3FF0 1FE0 0780 0000 0000 0000"
+ $"0006 0006"
+};
+
+data 'CURS' (3020, "dotbox") {
+ $"0000 0000 3FFC 2004 2004 2004 2004 2184"
+ $"2184 2004 2004 2004 2004 3FFC 0000 0000"
+ $"0000 0000 3FFC 3FFC 300C 300C 318C 33CC"
+ $"33CC 318C 300C 300C 3FFC 3FFC 0000 0000"
+ $"0007 0007"
+};
+
+data 'CURS' (3021, "double_arrow") {
+ $"0000 0180 03C0 07E0 0DB0 1998 0180 0180"
+ $"0180 0180 1998 0DB0 07E0 03C0 0180 0000"
+ $"0180 03C0 07E0 0FF0 1FF8 3FFC 3BDC 03C0"
+ $"03C0 3BDC 3FFC 1FF8 0FF0 07E0 03C0 0180"
+ $"0007 0007"
+};
+
+data 'CURS' (3022, "draft_large") {
+ $"0000 0002 000C 003C 00F8 03F8 0FF0 00F0"
+ $"0160 0260 0440 0840 1000 2000 4000 0000"
+ $"0003 000F 003E 00FE 03FC 0FFC 3FF8 FFF8"
+ $"03F0 07F0 0EE0 1CE0 38C0 70C0 E080 4080"
+ $"0001 000E"
+};
+
+data 'CURS' (3023, "draft_small") {
+ $"0000 0002 000C 003C 00F8 03F8 0070 00B0"
+ $"0120 0220 0400 0800 1000 2000 4000 0000"
+ $"0003 000F 003E 00FE 03FC 0FFC 3FF8 01F8"
+ $"03F0 0770 0E60 1C60 3840 7040 E000 4000"
+ $"0001 000E"
+};
+
+data 'CURS' (3024, "draped_box") {
+ $"0000 0000 3FFC 2244 2664 2C34 381C 2184"
+ $"2184 381C 2C34 2664 2244 3FFC 0000 0000"
+ $"0000 0000 3FFC 3E7C 3E7C 3C3C 399C 23C4"
+ $"23C4 399C 3C3C 3E7C 3E7C 3FFC 0000 0000"
+ $"0007 0007"
+};
+
+data 'CURS' (3025, "exchange") {
+ $"0000 47C0 6FE0 7C30 4810 4C00 7E00 0000"
+ $"0000 00FC 0064 1024 187C 0FEC 07C4 0000"
+ $"C7C0 EFE0 FFF0 FFF8 FC38 FE10 FF00 FF80"
+ $"03FE 01FE 10FE 387E 3FFE 1FFE 0FEE 07C6"
+ $"0007 0007"
+};
+
+data 'CURS' (3026, "fleur") {
+ $"0000 0180 03C0 07E0 0180 1188 318C 7FFE"
+ $"7FFE 318C 1188 0180 07E0 03C0 0180 0000"
+ $"0180 03C0 07E0 0FF0 17E8 3BDC 7FFE FFFF"
+ $"FFFF 7FFE 3BDC 17E8 0FF0 07E0 03C0 0180"
+ $"0007 0007"
+};
+
+data 'CURS' (3027, "gobbler") {
+ $"0000 0078 0070 4036 4FB0 7FF0 7E30 7C30"
+ $"3038 00F0 0FE0 0400 0400 0400 0F00 0000"
+ $"00FC 00FC E0FF FFFF FFFF FFF8 FFF8 FFF8"
+ $"FFFC 7FFC 3FF8 1FF0 0E00 1F80 1F80 1F80"
+ $"0003 000E"
+};
+
+data 'CURS' (3028, "gumby") {
+ $"3F00 10C0 C820 EAA0 C820 CBA0 F838 383E"
+ $"0826 0826 092E 0926 0920 1110 2108 3EF8"
+ $"3F00 1FC0 CFE0 EFE0 CFE0 CFE0 FFF8 3FFE"
+ $"0FE6 0FE6 0FEE 0FE6 0FE0 1FF0 3FF8 3EF8"
+ $"0000 0002"
+};
+
+data 'CURS' (3029, "hand1") {
+ $"000C 003C 00F0 01E0 03C0 07E0 0FF0 2FE0"
+ $"7FF0 5FF0 07E0 07C0 4A00 6200 3400 1800"
+ $"000C 003C 00F0 01E0 03C0 07E0 0FF0 2FE0"
+ $"7FF0 7FF0 7FE0 7FC0 7E00 7E00 3C00 1800"
+ $"0000 000D"
+};
+
+data 'CURS' (3030, "hand2") {
+ $"0000 3FC0 4020 3F10 0808 0708 0808 0714"
+ $"0822 0641 0182 0124 0088 0050 0020 0000"
+ $"0000 3FC0 7FE0 3FF0 0FF8 07F8 0FF8 07FC"
+ $"0FFE 07FF 01FE 01FC 00F8 0070 0020 0000"
+ $"0002 0001"
+};
+
+data 'CURS' (3031, "heart") {
+ $"0000 3EF8 638C C106 8002 8002 8002 8002"
+ $"C006 600C 3018 1830 0C60 06C0 0380 0000"
+ $"0000 3EF8 7FFC FFFE FFFE FFFE FFFE FFFE"
+ $"FFFE 7FFC 3FF8 1FF0 0FE0 07C0 0380 0000"
+ $"0003 0007"
+};
+
+data 'CURS' (3032, "icon") {
+ $"FFFF D555 AAAB D555 A00B D005 A00B D005"
+ $"A00B D005 A00B D005 AAAB D555 AAAB FFFF"
+ $"FFFF FFFF FFFF FFFF F00F F00F F00F F00F"
+ $"F00F F00F F00F F00F FFFF FFFF FFFF FFFF"
+ $"0007 0007"
+};
+
+data 'CURS' (3033, "iron_cross") {
+ $"0000 3FFC 1FF8 4FF2 67E6 73CE 799E 7FFE"
+ $"7FFE 799E 73CE 67E6 4FF2 1FF8 3FFC 0000"
+ $"7FFE 7FFE FFFF FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFFF FFFF FFFF FFFF 7FFE 7FFE"
+ $"0007 0006"
+};
+
+data 'CURS' (3034, "left_ptr") {
+ $"0000 0800 0C00 0E00 0F00 0F80 0FC0 0FE0"
+ $"0FF0 0F80 0D80 08C0 00C0 0060 0060 0000"
+ $"1800 1C00 1E00 1F00 1F80 1FC0 1FE0 1FF0"
+ $"1FF8 1FFC 1FC0 1DE0 19E0 10F0 00F0 0070"
+ $"0001 0004"
+};
+
+data 'CURS' (3035, "left_side") {
+ $"0000 6000 6000 6080 6100 6200 6400 6FFC"
+ $"6400 6200 6100 6080 6000 6000 0000 0000"
+ $"0000 0000 0000 0080 0100 0200 0400 0FFC"
+ $"0400 0200 0100 0080 0000 0000 0000 0000"
+ $"0007 0004"
+};
+
+data 'CURS' (3036, "left_tee") {
+ $"0000 0C00 0C00 0C00 0C00 0C00 0C00 0FF8"
+ $"0FF8 0C00 0C00 0C00 0C00 0C00 0C00 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0007 0004"
+};
+
+data 'CURS' (3037, "leftbutton") {
+ $"8002 7FFC 7FFC 4444 4554 4554 4554 4554"
+ $"4444 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 8002"
+ $"FFFE FFFE FFFE FFFE FFFE FFFE FFFE FFFE"
+ $"FFFE FFFE FFFE FFFE FFFE FFFE FFFE FFFE"
+ $"0004 0003"
+};
+
+data 'CURS' (3038, "ll_angle") {
+ $"0000 0000 0000 0C00 0C00 0C00 0C00 0C00"
+ $"0C00 0C00 0FF8 0FF8 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"000B 0004"
+};
+
+data 'CURS' (3039, "lr_angle") {
+ $"0000 0000 0000 0030 0030 0030 0030 0030"
+ $"0030 0030 1FF0 1FF0 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"000B 000B"
+};
+
+data 'CURS' (3040, "man") {
+ $"0380 1EF0 0280 8100 4387 244B 1D70 0540"
+ $"0440 0280 0440 0920 1290 1450 783C F83F"
+ $"0380 1FF0 0380 8100 4387 27CB 1FF0 07C0"
+ $"07C0 0380 07C0 0FE0 1EF0 1C70 783C F83F"
+ $"0001 0007"
+};
+
+data 'CURS' (3041, "middlebutton") {
+ $"8002 7FFC 7FFC 4444 5454 5454 5454 5454"
+ $"4444 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 8002"
+ $"FFFE FFFE FFFE FFFE FFFE FFFE FFFE FFFE"
+ $"FFFE FFFE FFFE FFFE FFFE FFFE FFFE FFFE"
+ $"0004 0007"
+};
+
+data 'CURS' (3042, "mouse") {
+ $"0600 0100 0180 0FF0 1008 17E8 1428 1428"
+ $"17E8 1008 1008 1008 1008 1008 1008 0FF0"
+ $"0600 0100 0180 0FF0 1FF8 1FF8 1FF8 1FF8"
+ $"1FF8 1FF8 1FF8 1FF8 1FF8 1FF8 1FF8 0FF0"
+ $"0000 0000"
+};
+
+data 'CURS' (3043, "pencil") {
+ $"0000 00F0 0088 0108 0190 0270 0220 0440"
+ $"0440 0880 0880 1100 1E00 1C00 1800 1000"
+ $"0000 00F0 00F8 01F8 01F0 03F0 03E0 07C0"
+ $"07C0 0F80 0F80 1F00 1E00 1C00 1800 1000"
+ $"000F 0003"
+};
+
+data 'CURS' (3044, "pirate") {
+ $"03C0 07E0 0FF0 1998 1998 0FF0 07E0 03C0"
+ $"43C2 43C3 2184 1C38 03C0 0FF1 781F 4002"
+ $"07E0 0FF0 1FF8 3FFC 3FFC 1FF8 0FF0 47E2"
+ $"E7E7 E7E7 7FFF 3FFC 1FF9 7FFF FFFF F81F"
+ $"000A 0007"
+};
+
+data 'CURS' (3045, "plus") {
+ $"0000 0000 0000 0180 0180 0180 0180 1FF8"
+ $"1FF8 0180 0180 0180 0180 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0007 0007"
+};
+
+data 'CURS' (3046, "question_arrow") {
+ $"07C0 0FE0 1C70 1830 1C30 0C70 00E0 03C0"
+ $"0380 0280 0280 0EE0 06C0 0380 0100 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 3FF8 1FF0 0FE0 07C0 0380 0100"
+ $"000E 0007"
+};
+
+data 'CURS' (3047, "right_ptr") {
+ $"0000 0010 0030 0070 00F0 01F0 03F0 07F0"
+ $"0FF0 01F0 01B0 0310 0300 0600 0600 0000"
+ $"0018 0038 0078 00F8 01F8 03F8 07F8 0FF8"
+ $"1FF8 3FF8 03F8 07B8 0798 0F08 0F00 0E00"
+ $"0001 000B"
+};
+
+data 'CURS' (3048, "right_side") {
+ $"0000 0000 0006 0006 0106 0086 0046 0026"
+ $"3FF6 0026 0046 0086 0106 0006 0006 0000"
+ $"0000 0000 0000 0000 0100 0080 0040 0020"
+ $"3FF0 0020 0040 0080 0100 0000 0000 0000"
+ $"0008 000B"
+};
+
+data 'CURS' (3049, "right_tee") {
+ $"0000 0030 0030 0030 0030 0030 0030 1FF0"
+ $"1FF0 0030 0030 0030 0030 0030 0030 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0007 000A"
+};
+
+data 'CURS' (3050, "rightbutton") {
+ $"8002 7FFC 7FFC 4444 5544 5544 5544 5544"
+ $"4444 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 8002"
+ $"FFFE FFFE FFFE FFFE FFFE FFFE FFFE FFFE"
+ $"FFFE FFFE FFFE FFFE FFFE FFFE FFFE FFFE"
+ $"0004 0003"
+};
+
+data 'CURS' (3051, "rtl_logo") {
+ $"0000 7FFE 4022 4022 4022 7FE2 4422 4422"
+ $"4422 4422 47FE 4402 4402 4402 7FFE 0000"
+ $"0000 7FFE 7FFE 6076 7FF6 7FF6 7C36 6C36"
+ $"6C36 6C3E 6FFE 6FFE 6E06 7FFE 7FFE 0000"
+ $"0007 0007"
+};
+
+data 'CURS' (3052, "sailboat") {
+ $"0000 0040 0040 0160 0160 0360 0370 0770"
+ $"0770 0F78 0F78 1F78 1F7C 3E38 0000 0000"
+ $"0040 00E0 01E0 03F0 03F0 07F0 07F8 0FF8"
+ $"0FF8 1FFC 1FFC 3FFC 3FFE 7F7C 7E38 0000"
+ $"000C 0008"
+};
+
+data 'CURS' (3053, "sb_down_arrow") {
+ $"0280 0280 0280 0280 0280 0280 0280 0280"
+ $"0280 0280 0280 0FE0 07C0 0380 0100 0000"
+ $"0380 0380 0380 0380 0380 0380 0380 0380"
+ $"0380 0380 0380 1FF0 0FE0 07C0 0380 0100"
+ $"000E 0007"
+};
+
+data 'CURS' (3054, "sb_h_double_arrow") {
+ $"0000 0000 0000 0000 0810 1818 3FFC 781E"
+ $"3FFC 1818 0810 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0810 1818 381C 7FFE FFFF"
+ $"7FFE 381C 1818 0810 0000 0000 0000 0000"
+ $"0007 0007"
+};
+
+data 'CURS' (3055, "sb_left_arrow") {
+ $"0000 0000 0000 0000 0800 1800 3FFF 7800"
+ $"3FFF 1800 0800 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0800 1800 3800 7FFF FFFF"
+ $"7FFF 3800 1800 0800 0000 0000 0000 0000"
+ $"0007 0001"
+};
+
+data 'CURS' (3056, "sb_right_arrow") {
+ $"0000 0000 0000 0000 0000 0010 0018 FFFC"
+ $"001E FFFC 0018 0010 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0010 0018 001C FFFE"
+ $"FFFF FFFE 001C 0018 0010 0000 0000 0000"
+ $"0008 000E"
+};
+
+data 'CURS' (3057, "sb_up_arrow") {
+ $"0000 0080 01C0 03E0 07F0 0140 0140 0140"
+ $"0140 0140 0140 0140 0140 0140 0140 0140"
+ $"0080 01C0 03E0 07F0 0FF8 01C0 01C0 01C0"
+ $"01C0 01C0 01C0 01C0 01C0 01C0 01C0 01C0"
+ $"0001 0008"
+};
+
+data 'CURS' (3058, "sb_v_double_arrow") {
+ $"0000 0100 0380 07C0 0FE0 0280 0280 0280"
+ $"0280 0280 0280 0FE0 07C0 0380 0100 0000"
+ $"0100 0380 07C0 0FE0 1FF0 0380 0380 0380"
+ $"0380 0380 0380 1FF0 0FE0 07C0 0380 0100"
+ $"0007 0007"
+};
+
+data 'CURS' (3059, "shuttle") {
+ $"0020 0070 00F8 01DE 05DE 09DE 11DE 11DE"
+ $"11DE 11DE 31DE 71DE FDDE 1888 0078 0030"
+ $"0020 0070 00F8 01FE 07FE 0FFE 1FFE 1FFE"
+ $"1FFE 1FFE 3FFE 7FFE FFFE 18F8 0078 0030"
+ $"0000 000A"
+};
+
+data 'CURS' (3060, "sizing") {
+ $"0000 7F80 4000 4000 4000 47E0 4420 4422"
+ $"4422 0422 07E2 0012 000A 0006 01FE 0000"
+ $"FFC0 FFC0 FFC0 E000 EFF0 EFF0 EC37 EC37"
+ $"EC37 EC37 0FF7 0FFF 001F 03FF 03FF 03FF"
+ $"000E 000E"
+};
+
+data 'CURS' (3061, "spider") {
+ $"2010 1020 1020 0840 0840 8787 6798 1FE0"
+ $"1FE0 6798 8787 0840 0840 1020 1020 2010"
+ $"7038 3870 3870 1CE0 9FE7 EFDF FFFF 7FF8"
+ $"7FF8 FFFF EFDF 9FE7 1CE0 3870 3870 7038"
+ $"0007 0007"
+};
+
+data 'CURS' (3062, "spraycan") {
+ $"0018 0040 0D18 1E40 1A18 3F00 2100 3900"
+ $"2900 3900 2900 3900 3900 2100 2100 3F00"
+ $"0000 0000 0C00 1E00 1E00 3F00 3F00 3F00"
+ $"3F00 3F00 3F00 3F00 3F00 3F00 3F00 3F00"
+ $"0002 0007"
+};
+
+data 'CURS' (3063, "star") {
+ $"0100 0280 0280 0280 0440 0440 0440 3938"
+ $"C006 3838 0920 1290 2448 2828 3018 2008"
+ $"0100 0380 0380 0380 07C0 07C0 07C0 3FF8"
+ $"FFFE 3FF8 0FE0 1EF0 3C78 3838 3018 2008"
+ $"0007 0007"
+};
+
+data 'CURS' (3064, "target") {
+ $"0000 0380 0FE0 1C70 3018 600C C106 C286"
+ $"C106 600C 3018 1C70 0FE0 0380 0000 0000"
+ $"0000 0380 0FE0 1FF0 3C78 701C E38E E38E"
+ $"E38E 701C 3C78 1FF0 0FE0 0380 0000 0000"
+ $"0007 0007"
+};
+
+data 'CURS' (3065, "tcross") {
+ $"0100 0100 0100 0100 0100 0100 0100 FFFE"
+ $"0100 0100 0100 0100 0100 0100 0100 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0007 0007"
+};
+
+data 'CURS' (3066, "top_left_arrow") {
+ $"0000 6000 7800 3E00 3F80 1FE0 1E00 0D00"
+ $"0C80 0440 0420 0010 0008 0004 0000 0000"
+ $"E000 F800 FE00 7F80 7FE0 3FF8 3FFE 1F80"
+ $"1FC0 0EE0 0E70 0638 061C 020E 0204 0000"
+ $"0001 0001"
+};
+
+data 'CURS' (3067, "top_left_corner") {
+ $"FFF0 FFF0 C000 C000 CFC0 CC00 CA00 C900"
+ $"C880 C840 C020 C000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0FC0 0C00 0A00 0900"
+ $"0880 0840 0020 0000 0000 0000 0000 0000"
+ $"0000 0000"
+};
+
+data 'CURS' (3068, "top_right_corner") {
+ $"0FFF 0FFF 0003 0003 03F3 0033 0053 0093"
+ $"0113 0213 0403 0003 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 03F0 0030 0050 0090"
+ $"0110 0210 0400 0000 0000 0000 0000 0000"
+ $"0000 000F"
+};
+
+data 'CURS' (3069, "top_side") {
+ $"0000 7FFC 7FFC 0000 0100 0380 0540 0920"
+ $"1110 0100 0100 0100 0100 0100 0000 0000"
+ $"0000 0000 0000 0000 0100 0380 0540 0920"
+ $"1110 0100 0100 0100 0100 0100 0000 0000"
+ $"0004 0007"
+};
+
+data 'CURS' (3070, "top_tee") {
+ $"0000 0000 0000 0000 7FFE 7FFE 0180 0180"
+ $"0180 0180 0180 0180 0180 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0004 0007"
+};
+
+data 'CURS' (3071, "trek") {
+ $"0100 0000 0380 07C0 0FE0 0EE0 0FE0 07C0"
+ $"0380 0100 0BA0 0D60 0920 0820 0820 0000"
+ $"0000 0380 07C0 0FE0 1FF0 1FF0 1FF0 0FE0"
+ $"07C0 0BA0 1FF0 1FF0 1FF0 1D70 1C70 0820"
+ $"0000 0007"
+};
+
+data 'CURS' (3072, "ul_angle") {
+ $"0000 0000 0000 0FF8 0FF8 0C00 0C00 0C00"
+ $"0C00 0C00 0C00 0C00 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0003 0004"
+};
+
+data 'CURS' (3073, "umbrella") {
+ $"0000 0890 0228 49A6 27C8 1930 610C 0100"
+ $"0100 0100 0100 0100 0140 0140 0080 0000"
+ $"0000 0FF0 1FF8 7FFE 7FFC FFFE FBBE E38E"
+ $"0380 0380 0380 03C0 03E0 03E0 01C0 0080"
+ $"0004 0007"
+};
+
+data 'CURS' (3074, "ur_angle") {
+ $"0000 0000 0000 0000 1FF0 1FF0 0030 0030"
+ $"0030 0030 0030 0030 0030 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0004 000B"
+};
+
+data 'CURS' (3075, "watch") {
+ $"07E0 07E0 07E0 07E0 0810 1088 1088 108C"
+ $"138C 1008 1008 0810 07E0 07E0 07E0 07E0"
+ $"07E0 07E0 07E0 07E0 0FF0 1FF8 1FF8 1FFC"
+ $"1FFC 1FF8 1FF8 0FF0 07E0 07E0 07E0 07E0"
+ $"0008 000D"
+};
+
+data 'CURS' (3076, "xterm") {
+ $"0C60 0280 0100 0100 0100 0100 0100 0100"
+ $"0100 0100 0100 0100 0100 0100 0280 0C60"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"000B 0007"
+};
+
+/*
+ * The following are color versions of some of the
+ * cursors defined above. The color cursors will be
+ * used if the exist in preference to the black & white
+ * cursors.
+ */
+
+data 'crsr' (3004, "boat", purgeable) {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0100 03C0"
+ $"8460 FFFF 0018 0020 0040 FFC0 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0100 03C0"
+ $"87E0 FFFF FFF8 FFE0 FFC0 FFC0 0000 0000"
+ $"0000 0000 0007 000F 0000 0000 0000 0000"
+ $"0000 0000 8008 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0004 0001 0004 0000 0000 0000 0112 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 000F 0000 0000 0000 00FF FF00"
+ $"0000 F000 0F32 25F0 0000 6FFF FFFF FFFF"
+ $"FFFF 2222 2222 221F F000 2222 2222 21F0"
+ $"0000 3333 3333 4F00 0000 FFFF FFFF FF00"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0007 0000 FFFF FFFF"
+ $"FFFF 0001 BBBB BBBB BBBB 0002 EEEE EEEE"
+ $"EEEE 0003 DDDD DDDD DDDD 0004 CCCC CCCC"
+ $"CCCC 0005 4444 4444 4444 0006 1111 1111"
+ $"1111 000F 0000 0000 0000"
+};
+
+data 'crsr' (3013, "clock") {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 1FF8 33CC 6466 4992 4F12 4422"
+ $"63C6 3FFC 2994 2994 2994 2BD4 6996 781E"
+ $"7FFE 7FFE 1FF8 3FFC 7FFE 7FFE 7FFE 7FFE"
+ $"7FFE 3FFC 3FFC 3FFC 3FFC 3FFC 7FFE 7FFE"
+ $"7FFE 7FFE 0004 0008 0000 0000 0000 0000"
+ $"0000 0000 8008 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0004 0001 0004 0000 0000 0000 0112 0000"
+ $"0000 000F FFFF FFFF F000 00F6 05FF FF50"
+ $"6F00 0F60 5F00 56F5 06F0 0F00 F021 F30F"
+ $"00F0 0F00 F6F1 000F 00F0 0F00 5F00 00F5"
+ $"00F0 0F60 05FF FF50 06F0 00FF FFFF FFFF"
+ $"FF00 00F0 F001 100F 0F00 00F0 F001 100F"
+ $"0F00 00F0 F021 120F 0F00 00F0 F01F F10F"
+ $"0F00 0FF0 F021 120F 0FF0 0FF4 F500 005F"
+ $"4FF0 0FFF FFFF FFFF FFF0 0FFF FFFF FFFF"
+ $"FFF0 0000 0000 0000 0007 0000 FFFF FFFF"
+ $"FFFF 0001 4444 4444 4444 0002 AAAA AAAA"
+ $"AAAA 0003 EEEE EEEE EEEE 0004 5555 5555"
+ $"5555 0005 DDDD DDDD DDDD 0006 7777 7777"
+ $"7777 000F 0000 0000 0000"
+};
+
+data 'crsr' (3014, "coffee_mug") {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 03F8 0C06 1001 1C07 33F9 7001"
+ $"D001 9001 960D DA55 7A55 36ED 10A1 1001"
+ $"0802 07FC 03F8 0FFE 1FFF 1FFF 3FFF 7FFF"
+ $"FFFF FFFF FFFF FFFF 7FFF 3FFF 1FFF 1FFF"
+ $"0FFE 07FC 0004 0003 0000 0000 0000 0000"
+ $"0000 0000 8008 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0004 0001 0004 0000 0000 0000 0112 0000"
+ $"0000 0000 00FF FFFF F000 0000 FF42 2222"
+ $"4FF0 000F 4221 1111 224F 000F FF11 1111"
+ $"1FFF 00FF 24FF FFFF F42F 0F5F 2222 2222"
+ $"222F F52F 2222 2222 222F F40F 2222 2222"
+ $"222F F40F 4FF2 2224 FF2F F52F F2F2 2F2F"
+ $"2F2F 0F5F F2F2 535F 2F2F 00FF 4FF2 F3F4"
+ $"FF2F 000F 2222 F2F2 222F 000F 4222 2222"
+ $"224F 0000 F422 2222 24F0 0000 0FFF FFFF"
+ $"FF00 0000 0000 0000 0006 0000 FFFF FFFF"
+ $"FFFF 0001 CCCC 9999 6666 0002 CCCC CCCC"
+ $"FFFF 0003 3333 3333 6666 0004 9999 9999"
+ $"FFFF 0005 6666 6666 CCCC 000F 0000 0000"
+ $"0000"
+};
+
+data 'crsr' (3027, "gobbler") {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 0000 0078 0070 4036 4FB0 7FF0"
+ $"7E30 7C30 3038 00F0 0FE0 0400 0400 0400"
+ $"0F00 0000 00FC 00FC E0FF FFFF FFFF FFF8"
+ $"FFF8 FFF8 FFFC 7FFC 3FF8 1FF0 0E00 1F80"
+ $"1F80 1F80 0003 000E 0000 0000 0000 0000"
+ $"0000 0000 8008 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0004 0001 0004 0000 0000 0000 0112 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0222"
+ $"2000 0000 0000 0111 0000 0300 0000 0011"
+ $"0220 0100 1616 1011 0000 0361 6111 1111"
+ $"0000 0111 1114 4415 0000 0311 1144 4451"
+ $"0000 0011 4444 4415 1000 0004 4444 5151"
+ $"0000 0000 1515 1510 0000 0000 0200 0000"
+ $"0000 0000 0300 0000 0000 0000 0200 0000"
+ $"0000 0000 2323 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0006 0000 FFFF FFFF"
+ $"FFFF 0001 CCCC 9999 6666 0002 DDDD 0000"
+ $"0000 0003 FFFF 6666 3333 0004 CCCC CCCC"
+ $"CCCC 0005 8888 8888 8888 0006 FFFF CCCC"
+ $"9999"
+};
+
+data 'crsr' (3028, "gumby") {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 3F00 10C0 C820 EAA0 C820 CBA0"
+ $"F838 383E 0826 0826 092E 0926 0920 1110"
+ $"2108 3EF8 3F00 1FC0 CFE0 EFE0 CFE0 CFE0"
+ $"FFF8 3FFE 0FE6 0FE6 0FEE 0FE6 0FE0 1FF0"
+ $"3FF8 3EF8 0000 0002 0000 0000 0000 0000"
+ $"0000 0000 8008 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0004 0001 0004 0000 0000 0000 0112 0000"
+ $"0000 00FF FFFF 0000 0000 000F 1212 FF00"
+ $"0000 FF00 F131 31F0 0000 FFF0 F3F3 F3F0"
+ $"0000 FF00 F131 31F0 0000 FF00 F2FF F2F0"
+ $"0000 4FFF F121 21FF F000 00FF F212 12FF"
+ $"FF40 0000 F121 21F0 0FF0 0000 F212 12F0"
+ $"0FF0 0000 F12F 21F0 FFF0 0000 F21F 12F0"
+ $"0FF0 0000 F12F 21F0 0000 000F 121F 121F"
+ $"0000 00F1 212F 2121 F000 00FF FFF0 FFFF"
+ $"F000 0000 0000 0000 0005 0000 FFFF FFFF"
+ $"FFFF 0001 0000 BBBB 0000 0002 CCCC CCCC"
+ $"CCCC 0003 AAAA AAAA AAAA 0004 4444 4444"
+ $"4444 000F 0000 0000 0000"
+};
+
+data 'crsr' (3031, "heart") {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 0000 3EF8 638C C106 8002 8002"
+ $"8002 8002 C006 600C 3018 1830 0C60 06C0"
+ $"0380 0000 0000 3EF8 7FFC FFFE FFFE FFFE"
+ $"FFFE FFFE FFFE 7FFC 3FF8 1FF0 0FE0 07C0"
+ $"0380 0000 0003 0007 0000 0000 0000 0000"
+ $"0000 0000 8004 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0002 0001 0002 0000 0000 0000 00D2 0000"
+ $"0000 0000 0000 0FFC FFC0 3AAB AA70 E99B"
+ $"999C E665 A65C E999 999C E666 665C E999"
+ $"999C D666 665C 3599 9970 0D66 65C0 0359"
+ $"9700 00D6 5C00 0035 7000 000F C000 0000"
+ $"0000 0000 0000 0000 0003 0000 FFFF FFFF"
+ $"FFFF 0001 DDDD 0000 0000 0002 FFFF 6666"
+ $"CCCC 0003 0000 0000 0000"
+};
+
+data 'crsr' (3042, "mouse", purgeable) {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 BE00 0100 0180 0FF0 1008 17E8"
+ $"1428 1428 17E8 1008 1008 1008 1008 1008"
+ $"1008 0FF0 FE00 0100 0180 0FF0 1FF8 1FF8"
+ $"1FF8 1FF8 1FF8 1FF8 1FF8 1FF8 1FF8 1FF8"
+ $"1FF8 0FF0 0001 0007 0000 0000 0000 0000"
+ $"0000 0000 8008 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0004 0001 0004 0000 0000 0000 0112 0000"
+ $"0000 1379 4AF0 0000 0000 0000 000F 0000"
+ $"0000 0000 000F F000 0000 0000 FFFF FFFF"
+ $"0000 000F 2111 1112 F000 000F 3655 5563"
+ $"F000 000F 3513 1351 F000 000F 3533 3351"
+ $"F000 000F 3655 5561 F000 000F 3311 1111"
+ $"F000 000F 3333 3333 F000 000F 3333 3333"
+ $"F000 000F 2222 2222 F000 000F 8888 8888"
+ $"F000 000F 7888 8887 F000 0000 FFFF FFFF"
+ $"0000 0000 0000 0000 000B 0000 FFFF FFFF"
+ $"FFFF 0001 EEEE EEEE EEEE 0002 CCCC CCCC"
+ $"CCCC 0003 DDDD DDDD DDDD 0004 4444 4444"
+ $"4444 0005 2222 2222 2222 0006 5555 5555"
+ $"5555 0007 AAAA AAAA AAAA 0008 BBBB BBBB"
+ $"BBBB 0009 7777 7777 7777 000A 1111 1111"
+ $"1111 000F 0000 0000 0000"
+};
+
+data 'crsr' (3043, "pencil", purgeable) {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 0000 00F0 0088 0108 0190 0270"
+ $"0220 0440 0440 0880 0880 1100 1E00 1C00"
+ $"1800 1000 0000 00F0 00F8 01F8 01F0 03F0"
+ $"03E0 07C0 07C0 0F80 0F80 1F00 1E00 1C00"
+ $"1800 1000 000F 0003 0000 0000 0000 0000"
+ $"0000 0000 8008 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0004 0001 0004 0000 0000 0000 0112 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 FFFF"
+ $"0000 0000 0000 F404 F000 0000 000F 4042"
+ $"F000 0000 000F F42F 0000 0000 00F5 3FFF"
+ $"0000 0000 00F3 52F0 0000 0000 0F35 1F00"
+ $"0000 0000 0F53 2F00 0000 0000 F532 F000"
+ $"0000 0000 F312 F000 0000 000F 352F 0000"
+ $"0000 000F FFF0 0000 0000 000F FF00 0000"
+ $"0000 000F F000 0000 0000 000F 0000 0000"
+ $"0000 0000 0000 0000 0006 0000 FFFF FFFF"
+ $"FFFF 0001 CCCC CCCC CCCC 0002 8888 8888"
+ $"8888 0003 FFFF FFFF 0000 0004 DDDD 0000"
+ $"0000 0005 FFFF 6666 3333 000F 0000 0000"
+ $"0000"
+};
+
+data 'crsr' (3059, "shuttle") {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 0020 0070 00F8 01DE 05DE 09DE"
+ $"11DE 11DE 11DE 11DE 31DE 71DE FDDE 1888"
+ $"0078 0030 0020 0070 00F8 01FE 07FE 0FFE"
+ $"1FFE 1FFE 1FFE 1FFE 3FFE 7FFE FFFE 18F8"
+ $"0078 0030 0000 000A 0000 0000 0000 0000"
+ $"0000 0000 8008 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0004 0001 0004 0000 0000 0000 0112 0000"
+ $"0000 0000 0000 00F0 0000 0000 0000 0F3F"
+ $"0000 0000 0000 F343 F000 0000 000F 3404"
+ $"3FF0 0000 0F4F 3404 3FF0 0000 F55F 3404"
+ $"3FF0 000F 505F 3404 3FF0 000F 005F 3404"
+ $"3FF0 000F 005F 3404 3FF0 000F 005F 3404"
+ $"3FF0 00F3 005F 3404 3FF0 0F33 505F 3404"
+ $"3FF0 FFF3 3F4F 3404 3FF0 000F F000 1222"
+ $"1000 0000 0000 0111 1000 0000 0000 0011"
+ $"0000 0000 0000 0000 0006 0000 FFFF FFFF"
+ $"FFFF 0001 FFFF 6666 3333 0002 DDDD 0000"
+ $"0000 0003 4444 4444 4444 0004 8888 8888"
+ $"8888 0005 DDDD DDDD DDDD 000F 0000 0000"
+ $"0000"
+};
+
+data 'crsr' (3062, "spraycan") {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 0018 0040 0D18 1E40 1A18 3F00"
+ $"2100 3900 2900 3900 2900 3900 3900 2100"
+ $"2100 3F00 0000 0000 0C00 1E00 1E00 3F00"
+ $"3F00 3F00 3F00 3F00 3F00 3F00 3F00 3F00"
+ $"3F00 3F00 0002 0007 0000 0000 0000 0000"
+ $"0000 0000 8008 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0004 0001 0004 0000 0000 0000 0112 0000"
+ $"0000 0000 0000 0005 2000 0000 0000 0460"
+ $"0000 0000 FF1F 6005 2000 000F 33F0 0460"
+ $"0000 000F 10F0 0005 2000 00FF FFFF 0000"
+ $"0000 00F8 170F 0000 0000 00F5 F70F 0000"
+ $"0000 00FA F70F 0000 0000 00F9 F70F 0000"
+ $"0000 00FA F70F 0000 0000 00F9 F70F 0000"
+ $"0000 00F5 F70F 0000 0000 00F8 170F 0000"
+ $"0000 00F8 170F 0000 0000 00FF FFFF 0000"
+ $"0000 0000 0000 0000 000B 0000 FFFF FFFF"
+ $"FFFF 0001 AAAA AAAA AAAA 0002 7777 7777"
+ $"7777 0003 5555 5555 5555 0004 2222 2222"
+ $"2222 0005 4444 4444 4444 0006 BBBB BBBB"
+ $"BBBB 0007 DDDD DDDD DDDD 0008 EEEE EEEE"
+ $"EEEE 0009 6666 6666 CCCC 000A CCCC CCCC"
+ $"FFFF 000F 0000 0000 0000"
+};
+
+data 'crsr' (3063, "star") {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 0100 0280 0280 0280 0440 0440"
+ $"0440 3938 C006 3838 0920 1290 2448 2828"
+ $"3018 2008 0100 0380 0380 0380 07C0 07C0"
+ $"07C0 3FF8 FFFE 3FF8 0FE0 1EF0 3C78 3838"
+ $"3018 2008 0007 0007 0000 0000 0000 0000"
+ $"0000 0000 8004 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0002 0001 0002 0000 0000 0000 00D2 0000"
+ $"0000 0003 0000 000D C000 000D C000 000D"
+ $"C000 0035 7000 0035 7000 0035 7000 0FD7"
+ $"5FC0 F555 557C 0FD5 5FC0 00D7 5C00 035C"
+ $"D700 0D70 35C0 0DC0 0DC0 0F00 03C0 0C00"
+ $"00C0 0000 0000 0000 0002 0000 FFFF FFFF"
+ $"FFFF 0001 FFFF FFFF 0000 0003 0000 0000"
+ $"0000"
+};
+
+data 'crsr' (3071, "trek") {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 0100 0000 0380 07C0 0FE0 0EE0"
+ $"0FE0 07C0 0380 0100 0BA0 0D60 0920 0820"
+ $"0820 0000 0000 0380 07C0 0FE0 1FF0 1FF0"
+ $"1FF0 0FE0 07C0 0BA0 1FF0 1FF0 1FF0 1D70"
+ $"1C70 0820 0000 0007 0000 0000 0000 0000"
+ $"0000 0000 8008 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0004 0001 0004 0000 0000 0000 0112 0000"
+ $"0000 0000 0005 0000 0000 0000 0005 0000"
+ $"0000 0000 00FF F000 0000 0000 0F31 3F00"
+ $"0000 0000 F322 23F0 0000 0000 F110 11F0"
+ $"0000 0000 F311 13F0 0000 0000 0F31 3F00"
+ $"0000 0000 00FF F000 0000 0000 000F 0000"
+ $"0000 0000 F0FF F0F0 0000 0000 FF0F 0FF0"
+ $"0000 0000 400F 0040 0000 0000 4000 0040"
+ $"0000 0000 4000 0040 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0006 0000 FFFF FFFF"
+ $"FFFF 0001 EEEE EEEE EEEE 0002 9999 9999"
+ $"FFFF 0003 DDDD DDDD DDDD 0004 3333 3333"
+ $"6666 0005 DDDD 0000 0000 000F 0000 0000"
+ $"0000"
+};
+
+data 'crsr' (3075, "watch", purgeable) {
+ $"8001 0000 0060 0000 0092 0000 0000 0000"
+ $"0000 0000 07E0 07E0 07E0 07E0 0810 1088"
+ $"1088 108C 138C 1008 1008 0810 07E0 07E0"
+ $"07E0 07E0 07E0 07E0 07E0 07E0 0FF0 1FF8"
+ $"1FF8 1FF8 1FF8 1FF8 1FF8 0FF0 07E0 07E0"
+ $"07E0 07E0 0008 000D 0000 0000 0000 0000"
+ $"0000 0000 8008 0000 0000 0010 0010 0000"
+ $"0000 0000 0000 0048 0000 0048 0000 0000"
+ $"0004 0001 0004 0000 0000 0000 0112 0000"
+ $"0000 0000 0FFF FFF0 0000 0000 0FFF FFF0"
+ $"0000 0000 0FFF FFF0 0000 0000 0FFF FFF0"
+ $"0000 0000 F020 202F 0000 000F 0222 F221"
+ $"F000 000F 2222 F123 F000 000F 0222 F121"
+ $"FF00 000F 22FF F123 FF00 000F 0222 2221"
+ $"F000 000F 2222 2213 F000 0000 F131 313F"
+ $"0000 0000 0FFF FFF0 0000 0000 0FFF FFF0"
+ $"0000 0000 0FFF FFF0 0000 0000 0FFF FFF0"
+ $"0000 0000 0000 0000 0004 0000 FFFF FFFF"
+ $"FFFF 0001 CCCC CCCC CCCC 0002 EEEE EEEE"
+ $"EEEE 0003 BBBB BBBB BBBB 000F 0000 0000"
+ $"0000"
+};
+
diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c
new file mode 100644
index 0000000..a92fbcf
--- /dev/null
+++ b/macosx/tkMacOSXXStubs.c
@@ -0,0 +1,862 @@
+/*
+ * tkMacOSXXStubs.c --
+ *
+ * This file contains most of the X calls called by Tk. Many of
+ * these calls are just stubs and either don't make sense on the
+ * Macintosh or thier implamentation just doesn't do anything. Other
+ * calls will eventually be moved into other files.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXXStubs.c,v 1.2 2002/08/31 06:12:31 das Exp $
+ */
+
+#include "tkInt.h"
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <sys/types.h>
+
+#include <X11/Xatom.h>
+
+#include <Carbon/Carbon.h>
+#include "tkMacOSXInt.h"
+#include "tkPort.h"
+#include "tkMacOSXEvent.h"
+
+/*
+ * Because this file is still under major development Debugger statements are
+ * used through out this file. The define TCL_DEBUG will decide whether
+ * the debugger statements actually call the debugger or not.
+ */
+
+#ifndef TCL_DEBUG
+# define Debugger()
+#endif
+
+#define ROOT_ID 10
+
+/*
+ * Declarations of static variables used in this file.
+ */
+
+static TkDisplay *gMacDisplay = NULL; /* Macintosh display. */
+static char *macScreenName = ":0"; /* Default name of macintosh display. */
+
+/*
+ * Forward declarations of procedures used in this file.
+ */
+
+static XID MacXIdAlloc _ANSI_ARGS_((Display *display));
+static int DefaultErrorHandler _ANSI_ARGS_((Display* display,
+ XErrorEvent* err_evt));
+
+/*
+ * Other declarations
+ */
+
+int TkMacOSXXDestroyImage _ANSI_ARGS_((XImage *image));
+unsigned long TkMacOSXXGetPixel _ANSI_ARGS_((XImage *image, int x, int y));
+int TkMacOSXXPutPixel _ANSI_ARGS_((XImage *image, int x, int y,
+ unsigned long pixel));
+XImage *TkMacOSXXSubImage _ANSI_ARGS_((XImage *image, int x, int y,
+ unsigned int width, unsigned int height));
+int TkMacOSXXAddPixel _ANSI_ARGS_((XImage *image, long value));
+int _XInitImageFuncPtrs _ANSI_ARGS_((XImage *image));
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpOpenDisplay --
+ *
+ * Create the Display structure and fill it with device
+ * specific information.
+ *
+ * Results:
+ * Returns a Display structure on success or NULL on failure.
+ *
+ * Side effects:
+ * Allocates a new Display structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkDisplay *
+TkpOpenDisplay(
+ CONST char *display_name)
+{
+ Display *display;
+ Screen *screen;
+ GDHandle graphicsDevice;
+ int fd = 0;
+ if (gMacDisplay != NULL) {
+ if (strcmp(gMacDisplay->display->display_name, display_name) == 0) {
+ return gMacDisplay;
+ } else {
+ return NULL;
+ }
+ }
+ InitCursor();
+
+ graphicsDevice = GetMainDevice();
+ display = (Display *) ckalloc(sizeof(Display));
+ display->resource_alloc = MacXIdAlloc;
+ screen = (Screen *) ckalloc(sizeof(Screen) * 2);
+ display->default_screen = 0;
+ display->request = 0;
+ display->nscreens = 1;
+ display->screens = screen;
+ display->display_name = macScreenName;
+ display->qlen = 0;
+ display->fd = fd;
+
+ screen->root = ROOT_ID;
+ screen->display = display;
+ screen->root_depth = (*(*graphicsDevice)->gdPMap)->cmpSize *
+ (*(*graphicsDevice)->gdPMap)->cmpCount;
+ screen->height = (*graphicsDevice)->gdRect.bottom -
+ (*graphicsDevice)->gdRect.top;
+ screen->width = (*graphicsDevice)->gdRect.right -
+ (*graphicsDevice)->gdRect.left;
+
+ screen->mwidth = (screen->width * 254 + 360) / 720;
+ screen->mheight = (screen->height * 254 + 360) / 720;
+ screen->black_pixel = 0x00000000;
+ screen->white_pixel = 0x00FFFFFF;
+ screen->root_visual = (Visual *) ckalloc(sizeof(Visual));
+ screen->root_visual->visualid = 0;
+ screen->root_visual->class = TrueColor;
+ screen->root_visual->red_mask = 0x00FF0000;
+ screen->root_visual->green_mask = 0x0000FF00;
+ screen->root_visual->blue_mask = 0x000000FF;
+ screen->root_visual->bits_per_rgb = 24;
+ screen->root_visual->map_entries = 2 ^ 8;
+
+ gMacDisplay = (TkDisplay *) ckalloc(sizeof(TkDisplay));
+
+ /*
+ * This is the quickest way to make sure that all the *Init
+ * flags get properly initialized
+ */
+
+ bzero (gMacDisplay, sizeof (TkDisplay));
+ gMacDisplay->display = display;
+ return gMacDisplay;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpCloseDisplay --
+ *
+ * Deallocates a display structure created by TkpOpenDisplay.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Frees memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpCloseDisplay(
+ TkDisplay *displayPtr)
+{
+ Display *display = displayPtr->display;
+ if (gMacDisplay != displayPtr) {
+ panic("TkpCloseDisplay: tried to call TkpCloseDisplay on bad display");
+ }
+
+ /*
+ * Make sure that the local scrap is transfered to the global
+ * scrap if needed.
+ */
+
+ TkSuspendClipboard();
+
+ gMacDisplay = NULL;
+ if (display->screens != (Screen *) NULL) {
+ if (display->screens->root_visual != (Visual *) NULL) {
+ ckfree((char *) display->screens->root_visual);
+ }
+ ckfree((char *) display->screens);
+ }
+ ckfree((char *) display);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MacXIdAlloc --
+ *
+ * This procedure is invoked by Xlib as the resource allocator
+ * for a display.
+ *
+ * Results:
+ * The return value is an X resource identifier that isn't currently
+ * in use.
+ *
+ * Side effects:
+ * The identifier is removed from the stack of free identifiers,
+ * if it was previously on the stack.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static XID
+MacXIdAlloc(
+ Display *display) /* Display for which to allocate. */
+{
+ static long int cur_id = 100;
+ /*
+ * Some special XIds are reserved
+ * - this is why we start at 100
+ */
+
+ return ++cur_id;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpWindowWasRecentlyDeleted --
+ *
+ * Tries to determine whether the given window was recently deleted.
+ * Called from the generic code error handler to attempt to deal with
+ * async BadWindow errors under some circumstances.
+ *
+ * Results:
+ * Always 0, we do not keep this information on the Mac, so we do not
+ * know whether the window was destroyed.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpWindowWasRecentlyDeleted(
+ Window win,
+ TkDisplay *dispPtr)
+{
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DefaultErrorHandler --
+ *
+ * This procedure is the default X error handler. Tk uses it's
+ * own error handler so this call should never be called.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * This function will call panic and exit.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DefaultErrorHandler(
+ Display* display,
+ XErrorEvent* err_evt)
+{
+ /*
+ * This call should never be called. Tk replaces
+ * it with its own error handler.
+ */
+ panic("Warning hit bogus error handler!");
+ return 0;
+}
+
+
+char *
+XGetAtomName(
+ Display * display,
+ Atom atom)
+{
+ display->request++;
+ return NULL;
+}
+
+int
+_XInitImageFuncPtrs(XImage *image)
+{
+ return 0;
+}
+
+XErrorHandler
+XSetErrorHandler(
+ XErrorHandler handler)
+{
+ return DefaultErrorHandler;
+}
+
+Window
+XRootWindow(Display *display, int screen_number)
+{
+ display->request++;
+ return ROOT_ID;
+}
+
+XImage *
+XGetImage(display, d, x, y, width, height, plane_mask, format)
+ Display *display;
+ Drawable d;
+ int x;
+ int y;
+ unsigned int width;
+ unsigned int height;
+ unsigned long plane_mask;
+ int format;
+{
+ XImage * imagePtr;
+ Visual * visual = NULL;
+ int depth = 0;
+ int offset = 0;
+ char * data = NULL;
+ int bitmap_pad = 0;
+ int bytes_per_line = 0;
+ CGrafPtr grafPtr;
+
+ imagePtr = XCreateImage(display,visual,depth,format, offset, data,
+ width, height, bitmap_pad, bytes_per_line );
+ grafPtr = TkMacOSXGetDrawablePort(d);
+ imagePtr->data = (char *) grafPtr;
+ return imagePtr;
+}
+
+int
+XGetGeometry(display, d, root_return, x_return, y_return, width_return,
+ height_return, border_width_return, depth_return)
+ Display* display;
+ Drawable d;
+ Window* root_return;
+ int* x_return;
+ int* y_return;
+ unsigned int* width_return;
+ unsigned int* height_return;
+ unsigned int* border_width_return;
+ unsigned int* depth_return;
+{
+ /* Used in tkCanvPs.c & wm code */
+ Debugger();
+ return 0;
+}
+
+void
+XChangeProperty(
+ Display* display,
+ Window w,
+ Atom property,
+ Atom type,
+ int format,
+ int mode,
+ _Xconst unsigned char* data,
+ int nelements)
+{
+ Debugger();
+}
+
+void
+XSelectInput(
+ Display* display,
+ Window w,
+ long event_mask)
+{
+ Debugger();
+}
+
+void
+XBell(
+ Display* display,
+ int percent)
+{
+ SysBeep(percent);
+}
+
+void
+XSetWMNormalHints(
+ Display* display,
+ Window w,
+ XSizeHints* hints)
+{
+ /*
+ * Do nothing. Shouldn't even be called.
+ */
+}
+
+XSizeHints *
+XAllocSizeHints()
+{
+ /*
+ * Always return NULL. Tk code checks to see if NULL
+ * is returned & does nothing if it is.
+ */
+
+ return NULL;
+}
+
+XImage *
+XCreateImage(
+ Display* display,
+ Visual* visual,
+ unsigned int depth,
+ int format,
+ int offset,
+ char* data,
+ unsigned int width,
+ unsigned int height,
+ int bitmap_pad,
+ int bytes_per_line)
+{
+ XImage *ximage;
+
+ display->request++;
+ ximage = (XImage *) ckalloc(sizeof(XImage));
+
+ ximage->height = height;
+ ximage->width = width;
+ ximage->depth = depth;
+ ximage->xoffset = offset;
+ ximage->format = format;
+ ximage->data = data;
+ ximage->bitmap_pad = bitmap_pad;
+ if (bytes_per_line == 0) {
+ ximage->bytes_per_line = width * 4; /* assuming 32 bits per pixel */
+ } else {
+ ximage->bytes_per_line = bytes_per_line;
+ }
+
+ if (format == ZPixmap) {
+ ximage->bits_per_pixel = 32;
+ ximage->bitmap_unit = 32;
+ } else {
+ ximage->bits_per_pixel = 1;
+ ximage->bitmap_unit = 8;
+ }
+ ximage->byte_order = LSBFirst;
+ ximage->bitmap_bit_order = LSBFirst;
+ ximage->red_mask = 0x00FF0000;
+ ximage->green_mask = 0x0000FF00;
+ ximage->blue_mask = 0x000000FF;
+
+ ximage->f.destroy_image = TkMacOSXXDestroyImage;
+ ximage->f.get_pixel = TkMacOSXXGetPixel;
+ ximage->f.put_pixel = TkMacOSXXPutPixel;
+ ximage->f.sub_image = TkMacOSXXSubImage;
+ ximage->f.add_pixel = TkMacOSXXAddPixel;
+
+ return ximage;
+}
+
+GContext
+XGContextFromGC(
+ GC gc)
+{
+ /* TODO - currently a no-op */
+ return 0;
+}
+
+Status
+XSendEvent(
+ Display* display,
+ Window w,
+ Bool propagate,
+ long event_mask,
+ XEvent* event_send)
+{
+ Debugger();
+ return 0;
+}
+
+void
+XClearWindow(
+ Display* display,
+ Window w)
+{
+}
+
+/*
+void
+XDrawPoint(
+ Display* display,
+ Drawable d,
+ GC gc,
+ int x,
+ int y)
+{
+}
+
+void
+XDrawPoints(
+ Display* display,
+ Drawable d,
+ GC gc,
+ XPoint* points,
+ int npoints,
+ int mode)
+{
+}
+*/
+
+void
+XWarpPointer(
+ Display* display,
+ Window src_w,
+ Window dest_w,
+ int src_x,
+ int src_y,
+ unsigned int src_width,
+ unsigned int src_height,
+ int dest_x,
+ int dest_y)
+{
+}
+
+void
+XQueryColor(
+ Display* display,
+ Colormap colormap,
+ XColor* def_in_out)
+{
+}
+
+void
+XQueryColors(
+ Display* display,
+ Colormap colormap,
+ XColor* defs_in_out,
+ int ncolors)
+{
+}
+
+int
+XQueryTree(display, w, root_return, parent_return, children_return,
+ nchildren_return)
+ Display* display;
+ Window w;
+ Window* root_return;
+ Window* parent_return;
+ Window** children_return;
+ unsigned int* nchildren_return;
+{
+ return 0;
+}
+
+
+int
+XGetWindowProperty(
+ Display *display,
+ Window w,
+ Atom property,
+ long long_offset,
+ long long_length,
+ Bool delete,
+ Atom req_type,
+ Atom *actual_type_return,
+ int *actual_format_return,
+ unsigned long *nitems_return,
+ unsigned long *bytes_after_return,
+ unsigned char ** prop_return)
+{
+ display->request++;
+ *actual_type_return = None;
+ *actual_format_return = *bytes_after_return = 0;
+ *nitems_return = 0;
+ return 0;
+}
+
+void
+XRefreshKeyboardMapping( XMappingEvent* x)
+{
+ /* used by tkXEvent.c */
+ Debugger();
+}
+
+void
+XSetIconName(
+ Display* display,
+ Window w,
+ const char *icon_name)
+{
+ /*
+ * This is a no-op, no icon name for Macs.
+ */
+ display->request++;
+}
+
+void
+XForceScreenSaver(
+ Display* display,
+ int mode)
+{
+ /*
+ * This function is just a no-op. It is defined to
+ * reset the screen saver. However, there is no real
+ * way to do this on a Mac. Let me know if there is!
+ */
+ display->request++;
+}
+
+void
+Tk_FreeXId (
+ Display *display,
+ XID xid)
+{
+ /* no-op function needed for stubs implementation. */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkGetServerInfo --
+ *
+ * Given a window, this procedure returns information about
+ * the window server for that window. This procedure provides
+ * the guts of the "winfo server" command.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkGetServerInfo(
+ Tcl_Interp *interp, /* The server information is returned in
+ * this interpreter's result. */
+ Tk_Window tkwin) /* Token for window; this selects a
+ * particular display and server. */
+{
+ char buffer[8 + TCL_INTEGER_SPACE * 2];
+ char buffer2[TCL_INTEGER_SPACE];
+
+ sprintf(buffer, "X%dR%d ", ProtocolVersion(Tk_Display(tkwin)),
+ ProtocolRevision(Tk_Display(tkwin)));
+ sprintf(buffer2, " %d", VendorRelease(Tk_Display(tkwin)));
+ Tcl_AppendResult(interp, buffer, ServerVendor(Tk_Display(tkwin)),
+ buffer2, (char *) NULL);
+}
+/*
+ * Image stuff
+ */
+
+int
+TkMacOSXXDestroyImage(
+ XImage *image)
+{
+ Debugger();
+ return 0;
+}
+
+unsigned long
+TkMacOSXXGetPixel(
+ XImage *image,
+ int x,
+ int y)
+{
+ CGrafPtr grafPtr;
+ RGBColor cPix;
+ unsigned long r, g, b, c;
+ grafPtr = (CGrafPtr)image->data;
+ SetPort(grafPtr);
+ GetCPixel(x,y,&cPix);
+ r = cPix . red;
+ g = cPix . green;
+ b = cPix . blue;
+ c = (r<<16)|(g<<8)|(b);
+ return c;
+}
+
+int
+TkMacOSXXPutPixel(
+ XImage *image,
+ int x,
+ int y,
+ unsigned long pixel)
+{
+ CGrafPtr grafPtr;
+ RGBColor cPix;
+ unsigned long r, g, b;
+ grafPtr = (CGrafPtr)image->data;
+ SetPort(grafPtr);
+ r = (pixel & image->red_mask)>>16;
+ g = (pixel & image->green_mask)>>8;
+ b = (pixel & image->blue_mask);
+ cPix . red = r;
+ cPix . green = g;
+ cPix . blue = b;
+ SetCPixel(x,y,&cPix);
+ return 0;
+}
+
+XImage *
+TkMacOSXXSubImage(
+ XImage *image,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height)
+{
+ Debugger();
+ return NULL;
+}
+
+int
+TkMacOSXXAddPixel(
+ XImage *image,
+ long value)
+{
+ Debugger();
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XChangeWindowAttributes, XSetWindowBackground,
+ * XSetWindowBackgroundPixmap, XSetWindowBorder, XSetWindowBorderPixmap,
+ * XSetWindowBorderWidth, XSetWindowColormap
+ *
+ * These functions are all no-ops. They all have equivilent
+ * Tk calls that should always be used instead.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XChangeWindowAttributes(
+ Display* display,
+ Window w,
+ unsigned long value_mask,
+ XSetWindowAttributes* attributes)
+{
+}
+
+void
+XSetWindowBackground(
+ Display *display,
+ Window window,
+ unsigned long value)
+{
+}
+
+void
+XSetWindowBackgroundPixmap(
+ Display* display,
+ Window w,
+ Pixmap background_pixmap)
+{
+}
+
+void
+XSetWindowBorder(
+ Display* display,
+ Window w,
+ unsigned long border_pixel)
+{
+}
+
+void
+XSetWindowBorderPixmap(
+ Display* display,
+ Window w,
+ Pixmap border_pixmap)
+{
+}
+
+void
+XSetWindowBorderWidth(
+ Display* display,
+ Window w,
+ unsigned int width)
+{
+}
+
+void
+XSetWindowColormap(
+ Display* display,
+ Window w,
+ Colormap colormap)
+{
+ Debugger();
+}
+
+Status
+XStringListToTextProperty(
+ char** list,
+ int count,
+ XTextProperty* text_prop_return)
+{
+ Debugger();
+ return (Status) 0;
+}
+void
+XSetWMClientMachine(
+ Display* display,
+ Window w,
+ XTextProperty* text_prop)
+{
+ Debugger();
+}
+XIC
+XCreateIC(
+ void)
+{
+ Debugger();
+ return (XIC) 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkGetDefaultScreenName --
+ *
+ * Returns the name of the screen that Tk should use during
+ * initialization.
+ *
+ * Results:
+ * Returns a statically allocated string.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+CONST char *
+TkGetDefaultScreenName(
+ Tcl_Interp *interp, /* Not used. */
+ CONST char *screenName) /* If NULL, use default string. */
+{
+#if 0
+ if ((screenName == NULL) || (screenName[0] == '\0')) {
+ screenName = macScreenName;
+ }
+ return screenName;
+#endif
+ return macScreenName;
+}