Lines 29-34
Link Here
|
29 |
|
29 |
|
30 |
int initialized = 0; |
30 |
int initialized = 0; |
31 |
|
31 |
|
|
|
32 |
/* The semaphore that blocks until the openDocuments/openApplication |
33 |
* Apple events have been received |
34 |
*/ |
35 |
MPSemaphoreID startupEventSemaphore; |
36 |
|
37 |
/* The list of opened document paths from an openDocuments Apple event */ |
38 |
_TCHAR** startupOpenedDocuments = NULL; |
39 |
|
40 |
/* The Apple Event event processor */ |
41 |
static OSStatus appleEventProc(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon); |
42 |
|
43 |
/* The openApplication Apple Event callback */ |
44 |
static pascal OSErr openApplicationAEProc(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon); |
45 |
|
46 |
/* The openDocuments Apple Event callback */ |
47 |
static pascal OSErr openDocumentsAEProc(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon); |
48 |
|
32 |
static void init() { |
49 |
static void init() { |
33 |
if (!initialized) { |
50 |
if (!initialized) { |
34 |
ProcessSerialNumber psn; |
51 |
ProcessSerialNumber psn; |
Lines 48-58
Link Here
|
48 |
*/ |
65 |
*/ |
49 |
void initWindowSystem( int* pArgc, char* argv[], int showSplash ) |
66 |
void initWindowSystem( int* pArgc, char* argv[], int showSplash ) |
50 |
{ |
67 |
{ |
|
|
68 |
EventTypeSpec kEvents[] = { {kEventClassAppleEvent, kEventAppleEvent} }; |
69 |
|
51 |
char *homeDir = getProgramDir(); |
70 |
char *homeDir = getProgramDir(); |
52 |
/*debug("install dir: %s\n", homeDir);*/ |
71 |
/*debug("install dir: %s\n", homeDir);*/ |
53 |
if (homeDir != NULL) |
72 |
if (homeDir != NULL) |
54 |
chdir(homeDir); |
73 |
chdir(homeDir); |
55 |
|
74 |
|
|
|
75 |
/* Create a semaphore and immediately lock it. This will be |
76 |
* unlocked by the openApplication or openDocuments Apple Event. |
77 |
* The OS guarantees that one (and only one) of these will be |
78 |
* sent during the app startup process. The events are delivered |
79 |
* very quickly, so this only slightly increases startup time. The |
80 |
* startJavaVM function in eclipseCarbon.c is also blocking on this |
81 |
* event, because startJavaVM is called prior to this initialization |
82 |
* process. |
83 |
*/ |
84 |
MPCreateBinarySemaphore(&startupEventSemaphore); |
85 |
MPWaitOnSemaphore(startupEventSemaphore, kDurationForever); |
86 |
|
87 |
/* Install the Apple Event handlers */ |
88 |
InstallApplicationEventHandler(NewEventHandlerUPP(appleEventProc), GetEventTypeCount(kEvents), kEvents, 0, NULL); |
89 |
AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, NewAEEventHandlerUPP(openApplicationAEProc), 0, false); |
90 |
AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerUPP(openDocumentsAEProc), 0, false); |
91 |
|
56 |
if (showSplash) |
92 |
if (showSplash) |
57 |
init(); |
93 |
init(); |
58 |
} |
94 |
} |
Lines 166-169
Link Here
|
166 |
} |
202 |
} |
167 |
CFRelease(url); |
203 |
CFRelease(url); |
168 |
return result; |
204 |
return result; |
169 |
} |
205 |
} |
|
|
206 |
|
207 |
/* This is taken from an Apple example on handling Apple Events manually */ |
208 |
static OSStatus appleEventProc(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon) { |
209 |
Boolean release = false; |
210 |
EventRecord eventRecord; |
211 |
OSErr ignoreErrForThisSample; |
212 |
|
213 |
// Events of type kEventAppleEvent must be removed from the queue |
214 |
// before being passed to AEProcessAppleEvent. |
215 |
if (IsEventInQueue(GetMainEventQueue(), inEvent)) { |
216 |
// RemoveEventFromQueue will release the event, which will |
217 |
// destroy it if we don't retain it first. |
218 |
RetainEvent(inEvent); |
219 |
release = true; |
220 |
RemoveEventFromQueue(GetMainEventQueue(), inEvent); |
221 |
} |
222 |
|
223 |
// Convert the event ref to the type AEProcessAppleEvent expects. |
224 |
ConvertEventRefToEventRecord(inEvent, &eventRecord); |
225 |
ignoreErrForThisSample = AEProcessAppleEvent(&eventRecord); |
226 |
|
227 |
if (release) { |
228 |
ReleaseEvent(inEvent); |
229 |
} |
230 |
|
231 |
// This Carbon event has been handled, even if no AppleEvent handlers |
232 |
// were installed for the Apple event. |
233 |
return noErr; |
234 |
} |
235 |
|
236 |
/* openApplication doesn't do anything except signal the startup semaphore */ |
237 |
static pascal OSErr openApplicationAEProc(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon) { |
238 |
MPSignalSemaphore(startupEventSemaphore); |
239 |
return noErr; |
240 |
} |
241 |
|
242 |
/* openDocuments parses out the list of files that triggered this application |
243 |
* to launch, and sets them into the _TCHAR **startupOpenedDocuments which |
244 |
* will be consumed by startJavaVM in eclipseCarbon.c as commandline |
245 |
* paramaters. When this process is complete, the startup semaphore |
246 |
* will be signalled. |
247 |
*/ |
248 |
static pascal OSErr openDocumentsAEProc(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon) { |
249 |
AEDescList docList; |
250 |
FSRef fsRef; |
251 |
CFURLRef resolved; |
252 |
Boolean isFolder, wasAliased; |
253 |
CFStringRef string; |
254 |
long index; |
255 |
long count = 0; |
256 |
OSErr err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList); |
257 |
require_noerr(err, CantGetDocList); |
258 |
|
259 |
err = AECountItems(&docList, &count); |
260 |
require_noerr(err, CantGetCount); |
261 |
|
262 |
//CFStringRef imageString = CFStringCreateWithCString(kCFAllocatorDefault, featureImage, kCFStringEncodingASCII); |
263 |
startupOpenedDocuments = malloc((count) * sizeof(_TCHAR*)); |
264 |
memset(startupOpenedDocuments, 0, (count) * sizeof(_TCHAR*)); |
265 |
for (index = 1; index <= count; index++) { |
266 |
err = AEGetNthPtr(&docList, index, typeFSRef, NULL, NULL, &fsRef, sizeof(FSRef), NULL); |
267 |
require_noerr(err, CantGetDocDescPtr); |
268 |
|
269 |
if (FSResolveAliasFile(&fsRef, true, &isFolder, &wasAliased) == noErr) { |
270 |
resolved = CFURLCreateFromFSRef(kCFAllocatorDefault, &fsRef); |
271 |
if (resolved != NULL) { |
272 |
string = CFURLCopyFileSystemPath(resolved, kCFURLPOSIXPathStyle); |
273 |
CFIndex length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(string), kCFStringEncodingUTF8); |
274 |
char *s = malloc(length); |
275 |
if (CFStringGetCString(string, s, length, kCFStringEncodingUTF8)) { |
276 |
startupOpenedDocuments[index - 1] = s; |
277 |
} |
278 |
else { |
279 |
free(s); |
280 |
} |
281 |
CFRelease(string); |
282 |
CFRelease(resolved); |
283 |
} |
284 |
} |
285 |
} |
286 |
|
287 |
CantGetCount: |
288 |
CantGetDocDescPtr: |
289 |
AEDisposeDesc(&docList); |
290 |
|
291 |
CantGetDocList: |
292 |
if (err != noErr) { |
293 |
// For handlers that expect a reply, add error information here. |
294 |
} |
295 |
|
296 |
MPSignalSemaphore(startupEventSemaphore); |
297 |
return err; |
298 |
} |