blob: 8fdbad508726f26ca36abe556aae7e84b9db0ad9 [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
Jack Jansen697842f2001-09-10 22:00:39 +000057#ifdef TARGET_API_MAC_OSX
58#define PATHNAMELEN 1024
59#else
60#define PATHNAMELEN 256
61#endif
62
Guido van Rossumdbfb2821995-02-19 15:51:30 +000063static int arg_count;
64static char *arg_vector[256];
Jack Jansen26ee1261996-11-09 18:45:18 +000065FSSpec PyMac_ApplicationFSSpec;
Jack Jansen697842f2001-09-10 22:00:39 +000066char PyMac_ApplicationPath[PATHNAMELEN];
Guido van Rossumdbfb2821995-02-19 15:51:30 +000067
Jack Jansen178652b1995-10-12 10:22:57 +000068/* Duplicate a string to the heap. We also export this since it isn't standard
69** and others use it
70*/
Jack Jansen9ae898b2000-07-11 21:16:03 +000071#ifndef HAVE_STRDUP
Jack Jansen178652b1995-10-12 10:22:57 +000072char *
Jack Jansen9ae898b2000-07-11 21:16:03 +000073strdup(const char *src)
Guido van Rossumdbfb2821995-02-19 15:51:30 +000074{
75 char *dst = malloc(strlen(src) + 1);
76 if (dst)
77 strcpy(dst, src);
78 return dst;
79}
Jack Jansen9ae898b2000-07-11 21:16:03 +000080#endif
Guido van Rossumdbfb2821995-02-19 15:51:30 +000081
Jack Jansendff77702001-09-05 22:07:52 +000082
83#if !TARGET_API_MAC_OSX
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 Jansendff77702001-09-05 22:07:52 +000087PyMac_init_process_location(void)
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;
Jack Jansendff77702001-09-05 22:07:52 +000092 static int applocation_inited;
Guido van Rossumdbfb2821995-02-19 15:51:30 +000093
Jack Jansen26ee1261996-11-09 18:45:18 +000094 if ( applocation_inited ) return 0;
Guido van Rossumdbfb2821995-02-19 15:51:30 +000095 currentPSN.highLongOfPSN = 0;
96 currentPSN.lowLongOfPSN = kCurrentProcess;
97 info.processInfoLength = sizeof(ProcessInfoRec);
98 info.processName = NULL;
Jack Jansen26ee1261996-11-09 18:45:18 +000099 info.processAppSpec = &PyMac_ApplicationFSSpec;
100 if ( err=GetProcessInformation(&currentPSN, &info))
101 return err;
Jack Jansen697842f2001-09-10 22:00:39 +0000102 if ( err=PyMac_GetFullPathname(&PyMac_ApplicationFSSpec, PyMac_ApplicationPath, PATHNAMELEN) )
Jack Jansen26ee1261996-11-09 18:45:18 +0000103 return err;
104 applocation_inited = 1;
105 return 0;
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000106}
Jack Jansendff77702001-09-05 22:07:52 +0000107#endif /* !TARGET_API_MAC_OSX */
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000108
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000109/* Check that there aren't any args remaining in the event */
110
111static OSErr
Jack Jansen14cd7502000-06-02 21:23:09 +0000112get_missing_params(const AppleEvent *theAppleEvent)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000113{
114 DescType theType;
115 Size actualSize;
116 OSErr err;
117
118 err = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
119 &theType, nil, 0, &actualSize);
120 if (err == errAEDescNotFound)
121 return noErr;
122 else
123 return errAEEventNotHandled;
124}
125
126static int got_one; /* Flag that we can stop getting events */
127
128/* Handle the Print or Quit events (by failing) */
129
130static pascal OSErr
Jack Jansen5daef312001-06-20 20:50:19 +0000131handle_not(const AppleEvent *theAppleEvent, AppleEvent *reply, refcontype refCon)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000132{
133 #pragma unused (reply, refCon)
134 got_one = 1;
135 return errAEEventNotHandled;
136}
137
138/* Handle the Open Application event (by ignoring it) */
139
140static pascal OSErr
Jack Jansen5daef312001-06-20 20:50:19 +0000141handle_open_app(const AppleEvent *theAppleEvent, AppleEvent *reply, refcontype refCon)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000142{
143 #pragma unused (reply, refCon)
Jack Jansendbe75ae1995-11-10 14:54:16 +0000144#if 0
145 /* Test by Jack: would removing this facilitate debugging? */
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000146 got_one = 1;
Jack Jansendbe75ae1995-11-10 14:54:16 +0000147#endif
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000148 return get_missing_params(theAppleEvent);
149}
150
151/* Handle the Open Document event, by adding an argument */
152
153static pascal OSErr
Jack Jansen5daef312001-06-20 20:50:19 +0000154handle_open_doc(const AppleEvent *theAppleEvent, AppleEvent *reply, refcontype refCon)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000155{
156 #pragma unused (reply, refCon)
157 OSErr err;
158 AEDescList doclist;
159 AEKeyword keywd;
160 DescType rttype;
161 long i, ndocs, size;
162 FSSpec fss;
Jack Jansen697842f2001-09-10 22:00:39 +0000163 char path[PATHNAMELEN];
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000164
165 got_one = 1;
Jack Jansendff77702001-09-05 22:07:52 +0000166 if ((err = AEGetParamDesc(theAppleEvent,
167 keyDirectObject, typeAEList, &doclist)))
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000168 return err;
Jack Jansendff77702001-09-05 22:07:52 +0000169 if ((err = get_missing_params(theAppleEvent)))
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000170 return err;
Jack Jansendff77702001-09-05 22:07:52 +0000171 if ((err = AECountItems(&doclist, &ndocs)))
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000172 return err;
173 for(i = 1; i <= ndocs; i++) {
174 err = AEGetNthPtr(&doclist, i, typeFSS,
175 &keywd, &rttype, &fss, sizeof(fss), &size);
176 if (err)
177 break;
Jack Jansen697842f2001-09-10 22:00:39 +0000178 PyMac_GetFullPathname(&fss, path, PATHNAMELEN);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000179 arg_vector[arg_count++] = strdup(path);
180 }
181 return err;
182}
183
184/* Install standard core event handlers */
Jack Jansencc456fb1995-07-29 13:50:59 +0000185AEEventHandlerUPP open_doc_upp;
186AEEventHandlerUPP open_app_upp;
187AEEventHandlerUPP not_upp;
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000188
189static void
Jack Jansendff77702001-09-05 22:07:52 +0000190set_ae_handlers(void)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000191{
Jack Jansen5daef312001-06-20 20:50:19 +0000192 open_doc_upp = NewAEEventHandlerUPP(&handle_open_doc);
193 open_app_upp = NewAEEventHandlerUPP(&handle_open_app);
194 not_upp = NewAEEventHandlerUPP(&handle_not);
Jack Jansencc456fb1995-07-29 13:50:59 +0000195
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000196 AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000197 open_app_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000198 AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000199 open_doc_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000200 AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000201 not_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000202 AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000203 not_upp, 0L, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000204}
205
206/* Uninstall standard core event handlers */
207
208static void
Jack Jansendff77702001-09-05 22:07:52 +0000209reset_ae_handlers(void)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000210{
211 AERemoveEventHandler(kCoreEventClass, kAEOpenApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000212 open_app_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000213 AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000214 open_doc_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000215 AERemoveEventHandler(kCoreEventClass, kAEPrintDocuments,
Jack Jansencc456fb1995-07-29 13:50:59 +0000216 not_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000217 AERemoveEventHandler(kCoreEventClass, kAEQuitApplication,
Jack Jansencc456fb1995-07-29 13:50:59 +0000218 not_upp, false);
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000219}
220
221/* Wait for events until a core event has been handled */
222
223static void
Jack Jansendff77702001-09-05 22:07:52 +0000224event_loop(void)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000225{
226 EventRecord event;
227 int n;
228 int ok;
229
230 got_one = 0;
231 for (n = 0; n < 100 && !got_one; n++) {
Jack Jansen74a1e632000-07-14 22:37:27 +0000232#if !TARGET_API_MAC_CARBON
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000233 SystemTask();
Jack Jansenca23d912000-06-20 07:40:34 +0000234#endif
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000235 ok = GetNextEvent(everyEvent, &event);
236 if (ok && event.what == kHighLevelEvent) {
237 AEProcessAppleEvent(&event);
238 }
239 }
240}
241
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000242/* Get the argv vector, return argc */
243
244int
Jack Jansendff77702001-09-05 22:07:52 +0000245PyMac_GetArgv(char ***pargv, int noevents)
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000246{
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000247 arg_count = 0;
Jack Jansendff77702001-09-05 22:07:52 +0000248#if TARGET_API_MAC_OSX
249 /* In an OSX bundle argv[0] is okay */
250 arg_count++;
251#else
Jack Jansen26ee1261996-11-09 18:45:18 +0000252 (void)PyMac_init_process_location();
253 arg_vector[arg_count++] = strdup(PyMac_ApplicationPath);
Jack Jansendff77702001-09-05 22:07:52 +0000254#endif /* TARGET_API_MAC_OSX */
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000255
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000256 if( !noevents ) {
257 set_ae_handlers();
258 event_loop();
259 reset_ae_handlers();
260 }
Guido van Rossumdbfb2821995-02-19 15:51:30 +0000261
262 arg_vector[arg_count] = NULL;
263
264 *pargv = arg_vector;
265 return arg_count;
266}