summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog39
-rw-r--r--doc/wm.n11
-rw-r--r--generic/tkMain.c11
-rw-r--r--generic/tkRectOval.c9
-rw-r--r--macosx/Makefile4
-rw-r--r--macosx/README22
-rw-r--r--macosx/Wish.pbproj/project.pbxproj60
-rw-r--r--macosx/tkMacOSXAppInit.c243
-rw-r--r--macosx/tkMacOSXDefault.h9
-rw-r--r--macosx/tkMacOSXDraw.c751
-rw-r--r--macosx/tkMacOSXInit.c213
-rw-r--r--macosx/tkMacOSXInt.h9
-rw-r--r--macosx/tkMacOSXMenu.c15
-rw-r--r--macosx/tkMacOSXMouseEvent.c28
-rw-r--r--macosx/tkMacOSXSubwindows.c4
-rw-r--r--macosx/tkMacOSXWm.c258
16 files changed, 1060 insertions, 626 deletions
diff --git a/ChangeLog b/ChangeLog
index c9dc674..91457fa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+2004-11-11 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tkMain.c:
+ * macosx/tkMacOSXAppInit.c (removed):
+ * macosx/Wish.pbproj/project.pbxproj:
+ * macosx/tkMacOSXInit.c:
+ * macosx/tkMacOSXInt.h: changes to make TkAqua dynamically loadable,
+ enabling [package require Tk] from tclsh. Startup code from
+ tkMacOSXAppInit.c moved into tkMacOSXInit.c, added code that
+ notifies the window server that an unbundled executable is a full
+ GUI application after loading Tk. [Patch 1035348]
+
+ * doc/wm.n: documented [wm attributes] on Mac OS X. [Bug 606665]
+ * macosx/tkMacOSXWm.c: implemented TIP 222 [wm attributes -alpha] on
+ Mac OS X. [Patch 892194]
+ WmIconbitmapCmd: adopted FSRef changes from [wm atttrs -titlepath].
+
+ * macosx/tkMacOSXSubwindows.c: synced spacing/formatting with
+ core-8-4-branch.
+
+ * generic/tkRectOval.c:
+ * macosx/README:
+ * macosx/tkMacOSXDefault.h:
+ * macosx/tkMacOSXDraw.c:
+ * macosx/tkMacOSXInit.c:
+ * macosx/tkMacOSXInt.h:
+ * macosx/tkMacOSXMenu.c:
+ * macosx/tkMacOSXWm.c: forward port from core-8-4-branch of Jim's
+ and my changes for CG drawing and [wm attributes] (corresponds to
+ 8.4 changes dating from 09-18, 07-27, 07-24).
+
+ * macosx/tkMacOSXMouseEvent.c: endianness fixes.
+
+ * macosx/Wish.pbproj/project.pbxproj: corrected path to html help
+ inside framework.
+
+ * macosx/Makefile: prevent parallel make from building several
+ targets at the same time.
+
2004-11-09 Vince Darley <vincentdarley@users.sourceforge.net>
* macosx/tkMacOSXButton.c: fix to dynamic reconfiguration of
diff --git a/doc/wm.n b/doc/wm.n
index 0dd461a..b5867e3 100644
--- a/doc/wm.n
+++ b/doc/wm.n
@@ -5,7 +5,7 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-'\" RCS: @(#) $Id: wm.n,v 1.20 2004/10/28 12:25:53 dkf Exp $
+'\" RCS: @(#) $Id: wm.n,v 1.21 2004/11/11 01:24:31 das Exp $
'\"
.so man.macros
.TH wm n 8.5 Tk "Tk Built-In Commands"
@@ -70,8 +70,13 @@ outside that range will be constrained. This is supported on Windows
\fB1.0\fR.
.VE 8.5
.PP
-On Macintosh, there are currently two attribute values:
-\fB\-modified\fR and \fB\-titlepath\fR.
+On Mac OS X, \fB\-modified\fR gets or sets the modification state of the
+window (determines whether the window close widget contains the modification
+indicator). \fB\-titlepath\fR gets or sets the path of the file referenced as
+the window proxy icon (which can be dragged and dropped in lieu of the file's
+finder icon). \fB\-alpha\fR sets the alpha transparency level of the window,
+it accepts a value from \fB0.0\fR (fully transparent) to \fB1.0\fR (opaque),
+values outside that range will be constrained.
.PP
On Unix, there are currently no special attribute values.
.RE
diff --git a/generic/tkMain.c b/generic/tkMain.c
index d723218..a225b70 100644
--- a/generic/tkMain.c
+++ b/generic/tkMain.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMain.c,v 1.17 2004/03/17 18:15:43 das Exp $
+ * RCS: @(#) $Id: tkMain.c,v 1.18 2004/11/11 01:24:31 das Exp $
*/
#include <ctype.h>
@@ -31,6 +31,9 @@
#ifdef __WIN32__
#include "tkWinInt.h"
#endif
+#ifdef MAC_OSX_TK
+#include "tkMacOSXInt.h"
+#endif
typedef struct ThreadSpecificData {
@@ -125,6 +128,12 @@ Tk_MainEx(argc, argv, appInitProc, interp)
#if defined(__WIN32__)
Tk_InitConsoleChannels(interp);
#endif
+
+#ifdef MAC_OSX_TK
+ if (Tcl_GetStartupScript(NULL) == NULL) {
+ TkMacOSXDefaultStartupScript();
+ }
+#endif
#ifdef TCL_MEM_DEBUG
Tcl_InitMemory(interp);
diff --git a/generic/tkRectOval.c b/generic/tkRectOval.c
index 454b9a5..8d13a60 100644
--- a/generic/tkRectOval.c
+++ b/generic/tkRectOval.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkRectOval.c,v 1.11 2004/01/13 02:06:00 davygrvy Exp $
+ * RCS: @(#) $Id: tkRectOval.c,v 1.12 2004/11/11 01:24:32 das Exp $
*/
#include <stdio.h>
@@ -672,7 +672,14 @@ ComputeRectOvalBbox(canvas, rectOvalPtr)
bloat = 0;
#endif
} else {
+#ifdef MAC_OSX_TK
+ /* Mac OS X CoreGraphics needs correct rounding here
+ * otherwise it will draw outside the bounding box.
+ * Probably correct on other platforms as well? */
+ bloat = (int) (width+1.5)/2;
+#else
bloat = (int) (width+1)/2;
+#endif
}
/*
diff --git a/macosx/Makefile b/macosx/Makefile
index c2fc70a..2f8f482 100644
--- a/macosx/Makefile
+++ b/macosx/Makefile
@@ -3,7 +3,7 @@
# Makefile to build AquaTk on Mac OS X packaged as a Framework
# uses Project Builder command line tool 'pbxbuild'
#
-# RCS: @(#) $Id: Makefile,v 1.14 2004/07/20 11:49:16 das Exp $
+# RCS: @(#) $Id: Makefile,v 1.15 2004/11/11 01:24:32 das Exp $
#
################################################################################
@@ -128,4 +128,6 @@ cleanup-embedded:
embedded-develop embedded-deploy install-embedded-develop install-embedded-deploy \
clean-develop clean-deploy cleanup-embedded
+.NOTPARALLEL:
+
################################################################################
diff --git a/macosx/README b/macosx/README
index 0c7e698..ba58466 100644
--- a/macosx/README
+++ b/macosx/README
@@ -1,7 +1,7 @@
TclTkAqua README
----------------
-RCS: @(#) $Id: README,v 1.9 2003/10/01 14:35:32 das Exp $
+RCS: @(#) $Id: README,v 1.10 2004/11/11 01:24:32 das Exp $
This is the README file for the Mac OS X native versions of Tcl & Tk.
@@ -83,6 +83,26 @@ you expect. (Wish started from the Finder inherits the Finder's environment
variables, which are essentially those set in $HOME/.MacOSX/environment.plist
and not those set by your shell configuration files).
+- As of Tk 8.4.7, AquaTk has a version of the low-level drawing primitives using
+the CoreGraphics routines - the code is primarily due to James Tittle. There
+were numerous problems with the QD version, mostly due to the different drawing
+model of QD & Tk. CG also trivially supports dashed lines, and the various end
+caps & miters. So this is a great improvement.
+
+The old QD code is retained for now, just in case there are any
+compatibility problems. To switch back to the QD drawing, just put:
+
+set tk::mac::useCGDrawing 0
+
+in your script before you do drawing. Also the CG drawing can anti-alias line drawing.
+However, anti-aliased thin lines look washed out, so the threshold for antialiasing
+is set to 3 pixel width lines. You can change this if you want by putting:
+
+set tk::mac::CGAntialiasLimit <limit>
+
+in your script before drawing, in which case only lines thinner that <limit> pixels
+will not be antialiased.
+
- Quickdraw text antialiasing is enabled by default when available (from 10.1.5
onwards). Changing the global boolean variable '::tk::mac::antialiasedtext'
allows to dis/enable antialiasing on the fly from tcl (even for existing text).
diff --git a/macosx/Wish.pbproj/project.pbxproj b/macosx/Wish.pbproj/project.pbxproj
index 7ac813a..c5bfafc 100644
--- a/macosx/Wish.pbproj/project.pbxproj
+++ b/macosx/Wish.pbproj/project.pbxproj
@@ -58,8 +58,7 @@
//F53
//F54
F50D96120196176E01DC9062 = {
- fallbackIsa = PBXFileReference;
- isa = PBXFrameworkReference;
+ isa = PBXFileReference;
lastKnownFileType = wrapper.framework;
name = ApplicationServices.framework;
path = /System/Library/Frameworks/ApplicationServices.framework;
@@ -163,7 +162,7 @@
isa = PBXShellScriptBuildPhase;
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\tln -fs \"Versions/Current/${PRODUCT_NAME}_debug\" ../..\n\tcp -fp \"libtkstub${FRAMEWORK_VERSION}.a\" \"libtkstub${FRAMEWORK_VERSION}g.a\"\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\\` +\"%Y%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\\` +\"%Y%m%d%H%M.%S\"` \"${OBJROOT}/Development.build/${PROJECT_NAME}.build/${TARGET_NAME}.build/Objects-normal/LinkFileList\"\n\tfi\nfi\n\n# fixup Framework structure\ncd \"${TARGET_BUILD_DIR}/${PRODUCT_NAME}.${WRAPPER_EXTENSION}/Versions/${FRAMEWORK_VERSION}\"\nln -fs `ls libtkstub* | sed -e \"s|.*|Versions/${FRAMEWORK_VERSION}/&|\"` ../..\nln -fs \"Versions/Current/tkConfig.sh\" ../..\nranlib libtkstub${FRAMEWORK_VERSION}*.a";
+ 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\tln -fs \"Versions/Current/${PRODUCT_NAME}_debug\" ../..\n\tcp -fp \"libtkstub${FRAMEWORK_VERSION}.a\" \"libtkstub${FRAMEWORK_VERSION}g.a\"\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\\` +\"%Y%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\\` +\"%Y%m%d%H%M.%S\"` \"${OBJROOT}/Development.build/${PROJECT_NAME}.build/${TARGET_NAME}.build/Objects-normal/LinkFileList\"\n\tfi\nfi\n\n# fixup Framework structure\ncd \"${TARGET_BUILD_DIR}/${PRODUCT_NAME}.${WRAPPER_EXTENSION}/Versions/${FRAMEWORK_VERSION}\"\nln -fs `ls libtkstub* | sed -e \"s|.*|Versions/${FRAMEWORK_VERSION}/&|\"` ../..\nln -fs \"Versions/Current/tkConfig.sh\" ../..\nranlib libtkstub${FRAMEWORK_VERSION}*.a\n\n# create pkgIndex\n( echo \"if {[package vcompare [package provide Tcl] ${FRAMEWORK_VERSION}] != 0} { return }\" && \\\n echo \"package ifneeded Tk ${FRAMEWORK_VERSION} [list load [file join \\$dir .. .. Tk] Tk]\" \\\n) > \"Resources/Scripts/pkgIndex.tcl\"";
};
F537552A016C352C01DC9062 = {
buildSettings = {
@@ -202,8 +201,6 @@
sourceTree = "<group>";
};
F537552C016C352C01DC9062 = {
- buildRules = (
- );
buildSettings = {
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
@@ -218,8 +215,6 @@
name = Development;
};
F537552D016C352C01DC9062 = {
- buildRules = (
- );
buildSettings = {
DEBUGGING_SYMBOLS = NO;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
@@ -502,7 +497,6 @@
};
F5375546016C376E01DC9062 = {
children = (
- F5375548016C376E01DC9062,
F5375549016C376E01DC9062,
F537554A016C376E01DC9062,
4C8A204405E0421900C18A82,
@@ -543,9 +537,10 @@
fileEncoding = 5;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.c;
- path = tkMacOSXAppInit.c;
- refType = 4;
- sourceTree = "<group>";
+ name = tkAppInit.c;
+ path = ../unix/tkAppInit.c;
+ refType = 2;
+ sourceTree = SOURCE_ROOT;
};
F5375549016C376E01DC9062 = {
fileEncoding = 5;
@@ -1645,6 +1640,7 @@
};
F53755C9016C389901DC9062 = {
children = (
+ F5375548016C376E01DC9062,
F53755CA016C389901DC9062,
F53755CB016C389901DC9062,
);
@@ -1850,8 +1846,7 @@
};
F53755DE016C38D201DC9062 = {
explicitFileType = wrapper.framework;
- fallbackIsa = PBXFileReference;
- isa = PBXFrameworkReference;
+ isa = PBXFileReference;
path = Tk.framework;
refType = 3;
sourceTree = BUILT_PRODUCTS_DIR;
@@ -1873,7 +1868,7 @@
F9A61D2F04C2C861006F5A0B,
);
buildSettings = {
- DOCDIR = "${INSTALL_PATH}/${PRODUCT_NAME}.${WRAPPER_EXTENSION}/Versions/${FRAMEWORK_VERSION}/Resources/English.lproj/Documentation/Reference";
+ DOCDIR = "${INSTALL_PATH}/${PRODUCT_NAME}.${WRAPPER_EXTENSION}/Versions/${FRAMEWORK_VERSION}/Resources/Documentation/Reference";
DYLIB_COMPATIBILITY_VERSION = 8.5;
DYLIB_CURRENT_VERSION = "$(FRAMEWORK_VERSION)";
DYLIB_INSTALL_PATH = /Library/Frameworks;
@@ -1917,7 +1912,7 @@
<key>CFBundleExecutable</key>
<string>Tk</string>
<key>CFBundleGetInfoString</key>
- <string>Tk Library 8.5, Copyright © 2003 Tcl Core Team.
+ <string>Tk Library 8.5, Copyright © 2004 Tcl Core Team.
MacOS X Port by Jim Ingham &lt;jingham@apple.com&gt; &amp; Ian Reid, Copyright © 2001-2002, Apple Computer, Inc.</string>
<key>CFBundleIconFile</key>
<string></string>
@@ -3056,8 +3051,7 @@ MacOS X Port by Jim Ingham &lt;jingham@apple.com&gt; &amp; Ian Reid, Copyright Â
sourceTree = "<group>";
};
F537567D016C3ADB01DC9062 = {
- fallbackIsa = PBXFileReference;
- isa = PBXFrameworkReference;
+ isa = PBXFileReference;
lastKnownFileType = wrapper.framework;
name = Carbon.framework;
path = /System/Library/Frameworks/Carbon.framework;
@@ -3260,8 +3254,7 @@ MacOS X Port by Jim Ingham &lt;jingham@apple.com&gt; &amp; Ian Reid, Copyright Â
};
F537569F016C4DD401DC9062 = {
explicitFileType = wrapper.application;
- fallbackIsa = PBXFileReference;
- isa = PBXApplicationReference;
+ isa = PBXFileReference;
path = "Wish Shell.app";
refType = 3;
sourceTree = BUILT_PRODUCTS_DIR;
@@ -3360,8 +3353,6 @@ MacOS X Port by Jim Ingham &lt;jingham@apple.com&gt; &amp; Ian Reid, Copyright Â
buildActionMask = 2147483647;
files = (
F53756AC016C4E1D01DC9062,
- F53756AD016C4E1D01DC9062,
- F53756AE016C4E1D01DC9062,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@@ -3432,18 +3423,6 @@ MacOS X Port by Jim Ingham &lt;jingham@apple.com&gt; &amp; Ian Reid, Copyright Â
settings = {
};
};
- F53756AD016C4E1D01DC9062 = {
- fileRef = F5375570016C37A601DC9062;
- isa = PBXBuildFile;
- settings = {
- };
- };
- F53756AE016C4E1D01DC9062 = {
- fileRef = F537553E016C376E01DC9062;
- isa = PBXBuildFile;
- settings = {
- };
- };
F53756B2016C525F01DC9062 = {
isa = PBXTargetDependency;
target = F53755DF016C38D201DC9062;
@@ -3514,8 +3493,7 @@ MacOS X Port by Jim Ingham &lt;jingham@apple.com&gt; &amp; Ian Reid, Copyright Â
};
F548F8CF0313CEF0016F146B = {
explicitFileType = "compiled.mach-o.dylib";
- fallbackIsa = PBXFileReference;
- isa = PBXLibraryReference;
+ isa = PBXFileReference;
path = libtkstub8.5.a;
refType = 3;
sourceTree = BUILT_PRODUCTS_DIR;
@@ -3576,8 +3554,7 @@ MacOS X Port by Jim Ingham &lt;jingham@apple.com&gt; &amp; Ian Reid, Copyright Â
};
};
F5875C7B016FEF1D01DC9062 = {
- fallbackIsa = PBXFileReference;
- isa = PBXFrameworkReference;
+ isa = PBXFileReference;
lastKnownFileType = wrapper.framework;
name = Tcl.framework;
path = ../tcl/Tcl.framework;
@@ -4051,9 +4028,8 @@ MacOS X Port by Jim Ingham &lt;jingham@apple.com&gt; &amp; Ian Reid, Copyright Â
sourceTree = SOURCE_ROOT;
};
F5DF092E016CD3F901DC9062 = {
- fallbackIsa = PBXFileReference;
includeInIndex = 0;
- isa = PBXFolderReference;
+ isa = PBXFileReference;
lastKnownFileType = folder;
name = demos;
path = ../library/demos;
@@ -4085,9 +4061,8 @@ MacOS X Port by Jim Ingham &lt;jingham@apple.com&gt; &amp; Ian Reid, Copyright Â
sourceTree = SOURCE_ROOT;
};
F5DF0932016CD3F901DC9062 = {
- fallbackIsa = PBXFileReference;
includeInIndex = 0;
- isa = PBXFolderReference;
+ isa = PBXFileReference;
lastKnownFileType = folder;
name = images;
path = ../library/images;
@@ -4119,9 +4094,8 @@ MacOS X Port by Jim Ingham &lt;jingham@apple.com&gt; &amp; Ian Reid, Copyright Â
sourceTree = SOURCE_ROOT;
};
F5DF0936016CD3F901DC9062 = {
- fallbackIsa = PBXFileReference;
includeInIndex = 0;
- isa = PBXFolderReference;
+ isa = PBXFileReference;
lastKnownFileType = folder;
name = msgs;
path = ../library/msgs;
diff --git a/macosx/tkMacOSXAppInit.c b/macosx/tkMacOSXAppInit.c
deleted file mode 100644
index 1825219..0000000
--- a/macosx/tkMacOSXAppInit.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * 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.5 2004/02/16 00:19:41 wolfsuit Exp $
- */
-#include <pthread.h>
-#include <sys/stat.h>
-#include "tk.h"
-#include "tclInt.h"
-#include "locale.h"
-
-#include <Carbon/Carbon.h>
-#include "tkPort.h"
-#include "tkMacOSX.h"
-#include "tkMacOSXEvent.h"
-
-/*
- * 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[PATH_MAX + 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(PATH_MAX + 1);
-
- if (CFURLGetFileSystemRepresentation (appMainURL, true,
- startupScript, PATH_MAX)) {
- TclSetStartupScriptFileName(startupScript);
- scriptFldrURL = CFBundleCopyResourceURL(bundleRef,
- CFSTR("Scripts"),
- NULL,
- NULL);
- CFURLGetFileSystemRepresentation(scriptFldrURL,
- true, scriptPath, PATH_MAX);
- 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 and stdin is a special character file of length 0,
- * (e.g. /dev/null, which is what Finder sets when double clicking Wish)
- * then use the Tk based console interpreter.
- */
-
- if (!isatty(0)) {
- struct stat st;
- if (fstat(0, &st) || (S_ISCHR(st.st_mode) && st.st_blocks == 0)) {
- Tk_InitConsoleChannels(interp);
- Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDIN));
- Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDOUT));
- Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDERR));
- 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/tkMacOSXDefault.h b/macosx/tkMacOSXDefault.h
index 97878a1..3c04fc0 100644
--- a/macosx/tkMacOSXDefault.h
+++ b/macosx/tkMacOSXDefault.h
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXDefault.h,v 1.5 2004/10/24 17:22:55 dkf Exp $
+ * RCS: @(#) $Id: tkMacOSXDefault.h,v 1.6 2004/11/11 01:24:32 das Exp $
*/
#ifndef _TKMACDEFAULT
@@ -295,7 +295,12 @@
#define DEF_MENU_SELECT_COLOR "SystemMenuActive"
#define DEF_MENU_SELECT_MONO BLACK
#define DEF_MENU_TAKE_FOCUS "0"
-#define DEF_MENU_TEAROFF "1"
+
+/*
+ * FIXME: Turn the default back to 1 when we make tearoff menus work again.
+ */
+
+#define DEF_MENU_TEAROFF "0"
#define DEF_MENU_TEAROFF_CMD (char *) NULL
#define DEF_MENU_TITLE ""
#define DEF_MENU_TYPE "normal"
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index d76b362..fff5370 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -11,9 +11,10 @@
* 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.4 2004/02/23 10:48:10 das Exp $
+ * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.5 2004/11/11 01:24:32 das Exp $
*/
+#include "tclInt.h"
#include "tkInt.h"
#include "X11/X.h"
#include "X11/Xlib.h"
@@ -27,9 +28,9 @@
#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)
+#define RGBFLOATRED(c) (float)((float)(c.red) / 65535.0f)
+#define RGBFLOATGREEN(c) (float)((float)(c.green) / 65535.0f)
+#define RGBFLOATBLUE(c) (float)((float)(c.blue) / 65535.0f)
/*
* Temporary regions that can be reused.
@@ -40,7 +41,8 @@ static RgnHandle tmpRgn2 = NULL;
static PixPatHandle gPenPat = NULL;
-static int useCGDrawing = 0;
+static int useCGDrawing = 1;
+static int tkMacOSXCGAntiAliasLimit = 1;
/*
* Prototypes for functions used only in this file.
@@ -51,6 +53,37 @@ void TkMacOSXSetUpCGContext(MacDrawable *macWin,
CGrafPtr destPort, GC gc, CGContextRef *contextPtr);
void TkMacOSXReleaseCGContext(MacDrawable *macWin, CGrafPtr destPort,
CGContextRef *context);
+static inline double radians(double degrees) { return degrees * PI / 180.0f; }
+
+int
+TkMacOSXInitCGDrawing(interp, enable, limit)
+ Tcl_Interp *interp;
+ int enable;
+ int limit;
+{
+ static Boolean initialized = FALSE;
+
+ if (!initialized) {
+ if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) {
+ Tcl_ResetResult(interp);
+ }
+ if (Tcl_LinkVar(interp, "::tk::mac::useCGDrawing",
+ (char *) &useCGDrawing,
+ TCL_LINK_BOOLEAN) != TCL_OK) {
+ Tcl_ResetResult(interp);
+ }
+ useCGDrawing = enable;
+
+ if (Tcl_LinkVar(interp, "::tk::mac::CGAntialiasLimit",
+ (char *) &tkMacOSXCGAntiAliasLimit,
+ TCL_LINK_INT) != TCL_OK) {
+ Tcl_ResetResult(interp);
+ }
+ tkMacOSXCGAntiAliasLimit = limit;
+ }
+ return TCL_OK;
+}
+
/*
*----------------------------------------------------------------------
*
@@ -118,15 +151,15 @@ XCopyArea(
srcPtr = &srcRect;
SetRect(&srcRect, (short) (srcDraw->xOff + src_x),
(short) (srcDraw->yOff + src_y),
- (short) (srcDraw->xOff + src_x + width ),
+ (short) (srcDraw->xOff + src_x + width),
(short) (srcDraw->yOff + src_y + height));
- if (tkPictureIsOpen ) {
+ 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->xOff + dest_x + width),
(short) (dstDraw->yOff + dest_y + height));
}
TkMacOSXSetUpClippingRgn(dst);
@@ -145,14 +178,15 @@ XCopyArea(
* In this case, would have also clipped to the srcRect
* ClipRect(&srcRect);
*/
+
GetPortBounds(dstPort,&clpRect);
dstPtr = &srcRect;
ClipRect(&clpRect);
}
- if (!gc->clip_mask ) {
+ if (!gc->clip_mask) {
} else if (((TkpClipMask*)gc->clip_mask)->type == TKP_CLIP_REGION) {
RgnHandle clipRgn = (RgnHandle)
- ((TkpClipMask*)gc->clip_mask)->value.region;
+ ((TkpClipMask*)gc->clip_mask)->value.region;
int xOffset, yOffset;
if (tmpRgn == NULL) {
@@ -170,8 +204,8 @@ XCopyArea(
OffsetRgn(clipRgn, -xOffset, -yOffset);
}
}
- srcBit = GetPortBitMapForCopyBits( srcPort );
- dstBit = GetPortBitMapForCopyBits( dstPort );
+ srcBit = GetPortBitMapForCopyBits(srcPort);
+ dstBit = GetPortBitMapForCopyBits(dstPort);
tmode = srcCopy;
CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL);
@@ -225,7 +259,7 @@ XCopyPlane(
CGrafPtr saveWorld;
GDHandle saveDevice;
RGBColor macColor;
- TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask;
+ TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
short tmode;
srcPort = TkMacOSXGetDrawablePort(src);
@@ -241,8 +275,8 @@ XCopyPlane(
TkMacOSXSetUpClippingRgn(dst);
- srcBit = GetPortBitMapForCopyBits ( srcPort );
- dstBit = GetPortBitMapForCopyBits ( dstPort );
+ srcBit = GetPortBitMapForCopyBits(srcPort);
+ dstBit = GetPortBitMapForCopyBits(dstPort);
SetRect(&srcRect, (short) (srcDraw->xOff + src_x),
(short) (srcDraw->yOff + src_y),
(short) (srcDraw->xOff + src_x + width),
@@ -255,6 +289,7 @@ XCopyPlane(
* clipping for color bitmaps.
* To circumvent this problem, we clip to the whole window
*/
+
Rect clpRect;
GetPortBounds(dstPort,&clpRect);
ClipRect(&clpRect);
@@ -262,9 +297,9 @@ XCopyPlane(
} 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));
+ (short) (dstDraw->yOff + dest_y),
+ (short) (dstDraw->xOff + dest_x + width),
+ (short) (dstDraw->yOff + dest_y + height));
}
tmode = srcOr;
tmode = srcCopy + transparent;
@@ -274,10 +309,10 @@ XCopyPlane(
}
if (clipPtr == NULL || clipPtr->type == TKP_CLIP_REGION) {
-
/*
* Case 1: opaque bitmaps.
*/
+
TkSetMacColor(gc->background, &macColor);
RGBBackColor(&macColor);
tmode = srcCopy;
@@ -289,6 +324,7 @@ XCopyPlane(
* Case 2: transparent bitmaps. If it's color we ignore
* the forecolor.
*/
+
pm = GetPortPixMap(srcPort);
if (GetPixDepth(pm) == 1) {
tmode = srcOr;
@@ -300,9 +336,10 @@ XCopyPlane(
/*
* Case 3: two arbitrary bitmaps.
*/
+
tmode = srcCopy;
mskPort = TkMacOSXGetDrawablePort(clipPtr->value.pixmap);
- mskBit = GetPortBitMapForCopyBits ( mskPort );
+ mskBit = GetPortBitMapForCopyBits(mskPort);
CopyDeepMask(srcBit, mskBit, dstBit,
srcPtr, srcPtr, dstPtr, tmode, NULL);
}
@@ -368,7 +405,7 @@ TkPutImage(
/* Image from XGetImage, copy from containing GWorld directly */
GWorldPtr srcPort = TkMacOSXGetDrawablePort((Drawable)image->obdata);
CopyBits(GetPortBitMapForCopyBits(srcPort),
- GetPortBitMapForCopyBits (destPort),
+ GetPortBitMapForCopyBits(destPort),
&srcRect, &destRect, srcCopy, NULL);
} else if (image->depth == 1) {
@@ -403,12 +440,15 @@ TkPutImage(
bitmap.baseAddr = newData;
bitmap.rowBytes = image->bytes_per_line;
}
- destBits = GetPortBitMapForCopyBits ( destPort );
+ destBits = GetPortBitMapForCopyBits(destPort);
CopyBits(&bitmap, destBits,
&srcRect, &destRect, srcCopy, NULL);
} else {
- /* Color image */
+ /*
+ * Color image
+ */
+
PixMap pixmap;
pixmap.bounds.left = 0;
@@ -430,7 +470,7 @@ TkPutImage(
pixmap.baseAddr = image->data;
pixmap.rowBytes = image->bytes_per_line | 0x8000;
- CopyBits((BitMap *) &pixmap, GetPortBitMapForCopyBits ( destPort ),
+ CopyBits((BitMap *) &pixmap, GetPortBitMapForCopyBits(destPort),
&srcRect, &destRect, srcCopy, NULL);
}
@@ -477,15 +517,31 @@ XFillRectangles(
SetGWorld(destPort, NULL);
TkMacOSXSetUpClippingRgn(d);
+ if (useCGDrawing) {
+ CGContextRef outContext;
+ CGRect rect;
+
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
- TkMacOSXSetUpGraphicsPort(gc, destPort);
+ for (i = 0; i < n_rectangles; i++) {
+ rect = CGRectMake((float)(macWin->xOff + rectangles[i].x),
+ (float)(macWin->yOff + rectangles[i].y),
+ (float)rectangles[i].width,
+ (float)rectangles[i].height);
+
+ CGContextFillRect(outContext, rect);
+ }
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
- for (i = 0; i < n_rectangles; 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);
+ for (i = 0; i < n_rectangles; 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);
@@ -539,13 +595,18 @@ XDrawLines(
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++) {
+ CGContextMoveToPoint(outContext, (float)(macWin->xOff + points[0].x),
+ (float)(macWin->yOff + points[0].y));
+
+ for (i = 1; i < npoints; i++) {
+ if(mode==CoordModeOrigin) {
CGContextAddLineToPoint(outContext,
- (float) points[i].x,
- (float) points[i].y);
+ (float) (macWin->xOff + points[i].x),
+ (float) (macWin->yOff + points[i].y));
+ } else {
+ CGContextAddLineToPoint(outContext,
+ (float)(macWin->xOff + points[i].x),
+ (float)(macWin->yOff + points[i].y));
}
}
@@ -585,7 +646,7 @@ XDrawLines(
* None.
*
* Side effects:
- * Renders a series of connected lines.
+ * Renders a series of unconnected lines.
*
*----------------------------------------------------------------------
*/
@@ -617,16 +678,17 @@ void XDrawSegments(
TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
- CGContextBeginPath(outContext);
for (i = 0; i < nsegments; i++) {
+ CGContextBeginPath(outContext);
CGContextMoveToPoint(outContext,
- (float) segments[i].x1,
- (float) segments[i].y1);
+ (float)(macWin->xOff + segments[i].x1),
+ (float)(macWin->yOff + segments[i].y1));
CGContextAddLineToPoint (outContext,
- (float) segments[i].x2,
- (float) segments[i].y2);
+ (float)(macWin->xOff + segments[i].x2),
+ (float)(macWin->yOff + segments[i].y2));
+ CGContextStrokePath(outContext);
+
}
- CGContextStrokePath(outContext);
TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
} else {
TkMacOSXSetUpGraphicsPort(gc, destPort);
@@ -693,18 +755,20 @@ XFillPolygon(
TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
CGContextBeginPath(outContext);
- CGContextMoveToPoint(outContext, (float) (points[0].x),
- (float) (points[0].y));
+ CGContextMoveToPoint(outContext, (float) (macWin->xOff + points[0].x),
+ (float) (macWin->yOff + points[0].y));
for (i = 1; i < npoints; i++) {
if (mode == CoordModePrevious) {
- CGContextAddLineToPoint(outContext, (float) points[i].x,
+ CGContextAddLineToPoint(outContext, (float)points[i].x,
(float) points[i].y);
} else {
+ CGContextAddLineToPoint(outContext,
+ (float)(macWin->xOff + points[i].x),
+ (float)(macWin->yOff + points[i].y));
}
}
- //CGContextStrokePath(outContext);
- CGContextFillPath(outContext);
+ CGContextEOFillPath(outContext);
TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
} else {
TkMacOSXSetUpGraphicsPort(gc, destPort);
@@ -772,19 +836,31 @@ XDrawRectangle(
SetGWorld(destPort, NULL);
TkMacOSXSetUpClippingRgn(d);
+ if (useCGDrawing) {
+ CGContextRef outContext;
+ CGRect rect;
+
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
- TkMacOSXSetUpGraphicsPort(gc, destPort);
+ rect = CGRectMake((float) ((float) macWin->xOff + (float) x),
+ (float) ((float) macWin->yOff + (float) y),
+ (float) width,
+ (float) height);
+ CGContextStrokeRect(outContext, rect);
+ 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);
+ 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();
-
+ ShowPen();
+ PenPixPat(gPenPat);
+ FrameRect(&theRect);
+ HidePen();
+ }
SetGWorld(saveWorld, saveDevice);
}
@@ -823,7 +899,7 @@ XDrawRectangles(
int nRects)
{
MacDrawable *macWin = (MacDrawable *) drawable;
- Rect rect;
+ Rect theRect;
CGrafPtr saveWorld;
GDHandle saveDevice;
GWorldPtr destPort;
@@ -838,21 +914,36 @@ XDrawRectangles(
TkMacOSXSetUpClippingRgn(drawable);
- TkMacOSXSetUpGraphicsPort(gc, destPort);
+ if (useCGDrawing) {
+ CGContextRef outContext;
+ CGRect rect;
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
- ShowPen();
- PenPixPat(gPenPat);
+ for (i = 0, rectPtr = rectArr; i < nRects; i++, rectPtr++) {
+ rect = CGRectMake((float) ((float) macWin->xOff
+ + (float) rectPtr->x),
+ (float) ((float) macWin->yOff + (float) rectPtr->y),
+ (float) rectPtr->width,
+ (float) rectPtr->height);
+ CGContextStrokeRect(outContext, rect);
+ }
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
- 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();
+ ShowPen();
+ PenPixPat(gPenPat);
+ for (i = 0, rectPtr = rectArr; i < nRects;i++, rectPtr++) {
+ theRect.left = (short) (macWin->xOff + rectPtr->x);
+ theRect.top = (short) (macWin->yOff + rectPtr->y);
+ theRect.right = (short) (theRect.left + rectPtr->width);
+ theRect.bottom = (short) (theRect.top + rectPtr->height);
+ FrameRect(&theRect);
+ }
+ HidePen();
+ }
SetGWorld(saveWorld, saveDevice);
}
@@ -890,10 +981,6 @@ XDrawArc(
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;
@@ -909,13 +996,20 @@ XDrawArc(
if (useCGDrawing) {
CGContextRef outContext;
- CGAffineTransform transform;
- int clockwise = angle1 ? 0 : 1;
+ CGRect boundingRect;
+ int clockwise;
+ float a,b;
+ CGPoint center;
+ float arc1, arc2;
+
+ if (angle2 > 0) {
+ clockwise = 1;
+ } else {
+ clockwise = 0;
+ }
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
@@ -923,17 +1017,24 @@ XDrawArc(
*/
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);
-
+ boundingRect = CGRectMake( (float)(macWin->xOff + x),
+ (float)(macWin->yOff + y),
+ (float)(width),
+ (float)(height));
+
+ center = CGPointMake(CGRectGetMidX(boundingRect),
+ CGRectGetMidY(boundingRect));
+ a = CGRectGetWidth(boundingRect)/2;
+ b = CGRectGetHeight(boundingRect)/2;
+
+ CGContextTranslateCTM(outContext, center.x, center.y);
+ CGContextBeginPath(outContext);
+ CGContextScaleCTM(outContext, a, b);
+ arc1 = radians(-(angle1/64));
+ arc2 = radians(-(angle2/64)) + arc1;
+ CGContextAddArc(outContext, 0.0, 0.0, 1, arc1, arc2, clockwise);
+
+ CGContextRestoreGState(outContext);
CGContextStrokePath(outContext);
TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
} else {
@@ -1003,23 +1104,66 @@ XDrawArcs(
SetGWorld(destPort, NULL);
TkMacOSXSetUpClippingRgn(d);
+ if (useCGDrawing) {
+ CGContextRef outContext;
- TkMacOSXSetUpGraphicsPort(gc, destPort);
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
+ for (i=0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) {
+ CGRect boundingRect;
+ int clockwise;
+ float a,b, arc1, arc2;
+ CGPoint center;
+
+ if (arcPtr[i].angle2 > 0) {
+ clockwise = 1;
+ } else {
+ clockwise = 0;
+ }
- 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();
+ /*
+ * If we are drawing an oval, we have to squash the coordinate
+ * system before drawing, since CGContextAddArcToPoint only draws
+ * circles.
+ */
+ CGContextSaveGState(outContext);
+ CGContextBeginPath(outContext);
+ boundingRect = CGRectMake( (float)(macWin->xOff + arcPtr[i].x),
+ (float)(macWin->yOff + arcPtr[i].y),
+ (float)arcPtr[i].width,
+ (float)arcPtr[i].height);
+
+ center = CGPointMake(CGRectGetMidX(boundingRect),
+ CGRectGetMidY(boundingRect));
+ a = CGRectGetWidth(boundingRect)/2;
+ b = CGRectGetHeight(boundingRect)/2;
+
+ CGContextTranslateCTM(outContext, center.x, center.y);
+ CGContextScaleCTM(outContext, a, b);
+ arc1 = radians(-(arcPtr[i].angle1/64));
+ arc2 = radians(-(arcPtr[i].angle2/64)) + arc1;
+ CGContextAddArc(outContext, 0.0, 0.0, 1, arc1, arc2, clockwise);
+ CGContextRestoreGState(outContext);
+ CGContextStrokePath(outContext);
+ }
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
+ 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);
}
@@ -1070,16 +1214,65 @@ XFillArc(
TkMacOSXSetUpClippingRgn(d);
- TkMacOSXSetUpGraphicsPort(gc, destPort);
+ if (useCGDrawing) {
+ CGContextRef outContext;
+ CGRect boundingRect;
+ int clockwise;
+ float a,b;
+ CGPoint center;
+
+ if (angle2 > 0) {
+ clockwise = 1;
+ } else {
+ clockwise = 0;
+ }
+
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
+
+ boundingRect = CGRectMake((float) (macWin->xOff + x),
+ (float) (macWin->yOff + y),
+ (float) width,
+ (float) height);
+ center = CGPointMake(CGRectGetMidX(boundingRect),
+ CGRectGetMidY(boundingRect));
+ a = CGRectGetWidth(boundingRect)/2;
+ b = CGRectGetHeight(boundingRect)/2;
+
+ if (gc->arc_mode == ArcChord) {
+ float arc1, arc2;
+
+ CGContextBeginPath(outContext);
+ CGContextTranslateCTM(outContext, center.x, center.y);
+ CGContextScaleCTM(outContext, a, b);
+ arc1 = radians(-(angle1/64));
+ arc2 = radians(-(angle2/64)) + arc1;
+ CGContextAddArc(outContext, 0.0, 0.0, 1, arc1, arc2, clockwise);
+ CGContextFillPath(outContext);
+ } else if (gc->arc_mode == ArcPieSlice) {
+ float arc1, arc2;
+
+ CGContextTranslateCTM(outContext, center.x, center.y);
+ CGContextScaleCTM(outContext,a,b);
+ arc1 = radians(-(angle1/64));
+ arc2 = radians(-(angle2/64)) + arc1;
+ CGContextAddArc(outContext, 0.0, 0.0, 1, arc1, arc2, clockwise);
+ CGContextAddLineToPoint(outContext, 0.0f, 0.0f);
+ CGContextClosePath(outContext);
+ CGContextFillPath(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));
+ 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) {
+ if (gc->arc_mode == ArcChord) {
boxWidth = theRect.right - theRect.left;
boxHeight = theRect.bottom - theRect.top;
angle = -(angle1/64.0)*PI/180.0;
@@ -1095,26 +1288,26 @@ XFillArc(
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));
+ 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();
+ 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();
+ ShowPen();
+ FillCArc(&theRect, start, extent, gPenPat);
+ FillCPoly(polygon, gPenPat);
+ HidePen();
- KillPoly(polygon);
- } else {
- ShowPen();
- FillCArc(&theRect, start, extent, gPenPat);
- HidePen();
+ KillPoly(polygon);
+ } else {
+ ShowPen();
+ FillCArc(&theRect, start, extent, gPenPat);
+ HidePen();
+ }
}
-
SetGWorld(saveWorld, saveDevice);
}
@@ -1162,50 +1355,139 @@ XFillArcs(
TkMacOSXSetUpClippingRgn(d);
- TkMacOSXSetUpGraphicsPort(gc, destPort);
+ if (useCGDrawing) {
+ CGContextRef outContext;
+
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
+ for (i = 0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) {
+ CGRect boundingRect;
+ int clockwise = arcPtr[i].angle1;
+ float a,b;
+ CGPoint center;
+
+ if (arcPtr[i].angle2 > 0) {
+ clockwise = 1;
+ } else {
+ clockwise = 0;
+ }
- 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 we are drawing an oval, we have to squash the coordinate
+ * system before drawing, since CGContextAddArcToPoint only draws
+ * circles.
+ */
+
+ if (gc->arc_mode == ArcChord) {
+
+ CGContextBeginPath(outContext);
+ boundingRect = CGRectMake((float)(macWin->xOff + arcPtr[i].x),
+ (float)(macWin->yOff + arcPtr[i].y),
+ (float)arcPtr[i].width,
+ (float)arcPtr[i].height);
+ center = CGPointMake(CGRectGetMidX(boundingRect),
+ CGRectGetMidY(boundingRect));
+ a = CGRectGetWidth(boundingRect)/2.0;
+ b = CGRectGetHeight(boundingRect)/2.0;
+
+ 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] = (CGRectGetMinX(boundingRect)
+ + CGRectGetMaxX(boundingRect))/2.0;
+ vertex[1] = (CGRectGetMaxY(boundingRect)
+ + CGRectGetMinY(boundingRect))/2.0;
+ center1[0] = vertex[0] + cos1*a;
+ center1[1] = vertex[1] + sin1*b;
+ center2[0] = vertex[0] + cos2*a;
+ center2[1] = vertex[1] + sin2*b;
+
+ CGContextScaleCTM(outContext, a, b);
+
+ CGContextBeginPath(outContext);
+ CGContextMoveToPoint(outContext, (float) vertex[0],
+ (float) vertex[1]);
+ CGContextAddLineToPoint(outContext,
+ (float) (center1[0] + 0.5),
+ (float) (center1[1] + 0.5));
+ CGContextAddLineToPoint(outContext,
+ (float) (center2[0] + 0.5),
+ (float) (center2[1] + 0.5));
+ CGContextFillPath(outContext);
+ } else if (gc->arc_mode == ArcPieSlice) {
+ float arc1, arc2;
+ CGContextBeginPath(outContext);
+ boundingRect = CGRectMake((float)(macWin->xOff + arcPtr[i].x),
+ (float)(macWin->yOff + arcPtr[i].y),
+ (float)arcPtr[i].width,
+ (float)arcPtr[i].height);
+ center = CGPointMake(CGRectGetMidX(boundingRect),
+ CGRectGetMidY(boundingRect));
+ a = CGRectGetWidth(boundingRect)/2;
+ b = CGRectGetHeight(boundingRect)/2;
+
+ CGContextTranslateCTM(outContext, center.x, center.y);
+ CGContextScaleCTM(outContext, a, b);
+ arc1 = radians(-(arcPtr[i].angle1/64));
+ arc2 = radians(-(arcPtr[i].angle2/64)) + arc1;
+ CGContextAddArc(outContext, 0.0, 0.0, 1,
+ arc1, arc2, clockwise);
+ CGContextAddLineToPoint(outContext, 0.0f, 0.0f);
+ CGContextClosePath(outContext);
+ CGContextFillPath(outContext);
+ }
+ }
+
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
+
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
- 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;
+ 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));
+ 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();
+ 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();
+ ShowPen();
+ FillCArc(&rect, start, extent, gPenPat);
+ FillCPoly(polygon, gPenPat);
+ HidePen();
- KillPoly(polygon);
- } else {
- ShowPen();
- FillCArc(&rect, start, extent, gPenPat);
- HidePen();
+ KillPoly(polygon);
+ } else {
+ ShowPen();
+ FillCArc(&rect, start, extent, gPenPat);
+ HidePen();
+ }
}
}
SetGWorld(saveWorld, saveDevice);
@@ -1389,7 +1671,6 @@ TkMacOSXSetUpGraphicsPort(
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.
@@ -1408,9 +1689,9 @@ TkMacOSXSetUpGraphicsPort(
* 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.
+ * This is not possible with QuickDraw line drawing. As of
+ * Tk 8.4.7 we have a complete set of drawing routines using
+ * CG, so there is no reason to support this here.
*/
}
}
@@ -1441,43 +1722,54 @@ TkMacOSXSetUpCGContext(
CGContextRef outContext;
OSStatus err;
Rect boundsRect;
- CGAffineTransform coordsTransform;
+ CGAffineTransform coordsTransform;
+ static RgnHandle clipRgn = NULL;
err = QDBeginCGContext(destPort, contextPtr);
outContext = *contextPtr;
-
- CGContextSaveGState(outContext);
-
+
+ /*
+ * Now clip the CG Context to the port. Note, we have already
+ * set up the port with our clip region, so we can just get
+ * the clip back out of there. If we use the macWin->clipRgn
+ * directly at this point, we get some odd drawing effects.
+ *
+ * We also have to intersect our clip region with the port
+ * visible region so we don't overwrite the window decoration.
+ */
+
+ if (!clipRgn) {
+ clipRgn = NewRgn();
+ }
+
GetPortBounds(destPort, &boundsRect);
- CGContextResetCTM(outContext);
- coordsTransform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0,
- (float)(boundsRect.bottom - boundsRect.top));
- CGContextConcatCTM(outContext, coordsTransform);
+ RectRgn(clipRgn, &boundsRect);
+ SectRegionWithPortClipRegion(destPort, clipRgn);
+ SectRegionWithPortVisibleRegion(destPort, clipRgn);
+ ClipCGContextToRegion(outContext, &boundsRect, clipRgn);
+ SetEmptyRgn(clipRgn);
- if (macWin->clipRgn != NULL) {
- ClipCGContextToRegion(outContext, &boundsRect, macWin->clipRgn);
- } else {
- RgnHandle clipRgn = NewRgn();
- GetPortClipRegion(destPort, clipRgn);
- ClipCGContextToRegion(outContext, &boundsRect,
- clipRgn);
- DisposeRgn(clipRgn);
- }
+ /*
+ * Note: You have to call SyncCGContextOriginWithPort
+ * AFTER all the clip region manipulations.
+ */
+
+ SyncCGContextOriginWithPort(outContext, destPort);
- /* Now offset the CTM to the subwindow offset */
+ coordsTransform = CGAffineTransformMake(1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
+ (float) (boundsRect.bottom - boundsRect.top));
+ CGContextConcatCTM(outContext, coordsTransform);
- CGContextTranslateCTM(outContext, macWin->xOff, macWin->yOff);
+ /* Now offset the CTM to the subwindow offset */
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);
+ RGBFLOATGREEN(macColor),
+ RGBFLOATBLUE(macColor), 1.0f);
+ CGContextSetRGBStrokeColor(outContext, RGBFLOATRED(macColor),
+ RGBFLOATGREEN(macColor),
+ RGBFLOATBLUE(macColor), 1.0f);
}
if(gc->function == GXxor) {
@@ -1485,30 +1777,44 @@ TkMacOSXSetUpCGContext(
CGContextSetLineWidth(outContext, (float) gc->line_width);
- if (gc->line_style != LineSolid) {
- unsigned char *p = (unsigned char *) &(gc->dashes);
+ /* When should we antialias? */
+ if (gc->line_width < tkMacOSXCGAntiAliasLimit) {
+ CGContextSetShouldAntialias(outContext, 0);
+ } else {
+ CGContextSetShouldAntialias(outContext, 1);
+ }
+
+ if (gc->line_style != LineSolid) {
+ int num = 0;
+ char *p = &(gc->dashes);
+ float dashOffset = (float) gc->dash_offset;
+ float lengths[10];
+
+ while (p[num] != '\0') {
+ lengths[num] = (float) (p[num]);
+ num++;
+ }
+ CGContextSetLineDash(outContext, dashOffset, lengths, num);
+ }
+
+ if (gc->cap_style == CapButt) {
/*
- * 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.
+ * What about CapNotLast, CapProjecting?
*/
+
+ CGContextSetLineCap(outContext, kCGLineCapButt);
+ } else if (gc->cap_style == CapRound) {
+ CGContextSetLineCap(outContext, kCGLineCapRound);
+ } else if (gc->cap_style == CapProjecting) {
+ CGContextSetLineCap(outContext, kCGLineCapSquare);
+ }
+
+ if (gc->join_style == JoinMiter) {
+ CGContextSetLineJoin(outContext, kCGLineJoinMiter);
+ } else if (gc->join_style == JoinRound) {
+ CGContextSetLineJoin(outContext, kCGLineJoinRound);
+ } else if (gc->join_style == JoinBevel) {
+ CGContextSetLineJoin(outContext, kCGLineJoinBevel);
}
}
@@ -1518,10 +1824,8 @@ TkMacOSXReleaseCGContext(
CGrafPtr destPort,
CGContextRef *outContext)
{
- CGContextResetCTM(*outContext);
- CGContextRestoreGState(*outContext);
+ CGContextSynchronize(*outContext);
QDEndCGContext(destPort, outContext);
-
}
/*
@@ -1617,7 +1921,7 @@ TkMacOSXMakeStippleMap(
destPort = TkMacOSXGetDrawablePort(drawable);
- GetPortBounds ( destPort, &portRect );
+ GetPortBounds (destPort, &portRect);
width = portRect.right - portRect.left;
height = portRect.bottom - portRect.top;
@@ -1640,7 +1944,7 @@ TkMacOSXMakeStippleMap(
bounds.right = j + stippleWidth;
bounds.bottom = i + stippleHeight;
- CopyBits(GetPortBitMapForCopyBits ( destPort ), bitmapPtr,
+ CopyBits(GetPortBitMapForCopyBits(destPort), bitmapPtr,
&portRect, &bounds, srcCopy, NULL);
}
}
@@ -1716,7 +2020,8 @@ TkpDrawHighlightBorder (
} else {
TkDrawInsetFocusHighlight (tkwin, bgGC, highlightWidth, drawable, 0);
if (fgGC != bgGC) {
- TkDrawInsetFocusHighlight (tkwin, fgGC, highlightWidth - 1, drawable, 0);
+ TkDrawInsetFocusHighlight (tkwin, fgGC, highlightWidth - 1,
+ drawable, 0);
}
}
}
diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c
index df7f255..07127eb 100644
--- a/macosx/tkMacOSXInit.c
+++ b/macosx/tkMacOSXInit.c
@@ -10,11 +10,14 @@
* 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.5 2004/02/16 00:19:42 wolfsuit Exp $
+ * RCS: @(#) $Id: tkMacOSXInit.c,v 1.6 2004/11/11 01:24:32 das Exp $
*/
#include "tkInt.h"
#include "tkMacOSXInt.h"
+#include "tclInt.h"
+#include <sys/stat.h>
+#include <mach-o/dyld.h>
/*
* The Init script (common to Windows and Unix platforms) is
@@ -23,6 +26,15 @@
#include "tkInitScript.h"
/*
+ * Define the following to 0 to not attempt to use an undocumented SPI
+ * to notify the window server that an unbundled executable is a full
+ * GUI application after loading Tk.
+ */
+#ifndef MAC_OSX_TK_USE_CPS_SPI
+#define MAC_OSX_TK_USE_CPS_SPI 1
+#endif
+
+/*
* 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
@@ -72,6 +84,11 @@ static Map scriptMap[] = {
Tcl_Encoding TkMacOSXCarbonEncoding = NULL;
+/*
+ * If the App is in an App package, then we want to add the Scripts
+ * directory to the auto_path.
+ */
+static char scriptPath[PATH_MAX + 1] = "";
/*
*----------------------------------------------------------------------
@@ -95,30 +112,28 @@ int
TkpInit(interp)
Tcl_Interp *interp;
{
- char tkLibPath[1024];
- int result;
- static int menusInitialized = false;
- static int carbonEncodingInitialized = false;
+ static char tkLibPath[PATH_MAX + 1];
+ static int tkMacOSXInitialized = false;
/*
* Since it is possible for TkInit to be called multiple times
- * and we don't want to do the menu initialization multiple times
+ * and we don't want to do the initialization multiple times
* we protect against doing it more than once.
*/
- if (menusInitialized == false) {
- menusInitialized = true;
+ if (tkMacOSXInitialized == false) {
+ CFStringEncoding encoding;
+ char *encodingStr = NULL;
+ int i;
+
+ tkMacOSXInitialized = true;
+
Tk_MacOSXSetupTkNotifier();
TkMacOSXInitAppleEvents(interp);
TkMacOSXInitCarbonEvents(interp);
TkMacOSXInitMenus(interp);
TkMacOSXUseAntialiasedText(interp, TRUE);
- }
-
- if (carbonEncodingInitialized == false) {
- CFStringEncoding encoding;
- char *encodingStr = NULL;
- int i;
+ TkMacOSXInitCGDrawing(interp, TRUE, 3);
encoding = CFStringGetSystemEncoding();
@@ -136,20 +151,112 @@ TkpInit(interp)
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?
+ */
+
+ Tcl_MacOSXOpenVersionedBundleResources(interp,
+ "com.tcltk.tklibrary", TK_VERSION, 1, 1024, tkLibPath);
+
+ /*
+ * If we don't have a TTY and stdin is a special character file of length 0,
+ * (e.g. /dev/null, which is what Finder sets when double clicking Wish)
+ * then use the Tk based console interpreter.
+ */
- /*
- * 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_MacOSXOpenVersionedBundleResources(interp,
- "com.tcltk.tklibrary", TK_VERSION, 1, 1024, tkLibPath);
-
- if (result != TCL_ERROR) {
+ if (!isatty(0)) {
+ struct stat st;
+ if (fstat(0, &st) || (S_ISCHR(st.st_mode) && st.st_blocks == 0)) {
+ Tk_InitConsoleChannels(interp);
+ Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDIN));
+ Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDOUT));
+ Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDERR));
+ if (Tk_CreateConsoleWindow(interp) == TCL_OK) {
+ /* Only show the console if we don't have a startup script */
+ if (Tcl_GetStartupScript(NULL) == NULL) {
+ Tcl_Eval(interp, "console show");
+ }
+ }
+ }
+ }
+#if MAC_OSX_TK_USE_CPS_SPI
+ /*
+ * If we are loaded into an executable that is not a bundled application,
+ * the window server does not let us come to the foreground.
+ * For such an executable, we attempt to use an undocumented SPI to
+ * notify the window server that we are now a full GUI application.
+ */
+ {
+ /* Check whether we are a bundled executable: */
+ int bundledExecutable = 0;
+ CFBundleRef bundleRef = CFBundleGetMainBundle();
+ CFURLRef bundleUrl = NULL;
+ if (bundleRef) {
+ bundleUrl = CFBundleCopyBundleURL(bundleRef);
+ }
+ if (bundleUrl) {
+ /*
+ * A bundled executable is two levels down from its main bundle
+ * directory (e.g. Wish.app/Contents/MacOS/Wish), whereas
+ * an unbundled executable's main bundle directory is just
+ * the directory containing the executable.
+ * So to check whether we are bundled, we delete the last three
+ * path components of the executable's url and compare the
+ * resulting url with the main bundle url.
+ */
+ int j = 3;
+ CFURLRef url = CFBundleCopyExecutableURL(bundleRef);
+ while (url && j--) {
+ CFURLRef parent = CFURLCreateCopyDeletingLastPathComponent(NULL, url);
+ CFRelease(url);
+ url = parent;
+ }
+ if (url) {
+ bundledExecutable = CFEqual(bundleUrl, url);
+ CFRelease(url);
+ }
+ CFRelease(bundleUrl);
+ }
+
+ /* If we are not a bundled executable, attempt to use the CPS SPI: */
+ if (!bundledExecutable) {
+ /*
+ * Load the CPS SPI symbol dynamically, so that we don't break
+ * if it every disappears or changes its name.
+ */
+ OSErr (*cpsEnableForegroundOperation)(ProcessSerialNumberPtr) = NULL;
+ NSSymbol nsSymbol;
+ if(NSIsSymbolNameDefinedWithHint(
+ "_CPSEnableForegroundOperation", "CoreGraphics")) {
+ nsSymbol = NSLookupAndBindSymbolWithHint(
+ "_CPSEnableForegroundOperation", "CoreGraphics");
+ if(nsSymbol) {
+ cpsEnableForegroundOperation = NSAddressOfSymbol(nsSymbol);
+ }
+ }
+ if (cpsEnableForegroundOperation) {
+ ProcessSerialNumber psn = { 0, kCurrentProcess };
+ /*
+ * Let the window server know that we are a foregroundable app
+ */
+ cpsEnableForegroundOperation(&psn);
+ }
+ }
+ }
+#endif /* MAC_OSX_TK_USE_CPS_SPI */
+ }
+
+ if (tkLibPath[0] != '\0') {
Tcl_SetVar(interp, "tk_library", tkLibPath, TCL_GLOBAL_ONLY);
}
+
+ if (scriptPath[0] != '\0') {
+ Tcl_SetVar(interp, "auto_path", scriptPath,
+ TCL_GLOBAL_ONLY|TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
+ }
return Tcl_Eval(interp, initScript);
}
@@ -221,3 +328,59 @@ TkpDisplayWarning(msg, title)
Tcl_WriteChars(errChannel, "\n", 1);
}
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXDefaultStartupScript --
+ *
+ *
+ * On MacOS X, we look for a file in the Resources/Scripts
+ * directory called AppMain.tcl and if found, we set argv[1] to
+ * that, so that the rest of the code will find it, and add the
+ * Scripts folder to the auto_path. If we don't find the startup
+ * script, we just bag it, assuming the user is starting up some
+ * other way.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Tcl_SetStartupScript() called when AppMain.tcl found.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXDefaultStartupScript(void)
+{
+ CFBundleRef bundleRef;
+
+ bundleRef = CFBundleGetMainBundle();
+
+ if (bundleRef != NULL) {
+ CFURLRef appMainURL;
+ appMainURL = CFBundleCopyResourceURL(bundleRef,
+ CFSTR("AppMain"),
+ CFSTR("tcl"),
+ CFSTR("Scripts"));
+
+ if (appMainURL != NULL) {
+ CFURLRef scriptFldrURL;
+ char startupScript[PATH_MAX + 1];
+
+ if (CFURLGetFileSystemRepresentation (appMainURL, true,
+ startupScript, PATH_MAX)) {
+ Tcl_SetStartupScript(Tcl_NewStringObj(startupScript, -1), NULL);
+ scriptFldrURL = CFURLCreateCopyDeletingLastPathComponent(
+ NULL, appMainURL);
+ if (scriptFldrURL != NULL) {
+ CFURLGetFileSystemRepresentation(scriptFldrURL,
+ true, scriptPath, PATH_MAX);
+ CFRelease(scriptFldrURL);
+ }
+ }
+ CFRelease(appMainURL);
+ }
+ }
+}
diff --git a/macosx/tkMacOSXInt.h b/macosx/tkMacOSXInt.h
index df1089b..978f12a 100644
--- a/macosx/tkMacOSXInt.h
+++ b/macosx/tkMacOSXInt.h
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXInt.h,v 1.4 2004/02/16 00:19:42 wolfsuit Exp $
+ * RCS: @(#) $Id: tkMacOSXInt.h,v 1.5 2004/11/11 01:24:32 das Exp $
*/
#ifndef _TKMACINT
@@ -151,12 +151,9 @@ extern TkMacOSXWindowList *tkMacOSXWindowListPtr;
extern Tcl_Encoding TkMacOSXCarbonEncoding;
extern int TkMacOSXUseAntialiasedText(Tcl_Interp *interp, int enable);
-
-/*
- * FIXME: Put this into the decls file?
- */
-
extern void TkMacOSXInitCarbonEvents (Tcl_Interp *interp);
+extern int TkMacOSXInitCGDrawing(Tcl_Interp *interp, int enable, int antiAlias);
+extern void TkMacOSXDefaultStartupScript(void);
#include "tkIntPlatDecls.h"
diff --git a/macosx/tkMacOSXMenu.c b/macosx/tkMacOSXMenu.c
index 7ad48b4..09126b8 100644
--- a/macosx/tkMacOSXMenu.c
+++ b/macosx/tkMacOSXMenu.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXMenu.c,v 1.15 2004/09/03 14:09:05 dkf Exp $
+ * RCS: @(#) $Id: tkMacOSXMenu.c,v 1.16 2004/11/11 01:24:32 das Exp $
*/
#include "tkMacOSXInt.h"
#include "tkMenubutton.h"
@@ -141,9 +141,6 @@ typedef struct TopLevelMenubarList {
#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
@@ -1079,7 +1076,9 @@ ReconfigureIndividualMenu(
*/
if (mePtr->type == SEPARATOR_ENTRY) {
- AppendMenu(macMenuHdl, SEPARATOR_TEXT);
+ AppendMenuItemTextWithCFString (macMenuHdl, NULL,
+ kMenuItemAttrSeparator | kMenuItemAttrDisabled,
+ 0, NULL);
} else {
Tcl_DString itemTextDString;
int destWrote;
@@ -1087,13 +1086,12 @@ ReconfigureIndividualMenu(
GetEntryText(mePtr, &itemTextDString);
cf = CFStringCreateWithCString(NULL,
Tcl_DStringValue(&itemTextDString), kCFStringEncodingUTF8);
- AppendMenu(macMenuHdl, "\px");
if (cf != NULL) {
- SetMenuItemTextWithCFString(macMenuHdl, base + index, cf);
+ AppendMenuItemTextWithCFString (macMenuHdl, cf, 0, 0, NULL);
CFRelease(cf);
} else {
cf = CFSTR ("<Error>");
- SetMenuItemTextWithCFString(macMenuHdl, base + index, cf);
+ AppendMenuItemTextWithCFString (macMenuHdl, cf, 0, 0, NULL);
}
Tcl_DStringFree(&itemTextDString);
@@ -2103,6 +2101,7 @@ EventuallyInvokeMenu (ClientData data)
code = TkInvokeMenu(realData->menuPtr->interp, realData->menuPtr,
realData->index);
+
if (code != TCL_OK && code != TCL_CONTINUE
&& code != TCL_BREAK) {
Tcl_AddErrorInfo(realData->menuPtr->interp, "\n (menu invoke)");
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
index cab8a93..168ef73 100644
--- a/macosx/tkMacOSXMouseEvent.c
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -117,6 +117,7 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr)
int status,err;
MouseEventData mouseEventData, * medPtr = &mouseEventData;
KeyMap keyMap;
+ long modif;
switch (eventPtr->eKind) {
case kEventMouseUp:
@@ -140,19 +141,21 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr)
}
medPtr->state = 0;
GetKeys(keyMap);
- if (keyMap[1] & 2) {
+ modif = EndianS32_BtoN(*(long*)(&keyMap[1]));
+
+ if (modif & 2) {
medPtr->state |= LockMask;
}
- if (keyMap[1] & 1) {
+ if (modif & 1) {
medPtr->state |= ShiftMask;
}
- if (keyMap[1] & 8) {
+ if (modif & 8) {
medPtr->state |= ControlMask;
}
- if (keyMap[1] & 32768) {
+ if (modif & 32768) {
medPtr->state |= Mod1Mask; /* command key */
}
- if (keyMap[1] & 4) {
+ if (modif & 4) {
medPtr->state |= Mod2Mask; /* option key */
}
if (eventPtr->eKind == kEventMouseDown
@@ -381,7 +384,7 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr)
TkMacOSXPreprocessMenu();
TkMacOSXHandleMenuSelect(MenuSelect(where),
- theKeys[1] & 4);
+ EndianS32_BtoN(*(long*)(&theKeys[1])) & 4);
Tcl_SetServiceMode(oldMode);
return true; /* TODO: may not be on event on queue. */
}
@@ -678,30 +681,33 @@ TkMacOSXButtonKeyState()
{
unsigned int state = 0;
KeyMap theKeys;
+ long modif;
if (Button() & !gEatButtonUp) {
state |= Button1Mask;
}
GetKeys(theKeys);
+
+ modif = EndianS32_BtoN(*(long*)(&theKeys[1]));
- if (theKeys[1] & 2) {
+ if (modif & 2) {
state |= LockMask;
}
- if (theKeys[1] & 1) {
+ if (modif & 1) {
state |= ShiftMask;
}
- if (theKeys[1] & 8) {
+ if (modif & 8) {
state |= ControlMask;
}
- if (theKeys[1] & 32768) {
+ if (modif & 32768) {
state |= Mod1Mask; /* command key */
}
- if (theKeys[1] & 4) {
+ if (modif & 4) {
state |= Mod2Mask; /* option key */
}
diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c
index 20b4506..f1f4cb1 100644
--- a/macosx/tkMacOSXSubwindows.c
+++ b/macosx/tkMacOSXSubwindows.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXSubwindows.c,v 1.5 2004/03/21 04:07:12 wolfsuit Exp $
+ * RCS: @(#) $Id: tkMacOSXSubwindows.c,v 1.6 2004/11/11 01:24:32 das Exp $
*/
#include "tkInt.h"
@@ -611,7 +611,7 @@ XMoveWindow(
UpdateOffsets(macWin->winPtr, deltaX, deltaY);
TkMacOSXWinBounds(macWin->winPtr, &bounds);
InvalWindowRect(GetWindowFromPort(destPort),&bounds);
- GenerateConfigureNotify(macWin->winPtr, 0);
+ GenerateConfigureNotify(macWin->winPtr, 0);
}
}
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index c53f404..47c038a 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXWm.c,v 1.14 2004/10/05 22:04:44 hobbs Exp $
+ * RCS: @(#) $Id: tkMacOSXWm.c,v 1.15 2004/11/11 01:24:32 das Exp $
*/
#include <Carbon/Carbon.h>
@@ -86,6 +86,11 @@ static int WmAspectCmd _ANSI_ARGS_((Tk_Window tkwin,
static int WmAttributesCmd _ANSI_ARGS_((Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
Tcl_Obj *CONST objv[]));
+static void WmAttrGetModifiedStatus(WindowRef macWindow, Tcl_Obj
+ *result);
+static void WmAttrGetTitlePath(WindowRef macWindow, Tcl_Obj
+ *result);
+static void WmAttrGetAlpha(WindowRef macWindow, Tcl_Obj *result);
static int WmClientCmd _ANSI_ARGS_((Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
Tcl_Obj *CONST objv[]));
@@ -762,74 +767,215 @@ Tcl_Interp *interp; /* Current interpreter. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument objects. */
{
- char buf[TCL_INTEGER_SPACE];
int i;
+ int index;
WindowRef macWindow;
-
+ Tcl_Obj *result = NULL;
+ const char *optionTable[] = {
+ "-modified",
+ "-titlepath",
+ "-alpha",
+ (char *)NULL
+ };
+ enum optionIdx {
+ WmAttrModifiedIdx,
+ WmAttrTitlePathIdx,
+ WmAttrAlphaIdx,
+ };
+
+ /* Must have objc >= 3 at this point. */
if (objc < 3) {
-configArgs:
Tcl_WrongNumArgs(interp, 1, objv,
- "attributes window ?-modified ?bool?? ?-titlepath ?path??");
- return TCL_ERROR;
+ "attributes window ?-modified ?bool?? ?-titlepath ?path?? ?-alpha ?double??");
+ 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);
- }
+ result = Tcl_NewObj();
+ Tcl_AppendToObj(result, "-modified ", -1);
+ WmAttrGetModifiedStatus(macWindow, result);
+ Tcl_AppendToObj(result, " -titlepath ", -1);
+ WmAttrGetTitlePath(macWindow, result);
+ Tcl_AppendToObj(result, " -alpha ", -1);
+ WmAttrGetAlpha(macWindow, result);
+ Tcl_SetObjResult(interp, result);
return TCL_OK;
}
+ if (objc == 4) {
+ if (Tcl_GetIndexFromObj(interp, objv[3], optionTable, "option", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = Tcl_NewObj();
+ switch (index) {
+ case WmAttrModifiedIdx:
+ WmAttrGetModifiedStatus(macWindow, result);
+ break;
+ case WmAttrTitlePathIdx:
+ WmAttrGetTitlePath(macWindow, result);
+ break;
+ case WmAttrAlphaIdx:
+ WmAttrGetAlpha(macWindow, result);
+ break;
+ }
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+ }
+
+ if ( (objc - 3) % 2 != 0 ) {
+ Tcl_WrongNumArgs(interp, 3, objv,
+ "?-modified ?bool?? ?-titlepath ?path?? ?-alpha ?double??");
+ return TCL_ERROR;
+ }
for (i = 3; i < objc; i += 2) {
- int 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);
+ int boolean;
+ OSErr err;
+ FSRef ref;
+ AliasHandle alias;
+ Boolean isDirectory;
+ double dval;
+
+ if (Tcl_GetIndexFromObj(interp, objv[i], optionTable, "option", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch (index) {
+ case WmAttrModifiedIdx:
+ if (Tcl_GetBooleanFromObj(interp, objv[i+1], &boolean) !=
+ TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = objv[i+1];
+ SetWindowModified(macWindow, boolean);
+ break;
+ case WmAttrTitlePathIdx:
+ 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;
- }
- }
+ err = FSNewAlias(NULL, &ref, &alias);
}
- }
- } else {
- goto configArgs;
- }
- if (i == objc - 2) {
- /* Want to return last result */
- Tcl_SetObjResult(interp, objv[i+1]);
- }
+ if (err == noErr) {
+ err = SetWindowProxyAlias(macWindow, alias);
+ }
+ if (err != noErr) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj("couldn't set window proxy title path",
+ -1));
+ return TCL_ERROR;
+ } else {
+ result = objv[i+1];
+ }
+ break;
+ case WmAttrAlphaIdx:
+ if (Tcl_GetDoubleFromObj(interp, objv[i+1], &dval) !=
+ TCL_OK) {
+ return TCL_ERROR;
+ }
+ /*
+ * The user should give (transparent) 0 .. 1.0 (opaque)
+ */
+ if (dval < 0.0) {
+ dval = 0.0;
+ } else if (dval > 1.0) {
+ dval = 1.0;
+ }
+ result = Tcl_NewDoubleObj(dval);
+ SetWindowAlpha(macWindow, dval);
+ break;
+ }
}
+ Tcl_SetObjResult(interp, result);
return TCL_OK;
}
+
+/*
+ *----------------------------------------------------------------------
+ * WmAttrGetModifiedStatus --
+ *
+ * Helper procedure to retrieve the -modified option for the wm
+ * attributes command.
+ *
+ * Results:
+ * Nothing.
+ *
+ * Side effects:
+ * Appends the modified status of the given window to the Tcl_Obj
+ * passed in.
+ *
+ *----------------------------------------------------------------------
+ */
+static void WmAttrGetModifiedStatus(WindowRef macWindow, Tcl_Obj *result)
+{
+ Tcl_AppendObjToObj(result, Tcl_NewBooleanObj(
+ (IsWindowModified(macWindow) == true)));
+}
+
+/*
+ *----------------------------------------------------------------------
+ * WmAttrGetTitlePath --
+ *
+ * Helper procedure to retrieve the -titlepath option for the wm
+ * attributes command.
+ *
+ * Results:
+ * Nothing.
+ *
+ * Side effects:
+ * Appends the proxy file path of the given window to the Tcl_Obj
+ * passed in.
+ *
+ *----------------------------------------------------------------------
+ */
+static void WmAttrGetTitlePath(WindowRef macWindow, Tcl_Obj *result)
+{
+ FSRef ref;
+ AliasHandle alias;
+ Boolean wasChanged;
+ UInt8 path[2048];
+ OSStatus err;
+ err = GetWindowProxyAlias(macWindow, &alias);
+ if (err == noErr) {
+ err = FSResolveAlias(NULL, alias, &ref, &wasChanged);
+ }
+ if (err == noErr) {
+ err = FSRefMakePath(&ref, path, 2048);
+ }
+ if (err == noErr) {
+ Tcl_AppendToObj(result, path, -1);
+ } else {
+ Tcl_AppendToObj(result, "{}", -1);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ * WmAttrGetAlpha --
+ *
+ * Helper procedure to retrieve the -alpha option for the wm
+ * attributes command.
+ *
+ * Results:
+ * Nothing.
+ *
+ * Side effects:
+ * Appends the alpha value of the given window to the Tcl_Obj
+ * passed in.
+ *
+ *----------------------------------------------------------------------
+ */
+static void WmAttrGetAlpha(WindowRef macWindow, Tcl_Obj *result)
+{
+ float fval;
+ if (GetWindowAlpha(macWindow, &fval) != noErr) {
+ fval = 1.0;
+ }
+ Tcl_AppendObjToObj(result, Tcl_NewDoubleObj(fval));
+}
+
/*
*----------------------------------------------------------------------
*
@@ -1451,16 +1597,16 @@ Tcl_Obj *CONST objv[]; /* Argument objects. */
wmPtr->hints.flags &= ~IconPixmapHint;
} else {
OSErr err;
- FSSpec spec;
+ AliasHandle alias;
FSRef ref;
Boolean isDirectory;
err = FSPathMakeRef(Tcl_GetStringFromObj(objv[3], NULL), &ref, &isDirectory);
if (err == noErr) {
- err = FSGetCatalogInfo (&ref, kFSCatInfoNone, NULL, NULL, &spec, NULL);
+ err = FSNewAlias(NULL, &ref, &alias);
if (err == noErr) {
WindowRef macWin
= GetWindowFromPort(TkMacOSXGetDrawablePort(winPtr->window));
- SetWindowProxyFSSpec(macWin, &spec);
+ SetWindowProxyAlias(macWin, alias);
return TCL_OK;
}
}