summaryrefslogtreecommitdiffstats
path: root/macosx
diff options
context:
space:
mode:
Diffstat (limited to 'macosx')
-rw-r--r--macosx/tkMacOSXDialog.c386
-rw-r--r--macosx/tkMacOSXDraw.c88
-rw-r--r--macosx/tkMacOSXFont.c18
-rw-r--r--macosx/tkMacOSXHLEvents.c756
-rw-r--r--macosx/tkMacOSXKeyEvent.c36
-rw-r--r--macosx/tkMacOSXMenu.c2
-rw-r--r--macosx/tkMacOSXMouseEvent.c80
-rw-r--r--macosx/tkMacOSXPrivate.h41
-rw-r--r--macosx/tkMacOSXSubwindows.c3
-rw-r--r--macosx/tkMacOSXWindowEvent.c28
-rw-r--r--macosx/tkMacOSXWm.c76
-rw-r--r--macosx/tkMacOSXXStubs.c58
12 files changed, 828 insertions, 744 deletions
diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c
index b5ff48b..9cd9cf3 100644
--- a/macosx/tkMacOSXDialog.c
+++ b/macosx/tkMacOSXDialog.c
@@ -7,24 +7,34 @@
* Copyright 2001-2009, Apple Inc.
* Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- */
+ * 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 "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 int TkBackgroundEvalObjv(Tcl_Interp *interp, int objc,
Tcl_Obj *const *objv, int flags);
-static const char *colorOptionStrings[] = {
+static const char *const colorOptionStrings[] = {
"-initialcolor", "-parent", "-title", NULL
};
enum colorOptions {
COLOR_INITIAL, COLOR_PARENT, COLOR_TITLE
};
-static const char *openOptionStrings[] = {
+static const char *const openOptionStrings[] = {
"-defaultextension", "-filetypes", "-initialdir", "-initialfile",
"-message", "-multiple", "-parent", "-title", "-typevariable",
"-command", NULL
@@ -34,7 +44,7 @@ enum openOptions {
OPEN_MESSAGE, OPEN_MULTIPLE, OPEN_PARENT, OPEN_TITLE,
OPEN_TYPEVARIABLE, OPEN_COMMAND,
};
-static const char *saveOptionStrings[] = {
+static const char *const saveOptionStrings[] = {
"-defaultextension", "-filetypes", "-initialdir", "-initialfile",
"-message", "-parent", "-title", "-typevariable", "-command",
"-confirmoverwrite", NULL
@@ -44,7 +54,7 @@ enum saveOptions {
SAVE_MESSAGE, SAVE_PARENT, SAVE_TITLE, SAVE_TYPEVARIABLE, SAVE_COMMAND,
SAVE_CONFIRMOW
};
-static const char *chooseOptionStrings[] = {
+static const char *const chooseOptionStrings[] = {
"-initialdir", "-message", "-mustexist", "-parent", "-title", "-command",
NULL
};
@@ -58,7 +68,7 @@ typedef struct {
int multiple;
} FilePanelCallbackInfo;
-static const char *alertOptionStrings[] = {
+static const char *const alertOptionStrings[] = {
"-default", "-detail", "-icon", "-message", "-parent", "-title",
"-type", "-command", NULL
};
@@ -71,7 +81,7 @@ typedef struct {
Tcl_Obj *cmdObj;
int typeIndex;
} AlertCallbackInfo;
-static const char *alertTypeStrings[] = {
+static const char *const alertTypeStrings[] = {
"abortretryignore", "ok", "okcancel", "retrycancel", "yesno",
"yesnocancel", NULL
};
@@ -79,13 +89,13 @@ enum alertTypeOptions {
TYPE_ABORTRETRYIGNORE, TYPE_OK, TYPE_OKCANCEL, TYPE_RETRYCANCEL,
TYPE_YESNO, TYPE_YESNOCANCEL
};
-static const char *alertIconStrings[] = {
+static const char *const alertIconStrings[] = {
"error", "info", "question", "warning", NULL
};
enum alertIconOptions {
ICON_ERROR, ICON_INFO, ICON_QUESTION, ICON_WARNING
};
-static const char *alertButtonStrings[] = {
+static const char *const alertButtonStrings[] = {
"abort", "retry", "ignore", "ok", "cancel", "yes", "no", NULL
};
@@ -105,9 +115,9 @@ static const NSAlertStyle alertStyles[] = {
};
/*
- * Need to map from 'alertButtonStrings' and its corresponding integer,
- * index to the native button index, which is 1, 2, 3, from right to left.
- * This is necessary to do for each separate '-type' of button sets.
+ * Need to map from 'alertButtonStrings' and its corresponding integer, index
+ * to the native button index, which is 1, 2, 3, from right to left. This is
+ * necessary to do for each separate '-type' of button sets.
*/
static const short alertButtonIndexAndTypeToNativeButtonIndex[][7] = {
@@ -134,27 +144,47 @@ static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
[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)
@interface NSColorPanel(TKDialog)
-- (void)_setUseModalAppearance:(BOOL)flag;
+- (void) _setUseModalAppearance: (BOOL) flag;
@end
@implementation TKApplication(TKDialog)
-- (void)tkFilePanelDidEnd:(NSSavePanel *)panel returnCode:(NSInteger)returnCode
- contextInfo:(void *)contextInfo {
+
+- (void) tkFilePanelDidEnd: (NSSavePanel *) panel
+ returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo
+{
FilePanelCallbackInfo *callbackInfo = contextInfo;
if (returnCode == NSFileHandlingPanelOKButton) {
Tcl_Obj *resultObj;
+
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;
@@ -179,14 +209,14 @@ static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
}
if (callbackInfo->cmdObj) {
Tcl_DecrRefCount(callbackInfo->cmdObj);
- ckfree((char*) callbackInfo);
+ ckfree((char *)callbackInfo);
}
}
- (void)tkAlertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode
contextInfo:(void *)contextInfo {
AlertCallbackInfo *callbackInfo = contextInfo;
- if (returnCode != NSAlertErrorReturn) {
+ if (returnCode >= NSAlertFirstButtonReturn) {
Tcl_Obj *resultObj = Tcl_NewStringObj(alertButtonStrings[
alertNativeButtonIndexAndTypeToButtonIndex[callbackInfo->
typeIndex][returnCode - NSAlertFirstButtonReturn]], -1);
@@ -211,7 +241,7 @@ static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
}
if (callbackInfo->cmdObj) {
Tcl_DecrRefCount(callbackInfo->cmdObj);
- ckfree((char*) callbackInfo);
+ ckfree((char *) callbackInfo);
}
}
@end
@@ -252,43 +282,41 @@ Tk_ChooseColorObjCmd(
for (i = 1; i < objc; i += 2) {
int index;
- const char *option, *value;
+ const char *value;
- if (Tcl_GetIndexFromObj(interp, objv[i], colorOptionStrings, "option",
- TCL_EXACT, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], colorOptionStrings,
+ sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
goto end;
}
if (i + 1 == objc) {
- option = Tcl_GetString(objv[i]);
- Tcl_AppendResult(interp, "value for \"", option, "\" missing",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "value for \"%s\" missing", Tcl_GetString(objv[i])));
+ Tcl_SetErrorCode(interp, "TK", "COLORDIALOG", "VALUE", NULL);
goto end;
}
value = Tcl_GetString(objv[i + 1]);
switch (index) {
- case COLOR_INITIAL: {
- XColor *colorPtr;
+ case COLOR_INITIAL: {
+ XColor *colorPtr;
- colorPtr = Tk_GetColor(interp, tkwin, value);
- if (colorPtr == NULL) {
- goto end;
- }
- initialColor = TkMacOSXGetNSColor(NULL, colorPtr->pixel);
- Tk_FreeColor(colorPtr);
- break;
- }
- case COLOR_PARENT: {
- parent = Tk_NameToWindow(interp, value, tkwin);
- if (parent == NULL) {
- goto end;
- }
- break;
+ colorPtr = Tk_GetColor(interp, tkwin, value);
+ if (colorPtr == NULL) {
+ goto end;
}
- case COLOR_TITLE: {
- title = value;
- break;
+ initialColor = TkMacOSXGetNSColor(NULL, colorPtr->pixel);
+ Tk_FreeColor(colorPtr);
+ break;
+ }
+ case COLOR_PARENT:
+ parent = Tk_NameToWindow(interp, value, tkwin);
+ if (parent == NULL) {
+ goto end;
}
+ break;
+ case COLOR_TITLE:
+ title = value;
+ break;
}
}
colorPanel = [NSColorPanel sharedColorPanel];
@@ -306,7 +334,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];
@@ -325,6 +353,7 @@ Tk_ChooseColorObjCmd(
Tcl_ResetResult(interp);
}
result = TCL_OK;
+
end:
return result;
}
@@ -365,17 +394,18 @@ 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) {
- if (Tcl_GetIndexFromObj(interp, objv[i], openOptionStrings, "option",
- TCL_EXACT, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings,
+ sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
goto end;
}
if (i + 1 == objc) {
- str = Tcl_GetString(objv[i]);
- Tcl_AppendResult(interp, "value for \"", str, "\" missing", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "value for \"%s\" missing", Tcl_GetString(objv[i])));
+ Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
goto end;
}
switch (index) {
@@ -434,6 +464,7 @@ Tk_GetOpenFileObjCmd(
break;
}
}
+ [panel setAllowsMultipleSelection:multiple];
if (fl.filters) {
fileTypes = [NSMutableArray array];
for (FileFilter *filterPtr = fl.filters; filterPtr;
@@ -466,10 +497,9 @@ Tk_GetOpenFileObjCmd(
}
}
}
- [panel setAllowsMultipleSelection:multiple];
+ [panel setAllowedFileTypes:fileTypes];
if (cmdObj) {
- callbackInfo = (FilePanelCallbackInfo *)
- ckalloc(sizeof(FilePanelCallbackInfo));
+ callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
if (Tcl_IsShared(cmdObj)) {
cmdObj = Tcl_DuplicateObj(cmdObj);
}
@@ -480,28 +510,47 @@ 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.
*/
- Tcl_SetVar(interp, Tcl_GetString(typeVariablePtr), "",
- TCL_GLOBAL_ONLY);
+ Tcl_SetVar2(interp, Tcl_GetString(typeVariablePtr), NULL,
+ "", TCL_GLOBAL_ONLY);
}
-end:
+
+ end:
TkFreeFileFilters(&fl);
return result;
}
@@ -543,18 +592,18 @@ 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) {
- if (Tcl_GetIndexFromObj(interp, objv[i], saveOptionStrings, "option",
- TCL_EXACT, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings,
+ sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
goto end;
}
if (i + 1 == objc) {
- str = Tcl_GetString(objv[i]);
- Tcl_AppendResult(interp, "value for \"", str, "\" missing",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "value for \"%s\" missing", Tcl_GetString(objv[i])));
+ Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
goto end;
}
switch (index) {
@@ -614,7 +663,7 @@ Tk_GetSaveFileObjCmd(
break;
case SAVE_CONFIRMOW:
if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
- &confirmOverwrite) != TCL_OK) {
+ &confirmOverwrite) != TCL_OK) {
goto end;
}
break;
@@ -649,8 +698,7 @@ Tk_GetSaveFileObjCmd(
[panel setCanSelectHiddenExtension:YES];
[panel setExtensionHidden:NO];
if (cmdObj) {
- callbackInfo = (FilePanelCallbackInfo *)
- ckalloc(sizeof(FilePanelCallbackInfo));
+ callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
if (Tcl_IsShared(cmdObj)) {
cmdObj = Tcl_DuplicateObj(cmdObj);
}
@@ -661,19 +709,36 @@ 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;
-end:
+ result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
+
+ end:
TkFreeFileFilters(&fl);
return result;
}
@@ -714,16 +779,17 @@ 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_GetIndexFromObj(interp, objv[i], chooseOptionStrings, "option",
- TCL_EXACT, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], chooseOptionStrings,
+ sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
goto end;
}
if (i + 1 == objc) {
- str = Tcl_GetString(objv[i]);
- Tcl_AppendResult(interp, "value for \"", str, "\" missing", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "value for \"%s\" missing", Tcl_GetString(objv[i])));
+ Tcl_SetErrorCode(interp, "TK", "DIRDIALOG", "VALUE", NULL);
goto end;
}
switch (index) {
@@ -770,8 +836,7 @@ Tk_ChooseDirectoryObjCmd(
[panel setCanChooseDirectories:YES];
[panel setCanCreateDirectories:!mustexist];
if (cmdObj) {
- callbackInfo = (FilePanelCallbackInfo *)
- ckalloc(sizeof(FilePanelCallbackInfo));
+ callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
if (Tcl_IsShared(cmdObj)) {
cmdObj = Tcl_DuplicateObj(cmdObj);
}
@@ -782,19 +847,35 @@ 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;
-end:
+ result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
+
+ end:
return result;
}
@@ -818,20 +899,29 @@ void
TkAboutDlg(void)
{
NSImage *image;
- NSString *path = [NSApp tkFrameworkImagePath:@"Tk.tiff"];
+ NSString *path = [NSApp tkFrameworkImagePath: @"Tk.tiff"];
+
if (path) {
image = [[[NSImage alloc] initWithContentsOfFile:path] autorelease];
} else {
image = [NSApp applicationIconImage];
}
+
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
+
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat:@"Y"];
+
NSString *year = [dateFormatter stringFromDate:[NSDate date]];
+
[dateFormatter release];
- NSMutableParagraphStyle *style = [[[NSParagraphStyle defaultParagraphStyle]
- mutableCopy] autorelease];
+
+ NSMutableParagraphStyle *style =
+ [[[NSParagraphStyle defaultParagraphStyle] mutableCopy]
+ autorelease];
+
[style setAlignment:NSCenterTextAlignment];
+
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
@"Tcl & Tk", @"ApplicationName",
@"Tcl " TCL_VERSION " & Tk " TK_VERSION, @"ApplicationVersion",
@@ -842,15 +932,15 @@ TkAboutDlg(void)
[[[NSAttributedString alloc] initWithString:
[NSString stringWithFormat:
@"%1$C 1987-%2$@ Tcl Core Team." "\n\n"
- "%1$C 1989-%2$@ Contributors." "\n\n"
+ "%1$C 1989-%2$@ Contributors." "\n\n"
"%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC." "\n\n"
"%1$C 2014-%2$@ Marc Culler." "\n\n"
- "%1$C 2002-%2$@ Daniel A. Steffen." "\n\n"
- "%1$C 2001-2009 Apple Inc." "\n\n"
- "%1$C 2001-2002 Jim Ingham & Ian Reid" "\n\n"
- "%1$C 1998-2000 Jim Ingham & Ray Johnson" "\n\n"
- "%1$C 1998-2000 Scriptics Inc." "\n\n"
- "%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year] attributes:
+ "%1$C 2002-%2$@ Daniel A. Steffen." "\n\n"
+ "%1$C 2001-2009 Apple Inc." "\n\n"
+ "%1$C 2001-2002 Jim Ingham & Ian Reid" "\n\n"
+ "%1$C 1998-2000 Jim Ingham & Ray Johnson" "\n\n"
+ "%1$C 1998-2000 Scriptics Inc." "\n\n"
+ "%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year] attributes:
[NSDictionary dictionaryWithObject:style
forKey:NSParagraphStyleAttributeName]] autorelease], @"Credits",
nil];
@@ -884,7 +974,7 @@ TkMacOSXStandardAboutPanelObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return TCL_ERROR;
}
- [NSApp orderFrontStandardAboutPanelWithOptions:nil];
+ [NSApp orderFrontStandardAboutPanelWithOptions:[NSDictionary dictionary]];
return TCL_OK;
}
@@ -922,18 +1012,19 @@ Tk_MessageBoxObjCmd(
NSWindow *parent;
NSArray *buttons;
NSAlert *alert = [NSAlert new];
- NSInteger returnCode = NSAlertErrorReturn;
+ NSInteger modalReturnCode = 1;
iconIndex = ICON_INFO;
typeIndex = TYPE_OK;
for (i = 1; i < objc; i += 2) {
- if (Tcl_GetIndexFromObj(interp, objv[i], alertOptionStrings, "option",
- TCL_EXACT, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], alertOptionStrings,
+ sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
goto end;
}
if (i + 1 == objc) {
- str = Tcl_GetString(objv[i]);
- Tcl_AppendResult(interp, "value for \"", str, "\" missing", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "value for \"%s\" missing", Tcl_GetString(objv[i])));
+ Tcl_SetErrorCode(interp, "TK", "MSGBOX", "VALUE", NULL);
goto end;
}
switch (index) {
@@ -954,8 +1045,8 @@ Tk_MessageBoxObjCmd(
break;
case ALERT_ICON:
- if (Tcl_GetIndexFromObj(interp, objv[i + 1], alertIconStrings,
- "value", TCL_EXACT, &iconIndex) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertIconStrings,
+ sizeof(char *), "value", TCL_EXACT, &iconIndex) != TCL_OK) {
goto end;
}
break;
@@ -984,8 +1075,8 @@ Tk_MessageBoxObjCmd(
break;
case ALERT_TYPE:
- if (Tcl_GetIndexFromObj(interp, objv[i + 1], alertTypeStrings,
- "value", TCL_EXACT, &typeIndex) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertTypeStrings,
+ sizeof(char *), "value", TCL_EXACT, &typeIndex) != TCL_OK) {
goto end;
}
break;
@@ -996,13 +1087,12 @@ Tk_MessageBoxObjCmd(
}
if (indexDefaultOption) {
/*
- * Any '-default' option needs to know the '-type' option, which is why
- * we do this here.
+ * Any '-default' option needs to know the '-type' option, which is
+ * why we do this here.
*/
- if (Tcl_GetIndexFromObj(interp, objv[indexDefaultOption + 1],
- alertButtonStrings, "value", TCL_EXACT, &index)
- != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[indexDefaultOption + 1],
+ alertButtonStrings, sizeof(char *), "value", TCL_EXACT, &index) != TCL_OK) {
goto end;
}
@@ -1015,6 +1105,7 @@ Tk_MessageBoxObjCmd(
if (!defaultNativeButtonIndex) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("Illegal default option", -1));
+ Tcl_SetErrorCode(interp, "TK", "MSGBOX", "DEFAULT", NULL);
goto end;
}
}
@@ -1027,15 +1118,17 @@ Tk_MessageBoxObjCmd(
buttons = [alert buttons];
for (NSButton *b in buttons) {
NSString *ke = [b keyEquivalent];
+
if (([ke isEqualToString:@"\r"] || [ke isEqualToString:@"\033"]) &&
![b keyEquivalentModifierMask]) {
[b setKeyEquivalent:@""];
}
}
- [[buttons objectAtIndex:[buttons count]-1] setKeyEquivalent:@"\033"];
- [[buttons objectAtIndex:defaultNativeButtonIndex-1] setKeyEquivalent:@"\r"];
+ [[buttons objectAtIndex: [buttons count]-1] setKeyEquivalent: @"\033"];
+ [[buttons objectAtIndex: defaultNativeButtonIndex-1]
+ setKeyEquivalent: @"\r"];
if (cmdObj) {
- callbackInfo = (AlertCallbackInfo *) ckalloc(sizeof(AlertCallbackInfo));
+ callbackInfo = (AlertCallbackInfo *)ckalloc(sizeof(AlertCallbackInfo));
if (Tcl_IsShared(cmdObj)) {
cmdObj = Tcl_DuplicateObj(cmdObj);
}
@@ -1046,18 +1139,27 @@ 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;
-end:
+ result = (modalReturnCode < 1) ? TCL_OK : TCL_ERROR;
+ end:
[alert release];
return result;
}
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index 3f51d00..45a07c7 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -141,7 +141,7 @@ BitmapRepFromDrawableRect(
if ( mac_drawable->flags & TK_IS_PIXMAP ) {
/*
This means that the MacDrawable is functioning as a Tk Pixmap, so its view
- field is NULL. It's context field should point to a CGImage.
+ field is NULL.
*/
cg_context = GetCGContextForDrawable(drawable);
CGRect image_rect = CGRectMake(x, y, width, height);
@@ -199,10 +199,10 @@ XCopyArea(
Display *display, /* Display. */
Drawable src, /* Source drawable. */
Drawable dst, /* Destination drawable. */
- GC gc, /* GC to use. */
+ GC gc, /* GC to use. */
int src_x, /* X & Y, width & height */
int src_y, /* define the source rectangle */
- unsigned int width, /* that will be copied. */
+ unsigned int width, /* that will be copied. */
unsigned int height,
int dest_x, /* Dest X & Y on dest rect. */
int dest_y)
@@ -282,10 +282,10 @@ XCopyPlane(
Display *display, /* Display. */
Drawable src, /* Source drawable. */
Drawable dst, /* Destination drawable. */
- GC gc, /* GC to use. */
+ GC gc, /* GC to use. */
int src_x, /* X & Y, width & height */
int src_y, /* define the source rectangle */
- unsigned int width, /* that will be copied. */
+ unsigned int width, /* that will be copied. */
unsigned int height,
int dest_x, /* Dest X & Y on dest rect. */
int dest_y,
@@ -293,6 +293,7 @@ XCopyPlane(
{
TkMacOSXDrawingContext dc;
MacDrawable *srcDraw = (MacDrawable *) src;
+ MacDrawable *dstDraw = (MacDrawable *) dst;
display->request++;
if (!width || !height) {
@@ -306,33 +307,47 @@ XCopyPlane(
if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
return;
}
- if (dc.context) {
+ CGContextRef context = dc.context;
+ if (context) {
CGImageRef img = TkMacOSXCreateCGImageWithDrawable(src);
-
if (img) {
TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
unsigned long imageBackground = gc->background;
-
- if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP &&
- clipPtr->value.pixmap == src) {
- imageBackground = TRANSPARENT_PIXEL << 24;
+ if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP){
+ CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap);
+ CGRect rect = CGRectMake(dest_x, dest_y, width, height);
+ rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff);
+ CGContextSaveGState(context);
+ /* Move the origin of the destination to top left. */
+ CGContextTranslateCTM(context, 0, rect.origin.y + CGRectGetMaxY(rect));
+ CGContextScaleCTM(context, 1, -1);
+ /* Fill with the background color, clipping to the mask. */
+ CGContextClipToMask(context, rect, mask);
+ TkMacOSXSetColorInContext(gc, gc->background, dc.context);
+ CGContextFillRect(dc.context, rect);
+ /* Fill with the foreground color, clipping to the intersection of img and mask. */
+ CGContextClipToMask(context, rect, img);
+ TkMacOSXSetColorInContext(gc, gc->foreground, context);
+ CGContextFillRect(context, rect);
+ CGContextRestoreGState(context);
+ CGImageRelease(mask);
+ CGImageRelease(img);
+ } else {
+ DrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground,
+ CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
+ CGRectMake(src_x, src_y, width, height),
+ CGRectMake(dest_x, dest_y, width, height));
+ CGImageRelease(img);
}
- DrawCGImage(dst, gc, dc.context, img, gc->foreground,
- imageBackground, CGRectMake(0, 0,
- srcDraw->size.width, srcDraw->size.height),
- CGRectMake(src_x, src_y, width, height),
- CGRectMake(dest_x, dest_y, width, height));
- CFRelease(img);
- } else {
+ } else { /* no image */
TkMacOSXDbgMsg("Invalid source drawable");
}
} else {
- TkMacOSXDbgMsg("Invalid destination drawable");
+ TkMacOSXDbgMsg("Invalid destination drawable - could not get a bitmap context.");
}
TkMacOSXRestoreDrawingContext(&dc);
- } else {
- XCopyArea(display, src, dst, gc, src_x, src_y, width, height, dest_x,
- dest_y);
+ } else { /* source drawable is a window, not a Pixmap */
+ XCopyArea(display, src, dst, gc, src_x, src_y, width, height, dest_x, dest_y);
}
}
@@ -356,16 +371,16 @@ XCopyPlane(
int
TkPutImage(
unsigned long *colors, /* Unused on Macintosh. */
- int ncolors, /* Unused on Macintosh. */
+ int ncolors, /* Unused on Macintosh. */
Display* display, /* Display. */
Drawable d, /* Drawable to place image on. */
- GC gc, /* GC to use. */
+ GC gc, /* GC to use. */
XImage* image, /* Image to place. */
int src_x, /* Source X & Y. */
int src_y,
int dest_x, /* Destination X & Y. */
int dest_y,
- unsigned int width, /* Same width & height for both */
+ unsigned int width, /* Same width & height for both */
unsigned int height) /* distination and source. */
{
TkMacOSXDrawingContext dc;
@@ -431,11 +446,12 @@ CreateCGImageWithXImage(
* BW image
*/
+ /* Reverses the sense of the bits */
static const CGFloat decodeWB[2] = {1, 0};
+ decode = decodeWB;
bitsPerComponent = 1;
bitsPerPixel = 1;
- decode = decodeWB;
if (image->bitmap_bit_order != MSBFirst) {
char *srcPtr = image->data + image->xoffset;
char *endPtr = srcPtr + len;
@@ -445,16 +461,14 @@ CreateCGImageWithXImage(
*destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
}
} else {
- data = memcpy(ckalloc(len), image->data + image->xoffset,
- len);
+ data = memcpy(ckalloc(len), image->data + image->xoffset, len);
}
if (data) {
provider = CGDataProviderCreateWithData(data, data, len, releaseData);
}
if (provider) {
img = CGImageMaskCreate(image->width, image->height, bitsPerComponent,
- bitsPerPixel, image->bytes_per_line,
- provider, decode, 0);
+ bitsPerPixel, image->bytes_per_line, provider, decode, 0);
}
} else if (image->format == ZPixmap && image->bits_per_pixel == 32) {
/*
@@ -476,6 +490,7 @@ CreateCGImageWithXImage(
img = CGImageCreate(image->width, image->height, bitsPerComponent,
bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
provider, decode, 0, kCGRenderingIntentDefault);
+ CFRelease(provider);
}
if (colorspace) {
CFRelease(colorspace);
@@ -483,10 +498,6 @@ CreateCGImageWithXImage(
} else {
TkMacOSXDbgMsg("Unsupported image type");
}
- if (provider) {
- CFRelease(provider);
- }
-
return img;
}
@@ -660,12 +671,11 @@ GetCGContextForDrawable(
kCGBitmapByteOrderDefault;
#endif
char *data;
- CGRect bounds = CGRectMake(0, 0, macDraw->size.width,
- macDraw->size.height);
+ CGRect bounds = CGRectMake(0, 0, macDraw->size.width, macDraw->size.height);
if (macDraw->flags & TK_IS_BW_PIXMAP) {
bitsPerPixel = 8;
- bitmapInfo = kCGImageAlphaOnly;
+ bitmapInfo = (CGBitmapInfo)kCGImageAlphaOnly;
} else {
colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
bitsPerPixel = 32;
@@ -738,6 +748,7 @@ DrawCGImage(
if (CGImageIsMask(image)) {
/*CGContextSaveGState(context);*/
if (macDraw->flags & TK_IS_BW_PIXMAP) {
+ /* Set fill color to black, background comes from the context, or is transparent. */
if (imageBackground != TRANSPARENT_PIXEL << 24) {
CGContextClearRect(context, dstBounds);
}
@@ -750,6 +761,7 @@ DrawCGImage(
TkMacOSXSetColorInContext(gc, imageForeground, context);
}
}
+
#ifdef TK_MAC_DEBUG_IMAGE_DRAWING
CGContextSaveGState(context);
CGContextSetLineWidth(context, 1.0);
@@ -1479,7 +1491,7 @@ TkScrollWindow(
{
Drawable drawable = Tk_WindowId(tkwin);
MacDrawable *macDraw = (MacDrawable *) drawable;
- NSView *view = TkMacOSXDrawableView(macDraw);
+ TKContentView *view = (TKContentView *)TkMacOSXDrawableView(macDraw);
CGRect srcRect, dstRect;
HIShapeRef dmgRgn = NULL, extraRgn = NULL;
NSRect bounds, visRect, scrollSrc, scrollDst;
diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c
index d30da09..f1e01d2 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 9671ab9..9c0f9d1 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);
-}
-
-- (void)preferences:(id)sender {
- PrefsHandler(NULL, NULL, (SRefCon) _eventInterp);
-}
-
-@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) terminate: (id) sender
{
- 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);
- }
- }
+ [self handleQuitApplicationEvent:Nil withReplyEvent:Nil];
}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXDoHLEvent --
- *
- * Dispatch incomming highlevel events.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Depends on the incoming event.
- *
- *----------------------------------------------------------------------
- */
-int
-TkMacOSXDoHLEvent(
- void *theEvent)
+- (void) preferences: (id) sender
{
- return AEProcessAppleEvent((EventRecord *)theEvent);
+ [self handleShowPreferencesEvent:Nil withReplyEvent:Nil];
}
-
-/*
- *----------------------------------------------------------------------
- *
- * QuitHandler --
- *
- * This is the 'quit' core Apple event handler.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-static OSErr
-QuitHandler(
- const AppleEvent *event,
- AppleEvent *reply,
- SRefCon handlerRefcon)
+- (void) handleQuitApplicationEvent: (NSAppleEventDescriptor *)event
+ withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
- 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
@@ -186,289 +67,292 @@ QuitHandler(
* quickly as possible.
*/
- eventPtr = (KillEvent *) ckalloc(sizeof(KillEvent));
+ eventPtr = (KillEvent*)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_CmdInfo dummy;
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
+ Tcl_Interp *interp = _eventInterp;
if (interp &&
- Tcl_GetCommandInfo(interp, "::tk::mac::OpenApplication", &dummy)){
- 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_BackgroundError(interp);
+ Tcl_BackgroundError(_eventInterp);
}
}
- 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_CmdInfo dummy;
- 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_GetCommandInfo(interp,
- "::tk::mac::ReopenApplication", &dummy)) {
- int code = Tcl_EvalEx(interp, "::tk::mac::ReopenApplication", -1, TCL_EVAL_GLOBAL);
+ SetFrontProcess(&thePSN);
+#else
+ [[NSApplication sharedApplication] activateIgnoringOtherApps: YES];
+#endif
+ if (_eventInterp && Tcl_FindCommand(_eventInterp,
+ "::tk::mac::ReopenApplication", NULL, 0)) {
+ int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ReopenApplication",
+ -1, TCL_EVAL_GLOBAL);
if (code != TCL_OK){
- Tcl_BackgroundError(interp);
+ Tcl_BackgroundError(_eventInterp);
}
}
- 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_CmdInfo dummy;
- Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
-
- if (interp &&
- Tcl_GetCommandInfo(interp, "::tk::mac::ShowPreferences", &dummy)){
- 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_BackgroundError(interp);
+ Tcl_BackgroundError(_eventInterp);
}
}
- 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;
- Tcl_CmdInfo dummy;
- 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_GetCommandInfo(interp, "::tk::mac::OpenDocument", &dummy)) {
- 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_BackgroundError(interp);
+ 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;
AEKeyword keyword;
Tcl_DString command, pathName;
- Tcl_CmdInfo dummy;
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_GetCommandInfo(interp, "::tk::mac::PrintDocument", &dummy)) {
- 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;
+
+ /* Get a copy of the AppleEvent's descriptor. */
+ AEGetParamDesc(fileSpecDesc, keyDirectObject, typeWildCard, &contents);
+ if (contents.descriptorType == typeAEList) {
+ fileSpecDesc = &contents;
}
- if (ChkErr(MissedAnyParameters, event) != noErr) {
- return noErr;
+
+ if (AECountItems(fileSpecDesc, &count) != noErr) {
+ AEDisposeDesc(&contents);
+ return;
}
- if (ChkErr(AECountItems, &fileSpecList, &count) != noErr) {
- return noErr;
- }
-
+
+ /*
+ * 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),
@@ -477,18 +361,19 @@ PrintHandler(
Tcl_BackgroundError(interp);
}
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.
@@ -496,108 +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) {
- tclErr = Tcl_EvalFile(interp, Tcl_DStringValue(&scriptName));
- Tcl_DStringFree(&scriptName);
- } 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(handleShowPreferencesEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEShowPreferences];
- 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:kAEOpenDocuments];
- 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(handleOpenDocumentsEvent:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEPrintDocuments];
+
+ [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
}
/*
@@ -616,7 +484,6 @@ ScriptHandler(
*
*----------------------------------------------------------------------
*/
-
static int
ReallyKillMe(
Tcl_Event *eventPtr,
@@ -666,38 +533,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/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c
index 8e278f7..d21389b 100644
--- a/macosx/tkMacOSXKeyEvent.c
+++ b/macosx/tkMacOSXKeyEvent.c
@@ -227,7 +227,7 @@ static unsigned isFunctionKey(unsigned int code);
-@implementation TKContentView(TKKeyEvent)
+@implementation TKContentView
/* <NSTextInput> implementation (called through interpretKeyEvents:]). */
/* <NSTextInput>: called when done composing;
@@ -293,22 +293,6 @@ static unsigned isFunctionKey(unsigned int code);
}
-/* delete display of composing characters [not in <NSTextInput>] */
-- (void)deleteWorkingText
-{
- if (privateWorkingText == nil)
- return;
- if (NS_KEYLOG)
- NSLog(@"deleteWorkingText len = %lu\n",
- (unsigned long)[privateWorkingText length]);
- [privateWorkingText release];
- privateWorkingText = nil;
- processingCompose = NO;
-
- //PENDING: delete working text
-}
-
-
- (BOOL)hasMarkedText
{
return privateWorkingText != nil;
@@ -418,6 +402,24 @@ static unsigned isFunctionKey(unsigned int code);
@end
+@implementation TKContentView(TKKeyEvent)
+/* delete display of composing characters [not in <NSTextInput>] */
+- (void)deleteWorkingText
+{
+ if (privateWorkingText == nil)
+ return;
+ if (NS_KEYLOG)
+ NSLog(@"deleteWorkingText len = %lu\n",
+ (unsigned long)[privateWorkingText length]);
+ [privateWorkingText release];
+ privateWorkingText = nil;
+ processingCompose = NO;
+
+ //PENDING: delete working text
+}
+@end
+
+
/*
* Set up basic fields in xevent for keyboard input.
diff --git a/macosx/tkMacOSXMenu.c b/macosx/tkMacOSXMenu.c
index c3121cb..3f4b3b5 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 10a615e..cd3eac1 100644
--- a/macosx/tkMacOSXMouseEvent.c
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -26,7 +26,7 @@ typedef struct {
static int GenerateButtonEvent(MouseEventData *medPtr);
static unsigned int ButtonModifiers2State(UInt32 buttonState,
- UInt32 keyModifiers);
+ UInt32 keyModifiers);
#pragma mark TKApplication(TKMouseEvent)
@@ -34,26 +34,41 @@ enum {
NSWindowWillMoveEventType = 20
};
+/*
+ * In OS X 10.6 an NSEvent of type NSMouseMoved would always have a non-Nil
+ * 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)
- (NSEvent *)tkProcessMouseEvent:(NSEvent *)theEvent {
#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:
-#if 0
- trackingArea = [theEvent trackingArea];
- /* fall through */
-#endif
case NSLeftMouseDown:
case NSLeftMouseUp:
case NSRightMouseDown:
@@ -75,24 +90,39 @@ 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];
NSPoint global, local = [theEvent locationInWindow];
- if (win) {
- global = [win convertBaseToScreen: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.y = tkMacOSXZeroScreenHeight - local.y;
- global = local;
+ } else { /* local will be in screen coordinates. */
+ if (_windowWithMouse ) {
+ eventWindow = _windowWithMouse;
+ global = local;
+ 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;
+ global = local;
+ }
}
- Window window = TkMacOSXGetXWindow(win);
+ Window window = TkMacOSXGetXWindow(eventWindow);
Tk_Window tkwin = window ? Tk_IdToWindow(TkGetDisplayList()->display,
window) : NULL;
if (!tkwin) {
@@ -120,7 +150,7 @@ enum {
state |= (buttons & ((1<<5) - 1)) << 8;
} else {
if (button < 5) {
- switch (type) {
+ switch (eventType) {
case NSLeftMouseDown:
case NSRightMouseDown:
case NSLeftMouseDragged:
@@ -157,12 +187,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;
@@ -178,7 +208,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));
@@ -186,7 +217,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));
@@ -357,7 +389,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;
@@ -455,7 +487,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 b93fa18..4891b32 100644
--- a/macosx/tkMacOSXPrivate.h
+++ b/macosx/tkMacOSXPrivate.h
@@ -272,6 +272,7 @@ VISIBILITY_HIDDEN
TKMenu *_defaultMainMenu, *_defaultApplicationMenu;
NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
NSArray *_defaultHelpMenuItems;
+ NSWindow *_windowWithMouse;
}
@end
@interface TKApplication(TKInit)
@@ -293,15 +294,33 @@ 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> {
@private
/*Remove private API calls.*/
- #if 0
+#if 0
id _savedSubviews;
BOOL _subviewsSetAside;
- #endif
+#endif
NSString *privateWorkingText;
}
@end
@@ -310,10 +329,27 @@ VISIBILITY_HIDDEN
- (void) deleteWorkingText;
@end
+@interface TKContentView(TKWindowEvent)
+- (void) drawRect: (NSRect) rect;
+- (void) generateExposeEvents: (HIShapeRef) shape;
+- (void) generateExposeEvents: (HIShapeRef) shape childrenOnly: (int) childrenOnly;
+- (void) viewDidEndLiveResize;
+- (void) tkToolbarButton: (id) sender;
+- (BOOL) isOpaque;
+- (BOOL) wantsDefaultClipping;
+- (BOOL) acceptsFirstResponder;
+- (void) keyDown: (NSEvent *) theEvent;
+@end
+
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)
@@ -342,5 +378,4 @@ VISIBILITY_HIDDEN
keyEquivalentModifierMask:(NSUInteger)keyEquivalentModifierMask;
@end
-
#endif /* _TKMACPRIV */
diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c
index 2f500fa..a601c50 100644
--- a/macosx/tkMacOSXSubwindows.c
+++ b/macosx/tkMacOSXSubwindows.c
@@ -805,9 +805,6 @@ TkMacOSXUpdateClipRgn(
/*
* TODO: Here we should handle out of process embedding.
*/
- } else if (winPtr->wmInfoPtr->attributes &
- kWindowResizableAttribute) {
- NSWindow *w = TkMacOSXDrawableWindow(winPtr->window);
}
macWin->aboveVisRgn = HIShapeCreateCopy(rgn);
diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c
index ef3c86b..0b32e7e 100644
--- a/macosx/tkMacOSXWindowEvent.c
+++ b/macosx/tkMacOSXWindowEvent.c
@@ -747,15 +747,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);
}
@@ -782,21 +783,6 @@ Tk_MacOSXIsAppInFront(void)
*
*/
-@interface TKContentView(TKWindowEvent)
-- (void) drawRect: (NSRect) rect;
-- (void) generateExposeEvents: (HIShapeRef) shape;
-- (void) generateExposeEvents: (HIShapeRef) shape childrenOnly: (int) childrenOnly;
-- (void) viewDidEndLiveResize;
-- (void) tkToolbarButton: (id) sender;
-- (BOOL) isOpaque;
-- (BOOL) wantsDefaultClipping;
-- (BOOL) acceptsFirstResponder;
-- (void) keyDown: (NSEvent *) theEvent;
-@end
-
-@implementation TKContentView
-@end
-
/*Restrict event processing to Expose events.*/
static Tk_RestrictAction
ExposeRestrictProc(
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 37a1d25..69d3cfb 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -200,6 +200,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:
*/
@@ -817,7 +859,7 @@ TkWmDeadWindow(
}
[pool drain];
}
- ckfree(wmPtr);
+ ckfree((char *)wmPtr);
winPtr->wmInfoPtr = NULL;
}
@@ -5194,22 +5236,22 @@ WmWinStyle(
{ "moveToActiveSpace", tkMoveToActiveSpaceAttribute },
{ "nonActivating", tkNonactivatingPanelAttribute },
{ "hud", tkHUDWindowAttribute },
- { "black", NULL },
- { "dark", NULL },
- { "light", NULL },
- { "gray", NULL },
- { "red", NULL },
- { "green", NULL },
- { "blue", NULL },
- { "cyan", NULL },
- { "yellow", NULL },
- { "magenta", NULL },
- { "orange", NULL },
- { "purple", NULL },
- { "brown", NULL },
- { "clear", NULL },
- { "opacity", NULL },
- { "fullscreen", NULL },
+ { "black", 0 },
+ { "dark", 0 },
+ { "light", 0 },
+ { "gray", 0 },
+ { "red", 0 },
+ { "green", 0 },
+ { "blue", 0 },
+ { "cyan", 0 },
+ { "yellow", 0 },
+ { "magenta", 0 },
+ { "orange", 0 },
+ { "purple", 0 },
+ { "brown", 0 },
+ { "clear", 0 },
+ { "opacity", 0 },
+ { "fullscreen", 0 },
{ NULL }
};
diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c
index 0be5416..f8adf1e 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
@@ -890,6 +904,7 @@ XGetImage(
int format)
{
NSBitmapImageRep *bitmap_rep;
+ NSUInteger bitmap_fmt;
XImage * imagePtr = NULL;
char * bitmap = NULL;
char * image_data=NULL;
@@ -908,10 +923,11 @@ XGetImage(
}
bitmap_rep = BitmapRepFromDrawableRect(d, x, y,width, height);
+ bitmap_fmt = [bitmap_rep bitmapFormat];
- if ( bitmap_rep == Nil ||
- [bitmap_rep bitmapFormat] != 0 ||
- [bitmap_rep samplesPerPixel] != 4 ||
+ if ( bitmap_rep == Nil ||
+ (bitmap_fmt != 0 && bitmap_fmt != 1) ||
+ [bitmap_rep samplesPerPixel] != 4 ||
[bitmap_rep isPlanar] != 0 ) {
TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
return NULL;
@@ -920,10 +936,9 @@ XGetImage(
NSSize image_size = NSMakeSize(width, height);
NSImage* ns_image = [[NSImage alloc]initWithSize:image_size];
[ns_image addRepresentation:bitmap_rep];
-
- /* Assume premultiplied nonplanar data with 4 bytes per pixel and alpha last.*/
- if ( [bitmap_rep bitmapFormat] == 0 &&
- [bitmap_rep isPlanar ] == 0 &&
+
+ /* Assume premultiplied nonplanar data with 4 bytes per pixel.*/
+ if ( [bitmap_rep isPlanar ] == 0 &&
[bitmap_rep samplesPerPixel] == 4 ) {
bytes_per_row = [bitmap_rep bytesPerRow];
size = bytes_per_row*height;
@@ -933,14 +948,27 @@ XGetImage(
bitmap = ckalloc(size);
/*
Oddly enough, the bitmap has the top row at the beginning,
- and the pixels are in BGRA format.
+ and the pixels are in BGRA or ABGR format.
*/
- for (row=0, n=0; row<height; row++, n+=bytes_per_row) {
- for (m=n; m<n+bytes_per_row; m+=4) {
- *(bitmap+m) = *(image_data+m+2);
- *(bitmap+m+1) = *(image_data+m+1);
- *(bitmap+m+2) = *(image_data+m);
- *(bitmap+m+3) = *(image_data+m+3);
+ if (bitmap_fmt == 0) {
+ /* BGRA */
+ for (row=0, n=0; row<height; row++, n+=bytes_per_row) {
+ for (m=n; m<n+bytes_per_row; m+=4) {
+ *(bitmap+m) = *(image_data+m+2);
+ *(bitmap+m+1) = *(image_data+m+1);
+ *(bitmap+m+2) = *(image_data+m);
+ *(bitmap+m+3) = *(image_data+m+3);
+ }
+ }
+ } else {
+ /* ABGR */
+ for (row=0, n=0; row<height; row++, n+=bytes_per_row) {
+ for (m=n; m<n+bytes_per_row; m+=4) {
+ *(bitmap+m) = *(image_data+m+3);
+ *(bitmap+m+1) = *(image_data+m+2);
+ *(bitmap+m+2) = *(image_data+m+1);
+ *(bitmap+m+3) = *(image_data+m);
+ }
}
}
}