blob: 6da7ca31c0a2a5df8e94618600163ddcc9be8099 [file] [log] [blame]
Guido van Rossumb3404661995-01-22 18:36:13 +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******************************************************************/
Jack Jansenf93c72a1994-12-14 14:07:50 +000024
25#include "Python.h"
Guido van Rossumbecdbec1995-02-14 01:27:24 +000026
Jack Jansenf93c72a1994-12-14 14:07:50 +000027#include "macglue.h"
Jack Jansen74162f31995-02-15 22:58:33 +000028#include "marshal.h"
29#include "import.h"
Jack Jansenf93c72a1994-12-14 14:07:50 +000030
31#include <OSUtils.h> /* for Set(Current)A5 */
Jack Jansene8e8ae01995-01-26 16:36:45 +000032#include <Files.h>
Jack Jansen8cd2b721995-02-13 11:33:28 +000033#include <Aliases.h>
Jack Jansen6cfab231995-02-13 22:46:00 +000034#include <Folders.h>
Jack Jansen8cd2b721995-02-13 11:33:28 +000035#include <StandardFile.h>
Jack Jansenf93c72a1994-12-14 14:07:50 +000036#include <Resources.h>
37#include <Memory.h>
38#include <Events.h>
39#include <Windows.h>
40#include <Desk.h>
Jack Jansene8e8ae01995-01-26 16:36:45 +000041#include <Traps.h>
Jack Jansenee23d6e1995-01-27 14:43:25 +000042#include <Processes.h>
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +000043#include <Fonts.h>
44#include <Menus.h>
Jack Jansen08305501995-06-18 20:03:40 +000045#include <TextUtils.h>
Guido van Rossumcc0d8791995-01-30 08:57:13 +000046#ifdef THINK_C
47#include <OSEvents.h> /* For EvQElPtr */
48#endif
Jack Jansen16df2aa1995-02-27 16:17:28 +000049#ifdef __MWERKS__
50#include <SIOUX.h>
51#endif
Jack Jansenee23d6e1995-01-27 14:43:25 +000052
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +000053#ifndef HAVE_UNIVERSAL_HEADERS
54#define GetResourceSizeOnDisk(x) SizeResource(x)
Guido van Rossum24a45e31995-02-20 23:45:53 +000055typedef DlgHookYDProcPtr DlgHookYDUPP;
56#define NewDlgHookYDProc(userRoutine) ((DlgHookYDUPP) (userRoutine))
57typedef FileFilterYDProcPtr FileFilterYDUPP;
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +000058#endif
59
Jack Jansenee23d6e1995-01-27 14:43:25 +000060#include <signal.h>
Jack Jansen74162f31995-02-15 22:58:33 +000061#include <stdio.h>
Jack Jansene8e8ae01995-01-26 16:36:45 +000062
Jack Jansen3ec804a1995-02-20 15:56:10 +000063/* The alert for "No Python directory, where is it?" */
Jack Jansen8cd2b721995-02-13 11:33:28 +000064#define NOPYTHON_ALERT 128
65#define YES_ITEM 1
66#define NO_ITEM 2
67#define CURWD_ITEM 3
68
Jack Jansen3ec804a1995-02-20 15:56:10 +000069/* The alert for "this is an applet template" */
70#define NOPYC_ALERT 129
71
72/* The dialog for our GetDirectory call */
73#define GETDIR_ID 130 /* Resource ID for our "get directory" */
74#define SELECTCUR_ITEM 10 /* "Select current directory" button */
75
Jack Jansen292b0f91995-07-29 13:52:37 +000076/* The dialog for interactive options */
77#define OPT_DIALOG 131 /* Resource ID for dialog */
78#define OPT_OK 1
79#define OPT_CANCEL 2
80#define OPT_INSPECT 3
81#define OPT_VERBOSE 4
82#define OPT_SUPPRESS 5
83#define OPT_UNBUFFERED 6
84#define OPT_DEBUGGING 7
85
Jack Jansen08305501995-06-18 20:03:40 +000086/* The STR# resource for sys.path initialization */
87#define PYTHONPATH_ID 128
88
Jack Jansenee23d6e1995-01-27 14:43:25 +000089/*
Jack Jansen16df2aa1995-02-27 16:17:28 +000090** We have to be careful, since we can't handle
Jack Jansenee23d6e1995-01-27 14:43:25 +000091** things like updates (and they'll keep coming back if we don't
Jack Jansen16df2aa1995-02-27 16:17:28 +000092** handle them). Note that we don't know who has windows open, so
93** even handing updates off to SIOUX under MW isn't going to work.
Jack Jansenee23d6e1995-01-27 14:43:25 +000094*/
95#define MAINLOOP_EVENTMASK (mDownMask|keyDownMask|osMask)
Jack Jansene8e8ae01995-01-26 16:36:45 +000096
97#include <signal.h>
Jack Jansenf93c72a1994-12-14 14:07:50 +000098
Guido van Rossumb3404661995-01-22 18:36:13 +000099/* XXX We should include Errors.h here, but it has a name conflict
Jack Jansen5f653091995-01-18 13:53:49 +0000100** with the python errors.h. */
101#define fnfErr -43
102
Jack Jansene8e8ae01995-01-26 16:36:45 +0000103/* Declared in macfsmodule.c: */
104extern FSSpec *mfs_GetFSSpecFSSpec();
105
Jack Jansenee23d6e1995-01-27 14:43:25 +0000106/* Interrupt code variables: */
107static int interrupted; /* Set to true when cmd-. seen */
108static RETSIGTYPE intcatcher Py_PROTO((int));
109
Jack Jansene8e8ae01995-01-26 16:36:45 +0000110/*
111** We attempt to be a good citizen by giving up the CPU periodically.
112** When in the foreground we do this less often and for shorter periods
113** than when in the background. At this time we also check for events and
Jack Jansenee23d6e1995-01-27 14:43:25 +0000114** pass them off to SIOUX, if compiling with mwerks.
Jack Jansene8e8ae01995-01-26 16:36:45 +0000115** The counts here are in ticks of 1/60th second.
116** XXXX The initial values here are not based on anything.
117** FG-python gives up the cpu for 1/60th 5 times per second,
118** BG-python for .2 second 10 times per second.
119*/
120static long interval_fg = 12;
121static long interval_bg = 6;
122static long yield_fg = 1;
123static long yield_bg = 12;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000124static long lastyield;
125static int in_foreground;
126
Guido van Rossume7134aa1995-02-26 10:20:53 +0000127/*
128** When > 0, do full scanning for events (program is not event aware)
129** when == 0, only scan for Command-period
130** when < 0, don't do any event scanning
131*/
132int PyMac_DoYieldEnabled = 1;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000133
Jack Jansen5f653091995-01-18 13:53:49 +0000134/* Convert C to Pascal string. Returns pointer to static buffer. */
135unsigned char *
136Pstring(char *str)
137{
138 static Str255 buf;
139 int len;
140
141 len = strlen(str);
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000142 if (len > 255)
143 len = 255;
Jack Jansen5f653091995-01-18 13:53:49 +0000144 buf[0] = (unsigned char)len;
145 strncpy((char *)buf+1, str, len);
146 return buf;
147}
148
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000149/* Like strerror() but for Mac OS error numbers */
150char *PyMac_StrError(int err)
Jack Jansenf93c72a1994-12-14 14:07:50 +0000151{
152 static char buf[256];
153 Handle h;
154 char *str;
155
156 h = GetResource('Estr', err);
157 if ( h ) {
158 HLock(h);
159 str = (char *)*h;
160 memcpy(buf, str+1, (unsigned char)str[0]);
Guido van Rossumcc9bc8f1995-02-13 16:17:03 +0000161 buf[(unsigned char)str[0]] = '\0';
Jack Jansenf93c72a1994-12-14 14:07:50 +0000162 HUnlock(h);
163 ReleaseResource(h);
164 } else {
165 sprintf(buf, "Mac OS error code %d", err);
166 }
167 return buf;
168}
169
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000170/* Exception object shared by all Mac specific modules for Mac OS errors */
171PyObject *PyMac_OSErrException;
172
173/* Initialize and return PyMac_OSErrException */
174PyObject *
175PyMac_GetOSErrException()
176{
177 if (PyMac_OSErrException == NULL)
178 PyMac_OSErrException = PyString_FromString("Mac OS Error");
179 return PyMac_OSErrException;
180}
181
Jack Jansenf93c72a1994-12-14 14:07:50 +0000182/* Set a MAC-specific error from errno, and return NULL; return None if no error */
183PyObject *
Guido van Rossumfffb8bb1995-01-12 12:37:24 +0000184PyErr_Mac(PyObject *eobj, int err)
Jack Jansenf93c72a1994-12-14 14:07:50 +0000185{
186 char *msg;
187 PyObject *v;
Jack Jansenf93c72a1994-12-14 14:07:50 +0000188
Guido van Rossum8f691791995-01-18 23:57:26 +0000189 if (err == 0 && !PyErr_Occurred()) {
Jack Jansenf93c72a1994-12-14 14:07:50 +0000190 Py_INCREF(Py_None);
191 return Py_None;
192 }
Guido van Rossum8f691791995-01-18 23:57:26 +0000193 if (err == -1 && PyErr_Occurred())
194 return NULL;
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000195 msg = PyMac_StrError(err);
Jack Jansenf93c72a1994-12-14 14:07:50 +0000196 v = Py_BuildValue("(is)", err, msg);
197 PyErr_SetObject(eobj, v);
198 Py_DECREF(v);
199 return NULL;
200}
201
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000202/* Call PyErr_Mac with PyMac_OSErrException */
203PyObject *
204PyMac_Error(OSErr err)
205{
206 return PyErr_Mac(PyMac_GetOSErrException(), err);
207}
208
Jack Jansenee23d6e1995-01-27 14:43:25 +0000209/* The catcher routine (which may not be used for all compilers) */
210static RETSIGTYPE
211intcatcher(sig)
212 int sig;
213{
214 interrupted = 1;
215 signal(SIGINT, intcatcher);
216}
217
218void
219PyOS_InitInterrupts()
220{
221 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
222 signal(SIGINT, intcatcher);
223}
224
225/*
226** This routine scans the event queue looking for cmd-.
227** This is the only way to get an interrupt under THINK (since it
228** doesn't do SIGINT handling), but is also used under MW, when
229** the full-fledged event loop is disabled. This way, we can at least
230** interrupt a runaway python program.
231*/
232static void
233scan_event_queue(flush)
234 int flush;
235{
Jack Jansenf74f63a1995-06-27 13:18:14 +0000236#if defined(__MWERKS__) && defined(__CFM68K__)
237 return; /* No GetEvQHdr yet */
238#else
Jack Jansenee23d6e1995-01-27 14:43:25 +0000239 register EvQElPtr q;
240
241 q = (EvQElPtr) GetEvQHdr()->qHead;
242
243 for (; q; q = (EvQElPtr)q->qLink) {
244 if (q->evtQWhat == keyDown &&
245 (char)q->evtQMessage == '.' &&
246 (q->evtQModifiers & cmdKey) != 0) {
247 if ( flush )
248 FlushEvents(keyDownMask, 0);
249 interrupted = 1;
250 break;
251 }
252 }
Jack Jansenf74f63a1995-06-27 13:18:14 +0000253#endif
Jack Jansenee23d6e1995-01-27 14:43:25 +0000254}
255
256int
257PyOS_InterruptOccurred()
258{
Guido van Rossume7134aa1995-02-26 10:20:53 +0000259 if (PyMac_DoYieldEnabled < 0)
260 return 0;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000261#ifdef THINK_C
262 scan_event_queue(1);
263#endif
264 PyMac_Yield();
265 if (interrupted) {
266 interrupted = 0;
267 return 1;
268 }
269 return 0;
270}
271
272/* intrpeek() is like intrcheck(), but it doesn't flush the events. The
273** idea is that you call intrpeek() somewhere in a busy-wait loop, and return
274** None as soon as it returns 1. The mainloop will then pick up the cmd-. soon
275** thereafter.
276*/
277static int
278intrpeek()
279{
280#ifdef THINK_C
281 scan_event_queue(0);
282#endif
283 return interrupted;
284}
285
286/* Check whether we are in the foreground */
287int
288PyMac_InForeground()
289{
290 static ProcessSerialNumber ours;
291 static inited;
292 ProcessSerialNumber curfg;
293 Boolean eq;
294
295 if ( inited == 0 )
296 (void)GetCurrentProcess(&ours);
297 inited = 1;
298 if ( GetFrontProcess(&curfg) < 0 )
299 eq = 1;
300 else if ( SameProcess(&ours, &curfg, &eq) < 0 )
301 eq = 1;
302 return (int)eq;
303
304}
305
Jack Jansenf93c72a1994-12-14 14:07:50 +0000306/*
Jack Jansene8e8ae01995-01-26 16:36:45 +0000307** Set yield timeouts
Jack Jansenf93c72a1994-12-14 14:07:50 +0000308*/
Jack Jansene8e8ae01995-01-26 16:36:45 +0000309void
310PyMac_SetYield(long fgi, long fgy, long bgi, long bgy)
311{
312 interval_fg = fgi;
313 yield_fg = fgy;
314 interval_bg = bgi;
315 yield_bg = bgy;
316}
317
318/*
Jack Jansena76382a1995-02-02 14:25:56 +0000319** Handle an event, either one found in the mainloop eventhandler or
320** one passed back from the python program.
321*/
322void
323PyMac_HandleEvent(evp)
324 EventRecord *evp;
325{
326 WindowPtr wp;
327
328#ifdef __MWERKS__
329 /* If SIOUX wants it we're done */
330 (void)SIOUXHandleOneEvent(evp);
331#else
332 /* Other compilers are just unlucky: we only weed out clicks in other applications */
333 if ( evp->what == mouseDown ) {
334 if ( FindWindow(evp->where, &wp) == inSysWindow )
335 SystemClick(evp, wp);
336 }
337#endif /* !__MWERKS__ */
338}
339
340/*
Jack Jansene8e8ae01995-01-26 16:36:45 +0000341** Yield the CPU to other tasks.
342*/
343static
344PyMac_DoYield()
Jack Jansenf93c72a1994-12-14 14:07:50 +0000345{
346 EventRecord ev;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000347 long yield;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000348 static int no_waitnextevent = -1;
349 int gotone;
350
351 if ( no_waitnextevent < 0 ) {
352 no_waitnextevent = (NGetTrapAddress(_WaitNextEvent, ToolTrap) ==
353 NGetTrapAddress(_Unimplemented, ToolTrap));
354 }
Jack Jansenf93c72a1994-12-14 14:07:50 +0000355
Jack Jansenee23d6e1995-01-27 14:43:25 +0000356 if ( !PyMac_DoYieldEnabled ) {
357#ifndef THINK_C
358 /* Under think this has been done before in intrcheck() or intrpeek() */
359 scan_event_queue(0);
360#endif
Jack Jansene8e8ae01995-01-26 16:36:45 +0000361 return;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000362 }
Jack Jansene8e8ae01995-01-26 16:36:45 +0000363
Jack Jansenee23d6e1995-01-27 14:43:25 +0000364 in_foreground = PyMac_InForeground();
365 if ( in_foreground )
Jack Jansene8e8ae01995-01-26 16:36:45 +0000366 yield = yield_fg;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000367 else
368 yield = yield_bg;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000369 while ( 1 ) {
370 if ( no_waitnextevent ) {
371 SystemTask();
Jack Jansenee23d6e1995-01-27 14:43:25 +0000372 gotone = GetNextEvent(MAINLOOP_EVENTMASK, &ev);
Jack Jansene8e8ae01995-01-26 16:36:45 +0000373 } else {
Jack Jansenee23d6e1995-01-27 14:43:25 +0000374 gotone = WaitNextEvent(MAINLOOP_EVENTMASK, &ev, yield, NULL);
Jack Jansene8e8ae01995-01-26 16:36:45 +0000375 }
376 /* Get out quickly if nothing interesting is happening */
377 if ( !gotone || ev.what == nullEvent )
378 break;
Jack Jansena76382a1995-02-02 14:25:56 +0000379 PyMac_HandleEvent(&ev);
Jack Jansenf93c72a1994-12-14 14:07:50 +0000380 }
Jack Jansene8e8ae01995-01-26 16:36:45 +0000381 lastyield = TickCount();
382}
383
384/*
385** Yield the CPU to other tasks if opportune
386*/
387void
388PyMac_Yield() {
389 long iv;
390
Jack Jansenee23d6e1995-01-27 14:43:25 +0000391 if ( in_foreground )
Jack Jansene8e8ae01995-01-26 16:36:45 +0000392 iv = interval_fg;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000393 else
394 iv = interval_bg;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000395 if ( TickCount() > lastyield + iv )
396 PyMac_DoYield();
397}
398
399/*
400** Idle routine for busy-wait loops.
401** Gives up CPU, handles events and returns true if an interrupt is pending
402** (but not actually handled yet).
403*/
404int
405PyMac_Idle()
406{
407 PyMac_DoYield();
408 return intrpeek();
Jack Jansenf93c72a1994-12-14 14:07:50 +0000409}
410
Jack Jansen8cd2b721995-02-13 11:33:28 +0000411/*
412** Return the name of the Python directory
413*/
414char *
415PyMac_GetPythonDir()
416{
417 int item;
418 static char name[256];
419 AliasHandle handle;
420 FSSpec dirspec;
Jack Jansen45ff77f1995-04-24 12:41:41 +0000421 int ok = 0;
Jack Jansen6cfab231995-02-13 22:46:00 +0000422 Boolean modified = 0, cannotmodify = 0;
Jack Jansen6cfab231995-02-13 22:46:00 +0000423 short oldrh, prefrh;
424 short prefdirRefNum;
425 long prefdirDirID;
Jack Jansen8cd2b721995-02-13 11:33:28 +0000426
Jack Jansen6cfab231995-02-13 22:46:00 +0000427 /*
428 ** Remember old resource file and try to open preferences file
429 ** in the preferences folder. If it doesn't exist we try to create
430 ** it. If anything fails here we limp on, but set cannotmodify so
431 ** we don't try to store things later on.
432 */
433 oldrh = CurResFile();
434 if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
435 &prefdirDirID) != noErr ) {
436 /* Something wrong with preferences folder */
437 cannotmodify = 1;
438 } else {
439 (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, "\pPython Preferences", &dirspec);
440 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
441 if ( prefrh == -1 ) {
Jack Jansen08305501995-06-18 20:03:40 +0000442#ifdef USE_MAC_MODPREFS
Jack Jansen6cfab231995-02-13 22:46:00 +0000443 /* It doesn't exist. Try to create it */
Guido van Rossumbecdbec1995-02-14 01:27:24 +0000444 FSpCreateResFile(&dirspec, 'PYTH', 'pref', 0);
Jack Jansen6cfab231995-02-13 22:46:00 +0000445 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
446 if ( prefrh == -1 ) {
Jack Jansen45ff77f1995-04-24 12:41:41 +0000447 /* This is strange, what should we do now? */
Jack Jansen6cfab231995-02-13 22:46:00 +0000448 cannotmodify = 1;
449 } else {
450 UseResFile(prefrh);
451 }
Jack Jansen08305501995-06-18 20:03:40 +0000452#else
453 printf("Error: no Preferences file. Attempting to limp on...\n");
454 name[0] = 0;
455 getwd(name);
456 return name;
457#endif
Jack Jansen6cfab231995-02-13 22:46:00 +0000458 }
459 }
460 /* So, we've opened our preferences file, we hope. Look for the alias */
461 handle = (AliasHandle)Get1Resource('alis', 128);
Jack Jansen8cd2b721995-02-13 11:33:28 +0000462 if ( handle ) {
Jack Jansen6cfab231995-02-13 22:46:00 +0000463 /* It exists. Resolve it (possibly updating it) */
Jack Jansen45ff77f1995-04-24 12:41:41 +0000464 if ( ResolveAlias(NULL, handle, &dirspec, &modified) == noErr ) {
Jack Jansen8cd2b721995-02-13 11:33:28 +0000465 ok = 1;
Jack Jansen45ff77f1995-04-24 12:41:41 +0000466 }
Jack Jansen8cd2b721995-02-13 11:33:28 +0000467 }
468 if ( !ok ) {
Jack Jansen08305501995-06-18 20:03:40 +0000469#ifdef USE_MAC_MODPREFS
Jack Jansen6cfab231995-02-13 22:46:00 +0000470 /* No luck, so far. ask the user for help */
Jack Jansen8cd2b721995-02-13 11:33:28 +0000471 item = Alert(NOPYTHON_ALERT, NULL);
472 if ( item == YES_ITEM ) {
Jack Jansen6cfab231995-02-13 22:46:00 +0000473 /* The user wants to point us to a directory. Let her do so */
Jack Jansen3ec804a1995-02-20 15:56:10 +0000474 ok = PyMac_GetDirectory(&dirspec);
475 if ( ok )
476 modified = 1;
Jack Jansen8cd2b721995-02-13 11:33:28 +0000477 } else if ( item == CURWD_ITEM ) {
Jack Jansen6cfab231995-02-13 22:46:00 +0000478 /* The user told us the current directory is fine. Build an FSSpec for it */
Jack Jansen8cd2b721995-02-13 11:33:28 +0000479 if ( getwd(name) ) {
480 if ( FSMakeFSSpec(0, 0, Pstring(name), &dirspec) == 0 ) {
481 ok = 1;
482 modified = 1;
483 }
484 }
485 }
Jack Jansen45ff77f1995-04-24 12:41:41 +0000486 if ( handle ) {
487 /* Set the (old, invalid) alias record to the new data */
488 UpdateAlias(NULL, &dirspec, handle, &modified);
489 }
Jack Jansen08305501995-06-18 20:03:40 +0000490#else
Jack Jansencf636931995-08-07 14:36:06 +0000491 printf("Error: corrupted Preferences file. Attempting to limp on...\n");
Jack Jansen08305501995-06-18 20:03:40 +0000492 name[0] = 0;
493 getwd(name);
494 return name;
495#endif
Jack Jansen8cd2b721995-02-13 11:33:28 +0000496 }
Jack Jansen08305501995-06-18 20:03:40 +0000497#ifdef USE_MAC_MODPREFS
Jack Jansen6cfab231995-02-13 22:46:00 +0000498 if ( ok && modified && !cannotmodify) {
499 /* We have a new, valid fsspec and we can update the preferences file. Do so. */
Jack Jansen45ff77f1995-04-24 12:41:41 +0000500 if ( !handle ) {
Jack Jansen8cd2b721995-02-13 11:33:28 +0000501 if (NewAlias(NULL, &dirspec, &handle) == 0 )
502 AddResource((Handle)handle, 'alis', 128, "\p");
503 } else {
504 ChangedResource((Handle)handle);
505 }
Jack Jansen6cfab231995-02-13 22:46:00 +0000506 UpdateResFile(prefrh);
Jack Jansen8cd2b721995-02-13 11:33:28 +0000507 }
Jack Jansen08305501995-06-18 20:03:40 +0000508#endif
Jack Jansen6cfab231995-02-13 22:46:00 +0000509 if ( !cannotmodify ) {
510 /* This means we have the resfile open. Close it. */
511 CloseResFile(prefrh);
512 }
513 /* Back to the old resource file */
514 UseResFile(oldrh);
515 /* Now turn the fsspec into a path to give back to our caller */
Jack Jansen8cd2b721995-02-13 11:33:28 +0000516 if ( ok ) {
517 ok = (nfullpath(&dirspec, name) == 0);
518 if ( ok ) strcat(name, ":");
519 }
520 if ( !ok ) {
521 /* If all fails, we return the current directory */
522 name[0] = 0;
523 (void)getwd(name);
524 }
525 return name;
526}
527
Jack Jansen08305501995-06-18 20:03:40 +0000528#ifndef USE_BUILTIN_PATH
529char *
530PyMac_GetPythonPath(dir)
531char *dir;
532{
533 FSSpec dirspec;
534 short oldrh, prefrh = -1;
535 short prefdirRefNum;
536 long prefdirDirID;
537 char *rv;
538 int i, newlen;
539 Str255 pathitem;
540
541 /*
542 ** Remember old resource file and try to open preferences file
543 ** in the preferences folder.
544 */
545 oldrh = CurResFile();
546 if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
547 &prefdirDirID) == noErr ) {
548 (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, "\pPython Preferences", &dirspec);
549 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
550 }
551 /* At this point, we may or may not have the preferences file open, and it
552 ** may or may not contain a sys.path STR# resource. We don't care, if it doesn't
553 ** exist we use the one from the application (the default).
554 ** We put an initial '\n' in front of the path that we don't return to the caller
555 */
556 if( (rv = malloc(2)) == NULL )
557 goto out;
558 strcpy(rv, "\n");
559 for(i=1; ; i++) {
560 GetIndString(pathitem, PYTHONPATH_ID, i);
561 if( pathitem[0] == 0 )
562 break;
563 if ( pathitem[0] >= 9 && strncmp((char *)pathitem+1, "$(PYTHON)", 9) == 0 ) {
564 /* We have to put the directory in place */
565 newlen = strlen(rv) + strlen(dir) + (pathitem[0]-9) + 2;
566 if( (rv=realloc(rv, newlen)) == NULL)
567 goto out;
568 strcat(rv, dir);
569 /* Skip a colon at the beginning of the item */
570 if ( pathitem[0] > 9 && pathitem[1+9] == ':' ) {
571 memcpy(rv+strlen(rv), pathitem+1+10, pathitem[0]-10);
572 newlen--;
573 } else {
574 memcpy(rv+strlen(rv), pathitem+1+9, pathitem[0]-9);
575 }
576 rv[newlen-2] = '\n';
577 rv[newlen-1] = 0;
578 } else {
579 /* Use as-is */
580 newlen = strlen(rv) + (pathitem[0]) + 2;
581 if( (rv=realloc(rv, newlen)) == NULL)
582 goto out;
583 memcpy(rv+strlen(rv), pathitem+1, pathitem[0]);
584 rv[newlen-2] = '\n';
585 rv[newlen-1] = 0;
586 }
587 }
588 if( strlen(rv) == 1) {
589 free(rv);
590 rv = NULL;
591 }
592 if ( rv ) {
593 rv[strlen(rv)-1] = 0;
594 rv++;
595 }
596out:
597 if ( prefrh ) {
598 CloseResFile(prefrh);
599 UseResFile(oldrh);
600 }
601 return rv;
602}
603#endif /* !USE_BUILTIN_PATH */
604
Jack Jansen74162f31995-02-15 22:58:33 +0000605/*
606** Returns true if the argument has a resource fork, and it contains
607** a 'PYC ' resource of the correct name
608*/
609int
610PyMac_FindResourceModule(module, filename)
611char *module;
612char *filename;
613{
614 FSSpec fss;
615 FInfo finfo;
616 short oldrh, filerh;
617 int ok;
618 Handle h;
619
620 if ( FSMakeFSSpec(0, 0, Pstring(filename), &fss) != noErr )
621 return 0; /* It doesn't exist */
622 if ( FSpGetFInfo(&fss, &finfo) != noErr )
623 return 0; /* shouldn't happen, I guess */
Jack Jansen74162f31995-02-15 22:58:33 +0000624 oldrh = CurResFile();
625 filerh = FSpOpenResFile(&fss, fsRdPerm);
626 if ( filerh == -1 )
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000627 return 0;
Jack Jansen74162f31995-02-15 22:58:33 +0000628 UseResFile(filerh);
629 SetResLoad(0);
630 h = Get1NamedResource('PYC ', Pstring(module));
631 SetResLoad(1);
632 ok = (h != NULL);
633 CloseResFile(filerh);
634 UseResFile(oldrh);
635 return ok;
636}
637
638/*
639** Load the specified module from a resource
640*/
641PyObject *
642PyMac_LoadResourceModule(module, filename)
643char *module;
644char *filename;
645{
646 FSSpec fss;
647 FInfo finfo;
648 short oldrh, filerh;
649 int ok;
650 Handle h;
651 OSErr err;
652 PyObject *m, *co;
653 long num, size;
654
655 if ( (err=FSMakeFSSpec(0, 0, Pstring(filename), &fss)) != noErr )
656 goto error;
657 if ( (err=FSpGetFInfo(&fss, &finfo)) != noErr )
658 goto error;
Jack Jansen74162f31995-02-15 22:58:33 +0000659 oldrh = CurResFile();
660 filerh = FSpOpenResFile(&fss, fsRdPerm);
661 if ( filerh == -1 ) {
662 err = ResError();
663 goto error;
664 }
665 UseResFile(filerh);
666 h = Get1NamedResource('PYC ', Pstring(module));
667 if ( h == NULL ) {
668 err = ResError();
669 goto error;
670 }
671 HLock(h);
672 /*
673 ** XXXX The next few lines are intimately tied to the format of pyc
674 ** files. I'm not sure whether this code should be here or in import.c -- Jack
675 */
676 size = GetHandleSize(h);
677 if ( size < 8 ) {
678 PyErr_SetString(PyExc_ImportError, "Resource too small");
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000679 co = NULL;
Jack Jansen74162f31995-02-15 22:58:33 +0000680 } else {
681 num = (*h)[0] & 0xff;
682 num = num | (((*h)[1] & 0xff) << 8);
683 num = num | (((*h)[2] & 0xff) << 16);
684 num = num | (((*h)[3] & 0xff) << 24);
685 if ( num != PyImport_GetMagicNumber() ) {
686 PyErr_SetString(PyExc_ImportError, "Bad MAGIC in resource");
687 co = NULL;
688 } else {
689 co = PyMarshal_ReadObjectFromString((*h)+8, size-8);
690 }
691 }
692 HUnlock(h);
693 CloseResFile(filerh);
694 UseResFile(oldrh);
695 if ( co ) {
696 m = PyImport_ExecCodeModule(module, co);
697 Py_DECREF(co);
698 } else {
699 m = NULL;
700 }
701 return m;
702error:
703 {
704 char buf[512];
705
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000706 sprintf(buf, "%s: %s", filename, PyMac_StrError(err));
Jack Jansen74162f31995-02-15 22:58:33 +0000707 PyErr_SetString(PyExc_ImportError, buf);
708 return NULL;
709 }
710}
Guido van Rossum24a45e31995-02-20 23:45:53 +0000711
Jack Jansen3ec804a1995-02-20 15:56:10 +0000712/*
713** Helper routine for GetDirectory
714*/
Guido van Rossum24a45e31995-02-20 23:45:53 +0000715static pascal short
716myhook_proc(short item, DialogPtr theDialog, void *dataptr)
Jack Jansen3ec804a1995-02-20 15:56:10 +0000717{
718 if ( item == SELECTCUR_ITEM ) {
719 item = sfItemCancelButton;
720 * (int *)dataptr = 1;
721 }
722 return item;
723}
724
725/*
726** Ask the user for a directory. I still can't understand
727** why Apple doesn't provide a standard solution for this...
728*/
729int
730PyMac_GetDirectory(dirfss)
731 FSSpec *dirfss;
732{
733 static SFTypeList list = {'fldr', 0, 0, 0};
734 static Point where = {-1, -1};
735 static DlgHookYDUPP myhook_upp;
736 static int upp_inited = 0;
737 StandardFileReply reply;
738 int select_clicked = 0;
739
740 if ( !upp_inited ) {
741 myhook_upp = NewDlgHookYDProc(myhook_proc);
742 upp_inited = 1;
743 }
Guido van Rossum24a45e31995-02-20 23:45:53 +0000744 CustomGetFile((FileFilterYDUPP)0, 1, list, &reply, GETDIR_ID, where, myhook_upp,
Jack Jansen3ec804a1995-02-20 15:56:10 +0000745 NULL, NULL, NULL, (void *)&select_clicked);
746
747 reply.sfFile.name[0] = 0;
748 if( FSMakeFSSpec(reply.sfFile.vRefNum, reply.sfFile.parID, reply.sfFile.name, dirfss) )
749 return 0;
750 return select_clicked;
751}
Jack Jansen5f653091995-01-18 13:53:49 +0000752
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000753/* Convert a 4-char string object argument to an OSType value */
Jack Jansen5f653091995-01-18 13:53:49 +0000754int
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000755PyMac_GetOSType(PyObject *v, OSType *pr)
Jack Jansen5f653091995-01-18 13:53:49 +0000756{
757 if (!PyString_Check(v) || PyString_Size(v) != 4) {
758 PyErr_SetString(PyExc_TypeError,
759 "OSType arg must be string of 4 chars");
760 return 0;
761 }
762 memcpy((char *)pr, PyString_AsString(v), 4);
763 return 1;
764}
765
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000766/* Convert an OSType value to a 4-char string object */
767PyObject *
768PyMac_BuildOSType(OSType t)
769{
770 return PyString_FromStringAndSize((char *)&t, 4);
771}
772
773
774/* Convert a Python string object to a Str255 */
Jack Jansen5f653091995-01-18 13:53:49 +0000775int
Guido van Rossum8f691791995-01-18 23:57:26 +0000776PyMac_GetStr255(PyObject *v, Str255 pbuf)
Jack Jansen5f653091995-01-18 13:53:49 +0000777{
778 int len;
779 if (!PyString_Check(v) || (len = PyString_Size(v)) > 255) {
780 PyErr_SetString(PyExc_TypeError,
781 "Str255 arg must be string of at most 255 chars");
782 return 0;
783 }
784 pbuf[0] = len;
785 memcpy((char *)(pbuf+1), PyString_AsString(v), len);
786 return 1;
787}
788
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000789/* Convert a Str255 to a Python string object */
790PyObject *
791PyMac_BuildStr255(Str255 s)
792{
793 return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
794}
795
796
Jack Jansen5f653091995-01-18 13:53:49 +0000797/*
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000798** Convert a Python object to an FSSpec.
799** The object may either be a full pathname or a triple
800** (vrefnum, dirid, path).
Jack Jansen5f653091995-01-18 13:53:49 +0000801** NOTE: This routine will fail on pre-sys7 machines.
802** The caller is responsible for not calling this routine
803** in those cases (which is fine, since everyone calling
804** this is probably sys7 dependent anyway).
805*/
806int
Guido van Rossum8f691791995-01-18 23:57:26 +0000807PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
Jack Jansen5f653091995-01-18 13:53:49 +0000808{
809 Str255 path;
810 short refnum;
811 long parid;
812 OSErr err;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000813 FSSpec *fs2;
Jack Jansen5f653091995-01-18 13:53:49 +0000814
Jack Jansene8e8ae01995-01-26 16:36:45 +0000815 /* first check whether it already is an FSSpec */
816 fs2 = mfs_GetFSSpecFSSpec(v);
817 if ( fs2 ) {
Jack Jansen3ec804a1995-02-20 15:56:10 +0000818 (void)FSMakeFSSpec(fs2->vRefNum, fs2->parID, fs2->name, fs);
Jack Jansene8e8ae01995-01-26 16:36:45 +0000819 return 1;
820 }
Jack Jansen5f653091995-01-18 13:53:49 +0000821 if ( PyString_Check(v) ) {
822 /* It's a pathname */
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000823 if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
Jack Jansen5f653091995-01-18 13:53:49 +0000824 return 0;
825 refnum = 0; /* XXXX Should get CurWD here... */
826 parid = 0;
827 } else {
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000828 if( !PyArg_Parse(v, "(hlO&); FSSpec should be fullpath or (vrefnum,dirid,path)",
829 &refnum, &parid, PyMac_GetStr255, &path)) {
Jack Jansen5f653091995-01-18 13:53:49 +0000830 return 0;
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000831 }
Jack Jansen5f653091995-01-18 13:53:49 +0000832 }
833 err = FSMakeFSSpec(refnum, parid, path, fs);
834 if ( err && err != fnfErr ) {
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000835 PyErr_Mac(PyExc_ValueError, err);
Jack Jansen5f653091995-01-18 13:53:49 +0000836 return 0;
837 }
838 return 1;
839}
840
Guido van Rossum8f691791995-01-18 23:57:26 +0000841
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000842
843/* Convert a Python object to a Rect.
Guido van Rossum5279ec61995-01-26 22:56:59 +0000844 The object must be a (left, top, right, bottom) tuple.
845 (This differs from the order in the struct but is consistent with
846 the arguments to SetRect(), and also with STDWIN). */
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000847int
848PyMac_GetRect(PyObject *v, Rect *r)
Guido van Rossum8f691791995-01-18 23:57:26 +0000849{
Guido van Rossum5279ec61995-01-26 22:56:59 +0000850 return PyArg_Parse(v, "(hhhh)", &r->left, &r->top, &r->right, &r->bottom);
Guido van Rossum8f691791995-01-18 23:57:26 +0000851}
Guido van Rossumb3404661995-01-22 18:36:13 +0000852
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000853/* Convert a Rect to a Python object */
Guido van Rossumb3404661995-01-22 18:36:13 +0000854PyObject *
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000855PyMac_BuildRect(Rect *r)
Guido van Rossumb3404661995-01-22 18:36:13 +0000856{
Guido van Rossum5279ec61995-01-26 22:56:59 +0000857 return Py_BuildValue("(hhhh)", r->left, r->top, r->right, r->bottom);
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000858}
859
860
861/* Convert a Python object to a Point.
Guido van Rossum5279ec61995-01-26 22:56:59 +0000862 The object must be a (h, v) tuple.
863 (This differs from the order in the struct but is consistent with
864 the arguments to SetPoint(), and also with STDWIN). */
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000865int
866PyMac_GetPoint(PyObject *v, Point *p)
867{
Guido van Rossum5279ec61995-01-26 22:56:59 +0000868 return PyArg_Parse(v, "(hh)", &p->h, &p->v);
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000869}
870
871/* Convert a Point to a Python object */
872PyObject *
873PyMac_BuildPoint(Point p)
874{
Guido van Rossum5279ec61995-01-26 22:56:59 +0000875 return Py_BuildValue("(hh)", p.h, p.v);
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000876}
877
878
879/* Convert a Python object to an EventRecord.
880 The object must be a (what, message, when, (v, h), modifiers) tuple. */
881int
882PyMac_GetEventRecord(PyObject *v, EventRecord *e)
883{
884 return PyArg_Parse(v, "(hll(hh)h)",
885 &e->what,
886 &e->message,
887 &e->when,
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000888 &e->where.h,
Guido van Rossum5279ec61995-01-26 22:56:59 +0000889 &e->where.v,
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000890 &e->modifiers);
891}
892
893/* Convert a Rect to an EventRecord object */
894PyObject *
895PyMac_BuildEventRecord(EventRecord *e)
896{
897 return Py_BuildValue("(hll(hh)h)",
898 e->what,
899 e->message,
900 e->when,
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000901 e->where.h,
Guido van Rossum5279ec61995-01-26 22:56:59 +0000902 e->where.v,
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000903 e->modifiers);
Guido van Rossumb3404661995-01-22 18:36:13 +0000904}
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000905
906
Jack Jansen76efd8e1995-02-24 22:53:16 +0000907#ifdef USE_MAC_APPLET_SUPPORT
Guido van Rossum8c89a6f1995-02-19 15:52:17 +0000908/* Applet support */
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000909
Guido van Rossum8c89a6f1995-02-19 15:52:17 +0000910/* Run a compiled Python Python script from 'PYC ' resource __main__ */
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000911static int
912run_main_resource()
913{
914 Handle h;
915 long size;
916 PyObject *code;
917 PyObject *result;
918
919 h = GetNamedResource('PYC ', "\p__main__");
920 if (h == NULL) {
Jack Jansen3ec804a1995-02-20 15:56:10 +0000921 Alert(NOPYC_ALERT, NULL);
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000922 return 1;
923 }
924 size = GetResourceSizeOnDisk(h);
925 HLock(h);
926 code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
927 HUnlock(h);
928 ReleaseResource(h);
929 if (code == NULL) {
930 PyErr_Print();
931 return 1;
932 }
933 result = PyImport_ExecCodeModule("__main__", code);
934 Py_DECREF(code);
935 if (result == NULL) {
936 PyErr_Print();
937 return 1;
938 }
939 Py_DECREF(result);
940 return 0;
941}
942
Guido van Rossum8c89a6f1995-02-19 15:52:17 +0000943/* Initialization sequence for applets */
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000944void
945PyMac_InitApplet()
946{
Guido van Rossum8c89a6f1995-02-19 15:52:17 +0000947 int argc;
948 char **argv;
Guido van Rossum24a45e31995-02-20 23:45:53 +0000949 int err;
Jack Jansen3ec804a1995-02-20 15:56:10 +0000950
Jack Jansen3ec804a1995-02-20 15:56:10 +0000951 PyMac_AddLibResources();
Jack Jansen3ec804a1995-02-20 15:56:10 +0000952#ifdef __MWERKS__
953 SIOUXSettings.asktosaveonclose = 0;
954 SIOUXSettings.showstatusline = 0;
955 SIOUXSettings.tabspaces = 4;
956#endif
Guido van Rossum8c89a6f1995-02-19 15:52:17 +0000957 argc = PyMac_GetArgv(&argv);
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000958 Py_Initialize();
Guido van Rossum8c89a6f1995-02-19 15:52:17 +0000959 PySys_SetArgv(argc, argv);
Jack Jansen3ec804a1995-02-20 15:56:10 +0000960 err = run_main_resource();
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000961 fflush(stderr);
962 fflush(stdout);
Jack Jansen3ec804a1995-02-20 15:56:10 +0000963#ifdef __MWERKS__
964 if (!err)
965 SIOUXSettings.autocloseonquit = 1;
966 else
Jack Jansen292b0f91995-07-29 13:52:37 +0000967 printf("\n[Terminated]\n");
Jack Jansen3ec804a1995-02-20 15:56:10 +0000968#endif
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000969 /* XXX Should we bother to Py_Exit(sts)? */
970}
Guido van Rossum24a45e31995-02-20 23:45:53 +0000971
Jack Jansen76efd8e1995-02-24 22:53:16 +0000972#endif /* USE_MAC_APPLET_SUPPORT */
973
974/* For normal application */
975void
976PyMac_InitApplication()
977{
978 int argc;
979 char **argv;
980
981#ifdef USE_MAC_SHARED_LIBRARY
982 PyMac_AddLibResources();
983#endif
984#ifdef __MWERKS__
985 SIOUXSettings.asktosaveonclose = 0;
986 SIOUXSettings.showstatusline = 0;
987 SIOUXSettings.tabspaces = 4;
988#endif
989 argc = PyMac_GetArgv(&argv);
990 if ( argc > 1 ) {
991 /* We're running a script. Attempt to change current directory */
992 char curwd[256], *endp;
993
994 strcpy(curwd, argv[1]);
995 endp = strrchr(curwd, ':');
996 if ( endp && endp > curwd ) {
997 *endp = '\0';
Jack Jansen45ff77f1995-04-24 12:41:41 +0000998
Jack Jansen76efd8e1995-02-24 22:53:16 +0000999 chdir(curwd);
1000 }
1001 }
1002 Py_Main(argc, argv);
1003}
Jack Jansen292b0f91995-07-29 13:52:37 +00001004
1005/*
1006** PyMac_InteractiveOptions - Allow user to set options if option key is pressed
1007*/
1008void
1009PyMac_InteractiveOptions(int *inspect, int *verbose, int *suppress_print,
1010 int *unbuffered, int *debugging)
1011{
1012 KeyMap rmap;
1013 unsigned char *map;
1014 short item, type;
1015 ControlHandle handle;
1016 DialogPtr dialog;
1017 Rect rect;
1018
1019 GetKeys(rmap);
1020 map = (unsigned char *)rmap;
1021 if ( ( map[0x3a>>3] & (1<<(0x3a&7)) ) == 0 ) /* option key is 3a */
1022 return;
1023
1024 dialog = GetNewDialog(OPT_DIALOG, NULL, (WindowPtr)-1);
Jack Jansencf636931995-08-07 14:36:06 +00001025 if ( dialog == NULL ) {
1026 printf("Option dialog not found - cannot set options\n");
Jack Jansen292b0f91995-07-29 13:52:37 +00001027 return;
Jack Jansencf636931995-08-07 14:36:06 +00001028 }
Jack Jansen292b0f91995-07-29 13:52:37 +00001029 while (1) {
1030 handle = NULL;
1031 ModalDialog(NULL, &item);
1032 if ( item == OPT_OK )
1033 break;
1034 if ( item == OPT_CANCEL ) {
1035 DisposDialog(dialog);
1036 exit(0);
1037 }
1038#define OPT_ITEM(num, var) \
1039 if ( item == (num) ) { \
1040 *(var) = !*(var); \
1041 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
1042 SetCtlValue(handle, (short)*(var)); \
1043 }
1044
1045 OPT_ITEM(OPT_INSPECT, inspect);
1046 OPT_ITEM(OPT_VERBOSE, verbose);
1047 OPT_ITEM(OPT_SUPPRESS, suppress_print);
1048 OPT_ITEM(OPT_UNBUFFERED, unbuffered);
1049 OPT_ITEM(OPT_DEBUGGING, debugging);
1050
1051#undef OPT_ITEM
1052 }
1053 DisposDialog(dialog);
Jack Jansen292b0f91995-07-29 13:52:37 +00001054}