blob: b395f9a60dac7190cb23ae17c626b115940a4c56 [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
Jack Jansen26ee1261996-11-09 18:45:18 +000049#include "Python.h"
50#include "macglue.h"
51
Guido van Rossumdbfb2821995-02-19 15:51:30 +000052#ifdef GENERATINGCFM /* Defined to 0 or 1 in Universal headers */
53#define HAVE_UNIVERSAL_HEADERS
54#endif
55
Jack Jansenf74f63a1995-06-27 13:18:14 +000056#ifdef SYMANTEC__CFM68K__
Guido van Rossumdbfb2821995-02-19 15:51:30 +000057#pragma lib_export on
58#endif
59
60#ifndef HAVE_UNIVERSAL_HEADERS
61#define NewAEEventHandlerProc(x) (x)
62#define AEEventHandlerUPP EventHandlerProcPtr
63#endif
64
65static int arg_count;
66static char *arg_vector[256];
Jack Jansen26ee1261996-11-09 18:45:18 +000067FSSpec PyMac_ApplicationFSSpec;
68char PyMac_ApplicationPath[256];
69static int applocation_inited;
Guido van Rossumdbfb2821995-02-19 15:51:30 +000070
Jack Jansen178652b1995-10-12 10:22:57 +000071/* Duplicate a string to the heap. We also export this since it isn't standard
72** and others use it
73*/
Guido van Rossumdbfb2821995-02-19 15:51:30 +000074
Jack Jansen178652b1995-10-12 10:22:57 +000075char *
Guido van Rossumdbfb2821995-02-19 15:51:30 +000076strdup(char *src)
77{
78 char *dst = malloc(strlen(src) + 1);
79 if (dst)
80 strcpy(dst, src);
81 return dst;
82}
83
Jack Jansen26ee1261996-11-09 18:45:18 +000084/* Initialize FSSpec and full name of current application */
Guido van Rossumdbfb2821995-02-19 15:51:30 +000085
Jack Jansen41fa7ea1995-08-31 13:59:36 +000086OSErr
Jack Jansen26ee1261996-11-09 18:45:18 +000087PyMac_init_process_location()
Guido van Rossumdbfb2821995-02-19 15:51:30 +000088{
89 ProcessSerialNumber currentPSN;
90 ProcessInfoRec info;
Jack Jansen26ee1261996-11-09 18:45:18 +000091 OSErr err;
Guido van Rossumdbfb2821995-02-19 15:51:30 +000092
Jack Jansen26ee1261996-11-09 18:45:18 +000093 if ( applocation_inited ) return 0;
Guido van Rossumdbfb2821995-02-19 15:51:30 +000094 currentPSN.highLongOfPSN = 0;
95 currentPSN.lowLongOfPSN = kCurrentProcess;
96 info.processInfoLength = sizeof(ProcessInfoRec);
97 info.processName = NULL;
Jack Jansen26ee1261996-11-09 18:45:18 +000098 info.processAppSpec = &PyMac_ApplicationFSSpec;
99 if ( err=GetProcessInformation(&currentPSN, &info))
100 return err;
101 if ( err=PyMac_GetFullPath(&PyMac_ApplicationFSSpec, PyMac_ApplicationPath) )
102 return err;
103 applocation_inited = 1;
104 return 0;
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000105}
106
107/* Given an FSSpec, return the FSSpec of the parent folder */
108
109static OSErr
110get_folder_parent (FSSpec * fss, FSSpec * parent)
111{
112 CInfoPBRec rec;
113 short err;
114
115 * parent = * fss;
116 rec.hFileInfo.ioNamePtr = parent->name;
117 rec.hFileInfo.ioVRefNum = parent->vRefNum;
118 rec.hFileInfo.ioDirID = parent->parID;
119 rec.hFileInfo.ioFDirIndex = -1;
120 rec.hFileInfo.ioFVersNum = 0;
121 if (err = PBGetCatInfoSync (& rec))
122 return err;
123 parent->parID = rec.dirInfo.ioDrParID;
124/* parent->name[0] = 0; */
125 return 0;
126}
127
128/* Given an FSSpec return a full, colon-separated pathname */
129
Jack Jansen26ee1261996-11-09 18:45:18 +0000130OSErr
131PyMac_GetFullPath (FSSpec *fss, char *buf)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000132{
133 short err;
134 FSSpec fss_parent, fss_current;
135 char tmpbuf[256];
136 int plen;
137
138 fss_current = *fss;
139 plen = fss_current.name[0];
140 memcpy(buf, &fss_current.name[1], plen);
141 buf[plen] = 0;
Jack Jansene1d8c9b1996-11-20 14:58:27 +0000142 /* Special case for disk names */
143 if ( fss_current.parID <= 1 ) {
144 buf[plen++] = ':';
145 buf[plen] = 0;
146 return 0;
147 }
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000148 while (fss_current.parID > 1) {
149 /* Get parent folder name */
150 if (err = get_folder_parent(&fss_current, &fss_parent))
151 return err;
152 fss_current = fss_parent;
153 /* Prepend path component just found to buf */
154 plen = fss_current.name[0];
155 if (strlen(buf) + plen + 1 > 256) {
156 /* Oops... Not enough space (shouldn't happen) */
157 *buf = 0;
158 return -1;
159 }
160 memcpy(tmpbuf, &fss_current.name[1], plen);
161 tmpbuf[plen] = ':';
162 strcpy(&tmpbuf[plen+1], buf);
163 strcpy(buf, tmpbuf);
164 }
165 return 0;
166}
167
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000168/* Check that there aren't any args remaining in the event */
169
170static OSErr
171get_missing_params(AppleEvent *theAppleEvent)
172{
173 DescType theType;
174 Size actualSize;
175 OSErr err;
176
177 err = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
178 &theType, nil, 0, &actualSize);
179 if (err == errAEDescNotFound)
180 return noErr;
181 else
182 return errAEEventNotHandled;
183}
184
185static int got_one; /* Flag that we can stop getting events */
186
187/* Handle the Print or Quit events (by failing) */
188
189static pascal OSErr
190handle_not(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
191{
192 #pragma unused (reply, refCon)
193 got_one = 1;
194 return errAEEventNotHandled;
195}
196
197/* Handle the Open Application event (by ignoring it) */
198
199static pascal OSErr
200handle_open_app(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
201{
202 #pragma unused (reply, refCon)
Jack Jansendbe75ae1995-11-10 14:54:16 +0000203#if 0
204 /* Test by Jack: would removing this facilitate debugging? */
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000205 got_one = 1;
Jack Jansendbe75ae1995-11-10 14:54:16 +0000206#endif
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000207 return get_missing_params(theAppleEvent);
208}
209
210/* Handle the Open Document event, by adding an argument */
211
212static pascal OSErr
213handle_open_doc(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
214{
215 #pragma unused (reply, refCon)
216 OSErr err;
217 AEDescList doclist;
218 AEKeyword keywd;
219 DescType rttype;
220 long i, ndocs, size;
221 FSSpec fss;
222 char path[256];
223
224 got_one = 1;
225 if (err = AEGetParamDesc(theAppleEvent,
226 keyDirectObject, typeAEList, &doclist))
227 return err;
228 if (err = get_missing_params(theAppleEvent))
229 return err;
230 if (err = AECountItems(&doclist, &ndocs))
231 return err;
232 for(i = 1; i <= ndocs; i++) {
233 err = AEGetNthPtr(&doclist, i, typeFSS,
234 &keywd, &rttype, &fss, sizeof(fss), &size);
235 if (err)
236 break;
Jack Jansen26ee1261996-11-09 18:45:18 +0000237 PyMac_GetFullPath(&fss, path);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000238 arg_vector[arg_count++] = strdup(path);
239 }
240 return err;
241}
242
243/* Install standard core event handlers */
Jack Jansencc456fb1995-07-29 13:50:59 +0000244AEEventHandlerUPP open_doc_upp;
245AEEventHandlerUPP open_app_upp;
246AEEventHandlerUPP not_upp;
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000247
248static void
249set_ae_handlers()
250{
Jack Jansencc456fb1995-07-29 13:50:59 +0000251 open_doc_upp = NewAEEventHandlerProc(handle_open_doc);
252 open_app_upp = NewAEEventHandlerProc(handle_open_app);
253 not_upp = NewAEEventHandlerProc(handle_not);
254
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000255 AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000256 open_app_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000257 AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000258 open_doc_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000259 AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000260 not_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000261 AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000262 not_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000263}
264
265/* Uninstall standard core event handlers */
266
267static void
268reset_ae_handlers()
269{
270 AERemoveEventHandler(kCoreEventClass, kAEOpenApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000271 open_app_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000272 AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000273 open_doc_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000274 AERemoveEventHandler(kCoreEventClass, kAEPrintDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000275 not_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000276 AERemoveEventHandler(kCoreEventClass, kAEQuitApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000277 not_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000278}
279
280/* Wait for events until a core event has been handled */
281
282static void
283event_loop()
284{
285 EventRecord event;
286 int n;
287 int ok;
288
289 got_one = 0;
290 for (n = 0; n < 100 && !got_one; n++) {
291 SystemTask();
292 ok = GetNextEvent(everyEvent, &event);
293 if (ok && event.what == kHighLevelEvent) {
294 AEProcessAppleEvent(&event);
295 }
296 }
297}
298
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000299/* Get the argv vector, return argc */
300
301int
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000302PyMac_GetArgv(pargv, noevents)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000303 char ***pargv;
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000304 int noevents;
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000305{
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000306
307 arg_count = 0;
Jack Jansen26ee1261996-11-09 18:45:18 +0000308 (void)PyMac_init_process_location();
309 arg_vector[arg_count++] = strdup(PyMac_ApplicationPath);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000310
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000311 if( !noevents ) {
312 set_ae_handlers();
313 event_loop();
314 reset_ae_handlers();
315 }
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000316
317 arg_vector[arg_count] = NULL;
318
319 *pargv = arg_vector;
320 return arg_count;
321}