Making ITAppleEventCenter use ITDebugLog for all debugging things. This
[ITFoundation.git] / ITAppleEventCenter.m
1 #import "ITAppleEventCenter.h"
2 #import "ITDebug.h"
3
4 static Boolean MyAEIdleCallback (
5                                          EventRecord * theEvent,
6                                          SInt32 * sleepTime,
7                                          RgnHandle * mouseRgn
8                                          )
9 {
10     return FALSE;
11 }
12
13 @implementation ITAppleEventCenter
14
15 static ITAppleEventCenter *_sharedAECenter = nil;
16
17 + (id)sharedCenter
18 {
19     if( _sharedAECenter ) {
20         return _sharedAECenter;
21     } else {
22         return _sharedAECenter = [[ITAppleEventCenter alloc] init];
23     }
24 }
25
26 - (id)init
27 {
28     if ( ( self = [super init] ) ) {
29         idleUPP = NewAEIdleUPP(MyAEIdleCallback);
30     }
31     return self;
32 }
33
34 - (void)dealloc
35 {
36     DisposeAEIdleUPP(idleUPP);
37 }
38
39 - (NSString*)sendAEWithRequestedKey:(NSString*)key eventClass:(NSString*)eventClass eventID:(NSString*)eventID appPSN:(ProcessSerialNumber)psn
40 {
41     //Add error checking...
42     AEEventClass eClass = *((unsigned long*)[eventClass UTF8String]);
43     AEEventID    eID    = *((unsigned long*)[eventID UTF8String]);
44     int pid;
45     NSString *nssendString = [NSString stringWithFormat:@"'----':obj { form:'prop', want:type('prop'), seld:type('%s'), from:'null'() }", [key UTF8String]];
46     const char *sendString = [nssendString UTF8String];
47     NSString  *_finalString = nil;
48
49     AppleEvent sendEvent, replyEvent;
50
51     DescType resultType;
52     Size resultSize, charResultSize;
53
54     AEBuildError buildError;
55     OSStatus err;
56     OSErr berr, err2, err3;
57     
58         if ((GetProcessPID(&psn, &pid) == noErr) && (pid == 0)) {
59             ITDebugLog(@"Error getting PID of application! Exiting.");
60             return nil;
61         }
62         
63     ITDebugLog(@"_sendString: %s", sendString);
64
65     berr = AEBuildAppleEvent(eClass, eID, typeProcessSerialNumber,(ProcessSerialNumber*)&psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, 0, &sendEvent, &buildError, sendString);
66     [self printCarbonDesc:&sendEvent];
67
68     if (err) {
69         ITDebugLog(@"%d:%d at \"%@\"",(int)buildError.fError,buildError.fErrorPos,[nssendString substringToIndex:buildError.fErrorPos]);
70     }
71
72     err = AESend(&sendEvent, &replyEvent, kAEWaitReply, kAENormalPriority, kNoTimeOut, idleUPP, NULL);
73
74     [self printCarbonDesc:&replyEvent];
75
76     if (err) {
77         ITDebugLog(@"Send Error: %i",err);
78     } else {
79         unichar *result = 0;
80
81         err2 = AESizeOfParam(&replyEvent, keyDirectObject, &resultType, &resultSize);
82         result = malloc(resultSize);
83
84         if (err2) {
85             ITDebugLog(@"Error After AESizeOfParam: %i", err2);
86         } else {
87             err3 = AEGetParamPtr(&replyEvent, keyDirectObject, resultType, NULL, result, resultSize, &charResultSize);
88
89             if (err3) {
90                 ITDebugLog(@"Error After AEGetParamPtr: %i", err3);
91             } else {
92                 _finalString = [NSString stringWithCharacters:result length:charResultSize/sizeof(unichar)];
93             }
94         }
95         free(result);
96     }
97
98     if (!berr) AEDisposeDesc(&sendEvent);
99     if (!err) AEDisposeDesc(&replyEvent);
100
101     return _finalString;
102 }
103
104 - (NSString*)sendAEWithSendString:(NSString*)nssendString eventClass:(NSString*)eventClass eventID:(NSString*)eventID appPSN:(ProcessSerialNumber)psn
105 {
106     //Add error checking...
107     AEEventClass eClass = *((unsigned long*)[eventClass UTF8String]);
108     AEEventID    eID    = *((unsigned long*)[eventID UTF8String]);
109     int pid;
110
111     const char *sendString = [nssendString UTF8String];
112     NSString  *_finalString = nil;
113
114     AppleEvent sendEvent, replyEvent;
115
116     DescType resultType;
117     Size resultSize, charResultSize;
118
119     AEBuildError buildError;
120     OSStatus berr,err;
121     OSErr err2, err3;
122     
123         if ((GetProcessPID(&psn, &pid) == noErr) && (pid == 0)) {
124             ITDebugLog(@"Error getting PID of application! Exiting.");
125             return nil;
126         }
127         
128     ITDebugLog(@"_sendString: %s", sendString);
129
130     berr = AEBuildAppleEvent(eClass, eID, typeProcessSerialNumber,(ProcessSerialNumber*)&psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, 0, &sendEvent, &buildError, sendString);
131         ITDebugLog(@"sending...");
132     if (!berr) [self printCarbonDesc:&sendEvent];
133
134     if (berr) {
135         ITDebugLog(@"%d:%d at \"%@\"",(int)buildError.fError,buildError.fErrorPos,[nssendString substringToIndex:buildError.fErrorPos]);
136     }
137
138     err = AESend(&sendEvent, &replyEvent, kAEWaitReply, kAENormalPriority, kNoTimeOut, idleUPP, NULL);
139     ITDebugLog(@"replying...");
140     if (!err) [self printCarbonDesc:&replyEvent];
141
142     if (err) {
143         ITDebugLog(@"Send Error: %i",err);
144     } else {
145         unichar *result = 0;
146
147         err2 = AESizeOfParam(&replyEvent, keyDirectObject, &resultType, &resultSize);
148         result = malloc(resultSize);
149
150         if (err2) {
151             ITDebugLog(@"Error After AESizeOfParam: %i", err2);
152         } else {
153             err3 = AEGetParamPtr(&replyEvent, keyDirectObject, resultType, NULL, result, resultSize, &charResultSize);
154
155             if (err3) {
156                 ITDebugLog(@"Error After AEGetParamPtr: %i", err3);
157             } else {
158                 _finalString = [NSString stringWithCharacters:result length:charResultSize/sizeof(unichar)];
159             }
160         }
161         free(result);
162     }
163
164     if (!berr) AEDisposeDesc(&sendEvent);
165     if (!err) AEDisposeDesc(&replyEvent);
166
167     return _finalString;
168 }
169
170 - (long)sendAEWithRequestedKeyForNumber:(NSString*)key eventClass:(NSString*)eventClass eventID:(NSString*)eventID appPSN:(ProcessSerialNumber)psn
171 {
172     //Add error checking...
173     AEEventClass eClass = *((unsigned long*)[eventClass UTF8String]);
174     AEEventID    eID    = *((unsigned long*)[eventID UTF8String]);
175     int pid;
176
177     NSString *nssendString = [NSString stringWithFormat:@"'----':obj { form:'prop', want:type('prop'), seld:type('%s'), from:'null'() }", [key UTF8String]];
178     const char *sendString = [nssendString UTF8String];
179     long result = 0;
180
181     AppleEvent sendEvent, replyEvent;
182
183     DescType resultType;
184     Size resultSize, charResultSize;
185
186     AEBuildError buildError;
187     OSStatus err;
188     OSErr berr, err2, err3;
189     
190         if ((GetProcessPID(&psn, &pid) == noErr) && (pid == 0)) {
191             ITDebugLog(@"Error getting PID of application! Exiting.");
192             return nil;
193         }
194         
195     ITDebugLog(@"_sendString: %s", sendString);
196
197     berr = AEBuildAppleEvent(eClass, eID, typeProcessSerialNumber,(ProcessSerialNumber*)&psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, 0, &sendEvent, &buildError, sendString);
198
199     [self printCarbonDesc:&sendEvent];
200
201     if (err) {
202         ITDebugLog(@"%d:%d at \"%@\"",(int)buildError.fError,buildError.fErrorPos,[nssendString substringToIndex:buildError.fErrorPos]);
203     }
204
205     err = AESend(&sendEvent, &replyEvent, kAEWaitReply, kAENormalPriority, kNoTimeOut, idleUPP, NULL);
206
207     [self printCarbonDesc:&replyEvent];
208
209     if (err) {
210         ITDebugLog(@"Send Error: %i",err);
211     } else {
212         err2 = AESizeOfParam(&replyEvent, keyDirectObject, &resultType, &resultSize);
213
214         if (err2) {
215             ITDebugLog(@"Error After AESizeOfParam: %i", err2);
216         } else {
217             err3 = AEGetParamPtr(&replyEvent, keyDirectObject, resultType, NULL, &result, resultSize, &charResultSize);
218
219             if (err3) {
220                 ITDebugLog(@"Error After AEGetParamPtr: %i", err3);
221             }
222         }
223     }
224
225     if (!berr) AEDisposeDesc(&sendEvent);
226     if (!err) AEDisposeDesc(&replyEvent);
227
228     return result;
229 }
230
231 - (NSString*)sendTwoTierAEWithRequestedKey:(NSString*)key fromObjectByKey:(NSString*)object eventClass:(NSString*)eventClass eventID:(NSString*)eventID appPSN:(ProcessSerialNumber)psn
232 {
233     AEEventClass eClass = *((unsigned long*)[eventClass UTF8String]);
234     AEEventID    eID    = *((unsigned long*)[eventID UTF8String]);
235     int pid;
236
237     NSString *nssendString = [NSString stringWithFormat:@"'----':obj { form:'prop', want:type('prop'), seld:type('%s'), from:obj { form:'prop', want:type('prop'), seld:type('%s'), from:'null'() } }", [key UTF8String], [object UTF8String]];
238     const char *sendString = [nssendString UTF8String];
239     NSString  *_finalString = nil;
240
241     AppleEvent sendEvent, replyEvent;
242
243     DescType resultType;
244     Size resultSize, charResultSize;
245
246     AEBuildError buildError;
247     OSStatus berr,err;
248     OSErr err2, err3;
249     
250         if ((GetProcessPID(&psn, &pid) == noErr) && (pid == 0)) {
251             ITDebugLog(@"Error getting PID of application! Exiting.");
252             return nil;
253         }
254
255     ITDebugLog(@"_sendString: %s", sendString);
256
257     berr = AEBuildAppleEvent(eClass, eID, typeProcessSerialNumber,(ProcessSerialNumber*)&psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, 0, &sendEvent, &buildError, sendString);
258
259     [self printCarbonDesc:&sendEvent];
260
261     if (err) {
262         ITDebugLog(@"%d:%d at \"%@\"",(int)buildError.fError,buildError.fErrorPos,[nssendString substringToIndex:buildError.fErrorPos]);
263     }
264
265     err = AESend(&sendEvent, &replyEvent, kAEWaitReply, kAENormalPriority, kNoTimeOut, idleUPP, NULL);
266
267     [self printCarbonDesc:&replyEvent];
268
269     if (err) {
270         ITDebugLog(@"Send Error: %i",err);
271     } else {
272         unichar *result = 0;
273
274         err2 = AESizeOfParam(&replyEvent, keyDirectObject, &resultType, &resultSize);
275         result = malloc(resultSize);
276
277         if (err2) {
278             ITDebugLog(@"Error After AESizeOfParam: %i", err2);
279         } else {
280             err3 = AEGetParamPtr(&replyEvent, keyDirectObject, resultType, NULL, result, resultSize, &charResultSize);
281
282             if (err3) {
283                 ITDebugLog(@"Error After AEGetParamPtr: %i", err3);
284             } else {
285                 _finalString = [NSString stringWithCharacters:result length:charResultSize/sizeof(unichar)];
286             }
287         }
288         free(result);
289     }
290
291     if (!berr) AEDisposeDesc(&sendEvent);
292     if (!err) AEDisposeDesc(&replyEvent);
293
294     return _finalString;
295 }
296
297 - (long)sendTwoTierAEWithRequestedKeyForNumber:(NSString*)key fromObjectByKey:(NSString*)object eventClass:(NSString*)eventClass eventID:(NSString*)eventID appPSN:(ProcessSerialNumber)psn
298 {
299     AEEventClass eClass = *((unsigned long*)[eventClass UTF8String]);
300     AEEventID    eID    = *((unsigned long*)[eventID UTF8String]);
301
302     NSString *nssendString = [NSString stringWithFormat:@"'----':obj { form:'prop', want:type('prop'), seld:type('%s'), from:obj { form:'prop', want:type('prop'), seld:type('%s'), from:'null'() } }", [key UTF8String], [object UTF8String]];
303     const char *sendString = [nssendString UTF8String];
304     long result = 0;
305
306     AppleEvent sendEvent, replyEvent;
307     int pid;
308
309     DescType resultType;
310     Size resultSize, charResultSize;
311
312     AEBuildError buildError;
313     OSStatus berr, err;
314     OSErr err2, err3;
315     
316         if ((GetProcessPID(&psn, &pid) == noErr) && (pid == 0)) {
317             ITDebugLog(@"Error getting PID of application! Exiting.");
318             return nil;
319         }
320         
321     ITDebugLog(@"_sendString: %s", sendString);
322
323     berr = AEBuildAppleEvent(eClass, eID, typeProcessSerialNumber,(ProcessSerialNumber*)&psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, 0, &sendEvent, &buildError, sendString);
324
325     [self printCarbonDesc:&sendEvent];
326
327     if (err) {
328         ITDebugLog(@"%d:%d at \"%@\"",(int)buildError.fError,buildError.fErrorPos,[nssendString substringToIndex:buildError.fErrorPos]);
329     }
330
331     err = AESend(&sendEvent, &replyEvent, kAEWaitReply, kAENormalPriority, kNoTimeOut, idleUPP, NULL);
332
333     [self printCarbonDesc:&replyEvent];
334
335     if (err) {
336         ITDebugLog(@"Send Error: %i",err);
337     } else {
338         err2 = AESizeOfParam(&replyEvent, keyDirectObject, &resultType, &resultSize);
339
340         if (err2) {
341             ITDebugLog(@"Error After AESizeOfParam: %i", err2);
342         } else {
343             err3 = AEGetParamPtr(&replyEvent, keyDirectObject, resultType, NULL, &result, resultSize, &charResultSize);
344
345             if (err3) {
346                 ITDebugLog(@"Error After AEGetParamPtr: %i", err3);
347             }
348         }
349     }
350
351     if (!berr) AEDisposeDesc(&sendEvent);
352     if (!err) AEDisposeDesc(&replyEvent);
353
354     return result;
355 }
356
357 - (NSString *)sendAEWithRequestedArray:(NSArray *)array eventClass:(NSString*)eventClass eventID:(NSString*)eventID appPSN:(ProcessSerialNumber)psn
358 {
359     NSString *buildString = [NSString stringWithFormat:@"{ form:'prop', want:type('prop'), seld:type('%s'), from:'null'() }", [[array objectAtIndex:0] UTF8String]];
360     const char *sendString;
361     int i;
362     NSString  *_finalString = nil;
363     int pid;
364
365     AEEventClass eClass = *((unsigned long*)[eventClass UTF8String]);
366     AEEventID    eID    = *((unsigned long*)[eventID UTF8String]);
367
368     AppleEvent sendEvent, replyEvent;
369
370     DescType resultType;
371     Size resultSize, charResultSize;
372
373     AEBuildError buildError;
374     OSStatus berr, err;
375     OSErr err2, err3;
376
377     for (i = 1; i < [array count]; i++) {
378         NSString *from = [NSString stringWithFormat:@"{ form:'prop', want:type('prop'), seld:type('%s'), from:obj %@ }",
379                   [[array objectAtIndex:i] UTF8String], buildString];
380         buildString = from;
381     }
382     buildString = [@"'----':obj " stringByAppendingString:buildString];
383     sendString = [buildString UTF8String];
384     
385         if ((GetProcessPID(&psn, &pid) == noErr) && (pid == 0)) {
386             ITDebugLog(@"Error getting PID of application! Exiting.");
387             return nil;
388         }
389         
390     ITDebugLog(@"_sendString: %s", sendString);
391
392     berr = AEBuildAppleEvent(eClass, eID, typeProcessSerialNumber,(ProcessSerialNumber*)&psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, 0, &sendEvent, &buildError, sendString);
393
394     [self printCarbonDesc:&sendEvent];
395
396     if (err) {
397         ITDebugLog(@"%d:%d at \"%@\"",(int)buildError.fError,buildError.fErrorPos,[buildString substringToIndex:buildError.fErrorPos]);
398     }
399
400     err = AESend(&sendEvent, &replyEvent, kAEWaitReply, kAENormalPriority, kNoTimeOut, idleUPP, NULL);
401
402     [self printCarbonDesc:&replyEvent];
403
404     if (err) {
405         ITDebugLog(@"Send Error: %i",err);
406     } else {
407         unichar *result = 0;
408
409         err2 = AESizeOfParam(&replyEvent, keyDirectObject, &resultType, &resultSize);
410         result=malloc(resultSize);
411
412         if (err2) {
413             ITDebugLog(@"Error After AESizeOfParam: %i", err2);
414         } else {
415             err3 = AEGetParamPtr(&replyEvent, keyDirectObject, resultType, NULL, result, resultSize, &charResultSize);
416             if (err3) {
417                 ITDebugLog(@"Error After AEGetParamPtr: %i", err3);
418             } else {
419                 _finalString = [NSString stringWithCharacters:result length:charResultSize/sizeof(unichar)];
420             }
421         }
422         free(result);
423     }
424     if (!berr) AEDisposeDesc(&sendEvent);
425     if (!err) AEDisposeDesc(&replyEvent);
426     return _finalString;
427 }
428
429 - (void)sendAEWithEventClass:(NSString*)eventClass eventID:(NSString*)eventID appPSN:(ProcessSerialNumber)psn
430 {
431     AEEventClass eClass = *((unsigned long*)[eventClass UTF8String]);
432     AEEventID    eID    = *((unsigned long*)[eventID UTF8String]);
433     AEDesc dest;
434     int pid;
435
436     AppleEvent event, reply;
437     OSStatus cerr,cerr2,err;
438     //AEBuildAppleEvent(eClass, eID, typeProcessSerialNumber,(ProcessSerialNumber*)&psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, kAnyTransactionID, &event, nil, "");
439     if ((GetProcessPID(&psn, &pid) == noErr) && (pid == 0)) {
440         ITDebugLog(@"Error getting PID of application! Exiting.");
441         return;
442     }
443     cerr = AECreateDesc(typeProcessSerialNumber,(ProcessSerialNumber*)&psn,sizeof(ProcessSerialNumber),&dest);
444     cerr2 = AECreateAppleEvent(eClass,eID,&dest,kAutoGenerateReturnID,kAnyTransactionID,&event);
445     [self printCarbonDesc:&event];
446     err = AESend(&event, &reply, kAENoReply, kAENormalPriority, kAEDefaultTimeout, idleUPP, nil);
447     [self printCarbonDesc:&reply];
448     if (!cerr2) AEDisposeDesc(&dest);
449     if (!cerr) AEDisposeDesc(&event);
450     if (!err) AEDisposeDesc(&reply);
451 }
452
453 - (void)printCarbonDesc:(AEDesc*)desc {
454     Handle xx;
455     AEPrintDescToHandle(desc,&xx);
456     ITDebugLog(@"Handle: %s", *xx);
457     DisposeHandle(xx);
458 }
459
460
461 - (AEArrayDataPointer)sendAEWithRequestedKeyForArray:(NSString*)key eventClass:(NSString*)eventClass eventID:(NSString*)eventID appPSN:(ProcessSerialNumber)psn
462 {
463     AEEventClass eClass = *((unsigned long*)[eventClass UTF8String]);
464     AEEventID    eID    = *((unsigned long*)[eventID UTF8String]);
465
466     NSString *nssendString = [NSString stringWithFormat:@"'----':obj { form:'indx', want:'%s', seld:abso($616C6C20$), from:'null'() }", [key UTF8String]];
467     const char *sendString = [nssendString UTF8String];
468     AEArrayDataPointer result = nil;
469     int pid;
470
471     AppleEvent sendEvent, replyEvent;
472
473
474     AEBuildError buildError;
475     OSStatus err;
476
477     ITDebugLog(@"_sendString: %s", sendString);
478 if ((GetProcessPID(&psn, &pid) == noErr) && (pid == 0)) {
479             ITDebugLog(@"Error getting PID of application! Exiting.");
480             return nil;
481         }
482     err = AEBuildAppleEvent(eClass, eID, typeProcessSerialNumber,(ProcessSerialNumber*)&psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, 0, &sendEvent, &buildError, sendString);
483
484     [self printCarbonDesc:&sendEvent];
485
486     if (err) {
487         ITDebugLog(@"%d:%d at \"%@\"",(int)buildError.fError,buildError.fErrorPos,[nssendString substringToIndex:buildError.fErrorPos]);
488     }
489
490
491     err = AESend(&sendEvent, &replyEvent, kAEWaitReply, kAENormalPriority, kNoTimeOut, idleUPP, NULL);
492
493     [self printCarbonDesc:&replyEvent];
494
495     if (err) {
496         ITDebugLog(@"Send Error: %i",err);
497     } else {
498            SInt32 count, resultCount;
499
500            AECountItems(&replyEvent,&count);
501            result=malloc(sizeof(AEDesc)*count);
502            AEGetArray(&replyEvent, kAEDescArray, result, sizeof(AEDesc)*count, NULL, NULL, &resultCount);
503
504         free(result);
505     }
506
507     AEDisposeDesc(&sendEvent);
508     AEDisposeDesc(&replyEvent);
509
510     return result;
511 }
512
513 - (long)sendAEWithSendStringForNumber:(NSString*)string eventClass:(NSString*)eventClass eventID:(NSString*)eventID appPSN:(ProcessSerialNumber)psn
514 {
515     //Add error checking...
516     AEEventClass eClass = *((unsigned long*)[eventClass UTF8String]);
517     AEEventID    eID    = *((unsigned long*)[eventID UTF8String]);
518
519     const char *sendString = [string UTF8String];
520     SInt32 result = 0;
521     int pid;
522
523     AppleEvent sendEvent, replyEvent;
524
525     DescType resultType;
526     Size resultSize, charResultSize;
527
528     AEBuildError buildError;
529     OSStatus berr, err;
530     OSErr err2, err3;
531     
532         if ((GetProcessPID(&psn, &pid) == noErr) && (pid == 0)) {
533             ITDebugLog(@"Error getting PID of application! Exiting.");
534             return nil;
535         }
536         
537     ITDebugLog(@"_sendString: %s", sendString);
538
539     berr = AEBuildAppleEvent(eClass, eID, typeProcessSerialNumber,(ProcessSerialNumber*)&psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, 0, &sendEvent, &buildError, sendString);
540
541     [self printCarbonDesc:&sendEvent];
542
543     if (err) {
544         ITDebugLog(@"%d:%d at \"%@\"",(int)buildError.fError,buildError.fErrorPos,[string substringToIndex:buildError.fErrorPos]);
545     }
546
547     err = AESend(&sendEvent, &replyEvent, kAEWaitReply, kAENormalPriority, kNoTimeOut, idleUPP, NULL);
548
549     [self printCarbonDesc:&replyEvent];
550
551     if (err) {
552         ITDebugLog(@"Send Error: %i",err);
553     } else {
554         err2 = AESizeOfParam(&replyEvent, keyDirectObject, &resultType, &resultSize);
555
556         if (err2) {
557             ITDebugLog(@"Error After AESizeOfParam: %i", err2);
558         } else {
559             err3 = AEGetParamPtr(&replyEvent, keyDirectObject, resultType, NULL, &result, resultSize, &charResultSize);
560
561             if (err3) {
562                 ITDebugLog(@"Error After AEGetParamPtr: %i", err3);
563             }
564         }
565     }
566
567
568 if (!berr) AEDisposeDesc(&sendEvent);
569 if (!err) AEDisposeDesc(&replyEvent);
570 ITDebugLog(@"waffles say %d",result);
571 return result;
572 }
573
574 - (AEArrayDataPointer)sendAEWithSendStringForArray:(NSString*)string eventClass:(NSString*)eventClass eventID:(NSString*)eventID appPSN:(ProcessSerialNumber)psn
575 {
576     //Add error checking...
577     AEEventClass eClass = *((unsigned long*)[eventClass UTF8String]);
578     AEEventID    eID    = *((unsigned long*)[eventID UTF8String]);
579     int pid;
580
581     const char *sendString = [string UTF8String];
582     AEArrayDataPointer result = NULL;
583
584     AppleEvent sendEvent, replyEvent;
585
586     AEBuildError buildError;
587     OSStatus berr, err;
588     
589         if ((GetProcessPID(&psn, &pid) == noErr) && (pid == 0)) {
590             ITDebugLog(@"Error getting PID of application! Exiting.");
591             return nil;
592         }
593         
594     ITDebugLog(@"_sendString: %s", sendString);
595
596     berr = AEBuildAppleEvent(eClass, eID, typeProcessSerialNumber,(ProcessSerialNumber*)&psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, 0, &sendEvent, &buildError, sendString);
597
598     [self printCarbonDesc:&sendEvent];
599
600     if (err) {
601         ITDebugLog(@"%d:%d at \"%@\"",(int)buildError.fError,buildError.fErrorPos,[string substringToIndex:buildError.fErrorPos]);
602     }
603
604     err = AESend(&sendEvent, &replyEvent, kAEWaitReply, kAENormalPriority, kNoTimeOut, idleUPP, NULL);
605
606     [self printCarbonDesc:&replyEvent];
607
608     if (err) {
609         ITDebugLog(@"Send Error: %i",err);
610     } else {
611            SInt32 count, resultCount;
612
613            AECountItems(&replyEvent,&count);
614            result=malloc(sizeof(AEDesc)*count);
615            AEGetArray(&replyEvent, kAEDescArray, result, sizeof(AEDesc)*count, NULL, NULL, &resultCount);
616
617         free(result);
618     }
619
620     if (!berr) AEDisposeDesc(&sendEvent);
621     if (!err) AEDisposeDesc(&replyEvent);
622
623     return result;
624 }
625 @end