From 5c1cdea3c6f8c5203e3e5e069fc9f404d077a817 Mon Sep 17 00:00:00 2001 From: daboe01 Date: Fri, 8 Jul 2016 21:34:14 +0200 Subject: [PATCH] Removed: Obsoleted Nativehost stuff --- AppKit/CPWindow/CPWindow.j | 3 +- CommonJS/lib/cappuccino/nativehost.js | 70 - .../UndoRedoWithMenuUpdate/AppController.j | 4 +- Tools/NativeHost/.gitignore | 5 - Tools/NativeHost/AppController+MainMenu.m | 33 - .../AppController+WebFrameLoadDelegate.m | 26 - .../AppController+WebPolicyDelegate.m | 35 - .../AppController+WebResourceLoadDelegate.m | 32 - .../NativeHost/AppController+WebUIDelegate.m | 71 - Tools/NativeHost/AppController.h | 54 - Tools/NativeHost/AppController.m | 221 --- Tools/NativeHost/Application.h | 18 - Tools/NativeHost/Application.m | 49 - Tools/NativeHost/BridgedMethods.h | 65 - Tools/NativeHost/BridgedMethods.m | 345 ----- Tools/NativeHost/Console.h | 21 - Tools/NativeHost/Console.m | 69 - .../English.lproj/InfoPlist.strings | Bin 92 -> 0 bytes Tools/NativeHost/English.lproj/MainMenu.cib | 1 - Tools/NativeHost/English.lproj/MainMenu.xib | 548 -------- Tools/NativeHost/Info.plist | 30 - Tools/NativeHost/Jakefile | 45 - Tools/NativeHost/MenuBridge.h | 22 - Tools/NativeHost/MenuBridge.m | 63 - Tools/NativeHost/MenuItemBridge.h | 24 - Tools/NativeHost/MenuItemBridge.m | 77 -- Tools/NativeHost/NSObject+WebAdditions.h | 16 - Tools/NativeHost/NSObject+WebAdditions.m | 19 - Tools/NativeHost/NSURL+Additions.h | 17 - Tools/NativeHost/NSURL+Additions.m | 36 - .../NativeHost.xcodeproj/TemplateIcon.icns | Bin 52318 -> 0 bytes .../NativeHost.xcodeproj/project.pbxproj | 424 ------ Tools/NativeHost/NativeHost_Prefix.pch | 8 - Tools/NativeHost/SSCrypto.h | 116 -- Tools/NativeHost/SSCrypto.m | 1214 ----------------- Tools/NativeHost/Server.h | 21 - Tools/NativeHost/Server.m | 193 --- Tools/NativeHost/WebPasteboardProxy.h | 19 - Tools/NativeHost/WebPasteboardProxy.m | 95 -- Tools/NativeHost/WebScripObject+Objective-J.h | 22 - Tools/NativeHost/WebScripObject+Objective-J.m | 46 - Tools/NativeHost/WebWindow.h | 44 - Tools/NativeHost/WebWindow.m | 515 ------- Tools/NativeHost/icon.icns | Bin 81151 -> 0 bytes Tools/NativeHost/main.m | 23 - .../Templates/NibApplication/Jakefile | 12 - 46 files changed, 3 insertions(+), 4768 deletions(-) delete mode 100644 CommonJS/lib/cappuccino/nativehost.js delete mode 100644 Tools/NativeHost/.gitignore delete mode 100644 Tools/NativeHost/AppController+MainMenu.m delete mode 100644 Tools/NativeHost/AppController+WebFrameLoadDelegate.m delete mode 100644 Tools/NativeHost/AppController+WebPolicyDelegate.m delete mode 100644 Tools/NativeHost/AppController+WebResourceLoadDelegate.m delete mode 100644 Tools/NativeHost/AppController+WebUIDelegate.m delete mode 100644 Tools/NativeHost/AppController.h delete mode 100644 Tools/NativeHost/AppController.m delete mode 100644 Tools/NativeHost/Application.h delete mode 100644 Tools/NativeHost/Application.m delete mode 100644 Tools/NativeHost/BridgedMethods.h delete mode 100644 Tools/NativeHost/BridgedMethods.m delete mode 100644 Tools/NativeHost/Console.h delete mode 100644 Tools/NativeHost/Console.m delete mode 100644 Tools/NativeHost/English.lproj/InfoPlist.strings delete mode 100644 Tools/NativeHost/English.lproj/MainMenu.cib delete mode 100644 Tools/NativeHost/English.lproj/MainMenu.xib delete mode 100644 Tools/NativeHost/Info.plist delete mode 100644 Tools/NativeHost/Jakefile delete mode 100644 Tools/NativeHost/MenuBridge.h delete mode 100644 Tools/NativeHost/MenuBridge.m delete mode 100644 Tools/NativeHost/MenuItemBridge.h delete mode 100644 Tools/NativeHost/MenuItemBridge.m delete mode 100644 Tools/NativeHost/NSObject+WebAdditions.h delete mode 100644 Tools/NativeHost/NSObject+WebAdditions.m delete mode 100644 Tools/NativeHost/NSURL+Additions.h delete mode 100644 Tools/NativeHost/NSURL+Additions.m delete mode 100644 Tools/NativeHost/NativeHost.xcodeproj/TemplateIcon.icns delete mode 100644 Tools/NativeHost/NativeHost.xcodeproj/project.pbxproj delete mode 100644 Tools/NativeHost/NativeHost_Prefix.pch delete mode 100644 Tools/NativeHost/SSCrypto.h delete mode 100644 Tools/NativeHost/SSCrypto.m delete mode 100644 Tools/NativeHost/Server.h delete mode 100644 Tools/NativeHost/Server.m delete mode 100644 Tools/NativeHost/WebPasteboardProxy.h delete mode 100644 Tools/NativeHost/WebPasteboardProxy.m delete mode 100644 Tools/NativeHost/WebScripObject+Objective-J.h delete mode 100644 Tools/NativeHost/WebScripObject+Objective-J.m delete mode 100644 Tools/NativeHost/WebWindow.h delete mode 100644 Tools/NativeHost/WebWindow.m delete mode 100644 Tools/NativeHost/icon.icns delete mode 100644 Tools/NativeHost/main.m diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index 9c4880938d..c9e8381aa8 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -308,7 +308,7 @@ CPTexturedBackgroundWindowMask [self setPlatformWindow:[CPPlatformWindow primaryPlatformWindow]]; else { - // give zero sized borderless bridge windows a default size if we're not in the browser so they show up in NativeHost. + // give zero sized borderless bridge windows a default size. if ((aStyleMask & CPBorderlessBridgeWindowMask) && aContentRect.size.width === 0 && aContentRect.size.height === 0) { var visibleFrame = [[[CPScreen alloc] init] visibleFrame]; @@ -655,7 +655,6 @@ CPTexturedBackgroundWindowMask CPBorderlessWindowMask CPTitledWindowMask CPClosableWindowMask - CPMiniaturizableWindowMask (NOTE: only available in NativeHost) CPResizableWindowMask CPTexturedBackgroundWindowMask CPBorderlessBridgeWindowMask diff --git a/CommonJS/lib/cappuccino/nativehost.js b/CommonJS/lib/cappuccino/nativehost.js deleted file mode 100644 index 8def876421..0000000000 --- a/CommonJS/lib/cappuccino/nativehost.js +++ /dev/null @@ -1,70 +0,0 @@ -var FILE = require("file"); -var OS = require("os"); - -var NATIVEHOST_SOURCE = FILE.path(module.path).dirname().dirname().dirname().join("support", "NativeHost.app"); - -exports.buildNativeHost = function(rootPath, buildNative, options) { - options = options || {}; - options.index = options.index || "index.html"; - - rootPath = FILE.path(rootPath); - buildNative = FILE.path(buildNative); - - if (buildNative.exists()) - buildNative.rmtree(); - - buildNative.dirname().mkdirs(); - // FIXME: Narwhal doesn't preserve permissions - // FILE.copyTree(NATIVEHOST_SOURCE, buildNative); - OS.system(["cp", "-r", NATIVEHOST_SOURCE, buildNative]); - FILE.chmod(buildNative.join("Contents", "MacOS", "NativeHost"), 0755); - - var rootBaseName = rootPath.basename(); - var buildClientDirectory = buildNative.join("Contents", "Resources", rootBaseName); - - FILE.mkdirs(FILE.dirname(buildClientDirectory)); - // FILE.copyTree(rootPath, buildClientDirectory); - OS.system(["cp", "-r", rootPath, buildClientDirectory]); - - var defaultBundleName = buildNative.basename().match(/^(.*)(\.app)?$/)[1]; - - function mergePlist(plist, path) { - var otherPlist = CFPropertyList.readPropertyListFromFile(String(path)); - - otherPlist.keys().forEach(function(key) { - var value = otherPlist.valueForKey(key); - plist.setValueForKey(key, value); - - if (key === "CPBundleName") - plist.setValueForKey("CFBundleName", value); - - if (key === "CFBundleIconFile") { - var iconPath = rootPath.join("Resources", value); - if (iconPath.isFile()) - iconPath.copy(buildNative.join("Contents", "Resources", value)); - else - print("Warning: CFBundleIconFile references " + value + " but does not exist in the resources directory."); - } - - if (key === "CFBundleExecutable") { - buildNative.join("Contents", "MacOS", "NativeHost").rename(value); - // FIXME: - FILE.chmod(buildNative.join("Contents", "MacOS", value), 0755); - } - }); - } - - CFPropertyList.modifyPlist(buildNative.join("Contents", "Info.plist"), function(plist) { - - plist.setValueForKey("CFBundleName", defaultBundleName); - plist.setValueForKey("NHInitialResource", FILE.join(rootBaseName, options.index)); - - // merge Cappuccino plist - var cappPlistPath = rootPath.join("Info.plist"); - if (cappPlistPath.isFile()) - mergePlist(plist, cappPlistPath); - - if (options.extraPlistPath) - mergePlist(plist, options.extraPlistPath); - }); -} diff --git a/Tests/Manual/UndoRedoWithMenuUpdate/AppController.j b/Tests/Manual/UndoRedoWithMenuUpdate/AppController.j index 8eb7177512..a7df347959 100644 --- a/Tests/Manual/UndoRedoWithMenuUpdate/AppController.j +++ b/Tests/Manual/UndoRedoWithMenuUpdate/AppController.j @@ -142,7 +142,7 @@ [_menuItemView setDirty]; } -// Performs autoenable processing, returns isEnabled to propagate state to NativeHost +// Performs autoenable processing, returns isEnabled to propagate state - (BOOL)_performAutoenable { if ([_menu autoenablesItems]) @@ -162,7 +162,7 @@ } else { - // XXX: will toggle state as part of _target check, required to sync stane with NativeHost + // XXX: will toggle state as part of _target check _isEnabled = isEnabled; [_menuItemView setDirty]; diff --git a/Tools/NativeHost/.gitignore b/Tools/NativeHost/.gitignore deleted file mode 100644 index f921bd442f..0000000000 --- a/Tools/NativeHost/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.DS_Store -*.mode1v3 -*.pbxuser -*.perspectivev3 -build diff --git a/Tools/NativeHost/AppController+MainMenu.m b/Tools/NativeHost/AppController+MainMenu.m deleted file mode 100644 index dbc98e63e3..0000000000 --- a/Tools/NativeHost/AppController+MainMenu.m +++ /dev/null @@ -1,33 +0,0 @@ -// -// AppController+MainMenu.m -// NativeHost -// -// Created by Francisco Tolmasky on 9/2/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import - -#import "MenuBridge.h" -#import "AppController.h" - - -@interface NSApplication (MenuMethods) - -- (void)setAppleMenu:(NSMenu *)aMenu; - -@end - -@implementation AppController (MainMenu) - -- (void)setMainMenuObject:(WebScriptObject *)aMenuObject -{ - NSMenu * mainMenu = [[MenuBridge alloc] initWithMenuObject:aMenuObject]; - - [NSApp setAppleMenu:[[mainMenu itemArray] objectAtIndex:0]]; - [NSApp setMainMenu:mainMenu]; - - [mainMenu release]; -} - -@end diff --git a/Tools/NativeHost/AppController+WebFrameLoadDelegate.m b/Tools/NativeHost/AppController+WebFrameLoadDelegate.m deleted file mode 100644 index fdce4d601d..0000000000 --- a/Tools/NativeHost/AppController+WebFrameLoadDelegate.m +++ /dev/null @@ -1,26 +0,0 @@ - - -// -// AppController+WebFrameLoadDelegate.m -// NativeHost -// -// Created by Francisco Tolmasky on 7/28/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import "AppController.h" - -#import "BridgedMethods.h" - - -@implementation AppController (WebFrameLoadDelegate) - -- (void)webView:(WebView *)aWebView didClearWindowObject:(WebScriptObject *)aWindowObject forFrame:(WebFrame *)aFrame -{ - if (aWebView == webView) - [GlobalMethods enhanceWindowObject:aWindowObject ofWebView:aWebView]; - else - [WindowMethods enhanceWindowObject:aWindowObject ofWebView:aWebView]; -} - -@end diff --git a/Tools/NativeHost/AppController+WebPolicyDelegate.m b/Tools/NativeHost/AppController+WebPolicyDelegate.m deleted file mode 100644 index 2c098dcd01..0000000000 --- a/Tools/NativeHost/AppController+WebPolicyDelegate.m +++ /dev/null @@ -1,35 +0,0 @@ -// -// AppController+WebPolicyDelegate.m -// NativeHost -// -// Created by Francisco Tolmasky on 5/11/10. -// Copyright 2010 280 North, Inc. All rights reserved. -// - -#import "NSURL+Additions.h" -#import "AppController.h" - - -@implementation AppController (WebPolicyDelegate) - -- (void)webView:(WebView *)aWebView decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)aRequest newFrameName:(NSString *)aFrameName decisionListener:(id /*< WebPolicyDecisionListener >*/)aListener -{ - [[NSWorkspace sharedWorkspace] openURL:[actionInformation objectForKey:WebActionOriginalURLKey]]; - [aListener ignore]; -} - -- (void)webView:(WebView *)aWebView decidePolicyForNavigationAction:(NSDictionary *)aDictionary request:(NSURLRequest *)aRequest frame:(WebFrame *)aWebFrame decisionListener:(id /**/)aDecisionListener -{ - NSURL * requestURL = [aRequest URL]; - - if([aWebView mainFrame] != aWebFrame || - [[baseURL scheme] isEqualTo:[requestURL scheme]] && - ![baseURL host] || [[baseURL host] isEqualTo:[requestURL host]] && - ![baseURL port] || [[baseURL port] isEqualTo:[requestURL port]]) - return [aDecisionListener use]; - - [[NSWorkspace sharedWorkspace] openURL:[aDictionary objectForKey:WebActionOriginalURLKey]]; - [aDecisionListener ignore]; -} - -@end diff --git a/Tools/NativeHost/AppController+WebResourceLoadDelegate.m b/Tools/NativeHost/AppController+WebResourceLoadDelegate.m deleted file mode 100644 index a60540b75c..0000000000 --- a/Tools/NativeHost/AppController+WebResourceLoadDelegate.m +++ /dev/null @@ -1,32 +0,0 @@ -// -// AppController+WebResourceLoadDelegate.m -// NativeHost -// -// Created by Francisco Tolmasky on 7/28/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import "AppController.h" -#import "SSCrypto.h" - -NSString *authHeader = nil; - -@implementation AppController (WebResourceLoadDelegate) - -- (NSURLRequest *)webView:(WebView *)aSender resource:(id)anIdentifier willSendRequest:(NSURLRequest *)aRequest redirectResponse:(NSURLResponse *)aRedirectResponse fromDataSource:(WebDataSource *)aDataSource -{ - aRequest = [[aRequest mutableCopy] autorelease]; - - if (!authHeader) - { - NSString *plaintext = [NSString stringWithFormat:@"%@:%@", SERVER_USER, SERVER_PASSWORD]; - NSData *data = [plaintext dataUsingEncoding:NSASCIIStringEncoding]; - authHeader = [[NSString alloc] initWithFormat:@"Basic %@", [data encodeBase64WithNewlines:NO]]; - } - - [(NSMutableURLRequest *)aRequest setValue:authHeader forHTTPHeaderField:@"Authorization"]; - - return aRequest; -} - -@end diff --git a/Tools/NativeHost/AppController+WebUIDelegate.m b/Tools/NativeHost/AppController+WebUIDelegate.m deleted file mode 100644 index a75f9d6a98..0000000000 --- a/Tools/NativeHost/AppController+WebUIDelegate.m +++ /dev/null @@ -1,71 +0,0 @@ -// -// AppController+WebUIDelegate.m -// NativeHost -// -// Created by Francisco Tolmasky on 7/28/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import "AppController.h" -#import "WebWindow.h" - - -@implementation AppController (WebUIDelegate) - -- (void)webView:(WebView *)aWebView setFrame:(NSRect)aFrame -{ - [[aWebView window] setFrame:aFrame display:YES]; -} - -- (NSRect)webViewFrame:(WebView *)aWebView -{ - return [[aWebView window] frame]; -} - -- (WebView *)webView:(WebView *)aWebView createWebViewWithRequest:(NSURLRequest *)aRequest -{ - return [[WebWindow webWindow] webView]; -} - -- (void)webViewClose:(WebView *)aWebView -{ - // Important to call close and not: - // -performClose:, which beeps without the presence of a close button. - // -orderOut:, which doesn't release the window. - [[aWebView window] close]; - //[[aWebView window] orderOut:self]; -} - -- (void)webViewShow:(WebView *)aWebView -{ - [[aWebView window] makeKeyAndOrderFront:self]; -} - -- (NSAttributedString *)loggedOutput; -{ - return loggedOutput; -} - -- (void)webView:(WebView *)aWebView addMessageToConsole:(NSDictionary *)aDictionary -{ - NSString * message = [aDictionary objectForKey:@"message"]; - NSAttributedString * attributedString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@\n", message, nil]]; - - [loggedOutput appendAttributedString:attributedString]; - - [attributedString release]; - NHLog(@"CONSOLE", message); -} - -- (void)webView:(WebView *)aSender runJavaScriptAlertPanelWithMessage:(NSString *)aMessage initiatedByFrame:(WebFrame *)aFrame -{ - WebDataSource * dataSource = [aFrame dataSource]; - NSString * title = [dataSource pageTitle]; - - if (![title length]) - title = [[[dataSource request] URL] absoluteString]; - - [[NSAlert alertWithMessageText:title defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", aMessage, nil] runModal]; -} - -@end diff --git a/Tools/NativeHost/AppController.h b/Tools/NativeHost/AppController.h deleted file mode 100644 index 69e1d23585..0000000000 --- a/Tools/NativeHost/AppController.h +++ /dev/null @@ -1,54 +0,0 @@ -// -// AppController.h -// NativeHost -// -// Created by Francisco Tolmasky on 6/4/09. -// Copyright 2009 280 North, Inc. All rights reserved. -// - -#import - -extern int SERVER_PORT; -extern NSString *SERVER_PASSWORD; -extern NSString *SERVER_USER; - -@class Server; -@class WebScriptObject; - -@interface AppController : NSObject -{ - NSWindow * webViewWindow; - WebView * webView; - - NSMutableArray * openingFilenames; - NSMutableArray * openingURLStrings; - - Server * server; - NSFileHandle * stdinFileHandle; - - NSMutableAttributedString * loggedOutput; - - NSURL * baseURL; -} - -- (void)configureLocalStorage; -- (NSURL *)baseURL; - -- (void)startServer; -- (void)startCappuccinoApplication; - -- (NSArray *)openingURLStrings; - -- (NSView *)keyView; -- (WebView *)webView; -- (WebScriptObject *)windowScriptObject; - -@end - -@interface AppController (MainMenu) - -- (void)setMainMenuObject:(WebScriptObject *)aMenuObject; - -@end - -void NHLog(NSString *type, NSString *message); \ No newline at end of file diff --git a/Tools/NativeHost/AppController.m b/Tools/NativeHost/AppController.m deleted file mode 100644 index fa64a749de..0000000000 --- a/Tools/NativeHost/AppController.m +++ /dev/null @@ -1,221 +0,0 @@ -// -// AppController.m -// NativeHost -// -// Created by Francisco Tolmasky on 6/4/09. -// Copyright 2009 280 North, Inc. All rights reserved. -// - -#import "Console.h" -#import "Server.h" -#import "AppController.h" -#import "NSURL+Additions.h" -#import "BridgedMethods.h" -#import "WebWindow.h" -#import "WebScripObject+Objective-J.h" - -extern int interactive; - -int SERVER_PORT = 9191; -NSString *SERVER_PASSWORD = nil; -NSString *SERVER_USER = nil; - - -@implementation AppController - -- (id)init -{ - self = [super init]; - - if (self) - openingURLStrings = [NSMutableArray new]; - - return self; -} - -- (void)dealloc -{ - [webView release]; - [webViewWindow release]; - - [openingURLStrings release]; - - [super dealloc]; -} - -- (BOOL)application:(NSApplication *)anApplication openFile:(NSString *)aFilename -{ - id canOpenFilesImmediately = [[webView windowScriptObject] evaluateWebScript:@"CPApp && CPApp._finishedLaunching"]; - - NSString *path = [[[NSURL fileURLWithPath:aFilename] HTTPFileSystemURL] absoluteString]; - if ([canOpenFilesImmediately isKindOfClass:[NSNumber class]] && [canOpenFilesImmediately boolValue]) - [[webView windowScriptObject] evaluateObjectiveJ:[NSString stringWithFormat:@"[CPApp _openURL:[CPURL URLWithString:\"%@\"]]", path]]; - else - [openingURLStrings addObject:path]; - - return NO; -} - -- (void)applicationWillFinishLaunching:(NSNotification *)aNotification -{ - NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; - - [defaults registerDefaults:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:@"WebKitDeveloperExtras"]]; - - [self startServer]; -} - -- (void)applicationDidFinishLaunching:(NSNotification *)notification -{ - [self startCappuccinoApplication]; -} - -- (void)applicationDidResignActive:(NSNotification *)aNotification -{ - // FIXME: handle this better. - [[self windowScriptObject] evaluateObjectiveJ:@"[CPApp _willResignActive];"]; - [[self windowScriptObject] evaluateObjectiveJ:@"CPApp._isActive = NO;"]; - [[self windowScriptObject] evaluateObjectiveJ:@"[CPApp _didResignActive];"]; -} - -- (void)applicationDidBecomeActive:(NSNotification *)aNotification -{ - // FIXME: handle this better. - [[self windowScriptObject] evaluateObjectiveJ:@"[CPApp _willBecomeActive];"]; - [[self windowScriptObject] evaluateObjectiveJ:@"CPApp._isActive = YES;"]; - [[self windowScriptObject] evaluateObjectiveJ:@"[CPApp _didBecomeActive];"]; -} - -- (NSArray *)openingURLStrings -{ - return openingURLStrings; -} - -- (NSView *)keyView -{ - return [[[webView mainFrame] frameView] documentView]; -} - -- (WebView *)webView -{ - return webView; -} - -- (WebScriptObject *)windowScriptObject -{ - return [webView windowScriptObject]; -} - -- (void)startServer -{ - server = [[Server alloc] init]; - - if (![server start]) - exit(0); - - if (interactive) - { - stdinFileHandle = [[NSFileHandle fileHandleWithStandardInput] retain]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(didReadStdin:) - name:NSFileHandleReadCompletionNotification - object:stdinFileHandle]; - - fprintf(stdout, "objj> "); - fflush(stdout); - [stdinFileHandle readInBackgroundAndNotify]; - } -} - -- (void)didReadStdin:(NSNotification *)aNotification -{ - NSString *string = [[NSString alloc] initWithData:[[aNotification userInfo] objectForKey:NSFileHandleNotificationDataItem] encoding:NSASCIIStringEncoding]; - NSString *result = [[self windowScriptObject] evaluateObjectiveJReturningString:string]; - [string release]; - if ([result respondsToSelector:@selector(UTF8String)]) - fprintf(stdout, "%s\n", [result UTF8String]); - fprintf(stdout, "objj> "); - fflush(stdout); - [stdinFileHandle readInBackgroundAndNotify]; -} - -- (NSURL *)baseURL -{ - return baseURL; -} - -- (void)startCappuccinoApplication -{ - NSString *initialURL = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NHInitialURL"]; - BOOL prependServer = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"NHInitialURLPrependServer"] boolValue]; - - if (!initialURL) - { - NSString *initialResource = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NHInitialResource"]; - - if (!initialResource) - initialResource = @"Application/index.html"; - - initialURL = [[NSString stringWithFormat:@"file://%@/%@", [[NSBundle mainBundle] resourcePath], initialResource] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - baseURL = [[NSURL alloc] initWithString:@"file:///"]; - } - else if (prependServer) - { - initialURL = [NSString stringWithFormat:@"http://127.0.0.1:%d/%@", SERVER_PORT, initialURL]; - baseURL = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", SERVER_PORT]]; - } - - NHLog(@"STARTUP", [initialURL description]); - - [[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:initialURL]]]; -} - -- (void)applicationWillTerminate:(NSNotification *)aNotification -{ - [server stop]; -} - -- (void)configureLocalStorage -{ - WebPreferences *webConfiguration = [WebPreferences standardPreferences]; - NSBundle *mainBundle = [NSBundle mainBundle]; - NSString *cappBundleName = [mainBundle objectForInfoDictionaryKey:@"CPBundleName"]; - NSString *applicationSupportFile = [@"~/Library/Application Support/" stringByExpandingTildeInPath]; - NSString *savePath = [NSString pathWithComponents:[NSArray arrayWithObjects:applicationSupportFile, cappBundleName, @"LocalStorage", nil]]; - - if ([webConfiguration respondsToSelector:@selector(setLocalStorageDatabasePath:)]) - [webConfiguration setLocalStorageDatabasePath:savePath]; - else - [webConfiguration _setLocalStorageDatabasePath:savePath]; - - [webView setPreferences:webConfiguration]; -} - -- (void)awakeFromNib -{ - webView = [[WebView alloc] init]; - - [webView setUIDelegate:self]; - [webView setFrameLoadDelegate:self]; - [webView setResourceLoadDelegate:self]; - [webView setPolicyDelegate:self]; - - [self configureLocalStorage]; - - webViewWindow = [[NSWindow alloc] init]; - - [webViewWindow setContentView:webView]; -} - -@end - -void NHLog(NSString *type, NSString *message) -{ - NSArray *lines = [message componentsSeparatedByString:@"\n"]; - for (NSString *line in lines) - { - if ([line length] > 0) - NSLog(@"%10@: %@", type, line); - } -} diff --git a/Tools/NativeHost/Application.h b/Tools/NativeHost/Application.h deleted file mode 100644 index d09086a9ff..0000000000 --- a/Tools/NativeHost/Application.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// Application.h -// NativeHost -// -// Created by Francisco Tolmasky on 10/8/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import - - -@interface Application : NSApplication -{ -} - -- (void)_reallyTerminate:(id)sender; - -@end diff --git a/Tools/NativeHost/Application.m b/Tools/NativeHost/Application.m deleted file mode 100644 index 2234f307de..0000000000 --- a/Tools/NativeHost/Application.m +++ /dev/null @@ -1,49 +0,0 @@ -// -// Application.m -// NativeHost -// -// Created by Francisco Tolmasky on 10/8/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import "Application.h" -#import "AppController.h" -#import "WebScripObject+Objective-J.h" -#import "WebWindow.h" - -@implementation Application - -- (void)sendEvent:(NSEvent *)anEvent -{ - [WebWindow enableAllWindows]; - - NSWindow * window = [anEvent window]; - - if (!window || [window isKindOfClass:[WebWindow class]]) - { - NSResponder * firstResponder = window ? [window firstResponder] : [(AppController *)[self delegate] keyView]; - - switch ([anEvent type]) - { - case NSKeyDown: return [firstResponder keyDown:anEvent]; - case NSKeyUp: return [firstResponder keyUp:anEvent]; - } - } - - [super sendEvent:anEvent]; -} - -- (void)terminate:(id)sender -{ - if ([[[self delegate] windowScriptObject] evaluateObjectiveJ:@"(CPApp)"] == [WebUndefined undefined]) - [self _reallyTerminate:sender]; - else - [[(AppController *)[self delegate] windowScriptObject] evaluateObjectiveJ:@"[CPApp terminate:nil]"]; -} - -- (void)_reallyTerminate:(id)sender -{ - [super terminate:sender]; -} - -@end diff --git a/Tools/NativeHost/BridgedMethods.h b/Tools/NativeHost/BridgedMethods.h deleted file mode 100644 index a9af18f1f6..0000000000 --- a/Tools/NativeHost/BridgedMethods.h +++ /dev/null @@ -1,65 +0,0 @@ -// -// BridgedMethods.h -// NativeHost -// -// Created by Francisco Tolmasky on 10/16/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import - - -@interface BridgedMethods : NSObject -{ - WebView * webView; -} -+ (NSMutableArray *)arrayFromWebScriptObject:(WebScriptObject *)incomingObject; -+ (void)enhanceWindowObject:(WebScriptObject *)aWindowObject ofWebView:(WebView *)aWebView; -@end - -@interface GlobalMethods : BridgedMethods -{ -} -- (id)isDesktop; - -- (id)openingURLStrings; - -- (id)setMainMenu:(id)arguments; - -- (id)terminate; -- (id)activateIgnoringOtherApps:(NSArray *)arguments; -- (id)deactivate; -- (id)hide; -- (id)hideOtherApplications; - -- (id)savePanel:(NSArray *)arguments; // FIXME: This should be implemented in Cappuccino. -- (id)openPanel; // FIXME: This should be implemented in Cappuccino. - -- (id)clearRecentDocuments; -- (id)noteNewRecentDocumentPath:(NSArray *)aURL; -- (id)recentDocumentURLs; - -- (id)pasteboardWithName:(NSArray *)arguments; - -@end - -@interface WindowMethods : BridgedMethods -{ -} -- (id)miniaturize; -- (id)deminiaturize; - -- (id)level; -- (id)setLevel:(NSArray *)arguments; - -- (id)hasShadow; -- (id)setHasShadow:(NSArray *)arguments; - -- (id)shadowStyle; -- (id)setShadowStyle:(NSArray *)arguments; - -- (id)frame; -- (id)setFrame:(NSArray *)arguments; - -@end - diff --git a/Tools/NativeHost/BridgedMethods.m b/Tools/NativeHost/BridgedMethods.m deleted file mode 100644 index 7e637692a2..0000000000 --- a/Tools/NativeHost/BridgedMethods.m +++ /dev/null @@ -1,345 +0,0 @@ -// -// BridgedMethods.m -// NativeHost -// -// Created by Francisco Tolmasky on 10/16/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - - -#import -#import "Application.h" -#import "AppController.h" -#import "BridgedMethods.h" -#import "NSObject+WebAdditions.h" -#import "NSURL+Additions.h" -#import "WebWindow.h" -#import "WebPasteboardProxy.h" - -static NSMutableDictionary * MethodClasses; - -@implementation GlobalMethods - -- (id)isDesktop -{ - return [NSNumber numberWithBool:YES]; -} - -- (id)openingURLStrings -{ - return [(AppController *)[NSApp delegate] openingURLStrings]; -} - -- (id)setMainMenu:(id)arguments -{ - [[NSApp delegate] setMainMenuObject:[arguments objectAtIndex:0]]; - - return [WebUndefined undefined]; -} - -- (id)terminate -{ - [(Application *)NSApp _reallyTerminate:self]; - - return [WebUndefined undefined]; -} - -- (id)activateIgnoringOtherApps:(NSArray *)arguments -{ - id argument = [arguments objectAtIndex:0]; - - [(NSApplication *)NSApp activateIgnoringOtherApps:[argument isKindOfClass:[NSNumber class]] && [(NSNumber *)argument boolValue]]; - - return [WebUndefined undefined]; -} - -- (id)deactivate -{ - [(NSApplication *)NSApp deactivate]; - return [WebUndefined undefined]; -} - -- (id)hide -{ - [NSApp hide:self]; - return [WebUndefined undefined]; -} - -- (id)hideOtherApplications -{ - [NSApp hideOtherApplications:self]; - return [WebUndefined undefined]; -} - -- (id)openPanel -{ - NSOpenPanel * openPanel = [NSOpenPanel openPanel]; - - NSInteger result = [openPanel runModal]; - - NSMutableString * resultObject = [NSMutableString stringWithFormat:@"({ button:%d, URLs:", result]; - - NSMutableArray * fileSystemURLs = [NSMutableArray array]; - - for (NSURL * URL in [openPanel URLs]) - [fileSystemURLs addObject:[URL HTTPFileSystemURL]]; - - if (result == NSFileHandlingPanelOKButton) - [resultObject appendString:[NSString stringWithFormat:@"[\"%@\"] })", [fileSystemURLs componentsJoinedByString:@"\", \""]]]; - - else - [resultObject appendString:@"[] })"]; - - return [[webView windowScriptObject] evaluateWebScript:resultObject]; -} - -- (id)savePanel:(NSArray *)arguments -{ - NSSavePanel * savePanel = [NSSavePanel savePanel]; - WebScriptObject *args = [arguments objectAtIndex:0]; - - [savePanel setAllowedFileTypes:[BridgedMethods arrayFromWebScriptObject:[args valueForKey:@"allowedFileTypes"]]]; - - id allowsOtherFileTypes = [args valueForKey:@"allowsOtherFileTypes"]; - - [savePanel setAllowsOtherFileTypes:allowsOtherFileTypes && [allowsOtherFileTypes webBoolValue]]; - - id isExtensionHidden = [args valueForKey:@"isExtensionHidden"]; - - [savePanel setExtensionHidden:isExtensionHidden && [isExtensionHidden webBoolValue]]; - - id canSelectHiddenExtension = [args valueForKey:@"canSelectHiddenExtension"]; - - [savePanel setCanSelectHiddenExtension:canSelectHiddenExtension && canSelectHiddenExtension]; - - id canCreateDirectories = [args valueForKey:@"canCreateDirectories"]; - - [savePanel setCanCreateDirectories:canCreateDirectories && [canCreateDirectories webBoolValue]]; - - NSInteger result = [savePanel runModal]; - - return [[webView windowScriptObject] evaluateWebScript:[NSString stringWithFormat:@"({ button:%d, URL:\"%@\" })", result, [[[savePanel URL] HTTPFileSystemURL] absoluteString]]]; -} - -- (id)clearRecentDocuments -{ - [[NSDocumentController sharedDocumentController] clearRecentDocuments:self]; - return [WebUndefined undefined]; -} - -- (id)noteNewRecentDocumentPath:(NSArray *)arguments -{ - if (![arguments count]) - return [WebUndefined undefined]; - - NSString *aURL = [arguments objectAtIndex:0]; - NSURL *fileURL = [NSURL fileSystemURLFromHTTPFileSystemString:aURL]; - - [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:fileURL]; - - return [WebUndefined undefined]; -} - -- (id)recentDocumentURLs -{ - NSArray *existingURLs = [[NSDocumentController sharedDocumentController] recentDocumentURLs]; - NSMutableArray *urlsAsStrings = [NSMutableArray array]; - - for (int i=0, count = [existingURLs count]; i < count; i++) - [urlsAsStrings addObject:[[existingURLs objectAtIndex:i] absoluteString]]; - - return urlsAsStrings; -} - -- (id)pasteboardWithName:(NSArray *)arguments -{ - if (![arguments count]) - return [WebUndefined undefined]; - - return [WebPasteboardProxy pasteboardWithName:[arguments objectAtIndex:0]]; -} - -@end - -@implementation WindowMethods - -- (id)miniaturize -{ - [[webView window] miniaturize:nil]; - return [WebUndefined undefined]; -} - -- (id)deminiaturize -{ - [[webView window] deminiaturize:nil]; - return [WebUndefined undefined]; -} - -- (id)level -{ - return [NSNumber numberWithInt:[[webView window] level]]; -} - -- (id)setLevel:(NSArray *)arguments -{ - [[webView window] setLevel:[[arguments objectAtIndex:0] intValue]]; - - return [WebUndefined undefined]; -} - -- (id)hasShadow -{ - return [NSNumber numberWithBool:[[webView window] hasShadow]]; -} - -- (id)setHasShadow:(NSArray *)arguments -{ - [[webView window] setHasShadow:[[arguments objectAtIndex:0] boolValue]]; - - return [WebUndefined undefined]; -} - -- (id)frame -{ - NSRect frame = [[webView window] frame]; - - return [[webView windowScriptObject] evaluateWebScript:[NSString stringWithFormat:@"({ origin:{%f, %f}, size:{%f, %f}})", NSMinX(frame), NSMinY(frame), NSWidth(frame), NSHeight(frame)]]; -} - -- (id)setFrame:(NSArray *)arguments -{ - id origin = [[arguments objectAtIndex:0] valueForKey:@"origin"], - size = [[arguments objectAtIndex:0] valueForKey:@"size"]; - - NSWindow * window = [webView window]; - NSScreen * screen = [window screen]; - - if (!screen) - screen = [NSScreen mainScreen]; // Is this correct? - - float height = [[size valueForKey:@"height"] floatValue]; - - [[webView window] setFrame:NSMakeRect([[origin valueForKey:@"x"] floatValue], NSMaxY([screen frame]) - [[origin valueForKey:@"y"] floatValue] - height, [[size valueForKey:@"width"] floatValue], height) display:YES]; - /* - NSLog([webView description]); - NSLog(@"%@ %@", [window screen], NSStringFromRect([window frame])); - NSLog(@"%f - %f - %f = %f", NSMaxY([[window screen] frame]), [[origin valueForKey:@"y"] floatValue], height, NSMaxY([[window screen] frame]) - [[origin valueForKey:@"y"] floatValue] - height); - NSLog(@"FROM: %@", NSStringFromRect(NSMakeRect([[origin valueForKey:@"x"] floatValue], [[origin valueForKey:@"y"] floatValue], [[size valueForKey:@"width"] floatValue], height))); - NSLog(@" TO: %@", NSStringFromRect([[webView window] frame])); - */ - - return [WebUndefined undefined]; -} - -- (id)shadowStyle -{ - WebWindow * window = (WebWindow *)[webView window]; - - return [NSNumber numberWithInt:[window shadowStyle]]; -} - -- (id)setShadowStyle:(id)arguments -{ - int type = [[arguments objectAtIndex:0] intValue]; - - WebWindow * window = (WebWindow *)[webView window]; - - [window setShadowStyle:type]; - - return [WebUndefined undefined]; -} - -@end - - -@interface WindowScriptObjectMethod : NSObject -{ - WebView * webView; -} - -- (id)initWithWebView:(WebView *)aWebView; - -@end - -@implementation WindowScriptObjectMethod - -- (id)initWithWebView:(WebView *)aWebView -{ - self = [super init]; - - if (self) - webView = aWebView; - - return self; -} - -@end - -@implementation BridgedMethods - -+ (NSMutableArray *)arrayFromWebScriptObject:(WebScriptObject *)incomingObject -{ - if (!incomingObject) - return nil; - - NSMutableArray * newItems = [[NSMutableArray alloc] init]; - - for (int i=0; [incomingObject webScriptValueAtIndex:i]!=[WebUndefined undefined]; i++) - { - id oneItem =[incomingObject webScriptValueAtIndex:i]; - [newItems addObject:oneItem]; - } - - return [newItems autorelease]; -} - -+ (void)enhanceWindowObject:(WebScriptObject *)aWindowObject ofWebView:(WebView *)aWebView -{ - NSDictionary * classMethods = [MethodClasses objectForKey:[self className]]; - NSString * key = nil; - NSEnumerator * keyEnumerator = [classMethods keyEnumerator]; - - while (key = [keyEnumerator nextObject]) - [aWindowObject setValue:[(WindowScriptObjectMethod *)[[[classMethods objectForKey:key] alloc] initWithWebView:aWebView] autorelease] forKey:key]; -} - -+ (void)bridgeMethod:(Method)aMethod dictionary:(NSMutableDictionary *)aDictionary -{ - NSString * methodName = NSStringFromSelector(method_getName(aMethod)), - * publicMethodName = [NSString stringWithFormat:@"cp%@", [[NSString stringWithFormat:@"%@%@", [[methodName substringToIndex:1] uppercaseString], [methodName substringFromIndex:1]] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@":"]]]; - - Class methodClass = objc_allocateClassPair([WindowScriptObjectMethod class], [[NSString stringWithFormat:@"WebScriptObjectMethod_%@", publicMethodName] cString], 0); - - class_addMethod(methodClass, @selector(invokeDefaultMethodWithArguments:), method_getImplementation(aMethod), "@@:@"); - - objc_registerClassPair(methodClass); - - [aDictionary setObject:methodClass forKey:publicMethodName]; -} - -+ (void)initialize -{ - if (!MethodClasses) - MethodClasses = [[NSMutableDictionary alloc] init]; - - NSMutableDictionary * dictionary = [[NSMutableDictionary alloc] init]; - - [MethodClasses setObject:dictionary forKey:[self className]]; - [dictionary release]; - - unsigned int methodCount = 0; - Method * methods = class_copyMethodList(self, &methodCount); - - if (!methods) - return; - - int index = 0; - - for (; index < methodCount; ++index) - [self bridgeMethod:methods[index] dictionary:dictionary]; - - free(methods); - methods = NULL; -} - -@end diff --git a/Tools/NativeHost/Console.h b/Tools/NativeHost/Console.h deleted file mode 100644 index a4d9b6c42c..0000000000 --- a/Tools/NativeHost/Console.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// Console.h -// NativeHost -// -// Created by Francisco Tolmasky on 6/16/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import - - -@interface Console : NSObject -{ - NSMutableAttributedString * contents; -} - -+ (id)sharedConsole; - -- (NSAttributedString *)contents; - -@end diff --git a/Tools/NativeHost/Console.m b/Tools/NativeHost/Console.m deleted file mode 100644 index 2118f999b4..0000000000 --- a/Tools/NativeHost/Console.m +++ /dev/null @@ -1,69 +0,0 @@ -// -// Console.m -// NativeHost -// -// Created by Francisco Tolmasky on 6/16/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import "Console.h" - -#import "AppController.h" - - -@implementation Console - -+ (id)sharedConsole -{ - static Console * console = nil; - - if (!console) - console = [[Console alloc] init]; - - return console; -} - -- (id)init -{ - self = [super init]; - - if (self) - contents = [[NSMutableAttributedString alloc] init]; - - return self; -} - -- (void)dealloc -{ - [contents release]; - [super dealloc]; -} - -- (NSAttributedString *)contents -{ - return contents; -} - -- (void)webView:(WebView *)aWebView addMessageToConsole:(NSDictionary *)aDictionary -{ - NSString * message = [aDictionary objectForKey:@"message"]; - - NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@\n", message, nil]]; - [contents appendAttributedString:attrString]; - [attrString release]; - - NHLog(@"CONSOLE", message); -} - -- (void)webView:(WebView *)aSender runJavaScriptAlertPanelWithMessage:(NSString *)aMessage initiatedByFrame:(WebFrame *)aFrame -{ - WebDataSource * dataSource = [aFrame dataSource]; - NSString * title = [dataSource pageTitle]; - - if (![title length]) - title = [[[dataSource request] URL] absoluteString]; - - [[NSAlert alertWithMessageText:title defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:aMessage, nil] runModal]; -} - -@end diff --git a/Tools/NativeHost/English.lproj/InfoPlist.strings b/Tools/NativeHost/English.lproj/InfoPlist.strings deleted file mode 100644 index 5e45963c382ba690b781b953a00585212b898ac5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92 zcmW-XQ3`+{5C!MkQ~2$No+IcIkqMDxWCV8j>LCj|yTg2Mz+o9F%uHlf9u}h9EuK`F a!Y*1dX%G66ZqL#C$|bw0ZoP5@jOGW1ArT7z diff --git a/Tools/NativeHost/English.lproj/MainMenu.cib b/Tools/NativeHost/English.lproj/MainMenu.cib deleted file mode 100644 index 36815f025f..0000000000 --- a/Tools/NativeHost/English.lproj/MainMenu.cib +++ /dev/null @@ -1 +0,0 @@ -280NPLIST;1.0;D;K;4;$topD;K;18;CPCibObjectDataKeyD;K;6;CP$UIDd;1;2E;E;K;8;$objectsA;S;5;$nullD;K;10;$classnameS;16;_CPCibObjectDataK;8;$classesA;S;16;_CPCibObjectDataS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;1E;K;28;_CPCibObjectDataNamesKeysKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataNamesValuesKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataClassesKeysKeyD;K;6;CP$UIDd;1;0E;K;32;_CPCibObjectDataClassesValuesKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataConnectionsKeyD;K;6;CP$UIDd;1;4E;K;28;_CPCibObjectDataFrameworkKeyD;K;6;CP$UIDd;1;0E;K;26;_CPCibObjectDataNextOidKeyD;K;6;CP$UIDd;1;5E;K;30;_CPCibObjectDataObjectsKeysKeyD;K;6;CP$UIDd;1;6E;K;32;_CPCibObjectDataObjectsValuesKeyD;K;6;CP$UIDd;1;7E;K;26;_CPCibObjectDataOidKeysKeyD;K;6;CP$UIDd;1;8E;K;28;_CPCibObjectDataOidValuesKeyD;K;6;CP$UIDd;1;9E;K;28;_CPCibObjectDataFileOwnerKeyD;K;6;CP$UIDd;2;11E;K;33;_CPCibObjectDataVisibleWindowsKeyD;K;6;CP$UIDd;2;13E;E;D;K;10;$classnameS;7;CPArrayK;8;$classesA;S;7;CPArrayS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;15E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;17E;D;K;6;CP$UIDd;2;18E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;11E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;10;$classnameS;18;_CPCibCustomObjectK;8;$classesA;S;18;_CPCibCustomObjectS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;10E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;2;19E;E;D;K;10;$classnameS;5;CPSetK;8;$classesA;S;5;CPSetS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;12E;K;15;CPSetObjectsKeyD;K;6;CP$UIDd;2;20E;E;D;K;10;$classnameS;20;CPCibOutletConnectorK;8;$classesA;S;20;CPCibOutletConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;16E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;18E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;21E;E;D;K;6;$classD;K;6;CP$UIDd;2;10E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;2;19E;E;D;K;6;$classD;K;6;CP$UIDd;2;10E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;2;22E;E;D;K;6;$classD;K;6;CP$UIDd;2;10E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;2;23E;E;S;13;CPApplicationD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;S;8;delegateS;13;NSFontManagerS;13;AppControllerE;K;9;$archiverS;15;CPKeyedArchiverK;8;$versionS;6;100000E; \ No newline at end of file diff --git a/Tools/NativeHost/English.lproj/MainMenu.xib b/Tools/NativeHost/English.lproj/MainMenu.xib deleted file mode 100644 index 2bce8a8107..0000000000 --- a/Tools/NativeHost/English.lproj/MainMenu.xib +++ /dev/null @@ -1,548 +0,0 @@ - - - - 1050 - 10C540 - 732 - 1038.25 - 458.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 732 - - - YES - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - NSApplication - - - FirstResponder - - - NSApplication - - - NSFontManager - - - AppController - - - - - YES - - - delegate - - - - 519 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 420 - - - - - 487 - - - - - - - -3.IBPluginDependency - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - - YES - - - - - YES - - - YES - - - - 677 - - - - YES - - AppController - NSObject - - IBProjectSource - AppController.h - - - - NSObject - - IBProjectSource - NSObject+WebAdditions.h - - - - - YES - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSFontManager - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebDownload.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebEditingDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebFrameLoadDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebJavaPlugIn.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebPlugin.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebPluginContainer.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebPolicyDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebResourceLoadDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebScriptObject.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebUIDelegate.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - - 0 - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - ../NativeHost.xcodeproj - 3 - - diff --git a/Tools/NativeHost/Info.plist b/Tools/NativeHost/Info.plist deleted file mode 100644 index 2f8dbca994..0000000000 --- a/Tools/NativeHost/Info.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFile - icon - CFBundleShortVersionString - 0.9 - CFBundleIdentifier - com.280north.${PRODUCT_NAME:identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - NativeHost - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleVersion - 1.0 - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - - diff --git a/Tools/NativeHost/Jakefile b/Tools/NativeHost/Jakefile deleted file mode 100644 index 8df9bce4bc..0000000000 --- a/Tools/NativeHost/Jakefile +++ /dev/null @@ -1,45 +0,0 @@ - -require("../../common.jake"); - -var OS = require("os"); -var task = require("jake").task -var stream = require("narwhal/term").stream; - -task ("build", function() -{ - if (executableExists("xcodebuild")) - { - var args = "-alltargets -configuration Release"; - - if (xcodebuildHasTenPointFiveSDK()) - args = "-sdk macosx10.5 " + args; - - else - args = "-sdk macosx " + args; - - if (OS.system("xcodebuild " + args)) - OS.exit(1); - - rm_rf(FILE.join($BUILD_CJS_CAPPUCCINO, "support", "NativeHost.app")); - FILE.mkdirs(FILE.join($BUILD_CJS_CAPPUCCINO, "support")) - cp_r(FILE.join("build", "Release", "NativeHost.app"), FILE.join($BUILD_CJS_CAPPUCCINO, "support", "NativeHost.app")); - } - else - { - print("Building NativeHost requires Xcode."); - } -}); - -task ("clean", function() -{ - if (OS.system("xcodebuild clean")) - OS.exit(1); -}); - -task ("clobber", function() -{ - if (OS.system("xcodebuild clean")) - OS.exit(1); -}); - -task ("default", ["build"]); diff --git a/Tools/NativeHost/MenuBridge.h b/Tools/NativeHost/MenuBridge.h deleted file mode 100644 index 847237409e..0000000000 --- a/Tools/NativeHost/MenuBridge.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// MenuBridge.h -// NativeHost -// -// Created by Francisco Tolmasky on 9/2/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import - - -@class WebScriptObject; - -@interface MenuBridge : NSMenu -{ - WebScriptObject * menuObject; -} - -+ (id)menuBridgeWithMenuObject:(WebScriptObject *)aMenuObject; -- (id)initWithMenuObject:(WebScriptObject *)aMenuObject; - -@end diff --git a/Tools/NativeHost/MenuBridge.m b/Tools/NativeHost/MenuBridge.m deleted file mode 100644 index ad14a71919..0000000000 --- a/Tools/NativeHost/MenuBridge.m +++ /dev/null @@ -1,63 +0,0 @@ -// -// MenuBridge.m -// NativeHost -// -// Created by Francisco Tolmasky on 9/2/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import "WebScripObject+Objective-J.h" -#import "MenuItemBridge.h" -#import "MenuBridge.h" - - -@implementation MenuBridge - -+ (id)menuBridgeWithMenuObject:(WebScriptObject *)aMenuObject -{ - if (!aMenuObject) - return nil; - - static NSMapTable * cache = nil; - - if (!cache) - cache = [[NSMapTable mapTableWithStrongToStrongObjects] retain]; - - MenuBridge * menuBridge = [cache objectForKey:aMenuObject]; - - if (!menuBridge) - { - menuBridge = [MenuBridge alloc]; - - [cache setObject:menuBridge forKey:aMenuObject]; - - [[menuBridge initWithMenuObject:aMenuObject] autorelease]; - } - - return menuBridge; -} - -- (id)initWithMenuObject:(WebScriptObject *)aMenuObject -{ - self = [super initWithTitle:[aMenuObject bridgeSelector:@selector(title)]]; - - if (self) - { - menuObject = aMenuObject; - - NSInteger index = 0, - count = [[aMenuObject bridgeSelector:@selector(numberOfItems)] intValue]; - - for (; index < count; ++index) - [self addItem:[[[MenuItemBridge alloc] initWithMenuItemObject:[aMenuObject bridgeSelector:@selector(itemAtIndex:) withObject:[NSNumber numberWithInt:index]]] autorelease]]; - } - - return self; -} - -- (void)performActionForItemAtIndex:(NSInteger)anIndex -{ - [menuObject bridgeSelector:@selector(performActionForItemAtIndex:) withObject:[NSNumber numberWithInt:anIndex]]; -} - -@end diff --git a/Tools/NativeHost/MenuItemBridge.h b/Tools/NativeHost/MenuItemBridge.h deleted file mode 100644 index 86e70d6f26..0000000000 --- a/Tools/NativeHost/MenuItemBridge.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// ReflectMenuItem.h -// NativeHost -// -// Created by Francisco Tolmasky on 9/2/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import - - -@class WebScriptObject; - -@interface MenuItemBridge : NSMenuItem -{ - WebScriptObject * menuItemObject; -} - -+ (id)menuItemBridgeWithMenuItemObject:(WebScriptObject *)aMenuItemObject; -- (id)initWithMenuItemObject:(WebScriptObject *)aMenuItemObject; - -- (void)updateFromMenuItemObject; - -@end diff --git a/Tools/NativeHost/MenuItemBridge.m b/Tools/NativeHost/MenuItemBridge.m deleted file mode 100644 index b661f35e8d..0000000000 --- a/Tools/NativeHost/MenuItemBridge.m +++ /dev/null @@ -1,77 +0,0 @@ -// -// ReflectMenuItem.m -// NativeHost -// -// Created by Francisco Tolmasky on 9/2/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import "WebScripObject+Objective-J.h" -#import "MenuBridge.h" -#import "MenuItemBridge.h" - - -@implementation MenuItemBridge - -+ (id)menuItemBridgeWithMenuItemObject:(WebScriptObject *)aMenuItemObject -{ - if (!aMenuItemObject) - return nil; - - static NSMapTable * cache = nil; - - if (!cache) - cache = [[NSMapTable mapTableWithStrongToStrongObjects] retain]; - - MenuItemBridge * menuItemBridge = [cache objectForKey:aMenuItemObject]; - - if (!menuItemBridge) - { - menuItemBridge = [MenuBridge alloc]; - - [cache setObject:menuItemBridge forKey:aMenuItemObject]; - - [[menuItemBridge initWithMenuItemObject:aMenuItemObject] autorelease]; - } - - return menuItemBridge; -} - -- (id)initWithMenuItemObject:(WebScriptObject *)aMenuItemObject -{ - if ([[aMenuItemObject bridgeSelector:@selector(isSeparatorItem)] boolValue]) - return [[NSMenuItem separatorItem] retain]; - - self = [super init]; - - if (self) - { - menuItemObject = aMenuItemObject; - - [self updateFromMenuItemObject]; - } - - return self; -} -/* -- (BOOL)isSeparatorItem -{ - return [[menuItemObject bridgeSelector:@selector(isSeparatorItem)] boolValue]; -} -*/ -- (void)updateFromMenuItemObject -{ - [self setTitle:[menuItemObject bridgeSelector:@selector(title)]]; - [self setSubmenu:[MenuBridge menuBridgeWithMenuObject:[menuItemObject bridgeSelector:@selector(submenu)]]]; - [self setKeyEquivalent:[menuItemObject bridgeSelector:@selector(keyEquivalent)]]; - [self setKeyEquivalentModifierMask:[[menuItemObject evaluateObjectiveJ:[NSString stringWithFormat:@"(function() { var mask = %u; return (((mask & CPAlphaShiftKeyMask) ? %u : 0) | ((mask & CPShiftKeyMask) ? %u : 0) | ((mask & CPControlKeyMask) ? %u : 0) | ((mask & CPAlternateKeyMask) ? %u : 0) | ((mask & CPCommandKeyMask) ? %u : 0) | ((mask & CPNumericPadKeyMask) ? %u : 0) | ((mask & CPHelpKeyMask) ? %u : 0) | ((mask & CPFunctionKeyMask) ? %u : 0)) }())", [[menuItemObject bridgeSelector:@selector(keyEquivalentModifierMask)] unsignedIntegerValue], NSAlphaShiftKeyMask, NSShiftKeyMask, NSControlKeyMask, NSAlternateKeyMask, NSCommandKeyMask, NSNumericPadKeyMask, NSHelpKeyMask, NSFunctionKeyMask, NSDeviceIndependentModifierFlagsMask]] unsignedIntegerValue]];[self setAction:@selector(bridgeAction:)]; - [self setTarget:self]; - [self setAction:@selector(bridgeAction:)]; -} - -// This exists so that the menu items are enabled. -- (void)bridgeAction:(id)aSender -{ -} - -@end diff --git a/Tools/NativeHost/NSObject+WebAdditions.h b/Tools/NativeHost/NSObject+WebAdditions.h deleted file mode 100644 index b4ab41035f..0000000000 --- a/Tools/NativeHost/NSObject+WebAdditions.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// NSObject+WebAdditions.h -// NativeHost -// -// Created by Francisco Tolmasky on 11/16/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import - - -@interface NSObject (WebAdditions) - -- (BOOL)webBoolValue; - -@end diff --git a/Tools/NativeHost/NSObject+WebAdditions.m b/Tools/NativeHost/NSObject+WebAdditions.m deleted file mode 100644 index 1ffd942a1e..0000000000 --- a/Tools/NativeHost/NSObject+WebAdditions.m +++ /dev/null @@ -1,19 +0,0 @@ -// -// NSObject+WebAdditions.m -// NativeHost -// -// Created by Francisco Tolmasky on 11/16/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import "NSObject+WebAdditions.h" - - -@implementation NSObject (WebAdditions) - -- (BOOL)webBoolValue -{ - return [self isKindOfClass:[NSNumber class]] && [(NSNumber *)self boolValue]; -} - -@end diff --git a/Tools/NativeHost/NSURL+Additions.h b/Tools/NativeHost/NSURL+Additions.h deleted file mode 100644 index 32cee28f64..0000000000 --- a/Tools/NativeHost/NSURL+Additions.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// NSURL+Additions.h -// NativeHost -// -// Created by Francisco Tolmasky on 6/3/09. -// Copyright 2009 280 North, Inc. All rights reserved. -// - -#import - - -@interface NSURL (Additions) - -- (NSURL *)HTTPFileSystemURL; -+ (NSURL *)fileSystemURLFromHTTPFileSystemString:(NSString *)aString; - -@end diff --git a/Tools/NativeHost/NSURL+Additions.m b/Tools/NativeHost/NSURL+Additions.m deleted file mode 100644 index 39cabb1a32..0000000000 --- a/Tools/NativeHost/NSURL+Additions.m +++ /dev/null @@ -1,36 +0,0 @@ -// -// NSURL+Additions.m -// NativeHost -// -// Created by Francisco Tolmasky on 6/3/09. -// Copyright 2009 280 North, Inc. All rights reserved. -// - -#import "NSURL+Additions.h" -#import "AppController.h" - -@implementation NSURL (Additions) - -- (NSURL *)HTTPFileSystemURL -{ - if ([[self scheme] caseInsensitiveCompare:@"file"] == NSOrderedSame) - return [[[NSURL alloc] initWithScheme:@"http" - host:[NSString stringWithFormat:@"127.0.0.1:%d", SERVER_PORT] - path:[@"/filesystem/" stringByAppendingString:[self path]]] autorelease]; - - return [[self copy] autorelease]; -} - -+ (NSURL *)fileSystemURLFromHTTPFileSystemString:(NSString *)aString -{ - NSURL *httpURL = [NSURL URLWithString:aString]; - NSString *path = [httpURL path]; - NSRange range = [path rangeOfString:@"/filesystem"]; - - if (range.location == 0 && NSMaxRange(range) < [path length]) - path = [path substringFromIndex:[@"/filesystem" length]]; - - return [[[NSURL alloc] initFileURLWithPath:path] autorelease]; -} - -@end diff --git a/Tools/NativeHost/NativeHost.xcodeproj/TemplateIcon.icns b/Tools/NativeHost/NativeHost.xcodeproj/TemplateIcon.icns deleted file mode 100644 index 62cb7015e09d6ea3e65d7f7949c4c07f9246a908..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52318 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 WhsmLR^b3` - #import -#endif diff --git a/Tools/NativeHost/SSCrypto.h b/Tools/NativeHost/SSCrypto.h deleted file mode 100644 index 89ff70a9e3..0000000000 --- a/Tools/NativeHost/SSCrypto.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - Copyright (c) 2003-2006, Septicus Software All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Septicus Software nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -// -// SSCrypto.h -// -// Created by Ed Silva on Sat May 31 2003. -// Copyright (c) 2003-2006 Septicus Software. All rights reserved. -// - - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -@interface NSData (HexDump) -- (NSString *)encodeBase64; -- (NSString *)encodeBase64WithNewlines:(BOOL)encodeWithNewlines; -- (NSData *)decodeBase64; -- (NSData *)decodeBase64WithNewLines:(BOOL)decodeWithNewLines; -- (NSString *)hexval; -- (NSString *)hexdump; -@end - -@interface SSCrypto : NSObject -{ - NSData *symmetricKey; - NSData *cipherText; - NSData *clearText; - NSData *publicKey; - NSData *privateKey; - - BOOL isSymmetric; -} - -- (id)init; -- (id)initWithSymmetricKey:(NSData *)k; -- (id)initWithPublicKey:(NSData *)pub; -- (id)initWithPrivateKey:(NSData *)priv; -- (id)initWithPublicKey:(NSData *)pub privateKey:(NSData *)priv; - -- (BOOL)isSymmetric; -- (void)setIsSymmetric:(BOOL)flag; - -- (NSData *)symmetricKey; -- (void)setSymmetricKey:(NSData *)k; - -- (NSData *)publicKey; -- (void)setPublicKey:(NSData *)k; - -- (NSData *)privateKey; -- (void)setPrivateKey:(NSData *)k; - -- (NSData *)clearTextAsData; -- (NSString *)clearTextAsString; -- (void)setClearTextWithData:(NSData *)c; -- (void)setClearTextWithString:(NSString *)c; - -- (NSData *)cipherTextAsData; -- (NSString *)cipherTextAsString; -- (void)setCipherText:(NSData *)c; - -- (NSData *)decrypt; -- (NSData *)decrypt:(NSString *)cipherName; - -- (NSData *)verify; - -- (NSData *)encrypt; -- (NSData *)encrypt:(NSString *)cipherName; - -- (NSData *)sign; - -- (NSData *)digest:(NSString *)digestName; - -+ (NSData *)generateRSAPrivateKeyWithLength:(int)length; -+ (NSData *)generateRSAPublicKeyFromPrivateKey:(NSData *)privateKey; -+ (NSData *)getKeyDataWithLength:(int)length; -+ (NSData *)getKeyDataWithLength:(int)length fromPassword:(NSString *)pass withSalt:(NSString *)salt; -+ (NSData *)getKeyDataWithLength:(int)length fromPassword:(NSString *)pass withSalt:(NSString *)salt withIterations:(int)count; -+ (NSData *)getSHA1ForData:(NSData *)d; -+ (NSData *)getMD5ForData:(NSData *)d; - -@end diff --git a/Tools/NativeHost/SSCrypto.m b/Tools/NativeHost/SSCrypto.m deleted file mode 100644 index 09c5575310..0000000000 --- a/Tools/NativeHost/SSCrypto.m +++ /dev/null @@ -1,1214 +0,0 @@ -/* - Copyright (c) 2003-2006, Septicus Software All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Septicus Software nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -// -// SSCrypto.m -// SimpleWebCam -// -// Created by Ed Silva on Sat May 31 2003. -// Copyright (c) 2003-2006 Septicus Software. All rights reserved. -// - -#import "SSCrypto.h" - -@implementation NSData (HexDump) - -/** - * Encodes the current data in base64, and creates and returns an NSString from the result. - * This is the same as piping data through "... | openssl enc -base64" on the command line. - * - * Code courtesy of DaveDribin (http://www.dribin.org/dave/) - * Taken from http://www.cocoadev.com/index.pl?BaseSixtyFour -**/ -- (NSString *)encodeBase64 -{ - return [self encodeBase64WithNewlines: YES]; -} - -/** - * Encodes the current data in base64, and creates and returns an NSString from the result. - * This is the same as piping data through "... | openssl enc -base64" on the command line. - * - * Code courtesy of DaveDribin (http://www.dribin.org/dave/) - * Taken from http://www.cocoadev.com/index.pl?BaseSixtyFour -**/ -- (NSString *)encodeBase64WithNewlines:(BOOL)encodeWithNewlines -{ - // Create a memory buffer which will contain the Base64 encoded string - BIO * mem = BIO_new(BIO_s_mem()); - - // Push on a Base64 filter so that writing to the buffer encodes the data - BIO * b64 = BIO_new(BIO_f_base64()); - if (!encodeWithNewlines) - BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); - mem = BIO_push(b64, mem); - - // Encode all the data - BIO_write(mem, [self bytes], [self length]); - BIO_flush(mem); - - // Create a new string from the data in the memory buffer - char * base64Pointer; - long base64Length = BIO_get_mem_data(mem, &base64Pointer); - // we use an NSData here since the base64pointer is not null terminated - // the byte array the NSData return should be - // so making an NSString from that will be okay - NSData * base64data = [NSData dataWithBytes:base64Pointer length:base64Length]; - NSString * base64String = [NSString stringWithUTF8String:[base64data bytes]]; - - // Clean up and go home - BIO_free_all(mem); - - if (!encodeWithNewlines) - base64String = [[base64String componentsSeparatedByString:@"\n"] componentsJoinedByString:@""]; - - return base64String; -} - -- (NSData *)decodeBase64 -{ - return [self decodeBase64WithNewLines:YES]; -} - -- (NSData *)decodeBase64WithNewLines:(BOOL)encodedWithNewlines -{ - // Create a memory buffer containing Base64 encoded string data - BIO * mem = BIO_new_mem_buf((void *) [self bytes], [self length]); - - // Push a Base64 filter so that reading from the buffer decodes it - BIO * b64 = BIO_new(BIO_f_base64()); - if (!encodedWithNewlines) - BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); - mem = BIO_push(b64, mem); - - // Decode into an NSMutableData - NSMutableData * data = [NSMutableData data]; - char inbuf[512]; - int inlen; - while ((inlen = BIO_read(mem, inbuf, sizeof(inbuf))) > 0) - [data appendBytes: inbuf length: inlen]; - - // Clean up and go home - BIO_free_all(mem); - return data; -} - -- (NSString *)hexval -{ - NSMutableString *hex = [NSMutableString string]; - unsigned char *bytes = (unsigned char *)[self bytes]; - char temp[3]; - int i = 0; - - for (i = 0; i < [self length]; i++) { - temp[0] = temp[1] = temp[2] = 0; - (void)sprintf(temp, "%02x", bytes[i]); - [hex appendString:[NSString stringWithUTF8String:temp]]; - } - - return hex; -} - -- (NSString *)hexdump -{ - NSMutableString *ret=[NSMutableString stringWithCapacity:[self length]*2]; - /* dumps size bytes of *data to string. Looks like: - * [0000] 75 6E 6B 6E 6F 77 6E 20 - * 30 FF 00 00 00 00 39 00 unknown 0.....9. - * (in a single line of course) - */ - unsigned int size= [self length]; - const unsigned char *p = [self bytes]; - unsigned char c; - int n; - char bytestr[4] = {0}; - char addrstr[10] = {0}; - char hexstr[ 16*3 + 5] = {0}; - char charstr[16*1 + 5] = {0}; - for(n=1;n<=size;n++) { - if (n%16 == 1) { - /* store address for this line */ - snprintf(addrstr, sizeof(addrstr), "%.4x", - (unsigned int)((long)p-(long)self) ); - } - - c = *p; - if (isalnum(c) == 0) { - c = '.'; - } - - /* store hex str (for left side) */ - snprintf(bytestr, sizeof(bytestr), "%02X ", *p); - strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1); - - /* store char str (for right side) */ - snprintf(bytestr, sizeof(bytestr), "%c", c); - strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1); - - if(n%16 == 0) { - /* line completed */ - //printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); - [ret appendString:[NSString stringWithFormat:@"[%4.4s] %-50.50s %s\n", - addrstr, hexstr, charstr]]; - hexstr[0] = 0; - charstr[0] = 0; - } else if(n%8 == 0) { - /* half line: add whitespaces */ - strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1); - strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1); - } - p++; /* next byte */ - } - - if (strlen(hexstr) > 0) { - /* print rest of buffer if not empty */ - //printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); - [ret appendString:[NSString stringWithFormat:@"[%4.4s] %-50.50s %s\n", - addrstr, hexstr, charstr]]; - } - return ret; -} - -@end - -@interface SSCrypto (PrivateAPI) -- (void)setupOpenSSL; -- (void)cleanupOpenSSL; -@end - -// SSCrypto object -@implementation SSCrypto - -/** - * Generic constructor. - * Simply configures internal OpenSSL setup. -**/ -- (id)init -{ - if(self = [super init]) - { - // Call private method to handle the setup for internal OpenSSL stuff - [self setupOpenSSL]; - } - return self; -} - -/** - * Symmetric key constructor. - * Configures the instance to use symmetric encryption/decryption using the given symmetric key. -**/ -- (id)initWithSymmetricKey:(NSData *)k -{ - if(self = [super init]) - { - // Call private method to handle the setup for internal OpenSSL stuff - [self setupOpenSSL]; - - [self setSymmetricKey:k]; - [self setIsSymmetric:YES]; - } - return self; -} - -/** - * Public key only constructor. - * Configures the instance to use non-symmetric encryption/decryption, and to use the given public key. -**/ -- (id)initWithPublicKey:(NSData *)pub -{ - return [self initWithPublicKey:pub privateKey:nil]; -} - -/** - * Private key only constructor. - * Configures the instance to use non-symmetric encryption/decryption, and to use the given private key. -**/ -- (id)initWithPrivateKey:(NSData *)priv -{ - return [self initWithPublicKey:nil privateKey:priv]; -} - -/** - * Public and Private key constructor. - * Configures the instance to use non-symmetric encryption/decryption, and to use the given public and private keys. -**/ -- (id)initWithPublicKey:(NSData *)pub privateKey:(NSData *)priv; -{ - if(self = [super init]) - { - // Call private method to handle the setup for internal OpenSSL stuff - [self setupOpenSSL]; - - // Store the publicKey variable (if not nil) - if(pub != nil) - [self setPublicKey:pub]; - - // Store the privateKey variable (if not nil) - if(priv != nil) - [self setPrivateKey:priv]; - - // Since we're using public and private keys, we can assume we're not using symmetric encryption - [self setIsSymmetric:NO]; - } - return self; -} - -/** - * This method sets up everything needed to use the OpenSSL libraries later within the code. - * This method should be called by every constructor. -**/ -- (void)setupOpenSSL -{ - // OpenSSL keeps an internal table of digest algorithms and ciphers. - // It uses this table to lookup ciphers via functions such as EVP_get_cipher_byname(). - // OpenSSL_add_all_digests() adds all digest algorithms to the table. - // OpenSSL_add_all_ciphers() adds all cipher algorithms to the table. - // OpenSSL_add_all_algorithms() adds all algorithms to the table (digests and ciphers). - // EVP_cleanup() removes all ciphers and digests from the table. - // - // A typical application will call OpenSSL_add_all_algorithms() initially and EVP_cleanup() before exiting. - - OpenSSL_add_all_algorithms(); - - // ERR_load_crypto_strings() registers the error strings for all libcrypto functions. - // SSL_load_error_strings() does the same, but also registers the libssl error strings. - // ERR_free_strings() frees all previously loaded error strings. - // - // One of these functions should be called before generating textual error messages. - // However, this is not required when memory usage is an issue. - - ERR_load_crypto_strings(); -} - -/** - * Standard deallocation method. -**/ -- (void)dealloc -{ - // Cleanup all OpenSSL stuff - [self cleanupOpenSSL]; - - // Release all instance variables - [symmetricKey release]; - [cipherText release]; - [clearText release]; - [publicKey release]; - [privateKey release]; - - // Move up the inheritance chain - [super dealloc]; -} - -- (void)cleanupOpenSSL -{ - // EVP_cleanup() removes all ciphers and digests from the table. - EVP_cleanup(); - - // ERR_free_strings() frees all previously loaded error strings. - ERR_free_strings(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark Getter, Setter Methods: -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * Returns whether or not symmetric encryption is to be used. - * If symmetric encryption is in use, then calls to encrypt or decrypt operate using symmetric encryption/decryption. - * Otherwise, it is assumed that asymmetric encryption/decryption is to be used. -**/ -- (BOOL)isSymmetric -{ - return isSymmetric; -} - -- (void)setIsSymmetric:(BOOL)flag -{ - isSymmetric = flag; -} - -- (NSData *)symmetricKey -{ - return symmetricKey; -} - -- (void)setSymmetricKey:(NSData *)k -{ - [k retain]; - [symmetricKey release]; - symmetricKey = k; -} - -/** - * Returns the public key currently in use. -**/ -- (NSData *)publicKey -{ - return publicKey; -} - -/** - * Sets the public key to use. - * Public keys are used to verify signed data, or to encrypt data. (ToDo) -**/ -- (void)setPublicKey:(NSData *)k -{ - [k retain]; - [publicKey release]; - publicKey = k; -} - -/** - * Returns the private key currently in use. -**/ -- (NSData *)privateKey -{ - return privateKey; -} - -/** - * Sets the private key to use. - * Private keys are used to sign data, or to decrypt data. (ToDo) - * - * The data that is provided should from a file (such as private.pem) that was generated by openssl. -**/ -- (void)setPrivateKey:(NSData *)k -{ - [k retain]; - [privateKey release]; - privateKey = k; -} - -/** - * Returns the clear text as plain NSData. - * The plain text contains the text that was previously set. - * It's the known text, which is to be encrypted, decrypted, etc. -**/ -- (NSData *)clearTextAsData -{ - return clearText; -} - -/** - * Returns the clear text formatted as an NSString. - * The plain text contains the text that was previously set. - * It's the known text, which is to be encrypted, decrypted, etc. -**/ -- (NSString *)clearTextAsString -{ - return [[[NSString alloc] initWithData:[self clearTextAsData] encoding:NSUTF8StringEncoding] autorelease]; -} - -/** - * Sets the clear text using the given data. - * The clear text will be used for encryption, decryption, etc. - * - * Note that the given data reference is retained and later used, so it shouldn't be externally modified. -**/ -- (void)setClearTextWithData:(NSData *)c -{ - [c retain]; - [clearText release]; - clearText = c; -} - -/** - * Sets the clear text using the given string. - * The clear text will be used for encryption, signing, and digests. - **/ -- (void)setClearTextWithString:(NSString *)c -{ - [clearText release]; - - // BUG FIX : PLL (2009/02/21) - // - // [c length] : Returns the number of Unicode characters in the receiver. - // For example "éàç test" in UTF8 is 11 bytes (c3 a9 c3 a0 c3 a7 20 74 65 73 74) - // but only 8 Unicode characters. - // So this will truncate the text and result in one error. - // - // clearText = [[NSData alloc] initWithBytes:[c UTF8String] length:[c length]]; - - // The number of bytes required to store the receiver in the encoding enc in a non-external representation. The length does not include space for a terminating NULL character. - unsigned int length = [c lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - clearText = [[NSData alloc] initWithBytes:[c UTF8String] length:length]; -} - -/** - * Returns the cipher text as plain NSData. - * The cipher text contains the most recent encrypted data. (Result of call to encrypt) -**/ -- (NSData *)cipherTextAsData -{ - return cipherText; -} - -/** - * Returns the ciper text formatted as an NSString. - * The ciper text contains the most recent encrypted data. (Result of call to encrypt) -**/ -- (NSString *)cipherTextAsString -{ - return [[[NSString alloc] initWithData:[self cipherTextAsData] encoding:NSUTF8StringEncoding] autorelease]; -} - -/** - * Sets the cipher text using the given data. - * The cipher text will be used for decryption and verifying. -**/ -- (void)setCipherText:(NSData *)c -{ - [c retain]; - [cipherText release]; - cipherText = c; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark Decryption methods: -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * Peforms decryption, and returns resulting clear text data. - * If symmetric decryption is being used, performs symmetric decryption using aes128. - * Otherwise, performs decryption using the private key. -**/ -- (NSData *)decrypt -{ - if([self isSymmetric] && [self symmetricKey]) - { - return [self decrypt:@"aes128"]; - } - else if([self privateKey]) - { - return [self decrypt:nil]; - } - else - { - NSLog(@"No symmetric key or private key is set!"); - return nil; - } -} - -/** - * Decrypts the cipher text data. - * If symmetric decryption is being used, then the decryption is done using the given cipher. - * Otherwise, asymmetric decryptions is used, and the data is encrypted using the private key. - * - * Returns the clear text data that is the result of the decryption. - * The resulting clear text data may also be later retrieved with the clearTextAsData or clearTextAsString methods. -**/ -- (NSData *)decrypt:(NSString *)cipherName -{ - // If there is no cipher text set, or the cipher text is an empty string (zero length data) - // then there is nothing to decrypt, and we may as well return nil - if(cipherText == nil || [cipherText length] == 0) - { - return nil; - } - - unsigned char *outbuf, iv[EVP_MAX_IV_LENGTH]; - int outlen, templen, inlen; - inlen = [cipherText length]; - unsigned char *input = (unsigned char *)[cipherText bytes]; - - if([self isSymmetric]) - { - // Use symmetric decryption... - - unsigned char evp_key[EVP_MAX_KEY_LENGTH] = {"\0"}; - EVP_CIPHER_CTX cCtx; - const EVP_CIPHER *cipher; - - if(cipherName) - { - cipher = EVP_get_cipherbyname((const char *)[cipherName UTF8String]); - if(!cipher) - { - NSLog(@"cannot get cipher with name %@", cipherName); - return nil; - } - } - else - { - cipher = EVP_bf_cbc(); - if(!cipher) - { - NSLog(@"cannot get cipher with name %@", @"EVP_bf_cbc"); - return nil; - } - } - - // Sometimes OpenSSL encrypted data contains an 8 byte salt. - // This is indicated by the "Salted__" prefix in the encrypted data. - - NSData *salt = nil; - - if([cipherText length] > 8+8) - { - if(strncmp((const char *)[cipherText bytes], "Salted__", 8) == 0) - { - salt = [cipherText subdataWithRange:NSMakeRange(8, 8)]; - - input += 16; - inlen -= 16; - } - } - - EVP_BytesToKey(cipher, EVP_md5(), [salt bytes], - [symmetricKey bytes], [symmetricKey length], 1, evp_key, iv); - - EVP_CIPHER_CTX_init(&cCtx); - - if (!EVP_DecryptInit(&cCtx, cipher, evp_key, iv)) - { - NSLog(@"EVP_DecryptInit() failed!"); - EVP_CIPHER_CTX_cleanup(&cCtx); - return nil; - } - EVP_CIPHER_CTX_set_key_length(&cCtx, EVP_MAX_KEY_LENGTH); - - // The data buffer passed to EVP_DecryptUpdate() should have sufficient room for - // (input_length + cipher_block_size) bytes unless the cipher block size is 1 in which - // case input_length bytes is sufficient. - - if(EVP_CIPHER_CTX_block_size(&cCtx) > 1) - outbuf = (unsigned char *)calloc(inlen + EVP_CIPHER_CTX_block_size(&cCtx), sizeof(unsigned char)); - else - outbuf = (unsigned char *)calloc(inlen, sizeof(unsigned char)); - - NSAssert(outbuf, @"Cannot allocate memory for buffer!"); - - if (!EVP_DecryptUpdate(&cCtx, outbuf, &outlen, input, inlen)) - { - NSLog(@"EVP_DecryptUpdate() failed!"); - EVP_CIPHER_CTX_cleanup(&cCtx); - return nil; - } - - if (!EVP_DecryptFinal(&cCtx, outbuf + outlen, &templen)) - { - NSLog(@"EVP_DecryptFinal() failed!"); - EVP_CIPHER_CTX_cleanup(&cCtx); - return nil; - } - - outlen += templen; - EVP_CIPHER_CTX_cleanup(&cCtx); - } - else - { - // Use asymmetric decryption... - - if([self privateKey] == nil) - { - NSLog(@"Cannot decrypt without the private key, which is currently nil"); - return nil; - } - - BIO *privateBIO = NULL; - RSA *privateRSA = NULL; - - if(!(privateBIO = BIO_new_mem_buf((unsigned char*)[[self privateKey] bytes], [[self privateKey] length]))) - { - NSLog(@"BIO_new_mem_buf() failed!"); - return nil; - } - - if(!PEM_read_bio_RSAPrivateKey(privateBIO, &privateRSA, NULL, NULL)) - { - NSLog(@"PEM_read_bio_RSAPrivateKey() failed!"); - return nil; - } - - // RSA_check_key() returns 1 if rsa is a valid RSA key, and 0 otherwise. - - unsigned long check = RSA_check_key(privateRSA); - if(check != 1) - { - NSLog(@"RSA_check_key() failed with result %d!", check); - return nil; - } - - // RSA_size() returns the RSA modulus size in bytes. - // It can be used to determine how much memory must be allocated for an RSA encrypted value. - - outbuf = (unsigned char *)malloc(RSA_size(privateRSA)); - - if(!(outlen = RSA_private_decrypt(inlen, input, outbuf, privateRSA, RSA_PKCS1_PADDING))) - { - NSLog(@"RSA_private_decrypt() failed!"); - return nil; - } - - if(outlen == -1) - { - NSLog(@"Decrypt error: %s (%s)", - ERR_error_string(ERR_get_error(), NULL), - ERR_reason_error_string(ERR_get_error())); - return nil; - } - - if (privateBIO) BIO_free(privateBIO); - if (privateRSA) RSA_free(privateRSA); - } - - // Store the decrypted data as the clear text - [self setClearTextWithData:[NSData dataWithBytes:outbuf length:outlen]]; - - // Release the outbuf, since it was malloc'd - if (outbuf) { - free(outbuf); - } - - return [self clearTextAsData]; -} - -/** - * Verifies (decrypts) the cipher text data using the public key. - * The resulting clear text data is returned. - * - * The resulting clear text data may also be later retrieved with the clearTextAsData or clearTextAsString methods. - **/ -- (NSData *)verify -{ - // If there is no cipher text set, or the cipher text is an empty string (zero length data) - // then there is nothing to decrypt, and we may as well return nil - if(cipherText == nil || [cipherText length] == 0) - { - return nil; - } - - unsigned char *outbuf; - int outlen, inlen; - inlen = [cipherText length]; - unsigned char *input = (unsigned char *)[cipherText bytes]; - - if([self publicKey] == nil) - { - NSLog(@"Cannot verify (decrypt) without the public key, which is currently nil"); - return nil; - } - - BIO *publicBIO = NULL; - RSA *publicRSA = NULL; - - if(!(publicBIO = BIO_new_mem_buf((unsigned char *)[[self publicKey] bytes], [[self publicKey] length]))) - { - NSLog(@"BIO_new_mem_buf() failed!"); - return nil; - } - - if(!PEM_read_bio_RSA_PUBKEY(publicBIO, &publicRSA, NULL, NULL)) - { - NSLog(@"PEM_read_bio_RSA_PUBKEY() failed!"); - return nil; - } - - // RSA_size() returns the RSA modulus size in bytes. - // It can be used to determine how much memory must be allocated for an RSA encrypted value. - - outbuf = (unsigned char *)malloc(RSA_size(publicRSA)); - - if(!(outlen = RSA_public_decrypt(inlen, input, outbuf, publicRSA, RSA_PKCS1_PADDING))) - { - NSLog(@"RSA_public_decrypt() failed!"); - return nil; - } - - if(outlen == -1) - { - NSLog(@"Decrypt error: %s (%s)", - ERR_error_string(ERR_get_error(), NULL), - ERR_reason_error_string(ERR_get_error())); - return nil; - } - - if (publicBIO) BIO_free(publicBIO); - if (publicRSA) RSA_free(publicRSA); - - // Store the decrypted data as the clear text - [self setClearTextWithData:[NSData dataWithBytes:outbuf length:outlen]]; - - // Release the outbuf, since it was malloc'd - if (outbuf) { - free(outbuf); - } - - return [self clearTextAsData]; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark Encryption methods: -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * Peforms encryption, and returns resulting ciper text data. - * If symmetric encryption is being used, performs symmetric encryption using aes128. - * Otherwise, performs encryption using the public key. -**/ -- (NSData *)encrypt -{ - if([self isSymmetric] && [self symmetricKey]) - { - return [self encrypt:@"aes128"]; - } - else if([self publicKey]) - { - return [self encrypt:nil]; - } - else - { - NSLog(@"No symmetric key or public key is set!"); - return nil; - } -} - -/** - * Encrypts the clear text data. - * If symmetric encryption is being used, then the encryption is done using the given cipher. - * Otherwise, asymmetric encryption is used, and the data is encrypted using the public key. - * - * Returns the cipher text data that is the result of the encryption. - * The resulting cipher text data may also be later retrieved with the cipherTextAsData or cipherTextAsString methods. -**/ -- (NSData *)encrypt:(NSString *)cipherName -{ - // If there is no clear text set, or the clear text is an empty string (zero length data) - // then there is nothing to encrypt, and we may as well return nil - if(clearText == nil || [clearText length] == 0) - { - return nil; - } - - unsigned char *input = (unsigned char *)[clearText bytes]; - unsigned char *outbuf, iv[EVP_MAX_IV_LENGTH]; - int outlen, templen, inlen; - inlen = [clearText length]; - - if([self isSymmetric]) - { - // Perform symmetric encryption... - - unsigned char evp_key[EVP_MAX_KEY_LENGTH] = {"\0"}; - EVP_CIPHER_CTX cCtx; - const EVP_CIPHER *cipher; - - if (cipherName){ - cipher = EVP_get_cipherbyname((const char *)[cipherName UTF8String]); - if (!cipher){ - NSLog(@"cannot get cipher with name %@", cipherName); - return nil; - } - } else { - cipher = EVP_bf_cbc(); - if (!cipher){ - NSLog(@"cannot get cipher with name %@", @"EVP_bf_cbc"); - return nil; - } - } - - EVP_BytesToKey(cipher, EVP_md5(), NULL, - [[self symmetricKey] bytes], [[self symmetricKey] length], 1, evp_key, iv); - EVP_CIPHER_CTX_init(&cCtx); - - if (!EVP_EncryptInit(&cCtx, cipher, evp_key, iv)) { - NSLog(@"EVP_EncryptInit() failed!"); - EVP_CIPHER_CTX_cleanup(&cCtx); - return nil; - } - EVP_CIPHER_CTX_set_key_length(&cCtx, EVP_MAX_KEY_LENGTH); - - // The data buffer passed to EVP_EncryptUpdate() should have sufficient room for - // (input_length + cipher_block_size - 1) - - outbuf = (unsigned char *)calloc(inlen + EVP_CIPHER_CTX_block_size(&cCtx) - 1, sizeof(unsigned char)); - NSAssert(outbuf, @"Cannot allocate memory for buffer!"); - - if (!EVP_EncryptUpdate(&cCtx, outbuf, &outlen, input, inlen)) - { - NSLog(@"EVP_EncryptUpdate() failed!"); - EVP_CIPHER_CTX_cleanup(&cCtx); - return nil; - } - if (!EVP_EncryptFinal(&cCtx, outbuf + outlen, &templen)) - { - NSLog(@"EVP_EncryptFinal() failed!"); - EVP_CIPHER_CTX_cleanup(&cCtx); - return nil; - } - outlen += templen; - EVP_CIPHER_CTX_cleanup(&cCtx); - - } - else - { - // Perform asymmetric encryption... - - if([self publicKey] == nil) - { - NSLog(@"Cannot encrypt without the public key, which is currently nil"); - return nil; - } - - BIO *publicBIO = NULL; - RSA *publicRSA = NULL; - - if(!(publicBIO = BIO_new_mem_buf((unsigned char*)[[self publicKey] bytes], [[self publicKey] length]))) - { - NSLog(@"BIO_new_mem_buf() failed!"); - return nil; - } - - if(!PEM_read_bio_RSA_PUBKEY(publicBIO, &publicRSA, NULL, NULL)) - { - NSLog(@"PEM_read_bio_RSA_PUBKEY() failed!"); - return nil; - } - - // RSA_size() returns the RSA modulus size in bytes. - // It can be used to determine how much memory must be allocated for an RSA encrypted value. - - outbuf = (unsigned char *)malloc(RSA_size(publicRSA)); - - if(!(outlen = RSA_public_encrypt(inlen, input, (unsigned char*)outbuf, publicRSA, RSA_PKCS1_PADDING))) - { - NSLog(@"RSA_public_encrypt failed!"); - return nil; - } - - if(outlen == -1) - { - NSLog(@"Encrypt error: %s (%s)", - ERR_error_string(ERR_get_error(), NULL), - ERR_reason_error_string(ERR_get_error())); - return nil; - } - - if (publicBIO) BIO_free(publicBIO); - if (publicRSA) RSA_free(publicRSA); - } - - // Store the encrypted data as the cipher text - [self setCipherText:[NSData dataWithBytes:outbuf length:outlen]]; - - // Release the outbuf, since it was malloc'd - if(outbuf) { - free(outbuf); - } - - return [self cipherTextAsData]; -} - -/** - * Signs (encrypts) the clear text data using the private key. - * The resulting cipher text data is returned, and may later be verified (decrypted) using the public key. - * - * The resulting cipher text data may also be later retrieved with the cipherTextAsData or cipherTextAsString methods. -**/ -- (NSData *)sign -{ - // If there is no clear text set, or the clear text is an empty string (zero length data) - // then there is nothing to encrypt, and we may as well return nil - if(clearText == nil || [clearText length] == 0) - { - return nil; - } - - unsigned char *input = (unsigned char *)[clearText bytes]; - unsigned char *outbuf; - int outlen, inlen; - inlen = [clearText length]; - - if([self privateKey] == nil) - { - NSLog(@"Cannot sign (encrypt) without the private key, which is currently nil"); - return nil; - } - - BIO *privateBIO = NULL; - RSA *privateRSA = NULL; - - if(!(privateBIO = BIO_new_mem_buf((unsigned char*)[[self privateKey] bytes], [[self privateKey] length]))) - { - NSLog(@"BIO_new_mem_buf() failed!"); - return nil; - } - - if(!PEM_read_bio_RSAPrivateKey(privateBIO, &privateRSA, NULL, NULL)) - { - NSLog(@"PEM_read_bio_RSAPrivateKey() failed!"); - return nil; - } - - // RSA_check_key() returns 1 if rsa is a valid RSA key, and 0 otherwise. - - unsigned long check = RSA_check_key(privateRSA); - if(check != 1) - { - NSLog(@"RSA_check_key() failed with result %d!", check); - return nil; - } - - // RSA_size() returns the RSA modulus size in bytes. - // It can be used to determine how much memory must be allocated for an RSA encrypted value. - - outbuf = (unsigned char *)malloc(RSA_size(privateRSA)); - - if(!(outlen = RSA_private_encrypt(inlen, input, (unsigned char*)outbuf, privateRSA, RSA_PKCS1_PADDING))) - { - NSLog(@"RSA_private_encrypt failed!"); - return nil; - } - - if(outlen == -1) - { - NSLog(@"Encrypt error: %s (%s)", - ERR_error_string(ERR_get_error(), NULL), - ERR_reason_error_string(ERR_get_error())); - return nil; - } - - if (privateBIO) BIO_free(privateBIO); - if (privateRSA) RSA_free(privateRSA); - - // Store the encrypted data as the cipher text - [self setCipherText:[NSData dataWithBytes:outbuf length:outlen]]; - - // Release the outbuf, since it was malloc'd - if(outbuf) { - free(outbuf); - } - - return [self cipherTextAsData]; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark Other methods: -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * Description forthcoming... -**/ -- (NSData *)digest:(NSString *)digestName -{ - if(clearText == nil) { - return nil; - } - - unsigned char outbuf[EVP_MAX_MD_SIZE]; - unsigned int templen, inlen; - unsigned char *input=(unsigned char*)[clearText bytes]; - EVP_MD_CTX ctx; - const EVP_MD *digest = NULL; - - inlen = [clearText length]; - - if(inlen==0) - return nil; - if(digestName) { - digest = EVP_get_digestbyname((const char*)[digestName UTF8String]); - if (!digest) { - NSLog(@"cannot get digest with name %@",digestName); - return nil; - } - } else { - digest=EVP_md5(); - if(!digest) { - NSLog(@"cannot get digest with name %@",@"MD5"); - return nil; - } - } - - EVP_MD_CTX_init(&ctx); - EVP_DigestInit(&ctx,digest); - if(!EVP_DigestUpdate(&ctx,input,inlen)) { - NSLog(@"EVP_DigestUpdate() failed!"); - EVP_MD_CTX_cleanup(&ctx); - return nil; - } - if (!EVP_DigestFinal(&ctx, outbuf, &templen)) { - NSLog(@"EVP_DigesttFinal() failed!"); - EVP_MD_CTX_cleanup(&ctx); - return nil; - } - EVP_MD_CTX_cleanup(&ctx); - - return [NSData dataWithBytes:outbuf length:templen]; -} - -- (NSString *)description -{ - NSString *format = @"clearText: %@, cipherText: %@, symmetricKey: %@, publicKey: %@, privateKey: %@"; - NSString *desc = [NSString stringWithFormat:format, [clearText hexdump], [cipherText hexdump], - [symmetricKey hexdump], [publicKey hexdump], [privateKey hexdump]]; - return desc; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark Class methods: -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -+ (NSData *)generateRSAPrivateKeyWithLength:(int)length -{ - RSA *key = NULL; - do { - key = RSA_generate_key(length, RSA_F4, NULL, NULL); - } while (1 != RSA_check_key(key)); - - BIO *bio = BIO_new(BIO_s_mem()); - - if (!PEM_write_bio_RSAPrivateKey(bio, key, NULL, NULL, 0, NULL, NULL)) - { - NSLog(@"cannot write private key to memory"); - return nil; - } - if (key) RSA_free(key); - - char *pbio_data = NULL; - int data_len = BIO_get_mem_data(bio, &pbio_data); - NSData *result = [NSData dataWithBytes:pbio_data length:data_len]; - - if (bio) - BIO_free(bio); - - return result; -} - -+ (NSData *)generateRSAPublicKeyFromPrivateKey:(NSData *)privateKey -{ - BIO *privateBIO = NULL; - RSA *privateRSA = NULL; - - if (!(privateBIO = BIO_new_mem_buf((unsigned char*)[privateKey bytes], [privateKey length]))) - { - NSLog(@"BIO_new_mem_buf() failed!"); - return nil; - } - - if (!PEM_read_bio_RSAPrivateKey(privateBIO, &privateRSA, NULL, NULL)) - { - NSLog(@"PEM_read_bio_RSAPrivateKey() failed!"); - return nil; - } - - // RSA_check_key() returns 1 if rsa is a valid RSA key, and 0 otherwise. - - unsigned long check = RSA_check_key(privateRSA); - if (check != 1) - { - NSLog(@"RSA_check_key() failed with result %d!", check); - return nil; - } - - BIO *bio = BIO_new(BIO_s_mem()); - - if (!PEM_write_bio_RSA_PUBKEY(bio, privateRSA)) - { - NSLog(@"cannot write public key to memory"); - return nil; - } - if (privateRSA) RSA_free(privateRSA); - - char *pbio_data = NULL; - int data_len = BIO_get_mem_data(bio, &pbio_data); - NSData *result = [NSData dataWithBytes:pbio_data length:data_len]; - - if (bio) - BIO_free(bio); - - return result; -} - -+ (NSData *)getKeyDataWithLength:(int)length -{ - NSData *randData = nil; - unsigned char *buffer; - - buffer = (unsigned char *)calloc(length*4, sizeof(unsigned char)); - NSAssert((buffer != NULL), @"Cannot calloc memory for buffer."); - - if (!RAND_bytes(buffer, length)){ - free(buffer); - } - - randData = [NSData dataWithBytes:buffer length:length]; - free(buffer); - - return randData; -} - -// PBKDF2 support functions -// Thanks to Chris Benedict (chrisbdaemon@gmail.com) for the code -+ (NSData *)getKeyDataWithLength:(int)length fromPassword:(NSString *)pass withSalt:(NSString *)salt -{ - return [SSCrypto getKeyDataWithLength:length fromPassword:pass withSalt:salt withIterations:1000]; -} - -+ (NSData *)getKeyDataWithLength:(int)length fromPassword:(NSString *)pass withSalt:(NSString *)salt withIterations:(int)count -{ - NSData *key = nil; - unsigned char *buffer = (unsigned char *)calloc(length, sizeof(unsigned char)); - NSAssert((buffer != NULL), @"Cannot calloc memory for buffer."); - const char *password = [pass UTF8String]; - const char *saltVal = [salt UTF8String]; - - if(!PKCS5_PBKDF2_HMAC_SHA1(password, [pass length], (unsigned char *)saltVal, [salt length], count, length, buffer)) { - return nil; - } - - key = [NSData dataWithBytes:buffer length:length]; - free(buffer); - - return key; -} - -+ (NSData *)getSHA1ForData:(NSData *)d -{ - unsigned length = [d length]; - const void *buffer = [d bytes]; - unsigned char *md = (unsigned char *)calloc(SHA_DIGEST_LENGTH, sizeof(unsigned char)); - NSAssert((md != NULL), @"Cannot calloc memory for buffer."); - - (void)SHA1(buffer, length, md); - - return [NSData dataWithBytesNoCopy:md length:SHA_DIGEST_LENGTH freeWhenDone:YES]; -} - -+ (NSData *)getMD5ForData:(NSData *)d -{ - unsigned length = [d length]; - const void *buffer = [d bytes]; - unsigned char *md = (unsigned char *)calloc(MD5_DIGEST_LENGTH, sizeof(unsigned char)); - NSAssert((md != NULL), @"Cannot calloc memory for buffer."); - - (void)MD5(buffer, length, md); - - return [NSData dataWithBytesNoCopy:md length:MD5_DIGEST_LENGTH freeWhenDone:YES]; -} - -@end diff --git a/Tools/NativeHost/Server.h b/Tools/NativeHost/Server.h deleted file mode 100644 index a11e9d701a..0000000000 --- a/Tools/NativeHost/Server.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// Server.h -// NativeHost -// -// Created by Francisco Tolmasky on 8/18/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import - -@interface Server : NSObject -{ - NSFileHandle * outputFile; - NSFileHandle * errorFile; - NSTask * process; -} - -- (BOOL)start; -- (void)stop; - -@end diff --git a/Tools/NativeHost/Server.m b/Tools/NativeHost/Server.m deleted file mode 100644 index 5439bc9677..0000000000 --- a/Tools/NativeHost/Server.m +++ /dev/null @@ -1,193 +0,0 @@ -// -// Server.m -// NativeHost -// -// Created by Francisco Tolmasky on 8/18/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import "Server.h" -#import "AppController.h" - -#import -#import - -@implementation Server - -- (BOOL)start -{ - NSBundle *mainBundle = [NSBundle mainBundle]; - NSString *serverPath = [mainBundle pathForResource:@"NativeHostServer" ofType:@"" inDirectory:@"Server"]; - - if (!serverPath) - { - return YES; - } - - // find an available port - struct sockaddr_in addr; - int sockfd; - int attempts = 0; - - while (SERVER_PORT == 9191 && attempts++ < 5) - { - // Create a socket - sockfd = socket( AF_INET, SOCK_STREAM, 0 ); - - // Setup its address structure - bzero( &addr, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl( INADDR_ANY ); - addr.sin_port = htons( 0 ); - - // Bind it to an address and port - bind( sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)); - - // Set it listening for connections - listen( sockfd, 5 ); - - // Find out what port the socket was bound to - socklen_t namelen = sizeof(struct sockaddr_in); - getsockname( sockfd, (struct sockaddr *)&addr, &namelen ); - - if (addr.sin_port <= 1024) - addr.sin_port = 9191; - else - SERVER_PORT = addr.sin_port; - - shutdown(sockfd, 2); - } - - if (SERVER_PASSWORD == nil) - { - CFUUIDRef uuidObj = CFUUIDCreate(nil); - SERVER_PASSWORD = (NSString*)CFUUIDCreateString(nil, uuidObj); - CFRelease(uuidObj); - } - - if (SERVER_USER == nil) - { - CFUUIDRef uuidObj = CFUUIDCreate(nil); - SERVER_USER = (NSString*)CFUUIDCreateString(nil, uuidObj); - CFRelease(uuidObj); - // usernames can't have "-" in them - SERVER_USER = [[SERVER_USER autorelease] stringByReplacingOccurrencesOfString:@"-" withString:@""]; - } - - // setup environment variables - NSDictionary *env = [[[NSProcessInfo processInfo] environment] mutableCopy]; - [env setValue:[mainBundle resourcePath] forKey:@"NATIVEHOST_RESOURCES"]; - [env setValue:[[NSNumber numberWithInt:SERVER_PORT] stringValue] forKey:@"NATIVEHOST_SERVER_PORT"]; - [env setValue:SERVER_USER forKey:@"NATIVEHOST_SERVER_USER"]; - [env setValue:SERVER_PASSWORD forKey:@"NATIVEHOST_SERVER_PASSWORD"]; - - // create pipes for stdout and stderr - NSPipe * outputPipe = [NSPipe pipe]; - outputFile = [outputPipe fileHandleForReading]; - NSPipe * errorPipe = [NSPipe pipe]; - errorFile = [errorPipe fileHandleForReading]; - - // setup the process - process = [[NSTask alloc] init]; - [process setLaunchPath:serverPath]; - [process setStandardOutput:outputPipe]; - [process setStandardError:errorPipe]; - [process setEnvironment:env]; - [env release]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(serverDidTerminate:) - name:NSTaskDidTerminateNotification - object:process]; - - [process launch]; - - BOOL didStartup = NO; - NSData * data = nil; - - while (!didStartup && (data = [outputFile availableData]) && [data length]) - { - NSString * string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - if (string) - { - NHLog(@"SERVER-OUT", string); - - didStartup = [string rangeOfString:@"Jack is starting up"].location != NSNotFound; - - [string release]; - } - } - NSLog(@"Server has started."); - - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(didReadStdOut:) - name:NSFileHandleReadCompletionNotification - object:outputFile]; - - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(didReadStdErr:) - name:NSFileHandleReadCompletionNotification - object:errorFile]; - - [outputFile readInBackgroundAndNotify]; - [errorFile readInBackgroundAndNotify]; - - return didStartup; -} - -- (void)stop -{ - [process terminate]; -} - -- (void)didReadStdOut:(NSNotification *)aNotification -{ - NSString * string = [[NSString alloc] initWithData:[[aNotification userInfo] objectForKey:NSFileHandleNotificationDataItem] - encoding:NSASCIIStringEncoding]; - NHLog(@"SERVER-OUT", string); - [string release]; - [outputFile readInBackgroundAndNotify]; -} - -- (void)didReadStdErr:(NSNotification *)aNotification -{ - NSString * string = [[NSString alloc] initWithData:[[aNotification userInfo] objectForKey:NSFileHandleNotificationDataItem] - encoding:NSASCIIStringEncoding]; - NHLog(@"SERVER-ERR", string); - [string release]; - [errorFile readInBackgroundAndNotify]; -} - -- (void)serverDidTerminate:(NSNotification *)note -{ - if ([process terminationStatus] != 0) - { - NSString *appName = [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:@"CFBundleDisplayName"]; - if (appName == nil) - appName = [[NSProcessInfo processInfo] processName]; - - if (SERVER_PORT != 9191 && [self start]) - { - NSRunAlertPanel(@"Unexpected Error", - [NSString stringWithFormat:@"%@ was not able to complete the last action you performed. Try again, and report the problem if it continues to occur.", appName], - @"OK", nil, nil); - } - else - { - NSRunAlertPanel(@"Unexpected Error", - [NSString stringWithFormat:@"A fatal error occurred. %@ could not recover and must terminate.", appName], - @"Terminate", nil, nil); - exit(1); - } - } -} - -- (void)dealloc -{ - [process release]; - [super dealloc]; -} - -@end diff --git a/Tools/NativeHost/WebPasteboardProxy.h b/Tools/NativeHost/WebPasteboardProxy.h deleted file mode 100644 index 887b95f4ca..0000000000 --- a/Tools/NativeHost/WebPasteboardProxy.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// WebPasteboardProxy.h -// NativeHost -// -// Created by Ross Boucher on 12/12/09. -// Copyright 2009 280 North. All rights reserved. -// - -#import - - -@interface WebPasteboardProxy : NSObject -{ - NSPasteboard *pasteboard; -} - -+ (id)pasteboardWithName:(NSString *)aName; - -@end diff --git a/Tools/NativeHost/WebPasteboardProxy.m b/Tools/NativeHost/WebPasteboardProxy.m deleted file mode 100644 index 6eba5c038e..0000000000 --- a/Tools/NativeHost/WebPasteboardProxy.m +++ /dev/null @@ -1,95 +0,0 @@ -// -// WebPasteboardProxy.m -// NativeHost -// -// Created by Ross Boucher on 12/12/09. -// Copyright 2009 280 North. All rights reserved. -// - -#import "WebPasteboardProxy.h" -#import "WebScripObject+Objective-J.h" -#import "BridgedMethods.h" - -NSMutableDictionary *WebPasteboardDictionary = nil; - -@implementation WebPasteboardProxy - -+ (void)initialize -{ - WebPasteboardDictionary = [[NSMutableDictionary dictionary] retain]; -} - -+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector -{ - return NO; -} - -+ (id)pasteboardWithName:(NSString *)aName -{ - if ([aName isEqual:@"CPGeneralPboard"]) - return [self pasteboardWithName:NSGeneralPboard]; - - id proxy = [WebPasteboardDictionary objectForKey:aName]; - if (!proxy) - { - proxy = [[self alloc] initWithPasteboard:[NSPasteboard pasteboardWithName:aName]]; - [WebPasteboardDictionary setObject:proxy forKey:aName]; - [proxy release]; - } - - return proxy; -} - -- (id)initWithPasteboard:(NSPasteboard *)aPasteboard -{ - if (self = [super init]) - { - pasteboard = [aPasteboard retain]; - } - - return self; -} - -- (void)dealloc -{ - [pasteboard release]; - [super dealloc]; -} - -- (int)changeCount -{ - return [pasteboard changeCount]; -} - -- (void)declareTypes:(WebScriptObject *)args -{ - [pasteboard declareTypes:[BridgedMethods arrayFromWebScriptObject:args] owner:self]; -} - -- (void)addTypes:(WebScriptObject *)args -{ - [pasteboard addTypes:[BridgedMethods arrayFromWebScriptObject:args ] owner:self]; -} - -- (NSArray *)types -{ - return [pasteboard types]; -} - -- (NSString *)stringForType:(NSString *)aType -{ - return [pasteboard stringForType:aType]; -} - -- (void)pasteboard:(NSPasteboard *)aPasteboard provideDataForType:(NSString *)aType -{ - NSString *name = aPasteboard == [NSPasteboard generalPasteboard] ? @"CPGeneralPboard" : [aPasteboard name]; - - NSString *data = [[[NSApp delegate] windowScriptObject] evaluateObjectiveJReturningString: - [NSString stringWithFormat:@"[[CPPasteboard pasteboardWithName:'%@'] stringForType:'%@']", name, aType] - ]; - - [aPasteboard setString:data forType:aType]; -} - -@end diff --git a/Tools/NativeHost/WebScripObject+Objective-J.h b/Tools/NativeHost/WebScripObject+Objective-J.h deleted file mode 100644 index 4b448574dd..0000000000 --- a/Tools/NativeHost/WebScripObject+Objective-J.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// WebScripObject+Objective-J.h -// NativeHost -// -// Created by Francisco Tolmasky on 9/1/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import -#import - - -@interface WebScriptObject (ObjectiveJ) - -- (id)evaluateObjectiveJ:(NSString *)aString; -- (NSString *)evaluateObjectiveJReturningString:(NSString *)aString; - -- (id)bridgeSelector:(SEL)aSelector; -- (id)bridgeSelector:(SEL)aSelector withObject:(id)anObject; -- (id)bridgeSelector:(SEL)aSelector withObjects:(NSArray *)array; - -@end diff --git a/Tools/NativeHost/WebScripObject+Objective-J.m b/Tools/NativeHost/WebScripObject+Objective-J.m deleted file mode 100644 index d1be2df470..0000000000 --- a/Tools/NativeHost/WebScripObject+Objective-J.m +++ /dev/null @@ -1,46 +0,0 @@ -// -// WebScripObject+Objective-J.m -// NativeHost -// -// Created by Francisco Tolmasky on 9/1/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import "WebScripObject+Objective-J.h" - - -@implementation WebScriptObject (ObjectiveJ) - -- (id)evaluateObjectiveJ:(NSString *)aString -{ - return [self evaluateWebScript:[NSString stringWithFormat:@"(ObjectiveJ.eval(decodeURIComponent(\"%@\")))", [aString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], nil]]; -} - -- (NSString *)evaluateObjectiveJReturningString:(NSString *)aString -{ - return [self evaluateWebScript:[NSString stringWithFormat:@"String(ObjectiveJ.eval(decodeURIComponent(\"%@\")))", [aString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], nil]]; -} - -- (id)bridgeSelector:(SEL)aSelector -{ - return [self bridgeSelector:aSelector withObjects:nil]; -} - -- (id)bridgeSelector:(SEL)aSelector withObject:(id)anObject -{ - return [self bridgeSelector:aSelector withObjects:[NSArray arrayWithObject:anObject]]; -} - -- (id)bridgeSelector:(SEL)aSelector withObjects:(NSArray *)objects -{ - [self evaluateWebScript:@"objj_object.prototype.__objj_msgSend = function() { return objj_msgSend.apply(null, arguments); }"]; - - NSArray * arguments = [NSArray arrayWithObjects:self, NSStringFromSelector(aSelector), nil]; - - if (objects) - arguments = [arguments arrayByAddingObjectsFromArray:objects]; - - return [self callWebScriptMethod:@"__objj_msgSend" withArguments:arguments]; -} - -@end diff --git a/Tools/NativeHost/WebWindow.h b/Tools/NativeHost/WebWindow.h deleted file mode 100644 index a7feb9fac8..0000000000 --- a/Tools/NativeHost/WebWindow.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// WebWindow.h -// NativeHost -// -// Created by Francisco Tolmasky on 10/18/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import - - -typedef enum _CPWindowShadowStyle -{ - CPStandardWindowShadowStyle = 0, - CPMenuWindowShadowStyle = 1, - CPPanelWindowShadowStyle = 2, - CPCustomWindowShadowStyle = 3 -} CPWindowShadowStyle; - -@interface WebWindow : NSWindow -{ - NSView * leftMouseDownView; - NSView * rightMouseDownView; - - WebView * webView; - NSView * shadowView; - - BOOL hasShadow; - CPWindowShadowStyle shadowStyle; -} - -+ (WebWindow *)webWindow; - -- (WebView *)webView; - -- (BOOL)hitTest:(NSPoint)aPoint; - -- (BOOL)hasShadow; -- (void)setHasShadow:(BOOL)shouldHaveShadow; - -- (void)setShadowStyle:(CPWindowShadowStyle)aStyle; -- (CPWindowShadowStyle)shadowStyle; - -@end diff --git a/Tools/NativeHost/WebWindow.m b/Tools/NativeHost/WebWindow.m deleted file mode 100644 index 1dc25e4a1c..0000000000 --- a/Tools/NativeHost/WebWindow.m +++ /dev/null @@ -1,515 +0,0 @@ -// -// WebWindow.m -// NativeHost -// -// Created by Francisco Tolmasky on 10/18/09. -// Copyright 2009 280 North, Inc.. All rights reserved. -// - -#import "WebWindow.h" - - -static NSMutableArray * DisabledWindows; - -CFMachPortRef tap_port; - -CGEventRef headTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) -{ - // It's dangerous to fail in this code: could disable mousedown system-wide. So just try catch it all. - @try - { - if (type == kCGEventLeftMouseDown) - { - CGPoint location = CGEventGetLocation(event); - NSPoint NSLocation = NSMakePoint(location.x, location.y); - - for (NSWindow * window in [NSApp windows]) - { - if ([window isKindOfClass:[WebWindow class]] && ![(WebWindow *)window hitTest:NSLocation]) - { - [window setIgnoresMouseEvents:YES]; - [window performSelector:@selector(setIgnoresMouseEvents:) withObject:NO afterDelay:1.0]; - - [DisabledWindows addObject:window]; - } - } - } - else if (type == kCGEventTapDisabledByTimeout) - CGEventTapEnable(tap_port, YES); - - } - @catch (NSException * anException) - { - } - - return event; -} - - -@interface WebWindowContentView : NSView -{ -} -@end - -@implementation WebWindow - -+ (void)enableAllWindows -{ - [DisabledWindows makeObjectsPerformSelector:@selector(stopIgnoringMouseEvents)]; - [DisabledWindows removeAllObjects]; -} - -+ (void)initialize -{ - if (self != [WebWindow class]) - return; - - DisabledWindows = [[NSMutableArray alloc] init]; - - //| CGEventMaskBit(kCGEventTapDisabledByTimeout) - tap_port = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, - kCGEventTapOptionDefault, - CGEventMaskBit(kCGEventLeftMouseDown), - headTapCallback, NULL); - - if (NULL == tap_port) - { - fprintf(stderr, "Error creating event tap\n"); - return; - } - - /* Create a run loop source from the tap port, add it to my run loop - * and start executing the loop - */ - CFRunLoopSourceRef tap_source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap_port, 0); - - if (NULL == tap_source) - { - fprintf(stderr, "Error converting port to run loop source\n"); - - if (tap_port != NULL) - CFRelease(tap_port); - - return; - } - - CFRunLoopAddSource(CFRunLoopGetCurrent(), tap_source, kCFRunLoopCommonModes); -} - -- (id)initWithContentRect:(NSRect)aContentRect styleMask:(NSUInteger)windowStyle backing:(NSBackingStoreType)aBufferingType defer:(BOOL)shouldDeferCreation -{ - self = [super initWithContentRect:aContentRect styleMask:NSBorderlessWindowMask backing:aBufferingType defer:shouldDeferCreation]; - - if (self) - { - id delegate = [NSApp delegate]; - - shadowView = [[WebWindowContentView alloc] init]; - - [self setContentView:shadowView]; - - webView = [[WebView alloc] initWithFrame:NSZeroRect]; - - [webView setDrawsBackground:NO]; - [webView setUIDelegate:delegate]; - [webView setFrameLoadDelegate:delegate]; - [webView setResourceLoadDelegate:delegate]; - [webView setPolicyDelegate:delegate]; - [webView setShouldCloseWithWindow:YES]; - - [shadowView addSubview:webView]; - - [self setBackgroundColor:[NSColor clearColor]]; - [self setOpaque:NO]; - [self setIgnoresMouseEvents:NO]; - [self setReleasedWhenClosed:YES]; - [super setHasShadow:NO]; - } - - return self; -} - -- (void)setFrame:(NSRect)aFrame display:(BOOL)shouldDisplay -{ - [webView setFrame:NSMakeRect(33.0, 33.0, NSWidth(aFrame), NSHeight(aFrame))]; - [super setFrame:NSInsetRect(aFrame, -33.0, -33.0) display:YES]; -} - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidResizeNotification object:self]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidBecomeKeyNotification object:self]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidResignKeyNotification object:self]; - - [shadowView release]; - [webView release]; - [super dealloc]; -} - -- (BOOL)canBecomeKeyWindow -{ - // Necessary since this apparently returns NO for borderless windows. - return YES; -} - -- (NSView *)webHitTest:(NSPoint)aPoint -{ - NSPoint locationInWebView = [[self contentView] convertPoint:aPoint fromView:nil]; - - return [(NSView *)[self contentView] hitTest:locationInWebView]; -} - -- (void)sendEvent:(NSEvent *)anEvent -{ - NSInteger type = [anEvent type]; - - if (type == NSLeftMouseDown) - { - NSView * view = [self webHitTest:[anEvent locationInWindow]]; - - leftMouseDownView = view; - - [view mouseDown:anEvent]; - } - - else if (type == NSLeftMouseDragged) - [leftMouseDownView mouseDragged:anEvent]; - - else if (type == NSLeftMouseUp) - [leftMouseDownView mouseUp:anEvent]; - - else if (type == NSRightMouseDown) - { - NSView * view = [self webHitTest:[anEvent locationInWindow]]; - - rightMouseDownView = view; - - [view rightMouseDown:anEvent]; - } - else if (type == NSRightMouseDragged) - [rightMouseDownView rightMouseDragged:anEvent]; - - else if (type == NSRightMouseUp) - [rightMouseDownView rightMouseUp:anEvent]; - - else - [super sendEvent:anEvent]; - - // FIXME: other -} - -// Override this to avoid the beep from unhandled events. -- (void)keyDown:(NSEvent *)anEvent -{ -} - -+ (WebWindow *)webWindow -{ - return [[WebWindow alloc] initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]; -} - -- (WebView *)webView -{ - return webView; -} - -- (void)updateShadow -{ - [super setHasShadow:hasShadow && shadowStyle == CPCustomWindowShadowStyle]; - [shadowView setNeedsDisplay:YES]; -} - -- (BOOL)hasShadow -{ - return hasShadow; -} - -- (void)setHasShadow:(BOOL)shouldHaveShadow -{ - if (hasShadow == shouldHaveShadow) - return; - - hasShadow = shouldHaveShadow; - - [self updateShadow]; -} - -- (CPWindowShadowStyle)shadowStyle -{ - return shadowStyle; -} - -- (void)setShadowStyle:(CPWindowShadowStyle)aStyle -{ - if (shadowStyle == aStyle) - return; - - shadowStyle = aStyle; - - [self updateShadow]; -} - -- (BOOL)hitTest:(NSPoint)aPoint -{ - NSInteger windowNumber = [[[webView windowScriptObject] valueForKey:@"cpWindowNumber"] intValue]; - -#if LOGGING - WebScriptObject * frame = [[[NSApp delegate] windowScriptObject] evaluateWebScript:[NSString stringWithFormat:@"(objj_msgSend(objj_msgSend(CPApp, \"windowWithWindowNumber:\", %d), \"frame\"))", windowNumber]], - * origin = [frame valueForKey:@"origin"], - * size = [frame valueForKey:@"size"]; - - NSLog(@"(%f, %f) in { %f, %f, %f, %f }", aPoint.x, aPoint.y, [[origin valueForKey:@"x"] floatValue], [[origin valueForKey:@"y"] floatValue], [[size valueForKey:@"width"] floatValue], [[size valueForKey:@"height"] floatValue]); -#endif - - return [[[[NSApp delegate] windowScriptObject] evaluateWebScript:[NSString stringWithFormat:@"(CGRectContainsPoint(objj_msgSend(objj_msgSend(CPApp, \"windowWithWindowNumber:\", %d), \"frame\"), CGPointMake(%f, %f)))", windowNumber, aPoint.x, aPoint.y]] boolValue]; -} - -- (void)stopIgnoringMouseEvents -{ - [self setIgnoresMouseEvents:NO]; -} - -- (void)becomeKeyWindow -{ - [super becomeKeyWindow]; - - [self updateShadow]; -} - -- (void)resignKeyWindow -{ - [super resignKeyWindow]; - - [self updateShadow]; -} - -@end - -@interface NSImage (Additions) - -- (void)drawInRect:(NSRect)aRect slices:(CGFloat [])slices; - -@end - -@implementation NSImage (Additions) - -- (void)drawInRect:(NSRect)aRect slices:(CGFloat [])slices -{ - NSRect imageBounds = NSMakeRect(0.0, 0.0, [self size].width, [self size].height); - - [self drawInRect:NSMakeRect(0.0, 0.0, slices[0], slices[1]) - fromRect:NSMakeRect(0.0, 0.0, slices[0], slices[1]) - operation:NSCompositeSourceOver - fraction:1.0]; - - [self drawInRect:NSMakeRect(NSMaxX(aRect) - slices[2], 0.0, slices[2], slices[1]) - fromRect:NSMakeRect(NSMaxX(imageBounds) - slices[2], 0.0, slices[2], slices[1]) - operation:NSCompositeSourceOver - fraction:1.0]; - - [self drawInRect:NSMakeRect(0.0, NSMaxY(aRect) - slices[3], slices[0], slices[3]) - fromRect:NSMakeRect(0.0, NSMaxY(imageBounds) - slices[3], slices[0], slices[3]) - operation:NSCompositeSourceOver - fraction:1.0]; - - [self drawInRect:NSMakeRect(NSMaxX(aRect) - slices[2], NSMaxY(aRect) - slices[3], slices[2], slices[3]) - fromRect:NSMakeRect(NSMaxX(imageBounds) - slices[2], NSMaxY(imageBounds) - slices[3], slices[2], slices[3]) - operation:NSCompositeSourceOver - fraction:1.0]; - - [self drawInRect:NSMakeRect(slices[0], 0.0, NSWidth(aRect) - slices[0] - slices[2], slices[1]) - fromRect:NSMakeRect(slices[0], 0.0, 1.0, slices[1]) - operation:NSCompositeSourceOver - fraction:1.0]; - - [self drawInRect:NSMakeRect(0.0, slices[1], slices[0], NSHeight(aRect) - slices[1] - slices[3]) - fromRect:NSMakeRect(0.0, slices[1], slices[0], 1.0) - operation:NSCompositeSourceOver - fraction:1.0]; - - [self drawInRect:NSMakeRect(NSMaxX(aRect) - slices[2], slices[1], slices[2], NSHeight(aRect) - slices[1] - slices[3]) - fromRect:NSMakeRect(NSMaxX(imageBounds) - slices[2], slices[1], slices[2], 1.0) - operation:NSCompositeSourceOver - fraction:1.0]; - - [self drawInRect:NSMakeRect(slices[0], NSMaxY(aRect) - slices[3], NSWidth(aRect) - slices[0] - slices[2], slices[3]) - fromRect:NSMakeRect(slices[0], NSMaxY(imageBounds) - slices[3], 1.0, slices[3]) - operation:NSCompositeSourceOver - fraction:1.0]; -} - -@end - -@implementation WebWindowContentView : NSView -{ -} - -static float OUTlINE_HORIZONTAL_INSET = 33.0; -static float OUTlINE_VERTICAL_INSET = 33.0; - -- (void)drawStandardActiveShadowInRect:(NSRect)aRect -{ - CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; - - CGRect bounds = CGRectInset(*(CGRect *)&aRect, OUTlINE_HORIZONTAL_INSET - 0.5, OUTlINE_VERTICAL_INSET - 0.5); - - CGColorRef shadowColor = CGColorCreateGenericGray(0.0, 0.8); - CGContextSetShadowWithColor (context, CGSizeMake(0.0, -10.0), 100.0, shadowColor); - CGColorRelease(shadowColor); - - CGColorRef fillColor = CGColorCreateGenericGray(1.0, 1.0); - CGColorRef strokeColor = CGColorCreateGenericGray(0.0, 0.2); - - CGContextSetFillColorWithColor(context, fillColor); - CGContextSetStrokeColorWithColor(context, strokeColor); - - CGColorRelease(fillColor); - CGColorRelease(strokeColor); - - CGContextBeginPath(context); - - CGContextAddArc(context, CGRectGetMinX(bounds) + 5.0, CGRectGetMaxY(bounds) - 5.0, 5.0, M_PI, M_PI_2, YES); - CGContextAddArc(context, CGRectGetMaxX(bounds) - 5.0, CGRectGetMaxY(bounds) - 5.0, 5.0, M_PI_2, 0, YES); - CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), CGRectGetMinY(bounds)); - CGContextAddLineToPoint(context, CGRectGetMinX(bounds), CGRectGetMinY(bounds)); - - CGContextClosePath(context); - - CGContextDrawPath(context, kCGPathFillStroke); -} - -- (void)drawStandardInactiveShadowInRect:(NSRect)aRect -{ - CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; - - CGRect bounds = CGRectInset(*(CGRect *)&aRect, OUTlINE_HORIZONTAL_INSET - 0.5, OUTlINE_VERTICAL_INSET - 0.5); - - CGColorRef shadowColor = CGColorCreateGenericGray(0.0, 0.5); - CGContextSetShadowWithColor (context, CGSizeMake(0.0, -10.0), 40.0, shadowColor); - CGColorRelease(shadowColor); - - CGColorRef fillColor = CGColorCreateGenericGray(1.0, 1.0); - CGColorRef strokeColor = CGColorCreateGenericGray(0.0, 0.2); - - CGContextSetFillColorWithColor(context, fillColor); - CGContextSetStrokeColorWithColor(context, strokeColor); - - CGColorRelease(fillColor); - CGColorRelease(strokeColor); - - CGContextBeginPath(context); - - CGContextAddArc(context, CGRectGetMinX(bounds) + 5.0, CGRectGetMaxY(bounds) - 5.0, 5.0, M_PI, M_PI_2, YES); - CGContextAddArc(context, CGRectGetMaxX(bounds) - 5.0, CGRectGetMaxY(bounds) - 5.0, 5.0, M_PI_2, 0, YES); - CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), CGRectGetMinY(bounds)); - CGContextAddLineToPoint(context, CGRectGetMinX(bounds), CGRectGetMinY(bounds)); - - CGContextClosePath(context); - - CGContextDrawPath(context, kCGPathFillStroke); -} - -- (void)drawMenuShadowInRect:(NSRect)aRect -{ - CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; - - CGRect bounds = CGRectInset(*(CGRect *)&aRect, OUTlINE_HORIZONTAL_INSET - 0.5, OUTlINE_VERTICAL_INSET - 0.5); - - CGColorRef shadowColor = CGColorCreateGenericGray(0.0, 0.5); - CGContextSetShadowWithColor (context, CGSizeMake(0.0, -10.0), 30.0, shadowColor); - CGColorRelease(shadowColor); - - CGColorRef fillColor = CGColorCreateGenericGray(1.0, 1.0); - CGColorRef strokeColor = CGColorCreateGenericGray(0.0, 0.2); - - CGContextSetFillColorWithColor(context, fillColor); - CGContextSetStrokeColorWithColor(context, strokeColor); - - CGColorRelease(fillColor); - CGColorRelease(strokeColor); - - CGContextBeginPath(context); - - CGContextAddArc(context, CGRectGetMinX(bounds) + 3.0, CGRectGetMaxY(bounds) - 3.0, 2.0, M_PI, M_PI_2, YES); - CGContextAddArc(context, CGRectGetMaxX(bounds) - 3.0, CGRectGetMaxY(bounds) - 3.0, 2.0, M_PI_2, 0, YES); - CGContextAddArc(context, CGRectGetMaxX(bounds) - 3.0, CGRectGetMinY(bounds) + 3.0, 2.0, 0, 3 * M_PI_2, YES); - CGContextAddArc(context, CGRectGetMinX(bounds) + 3.0, CGRectGetMinY(bounds) + 3.0, 2.0, 3 * M_PI_2, M_PI, YES); - - CGContextClosePath(context); - - CGContextDrawPath(context, kCGPathFill);//Stroke); - -/* - CGContextBeginPath(context); - - CGContextAddArc(context, CGRectGetMinX(bounds) + 3.0, CGRectGetMaxY(bounds) - 3.0, 2.0, M_PI, M_PI_2, YES); - CGContextAddArc(context, CGRectGetMaxX(bounds) - 3.0, CGRectGetMaxY(bounds) - 3.0, 2.0, M_PI_2, 0, YES); - CGContextAddArc(context, CGRectGetMaxX(bounds) - 3.0, CGRectGetMinY(bounds) + 3.0, 2.0, 0, 3 * M_PI_2, YES); - CGContextAddArc(context, CGRectGetMinX(bounds) + 3.0, CGRectGetMinY(bounds) + 3.0, 2.0, 3 * M_PI_2, M_PI, YES); - - CGContextClosePath(context); - - CGContextSetFillColorWithColor(context, CGColorGetConstantColor(kCGColorClear)); - - CGContextSetBlendMode(context, kCGBlendModeCopy); - CGContextDrawPath(context, kCGPathFill); -*/ -} - -- (NSImage *)shadowImageWithSelector:(SEL)aSelector -{ - static NSMutableDictionary * images = nil; - - if (!images) - images = [[NSMutableDictionary alloc] init]; - - NSString * name = NSStringFromSelector(aSelector); - NSImage * image = [images objectForKey:name]; - - if (!image) - { - image = [[NSImage alloc] initWithSize:NSMakeSize(100.0, 100.0)]; - - [image lockFocus]; - objc_msgSend(self, aSelector, NSMakeRect(0.0, 0.0, 100.0, 100.0)); - [image unlockFocus]; - - [images setObject:image forKey:name]; - - [image release]; - } - - return image; -} - -- (void)drawShadowWithSelector:(SEL)aSelector inRect:(NSRect)aRect -{ - CGFloat slices[] = { 40.0, 49.0, 40.0, 49.0 }; - - if (NSWidth(aRect) > 100.0 || NSHeight(aRect) > 100.0) - [[self shadowImageWithSelector:aSelector] drawInRect:aRect slices:slices]; - else - objc_msgSend(self, aSelector, aRect); -} - -- (void)drawRect:(NSRect)aRect -{ - WebWindow * window = (WebWindow *)[self window]; - NSRect bounds = [self bounds]; - - if (![window hasShadow]) - return; - - if ([window shadowStyle] == CPStandardWindowShadowStyle) - if ([window isKeyWindow]) - return [self drawShadowWithSelector:@selector(drawStandardActiveShadowInRect:) inRect:bounds]; - else - return [self drawShadowWithSelector:@selector(drawStandardInactiveShadowInRect:) inRect:bounds]; - - - if ([window shadowStyle] == CPMenuWindowShadowStyle) - return [self drawShadowWithSelector:@selector(drawMenuShadowInRect:) inRect:bounds]; -} - -@end - diff --git a/Tools/NativeHost/icon.icns b/Tools/NativeHost/icon.icns deleted file mode 100644 index cd9ecb6bb8810528ef1b89898a30fd6f8c89e963..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81151 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 F{uh$X`~(01 diff --git a/Tools/NativeHost/main.m b/Tools/NativeHost/main.m deleted file mode 100644 index 2a040439e8..0000000000 --- a/Tools/NativeHost/main.m +++ /dev/null @@ -1,23 +0,0 @@ -// -// main.m -// NativeHost -// -// Created by Francisco Tolmasky on 5/24/09. -// Copyright 280 North, Inc. 2009. All rights reserved. -// - -#import -#import "Application.h" - -int interactive = 0; - -int main(int argc, char *argv[]) -{ - if (argc > 1 && strcmp(argv[1], "-i") == 0) { - interactive = 1; - } - - [Application sharedApplication]; - - return NSApplicationMain(argc, (const char **) argv); -} diff --git a/Tools/capp/Resources/Templates/NibApplication/Jakefile b/Tools/capp/Resources/Templates/NibApplication/Jakefile index a25464947c..fd053cf00c 100644 --- a/Tools/capp/Resources/Templates/NibApplication/Jakefile +++ b/Tools/capp/Resources/Templates/NibApplication/Jakefile @@ -82,18 +82,6 @@ task ("deploy", ["release"], function() printResults("Deployment") }); -task ("desktop", ["release"], function() -{ - FILE.mkdirs(FILE.join("Build", "Desktop", projectName)); - require("cappuccino/nativehost").buildNativeHost(FILE.join("Build", "Release", projectName), FILE.join("Build", "Desktop", projectName, "__project.nameasidentifier__.app")); - printResults("Desktop") -}); - -task ("run-desktop", ["desktop"], function() -{ - OS.system([FILE.join("Build", "Desktop", projectName, "__project.nameasidentifier__.app", "Contents", "MacOS", "NativeHost"), "-i"]); -}); - function printResults(configuration) { print("----------------------------");