blob: c5af0ecc8d68dbb69b01d32a7f0c788107fb3cee [file] [log] [blame]
Guido van Rossumdbfb2821995-02-19 15:51:30 +00001/***********************************************************
Jack Jansen42218ce1997-01-31 16:15:11 +00002Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
Guido van Rossumdbfb2821995-02-19 15:51:30 +00003The 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
Jack Jansendff77702001-09-05 22:07:52 +000030#ifdef WITHOUT_FRAMEWORKS
Guido van Rossumdbfb2821995-02-19 15:51:30 +000031#include <Types.h>
32#include <Files.h>
33#include <Events.h>
34#include <Memory.h>
35#include <Processes.h>
36#include <Errors.h>
37#include <AppleEvents.h>
38#include <AEObjects.h>
Guido van Rossumdbfb2821995-02-19 15:51:30 +000039#include <Fonts.h>
Guido van Rossum6fc5aec1995-02-19 23:32:59 +000040#include <TextEdit.h>
41#include <Menus.h>
42#include <Dialogs.h>
43#include <Windows.h>
Jack Jansendff77702001-09-05 22:07:52 +000044#else
45#include <Carbon/Carbon.h>
46#endif /* WITHOUT_FRAMEWORKS */
Guido van Rossumdbfb2821995-02-19 15:51:30 +000047
Jack Jansen5daef312001-06-20 20:50:19 +000048#if UNIVERSAL_INTERFACES_VERSION >= 0x0340
49typedef long refcontype;
50#else
51typedef unsigned long refcontype;
52#endif
53
Jack Jansen26ee1261996-11-09 18:45:18 +000054#include "Python.h"
55#include "macglue.h"
56
Guido van Rossumdbfb2821995-02-19 15:51:30 +000057static int arg_count;
58static char *arg_vector[256];
Jack Jansen26ee1261996-11-09 18:45:18 +000059FSSpec PyMac_ApplicationFSSpec;
60char PyMac_ApplicationPath[256];
Guido van Rossumdbfb2821995-02-19 15:51:30 +000061
Jack Jansen178652b1995-10-12 10:22:57 +000062/* Duplicate a string to the heap. We also export this since it isn't standard
63** and others use it
64*/
Jack Jansen9ae898b2000-07-11 21:16:03 +000065#ifndef HAVE_STRDUP
Jack Jansen178652b1995-10-12 10:22:57 +000066char *
Jack Jansen9ae898b2000-07-11 21:16:03 +000067strdup(const char *src)
Guido van Rossumdbfb2821995-02-19 15:51:30 +000068{
69 char *dst = malloc(strlen(src) + 1);
70 if (dst)
71 strcpy(dst, src);
72 return dst;
73}
Jack Jansen9ae898b2000-07-11 21:16:03 +000074#endif
Guido van Rossumdbfb2821995-02-19 15:51:30 +000075
Jack Jansendff77702001-09-05 22:07:52 +000076#if TARGET_API_MAC_OSX
77OSErr
78PyMac_GetFullPath(FSSpec *fss, char *path)
79{
80 FSRef fsr;
81 OSErr err;
82
83 *path = '\0';
84 err = FSpMakeFSRef(fss, &fsr);
85 if ( err ) return err;
86 err = (OSErr)FSRefMakePath(&fsr, path, 1024);
87 if ( err ) return err;
88 return 0;
89}
90#endif /* TARGET_API_MAC_OSX */
91
92
93#if !TARGET_API_MAC_OSX
Jack Jansen26ee1261996-11-09 18:45:18 +000094/* Initialize FSSpec and full name of current application */
Guido van Rossumdbfb2821995-02-19 15:51:30 +000095
Jack Jansen41fa7ea1995-08-31 13:59:36 +000096OSErr
Jack Jansendff77702001-09-05 22:07:52 +000097PyMac_init_process_location(void)
Guido van Rossumdbfb2821995-02-19 15:51:30 +000098{
99 ProcessSerialNumber currentPSN;
100 ProcessInfoRec info;
Jack Jansen26ee1261996-11-09 18:45:18 +0000101 OSErr err;
Jack Jansendff77702001-09-05 22:07:52 +0000102 static int applocation_inited;
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000103
Jack Jansen26ee1261996-11-09 18:45:18 +0000104 if ( applocation_inited ) return 0;
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000105 currentPSN.highLongOfPSN = 0;
106 currentPSN.lowLongOfPSN = kCurrentProcess;
107 info.processInfoLength = sizeof(ProcessInfoRec);
108 info.processName = NULL;
Jack Jansen26ee1261996-11-09 18:45:18 +0000109 info.processAppSpec = &PyMac_ApplicationFSSpec;
110 if ( err=GetProcessInformation(&currentPSN, &info))
111 return err;
112 if ( err=PyMac_GetFullPath(&PyMac_ApplicationFSSpec, PyMac_ApplicationPath) )
113 return err;
114 applocation_inited = 1;
115 return 0;
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000116}
Jack Jansendff77702001-09-05 22:07:52 +0000117#endif /* !TARGET_API_MAC_OSX */
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000118
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000119/* Check that there aren't any args remaining in the event */
120
121static OSErr
Jack Jansen14cd7502000-06-02 21:23:09 +0000122get_missing_params(const AppleEvent *theAppleEvent)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000123{
124 DescType theType;
125 Size actualSize;
126 OSErr err;
127
128 err = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
129 &theType, nil, 0, &actualSize);
130 if (err == errAEDescNotFound)
131 return noErr;
132 else
133 return errAEEventNotHandled;
134}
135
136static int got_one; /* Flag that we can stop getting events */
137
138/* Handle the Print or Quit events (by failing) */
139
140static pascal OSErr
Jack Jansen5daef312001-06-20 20:50:19 +0000141handle_not(const AppleEvent *theAppleEvent, AppleEvent *reply, refcontype refCon)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000142{
143 #pragma unused (reply, refCon)
144 got_one = 1;
145 return errAEEventNotHandled;
146}
147
148/* Handle the Open Application event (by ignoring it) */
149
150static pascal OSErr
Jack Jansen5daef312001-06-20 20:50:19 +0000151handle_open_app(const AppleEvent *theAppleEvent, AppleEvent *reply, refcontype refCon)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000152{
153 #pragma unused (reply, refCon)
Jack Jansendbe75ae1995-11-10 14:54:16 +0000154#if 0
155 /* Test by Jack: would removing this facilitate debugging? */
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000156 got_one = 1;
Jack Jansendbe75ae1995-11-10 14:54:16 +0000157#endif
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000158 return get_missing_params(theAppleEvent);
159}
160
161/* Handle the Open Document event, by adding an argument */
162
163static pascal OSErr
Jack Jansen5daef312001-06-20 20:50:19 +0000164handle_open_doc(const AppleEvent *theAppleEvent, AppleEvent *reply, refcontype refCon)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000165{
166 #pragma unused (reply, refCon)
167 OSErr err;
168 AEDescList doclist;
169 AEKeyword keywd;
170 DescType rttype;
171 long i, ndocs, size;
172 FSSpec fss;
Jack Jansendff77702001-09-05 22:07:52 +0000173 char path[1024];
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000174
175 got_one = 1;
Jack Jansendff77702001-09-05 22:07:52 +0000176 if ((err = AEGetParamDesc(theAppleEvent,
177 keyDirectObject, typeAEList, &doclist)))
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000178 return err;
Jack Jansendff77702001-09-05 22:07:52 +0000179 if ((err = get_missing_params(theAppleEvent)))
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000180 return err;
Jack Jansendff77702001-09-05 22:07:52 +0000181 if ((err = AECountItems(&doclist, &ndocs)))
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000182 return err;
183 for(i = 1; i <= ndocs; i++) {
184 err = AEGetNthPtr(&doclist, i, typeFSS,
185 &keywd, &rttype, &fss, sizeof(fss), &size);
186 if (err)
187 break;
Jack Jansen26ee1261996-11-09 18:45:18 +0000188 PyMac_GetFullPath(&fss, path);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000189 arg_vector[arg_count++] = strdup(path);
190 }
191 return err;
192}
193
194/* Install standard core event handlers */
Jack Jansencc456fb1995-07-29 13:50:59 +0000195AEEventHandlerUPP open_doc_upp;
196AEEventHandlerUPP open_app_upp;
197AEEventHandlerUPP not_upp;
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000198
199static void
Jack Jansendff77702001-09-05 22:07:52 +0000200set_ae_handlers(void)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000201{
Jack Jansen5daef312001-06-20 20:50:19 +0000202 open_doc_upp = NewAEEventHandlerUPP(&handle_open_doc);
203 open_app_upp = NewAEEventHandlerUPP(&handle_open_app);
204 not_upp = NewAEEventHandlerUPP(&handle_not);
Jack Jansencc456fb1995-07-29 13:50:59 +0000205
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000206 AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000207 open_app_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000208 AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000209 open_doc_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000210 AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000211 not_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000212 AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000213 not_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000214}
215
216/* Uninstall standard core event handlers */
217
218static void
Jack Jansendff77702001-09-05 22:07:52 +0000219reset_ae_handlers(void)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000220{
221 AERemoveEventHandler(kCoreEventClass, kAEOpenApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000222 open_app_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000223 AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000224 open_doc_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000225 AERemoveEventHandler(kCoreEventClass, kAEPrintDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000226 not_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000227 AERemoveEventHandler(kCoreEventClass, kAEQuitApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000228 not_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000229}
230
231/* Wait for events until a core event has been handled */
232
233static void
Jack Jansendff77702001-09-05 22:07:52 +0000234event_loop(void)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000235{
236 EventRecord event;
237 int n;
238 int ok;
239
240 got_one = 0;
241 for (n = 0; n < 100 && !got_one; n++) {
Jack Jansen74a1e632000-07-14 22:37:27 +0000242#if !TARGET_API_MAC_CARBON
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000243 SystemTask();
Jack Jansenca23d912000-06-20 07:40:34 +0000244#endif
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000245 ok = GetNextEvent(everyEvent, &event);
246 if (ok && event.what == kHighLevelEvent) {
247 AEProcessAppleEvent(&event);
248 }
249 }
250}
251
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000252/* Get the argv vector, return argc */
253
254int
Jack Jansendff77702001-09-05 22:07:52 +0000255PyMac_GetArgv(char ***pargv, int noevents)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000256{
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000257 arg_count = 0;
Jack Jansendff77702001-09-05 22:07:52 +0000258#if TARGET_API_MAC_OSX
259 /* In an OSX bundle argv[0] is okay */
260 arg_count++;
261#else
Jack Jansen26ee1261996-11-09 18:45:18 +0000262 (void)PyMac_init_process_location();
263 arg_vector[arg_count++] = strdup(PyMac_ApplicationPath);
Jack Jansendff77702001-09-05 22:07:52 +0000264#endif /* TARGET_API_MAC_OSX */
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000265
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000266 if( !noevents ) {
267 set_ae_handlers();
268 event_loop();
269 reset_ae_handlers();
270 }
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000271
272 arg_vector[arg_count] = NULL;
273
274 *pargv = arg_vector;
275 return arg_count;
276}