mirror of https://github.com/python/cpython.git
Added eventhandling in mainloop/busywait routine plus leaving some
cycles for background apps. MacOS has a new method to set the amount of time for bg apps.
This commit is contained in:
parent
9eeb82dde1
commit
e8e8ae0f2c
|
@ -107,6 +107,8 @@ MacOS_HighLevelEventProc(EventRecord *e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXXX Need to come here from PyMac_DoYield too... */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
MacOS_SetHighLevelEventHandler(self, args)
|
MacOS_SetHighLevelEventHandler(self, args)
|
||||||
PyObject *self;
|
PyObject *self;
|
||||||
|
@ -166,6 +168,26 @@ MacOS_AcceptHighLevelEvent(self, args)
|
||||||
return res;
|
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[] = {
|
static PyMethodDef MacOS_Methods[] = {
|
||||||
{"AcceptHighLevelEvent", MacOS_AcceptHighLevelEvent, 1},
|
{"AcceptHighLevelEvent", MacOS_AcceptHighLevelEvent, 1},
|
||||||
{"GetCreatorAndType", MacOS_GetCreatorAndType, 1},
|
{"GetCreatorAndType", MacOS_GetCreatorAndType, 1},
|
||||||
|
@ -173,6 +195,7 @@ static PyMethodDef MacOS_Methods[] = {
|
||||||
#ifdef USE_STDWIN
|
#ifdef USE_STDWIN
|
||||||
{"SetHighLevelEventHandler", MacOS_SetHighLevelEventHandler, 1},
|
{"SetHighLevelEventHandler", MacOS_SetHighLevelEventHandler, 1},
|
||||||
#endif
|
#endif
|
||||||
|
{"SetScheduleTimes", MacOS_SetScheduleTimes, 1},
|
||||||
{NULL, NULL} /* Sentinel */
|
{NULL, NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,16 +26,43 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include "macglue.h"
|
#include "macglue.h"
|
||||||
|
|
||||||
#include <OSUtils.h> /* for Set(Current)A5 */
|
#include <OSUtils.h> /* for Set(Current)A5 */
|
||||||
|
#include <Files.h>
|
||||||
#include <Resources.h>
|
#include <Resources.h>
|
||||||
#include <Memory.h>
|
#include <Memory.h>
|
||||||
#include <Events.h>
|
#include <Events.h>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <Desk.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
|
/* XXX We should include Errors.h here, but it has a name conflict
|
||||||
** with the python errors.h. */
|
** with the python errors.h. */
|
||||||
#define fnfErr -43
|
#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. */
|
/* Convert C to Pascal string. Returns pointer to static buffer. */
|
||||||
unsigned char *
|
unsigned char *
|
||||||
Pstring(char *str)
|
Pstring(char *str)
|
||||||
|
@ -111,28 +138,101 @@ PyMac_Error(OSErr err)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Idle routine for busy-wait loops.
|
** Set yield timeouts
|
||||||
** 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...
|
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
PyMac_Idle()
|
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;
|
EventRecord ev;
|
||||||
WindowPtr wp;
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( StdwinIsActive )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( in_background )
|
||||||
|
yield = yield_bg;
|
||||||
|
else
|
||||||
|
yield = yield_fg;
|
||||||
|
while ( 1 ) {
|
||||||
|
if ( no_waitnextevent ) {
|
||||||
SystemTask();
|
SystemTask();
|
||||||
if ( intrpeek() )
|
gotone = GetNextEvent(0xffff, &ev);
|
||||||
return 0;
|
} else {
|
||||||
if ( GetNextEvent(0xffff, &ev) ) {
|
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 ( ev.what == mouseDown ) {
|
||||||
if ( FindWindow(ev.where, &wp) == inSysWindow )
|
if ( FindWindow(ev.where, &wp) == inSysWindow )
|
||||||
SystemClick(&ev, wp);
|
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;
|
short refnum;
|
||||||
long parid;
|
long parid;
|
||||||
OSErr err;
|
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) ) {
|
if ( PyString_Check(v) ) {
|
||||||
/* It's a pathname */
|
/* It's a pathname */
|
||||||
if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
|
if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
|
||||||
|
@ -217,12 +324,6 @@ PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
|
||||||
return 1;
|
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.
|
/* Convert a Python object to a Rect.
|
||||||
|
|
Loading…
Reference in New Issue