summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Walzer <kw@codebykevin.com>2015-11-25 03:13:02 (GMT)
committerKevin Walzer <kw@codebykevin.com>2015-11-25 03:13:02 (GMT)
commitf56728f92c68f0ebbc445ee1e3daeda392780922 (patch)
tree488f2e6ce16f942a290281b14b92dc3705430ff7
parent6a1c77254b102ec6c7f6e28355e92dc0a7bad771 (diff)
downloadtk-f56728f92c68f0ebbc445ee1e3daeda392780922.zip
tk-f56728f92c68f0ebbc445ee1e3daeda392780922.tar.gz
tk-f56728f92c68f0ebbc445ee1e3daeda392780922.tar.bz2
Remove multiple deprecated internal API calls on OS X; streamline Apple Events implementation; thanks to Marc Culler for extensive patches
-rw-r--r--generic/tkText.h2
-rw-r--r--macosx/tkMacOSXDialog.c179
-rw-r--r--macosx/tkMacOSXDraw.c2
-rw-r--r--macosx/tkMacOSXFont.c18
-rw-r--r--macosx/tkMacOSXHLEvents.c747
-rw-r--r--macosx/tkMacOSXMenu.c2
-rw-r--r--macosx/tkMacOSXMouseEvent.c116
-rw-r--r--macosx/tkMacOSXPrivate.h27
-rw-r--r--macosx/tkMacOSXWindowEvent.c13
-rw-r--r--macosx/tkMacOSXWm.c42
-rw-r--r--macosx/tkMacOSXXStubs.c16
11 files changed, 566 insertions, 598 deletions
diff --git a/generic/tkText.h b/generic/tkText.h
index 99a4888..78a99a9 100644
--- a/generic/tkText.h
+++ b/generic/tkText.h
@@ -168,7 +168,7 @@ typedef struct TkTextSegment {
int size; /* Size of this segment (# of bytes of index
* space it occupies). */
union {
- char chars[1]; /* Characters that make up character info.
+ char chars[2]; /* Characters that make up character info.
* Actual length varies to hold as many
* characters as needed.*/
TkTextToggle toggle; /* Information about tag toggle. */
diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c
index 4b19260..ca17195 100644
--- a/macosx/tkMacOSXDialog.c
+++ b/macosx/tkMacOSXDialog.c
@@ -14,6 +14,17 @@
#include "tkMacOSXPrivate.h"
#include "tkFileFilter.h"
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
+#define modalOK NSOKButton
+#define modalCancel NSCancelButton
+#else
+#define modalOK NSModalResponseOK
+#define modalCancel NSModalResponseCancel
+#endif
+#define modalOther -1
+#define modalError -2
+
+
static const char *const colorOptionStrings[] = {
"-initialcolor", "-parent", "-title", NULL
};
@@ -130,6 +141,23 @@ static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
[TYPE_YESNO] = {5, 6, 0},
[TYPE_YESNOCANCEL] = {5, 6, 4},
};
+
+/*
+ * Construct a file URL from directory and filename. Either may
+ * be nil. If both are nil, returns nil.
+ */
+#if MAC_OS_X_VERSION_MIN_REQUIRED > 1050
+static NSURL *getFileURL(NSString *directory, NSString *filename) {
+ NSURL *url = nil;
+ if (directory) {
+ url = [NSURL fileURLWithPath:directory];
+ }
+ if (filename) {
+ url = [NSURL URLWithString:filename relativeToURL:url];
+ }
+ return url;
+}
+#endif
#pragma mark TKApplication(TKDialog)
@@ -149,12 +177,12 @@ static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
if (callbackInfo->multiple) {
resultObj = Tcl_NewListObj(0, NULL);
- for (NSString *name in [(NSOpenPanel*)panel filenames]) {
+ for (NSURL *url in [(NSOpenPanel*)panel URLs]) {
Tcl_ListObjAppendElement(callbackInfo->interp, resultObj,
- Tcl_NewStringObj([name UTF8String], -1));
+ Tcl_NewStringObj([[url path] UTF8String], -1));
}
} else {
- resultObj = Tcl_NewStringObj([[panel filename] UTF8String], -1);
+ resultObj = Tcl_NewStringObj([[[panel URL]path] UTF8String], -1);
}
if (callbackInfo->cmdObj) {
Tcl_Obj **objv, **tmpv;
@@ -189,7 +217,7 @@ static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
{
AlertCallbackInfo *callbackInfo = contextInfo;
- if (returnCode != NSAlertErrorReturn) {
+ if (returnCode >= NSAlertFirstButtonReturn) {
Tcl_Obj *resultObj = Tcl_NewStringObj(alertButtonStrings[
alertNativeButtonIndexAndTypeToButtonIndex[callbackInfo->
typeIndex][returnCode - NSAlertFirstButtonReturn]], -1);
@@ -309,7 +337,7 @@ Tk_ChooseColorObjCmd(
[colorPanel setColor:initialColor];
}
returnCode = [NSApp runModalForWindow:colorPanel];
- if (returnCode == NSOKButton) {
+ if (returnCode == modalOK) {
color = [[colorPanel color] colorUsingColorSpace:
[NSColorSpace genericRGBColorSpace]];
numberOfComponents = [color numberOfComponents];
@@ -369,7 +397,7 @@ Tk_GetOpenFileObjCmd(
NSWindow *parent;
NSMutableArray *fileTypes = nil;
NSOpenPanel *panel = [NSOpenPanel openPanel];
- NSInteger returnCode = NSAlertErrorReturn;
+ NSInteger modalReturnCode = modalError;
TkInitFileFilters(&fl);
for (i = 1; i < objc; i += 2) {
@@ -439,6 +467,7 @@ Tk_GetOpenFileObjCmd(
break;
}
}
+ [panel setAllowsMultipleSelection:multiple];
if (fl.filters) {
fileTypes = [NSMutableArray array];
for (FileFilter *filterPtr = fl.filters; filterPtr;
@@ -471,7 +500,7 @@ Tk_GetOpenFileObjCmd(
}
}
}
- [panel setAllowsMultipleSelection:multiple];
+ [panel setAllowedFileTypes:fileTypes];
if (cmdObj) {
callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo));
if (Tcl_IsShared(cmdObj)) {
@@ -484,19 +513,37 @@ Tk_GetOpenFileObjCmd(
callbackInfo->multiple = multiple;
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
if (haveParentOption && parent && ![parent attachedSheet]) {
- [panel beginSheetForDirectory:directory file:filename types:fileTypes
- modalForWindow:parent modalDelegate:NSApp didEndSelector:
- @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
- contextInfo:callbackInfo];
- returnCode = cmdObj ? NSAlertOtherReturn :
- [NSApp runModalForWindow:panel];
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ [panel beginSheetForDirectory:directory
+ file:filename
+ types:fileTypes
+ modalForWindow:parent
+ modalDelegate:NSApp
+ didEndSelector:
+ @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
+ contextInfo:callbackInfo];
+#else
+ [panel setAllowedFileTypes:fileTypes];
+ [panel setDirectoryURL:getFileURL(directory, filename)];
+ [panel beginSheetModalForWindow:parent
+ completionHandler:^(NSInteger returnCode)
+ { [NSApp tkFilePanelDidEnd:panel
+ returnCode:returnCode
+ contextInfo:callbackInfo ]; } ];
+#endif
+ modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
} else {
- returnCode = [panel runModalForDirectory:directory file:filename
- types:fileTypes];
- [NSApp tkFilePanelDidEnd:panel returnCode:returnCode
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ modalReturnCode = [panel runModalForDirectory:directory
+ file:filename];
+#else
+ [panel setDirectoryURL:getFileURL(directory, filename)];
+ modalReturnCode = [panel runModal];
+#endif
+ [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
contextInfo:callbackInfo];
}
- result = (returnCode != NSAlertErrorReturn) ? TCL_OK : TCL_ERROR;
+ result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
if (typeVariablePtr && result == TCL_OK) {
/*
* The -typevariable option is not really supported.
@@ -548,7 +595,7 @@ Tk_GetSaveFileObjCmd(
NSWindow *parent;
NSMutableArray *fileTypes = nil;
NSSavePanel *panel = [NSSavePanel savePanel];
- NSInteger returnCode = NSAlertErrorReturn;
+ NSInteger modalReturnCode = modalError;
TkInitFileFilters(&fl);
for (i = 1; i < objc; i += 2) {
@@ -665,18 +712,34 @@ Tk_GetSaveFileObjCmd(
callbackInfo->multiple = 0;
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
if (haveParentOption && parent && ![parent attachedSheet]) {
- [panel beginSheetForDirectory:directory file:filename
- modalForWindow:parent modalDelegate:NSApp didEndSelector:
- @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
- contextInfo:callbackInfo];
- returnCode = cmdObj ? NSAlertOtherReturn :
- [NSApp runModalForWindow:panel];
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ [panel beginSheetForDirectory:directory
+ file:filename
+ modalForWindow:parent
+ modalDelegate:NSApp
+ didEndSelector:
+ @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
+ contextInfo:callbackInfo];
+#else
+ [panel setDirectoryURL:getFileURL(directory, filename)];
+ [panel beginSheetModalForWindow:parent
+ completionHandler:^(NSInteger returnCode)
+ { [NSApp tkFilePanelDidEnd:panel
+ returnCode:returnCode
+ contextInfo:callbackInfo ]; } ];
+#endif
+ modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
} else {
- returnCode = [panel runModalForDirectory:directory file:filename];
- [NSApp tkFilePanelDidEnd:panel returnCode:returnCode
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ modalReturnCode = [panel runModalForDirectory:directory file:filename];
+#else
+ [panel setDirectoryURL:getFileURL(directory, filename)];
+ modalReturnCode = [panel runModal];
+#endif
+ [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
contextInfo:callbackInfo];
}
- result = (returnCode != NSAlertErrorReturn) ? TCL_OK : TCL_ERROR;
+ result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
end:
TkFreeFileFilters(&fl);
@@ -719,7 +782,7 @@ Tk_ChooseDirectoryObjCmd(
NSString *message, *title;
NSWindow *parent;
NSOpenPanel *panel = [NSOpenPanel openPanel];
- NSInteger returnCode = NSAlertErrorReturn;
+ NSInteger modalReturnCode = modalError;
for (i = 1; i < objc; i += 2) {
if (Tcl_GetIndexFromObjStruct(interp, objv[i], chooseOptionStrings,
@@ -787,18 +850,33 @@ Tk_ChooseDirectoryObjCmd(
callbackInfo->multiple = 0;
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
if (haveParentOption && parent && ![parent attachedSheet]) {
- [panel beginSheetForDirectory:directory file:filename
- modalForWindow:parent modalDelegate:NSApp didEndSelector:
- @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ [panel beginSheetForDirectory:directory
+ file:filename
+ modalForWindow:parent
+ modalDelegate:NSApp
+ didEndSelector: @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
contextInfo:callbackInfo];
- returnCode = cmdObj ? NSAlertOtherReturn :
- [NSApp runModalForWindow:panel];
+#else
+ [panel setDirectoryURL:getFileURL(directory, filename)];
+ [panel beginSheetModalForWindow:parent
+ completionHandler:^(NSInteger returnCode)
+ { [NSApp tkFilePanelDidEnd:panel
+ returnCode:returnCode
+ contextInfo:callbackInfo ]; } ];
+#endif
+ modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
} else {
- returnCode = [panel runModalForDirectory:directory file:filename];
- [NSApp tkFilePanelDidEnd:panel returnCode:returnCode
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ modalReturnCode = [panel runModalForDirectory:directory file:nil];
+#else
+ [panel setDirectoryURL:getFileURL(directory, filename)];
+ modalReturnCode = [panel runModal];
+#endif
+ [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
contextInfo:callbackInfo];
}
- result = (returnCode != NSAlertErrorReturn) ? TCL_OK : TCL_ERROR;
+ result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
end:
return result;
@@ -899,7 +977,7 @@ TkMacOSXStandardAboutPanelObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return TCL_ERROR;
}
- [NSApp orderFrontStandardAboutPanelWithOptions:nil];
+ [NSApp orderFrontStandardAboutPanelWithOptions:[NSDictionary dictionary]];
return TCL_OK;
}
@@ -937,7 +1015,7 @@ Tk_MessageBoxObjCmd(
NSWindow *parent;
NSArray *buttons;
NSAlert *alert = [NSAlert new];
- NSInteger returnCode = NSAlertErrorReturn;
+ NSInteger modalReturnCode = 1;
iconIndex = ICON_INFO;
typeIndex = TYPE_OK;
@@ -1064,17 +1142,26 @@ Tk_MessageBoxObjCmd(
callbackInfo->typeIndex = typeIndex;
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
if (haveParentOption && parent && ![parent attachedSheet]) {
- [alert beginSheetModalForWindow:parent modalDelegate:NSApp
- didEndSelector:@selector(tkAlertDidEnd:returnCode:contextInfo:)
- contextInfo:callbackInfo];
- returnCode = cmdObj ? NSAlertOtherReturn :
- [NSApp runModalForWindow:[alert window]];
+#if MAC_OS_X_VERSION_MIN_REQUIRED > 1090
+ [alert beginSheetModalForWindow:parent
+ completionHandler:^(NSModalResponse returnCode)
+ { [NSApp tkAlertDidEnd:alert
+ returnCode:returnCode
+ contextInfo:callbackInfo ]; } ];
+#else
+ [alert beginSheetModalForWindow:parent
+ modalDelegate:NSApp
+ didEndSelector:@selector(tkAlertDidEnd:returnCode:contextInfo:)
+ contextInfo:callbackInfo];
+#endif
+ modalReturnCode = cmdObj ? 0 :
+ [NSApp runModalForWindow:[alert window]];
} else {
- returnCode = [alert runModal];
- [NSApp tkAlertDidEnd:alert returnCode:returnCode
+ modalReturnCode = [alert runModal];
+ [NSApp tkAlertDidEnd:alert returnCode:modalReturnCode
contextInfo:callbackInfo];
}
- result = (returnCode != NSAlertErrorReturn) ? TCL_OK : TCL_ERROR;
+ result = (modalReturnCode < 1) ? TCL_OK : TCL_ERROR;
end:
[alert release];
return result;
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index 4728fea..ed8c428 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -675,7 +675,7 @@ GetCGContextForDrawable(
if (macDraw->flags & TK_IS_BW_PIXMAP) {
bitsPerPixel = 8;
- bitmapInfo = kCGImageAlphaOnly;
+ bitmapInfo = (CGBitmapInfo)kCGImageAlphaOnly;
} else {
colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
bitsPerPixel = 32;
diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c
index 45a68f7..54b0fb8 100644
--- a/macosx/tkMacOSXFont.c
+++ b/macosx/tkMacOSXFont.c
@@ -15,6 +15,19 @@
#include "tkMacOSXPrivate.h"
#include "tkMacOSXFont.h"
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
+#define defaultOrientation kCTFontDefaultOrientation
+#define verticalOrientation kCTFontVerticalOrientation
+#else
+#define defaultOrientation kCTFontOrientationDefault
+#define verticalOrientation kCTFontOrientationVertical
+#endif
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100
+#define fixedPitch kCTFontUserFixedPitchFontType
+#else
+#define fixedPitch kCTFontUIFontUserFixedPitch
+#endif
+
/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_FONTS
@@ -270,7 +283,7 @@ InitFont(
fmPtr->fixed = [nsFont advancementForGlyph:glyphs[0]].width ==
[nsFont advancementForGlyph:glyphs[1]].width;
bounds = NSRectFromCGRect(CTFontGetBoundingRectsForGlyphs((CTFontRef)
- nsFont, kCTFontDefaultOrientation, ch, boundingRects, nCh));
+ nsFont, defaultOrientation, ch, boundingRects, nCh));
kern = [nsFont advancementForGlyph:glyphs[2]].width -
[fontPtr->nsFont advancementForGlyph:glyphs[2]].width;
}
@@ -382,8 +395,7 @@ TkpFontPkgInit(
systemFont++;
}
TkInitFontAttributes(&fa);
- nsFont = (NSFont*) CTFontCreateUIFontForLanguage(
- kCTFontUserFixedPitchFontType, 11, NULL);
+ nsFont = (NSFont*) CTFontCreateUIFontForLanguage(fixedPitch, 11, NULL);
if (nsFont) {
GetTkFontAttributesForNSFont(nsFont, &fa);
CFRelease(nsFont);
diff --git a/macosx/tkMacOSXHLEvents.c b/macosx/tkMacOSXHLEvents.c
index daf860f..47033b0 100644
--- a/macosx/tkMacOSXHLEvents.c
+++ b/macosx/tkMacOSXHLEvents.c
@@ -7,12 +7,15 @@
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
* Copyright 2001-2009, Apple Inc.
* Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright (c) 2015 Marc Culler
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkMacOSXPrivate.h"
+#include <sys/param.h>
+#define URL_MAX_LENGTH (17 + MAXPATHLEN)
/*
* This is a Tcl_Event structure that the Quit AppleEvent handler uses to
@@ -30,154 +33,32 @@ typedef struct KillEvent {
* Static functions used only in this file.
*/
-static OSErr QuitHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static OSErr OappHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static OSErr RappHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static OSErr OdocHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static OSErr PrintHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static OSErr ScriptHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static OSErr PrefsHandler(const AppleEvent *event,
- AppleEvent *reply, SRefCon handlerRefcon);
-static int MissedAnyParameters(const AppleEvent *theEvent);
-static int ReallyKillMe(Tcl_Event *eventPtr, int flags);
-static OSStatus FSRefToDString(const FSRef *fsref, Tcl_DString *ds);
+static void tkMacOSXProcessFiles(NSAppleEventDescriptor* event,
+ NSAppleEventDescriptor* replyEvent,
+ Tcl_Interp *interp,
+ char* procedure);
+static int MissedAnyParameters(const AppleEvent *theEvent);
+static int ReallyKillMe(Tcl_Event *eventPtr, int flags);
#pragma mark TKApplication(TKHLEvents)
@implementation TKApplication(TKHLEvents)
- (void) terminate: (id) sender
{
- QuitHandler(NULL, NULL, (SRefCon) _eventInterp);
+ [self handleQuitApplicationEvent:Nil withReplyEvent:Nil];
}
- (void) preferences: (id) sender
{
- PrefsHandler(NULL, NULL, (SRefCon) _eventInterp);
+ [self handleShowPreferencesEvent:Nil withReplyEvent:Nil];
}
-@end
-
-#pragma mark -
-
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXInitAppleEvents --
- *
- * Initilize the Apple Events on the Macintosh. This registers the core
- * event handlers.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-void
-TkMacOSXInitAppleEvents(
- Tcl_Interp *interp) /* Interp to handle basic events. */
+- (void) handleQuitApplicationEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
- AEEventHandlerUPP OappHandlerUPP, RappHandlerUPP, OdocHandlerUPP;
- AEEventHandlerUPP PrintHandlerUPP, QuitHandlerUPP, ScriptHandlerUPP;
- AEEventHandlerUPP PrefsHandlerUPP;
- static Boolean initialized = FALSE;
-
- if (!initialized) {
- initialized = TRUE;
-
- /*
- * Install event handlers for the core apple events.
- */
-
- QuitHandlerUPP = NewAEEventHandlerUPP(QuitHandler);
- ChkErr(AEInstallEventHandler, kCoreEventClass, kAEQuitApplication,
- QuitHandlerUPP, (SRefCon) interp, false);
-
- OappHandlerUPP = NewAEEventHandlerUPP(OappHandler);
- ChkErr(AEInstallEventHandler, kCoreEventClass, kAEOpenApplication,
- OappHandlerUPP, (SRefCon) interp, false);
-
- RappHandlerUPP = NewAEEventHandlerUPP(RappHandler);
- ChkErr(AEInstallEventHandler, kCoreEventClass, kAEReopenApplication,
- RappHandlerUPP, (SRefCon) interp, false);
-
- OdocHandlerUPP = NewAEEventHandlerUPP(OdocHandler);
- ChkErr(AEInstallEventHandler, kCoreEventClass, kAEOpenDocuments,
- OdocHandlerUPP, (SRefCon) interp, false);
-
- PrintHandlerUPP = NewAEEventHandlerUPP(PrintHandler);
- ChkErr(AEInstallEventHandler, kCoreEventClass, kAEPrintDocuments,
- PrintHandlerUPP, (SRefCon) interp, false);
-
- PrefsHandlerUPP = NewAEEventHandlerUPP(PrefsHandler);
- ChkErr(AEInstallEventHandler, kCoreEventClass, kAEShowPreferences,
- PrefsHandlerUPP, (SRefCon) interp, false);
-
- if (interp) {
- ScriptHandlerUPP = NewAEEventHandlerUPP(ScriptHandler);
- ChkErr(AEInstallEventHandler, kAEMiscStandards, kAEDoScript,
- ScriptHandlerUPP, (SRefCon) interp, false);
- }
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXDoHLEvent --
- *
- * Dispatch incomming highlevel events.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Depends on the incoming event.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TkMacOSXDoHLEvent(
- void *theEvent)
-{
- return AEProcessAppleEvent((EventRecord *)theEvent);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * QuitHandler --
- *
- * This is the 'quit' core Apple event handler.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static OSErr
-QuitHandler(
- const AppleEvent *event,
- AppleEvent *reply,
- SRefCon handlerRefcon)
-{
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
KillEvent *eventPtr;
- if (interp) {
+ if (_eventInterp) {
/*
* Call the exit command from the event loop, since you are not
* supposed to call ExitToShell in an Apple Event Handler. We put this
@@ -188,233 +69,221 @@ QuitHandler(
eventPtr = ckalloc(sizeof(KillEvent));
eventPtr->header.proc = ReallyKillMe;
- eventPtr->interp = interp;
+ eventPtr->interp = _eventInterp;
Tcl_QueueEvent((Tcl_Event *) eventPtr, TCL_QUEUE_HEAD);
}
- return noErr;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * OappHandler --
- *
- * This is the 'oapp' core Apple event handler.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-static OSErr
-OappHandler(
- const AppleEvent *event,
- AppleEvent *reply,
- SRefCon handlerRefcon)
+- (void) handleOpenApplicationEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
+ Tcl_Interp *interp = _eventInterp;
if (interp &&
- Tcl_FindCommand(interp, "::tk::mac::OpenApplication", NULL, 0)){
- int code = Tcl_EvalEx(interp, "::tk::mac::OpenApplication", -1, TCL_EVAL_GLOBAL);
+ Tcl_FindCommand(_eventInterp, "::tk::mac::OpenApplication", NULL, 0)){
+ int code = Tcl_EvalEx(_eventInterp, "::tk::mac::OpenApplication",
+ -1, TCL_EVAL_GLOBAL);
if (code != TCL_OK) {
- Tcl_BackgroundException(interp, code);
+ Tcl_BackgroundException(_eventInterp, code);
}
}
- return noErr;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * RappHandler --
- *
- * This is the 'rapp' core Apple event handler.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-static OSErr
-RappHandler(
- const AppleEvent *event,
- AppleEvent *reply,
- SRefCon handlerRefcon)
+- (void) handleReopenApplicationEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
ProcessSerialNumber thePSN = {0, kCurrentProcess};
- OSStatus err = ChkErr(SetFrontProcess, &thePSN);
-
- if (interp && Tcl_FindCommand(interp,
+ SetFrontProcess(&thePSN);
+#else
+ [[NSApplication sharedApplication] activateIgnoringOtherApps: YES];
+#endif
+ if (_eventInterp && Tcl_FindCommand(_eventInterp,
"::tk::mac::ReopenApplication", NULL, 0)) {
- int code = Tcl_EvalEx(interp, "::tk::mac::ReopenApplication", -1, TCL_EVAL_GLOBAL);
+ int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ReopenApplication",
+ -1, TCL_EVAL_GLOBAL);
if (code != TCL_OK){
- Tcl_BackgroundException(interp, code);
+ Tcl_BackgroundException(_eventInterp, code);
}
}
- return err;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * PrefsHandler --
- *
- * This is the 'pref' core Apple event handler. Called when the user
- * selects 'Preferences...' in MacOS X
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-static OSErr
-PrefsHandler(
- const AppleEvent *event,
- AppleEvent *reply,
- SRefCon handlerRefcon)
+- (void) handleShowPreferencesEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
-
- if (interp &&
- Tcl_FindCommand(interp, "::tk::mac::ShowPreferences", NULL, 0)){
- int code = Tcl_EvalEx(interp, "::tk::mac::ShowPreferences", -1, TCL_EVAL_GLOBAL);
+ if (_eventInterp &&
+ Tcl_FindCommand(_eventInterp, "::tk::mac::ShowPreferences", NULL, 0)){
+ int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ShowPreferences",
+ -1, TCL_EVAL_GLOBAL);
if (code != TCL_OK) {
- Tcl_BackgroundException(interp, code);
+ Tcl_BackgroundException(_eventInterp, code);
}
}
- return noErr;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * OdocHandler --
- *
- * This is the 'odoc' core Apple event handler.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-static OSErr
-OdocHandler(
- const AppleEvent *event,
- AppleEvent *reply,
- SRefCon handlerRefcon)
+- (void) handleOpenDocumentsEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
- AEDescList fileSpecList;
- FSRef file;
- DescType type;
- Size actual;
- long count, index;
- AEKeyword keyword;
- Tcl_DString command, pathName;
- int code;
+ tkMacOSXProcessFiles(event, replyEvent, _eventInterp, "::tk::mac::OpenDocument");
+}
- /*
- * Don't bother if we don't have an interp or the open document procedure
- * doesn't exist.
- */
+- (void) handlePrintDocumentsEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
+{
+ tkMacOSXProcessFiles(event, replyEvent, _eventInterp, "::tk::mac::PrintDocument");
+}
- if (!interp ||
- !Tcl_FindCommand(interp, "::tk::mac::OpenDocument", NULL, 0)) {
- return noErr;
- }
+- (void) handleDoScriptEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
+{
+ OSStatus err;
+ const AEDesc *theDesc = nil;
+ DescType type = 0, initialType = 0;
+ Size actual;
+ int tclErr = -1;
+ char URLBuffer[1 + URL_MAX_LENGTH];
+ char errString[128];
+ char typeString[5];
/*
- * If we get any errors while retrieving our parameters we just return with
- * no error.
+ * The DoScript event receives one parameter that should be text data or a
+ * fileURL.
*/
- if (ChkErr(AEGetParamDesc, event, keyDirectObject, typeAEList,
- &fileSpecList) != noErr) {
- return noErr;
+ theDesc = [event aeDesc];
+ if (theDesc == nil) {
+ return;
}
- if (MissedAnyParameters(event) != noErr) {
- return noErr;
+
+ err = AEGetParamPtr(theDesc, keyDirectObject, typeWildCard, &initialType,
+ NULL, 0, NULL);
+ if (err != noErr) {
+ sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", (int)err);
+ AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar,
+ errString, strlen(errString));
+ return;
}
- if (ChkErr(AECountItems, &fileSpecList, &count) != noErr) {
- return noErr;
+
+ if (MissedAnyParameters((AppleEvent*)theDesc)) {
+ sprintf(errString, "AEDoScriptHandler: extra parameters");
+ AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar,
+ errString, strlen(errString));
+ return;
}
- /*
- * Convert our parameters into a script to evaluate, skipping things that
- * we can't handle right.
- */
-
- Tcl_DStringInit(&command);
- Tcl_DStringAppend(&command, "::tk::mac::OpenDocument", -1);
- for (index = 1; index <= count; index++) {
- if (ChkErr(AEGetNthPtr, &fileSpecList, index, typeFSRef, &keyword,
- &type, (Ptr) &file, sizeof(FSRef), &actual) != noErr) {
- continue;
+ if (initialType == typeFileURL || initialType == typeAlias) {
+ /*
+ * The descriptor can be coerced to a file url. Source the file, or
+ * pass the path as a string argument to ::tk::mac::DoScriptFile if
+ * that procedure exists.
+ */
+ err = AEGetParamPtr(theDesc, keyDirectObject, typeFileURL, &type,
+ (Ptr) URLBuffer, URL_MAX_LENGTH, &actual);
+ if (err == noErr && actual > 0){
+ URLBuffer[actual] = '\0';
+ NSString *urlString = [NSString stringWithUTF8String:(char*)URLBuffer];
+ NSURL *fileURL = [NSURL URLWithString:urlString];
+ Tcl_DString command;
+ Tcl_DStringInit(&command);
+ if (Tcl_FindCommand(_eventInterp, "::tk::mac::DoScriptFile", NULL, 0)){
+ Tcl_DStringAppend(&command, "::tk::mac::DoScriptFile", -1);
+ } else {
+ Tcl_DStringAppend(&command, "source", -1);
+ }
+ Tcl_DStringAppendElement(&command, [[fileURL path] UTF8String]);
+ tclErr = Tcl_EvalEx(_eventInterp, Tcl_DStringValue(&command),
+ Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
}
-
- if (ChkErr(FSRefToDString, &file, &pathName) == noErr) {
- Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName));
- Tcl_DStringFree(&pathName);
+ } else if (noErr == AEGetParamPtr(theDesc, keyDirectObject, typeUTF8Text, &type,
+ NULL, 0, &actual)) {
+ if (actual > 0) {
+ /*
+ * The descriptor can be coerced to UTF8 text. Evaluate as Tcl, or
+ * or pass the text as a string argument to ::tk::mac::DoScriptText
+ * if that procedure exists.
+ */
+ char *data = ckalloc(actual + 1);
+ if (noErr == AEGetParamPtr(theDesc, keyDirectObject, typeUTF8Text, &type,
+ data, actual, NULL)) {
+ if (Tcl_FindCommand(_eventInterp, "::tk::mac::DoScriptText", NULL, 0)){
+ Tcl_DString command;
+ Tcl_DStringInit(&command);
+ Tcl_DStringAppend(&command, "::tk::mac::DoScriptText", -1);
+ Tcl_DStringAppendElement(&command, data);
+ tclErr = Tcl_EvalEx(_eventInterp, Tcl_DStringValue(&command),
+ Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
+ } else {
+ tclErr = Tcl_EvalEx(_eventInterp, data, actual, TCL_EVAL_GLOBAL);
+ }
+ }
+ ckfree(data);
+ }
+ } else {
+ /*
+ * The descriptor can not be coerced to a fileURL or UTF8 text.
+ */
+ for (int i = 0; i < 4; i++) {
+ typeString[i] = ((char*)&initialType)[3-i];
}
+ typeString[4] = '\0';
+ sprintf(errString, "AEDoScriptHandler: invalid script type '%s', "
+ "must be coercable to 'furl' or 'utf8'", typeString);
+ AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar, errString,
+ strlen(errString));
}
-
/*
- * Now handle the event by evaluating a script.
+ * If we ran some Tcl code, put the result in the reply.
*/
-
- code = Tcl_EvalEx(interp, Tcl_DStringValue(&command),
- Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
- if (code != TCL_OK) {
- Tcl_BackgroundException(interp, code);
+ if (tclErr >= 0) {
+ int reslen;
+ const char *result =
+ Tcl_GetStringFromObj(Tcl_GetObjResult(_eventInterp), &reslen);
+ if (tclErr == TCL_OK) {
+ AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyDirectObject, typeChar,
+ result, reslen);
+ } else {
+ AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar,
+ result, reslen);
+ AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorNumber, typeSInt32,
+ (Ptr) &tclErr,sizeof(int));
+ }
}
- Tcl_DStringFree(&command);
- return noErr;
+ return;
}
-
+@end
+
+#pragma mark -
+
/*
*----------------------------------------------------------------------
*
- * PrintHandler --
+ * TkMacOSXProcessFiles --
*
- * This is the 'pdoc' core Apple event handler.
+ * Extract a list of fileURLs from an AppleEvent and call the specified
+ * procedure with the file paths as arguments.
*
* Results:
* None.
*
* Side effects:
- * None.
+ * The event is handled by running the procedure.
*
*----------------------------------------------------------------------
*/
-static OSErr
-PrintHandler(
- const AppleEvent * event,
- AppleEvent * reply,
- SRefCon handlerRefcon)
+static void
+tkMacOSXProcessFiles(
+ NSAppleEventDescriptor* event,
+ NSAppleEventDescriptor* replyEvent,
+ Tcl_Interp *interp,
+ char* procedure)
{
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
- AEDescList fileSpecList;
- FSRef file;
+ Tcl_Encoding utf8 = Tcl_GetEncoding(NULL, "utf-8");
+ const AEDesc *fileSpecDesc = nil;
+ AEDesc contents;
+ char URLString[1 + URL_MAX_LENGTH];
+ NSURL *fileURL;
DescType type;
Size actual;
long count, index;
@@ -423,47 +292,67 @@ PrintHandler(
int code;
/*
- * Don't bother if we don't have an interp or the print document procedure
- * doesn't exist.
+ * Do nothing if we don't have an interpreter or the procedure doesn't exist.
*/
- if (!interp ||
- !Tcl_FindCommand(interp, "::tk::mac::PrintDocument", NULL, 0)) {
- return noErr;
+ if (!interp || !Tcl_FindCommand(interp, procedure, NULL, 0)) {
+ return;
}
-
+
+ fileSpecDesc = [event aeDesc];
+ if (fileSpecDesc == nil ) {
+ return;
+ }
+
/*
- * If we get any errors while retrieving our parameters we just return with
- * no error.
+ * The AppleEvent's descriptor should either contain a value of
+ * typeObjectSpecifier or typeAEList. In the first case, the descriptor
+ * can be treated as a list of size 1 containing a value which can be
+ * coerced into a fileURL. In the second case we want to work with the list
+ * itself. Values in the list will be coerced into fileURL's if possible;
+ * otherwise they will be ignored.
*/
-
- if (ChkErr(AEGetParamDesc, event, keyDirectObject, typeAEList,
- &fileSpecList) != noErr) {
- return noErr;
- }
- if (ChkErr(MissedAnyParameters, event) != noErr) {
- return noErr;
+
+ /* Get a copy of the AppleEvent's descriptor. */
+ AEGetParamDesc(fileSpecDesc, keyDirectObject, typeWildCard, &contents);
+ if (contents.descriptorType == typeAEList) {
+ fileSpecDesc = &contents;
}
- if (ChkErr(AECountItems, &fileSpecList, &count) != noErr) {
- return noErr;
+
+ if (AECountItems(fileSpecDesc, &count) != noErr) {
+ AEDisposeDesc(&contents);
+ return;
}
-
+
+ /*
+ * Construct a Tcl command which calls the procedure, passing the
+ * paths contained in the AppleEvent as arguments.
+ */
+
Tcl_DStringInit(&command);
- Tcl_DStringAppend(&command, "::tk::mac::PrintDocument", -1);
+ Tcl_DStringAppend(&command, procedure, -1);
+
for (index = 1; index <= count; index++) {
- if (ChkErr(AEGetNthPtr, &fileSpecList, index, typeFSRef, &keyword,
- &type, (Ptr) &file, sizeof(FSRef), &actual) != noErr) {
+ if (noErr != AEGetNthPtr(fileSpecDesc, index, typeFileURL, &keyword,
+ &type, (Ptr) URLString, URL_MAX_LENGTH, &actual)) {
continue;
}
-
- if (ChkErr(FSRefToDString, &file, &pathName) == noErr) {
- Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName));
- Tcl_DStringFree(&pathName);
+ if (type != typeFileURL) {
+ continue;
+ }
+ URLString[actual] = '\0';
+ fileURL = [NSURL URLWithString:[NSString stringWithUTF8String:(char*)URLString]];
+ if (fileURL == nil) {
+ continue;
}
+ Tcl_ExternalToUtfDString(utf8, [[fileURL path] UTF8String], -1, &pathName);
+ Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName));
+ Tcl_DStringFree(&pathName);
}
+ AEDisposeDesc(&contents);
/*
- * Now handle the event by evaluating a script.
+ * Handle the event by evaluating the Tcl expression we constructed.
*/
code = Tcl_EvalEx(interp, Tcl_DStringValue(&command),
@@ -472,18 +361,19 @@ PrintHandler(
Tcl_BackgroundException(interp, code);
}
Tcl_DStringFree(&command);
- return noErr;
+ return;
}
/*
*----------------------------------------------------------------------
*
- * ScriptHandler --
+ * TkMacOSXInitAppleEvents --
*
- * This handler process the script event.
+ * Register AppleEvent handlers with the NSAppleEventManager for
+ * this NSApplication.
*
* Results:
- * Schedules the given event to be processed.
+ * None.
*
* Side effects:
* None.
@@ -491,112 +381,91 @@ PrintHandler(
*----------------------------------------------------------------------
*/
-static OSErr
-ScriptHandler(
- const AppleEvent *event,
- AppleEvent *reply,
- SRefCon handlerRefcon)
+void
+TkMacOSXInitAppleEvents(
+ Tcl_Interp *interp) /* not used */
{
- OSStatus theErr;
- AEDescList theDesc;
- Size size;
- int tclErr = -1;
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
- char errString[128];
+ NSAppleEventManager *aeManager = [NSAppleEventManager sharedAppleEventManager];
+ static Boolean initialized = FALSE;
- /*
- * The do script event receives one parameter that should be data or a
- * file.
- */
+ if (!initialized) {
+ initialized = TRUE;
- theErr = AEGetParamDesc(event, keyDirectObject, typeWildCard,
- &theDesc);
- if (theErr != noErr) {
- sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d",
- (int)theErr);
- theErr = AEPutParamPtr(reply, keyErrorString, typeChar, errString,
- strlen(errString));
- } else if (MissedAnyParameters(event)) {
- /*
- * Return error if parameter is missing.
- */
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleQuitApplicationEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
- sprintf(errString, "AEDoScriptHandler: extra parameters");
- AEPutParamPtr(reply, keyErrorString, typeChar, errString,
- strlen(errString));
- theErr = -1771;
- } else if (theDesc.descriptorType == (DescType) typeAlias &&
- AEGetParamPtr(event, keyDirectObject, typeFSRef, NULL, NULL,
- 0, &size) == noErr && size == sizeof(FSRef)) {
- /*
- * We've had a file sent to us. Source it.
- */
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleOpenApplicationEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEOpenApplication];
- FSRef file;
- theErr = AEGetParamPtr(event, keyDirectObject, typeFSRef, NULL, &file,
- size, NULL);
- if (theErr == noErr) {
- Tcl_DString scriptName;
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleReopenApplicationEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEReopenApplication];
- theErr = FSRefToDString(&file, &scriptName);
- if (theErr == noErr) {
- Tcl_Obj *pathName =
- Tcl_NewStringObj(Tcl_DStringValue(&scriptName), -1);
- Tcl_DStringFree(&scriptName);
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleShowPreferencesEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEShowPreferences];
- tclErr = Tcl_FSEvalFile(interp, pathName);
- Tcl_DecrRefCount(pathName);
- } else {
- sprintf(errString, "AEDoScriptHandler: file not found");
- AEPutParamPtr(reply, keyErrorString, typeChar, errString,
- strlen(errString));
- }
- }
- } else if (AEGetParamPtr(event, keyDirectObject, typeUTF8Text, NULL, NULL,
- 0, &size) == noErr && size) {
- /*
- * We've had some data sent to us. Evaluate it.
- */
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleOpenDocumentsEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEOpenDocuments];
- char *data = ckalloc(size + 1);
- theErr = AEGetParamPtr(event, keyDirectObject, typeUTF8Text, NULL, data,
- size, NULL);
- if (theErr == noErr) {
- tclErr = Tcl_EvalEx(interp, data, size, TCL_EVAL_GLOBAL);
- }
- } else {
- /*
- * Umm, don't recognize what we've got...
- */
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleOpenDocumentsEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEPrintDocuments];
- sprintf(errString, "AEDoScriptHandler: invalid script type '%-4.4s', "
- "must be 'alis' or coercable to 'utf8'",
- (char*) &theDesc.descriptorType);
- AEPutParamPtr(reply, keyErrorString, typeChar, errString,
- strlen(errString));
- theErr = -1770;
+ [aeManager setEventHandler:NSApp
+ andSelector:@selector(handleDoScriptEvent:withReplyEvent:)
+ forEventClass:kAEMiscStandards andEventID:kAEDoScript];
}
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXDoHLEvent --
+ *
+ * Dispatch an AppleEvent.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Depend on the AppleEvent.
+ *
+ *----------------------------------------------------------------------
+ */
- /*
- * If we actually go to run Tcl code - put the result in the reply.
+int
+TkMacOSXDoHLEvent(
+ void *theEvent)
+{
+ /* According to the NSAppleEventManager reference:
+ * "The theReply parameter always specifies a reply Apple event, never
+ * nil. However, the handler should not fill out the reply if the
+ * descriptor type for the reply event is typeNull, indicating the sender
+ * does not want a reply."
+ * The specified way to build such a non-nil descriptor is used here. But
+ * on OSX 10.11, the compiler nonetheless generates a warning. I am
+ * supressing the warning here -- maybe the warnings will stop in a future
+ * compiler release.
*/
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+#endif
- if (tclErr >= 0) {
- int reslen;
- const char *result =
- Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &reslen);
+ NSAppleEventDescriptor* theReply = [NSAppleEventDescriptor nullDescriptor];
+ NSAppleEventManager *aeManager = [NSAppleEventManager sharedAppleEventManager];
- if (tclErr == TCL_OK) {
- AEPutParamPtr(reply, keyDirectObject, typeChar, result, reslen);
- } else {
- AEPutParamPtr(reply, keyErrorString, typeChar, result, reslen);
- AEPutParamPtr(reply, keyErrorNumber, typeSInt32, (Ptr) &tclErr,
- sizeof(int));
- }
- }
+ return [aeManager dispatchRawAppleEvent:(const AppleEvent*)theEvent
+ withRawReply: (AppleEvent *)theReply
+ handlerRefCon: (SRefCon)0];
- AEDisposeDesc(&theDesc);
- return theErr;
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
}
/*
@@ -604,8 +473,8 @@ ScriptHandler(
*
* ReallyKillMe --
*
- * This proc tries to kill the shell by running exit, called from an
- * event scheduled by the "Quit" AppleEvent handler.
+ * This procedure tries to kill the shell by running exit, called from
+ * an event scheduled by the "Quit" AppleEvent handler.
*
* Results:
* Runs the "exit" command which might kill the shell.
@@ -665,37 +534,7 @@ MissedAnyParameters(
return (err != errAEDescNotFound);
}
-/*
- *----------------------------------------------------------------------
- *
- * FSRefToDString --
- *
- * Get a POSIX path from an FSRef.
- *
- * Results:
- * In the parameter ds.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static OSStatus
-FSRefToDString(
- const FSRef *fsref,
- Tcl_DString *ds)
-{
- UInt8 fileName[PATH_MAX+1];
- OSStatus err;
- err = ChkErr(FSRefMakePath, fsref, fileName, sizeof(fileName));
- if (err == noErr) {
- Tcl_ExternalToUtfDString(NULL, (char*) fileName, -1, ds);
- }
- return err;
-}
-
/*
* Local Variables:
* mode: objc
diff --git a/macosx/tkMacOSXMenu.c b/macosx/tkMacOSXMenu.c
index ed22640..0c078ce 100644
--- a/macosx/tkMacOSXMenu.c
+++ b/macosx/tkMacOSXMenu.c
@@ -792,7 +792,7 @@ TkpPostMenu(
NSRect frame = NSMakeRect(x + 9, tkMacOSXZeroScreenHeight - y - 9, 1, 1);
frame.origin = [view convertPoint:
- [win convertScreenToBase:frame.origin] fromView:nil];
+ [win convertPointFromScreen:frame.origin] fromView:nil];
NSMenu *menu = (NSMenu *) menuPtr->platformData;
NSPopUpButtonCell *popUpButtonCell = [[NSPopUpButtonCell alloc]
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
index 1fdbc52..c4197f7 100644
--- a/macosx/tkMacOSXMouseEvent.c
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -26,49 +26,7 @@ typedef struct {
static int GenerateButtonEvent(MouseEventData *medPtr);
static unsigned int ButtonModifiers2State(UInt32 buttonState,
- UInt32 keyModifiers);
-
-#pragma mark NSWindow(TKMouseEvent)
-
-/* Conversion of coordinates between window and screen */
-@interface NSWindow(TKWm)
-- (NSPoint) convertPointToScreen:(NSPoint)point;
-- (NSPoint) convertPointFromScreen:(NSPoint)point;
-@end
-
-@implementation NSWindow(TKMouseEvent)
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
-- (NSPoint) convertPointToScreen: (NSPoint) point
-{
- return [self convertBaseToScreen:point];
-}
-- (NSPoint) convertPointFromScreen: (NSPoint)point
-{
- return [self convertScreenToBase:point];
-}
-@end
-#else
-- (NSPoint) convertPointToScreen: (NSPoint) point
-{
- NSRect pointrect;
- pointrect.origin = point;
- pointrect.size.width = 0;
- pointrect.size.height = 0;
- return [self convertRectToScreen:pointrect].origin;
-}
-- (NSPoint) convertPointFromScreen: (NSPoint)point
-{
- NSRect pointrect;
- pointrect.origin = point;
- pointrect.size.width = 0;
- pointrect.size.height = 0;
- return [self convertRectFromScreen:pointrect].origin;
-}
-@end
-#endif
-
-#pragma mark -
-
+ UInt32 keyModifiers);
#pragma mark TKApplication(TKMouseEvent)
@@ -77,14 +35,12 @@ enum {
};
/*
* In OS X 10.6 an NSEvent of type NSMouseMoved would always have a non-Nil
- * window attribute when the mouse was inside a window. As of 10.8 this
- * behavior had changed. The new behavior was that if the mouse were ever
- * moved outside of a window, all subsequent NSMouseMoved NSEvents would have a
- * Nil window attribute. To work around this we remember which window the
- * mouse is in by saving the window attribute of each NSEvent of type
- * NSMouseEntered. If an NSEvent has a Nil window attribute we use our saved
- * window. It may be the case that the mouse has actually left the window, but
- * this is harmless since Tk will ignore the event in that case.
+ * window attribute pointing to the active window. As of 10.8 this behavior
+ * had changed. The new behavior was that if the mouse were ever moved outside
+ * of a window, all subsequent NSMouseMoved NSEvents would have a Nil window
+ * attribute. To work around this the TKApplication remembers the last non-Nil
+ * window that it received in a mouse event. If it receives an NSEvent with a
+ * Nil window attribute then the saved window is used.
*/
@implementation TKApplication(TKMouseEvent)
@@ -93,24 +49,14 @@ enum {
#ifdef TK_MAC_DEBUG_EVENTS
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
- id win;
- NSEventType type = [theEvent type];
+ NSWindow* eventWindow = [theEvent window];
+ NSEventType eventType = [theEvent type];
#if 0
NSTrackingArea *trackingArea = nil;
NSInteger eventNumber, clickCount, buttonNumber;
#endif
-
- switch (type) {
+ switch (eventType) {
case NSMouseEntered:
- /* Remember which window has the mouse. */
- if (_windowWithMouse) {
- [_windowWithMouse release];
- }
- _windowWithMouse = [theEvent window];
- if (_windowWithMouse) {
- [_windowWithMouse retain];
- }
- break;
case NSMouseExited:
case NSCursorUpdate:
case NSLeftMouseDown:
@@ -127,25 +73,31 @@ enum {
case NSTabletProximity:
case NSScrollWheel:
break;
-
default: /* Unrecognized mouse event. */
return theEvent;
}
+ /* Remember the window in case we need it next time. */
+ if (eventWindow && eventWindow != _windowWithMouse) {
+ if (_windowWithMouse) {
+ [_windowWithMouse release];
+ }
+ _windowWithMouse = eventWindow;
+ [_windowWithMouse retain];
+ }
+
/* Create an Xevent to add to the Tk queue. */
- win = [theEvent window];
- NSWindow *nswindow = (NSWindow *)win;
NSPoint global, local = [theEvent locationInWindow];
- if (win) { /* local will be in window coordinates. */
- global = [nswindow convertPointToScreen: local];
- local.y = [win frame].size.height - local.y;
+ if (eventWindow) { /* local will be in window coordinates. */
+ global = [eventWindow convertPointToScreen: local];
+ local.y = [eventWindow frame].size.height - local.y;
global.y = tkMacOSXZeroScreenHeight - global.y;
} else { /* local will be in screen coordinates. */
if (_windowWithMouse ) {
- win = _windowWithMouse;
+ eventWindow = _windowWithMouse;
global = local;
- local = [nswindow convertPointFromScreen: local];
- local.y = [win frame].size.height - local.y;
+ local = [eventWindow convertPointFromScreen: local];
+ local.y = [eventWindow frame].size.height - local.y;
global.y = tkMacOSXZeroScreenHeight - global.y;
} else { /* We have no window. Use the screen???*/
local.y = tkMacOSXZeroScreenHeight - local.y;
@@ -153,7 +105,7 @@ enum {
}
}
- Window window = TkMacOSXGetXWindow(win);
+ Window window = TkMacOSXGetXWindow(eventWindow);
Tk_Window tkwin = window ? Tk_IdToWindow(TkGetDisplayList()->display,
window) : NULL;
if (!tkwin) {
@@ -181,7 +133,7 @@ enum {
if (err == noErr) {
state |= (buttons & ((1<<5) - 1)) << 8;
} else if (button < 5) {
- switch (type) {
+ switch (eventType) {
case NSLeftMouseDown:
case NSRightMouseDown:
case NSLeftMouseDragged:
@@ -218,12 +170,12 @@ enum {
state |= Mod4Mask;
}
- if (type != NSScrollWheel) {
+ if (eventType != NSScrollWheel) {
#ifdef TK_MAC_DEBUG_EVENTS
TKLog(@"UpdatePointer %p x %f.0 y %f.0 %d", tkwin, global.x, global.y, state);
#endif
Tk_UpdatePointer(tkwin, global.x, global.y, state);
- } else {
+ } else { /* handle scroll wheel event */
CGFloat delta;
int coarseDelta;
XEvent xEvent;
@@ -239,7 +191,8 @@ enum {
delta = [theEvent deltaY];
if (delta != 0.0) {
- coarseDelta = (delta > -1.0 && delta < 1.0) ? (signbit(delta) ? -1 : 1) : lround(delta);
+ coarseDelta = (delta > -1.0 && delta < 1.0) ?
+ (signbit(delta) ? -1 : 1) : lround(delta);
xEvent.xbutton.state = state;
xEvent.xkey.keycode = coarseDelta;
xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
@@ -247,7 +200,8 @@ enum {
}
delta = [theEvent deltaX];
if (delta != 0.0) {
- coarseDelta = (delta > -1.0 && delta < 1.0) ? (signbit(delta) ? -1 : 1) : lround(delta);
+ coarseDelta = (delta > -1.0 && delta < 1.0) ?
+ (signbit(delta) ? -1 : 1) : lround(delta);
xEvent.xbutton.state = state | ShiftMask;
xEvent.xkey.keycode = coarseDelta;
xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
@@ -418,7 +372,7 @@ XQueryPointer(
if (win) {
NSPoint local;
- local = [win convertScreenToBase:global];
+ local = [win convertPointFromScreen:global];
local.y = [win frame].size.height - local.y;
if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
local.x -= macWin->winPtr->wmInfoPtr->xInParent;
@@ -516,7 +470,7 @@ TkGenerateButtonEvent(
if (win) {
NSPoint local = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);
- local = [win convertScreenToBase:local];
+ local = [win convertPointFromScreen:local];
local.y = [win frame].size.height - local.y;
if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
local.x -= macWin->winPtr->wmInfoPtr->xInParent;
diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h
index 9cdc27c..d0a52ee 100644
--- a/macosx/tkMacOSXPrivate.h
+++ b/macosx/tkMacOSXPrivate.h
@@ -296,6 +296,24 @@ VISIBILITY_HIDDEN
- (void)tkProvidePasteboard:(TkDisplay *)dispPtr;
- (void)tkCheckPasteboard;
@end
+@interface TKApplication(TKHLEvents)
+- (void) terminate: (id) sender;
+- (void) preferences: (id) sender;
+- (void) handleQuitApplicationEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+- (void) handleOpenApplicationEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+- (void) handleReopenApplicationEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+- (void) handleShowPreferencesEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+- (void) handleOpenDocumentsEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+- (void) handlePrintDocumentsEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+- (void) handleDoScriptEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
+@end
VISIBILITY_HIDDEN
@interface TKContentView : NSView <NSTextInput> {
@@ -329,6 +347,11 @@ VISIBILITY_HIDDEN
@interface TKWindow : NSWindow
@end
+@interface NSWindow(TKWm)
+- (NSPoint) convertPointToScreen:(NSPoint)point;
+- (NSPoint) convertPointFromScreen:(NSPoint)point;
+@end
+
#pragma mark NSMenu & NSMenuItem Utilities
@interface NSMenu(TKUtils)
@@ -357,8 +380,4 @@ VISIBILITY_HIDDEN
keyEquivalentModifierMask:(NSUInteger)keyEquivalentModifierMask;
@end
-/* Helper functions from tkMacOSXDeprecations.c */
-
-extern NSPoint convertWindowToScreen( NSWindow *window, NSPoint point);
-
#endif /* _TKMACPRIV */
diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c
index 7f1cf90..851358d 100644
--- a/macosx/tkMacOSXWindowEvent.c
+++ b/macosx/tkMacOSXWindowEvent.c
@@ -745,15 +745,16 @@ TkWmProtocolEventProc(
int
Tk_MacOSXIsAppInFront(void)
{
- OSStatus err;
- ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess};
Boolean isFrontProcess = true;
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess};
- err = ChkErr(GetFrontProcess, &frontPsn);
- if (err == noErr) {
- ChkErr(SameProcess, &frontPsn, &ourPsn, &isFrontProcess);
+ if (noErr == GetFrontProcess(&frontPsn)){
+ SameProcess(&frontPsn, &ourPsn, &isFrontProcess);
}
-
+#else
+ isFrontProcess = [NSRunningApplication currentApplication].active;
+#endif
return (isFrontProcess == true);
}
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 417f130..fb58904 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -196,6 +196,48 @@ static int tkMacOSXWmAttrNotifyVal = 0;
static Tcl_HashTable windowTable;
static int windowHashInit = false;
+
+
+#pragma mark NSWindow(TKWm)
+
+/*
+ * Conversion of coordinates between window and screen.
+ */
+
+@implementation NSWindow(TKWm)
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
+- (NSPoint) convertPointToScreen: (NSPoint) point
+{
+ return [self convertBaseToScreen:point];
+}
+- (NSPoint) convertPointFromScreen: (NSPoint)point
+{
+ return [self convertScreenToBase:point];
+}
+@end
+#else
+- (NSPoint) convertPointToScreen: (NSPoint) point
+{
+ NSRect pointrect;
+ pointrect.origin = point;
+ pointrect.size.width = 0;
+ pointrect.size.height = 0;
+ return [self convertRectToScreen:pointrect].origin;
+}
+- (NSPoint) convertPointFromScreen: (NSPoint)point
+{
+ NSRect pointrect;
+ pointrect.origin = point;
+ pointrect.size.width = 0;
+ pointrect.size.height = 0;
+ return [self convertRectFromScreen:pointrect].origin;
+}
+@end
+#endif
+
+#pragma mark -
+
+
/*
* Forward declarations for procedures defined in this file:
*/
diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c
index a5f1c60..e87bb39 100644
--- a/macosx/tkMacOSXXStubs.c
+++ b/macosx/tkMacOSXXStubs.c
@@ -181,7 +181,21 @@ TkpOpenDisplay(
NSAppKitVersionNumber);
}
display->vendor = vendor;
- Gestalt(gestaltSystemVersion, (SInt32 *) &display->release);
+ {
+ int major, minor, patch;
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
+ Gestalt(gestaltSystemVersionMajor, (SInt32*)&major);
+ Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor);
+ Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch);
+#else
+ NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
+ major = systemVersion.majorVersion;
+ minor = systemVersion.minorVersion;
+ patch = systemVersion.patchVersion;
+#endif
+ display->release = major << 16 | minor << 8 | patch;
+ }
/*
* These screen bits never change