Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dbfb282

Browse files
committed
get argc/argv from AppleEvents
1 parent 40d94e0 commit dbfb282

1 file changed

Lines changed: 325 additions & 0 deletions

File tree

Mac/Python/macgetargv.c

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
/***********************************************************
2+
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3+
The Netherlands.
4+
5+
All Rights Reserved
6+
7+
Permission to use, copy, modify, and distribute this software and its
8+
documentation for any purpose and without fee is hereby granted,
9+
provided that the above copyright notice appear in all copies and that
10+
both that copyright notice and this permission notice appear in
11+
supporting documentation, and that the names of Stichting Mathematisch
12+
Centrum or CWI not be used in advertising or publicity pertaining to
13+
distribution of the software without specific, written prior permission.
14+
15+
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16+
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17+
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18+
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21+
OF 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>
44+
45+
#ifdef GENERATINGCFM /* Defined to 0 or 1 in Universal headers */
46+
#define HAVE_UNIVERSAL_HEADERS
47+
#endif
48+
49+
#ifdef __CFM68K__
50+
#pragma lib_export on
51+
#endif
52+
53+
#ifndef HAVE_UNIVERSAL_HEADERS
54+
#define NewAEEventHandlerProc(x) (x)
55+
#define AEEventHandlerUPP EventHandlerProcPtr
56+
#endif
57+
58+
static int arg_count;
59+
static char *arg_vector[256];
60+
61+
/* Duplicate a string to the heap */
62+
63+
static char *
64+
strdup(char *src)
65+
{
66+
char *dst = malloc(strlen(src) + 1);
67+
if (dst)
68+
strcpy(dst, src);
69+
return dst;
70+
}
71+
72+
/* Return FSSpec of current application */
73+
74+
static OSErr
75+
current_process_location(FSSpec *applicationSpec)
76+
{
77+
ProcessSerialNumber currentPSN;
78+
ProcessInfoRec info;
79+
80+
currentPSN.highLongOfPSN = 0;
81+
currentPSN.lowLongOfPSN = kCurrentProcess;
82+
info.processInfoLength = sizeof(ProcessInfoRec);
83+
info.processName = NULL;
84+
info.processAppSpec = applicationSpec;
85+
return GetProcessInformation(&currentPSN, &info);
86+
}
87+
88+
/* Given an FSSpec, return the FSSpec of the parent folder */
89+
90+
static OSErr
91+
get_folder_parent (FSSpec * fss, FSSpec * parent)
92+
{
93+
CInfoPBRec rec;
94+
short err;
95+
96+
* parent = * fss;
97+
rec.hFileInfo.ioNamePtr = parent->name;
98+
rec.hFileInfo.ioVRefNum = parent->vRefNum;
99+
rec.hFileInfo.ioDirID = parent->parID;
100+
rec.hFileInfo.ioFDirIndex = -1;
101+
rec.hFileInfo.ioFVersNum = 0;
102+
if (err = PBGetCatInfoSync (& rec))
103+
return err;
104+
parent->parID = rec.dirInfo.ioDrParID;
105+
/* parent->name[0] = 0; */
106+
return 0;
107+
}
108+
109+
/* Given an FSSpec return a full, colon-separated pathname */
110+
111+
static OSErr
112+
get_full_path (FSSpec *fss, char *buf)
113+
{
114+
short err;
115+
FSSpec fss_parent, fss_current;
116+
char tmpbuf[256];
117+
int plen;
118+
119+
fss_current = *fss;
120+
plen = fss_current.name[0];
121+
memcpy(buf, &fss_current.name[1], plen);
122+
buf[plen] = 0;
123+
while (fss_current.parID > 1) {
124+
/* Get parent folder name */
125+
if (err = get_folder_parent(&fss_current, &fss_parent))
126+
return err;
127+
fss_current = fss_parent;
128+
/* Prepend path component just found to buf */
129+
plen = fss_current.name[0];
130+
if (strlen(buf) + plen + 1 > 256) {
131+
/* Oops... Not enough space (shouldn't happen) */
132+
*buf = 0;
133+
return -1;
134+
}
135+
memcpy(tmpbuf, &fss_current.name[1], plen);
136+
tmpbuf[plen] = ':';
137+
strcpy(&tmpbuf[plen+1], buf);
138+
strcpy(buf, tmpbuf);
139+
}
140+
return 0;
141+
}
142+
143+
/* Return the full program name */
144+
145+
static char *
146+
get_application_name()
147+
{
148+
static char appname[256];
149+
FSSpec appspec;
150+
long size;
151+
152+
if (current_process_location(&appspec))
153+
return NULL;
154+
if (get_full_path(&appspec, appname))
155+
return NULL;
156+
return appname;
157+
}
158+
159+
/* Check that there aren't any args remaining in the event */
160+
161+
static OSErr
162+
get_missing_params(AppleEvent *theAppleEvent)
163+
{
164+
DescType theType;
165+
Size actualSize;
166+
OSErr err;
167+
168+
err = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
169+
&theType, nil, 0, &actualSize);
170+
if (err == errAEDescNotFound)
171+
return noErr;
172+
else
173+
return errAEEventNotHandled;
174+
}
175+
176+
static int got_one; /* Flag that we can stop getting events */
177+
178+
/* Handle the Print or Quit events (by failing) */
179+
180+
static pascal OSErr
181+
handle_not(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
182+
{
183+
#pragma unused (reply, refCon)
184+
got_one = 1;
185+
return errAEEventNotHandled;
186+
}
187+
188+
/* Handle the Open Application event (by ignoring it) */
189+
190+
static pascal OSErr
191+
handle_open_app(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
192+
{
193+
#pragma unused (reply, refCon)
194+
got_one = 1;
195+
return get_missing_params(theAppleEvent);
196+
}
197+
198+
/* Handle the Open Document event, by adding an argument */
199+
200+
static pascal OSErr
201+
handle_open_doc(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
202+
{
203+
#pragma unused (reply, refCon)
204+
OSErr err;
205+
AEDescList doclist;
206+
AEKeyword keywd;
207+
DescType rttype;
208+
long i, ndocs, size;
209+
FSSpec fss;
210+
char path[256];
211+
212+
got_one = 1;
213+
if (err = AEGetParamDesc(theAppleEvent,
214+
keyDirectObject, typeAEList, &doclist))
215+
return err;
216+
if (err = get_missing_params(theAppleEvent))
217+
return err;
218+
if (err = AECountItems(&doclist, &ndocs))
219+
return err;
220+
for(i = 1; i <= ndocs; i++) {
221+
err = AEGetNthPtr(&doclist, i, typeFSS,
222+
&keywd, &rttype, &fss, sizeof(fss), &size);
223+
if (err)
224+
break;
225+
get_full_path(&fss, path);
226+
arg_vector[arg_count++] = strdup(path);
227+
}
228+
return err;
229+
}
230+
231+
/* Install standard core event handlers */
232+
233+
static void
234+
set_ae_handlers()
235+
{
236+
AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
237+
NewAEEventHandlerProc(handle_open_app), 0L, false);
238+
AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
239+
NewAEEventHandlerProc(handle_open_doc), 0L, false);
240+
AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
241+
NewAEEventHandlerProc(handle_not), 0L, false);
242+
AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
243+
NewAEEventHandlerProc(handle_not), 0L, false);
244+
}
245+
246+
/* Uninstall standard core event handlers */
247+
248+
static void
249+
reset_ae_handlers()
250+
{
251+
AERemoveEventHandler(kCoreEventClass, kAEOpenApplication,
252+
NewAEEventHandlerProc(handle_open_app), false);
253+
AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments,
254+
NewAEEventHandlerProc(handle_open_doc), false);
255+
AERemoveEventHandler(kCoreEventClass, kAEPrintDocuments,
256+
NewAEEventHandlerProc(handle_not), false);
257+
AERemoveEventHandler(kCoreEventClass, kAEQuitApplication,
258+
NewAEEventHandlerProc(handle_not), false);
259+
}
260+
261+
/* Wait for events until a core event has been handled */
262+
263+
static void
264+
event_loop()
265+
{
266+
EventRecord event;
267+
int n;
268+
int ok;
269+
270+
got_one = 0;
271+
for (n = 0; n < 100 && !got_one; n++) {
272+
SystemTask();
273+
ok = GetNextEvent(everyEvent, &event);
274+
if (ok && event.what == kHighLevelEvent) {
275+
AEProcessAppleEvent(&event);
276+
}
277+
}
278+
}
279+
280+
/* Initialize the Mac toolbox world */
281+
282+
static void
283+
init_mac_world()
284+
{
285+
MaxApplZone();
286+
InitGraf(&qd.thePort);
287+
InitFonts();
288+
InitWindows();
289+
TEInit();
290+
InitDialogs((long)0);
291+
InitMenus();
292+
InitCursor();
293+
}
294+
/* Get the argv vector, return argc */
295+
296+
int
297+
PyMac_GetArgv(pargv)
298+
char ***pargv;
299+
{
300+
init_mac_world();
301+
302+
arg_count = 0;
303+
arg_vector[arg_count++] = strdup(get_application_name());
304+
305+
set_ae_handlers();
306+
event_loop();
307+
reset_ae_handlers();
308+
309+
arg_vector[arg_count] = NULL;
310+
311+
*pargv = arg_vector;
312+
return arg_count;
313+
}
314+
315+
/* Initialization sequence for normal application */
316+
317+
void
318+
main()
319+
{
320+
int argc;
321+
char **argv;
322+
323+
argc = PyMac_GetArgv(&argv);
324+
Py_Main(argc, argv);
325+
}

0 commit comments

Comments
 (0)