summaryrefslogtreecommitdiffstats
path: root/Mac/Python/macglue.c
diff options
context:
space:
mode:
Diffstat (limited to 'Mac/Python/macglue.c')
-rw-r--r--Mac/Python/macglue.c216
1 files changed, 116 insertions, 100 deletions
diff --git a/Mac/Python/macglue.c b/Mac/Python/macglue.c
index 480b741..5d7c2c7 100644
--- a/Mac/Python/macglue.c
+++ b/Mac/Python/macglue.c
@@ -70,13 +70,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* The ID of the Sioux apple menu */
#define SIOUX_APPLEID 32000
-#ifndef HAVE_UNIVERSAL_HEADERS
-#define GetResourceSizeOnDisk(x) SizeResource(x)
-typedef DlgHookYDProcPtr DlgHookYDUPP;
-#define NewDlgHookYDProc(userRoutine) ((DlgHookYDUPP) (userRoutine))
-typedef FileFilterYDProcPtr FileFilterYDUPP;
-#endif
-
#include <signal.h>
#include <stdio.h>
@@ -113,8 +106,29 @@ extern FSSpec *mfs_GetFSSpecFSSpec();
static int interrupted; /* Set to true when cmd-. seen */
static RETSIGTYPE intcatcher Py_PROTO((int));
-static void PyMac_DoYield Py_PROTO((int));
+static void PyMac_DoYield Py_PROTO((int, int));
+
+/*
+** These are the real scheduling parameters that control what we check
+** in the event loop, and how often we check. The values are initialized
+** from pyMac_SchedParamStruct.
+*/
+
+struct real_sched_param_struct {
+ int check_interrupt; /* if true check for command-dot */
+ int process_events; /* if nonzero enable evt processing, this mask */
+ int besocial; /* if nonzero be a little social with CPU */
+ unsigned long check_interval; /* how often to check, in ticks */
+ unsigned long bg_yield; /* yield so long when in background */
+ /* these are computed from previous and clock and such */
+ int enabled; /* check_interrupt OR process_event OR yield */
+ unsigned long next_check; /* when to check/yield next, in ticks */
+};
+
+static struct real_sched_param_struct schedparams =
+ { 1, MAINLOOP_EVENTMASK, 1, 15, 15, 1, 0};
+#if 0
/*
** We attempt to be a good citizen by giving up the CPU periodically.
** When in the foreground we do this less often and for shorter periods
@@ -129,7 +143,7 @@ static long interval_fg = 12;
static long interval_bg = 6;
static long yield_fg = 1;
static long yield_bg = 2;
-static long lastyield;
+static unsigned long lastyield;
static int in_foreground;
/*
@@ -138,6 +152,7 @@ static int in_foreground;
** when < 0, don't do any event scanning
*/
int PyMac_DoYieldEnabled = 1;
+#endif
/*
** Workaround for sioux/gusi combo: set when we are exiting
@@ -189,8 +204,8 @@ void SpinCursor(short x) { /* Dummy */ }
static int
PyMac_GUSISpin(spin_msg msg, long arg)
{
- static Boolean inForeground = true;
- int maysleep;
+ static Boolean inForeground = true;
+ int maxsleep = 6; /* 6 ticks is "normal" sleeptime */
if (PyMac_ConsoleIsDead) return 0;
#if 0
@@ -200,12 +215,12 @@ PyMac_GUSISpin(spin_msg msg, long arg)
if (interrupted) return -1;
- if ( msg == SP_AUTO_SPIN || ((msg==SP_SLEEP||msg==SP_SELECT) && arg <= yield_fg))
- maysleep = 0;
- else
- maysleep = 0;
+ if ( msg == SP_AUTO_SPIN )
+ maxsleep = 0;
+ if ( msg==SP_SLEEP||msg==SP_SELECT )
+ maxsleep = arg;
- PyMac_DoYield(maysleep);
+ PyMac_DoYield(maxsleep, 0); /* XXXX or is it safe to call python here? */
return 0;
}
@@ -405,26 +420,22 @@ scan_event_queue(flush)
int
PyOS_InterruptOccurred()
{
- static unsigned long nextticktime;
- unsigned long curticktime;
-
- if (PyMac_DoYieldEnabled < 0)
- return 0;
- curticktime = (unsigned long)LMGetTicks();
- if ( curticktime < nextticktime )
- return 0;
- nextticktime = curticktime + TICKCOUNT;
-#ifdef THINK_C
- scan_event_queue(1);
-#endif
- PyMac_Yield();
- if (interrupted) {
- interrupted = 0;
- return 1;
+ if (schedparams.enabled) {
+ if ( (unsigned long)LMGetTicks() > schedparams.next_check ) {
+ PyMac_Yield();
+ schedparams.next_check = (unsigned long)LMGetTicks()
+ + schedparams.check_interval;
+ if (interrupted) {
+ interrupted = 0;
+ return 1;
+ }
+ }
}
return 0;
}
+#if 0
+
/* intrpeek() is like intrcheck(), but it doesn't flush the events. The
** idea is that you call intrpeek() somewhere in a busy-wait loop, and return
** None as soon as it returns 1. The mainloop will then pick up the cmd-. soon
@@ -438,6 +449,7 @@ intrpeek()
#endif
return interrupted;
}
+#endif
/* Check whether we are in the foreground */
int
@@ -448,9 +460,10 @@ PyMac_InForeground()
ProcessSerialNumber curfg;
Boolean eq;
- if ( inited == 0 )
+ if ( inited == 0 ) {
(void)GetCurrentProcess(&ours);
- inited = 1;
+ inited = 1;
+ }
if ( GetFrontProcess(&curfg) < 0 )
eq = 1;
else if ( SameProcess(&ours, &curfg, &eq) < 0 )
@@ -460,26 +473,18 @@ PyMac_InForeground()
}
/*
-** Set yield timeouts
-*/
-void
-PyMac_SetYield(long fgi, long fgy, long bgi, long bgy)
-{
- interval_fg = fgi;
- yield_fg = fgy;
- interval_bg = bgi;
- yield_bg = bgy;
-}
-
-/*
** Handle an event, either one found in the mainloop eventhandler or
** one passed back from the python program.
*/
void
-PyMac_HandleEvent(evp)
+PyMac_HandleEvent(evp, maycallpython)
EventRecord *evp;
+ int maycallpython;
{
-
+
+ if ( maycallpython ) {
+ /* To be implemented */
+ }
#ifdef __MWERKS__
{
int siouxdidit;
@@ -503,84 +508,95 @@ PyMac_HandleEvent(evp)
}
/*
-** Yield the CPU to other tasks.
+** Yield the CPU to other tasks without processing events.
*/
static void
-PyMac_DoYield(int maysleep)
+PyMac_DoYield(int maxsleep, int maycallpython)
{
EventRecord ev;
- long yield;
- static int no_waitnextevent = -1;
int gotone;
+ long latest_time_ready;
- if ( no_waitnextevent < 0 ) {
- no_waitnextevent = (NGetTrapAddress(_WaitNextEvent, ToolTrap) ==
- NGetTrapAddress(_Unimplemented, ToolTrap));
- }
-
- lastyield = TickCount();
-#ifndef THINK_C
- /* Under think this has been done before in intrcheck() or intrpeek() */
- if (PyMac_DoYieldEnabled >= 0)
+ /*
+ ** First check for interrupts, if wanted.
+ ** This sets a flag that will be picked up at an appropriate
+ ** moment in the mainloop.
+ */
+ if (schedparams.check_interrupt)
scan_event_queue(0);
-#endif
- if (PyMac_DoYieldEnabled == 0)
- return;
-
- in_foreground = PyMac_InForeground();
- if ( maysleep ) {
- if ( in_foreground )
- yield = yield_fg;
- else
- yield = yield_bg;
- } else {
- yield = 0;
- }
+
+ /* XXXX Implementing an idle routine goes here */
- while ( 1 ) {
- if ( no_waitnextevent ) {
+ /*
+ ** Check which of the eventloop cases we have:
+ ** - process events
+ ** - don't process events but do yield
+ ** - do neither
+ */
+ if( !schedparams.process_events ) {
+ if ( maxsleep >= 0 ) {
SystemTask();
- gotone = GetNextEvent(MAINLOOP_EVENTMASK, &ev);
- } else {
- gotone = WaitNextEvent(MAINLOOP_EVENTMASK, &ev, yield, NULL);
- }
- /* Get out quickly if nothing interesting is happening */
- if ( !gotone || ev.what == nullEvent )
- break;
- PyMac_HandleEvent(&ev);
+ }
+ } else {
+ latest_time_ready = LMGetTicks() + maxsleep;
+ while ( maxsleep >= 0 ) {
+ gotone = WaitNextEvent(schedparams.process_events, &ev, 0 /*maxsleep*/, NULL);
+ /* Get out quickly if nothing interesting is happening */
+ if ( !gotone || ev.what == nullEvent )
+ break;
+ PyMac_HandleEvent(&ev, maycallpython);
+ maxsleep = latest_time_ready - LMGetTicks();
+ }
}
}
/*
-** Yield the CPU to other tasks if opportune
+** Process events and/or yield the CPU to other tasks if opportune
*/
void
PyMac_Yield() {
- long iv;
+ unsigned long maxsleep;
- if ( in_foreground )
- iv = interval_fg;
+ if( PyMac_InForeground() )
+ maxsleep = 0;
else
- iv = interval_bg;
- if ( TickCount() > lastyield + iv )
- PyMac_DoYield(1);
+ maxsleep = schedparams.bg_yield;
+
+ PyMac_DoYield(maxsleep, 1);
}
-#ifdef USE_MACTCP
/*
-** Idle routine for busy-wait loops.
-** Gives up CPU, handles events and returns true if an interrupt is pending
-** (but not actually handled yet).
+** Return current scheduler parameters
*/
-int
-PyMac_Idle()
+void
+PyMac_GetSchedParams(PyMacSchedParams *sp)
{
- PyMac_DoYield(1);
- return intrpeek();
+ sp->check_interrupt = schedparams.check_interrupt;
+ sp->process_events = schedparams.process_events;
+ sp->besocial = schedparams.besocial;
+ sp->check_interval = schedparams.check_interval / 60.0;
+ sp->bg_yield = schedparams.bg_yield / 60.0;
}
-#endif
/*
+** Set current scheduler parameters
+*/
+void
+PyMac_SetSchedParams(PyMacSchedParams *sp)
+{
+ schedparams.check_interrupt = sp->check_interrupt;
+ schedparams.process_events = sp->process_events;
+ schedparams.besocial = sp->besocial;
+ schedparams.check_interval = (unsigned long)(sp->check_interval*60);
+ schedparams.bg_yield = (unsigned long)(sp->bg_yield*60);
+ if ( schedparams.check_interrupt || schedparams.process_events ||
+ schedparams.besocial )
+ schedparams.enabled = 1;
+ else
+ schedparams.enabled = 0;
+ schedparams.next_check = 0; /* Check immedeately */
+}
+/*
** Install our menu bar.
*/
void