blob: 2c909973c539b4d4d043b9104603e63b10cf7e51 [file] [log] [blame]
Guido van Rossumdbfb2821995-02-19 15:51:30 +00001/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Construct argc and argv for main() by using Apple Events */
26/* From Jack's implementation for STDWIN */
27
28#include <stdlib.h>
29
30#ifndef SystemSevenOrLater
31#define SystemSevenOrLater 1
32#endif
33
34#include <Types.h>
35#include <Files.h>
36#include <Events.h>
37#include <Memory.h>
38#include <Processes.h>
39#include <Errors.h>
40#include <AppleEvents.h>
41#include <AEObjects.h>
42#include <Desk.h>
43#include <Fonts.h>
Guido van Rossum6fc5aec1995-02-19 23:32:59 +000044#include <TextEdit.h>
45#include <Menus.h>
46#include <Dialogs.h>
47#include <Windows.h>
Guido van Rossumdbfb2821995-02-19 15:51:30 +000048
49#ifdef GENERATINGCFM /* Defined to 0 or 1 in Universal headers */
50#define HAVE_UNIVERSAL_HEADERS
51#endif
52
Jack Jansenf74f63a1995-06-27 13:18:14 +000053#ifdef SYMANTEC__CFM68K__
Guido van Rossumdbfb2821995-02-19 15:51:30 +000054#pragma lib_export on
55#endif
56
57#ifndef HAVE_UNIVERSAL_HEADERS
58#define NewAEEventHandlerProc(x) (x)
59#define AEEventHandlerUPP EventHandlerProcPtr
60#endif
61
62static int arg_count;
63static char *arg_vector[256];
64
65/* Duplicate a string to the heap */
66
67static char *
68strdup(char *src)
69{
70 char *dst = malloc(strlen(src) + 1);
71 if (dst)
72 strcpy(dst, src);
73 return dst;
74}
75
76/* Return FSSpec of current application */
77
78static OSErr
79current_process_location(FSSpec *applicationSpec)
80{
81 ProcessSerialNumber currentPSN;
82 ProcessInfoRec info;
83
84 currentPSN.highLongOfPSN = 0;
85 currentPSN.lowLongOfPSN = kCurrentProcess;
86 info.processInfoLength = sizeof(ProcessInfoRec);
87 info.processName = NULL;
88 info.processAppSpec = applicationSpec;
89 return GetProcessInformation(&currentPSN, &info);
90}
91
92/* Given an FSSpec, return the FSSpec of the parent folder */
93
94static OSErr
95get_folder_parent (FSSpec * fss, FSSpec * parent)
96{
97 CInfoPBRec rec;
98 short err;
99
100 * parent = * fss;
101 rec.hFileInfo.ioNamePtr = parent->name;
102 rec.hFileInfo.ioVRefNum = parent->vRefNum;
103 rec.hFileInfo.ioDirID = parent->parID;
104 rec.hFileInfo.ioFDirIndex = -1;
105 rec.hFileInfo.ioFVersNum = 0;
106 if (err = PBGetCatInfoSync (& rec))
107 return err;
108 parent->parID = rec.dirInfo.ioDrParID;
109/* parent->name[0] = 0; */
110 return 0;
111}
112
113/* Given an FSSpec return a full, colon-separated pathname */
114
115static OSErr
116get_full_path (FSSpec *fss, char *buf)
117{
118 short err;
119 FSSpec fss_parent, fss_current;
120 char tmpbuf[256];
121 int plen;
122
Jack Jansenf74f63a1995-06-27 13:18:14 +0000123#if defined(__MWERKS__) && defined(__CFM68K__)
124 return -1; /* get_folder_parent doesn't work */
125#endif
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000126 fss_current = *fss;
127 plen = fss_current.name[0];
128 memcpy(buf, &fss_current.name[1], plen);
129 buf[plen] = 0;
130 while (fss_current.parID > 1) {
131 /* Get parent folder name */
132 if (err = get_folder_parent(&fss_current, &fss_parent))
133 return err;
134 fss_current = fss_parent;
135 /* Prepend path component just found to buf */
136 plen = fss_current.name[0];
137 if (strlen(buf) + plen + 1 > 256) {
138 /* Oops... Not enough space (shouldn't happen) */
139 *buf = 0;
140 return -1;
141 }
142 memcpy(tmpbuf, &fss_current.name[1], plen);
143 tmpbuf[plen] = ':';
144 strcpy(&tmpbuf[plen+1], buf);
145 strcpy(buf, tmpbuf);
146 }
147 return 0;
148}
149
150/* Return the full program name */
151
152static char *
153get_application_name()
154{
155 static char appname[256];
156 FSSpec appspec;
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000157
158 if (current_process_location(&appspec))
159 return NULL;
160 if (get_full_path(&appspec, appname))
161 return NULL;
162 return appname;
163}
164
165/* Check that there aren't any args remaining in the event */
166
167static OSErr
168get_missing_params(AppleEvent *theAppleEvent)
169{
170 DescType theType;
171 Size actualSize;
172 OSErr err;
173
174 err = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
175 &theType, nil, 0, &actualSize);
176 if (err == errAEDescNotFound)
177 return noErr;
178 else
179 return errAEEventNotHandled;
180}
181
182static int got_one; /* Flag that we can stop getting events */
183
184/* Handle the Print or Quit events (by failing) */
185
186static pascal OSErr
187handle_not(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
188{
189 #pragma unused (reply, refCon)
190 got_one = 1;
191 return errAEEventNotHandled;
192}
193
194/* Handle the Open Application event (by ignoring it) */
195
196static pascal OSErr
197handle_open_app(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
198{
199 #pragma unused (reply, refCon)
200 got_one = 1;
201 return get_missing_params(theAppleEvent);
202}
203
204/* Handle the Open Document event, by adding an argument */
205
206static pascal OSErr
207handle_open_doc(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
208{
209 #pragma unused (reply, refCon)
210 OSErr err;
211 AEDescList doclist;
212 AEKeyword keywd;
213 DescType rttype;
214 long i, ndocs, size;
215 FSSpec fss;
216 char path[256];
217
218 got_one = 1;
219 if (err = AEGetParamDesc(theAppleEvent,
220 keyDirectObject, typeAEList, &doclist))
221 return err;
222 if (err = get_missing_params(theAppleEvent))
223 return err;
224 if (err = AECountItems(&doclist, &ndocs))
225 return err;
226 for(i = 1; i <= ndocs; i++) {
227 err = AEGetNthPtr(&doclist, i, typeFSS,
228 &keywd, &rttype, &fss, sizeof(fss), &size);
229 if (err)
230 break;
231 get_full_path(&fss, path);
232 arg_vector[arg_count++] = strdup(path);
233 }
234 return err;
235}
236
237/* Install standard core event handlers */
Jack Jansencc456fb1995-07-29 13:50:59 +0000238AEEventHandlerUPP open_doc_upp;
239AEEventHandlerUPP open_app_upp;
240AEEventHandlerUPP not_upp;
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000241
242static void
243set_ae_handlers()
244{
Jack Jansencc456fb1995-07-29 13:50:59 +0000245 open_doc_upp = NewAEEventHandlerProc(handle_open_doc);
246 open_app_upp = NewAEEventHandlerProc(handle_open_app);
247 not_upp = NewAEEventHandlerProc(handle_not);
248
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000249 AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000250 open_app_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000251 AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000252 open_doc_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000253 AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000254 not_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000255 AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000256 not_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000257}
258
259/* Uninstall standard core event handlers */
260
261static void
262reset_ae_handlers()
263{
264 AERemoveEventHandler(kCoreEventClass, kAEOpenApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000265 open_app_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000266 AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000267 open_doc_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000268 AERemoveEventHandler(kCoreEventClass, kAEPrintDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000269 not_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000270 AERemoveEventHandler(kCoreEventClass, kAEQuitApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000271 not_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000272}
273
274/* Wait for events until a core event has been handled */
275
276static void
277event_loop()
278{
279 EventRecord event;
280 int n;
281 int ok;
282
283 got_one = 0;
284 for (n = 0; n < 100 && !got_one; n++) {
285 SystemTask();
286 ok = GetNextEvent(everyEvent, &event);
287 if (ok && event.what == kHighLevelEvent) {
288 AEProcessAppleEvent(&event);
289 }
290 }
291}
292
293/* Initialize the Mac toolbox world */
294
295static void
296init_mac_world()
297{
Guido van Rossum6fc5aec1995-02-19 23:32:59 +0000298#ifdef THINK_C
299 printf("\n");
300#else
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000301 MaxApplZone();
302 InitGraf(&qd.thePort);
303 InitFonts();
304 InitWindows();
305 TEInit();
306 InitDialogs((long)0);
307 InitMenus();
308 InitCursor();
Guido van Rossum6fc5aec1995-02-19 23:32:59 +0000309#endif
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000310}
311/* Get the argv vector, return argc */
312
313int
314PyMac_GetArgv(pargv)
315 char ***pargv;
316{
317 init_mac_world();
318
319 arg_count = 0;
320 arg_vector[arg_count++] = strdup(get_application_name());
321
322 set_ae_handlers();
323 event_loop();
324 reset_ae_handlers();
325
326 arg_vector[arg_count] = NULL;
327
328 *pargv = arg_vector;
329 return arg_count;
330}