diff options
| author | Jack Jansen <jack.jansen@cwi.nl> | 1997-06-20 16:18:15 +0000 | 
|---|---|---|
| committer | Jack Jansen <jack.jansen@cwi.nl> | 1997-06-20 16:18:15 +0000 | 
| commit | 36ed506f09b0b73d6d99341541f2dbc4b89ffe99 (patch) | |
| tree | 2be46594fa36d775da0a492701cc3637912f9c00 /Mac/Python | |
| parent | d993648ef6f9e76cf847dfc8f66904f76c621894 (diff) | |
| download | cpython-git-36ed506f09b0b73d6d99341541f2dbc4b89ffe99.tar.gz | |
Added PyMac_SetEventHandler which allows you to replace complete event
handling in inner loop with python code. Also move (previously
machine independent) PyErr_CheckSignals here, so we can propagate
exceptions in event handling code.
Diffstat (limited to 'Mac/Python')
| -rw-r--r-- | Mac/Python/macglue.c | 114 | 
1 files changed, 71 insertions, 43 deletions
diff --git a/Mac/Python/macglue.c b/Mac/Python/macglue.c index 217703627e..b4db23c4cf 100644 --- a/Mac/Python/macglue.c +++ b/Mac/Python/macglue.c @@ -107,7 +107,8 @@ 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, int)); +static int PyMac_DoYield Py_PROTO((int, int)); +static int PyMac_Yield Py_PROTO((void));  /*  ** These are the real scheduling parameters that control what we check @@ -129,32 +130,6 @@ struct real_sched_param_struct {  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 -** than when in the background. At this time we also check for events and -** pass them off to 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 = 2; -static unsigned long lastyield; -static int in_foreground; - -/*  -** When > 0, do full scanning for events (program is not event aware) -** when == 0, only scan for Command-period -** when < 0, don't do any event scanning  -*/ -int PyMac_DoYieldEnabled = 1; -#endif -  /*  ** Workaround for sioux/gusi combo: set when we are exiting  */ @@ -175,6 +150,11 @@ struct hook_args {  static DlgHookYDUPP myhook_upp;  static int upp_inited = 0; +/* +** The python-code event handler +*/ +static PyObject *python_event_handler; +  #ifdef USE_GUSI  /*  ** GUSI (1.6.0 and earlier, at the least) do not set the MacOS idea of @@ -422,23 +402,31 @@ scan_event_queue(flush)  }  int -PyOS_InterruptOccurred() +PyErr_CheckSignals()  {  	if (schedparams.enabled) {  		if ( (unsigned long)LMGetTicks() > schedparams.next_check ) { -			PyMac_Yield(); +			if ( PyMac_Yield() < 0) +				return -1;  			schedparams.next_check = (unsigned long)LMGetTicks()  					 + schedparams.check_interval;  			if (interrupted) {  				scan_event_queue(1);	/* Eat events up to cmd-. */  				interrupted = 0; -				return 1; +				PyErr_SetNone(PyExc_KeyboardInterrupt); +				return -1;  			}  		}  	}  	return 0;  } +int +PyOS_InterruptOccurred() +{ +	scan_event_queue(1); +	return interrupted; +}  /* Check whether we are in the foreground */  int  PyMac_InForeground() @@ -460,19 +448,29 @@ PyMac_InForeground()  } +int +PyMac_SetEventHandler(PyObject *evh) +{ +	if ( evh && python_event_handler ) { +		PyErr_SetString(PyExc_RuntimeError, "Python event handler already set"); +		return 0; +	} +	if ( python_event_handler ) +		Py_DECREF(python_event_handler); +	if ( evh ) +		Py_INCREF(evh); +	python_event_handler = evh; +	return 1; +} +  /*  ** Handle an event, either one found in the mainloop eventhandler or  ** one passed back from the python program.  */  void -PyMac_HandleEvent(evp, maycallpython) +PyMac_HandleEventIntern(evp)  	EventRecord *evp; -	int maycallpython;  { -	 -	if ( maycallpython ) { -		/* To be implemented */ -	}		  #ifdef __MWERKS__  	{  		int siouxdidit; @@ -493,19 +491,43 @@ PyMac_HandleEvent(evp, maycallpython)  		}  	}  #endif /* !__MWERKS__ */ -	printf("not handled\n"); +} + +/* +** Handle an event, either through HandleEvent or by passing it to the Python +** event handler. +*/ +int +PyMac_HandleEvent(evp) +	EventRecord *evp; +{ +	PyObject *rv; +	 +	if ( python_event_handler ) { +		rv = PyObject_CallFunction(python_event_handler, "(O&)",  +			PyMac_BuildEventRecord, evp); +		if ( rv ) +			Py_DECREF(rv); +		else +			return -1;	/* Propagate exception */ +	} else { +		PyMac_HandleEventIntern(evp); +	} +	return 0;  }  /*  ** Yield the CPU to other tasks without processing events.  */ -static void +static int  PyMac_DoYield(int maxsleep, int maycallpython)  {  	EventRecord ev;  	int gotone;  	long latest_time_ready; +	static int in_here = 0; +	in_here++;  	/*  	** First check for interrupts, if wanted.  	** This sets a flag that will be picked up at an appropriate @@ -522,27 +544,33 @@ PyMac_DoYield(int maxsleep, int maycallpython)  	** - don't process events but do yield  	** - do neither  	*/ -	if( !schedparams.process_events ) { +	if( in_here > 1 || !schedparams.process_events ||  +	    (python_event_handler && !maycallpython) ) {  		if ( maxsleep >= 0 ) {  			SystemTask();  		}  	} else {  		latest_time_ready = LMGetTicks() + maxsleep;  		while ( maxsleep >= 0 ) { -			gotone = WaitNextEvent(schedparams.process_events, &ev, 0 /*maxsleep*/, NULL);	 +			gotone = WaitNextEvent(schedparams.process_events, &ev, maxsleep, NULL);	  			/* Get out quickly if nothing interesting is happening */  			if ( !gotone || ev.what == nullEvent )  				break; -			PyMac_HandleEvent(&ev, maycallpython); +			if ( PyMac_HandleEvent(&ev) < 0 ) { +				in_here--; +				return -1; +			}  			maxsleep = latest_time_ready - LMGetTicks();  		}  	} +	in_here--; +	return 0;  }  /*  ** Process events and/or yield the CPU to other tasks if opportune  */ -void +int  PyMac_Yield() {  	unsigned long maxsleep; @@ -551,7 +579,7 @@ PyMac_Yield() {  	else  		maxsleep = schedparams.bg_yield; -	PyMac_DoYield(maxsleep, 1); +	return PyMac_DoYield(maxsleep, 1);  }  /*  | 
