blob: 51d73edb64508f53bf2705e1db5dd295ae66c801 [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 Jansenee23d6e1995-01-27 14:43:25 +0000286/* The catcher routine (which may not be used for all compilers) */
287static RETSIGTYPE
288intcatcher(sig)
289 int sig;
290{
291 interrupted = 1;
292 signal(SIGINT, intcatcher);
293}
294
295void
296PyOS_InitInterrupts()
297{
298 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
299 signal(SIGINT, intcatcher);
300}
301
Jack Jansena8441de1997-08-08 14:57:37 +0000302void
303PyOS_FiniInterrupts()
304{
305}
306
Jack Jansenee23d6e1995-01-27 14:43:25 +0000307/* Check whether we are in the foreground */
Jack Jansen9ae898b2000-07-11 21:16:03 +0000308static int
309PyMac_InForeground(void)
Jack Jansenee23d6e1995-01-27 14:43:25 +0000310{
311 static ProcessSerialNumber ours;
312 static inited;
313 ProcessSerialNumber curfg;
314 Boolean eq;
315
Jack Jansene3ae0df1997-06-03 15:28:29 +0000316 if ( inited == 0 ) {
Jack Jansenee23d6e1995-01-27 14:43:25 +0000317 (void)GetCurrentProcess(&ours);
Jack Jansene3ae0df1997-06-03 15:28:29 +0000318 inited = 1;
319 }
Jack Jansenee23d6e1995-01-27 14:43:25 +0000320 if ( GetFrontProcess(&curfg) < 0 )
321 eq = 1;
322 else if ( SameProcess(&ours, &curfg, &eq) < 0 )
323 eq = 1;
324 return (int)eq;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000325}
Jack Jansen439eaa92001-11-10 00:41:43 +0000326
327/*
328** This routine scans the event queue looking for cmd-.
329*/
330static void
331scan_event_queue(force)
332 int force;
333{
Jack Jansen439eaa92001-11-10 00:41:43 +0000334 if ( interrupted || (!schedparams.check_interrupt && !force) )
335 return;
336 if ( CheckEventQueueForUserCancel() )
337 interrupted = 1;
Jack Jansen439eaa92001-11-10 00:41:43 +0000338}
339
340int
341PyErr_CheckSignals()
342{
Jack Jansen439eaa92001-11-10 00:41:43 +0000343 if (schedparams.enabled) {
Jack Jansen6c7e3262002-12-12 10:31:54 +0000344 if ( interrupted || (unsigned long)TickCount() > schedparams.next_check ) {
Jack Jansen439eaa92001-11-10 00:41:43 +0000345 scan_event_queue(0);
346 if (interrupted) {
347 interrupted = 0;
348 PyErr_SetNone(PyExc_KeyboardInterrupt);
349 return -1;
350 }
351 if ( PyMac_Yield() < 0)
352 return -1;
Jack Jansen6c7e3262002-12-12 10:31:54 +0000353 schedparams.next_check = (unsigned long)TickCount()
Jack Jansen439eaa92001-11-10 00:41:43 +0000354 + schedparams.check_interval;
355 }
356 }
357 return 0;
358}
359
360int
361PyOS_InterruptOccurred()
362{
363 scan_event_queue(0);
364 if ( !interrupted )
365 return 0;
366 interrupted = 0;
367 return 1;
368}
Jack Jansen0194ad52001-05-12 22:46:35 +0000369#endif
Jack Jansenee23d6e1995-01-27 14:43:25 +0000370
Jack Jansen36ed5061997-06-20 16:18:15 +0000371int
372PyMac_SetEventHandler(PyObject *evh)
373{
374 if ( evh && python_event_handler ) {
375 PyErr_SetString(PyExc_RuntimeError, "Python event handler already set");
376 return 0;
377 }
378 if ( python_event_handler )
379 Py_DECREF(python_event_handler);
380 if ( evh )
381 Py_INCREF(evh);
382 python_event_handler = evh;
383 return 1;
384}
385
Jack Jansenf93c72a1994-12-14 14:07:50 +0000386/*
Jack Jansena76382a1995-02-02 14:25:56 +0000387** Handle an event, either one found in the mainloop eventhandler or
388** one passed back from the python program.
389*/
390void
Jack Jansen36ed5061997-06-20 16:18:15 +0000391PyMac_HandleEventIntern(evp)
Jack Jansena76382a1995-02-02 14:25:56 +0000392 EventRecord *evp;
393{
Jack Jansena76382a1995-02-02 14:25:56 +0000394#ifdef __MWERKS__
Jack Jansen38e97661995-11-10 14:53:00 +0000395 {
396 int siouxdidit;
397
398 /* If SIOUX wants it we're done */
399 siouxdidit = SIOUXHandleOneEvent(evp);
400 if ( siouxdidit )
401 return;
402 }
Jack Jansena76382a1995-02-02 14:25:56 +0000403#else
Jack Jansen0c968871997-08-26 13:20:34 +0000404 /* Other compilers are just unlucky... */
Jack Jansena76382a1995-02-02 14:25:56 +0000405#endif /* !__MWERKS__ */
Jack Jansen36ed5061997-06-20 16:18:15 +0000406}
407
408/*
409** Handle an event, either through HandleEvent or by passing it to the Python
410** event handler.
411*/
412int
413PyMac_HandleEvent(evp)
414 EventRecord *evp;
415{
416 PyObject *rv;
417
418 if ( python_event_handler ) {
419 rv = PyObject_CallFunction(python_event_handler, "(O&)",
420 PyMac_BuildEventRecord, evp);
421 if ( rv )
422 Py_DECREF(rv);
423 else
424 return -1; /* Propagate exception */
425 } else {
426 PyMac_HandleEventIntern(evp);
427 }
428 return 0;
Jack Jansena76382a1995-02-02 14:25:56 +0000429}
430
Jack Jansen0194ad52001-05-12 22:46:35 +0000431#if !TARGET_API_MAC_OSX
Jack Jansena76382a1995-02-02 14:25:56 +0000432/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000433** Yield the CPU to other tasks without processing events.
Jack Jansene8e8ae01995-01-26 16:36:45 +0000434*/
Jack Jansen2d1306b2000-04-07 09:10:49 +0000435int
Jack Jansene3ae0df1997-06-03 15:28:29 +0000436PyMac_DoYield(int maxsleep, int maycallpython)
Jack Jansenf93c72a1994-12-14 14:07:50 +0000437{
438 EventRecord ev;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000439 int gotone;
Jack Jansene3ae0df1997-06-03 15:28:29 +0000440 long latest_time_ready;
Jack Jansen36ed5061997-06-20 16:18:15 +0000441 static int in_here = 0;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000442
Jack Jansen36ed5061997-06-20 16:18:15 +0000443 in_here++;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000444
Jack Jansene3ae0df1997-06-03 15:28:29 +0000445 /*
446 ** Check which of the eventloop cases we have:
447 ** - process events
448 ** - don't process events but do yield
449 ** - do neither
450 */
Jack Jansen36ed5061997-06-20 16:18:15 +0000451 if( in_here > 1 || !schedparams.process_events ||
452 (python_event_handler && !maycallpython) ) {
Jack Jansene3ae0df1997-06-03 15:28:29 +0000453 if ( maxsleep >= 0 ) {
Jack Jansen6c7e3262002-12-12 10:31:54 +0000454 /* XXXX Need to do something here */
Jack Jansen15f1c082001-04-25 22:07:27 +0000455 }
Jack Jansene3ae0df1997-06-03 15:28:29 +0000456 } else {
Jack Jansen6c7e3262002-12-12 10:31:54 +0000457 latest_time_ready = TickCount() + maxsleep;
Jack Jansen2d1306b2000-04-07 09:10:49 +0000458 do {
Jack Jansen0c968871997-08-26 13:20:34 +0000459 /* XXXX Hack by Jack.
460 ** In time.sleep() you can click to another application
461 ** once only. If you come back to Python you cannot get away
462 ** again.
463 **/
Jack Jansen36ed5061997-06-20 16:18:15 +0000464 gotone = WaitNextEvent(schedparams.process_events, &ev, maxsleep, NULL);
Jack Jansene3ae0df1997-06-03 15:28:29 +0000465 /* Get out quickly if nothing interesting is happening */
466 if ( !gotone || ev.what == nullEvent )
467 break;
Jack Jansen36ed5061997-06-20 16:18:15 +0000468 if ( PyMac_HandleEvent(&ev) < 0 ) {
469 in_here--;
470 return -1;
471 }
Jack Jansen6c7e3262002-12-12 10:31:54 +0000472 maxsleep = latest_time_ready - TickCount();
Jack Jansen2d1306b2000-04-07 09:10:49 +0000473 } while ( maxsleep > 0 );
Jack Jansenf93c72a1994-12-14 14:07:50 +0000474 }
Jack Jansen36ed5061997-06-20 16:18:15 +0000475 in_here--;
476 return 0;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000477}
478
479/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000480** Process events and/or yield the CPU to other tasks if opportune
Jack Jansene8e8ae01995-01-26 16:36:45 +0000481*/
Jack Jansen36ed5061997-06-20 16:18:15 +0000482int
Jack Jansene8e8ae01995-01-26 16:36:45 +0000483PyMac_Yield() {
Jack Jansene3ae0df1997-06-03 15:28:29 +0000484 unsigned long maxsleep;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000485
Jack Jansene3ae0df1997-06-03 15:28:29 +0000486 if( PyMac_InForeground() )
487 maxsleep = 0;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000488 else
Jack Jansene3ae0df1997-06-03 15:28:29 +0000489 maxsleep = schedparams.bg_yield;
490
Jack Jansen36ed5061997-06-20 16:18:15 +0000491 return PyMac_DoYield(maxsleep, 1);
Jack Jansene8e8ae01995-01-26 16:36:45 +0000492}
493
494/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000495** Return current scheduler parameters
Jack Jansene8e8ae01995-01-26 16:36:45 +0000496*/
Jack Jansene3ae0df1997-06-03 15:28:29 +0000497void
498PyMac_GetSchedParams(PyMacSchedParams *sp)
Jack Jansene8e8ae01995-01-26 16:36:45 +0000499{
Jack Jansene3ae0df1997-06-03 15:28:29 +0000500 sp->check_interrupt = schedparams.check_interrupt;
501 sp->process_events = schedparams.process_events;
502 sp->besocial = schedparams.besocial;
503 sp->check_interval = schedparams.check_interval / 60.0;
504 sp->bg_yield = schedparams.bg_yield / 60.0;
Jack Jansenf93c72a1994-12-14 14:07:50 +0000505}
Jack Jansenf6865f71996-09-04 15:24:59 +0000506
Jack Jansen74162f31995-02-15 22:58:33 +0000507/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000508** Set current scheduler parameters
509*/
510void
511PyMac_SetSchedParams(PyMacSchedParams *sp)
512{
513 schedparams.check_interrupt = sp->check_interrupt;
514 schedparams.process_events = sp->process_events;
515 schedparams.besocial = sp->besocial;
516 schedparams.check_interval = (unsigned long)(sp->check_interval*60);
517 schedparams.bg_yield = (unsigned long)(sp->bg_yield*60);
518 if ( schedparams.check_interrupt || schedparams.process_events ||
519 schedparams.besocial )
520 schedparams.enabled = 1;
521 else
522 schedparams.enabled = 0;
523 schedparams.next_check = 0; /* Check immedeately */
524}
Jack Jansencaa7c461997-06-12 10:49:13 +0000525
Jack Jansene3ae0df1997-06-03 15:28:29 +0000526/*
Jack Jansen3469e991996-09-06 00:30:45 +0000527** Install our menu bar.
528*/
529void
530PyMac_InitMenuBar()
531{
Jack Jansen3469e991996-09-06 00:30:45 +0000532 MenuHandle applemenu;
Jack Jansen52306a72001-12-10 16:08:14 +0000533 Str255 about_text;
534 static unsigned char about_sioux[] = "\pAbout SIOUX";
Jack Jansen3469e991996-09-06 00:30:45 +0000535
Jack Jansen15f1c082001-04-25 22:07:27 +0000536 if ( sioux_mbar ) return;
Jack Jansenb3be2162001-11-30 14:16:36 +0000537 if ( (sioux_mbar=GetMenuBar()) == NULL || GetMenuHandle(SIOUX_APPLEID) == NULL) {
Jack Jansencaa7c461997-06-12 10:49:13 +0000538 /* Sioux menu not installed yet. Do so */
539 SIOUXSetupMenus();
540 if ( (sioux_mbar=GetMenuBar()) == NULL )
541 return;
542 }
Jack Jansen08c3be31997-04-08 15:27:00 +0000543 if ( (applemenu=GetMenuHandle(SIOUX_APPLEID)) == NULL ) return;
Jack Jansen52306a72001-12-10 16:08:14 +0000544 GetMenuItemText(applemenu, 1, about_text);
545 if ( about_text[0] == about_sioux[0] &&
546 strncmp((char *)(about_text+1), (char *)(about_sioux+1), about_text[0]) == 0 )
547 SetMenuItemText(applemenu, 1, "\pAbout Python...");
Jack Jansen3469e991996-09-06 00:30:45 +0000548}
549
550/*
Jack Jansencaa7c461997-06-12 10:49:13 +0000551** Restore sioux menu bar
552*/
553void
554PyMac_RestoreMenuBar()
555{
Jack Jansen657ba272001-02-17 22:02:07 +0000556 MenuBarHandle curmenubar;
557
558 curmenubar = GetMenuBar();
Jack Janseneda78631997-06-12 15:29:46 +0000559 if ( sioux_mbar ) {
Jack Jansencaa7c461997-06-12 10:49:13 +0000560 SetMenuBar(sioux_mbar);
Jack Janseneda78631997-06-12 15:29:46 +0000561 DrawMenuBar();
Jack Jansen657ba272001-02-17 22:02:07 +0000562 } else {
Jack Jansenefaada71998-02-20 16:03:15 +0000563 PyMac_InitMenuBar();
Jack Jansen657ba272001-02-17 22:02:07 +0000564 DrawMenuBar();
565 }
Jack Jansencaa7c461997-06-12 10:49:13 +0000566}
567
Jack Jansen15f1c082001-04-25 22:07:27 +0000568void
569PyMac_RaiseConsoleWindow()
570{
571 /* Note: this is a hack. SIOUXTextWindow is SIOUX's internal structure
572 ** and we happen to know that the first entry is the window pointer.
573 */
574 extern WindowRef *SIOUXTextWindow;
575
576 if ( SIOUXTextWindow == NULL || *SIOUXTextWindow == NULL )
577 return;
578 if ( FrontWindow() != *SIOUXTextWindow )
579 BringToFront(*SIOUXTextWindow);
580}
Jack Jansencaa7c461997-06-12 10:49:13 +0000581
582/*
Jack Jansen3469e991996-09-06 00:30:45 +0000583** Our replacement about box
584*/
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000585
586#include "patchlevel.h"
587
Jack Jansen3469e991996-09-06 00:30:45 +0000588void
589SIOUXDoAboutBox(void)
590{
591 DialogPtr theDialog;
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000592 WindowPtr theWindow;
Jack Jansen3469e991996-09-06 00:30:45 +0000593 short item;
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000594 short fontID;
Jack Jansen3469e991996-09-06 00:30:45 +0000595
596 if( (theDialog = GetNewDialog(ABOUT_ID, NULL, (WindowPtr)-1)) == NULL )
597 return;
Jack Jansend617c571996-09-22 22:14:30 +0000598 theWindow = GetDialogWindow(theDialog);
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000599 SetPortWindowPort(theWindow);
600 GetFNum("\pPython-Sans", &fontID);
601 if (fontID == 0)
602 fontID = kFontIDGeneva;
603 TextFont(fontID);
604 TextSize(9);
Jack Jansenf60edf82001-08-19 22:32:27 +0000605 ParamText(Pstring(PY_VERSION), "\p", "\p", "\p");
Jack Jansend617c571996-09-22 22:14:30 +0000606 ShowWindow(theWindow);
Jack Jansen3469e991996-09-06 00:30:45 +0000607 ModalDialog(NULL, &item);
608 DisposeDialog(theDialog);
609}
610
Jack Jansen0194ad52001-05-12 22:46:35 +0000611#endif /* !TARGET_API_MAC_OSX */