Hopefully added a bit more error checking.
[ITFoundation.git] / ITAppleEventCenter.m
1 #import "ITAppleEventCenter.h"
2
3 Boolean MyAEIdleCallback (
4                                          EventRecord * theEvent,
5                                          SInt32 * sleepTime,
6                                          RgnHandle * mouseRgn
7                                          );
8
9 Boolean MyAEIdleCallback (
10                                          EventRecord * theEvent,
11                                          SInt32 * sleepTime,
12                                          RgnHandle * mouseRgn
13                                          )
14 {
15     return FALSE;
16 }
17
18 @implementation ITAppleEventCenter
19
20 static ITAppleEventCenter *_sharedAECenter = nil;
21
22 + (id)sharedCenter
23 {
24     if( _sharedAECenter != nil ) {
25         return _sharedAECenter;
26     } else {    
27         _sharedAECenter = [[ITAppleEventCenter alloc] init];
28         return _sharedAECenter;
29     }
30 }
31
32 - (NSString*)runAEWithRequestedKey:(NSString*)key eventClass:(NSString*)eventClass eventID:(NSString*)eventID appPSN:(ProcessSerialNumber)psn
33 {
34     AEEventClass eClass = *((unsigned long*)[eventClass UTF8String]);
35     AEEventID    eID    = *((unsigned long*)[eventID UTF8String]);
36     
37     const char *sendString = [[NSString stringWithFormat:@"'----':obj { form:'prop', want:type('prop'), seld:type('%s'), from:'null'() }", [key UTF8String]] UTF8String];
38     NSString  *_finalString;
39     
40     // Variables for building and sending the event    
41     AppleEvent sendEvent, replyEvent;
42     //AEDesc replyDesc;
43     AEIdleUPP upp = NewAEIdleUPP(&MyAEIdleCallback);
44     
45     // Variables for getting the result
46     char *charResult;
47     DescType resultType;
48     Size resultSize, charResultSize;
49     int pid;
50     
51     // Variables for error checking
52     AEBuildError buildError;
53     OSStatus err;
54     OSErr err2, err3;
55     //Ptr buffer;
56     //Size length;
57     
58     // Start Code
59     // ^ Most pointless comment EVAR!
60     // ^^ Nope, that one is
61     
62     if (GetProcessPID(&psn, &pid) == noErr) {
63         if (pid ==0) {
64             NSLog(@"Process doesn't exist! Exiting.");
65             return;
66         }
67     } else {
68         NSLog(@"Error getting PID of application to send to! Exiting.");
69         return;
70     }
71     
72     NSLog(@"_sendString: %s", sendString);
73     
74     // The problem is, if I use eClass and eID in place of 'core' and 'getd' respectively, It won't build a valid AppleEvent :'(
75     err = AEBuildAppleEvent(eClass, eID, typeProcessSerialNumber,(ProcessSerialNumber*)&psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, 0, &sendEvent, &buildError, sendString);
76     
77     [self printCarbonDesc:&sendEvent];
78     
79     if (err) {
80         NSLog(@"%d:%d at \"%@\"",buildError.fError,buildError.fErrorPos,[sendString substringToIndex:buildError.fErrorPos]);
81     }
82     
83     err = AESend(&sendEvent, &replyEvent, kAEWaitReply, kAENormalPriority, kNoTimeOut, upp, NULL);
84     
85     [self printCarbonDesc:&replyEvent];
86     
87     if (err) {
88         NSLog(@"Send Error: %i",err);
89     } else {
90
91         unichar* result=0;
92         
93         err2 = AESizeOfParam(&replyEvent, keyDirectObject, &resultType, &resultSize);
94         result=malloc(resultSize);
95         //err2 = AEGetParamDesc(&replyEvent, keyDirectObject, typeWildCard, &replyDesc);
96         
97         if (err2) { NSLog(@"Error After AESizeOfParam: %i", err2); } else {
98         //if (err2) { NSLog(@"Error After AEGetParamDesc: %i", err2); } else {
99         
100         err3 = AEGetParamPtr(&replyEvent, keyDirectObject, resultType, NULL, result, resultSize, &charResultSize);
101         //length = AEGetDescDataSize(&replyDesc);
102         //buffer = malloc(length);
103     
104         //err3 = AEGetDescData(&replyDesc, buffer, length);
105         
106         if (err3) { NSLog(@"Error After AEGetParamPtr: %i", err3); } else {
107         
108         // if (err3) { NSLog(@"Error After AEGetDescData: %i", err3); } else {
109         
110         _finalString = [[NSString stringWithCharacters:result length:charResultSize/sizeof(unichar)] copy];
111         
112         /* _finalString = [NSString stringWithCString:buffer length:length];
113         
114         if ( (! [_finalString isEqualToString:@""])      &&
115             ([_finalString characterAtIndex:0] == '\"') &&
116             ([_finalString characterAtIndex:[_finalString length] - 1] == '\"') ) {
117             _finalString = [_finalString substringWithRange:NSMakeRange(1, [_finalString length] - 2)];
118         }
119         free(buffer);
120         buffer = nil; */
121
122         }
123         }
124     }
125     
126     //NSLog(@"Result Size: %i", charResultSize);
127     //NSLog(@"Result: %c", charResult);
128     
129     AEDisposeDesc(&sendEvent);
130     AEDisposeDesc(&replyEvent);
131     
132     return _finalString;
133 }
134
135 - (void)printCarbonDesc:(AEDesc*)desc {
136     Handle xx;
137     AEPrintDescToHandle(desc,&xx);
138     NSLog(@"Handle: %s", *xx);
139     DisposeHandle(xx);
140 }
141
142 @end