]> gitweb.factorcode.org Git - factor.git/blob - vm/os-macosx.mm
vm: setting current directory when launching Factor.app
[factor.git] / vm / os-macosx.mm
1 #import <Cocoa/Cocoa.h>
2
3 #include <mach/mach_time.h>
4 #include <sys/utsname.h>
5
6 #include "master.hpp"
7
8 namespace factor {
9
10 void factor_vm::c_to_factor_toplevel(cell quot) { c_to_factor(quot); }
11
12 // Darwin 9 is 10.5, Darwin 10 is 10.6
13 // http://en.wikipedia.org/wiki/Darwin_(operating_system)#Release_history
14 void early_init(void) {
15   struct utsname u;
16   int n;
17   uname(&u);
18   sscanf(u.release, "%d", &n);
19   if (n < 9) {
20     std::cout << "Factor requires Mac OS X 10.5 or later.\n";
21     exit(1);
22   }
23 }
24
25 // You must free() this yourself.
26 const char* vm_executable_path(void) {
27   return safe_strdup([[[NSBundle mainBundle] executablePath] UTF8String]);
28 }
29
30 const char* default_image_path(void) {
31   NSBundle* bundle = [NSBundle mainBundle];
32   NSString* path = [bundle bundlePath];
33   NSString* executablePath = [[bundle executablePath] stringByResolvingSymlinksInPath];
34   NSString* executable = [executablePath lastPathComponent];
35   NSString* image = [executable stringByAppendingString:@".image"];
36
37   NSString* returnVal;
38
39   if ([path hasSuffix:@".app"] || [path hasSuffix:@".app/"]) {
40     NSFileManager* mgr = [NSFileManager defaultManager];
41
42     NSString* root = [path stringByDeletingLastPathComponent];
43     [mgr changeCurrentDirectoryPath: root];
44
45     NSString* imageInBundle =
46         [[path stringByAppendingPathComponent:@"Contents/Resources"]
47             stringByAppendingPathComponent:image];
48     NSString* imageAlongBundle = [[path stringByDeletingLastPathComponent]
49         stringByAppendingPathComponent:image];
50
51     returnVal = ([mgr fileExistsAtPath:imageInBundle] ? imageInBundle
52                                                       : imageAlongBundle);
53   } else if ([executablePath hasSuffix:@".app/Contents/MacOS/factor"]) {
54     returnVal = executablePath;
55     returnVal = [returnVal stringByDeletingLastPathComponent];
56     returnVal = [returnVal stringByDeletingLastPathComponent];
57     returnVal = [returnVal stringByDeletingLastPathComponent];
58     returnVal = [returnVal stringByDeletingLastPathComponent];
59     returnVal = [returnVal stringByAppendingPathComponent:image];
60   } else {
61     returnVal = [path stringByAppendingPathComponent:image];
62   }
63
64   return [returnVal UTF8String];
65 }
66
67 void factor_vm::init_signals(void) {
68   unix_init_signals();
69   mach_initialize();
70 }
71
72 // Amateurs at Apple: implement this function, properly!
73 Protocol* objc_getProtocol(char* name) {
74   if (strcmp(name, "NSTextInput") == 0)
75     return @protocol(NSTextInput);
76   else
77     return nil;
78 }
79
80 uint64_t nano_count() {
81   uint64_t time = mach_absolute_time();
82
83   static uint64_t scaling_factor = 0;
84   if (!scaling_factor) {
85     mach_timebase_info_data_t info;
86     kern_return_t ret = mach_timebase_info(&info);
87     if (ret != 0)
88       fatal_error("mach_timebase_info failed", ret);
89     scaling_factor = info.numer / info.denom;
90   }
91
92   return time * scaling_factor;
93 }
94
95 }