summaryrefslogtreecommitdiffstats
path: root/mac
diff options
context:
space:
mode:
authorstanton <stanton@noemail.net>1998-09-29 00:25:04 (GMT)
committerstanton <stanton@noemail.net>1998-09-29 00:25:04 (GMT)
commitf110d4e2a4b45b23f037e22b18041093a18a028f (patch)
tree99c199f65b7d32755dc8f0ee5cc773bd922a74a6 /mac
parent44fe62a9cda522475be53f14654970aaa3d4a648 (diff)
downloadtk-f110d4e2a4b45b23f037e22b18041093a18a028f.zip
tk-f110d4e2a4b45b23f037e22b18041093a18a028f.tar.gz
tk-f110d4e2a4b45b23f037e22b18041093a18a028f.tar.bz2
initial tk8.1a2 version
FossilOrigin-Name: 644396f2dabc649ad5784768cfe962017d991df1
Diffstat (limited to 'mac')
-rw-r--r--mac/MW_TkHeader.pch78
-rw-r--r--mac/README107
-rw-r--r--mac/bugs.doc8
-rw-r--r--mac/tkMac.h39
-rw-r--r--mac/tkMacAppInit.c6
-rw-r--r--mac/tkMacBitmap.c29
-rw-r--r--mac/tkMacButton.c428
-rw-r--r--mac/tkMacClipboard.c4
-rw-r--r--mac/tkMacConfig.c45
-rw-r--r--mac/tkMacCursor.c60
-rw-r--r--mac/tkMacDefault.h5
-rw-r--r--mac/tkMacDialog.c776
-rw-r--r--mac/tkMacEmbed.c186
-rw-r--r--mac/tkMacFont.c1984
-rw-r--r--mac/tkMacHLEvents.c8
-rw-r--r--mac/tkMacInit.c4
-rw-r--r--mac/tkMacInt.h21
-rw-r--r--mac/tkMacKeyboard.c70
-rw-r--r--mac/tkMacLibrary.r4
-rw-r--r--mac/tkMacMenu.c546
-rw-r--r--mac/tkMacPort.h5
-rw-r--r--mac/tkMacProjects.sit.hqx800
-rw-r--r--mac/tkMacResource.r24
-rw-r--r--mac/tkMacSend.c330
-rw-r--r--mac/tkMacShLib.exp2
-rw-r--r--mac/tkMacSubwindows.c130
-rw-r--r--mac/tkMacTest.c3
-rw-r--r--mac/tkMacWindowMgr.c126
-rw-r--r--mac/tkMacWm.c222
-rw-r--r--mac/tkMacXStubs.c7
30 files changed, 4534 insertions, 1523 deletions
diff --git a/mac/MW_TkHeader.pch b/mac/MW_TkHeader.pch
index 7b7e2a4..a049f62 100644
--- a/mac/MW_TkHeader.pch
+++ b/mac/MW_TkHeader.pch
@@ -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.
*
- * SCCS: @(#) MW_TkHeader.pch 1.26 97/11/20 19:37:29
+ * SCCS: @(#) MW_TkHeader.pch 1.29 98/02/18 16:23:13
*/
/*
@@ -31,42 +31,13 @@
#pragma precompile_target "MW_TkHeader68K"
#endif
-/*
- * Macintosh Tcl must be compiled with certain compiler options to
- * ensure that it will work correctly. The following pragmas are
- * used to ensure that those options are set correctly. An error
- * will occur at compile time if they are not set correctly.
- */
+#include "tclMacCommonDefines.h"
-#if !__option(enumsalwaysint)
-#error Tcl requires the Metrowerks setting "Enums always ints".
-#endif
-
-#if !defined(__POWERPC__)
-#if !__option(far_data)
-#error Tcl requires the Metrowerks setting "Far data".
-#endif
-#endif
-
-#if !defined(__POWERPC__)
-#if !__option(fourbyteints)
-#error Tcl requires the Metrowerks setting "4 byte ints".
-#endif
-#endif
-
-#if !defined(__POWERPC__)
-#if !__option(IEEEdoubles)
-#error Tcl requires the Metrowerks setting "8 byte doubles".
-#endif
+#ifdef TCL_DEBUG
+#define TK_TEST
#endif
/*
- * The define is used most everywhere to tell Tk (or any Tk
- * extensions) that we are compiling for the Macintosh platform.
- */
-#define MAC_TCL
-
-/*
* The following defines are for the Xlib.h file to force
* it to generate prototypes in the way we need it. This is
* defined here in case X.h & company are ever included before
@@ -77,47 +48,6 @@
#define NeedWidePrototypes 0
/*
- * The following defines control the behavior of the Macintosh
- * Universial Headers.
- */
-
-#define SystemSevenOrLater 1
-#define STRICT_CONTROLS 0
-#define STRICT_WINDOWS 0
-
-/*
- * The appearance manager has not yet been shiped by Apple (10/29/97).
- * It's currently in beta testing which is why we were able to write
- * some code that depends on it. If you have access to the appearance
- * manager you can define the symbol HAVE_APPEARANCE below to compile
- * the code that uses the new appearance manager.
- */
-
-/* #define HAVE_APPEARANCE 1 */
-
-/*
- * Define the following symbol if you want
- * comprehensive debugging turned on.
- */
-
-/* #define TCL_DEBUG */
-
-#ifdef TCL_DEBUG
-# define TCL_MEM_DEBUG
-# define TK_TEST
-# define TCL_TEST
-#endif
-
-/*
- * Apple's Universal Headers 2.0 & 3.0 change alot of names and constants.
- * We will switch to the new names as soon as we can be reasonably sure the
- * number of people with older versions of CodeWarrior, who will then not be
- * able to build Tcl/Tk, is negligible.
- */
-
-#define OLDROUTINENAMES 1
-
-/*
* Place any includes below that will are needed by the majority of the
* and is OK to be in any file in the system.
*/
diff --git a/mac/README b/mac/README
index 3c8824a..e811a3a 100644
--- a/mac/README
+++ b/mac/README
@@ -1,10 +1,11 @@
-Tk 8.0 for Macintosh
+Tk 8.1 for Macintosh
-by Ray Johnson
+by Ray Johnson and Jim Ingham
Sun Microsystems Laboratories
rjohnson@eng.sun.com
+jim.ingham@sun.com
-SCCS: @(#) README 1.30 97/11/20 22:06:57
+SCCS: @(#) README 1.33 98/02/18 11:23:12
1. Introduction
---------------
@@ -18,50 +19,12 @@ directory.
2. What's new?
-------------
-Native Look & Feel!!! We now try really hard to support the
-Macintosh Look & Feel with Tcl/Tk 8.0. We aren't finished but
-it look pretty good. Let me know what are the most "un-mac like"
-problems and I'll fix them as quickly as I can.
-
-The button, checkbutton, radiobutton, and scrollbar widgets actually
-use the Mac toolbox controls. This means that they will track the
-look&feel if you use extension that change the appearance of
-applications (like Aaron.) We also use "system" colors so the default
-backgrounds etc. will also change colors. We plan to support this
-feature - so let me know if something doesn't work quite right.
-Unfortunantly, we are not able to change the colors of buttons under
-MacOS 8. We are working on a solution to this.
-In the meantime, if you really must have colored buttons, turn off the
-"System-wide platinum appearance" option in the Appearance Control Panel,
-and you will get the System 7, colorable, buttons back.
-
-We also now support native menus! By using the new -menu option
-on toplevels you can have a menubar that is cross platform. You
-can also place Tk menus in the Apple and Help menus! Check out
-the documentation for more details. Syd Polk <icepick@eng.sun.com> is
-the author of the new menu code. Feel free to contact him if you
-have questions or comments about the menu mechanism.
-
-The "tk_messageBox" command on the Macintosh is now much more
-mac-like. I'll probably still need to adjust this more - but it
-looks a hell of alot better than it did before.
-
-I've also added a command that allows you to get more native window
-styles. However, we have yet to decide on a cross platform solution
-to the problem of varying window styles. None the less, I thought
-it would be use full to add the capability in an unsupported means
-to tide you over until a better solution is available. The command
-is called "unsupported1". It can be used in the following way:
-
- toplevel .foo; unsupported1 style .foo zoomDocProc
-
-The above command will create a document window with a zoom box.
-Type "unsupported1 style . ???" to get a list of the supported
-styles. The command works like "wm overrideredirect" - you must
-make the call before the window is mapped.
-
-As always - report the bugs you find - including asthetic ones
-in the look & feel of widgets.
+All the widgets will now display internationalized text!
+
+The widget configuration package has been changed to support the new object
+model introduced with the 8.0 compiler. For now the old configuration
+package is retained, and in fact, only the menu and button widgets use
+the new package.
3. Mac specific features
------------------------
@@ -94,8 +57,8 @@ pointers to where you can find more information about the feature.
Mac version of Tk allows you to use several Mac specific icons. See
the GetBitmap.3 man page for a complete list.
-* The send command does not yet work on the Macintosh. We hope to
- have it available in Tk 8.1.
+* The send command works among interpreters in the same application. We hope to
+ have the complete implementation available in Tk 8.1.
* The -use and -container options almost work. The focus bugs that
were in Tk8.0 final have been fixed. But there are still some
@@ -109,7 +72,7 @@ Macintosh Tk is distributed in three different forms. This
should make it easier to only download what you need. The
packages are as follows:
-mactk8.0.sea.hqx
+mactk8.1.sea.hqx
This distribution is a "binary" only release. It contains an
installer program that will install a 68k, PowerPC, or Fat
@@ -117,13 +80,13 @@ mactk8.0.sea.hqx
the Tcl & Tk libraries in the Extensions folder inside your
System Folder. (No "INIT"'s or Control Pannels are installed.)
-mactcltk-full-8.0.sea.hqx
+mactcltk-full-8.1.sea.hqx
This release contains the full release of Tcl and Tk for the
Macintosh plus the More Files package on which Macintosh Tcl and
Tk rely.
-mactk-source-8.0.sea.hqx
+mactk-source-8.1.sea.hqx
This release contains the complete source to Tk for the Macintosh
In addition, Metrowerks CodeWarrior libraries and project files
@@ -172,44 +135,36 @@ available (see below).
In order to compile Macintosh Tk you must have the
following items:
- CodeWarrior Pro 1 or higher (CodeWarrior release 9 or higher can work
- and we have project files, but we are depricating support)
- Mac Tcl 8.0 (source)
+ CodeWarrior Pro 2 or higher
+ Mac Tcl 8.1 (source)
(which requires More Files 1.4.2 or 1.4.3)
- Mac Tk 8.0 (source)
+ Mac Tk 8.1 (source)
The project files included with the Mac Tcl source should work
fine. The only thing you may need to update are the access paths.
-As with Tcl, there is something in the initial release of the CW Pro 2
-linker that rendersthe CFM68K version of Wish very unstable. I am
-working with Metrowerks to resolve the issue.
+As with Tcl, you need to upgrade to the 2.0.1 version of the C
+compilers or later to build the CFM68K version of Tcl/Tk.
Special notes:
* Check out the file bugs.doc for information about known bugs.
* We are starting to support the new Appearance Manager that shipped
- with MacOS 8. At this point, the only feature that we are using is
- the API to Iconify windows (so that wm iconify will work). However,
- as of the release of Tk8.0p1, the SDK from Apple is still in Beta, so
- we cannot ship it. So support for the Appearance Manager is turned off
- in the source version of Tk8.0p1.
- If you want to build Tk, and want to get the Appearance Manager features,
- then need to do the following:
- 1) get the SDK from Apple
- 2) Uncomment the #define HAVE_APPEARANCE line in tk8.0:mac:MW_TkHeader.pch
- 3) Add the Appearance.lib to tk8.0:mac:TkShells.¼, and put the include
- directory of the SDK on your path in this project, and TkLibraries.¼.
+ with MacOS 8. wm iconify uses it, and the coloring of the
+ backgrounds of radiobuttons & checkbuttons now works under
+ Appearance. Tk correctly checks the Gestalt for Appearance, so you
+ do not have to install it on your target machines. However, you do
+ have to have the header and stub files to build it. These come with
+ CWPro 2, and are also available now from Apple.
+
7. About Dialog
---------------
-There is now a way to replace the default dialog box for the Wish
-application. If you create the tcl procedure "tkAboutDialog" it will
-be called instead of creating the default dialog box. Your procedure
-is then responsible for displaying a window, removing it, etc. This
-interface is experimental and may change in the future - tell me what
-you think of it.
+The prefered method for replacing the about dialog is to replace the
+main menubar of the application, using the -menu option for the "."
+window. Then add a cascade called .mainMenu.apple to your mainMenu,
+and you can put an about item in here WITH YOUR OWN LABEL!
8. Apple Events
---------------
diff --git a/mac/bugs.doc b/mac/bugs.doc
index e522d8c..5e5a3e8 100644
--- a/mac/bugs.doc
+++ b/mac/bugs.doc
@@ -4,7 +4,7 @@ by Ray Johnson
Sun Microsystems Laboratories
rjohnson@eng.sun.com
-SCCS: @(#) bugs.doc 1.10 97/11/03 17:16:00
+SCCS: @(#) bugs.doc 1.11 98/02/18 13:24:41
We are now very close to passing the test suite for Tk. We are very
interested in finding remaining bugs that still linger. Please let us
@@ -26,7 +26,11 @@ Known bugs:
container, so you can watch that instead.
All the focus bugs in Tk8.0 have been fixed, however.
-* The send command is not yet implemented.
+* The send command is only implemented within the same app.
+
+* You cannot color buttons, and the indicators for radiobuttons and
+ checkbuttons under Appearance. They will always use the current
+ Theme color. But, then, you are not supposed to...
* Drawing is not really correct. This shows up mostly in the canvas
when line widths are greater than one. Unfortunantly, this will not
diff --git a/mac/tkMac.h b/mac/tkMac.h
index ce41c81..87c005a 100644
--- a/mac/tkMac.h
+++ b/mac/tkMac.h
@@ -8,13 +8,15 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tkMacInt.h 1.58 97/05/06 16:45:18
+ * SCCS: %Z% %M% %I% %E% %U%
*/
#ifndef _TKMAC
#define _TKMAC
#include <Windows.h>
+#include <QDOffscreen.h>
+#include "tkInt.h"
/*
* "export" is a MetroWerks specific pragma. It flags the linker that
@@ -32,21 +34,46 @@
EXTERN QDGlobalsPtr tcl_macQdPtr;
+/*
+ * Structures and function types for handling Netscape-type in process
+ * embedding where Tk does not control the top-level
+ */
+typedef int (Tk_MacEmbedRegisterWinProc) (int winID, Tk_Window window);
+typedef GWorldPtr (Tk_MacEmbedGetGrafPortProc) (Tk_Window window);
+typedef int (Tk_MacEmbedMakeContainerExistProc) (Tk_Window window);
+typedef void (Tk_MacEmbedGetClipProc) (Tk_Window window, RgnHandle rgn);
+typedef void (Tk_MacEmbedGetOffsetInParentProc) (Tk_Window window, Point *ulCorner);
+
/*
- * The following functions are needed to create a shell, and so they must be exported
- * from the Tk library. However, these are not the final form of these interfaces, so
- * they are not currently supported as public interfaces.
+ * Mac Specific functions that are available to extension writers.
*/
+
+EXTERN void Tk_MacSetEmbedHandler _ANSI_ARGS_((
+ Tk_MacEmbedRegisterWinProc *registerWinProcPtr,
+ Tk_MacEmbedGetGrafPortProc *getPortProcPtr,
+ Tk_MacEmbedMakeContainerExistProc *containerExistProcPtr,
+ Tk_MacEmbedGetClipProc *getClipProc,
+ Tk_MacEmbedGetOffsetInParentProc *getOffsetProc));
+
+EXTERN void Tk_MacTurnOffMenus _ANSI_ARGS_ (());
+EXTERN void Tk_MacTkOwnsCursor _ANSI_ARGS_ ((int tkOwnsIt));
+
/*
* These functions are currently in tkMacInt.h. They are just copied over here
* so they can be exported.
*/
EXTERN void TkMacInitMenus _ANSI_ARGS_((Tcl_Interp *interp));
-EXTERN void TkMacInitAppleEvents _ANSI_ARGS_((Tcl_Interp *interp));
+EXTERN void TkMacInitAppleEvents _ANSI_ARGS_((Tcl_Interp *interp));
+
+EXTERN int TkMacConvertEvent _ANSI_ARGS_((EventRecord *eventPtr));
+EXTERN int TkMacConvertTkEvent _ANSI_ARGS_((EventRecord *eventPtr,
+ Window window));
+EXTERN void TkGenWMConfigureEvent _ANSI_ARGS_((Tk_Window tkwin,
+ int x, int y, int width, int height, int flags));
+EXTERN void TkMacInvalClipRgns _ANSI_ARGS_((TkWindow *winPtr));
-EXTERN int TkMacConvertEvent _ANSI_ARGS_((EventRecord *eventPtr));
#pragma export reset
diff --git a/mac/tkMacAppInit.c b/mac/tkMacAppInit.c
index ebc2c18..226127f 100644
--- a/mac/tkMacAppInit.c
+++ b/mac/tkMacAppInit.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.
*
- * SCCS: @(#) tkMacAppInit.c 1.35 97/07/28 11:18:55
+ * SCCS: @(#) tkMacAppInit.c 1.36 97/11/07 21:20:46
*/
#include <Gestalt.h>
@@ -108,7 +108,7 @@ main(
*
* Results:
* Returns a standard Tcl completion code, and leaves an error
- * message in interp->result if an error occurs.
+ * message in the interp's result if an error occurs.
*
* Side effects:
* Depends on the startup script.
@@ -307,7 +307,7 @@ SetupMainInterp(
return TCL_OK;
error:
- panic(interp->result);
+ panic(Tcl_GetStringResult(interp));
return TCL_ERROR;
}
diff --git a/mac/tkMacBitmap.c b/mac/tkMacBitmap.c
index fd08193..6571d43 100644
--- a/mac/tkMacBitmap.c
+++ b/mac/tkMacBitmap.c
@@ -3,12 +3,12 @@
*
* This file handles the implementation of native bitmaps.
*
- * Copyright (c) 1996 Sun Microsystems, Inc.
+ * Copyright (c) 1996-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.
*
- * SCCS: @(#) tkMacBitmap.c 1.4 96/12/13 11:13:16
+ * SCCS: @(#) tkMacBitmap.c 1.7 98/01/22 17:00:58
*/
#include "tkPort.h"
@@ -82,7 +82,7 @@ static BuiltInIcon builtInIcons[] = {
*
* Results:
* A standard Tcl result. If an error occurs then TCL_ERROR is
- * returned and a message is left in interp->result.
+ * 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
@@ -128,7 +128,7 @@ TkpDefineNativeBitmaps()
*
* Results:
* A standard Tcl result. If an error occurs then TCL_ERROR is
- * returned and a message is left in interp->result.
+ * 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
@@ -188,7 +188,7 @@ TkpCreateNativeBitmap(
*
* Results:
* A standard Tcl result. If an error occurs then TCL_ERROR is
- * returned and a message is left in interp->result.
+ * 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
@@ -210,19 +210,28 @@ TkpGetNativeAppBitmap(
GWorldPtr destPort;
Rect destRect;
Handle resource;
- int type;
+ int type, 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;
- c2pstr(name);
- resource = GetNamedResource('cicn', (StringPtr) name);
+ resource = GetNamedResource('cicn', nativeName);
if (resource != NULL) {
type = TYPE3;
} else {
- resource = GetNamedResource('ICON', (StringPtr) name);
+ resource = GetNamedResource('ICON', nativeName);
if (resource != NULL) {
type = TYPE2;
}
}
- p2cstr((StringPtr) name);
if (resource == NULL) {
return NULL;
diff --git a/mac/tkMacButton.c b/mac/tkMacButton.c
index 767baff..287c2ef 100644
--- a/mac/tkMacButton.c
+++ b/mac/tkMacButton.c
@@ -2,20 +2,21 @@
* tkMacButton.c --
*
* This file implements the Macintosh specific portion of the
- * button widgets.
+ * button widgets.
*
* Copyright (c) 1996-1997 by Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tkMacButton.c 1.18 97/11/20 18:27:21
+ * SCCS: @(#) tkMacButton.c 1.20 98/02/18 10:48:42
*/
#include "tkButton.h"
#include "tkMacInt.h"
#include <Controls.h>
#include <LowMem.h>
+#include <Appearance.h>
/*
* Some defines used to control what type of control is drawn.
@@ -43,18 +44,36 @@ static CCTabHandle radioTabHandle;
static PixMapHandle oldPixPtr;
/*
+ * These functions are used when Appearance is present.
+ * By embedding all our controls in a userPane control,
+ * we can color the background of the text in radiobuttons
+ * and checkbuttons. Thanks to Peter Gontier of Apple DTS
+ * for help on this one.
+ */
+
+static ControlRef userPaneHandle;
+static RGBColor gUserPaneBackground = { ~0, ~0, ~0};
+static pascal OSErr SetUserPaneDrawProc(ControlRef control,
+ ControlUserPaneDrawProcPtr upp);
+static pascal OSErr SetUserPaneSetUpSpecialBackgroundProc(ControlRef control,
+ ControlUserPaneBackgroundProcPtr upp);
+static pascal void UserPaneDraw(ControlRef control, ControlPartCode cpc);
+static pascal void UserPaneBackgroundProc(ControlHandle,
+ ControlBackgroundPtr info);
+
+/*
* Forward declarations for procedures defined later in this file:
*/
-static int UpdateControlColors _ANSI_ARGS_((TkButton *butPtr,
- ControlRef controlHandle, CCTabHandle ccTabHandle,
- RGBColor *saveColorPtr));
-static void DrawBufferedControl _ANSI_ARGS_((TkButton *butPtr,
- GWorldPtr destPort));
-static void ChangeBackgroundWindowColor _ANSI_ARGS_((
- WindowRef macintoshWindow, RGBColor rgbColor,
- RGBColor *oldColor));
-static void ButtonExitProc _ANSI_ARGS_((ClientData clientData));
+static int UpdateControlColors _ANSI_ARGS_((TkButton *butPtr,
+ ControlRef controlHandle, CCTabHandle ccTabHandle,
+ RGBColor *saveColorPtr));
+static void DrawBufferedControl _ANSI_ARGS_((TkButton *butPtr,
+ GWorldPtr destPort));
+static void ChangeBackgroundWindowColor _ANSI_ARGS_((
+ WindowRef macintoshWindow, RGBColor rgbColor,
+ RGBColor *oldColor));
+static void ButtonExitProc _ANSI_ARGS_((ClientData clientData));
/*
* The class procedure table for the button widgets.
@@ -137,15 +156,16 @@ TkpDisplayButton(
}
border = butPtr->normalBorder;
- if ((butPtr->state == tkDisabledUid) && (butPtr->disabledFg != NULL)) {
+ if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
gc = butPtr->disabledGC;
- } else if ((butPtr->type == TYPE_BUTTON) && (butPtr->state == tkActiveUid)) {
+ } else if ((butPtr->type == TYPE_BUTTON)
+ && (butPtr->state == STATE_ACTIVE)) {
gc = butPtr->activeTextGC;
border = butPtr->activeBorder;
} else {
gc = butPtr->normalTextGC;
}
- if ((butPtr->flags & SELECTED) && (butPtr->state != tkActiveUid)
+ if ((butPtr->flags & SELECTED) && (butPtr->state != STATE_ACTIVE)
&& (butPtr->selectBorder != NULL) && !butPtr->indicatorOn) {
border = butPtr->selectBorder;
}
@@ -173,9 +193,18 @@ TkpDisplayButton(
pixmap = Tk_GetPixmap(butPtr->display, Tk_WindowId(tkwin),
Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
- Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
- Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
-
+ /*
+ * See the comment in UpdateControlColors as to why we use the
+ * highlightbackground for the border of Macintosh buttons.
+ */
+
+ if (butPtr->type == TYPE_BUTTON) {
+ Tk_Fill3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0, 0,
+ Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
+ } else {
+ Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
+ Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
+ }
if (butPtr->type == TYPE_LABEL) {
drawType = DRAW_LABEL;
@@ -274,7 +303,7 @@ TkpDisplayButton(
* must temporarily modify the GC.
*/
- if ((butPtr->state == tkDisabledUid)
+ if ((butPtr->state == STATE_DISABLED)
&& ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) {
if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
&& (butPtr->selectBorder != NULL)) {
@@ -361,7 +390,7 @@ TkpComputeButtonGeometry(
* highlight width as there is also one pixel of spacing.
*/
- if (butPtr->defaultState != tkDisabledUid) {
+ if (butPtr->defaultState != DEFAULT_DISABLED) {
butPtr->inset += butPtr->highlightWidth;
}
butPtr->indicatorSpace = 0;
@@ -388,8 +417,8 @@ TkpComputeButtonGeometry(
} else {
Tk_FreeTextLayout(butPtr->textLayout);
butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
- butPtr->text, -1, butPtr->wrapLength, butPtr->justify, 0,
- &butPtr->textWidth, &butPtr->textHeight);
+ Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
+ butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);
width = butPtr->textWidth;
height = butPtr->textHeight;
@@ -491,36 +520,74 @@ DrawBufferedControl(
/*
* Create a dummy window that we can draw to. We will
- * actually replace this windows bitmap with a the one
+ * actually replace this window's bitmap with the one
* we want to draw to at a later time. This window and
* the data structures attached to it are only deallocated
* on exit of the application.
*/
-
- windowRef = NewCWindow(NULL, &geometry, "\pempty", false,
+
+ windowRef = NewCWindow(NULL, &geometry, "\pempty", false,
zoomDocProc, (WindowRef) -1, true, 0);
if (windowRef == NULL) {
panic("Can't allocate buffer window.");
}
-
+
/*
* Now add the three standard controls to hidden window. We
* only create one of each and reuse them for every widget in
* Tk.
+ * Under Appearance, we have to embed the controls in a UserPane
+ * control, so that we can color the background text in
+ * radiobuttons and checkbuttons.
*/
SetPort(windowRef);
- buttonHandle = NewControl(windowRef, &geometry, "\p",
- false, 1, 0, 1, pushButProc, (SInt32) 0);
- checkHandle = NewControl(windowRef, &geometry, "\p",
- false, 1, 0, 1, checkBoxProc, (SInt32) 0);
- radioHandle = NewControl(windowRef, &geometry, "\p",
- false, 1, 0, 1, radioButProc, (SInt32) 0);
- ((CWindowPeek) windowRef)->visible = true;
-
- buttonTabHandle = (CCTabHandle) NewHandle(sizeof(CtlCTab));
- checkTabHandle = (CCTabHandle) NewHandle(sizeof(CtlCTab));
- radioTabHandle = (CCTabHandle) NewHandle(sizeof(CtlCTab));
+
+ if (TkMacHaveAppearance()) {
+
+ OSErr err;
+ ControlRef dontCare;
+
+ /* Adding UserPaneBackgroundProcs to the root control does
+ * not seem to work, so we have to add another UserPane to
+ * the root control.
+ */
+
+ err = CreateRootControl(windowRef, &dontCare);
+ if (err != noErr) {
+ panic("Can't create root control in DrawBufferedControl");
+ }
+
+ userPaneHandle = NewControl(windowRef, &geometry, "\p",
+ true, kControlSupportsEmbedding|kControlHasSpecialBackground,
+ 0, 1, kControlUserPaneProc, (SInt32) 5);
+ SetUserPaneSetUpSpecialBackgroundProc(userPaneHandle,
+ UserPaneBackgroundProc);
+ SetUserPaneDrawProc(userPaneHandle, UserPaneDraw);
+
+ buttonHandle = NewControl(windowRef, &geometry, "\p",
+ false, 1, 0, 1, kControlPushButtonProc, (SInt32) 6);
+ EmbedControl(buttonHandle, userPaneHandle);
+ checkHandle = NewControl(windowRef, &geometry, "\p",
+ false, 1, 0, 1, kControlCheckBoxProc, (SInt32) 7);
+ EmbedControl(checkHandle, userPaneHandle);
+ radioHandle = NewControl(windowRef, &geometry, "\p",
+ false, 1, 0, 1, kControlRadioButtonProc, (SInt32) 8);
+ EmbedControl(radioHandle, userPaneHandle);
+ ((CWindowPeek) windowRef)->visible = true;
+ } else {
+ buttonHandle = NewControl(windowRef, &geometry, "\p",
+ false, 1, 0, 1, pushButProc, (SInt32) 0);
+ checkHandle = NewControl(windowRef, &geometry, "\p",
+ false, 1, 0, 1, checkBoxProc, (SInt32) 0);
+ radioHandle = NewControl(windowRef, &geometry, "\p",
+ false, 1, 0, 1, radioButProc, (SInt32) 0);
+ ((CWindowPeek) windowRef)->visible = true;
+
+ buttonTabHandle = (CCTabHandle) NewHandle(sizeof(CtlCTab));
+ checkTabHandle = (CCTabHandle) NewHandle(sizeof(CtlCTab));
+ radioTabHandle = (CCTabHandle) NewHandle(sizeof(CtlCTab));
+ }
/*
* Remove our window from the window list. This way our
@@ -556,10 +623,29 @@ DrawBufferedControl(
}
/*
+ * Now swap in the passed in GWorld for the portBits of our fake
+ * window. We also adjust various fields in the WindowRecord to make
+ * the system think this is a normal window.
+ * Note, we can use DrawControlInCurrentPort under Appearance, so we don't
+ * need to swap pixmaps.
+ */
+
+ if (!TkMacHaveAppearance()) {
+ ((CWindowPeek) windowRef)->port.portPixMap = destPort->portPixMap;
+ }
+
+ ((CWindowPeek) windowRef)->port.portRect = destPort->portRect;
+ RectRgn(((CWindowPeek) windowRef)->port.visRgn, &destPort->portRect);
+ RectRgn(((CWindowPeek) windowRef)->strucRgn, &destPort->portRect);
+ RectRgn(((CWindowPeek) windowRef)->updateRgn, &destPort->portRect);
+ RectRgn(((CWindowPeek) windowRef)->contRgn, &destPort->portRect);
+ PortChanged(windowRef);
+
+ /*
* Set up control in hidden window to match what we need
- * to draw in the buffered window.
+ * to draw in the buffered window.
*/
-
+
switch (butPtr->type) {
case TYPE_BUTTON:
controlHandle = buttonHandle;
@@ -574,21 +660,38 @@ DrawBufferedControl(
ccTabHandle = checkTabHandle;
break;
}
+
(**controlHandle).contrlRect.left = butPtr->inset;
(**controlHandle).contrlRect.top = butPtr->inset;
(**controlHandle).contrlRect.right = Tk_Width(butPtr->tkwin)
- butPtr->inset;
(**controlHandle).contrlRect.bottom = Tk_Height(butPtr->tkwin)
- butPtr->inset;
- if ((**controlHandle).contrlVis != 255) {
- (**controlHandle).contrlVis = 255;
- }
+
+ /*
+ * Setting the control visibility by hand does not
+ * seem to work under Appearance.
+ */
+
+ if (TkMacHaveAppearance()) {
+ SetControlVisibility(controlHandle, true, false);
+ (**userPaneHandle).contrlRect.left = 0;
+ (**userPaneHandle).contrlRect.top = 0;
+ (**userPaneHandle).contrlRect.right = Tk_Width(butPtr->tkwin);
+ (**userPaneHandle).contrlRect.bottom = Tk_Height(butPtr->tkwin);
+ } else {
+ (**controlHandle).contrlVis = 255;
+ }
+
+
+
if (butPtr->flags & SELECTED) {
(**controlHandle).contrlValue = 1;
} else {
(**controlHandle).contrlValue = 0;
}
- if (butPtr->state == tkActiveUid) {
+
+ if (butPtr->state == STATE_ACTIVE) {
switch (butPtr->type) {
case TYPE_BUTTON:
(**controlHandle).contrlHilite = kControlButtonPart;
@@ -600,27 +703,13 @@ DrawBufferedControl(
(**controlHandle).contrlHilite = kControlCheckBoxPart;
break;
}
- } else if (butPtr->state == tkDisabledUid) {
+ } else if (butPtr->state == STATE_DISABLED) {
(**controlHandle).contrlHilite = kControlInactivePart;
} else {
(**controlHandle).contrlHilite = kControlNoPart;
}
/*
- * Now swap in the passed in GWorld for the portBits of our fake
- * window. We also adjust various fields in the WindowRecord to make
- * the system think this is a normal window.
- */
-
- ((CWindowPeek) windowRef)->port.portPixMap = destPort->portPixMap;
- ((CWindowPeek) windowRef)->port.portRect = destPort->portRect;
- RectRgn(((CWindowPeek) windowRef)->port.visRgn, &destPort->portRect);
- RectRgn(((CWindowPeek) windowRef)->strucRgn, &destPort->portRect);
- RectRgn(((CWindowPeek) windowRef)->updateRgn, &destPort->portRect);
- RectRgn(((CWindowPeek) windowRef)->contRgn, &destPort->portRect);
- PortChanged(windowRef);
-
- /*
* Before we draw the control we must add the hidden window back to the
* main window list. Otherwise, radiobuttons and checkbuttons will draw
* incorrectly. I don't really know why - but clearly the control draw
@@ -635,14 +724,41 @@ DrawBufferedControl(
* to muck with the colors for the port & window to draw the control
* with the proper Tk colors. If we need to we also draw a default
* ring for buttons.
+ * Under Appearance, we draw the control directly into destPort, and
+ * just set the default control data.
*/
- SetPort(windowRef);
+ if (TkMacHaveAppearance()) {
+ SetPort((GrafPort *) destPort);
+ } else {
+ SetPort(windowRef);
+ }
+
windowColorChanged = UpdateControlColors(butPtr, controlHandle,
ccTabHandle, &saveBackColor);
- Draw1Control(controlHandle);
- if ((butPtr->type == TYPE_BUTTON) &&
- (butPtr->defaultState == tkActiveUid)) {
+
+ if ((butPtr->type == TYPE_BUTTON) && TkMacHaveAppearance()) {
+ Boolean isDefault;
+
+ if (butPtr->defaultState == DEFAULT_ACTIVE) {
+ isDefault = true;
+ } else {
+ isDefault = false;
+ }
+ SetControlData(controlHandle, kControlNoPart,
+ kControlPushButtonDefaultTag,
+ sizeof(isDefault), (Ptr) &isDefault);
+ }
+
+ if (TkMacHaveAppearance()) {
+ DrawControlInCurrentPort(userPaneHandle);
+ } else {
+ Draw1Control(controlHandle);
+ }
+
+ if (!TkMacHaveAppearance() &&
+ (butPtr->type == TYPE_BUTTON) &&
+ (butPtr->defaultState == DEFAULT_ACTIVE)) {
Rect box = (**controlHandle).contrlRect;
RGBColor rgbColor;
@@ -652,21 +768,139 @@ DrawBufferedControl(
InsetRect(&box, -butPtr->highlightWidth, -butPtr->highlightWidth);
FrameRoundRect(&box, 16, 16);
}
+
if (windowColorChanged) {
RGBColor dummyColor;
ChangeBackgroundWindowColor(windowRef, saveBackColor, &dummyColor);
}
/*
- * Clean up: remove the hidden window from the main window list.
+ * Clean up: remove the hidden window from the main window list, and
+ * hide the control we drew.
*/
+ if (TkMacHaveAppearance()) {
+ SetControlVisibility(controlHandle, false, false);
+ } else {
+ (**controlHandle).contrlVis = 0;
+ }
LMSetWindowList((WindowRef) ((CWindowPeek) windowRef)->nextWindow);
}
/*
*--------------------------------------------------------------
*
+ * 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.
+ *
+ *--------------------------------------------------------------
+ */
+pascal OSErr SetUserPaneDrawProc (
+ ControlRef control,
+ ControlUserPaneDrawProcPtr upp)
+{
+ ControlUserPaneDrawUPP myControlUserPaneDrawUPP;
+ myControlUserPaneDrawUPP = NewControlUserPaneDrawProc(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.
+ *
+ *--------------------------------------------------------------
+ */
+pascal OSErr
+SetUserPaneSetUpSpecialBackgroundProc(
+ ControlRef control,
+ ControlUserPaneBackgroundProcPtr upp)
+{
+ ControlUserPaneBackgroundUPP myControlUserPaneBackgroundUPP;
+ myControlUserPaneBackgroundUPP = NewControlUserPaneBackgroundProc(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.
+ *
+ *--------------------------------------------------------------
+ */
+pascal void
+UserPaneDraw(
+ ControlRef control,
+ ControlPartCode cpc)
+{
+ Rect contrlRect = (**control).contrlRect;
+ RGBBackColor (&gUserPaneBackground);
+ 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.
+ *
+ *--------------------------------------------------------------
+ */
+
+pascal void
+UserPaneBackgroundProc(
+ ControlHandle,
+ ControlBackgroundPtr info)
+{
+ if (info->colorDevice) {
+ RGBBackColor (&gUserPaneBackground);
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
* UpdateControlColors --
*
* This function will review the colors used to display
@@ -674,6 +908,9 @@ DrawBufferedControl(
* 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.
*
@@ -692,33 +929,50 @@ UpdateControlColors(
{
XColor *xcolor;
- xcolor = Tk_3DBorderColor(butPtr->normalBorder);
-
- (**ccTabHandle).ccSeed = 0;
- (**ccTabHandle).ccRider = 0;
- (**ccTabHandle).ctSize = 3;
- (**ccTabHandle).ctTable[0].value = cBodyColor;
- TkSetMacColor(xcolor->pixel,
- &(**ccTabHandle).ctTable[0].rgb);
- (**ccTabHandle).ctTable[1].value = cTextColor;
- TkSetMacColor(butPtr->normalFg->pixel,
- &(**ccTabHandle).ctTable[1].rgb);
- (**ccTabHandle).ctTable[2].value = cFrameColor;
- TkSetMacColor(butPtr->highlightColorPtr->pixel,
- &(**ccTabHandle).ctTable[2].rgb);
- SetControlColor(controlHandle, ccTabHandle);
-
- if (((xcolor->pixel >> 24) != CONTROL_BODY_PIXEL) &&
- ((butPtr->type == TYPE_CHECK_BUTTON) ||
- (butPtr->type == TYPE_RADIO_BUTTON))) {
- RGBColor newColor;
+ /*
+ * 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 (TkMacHaveAppearance() && (butPtr->type == TYPE_BUTTON)) {
+ xcolor = Tk_3DBorderColor(butPtr->highlightBorder);
+ } else {
+ xcolor = Tk_3DBorderColor(butPtr->normalBorder);
+ }
+ if (TkMacHaveAppearance()) {
+ TkSetMacColor(xcolor->pixel, &gUserPaneBackground);
+ } else {
+ (**ccTabHandle).ccSeed = 0;
+ (**ccTabHandle).ccRider = 0;
+ (**ccTabHandle).ctSize = 3;
+ (**ccTabHandle).ctTable[0].value = cBodyColor;
+ TkSetMacColor(xcolor->pixel,
+ &(**ccTabHandle).ctTable[0].rgb);
+ (**ccTabHandle).ctTable[1].value = cTextColor;
+ TkSetMacColor(butPtr->normalFg->pixel,
+ &(**ccTabHandle).ctTable[1].rgb);
+ (**ccTabHandle).ctTable[2].value = cFrameColor;
+ TkSetMacColor(butPtr->highlightColorPtr->pixel,
+ &(**ccTabHandle).ctTable[2].rgb);
+ SetControlColor(controlHandle, ccTabHandle);
+ if (((xcolor->pixel >> 24) != CONTROL_BODY_PIXEL) &&
+ ((butPtr->type == TYPE_CHECK_BUTTON) ||
+ (butPtr->type == TYPE_RADIO_BUTTON))) {
+ RGBColor newColor;
- TkSetMacColor(xcolor->pixel, &newColor);
- ChangeBackgroundWindowColor((**controlHandle).contrlOwner,
- newColor, saveColorPtr);
- return true;
+ TkSetMacColor(xcolor->pixel, &newColor);
+ ChangeBackgroundWindowColor((**controlHandle).contrlOwner,
+ newColor, saveColorPtr);
+ return true;
+ }
}
-
+
return false;
}
diff --git a/mac/tkMacClipboard.c b/mac/tkMacClipboard.c
index 0c06f1d..1ae497c 100644
--- a/mac/tkMacClipboard.c
+++ b/mac/tkMacClipboard.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tkMacClipboard.c 1.18 97/05/01 15:41:17
+ * SCCS: @(#) tkMacClipboard.c 1.19 97/11/07 21:21:42
*/
#include "tkInt.h"
@@ -32,7 +32,7 @@
* 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 interp->result.
+ * then an error message is left in the interp's result.
*
* Side effects:
* None.
diff --git a/mac/tkMacConfig.c b/mac/tkMacConfig.c
new file mode 100644
index 0000000..83da6cf
--- /dev/null
+++ b/mac/tkMacConfig.c
@@ -0,0 +1,45 @@
+/*
+ * tkMacConfig.c --
+ *
+ * This module implements the Macintosh system defaults for
+ * the configuration package.
+ *
+ * Copyright (c) 1997 by Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * SCCS: @(#) tkMacConfig.c 1.3 97/10/08 10:07:55
+ */
+
+#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. */
+ char *dbName, /* The option database name. */
+ char *className) /* The name of the option class. */
+{
+ return NULL;
+}
diff --git a/mac/tkMacCursor.c b/mac/tkMacCursor.c
index f221189..3f34434 100644
--- a/mac/tkMacCursor.c
+++ b/mac/tkMacCursor.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tkMacCursor.c 1.20 97/09/17 19:33:13
+ * SCCS: @(#) tkMacCursor.c 1.24 98/01/22 17:00:29
*/
#include "tkPort.h"
@@ -64,9 +64,16 @@ static struct CursorName {
static TkMacCursor * gCurrentCursor = NULL; /* A pointer to the current
* cursor. */
-static int gResizeOverride = false; /* A boolean indicating wether
+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
@@ -102,13 +109,23 @@ FindCursorByName(
{
Handle resource;
Str255 curName;
+ int destWrote, inCurLen;
- curName[0] = strlen(string);
- if (curName[0] > 255) {
+ inCurLen = strlen(string);
+ if (inCurLen > 255) {
return;
}
-
- strcpy((char *) curName + 1, string);
+
+ /*
+ * 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) {
@@ -245,7 +262,7 @@ TkCreateCursorFromData(
/*
*----------------------------------------------------------------------
*
- * TkFreeCursor --
+ * TkpFreeCursor --
*
* This procedure is called to release a cursor allocated by
* TkGetCursorByName.
@@ -260,7 +277,7 @@ TkCreateCursorFromData(
*/
void
-TkFreeCursor(
+TkpFreeCursor(
TkCursor *cursorPtr)
{
TkMacCursor *macCursorPtr = (TkMacCursor *) cursorPtr;
@@ -277,8 +294,6 @@ TkFreeCursor(
if (macCursorPtr == gCurrentCursor) {
gCurrentCursor = NULL;
}
-
- ckfree((char *) macCursorPtr);
}
/*
@@ -348,6 +363,9 @@ void
TkpSetCursor(
TkpCursor cursor)
{
+ if (!gTkOwnsCursor) {
+ return;
+ }
if (cursor == None) {
gCurrentCursor = NULL;
} else {
@@ -358,3 +376,25 @@ TkpSetCursor(
TkMacInstallCursor(gResizeOverride);
}
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_MacTkOwnsCursor --
+ *
+ * Sets whether Tk has the right to adjust the cursor.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May keep Tk from changing the cursor.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void Tk_MacTkOwnsCursor(
+ int tkOwnsIt)
+{
+ gTkOwnsCursor = tkOwnsIt;
+}
diff --git a/mac/tkMacDefault.h b/mac/tkMacDefault.h
index 372d89b..da574fd 100644
--- a/mac/tkMacDefault.h
+++ b/mac/tkMacDefault.h
@@ -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.
*
- * SCCS: @(#) tkMacDefault.h 1.48 97/10/09 17:45:04
+ * SCCS: @(#) tkMacDefault.h 1.49 98/01/08 13:18:41
*/
#ifndef _TKMACDEFAULT
@@ -61,7 +61,8 @@
#define DEF_CHKRAD_FG DEF_BUTTON_FG
#define DEF_BUTTON_FONT "system"
#define DEF_BUTTON_HEIGHT "0"
-#define DEF_BUTTON_HIGHLIGHT_BG NORMAL_BG
+#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"
diff --git a/mac/tkMacDialog.c b/mac/tkMacDialog.c
index 43d11a5..e1031d9 100644
--- a/mac/tkMacDialog.c
+++ b/mac/tkMacDialog.c
@@ -3,13 +3,12 @@
*
* Contains the Mac implementation of the common dialog boxes.
*
- * Copyright (c) 1996 Sun Microsystems, Inc.
+ * Copyright (c) 1996-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.
*
- * SCCS: @(#) tkMacDialog.c 1.12 96/12/03 11:15:12
- *
+ * SCCS: @(#) tkMacDialog.c 1.20 97/11/07 21:23:36
*/
#include <Gestalt.h>
@@ -26,6 +25,13 @@
#include "tclMacInt.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 tkMacResource.r
*/
@@ -45,38 +51,27 @@
* information about the file dialog and the file filters.
*/
typedef struct _OpenFileData {
- Tcl_Interp * interp;
- char * initialFile; /* default file to appear in the
- * save dialog */
- char * defExt; /* default extension (not used on the
- * Mac) */
FileFilterList fl; /* List of file filters. */
SInt16 curType; /* The filetype currently being
- * listed */
- int isOpen; /* True if this is an Open dialog,
- * false if it is a Save dialog. */
- MenuHandle menu; /* Handle of the menu in the popup*/
- short dialogId; /* resource ID of the dialog */
- int popupId; /* resource ID of the popup */
- short popupItem; /* item number of the popup in the
- * dialog */
+ * 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)
- */
+ * -filetypes option is set). */
} OpenFileData;
static pascal Boolean FileFilterProc _ANSI_ARGS_((CInfoPBPtr pb,
void *myData));
-static int GetFileName _ANSI_ARGS_ ((
- ClientData clientData, Tcl_Interp *interp,
- int argc, char **argv, int isOpen ));
+static int GetFileName _ANSI_ARGS_ ((ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[], int isOpen));
static Boolean MatchOneType _ANSI_ARGS_((CInfoPBPtr pb,
- OpenFileData * myDataPtr, FileFilter * filterPtr));
+ OpenFileData *myofdPtr, FileFilter *filterPtr));
static pascal short OpenHookProc _ANSI_ARGS_((short item,
- DialogPtr theDialog, OpenFileData * myDataPtr));
+ DialogPtr theDialog, OpenFileData * myofdPtr));
static int ParseFileDlgArgs _ANSI_ARGS_ ((Tcl_Interp * interp,
- OpenFileData * myDataPtr, int argc, char ** argv,
+ OpenFileData * myofdPtr, int argc, char ** argv,
int isOpen));
/*
@@ -92,68 +87,7 @@ static DlgHookYDUPP saveHook = NULL;
/*
*----------------------------------------------------------------------
*
- * EvalArgv --
- *
- * Invokes the Tcl procedure with the arguments. argv[0] is set by
- * the caller of this function. It may be different than cmdName.
- * The TCL command will see argv[0], not cmdName, as its name if it
- * invokes [lindex [info level 0] 0]
- *
- * Results:
- * TCL_ERROR if the command does not exist and cannot be autoloaded.
- * Otherwise, return the result of the evaluation of the command.
- *
- * Side effects:
- * The command may be autoloaded.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-EvalArgv(
- Tcl_Interp *interp, /* Current interpreter. */
- char * cmdName, /* Name of the TCL command to call */
- int argc, /* Number of arguments. */
- char **argv) /* Argument strings. */
-{
- Tcl_CmdInfo cmdInfo;
-
- if (!Tcl_GetCommandInfo(interp, cmdName, &cmdInfo)) {
- char * cmdArgv[2];
-
- /*
- * This comand is not in the interpreter yet -- looks like we
- * have to auto-load it
- */
- if (!Tcl_GetCommandInfo(interp, "auto_load", &cmdInfo)) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "cannot execute command \"auto_load\"",
- NULL);
- return TCL_ERROR;
- }
-
- cmdArgv[0] = "auto_load";
- cmdArgv[1] = cmdName;
-
- if ((*cmdInfo.proc)(cmdInfo.clientData, interp, 2, cmdArgv)!= TCL_OK){
- return TCL_ERROR;
- }
-
- if (!Tcl_GetCommandInfo(interp, cmdName, &cmdInfo)) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "cannot auto-load command \"",
- cmdName, "\"",NULL);
- return TCL_ERROR;
- }
- }
-
- return (*cmdInfo.proc)(cmdInfo.clientData, interp, argc, argv);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_ChooseColorCmd --
+ * Tk_ChooseColorObjCmd --
*
* This procedure implements the color dialog box for the Mac
* platform. See the user documentation for details on what it
@@ -169,23 +103,86 @@ EvalArgv(
*/
int
-Tk_ChooseColorCmd(
+Tk_ChooseColorObjCmd(
ClientData clientData, /* Main window associated with interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- Tk_Window parent = Tk_MainWindow(interp);
- char * colorStr = NULL;
- XColor * colorPtr = NULL;
- char * title = "Choose a color:";
- int i, version;
- long response = 0;
- OSErr err = noErr;
- char buff[40];
- static RGBColor in;
+ Tk_Window parent;
+ char *title;
+ int i, picked, srcRead, dstWrote;
+ long response;
+ OSErr err;
static inited = 0;
-
+ static RGBColor in;
+ static 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;
+ }
+ }
+ }
+
/*
* Use the gestalt manager to determine how to bring
* up the color picker. If versin 2.0 isn't available
@@ -194,92 +191,12 @@ Tk_ChooseColorCmd(
*/
err = Gestalt(gestaltColorPicker, &response);
- if ((err == noErr) || (response == 0x0200L)) {
- version = 2;
- } else {
- version = 1;
- }
-
- for (i=1; i<argc; i+=2) {
- int v = i+1;
- int len = strlen(argv[i]);
-
- if (strncmp(argv[i], "-initialcolor", len)==0) {
- if (v==argc) {goto arg_missing;}
-
- colorStr = argv[v];
- } else if (strncmp(argv[i], "-parent", len)==0) {
- if (v==argc) {goto arg_missing;}
-
- parent=Tk_NameToWindow(interp, argv[v], Tk_MainWindow(interp));
- if (parent == NULL) {
- return TCL_ERROR;
- }
- } else if (strncmp(argv[i], "-title", len)==0) {
- if (v==argc) {goto arg_missing;}
-
- title = argv[v];
- } else {
- Tcl_AppendResult(interp, "unknown option \"",
- argv[i], "\", must be -initialcolor, -parent or -title",
- NULL);
- return TCL_ERROR;
- }
- }
-
- if (colorStr) {
- colorPtr = Tk_GetColor(interp, parent, colorStr);
- if (colorPtr == NULL) {
- return TCL_ERROR;
- }
- }
-
- if (!inited) {
- inited = 1;
- in.red = 0xffff;
- in.green = 0xffff;
- in.blue = 0xffff;
- }
- if (colorPtr) {
- in.red = colorPtr->red;
- in.green = colorPtr->green;
- in.blue = colorPtr->blue;
- }
-
- if (version == 1) {
- /*
- * Use version 1.0 of the color picker
- */
-
- RGBColor out;
- Str255 prompt;
- Point point = {-1, -1};
-
- prompt[0] = strlen(title);
- strncpy((char*) prompt+1, title, 255);
-
- if (GetColor(point, prompt, &in, &out)) {
- /*
- * user selected a color
- */
- sprintf(buff, "#%02x%02x%02x", out.red >> 8, out.green >> 8,
- out.blue >> 8);
- Tcl_SetResult(interp, buff, TCL_VOLATILE);
+ if ((err == noErr) && (response == 0x0200L)) {
+ ColorPickerInfo cpinfo;
- /*
- * Save it for the next time
- */
- in.red = out.red;
- in.green = out.green;
- in.blue = out.blue;
- } else {
- Tcl_ResetResult(interp);
- }
- } else {
/*
* Version 2.0 of the color picker is available. Let's use it
*/
- ColorPickerInfo cpinfo;
cpinfo.theColor.profile = 0L;
cpinfo.theColor.color.rgb.red = in.red;
@@ -292,41 +209,50 @@ Tk_ChooseColorCmd(
cpinfo.eventProc = NULL;
cpinfo.colorProc = NULL;
cpinfo.colorProcData = NULL;
+
+ 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;
+ }
+ } else {
+ RGBColor out;
+ Str255 prompt;
+ Point point = {-1, -1};
+
+ /*
+ * Use version 1.0 of the color picker
+ */
+
+ Tcl_UtfToExternal(NULL, NULL, title, -1, 0, NULL, StrBody(prompt),
+ 255, &srcRead, &dstWrote, NULL);
+ StrLength(prompt) = (unsigned char) dstWrote;
- cpinfo.prompt[0] = strlen(title);
- strncpy((char*)cpinfo.prompt+1, title, 255);
-
- if ((PickColor(&cpinfo) == noErr) && cpinfo.newColorChosen) {
- sprintf(buff, "#%02x%02x%02x",
- cpinfo.theColor.color.rgb.red >> 8,
- cpinfo.theColor.color.rgb.green >> 8,
- cpinfo.theColor.color.rgb.blue >> 8);
- Tcl_SetResult(interp, buff, TCL_VOLATILE);
-
- in.blue = cpinfo.theColor.color.rgb.red;
- in.green = cpinfo.theColor.color.rgb.green;
- in.blue = cpinfo.theColor.color.rgb.blue;
- } else {
- Tcl_ResetResult(interp);
+ if (GetColor(point, prompt, &in, &out)) {
+ in = out;
+ picked = 1;
}
- }
+ }
+
+ if (picked != 0) {
+ char result[32];
- if (colorPtr) {
- Tk_FreeColor(colorPtr);
+ sprintf(result, "#%02x%02x%02x", in.red >> 8, in.green >> 8,
+ in.blue >> 8);
+ Tcl_AppendResult(interp, result, NULL);
}
-
return TCL_OK;
-
- arg_missing:
- Tcl_AppendResult(interp, "value for \"", argv[argc-1], "\" missing",
- NULL);
- return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
*
- * Tk_GetOpenFileCmd --
+ * Tk_GetOpenFileObjCmd --
*
* This procedure implements the "open file" dialog box for the
* Mac platform. See the user documentation for details on what
@@ -341,19 +267,19 @@ Tk_ChooseColorCmd(
*/
int
-Tk_GetOpenFileCmd(
+Tk_GetOpenFileObjCmd(
ClientData clientData, /* Main window associated with interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- return GetFileName(clientData, interp, argc, argv, OPEN_FILE);
+ return GetFileName(clientData, interp, objc, objv, OPEN_FILE);
}
/*
*----------------------------------------------------------------------
*
- * Tk_GetSaveFileCmd --
+ * Tk_GetSaveFileObjCmd --
*
* Same as Tk_GetOpenFileCmd but opens a "save file" dialog box
* instead
@@ -367,13 +293,13 @@ Tk_GetOpenFileCmd(
*/
int
-Tk_GetSaveFileCmd(
+Tk_GetSaveFileObjCmd(
ClientData clientData, /* Main window associated with interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- return GetFileName(clientData, interp, argc, argv, SAVE_FILE);
+ return GetFileName(clientData, interp, objc, objv, SAVE_FILE);
}
/*
@@ -389,8 +315,8 @@ Tk_GetSaveFileCmd(
*
* Side effects:
* If the user selects a file, the native pathname of the file
- * is returned in interp->result. Otherwise an empty string
- * is returned in interp->result.
+ * is returned in the interp's result. Otherwise an empty string
+ * is returned in the interp's result.
*
*----------------------------------------------------------------------
*/
@@ -399,32 +325,124 @@ static int
GetFileName(
ClientData clientData, /* Main window associated with interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- char **argv, /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[], /* Argument objects. */
int isOpen) /* true if we should call GetOpenFileName(),
* false if we should call GetSaveFileName() */
{
- int code = TCL_OK;
- int i;
- OpenFileData myData, *myDataPtr;
+ int i, result;
+ OpenFileData ofd;
StandardFileReply reply;
Point mypoint;
- Str255 str;
-
- myDataPtr = &myData;
+ MenuHandle menu;
+ Str255 initialFile;
+ char *choice[6];
+ Tk_Window parent;
+ static char *optionStrings[] = {
+ "-defaultextension", "-filetypes", "-initialdir", "-initialfile",
+ "-parent", "-title", NULL
+ };
+ enum options {
+ FILE_DEFAULT, FILE_TYPES, FILE_INITDIR, FILE_INITFILE,
+ FILE_PARENT, FILE_TITLE
+ };
if (openFilter == NULL) {
openFilter = NewFileFilterYDProc(FileFilterProc);
openHook = NewDlgHookYDProc(OpenHookProc);
saveHook = NewDlgHookYDProc(OpenHookProc);
}
+
+ result = TCL_ERROR;
+ parent = (Tk_Window) clientData;
+ memset(choice, 0, sizeof(choice));
- /*
- * 1. Parse the arguments.
- */
- if (ParseFileDlgArgs(interp, myDataPtr, argc, argv, isOpen)
- != TCL_OK) {
- return TCL_ERROR;
+ for (i = 1; i < objc; i += 2) {
+ int index;
+ char *string;
+
+ if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "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;
+ }
+ choice[index] = Tcl_GetStringFromObj(objv[i + 1], NULL);
+ }
+
+ StrLength(initialFile) = 0;
+ menu = NULL;
+
+ TkInitFileFilters(&ofd.fl);
+ ofd.curType = 0;
+ ofd.popupItem = OPEN_POPUP_ITEM;
+ ofd.usePopup = isOpen;
+
+ if (choice[FILE_TYPES] != NULL) {
+ if (TkGetFileFilters(interp, &ofd.fl, choice[FILE_TYPES], 0) != TCL_OK) {
+ goto end;
+ }
+ }
+ if (choice[FILE_INITDIR] != NULL) {
+ FSSpec dirSpec;
+ Tcl_DString ds;
+ long dirID;
+ OSErr err;
+ Boolean isDirectory;
+ char *string;
+ Str255 dir;
+ int srcRead, dstWrote;
+
+ string = choice[FILE_INITDIR];
+ if (Tcl_TranslateFileName(interp, string, &ds) == NULL) {
+ goto end;
+ }
+ Tcl_UtfToExternal(NULL, NULL, Tcl_DStringValue(&ds),
+ Tcl_DStringLength(&ds), 0, NULL, StrBody(dir), 255,
+ &srcRead, &dstWrote, NULL);
+ StrLength(dir) = (unsigned char) dstWrote;
+ Tcl_DStringFree(&ds);
+
+ err = FSpLocationFromPath(StrLength(dir), StrBody(dir), &dirSpec);
+ if (err != noErr) {
+ Tcl_AppendResult(interp, "bad directory \"", string, "\"", NULL);
+ goto end;
+ }
+ err = FSpGetDirectoryID(&dirSpec, &dirID, &isDirectory);
+ if ((err != noErr) || !isDirectory) {
+ Tcl_AppendResult(interp, "bad directory \"", string, "\"", NULL);
+ goto end;
+ }
+ /*
+ * Make sure you negate -dirSpec.vRefNum because the
+ * standard file package wants it that way !
+ */
+
+ LMSetSFSaveDisk(-dirSpec.vRefNum);
+ LMSetCurDirStore(dirID);
+ }
+ if (choice[FILE_INITFILE] != NULL) {
+ Tcl_DString ds;
+ int srcRead, dstWrote;
+
+ if (Tcl_TranslateFileName(interp, choice[FILE_INITFILE], &ds) == NULL) {
+ goto end;
+ }
+ Tcl_UtfToExternal(NULL, NULL, Tcl_DStringValue(&ds),
+ Tcl_DStringLength(&ds), 0, NULL,
+ StrBody(initialFile), 255, &srcRead, &dstWrote, NULL);
+ StrLength(initialFile) = (unsigned char) dstWrote;
+ Tcl_DStringFree(&ds);
+ }
+ if (choice[FILE_PARENT] != NULL) {
+ parent = Tk_NameToWindow(interp, choice[FILE_PARENT], parent);
+ if (parent == NULL) {
+ return TCL_ERROR;
+ }
}
/*
@@ -436,237 +454,89 @@ GetFileName(
* left overs from previous invocation of this command
*/
- if (myDataPtr->usePopup) {
- FileFilter * filterPtr;
-
- for (i=CountMItems(myDataPtr->menu); i>0; i--) {
+ if (ofd.usePopup) {
+ FileFilter *filterPtr;
+
+ menu = GetMenu(OPEN_MENU);
+ for (i = CountMItems(menu); i > 0; i--) {
/*
* The item indices are one based. Also, if we delete from
* the beginning, the items may be re-numbered. So we
* delete from the end
*/
- DeleteMenuItem(myDataPtr->menu, i);
+
+ DeleteMenuItem(menu, i);
}
- if (myDataPtr->fl.filters) {
- for (filterPtr=myDataPtr->fl.filters; filterPtr;
- filterPtr=filterPtr->next) {
- strncpy((char*)str+1, filterPtr->name, 254);
- str[0] = strlen(filterPtr->name);
- AppendMenu(myDataPtr->menu, (ConstStr255Param) str);
- }
+ filterPtr = ofd.fl.filters;
+ if (filterPtr == NULL) {
+ ofd.usePopup = 0;
} else {
- myDataPtr->usePopup = 0;
+ for ( ; filterPtr != NULL; filterPtr = filterPtr->next) {
+ Str255 str;
+
+ StrLength(str) = (unsigned char) strlen(filterPtr->name);
+ strcpy(StrBody(str), filterPtr->name);
+ AppendMenu(menu, str);
+ }
}
}
/*
* 3. Call the toolbox file dialog function.
*/
+
SetPt(&mypoint, -1, -1);
TkpSetCursor(NULL);
-
- if (myDataPtr->isOpen) {
- if (myDataPtr->usePopup) {
- CustomGetFile(openFilter, (short) -1, NULL, &reply,
- myDataPtr->dialogId,
- mypoint, openHook, NULL, NULL, NULL, (void*)myDataPtr);
+ if (isOpen) {
+ if (ofd.usePopup) {
+ CustomGetFile(openFilter, (short) -1, NULL, &reply, OPEN_BOX,
+ mypoint, openHook, NULL, NULL, NULL, (void*) &ofd);
} else {
StandardGetFile(NULL, -1, NULL, &reply);
}
} else {
- Str255 prompt, def;
-
- strcpy((char*)prompt+1, "Save as");
- prompt[0] = strlen("Save as");
- if (myDataPtr->initialFile) {
- strncpy((char*)def+1, myDataPtr->initialFile, 254);
- def[0] = strlen(myDataPtr->initialFile);
- } else {
- def[0] = 0;
- }
- if (myDataPtr->usePopup) {
+ static Str255 prompt = "\pSave as";
+
+ if (ofd.usePopup) {
/*
* Currently this never gets called because we don't use
* popup for the save dialog.
*/
- CustomPutFile(prompt, def, &reply, myDataPtr->dialogId, mypoint,
- saveHook, NULL, NULL, NULL, myDataPtr);
+ CustomPutFile(prompt, initialFile, &reply, OPEN_BOX,
+ mypoint, saveHook, NULL, NULL, NULL, (void *) &ofd);
} else {
- StandardPutFile(prompt, def, &reply);
+ StandardPutFile(prompt, initialFile, &reply);
}
}
- Tcl_ResetResult(interp);
if (reply.sfGood) {
int length;
- Handle pathHandle = NULL;
- char * pathName = NULL;
+ Handle pathHandle;
+ pathHandle = NULL;
FSpPathFromLocation(&reply.sfFile, &length, &pathHandle);
-
if (pathHandle != NULL) {
+ Tcl_DString ds;
+
HLock(pathHandle);
- pathName = (char *) ckalloc((unsigned) (length + 1));
- strcpy(pathName, *pathHandle);
+ Tcl_ExternalToUtfDString(NULL, (char *) *pathHandle, -1, &ds);
+ Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL);
+ Tcl_DStringFree(&ds);
HUnlock(pathHandle);
DisposeHandle(pathHandle);
-
- /*
- * Return the full pathname of the selected file
- */
-
- Tcl_SetResult(interp, pathName, TCL_DYNAMIC);
}
}
-
- done:
- TkFreeFileFilters(&myDataPtr->fl);
- return code;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * ParseFileDlgArgs --
- *
- * Parses the arguments passed to tk_getOpenFile and tk_getSaveFile.
- *
- * Results:
- * A standard TCL return value.
- *
- * Side effects:
- * The OpenFileData structure is initialized and modified according
- * to the arguments.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-ParseFileDlgArgs(
- Tcl_Interp * interp, /* Current interpreter. */
- OpenFileData * myDataPtr, /* Information about the file dialog */
- int argc, /* Number of arguments */
- char ** argv, /* Argument strings */
- int isOpen) /* TRUE if this is an "open" dialog */
-{
- int i;
-
- myDataPtr->interp = interp;
- myDataPtr->initialFile = NULL;
- myDataPtr->curType = 0;
-
- TkInitFileFilters(&myDataPtr->fl);
- if (isOpen) {
- myDataPtr->isOpen = 1;
- myDataPtr->usePopup = 1;
- myDataPtr->menu = GetMenu(OPEN_MENU);
- myDataPtr->dialogId = OPEN_BOX;
- myDataPtr->popupId = OPEN_POPUP;
- myDataPtr->popupItem = OPEN_POPUP_ITEM;
- if (myDataPtr->menu == NULL) {
- Debugger();
- }
- } else {
- myDataPtr->isOpen = 0;
- myDataPtr->usePopup = 0;
- }
-
- for (i=1; i<argc; i+=2) {
- int v = i+1;
- int len = strlen(argv[i]);
-
- if (strncmp(argv[i], "-defaultextension", len)==0) {
- if (v==argc) {goto arg_missing;}
+ result = TCL_OK;
- myDataPtr->defExt = argv[v];
- }
- else if (strncmp(argv[i], "-filetypes", len)==0) {
- if (v==argc) {goto arg_missing;}
-
- if (TkGetFileFilters(interp, &myDataPtr->fl,argv[v],0) != TCL_OK) {
- return TCL_ERROR;
- }
- }
- else if (strncmp(argv[i], "-initialdir", len)==0) {
- FSSpec dirSpec;
- char * dirName;
- Tcl_DString dstring;
- long dirID;
- OSErr err;
- Boolean isDirectory;
-
- if (v==argc) {goto arg_missing;}
-
- if (Tcl_TranslateFileName(interp, argv[v], &dstring) == NULL) {
- return TCL_ERROR;
- }
- dirName = dstring.string;
- if (FSpLocationFromPath(strlen(dirName), dirName, &dirSpec) !=
- noErr) {
- Tcl_AppendResult(interp, "bad directory \"", argv[v],
- "\"", NULL);
- return TCL_ERROR;
- }
- err = FSpGetDirectoryID(&dirSpec, &dirID, &isDirectory);
- if ((err != noErr) || !isDirectory) {
- Tcl_AppendResult(interp, "bad directory \"", argv[v],
- "\"", NULL);
- return TCL_ERROR;
- }
- /*
- * Make sure you negate -dirSpec.vRefNum because the standard file
- * package wants it that way !
- */
- LMSetSFSaveDisk(-dirSpec.vRefNum);
- LMSetCurDirStore(dirID);
- Tcl_DStringFree(&dstring);
- }
- else if (strncmp(argv[i], "-initialfile", len)==0) {
- if (v==argc) {goto arg_missing;}
-
- myDataPtr->initialFile = argv[v];
- }
- else if (strncmp(argv[i], "-parent", len)==0) {
- /*
- * Ignored on the Mac, but make sure that it's a valid window
- * pathname
- */
- Tk_Window parent;
-
- if (v==argc) {goto arg_missing;}
-
- parent=Tk_NameToWindow(interp, argv[v], Tk_MainWindow(interp));
- if (parent == NULL) {
- return TCL_ERROR;
- }
- }
- else if (strncmp(argv[i], "-title", len)==0) {
- if (v==argc) {goto arg_missing;}
-
- /*
- * This option is ignored on the Mac because the Mac file
- * dialog do not support titles.
- */
- }
- else {
- Tcl_AppendResult(interp, "unknown option \"",
- argv[i], "\", must be -defaultextension, ",
- "-filetypes, -initialdir, -initialfile, -parent or -title",
- NULL);
- return TCL_ERROR;
- }
+ end:
+ TkFreeFileFilters(&ofd.fl);
+ if (menu != NULL) {
+ DisposeMenu(menu);
}
-
- return TCL_OK;
-
- arg_missing:
- Tcl_AppendResult(interp, "value for \"", argv[argc-1], "\" missing",
- NULL);
- return TCL_ERROR;
+ return result;
}
-
/*
*----------------------------------------------------------------------
*
@@ -689,7 +559,7 @@ static pascal short
OpenHookProc(
short item, /* Event description. */
DialogPtr theDialog, /* The dialog where the event occurs. */
- OpenFileData * myDataPtr) /* Information about the file dialog. */
+ OpenFileData *ofdPtr) /* Information about the file dialog. */
{
short ignore;
Rect rect;
@@ -698,29 +568,29 @@ OpenHookProc(
switch (item) {
case sfHookFirstCall:
- if (myDataPtr->usePopup) {
+ if (ofdPtr->usePopup) {
/*
* Set the popup list to display the selected type.
*/
- GetDialogItem(theDialog, myDataPtr->popupItem,
- &ignore, &handle, &rect);
- SetControlValue((ControlRef) handle, myDataPtr->curType + 1);
+ GetDialogItem(theDialog, ofdPtr->popupItem, &ignore, &handle,
+ &rect);
+ SetControlValue((ControlRef) handle, ofdPtr->curType + 1);
}
return sfHookNullEvent;
case OPEN_POPUP_ITEM:
- if (myDataPtr->usePopup) {
- GetDialogItem(theDialog, myDataPtr->popupItem,
+ if (ofdPtr->usePopup) {
+ GetDialogItem(theDialog, ofdPtr->popupItem,
&ignore, &handle, &rect);
newType = GetCtlValue((ControlRef) handle) - 1;
- if (myDataPtr->curType != newType) {
- if (newType<0 || newType>myDataPtr->fl.numFilters) {
+ if (ofdPtr->curType != newType) {
+ if (newType<0 || newType>ofdPtr->fl.numFilters) {
/*
* Sanity check. Looks like the user selected an
* non-existent menu item?? Don't do anything.
*/
} else {
- myDataPtr->curType = newType;
+ ofdPtr->curType = newType;
}
return sfHookRebuildList;
}
@@ -755,10 +625,10 @@ FileFilterProc(
void *myData) /* Client data for this file dialog */
{
int i;
- OpenFileData * myDataPtr = (OpenFileData*)myData;
+ OpenFileData * ofdPtr = (OpenFileData*)myData;
FileFilter * filterPtr;
- if (myDataPtr->fl.numFilters == 0) {
+ if (ofdPtr->fl.numFilters == 0) {
/*
* No types have been specified. List all files by default
*/
@@ -772,13 +642,13 @@ FileFilterProc(
return MATCHED;
}
- if (myDataPtr->usePopup) {
- i = myDataPtr->curType;
- for (filterPtr=myDataPtr->fl.filters; filterPtr && i>0; i--) {
+ if (ofdPtr->usePopup) {
+ i = ofdPtr->curType;
+ for (filterPtr=ofdPtr->fl.filters; filterPtr && i>0; i--) {
filterPtr = filterPtr->next;
}
if (filterPtr) {
- return MatchOneType(pb, myDataPtr, filterPtr);
+ return MatchOneType(pb, ofdPtr, filterPtr);
} else {
return UNMATCHED;
}
@@ -788,9 +658,9 @@ FileFilterProc(
* considered matched if it matches any of the file filters.
*/
- for (filterPtr=myDataPtr->fl.filters; filterPtr;
+ for (filterPtr=ofdPtr->fl.filters; filterPtr;
filterPtr=filterPtr->next) {
- if (MatchOneType(pb, myDataPtr, filterPtr) == MATCHED) {
+ if (MatchOneType(pb, ofdPtr, filterPtr) == MATCHED) {
return MATCHED;
}
}
@@ -818,7 +688,7 @@ FileFilterProc(
static Boolean
MatchOneType(
CInfoPBPtr pb, /* Information about the file */
- OpenFileData * myDataPtr, /* Information about this file dialog */
+ OpenFileData * ofdPtr, /* Information about this file dialog */
FileFilter * filterPtr) /* Match the file described by pb against
* this filter */
{
@@ -909,31 +779,33 @@ MatchOneType(
return UNMATCHED;
}
-
/*
*----------------------------------------------------------------------
*
- * Tk_MessageBoxCmd --
+ * Tk_ChooseDirectoryObjCmd --
*
- * This procedure implements the MessageBox window for the
- * Mac platform. See the user documentation for details on what
- * it does.
+ * This procedure implements the "tk_chooseDirectory" dialog box
+ * for the Windows platform. See the user documentation for details
+ * on what it does.
*
* Results:
- * A standard Tcl result.
+ * See user documentation.
*
* Side effects:
- * See user documentation.
+ * A modal dialog window is created. Tcl_SetServiceMode() is
+ * called to allow background events to be processed
*
*----------------------------------------------------------------------
*/
int
-Tk_MessageBoxCmd(
- ClientData clientData, /* Main window associated with interpreter. */
- Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- char **argv) /* Argument strings. */
+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. */
{
- return EvalArgv(interp, "tkMessageBox", argc, argv);
+ return TCL_ERROR;
}
+
+
diff --git a/mac/tkMacEmbed.c b/mac/tkMacEmbed.c
index 7a73b54..21e4803 100644
--- a/mac/tkMacEmbed.c
+++ b/mac/tkMacEmbed.c
@@ -8,12 +8,12 @@
* Currently only Toplevel embedding within the same Tk application is
* allowed on the Macintosh.
*
- * Copyright (c) 1996-97 Sun Microsystems, Inc.
+ * Copyright (c) 1996-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.
*
- * SCCS: @(#) tkMacEmbed.c 1.6 97/10/31 17:20:22
+ * SCCS: @(#) tkMacEmbed.c 1.8 97/12/03 18:56:10
*/
#include "tkInt.h"
@@ -53,6 +53,11 @@ typedef struct Container {
static Container *firstContainerPtr = NULL;
/* First in list of all containers
* managed by this process. */
+/*
+ * Globals defined in this file
+ */
+
+TkMacEmbedHandler *gMacEmbedHandler = NULL;
/*
* Prototypes for static procedures defined in this file:
@@ -74,9 +79,41 @@ static void EmbedStructureProc _ANSI_ARGS_((ClientData clientData,
XEvent *eventPtr));
static void EmbedWindowDeleted _ANSI_ARGS_((TkWindow *winPtr));
-/* WARNING - HACK */
-static void GenerateFocusEvents _ANSI_ARGS_((TkWindow *sourcePtr,
- TkWindow *destPtr));
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_MacSetEmbedHandler --
+ *
+ * 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_MacSetEmbedHandler(
+ Tk_MacEmbedRegisterWinProc *registerWinProc,
+ Tk_MacEmbedGetGrafPortProc *getPortProc,
+ Tk_MacEmbedMakeContainerExistProc *containerExistProc,
+ Tk_MacEmbedGetClipProc *getClipProc,
+ Tk_MacEmbedGetOffsetInParentProc *getOffsetProc)
+{
+ if (gMacEmbedHandler == NULL) {
+ gMacEmbedHandler = (TkMacEmbedHandler *) ckalloc(sizeof(TkMacEmbedHandler));
+ }
+ gMacEmbedHandler->registerWinProc = registerWinProc;
+ gMacEmbedHandler->getPortProc = getPortProc;
+ gMacEmbedHandler->containerExistProc = containerExistProc;
+ gMacEmbedHandler->getClipProc = getClipProc;
+ gMacEmbedHandler->getOffsetProc = getOffsetProc;
+}
/*
@@ -180,7 +217,7 @@ TkpMakeWindow(
* 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 interp->result if
+ * is TCL_ERROR and an error message is left in the interp's result if
* interp is non-NULL.
*
* Side effects:
@@ -240,18 +277,6 @@ TkpUseWindow(
}
}
- /*
- * We should not get to this code until we start to allow
- * embedding in other applications.
- */
-
- if (containerPtr == NULL) {
- Tcl_AppendResult(interp, "The window ID ", string,
- " does not correspond to a valid Tk Window.",
- (char *) NULL);
- return TCL_ERROR;
- }
-
/*
* Make the embedded window.
*/
@@ -264,13 +289,27 @@ TkpUseWindow(
macWin->winPtr = winPtr;
winPtr->privatePtr = macWin;
+
+ /*
+ * The portPtr 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 TkMacGetDrawablePort
+ * to get the portPtr. It will correctly find the container's port.
+ */
+
+ macWin->portPtr = (GWorldPtr) 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
@@ -279,33 +318,67 @@ TkpUseWindow(
macWin->flags |= TK_EMBEDDED;
- /*
- * The portPtr will be NULL for an embedded window.
- * Always use TkMacGetDrawablePort to get the portPtr.
- * It will correctly find the container's port.
+ /*
+ * 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.
*/
-
- macWin->portPtr = (GWorldPtr) NULL;
-
- macWin->toplevel = macWin;
- 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;
- macWin->toplevel->referenceCount++;
+ 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.
- */
+
+ /*
+ * Finish filling up the container structure with the embedded window's
+ * information.
+ */
- containerPtr->embedded = (Window) macWin;
- containerPtr->embeddedPtr = macWin->winPtr;
+ 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.
*/
@@ -318,15 +391,19 @@ TkpUseWindow(
event.xvisibility.state = VisibilityUnobscured;
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
- /*
- * Create an event handler to clean up the Container structure when
- * tkwin is eventually deleted.
+
+ /*
+ * TODO: need general solution for visibility events.
*/
-
- Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc,
- (ClientData) winPtr);
-
+ 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;
}
@@ -884,11 +961,10 @@ EmbedActivateProc(clientData, eventPtr)
Container *containerPtr = (Container *) clientData;
if (containerPtr->embeddedPtr != NULL) {
-
- if (eventPtr->type == ActivateNotify) {
- TkGenerateActivateEvents(containerPtr->embeddedPtr, 1);
+ if (eventPtr->type == ActivateNotify) {
+ TkGenerateActivateEvents(containerPtr->embeddedPtr,1);
} else if (eventPtr->type == DeactivateNotify) {
- TkGenerateActivateEvents(containerPtr->embeddedPtr, 0);
+ TkGenerateActivateEvents(containerPtr->embeddedPtr,0);
}
}
}
@@ -923,14 +999,14 @@ EmbedFocusProc(clientData, eventPtr)
XEvent event;
if (containerPtr->embeddedPtr != NULL) {
- display = Tk_Display(containerPtr->parentPtr);
+ 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) {
+ 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.
@@ -951,7 +1027,7 @@ EmbedFocusProc(clientData, eventPtr)
}
Tk_QueueWindowEvent(&event, TCL_QUEUE_MARK);
- }
+ }
}
/*
diff --git a/mac/tkMacFont.c b/mac/tkMacFont.c
index 8619880..616034e 100644
--- a/mac/tkMacFont.c
+++ b/mac/tkMacFont.c
@@ -10,36 +10,389 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS:@(#) tkMacFont.c 1.52 97/11/20 18:29:51
+ * SCCS: @(#) tkMacFont.c 1.54 97/11/26 10:51:12
*/
#include <Windows.h>
#include <Strings.h>
#include <Fonts.h>
+#include <Script.h>
#include <Resources.h>
+#include <TextUtils.h>
#include "tkMacInt.h"
#include "tkFont.h"
-#include "tkPort.h"
/*
- * The following structure represents the Macintosh's' implementation of a
- * font.
+ * 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.
+ */
+
+ short 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. */
- short family;
- short size;
- short style;
+ 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. */
+ short 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;
-static TkFont * AllocMacFont _ANSI_ARGS_((TkFont *tkfont,
- Tk_Window tkwin, int family, int size, int style));
+/*
+ * 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,
+ 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 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. */
+{
+ MenuHandle fontMenu;
+ FontNameMap *tmpFontNameMap, *newFontNameMap, *mapPtr;
+ int i, j, numFonts, fontMapOffset, isSymbol;
+ Str255 nativeName;
+ Tcl_DString ds;
+ Tcl_Encoding encoding;
+ Tcl_Encoding *encodings;
+
+ if (gWorld == NULL) {
+ /*
+ * Do the following one time only.
+ */
+
+ 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.
+ */
+
+ fontMenu = NewMenu('FT', "\px");
+ AddResMenu(fontMenu, 'FONT');
+
+ numFonts = CountMItems(fontMenu);
+ tmpFontNameMap = (FontNameMap *) ckalloc(sizeof(FontNameMap) * numFonts);
+ encodings = (Tcl_Encoding *) ckalloc(sizeof(Tcl_Encoding) * numFonts);
+
+ mapPtr = tmpFontNameMap;
+ for (i = 0; i < numFonts; i++) {
+ GetMenuItemText(fontMenu, i + 1, nativeName);
+ GetFNum(nativeName, &mapPtr->faceNum);
+ encodings[i] = GetFontEncoding(mapPtr->faceNum, 0, &isSymbol);
+ 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++;
+ }
+ DisposeMenu(fontMenu);
+
+ /*
+ * 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;
+ }
+}
/*
*---------------------------------------------------------------------------
@@ -73,6 +426,7 @@ TkpGetNativeFont(
CONST char *name) /* Platform-specific font name. */
{
short family;
+ MacFont *fontPtr;
if (strcmp(name, "system") == 0) {
family = GetSysFont();
@@ -81,8 +435,11 @@ TkpGetNativeFont(
} else {
return NULL;
}
-
- return AllocMacFont(NULL, tkwin, family, 0, 0);
+
+ fontPtr = (MacFont *) ckalloc(sizeof(MacFont));
+ InitFont(tkwin, family, 0, 0, fontPtr);
+
+ return (TkFont *) fontPtr;
}
/*
@@ -122,41 +479,47 @@ TkpGetFontFromAttributes(
* 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. */
+ CONST TkFontAttributes *faPtr)
+ /* Set of attributes to match. */
{
- char buf[257];
- size_t len;
- short family, size, style;
-
- if (faPtr->family == NULL) {
- family = 0;
- } else {
- CONST char *familyName;
-
- familyName = faPtr->family;
- if (strcasecmp(familyName, "Times New Roman") == 0) {
- familyName = "Times";
- } else if (strcasecmp(familyName, "Courier New") == 0) {
- familyName = "Courier";
- } else if (strcasecmp(familyName, "Arial") == 0) {
- familyName = "Helvetica";
- }
-
- len = strlen(familyName);
- if (len > 255) {
- len = 255;
+ short faceNum, style;
+ int i, j;
+ 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;
+ }
}
- buf[0] = (char) len;
- memcpy(buf + 1, familyName, len);
- buf[len + 1] = '\0';
- GetFNum((StringPtr) buf, &family);
}
-
- size = faPtr->pointsize;
- if (size <= 0) {
- size = GetDefFontSize();
- }
-
+
+ found:
style = 0;
if (faPtr->weight != TK_FW_NORMAL) {
style |= bold;
@@ -167,8 +530,15 @@ TkpGetFontFromAttributes(
if (faPtr->underline) {
style |= underline;
}
-
- return AllocMacFont(tkFontPtr, tkwin, family, size, style);
+ if (tkFontPtr == NULL) {
+ fontPtr = (MacFont *) ckalloc(sizeof(MacFont));
+ } else {
+ fontPtr = (MacFont *) tkFontPtr;
+ ReleaseFont(fontPtr);
+ }
+ InitFont(tkwin, faceNum, faPtr->size, style, fontPtr);
+
+ return (TkFont *) fontPtr;
}
/*
@@ -194,7 +564,10 @@ void
TkpDeleteFont(
TkFont *tkFontPtr) /* Token of font to be deleted. */
{
- ckfree((char *) tkFontPtr);
+ MacFont *fontPtr;
+
+ fontPtr = (MacFont *) tkFontPtr;
+ ReleaseFont(fontPtr);
}
/*
@@ -206,7 +579,7 @@ TkpDeleteFont(
* on the display of the given window.
*
* Results:
- * interp->result is modified to hold a list of all the available
+ * Modifies interp's result object to hold a list of all the available
* font families.
*
* Side effects:
@@ -220,76 +593,54 @@ TkpGetFontFamilies(
Tcl_Interp *interp, /* Interp to hold result. */
Tk_Window tkwin) /* For display to query. */
{
- MenuHandle fontMenu;
- int i;
- char itemText[257];
-
- fontMenu = NewMenu(1, "\px");
- AddResMenu(fontMenu, 'FONT');
-
- for (i = 1; i < CountMItems(fontMenu); i++) {
- /*
- * Each item is a pascal string. Convert it to C and append.
- */
- GetMenuItemText(fontMenu, i, (unsigned char *) itemText);
- itemText[itemText[0] + 1] = '\0';
- Tcl_AppendElement(interp, &itemText[1]);
+ 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);
}
- DisposeMenu(fontMenu);
}
-
/*
- *---------------------------------------------------------------------------
+ *-------------------------------------------------------------------------
*
- * TkMacIsCharacterMissing --
+ * TkpGetSubFonts --
*
- * 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.
+ * A function used by the testing package for querying the actual
+ * screen fonts that make up a font object.
*
* Results:
- * Returns a 1 if the character is missing, a 0 if it is not.
+ * 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.
*
- *---------------------------------------------------------------------------
+ *-------------------------------------------------------------------------
*/
-
-int
-TkMacIsCharacterMissing(
- Tk_Font tkfont, /* The font we are looking in. */
- unsigned int searchChar) /* The character we are looking for. */
+
+void
+TkpGetSubFonts(interp, tkfont)
+ Tcl_Interp *interp; /* Interp to hold result. */
+ Tk_Font tkfont; /* Font object to query. */
{
- MacFont *fontPtr = (MacFont *) tkfont;
- FMInput fm;
- FontRec **fontRecHandle;
-
- fm.family = fontPtr->family;
- 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;
+ int i;
+ Tcl_Obj *resultPtr, *strPtr;
+ MacFont *fontPtr;
+ FontFamily *familyPtr;
+ Str255 nativeName;
- /*
- * This element of the FMOutput structure was changed between the 2.0 & 3.0
- * versions of the Universal Headers.
- */
-
-#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;
+ 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);
+ }
}
-
/*
*---------------------------------------------------------------------------
@@ -316,14 +667,14 @@ TkMacIsCharacterMissing(
int
Tk_MeasureChars(
Tk_Font tkfont, /* Font in which characters will be drawn. */
- CONST char *source, /* Characters to be displayed. Need not be
+ CONST char *source, /* UTF-8 string to be displayed. Need not be
* '\0' terminated. */
- int numChars, /* Maximum number of characters to consider
+ int numBytes, /* Maximum number of bytes to consider
* from source string. */
- int maxLength, /* If > 0, maxLength specifies the longest
+ 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
+ * x-position. If < 0, then line length is
* unbounded and the flags argument is
* ignored. */
int flags, /* Various flag bits OR-ed together:
@@ -336,134 +687,270 @@ Tk_MeasureChars(
int *lengthPtr) /* Filled with x-location just after the
* terminating character. */
{
- short staticWidths[128];
- short *widths;
- CONST char *p, *term;
- int curX, termX, curIdx, sawNonSpace;
MacFont *fontPtr;
+ FontFamily *lastFamilyPtr;
CGrafPtr saveWorld;
GDHandle saveDevice;
+ int curX, curByte;
- if (numChars == 0) {
- *lengthPtr = 0;
- return 0;
- }
-
- if (gWorld == NULL) {
- Rect rect = {0, 0, 1, 1};
+ /*
+ * 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;
- if (NewGWorld(&gWorld, 0, &rect, NULL, NULL, 0) != noErr) {
- panic("NewGWorld failed in Tk_MeasureChars");
- }
- }
GetGWorld(&saveWorld, &saveDevice);
SetGWorld(gWorld, NULL);
-
- fontPtr = (MacFont *) tkfont;
- TextFont(fontPtr->family);
+
TextSize(fontPtr->size);
TextFace(fontPtr->style);
- if (maxLength <= 0) {
- *lengthPtr = TextWidth(source, 0, numChars);
- SetGWorld(saveWorld, saveDevice);
- return numChars;
- }
-
- if (numChars > maxLength) {
- /*
- * Assume that all chars are at least 1 pixel wide, so there's no
- * need to measure more characters than there are pixels. This
- * assumption could be refined to an iterative approach that would
- * use that as a starting point and try more chars if necessary (if
- * there actually were some zero-width chars).
- */
-
- numChars = maxLength;
- }
- if (numChars > SHRT_MAX) {
- /*
- * If they are trying to measure more than 32767 chars at one time,
- * it would require several separate measurements.
- */
-
- numChars = SHRT_MAX;
- }
-
- widths = staticWidths;
- if (numChars >= sizeof(staticWidths) / sizeof(staticWidths[0])) {
- widths = (short *) ckalloc((numChars + 1) * sizeof(short));
- }
+ lastFamilyPtr = fontPtr->subFontArray[0].familyPtr;
- MeasureText((short) numChars, source, widths);
-
- if (widths[numChars] <= maxLength) {
- curX = widths[numChars];
- curIdx = numChars;
+ 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 {
- p = term = source;
- curX = termX = 0;
-
- sawNonSpace = !isspace(UCHAR(*p));
- for (curIdx = 1; ; curIdx++) {
- if (isspace(UCHAR(*p))) {
- if (sawNonSpace) {
- term = p;
- termX = widths[curIdx - 1];
- sawNonSpace = 0;
- }
- } else {
- sawNonSpace = 1;
- }
- if (widths[curIdx] > maxLength) {
- curIdx--;
- curX = widths[curIdx];
- break;
+ CONST char *p, *end, *next, *sourceOrig;
+ int widthLeft;
+ FontFamily *thisFamilyPtr;
+ Tcl_UniChar ch;
+ char *rest;
+
+ /*
+ * 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;
}
- p++;
}
- if (flags & TK_PARTIAL_OK) {
- curIdx++;
- curX = widths[curIdx];
+
+ if (p > source) {
+ rest = BreakLine(lastFamilyPtr, flags, source, p - source,
+ &widthLeft);
}
- if ((curIdx == 0) && (flags & TK_AT_LEAST_ONE)) {
- /*
- * The space was too small to hold even one character. Since at
- * least one character must always fit on a line, return the width
- * of the first character.
- */
-
- curX = TextWidth(source, 0, 1);
- curIdx = 1;
- } else if (flags & TK_WHOLE_WORDS) {
- /*
- * Break at last word that fits on the line.
- */
-
- if ((flags & TK_AT_LEAST_ONE) && (term == source)) {
- /*
- * The space was too small to hold an entire word. This
- * is the only word on the line, so just return the part of th
- * word that fit.
- */
-
- ;
- } else {
- curIdx = term - source;
- curX = termX;
- }
- }
+
+ if (rest == NULL) {
+ curByte = numBytes;
+ } else {
+ curByte = rest - sourceOrig;
+ }
+ curX = maxLength - widthLeft;
}
- if (widths != staticWidths) {
- ckfree((char *) widths);
- }
+ 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 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;
- SetGWorld(saveWorld, saveDevice);
+ 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++;
+ }
+ }
- return curIdx;
+ 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);
}
/*
@@ -489,14 +976,14 @@ Tk_DrawChars(
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, /* Characters to be displayed. Need not be
+ 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 numChars, /* Number of characters in string. */
+ int numBytes, /* Number of bytes in string. */
int x, int y) /* Coordinates at which to place origin of
* string when drawing. */
{
@@ -538,19 +1025,12 @@ Tk_DrawChars(
bufferPort = TkMacGetDrawablePort(pixmap);
SetGWorld(bufferPort, NULL);
- TextFont(fontPtr->family);
- TextSize(fontPtr->size);
- TextFace(fontPtr->style);
-
if (TkSetMacColor(gc->foreground, &macColor) == true) {
RGBForeColor(&macColor);
}
-
ShowPen();
- MoveTo((short) 0, (short) 0);
FillRect(&stippleMap->bounds, &tcl_macQdPtr->white);
- MoveTo((short) x, (short) y);
- DrawText(source, 0, (short) numChars);
+ MultiFontDrawText(fontPtr, source, numBytes, 0, 0);
SetGWorld(destPort, NULL);
CopyDeepMask(&((GrafPtr) bufferPort)->portBits, stippleMap,
@@ -565,18 +1045,13 @@ Tk_DrawChars(
Tk_FreePixmap(display, pixmap);
ckfree(stippleMap->baseAddr);
ckfree((char *)stippleMap);
- } else {
- TextFont(fontPtr->family);
- TextSize(fontPtr->size);
- TextFace(fontPtr->style);
-
+ } else {
if (TkSetMacColor(gc->foreground, &macColor) == true) {
RGBForeColor(&macColor);
}
-
ShowPen();
- MoveTo((short) (macWin->xOff + x), (short) (macWin->yOff + y));
- DrawText(source, 0, (short) numChars);
+ MultiFontDrawText(fontPtr, source, numBytes, macWin->xOff + x,
+ macWin->yOff + y);
}
TextFont(txFont);
@@ -587,92 +1062,1057 @@ Tk_DrawChars(
}
/*
+ *-------------------------------------------------------------------------
+ *
+ * MultiFontDrawText --
+ *
+ * Helper function for Tk_DrawChars. Draws characters, using the
+ * various screen fonts in fontPtr to draw multilingual characters.
+ * Note: No bidirectional support.
+ *
+ * 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;
+ 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);
+ }
+}
+
+/*
*---------------------------------------------------------------------------
*
- * AllocMacFont --
+ * TkMacIsCharacterMissing --
*
- * Helper for TkpGetNativeFont() and TkpGetFontFromAttributes().
- * Allocates and intializes the memory for a new TkFont that
- * wraps the platform-specific data.
+ * 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 pointer to newly constructed TkFont.
+ * Returns a 1 if the character is missing, a 0 if it is not.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TkMacIsCharacterMissing(
+ Tk_Font tkfont, /* The font we are looking in. */
+ unsigned int searchChar) /* The character we are looking for. */
+{
+ MacFont *fontPtr = (MacFont *) tkfont;
+ FMInput fm;
+ FontRec **fontRecHandle;
+
+ 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;
+
+#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;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * 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 TkFont *
-AllocMacFont(
- 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. */
+static void
+InitFont(
Tk_Window tkwin, /* For display where font will be used. */
- int family, /* Macintosh font family. */
+ int faceNum, /* Macintosh font number. */
int size, /* Point size for Macintosh font. */
- int style) /* Macintosh style bits. */
+ int style, /* Macintosh style bits. */
+ MacFont *fontPtr) /* Filled with information constructed from
+ * the above arguments. */
{
- char buf[257];
+ Str255 nativeName;
FontInfo fi;
- MacFont *fontPtr;
TkFontAttributes *faPtr;
TkFontMetrics *fmPtr;
CGrafPtr saveWorld;
GDHandle saveDevice;
+ short pixels;
- if (gWorld == NULL) {
- Rect rect = {0, 0, 1, 1};
-
- if (NewGWorld(&gWorld, 0, &rect, NULL, NULL, 0) != noErr) {
- panic("NewGWorld failed in AllocMacFont");
- }
+ if (size == 0) {
+ size = -GetDefFontSize();
}
+ pixels = (short) TkFontGetPixels(tkwin, size);
+
GetGWorld(&saveWorld, &saveDevice);
SetGWorld(gWorld, NULL);
+ TextFont(faceNum);
+ TextSize(pixels);
+ TextFace(style);
- if (tkFontPtr == NULL) {
- fontPtr = (MacFont *) ckalloc(sizeof(MacFont));
- } else {
- fontPtr = (MacFont *) tkFontPtr;
- }
+ GetFontInfo(&fi);
+ GetFontName(faceNum, nativeName);
fontPtr->font.fid = (Font) fontPtr;
- faPtr = &fontPtr->font.fa;
- GetFontName(family, (StringPtr) buf);
- buf[UCHAR(buf[0]) + 1] = '\0';
- faPtr->family = Tk_GetUid(buf + 1);
- faPtr->pointsize = size;
+ 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;
- TextFont(family);
- TextSize(size);
- TextFace(style);
- GetFontInfo(&fi);
+ fmPtr = &fontPtr->font.fm;
fmPtr->ascent = fi.ascent;
fmPtr->descent = fi.descent;
fmPtr->maxWidth = fi.widMax;
fmPtr->fixed = (CharWidth('i') == CharWidth('w'));
-
- fontPtr->family = (short) family;
- fontPtr->size = (short) size;
+
+ 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;
- return (TkFont *) fontPtr;
+ 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;
+ 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;
+ FontRec *fontRecPtr;
+ short *widths;
+ int i, end, bitOffset, isMultiByteFont;
+ char src[TCL_UTF_MAX];
+ unsigned char buf[16];
+ int srcRead, dstWrote;
+ Tcl_Encoding encoding;
+
+ 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)
+ fontRecPtr = *((FontRec **) FMSwapFont(&fm)->fontResult);
+#else
+ fontRecPtr = *((FontRec **) FMSwapFont(&fm)->fontHandle);
+#endif
+ widths = (short *) ((long) &fontRecPtr->owTLoc
+ + ((long) (fontRecPtr->owTLoc - fontRecPtr->firstChar)
+ * sizeof(short)));
+ isMultiByteFont = subFontPtr->familyPtr->isMultiByteFont;
+
+ 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);
+ }
+ }
+ }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * 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. */
+ 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);
+}
diff --git a/mac/tkMacHLEvents.c b/mac/tkMacHLEvents.c
index 39f7836..bbf56fb 100644
--- a/mac/tkMacHLEvents.c
+++ b/mac/tkMacHLEvents.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.
*
- * SCCS: @(#) tkMacHLEvents.c 1.21 97/09/17 17:19:00
+ * SCCS: @(#) tkMacHLEvents.c 1.22 97/11/07 21:20:50
*/
#include "tcl.h"
@@ -361,10 +361,12 @@ ScriptHandler(
if (tclErr >= 0) {
if (tclErr == TCL_OK) {
AEPutParamPtr(reply, keyDirectObject, typeChar,
- interp->result, strlen(interp->result));
+ Tcl_GetStringResult(interp),
+ strlen(Tcl_GetStringResult(interp)));
} else {
AEPutParamPtr(reply, keyErrorString, typeChar,
- interp->result, strlen(interp->result));
+ Tcl_GetStringResult(interp),
+ strlen(Tcl_GetStringResult(interp)));
AEPutParamPtr(reply, keyErrorNumber, typeInteger,
(Ptr) &tclErr, sizeof(int));
}
diff --git a/mac/tkMacInit.c b/mac/tkMacInit.c
index bb1f8b3..11f730a 100644
--- a/mac/tkMacInit.c
+++ b/mac/tkMacInit.c
@@ -4,7 +4,7 @@
* This file contains Mac-specific interpreter initialization
* functions.
*
- * Copyright (c) 1995-1996 Sun Microsystems, Inc.
+ * 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.
@@ -41,7 +41,7 @@ QDGlobalsPtr tcl_macQdPtr = NULL;
*
* Results:
* A standard Tcl completion code (TCL_OK or TCL_ERROR). Also
- * leaves information in interp->result.
+ * leaves information in the interp's result.
*
* Side effects:
* Sets "tk_library" Tcl variable, runs initialization scripts
diff --git a/mac/tkMacInt.h b/mac/tkMacInt.h
index fcb8174..7cbb21e 100644
--- a/mac/tkMacInt.h
+++ b/mac/tkMacInt.h
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tkMacInt.h 1.67 97/11/20 18:30:38
+ * SCCS:@(#) tkMacInt.h 1.69 98/02/18 10:50:53
*/
#ifndef _TKMACINT
@@ -73,6 +73,24 @@ typedef struct TkMacWindowList {
*/
/*
+ * 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
+ * TkMacGetDrawablePort. The definitions of the function types
+ * are in tclMac.h.
+ */
+
+typedef struct {
+ Tk_MacEmbedRegisterWinProc *registerWinProc;
+ Tk_MacEmbedGetGrafPortProc *getPortProc;
+ Tk_MacEmbedMakeContainerExistProc *containerExistProc;
+ Tk_MacEmbedGetClipProc *getClipProc;
+ Tk_MacEmbedGetOffsetInParentProc *getOffsetProc;
+} TkMacEmbedHandler;
+
+extern TkMacEmbedHandler *gMacEmbedHandler;
+
+/*
* Defines used for TkMacInvalidateWindow
*/
@@ -233,6 +251,7 @@ extern int TkMacGrowToplevel _ANSI_ARGS_((WindowRef whichWindow,
Point start));
extern void TkMacHandleMenuSelect _ANSI_ARGS_((long mResult,
int optionKeyPressed));
+extern int TkMacHaveAppearance _ANSI_ARGS_((void));
extern void TkMacInitAppleEvents _ANSI_ARGS_((Tcl_Interp *interp));
extern void TkMacInitMenus _ANSI_ARGS_((Tcl_Interp *interp));
extern void TkMacInvalidateWindow _ANSI_ARGS_((MacDrawable *macWin, int flag));
diff --git a/mac/tkMacKeyboard.c b/mac/tkMacKeyboard.c
index a1dfad8..3c10b58 100644
--- a/mac/tkMacKeyboard.c
+++ b/mac/tkMacKeyboard.c
@@ -3,12 +3,12 @@
*
* Routines to support keyboard events on the Macintosh.
*
- * Copyright (c) 1995-1996 Sun Microsystems, Inc.
+ * 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.
*
- * SCCS: @(#) tkMacKeyboard.c 1.14 96/08/15 15:34:00
+ * SCCS: @(#) tkMacKeyboard.c 1.16 98/01/16 10:42:35
*/
#include "tkInt.h"
@@ -137,7 +137,7 @@ XKeycodeToKeysym(
int index)
{
register Tcl_HashEntry *hPtr;
- register char c;
+ int c;
char virtualKey;
int newKeycode;
unsigned long dummy, newChar;
@@ -146,8 +146,11 @@ XKeycodeToKeysym(
InitKeyMaps();
}
- c = keycode & charCodeMask;
- virtualKey = (keycode & keyCodeMask) >> 8;
+ virtualKey = (char) (keycode >> 16);
+ c = (keycode) & 0xffff;
+ if (c > 255) {
+ return NoSymbol;
+ }
/*
* When determining what keysym to produce we firt check to see if
@@ -161,8 +164,6 @@ XKeycodeToKeysym(
return (KeySym) Tcl_GetHashValue(hPtr);
}
}
-
-
hPtr = Tcl_FindHashEntry(&keycodeTable, (char *) virtualKey);
if (hPtr != NULL) {
return (KeySym) Tcl_GetHashValue(hPtr);
@@ -190,60 +191,63 @@ XKeycodeToKeysym(
/*
*----------------------------------------------------------------------
*
- * XLookupString --
+ * TkpGetString --
*
* Retrieve the string equivalent for the given keyboard event.
*
* Results:
- * Returns the number of characters stored in buffer_return.
+ * Returns the UTF string.
*
* Side effects:
- * Retrieves the characters stored in the event and inserts them
- * into buffer_return.
+ * None.
*
*----------------------------------------------------------------------
*/
-int
-XLookupString(
- XKeyEvent* event_struct,
- char* buffer_return,
- int bytes_buffer,
- KeySym* keysym_return,
- XComposeStatus* status_in_out)
+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];
char virtualKey;
- char c;
+ int c, len;
if (!initialized) {
InitKeyMaps();
}
-
- c = event_struct->keycode & charCodeMask;
- string[0] = c;
- string[1] = '\0';
+
+ 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) {
- string[0] = '\0';
+ len = 0;
} else {
- virtualKey = (event_struct->keycode & keyCodeMask) >> 8;
hPtr = Tcl_FindHashEntry(&keycodeTable, (char *) virtualKey);
if (hPtr != NULL) {
- string[0] = '\0';
+ len = 0;
}
}
-
- if (buffer_return != NULL) {
- strncpy(buffer_return, string, bytes_buffer);
- }
-
- return strlen(string);
+ return Tcl_ExternalToUtfDString(NULL, string, len, dsPtr);
}
/*
@@ -377,7 +381,7 @@ XKeysymToKeycode(
virtualKeyCode = 0x24;
keysym = '\r';
}
- keycode = keysym + ((virtualKeyCode << 8) & keyCodeMask);
+ keycode = keysym + (virtualKeyCode <<16);
}
return keycode;
diff --git a/mac/tkMacLibrary.r b/mac/tkMacLibrary.r
index c86954a..1d9c041 100644
--- a/mac/tkMacLibrary.r
+++ b/mac/tkMacLibrary.r
@@ -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.
*
- * SCCS: @(#) tkMacLibrary.r 1.9 97/11/20 18:31:20
+ * SCCS: @(#) tkMacLibrary.r 1.10 98/02/10 10:37:21
*/
/*
@@ -118,8 +118,6 @@ read 'TEXT' (TK_LIBRARY_RESOURCES+16, "msgbox", purgeable, preload)
"::library:msgbox.tcl";
read 'TEXT' (TK_LIBRARY_RESOURCES+17, "comdlg", purgeable, preload)
"::library:comdlg.tcl";
-read 'TEXT' (TK_LIBRARY_RESOURCES+18, "prolog", purgeable, preload)
- "::library:prolog.ps";
/*
* The following two resources define the default "About Box" for Mac Tk.
diff --git a/mac/tkMacMenu.c b/mac/tkMacMenu.c
index 33bb82b..a44636c 100644
--- a/mac/tkMacMenu.c
+++ b/mac/tkMacMenu.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tkMacMenu.c 1.107 97/11/20 18:33:09
+ * SCCS: @(#) tkMacMenu.c 1.111 98/01/21 22:04:59
*/
#include <Menus.h>
@@ -18,11 +18,11 @@
#include <string.h>
#include <ToolUtils.h>
#include <Balloons.h>
-#undef Status
-#include <Devices.h>
#include "tkMenu.h"
#include "tkMacInt.h"
-#include "tkMenuButton.h"
+#include "tkMenubutton.h"
+#undef Status
+#include <Devices.h>
typedef struct MacMenu {
MenuHandle menuHdl; /* The Menu Manager data structure. */
@@ -46,7 +46,7 @@ typedef struct MacMenu {
* The following are constants relating to the SICNs used for drawing the MDEF.
*/
-#define SICN_RESOURCE_NUMBER 128
+#define SICN_RESOURCE_NUMBER 128
#define SICN_HEIGHT 16
#define SICN_ROWS 2
@@ -139,6 +139,8 @@ typedef struct TopLevelMenubarList {
#define MENUBAR_REDRAW_PENDING 1
+static int gNoTkMenus = 0; /* This is used by Tk_MacTurnOffMenus 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. */
@@ -166,6 +168,9 @@ static char *currentMenuBarName;
* DString. */
static Tk_Window currentMenuBarOwner;
/* Which window owns the current menu bar. */
+static char elipsisString[TCL_UTF_MAX + 1];
+ /* The UTF representation of the elipsis (ƒ)
+ * character. */
static int helpItemCount; /* The number of items in the help menu.
* -1 means that the help menu is
* unavailable. This does not include
@@ -182,7 +187,8 @@ static MacDrawable macMDEFDrawable;
static 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 TkMenuDefUPP menuDefProc;/* The routine descriptor to the MDEF proc.
+static TkMenuDefUPP menuDefProc = NULL ;
+ /* The routine descriptor to the MDEF proc.
* The MDEF is needed to draw menus with
* non-standard attributes and to support
* tearoff menus. */
@@ -240,6 +246,8 @@ static void DrawTearoffEntry _ANSI_ARGS_((TkMenu *menuPtr,
Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
int x, int y, int width, int height));
static void FixMDEF _ANSI_ARGS_((void));
+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,
@@ -284,6 +292,8 @@ static void RecursivelyInsertMenu _ANSI_ARGS_((
static void SetDefaultMenubar _ANSI_ARGS_((void));
static int SetMenuCascade _ANSI_ARGS_((TkMenu *menuPtr));
static void SetMenuIndicator _ANSI_ARGS_((TkMenuEntry *mePtr));
+static void SetMenuTitle _ANSI_ARGS_((MenuHandle menuHdl,
+ Tcl_Obj *titlePtr));
/*
@@ -308,7 +318,7 @@ static void SetMenuIndicator _ANSI_ARGS_((TkMenuEntry *mePtr));
int
TkMacUseMenuID(
- short macID) /* The id to take out of the table */
+ short macID) /* The id to take out of the table */
{
Tcl_HashEntry *commandEntryPtr;
int newEntry;
@@ -419,6 +429,7 @@ GetNewID(
*menuIDPtr = returnID;
return TCL_OK;
} else {
+ Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "No more menus can be allocated.",
(char *) NULL);
return TCL_ERROR;
@@ -655,7 +666,8 @@ TkpDestroyMenuEntry(
*
* 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.
+ * handled specially. This is primarily used to do a substitution
+ * between "..." and "ƒ".
*
* Results:
* itemText points to the new text for the item.
@@ -669,36 +681,41 @@ TkpDestroyMenuEntry(
static void
GetEntryText(
TkMenuEntry *mePtr, /* A pointer to the menu entry. */
- Str255 itemText) /* The pascal string containing the text */
+ 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) {
- strcpy((char *)itemText, (const char *)"\p(Tear-off)");
- } else if (mePtr->imageString != NULL) {
- strcpy((char *)itemText, (const char *)"\p(Image)");
- } else if (mePtr->bitmap != None) {
- strcpy((char *)itemText, (const char *)"\p(Pixmap)");
- } else if (mePtr->label == NULL || mePtr->labelLength == 0) {
+ 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.
*/
- strcpy((char *)itemText, (const char *)"\p ");
+ Tcl_DStringAppend(dStringPtr, " ", -1);
} else {
- char *text = mePtr->label;
+ int length;
+ char *text = Tcl_GetStringFromObj(mePtr->labelPtr, &length);
+ char *dStringText;
int i;
- itemText[0] = 0;
- for (i = 1; (*text != '\0') && (i <= 230); i++, text++) {
+ for (i = 0; i < length; text++, i++) {
if ((*text == '.')
&& (*(text + 1) != '\0') && (*(text + 1) == '.')
&& (*(text + 2) != '\0') && (*(text + 2) == '.')) {
- itemText[i] = 'É';
- text += 2;
- } else {
- itemText[i] = *text;
+ Tcl_DStringAppend(dStringPtr, elipsisString, -1);
+ i += strlen(elipsisString) - 1;
+ } else {
+ Tcl_DStringSetLength(dStringPtr,
+ Tcl_DStringLength(dStringPtr) + 1);
+ dStringText = Tcl_DStringValue(dStringPtr);
+ dStringText[i] = *text;
}
- itemText[0] += 1;
}
}
}
@@ -715,10 +732,10 @@ GetEntryText(
* We try the following special mac characters. If none of them
* are present, just use the check mark.
* '' - Check mark character
- * '¥' - Bullet character
+ * '´' - Bullet character
* '' - Filled diamond
* '×' - Hollow diamond
- * 'Ñ' = Long dash ("em dash")
+ * '„' = Long dash ("em dash")
* '-' = short dash (minus, "en dash");
*
* Results:
@@ -736,19 +753,22 @@ FindMarkCharacter(
* for. */
{
char markChar;
- Tk_Font tkfont = (mePtr->tkfont == NULL) ? mePtr->menuPtr->tkfont
- : mePtr->tkfont;
+ Tk_Font tkfont;
+
+ tkfont = Tk_GetFontFromObj(mePtr->menuPtr->tkwin,
+ (mePtr->fontPtr == NULL) ? mePtr->menuPtr->fontPtr
+ : mePtr->fontPtr);
if (!TkMacIsCharacterMissing(tkfont, '')) {
markChar = '';
- } else if (!TkMacIsCharacterMissing(tkfont, '¥')) {
- markChar = '¥';
+ } else if (!TkMacIsCharacterMissing(tkfont, '´')) {
+ markChar = '´';
} else if (!TkMacIsCharacterMissing(tkfont, '')) {
markChar = '';
} else if (!TkMacIsCharacterMissing(tkfont, '×')) {
markChar = '×';
- } else if (!TkMacIsCharacterMissing(tkfont, 'Ñ')) {
- markChar = 'Ñ';
+ } else if (!TkMacIsCharacterMissing(tkfont, '„')) {
+ markChar = '„';
} else if (!TkMacIsCharacterMissing(tkfont, '-')) {
markChar = '-';
} else {
@@ -781,6 +801,7 @@ SetMenuIndicator(
TkMenu *menuPtr = mePtr->menuPtr;
MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl;
char markChar;
+ int indicatorOn;
/*
* There can be no indicators on menus that are not checkbuttons
@@ -795,14 +816,14 @@ SetMenuIndicator(
if (mePtr->type == CASCADE_ENTRY) {
return;
}
-
- if (((mePtr->type == RADIO_BUTTON_ENTRY)
- || (mePtr->type == CHECK_BUTTON_ENTRY))
- && (mePtr->indicatorOn)
- && (mePtr->entryFlags & ENTRY_SELECTED)) {
- markChar = FindMarkCharacter(mePtr);
- } else {
- markChar = 0;
+
+ markChar = 0;
+ if ((mePtr->type == RADIO_BUTTON_ENTRY)
+ || (mePtr->type == CHECK_BUTTON_ENTRY)) {
+ Tcl_GetBooleanFromObj(NULL, mePtr->indicatorOnPtr, &indicatorOn);
+ if (indicatorOn && (mePtr->entryFlags & ENTRY_SELECTED)) {
+ markChar = FindMarkCharacter(mePtr);
+ }
}
SetItemMark(macMenuHdl, mePtr->index + 1, markChar);
}
@@ -829,10 +850,12 @@ SetMenuIndicator(
static void
SetMenuTitle(
MenuHandle menuHdl, /* The menu we are setting the title of. */
- char *title) /* The C string to set the title to. */
+ Tcl_Obj *titlePtr) /* The C string to set the title to. */
{
int oldLength, newLength, oldHandleSize, dataLength;
Ptr menuDataPtr;
+ char *title = (titlePtr == NULL) ? ""
+ : Tcl_GetStringFromObj(titlePtr, NULL);
menuDataPtr = (Ptr) (*menuHdl)->menuData;
@@ -869,7 +892,7 @@ SetMenuTitle(
*
* Results:
* Returns standard TCL result. If TCL_ERROR is returned, then
- * interp->result contains an error message.
+ * the interp's result contains an error message.
*
* Side effects:
* Configuration information get set for mePtr; old resources
@@ -909,7 +932,7 @@ TkpConfigureMenuEntry(
}
if (menuPtr->menuType == MENUBAR) {
- SetMenuTitle(childMenuHdl, mePtr->label);
+ SetMenuTitle(childMenuHdl, mePtr->labelPtr);
}
}
}
@@ -925,7 +948,9 @@ TkpConfigureMenuEntry(
if (0 == mePtr->accelLength) {
((EntryGeometry *)mePtr->platformEntryData)->accelTextStart = -1;
} else {
- char *accelString = mePtr->accel;
+ char *accelString = (mePtr->accelPtr == NULL) ? ""
+ : Tcl_GetStringFromObj(mePtr->accelPtr, NULL);
+ char *accel = accelString;
mePtr->entryFlags |= ~ENTRY_ACCEL_MASK;
while (1) {
@@ -971,7 +996,7 @@ TkpConfigureMenuEntry(
}
((EntryGeometry *)mePtr->platformEntryData)->accelTextStart
- = ((long) accelString - (long) mePtr->accel);
+ = ((long) accelString - (long) accel);
}
if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
@@ -1018,11 +1043,17 @@ ReconfigureIndividualMenu(
TkMenuEntry *mePtr;
Str255 itemText;
int parentDisabled = 0;
+ int state;
for (mePtr = menuPtr->menuRefPtr->parentEntryPtr; mePtr != NULL;
mePtr = mePtr->nextCascadePtr) {
- if (strcmp(Tk_PathName(menuPtr->tkwin), mePtr->name) == 0) {
- if (mePtr->state == tkDisabledUid) {
+ char *name = (mePtr->namePtr == NULL) ? ""
+ : Tcl_GetStringFromObj(mePtr->namePtr, NULL);
+
+ if (strcmp(Tk_PathName(menuPtr->tkwin), name) == 0) {
+ Tcl_GetIndexFromObj(NULL, mePtr->statePtr, tkMenuStateStrings,
+ NULL, 0, &state);
+ if (state == ENTRY_DISABLED) {
parentDisabled = 1;
}
break;
@@ -1051,15 +1082,27 @@ ReconfigureIndividualMenu(
if (mePtr->type == SEPARATOR_ENTRY) {
AppendMenu(macMenuHdl, SEPARATOR_TEXT);
} else {
- GetEntryText(mePtr, itemText);
+ Tcl_DString itemTextDString;
+ int destWrote;
+
+ GetEntryText(mePtr, &itemTextDString);
+ Tcl_UtfToExternal(NULL, NULL, Tcl_DStringValue(&itemTextDString),
+ Tcl_DStringLength(&itemTextDString), 0, NULL,
+ (char *) &itemText[1],
+ 231, NULL, &destWrote, NULL);
+ itemText[0] = destWrote;
+
AppendMenu(macMenuHdl, "\px");
SetMenuItemText(macMenuHdl, base + index, itemText);
+ Tcl_DStringFree(&itemTextDString);
/*
* Set enabling and disabling correctly.
*/
- if (parentDisabled || (mePtr->state == tkDisabledUid)) {
+ Tcl_GetIndexFromObj(NULL, mePtr->statePtr, tkMenuStateStrings,
+ NULL, 0, &state);
+ if (parentDisabled || (state == ENTRY_DISABLED)) {
DisableItem(macMenuHdl, base + index);
} else {
EnableItem(macMenuHdl, base + index);
@@ -1072,9 +1115,13 @@ ReconfigureIndividualMenu(
SetItemMark(macMenuHdl, base + index, 0);
if ((mePtr->type == CHECK_BUTTON_ENTRY)
|| (mePtr->type == RADIO_BUTTON_ENTRY)) {
+ int indicatorOn;
+
+ Tcl_GetBooleanFromObj(NULL, mePtr->indicatorOnPtr,
+ &indicatorOn);
CheckItem(macMenuHdl, base + index, (mePtr->entryFlags
- & ENTRY_SELECTED) && (mePtr->indicatorOn));
- if ((mePtr->indicatorOn)
+ & ENTRY_SELECTED) && (indicatorOn));
+ if ((indicatorOn)
&& (mePtr->entryFlags & ENTRY_SELECTED)) {
SetItemMark(macMenuHdl, base + index,
FindMarkCharacter(mePtr));
@@ -1116,9 +1163,9 @@ ReconfigureIndividualMenu(
if ((mePtr->type != CASCADE_ENTRY)
&& (ENTRY_COMMAND_ACCEL
== (mePtr->entryFlags & ENTRY_ACCEL_MASK))) {
- SetItemCmd(macMenuHdl, index, mePtr
- ->accel[((EntryGeometry *)mePtr->platformEntryData)
- ->accelTextStart]);
+ char *accel = Tcl_GetStringFromObj(mePtr->accelPtr, NULL);
+ SetItemCmd(macMenuHdl, index, accel[((EntryGeometry *)
+ mePtr->platformEntryData)->accelTextStart]);
}
}
}
@@ -1396,6 +1443,31 @@ TkpMenuNewEntry(
*----------------------------------------------------------------------
*
*
+ * Tk_MacTurnOffMenus --
+ *
+ * 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.
+ *
+ *----------------------------------------------------------------------
+ */
+
+EXTERN void
+Tk_MacTurnOffMenus()
+{
+ gNoTkMenus = 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ *
* DrawMenuBarWhenIdle --
*
* Update the menu bar next time there is an idle event.
@@ -1419,6 +1491,14 @@ DrawMenuBarWhenIdle(
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.
*/
@@ -1527,9 +1607,14 @@ DrawMenuBarWhenIdle(
if (menuBarPtr == NULL) {
SetDefaultMenubar();
- } else {
- if (menuBarPtr->tearOff != menuPtr->tearOff) {
- if (menuBarPtr->tearOff) {
+ } else {
+ int menuBarTearoff, menuTearoff;
+
+ Tcl_GetBooleanFromObj(NULL, menuBarPtr->tearoffPtr,
+ &menuBarTearoff);
+ Tcl_GetBooleanFromObj(NULL, menuPtr->tearoffPtr, &menuTearoff);
+ if (menuBarTearoff != menuTearoff) {
+ if (menuBarTearoff) {
appleIndex = (-1 == appleIndex) ? appleIndex
: appleIndex + 1;
helpIndex = (-1 == helpIndex) ? helpIndex
@@ -1577,7 +1662,12 @@ DrawMenuBarWhenIdle(
for (i = 0; i < menuBarPtr->numEntries; i++) {
if (i == appleIndex) {
- if (menuBarPtr->entries[i]->state == tkDisabledUid) {
+ int state;
+
+ Tcl_GetIndexFromObj(NULL,
+ menuBarPtr->entries[i]->statePtr,
+ tkMenuStateStrings, NULL, 0, &state);
+ if (state == ENTRY_DISABLED) {
DisableItem(((MacMenu *) menuBarPtr->entries[i]
->childMenuRefPtr->menuPtr
->platformData)->menuHdl,
@@ -1613,6 +1703,8 @@ DrawMenuBarWhenIdle(
if ((menuBarPtr->entries[i]->childMenuRefPtr != NULL)
&& menuBarPtr->entries[i]->childMenuRefPtr
->menuPtr != NULL) {
+ int state;
+
cascadeMenuPtr = menuBarPtr->entries[i]
->childMenuRefPtr->menuPtr;
macMenuHdl = ((MacMenu *) cascadeMenuPtr
@@ -1620,7 +1712,10 @@ DrawMenuBarWhenIdle(
DeleteMenu((*macMenuHdl)->menuID);
InsertMenu(macMenuHdl, 0);
RecursivelyInsertMenu(cascadeMenuPtr);
- if (menuBarPtr->entries[i]->state == tkDisabledUid) {
+ Tcl_GetIndexFromObj(NULL,
+ menuBarPtr->entries[i]->statePtr,
+ tkMenuStateStrings, NULL, 0, &state);
+ if (state == ENTRY_DISABLED) {
DisableItem(((MacMenu *) menuBarPtr->entries[i]
->childMenuRefPtr->menuPtr
->platformData)->menuHdl,
@@ -1675,7 +1770,8 @@ RecursivelyInsertMenu(
&& (menuPtr->entries[i]->childMenuRefPtr->menuPtr
!= NULL)) {
cascadeMenuPtr = menuPtr->entries[i]->childMenuRefPtr->menuPtr;
- macMenuHdl = ((MacMenu *) cascadeMenuPtr->platformData)->menuHdl;
+ macMenuHdl =
+ ((MacMenu *) cascadeMenuPtr->platformData)->menuHdl;
InsertMenu(macMenuHdl, -1);
RecursivelyInsertMenu(cascadeMenuPtr);
}
@@ -1716,7 +1812,8 @@ RecursivelyDeleteMenu(
&& (menuPtr->entries[i]->childMenuRefPtr->menuPtr
!= NULL)) {
cascadeMenuPtr = menuPtr->entries[i]->childMenuRefPtr->menuPtr;
- macMenuHdl = ((MacMenu *) cascadeMenuPtr->platformData)->menuHdl;
+ macMenuHdl =
+ ((MacMenu *) cascadeMenuPtr->platformData)->menuHdl;
DeleteMenu((*macMenuHdl)->menuID);
RecursivelyInsertMenu(cascadeMenuPtr);
}
@@ -1826,7 +1923,8 @@ TkpSetMainMenubar(
}
}
if (listPtr != NULL) {
- menuName = Tk_PathName(listPtr->menuPtr->masterMenuPtr->tkwin);
+ menuName = Tk_PathName(listPtr->menuPtr->masterMenuPtr
+ ->tkwin);
break;
}
}
@@ -2028,15 +2126,15 @@ GetMenuAccelGeometry (
} 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, mePtr->accel,
- mePtr->accelLength);
+ *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, mePtr->accel,
- mePtr->accelLength);
+ int width = Tk_TextWidth(tkfont, accel, mePtr->accelLength);
*textWidthPtr = emWidth;
if (width < emWidth) {
*modWidthPtr = 0;
@@ -2061,7 +2159,7 @@ GetMenuAccelGeometry (
if (1 == (mePtr->accelLength - length)) {
*textWidthPtr = emWidth;
} else {
- *textWidthPtr += Tk_TextWidth(tkfont, mePtr->accel
+ *textWidthPtr += Tk_TextWidth(tkfont, accel
+ length, mePtr->accelLength - length);
}
}
@@ -2163,21 +2261,31 @@ DrawMenuEntryIndicator(
int width, /* width of entry */
int height) /* height of entry */
{
- if (((mePtr->type == CHECK_BUTTON_ENTRY) ||
- (mePtr->type == RADIO_BUTTON_ENTRY))
- && (mePtr->indicatorOn)
- && (mePtr->entryFlags & ENTRY_SELECTED)) {
- int baseline;
- short markShort;
- char markChar;
+ if ((mePtr->type == CHECK_BUTTON_ENTRY) ||
+ (mePtr->type == RADIO_BUTTON_ENTRY)) {
+ int indicatorOn;
+
+ Tcl_GetBooleanFromObj(NULL, mePtr->indicatorOnPtr, &indicatorOn);
+
+ if ((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) {
- markChar = (char) markShort;
- Tk_DrawChars(menuPtr->display, d, gc, tkfont, &markChar, 1,
- x + 2, baseline);
+ 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;
+ 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);
+ }
}
}
}
@@ -2289,6 +2397,10 @@ DrawMenuEntryAccelerator(
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) {
if (0 == DrawSICN(SICN_RESOURCE_NUMBER, CASCADE_ARROW, d, gc,
x + width - SICN_HEIGHT, (y + (height / 2))
@@ -2297,7 +2409,7 @@ DrawMenuEntryAccelerator(
Tk_Window tkwin = menuPtr->tkwin;
if (mePtr->type == CASCADE_ENTRY) {
- points[0].x = width - menuPtr->activeBorderWidth
+ points[0].x = width - activeBorderWidth
- MAC_MARGIN_WIDTH - CASCADE_ARROW_WIDTH;
points[0].y = y + (height - CASCADE_ARROW_HEIGHT)/2;
points[1].x = points[0].x;
@@ -2311,11 +2423,14 @@ DrawMenuEntryAccelerator(
} 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, mePtr->accel,
+ Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
mePtr->accelLength, leftEdge, baseline);
} else {
EntryGeometry *geometryPtr =
@@ -2327,7 +2442,7 @@ DrawMenuEntryAccelerator(
leftEdge -= geometryPtr->modifierWidth;
}
- Tk_DrawChars(menuPtr->display, d, gc, tkfont, mePtr->accel
+ Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel
+ geometryPtr->accelTextStart, length, leftEdge, baseline);
if (mePtr->entryFlags & ENTRY_COMMAND_ACCEL) {
@@ -2403,10 +2518,8 @@ DrawMenuSeparator(
TkMacSetUpGraphicsPort(mePtr->disabledGC != None ? mePtr->disabledGC
: menuPtr->disabledGC);
-
MoveTo(x, y + (height / 2));
Line(width, 0);
-
SetGWorld(saveWorld, saveDevice);
}
@@ -2447,7 +2560,7 @@ MenuDefProc(
TkMenuEntry *parentEntryPtr;
Tcl_HashEntry *commandEntryPtr;
GrafPtr windowMgrPort;
- Tk_Font tkfont;
+ Tk_Font tkfont, menuFont;
Tk_FontMetrics fontMetrics, entryMetrics;
Tk_FontMetrics *fmPtr;
TkMenuEntry *mePtr;
@@ -2562,7 +2675,8 @@ MenuDefProc(
* that are lower than the bottom.
*/
- Tk_GetFontMetrics(menuPtr->tkfont, &fontMetrics);
+ menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
+ Tk_GetFontMetrics(menuFont, &fontMetrics);
for (i = 0; i < menuPtr->numEntries; i++) {
mePtr = menuPtr->entries[i];
if (globalsPtr->menuTop + mePtr->y + mePtr->height
@@ -2573,11 +2687,11 @@ MenuDefProc(
continue;
}
ClipRect(&menuClipRect);
- if (mePtr->tkfont == NULL) {
+ if (mePtr->fontPtr == NULL) {
fmPtr = &fontMetrics;
- tkfont = menuPtr->tkfont;
+ tkfont = menuFont;
} else {
- tkfont = mePtr->tkfont;
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
Tk_GetFontMetrics(tkfont, &entryMetrics);
fmPtr = &entryMetrics;
}
@@ -2598,7 +2712,7 @@ MenuDefProc(
break;
case mChooseMsg: {
- int hasTopScroll, hasBottomScroll;
+ int hasTopScroll, hasBottomScroll, tearoff;
enum {
DONT_SCROLL, DOWN_SCROLL, UP_SCROLL
} scrollDirection;
@@ -2640,8 +2754,12 @@ MenuDefProc(
itemRect.bottom = itemRect.top
+ menuPtr->entries[i]->height;
if (PtInRect(hitPt, &itemRect)) {
+ int state;
+
+ Tcl_GetIndexFromObj(NULL, mePtr->statePtr,
+ tkMenuStateStrings, NULL, 0, &state);
if ((mePtr->type == SEPARATOR_ENTRY)
- || (mePtr->state == tkDisabledUid)) {
+ || (state == ENTRY_DISABLED)) {
newItem = -1;
} else {
TkMenuEntry *cascadeEntryPtr;
@@ -2652,10 +2770,17 @@ MenuDefProc(
cascadeEntryPtr != NULL;
cascadeEntryPtr
= cascadeEntryPtr->nextCascadePtr) {
- if (strcmp(cascadeEntryPtr->name,
- Tk_PathName(menuPtr->tkwin)) == 0) {
- if (cascadeEntryPtr->state
- == tkDisabledUid) {
+ char *name;
+
+ name = Tcl_GetStringFromObj(
+ cascadeEntryPtr->namePtr, NULL);
+ if (strcmp(name, Tk_PathName(menuPtr->tkwin))
+ == 0) {
+ Tcl_GetIndexFromObj(NULL,
+ cascadeEntryPtr->statePtr,
+ tkMenuStateStrings, NULL, 0,
+ &state);
+ if (state == ENTRY_DISABLED) {
parentDisabled = 1;
}
break;
@@ -2707,9 +2832,17 @@ MenuDefProc(
ClipRect(&menuClipRect);
if (oldItem != newItem) {
+ int state;
+
if (oldItem >= 0) {
mePtr = menuPtr->entries[oldItem];
- tkfont = mePtr->tkfont ? mePtr->tkfont : menuPtr->tkfont;
+ if (mePtr->fontPtr == NULL) {
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin,
+ menuPtr->fontPtr);
+ } else {
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin,
+ mePtr->fontPtr);
+ }
Tk_GetFontMetrics(tkfont, &fontMetrics);
TkpDrawMenuEntry(mePtr, (Drawable) &macMDEFDrawable,
tkfont, &fontMetrics,
@@ -2723,10 +2856,18 @@ MenuDefProc(
int oldActiveItem = menuPtr->active;
mePtr = menuPtr->entries[newItem];
- if (mePtr->state != tkDisabledUid) {
+ Tcl_GetIndexFromObj(NULL, mePtr->statePtr,
+ tkMenuStateStrings, NULL, 0, &state);
+ if (state != ENTRY_DISABLED) {
TkActivateMenuEntry(menuPtr, newItem);
}
- tkfont = mePtr->tkfont ? mePtr->tkfont : menuPtr->tkfont;
+ if (mePtr->fontPtr == NULL) {
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin,
+ menuPtr->fontPtr);
+ } else {
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin,
+ mePtr->fontPtr);
+ }
Tk_GetFontMetrics(tkfont, &fontMetrics);
TkpDrawMenuEntry(mePtr, (Drawable) &macMDEFDrawable,
tkfont, &fontMetrics,
@@ -2742,7 +2883,9 @@ MenuDefProc(
MenuSelectEvent(menuPtr);
Tcl_ServiceAll();
tkUseMenuCascadeRgn = 0;
- if (mePtr->state != tkDisabledUid) {
+ Tcl_GetIndexFromObj(NULL, mePtr->statePtr,
+ tkMenuStateStrings, NULL, 0, &state);
+ if (state != ENTRY_DISABLED) {
TkActivateMenuEntry(menuPtr, -1);
}
*whichItem = newItem + 1;
@@ -2755,7 +2898,8 @@ MenuDefProc(
- globalsPtr->menuBottom) {
scrollAmt = menuRectPtr->bottom - globalsPtr->menuBottom;
}
- if (!hasTopScroll && ((globalsPtr->menuTop + scrollAmt) < menuRectPtr->top)) {
+ if (!hasTopScroll && ((globalsPtr->menuTop + scrollAmt)
+ < menuRectPtr->top)) {
SetRect(&updateRect, menuRectPtr->left,
globalsPtr->menuTop, menuRectPtr->right,
globalsPtr->menuTop + SICN_HEIGHT);
@@ -2787,6 +2931,7 @@ MenuDefProc(
}
}
if (scrollDirection != DONT_SCROLL) {
+ Tk_Font menuFont;
RgnHandle updateRgn = NewRgn();
ScrollRect(&menuClipRect, 0, scrollAmt, updateRgn);
updateRect = (*updateRgn)->rgnBBox;
@@ -2801,7 +2946,8 @@ MenuDefProc(
}
ClipRect(&updateRect);
EraseRect(&updateRect);
- Tk_GetFontMetrics(menuPtr->tkfont, &fontMetrics);
+ menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
+ Tk_GetFontMetrics(menuFont, &fontMetrics);
for (i = 0; i < menuPtr->numEntries; i++) {
mePtr = menuPtr->entries[i];
if (globalsPtr->menuTop + mePtr->y + mePtr->height
@@ -2811,11 +2957,12 @@ MenuDefProc(
> updateRect.bottom) {
continue;
}
- if (mePtr->tkfont == NULL) {
+ if (mePtr->fontPtr == NULL) {
fmPtr = &fontMetrics;
- tkfont = menuPtr->tkfont;
+ tkfont = menuFont;
} else {
- tkfont = mePtr->tkfont;
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin,
+ mePtr->fontPtr);
Tk_GetFontMetrics(tkfont, &entryMetrics);
fmPtr = &entryMetrics;
}
@@ -2844,18 +2991,24 @@ MenuDefProc(
menuRefPtr = TkFindMenuReferences(menuPtr->interp,
Tk_PathName(menuPtr->tkwin));
if ((menuRefPtr != NULL) && (menuRefPtr->parentEntryPtr != NULL)) {
+ char *name;
for (parentEntryPtr = menuRefPtr->parentEntryPtr;
- strcmp(parentEntryPtr->name,
- Tk_PathName(menuPtr->tkwin)) == 0;
- parentEntryPtr = parentEntryPtr->nextCascadePtr) {
+ 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);
+ parentEntryPtr->index);
}
}
- if (menuPtr->tearOff) {
+ Tcl_GetBooleanFromObj(NULL, menuPtr->tearoffPtr, &tearoff);
+ if (tearoff) {
scratchRect = *menuRectPtr;
if (tearoffStruct.menuPtr == NULL) {
scratchRect.top -= 10;
@@ -2982,7 +3135,7 @@ TkMacHandleTearoffMenu(void)
{
if (tearoffStruct.menuPtr != NULL) {
Tcl_DString tearoffCmdStr;
- char intString[20];
+ char intString[TCL_INTEGER_SPACE];
short windowPart;
WindowRef whichWindow;
@@ -3092,8 +3245,10 @@ DrawTearoffEntry(
{
XPoint points[2];
int margin, segmentWidth, maxX;
+ Tk_3DBorder border;
- if ((menuPtr->menuType != MASTER_MENU) || (GetResource('MDEF', 591) != NULL)) {
+ if ((menuPtr->menuType != MASTER_MENU)
+ || (GetResource('MDEF', 591) != NULL)) {
return;
}
@@ -3103,13 +3258,14 @@ DrawTearoffEntry(
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, menuPtr->border, points, 2, 1,
+ Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1,
TK_RELIEF_RAISED);
points[0].x += 2*segmentWidth;
}
@@ -3228,13 +3384,15 @@ TkpDrawMenuEntry(
int padY = (menuPtr->menuType == MENUBAR) ? 3 : 0;
int adjustedY = y + padY;
int adjustedHeight = height - 2 * padY;
+ int state;
/*
* Choose the gc for drawing the foreground part of the entry.
*/
- if ((mePtr->state == tkActiveUid)
- && !strictMotif) {
+ Tcl_GetIndexFromObj(NULL, mePtr->statePtr, tkMenuStateStrings, NULL,
+ 0, &state);
+ if ((state == ENTRY_ACTIVE) && !strictMotif) {
gc = mePtr->activeGC;
if (gc == NULL) {
gc = menuPtr->activeGC;
@@ -3246,17 +3404,23 @@ TkpDrawMenuEntry(
for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
cascadeEntryPtr != NULL;
cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
- if (strcmp(cascadeEntryPtr->name,
- Tk_PathName(menuPtr->tkwin)) == 0) {
- if (cascadeEntryPtr->state == tkDisabledUid) {
+ char *name = (cascadeEntryPtr->namePtr == NULL) ? ""
+ : Tcl_GetStringFromObj(cascadeEntryPtr->namePtr, NULL);
+
+ if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) {
+ int cascadeState;
+
+ Tcl_GetIndexFromObj(NULL, cascadeEntryPtr->statePtr,
+ tkMenuStateStrings, NULL, 0, &cascadeState);
+ if (cascadeState == ENTRY_DISABLED) {
parentDisabled = 1;
}
break;
}
}
- if (((parentDisabled || (mePtr->state == tkDisabledUid)))
- && (menuPtr->disabledFg != NULL)) {
+ if (((parentDisabled || (state == ENTRY_DISABLED)))
+ && (menuPtr->disabledFgPtr != NULL)) {
gc = mePtr->disabledGC;
if (gc == NULL) {
gc = menuPtr->disabledGC;
@@ -3272,24 +3436,22 @@ TkpDrawMenuEntry(
if (indicatorGC == NULL) {
indicatorGC = menuPtr->indicatorGC;
}
-
- bgBorder = mePtr->border;
- if (bgBorder == NULL) {
- bgBorder = menuPtr->border;
- }
+
+ bgBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin,
+ (mePtr->borderPtr == NULL)
+ ? menuPtr->borderPtr : mePtr->borderPtr);
if (strictMotif) {
activeBorder = bgBorder;
} else {
- activeBorder = mePtr->activeBorder;
- if (activeBorder == NULL) {
- activeBorder = menuPtr->activeBorder;
- }
+ activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin,
+ (mePtr->activeBorderPtr == NULL)
+ ? menuPtr->activeBorderPtr : mePtr->activeBorderPtr);
}
- if (mePtr->tkfont == NULL) {
+ if (mePtr->fontPtr == NULL) {
fmPtr = menuMetricsPtr;
} else {
- tkfont = mePtr->tkfont;
+ tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
Tk_GetFontMetrics(tkfont, &entryMetrics);
fmPtr = &entryMetrics;
}
@@ -3310,11 +3472,14 @@ TkpDrawMenuEntry(
DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
width, adjustedHeight);
} else {
+ int hideMargin;
+
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) {
+ Tcl_GetBooleanFromObj(NULL, mePtr->hideMarginPtr, &hideMargin);
+ if (!hideMargin) {
DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont,
fmPtr, x, adjustedY, width, adjustedHeight);
}
@@ -3344,13 +3509,13 @@ void
TkpComputeStandardMenuGeometry(
TkMenu *menuPtr) /* Structure describing menu. */
{
- Tk_Font tkfont;
+ 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;
+ int entryWidth, maxIndicatorSpace, borderWidth, activeBorderWidth;
TkMenuEntry *mePtr, *columnEntryPtr;
EntryGeometry *geometryPtr;
@@ -3358,7 +3523,11 @@ TkpComputeStandardMenuGeometry(
return;
}
- x = y = menuPtr->borderWidth;
+ 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;
@@ -3376,20 +3545,24 @@ TkpComputeStandardMenuGeometry(
* give all of the geometry/drawing the entry's font and metrics.
*/
- Tk_GetFontMetrics(menuPtr->tkfont, &menuMetrics);
+ menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
+ Tk_GetFontMetrics(menuFont, &menuMetrics);
for (i = 0; i < menuPtr->numEntries; i++) {
+ int columnBreak;
+
mePtr = menuPtr->entries[i];
- tkfont = mePtr->tkfont;
- if (tkfont == NULL) {
- tkfont = menuPtr->tkfont;
- fmPtr = &menuMetrics;
+ 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) {
+ Tcl_GetBooleanFromObj(NULL, mePtr->columnBreakPtr, &columnBreak);
+ if ((i > 0) && columnBreak) {
if (maxIndicatorSpace != 0) {
maxIndicatorSpace += 2;
}
@@ -3400,7 +3573,7 @@ TkpComputeStandardMenuGeometry(
columnEntryPtr->indicatorSpace = maxIndicatorSpace;
columnEntryPtr->width = maxIndicatorSpace + maxWidth
- + 2 * menuPtr->activeBorderWidth;
+ + 2 * activeBorderWidth;
geometryPtr->accelTextWidth = maxAccelTextWidth;
geometryPtr->modifierWidth = maxModifierWidth;
columnEntryPtr->x = x;
@@ -3415,13 +3588,13 @@ TkpComputeStandardMenuGeometry(
geometryPtr->nonAccelMargin = 0;
}
}
- x += maxIndicatorSpace + maxWidth + 2 * menuPtr->borderWidth;
+ x += maxIndicatorSpace + maxWidth + 2 * borderWidth;
windowWidth = x;
maxWidth = maxIndicatorSpace = maxAccelTextWidth = 0;
maxModifierWidth = maxNonAccelMargin = maxEntryWithAccelWidth = 0;
maxEntryWithoutAccelWidth = 0;
lastColumnBreak = i;
- y = menuPtr->borderWidth;
+ y = borderWidth;
}
if (mePtr->type == SEPARATOR_ENTRY) {
@@ -3433,6 +3606,9 @@ TkpComputeStandardMenuGeometry(
fmPtr, &entryWidth, &height);
mePtr->height = height;
} else {
+ int hideMargin;
+
+ Tcl_GetBooleanFromObj(NULL, mePtr->hideMarginPtr, &hideMargin);
/*
* For each entry, compute the height required by that
@@ -3453,7 +3629,7 @@ TkpComputeStandardMenuGeometry(
&modifierWidth, &accelWidth, &height);
nonAccelMargin = 0;
} else if (mePtr->accelLength == 0) {
- nonAccelMargin = mePtr->hideMargin ? 0
+ nonAccelMargin = hideMargin ? 0
: Tk_TextWidth(tkfont, "m", 1);
accelWidth = modifierWidth = 0;
} else {
@@ -3466,7 +3642,7 @@ TkpComputeStandardMenuGeometry(
nonAccelMargin = 0;
}
- if (!(mePtr->hideMargin)) {
+ if (!(hideMargin)) {
GetMenuIndicatorGeometry(menuPtr, mePtr, tkfont,
fmPtr, &indicatorSpace, &height);
if (height > mePtr->height) {
@@ -3506,10 +3682,10 @@ TkpComputeStandardMenuGeometry(
}
}
- mePtr->height += 2 * menuPtr->activeBorderWidth;
+ mePtr->height += 2 * activeBorderWidth;
}
mePtr->y = y;
- y += menuPtr->entries[i]->height + menuPtr->borderWidth;
+ y += menuPtr->entries[i]->height + borderWidth;
if (y > windowHeight) {
windowHeight = y;
}
@@ -3521,7 +3697,7 @@ TkpComputeStandardMenuGeometry(
columnEntryPtr->indicatorSpace = maxIndicatorSpace;
columnEntryPtr->width = maxIndicatorSpace + maxWidth
- + 2 * menuPtr->activeBorderWidth;
+ + 2 * activeBorderWidth;
geometryPtr->accelTextWidth = maxAccelTextWidth;
geometryPtr->modifierWidth = maxModifierWidth;
columnEntryPtr->x = x;
@@ -3537,8 +3713,8 @@ TkpComputeStandardMenuGeometry(
}
}
windowWidth = x + maxIndicatorSpace + maxWidth
- + 2 * menuPtr->activeBorderWidth + menuPtr->borderWidth;
- windowHeight += menuPtr->borderWidth;
+ + 2 * activeBorderWidth + borderWidth;
+ windowHeight += borderWidth;
/*
* The X server doesn't like zero dimensions, so round up to at least
@@ -3589,6 +3765,7 @@ DrawMenuEntryLabel(
int indicatorSpace = mePtr->indicatorSpace;
int leftEdge = x + indicatorSpace;
int imageHeight, imageWidth;
+ int state;
/*
* Draw label or bitmap or image for entry.
@@ -3607,30 +3784,31 @@ DrawMenuEntryLabel(
imageHeight, d, leftEdge,
(int) (y + (mePtr->height - imageHeight)/2));
}
- } else if (mePtr->bitmap != None) {
+ } else if (mePtr->bitmapPtr != NULL) {
int width, height;
-
+ Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr);
Tk_SizeOfBitmap(menuPtr->display,
- mePtr->bitmap, &width, &height);
- XCopyPlane(menuPtr->display,
- mePtr->bitmap, d,
- gc, 0, 0, (unsigned) width, (unsigned) height, leftEdge,
+ 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) {
- Str255 itemText;
+ Tcl_DString itemTextDString;
- GetEntryText(mePtr, itemText);
+ GetEntryText(mePtr, &itemTextDString);
Tk_DrawChars(menuPtr->display, d, gc,
- tkfont, (char *) itemText + 1, itemText[0],
+ tkfont, Tcl_DStringValue(&itemTextDString),
+ Tcl_DStringLength(&itemTextDString),
leftEdge, baseline);
-/* TkpDrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y,
- width, height);*/
+ Tcl_DStringFree(&itemTextDString);
}
}
- if (mePtr->state == tkDisabledUid) {
- if (menuPtr->disabledFg == NULL) {
+ Tcl_GetIndexFromObj(NULL, mePtr->statePtr, tkMenuStateStrings, NULL,
+ 0, &state);
+ if (state == ENTRY_DISABLED) {
+ if (menuPtr->disabledFgPtr == NULL) {
XFillRectangle(menuPtr->display, d, menuPtr->disabledGC, x, y,
(unsigned) width, (unsigned) height);
} else if ((mePtr->image != NULL)
@@ -3672,7 +3850,11 @@ DrawMenuEntryBackground(
int width, /* width of rectangle to draw */
int height) /* height of rectangle to draw */
{
- if (mePtr->state == tkActiveUid) {
+ int state;
+
+ Tcl_GetIndexFromObj(NULL, mePtr->statePtr, tkMenuStateStrings, NULL,
+ 0, &state);
+ if (state == ENTRY_ACTIVE) {
bgBorder = activeBorder;
}
Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder,
@@ -3710,17 +3892,20 @@ GetMenuLabelGeometry(
if (mePtr->image != NULL) {
Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr);
- } else if (mePtr->bitmap != (Pixmap) NULL) {
- Tk_SizeOfBitmap(menuPtr->display, mePtr->bitmap, 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->label != NULL) {
- Str255 itemText;
+ if (mePtr->labelPtr != NULL) {
+ Tcl_DString itemTextDString;
- GetEntryText(mePtr, itemText);
- *widthPtr = Tk_TextWidth(tkfont, (char *) itemText + 1,
- itemText[0]);
+ GetEntryText(mePtr, &itemTextDString);
+ *widthPtr = Tk_TextWidth(tkfont,
+ Tcl_DStringValue(&itemTextDString),
+ Tcl_DStringLength(&itemTextDString));
+ Tcl_DStringFree(&itemTextDString);
} else {
*widthPtr = 0;
}
@@ -3882,7 +4067,8 @@ TkMacClearMenubarActive(void) {
if ((menuBarRefPtr != NULL) && (menuBarRefPtr->menuPtr != NULL)) {
TkMenu *menuPtr;
- for (menuPtr = menuBarRefPtr->menuPtr->masterMenuPtr; menuPtr != NULL;
+ for (menuPtr = menuBarRefPtr->menuPtr->masterMenuPtr;
+ menuPtr != NULL;
menuPtr = menuPtr->nextInstancePtr) {
if (menuPtr->menuType == MENUBAR) {
RecursivelyClearActiveMenu(menuPtr);
@@ -3957,9 +4143,12 @@ FixMDEF(void)
if ((MDEFHandle != NULL) && (SICNHandle != NULL)) {
MoveHHi(MDEFHandle);
HLock(MDEFHandle);
- menuDefProc = TkNewMenuDefProc(MenuDefProc);
+ if ( menuDefProc == NULL) {
+ menuDefProc = TkNewMenuDefProc(MenuDefProc);
+ }
memmove((void *) (((long) (*MDEFHandle)) + 0x24), &menuDefProc, 4);
}
+
#endif
}
@@ -3974,7 +4163,7 @@ FixMDEF(void)
* None.
*
* Side effects:
- * Allcates a hash table.
+ * Allocates a hash table.
*
*----------------------------------------------------------------------
*/
@@ -3991,4 +4180,9 @@ TkpMenuInit(void)
currentMenuBarInterp = NULL;
currentMenuBarName = NULL;
windowListPtr = NULL;
+ FixMDEF();
+
+
+ Tcl_ExternalToUtf(NULL, NULL, "É", -1, 0, NULL, elipsisString,
+ TCL_UTF_MAX + 1, NULL, NULL, NULL);
}
diff --git a/mac/tkMacPort.h b/mac/tkMacPort.h
index 733e745..e05b7ba 100644
--- a/mac/tkMacPort.h
+++ b/mac/tkMacPort.h
@@ -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.
*
- * SCCS: @(#) tkMacPort.h 1.52 97/07/28 11:18:59
+ * SCCS: @(#) tkMacPort.h 1.53 98/01/08 14:59:32
*/
#ifndef _TKMACPORT
@@ -90,11 +90,12 @@ extern int strncasecmp _ANSI_ARGS_((CONST char *s1,
#define XVisualIDFromVisual(visual) (visual->visualid)
/*
- * The following functions are not used on the Mac, so we stub it out.
+ * 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) {}
diff --git a/mac/tkMacProjects.sit.hqx b/mac/tkMacProjects.sit.hqx
new file mode 100644
index 0000000..97ae8be
--- /dev/null
+++ b/mac/tkMacProjects.sit.hqx
@@ -0,0 +1,800 @@
+(This file must be converted with BinHex 4.0)
+:#d&bBfKTGQ8ZFfPd!&0*9%46593K!*!%PA%!N!4%'e0*9#%!!`!!PA&b6'&e!RX
+!N!-@EhX!$3P8Dep04%9',VQ(b!4BE$J!20%U!*!$J!#3"!4J125YX`#3&!mM!*!
+%rj!%68e3FN0A588"!,$B'6'a%)MK!*!'Fhm!N!B1R3!!h98!N!DCC`i!AFIem[-
+jj3lP(TkERCDheq5$M%@jqk4QRbHR$MBGj(%*IhTQ-Xr1YlekmI16E#R[#$r##2m
+)Pr!NQp$)2R,E5l)*2r*l32N4IQjMC*00f*E`k`JRYmrB%dEfQ3dBi8H1EBpXbEk
+-2q'%E8CBY`*IApGRRAPb+[25)V62c3Kr`Lpb@r,Ef!9!0M$qp1eYi&29)#(%4)K
+84%JiJa#eQ"#c"f`XNLc"NiPGEI-hHU24J"T92&'edqr6%lD#&*NNNAMF8-EM%JU
+UjV)RbXD0K&`9a`p-**)pbDQ'[6je"*@C&*%XkA'j1r%HP!3i3j%(IjRV#PRQ8VQ
+BSQ&5$IqcZ-k,XH1keI#($+Hb!IkCA2GGq%rQZXh`cq+kTq'IcA8[`$q(krE!I`S
+25bimm)qk#hKm8,F-([PFGc8mcZDkCRJ8F"h'iabZZ`-H8lRZQr#BaR8rK-GdVRX
+#(M1ilRI`Q-Per`q2@8`RBhaRFahDc1%k#mmAe&A"iebZZajcQ1ZLm*Kh)%[44J(
+lfhQ+[HdMQC8m@b@b@&j$HNal3'HDdi2fp9h0c[++bT++YS#Z4K2U5M@X*j31l`h
+H4)8eM$aHcHF0+RBe&!N%r8R2h!i+FcJ3EYH5GXbr8V&DMhU6C[DBTUXKj@VrQK[
+9D&[5cZEcq690mAMeMU44@5`3E0Z2i2+P9d-8f[c,rH%"Qr+!jY8dIkLe2cTS@"-
+)G`fDl!qZ[GLqH2&EX@9QEiE@AZN%%-P)Hqa["J4Y$JB%$3F$JLDHLXTpq[hCjl(
+EY"#N4pJI6"M9qYHq&E0kEl6GVbYeIPdI#&SPH&'FhNL%@KRC5DeU!PS5DA@YiSl
+SJ9"JE4mSTpIRVP1FIS!f'!0D+fUmiIDBYpfrcmSGdb1aI9@PA2@*@ULE@%+3!*)
+Je8++KG3++495&U4L5+Q3!%SKK6)S'e)FT(j)DC!![L"Y3D+"P!@T$G)rj#4)YC!
+!BL'e3NU&9!ST&0*!T%q-0L&+AK)XD`-4F8f5VUcf+!lE#K[qmjaq2DVHk)pfD3U
+YV(AcDj9&NVAh3FQkUV6"VG4@GC!!"8SG[XS@cPY'*0H2#6R[PrRc(+4GDA!65fm
+AXDc+bVq)@19eVh'#EpSUEpc%8rY+S+-P9I+k9hVPkkUrYHK2Q1Q5Jf3l+e`0N!$
+VV8JU`1DfZ[VDmd&rYmHMYS*q8ffJV3EHMh[pZKrH6i-pN!"8mQaPd)[qrPc[p+$
+pbj'SIa@mhlM"(p@)p(C-SB3%D29"FNl-RE4Dh%m$e8fVc'j858Z`!5,4jS"N)88
++NEj)GCmKRiAAHZk[&(32Fjd$LY`2H&,9Jqi4ERFY&,TbVJZ$$QbTlLD&j(C`(@4
++(Y0*L([U6kK1TVTAZBq[3C%VP+pcl-L*F%kPViRi*hGLRU,'Y-+TjI3ckKaR32-
+TGAS8L9L@[I&cLNCeNi'4"j[48e+684&Z$`DdMV2l!5JZEmJr!-Q-qE82j!#(cbQ
+fN!"m,d6YE,1mERGqP`6eZR#44pli#'Q"A#U2UK'-0HDrDc0jfEBRrKFPmpi'd'f
+SfAP1KQ[2c09JmjYYH`QjB$keM&@p-)PFieC8NMpI*91A&*1CFh[Q04%*rM,m64I
+0d%P,HF(-I%NZ*GhY1GZPI+QUZfV,MZk@SVQhS#GU@GUHBjfaUqVj8QUCDhKI-'2
+AlFprjBm2&C'k@afhKKpVFYIX*#f)1PpC8+SX)C8Nka[G-8Ge25NX@d)FeQ82I[Z
+"bZ*-kl,lHZk[I'MRLLhPC&BTF45ELV0FQq2Pa34H,[IrNCa&$P,T!)rYjSKdAdr
+06R1Q+fEEmmBHM1f#G4MERphTLLR0mkZf2p2E%j4GfhTl9(KG-V1hCj9jkeEAe[U
+U,ci9Ip@ec49cV5!%-L[c+J[*JAmZCYMXap!#0HGfZ+iImR%2@N,HQ#&r-U1N),r
+J'DY8Ch18KPp$Mr(G95m3ki9KN[QC)2P#I$HmbZ*lFllH#Sh59C-@G"&cbi80lZ,
+XiQ@YUY(iBXfjV!C2Y3@,33$l@X-L`3HX$CZ&K0a-@iTpVdb!)P1'C`CDGaCk+a(
+Ad$4KLQ"aLB-!XD,9Sd6i9K#-HJ"2%c!&X4`r3'i*r+"%p`@A@Li@YK8'Saj!rm"
+-Hm-5$Lpafm5d%RfM&[l`bS!Ar9(,b861-IV%85hUqeF8d1h(VJm+aN*f8j@C0%J
+ET-Rb6F+$4-UQ53*rQ-#SmR[ES(pUB4h*Y*MSG"K,0Q-SDb!ra6r5h+cThUMJBBk
+&G[&S!4f`5T68$&CU2mPf'Q@a3kL0B8(4M'"hP[9SMp@*j)!SqXc$i3"l%)I60%Z
+R&dF1"`4R6jb0+h%!Pr9h6Z#NI@0J'haQ&bU3!$%Cb[6bA3NrD'K+qMP8S4!2pdA
+McDQ3!'NJRJPA2,U5-@*j3'!5+B0cbRGFA!9Lmq$8LJ36%IM(DC+Q,3+%M*B3H5+
++(YC(%F%3YDN,lHlbLSA+`R*E[3fHRQTlr8,45JV3XMG!mXa8GeE[+jZZM-HrqUc
+iT8B)A35j%8j8d[G$qHZI)f6Tli9Zp5!Pf&*P!p``Pre[#!PZM'c%A&kc[-RA&@M
+$)F2'1SqGmC4DYjY08KU`PpFfX%B#k$+@4p9B4-%p%A*PG8d&NRRqPPY%$UPKY!5
+-k1KGd'e&#iX2qklZ1NX`d%T+"VV40B&@T6S88D1kJVX!R*l'IR@C0aK8eE"5j3p
+'L,04BBX%U+0''+#R'a03#a2m"%Erqef,QJ8R*,$662XUm%FqMIX2N!"Eiki%h*1
+!8qI[GPcIPp2-59`3&9'+I0326qBX#PB))rp`!iCKMeeSBqlQ3Pj98#lMP3A&cUX
+15Lh(JS)l%)aP5,JDbeL'Y*CA)T3[`ppBKL4HN94(p+@pYRMmH`m)@r*#$#-$(G(
+H[i@ZMmI[Z&RS9Jp5FTTeraf-N!"riEiEf!&$U4lScGEHhrkKqjbqABA)m0MqV,j
+PC-*9'4Zk%k')%'k($K@CC1Fc-YLh#(*3CV2jdp1#ic5f5!5lK`)!(%jR69RD6pm
+m$%6fN!!2@!Bh6J'1i@LdXmeYCq*D@eFlK2"p(2896I@@eJlLdl3@BYUfRK6-C9[
+Q8!UHh)(2JBNJSaJmkVQA[U1hB4H"i4ME9T%B*KV1$J2(iX@L!"a(![*2(%G@2Cl
+#-3VN*!lrDJ(!lNQ+Bf`E4cSH1$*!FBa&)cNhPJSX``'VFJ8"1(bMN8h(&3IR$4`
+MPHJNMV'H'8l5(FYAMA5-e'QfD*I33QfBlUr66AEh1)p"(iQj[U(BYUQqf+Fe#2Q
+(''$($H,31S+ieA08qUB9K`Z)TXF%!6K3,*!!**r%&AZjR('RfUrL$mBp2$Ik!H0
+1i4!'-'jhQB0@d"%C(+8p+))2jRjib[FpjMk1i`4c(mGaJVNIaA'FZDGaL"HBqe!
+m2Q,ZUF#qcpc61%i`pb%B(c,h0!k"!(2hYj2$G4U"d+h("jRlhE41#cmBph$LIm#
+i4rF-#!)BGf-JI1NPbZUPP`malUch'"2J'+d-lc+QF4`RQ-j4(-HC6KV(Zj9m#-H
+(P6b0BkcS!3l)qk2-r0-+Nm#"DcN15epRih#Q!3keYA-%KlZeFac(C1FliaaF-Te
+11ajp)3#3!'19%bk5`)`qLL0iK(-#$Tb,6jiC-93CfZKqIa&!A-p8KJ3R2liMmbL
+1G!8Hbl0%IZLMDAC-XYQT&DNDNdZlQ$Hr(JE@Qf,*"k5I*5HkQ%)!(2DJTK%S-9"
+!KR%!Cm#iNT&q1qdq#J(L3EZ'3J!F4YG`"-I*VQ'((JU5l4k'Sh',I'h*HRN$k![
+bHZAUja5bBIY@d'q3!+qjSKGF`Ld@mei&IEIXI6&(GTMT,3m8"akF3&,aQ-JchUd
+*4!lR+hCV8Pd@KJ2hC4!mlZ*-hY0ZM4!JAfQh4JL!!i@9-fMHr#HZ&!HNadJhD`+
+(5`hMe48TNCa1M`"JeKahrSr2Vmm4[de3M-MEA'Lr#'iR+#+4dDQ&G&`&"C-BCd5
+F0)R4GlR4)5FCiJRQ,UKJTN+!bLP@U&36NPj$)3$Tk3KFpP#-L)#J&b0Hh80aXKG
+c#)L3!'#IaDM`I4DM)YlDCj%H"#06a42-hHkqXb[YajKi'4%k85B%`1(SM+kb`2q
+6Z#*M%Tad!1KNfZRm5%kQRFjALL-N!"Ja&3J`,cVK0LB6F9dCL)`cV`NFiJRQKF)
+RjIiE9iVM`%EZMh%)!1S3a6&fYGi%$Zi$cb%ma10b6M%Q3*(bFBSaMH+BB#MTbLR
+mB#LMq5&NB"E$mF#*c92-BM5Z%iaJ)Zp46M##dAK3(-FVm"%Fl$JQ-G!K6!*Q-8%
+rhda#F$EN2M[T1r$["VY"8T`"rJMD`Cf6!cMQ`k-)l!,ll"EFNX4RHM&TGa%F3Q[
+JklFV!Rm'[Ril21HA@1RYPhQ"Hp#!fcA"`m(X@[(@6(ir4FCIiB3($lA,hI&c$"#
+cQr*jH#aPrLl$Zc$jA48QZ1f56'(qGZ+0Zrc'#Y-em*M+r-Q2JSlI@c%&Hf5cQEp
+06b*JEJGh5@8bh(NA[`3'r!k,D6[40l0VY)+1hf3aE4FmCM+l*EM@QppR-Heee$&
+m@fi&(Er9BMVLc'AqfR##MGpY-4fZ)j8i[T)e'!KQ0`2[h5aKGUCISfpZei#q'Ek
+pZ!Q#(lSl!jSAdV2-Ac2HPm'2hTeeC6)2[*Jcr!$H@AM$'SY6AXFES12(m-l#[(Q
+#iA[T0Y$a`hKR`m@RdR6QldXB2hiNEb(@M3HCh3V`B4c-1qG5H0!c*%PH,Gi)b)r
+R24I`bcaq2m8Bmd0kVC!!Cj1ihF1[B'iaZmXK&bqpRH&BLGd-IQ"[)4iAV)4d$HY
+F(i1Ima3m2#'GcLcdf4@Lhmb3!"l%'Y&[GalQ#[M$12ECcB0BbS8K[Af`cTeh"GJ
+Y#88dm0G[Gri[i&(UUB%VD[2Z`KV%MrqerLKCAr[p&GTB2#,B#qQ2(cDKH"lXqJF
+DF(`iZY[+mU!H,ilM&fiY!Ka5!E@EmRhX'['$JZGJ[Eq%fEAp#R6mZ1"1U(rQc3b
+I"A18(K(m2`!!$3e8DdaTBR*KFQPPFbkjE$J!20%U!*!$J!#3"!4J125d13#3%4B
+!!%kJ!*!%rj!%68e3FN0A588"!,$B"&#a%)MH!*!&!P"2!*!'2`d!!*5m!*!'8,8
+'q)klAkmMI''hf-4m`YH&hd)iECq%VqaDH)36YMY1&TN,cGjEU%`AHV+&Zr"&#GY
+iDRK16kC[(*qdcrdGLq`MYeh)2X)AY[!LYr![mb5l)mIc)X[aA2KJ-F+AQC&p,[a
++ZmKQNB@6@ikl#5Il1V,`Uq00b#DF,$bbBSAAGF!kkmNYG*YH!`+`MbcN1GPN1E)
+M#aNXj$ECVFZYXlbXXdPqCTlFcXZFTH9(Qq6C)0V,G60lb`Cf$MVGfRPTRA@3!0r
+#VIF)h+8(#H6`0[6Ehl@lpX@$qb&Iq+),KrUP!mJA)9QZjh"$#GcNi1ekXZ%QN!"
+XH"k"4jE)NZdZXN6i!S!&F1,6p5a1CrLMRmm*jHG[Jr`@IQ3Km!L(YjmZ!*cJ$cM
+cFZ"AilJH"-&*3C!!@arNIhThN!"rc9Z#B1f(ZI2jA$l(dAcemAadBCJNY6JTP*0
+i6e40HhFG+9qUA`Za$f'r(33[2K`%2p$eGh`fi'"@b5a3kP[acRd*kVKb5-"VmaE
++TX0L[(bmd'p`6fF1FYkE1j4ERArpBqpL-Z+Fb3@G6[ILRh9bqR$0FNHqRldQ#&l
+6dDqZa)29,bc&cE!D(hq[E,!q@*2lmrc"hVRM3H2"&IR6FSqF0"TXi"Pq13JHh"'
+FGV4@+hH@*iUY*,UNY[mE9F%TRVeNi920NbH,"EqF2D`p84&aRPb&j!(-8hY@lZ#
+Vk,Vec@3@5!FcJA9KHDQDDm9AmI0`I23Fmah'2QC2HH,a1M29j(6S)(QVXI'P#hG
+APVC(iAb8R,rTClpCFp)hP$Q3!'rNccVT2B-Q&282mk"qqDZR,hDLJXGf!#G)%h!
+*$"i9@IrdZUl,SA(NJT2@9*E1S9FXUGIQrVXS0YMR$LLb8LiGPH-Qq'MQLFGEH[r
+hqQMQa6*0d!bFqh)(me@DR0pTE8EUZm`LmDh'UMkX[phGeU+qHl"Tmcf1cCM[&p9
+Ga2I9V!ZB6kd%9,@ElrIdF*)bqH60G`@(+[04Jq2-Gk$rk[&P$YAQqqXF*TM[(h#
+BD$l@$T2-pami6$EILacdAN)p,fpmLIQ@FCKU[ZdFTTQ[PF0dmlf2`kAQqaN1-mc
+h+eB[q2ijKjRQqmmF,RHqT'TMP[RQF*KY[R8FDXc('r2qq1M[a-(h)3jAQZqA1&a
+P[PrR-0Gmri,$222p9`jA1ep+G6AII0braRce("DBldi1#mhh-)G&j[YT$S[0p`b
+(*HEl"JI90l521UCfD!AdL'[0ajXZ0ap[A'XqqXF+ml&FZmjmIih$5[2p23kVc2G
+&kcrirK@(kmhh"acUR#qM2V,'I,ce@[0YjN$Zq'lMX0jmY%RTljP$(25mT(c8eNE
+cICR$*[2p,JIU"GmIFb![@KajEc%IpEr9I,c[0[2YiR#MqHLA$HEl!!Ik$,k2Fj!
+!3ERL9JilcIFl("V04je*MmkU4j-A2RT0NrQSQAHCMpbS0A`-9FhQHj6$([2pE3j
+lcIIh1H`chpFiY*L2Ypp[[MrLF,2cjG4ck9Iik#1hQ)rDZp9mj%$GiEZI`qhQ8d[
+8f'lc8A0hQ)qmk8AirLd('3CcRq2!kS14JCjqa(cdV+2QScl[-KpjhfdqCS9Mj[Y
+E(1MRq06-%pYM2RSRYBR[[h#J,c'5-,IFDclklhhQ)eFCHr0khj2QSkr`c[LSV92
+QHjC$QrPqQi2-l[P2Fq"pe&HPQRl3I-`-Cma(,j'aVNUeqKlcNF0lcIFh1FKm@U8
+CL"k1l`81MjL2@H3Rc-HF6ap3hcM0-$+9Me2rIFamp!lQ(Abmlr[04jqQGq(l*!I
+Q2RaIiI#%qIie"fSF(l2)Ah@qmCS92fJqqZ92QSrjJEc`d9YrbRc8&V-22YlJ`qB
+MIqBqI"rP3!r(aacf0mc(h2QNqCJlU4&m[mq"2S#21[L)me9VRU4Qm6%M-I[JBaj
+JeX0(lp1l+1@M,r`Gmr(Z[!-qlRr-I*rQ3'r(pimir*cjk1XrEllra1([QSrCp"2
+10d&plKI-aic(6)f2qBIj#"rpJ"V%4frkP2QS+rSU2Q)pC6lHJ$I"pdd1p(amp0I
+210p%cHHI04qck1I-4eqRYq#M[cjY2RSS[43I2B)j%4re3$hLSrpphRb!*r$MSrm
+alkK[NRB0cjQ21INIQSqHp'[QBiEjJ[R)QpN3(hhY5qDMKTQ,mI&'[$Nqm[i0mre
+($XahkTZX[1PGq-LE[S'2pfBH`8F[r-IQ)qrRc8FIqNhc8F0I0ar[dJ0lF0Ym&Ed
+Grp[I`GhY0-`1TiBe)($8K$1mR@@hZ,&FCXD2-hGKf6rXYalN02MLJkfQ49'ST8d
+#Qm5QX#aa+V"6XAPX$MX"@idGMjf"[4`l'mYF3[p6F*p+-Y&V1rc-cHTkl15E2V2
+QQNlRZPQ(lT!!*6`EZX@kVM2`prIH-lNrqTJ6iR-lY-"#'AF"3TV+YNFEr**jka@
+PAX!fk+aENmHDY)d2r-I1A!!0qP-aUbI$[H&B2@bhShCa6fLl'[ml-&%ZP#kmb1h
+@D&IU8Ea0D[GlaeDASQ3K+NbI`'EdIiA*3-1D0NpYfe9GUXd,80Jb5pd%MC%pdeN
+e6f8ICc-Pq"q*dRVmV3Ti'"1,V6VE$cCkp'ED1&Yh0K"XcGQ@Xd9QSmpQLZl1YSr
+*QNdI'`-f08cAE2MBmV$YCV214Te01KYd0ZGXQc`X$"XJYTFH*S%DiaAC9V#PB$[
+"9S)0"YX-YK*X)pK#X!eKfm'%cf61"S,0!aX(TR1f$@`Cf#k`9@#E`"D"l3(61GX
+#YJ4X6pMfXFeKJm*@MfdKfd!f6P3CRB&Y)T-r@cbUQkdGfcUfG'cRf-UaM@-,arD
+0V4YE#ECX6(KX(GQXX9&M5m,QJ#dlfh@fkQc6fD+bd@3EaKDGl6QE+$D2E,ICqV-
+eCA2"aT302pY5*NGk)p-B'hifl@`0fDbc2@%Vc!DGIX#'J`d5Qh-3#'cTfI+!0'"
+Mc"DDl60EClE@E+[C1V0YTK1beDD$X`PM8mG@PSQ2M5bEF,DaE%(Ba,)jBi214TS
+0#YXE0XpXVGJdXbeRbm)fL3dcQhSfp-bSE16C,V2*BM2)4T!!65#E0MD)E!,C!,,
+jB`2*KT(0RlIeBp[(PSm0$KXqYN*Xp0MNXD&MFmH'LNdG'cSfFf`XfFUab@%,*pX
+hjm&(0lfcH+"Q1f4hcFFdYRhdjdGPUdY4QX6lSQ5TAG!39c0laNcK&EQ00efIfhM
+*jTh6KCRYLm'2&fCefM4bqJ9"EJGpriUlejiq'5`8GMVNK%a6MhD'3IaGErVR1F5
+'3VbMUqDImlB-%Re%-h#F'6EcXYaGffr,AIGUKq,kD$BE-iH`NhZl(m8k'pBX6dj
+8J[CL&`dAblGE6"8dZMA-FRAEmqfSN!![If6ajCSBCqBQJe0+icYfmMD(+Q'L#IH
+*fFV-QILI,*GM6C62cG6Q03eq,Ba56AB[F*q*m9YEkk(LIEG5dKicpMQ"$pAjaEe
+4dQDh8,NPLCAjR&@'[1&,eE+YJXEpT2CN@`'$D6LEE3,q*(Zc4F+JaV-03E`BV#m
+%Z3c2&$p(dfcFi8M1DMU-1fc"@8fYHF-Pk1R5`afkCVi%dl["IcTJeUY64XDQYib
+2&%DfM&C'16C0M&8-,1P+qG5qEJ4"2[39-3cl[i,TrMrj&*cGH'Z0Nh!,I+"0fMI
+-Eh`1#,4*`'c!Gfj(cBied88RGhmT)Jc%6a-KZZqUQEh8A[XPlJTc#TK0p("@T*j
+SVhC(6A@prMNLJ$%&bTX#qBDTE3[++S&9A!+8(fP(YD&31#(9KRZ!5Z2lG@'cIJZ
+Hid+!hlce*VPJeGV+dUELZ@0E5f)hD9ZXrbHpbCjUIHUr`JkqFF(C6fcL&*Je2"M
+Ba!%-c"6%D(5JL3#(G%[c8%%&dK(J34UXl&d!(r3m)@Hr`"SS!#%0V934iP`%!+-
+[DN53!,T`1C%F&Jh(riDiV6b'+iRTPP[h5Dq3!$0J2kqa!#ccD(d!RhNE"`"NAN-
+&N!$PdIS!"20@2!$r2&SIJ(%HV3q!1!rJ"c",D(dd!%YSI65J6fKp0($2)c-#N!!
+RY$kaZl%#C)L*6N*SI@+LX4"DRjMS5$aD(pj)D(hLZL1d2TT15'KpiJ,C#De2A'!
+cSI@*#q3QY$ja!4Z&eLFZB+$3qX3&pT2&@9cJ2D(eL3Z)*V3qFEfad2V%"HJ3@Tq
+i3)C#ka2AJ#+d2R%"%iA@*blJQY$ka%9()V3qF9&A#+e2r(i1dVVLUJ0Ca-8rbd&
+SIH+2@Le6jY5Ud2SN9"0#kj23H`QY6d,hKGBR)D#Jd2SN"1i6@Tq%)"K#kj03h3Z
+YMkC'%PUIK1T$D(d5!MJ+V8p#S$bKp8N)G#Hd2JRe!+(e5@K'%eUIK)#C3ZZ6%*!
+!8'Kp%U)F%PUIa(dFK0BR)5S(SI9*r$-(Q@i6AqBJY$j*eB(3qL69Di6@*kRD&MK
+b8R8SY$j*eBR3qL6eMN,VNe4Z3ZZ6e2!UY$j*J4Q&eLFT3+E3qL3&+*8K0bP`U0$
+k*!9L&&UIT%#-3ZZ6&!K4D(ddcC23qL3&C"9DRk6!VN,VSbQIK0BRUCS3@TrN!ab
+%eNG633QY6r)4$N,VNe+r&&UIP2UXd2UNe"Z%eLHPRL+d2LR9[0$kT&4A3ZZ6dMX
++V8p+XB6@4i&p#V3q+I8'SI9*#3!Vfib8hPjSI9)#CJUY6dVJ5k(e5@Qk&eUIP%C
+fSI9*#A3Ui+,8acJ)V8rUlf`H`FGm),3q+G%f#De2@V1(d2UN03m)V8pDI9CSIG+
+UHi&NTY8,K0BRV4U6e8"Dlb@d2ZNZ-"JIS&qKp8N,`#Ud2QR0"d,VNaEd5@KpdS)
+b#Df2TVX5@TrdA4aN1j2@$#5d2QP4aJLY6rVc()6@*k1j6QKp-TUA"$+488d,V8p
+'r9jSI6,UZ8,VNe%r&9UIM2U8d2TNe#1%eLHMfK0DRicH@QKp-XT(D(db1JZY6dE
+pAQKp-PVG#+e24U"XSIA*L*C&D(dbUPfKpFNmb%&SI6,Uj8,V8k(j8'Kp+P5l3ZY
+6SGS9@Kp0[b@d2K@D(i6@Td)p8@Kp+P6E3ZY6S6F9@Tq+,MJB(h1Ed2T8U2F)V8q
+&!1C#ke1K199SI5SdR`QY6iAkVY$kk$&CD(ddACF!Ll1Dpi6@*kXj5QKpXTT$K0B
+RUei[Y$kDaNYSIE,U4d,VNe@G#ke29M8QY$jC[DA3qQ59Mp$kC09[K0BR+c#j`1H
+bQLH%eLFVqLfKpFQ+DNeSIE+D,iA@*kH(&9UIR2U0d2VN0"X,VBqQ"K0DRjcU8QK
+p0%fBd2VN0#m*VBqQ$"0DRjaQ!+(ebDQr#Ue26Me4D(ebkN&#kj06R3ZY6dke**3
+U1H8XY$kj1cN)V8rZEcN)V8p1ml63qZ5qb%&SICa!hrJq#q[rCK&fJp!"[8j3%P(
+G[NaY@b*cCDRaFFi$5+q2m5`$5+qIH`B*p[-RN!"JcJ`H*&8ZKl&(X%HaGf([aKl
+$YQ,IMEd(Hbrf2Z`*,,6[!,3!DU8GEbl&TdNCFeL)N!$b@!MpaQ((BkZa%l'6X*1
+a8l#AB+GLTf%[apCJVm$1`9k*[3Sl&cX2Hc9f2[BDl!,X3Z`Ll',X%Za5l$,XYGM
+Pf&VXGGL9f&ABeGMVXAAB0GLef(ABpGJ0f"Z`'l'EX2ABcGJYf+hBEGJEX3hBlGJ
+Gf*hB4Za0f&hB*ZblX,ZacGJpf,hBIGJ@l(lXcGJ$f&Z`Yf*[`pk12BLp!hZRE!%
+#CCTELDqRm1PSVm`&P100dcY'5q2&m9ffd@[rcR-PU`HrXcSp@`#f8M09Dbj&Am'
+(Z%qrPCZ@IUHb0&@E5m,%YT@ZP8r0*B*-F,apDK5p&j[!+Tkkf#TX'X[f[3+EaEC
+LFpK+E"jEK4f((BqYaNl%3RJ+qHJ8l#ABUGKTf0RB'Z`9f$RB+l&ABHGLjf'[aXl
+(AS0GJ&f)AB4GM&f#ABTGKVd@Zabl!RXGGL9f&ABepRTX(AB0GLef(ABpGJ2f"Za
+'l#CX2ABcGJYf+hBEpNCX!hBlGJGf*lB4Ha0f&lB*qblXEQ`cGJpf,hBIYJ@l(hX
+cpJ$f&ZbYf0Z`Yf-2BZr!(X)HaKl"(XAHKEdEH`clEZaa,+!0c6(TRCpCHmAIGcU
+I-T!!Krpj5$E(i1H"QYN+'8Kc@h(!GG6rZ4"``iBpda28)9PEU(!aP33E,b"22i"
+Ab`8IAUf#Ti5h9QGfCMkm@PeiE`D[,MapLHM4)iS%RdFE"d-+GK6-U%G##9i2I"U
+i(`mEkNci(#[69,$GD8ULDYaSeHUeD,jJrBe@9e0C#RB9aZ*')fi'fk*QP05b1aE
+D[k49A3c5*B*YUU@0X&@XQ[H"0)fEA@ppA)q6R[1"T$h`(UqejZ)`QHpHf&`,kr&
+#chXUh0IeEBfEDGGhip6ihULCYV[qKQDYGhG(G0PM'69'cH@M[N12[3dh#QQSVQU
+6hadYe2U"QUY*IDlhEXe4XjGJmr,F[PTc2YlAbk-PFcFZp-+e0,UHrE2TmT`#294
+99@M2%II+$be8G@TYK!Z4(!qNYAS@Y[$bHjZerHHj[(%e9m1k)TeHXNXENi@pcR%
+kGKP[iLA%8DK2@jceBA2[D++dMHp1pi5i0RA$i@aSZ+V!TaEL*QQF6A(pXVl6Mli
+RfZqH$1IHlN2LT$D-Xe6kpBejLejS&[9amj+DjAfLfBlYV@d$fG*-%jIqPL6ThU%
+a50NFYY,H@UY(f0-d,1dq&6CF,Y['h2&Sh)#4dD5b,A,KYbAKR$PDh4Xe@'ALZEY
+A(mUhE@*Vep98,[9Faq)dlMS,0E#ceNlRi[h@$eTlr8A9KGqTLJkr"jDEep&fZrX
+HZeTTYe8eKG8PjcJH9YhYTVM@l,lpEZ3+lGSEZVI`'iMUELIUpER3"@Q1kS64VN)
+KipK855)A$qrQ@YY9!%kr0V6h[[R)26(HaM"a6i*c6qK+'PqK&qa*V0!,CE+[ePk
+f9c,G9,P1YUU$XF9iQaIaamEhYq)N"D[4PJECMCSU+SeUcLSN86YH6UT41f"`8I`
+U06$K%&eGE9YZ+@M-jG0+L*BSA-V`(ZT`U'h0R@b@42YE39UYijIXJfQQVCKBGbr
+l[@MLEY`b[K@I*H946l+kZ0'4a65S51qLD(R4M6YQ*`TM4FA"h4LQf82VjpLph%a
+VG$"pXF@m1(A[E+T9!DcJVKX)ED%Q'KTCPDJVX9,j`U2Z6@'p(XG0TVrM,9+U'GX
+`G[EC,P",S4bfk42DZcXk%*6(Yai06C,HDpSNe48r%A&+)RL9hGKZ",['TVIfXY(
+hr14`Uq3+jG%i1e@`YbEIc906fC@1LP#Ar-,aqS@Ulb8Ib1TB"ffBhVQV&d-phEf
+dkTJMULNdPDfeT*d@CU1&"K0&l#FG`Nd+dB5U@IqUfZj0mkrSj9em$"1LF,9BU1D
+U&(q4,dMG+"56HI[LE99#IV2DXm4SIL6U6qq&i9hh16m36kTk$jI81qM8JNIF'Kj
+p4Zre6ISmKRQCpXF)VJI086p"+ETL0[,,8,GZVihA(Aec&K1PLqU#[ULErH&kpfQ
+#l(64PLmARdUZf'$baS@JrU+!lRc3pHQfT0TcIU(VS5lXI4ei5f-ZkQd$l05kDfl
+2iejeeXX6$a5V,KfIliABf'T&B4)fh3"J(Uh%*U9,XRa$"bP8JSPJhITkmHjIm&+
+jb$kA%`qjhY-#mpBmcX)!EB$IPYrChQ[rfqqfaqk,eCjIej[f[8(4$ZIApAB$Ec[
+`IPde-2!'IIIlB[5phi9D((fMU"ik-KUS*lG!$aKpleGV9hM)6hr8k&X8$rRTHap
+qM)Imp0h[cPpmjm(64GMK@Z-Krk'NZ1m6D6J*2R"4F2Yi*3iI$Ra$3+6!6F'9!aJ
++K"5F-[$3`$N$Ca1m5[!J`5X%p`m)+QJZi+%"*`8R&"`fF$I"E35)LSB&Ya%i+IL
+Mi(Z#N`NH*##1P!*9!mm42%0`3-'M",q4*jD#pNS6KPV$NbJ%$a4m4h"-`DF$"JX
+1+$LEi"2bq,CSUl3jH)iS3cLHi0J#q3hI%EaDF*A!F`@2%Ka&F"-"*S0VL,B)$aH
+F5F$F2+iMH(NmS4T`f8%K!XqB*hkMA44(83a(Rl!06p!'A%r`#X%("jm9R(ZHQ!a
+2M!E8+2!V`3B"VaYmER#h`H8'$a(m8h#fHEJd4J"@)r!6J8pM2H,Kdq![mM"URS!
+5D#(J+S)2#@kNSSL5SL!5i+ZH+")ie1!FK01*%B44"Niiq0pB%M"k`)-%,a+m4ee
+L1M`4(I#i`68&KaYmE(#f`G8'4aXM$jaXF,%a9X&$#1mG('a`Q6&D`G8%Ga0F6R#
+NJG@$d`XU'ALGi",cK)1i&,i#rBEDBcTEk6F#T*16jA2'd@qi%$iAKGK3Tm2Hbhe
+4U`@j$"iCYG2YDjbG'&qA3@E[Lp)#!'!&IIhc49%$H&$#+PbS8"!lelk-i9FH2-q
+B+"Aii-%,@(GDr-U$'qr*m#X36,Y,m#YT`[[`d'k%U(Y!R-6&cc*iSPj1(8qD'Q1
+21l)3+@lNhLU1-V&,I4`J&kGm(+!6E6i1-))(qR%ma38[a3&HF'BP6Q`3"rM"Hh`
+q`")HASQ6(X3"Z[#KVqIM1G3Yi!dIpR'!1$cTi`"pH+SITfI*SH)!MAMfkh9QifM
+DD6p156q,d*rV1%!BR[0j!h0iAK5[qUf#GbbSd4%9I&pHHHr#)kKE3#db+qrBdH,
+8p6rM'fQ&c[Nij8pN0la0[9E8"9L%XJ%cDiHB!@rcB'KGZ[mm[ArY-$*2Ialc%6"
+"p`%mX&eRhJ!dd02!ekk0VkL*VdrIAK&baij%T%ii+ck82`8G4a9R1Y8'b((aESk
+$6ffiK%T1FG#e(SLJ#6282aHq-Hd"*[mp8G+S0F2d1qRV-RE5S%Iqldl8UkMr0dZ
+j''JX(669Eb8`cD0mVmE1aek$AB"GL&f%ABaGJPf+ABDp&VXF@iYGJEd1Za+l#VX
+DHcff$VX'ZaDl$VXHZ`&l!hBMGK1f(VXCZ`@l&EX0Hb1f!EXGQmCQX"AB,$D&6@,
+[`4kAG5dS(bMaJYD*BeE4!0D8DZhUXDZ+NQrhQ+K"i4dlGHcb3j[1ckM*&'9Sjdd
+"G(GFP(6E(m&`a[@Q+VGE`U4CDbk)kkaiHmYm,BfI#!QCC[Q+T[2T69pUB-[q0!Q
+Ib+pqZ3h2CJf%SfILC2k*faZVd!kf3AThH['*UjZ@DrAjImX*3VDHiZ'QSPa%XY5
+pFemY"DY9SH0Lcq-DFVlHdM+AHbY,#1c+YD,JqMe2amhqTl-irik,LK'`keC2Y@T
+@399bpdAeBeF9Ff(I5i2M84#bjLK0[rE8F)I@P-*@+lYE!QB((6+i@Zk3!-(PBSI
+XZ#QPd((4Hr6JTR5ji*,ZFZA(+RI5lYZ&HJpZPcTN6`e)0`XZYhI)i(DT3`CA5ad
+bZ&VXN!!G0dYYTZ0kGfd91f6jrB)1fA@jYf+N3jCVaAE)MT[p6fFlC-G&1Q6RVCj
+U,AE)i'UT3`CAfcYNZGGdGNK0UpM9(mh&lZjSVREd4[pHU36mDm&65qVGhDjdYeb
+jjQkTQjSVYTHD#jhG-(M[8Ymb9hXkSEREf3I0aFiZD#jfp%$rAQFEm5ph9P"(pj-
+AkqTpaD[Gp92UHe)9,h8preli@#pe22qDhqrXRDjUl1KejQ*RTc-AHrUFG)&5Pr-
+UAGr5Y-2"e0J`8a!RmlfXNG[(6GdpP"b!Nl$*GYlF9cTfbh$K'"8"AAflP'VRf#D
+TGYj8U3DhqP)e&G#CU1f(T66Y[8+5jNj(LJ(VlNZ0XRbpe#[,Gp[,Yh`pU1$bj9+
+V,GmYGY[1Uk8HeRPIfPMR6DpVYCG!d(QlEaHDErYYdhr,YdUP@ljEV0kZUlf2j"9
+hqGT)IEF2CMhAqjkh1%YdAKdS46Y4G0jNU1Lke[2iTG'LI,FdAC6[PZIHmZhLk0Y
+jYHIaLJ0`A`rYETjpAE1RAAEhbDi''AE'cTEBe3YlQf"[pbZh[HjqepASZMYFHfZ
+,HPTI-q[VBPhY+qaER3fV[90eYDMZhY6GP(Ul89FEkZ`rABeRB)!,TlH"d5fDfm+
+KV@pL'acAHQHe[N'YIdVV(p%kjl0`11ZEc-+aV'XQ1cH3!!e-B`1M@0mF0ML%p8j
+JAH0Ahq`9$PlKe0@j9YNC0KH@NDM3HAGcA&hCPJD41qi@)jGUX"#cH+XBlD@UYHm
+6h1aiRDkSl6H,89rld,@9cR"YS*%QCc4XG3Y1qSHcMBm0!*TJdG&"kS#MjE2p!1i
+m04mFbU5PY!f$Q`m8La6pi!'NbEMFTJ6E$c+Z(cb%J!p(A$qSF2fJ$V%SLQM%fEC
+Am[U"fLp1H,`Ih"X1CpXafRi`8BVQ"E$3l03CeCNH,CGDBr$kJ5)X5EPqi'Y8D8l
+$jMb+X86GN!!#V+,eU!k4@bkcrQ$RJpbrp`0pdV,9kXV,Fh98Uc8dUrAPq@Jif"K
+Kqd(&mre!6C91XQB3p)2XirXNC((GQ3jI@bRCIM$*qN%M&2q!L0X+jaCI96a[f&T
+(X2fJQRQaDZfcfQ*Q1*h+2rkJJ99kcPl5*rSAH65@TNc%I259PGGeIdTfJ)LE(mZ
+MCFc%drriAAI2cUaNq(SHHmCh9BTcLd'ehAiib$hbjZ$8b6lS1AY$jLX*h2-k`lH
+[c86[appj@'QB2)CiHdZ5pRSrNmG#%q2rPhQFHj!!lqGa6ZVCDhN-*R)a$j6i,6f
+`fGAVddF@1erDR*Gr#YVfUbjlAkBdF"Bmf0PYQ9"mGIFEf*2j$@mSj"ikR"&BkMb
+'G*J1[`GdecU2Fq949LrBrkiRBD*`"15KK(AqrhG&XS#Aad!RZTM(N!#b$T8(&6[
+ik6cDJXAMI9Td)HT'l9eYlp1)4MbAUBP48T,Bq4e"(qC`(X-I$k+&!$S"mKK99e(
+@apMpYD%`e!f3!!II%SVNKqm+CET-h*'BE[I(a+eHYLI''a0hP)FcB1,Hp616cdQ
+j+L[$l2iF(j0lq+T[61iMHCbIh%Ib1$qj[jc(Uj2lF"l$NcZI61la"qlG1!4JFZp
+pMlFQpqKKAjrFKr-i2lRhT[(Qj$kFKd0JFMqkm,pelrbBZ"9e9%q-0bEZ-!mq4m$
+%VCMGDRqL-#"Y+hqjEdp-+Sr"cR"KBKV*irbNmh)HVdik`hPFk15pHEcCbBIc''T
+k+Jr0k$IF)E5Je[l2EL6k+d6PF@*1S[r#6`PH(FNM9hT'iPff9"U6,Jm(`2G+ae1
+NGP6LbhNFIhT@9(NFK`22Ck6VVHJMQ3)N&m#lMXd-K9Rk99AM,qFah$Q(kUa3(kG
+2P0NVApi4j88pCRbfIIa-mmVFN@ZHh%*eIIi@kMZ[kfdIR3"je0IElB!@SaT)Q)I
+UpEaVl2LHA'm0R3$[SEGp6S!m['hI3"iAYhh(dNBpZ,cXmRML(Qjr1(FrrUQAEXa
+GI98Vq0(FM@pBIrR"h2@RU*NSC6,96HkIcGfBh*+lqPEL54l[9K9&lc&DCl*PD@d
+p9DqX@(3MkXm$YE%aLE)GUhZpCA%#e+[HXMJ"mZ!cl5cfhAI9HDMbL(f[2Qk+Qdq
+V2BZA5Z8K!*)M%G`a2(V%eJfI3$l86lrYUGf8qE`D'rMd$1-%b'2lRZ55)[D(lmT
+8kUl!,!jmAE03qqI23MqZ$hm@qR'pMQkF4pE0kY1cd&MrS!-IU,@H3q#-[UYlBR2
+0*c29Mpj9jc'N!hSdMf')9qbP`pm`AJ2Ia8R(VB6a'[XF5aL[Nkd6dqR`Zel!LSe
+1lJ@Xf0MR!-'+p6D3!$HaBQ'RGJ9JaD`qK*iJ&F-R*RG(a@6U"1LFES910IU0L("
+fIqad(#j-131IJf!Ai`CLbKRl(%Y-14Gh-6f*Z!Kf-HGL#121i1IHBY`CK[r(eJk
+V`2qIRq$F'c`#&bD[hMcHQVbL"hPpmKV1`cR"Mh"amZT*a#h!Xf$b1(ULcNK#FC+
+DSD!rMKYJ)Y"j1#9i(`46KNbGRK'PkRNNUXSLL[%D%R8`Mp%Gh2"-l[a!IJl@Kj-
+"q4Qqaa[)cm&h(GdeM0BphhR%jZ"lk$aH4@`1jU&iF9%,@Y(6U#`1llUR'GT)BSk
+Gl12!mC6cFG"3@ZRMS,-dlq1JaE6+ad(AdMJI"dfRihdFG*p@qcKS3jhJik!IGD+
+2JmE856i11P3RqcKS9*hLik!,H+U2JhEJD6i1qS+RqcKS%,l8ad'6m!`I"lh#PrN
+iD"UHkH1JFAK1,ij4U0m9KlPQELm1D[CliU#4H*k2JilLUhdFY"E2ph(3Bhb0Mi0
+Qi`8q$VU1&rSiD$pHj11J$hQaMi1'j#8q$MU6PrSil+D@q6MS9El@ad(6mR)I"ph
+,Y6i1fTKAq$L`S&cRik!"HD@2J`lR96i1@TeAqcKSHDlcFGJTVI&ad!5peXG"0r3
+k(`GYdHYp(!3'E2"ad#KpJiq$MZQ02JjDTcIj11LKV[Ga8-klfFGKhE,&ad&lp9B
+I"`cI0Kq(IGb02JiB[!BI"qQmfhdFpNSlI"`dCHrdFH#hDr4ad+CpNiq$IZeG2Jl
+)iLBI"icRZh`FY(,[pR(3dphXik#jHiq2`i*lViq$!ZKp2Jlk[PYm($5!lrGa8"0
+pXiq$P[!$2Jjk`fraFG"RIUZ2JiEcfh`FG+$IlZ1J&IfJMi1Hp$Ym($5RhqRMS%[
+pN!#2JeEc`ci1HXk2q$LXGirk1+cBlr*af0THfBZ$'(JEacT34R#9M`1`rh)I"jD
+Y@6i1h!kcI4a!$M8q6L[(+h`F8#GIm((!MAc4a`(eq1Xq$T@C@BP6$(L#ifriI&k
+*icF'9ihfIAGb(!85#R"#jAR&QeY9N!!!*a6&#A"#84a`3Mlq*iS$6XM(%d9a!Ta
+3&#I!#89a!Ta3&#I!#89a!Ta3&#I!#89a!Ta3&#I!#89a!Ta3&#I!#89a!Ta3&#I
+!#89a!Ta3&#I!#89a!Ta3&#I!#89aCR2dm6p4(("#2[iRLJ01b-Ir4((!#IRiRbJ
+11#%Ira2&!5INihqL11#%I2a2&!HFN!#2riRLJ"2bm6p4(("#2[iRLJ01b-Ir4((
+!#IRiRbJ11#%Ira2&!5INihqL11#%I2a2&!HFN!#2riRLJ"2bm6p4(("#2[iRLJ0
+1b-Ir4((!#IRiRbM1#SiqrLH+!dl)arp%FF!*qILI+!ii)4rr%m8"*q6MHU)ii)4
+m2'!8"jb3!)rrLH+!%r*a4e'F!#F8a3P`3P'F!#F8a3P`3P'F!#F8a3P`3P'F!#F
+8a3P`3P'F!#F8a3P`3P%FF%)qrLH+!dl)ar9%F3+F8"3(R*!!Mrq*iS!6m[%r84a
+`3Mlq*iS$6XM(rd4a`!Rjq*mS$MJK(rm6a3%Rj10rSMMJK(cm6a3(R*!!Mrq*iS!
+6m[%r84a`3Mlq*iS$6XM(rd4a`!Rjq*mS$MJK(rm6a3%Rj10rSMMJK(cm6a3(R*!
+!Mrq*iS!6m[%r84a`3Mlq*iS$6XM(rd4a`!Rjq*mS$MJK(rm6a3%Rj10rSMMJK(c
+m6a3(PTB4r)q+!djS"2qMiS!6'X(rU$MJK%E`2bS11+%4r)q+!djS"2qMiS!6'X(
+rU$MJK%E`2bS11+%4r)q+!hA+#2j(a3%Re)Ir+FDKJNG`24ILq)hKR4i#rJH85cS
+XaQL3!(rlfm"RZ),M"hH*CQhX)jq#FfrZ8'jer[A(AY8*N!"PpiIQlErm%L#P`!5
+j!$lH`SfRfGdPTm(DD$4hZ(@#PrU"D,KhcfPfGmKTqRI2DAEh02@qFel3l2i$MHC
+Z0-hZfD&cQYec3qFdZdmB3UIChI!&!P2QE$k$`RhNrGphlF@GcUpH1@5Y136IhFB
+R@H`,Mp-AEZpdlKJ#S$A)kI8GJi`8AY"LArM0pkppiiFlRB1(KVVeK9pK@'LI&lj
++ArKQTr-*Tf(DcIE4"I)cdp0LB#YmZ@dc1l[DLI)[,LH4PT0U*A8%A6iDi%6JV40
+6ir56Xi0BL4HbZ+kTL)9qQPe[Y[-H1qqemb0fhQIR&M[[Yr20GRlBcJIXI)ZGElA
+cEADqhFi(lAb(R3rCqE#GMpMjU*h[X[2GGMifH-lNbEX-QD'F&4EJT*h[Yr-T1lI
+CqE5G(l$cJi1%8QZf145TUC(0&U,5cRNl9pPjR*h(flRDcK2X20(1Nq`mfFj6l(b
+*RDIDfD[*kADqe-icl(bCR@IDqA)lcl,cE$[Af2N+1mqaFj1GVl6c9ADHDqGjGVl
+Dc[2YI)fG&pKjSCdAfAQaRCIBHDQGPpRj@MX[Yh1YR9IBq6SlVl6cShCqc-kVl,c
+DcYIEZFl1DqbmeXlVl,cHcK[XI)1G0pTjNjhVlHc9qaBlElAc0M[ID1F'1fmIY)l
+-$mdZ5UE8iAJq+Ta93'$9LH@NQXQXdTe*$Ie*1kIXV-YARAAjUR2DcVVFe6Na5+m
+LRh8NhG69eBV"eH`29UVe!L`UB&48kQd1kdKrP'KHAr!5[h332EIDS9YDXkI+@S5
+FRA9R8QIGfG6Ckf`k-h@qamlhfIhm),2+dbk-`U9-4*8k(&*k#3ZM'kBkcch8V+B
+ej%5eYJX)cQjY-X'd0J[4rM3*fm9UiCAL"IBN+M%*`II1M+aLD`jfpLK`Tm-a"1F
+jh%9`PF0$$XFir1(XDC%6"IFh[0j`GX2($@FNI*!!F$h#i`K()hc&F&2#1`NA0cc
+EF'JVPFkaPf"RB#r$cX5LV@F@&ZjXH,(K[)E2'UjUH+MKQ)Br'QjSH*rKG)D['5j
+QH*EK-SC(Q6H'VaJZB[6)`$8-Mc!F`I$r`Zd,Ebp!!rKfiFL&6aF1A,LQi+k&PaE
+1@IKNiBU&"aD19rKEi@D&Ga919IK5i8+&ja318rK*U9Gi4H%-K3q854-H6lJSiCQ
+%3a*p')i!jBj[ISRJe,A2bRfF-Ea,lH2KTr45Ap6El9C5qlMd`'CAVdmI@HamDA0
+HrLRh-@qpjhfCe,"CJ''bfm6U'Z2Z0l!Rma[H8-JpG$MEE$U@e$i1+9j6HBb)AK1
+9MXH1pfP4kDJEYAHe[8qlYe3kbX3GLDCfIdcF$L$0e)k&bGd0T*PkB(,RNmNprX#
+p'iF!61lZ(mh8$S(*A@QG(UYl"iM@k9kPPQpURHjAI1N)Q,L(KE(QKPASBR91k&P
+e6qJqG3,S0G8GaLQKMc4AHP*eYIQbTG+B-#F1J1q9MPI[+[(P2)ir25ZU2&$!#Ci
+3*'AliaBU@X'8(!([1MBc&'ETSCRmBKl$RA1ScJVeFISj5DXMAei+33Gkc2KXqrL
+CjT@j)pFmZBAUq[`Ye(GHepXq1J(bd%THMB65-!p42KSl[LIA@d-R`([SECm6)!p
+[fcH3!-I&ECp@"2YBfHAaa$hFrR$ZI[a6,pfBZrUU9R"clXBhlEVmB1lk8p4-&1*
+Z`KAF2jZlFImYZDY[*9j4%@cd(U0e*PZ@eYC6pFU+46HLrMbd)PJNVil9[Gkb1!(
+U9@pCR!"jm*Pf&[[ZZqSm9(R%[PFI0mA0&3RiAX$'8[QCVGR,(d$+iG%MYQli"2,
+K06A#Jc&H8b-m''2lRZ55)[D(lmT8kMK4+1pD8%FmQ)Z634eaH2m0GF5$-G`6QfZ
+qmbU,4r)jVl,iA!d03EaL,ahqK[%Dq#j11QiPM0IBjeM#H&e8"0q6b!@Xf1MNAX#
++MAd1%+aBE`0j%bX@GQTA!&E-61k08E+`XK5Y'$iaZ6XU*P-R31Gd+h5Ud@qB+-F
+"XY0aZ$$P$(`1JPf-'iJTCqac,$(PA0c&p#6L)YM&R)XKM$Z$RhZ,F@FBrKpE1k`
+#rhpqJR0[m!KFQ,akmhKVmSSHj2A*DcJ2j`3r`XA*UbF4Y`$2JXP$Xk#'(dNSh3p
+Q+1L2i`DB#(3H6JRH"m'8EBkV+b0+eI0)9*9&&1-e*1TJ(U-lZ1'Ch2Q"r"bX$bF
+$mM0mMcH3!*q$lcUkDaLYHllcL-h"pp"j[)VB2*G(JX&!D4$4[r2PQc)b0VePI+3
+`XQ@d-XUaD@+X)U*PKmS(%lCMjS19A"erTUGH05&hi5Yd6&(Cm*8A10NQ*i*9Mm9
+jE"!(K['6ckTK9A&J)Eqr(kId,-8i-*@ImR&J-frcF@!lYkUp`cJ`SP[9hQ%F@01
+YDZm`$XcU9V9h'!IfGD[D1i`$3lY9l4h'BILeUVh$1$#p@pAHB4cBi+eUlc!1M2&
+@YAFB"eCjUpSlM!1c[&AY(FD"IGkUpJlM`&"[9AZ(F@#aYkUp`cJ`h9[9hQ%Ff2#
+YDZm`$Scj9V9h'!G@ID[D1i`$mlj9l4h'JChIU[B1im$JEe9lKh(BFPM9hQ%FP!"
+BeGjK(03#@2AFB4`8"9Kehf%F9!GBeGjK(*3*@$AHB4c8#eJehQ%F"QqVaMZ-J`S
+#UmBlM)05!U['1ib$QJ+VaMZ-`kEDU[%1ik$+`+Va$Z1JfX#Um3lMS#E"U[%1ik!
+!BBH2!bH59HdGaN&0JPAM(FC"FB*9pah'3C@#9HdGaN'jJPAY(FC"hB*9l4h'B40
+Y9AZ(F9$*B&9lKh&3dQ"9HiGa80YJ9AZ(F9$NB&9lKh&3l@"9HiGa829J9AZ(F9!
+!B99lKh&3#'&9HiGa8"&K9AZ(F9M5@YAHB4c85&M9hQ%FN!#r9V9h')FY[PAY(FB
+"Z@Y9HiGa8%GK9AZ(FGK'@pAHB4a89PM9hQ%F@$'YDZm`$QSYV'V[-!k+,UaUlc!
+1F"+VqMk-JrU,#Km(K4KC(`F9'6NI"m8GP6i1UMcb2Jl+2UTm(04rM20a8!JbhXG
+"48LeMi25N!!*2Ji+2#Ek1+MdQ16MS14MXSm$q''+M`-fDDU2!kCKQSq$ESMT2Jk
+d&jIk1($3cI"aB$kjc-F"!M66a`%&pG0q$`d3k)b2JlbG6r6L**q-Fi,M8rdi24!
+"&3FNLUrL2IRNA[YqMVk+pbJ1'#*IaAX8"ab0Vq)pLJ1dcPIa(X8"1qLVH)rL2-M
+49r%Ha6R$m9NI"qM3VrEMq++Ge&I%$k$mqMPIM`pcp0A$"hNAicc#d9F2(m9jP+1
+[(Mk+!hc59`mIaH&0I9A`8Cc(1AjjT8m9LN3j2[$01)A#FqDT3AGB[*p43BikS5`
+,0&%Tkja63HjUD`0GrF"CThVE1DH5hPQ[JPcY&bF1Pe0"V[V"K+qT)#mSrR1RY3E
+E$mB2R92&RKiZTiTGpB2-F$P9l+SIr%!P[300&E[U"pRKFUVB96qS(LkRLPheJdU
+a()jSbh'HIUVcIE+bP!P#GV88J"-1dkkr42#Lrc2fD$G$djAcl@ZFR4KI0p&-Sk3
+CTBAarDdkR%P[-"mdX*mQV0T6Rf09F*GpQ3eVPLFR+X'qU8`4[aB1FfBRbU$JB&U
+$`U#klIPp%dIb&ppjm!cTVCUCQ`a1+Bh[f!NAak&+Q!JTq-4XCHC-r%q@bl&f&-r
+0e1D&,2TD'+AU+Lp`RkR`@e[VSH*pY`*%4jhrX*9%iSCiF5pXX8Vi4Z@@*'BbLTq
+aDM"JTfUC2M5djX4@lFQdLIeLG[&XTJ2X6l)h@b6ZmVMdUm9ba@"p)FMpA1CE,'e
+3m5XXRKSXicHE6fNGb[qZTBMq)#@l)mlR*1Y`lY2[RCR%j))'Ud5'`8PRZMmGq4U
+XA('DHV3qADHFTKkY3pJeTk%Q09a13ifD$h,Id9$M11X(fH&b'QUd$R6AR#B[dI6
+RLY28SrA,&c68p2-"1dqrNkhUm&J0099VRad'(9lFm)IElBH$h#0[$NkGl*15CQr
+)I&fmP2%Mem,eTFiI2k`dA%cFm2he#M'P9l!GpIUGIVfkNlMKA3+FlXH1pfRKG1q
+YHpZReAjh*1'Kclh&$5q6Hb69CmE`0k8qMS80J"Y)UFr3"N#V%(-(E!$F2dTpKMB
+!+Sq4*8""BFpBh6Y!&2EdkJ0i8f&2[mi!4m$%25c()MHX3Sf&Fd*&KAY#EB363#@
+%lM"1#981ZG)cf,jXU63'SlF,i(ZPip@l5R`jMq02ciSU$h3A`'a`%N'JlBpEU1J
+M'CHi#q"GafD'`L`p0*0Ic'1iF`l9@D%q6MmRT',NbcmVLA"mYRhm622+h*&V[M(
+GGRl&kED`IA3#j+(eBaMK$Q%HRN+kJAflhKSk!Gj$ErZF!(Piflk"2#jZql31MCf
+(A"j2S!-JmD,m,[a6,pfBAhIa2F(0qH,&ZkEq0&miI)53!0-KX2TRh2p+[MMcD(l
+Gj9Nq[Jk0k$e'kdbf,+fYTqU9&8Zd(6&jD"dD#+dBUhZpCA%#e+[HXMJ"mZ!6(4S
+rHPHGKbU2J5h8D"l['([8@#U5pH"c!iRD1VLlRBBRTMN(`SG!XAIZ#"V&P1B(aY"
+iT9S(IGE3V+@eX&il%'e0`S9'e2c@A-8%&[ZI#8bRE[,I%b@0@M0-[jfqHX2N9bq
+Pdb9NE6KG+M["'P+0TITh[Ra64XDQYib2&%DfM&C'16C0M&9'KUf8`(eB@2dDX%V
+9DN`BCj!!T)hBQl#lX+bY8F5k'pZ-4I(UAZ`qE!Yf2rCQl!(X,GKEXHblMQ#"-X-
+C"!Tp'jEP*V[[$*BC!a9d15cU@r2B+Lb+AFGMUl%X4LGL*f%RUf59[33l&BZD9m8
+R&RX*GJB@4DmcXCGMCf&RBpPJAS'GJld5Ha9f,RBHPP*(PH`ef!9BN!!2Ll#,X8Z
+`5l(`96%Y,-I@BPGJP5VBQ,ETUl#VXGGM%8Ha"VX@Z`kl(VX"b`*d)aBd,&YV8+K
+EX'a%%eJQ&2CrDHcYf0ZX,P%Xbl+5pA3VPMdr@hL@c'$%6Q$C20,$hqlM+['(XIG
+K6f,[ajl#YQ&2Bar!2SJpJhd[pK(XSpLcf-H`Mf1EXAZ`Hl(lX#hBrGLEX3H`Yf"
+[aGk'[4el%(X(pK$f-2B)pLMf,ZcGf'2B*Q`P0SqY`Sl$MXG@BbGJ*f)RB5GMTf!
+[`8l&6X01aek+RB'p$$X6HcPf&RBfYJCl"AB1pNVX9GLjf(RBUl(cXGGJ&f!ABKG
+K&f1AB*GLPf'[a5l(eQ*AB+r$VX5Z`Ul'ASqY`kl"VX@Z`kl(EX$HJ0f)hB5Yafl
+'EX&Za@l$hSKY`'l(SJi`Jkh!CV%TE"*l$eEeJFIS(91#4MXpYZ[2ISEb1FZp-L"
+KqJ1%jaiphhjapEEjh+22f'rRJfV(*VrN2rE[,IYJ2lrL[6[Sj9jqaAYT+HkYc06
+k9Vlf!reqPIiEp@0cEjrk)2f3!(Yrh)ZAqa"[i%ha'F9pdX@l@Re@pZDCYfYf-I&
+qjpHYPj,1LqV2jYlrZ-pQ$Y+KGipcpclp6cD(F*eFPlRmjQVZ%*A8&CSV6(k9NjT
+lQ&FB0G5-NbklHl29Vl@#B"AfhfK1-IPprJDEDmLErMr$a@[42-5XSlk2m,icMVK
+lLhr,jKrL-3YNA"lIqi,040aMYTVZl[h"ApUFa,frdUqchCV(H%2Z2DlBjYiHc6V
+-8lbVQXhL,Vr+efSfBXDLI*L"kPaqrel[apa&(Y4CPBYh4$-GXaMMQ(U2q(hZAS0
+Q(HBciU'3!0M83H9@jFI-aVf[pH[l'Fe)c('Nb9cc[,[hUHjXarMfHI+Ek[*Se"c
+%[%GUc'92ZA[[8`dc!e*rc%P,A"iIHk20KBb![d92-1qAq`2e*fC&4M49caPlebH
+[YIP4I8r6,eGeij%c-b@Mip-FcME5Y[UVREfqqbqmbIa'QM%Sf([V2SRlTaTTA61
+E[CHk8M@UiY&hlEhNErIVq0($0XGbli9H[mapp+-ffh,[$r[a&UM@QAHjplrkr9+
+MPjL"'A@Ik2Hch,YX,ZBp8,GXqPrZphl*CQAZIDFIljMQBHCRkZaRHrfemTAD(6"
+6%drh-(2[(Xf`XP,C6hreqZ86HJYQErS0G5&pB[*[fMc1[IIhqf@6HJ-cZUU8#EI
+hqq9kp84",+CZl2A,bZrA$%!I)ir2pITPj6VP`(c22AURp+&[kmfBq8RKhrAljIZ
+e&f%23$PmXpm[PdN90,9!qf,H0rfbFS[kQ@`ATfJ1N!#qFN)c'R-@crj`VerQhV(
+ApJVNFDCI"rImXHdDD+HmJGF2[QVl"mV`Gh[pXR,c&fdR3EQTpr,kj9RYEGK68$j
+SY*CqZI*qeDlN63m`rE*bKpk-I3CAIUhA,bX[rkcHf0`lc0Ylr6,h'eaJlk&5V[[
+AIVrmR(SB-aUPara6Bre5CMbq2kA(UrR9p%YlEb[c3r`+kjIfhV5h$[UP[4GA(r(
+QaCp8`j9ll+0N[Qa5hE16i4kp6H*p6lXBDTCle,6dbmAADc#3!$Q5Z8,khe(9)M-
+1pqLT-LqZek`P$#1*GrIMR9)2*8Ieh80rN[kAZehi@%(&*65$HR-52[CNe)hUFi@
+kXC[XqjQR+dkfZV(hTRa+05GeBqpGSTfG9cIq[IMCe'jf[T%Z(*[MYlf60eR8D,@
+*Cqr&ck1qdd&jUTh5cjL9fI@4(r1'l!q+H6cd*q54)Qp`G[jm%pp%(JR92IGX(Hr
+3([*CZfIIEpT(qRhd$QBX[9rN(VeUZE[h@jSCC(H@rCL'!A2[SqS0l0@S*qD%3eC
+Rc00D&ELkpk&qILpS4K@3!1$#rIhmlYFZ8i#CDHV$bqqh03X*PRHKCQA*lq[DX3M
+QEj(QI-RM3Gd4HUH%GRZ5arFdSaTZeIJb14AkSSm062c8AB1kmHr&,Y"1aCY(lEh
+TQXqmZVGjV#12q"h@*fbm$HrSpFZU9fYrm$kE9jKG6,qXqM(0$FaPkQ[9c'(kCGA
+eQTmqB(QSZTIq9e93$6'6mKl%0Zqpib,Y,$lLlTh9fH5p)e8YdMrTPjrSjEhMGXe
+rq*RrU$Q6pijcp@DrB(P3"bE[(Hr9h'q8RXI1%CbmYG%qe[pLNhS2ljkYJbAD@e6
+5cqM[0YjmpA%cMpCHS,di-ijkM`rq%DZ%rqEZrEjf**pdpcl&h#Pc8ZeYQRFrjHj
+pPRHDlGkepY1hFH1AV+p3rfDqV2fJCKeQ%1BfpZaQIUepcbhi2ZhZcG2F*RPm8$X
+DqJr[4&mcmf[YEXdBc-Ad)6Arb2bkiSFechh@kS1jaFb[Y9ri1$lQCI+QKmRlEA`
+)RbKHIbqpAqEA&5r6hS9p#2'!hNUm*YAm,eYq[pIVIl9YeHicVJlqk9rdjU(DGrd
+D0ibkpYL2X1q42V(L61d$m&1Ap%M6AfXl$fY@-2I@k2h-(Q*&3EhN9bdH2F$X)@V
+r3EXmDSelc)KQhUTpVfU)1BYlp$#TTqqTMYAmUr06mlV-f5YHVPQ@2X0BSHCHQE0
+Vhhi(&llSlUh6r'cQl0U1pNPIXMl02'RQl0Srdda!6*A#+@T)jZcD6fU@9[f%lpe
+[iI+Nl&lf&l4cC#HJV[a,DMheKfk1c'Ph3lp9hm2X-b4HEN*lXUqiH0pNIT*ifAG
+U9Q1(S,kIS2kmr"l3VN6YGBRh,I,fmUY9$f92`[[4$dcrUlVSVr!C03MaqjQ(Tpc
+NlYfNHBXC@Ghllr3BkArj4a@2Q8,GqjpICNq`am@E*Z`)FcTelqp[mQr9[TDG%RN
+cPj[qPdqe3a%H[V@D%f3ZfDPpMc#JV98I02d[IkYfVQ"C90l9l"ZNre9YeHi'I!Y
+TXYXcr5rrFHhik1h--IIhqPRq1RCi3Yq3!$LARBVd[rc[r`ShY&Tm&Bpq)r'qT"Q
+!Q9'&1Nfp5Te9M@VAmh@A4bhcU04C988pk*rBHc#[QckA[qVcq)6"mD$b0(dZrbE
+Y'i4KEB2H`25jUPr82NcB%EDV$jSqPrpV+Gd([m-pY3H9ZXPr3Rf)I09lV0,q`25
+jUY@U#A!qkYjUjJhTFeARDer&$Pap*jRMTFp9EGG-b*c#1r%HTXrP$bT[-%)UMqZ
+e$j!!q[K6p6PU2rEr!*!$$3T8De0SC@aXFbkjb!4BE$J!20%U!*!$J!#3"!4J124
+[r`#3%!mM!*!)rj!%68e3FN0A588"!,$B&&Qa%)MG!*!&!c0$!*!'4Q%!!0TK!*!
+'VGB'!'[F1XTYj4hPbl&&)iXGiH[#-lh)CUh-le0ZYkLHIFUL-Yh8Lp2fNFA@MDI
+i!0DALFq,iEm'r,TBNAeNmFK#0Q(E"VhR,DBGiEFF@r6)F[cV*0ZHl(-jAZq4K@F
+ZcaFH@F`)Gr&kKr'&PaQ2m"6Sm%V2'T3aXLR[,9PN*3[Cj$RCC,c*FE,*EYeNYFr
+XNZXeX%N1E*!!j@9XXbr@kI&EI(CHRpIDj@CHJlb-EMD3!$pYB*GfREIVP"98qcM
+NLqFYAPiQh0!AlN&R$MV6jIRLj8[fp4Q('fli[TIC#hFqI)8$ff4jMd!Hh!H-"A$
+L,jqHek6cQRJEXZh&pK@ra50`i)#l$B"#J%j(2S"RqlkVP$T&UF3'GFTCPkP6RKd
+UpBYh`cildC@!UcheIPP2@d(Jq%%U(rKlY4dYqcT56VV9#iR2SM[N1K9G-dhXI5F
+-H#DV9"`SrAracTiNqVLm3d#eUBAm5kbdhhbmdCp[5QF[HYqBZ$Ta@YH94kTXXV'
+h6%)G2VcNq,A$#4j-Xmf9ma0[8HV5`rc%4@-(cXNMk8X$%LbKpXFTK6HR622j9DC
+crVVl2(ADdh+qCpRqi`A,UJeUEH)[ZUjD[[G@e&2cLAFR[YVe1E8*CALh8PrBVCj
+a"#R,Tr,CG#23&@IKZfh"$3b4'cRCk[PrpF&@ZQ3fRUNiN!!0"Y1adF2-JX!aZYL
+baFJr"IpR5Vjc9[+e+)@MG&K8VX$#CCb8DRaZZP5F(G0@@3FA$Pc@KS65Z'4qY31
+%Secq2AQmH-2REpSZE#1Fm[!j$-0qAfKR1"b`jqE%hBRE6cPP"AZq34"-H)1XDRH
+Cd)4qE'V1CpTe5(8*#)E0N8I82%Dk(IVrI+ql*ATE#qF-k1dRk!'a2(66m*Q&rf+
+69',pXE`J"8T6fK,rP[Mm+C89c-hM&QH'9)Cc$A&%EHZA5LVR0[a,a%CRCm6f6r!
+h(%r13c%+f204r-[%pQRmr@lmlc(#fI6KF"9LZaUA5m6@L)Y5)ipj9iU0[+[%pNC
+F*SMY39`QLZeIi6**E&r!CE)d%M@U&YZPZ*!!1lERi$*9E"Y`-6+5f2EJ-PeX,jB
+H`IBkA)L2l4GaQ5Qf4k3EXIe(BUP#-[dc4fcie)LY$THjBQ["CClBpZ)bAf`rM-X
+#XIdd,TH*lGGa@5LfIi2,j@,l,#k+&UQ(FEP#N!#!fPdTYQYaHDEBAS$,9@)MlfH
+*ME`ALHeRF"(F-$EkHl(BrLdZ5m6fAh&CDQ`Pl'ek'4YeTlq`,FGPQGJf#FjJkm5
+&QQ$l4lJ3"pXEF+N9're0[f!6264aXGMq-blA'eZ'Z2-$BU1[RLXfr*mRYYBPR"B
+Ep9iK0[*H+ECrLSYbVFclF'N3'hLf5QarM-YUXAdCPcA'9NVFZ8&Xp-aDXH'c6Q`
+lF&'GSA34PjcBIK`AF!rE1h"4M#lp5m&KE1"SXpJHaBAq"A,"5V!,'lJ!RQ#MMY3
+FfeCF0SU0RU-(XGf$bfDa8IXYB[X9A'i5fqrJ3RaXr`@AEFCQi2eQXB'cfm8'6Yd
+L0RUq6@cdc![&4Jld!VD$Z1`8fcr!CCIBU-eZXB'll@,lH9aZ&GZ(K*YJ!j0Z&p[
+RF1N3ferL!Tj$3q!Ep$ifX"[0(4[BYepXi!)pJSfH8GTEcRT4+fb(F,P$E#r("6X
+fkL5k[E'p'4IPM1A%X#0LqbeFlK6E*h'j5fcJU'SrimM(`!GXp0D,a!BZ+k-F4pb
+KAl$4Krp3E2MrN!$BAS-,r!AE1h&49MlZ$PcZ&YYRF(Q*f-!9m&"1"I%-,S!0M[&
+5XB'$p#BfX10PBU2hk!9Xe2S9B[[(Z2b)f1MGHmAfch("&aZFk6jMZi4Fl8I&"[p
+jTGM!lPH*M9kmAfcd`!0LSrpq6'brM-ZVaIClZ0!,f1!0i+fFmH5PVa8Ef%PmE'#
+R8G,%"PDpAQcdf%q+$Hi,6m(fIPb`BrYpA1#Rf1#li+UF5[,2Ra)EH!1R``C2J'G
+K!pIH*$Ekm*q*$Ar`""[mlbeL)pHhLZd[F(QEX9@4hrkXf1"J2bFfm1cYBJ1Ek%G
+Xp!qm!pZlF!%VX2eVA,"MSfp%2q"-B0rmJYMJPR"KE2#FpiJ062mPXB%lla8EI3)
+HBS0MdDIBi"R`$QaI`Z9AM@dL16RF%aZFN!#Bf1!`la-EZ%N2BU2Rk4&Xe23$B[Y
+YA$iS0Pk+`"hN6++@mE$Bi1&J)cCijSI&"Xl"aE#"qlmK0R$Y0m9'Mi,Yf-JCI--
+'pT!!1cEidlm`YXNN81J'f-#jIbNfq$"m%aYm$dd$'j`%rSZ0[1P0E'!"1J!fkJi
+2`[B(Z0"6f,k)bqmD@cAV68f`S8PmA'cNr3QaN6IBJJfq"%r""Vk6&cC`kP0LSkr
+q8'c%qL1a`EhJbh+QX0j`@'cNrHr%"NH(Jf#$arb*f1!aD"VB`&Ni(6D`ir0LSdr
+q[GLi$li!FXmFkF6+JP0[Z$T9R%eY`0-(eBUqG6CR`l("I"lkaB48AP$eUI-mR-$
+BUjc+'5IFJ1-#N!#)jC3Z[d[jfp0@#L-V[KcUe2!-ErM&aiRh,fT&8lJ5`8Q!hNF
+r[C)#Vr`A(RrPBSi)QA2`Ri,r,2c"la&e1S8)Trh6L($D[`34K[frrhM'9-LmQ2#
+I,q92mY3%kjhL$5C0VUM3U-qScUK)U09d$5S*hB6bLA+"#S`DLAS$Qd+jJIQ!CM!
+Ue!SD$4D')N"q+0#`A"4Re&TI,8GT4UAbRaE4X#M+X%pB*f`6PJPlKCh#-Q'AX%V
+B,H`99JQ,JMh"QQ"*X#CB*@`5&JPlK$A#&Q'*X%0B)8`B*3B&"Z8&a3AQL9+$BS$
+5!YY'k8(*3@'"iD'ZS+UJTX$b3#J8&*36Q"`+!!S*bJL+#%S)l"PP#&D*kS(D!E0
+&S8BY3IP#989Y3-&'L8D"4RN'`9!GBHbS1+JdX&"8-*3V&$"B+bS%kMTX'j8DC35
+&%M8DpS[k$1+!ELJ0U-kSf+MfU-US!`!-+JFU,ZSYULd+,bS1ULeU,H`CG3i9#4@
+3!aQe$ED-dSD#KVS$BdCK3h&%J8E44FP&`8@j4De"j8!jK5@M3U$3SR5MF-1B8-9
+3F9!k8'e3De#"8(P3De"T8'G3L9#"8'GJfbJc+$+`D4Jh+J`-#p8&Y3@9"A8&939
+9!88$RSHUK0+(ZSUULMU!DS8+LjU+N!05J9U,5SHkL4+%HSJUJ(+)`SYUL$+!SS"
+#M$+-dSV#LX+#SSU5#Up#"8D"4P9%18@43bP!F9DPfA&``"2k@49Cdr[d1Me!VF!
+rkNC0`AYU4Th!*HS'6S%YB$pB36q$'q!(@!+1JV(J+aJ&4S!,B!ei!Lk!#H!"r3r
+QJXGJ-2e'2i&AB$2m!Ai#"S0ci#IF!a`#8q!8p"QF!b`&2q%am"!i$2e)Mp+[F"*
+i$MJ$jS)jp"ki#"l4Jf!A'!3QJEpJ0GK+li2CB#bm"R`'3q%6B$Gi#`l5ih!Um"2
+F"2r!C$!BVJ0qJr[d2Y`+I!B2`"Ii%0J#[i+$`C(!DR!DA!![i3"J,hJ,$`#6`5Y
+`#B`"`m!Z-!h1!RD"4A!`q"Pm!A`#Dq!hi$4i$SH$Dm!0i@M`(rJK("#Z#*F"Zq'
+#F$f`%Db%1m%CiA4`#hd*FqVilkYF-qI[hNRQMl`F2U0!N!"K$CYAr[)ZFI"eFZ!
+P"m)VK$B,JQjHYVe1"F54XZY(c2h0jLjN`9Yk1MD3!(9&("li'mH,r1HX2(m0Uq2
+q1@i(l5jSibHHKAj(mV2hi*Ai031c0aMaYh9@66YK649YGa0di*`c%eL"Sd09@!`
+MA9paf+"$[aRBX"bHc9RfB+14pC`SEF2FUN0M%,r!eV+[D38D*NRY@8KiNH[-U1)
+X6$I'*SQe[K"E9Z`ZC%HY$9ZF632Pmc0T"T!!Y#A!i4VZBUjCpMD1*XrkCK$k3CJ
+1M(R,FEYI,E%IE0LYBNZqqrh)9p2DBV8lMj5F3JPpm![PQc6NSV*[Uk`AkD"LfAU
+P3)RFG'Dbk891AFIPSC`eQI45q(VIpB1mBmrUB,PiMF-MSkK-9ke9Q1C!fhkpiEL
+1,UF-PHQ+@l-'REE2XDh)mEfP0QfTSE9fVj3Z*%#,'REFcX[6[HQ`jV+8J8P5L5V
+91#h@S$"KVP+IS19VcNZKJfXiH#Eab+1"ZNFF**QDE,hK"a'#hUKbqHNMjT@@krU
+qKa,[Dk!!0CP0QHFrh`6DR-TES@fjXA@$[N,P4dD2K)ibPHk+-iAf"GQS8E2"+[m
+9B9hYb8b-,UGNr2)CBSibl+TG!153!2UD*T3@5Z3+iqMV!)rDP[!)[jEXa05H&R5
+C5##!Ep9'Le`+cGJ$Gh&kBIL'mI%M,Rl+KfFc[KIkVL"Z!!f,EJ-!4&EJd0U2UHe
+()!p5%$[kS%e%XEI%B)HR0!0"$D4)rNARqY%Fbf,meF82Y[H'T@U3!'5H$CJFBdq
+r,0E6cbq2C6E*(YFSFpqcTf!f8'$@0!)FML$!qPja[&Xe4lme)a#eVKCaJ`alHk+
+[9$@&''N&D2-m5b!X*LIL(&-dJd`4([[ekN1a`lDl3XjfZFFXkfIf`KLe8p$5VE1
+PQ+d!)mC#!eQA3f%!V0Q,LZh69UK63dh(,DY4*`LM9%&AkpU,e(Bc0D(1*06ZZNX
+3T!fhbfeeR&6BiRUH&aAFrA,kf4KiXCD3!0-@STUQk'ldI!J6`HmF%YX"$Y3HfS(
+6L&Mef#%2Fe%8[me$(j13!+"*RjIIml'RB4p&&aZ*aT8L#GK)2I*'beMST6#!C4*
+"#%1E+(XB`P$ZI@kU%)(Rl5+GPrB2f,VPTqeH%r`[ER3*)S2'@TS0XU8mf#mj"[D
+#E$dH*NJhqNCQialjjL&56B+ml9CJHBCdYpB#d0`ZQTbq4eiZM-bci6@QIGh*e"A
+q[2(BdK(JRHHjikfm!rfE&hlGVaF(hrX9iTip5Ea-XG1c($#Dqq6eQBRKNI@TpF1
+$a8&FQl1CSJbJFD8FH@Xd1JhUh)R3GFXhjf6phh`#im$EDB2JES($fqR("hUG2!k
+)Yp24E,6`a86HTL9f"d`rFp@miaTjKI@hllaXCbIf*$k@q!L)RabGIZBbHdJPbNB
+dem,Sb6dR2lH#Kk)mcU6lh3!6,%DU%l)dQ)$lJcha$Ud+rb6q@IbVm6H$Q18r(Ip
+,mCq*rbcmCq-r"rmDr1IM[a$rbq2*%p+a%lreBQ'`BhPHQq+%&f&AcS@12IGNXr1
+QPa4hhl6rSIf(pYqrrhrf2b5``[YNreQI2db$jk6d2p"M"h!mmIa2iP6ZXZDXM'Z
+&)4lel,&NpPMqE-hQm6*PUjN9jdpcp-''ppaqVVclp[ejjq`c)pjXqp-HHI2Y6h[
+NcEV2B[fhc4cr$6D(pqMqr!VHbqZd4r1HADFpQMIJ1Zh4c(R`P6lQ$1Ld4c1h3UF
+pQMN*1Zda`5P81Zh46*2dTce58jhfD#C,kV4(Mfr"GGUMalIT1Zh4ihYjRIESm6f
+q6R[dq+jITcekI21Ydaip[Yr@r[HSVZLd4ip[rRADSmGhr$VYdH--"Thfk('QJNj
+lp$K[3kFpHTb0SG-H2GC9TcekR#USdal0j%UGpTKNI99X5r+ZV$R*YrJ+QNR1&0"
+TMdR@6kFp*PNrRICSe#'GpTMNHhqGpTMNqhDGpTMN(!kGpTMNl!LGpTMN[!LGpTM
+N$"+GpTMNc"#GpTMN2!QGpTMm6ecdMAZ5GG9TMbRLK8jl6,%2GGTMLMA5DBmTaY9
+TMbRfT8jl62&p[Njl62'p[Njl62'G[b*fLM-5G0TMLV-aG0TMLVa"TcfQ120%PB3
+8Ce(SY-F8Th6TY-F8X9bR2DD*GcVY-8emd@Q2DIDf6RY-XjGdfQ1DYG0TMqQPH5(
+BQ1'Jdal0j%fGpTKHQ[H!M4N-1Zdac6N21ZdacANT1ZdacENI1ZdacGNG1ZdacEN
+[1Zh461V8DBpTcS$4DBpTiSe1HdbcaMVYd8c`e'Q2*F3qRICB3Pc3DBmPV,Y1Hbc
+KE!5G`9&#l0GTMb@FYD$6(NXiUd+R2CC`TSXqhbRK,"+GpPM#Q6BklE'%mfYdfQ-
+*qe+R2CC`LTP1HbcKJfHGpTJKPZLda`baAUFpCSLc1Zda3ac8DBmCBT01Hm`34h6
+DBiBpUM*IKVA@DBmCjU26(M0,XdQ`-EY#TceQ@'pPiKR1H0"TMfDLU%jlc,"IGGT
+MK[0jp#P$KR0lG,C)KM0iG0TMKR0D9-R0r"FZ1ZfaP0a-Tcf@NVISY-G5mKDGpPM
++HUX+@8T-e'Q2TF3)RICBbTl4DBqPj'FklG&-)p9TMk@F+D26(NXj%dDR2CDbCMV
+YXC4cAA6DBbPa4DFpCXNjGGTMPRa2TceQL5Xkl6&,(U26(V2N$cVY-8[me@Q2@H+
+86R[-XKGefQ1@ID,6(V2-AkFpCPNrRIDBj9`KRIDB*3r3DBpCeP+R26S6$LJ&Ji#
+pfSRQPQA6'EiU!)Z&!F2+BG'J-D`CKJ`$KK(l%kGF"-G&qmj&F,!XTi1U6NhmZ"1
+#,Z"K5ATiI1FHHpBTFhH2c3@mBbM-RQ2Q(!HQX#0pK5-Fe&ecd$VA$9iqb(pP6NH
+"2kq$f6"&LE5QF-jNk[a%lmd(%lf9(9-6UFQaQMSh9H"YjIUc,i(B*mVFh$YlcYk
+PUUNTSl`%hEJ5%p6US4E@Jm(AJj8h32&T`25k"NcDDm"mp99339D"`Dr#*,A98+a
+@Bh,H'LK@Da$M"Ya[J0*a!pM`@LK$Dm&mef,'m6US11ZJ!+c$P,CeQ,Th)bM&MBL
+A3p2R`'acQ0#@JemM9)R'jSQDLN!NUYPke+3CE,mCDNXcTZ8eh`q"51Va!UKc,m$
+-e3e3dcCJ5-`'q,9!Z@N"Hfi&Vfb&DY-+0Yb++B!ES4"Ya&5qMCMmYJRjE`,,hJ5
+9B$2bfJa9Bc-Qq@d"cpb#QQh"j,iYb1XQe1XQU!3h34@i#IjESBaYKC+b&DVD0UL
+#fk!)E2XmK#*4VQk'%R%c&-,Yk+(Yi!$E`HDhBaVG,DM$,9#'EN%2Y%'eE)1Ld)C
+FASKFASKTKMZJDZk!BV)$YGca$BK&SZ,YK#U`%kVL,UL(Zj!!ebj-SpZ0'Zm'Qpm
+0KDXGr,JGDQXle+&f-2jfc,'q&HVEVHM[@a(h0[6!E9!PES2kHYYA)"`*"lmGrGi
+"P1e!EhE!E`q8P$fSbaj-4pb,[YU,h2CLQZ)qe'mI&0"pk+Api"rlSIlXac6"6[$
+`6LKCRCLZG`!mrJ"8[!03X!qJrJHKAKa%[3pLHYj"B-!Gi1jhS2IZJ$,("+K$k+P
+$8)J223J"5HV3"I@L#e-D$m2[-2$J#(VT#05Y)e$)MU"Ali5LHbG8[$[4VhGLUZ4
+G`++ld#phS9q13R%m#KAY+2$R'*63BqL2Br"l%@+m#1VXXpFfGf@,U[j-8H0NhY$
+qXp#[!0ee`)bkXDjkXY%erI$"FcRhEfCLPcSp0l*l#QV!cU)98'qlTe#FI#lX$q6
+c2V@l"bHG-VA-KbdG8DIl+2c4ZMmjkPU-prPLMU`[m3!Il-VpUh-FD1-PeJi(2[L
+-GmiD8HiiD5G@3)aZQ0iEkr0f![Ea@(Y(-diN0R*M#5pq9q#PeBD85X4kU#MkSZ9
+j4SFk6VhA-j1SMe1$04221@KHVTVAGa(l("SX4BLNH61LdD+CCbbRJaKZH+ZCILN
+1Q9-P-AqNCI#H",hDD(2LB%)Jk"Pa$`Ia30!dZD#k'lAG$fh'E%U%'8[*SE-EcFr
+2"G!aSU%km1i[b-HIc"RNBfSM%B*LRDf041,4Kh%d8bl&B6C$bjeA(rQLL8208Nl
+qE0!Jkh0&%j`bdl%Bhf''9,9rmhf2qr6%%qVF,%HBP6k"FVdGPpP,GApc*K9Jr(r
+2[N`fQ,`0iMQ3!0%2+*Yj@HDV#6`Y-dr+I!IHP*QhC#@5!)qNc$-*2`+[b-cV-H2
+JUTeY3ejrRi)$BMU$3(YfHAETi(&%c&AilM5$D*jAF@i2RY5q#[mNrY2aRi(rTIM
+2a(m@rV2aRi[r22`Ai(mCHdAqeIMcH2M-S)F4IkRR92aRi(mTrM2aVm&r([lcm9m
+!J[HYpCpF+XH"m-`ZH'hR$YMP+Y)Skf34[jUF%h+5DZLjfI%Q-jLGc("R%I*Mhk-
+$&mC6PGGSle&(9Ik,ITTU6rjff2&JQZSX5`0f1Pie21DmUZa%r['!Uhh-ESdpc'1
+k`FbemUX@SX!kRPYp-icmHZSb[6M["qAMcLYX6,RY`TMQ`lAMRQD5l%"#[)JBD"J
+F'jb3!"4Lrm`h'b"m5&(d'bLU(53pf%h@Gl#CG!*`Gi-dXrhlDSEMF-h`lUmCIM+
+hZXpTS$[0j'YTXNjpG%EZhZfBX(fL`$cjDZF-hm24Sa9HMAJe1FbT0Dl4F29Z$)`
+pHc!`pSd`X1LS$9$dmf[GRAm2"[Bl"fdE1bX'aMi'!f12'!-(+Uq3!"Al&M!`GSi
+a-2D--6$fM$#`k"MM5G'l[jdL$1`ZA$F'p[N10T0LB(H$K"KBG"bZ@BL"46m`X0G
+TS$XM$)`pB`b-23XBf!d0-3D'Brbl)6"bl%(!b$8#`)+I&VrJjTFj6Vd(rITmJhk
+0I"Al)KF$IC&$M(cpp9DFLP`,Z"IjaV!A1FDS&cP'S&I`Lr'Mi0cA34(La4AV"Va
+Hei(q8EL,Zb*%Zi,I8,&#V#Zi!A9&RrjZM)!ZFSaa,R)X`&b-!M(+)59f`j[ak-%
+eia-"@Z#JT3hXI[eXAMhB&6N&6@HF&+f-cF#8XF6i&&G+SF6i&"$*1-93C$aL$$)
+H%IJ%$R%M"ej4Q51FX3AS"TM3Tl[)#LQfN!!KPJ31[EQ(k"(BJBfm-Hk1##L-4i`
+3aU-!$EEPBNc`QmaijCc`Z2D`GM)edF"U""eA2+)`Q(i9RHmJ9,KHadfjBdlf-D`
+9"rY)A*aQ,f(A0(XG*FhBU6I0#!hM,)[F5*-XqNQ1N8p[LUDViYcbJ+C*j4dN'f2
+X6D0RMB8Le"AmBp3V1"Fk[q$I$3)&laJq#mi4N[ElaX$@(d!aVYr94lKL,h5MlU"
+l!-"&Gi[&"EHiC3[18IF1q*iXPGrP"Eq[0hb"3Ch`(bTc4$2kIFmdCNJqqPhK)30
+q*lSJCLF&jjLS&*alf'M"25+QrEiRDKM4eF+q%d@N,3D)SEESAF$DBS"ZX#fkafK
+Ep)lJGX!jEZZ"#0S6!ll$6G%0Z5Im!c$UpIFAkHMaLe'hk"h"lU$c8-&mi#dkpL*
+[-83"HNm''#jh",i$cQIE0)6I!9r`Gp$aC$[%#&cdML%iA#@ML)@4E`b$N@-"!52
+IE[#,2'2FLa`Mb#[ia@e8F0B1+VMj24,AZ4[HHPf$9SpG,DK&,M'H4BkpX"0j&a#
+RchHJ!K(1&2b'HL0%Pi)E`&,dkHZA'%iLaq%h+!D3!(1@9feD9IfSDi0[Ie[Vlij
+EG)hL&X@D)'c"-iUD9f1#F)&,&'H!fJFKqlfMk)-%*3Jri"l&MjUX1h648`P6dHp
+N+P'DVTIchCHV,S4CJ[qR*QNLf0rA*(K(2&L6i(LBEH#22!hR'1J,hP0c$03K2mG
+!3hE2-A#BcFV34BBRi$m4rdRi6m&r+[l6m*q"rdcmCq%r'rmjCX0PYN"*R)&r*Ij
+9q*IM2`lrLNHHC-YIjkXl!3iMMe0QdUm!dZ61F*0mi#&I`j&V*XD$ZUVfG1$B(GZ
+!)F3$q,IJ`9&XjH4bB`NK(T3D2+M$CPkb!C@cM5IiH#$k`B4MH,$IkXc''8-mQ-L
+GDqY@*S+,00pCYS+PE3#2EBqAckXEFVa1CN!4iN(C$r(!h!l8klkh2GqF`C+(09R
+2GTYP(AB%JiN3$mUIa!0jC1BN!i0Z2"KRm-!m*p6PrHTN[8bAQT!!i11"M,9,I`X
+2JT8Lh@Q)%1*"b6&pN4e8Gd5Geb6'N!![6K)mD23$cGIhADQqp*EdjNjVL"$L3GA
+bpR869VD[de%'jikEiRedIZ%r@qB-GpF`pHeH`XC,b%C3iX9Q4Z1@il$Y@[lF[4+
+(bHd9bh&54q0%qE$$519b(,Bb(Sc$jNG9l6KXKc5K(BFG5kjlV$kKJHf6RYq1`p$
+SPHdiE+e8reLIK3DfBXUfil$p8QNl$LZ*V'V&'Cbk,1k-I,kYR3plUGcHMX-ZBah
+Y1+`PdY#ZMpN(2amRlV0JmVQi-j+kE$A[+"p@'(RPDMj4((CDHqeUR1#Y[ELcqFM
+V6XE*!e,`eZh-FGM'F6jY"CAHX@9E[dV1QrP+E601&+TN"NX*(pC$6P5h'LSCk(e
+0"`YkYf#X8b*Cpm1Si&5(RDS6UH3`eQdqj#m@-+0*I'A$iM8kZY`*QjDVNYQTR&A
+0&k)!L8Qk9B'ZBUEQS8@)&`Ge%#fUlZ,XG$hV98l8G,IU,ZY'9-Y(JHU'FVG[NJ0
+kXQR-eYU&GF%6hCGDRZreEGQXILQGU9QHdN1@29X0r+CAaYLmhIjm[+PiBPfk10[
+!-#lV`bE)+a%p[@2cYQdU#9pF'hGEG4e(DX[jFaSV5dZPE8$6(eHV*-B0lG0CEa*
+hUE0-%*%k5!5U)h9QjT2@1DdA'LkV,9X[(h$G3C[,Kd[&GkQHp%Kp"M(VDpUHM6f
+b@"Hj,@FjRRTfZP5bI3p,*4dZ93+rA[,d[1Yif)VDVr0ciTSYMqZ"EGQfAT9%VGX
+$aT'CBP+9[6ZeAdFE(F2LbjlUE[MZBX'DdkSl@QbJH,IkUR[+FrBeGABBRA6BahX
+*Q92PClK-VA&e*9*V&LFUP6MEfMKEmC0XPm6p8@pjFhN!J1lr[,q-kZq[jQYB+(e
+eS0P$8Z1eG3aQN[PE"ef,[8iYTL%f@kl,M+G$l-'G9X$1N!$D90&aVkD6GP`9))5
+'h,fd1RC3S@[LHR"E4XcUp#1RXMLX)m[K'Rbk&96Rf0h#2"*GhJZa+N5i&96Rb#&
+Z"A8C&3ehb9C3qANYQH9j,Hkjq4bZ0KMSai0dalPj,6h[jpcemeUFpZr[api,mjc
+Fpr0DJZe4`m8YR+XR@[[$dG)!lVMY8GebUhf+1-#JUeYEJjVLf8c")#RaBN$8LT-
+$SL31!k+fYq-`)'VEmPbbEL5+mRB2a'&&rPA,!h91$0KbAm54X`-ePTA)Kmj1M+J
+EpSr6NR@Sl3LmX'YN6j*J&pR%Zl#hZJ`5ijhlpdm5da2-C!i(`+%@5CAX15PXc6$
+EM(l[X#6jLJD'dMJ"mQM-M3qGM#-21@UbGEi%T,+$-@4X#QYPZ`$bf*`ClJa3e`f
+&bG8-RmLMG@42-6e68hBBhUm5$lj+*AHejMjQhaRE9PUZkrYHDNblbc1[[%2Aa%Z
+YHQqpPfRB2'3$pY1RF6TPYR-DkJirMfFq[e0!(QF,mUdmcSlkqRBHCa+jN!#(6'a
++E,TLKqRAGafU(IlDMLlD*hm#XbL2h43(QJdkNGeCTNPm2iEr`Dj0,dXP[RK[c$T
+0(Z'XRrpG$mC2QMc1YJGjk&*8`i@eHFJU@Bk!2(Cp[l)MGBA"qRQF4U),HCc6rb8
+2fF2UE!b64jHU2Bl6GXZV4!c8[QX"TlGN*TlJ-F4Br3-QXpZhipf4RMS8j&!Br)!
+e2*C(9mhPr+Xc4lEP'Z9RA9'c3d!HR%9SNUIUbP"HCGc$LmLl2aMhd"MM*aRhF"l
+1!-DpIQJA*kQG1Bhjk5IUiIKJlUH'6[m[jMkDaq2-I652ajRler0iM,Q2j2&YjZj
+pqZ1p(3#BqiPkI*Hj$aIf#HBqNXIMc2e%'YpKlL0jR'2ZSl6Gck0,9rqrljdIM&X
+fb"Z-m56M(XU$i`KJh$,9mqVqe-SkNMfRl%H-5I)iJ`cIC%bMH6c1G,kHaf0-Cb5
+2Eb,jL6bqJq3MHC`$2FR$l+ijJK#,-(I`Y(qS5*cU%-RM`-cHar0B2l2hL6c+FMp
+iAjc0j6+B)qX#10p!2&PYN8lmHKllrTFV5KlXUj!!hd[a4%I[MLIBZJ$UqM4R#,M
+d18jq)Bm4j$cACd&rb&cXljpaCRA&BB`C(kZ2ErF1*!kpj6XU92r*Ue#IHHQbqZJ
+%b+2H$8-&L"%!'FT$X*kk*KlAbBeUk!5SKe(lR!"jq'VIk6`ZU(fh4h9A[3)28mR
+M(NbIpJiNlS0pbVlHa*[Id&"A*'kmk6@[Z#Tam(5#LFbHV[6JIcaairAV%QrqXhK
+DYFPM$lYSZ"lRqda9PSl'prS9PF8!dDNmQ$DIi&$qTr[HU#a1J(ie+SX6)!q1KE2
+%6qTUmT!!pNMmY$qDI)pcaBH2Pm[P1`$-Zf$pqa(UN6Lcmm6,KrU*ecialF$[XG2
+(F"JR3"lVpJD902j2e49@kUjiXhMkp(1K`XPcSHre4ji,IDpIh3'+Xq&#6q-(#,c
+9D6ca!ZGmAGd6bM9(1GA&ZTSmcZf"F6k2N5GHLHGdIR[MGITFB$TZT6GH6ar(dKZ
+[Jih[Xp14ZMS+hSSpI4`JEm91!-KhhSUG@T(+$I"@,0`5Hc")DHF*jZkSB+C1!14
+d+b$9q6-k!G,pSHNiA#EPR$i1!Lh'$63TjqRM@*U8Fd','8c%4D$&R)fK%hI1(2I
+@a*f4jrqb!*5Mi[hri`c1[6&(i*[-kd3Hhf9H``9jJRQ0j1'FQ)p`JAN0*Z)@Q,0
+Jmj!!9F*1(C+3!&RlPK5FLZ-'B!3Q$kI%h!Gp8pEJfkX8TH,*PkL5aA#-Elp%2C2
+(H3eZK*-l2ejqRZN2*m2,ck&k22RbmdaGcfX0jrZHmrL,c62e-(NmpQ,c6"ibdIF
+EZfY+((EAR,)kSMRBA92LX,[QT08i86jX(cLeR6IlY%eEc5Ha%SIj`02EHE-*h-c
+91#8VFFEMQYq&FlJql,LChm&c1!i`Qpr"FcJ1Zf[q`'0e$2Z@h6@Ifil$D1MRYH1
+`iqESETd5Kp(ISlYe5KbfV"[GV92LX,[Qk'kGiXAZQU1lG8SF0VSEhDe6iV$MjZK
+ZR4+(%HElf[9KK2Q2VSj%[hXP$L2(4hIe&#ri6rA*A6dPcMaFlf[AF6kZ*hIkM1)
+X`2AN6Tp4R)@iRYcTXf3P$T2a6qld'F6*!q&B#f%(6l0RCk-94Y!Hd`X0(aYiXKR
+QLJSFc)k9c8-6$Hd0MaB@29XPXE)QVa4c6KdEH-UQQHbYfD!V@!1c[KQ%f(NcQhI
+p+)Yp-X@hH@J-m9CcqdX624dk(RDR2+5MCZ$TFK'EBFSqPFX(6Y3d[D1r$eYQ5RV
+09K$U`D!kaeL,ZB9Ql3#fiT3Y0A0B'A-YeY!mLMJ*Yj5(d0`HB+p,'EkjclGR5a8
+[9$eeDb(RPjf+Si0TTac98*GkhkXie@DJKjT4K%Ua)@BEem[F%3i(eV`eiqU-l`G
+PE-!Td9FZ4Yb&Xm[&1TYQ)p$kh$Kf#@hh9(F@)IG09Vei2defc,4VG,E1MXaT$pY
+X5Qe0[4CcMmdPII'YPKYd,ZhVikff0kiTZfl@$X#[a5PMMdhkVm'Xp#RYNp0H&98
+cAEN+kE+C$K@@ABAUXA!S@5kpL0NX(lJ)G@L*9rr8(6GeqdmU`1DD5r[kicTJ@h)
+4Ue%lX"9lP0Te19Gjf0icN@4qM4B@(9f6(9AV#YQ*U6fS`T&'85r))U1*j(J1Hh*
++TTXJh#H5NpM"V3%lQlBkf'5dSP6#HU*Yh2UcSdb%N!#Y6J9K@1kd$5dP+*2&jU!
+(XT'ZUfidr'E6CfcrZDU-YpFKSZJ1U0QC'AmKVQ-9Hd#+)FUk*(l%a8kQH*MY2a0
+&fF(c`'pH*m`MdH@r6S"1Gr!mm-UEiadmli5,Xf3(6h3BqD1UC2![a6q,IaRqjIK
+IJ[pir#[aVm*r)[k6m*q-IcAq8r#IL[m-r#r&IbEq0IM2`hmqrJ[`AbLD"SHpQUN
+@QKfl+G[Y)YMedZiVM,k"ESSQ#Y0$bd3(C-pQZJ'0%Id3,3qG$Jh1AA$)Nhc4fra
+D8"IU46G5Zd,GU#depZZ&pNIpU$8epq['9UI8$Sf1ENCEFfFFHS"Dqre,[HN*kKh
+eJpmcp!6p3"rirF[GCA$ml!aR,Cr+Cp-%h)k&EdF,P$CR!8Dj#XljR6`FAT-'('-
+lHI$-bDQeNmHh*`3i!(Eb-(R)2R'M#CmlB`f(h6kqYCA2'"YLYiqA*'kmCF1*h6l
+HHZI2LN'lIC`i@3`!6TRTcc+bD4)R"GGYVfT2"ikpr5QSFASG4N,VPJUT'!pFE6$
+3M`FPKKmFKE,JFN1&%!mb"JrU-19hHEU[BaY[p2&!p)1*ar"J[p@C68-)m@!#0MR
+`YTZ(T5h0"MALZM&Xb#'EBEM8J-((!e&Tdpr#!hQ'F-J+(0e"$4&#2#JaH*!!hhD
+Q*E+mXK@8m8S%9$Lf29FB6f@f$cPH*c0d#2PLq3raJ*Z`L,TmFmCel&6@XpeQZA-
+BJ`Ma)2XN(XMXhIfqej%-%N)m+$ZQ,ql#Z18G8HFeL6(%JbV"JdBrd0c9U5[9Ppk
+5hYaT$4&#2+MNhN+MFibFTkHVGN2"U6GFAAcL3EfVj$MKhUbDiq$B)SY"#%kG,E)
+@Qkd!0X5E4jQ6(AX6V`0E*Icj!l(0HmH"H#Fk"p0-Ze2pbN!0[f&lqrAeVAjeG@f
+40G6h!eYNpH1dZhk,,*H#!Z!'fM$JR!*3h*IP+3A!,E9&eY0p2kCPf#,VhHIG"EB
+kc'll6X4Z!rA4#C!!4lK&eP!H!pXbpDKL4M9d!Y6$U(e1J$b#,E*1jA&"l62cFh0
+AYlE)NNGL@f#A,E+5CliNYPGqH2cfVY5pKf"LLka(i2r"VNe2Fl[1I%@m994qIZj
+`2Flh@EK&eP!H!eYNpH34ET&eX4j'CA%#p+Y4@C`!HA"dIZl&ZTSml"CC&r-B-rC
+XN58E'%`ddk9VLV1T$CR4(0kDA2%Mr0LF$FI-'i$+KrEFrK33kANH6Q$FQ,JkF9V
+APFFLC1-EFq*0NlX!6M,qFh[X(%6b-lrMR9*U2lFTkVf*Chmd%XpdaI@8a$aMd1-
+P[18ie(eD+djh0Q%F%,hqXAc#[#IKZUS9Cl$q%UFDedQVH8Ij6-9eHMZ1$1*)A0U
+1-ahA&HdiPa)6rQHpDGR5GTaCZ0l@MM-Eep[EFHEJfY'1!q@j["eR,UlhY2Yf(Ui
+0l6McFAheUI(QD"+cZmr33r`i#h'pEl8q86kAieV@MJ22q2(9rSlbIJDZVh`-p`U
+(G(@G+9G[(&MQMT2LJJ[Q)&'Y'lamN!$rbT@9CXbiRjCc*P2R*hT[2TMSVHbBQNK
+0MYA8ZDN#Eb[ARhf*5Zbq$66ZNCkcGkPUN!2#0+Dp(G4H*ZrB8623+MRPZEipQhF
+@0'E0966LA@MDA0[hjY5jT9)j+TAk,bb9'PB31CCEXS,!@LaK5jV$3G11r'"d$NP
+9TBHD8H4l)h2DLr)"e+#UG('f90#ZYL2(pc,eXZUjh!QEPMZ-Y-9M4h#LTVApI@V
+0MVl0[&flq5,FP[G[98N,'p`X,3@P4Y!)N!"Y0Ve64k1lQhK,Y'KN(h*UMP6hJP1
+hUKS[6E*CciPf"PC&GEZf'pMDG982!M)K6qBaG8CCVq+V068SiT*IEAprR$'hjId
+AUQ3kbccUI6mSKfTGdDp@A3hKZ$e6XlbUMQYE8CbP4kXr''K,*G%M"p!dlD@kYF$
+U5%&A,NE)VLSr0)l1fX$!+m*&ceCVE+[aSMMVUq1XZ5h[hkE@3+dlV*)9*`LMR$q
+Rme'JNUKCUej!ZAEV"C8-jjh)VZR`A0DUSK*S24aBmaEbPLVYFNZMMPIHEG9ef,"
+XIEQ&q-e$`qLr`lV!c#X+1LT%j3`,f+@'5b8EI9fV&fcGB$ZZRXaXf6CMKHKmDH`
+1VhU*[E&[LefcJP)8@%i8AQ+rB'0I2pALA4DkAXc2CDdlI,64%6G5238lF"V4'&E
+YN5Q%'r0je90ZeZZ,3qLMpQ$H+8FeB%+$%cCFDc&MHA-XED,EmQ`JbB&!GA[0HT%
+EA8P(,0hFUpC-!MN5kp*ld!@0IYQT1$V)@Bd'5T0BJdEE%RG43QeDfpb9,DV'ZiA
+,HkUVm3%-BJ2SVX-ialUaVXDlVZkDI[MJmqk"bmc%,R9kEQ6h&25`R88Vi2#!H`V
+&bHI#rN!qlr2C`S166TQ2M4qfd$abrbMm88dq1HTDM2Ij)PlYb[f,M5!HU[M91D`
+Q*T5RI$M``@HmFpDXD1jT4jf"DeYXfa1V9fq+(Br(LY+AijTG4DENVBeYLp5'P%U
+m-,Bp5fh&lH856f4)leDaVF1i`AG+LUhN8e*[,el*-G9DbG&e`khF*bGFZ8m@BR,
+-VGcRVd!dGZ*BZFpImGC*Yh+I(3IUCPfjEl-6rR3*%ZI(FALZh1I@'3!X#hIpQ9Q
+KC&eVmPcfRE&YB!@A6em6VmcL[I9HTZ&Q@VP[U&m(9Zi,q[8cVAjeGDhF0p6h!b[
+hpH1dZhlP2TH#!Z!+@VR[M!*3A#lU+3A!0E9bhm@q(p-bV0chGZp!iY"E[XYZqdl
+%EJ2ed3Q3!%HiFYp3(J1VaI@SBNBeG!,8`kKp6S!mJTAl6Z9a3HdVVYbAI2V4PIX
+qdlATMYHF@,R[SBf2VY`hA)rcI4DZh$H8am$+I6ejK#[hADb(89QF!2eU9"BR3"i
+FA6EJBPe0(REP[SYjM"Pl9Zk6PahbC`d['EHZ*af2B,rbPQGHmb#UqTDRS-ApG5C
+L5l[-F9aB#PciJP,2ZlHM'bl-aYCl*FGaSIEQVlcl'9cT`ZPfNL#4"9cB$9bSa0U
+1l+ISEMYE!3VS$"%ZE#-ZI1h`'cX![!9aHTd$%"Ib#ePDA%MFdM0hpZ($ph9f`i9
+l34C1i-,a&h4bJ`@cXL`EBCVl,r5mjTl$KcqclC%JHD,TGMY64V2M)k#A+Gj&PTU
+6K90+pX`eEaeBG01mL[)9+hCTh($%S3Areb$N&DFQc0k`[(LkAb+`q5ZlcjT&CPq
+'[eQrNF9P1Dr!rdH@FY(YCdh@2%GCFb4*jYT5Qm""9RC-[!NKjbpPcA5&9beP66T
+brqXUKZ&Y&F8iM`R+RBe`HkUSSI09P-$La*ZF[kTLP,@TSKMR,T99cZ!bYQk%`ak
+8U9LXcU#Je@E[*&IE[S[q#IHJ6(@'fcNRa!-8+1%(4r&feZ@'#L%HP(5Ffj28he[
+0(EFRkD5IH6$f**hFb@j2dP2E9cK26reS$Z$hjS*6ElLkq-6B5"I*FAMZ5FTB!DI
+1RU5,cGj,'mV,!E*MmDL&JEfTr[b"f1Dpim"e[$ZCpL3GkYH"28Q$IRepUepGAAZ
+5$[Ap`*kNr6MYVYq6e+@J!,L#pL3pS`!80m*l5J&`6He*HV([al3-Hj+qqlbl`&D
+(f@hILGKYS$ik!I))pb3GbQ0J(m`H9FbSKNk!HKLec`Q3!%H`*qQT2#kSIF8p5H@
+4@,3RUCc+$jrBNc6M2VSRkA!pc[GCZ#IT8"i$Hj,fj"(Z5AUa(NCPF3,dUe&CR!"
+jF(4$P)Ye0ARB28N[jM&Ql0Q60,mGU4i[RPVVqMPYT6#b[XrQ(!M(LrH*fh%5)e`
+`"kDaE[$b3IiV9cE6-&-E@XkC6*fIk,hjB++hXQ0U)M8j9P2RTJUmV9arpL8UXIX
+f,(lf5-rCZe3e0F@9eB,GccULZYA)@@%%9TYHD2LK5KCYYc4BJ80p[Db5qD'*K[D
+'4`Z,RUf5"4har8[1U6X48UK+&fG,`lVLH$V6$%)r80ejeiqbYZr"YhPS$2&@Clf
++(dG2KilAVj+"MTU"Tm[&aBC@DhB-$*bSDAT(Iem[DV'hP,H#8!m'e6R'@Mb!@qh
+!CTAdp2biVN4CVk`A%#IKP[+3!$$DJcP080RRfl1PLKHURVUeN!$cbdl&dF'd8ij
+UU%Zple@FDM233mdS3U@QXBVePMGRKF1"0@r0Z$VMqd%j90f)[R)aJM55$9eV6ZF
+M9,Jq0qkJAcT9GaBKpde@2E81'FJ,*%RX6Ke%aGQ41He&F@e0[4C[a@e*AhbVhB,
+EdViqhQTlijV@aM89[aDRV08kpPp$)3SFViVfb@Q[LUUCVPb&G0NhJJV,"KVeIM2
+1FZP&c'Ej`%@S3iXGq+ilB`@$GZ6iAMi!VD)#em4C,ihVJ'h*4Da'lF"@P4af`SC
+V,Bji8E#SNXb[dBVXfXlXU&TAb%j-l8%9MM5+HL'##,6EReI*mGa1(5(66C!!K'5
+`L@a@e'"&ZZM8Y8U@5P8GP5,dGNHC#,%c4TJfA0[38S)bf5D5@"[TZZT'`fmfIEB
+2VEbUM&Gp)D+XM#-RZQGQr)@iMPAX!5Q'D$D5q"%h8Yhd@"eS[!CXhE5fZ5YE92X
+q(Xr6!H#5q`jKGJj!GafQFY@0GHflje$Ap--(cqZ(bmc%,R9kEQ6h&1DelbaD!Gq
+!hP-S6MiApJIbHCrUdi166TP[aKkfG)38%hI"(pVjb9(ABVc2&r(i5ZjIE!6aE+b
+[S[ZlX-e[qA$JJmpijkaCN8l5MMU$T-[BpULcF(e6l(KF23Hh,mFeZiVlEAPVBpX
+LY5'P%Y`R,j'i3'h&c5b(*r&%-["Z&CXXHMIZMbA&9[a,XGfGP2bTeHi-,h3lN!$
+$8V-2Rh2Qb2*q%mef$6A&fG5'X(C"Sf'IIc6%jQ`iCYijSTDP2KXM4#*rH`H%fRL
+AiUJY#4%A$$)ij(SjNpGR*SC(eUI@$`m@"h&YcQD+kcZV0%"qHq8m9(#4c3p,V,6
+II)TIJ$J@klbVp[!ja0-R4,#%QNTFR6LYkmVMPA-#C"QIFB+3!"A3$R3rXFHR'[E
+TS5kJiiM33r2E@CUY-#XTKTRjR1dKAMi8hbbJ#cC1[pJmQf&[4TP5bRL%QSNIBfZ
+!Ua3L26bqFimpkj3K`1bC,Z!Yi(J$0EC+j92jE*VL4mI#BrA8URBcHPQ[N`4Ld$+
+&0q)&SC*25J!(%A2QGl`PeaGcDF$H@j!!X$NX+bVAVUlPQJe@31+![Lmq'5GIef"
+[`E%Z3KaHiXMHBh*,3@"fc1eJbKY&Ypb1PA*&S((,m3121j!!Q@R96YFGb14GeJE
+YDL[8UD'QilBQ[VY6MNYZ"l,-cd)YQ`XiSHH#-l2'qABD#pQ4-l-HjP9hkLJeXY"
+`XCApNqq+ed,p)DbS3'II,,[,6NDQ4aqklfVM)&-)$hhQrU26S`ppmVTiHM34h#E
+6Sdherqii)DC(ZfQ16)mHQEJE6G5eIl"L5bI+kG'P(*0V4p$+hrdc5jUTYrjaTFf
+9GS4-LAD$5"8$4r3,LMSkL$VI%Q0QK!(66mCa1Tbc'`9BIPC$RGP`YIcJl'6Rqm(
+CJJGMe)6"f5YF0e@)V-La1`%X8HrS1)l'`GPM6C&aXU0Vc%cZ8,V'c2kIY'Xq$fI
+%1M3Q$cI11M4pbdcq[c`F!$KNmR!$V'IMJKi)l[iDr[TAQjqkj8E&ZQJ@KMB6FX1
+KRf0TK$2@h1&bdK'9R2Y6cbP$lH'*Z@&-9fUFIM'(+,*rMa0Z+FL'dI&L"i#P),m
+AhJ9f&[If%NFF-(d`PNG3dq!XjC-6%dFjA'ERj*54LL4!HYS*1EBd1jSG(i(8j-Q
+p@Zj6j$jIlP2P2N2Z-q9qk8T5*8r(QJRlrFL(,5RqTA,2VX4*pK4YGe0a&X0LG`C
+@i'J1d5aR)+QERf#0f$0LpqpcH*F0#8eKj(i&lc,RFClFjdUFk5X*ThS+Lf'NkdF
+6(Lm*qK9D)2FbZIX&Z86ZPC,`G%R8G)VX$6PEr+XNlL5j6jEl4)NlGk8JQCqIeKE
+VhhQX#9)5dq3Xpi9b[h`PG[Qk54hkcF$@BHSmE0ba0jAabpb'`a4-%M@G)d&04mM
+G&%lZTP"bRb9h[f#Q%D53!+EPCI9-8`5acf'fccpPI1e,AFHVTUc8(-Ud)r'#jec
+YH+&6eLRV$0Z[ebf[R&Tbk%aC3@!YGL)M&%k')a$,Si"-Dah)RS8S1jIM)(a2@ik
+61E,BTcMNic!KZIkaI-+m*q'kkZ3DNP!!ZGkmQRH8ca4FYlIM6-Fefkl2$&a,fh(
+BN!$hYRBF9[kl[4eR&UiGl6LcFEfm(3H'F8qlcaJKhG#1-aIA9jf+1#DQGl62JVe
+6iBTb[9rL62THR!@ihVGDabM[bh!YDmGCL1XV@h'kFDT`A06V@EEG$*UCU)I4m4F
+ajCMDAd'rRZRpdkrKBVRLT``db(3T,Xq!AmFa[`9l*3r*,rACPYre,`EG1flbLra
+Q)EmNr55rb+q8r+BmhUkkI1BC60MkCIq959UrEAYJ8b+9i3CZ0PlC4cPYAiP*'AR
+e!bEH9Dq(6EIN,82HL9dQhXFr"jY3'dlkCEJX0hk2EQ*LeLq*[NQFBIcHaC(R1U`
+qLhSRHNeq9e,"dJGXf9Cqj42[C-,@l`E`pj+mm9[`TkbCpKqeR'cbqaAflcM*qrf
+ic$$aERirE"A'l`Ir#Rhm-H1hp#ZXMFEEcCVC2,k5KBhHSDlN1Xhir3@jGkAi2G,
+UXmhF*KYp!ErIBfcVGp0[`$E"q%e"rhSQ[h+,+q&10(iPa)dkNpqIX(lS$q4"[eD
+BH"h[BifYhcc`A1m6aUrTGq#!$N%mfGYEqk$m-ZD(lN"qp+hfpi0[JSdYZVQ#Bam
+fIQpR$DBC[aV8f(Z@b@2$"`PNeQmaqr9YaZpP[mEHd[`qJSYCG$GafY[r$MCd"cP
+,IJmpCHYApS&IKB1Z&YU-2Xp)A9rl(`3bkrF4k!EA5Vch%c2&cTP'r$KHMd,@+#6
+AVd'-c([U8Ec85HMhJka,Fceb+85(IL8EfD-5$pb0r%+mI#Ne"+0m5QjX&flaXZ`
+IQ*1ZXT!!qTG@['II$4XaJ6Ab8lbmJre+A[MpHJ[2aRmHY[Q50pLMH2P,(f'ZkJI
+Z@,`XVh0rC[3&kK(LjE0r'cEd"2a#[$ai)f`k!Im0m2IamPiZ6I--L3HZ+%j-q`a
+X9iJIbjmSAQjm$faA'VqIRQ[KCIf,i+#,jb4C$m@cUC5RU6re`fEaX[aCA16M@H*
+hI3Z(2NIHX%MmhY,#bjF6Rq!1FUiqf-,,CAr2fLXrJ#GB[#c2rKD"4ZY(A44A$K2
+li9PbVN@G&#r,V[Yc*UCjX(k6pX%Gj"M2%Ep0+hJ!Cj!!,G)jcb('@l`X(b92ZXE
+i,IY8#bpI#Xa,E$0qYH`RaF[Vf8[,K6r4IaB[bi[Xq9VMer#UCE`XIc9l46FMI!L
+V6rKi14kj*Lif0,)#fkaI@c4er8AL+$%T(EbL4[!b&-ZqJKS)Ml4iQIIcZVq1fqf
+#Pf'mF[D2MjHKAj,pURhmb$f`JHhiIEc&,cGbjBERLYqMVAL2[JifAAXK4GkSH,R
+d!GMS+IaHfm+c2@q%EBA`DITImI*$V*@Z6eA1Zq,P`QYKdp8q8PpZi@8p1(4#PTY
+*NeGSIRH4Ck`bIC!!!YG8[#al2hQ2VTaKpT&AR-J4)pB),k(r,9k@hFUkbVldj0%
+!RZ2MjEh-$5j*(ra8#bqRIBded$cbH&Rfk8r$TNZ8CEPTKZ,3&-E@*ALQ[ED&Pmp
+i1fb0aQme0V6hmA,0'q$3C2cQXQm8,rFcYrA56p49F@AaRj!!-eQr6H#C2VmFph)
+iQ'hU*4ipVAd`(GLFQ*6mIUC9TmRXh4E"[rr8`XY1jUc2N4T49mA,XRrF$iH0aUr
+Z[eYikEf9KE"qmiNIbLprlC@`E6Cq@m"aIEcFIi!1Y[pZ4YiqAQiRaX"Ca'mRq*b
+2Pjqk(KjJ![@$"rYiQ4GP[@XrKMaH*ALCpdYX"qiQKJ8[3lpTM12MCHMRNAGTIa`
+K4Qm62r*AI[P1iKbF'Mmd!ifhP0abZrLabElLj@6@i"E"&ELTkM([S`CJYZ8A@J3
+2X(KC[S-jkHBLFfpUiHAL6m+Qfk)NZBD)aFZb$pi#Qkk*Y1c0,EbF4@h$,L,L[30
+jqRMjQm35p"2S$hfV1(%hZB(ZkVD!2&2amK2NE(B$(Zm2J6f6EcEaMU2R%V+1A3R
+a9r(X!@SBZQI,!Z+lmX[DIE#TMMEhYPEIc#6f`drT!h"@mA)EHDHZ)V-9I-[(bqX
+q#JI9lkkP$U*kc+28X(6KU#A%&m@9&QS"UZXGicDVLTHl@!0`JAMdJrE"SPI$TQZ
+H,#2H+"rk0@)V033@i,+Uahb-2D`kihC`G*pI,LC1k0)T0a2I&5qVUBATQL2ANFm
+T[pc&2Y"PHMi)A2Eam[lli##mR[jl(h*9[#cl!$K%BYli2B`qmI(b5`r"3pFB[iD
+kL)qAiHEX$b-2EdQ2#IfQNEX),KUm$2hQ84Icm6,[jcd)lMAqTRT82DCh*VY4Mq6
+'HL0%[0![G3EiA2+Ur(JBUG2H4FkU$p$QhS',kUaK21mdiTVNGj!!I44ZKej1hH@
+$iKIbhATLj0[%,m6ekql#j5Va#qZkM$USlDH*Gc#HlK0c2AR!8Z2h9Q+SlNCI3Pd
+X(IY05K$6L3r040[EDI`-lX,&b!mHS2RGrpH`JHhJ!Ia*mrX)X4jZ4Al`4T[Ia(R
+@9Gqih2+0jI`Q9VR`bYf50reYmjZdPEDA',qlU-0TITpP$m(&b!pFe[V0Bmd%9dd
+mY!UYhdcbaCFD[bELMZEh#'YkMr%l5RjZmj[d"ZSZB#EjJDPD[rp!$N(pL8FHQPm
+VYC9A5(krM-XEkZ%M1YpkmY,hLPqq[j0VUCRpK[L&rIeKkU62&ja6MCX)%m$4!ek
+Bpr01TalRid6H,r&XpV12Fk(IGR,ak`8A3lmQpT[P56GqLM`-AJ"d5ee99mKY)Jq
+ierKGKMj4r-lG4Xa$(a#rCb+'iRHZrk[`Z-rNPb('@0k6ZjYB#AH@XjPF`I+U'ap
+Llk*T8)ph,219h"rp,@a`"$PEb)dXVmTGc*Va4N$ki29FTNEcDk,qJ4BKjpA%"XZ
+VFNmMrk#'p!'iU2A,8FY!!j6kl56[XE`UGq@(iB(Q56`d')hh@q6-j%9BY&L,(lR
+,U(QJ48JHZk(j+8r0lDA'"*qPjF42F5AhIZ,I6aLrea!E,+lFq#AU8ZLVp$GiErP
+dlMh8*0#D`!Rd#-ZRFkpLVk-"iTIRIcGqm@(Bd$5S(cA3IVUFfZJE6ChfN!!2@Ik
+AZ`"[&"*[%lrIAHCrZ8&L*Aa+r2CqBCRrjHlq%'aS34,U*kR,@2kA1qm'f0"R*0i
+qp*[b[pa1BZfEK+I#kk`1NEZ6IB`fJNYHImVY)Kk6#b8#Ak`1NHZPGS!H++H0I0l
+U",QcL(9[0AQ2)lrem6A%ZHR%Y5V`-hKaRMmP3q"LL4*me6FN"[r39G%[`GHmAq*
+Af!Fq(ihm`"dIGd-rHa4hmhlHYH`VLl[9HpLVF"E*qbMUNGPKr!j6ZraCirG$`&r
+&hHUA8q[RVBVir6"`CdBYpT[mGGB%IL'RP$c2iQ+eaGj$Kj&iRHacLl[9Yl*R`&Y
+`#2b`r9Gp2I8cp'IkMhkeZ&Yp"h9PY$[b%(kJZ&[Gi"X$q*Vi(D!@ER'h@K22i"6
+8qk&P(+hqGElE3&-LRQL6LV[9ee)VHBraZi2BVr&qKhM'ZaMmrR!CGkZrr$IN@0E
+[MAM,SVKEr5&U13m+r`!R,1j@Rdrp'liQm3laABh&hHSm-C3h#2L"(aChU`m3iq'
+$q0'(&RHVCmJjU5Gqj'PaYlVr%l$a&J1rhfleNdIZbTXJm61pCA'hqQh-PAi4[cI
+M(BlLERAkRq$"1`laH`XjU-AGkYqP,S*@6(jSi4ChU`r`$BaG)LRj"qJEaGh*hb!
+@`6[Nh%$X+4Im#r&T#hRR$X(,%2rHJI`#A-`[r*5mPARlZ*Mh5ea-AZ(MBKM[2G5
+*I&`X,JkPZ"M'kb+f@9aXqMJeUBFP$qNjaFA'KiQ,F%raqe9`%FA&TR2iaJ9Z)Ri
+I31pHDZ)eh8AYM(G$Y!$pCh'Vk8kqHB$l5,bh%9FX,MDGahKS(G3MrikND5-a'fj
+)2$LZaF@QAfD0H&-MIMm,6Uqif,5'ZB)$i[GcI20KFE(T$2)`X!Xrp%@Yhh6L*Hq
+mm*2BLSY0,k'@J'BSIMp22,$a'Vp%A3HHL"r[4LbH06j)[%6Ea!pHD['XkII*AF!
+dr2#hH0Ddb2F"i#eqk%m@cjSX[[8#Ur&$kp8qH)Kp`aXCr0$r,*iehXmh#Z#$q2d
+"hUFTRM9G4Yi[["+r6m@kKI9l,ppXS$AK4adYRM@pPpS5lc[`%ma62'[D5*hJ%kD
+2Mj,6qlJ9iNS6ZC62md*Fq@1mir&q,XkMiTrj4Z,hMGqRS@HRhf[m$T-EJ1(LpeR
+8dBqhL'q``'6aqpbrYq+Y*lHRAm6[6i%0IV`0j'EJLIKp!6c(MrGMe(6rb2Mp'Gr
+RDE`h%-qSTrMp0qKVIV`rT6EmDH2hPp#Fr(K',k%Qi[FPk-eq202#q)VI9m"aJhV
+`pSQh(Z,h2r"16q0GmJ[N@V`2%Th*!blim6l%0f#I-hj*jQ2j9X@YY%Rpm8[KhBE
+bVBVA%r0jfb9q@I")[aiI)+Fh@ZMr"`"'`J!!:
diff --git a/mac/tkMacResource.r b/mac/tkMacResource.r
index 23a2000..76bd528 100644
--- a/mac/tkMacResource.r
+++ b/mac/tkMacResource.r
@@ -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.
*
- * SCCS: @(#) tkMacResource.r 1.35 97/11/03 17:16:34
+ * SCCS: @(#) tkMacResource.r 1.38 98/02/10 10:38:07
*/
/*
@@ -73,12 +73,7 @@ resource 'vers' (2) {
* will load the TEXT resource named "Init".
*/
-read 'TEXT' (0, "Init", purgeable, preload)
- ":::tcl" TCL_VERSION ":library:init.tcl";
-read 'TEXT' (1, "History", purgeable, preload)
- ":::tcl" TCL_VERSION ":library:history.tcl";
-read 'TEXT' (2, "Word", purgeable,preload)
- ":::tcl" TCL_VERSION ":library:word.tcl";
+#include "tclMacTclCode.r"
read 'TEXT' (10, "tk", purgeable, preload) "::library:tk.tcl";
read 'TEXT' (11, "button", purgeable, preload) "::library:button.tcl";
@@ -97,7 +92,6 @@ 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";
-read 'TEXT' (27, "prolog", purgeable, preload) "::library:prolog.ps";
/*
@@ -130,18 +124,20 @@ resource 'STR#' (128, "Tcl Environment Variables") {
*/
resource 'DLOG' (128, "Default About Box", purgeable) {
- {85, 107, 243, 406}, dBoxProc, visible, goAway, 0,
+ {85, 107, 260, 412}, dBoxProc, visible, goAway, 0,
128, "", centerMainScreen
};
resource 'DITL' (128, "About Box", purgeable) {
{
- {128, 128, 148, 186}, Button {enabled, "Ok"},
- { 14, 108, 117, 310}, StaticText {disabled,
+ {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" "\n"
- "Sun Microsystems Labs" "\n" "ray.johnson@eng.sun.com"},
- { 11, 24, 111, 92}, Picture {enabled, 128}
+ TCL_PATCH_LEVEL " & Tk " TK_PATCH_LEVEL "\n\n"
+ "Ray Johnson & Jim Ingham" "\n"
+ "Sun Microsystems Labs" "\n" "ray.johnson@eng.sun.com"
+ "\n" "jim.ingham@eng.sun.com"},
+ { 19, 24, 119, 92}, Picture {enabled, 128}
}
};
diff --git a/mac/tkMacSend.c b/mac/tkMacSend.c
index 85065ac..dc4e8fd 100644
--- a/mac/tkMacSend.c
+++ b/mac/tkMacSend.c
@@ -6,18 +6,41 @@
* 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-1996 Sun Microsystems, Inc.
+ * Copyright (c) 1994-1998 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tkMacSend.c 1.7 96/12/03 11:48:27
+ * SCCS: @(#) tkMacSend.c 1.9 98/02/18 11:01:26
*/
+#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.
@@ -27,17 +50,12 @@ typedef struct RegisteredInterp {
char *name; /* Interpreter's name (malloc-ed). */
Tcl_Interp *interp; /* Interpreter associated with
* name. */
- TkWindow *winPtr; /* Main window for the application. */
struct RegisteredInterp *nextPtr;
/* Next in list of names associated
* with interps in this process.
* NULL means end of list. */
} RegisteredInterp;
-static RegisteredInterp *registry = NULL;
-/* List of all interpreters
- * registered by this process. */
-
/*
* A registry of all interpreters for a display is kept in a
* property "InterpRegistry" on the root window of the display.
@@ -61,54 +79,19 @@ typedef struct NameRegistry {
* 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. See format
- * above; this is *not* terminated by the
- * first null character. Dynamically
- * allocated. */
+ 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;
- /*
- * When a result is being awaited from a sent command, one of
- * the following structures is present on a list of all outstanding
- * sent commands. The information in the structure is used to
- * process the result when it arrives. You're probably wondering
- * how there could ever be multiple outstanding sent commands.
- * This could happen if interpreters invoke each other recursively.
- * It's unlikely, but possible.
- */
+static initialized = false; /* A flag to denote if we have initialized yet. */
-typedef struct PendingCommand {
- int serial; /* Serial number expected in
- * result. */
- TkDisplay *dispPtr; /* Display being used for communication. */
- char *target; /* Name of interpreter command is
- * being sent to. */
- Window commWindow; /* Target's communication window. */
- Tk_TimerToken timeout; /* Token for timer handler used to check
- * up on target during long sends. */
- Tcl_Interp *interp; /* Interpreter from which the send
- * was invoked. */
- int code; /* Tcl return code for command
- * will be stored here. */
- char *result; /* String result for command (malloc'ed),
- * or NULL. */
- char *errorInfo; /* Information for "errorInfo" variable,
- * or NULL (malloc'ed). */
- char *errorCode; /* Information for "errorCode" variable,
- * or NULL (malloc'ed). */
- int gotResponse; /* 1 means a response has been received,
- * 0 means the command is still outstanding. */
- struct PendingCommand *nextPtr;
- /* Next in list of all outstanding
- * commands. NULL means end of
- * list. */
-} PendingCommand;
-
-static PendingCommand *pendingCommands = NULL;
-/* List of all commands currently
- * being waited for. */
+static RegisteredInterp *interpListPtr = NULL;
+/* List of all interpreters
+ * registered by this process. */
/*
* The information below is used for communication between processes
@@ -206,9 +189,6 @@ int tkSendSerial = 0;
static int AppendErrorProc _ANSI_ARGS_((ClientData clientData,
XErrorEvent *errorPtr));
-static void AppendPropCarefully _ANSI_ARGS_((Display *display,
- Window window, Atom property, char *value,
- int length, PendingCommand *pendingPtr));
static void DeleteProc _ANSI_ARGS_((ClientData clientData));
static void RegAddName _ANSI_ARGS_((NameRegistry *regPtr,
char *name, Window commWindow));
@@ -221,8 +201,7 @@ static NameRegistry * RegOpen _ANSI_ARGS_((Tcl_Interp *interp,
TkWindow *winPtr, int lock));
static void SendEventProc _ANSI_ARGS_((ClientData clientData,
XEvent *eventPtr));
-static int SendInit _ANSI_ARGS_((Tcl_Interp *interp,
- TkWindow *winPtr));
+static int SendInit _ANSI_ARGS_((Tcl_Interp *interp));
static Bool SendRestrictProc _ANSI_ARGS_((Display *display,
XEvent *eventPtr, char *arg));
static int ServerSecure _ANSI_ARGS_((TkDisplay *dispPtr));
@@ -265,13 +244,103 @@ Tk_SetAppName(
* "send" commands. Must be globally
* unique. */
{
- return name;
+ TkWindow *winPtr = (TkWindow *) tkwin;
+ Tcl_Interp *interp = winPtr->mainPtr->interp;
+ int i, suffix, offset, result;
+ int createCommand = 0;
+ RegisteredInterp *riPtr, *prevPtr;
+ 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(actualName + 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_SendCmd --
+ * Tk_SendObjCmd --
*
* This procedure is invoked to process the "send" Tcl command.
* See the user documentation for details on what it does.
@@ -286,15 +355,127 @@ Tk_SetAppName(
*/
int
-Tk_SendCmd(
- ClientData clientData, /* Information about sender (only
- * dispPtr field is used). */
- Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- char **argv) /* Argument strings. */
+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 */
{
- Tcl_SetResult(interp, "Send not yet implemented", TCL_STATIC);
- return TCL_ERROR;
+ static char *sendOptions[] = {"-async", "-displayof", "-", (char *) NULL};
+ char *stringRep, *destName;
+ int async = 0;
+ int i, index, firstArg;
+ RegisteredInterp *riPtr;
+ Tcl_Obj *resultPtr, *listObjPtr;
+ int result;
+
+ 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_EvalObj(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_EvalObj(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!!!
+ */
+ }
+
+done:
+ return result;
}
/*
@@ -324,8 +505,19 @@ TkGetInterpNames(
Tk_Window tkwin) /* Window whose display is to be used
* for the lookup. */
{
- Tcl_SetResult(interp, "Send not yet implemented", TCL_STATIC);
- return TCL_ERROR;
+ 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;
}
/*
@@ -348,11 +540,9 @@ TkGetInterpNames(
static int
SendInit(
- Tcl_Interp *interp, /* Interpreter to use for error reporting
+ Tcl_Interp *interp) /* Interpreter to use for error reporting
* (no errors are ever returned, but the
* interpreter is needed anyway). */
- TkWindow *winPtr) /* Window that identifies the display to
- * initialize. */
{
return TCL_OK;
}
diff --git a/mac/tkMacShLib.exp b/mac/tkMacShLib.exp
index 0c28a4c..04e397a 100644
--- a/mac/tkMacShLib.exp
+++ b/mac/tkMacShLib.exp
@@ -83,9 +83,7 @@ TkGetInterpNames
TkGetMenuHashTable
TkGetMenuIndex
TkGetMiterPoints
-TkGetNativeProlog
TkGetPointerCoords
-TkGetProlog
TkGetServerInfo
TkGetTransientMaster
TkGrabDeadWindow
diff --git a/mac/tkMacSubwindows.c b/mac/tkMacSubwindows.c
index 65c1a7e..562a977 100644
--- a/mac/tkMacSubwindows.c
+++ b/mac/tkMacSubwindows.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tkMacSubwindows.c 1.81 97/10/29 11:46:54
+ * SCCS: @(#) tkMacSubwindows.c 1.84 98/02/19 14:56:28
*/
#include "tkInt.h"
@@ -288,67 +288,76 @@ XResizeWindow(
display->request++;
SetPort((GrafPtr) 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((WindowRef) destPort,
- (short) width, (short) height, false);
- TkMacInvalidateWindow(macWin, TK_WINDOW_ONLY);
- TkMacInvalClipRgns(macWin->winPtr);
- } else {
- /* TODO: update all xOff & yOffs */
- int deltaX, deltaY, parentBorderwidth;
- MacDrawable *macParent = macWin->winPtr->parentPtr->privatePtr;
-
- /*
- * Find the Parent window -
- * For an embedded window this will be its container.
- */
-
- if (Tk_IsEmbedded(macWin->winPtr)) {
+ 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((WindowRef) destPort,
+ (short) width, (short) height, false);
+ TkMacInvalidateWindow(macWin, TK_WINDOW_ONLY);
+ TkMacInvalClipRgns(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) {
- 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 */
+ if (contWinPtr != NULL) {
+ MacDrawable *macParent = contWinPtr->privatePtr;
+
+ TkMacInvalClipRgns(macParent->winPtr);
+ TkMacInvalidateWindow(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.
+ */
+
+ TkMacInvalidateWindow(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 */
}
- TkMacInvalClipRgns(macParent->winPtr);
+ TkMacInvalClipRgns(macParent->winPtr);
TkMacInvalidateWindow(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;
- }
+ 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);
}
}
@@ -744,6 +753,9 @@ TkMacUpdateClipRgn(
TkMacUpdateClipRgn(contWinPtr);
SectRgn(rgn,
contWinPtr->privatePtr->aboveClipRgn, rgn);
+ } else if (gMacEmbedHandler != NULL) {
+ gMacEmbedHandler->getClipProc((Tk_Window) winPtr, tmpRgn);
+ SectRgn(rgn, tmpRgn, rgn);
}
/*
@@ -883,6 +895,7 @@ TkMacGetDrawablePort(
Drawable drawable)
{
MacDrawable *macWin = (MacDrawable *) drawable;
+ GWorldPtr resultPort = NULL;
if (macWin == NULL) {
return NULL;
@@ -917,18 +930,27 @@ TkMacGetDrawablePort(
contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);
if (contWinPtr != NULL) {
- return TkMacGetDrawablePort((Drawable) contWinPtr->privatePtr);
+ resultPort = TkMacGetDrawablePort(
+ (Drawable) contWinPtr->privatePtr);
+ } else if (gMacEmbedHandler != NULL) {
+ resultPort = gMacEmbedHandler->getPortProc(
+ (Tk_Window) macWin->winPtr);
+ if (resultPort == NULL) {
+ panic("Embed Handler couldn't find port");
+ return NULL;
+ }
} else {
- panic("TkMacGetDrawablePort couldn't find container");
- return NULL;
- }
+ panic("TkMacGetDrawablePort couldn't find container");
+ return NULL;
- /*
- * NOTE: Here we should handle out of process embedding.
- */
+ /*
+ * NOTE: Here we should handle out of process embedding.
+ */
+ }
+
}
-
+ return resultPort;
}
/*
diff --git a/mac/tkMacTest.c b/mac/tkMacTest.c
index 46a7bb1..b1b9db0 100644
--- a/mac/tkMacTest.c
+++ b/mac/tkMacTest.c
@@ -9,10 +9,11 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tkMacTest.c 1.2 96/12/15 14:34:00
+ * SCCS: @(#) tkMacTest.c 1.3 97/09/23 16:25:54
*/
#include <Types.h>
+#include <tcl.h>
/*
* Forward declarations of procedures defined later in this file:
diff --git a/mac/tkMacWindowMgr.c b/mac/tkMacWindowMgr.c
index 7c8206c..e04abd6 100644
--- a/mac/tkMacWindowMgr.c
+++ b/mac/tkMacWindowMgr.c
@@ -3,12 +3,12 @@
*
* Implements common window manager functions for the Macintosh.
*
- * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1995-1998 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tkMacWindowMgr.c 1.59 97/11/20 18:56:39
+ * SCCS: @(#) tkMacWindowMgr.c 1.62 98/01/16 10:42:51
*/
#include <Events.h>
@@ -63,13 +63,14 @@ static int GenerateActivateEvents _ANSI_ARGS_((EventRecord *eventPtr,
static int GenerateFocusEvent _ANSI_ARGS_((EventRecord *eventPtr,
Window window));
static int GenerateKeyEvent _ANSI_ARGS_((EventRecord *eventPtr,
- Window window));
+ Window window, UInt32 savedCode));
static int GenerateUpdateEvent _ANSI_ARGS_((EventRecord *eventPtr,
Window window));
static void GenerateUpdates _ANSI_ARGS_((RgnHandle updateRgn,
TkWindow *winPtr));
static int GeneratePollingEvents _ANSI_ARGS_((void));
-static int GeneratePollingEvents2 _ANSI_ARGS_((Window window));
+static int GeneratePollingEvents2 _ANSI_ARGS_((Window window,
+ int adjustCursor));
static OSErr TellWindowDefProcToCalcRegions _ANSI_ARGS_((WindowRef wRef));
static int WindowManagerMouse _ANSI_ARGS_((EventRecord *theEvent,
Window window));
@@ -678,12 +679,18 @@ GenerateFocusEvent(
static int
GenerateKeyEvent(
EventRecord *eventPtr, /* Incoming Mac event */
- Window window) /* Root X window for event. */
+ Window window, /* Root X window for event. */
+ UInt32 savedKeyCode) /* If non-zero, this is a lead byte which
+ * should be combined with the character
+ * in this event to form one multi-byte
+ * character. */
{
Point where;
Tk_Window tkwin;
XEvent event;
-
+ unsigned char byte;
+ char buf[16];
+
/*
* The focus must be in the FrontWindow on the Macintosh.
* We then query Tk to determine the exact Tk window
@@ -695,6 +702,17 @@ GenerateKeyEvent(
if (tkwin == NULL) {
return false;
}
+ byte = (unsigned char) (eventPtr->message & charCodeMask);
+ if ((savedKeyCode == 0) &&
+ (Tcl_ExternalToUtf(NULL, NULL, (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.
+ */
+
+ return false;
+ }
where.v = eventPtr->where.v;
where.h = eventPtr->where.h;
@@ -709,7 +727,10 @@ GenerateKeyEvent(
GlobalToLocal(&where);
Tk_TopCoordsToWindow(tkwin, where.h, where.v,
&event.xkey.x, &event.xkey.y);
- event.xkey.keycode = eventPtr->message;
+
+ event.xkey.keycode = byte |
+ ((savedKeyCode & charCodeMask) << 8) |
+ ((eventPtr->message & keyCodeMask) << 8);
event.xany.serial = Tk_Display(tkwin)->request;
event.xkey.window = Tk_WindowId(tkwin);
@@ -810,7 +831,7 @@ GeneratePollingEvents()
}
Tk_UpdatePointer(tkwin, whereGlobal.h, whereGlobal.v,
TkMacButtonKeyState());
-
+
/*
* Finally, we make sure the proper cursor is installed. The installation
* is polled to 1) make our resize hack work, and 2) make sure we have the
@@ -849,7 +870,8 @@ GeneratePollingEvents()
static int
GeneratePollingEvents2(
- Window window)
+ Window window,
+ int adjustCursor)
{
Tk_Window tkwin, rootwin;
WindowRef whichwindow, frontWin;
@@ -889,6 +911,7 @@ GeneratePollingEvents2(
}
}
+
/*
* The following call will generate the appropiate X events and
* adjust any state that Tk must remember.
@@ -899,15 +922,17 @@ GeneratePollingEvents2(
}
Tk_UpdatePointer(tkwin, whereGlobal.h, whereGlobal.v,
TkMacButtonKeyState());
-
+
/*
* Finally, we make sure the proper cursor is installed. The installation
* is polled to 1) make our resize hack work, and 2) make sure we have the
* proper cursor even if someone else changed the cursor out from under
* us.
*/
- TkMacInstallCursor(0);
-
+
+ if (adjustCursor) {
+ TkMacInstallCursor(0);
+ }
return true;
}
@@ -1105,6 +1130,7 @@ TkMacConvertEvent(
WindowRef whichWindow;
Window window;
int eventFound = false;
+ static UInt32 savedKeyCode;
switch (eventPtr->what) {
case nullEvent:
@@ -1148,11 +1174,28 @@ TkMacConvertEvent(
break;
}
}
+ /* fall through */
+
case keyUp:
whichWindow = FrontWindow();
+ if (whichWindow == NULL) {
+ /*
+ * This happens if we get a key event before Tk has had a
+ * chance to actually create and realize ".", if they type
+ * when "." is withdrawn(!), or between the time "." is
+ * destroyed and the app exits.
+ */
+
+ return false;
+ }
window = TkMacGetXWindow(whichWindow);
- eventFound |= GenerateKeyEvent(eventPtr, window);
+ if (GenerateKeyEvent(eventPtr, window, savedKeyCode) == 0) {
+ savedKeyCode = eventPtr->message;
+ return false;
+ }
+ eventFound = true;
break;
+
case activateEvt:
window = TkMacGetXWindow((WindowRef) eventPtr->message);
eventFound |= GenerateActivateEvents(eventPtr, window);
@@ -1205,6 +1248,7 @@ TkMacConvertEvent(
break;
}
+ savedKeyCode = 0;
return eventFound;
}
@@ -1214,7 +1258,7 @@ TkMacConvertEvent(
* TkMacConvertTkEvent --
*
* This function converts a Macintosh event into zero or more
- * Tcl events.
+ * Tcl events. It is intended for use in Netscape-style embedding.
*
* Results:
* Returns 1 if event added to Tcl queue, 0 otherwse.
@@ -1232,15 +1276,36 @@ TkMacConvertTkEvent(
{
int eventFound = false;
Point where;
+ static UInt32 savedKeyCode;
+
+ /*
+ * By default, assume it is legal for us to set the cursor
+ */
+
+ Tk_MacTkOwnsCursor(1);
switch (eventPtr->what) {
case nullEvent:
+ /*
+ * We get NULL events only when the cursor is NOT over
+ * the plugin. Otherwise we get updateCursor events.
+ * We will not generate polling events or move the cursor
+ * in this case.
+ */
+
+ eventFound = false;
+ break;
case adjustCursorEvent:
- if (GeneratePollingEvents2(window)) {
+ if (GeneratePollingEvents2(window, 1)) {
eventFound = true;
}
break;
case updateEvt:
+ /*
+ * It is possibly not legal for us to set the cursor
+ */
+
+ Tk_MacTkOwnsCursor(0);
if (GenerateUpdateEvent(eventPtr, window)) {
eventFound = true;
}
@@ -1267,10 +1332,24 @@ TkMacConvertTkEvent(
break;
}
}
+ /* fall through. */
+
case keyUp:
- eventFound |= GenerateKeyEvent(eventPtr, window);
+ if (GenerateKeyEvent(eventPtr, window, savedKeyCode) == 0) {
+ savedKeyCode = eventPtr->message;
+ return false;
+ }
+ eventFound = true;
break;
+
case activateEvt:
+ /*
+ * It is probably not legal for us to set the cursor
+ * here, since we don't know where the mouse is in the
+ * window that is being activated.
+ */
+
+ Tk_MacTkOwnsCursor(0);
eventFound |= GenerateActivateEvents(eventPtr, window);
eventFound |= GenerateFocusEvent(eventPtr, window);
break;
@@ -1291,10 +1370,18 @@ TkMacConvertTkEvent(
* Do clipboard conversion.
*/
switch ((eventPtr->message & osEvtMessageMask) >> 24) {
+ /*
+ * It is possibly not legal for us to set the cursor.
+ * Netscape sends us these events all the time...
+ */
+
+ Tk_MacTkOwnsCursor(0);
+
case mouseMovedMessage:
- if (GeneratePollingEvents2(window)) {
+ /* if (GeneratePollingEvents2(window, 0)) {
eventFound = true;
- }
+ } NEXT LINE IS TEMPORARY */
+ eventFound = false;
break;
case suspendResumeMessage:
if (!(eventPtr->message & resumeFlag)) {
@@ -1318,7 +1405,7 @@ TkMacConvertTkEvent(
}
break;
}
-
+ savedKeyCode = 0;
return eventFound;
}
@@ -1516,7 +1603,6 @@ TellWindowDefProcToCalcRegions(
* Assuming there are no errors we now call the window definition
* procedure to tell it to calculate the regions for the window.
*/
-
if (err == noErr) {
(void) CallWindowDefProc((UniversalProcPtr) *wdef,
GetWVariant(wRef), wRef, wCalcRgns, 0);
diff --git a/mac/tkMacWm.c b/mac/tkMacWm.c
index 56c4b8a..4cd7920 100644
--- a/mac/tkMacWm.c
+++ b/mac/tkMacWm.c
@@ -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.
*
- * SCCS: @(#) tkMacWm.c 1.72 97/10/29 13:27:30
+ * SCCS: @(#) tkMacWm.c 1.77 98/02/18 11:03:54
*/
#include <Gestalt.h>
@@ -19,6 +19,7 @@
#include <Windows.h>
#include <ToolUtils.h>
+#include <tclMac.h>
#include "tkPort.h"
#include "tkInt.h"
#include "tkMacInt.h"
@@ -26,14 +27,12 @@
#include "tkScrollbar.h"
/*
- * If HAVE_APPEARANCE is defined in MW_TkHeader.pch then we must have the
- * Appearance manager header & library. If so we can use these new API's to
- * have the iconify code do the right thing.
+ * We now require the Appearance headers. They come with CodeWarrior Pro,
+ * and are on the SDK CD. However, we do not require the Appearance
+ * extension
*/
-
-#ifdef HAVE_APPEARANCE
-# include <Appearance.h>
-#endif
+
+#include <Appearance.h>
/*
* A data structure of the following type holds information for
@@ -313,7 +312,6 @@ void MacMoveWindow(WindowRef window, int x, int y);
* Forward declarations for procedures defined in this file:
*/
-static int HaveAppearance _ANSI_ARGS_((void));
static void InitialWindowBounds _ANSI_ARGS_((TkWindow *winPtr,
Rect *geometry));
static int ParseGeometry _ANSI_ARGS_((Tcl_Interp *interp,
@@ -532,7 +530,7 @@ TkWmMapWindow(
*/
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
@@ -711,7 +709,7 @@ Tk_WmCmd(
return TCL_ERROR;
}
if (argc == 2) {
- interp->result = (wmTracing) ? "on" : "off";
+ Tcl_SetResult(interp, ((wmTracing) ? "on" : "off"), TCL_STATIC);
return TCL_OK;
}
return Tcl_GetBoolean(interp, argv[2], &wmTracing);
@@ -741,9 +739,12 @@ Tk_WmCmd(
}
if (argc == 3) {
if (wmPtr->sizeHintsFlags & PAspect) {
- sprintf(interp->result, "%d %d %d %d", wmPtr->minAspect.x,
+ 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;
}
@@ -758,7 +759,8 @@ Tk_WmCmd(
}
if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
(denom2 <= 0)) {
- interp->result = "aspect number can't be <= 0";
+ Tcl_SetResult(interp, "aspect number can't be <= 0",
+ TCL_STATIC);
return TCL_ERROR;
}
wmPtr->minAspect.x = numer1;
@@ -779,7 +781,7 @@ Tk_WmCmd(
}
if (argc == 3) {
if (wmPtr->clientMachine != NULL) {
- interp->result = wmPtr->clientMachine;
+ Tcl_SetResult(interp, wmPtr->clientMachine, TCL_STATIC);
}
return TCL_OK;
}
@@ -877,8 +879,9 @@ Tk_WmCmd(
}
if (argc == 3) {
if (wmPtr->cmdArgv != NULL) {
- interp->result = Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv);
- interp->freeProc = (Tcl_FreeProc *) free;
+ Tcl_SetResult(interp,
+ Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv),
+ TCL_DYNAMIC);
}
return TCL_OK;
}
@@ -928,7 +931,8 @@ Tk_WmCmd(
return TCL_ERROR;
}
if (argc == 3) {
- interp->result = wmPtr->hints.input ? "passive" : "active";
+ Tcl_SetResult(interp, (wmPtr->hints.input ? "passive" : "active"),
+ TCL_STATIC);
return TCL_OK;
}
c = argv[3][0];
@@ -945,6 +949,7 @@ Tk_WmCmd(
} else if ((c == 'f') && (strncmp(argv[1], "frame", length) == 0)
&& (length >= 2)) {
Window window;
+ char buf[TCL_INTEGER_SPACE];
if (argc != 3) {
Tcl_AppendResult(interp, "wrong # arguments: must be \"",
@@ -955,7 +960,8 @@ Tk_WmCmd(
if (window == None) {
window = Tk_WindowId((Tk_Window) winPtr);
}
- sprintf(interp->result, "0x%x", (unsigned int) window);
+ sprintf(buf, "0x%x", (unsigned int) window);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
} else if ((c == 'g') && (strncmp(argv[1], "geometry", length) == 0)
&& (length >= 2)) {
char xSign, ySign;
@@ -968,6 +974,8 @@ Tk_WmCmd(
return TCL_ERROR;
}
if (argc == 3) {
+ char buf[16 + TCL_INTEGER_SPACE * 4];
+
xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+';
ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+';
if (wmPtr->gridWin != NULL) {
@@ -979,8 +987,9 @@ Tk_WmCmd(
width = winPtr->changes.width;
height = winPtr->changes.height;
}
- sprintf(interp->result, "%dx%d%c%d%c%d", width, height,
- xSign, wmPtr->x, ySign, wmPtr->y);
+ 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;
}
if (*argv[3] == '\0') {
@@ -1001,9 +1010,12 @@ Tk_WmCmd(
}
if (argc == 3) {
if (wmPtr->sizeHintsFlags & PBaseSize) {
- sprintf(interp->result, "%d %d %d %d", wmPtr->reqGridWidth,
+ 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;
}
@@ -1030,19 +1042,19 @@ Tk_WmCmd(
return TCL_ERROR;
}
if (reqWidth < 0) {
- interp->result = "baseWidth can't be < 0";
+ Tcl_SetResult(interp, "baseWidth can't be < 0", TCL_STATIC);
return TCL_ERROR;
}
if (reqHeight < 0) {
- interp->result = "baseHeight can't be < 0";
+ Tcl_SetResult(interp, "baseHeight can't be < 0", TCL_STATIC);
return TCL_ERROR;
}
if (widthInc < 0) {
- interp->result = "widthInc can't be < 0";
+ Tcl_SetResult(interp, "widthInc can't be < 0", TCL_STATIC);
return TCL_ERROR;
}
if (heightInc < 0) {
- interp->result = "heightInc can't be < 0";
+ Tcl_SetResult(interp, "heightInc can't be < 0", TCL_STATIC);
return TCL_ERROR;
}
Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
@@ -1062,7 +1074,7 @@ Tk_WmCmd(
}
if (argc == 3) {
if (wmPtr->hints.flags & WindowGroupHint) {
- interp->result = wmPtr->leaderName;
+ Tcl_SetResult(interp, wmPtr->leaderName, TCL_STATIC);
}
return TCL_OK;
}
@@ -1095,8 +1107,9 @@ Tk_WmCmd(
}
if (argc == 3) {
if (wmPtr->hints.flags & IconPixmapHint) {
- interp->result = Tk_NameOfBitmap(winPtr->display,
- wmPtr->hints.icon_pixmap);
+ Tcl_SetResult(interp,
+ Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_pixmap),
+ TCL_STATIC);
}
return TCL_OK;
}
@@ -1155,8 +1168,9 @@ Tk_WmCmd(
}
if (argc == 3) {
if (wmPtr->hints.flags & IconMaskHint) {
- interp->result = Tk_NameOfBitmap(winPtr->display,
- wmPtr->hints.icon_mask);
+ Tcl_SetResult(interp,
+ Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask),
+ TCL_STATIC);
}
return TCL_OK;
}
@@ -1181,7 +1195,9 @@ Tk_WmCmd(
return TCL_ERROR;
}
if (argc == 3) {
- interp->result = (wmPtr->iconName != NULL) ? wmPtr->iconName : "";
+ Tcl_SetResult(interp,
+ ((wmPtr->iconName != NULL) ? wmPtr->iconName : ""),
+ TCL_STATIC);
return TCL_OK;
} else {
wmPtr->iconName = Tk_GetUid(argv[3]);
@@ -1201,8 +1217,11 @@ Tk_WmCmd(
}
if (argc == 3) {
if (wmPtr->hints.flags & IconPositionHint) {
- sprintf(interp->result, "%d %d", wmPtr->hints.icon_x,
+ 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;
}
@@ -1230,7 +1249,7 @@ Tk_WmCmd(
}
if (argc == 3) {
if (wmPtr->icon != NULL) {
- interp->result = Tk_PathName(wmPtr->icon);
+ Tcl_SetResult(interp, Tk_PathName(wmPtr->icon), TCL_STATIC);
}
return TCL_OK;
}
@@ -1284,8 +1303,10 @@ Tk_WmCmd(
return TCL_ERROR;
}
if (argc == 3) {
- sprintf(interp->result, "%d %d", wmPtr->maxWidth,
- wmPtr->maxHeight);
+ 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_GetInt(interp, argv[3], &width) != TCL_OK)
@@ -1305,8 +1326,10 @@ Tk_WmCmd(
return TCL_ERROR;
}
if (argc == 3) {
- sprintf(interp->result, "%d %d", wmPtr->minWidth,
- wmPtr->minHeight);
+ 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_GetInt(interp, argv[3], &width) != TCL_OK)
@@ -1330,9 +1353,9 @@ Tk_WmCmd(
}
if (argc == 3) {
if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
- interp->result = "1";
+ Tcl_SetResult(interp, "1", TCL_STATIC);
} else {
- interp->result = "0";
+ Tcl_SetResult(interp, "0", TCL_STATIC);
}
return TCL_OK;
}
@@ -1353,9 +1376,9 @@ Tk_WmCmd(
}
if (argc == 3) {
if (wmPtr->sizeHintsFlags & USPosition) {
- interp->result = "user";
+ Tcl_SetResult(interp, "user", TCL_STATIC);
} else if (wmPtr->sizeHintsFlags & PPosition) {
- interp->result = "program";
+ Tcl_SetResult(interp, "program", TCL_STATIC);
}
return TCL_OK;
}
@@ -1410,7 +1433,7 @@ Tk_WmCmd(
for (protPtr = wmPtr->protPtr; protPtr != NULL;
protPtr = protPtr->nextPtr) {
if (protPtr->protocol == protocol) {
- interp->result = protPtr->command;
+ Tcl_SetResult(interp, protPtr->command, TCL_STATIC);
return TCL_OK;
}
}
@@ -1454,9 +1477,12 @@ Tk_WmCmd(
return TCL_ERROR;
}
if (argc == 3) {
- sprintf(interp->result, "%d %d",
+ 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_GetBoolean(interp, argv[3], &width) != TCL_OK)
@@ -1489,9 +1515,9 @@ Tk_WmCmd(
}
if (argc == 3) {
if (wmPtr->sizeHintsFlags & USSize) {
- interp->result = "user";
+ Tcl_SetResult(interp, "user", TCL_STATIC);
} else if (wmPtr->sizeHintsFlags & PSize) {
- interp->result = "program";
+ Tcl_SetResult(interp, "program", TCL_STATIC);
}
return TCL_OK;
}
@@ -1523,20 +1549,20 @@ Tk_WmCmd(
return TCL_ERROR;
}
if (wmPtr->iconFor != NULL) {
- interp->result = "icon";
+ Tcl_SetResult(interp, "icon", TCL_STATIC);
} else {
switch (wmPtr->hints.initial_state) {
case NormalState:
- interp->result = "normal";
+ Tcl_SetResult(interp, "normal", TCL_STATIC);
break;
case IconicState:
- interp->result = "iconic";
+ Tcl_SetResult(interp, "iconic", TCL_STATIC);
break;
case WithdrawnState:
- interp->result = "withdrawn";
+ Tcl_SetResult(interp, "withdrawn", TCL_STATIC);
break;
case ZoomState:
- interp->result = "zoomed";
+ Tcl_SetResult(interp, "zoomed", TCL_STATIC);
break;
}
}
@@ -1548,8 +1574,9 @@ Tk_WmCmd(
return TCL_ERROR;
}
if (argc == 3) {
- interp->result = (wmPtr->titleUid != NULL) ? wmPtr->titleUid
- : winPtr->nameUid;
+ Tcl_SetResult(interp,
+ ((wmPtr->titleUid != NULL) ? wmPtr->titleUid : winPtr->nameUid),
+ TCL_STATIC);
return TCL_OK;
} else {
wmPtr->titleUid = Tk_GetUid(argv[3]);
@@ -1568,7 +1595,7 @@ Tk_WmCmd(
}
if (argc == 3) {
if (wmPtr->master != None) {
- interp->result = wmPtr->masterWindowName;
+ Tcl_SetResult(interp, wmPtr->masterWindowName, TCL_STATIC);
}
return TCL_OK;
}
@@ -2148,7 +2175,7 @@ UpdateSizeHints(
*
* Results:
* A standard Tcl return value, plus an error message in
- * interp->result if an error occurs.
+ * the interp's result if an error occurs.
*
* Side effects:
* The size and/or location of winPtr may change.
@@ -2333,12 +2360,26 @@ Tk_GetRootCoords(
y += winPtr->changes.y + winPtr->changes.border_width;
} else {
+ Point theOffset;
- /*
- * NOTE: Here we should handle
- * out of process embedding.
- */
-
+ 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;
}
}
@@ -3318,15 +3359,19 @@ TkSetWMName(
{
Str255 pTitle;
GWorldPtr macWin;
+ int destWrote;
if (Tk_IsEmbedded(winPtr)) {
return;
}
+ Tcl_UtfToExternal(NULL, NULL, titleUid,
+ strlen(titleUid), 0, NULL,
+ (char *) &pTitle[1],
+ 255, NULL, &destWrote, NULL); /* Internalize native */
+ pTitle[0] = destWrote;
- macWin = TkMacGetDrawablePort(winPtr->window);
-
- strcpy((char *) pTitle + 1, titleUid);
- pTitle[0] = strlen(titleUid);
+ macWin = TkMacGetDrawablePort(winPtr->window);
+
SetWTitle((WindowPtr) macWin, pTitle);
}
@@ -3685,42 +3730,42 @@ TkUnsupported1Cmd(
switch (wmPtr->style) {
case noGrowDocProc:
case documentProc:
- interp->result = "documentProc";
+ Tcl_SetResult(interp, "documentProc", TCL_STATIC);
break;
case dBoxProc:
- interp->result = "dBoxProc";
+ Tcl_SetResult(interp, "dBoxProc", TCL_STATIC);
break;
case plainDBox:
- interp->result = "plainDBox";
+ Tcl_SetResult(interp, "plainDBox", TCL_STATIC);
break;
case altDBoxProc:
- interp->result = "altDBoxProc";
+ Tcl_SetResult(interp, "altDBoxProc", TCL_STATIC);
break;
case movableDBoxProc:
- interp->result = "movableDBoxProc";
+ Tcl_SetResult(interp, "movableDBoxProc", TCL_STATIC);
break;
case zoomDocProc:
case zoomNoGrow:
- interp->result = "zoomDocProc";
+ Tcl_SetResult(interp, "zoomDocProc", TCL_STATIC);
break;
case rDocProc:
- interp->result = "rDocProc";
+ Tcl_SetResult(interp, "rDocProc", TCL_STATIC);
break;
case floatProc:
case floatGrowProc:
- interp->result = "floatProc";
+ Tcl_SetResult(interp, "floatProc", TCL_STATIC);
break;
case floatZoomProc:
case floatZoomGrowProc:
- interp->result = "floatZoomProc";
+ Tcl_SetResult(interp, "floatZoomProc", TCL_STATIC);
break;
case floatSideProc:
case floatSideGrowProc:
- interp->result = "floatSideProc";
+ Tcl_SetResult(interp, "floatSideProc", TCL_STATIC);
break;
case floatSideZoomProc:
case floatSideZoomGrowProc:
- interp->result = "floatSideZoomProc";
+ Tcl_SetResult(interp, "floatSideZoomProc", TCL_STATIC);
break;
default:
panic("invalid style");
@@ -3861,6 +3906,13 @@ TkMacMakeRealWindowExist(
TkMacMakeRealWindowExist(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("TkMacMakeRealWindowExist could not find container");
}
@@ -4148,8 +4200,7 @@ TkpWmSetState(winPtr, state)
Tk_UnmapWindow((Tk_Window) winPtr);
} else if (state == IconicState) {
Tk_UnmapWindow((Tk_Window) winPtr);
-#ifdef HAVE_APPEARANCE
- if (HaveAppearance()) {
+ if (TkMacHaveAppearance()) {
/*
* The window always gets unmapped. However, if we can show the
* icon version of the window (collapsed) we make the window visable
@@ -4163,14 +4214,11 @@ TkpWmSetState(winPtr, state)
CollapseWindow((WindowPtr) macWin, true);
}
}
-#endif
} else if (state == NormalState) {
Tk_MapWindow((Tk_Window) winPtr);
-#ifdef HAVE_APPEARANCE
- if (HaveAppearance()) {
+ if (TkMacHaveAppearance()) {
CollapseWindow((WindowPtr) macWin, false);
}
-#endif
} else if (state == ZoomState) {
/* TODO: need to support zoomed windows */
}
@@ -4178,7 +4226,7 @@ TkpWmSetState(winPtr, state)
/*
*----------------------------------------------------------------------
*
- * HaveAppearance --
+ * TkMacHaveAppearance --
*
* Determine if the appearance manager is available on this Mac.
* We cache the result so future calls are fast.
@@ -4192,22 +4240,20 @@ TkpWmSetState(winPtr, state)
*----------------------------------------------------------------------
*/
-static int
-HaveAppearance()
+int
+TkMacHaveAppearance()
{
static initialized = false;
- static int haveAppearance = false;
+ static int TkMacHaveAppearance = false;
long response = 0;
OSErr err = noErr;
-#ifdef HAVE_APPEARANCE
if (!initialized) {
err = Gestalt(gestaltAppearanceAttr, &response);
if (err == noErr) {
- haveAppearance = true;
+ TkMacHaveAppearance = true;
}
}
-#endif
- return haveAppearance;
+ return TkMacHaveAppearance;
}
diff --git a/mac/tkMacXStubs.c b/mac/tkMacXStubs.c
index f1042c2..4f52e41 100644
--- a/mac/tkMacXStubs.c
+++ b/mac/tkMacXStubs.c
@@ -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.
*
- * SCCS: @(#) tkMacXStubs.c 1.87 97/11/20 18:35:29
+ * SCCS: @(#) tkMacXStubs.c 1.89 97/11/26 13:10:52
*/
#include "tkInt.h"
@@ -46,7 +46,7 @@
*/
static TkDisplay *gMacDisplay = NULL; /* Macintosh display. */
-static char *macScreenName = "Macintosh:0";
+static char *macScreenName = ":0";
/* Default name of macintosh display. */
/*
@@ -541,7 +541,8 @@ TkGetServerInfo(
Tk_Window tkwin) /* Token for window; this selects a
* particular display and server. */
{
- char buffer[50], buffer2[50];
+ 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)));