summaryrefslogtreecommitdiffstats
path: root/Mac/Modules/snd/sndsupport.py
diff options
context:
space:
mode:
Diffstat (limited to 'Mac/Modules/snd/sndsupport.py')
-rw-r--r--Mac/Modules/snd/sndsupport.py218
1 files changed, 218 insertions, 0 deletions
diff --git a/Mac/Modules/snd/sndsupport.py b/Mac/Modules/snd/sndsupport.py
new file mode 100644
index 0000000..3516fa6
--- /dev/null
+++ b/Mac/Modules/snd/sndsupport.py
@@ -0,0 +1,218 @@
+# 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>
+
+#ifndef __MWERKS__
+#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):
+ Output("if (%s != Py_None && !callable(%s))", name, name)
+ OutLbrace()
+ Output('PyErr_SetString(PyExc_TypeError, "callback must be callable");')
+ Output("goto %s__error__;", name)
+ OutRbrace()
+ def passInput(self, name):
+ return "(SndCallBackProcPtr)&SndCh_UserRoutine"
+ 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()