| 
									
										
										
										
											1995-01-30 11:53:55 +00:00
										 |  |  | # This script generates the Sound interface for Python. | 
					
						
							|  |  |  | # It uses the "bgen" package to generate C code. | 
					
						
							|  |  |  | # It execs the file sndgen.py which contain the function definitions | 
					
						
							|  |  |  | # (sndgen.py was generated by sndscan.py, scanning the <Sound.h> header file). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from macsupport import * | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # define our own function and module generators | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SndMixIn: pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SndFunction(SndMixIn, OSErrFunctionGenerator): pass | 
					
						
							|  |  |  | class SndMethod(SndMixIn, OSErrMethodGenerator): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # includestuff etc. are imported from macsupport | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | includestuff = includestuff + """
 | 
					
						
							|  |  |  | #include <Sound.h> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-02-19 15:59:49 +00:00
										 |  |  | #ifndef HAVE_UNIVERSAL_HEADERS | 
					
						
							| 
									
										
										
										
											1995-01-30 11:53:55 +00:00
										 |  |  | #define SndCallBackUPP ProcPtr | 
					
						
							|  |  |  | #define NewSndCallBackProc(x) (x) | 
					
						
							|  |  |  | #define SndListHandle Handle | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | initstuff = initstuff + """
 | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # define types used for arguments (in addition to standard and macsupport types) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SndChannelPtrType(OpaqueByValueType): | 
					
						
							|  |  |  | 	def declare(self, name): | 
					
						
							|  |  |  | 		# Initializing all SndChannelPtr objects to 0 saves | 
					
						
							|  |  |  | 		# special-casing NewSndChannel(), where it is formally an | 
					
						
							|  |  |  | 		# input-output parameter but we treat it as output-only | 
					
						
							|  |  |  | 		# (since Python users are not supposed to allocate memory) | 
					
						
							|  |  |  | 		Output("SndChannelPtr %s = 0;", name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SndChannelPtr = SndChannelPtrType('SndChannelPtr', 'SndCh') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SndCommand = OpaqueType('SndCommand', 'SndCmd') | 
					
						
							|  |  |  | SndCommand_ptr = OpaqueType('SndCommand', 'SndCmd') | 
					
						
							|  |  |  | SndListHandle = OpaqueByValueType("SndListHandle", "ResObj") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SndCallBackType(InputOnlyType): | 
					
						
							|  |  |  | 	def __init__(self): | 
					
						
							|  |  |  | 		Type.__init__(self, 'PyObject*', 'O') | 
					
						
							|  |  |  | 	def getargsCheck(self, name): | 
					
						
							| 
									
										
										
										
											1995-02-19 15:59:49 +00:00
										 |  |  | 		Output("if (%s != Py_None && !PyCallable_Check(%s))", name, name) | 
					
						
							| 
									
										
										
										
											1995-01-30 11:53:55 +00:00
										 |  |  | 		OutLbrace() | 
					
						
							|  |  |  | 		Output('PyErr_SetString(PyExc_TypeError, "callback must be callable");') | 
					
						
							|  |  |  | 		Output("goto %s__error__;", name) | 
					
						
							|  |  |  | 		OutRbrace() | 
					
						
							|  |  |  | 	def passInput(self, name): | 
					
						
							| 
									
										
										
										
											1995-02-19 15:59:49 +00:00
										 |  |  | 		return "NewSndCallBackProc(SndCh_UserRoutine)" | 
					
						
							| 
									
										
										
										
											1995-01-30 11:53:55 +00:00
										 |  |  | 	def cleanup(self, name): | 
					
						
							|  |  |  | 		# XXX This knows it is executing inside the SndNewChannel wrapper | 
					
						
							|  |  |  | 		Output("if (_res != NULL && %s != Py_None)", name) | 
					
						
							|  |  |  | 		OutLbrace() | 
					
						
							|  |  |  | 		Output("SndChannelObject *p = (SndChannelObject *)_res;") | 
					
						
							|  |  |  | 		Output("p->ob_itself->userInfo = (long)p;") | 
					
						
							|  |  |  | 		Output("Py_INCREF(%s);", name) | 
					
						
							|  |  |  | 		Output("p->ob_callback = %s;", name) | 
					
						
							|  |  |  | 		OutRbrace() | 
					
						
							|  |  |  | 		DedentLevel() | 
					
						
							|  |  |  | 		Output(" %s__error__: ;", name) | 
					
						
							|  |  |  | 		IndentLevel() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SndCallBackProcPtr = SndCallBackType() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SndCompletionProcPtr = FakeType('(SndCompletionProcPtr)0') # XXX | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NumVersion = OpaqueByValueType('NumVersion', 'NumVer') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | InOutBuf128 = FixedInputOutputBufferType(128) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AudioSelectionPtr = FakeType('0') # XXX | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ProcPtr = FakeType('0') # XXX | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SCStatus = StructOutputBufferType('SCStatus') | 
					
						
							|  |  |  | SMStatus = StructOutputBufferType('SMStatus') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | includestuff = includestuff + """
 | 
					
						
							|  |  |  | #include <OSUtils.h> /* for Set(Current)A5 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Create a SndCommand object (an (int, int, int) tuple) */ | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | SndCmd_New(SndCommand *pc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return Py_BuildValue("hhl", pc->cmd, pc->param1, pc->param2); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Convert a SndCommand argument */ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | SndCmd_Convert(PyObject *v, SndCommand *pc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int len; | 
					
						
							|  |  |  | 	pc->param1 = 0; | 
					
						
							|  |  |  | 	pc->param2 = 0; | 
					
						
							|  |  |  | 	if (PyTuple_Check(v)) { | 
					
						
							|  |  |  | 		if (PyArg_ParseTuple(v, "h|hl", &pc->cmd, &pc->param1, &pc->param2)) | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 		PyErr_Clear(); | 
					
						
							|  |  |  | 		return PyArg_ParseTuple(v, "hhs#", &pc->cmd, &pc->param1, &pc->param2, &len); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return PyArg_Parse(v, "h", &pc->cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Create a NumVersion object (a quintuple of integers) */ | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | NumVer_New(NumVersion nv) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return Py_BuildValue("iiiii", | 
					
						
							|  |  |  | 	                     nv.majorRev, | 
					
						
							|  |  |  | #ifdef THINK_C | 
					
						
							|  |  |  | 	                     nv.minorRev, | 
					
						
							|  |  |  | 	                     nv.bugFixRev, | 
					
						
							|  |  |  | #else | 
					
						
							|  |  |  | 	                     (nv.minorAndBugRev>>4) & 0xf, | 
					
						
							|  |  |  | 	                     nv.minorAndBugRev & 0xf, | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 	                     nv.stage, | 
					
						
							|  |  |  | 	                     nv.nonRelRev); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static pascal void SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd); /* Forward */ | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | finalstuff = finalstuff + """
 | 
					
						
							|  |  |  | /* Routine passed to Py_AddPendingCall -- call the Python callback */ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | SndCh_CallCallBack(arg) | 
					
						
							|  |  |  | 	void *arg; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	SndChannelObject *p = (SndChannelObject *)arg; | 
					
						
							|  |  |  | 	PyObject *args; | 
					
						
							|  |  |  | 	PyObject *res; | 
					
						
							|  |  |  | 	args = Py_BuildValue("(O(hhl))", | 
					
						
							|  |  |  | 	                     p, p->ob_cmd.cmd, p->ob_cmd.param1, p->ob_cmd.param2); | 
					
						
							|  |  |  | 	res = PyEval_CallObject(p->ob_callback, args); | 
					
						
							|  |  |  | 	Py_DECREF(args); | 
					
						
							|  |  |  | 	if (res == NULL) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	Py_DECREF(res); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Routine passed to NewSndChannel -- schedule a call to SndCh_CallCallBack */ | 
					
						
							|  |  |  | static pascal void | 
					
						
							|  |  |  | SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	SndChannelObject *p = (SndChannelObject *)(chan->userInfo); | 
					
						
							|  |  |  | 	if (p->ob_callback != NULL) { | 
					
						
							|  |  |  | 		long A5 = SetA5(p->ob_A5); | 
					
						
							|  |  |  | 		p->ob_cmd = *cmd; | 
					
						
							|  |  |  | 		Py_AddPendingCall(SndCh_CallCallBack, (void *)p); | 
					
						
							|  |  |  | 		SetA5(A5); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # create the module and object definition and link them | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SndObjectDefinition(ObjectDefinition): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def outputStructMembers(self): | 
					
						
							|  |  |  | 		ObjectDefinition.outputStructMembers(self) | 
					
						
							|  |  |  | 		Output("/* Members used to implement callbacks: */") | 
					
						
							|  |  |  | 		Output("PyObject *ob_callback;") | 
					
						
							|  |  |  | 		Output("long ob_A5;"); | 
					
						
							|  |  |  | 		Output("SndCommand ob_cmd;") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def outputInitStructMembers(self): | 
					
						
							|  |  |  | 		ObjectDefinition.outputInitStructMembers(self) | 
					
						
							|  |  |  | 		Output("it->ob_callback = NULL;") | 
					
						
							|  |  |  | 		Output("it->ob_A5 = SetCurrentA5();"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def outputCleanupStructMembers(self): | 
					
						
							|  |  |  | 		ObjectDefinition.outputCleanupStructMembers(self) | 
					
						
							|  |  |  | 		Output("Py_XDECREF(self->ob_callback);") | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	def outputFreeIt(self, itselfname): | 
					
						
							|  |  |  | 		Output("SndDisposeChannel(%s, 1);", itselfname) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sndobject = SndObjectDefinition('SndChannel', 'SndCh', 'SndChannelPtr') | 
					
						
							|  |  |  | module = MacModule('Snd', 'Snd', includestuff, finalstuff, initstuff) | 
					
						
							|  |  |  | module.addobject(sndobject) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # create lists of functions and object methods | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | functions = [] | 
					
						
							|  |  |  | sndmethods = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # populate the lists | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | execfile('sndgen.py') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # add the functions and methods to the module and object, respectively | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | for f in functions: module.add(f) | 
					
						
							|  |  |  | for f in sndmethods: sndobject.add(f) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # generate output | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SetOutputFileName('Sndmodule.c') | 
					
						
							|  |  |  | module.generate() |