blob: 8b24d2ecf1e2b2bb32a2c64e17faf8ba5a80e0ec (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
#import <Foundation/Foundation.h>
#import <CoreServices/CoreServices.h>
#import <Carbon/Carbon.h>
#import <stdlib.h>
#import <stdio.h>
#import <unistd.h>
#import <errno.h>
#import <sys/types.h>
#import <sys/stat.h>
// The path to the command file, which we'll delete on death (if it exists)
static char s_command_path[PATH_MAX];
static void die(const char *format, ...) {
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fputc('\n', stderr);
if (s_command_path[0] != '\0') {
unlink(s_command_path);
}
exit(EXIT_FAILURE);
}
static void launch_fish_with_applescript(NSString *fish_binary_path)
{
// load the script from a resource by fetching its URL from within our bundle
NSString *path = [[NSBundle mainBundle] pathForResource:@"launch_fish" ofType:@"scpt"];
if (! path) die("Couldn't get path to launch_fish.scpt");
NSURL *url = [NSURL fileURLWithPath:path isDirectory:NO];
if (! url) die("Couldn't get URL to launch_fish.scpt");
NSDictionary *errors = nil;
NSAppleScript *appleScript = [[NSAppleScript alloc] initWithContentsOfURL:url error:&errors];
if (! appleScript) die("Couldn't load AppleScript");
// create the first parameter
NSAppleEventDescriptor *firstParameter =
[NSAppleEventDescriptor descriptorWithString:fish_binary_path];
// create and populate the list of parameters (in our case just one)
NSAppleEventDescriptor *parameters = [NSAppleEventDescriptor listDescriptor];
[parameters insertDescriptor:firstParameter atIndex:1];
// create the AppleEvent target
ProcessSerialNumber psn = {0, kCurrentProcess};
NSAppleEventDescriptor *target =
[NSAppleEventDescriptor
descriptorWithDescriptorType:typeProcessSerialNumber
bytes:&psn
length:sizeof(ProcessSerialNumber)];
// create an NSAppleEventDescriptor with the script's method name to call,
// this is used for the script statement: "on show_message(user_message)"
// Note that the routine name must be in lower case.
NSAppleEventDescriptor *handler = [NSAppleEventDescriptor descriptorWithString:
[@"launch_fish" lowercaseString]];
// create the event for an AppleScript subroutine,
// set the method name and the list of parameters
NSAppleEventDescriptor *event =
[NSAppleEventDescriptor appleEventWithEventClass:kASAppleScriptSuite
eventID:kASSubroutineEvent
targetDescriptor:target
returnID:kAutoGenerateReturnID
transactionID:kAnyTransactionID];
[event setParamDescriptor:handler forKeyword:keyASSubroutineName];
[event setParamDescriptor:parameters forKeyword:keyDirectObject];
// call the event in AppleScript
if (![appleScript executeAppleEvent:event error:&errors])
{
// report any errors from 'errors'
NSLog(@"Oops: %@", errors);
}
[appleScript release];
}
/* This approach asks Terminal to open a script that we control */
int main(void) {
[[NSAutoreleasePool alloc] init];
/* Get the fish executable. Make sure it's absolute. */
NSURL *fish_executable = [[NSBundle mainBundle] URLForResource:@"fish" withExtension:@"" subdirectory:@"base/bin"];
if (! fish_executable)
die("Could not find fish executable in bundle");
launch_fish_with_applescript([fish_executable path]);
/* If we succeeded, it will clean itself up */
return 0;
}
|