blob: 371161020ea013d272becee19324e59413daf332 [file] [log] [blame]
Guido van Rossumb3404661995-01-22 18:36:13 +00001/***********************************************************
Jack Jansen42218ce1997-01-31 16:15:11 +00002Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
Guido van Rossumb3404661995-01-22 18:36:13 +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******************************************************************/
Jack Jansenf93c72a1994-12-14 14:07:50 +000024
Jack Jansenbf05d4c1996-08-19 15:11:45 +000025
Jack Jansenf93c72a1994-12-14 14:07:50 +000026#include "Python.h"
Guido van Rossumbecdbec1995-02-14 01:27:24 +000027
Jack Jansenf93c72a1994-12-14 14:07:50 +000028#include "macglue.h"
Jack Jansen74162f31995-02-15 22:58:33 +000029#include "marshal.h"
30#include "import.h"
Jack Janseneda78631997-06-12 15:29:46 +000031#include "importdl.h"
Jack Jansen8bb1dc12001-05-19 12:31:09 +000032#include "pymactoolbox.h"
Jack Jansenf93c72a1994-12-14 14:07:50 +000033
Jack Jansen819f1771995-08-14 12:35:10 +000034#include "pythonresources.h"
35
Jack Jansen0194ad52001-05-12 22:46:35 +000036#ifdef WITHOUT_FRAMEWORKS
Jack Jansenf93c72a1994-12-14 14:07:50 +000037#include <OSUtils.h> /* for Set(Current)A5 */
Jack Jansene8e8ae01995-01-26 16:36:45 +000038#include <Files.h>
Jack Jansen8cd2b721995-02-13 11:33:28 +000039#include <StandardFile.h>
Jack Jansenf93c72a1994-12-14 14:07:50 +000040#include <Resources.h>
41#include <Memory.h>
Jack Jansenf93c72a1994-12-14 14:07:50 +000042#include <Windows.h>
Jack Jansene8e8ae01995-01-26 16:36:45 +000043#include <Traps.h>
Jack Jansenee23d6e1995-01-27 14:43:25 +000044#include <Processes.h>
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +000045#include <Fonts.h>
46#include <Menus.h>
Jack Jansen08305501995-06-18 20:03:40 +000047#include <TextUtils.h>
Jack Jansen0194ad52001-05-12 22:46:35 +000048#include <LowMem.h>
Jack Jansen0194ad52001-05-12 22:46:35 +000049#include <Events.h>
Jack Jansen0194ad52001-05-12 22:46:35 +000050#else
51#include <Carbon/Carbon.h>
52#endif
53
Jack Jansen16df2aa1995-02-27 16:17:28 +000054#ifdef __MWERKS__
55#include <SIOUX.h>
Jack Jansen9ae898b2000-07-11 21:16:03 +000056extern void SIOUXSetupMenus(void);
57extern void SIOUXDoAboutBox(void);
Jack Jansen16df2aa1995-02-27 16:17:28 +000058#endif
Jack Jansen9ae898b2000-07-11 21:16:03 +000059#ifdef USE_GUSI
60/* Functions we redefine because they're in obscure libraries */
61extern void SpinCursor(short x);
62extern void RotateCursor(short x);
Jack Jansen027f6722002-06-26 20:37:40 +000063extern pascal unsigned char * PLstrcpy(unsigned char *, const unsigned char *);
64extern pascal short PLstrcmp(const unsigned char *, const unsigned char *);
65extern pascal char *PLstrrchr(const unsigned char *, short);
Jack Jansen9ae898b2000-07-11 21:16:03 +000066
67#endif
68
Jack Jansen3469e991996-09-06 00:30:45 +000069/* The ID of the Sioux apple menu */
70#define SIOUX_APPLEID 32000
71
Jack Jansenee23d6e1995-01-27 14:43:25 +000072#include <signal.h>
Jack Jansen74162f31995-02-15 22:58:33 +000073#include <stdio.h>
Jack Jansene8e8ae01995-01-26 16:36:45 +000074
Jack Jansenee23d6e1995-01-27 14:43:25 +000075/*
Jack Jansend1f06311996-08-01 15:23:54 +000076** When less than this amount of stackspace is left we
77** raise a MemoryError.
78*/
79#ifndef MINIMUM_STACK_SIZE
Jack Jansend1f06311996-08-01 15:23:54 +000080#define MINIMUM_STACK_SIZE 8192
Jack Jansend1f06311996-08-01 15:23:54 +000081#endif
82
Jack Jansen340eb882001-02-02 22:40:28 +000083/*
84** On MacOSX StackSpace() lies: it gives the distance from heap end to stack pointer,
85** but the stack cannot grow that far due to rlimit values. We cannot get at this value
86** from Carbon, so we set a maximum to the stack here that is based on the default
87** stack limit of 512K.
88*/
89#define MAXIMUM_STACK_SIZE (256*1024)
Jack Jansen340eb882001-02-02 22:40:28 +000090
Jack Jansend1f06311996-08-01 15:23:54 +000091/*
Jack Jansen16df2aa1995-02-27 16:17:28 +000092** We have to be careful, since we can't handle
Jack Jansenee23d6e1995-01-27 14:43:25 +000093** things like updates (and they'll keep coming back if we don't
Jack Jansen16df2aa1995-02-27 16:17:28 +000094** handle them). Note that we don't know who has windows open, so
95** even handing updates off to SIOUX under MW isn't going to work.
Jack Jansenee23d6e1995-01-27 14:43:25 +000096*/
Jack Jansen0c968871997-08-26 13:20:34 +000097#define MAINLOOP_EVENTMASK (mDownMask|keyDownMask|osMask|activMask)
Jack Jansene8e8ae01995-01-26 16:36:45 +000098
99#include <signal.h>
Jack Jansenf93c72a1994-12-14 14:07:50 +0000100
Guido van Rossumb3404661995-01-22 18:36:13 +0000101/* XXX We should include Errors.h here, but it has a name conflict
Jack Jansen5f653091995-01-18 13:53:49 +0000102** with the python errors.h. */
103#define fnfErr -43
104
Jack Jansenee23d6e1995-01-27 14:43:25 +0000105/* Interrupt code variables: */
106static int interrupted; /* Set to true when cmd-. seen */
Jack Jansend88296d2000-07-11 19:51:05 +0000107static RETSIGTYPE intcatcher(int);
Jack Jansenee23d6e1995-01-27 14:43:25 +0000108
Jack Jansen0194ad52001-05-12 22:46:35 +0000109#if !TARGET_API_MAC_OSX
Jack Jansend88296d2000-07-11 19:51:05 +0000110static int PyMac_Yield(void);
Jack Jansen0194ad52001-05-12 22:46:35 +0000111#endif
Jack Jansenf6865f71996-09-04 15:24:59 +0000112
Jack Jansene8e8ae01995-01-26 16:36:45 +0000113/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000114** These are the real scheduling parameters that control what we check
115** in the event loop, and how often we check. The values are initialized
116** from pyMac_SchedParamStruct.
117*/
118
119struct real_sched_param_struct {
120 int check_interrupt; /* if true check for command-dot */
121 int process_events; /* if nonzero enable evt processing, this mask */
122 int besocial; /* if nonzero be a little social with CPU */
123 unsigned long check_interval; /* how often to check, in ticks */
124 unsigned long bg_yield; /* yield so long when in background */
125 /* these are computed from previous and clock and such */
126 int enabled; /* check_interrupt OR process_event OR yield */
127 unsigned long next_check; /* when to check/yield next, in ticks */
128};
129
130static struct real_sched_param_struct schedparams =
131 { 1, MAINLOOP_EVENTMASK, 1, 15, 15, 1, 0};
132
Jack Jansen819f1771995-08-14 12:35:10 +0000133/*
Jack Jansenf6865f71996-09-04 15:24:59 +0000134** Workaround for sioux/gusi combo: set when we are exiting
135*/
136int PyMac_ConsoleIsDead;
137
138/*
Jack Jansencaa7c461997-06-12 10:49:13 +0000139** Sioux menu bar, saved early so we can restore it
140*/
Jack Jansen657ba272001-02-17 22:02:07 +0000141static MenuBarHandle sioux_mbar;
Jack Jansencaa7c461997-06-12 10:49:13 +0000142
143/*
Jack Jansen36ed5061997-06-20 16:18:15 +0000144** The python-code event handler
145*/
146static PyObject *python_event_handler;
147
Jack Jansen741e0372001-05-19 12:55:57 +0000148/* Given an FSSpec, return the FSSpec of the parent folder */
149
150static OSErr
151get_folder_parent (FSSpec * fss, FSSpec * parent)
152{
153 CInfoPBRec rec;
154 short err;
155
156 * parent = * fss;
157 rec.hFileInfo.ioNamePtr = parent->name;
158 rec.hFileInfo.ioVRefNum = parent->vRefNum;
159 rec.hFileInfo.ioDirID = parent->parID;
160 rec.hFileInfo.ioFDirIndex = -1;
161 rec.hFileInfo.ioFVersNum = 0;
162 if (err = PBGetCatInfoSync (& rec))
163 return err;
164 parent->parID = rec.dirInfo.ioDrParID;
165/* parent->name[0] = 0; */
166 return 0;
167}
168
169/* Given an FSSpec return a full, colon-separated pathname */
170
171OSErr
Jack Jansencf031932001-09-11 09:22:19 +0000172PyMac_GetFullPathname (FSSpec *fss, char *buf, int length)
Jack Jansen741e0372001-05-19 12:55:57 +0000173{
174 short err;
175 FSSpec fss_parent, fss_current;
176 char tmpbuf[1024];
177 int plen;
178
179 fss_current = *fss;
180 plen = fss_current.name[0];
Jack Jansencf031932001-09-11 09:22:19 +0000181 if ( plen+2 > length ) {
182 *buf = 0;
183 return errFSNameTooLong;
184 }
Jack Jansen741e0372001-05-19 12:55:57 +0000185 memcpy(buf, &fss_current.name[1], plen);
186 buf[plen] = 0;
187 /* Special case for disk names */
188 if ( fss_current.parID <= 1 ) {
189 buf[plen++] = ':';
190 buf[plen] = 0;
191 return 0;
192 }
193 while (fss_current.parID > 1) {
194 /* Get parent folder name */
Jack Jansencf031932001-09-11 09:22:19 +0000195 if (err = get_folder_parent(&fss_current, &fss_parent)) {
196 *buf = 0;
Jack Jansen741e0372001-05-19 12:55:57 +0000197 return err;
Jack Jansencf031932001-09-11 09:22:19 +0000198 }
Jack Jansen741e0372001-05-19 12:55:57 +0000199 fss_current = fss_parent;
200 /* Prepend path component just found to buf */
201 plen = fss_current.name[0];
202 if (strlen(buf) + plen + 1 > 1024) {
203 /* Oops... Not enough space (shouldn't happen) */
204 *buf = 0;
Jack Jansencf031932001-09-11 09:22:19 +0000205 return errFSNameTooLong;
Jack Jansen741e0372001-05-19 12:55:57 +0000206 }
207 memcpy(tmpbuf, &fss_current.name[1], plen);
208 tmpbuf[plen] = ':';
209 strcpy(&tmpbuf[plen+1], buf);
Jack Jansencf031932001-09-11 09:22:19 +0000210 if ( strlen(tmpbuf) > length ) {
211 *buf = 0;
212 return errFSNameTooLong;
213 }
Jack Jansen741e0372001-05-19 12:55:57 +0000214 strcpy(buf, tmpbuf);
215 }
216 return 0;
217}
Jack Jansen1f9f2f42000-07-24 19:50:16 +0000218
Jack Jansen7ac70af1996-08-19 11:01:05 +0000219
Jack Jansen2d1306b2000-04-07 09:10:49 +0000220#ifdef USE_GUSI
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000221/*
222** SpinCursor (needed by GUSI) drags in heaps of stuff, so we
223** provide a dummy here.
224*/
Jack Jansencfadbd41996-08-19 11:36:25 +0000225void SpinCursor(short x) { /* Dummy */ }
Jack Jansenefaada71998-02-20 16:03:15 +0000226void RotateCursor(short x) { /* Dummy */ }
Jack Jansencfadbd41996-08-19 11:36:25 +0000227
Jack Jansenf6865f71996-09-04 15:24:59 +0000228
Jack Jansena39f1b01997-05-23 15:35:14 +0000229/* Called at exit() time thru atexit(), to stop event processing */
230void
231PyMac_StopGUSISpin() {
232 PyMac_ConsoleIsDead = 1;
233}
234
Jack Jansena39f1b01997-05-23 15:35:14 +0000235#endif /* USE_GUSI */
Jack Jansen378815c1996-03-06 16:21:34 +0000236
Jack Jansen819f1771995-08-14 12:35:10 +0000237
Jack Jansen5f653091995-01-18 13:53:49 +0000238/* Convert C to Pascal string. Returns pointer to static buffer. */
239unsigned char *
240Pstring(char *str)
241{
242 static Str255 buf;
243 int len;
244
245 len = strlen(str);
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000246 if (len > 255)
247 len = 255;
Jack Jansen5f653091995-01-18 13:53:49 +0000248 buf[0] = (unsigned char)len;
249 strncpy((char *)buf+1, str, len);
250 return buf;
251}
252
Jack Jansen5afad832000-12-12 22:12:14 +0000253
Jack Jansen1ed95291996-07-22 15:25:10 +0000254#ifdef USE_STACKCHECK
255/* Check for stack overflow */
256int
257PyOS_CheckStack()
258{
Jack Jansen14a91712000-08-25 21:57:23 +0000259 char here;
260 static char *sentinel = 0;
Jack Jansen53bafd92000-09-08 22:05:48 +0000261 static PyThreadState *thread_for_sentinel = 0;
Jack Jansen1ed95291996-07-22 15:25:10 +0000262
Jack Jansen340eb882001-02-02 22:40:28 +0000263 if ( sentinel == 0 ) {
264 unsigned long stackspace = StackSpace();
265
266#ifdef MAXIMUM_STACK_SIZE
267 /* See the comment at the definition */
268 if ( stackspace > MAXIMUM_STACK_SIZE )
269 stackspace = MAXIMUM_STACK_SIZE;
270#endif
271 sentinel = &here - stackspace + MINIMUM_STACK_SIZE;
Jack Jansen14a91712000-08-25 21:57:23 +0000272 }
Jack Jansen53bafd92000-09-08 22:05:48 +0000273 if ( thread_for_sentinel == 0 ) {
274 thread_for_sentinel = PyThreadState_Get();
275 }
276 if ( &here < sentinel ) {
277 if (thread_for_sentinel == PyThreadState_Get()) {
278 return -1;
Jack Jansen53bafd92000-09-08 22:05:48 +0000279 }
280 }
Jack Jansen1ed95291996-07-22 15:25:10 +0000281 return 0;
282}
283#endif /* USE_STACKCHECK */
284
Jack Jansen0194ad52001-05-12 22:46:35 +0000285#if !TARGET_API_MAC_OSX
Jack Jansen18452a42003-07-23 11:39:28 +0000286void
287PyErr_SetInterrupt(void)
288{
289 interrupted = 1;
290}
291
Jack Jansenee23d6e1995-01-27 14:43:25 +0000292/* The catcher routine (which may not be used for all compilers) */
293static RETSIGTYPE
294intcatcher(sig)
295 int sig;
296{
297 interrupted = 1;
298 signal(SIGINT, intcatcher);
299}
300
301void
302PyOS_InitInterrupts()
303{
304 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
305 signal(SIGINT, intcatcher);
306}
307
Jack Jansena8441de1997-08-08 14:57:37 +0000308void
309PyOS_FiniInterrupts()
310{
311}
312
Jack Jansenee23d6e1995-01-27 14:43:25 +0000313/* Check whether we are in the foreground */
Jack Jansen9ae898b2000-07-11 21:16:03 +0000314static int
315PyMac_InForeground(void)
Jack Jansenee23d6e1995-01-27 14:43:25 +0000316{
317 static ProcessSerialNumber ours;
318 static inited;
319 ProcessSerialNumber curfg;
320 Boolean eq;
321
Jack Jansene3ae0df1997-06-03 15:28:29 +0000322 if ( inited == 0 ) {
Jack Jansenee23d6e1995-01-27 14:43:25 +0000323 (void)GetCurrentProcess(&ours);
Jack Jansene3ae0df1997-06-03 15:28:29 +0000324 inited = 1;
325 }
Jack Jansenee23d6e1995-01-27 14:43:25 +0000326 if ( GetFrontProcess(&curfg) < 0 )
327 eq = 1;
328 else if ( SameProcess(&ours, &curfg, &eq) < 0 )
329 eq = 1;
330 return (int)eq;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000331}
Jack Jansen439eaa92001-11-10 00:41:43 +0000332
333/*
334** This routine scans the event queue looking for cmd-.
335*/
336static void
337scan_event_queue(force)
338 int force;
339{
Jack Jansen439eaa92001-11-10 00:41:43 +0000340 if ( interrupted || (!schedparams.check_interrupt && !force) )
341 return;
342 if ( CheckEventQueueForUserCancel() )
343 interrupted = 1;
Jack Jansen439eaa92001-11-10 00:41:43 +0000344}
345
346int
347PyErr_CheckSignals()
348{
Jack Jansen439eaa92001-11-10 00:41:43 +0000349 if (schedparams.enabled) {
Jack Jansen6c7e3262002-12-12 10:31:54 +0000350 if ( interrupted || (unsigned long)TickCount() > schedparams.next_check ) {
Jack Jansen439eaa92001-11-10 00:41:43 +0000351 scan_event_queue(0);
352 if (interrupted) {
353 interrupted = 0;
354 PyErr_SetNone(PyExc_KeyboardInterrupt);
355 return -1;
356 }
357 if ( PyMac_Yield() < 0)
358 return -1;
Jack Jansen6c7e3262002-12-12 10:31:54 +0000359 schedparams.next_check = (unsigned long)TickCount()
Jack Jansen439eaa92001-11-10 00:41:43 +0000360 + schedparams.check_interval;
361 }
362 }
363 return 0;
364}
365
366int
367PyOS_InterruptOccurred()
368{
369 scan_event_queue(0);
370 if ( !interrupted )
371 return 0;
372 interrupted = 0;
373 return 1;
374}
Jack Jansen0194ad52001-05-12 22:46:35 +0000375#endif
Jack Jansenee23d6e1995-01-27 14:43:25 +0000376
Jack Jansen36ed5061997-06-20 16:18:15 +0000377int
378PyMac_SetEventHandler(PyObject *evh)
379{
380 if ( evh && python_event_handler ) {
381 PyErr_SetString(PyExc_RuntimeError, "Python event handler already set");
382 return 0;
383 }
384 if ( python_event_handler )
385 Py_DECREF(python_event_handler);
386 if ( evh )
387 Py_INCREF(evh);
388 python_event_handler = evh;
389 return 1;
390}
391
Jack Jansenf93c72a1994-12-14 14:07:50 +0000392/*
Jack Jansena76382a1995-02-02 14:25:56 +0000393** Handle an event, either one found in the mainloop eventhandler or
394** one passed back from the python program.
395*/
396void
Jack Jansen36ed5061997-06-20 16:18:15 +0000397PyMac_HandleEventIntern(evp)
Jack Jansena76382a1995-02-02 14:25:56 +0000398 EventRecord *evp;
399{
Jack Jansena76382a1995-02-02 14:25:56 +0000400#ifdef __MWERKS__
Jack Jansen38e97661995-11-10 14:53:00 +0000401 {
402 int siouxdidit;
403
404 /* If SIOUX wants it we're done */
405 siouxdidit = SIOUXHandleOneEvent(evp);
406 if ( siouxdidit )
407 return;
408 }
Jack Jansena76382a1995-02-02 14:25:56 +0000409#else
Jack Jansen0c968871997-08-26 13:20:34 +0000410 /* Other compilers are just unlucky... */
Jack Jansena76382a1995-02-02 14:25:56 +0000411#endif /* !__MWERKS__ */
Jack Jansen36ed5061997-06-20 16:18:15 +0000412}
413
414/*
415** Handle an event, either through HandleEvent or by passing it to the Python
416** event handler.
417*/
418int
419PyMac_HandleEvent(evp)
420 EventRecord *evp;
421{
422 PyObject *rv;
423
424 if ( python_event_handler ) {
425 rv = PyObject_CallFunction(python_event_handler, "(O&)",
426 PyMac_BuildEventRecord, evp);
427 if ( rv )
428 Py_DECREF(rv);
429 else
430 return -1; /* Propagate exception */
431 } else {
432 PyMac_HandleEventIntern(evp);
433 }
434 return 0;
Jack Jansena76382a1995-02-02 14:25:56 +0000435}
436
Jack Jansen0194ad52001-05-12 22:46:35 +0000437#if !TARGET_API_MAC_OSX
Jack Jansena76382a1995-02-02 14:25:56 +0000438/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000439** Yield the CPU to other tasks without processing events.
Jack Jansene8e8ae01995-01-26 16:36:45 +0000440*/
Jack Jansen2d1306b2000-04-07 09:10:49 +0000441int
Jack Jansene3ae0df1997-06-03 15:28:29 +0000442PyMac_DoYield(int maxsleep, int maycallpython)
Jack Jansenf93c72a1994-12-14 14:07:50 +0000443{
444 EventRecord ev;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000445 int gotone;
Jack Jansene3ae0df1997-06-03 15:28:29 +0000446 long latest_time_ready;
Jack Jansen36ed5061997-06-20 16:18:15 +0000447 static int in_here = 0;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000448
Jack Jansen36ed5061997-06-20 16:18:15 +0000449 in_here++;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000450
Jack Jansene3ae0df1997-06-03 15:28:29 +0000451 /*
452 ** Check which of the eventloop cases we have:
453 ** - process events
454 ** - don't process events but do yield
455 ** - do neither
456 */
Jack Jansen36ed5061997-06-20 16:18:15 +0000457 if( in_here > 1 || !schedparams.process_events ||
458 (python_event_handler && !maycallpython) ) {
Jack Jansene3ae0df1997-06-03 15:28:29 +0000459 if ( maxsleep >= 0 ) {
Jack Jansen6c7e3262002-12-12 10:31:54 +0000460 /* XXXX Need to do something here */
Jack Jansen15f1c082001-04-25 22:07:27 +0000461 }
Jack Jansene3ae0df1997-06-03 15:28:29 +0000462 } else {
Jack Jansen6c7e3262002-12-12 10:31:54 +0000463 latest_time_ready = TickCount() + maxsleep;
Jack Jansen2d1306b2000-04-07 09:10:49 +0000464 do {
Jack Jansen0c968871997-08-26 13:20:34 +0000465 /* XXXX Hack by Jack.
466 ** In time.sleep() you can click to another application
467 ** once only. If you come back to Python you cannot get away
468 ** again.
469 **/
Jack Jansen36ed5061997-06-20 16:18:15 +0000470 gotone = WaitNextEvent(schedparams.process_events, &ev, maxsleep, NULL);
Jack Jansene3ae0df1997-06-03 15:28:29 +0000471 /* Get out quickly if nothing interesting is happening */
472 if ( !gotone || ev.what == nullEvent )
473 break;
Jack Jansen36ed5061997-06-20 16:18:15 +0000474 if ( PyMac_HandleEvent(&ev) < 0 ) {
475 in_here--;
476 return -1;
477 }
Jack Jansen6c7e3262002-12-12 10:31:54 +0000478 maxsleep = latest_time_ready - TickCount();
Jack Jansen2d1306b2000-04-07 09:10:49 +0000479 } while ( maxsleep > 0 );
Jack Jansenf93c72a1994-12-14 14:07:50 +0000480 }
Jack Jansen36ed5061997-06-20 16:18:15 +0000481 in_here--;
482 return 0;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000483}
484
485/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000486** Process events and/or yield the CPU to other tasks if opportune
Jack Jansene8e8ae01995-01-26 16:36:45 +0000487*/
Jack Jansen36ed5061997-06-20 16:18:15 +0000488int
Jack Jansene8e8ae01995-01-26 16:36:45 +0000489PyMac_Yield() {
Jack Jansene3ae0df1997-06-03 15:28:29 +0000490 unsigned long maxsleep;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000491
Jack Jansene3ae0df1997-06-03 15:28:29 +0000492 if( PyMac_InForeground() )
493 maxsleep = 0;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000494 else
Jack Jansene3ae0df1997-06-03 15:28:29 +0000495 maxsleep = schedparams.bg_yield;
496
Jack Jansen36ed5061997-06-20 16:18:15 +0000497 return PyMac_DoYield(maxsleep, 1);
Jack Jansene8e8ae01995-01-26 16:36:45 +0000498}
499
500/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000501** Return current scheduler parameters
Jack Jansene8e8ae01995-01-26 16:36:45 +0000502*/
Jack Jansene3ae0df1997-06-03 15:28:29 +0000503void
504PyMac_GetSchedParams(PyMacSchedParams *sp)
Jack Jansene8e8ae01995-01-26 16:36:45 +0000505{
Jack Jansene3ae0df1997-06-03 15:28:29 +0000506 sp->check_interrupt = schedparams.check_interrupt;
507 sp->process_events = schedparams.process_events;
508 sp->besocial = schedparams.besocial;
509 sp->check_interval = schedparams.check_interval / 60.0;
510 sp->bg_yield = schedparams.bg_yield / 60.0;
Jack Jansenf93c72a1994-12-14 14:07:50 +0000511}
Jack Jansenf6865f71996-09-04 15:24:59 +0000512
Jack Jansen74162f31995-02-15 22:58:33 +0000513/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000514** Set current scheduler parameters
515*/
516void
517PyMac_SetSchedParams(PyMacSchedParams *sp)
518{
519 schedparams.check_interrupt = sp->check_interrupt;
520 schedparams.process_events = sp->process_events;
521 schedparams.besocial = sp->besocial;
522 schedparams.check_interval = (unsigned long)(sp->check_interval*60);
523 schedparams.bg_yield = (unsigned long)(sp->bg_yield*60);
524 if ( schedparams.check_interrupt || schedparams.process_events ||
525 schedparams.besocial )
526 schedparams.enabled = 1;
527 else
528 schedparams.enabled = 0;
529 schedparams.next_check = 0; /* Check immedeately */
530}
Jack Jansencaa7c461997-06-12 10:49:13 +0000531
Jack Jansene3ae0df1997-06-03 15:28:29 +0000532/*
Jack Jansen3469e991996-09-06 00:30:45 +0000533** Install our menu bar.
534*/
535void
536PyMac_InitMenuBar()
537{
Jack Jansen3469e991996-09-06 00:30:45 +0000538 MenuHandle applemenu;
Jack Jansen52306a72001-12-10 16:08:14 +0000539 Str255 about_text;
540 static unsigned char about_sioux[] = "\pAbout SIOUX";
Jack Jansen3469e991996-09-06 00:30:45 +0000541
Jack Jansen15f1c082001-04-25 22:07:27 +0000542 if ( sioux_mbar ) return;
Jack Jansenb3be2162001-11-30 14:16:36 +0000543 if ( (sioux_mbar=GetMenuBar()) == NULL || GetMenuHandle(SIOUX_APPLEID) == NULL) {
Jack Jansencaa7c461997-06-12 10:49:13 +0000544 /* Sioux menu not installed yet. Do so */
545 SIOUXSetupMenus();
546 if ( (sioux_mbar=GetMenuBar()) == NULL )
547 return;
548 }
Jack Jansen08c3be31997-04-08 15:27:00 +0000549 if ( (applemenu=GetMenuHandle(SIOUX_APPLEID)) == NULL ) return;
Jack Jansen52306a72001-12-10 16:08:14 +0000550 GetMenuItemText(applemenu, 1, about_text);
551 if ( about_text[0] == about_sioux[0] &&
552 strncmp((char *)(about_text+1), (char *)(about_sioux+1), about_text[0]) == 0 )
553 SetMenuItemText(applemenu, 1, "\pAbout Python...");
Jack Jansen3469e991996-09-06 00:30:45 +0000554}
555
556/*
Jack Jansencaa7c461997-06-12 10:49:13 +0000557** Restore sioux menu bar
558*/
559void
560PyMac_RestoreMenuBar()
561{
Jack Jansen657ba272001-02-17 22:02:07 +0000562 MenuBarHandle curmenubar;
563
564 curmenubar = GetMenuBar();
Jack Janseneda78631997-06-12 15:29:46 +0000565 if ( sioux_mbar ) {
Jack Jansencaa7c461997-06-12 10:49:13 +0000566 SetMenuBar(sioux_mbar);
Jack Janseneda78631997-06-12 15:29:46 +0000567 DrawMenuBar();
Jack Jansen657ba272001-02-17 22:02:07 +0000568 } else {
Jack Jansenefaada71998-02-20 16:03:15 +0000569 PyMac_InitMenuBar();
Jack Jansen657ba272001-02-17 22:02:07 +0000570 DrawMenuBar();
571 }
Jack Jansencaa7c461997-06-12 10:49:13 +0000572}
573
Jack Jansen15f1c082001-04-25 22:07:27 +0000574void
575PyMac_RaiseConsoleWindow()
576{
577 /* Note: this is a hack. SIOUXTextWindow is SIOUX's internal structure
578 ** and we happen to know that the first entry is the window pointer.
579 */
580 extern WindowRef *SIOUXTextWindow;
581
582 if ( SIOUXTextWindow == NULL || *SIOUXTextWindow == NULL )
583 return;
584 if ( FrontWindow() != *SIOUXTextWindow )
585 BringToFront(*SIOUXTextWindow);
586}
Jack Jansencaa7c461997-06-12 10:49:13 +0000587
588/*
Jack Jansen3469e991996-09-06 00:30:45 +0000589** Our replacement about box
590*/
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000591
592#include "patchlevel.h"
593
Jack Jansen3469e991996-09-06 00:30:45 +0000594void
595SIOUXDoAboutBox(void)
596{
597 DialogPtr theDialog;
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000598 WindowPtr theWindow;
Jack Jansen3469e991996-09-06 00:30:45 +0000599 short item;
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000600 short fontID;
Jack Jansen3469e991996-09-06 00:30:45 +0000601
602 if( (theDialog = GetNewDialog(ABOUT_ID, NULL, (WindowPtr)-1)) == NULL )
603 return;
Jack Jansend617c571996-09-22 22:14:30 +0000604 theWindow = GetDialogWindow(theDialog);
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000605 SetPortWindowPort(theWindow);
606 GetFNum("\pPython-Sans", &fontID);
607 if (fontID == 0)
608 fontID = kFontIDGeneva;
609 TextFont(fontID);
610 TextSize(9);
Jack Jansenf60edf82001-08-19 22:32:27 +0000611 ParamText(Pstring(PY_VERSION), "\p", "\p", "\p");
Jack Jansend617c571996-09-22 22:14:30 +0000612 ShowWindow(theWindow);
Jack Jansen3469e991996-09-06 00:30:45 +0000613 ModalDialog(NULL, &item);
614 DisposeDialog(theDialog);
615}
616
Jack Jansen0194ad52001-05-12 22:46:35 +0000617#endif /* !TARGET_API_MAC_OSX */