| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | /***********************************************************
 | 
					
						
							|  |  |  | Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, | 
					
						
							|  |  |  | The Netherlands. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         All Rights Reserved | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Permission to use, copy, modify, and distribute this software and its  | 
					
						
							|  |  |  | documentation for any purpose and without fee is hereby granted,  | 
					
						
							|  |  |  | provided that the above copyright notice appear in all copies and that | 
					
						
							|  |  |  | both that copyright notice and this permission notice appear in  | 
					
						
							|  |  |  | supporting documentation, and that the names of Stichting Mathematisch | 
					
						
							|  |  |  | Centrum or CWI not be used in advertising or publicity pertaining to | 
					
						
							|  |  |  | distribution of the software without specific, written prior permission. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO | 
					
						
							|  |  |  | THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | 
					
						
							|  |  |  | FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE | 
					
						
							|  |  |  | FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 
					
						
							|  |  |  | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 
					
						
							|  |  |  | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | 
					
						
							|  |  |  | OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ******************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Construct argc and argv for main() by using Apple Events */ | 
					
						
							|  |  |  | /* From Jack's implementation for STDWIN */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef SystemSevenOrLater
 | 
					
						
							|  |  |  | #define SystemSevenOrLater 1
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <Types.h>
 | 
					
						
							|  |  |  | #include <Files.h>
 | 
					
						
							|  |  |  | #include <Events.h>
 | 
					
						
							|  |  |  | #include <Memory.h>
 | 
					
						
							|  |  |  | #include <Processes.h>
 | 
					
						
							|  |  |  | #include <Errors.h>
 | 
					
						
							|  |  |  | #include <AppleEvents.h>
 | 
					
						
							|  |  |  | #include <AEObjects.h>
 | 
					
						
							|  |  |  | #include <Desk.h>
 | 
					
						
							|  |  |  | #include <Fonts.h>
 | 
					
						
							| 
									
										
										
										
											1995-02-19 23:32:59 +00:00
										 |  |  | #include <TextEdit.h>
 | 
					
						
							|  |  |  | #include <Menus.h>
 | 
					
						
							|  |  |  | #include <Dialogs.h>
 | 
					
						
							|  |  |  | #include <Windows.h>
 | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef GENERATINGCFM	/* Defined to 0 or 1 in Universal headers */
 | 
					
						
							|  |  |  | #define HAVE_UNIVERSAL_HEADERS
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-06-27 13:18:14 +00:00
										 |  |  | #ifdef SYMANTEC__CFM68K__
 | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | #pragma lib_export on
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef HAVE_UNIVERSAL_HEADERS
 | 
					
						
							|  |  |  | #define NewAEEventHandlerProc(x) (x)
 | 
					
						
							|  |  |  | #define AEEventHandlerUPP EventHandlerProcPtr
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int arg_count; | 
					
						
							|  |  |  | static char *arg_vector[256]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-10-12 10:22:57 +00:00
										 |  |  | /* Duplicate a string to the heap. We also export this since it isn't standard
 | 
					
						
							|  |  |  | ** and others use it | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-10-12 10:22:57 +00:00
										 |  |  | char * | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | strdup(char *src) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char *dst = malloc(strlen(src) + 1); | 
					
						
							|  |  |  | 	if (dst) | 
					
						
							|  |  |  | 		strcpy(dst, src); | 
					
						
							|  |  |  | 	return dst; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Return FSSpec of current application */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-08-31 13:59:36 +00:00
										 |  |  | OSErr | 
					
						
							|  |  |  | PyMac_process_location(FSSpec *applicationSpec) | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	ProcessSerialNumber currentPSN; | 
					
						
							|  |  |  | 	ProcessInfoRec info; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	currentPSN.highLongOfPSN = 0; | 
					
						
							|  |  |  | 	currentPSN.lowLongOfPSN = kCurrentProcess; | 
					
						
							|  |  |  | 	info.processInfoLength = sizeof(ProcessInfoRec); | 
					
						
							|  |  |  | 	info.processName = NULL; | 
					
						
							|  |  |  | 	info.processAppSpec = applicationSpec; | 
					
						
							|  |  |  | 	return GetProcessInformation(¤tPSN, &info); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Given an FSSpec, return the FSSpec of the parent folder */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static OSErr | 
					
						
							|  |  |  | get_folder_parent (FSSpec * fss, FSSpec * parent) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CInfoPBRec rec; | 
					
						
							|  |  |  | 	short err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         * parent = * fss; | 
					
						
							|  |  |  |         rec.hFileInfo.ioNamePtr = parent->name; | 
					
						
							|  |  |  |         rec.hFileInfo.ioVRefNum = parent->vRefNum; | 
					
						
							|  |  |  |         rec.hFileInfo.ioDirID = parent->parID; | 
					
						
							|  |  |  | 		rec.hFileInfo.ioFDirIndex = -1; | 
					
						
							|  |  |  |         rec.hFileInfo.ioFVersNum = 0; | 
					
						
							|  |  |  |         if (err = PBGetCatInfoSync (& rec)) | 
					
						
							|  |  |  |         	return err; | 
					
						
							|  |  |  |         parent->parID = rec.dirInfo.ioDrParID; | 
					
						
							|  |  |  | /*	parent->name[0] = 0; */ | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Given an FSSpec return a full, colon-separated pathname */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static OSErr | 
					
						
							|  |  |  | get_full_path (FSSpec *fss, char *buf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	short err; | 
					
						
							|  |  |  | 	FSSpec fss_parent, fss_current; | 
					
						
							|  |  |  | 	char tmpbuf[256]; | 
					
						
							|  |  |  | 	int plen; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-06-27 13:18:14 +00:00
										 |  |  | #if defined(__MWERKS__) && defined(__CFM68K__)
 | 
					
						
							|  |  |  | 	return -1; /* get_folder_parent doesn't work */ | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 	fss_current = *fss; | 
					
						
							|  |  |  | 	plen = fss_current.name[0]; | 
					
						
							|  |  |  | 	memcpy(buf, &fss_current.name[1], plen); | 
					
						
							|  |  |  | 	buf[plen] = 0; | 
					
						
							|  |  |  | 	while (fss_current.parID > 1) { | 
					
						
							|  |  |  |     		/* Get parent folder name */ | 
					
						
							|  |  |  |                 if (err = get_folder_parent(&fss_current, &fss_parent)) | 
					
						
							|  |  |  |              		return err; | 
					
						
							|  |  |  |                 fss_current = fss_parent; | 
					
						
							|  |  |  |                 /* Prepend path component just found to buf */ | 
					
						
							|  |  |  |     			plen = fss_current.name[0]; | 
					
						
							|  |  |  |     			if (strlen(buf) + plen + 1 > 256) { | 
					
						
							|  |  |  |     				/* Oops... Not enough space (shouldn't happen) */ | 
					
						
							|  |  |  |     				*buf = 0; | 
					
						
							|  |  |  |     				return -1; | 
					
						
							|  |  |  |     			} | 
					
						
							|  |  |  |     			memcpy(tmpbuf, &fss_current.name[1], plen); | 
					
						
							|  |  |  |     			tmpbuf[plen] = ':'; | 
					
						
							|  |  |  |     			strcpy(&tmpbuf[plen+1], buf); | 
					
						
							|  |  |  |     			strcpy(buf, tmpbuf); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Return the full program name */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							|  |  |  | get_application_name() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static char appname[256]; | 
					
						
							|  |  |  | 	FSSpec appspec; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1995-08-31 13:59:36 +00:00
										 |  |  | 	if (PyMac_process_location(&appspec)) | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	if (get_full_path(&appspec, appname)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	return appname; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Check that there aren't any args remaining in the event */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static OSErr  | 
					
						
							|  |  |  | get_missing_params(AppleEvent *theAppleEvent) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	DescType theType; | 
					
						
							|  |  |  | 	Size actualSize; | 
					
						
							|  |  |  | 	OSErr err; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	err = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard, | 
					
						
							|  |  |  | 				&theType, nil, 0, &actualSize); | 
					
						
							|  |  |  | 	if (err == errAEDescNotFound) | 
					
						
							|  |  |  | 		return noErr; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return errAEEventNotHandled; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int got_one; /* Flag that we can stop getting events */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Handle the Print or Quit events (by failing) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static pascal OSErr | 
					
						
							|  |  |  | handle_not(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	#pragma unused (reply, refCon)
 | 
					
						
							|  |  |  | 	got_one = 1; | 
					
						
							|  |  |  | 	return errAEEventNotHandled; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Handle the Open Application event (by ignoring it) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static pascal OSErr | 
					
						
							|  |  |  | handle_open_app(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	#pragma unused (reply, refCon)
 | 
					
						
							| 
									
										
										
										
											1995-11-10 14:54:16 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | 	/* Test by Jack: would removing this facilitate debugging? */ | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 	got_one = 1; | 
					
						
							| 
									
										
										
										
											1995-11-10 14:54:16 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 	return get_missing_params(theAppleEvent); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Handle the Open Document event, by adding an argument */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static pascal OSErr | 
					
						
							|  |  |  | handle_open_doc(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	#pragma unused (reply, refCon)
 | 
					
						
							|  |  |  | 	OSErr err; | 
					
						
							|  |  |  | 	AEDescList doclist; | 
					
						
							|  |  |  | 	AEKeyword keywd; | 
					
						
							|  |  |  | 	DescType rttype; | 
					
						
							|  |  |  | 	long i, ndocs, size; | 
					
						
							|  |  |  | 	FSSpec fss; | 
					
						
							|  |  |  | 	char path[256]; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	got_one = 1; | 
					
						
							|  |  |  | 	if (err = AEGetParamDesc(theAppleEvent, | 
					
						
							|  |  |  | 				 keyDirectObject, typeAEList, &doclist)) | 
					
						
							|  |  |  | 		return err; | 
					
						
							|  |  |  | 	if (err = get_missing_params(theAppleEvent)) | 
					
						
							|  |  |  | 		return err; | 
					
						
							|  |  |  | 	if (err = AECountItems(&doclist, &ndocs)) | 
					
						
							|  |  |  | 		return err; | 
					
						
							|  |  |  | 	for(i = 1; i <= ndocs; i++) { | 
					
						
							|  |  |  | 		err = AEGetNthPtr(&doclist, i, typeFSS, | 
					
						
							|  |  |  | 				  &keywd, &rttype, &fss, sizeof(fss), &size); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		get_full_path(&fss, path); | 
					
						
							|  |  |  | 		arg_vector[arg_count++] = strdup(path); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return err; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Install standard core event handlers */ | 
					
						
							| 
									
										
										
										
											1995-07-29 13:50:59 +00:00
										 |  |  | AEEventHandlerUPP open_doc_upp; | 
					
						
							|  |  |  | AEEventHandlerUPP open_app_upp; | 
					
						
							|  |  |  | AEEventHandlerUPP not_upp; | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | set_ae_handlers() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1995-07-29 13:50:59 +00:00
										 |  |  | 	open_doc_upp = NewAEEventHandlerProc(handle_open_doc); | 
					
						
							|  |  |  | 	open_app_upp = NewAEEventHandlerProc(handle_open_app); | 
					
						
							|  |  |  | 	not_upp = NewAEEventHandlerProc(handle_not); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 	AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, | 
					
						
							| 
									
										
										
										
											1995-07-29 13:50:59 +00:00
										 |  |  | 			      open_app_upp, 0L, false); | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 	AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, | 
					
						
							| 
									
										
										
										
											1995-07-29 13:50:59 +00:00
										 |  |  | 			      open_doc_upp, 0L, false); | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 	AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, | 
					
						
							| 
									
										
										
										
											1995-07-29 13:50:59 +00:00
										 |  |  | 			      not_upp, 0L, false); | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 	AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, | 
					
						
							| 
									
										
										
										
											1995-07-29 13:50:59 +00:00
										 |  |  | 			      not_upp, 0L, false); | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Uninstall standard core event handlers */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | reset_ae_handlers() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	AERemoveEventHandler(kCoreEventClass, kAEOpenApplication, | 
					
						
							| 
									
										
										
										
											1995-07-29 13:50:59 +00:00
										 |  |  | 			     open_app_upp, false); | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 	AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments, | 
					
						
							| 
									
										
										
										
											1995-07-29 13:50:59 +00:00
										 |  |  | 			     open_doc_upp, false); | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 	AERemoveEventHandler(kCoreEventClass, kAEPrintDocuments, | 
					
						
							| 
									
										
										
										
											1995-07-29 13:50:59 +00:00
										 |  |  | 			     not_upp, false); | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | 	AERemoveEventHandler(kCoreEventClass, kAEQuitApplication, | 
					
						
							| 
									
										
										
										
											1995-07-29 13:50:59 +00:00
										 |  |  | 			     not_upp, false); | 
					
						
							| 
									
										
										
										
											1995-02-19 15:51:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Wait for events until a core event has been handled */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void  | 
					
						
							|  |  |  | event_loop() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	EventRecord event; | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | 	int ok; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	got_one = 0; | 
					
						
							|  |  |  | 	for (n = 0; n < 100 && !got_one; n++) { | 
					
						
							|  |  |  | 		SystemTask(); | 
					
						
							|  |  |  | 		ok = GetNextEvent(everyEvent, &event); | 
					
						
							|  |  |  | 		if (ok && event.what == kHighLevelEvent) { | 
					
						
							|  |  |  | 			AEProcessAppleEvent(&event); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Get the argv vector, return argc */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | PyMac_GetArgv(pargv) | 
					
						
							|  |  |  | 	char ***pargv; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	arg_count = 0; | 
					
						
							|  |  |  | 	arg_vector[arg_count++] = strdup(get_application_name()); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	set_ae_handlers(); | 
					
						
							|  |  |  | 	event_loop(); | 
					
						
							|  |  |  | 	reset_ae_handlers(); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	arg_vector[arg_count] = NULL; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	*pargv = arg_vector; | 
					
						
							|  |  |  | 	return arg_count; | 
					
						
							|  |  |  | } |