]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Added eventhandling in mainloop/busywait routine plus leaving some
authorJack Jansen <jack.jansen@cwi.nl>
Thu, 26 Jan 1995 16:36:45 +0000 (16:36 +0000)
committerJack Jansen <jack.jansen@cwi.nl>
Thu, 26 Jan 1995 16:36:45 +0000 (16:36 +0000)
cycles for background apps. MacOS has a new method to set the amount
of time for bg apps.

Mac/Modules/macosmodule.c
Mac/Python/macglue.c

index 7fb069c21a68e1153307516e827197e22079fe55..6c274e84260a90a05e4aefa286c500d684855653 100644 (file)
@@ -107,6 +107,8 @@ MacOS_HighLevelEventProc(EventRecord *e)
        }
 }
 
+/* XXXX Need to come here from PyMac_DoYield too... */
+
 static PyObject *
 MacOS_SetHighLevelEventHandler(self, args)
        PyObject *self;
@@ -166,6 +168,26 @@ MacOS_AcceptHighLevelEvent(self, args)
        return res;
 }
 
+/*
+** Set poll frequency and cpu-yield-time
+*/
+static PyObject *
+MacOS_SetScheduleTimes(PyObject *self, PyObject *args)
+{
+       long fgi, fgy, bgi, bgy;
+       
+       bgi = bgy = -2; 
+       if (!PyArg_ParseTuple(args, "ll|ll", &fgi, &fgy, &bgi, &bgy))
+               return NULL;
+       if ( bgi == -2 ) {
+               bgi = fgi;
+               bgy = fgy;
+       }
+       PyMac_SetYield(fgi, fgy, bgi, bgy);
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
 static PyMethodDef MacOS_Methods[] = {
        {"AcceptHighLevelEvent",        MacOS_AcceptHighLevelEvent, 1},
        {"GetCreatorAndType",           MacOS_GetCreatorAndType, 1},
@@ -173,6 +195,7 @@ static PyMethodDef MacOS_Methods[] = {
 #ifdef USE_STDWIN
        {"SetHighLevelEventHandler",    MacOS_SetHighLevelEventHandler, 1},
 #endif
+       {"SetScheduleTimes",    MacOS_SetScheduleTimes, 1},
        {NULL,                          NULL}            /* Sentinel */
 };
 
index f70ca60aad0fa3a1cd90d55193aae4aa7cb3db13..b4a5fbd63a11fe1d2862facc96ccfa87dc8ef014 100644 (file)
@@ -26,16 +26,43 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "macglue.h"
 
 #include <OSUtils.h> /* for Set(Current)A5 */
+#include <Files.h>
 #include <Resources.h>
 #include <Memory.h>
 #include <Events.h>
 #include <Windows.h>
 #include <Desk.h>
+#include <Traps.h>
+
+#ifdef __MWERKS__
+#include <SIOUX.h>
+#endif /* __MWERKS__ */
+
+#include <signal.h>
 
 /* XXX We should include Errors.h here, but it has a name conflict
 ** with the python errors.h. */
 #define fnfErr -43
 
+/* Declared in macfsmodule.c: */
+extern FSSpec *mfs_GetFSSpecFSSpec();
+
+/*
+** 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
+** than when in the background. At this time we also check for events and
+** pass them off to stdwin (or SIOUX, if compiling with mwerks).
+** The counts here are in ticks of 1/60th second.
+** XXXX The initial values here are not based on anything.
+** FG-python gives up the cpu for 1/60th 5 times per second,
+** BG-python for .2 second 10 times per second.
+*/
+static long interval_fg = 12;
+static long interval_bg = 6;
+static long yield_fg = 1;
+static long yield_bg = 12;
+static long lastyield, in_background;
+
 /* Convert C to Pascal string. Returns pointer to static buffer. */
 unsigned char *
 Pstring(char *str)
@@ -111,28 +138,101 @@ PyMac_Error(OSErr err)
 }
 
 /*
-** Idle routine for busy-wait loops.
-** This is rather tricky: if we see an event we check whether it is
-** for somebody else (i.e. a click outside our windows) and, if so,
-** we pass the event on (so the user can switch processes). However,
-** by doing this we loose events meant for our windows. Too bad, I guess...
+** Set yield timeouts
 */
-int
-PyMac_Idle()
+void
+PyMac_SetYield(long fgi, long fgy, long bgi, long bgy)
+{
+       interval_fg = fgi;
+       yield_fg = fgy;
+       interval_bg = bgi;
+       yield_bg = bgy;
+}
+
+/*
+** Yield the CPU to other tasks.
+*/
+static
+PyMac_DoYield()
 {
        EventRecord ev;
        WindowPtr wp;
+       long yield;
+       extern int StdwinIsActive;
+       static int no_waitnextevent = -1;
+       int gotone;
+       
+       if ( no_waitnextevent < 0 ) {
+               no_waitnextevent = (NGetTrapAddress(_WaitNextEvent, ToolTrap) ==
+                                                       NGetTrapAddress(_Unimplemented, ToolTrap));
+       }
 
-       SystemTask();
-       if ( intrpeek() )
-               return 0;
-       if ( GetNextEvent(0xffff, &ev) ) {
+       if ( StdwinIsActive )
+               return;
+               
+       if ( in_background )
+               yield = yield_bg;
+       else
+               yield = yield_fg;
+       while ( 1 ) {
+               if ( no_waitnextevent ) {
+                       SystemTask();
+                       gotone = GetNextEvent(0xffff, &ev);
+               } else {
+                       gotone = WaitNextEvent(everyEvent, &ev, yield, NULL);
+               }       
+               /* Get out quickly if nothing interesting is happening */
+               if ( !gotone || ev.what == nullEvent )
+                       break;
+                       
+               /* Check whether we've moved to foreground or background */
+               if ( ev.what == osEvt &&
+                        (ev.message & osEvtMessageMask) == (suspendResumeMessage<<24)) {
+                       if ( ev.message & resumeFlag ) {
+                               in_background = 0;
+                       } else {
+                               in_background = 1;
+                       }
+               }
+#ifdef __MWERKS__
+               /* If SIOUX wants it we're done too */
+               (void)SIOUXHandleOneEvent(&ev);
+#else
+               /* Other compilers are just unlucky: we only weed out clicks in other applications */
                if ( ev.what == mouseDown ) {
                        if ( FindWindow(ev.where, &wp) == inSysWindow )
                                SystemClick(&ev, wp);
                }
+#endif /* !__MWERKS__ */
        }
-       return 1;
+       lastyield = TickCount();
+}
+
+/*
+** Yield the CPU to other tasks if opportune
+*/
+void
+PyMac_Yield() {
+       long iv;
+       
+       if ( in_background )
+               iv = interval_bg;
+       else
+               iv = interval_fg;
+       if ( TickCount() > lastyield + iv )
+               PyMac_DoYield();
+}
+
+/*
+** Idle routine for busy-wait loops.
+** Gives up CPU, handles events and returns true if an interrupt is pending
+** (but not actually handled yet).
+*/
+int
+PyMac_Idle()
+{
+       PyMac_DoYield();
+       return intrpeek();
 }
 
 
@@ -196,7 +296,14 @@ PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
        short refnum;
        long parid;
        OSErr err;
+       FSSpec *fs2;
 
+       /* first check whether it already is an FSSpec */
+       fs2 = mfs_GetFSSpecFSSpec(v);
+       if ( fs2 ) {
+               fs = fs2;
+               return 1;
+       }
        if ( PyString_Check(v) ) {
                /* It's a pathname */
                if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
@@ -217,12 +324,6 @@ PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
        return 1;
 }
 
-/* Convert an FSSpec to a Python object -- a triple (vrefnum, dirid, path) */
-PyObject *
-PyMac_BuildFSSpec(FSSpec *fs)
-{
-       return Py_BuildValue("(iis#)", fs->vRefNum, fs->parID, &fs->name[1], fs->name[0]);
-}
 
 
 /* Convert a Python object to a Rect.