(py-indent-right, py-outdent-left): new commands, bound to C-c C-r and
[python/dscho.git] / Mac / Modules / snd / sndsupport.py
blobfb561e83c9807ff0f6092aa10d7ec68139ab6935
1 # This script generates the Sound interface for Python.
2 # It uses the "bgen" package to generate C code.
3 # It execs the file sndgen.py which contain the function definitions
4 # (sndgen.py was generated by sndscan.py, scanning the <Sound.h> header file).
6 from macsupport import *
9 # define our own function and module generators
11 class SndMixIn: pass
13 class SndFunction(SndMixIn, OSErrFunctionGenerator): pass
14 class SndMethod(SndMixIn, OSErrMethodGenerator): pass
17 # includestuff etc. are imported from macsupport
19 includestuff = includestuff + """
20 #include <Sound.h>
22 #ifndef HAVE_UNIVERSAL_HEADERS
23 #define SndCallBackUPP ProcPtr
24 #define NewSndCallBackProc(x) ((SndCallBackProcPtr)(x))
25 #define SndListHandle Handle
26 #endif
27 """
29 initstuff = initstuff + """
30 """
33 # define types used for arguments (in addition to standard and macsupport types)
35 class SndChannelPtrType(OpaqueByValueType):
36 def declare(self, name):
37 # Initializing all SndChannelPtr objects to 0 saves
38 # special-casing NewSndChannel(), where it is formally an
39 # input-output parameter but we treat it as output-only
40 # (since Python users are not supposed to allocate memory)
41 Output("SndChannelPtr %s = 0;", name)
43 SndChannelPtr = SndChannelPtrType('SndChannelPtr', 'SndCh')
45 SndCommand = OpaqueType('SndCommand', 'SndCmd')
46 SndCommand_ptr = OpaqueType('SndCommand', 'SndCmd')
47 SndListHandle = OpaqueByValueType("SndListHandle", "ResObj")
49 class SndCallBackType(InputOnlyType):
50 def __init__(self):
51 Type.__init__(self, 'PyObject*', 'O')
52 def getargsCheck(self, name):
53 Output("if (%s != Py_None && !PyCallable_Check(%s))", name, name)
54 OutLbrace()
55 Output('PyErr_SetString(PyExc_TypeError, "callback must be callable");')
56 Output("goto %s__error__;", name)
57 OutRbrace()
58 def passInput(self, name):
59 return "NewSndCallBackProc(SndCh_UserRoutine)"
60 def cleanup(self, name):
61 # XXX This knows it is executing inside the SndNewChannel wrapper
62 Output("if (_res != NULL && %s != Py_None)", name)
63 OutLbrace()
64 Output("SndChannelObject *p = (SndChannelObject *)_res;")
65 Output("p->ob_itself->userInfo = (long)p;")
66 Output("Py_INCREF(%s);", name)
67 Output("p->ob_callback = %s;", name)
68 OutRbrace()
69 DedentLevel()
70 Output(" %s__error__: ;", name)
71 IndentLevel()
73 SndCallBackProcPtr = SndCallBackType()
75 SndCompletionProcPtr = FakeType('(SndCompletionProcPtr)0') # XXX
77 NumVersion = OpaqueByValueType('NumVersion', 'NumVer')
79 InOutBuf128 = FixedInputOutputBufferType(128)
81 AudioSelectionPtr = FakeType('0') # XXX
83 ProcPtr = FakeType('0') # XXX
85 SCStatus = StructOutputBufferType('SCStatus')
86 SMStatus = StructOutputBufferType('SMStatus')
88 includestuff = includestuff + """
89 #include <OSUtils.h> /* for Set(Current)A5 */
91 /* Create a SndCommand object (an (int, int, int) tuple) */
92 static PyObject *
93 SndCmd_New(SndCommand *pc)
95 return Py_BuildValue("hhl", pc->cmd, pc->param1, pc->param2);
98 /* Convert a SndCommand argument */
99 static int
100 SndCmd_Convert(PyObject *v, SndCommand *pc)
102 int len;
103 pc->param1 = 0;
104 pc->param2 = 0;
105 if (PyTuple_Check(v)) {
106 if (PyArg_ParseTuple(v, "h|hl", &pc->cmd, &pc->param1, &pc->param2))
107 return 1;
108 PyErr_Clear();
109 return PyArg_ParseTuple(v, "hhs#", &pc->cmd, &pc->param1, &pc->param2, &len);
111 return PyArg_Parse(v, "h", &pc->cmd);
114 /* Create a NumVersion object (a quintuple of integers) */
115 static PyObject *
116 NumVer_New(NumVersion nv)
118 return Py_BuildValue("iiiii",
119 nv.majorRev,
120 #ifdef THINK_C
121 nv.minorRev,
122 nv.bugFixRev,
123 #else
124 (nv.minorAndBugRev>>4) & 0xf,
125 nv.minorAndBugRev & 0xf,
126 #endif
127 nv.stage,
128 nv.nonRelRev);
131 static pascal void SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd); /* Forward */
135 finalstuff = finalstuff + """
136 /* Routine passed to Py_AddPendingCall -- call the Python callback */
137 static int
138 SndCh_CallCallBack(arg)
139 void *arg;
141 SndChannelObject *p = (SndChannelObject *)arg;
142 PyObject *args;
143 PyObject *res;
144 args = Py_BuildValue("(O(hhl))",
145 p, p->ob_cmd.cmd, p->ob_cmd.param1, p->ob_cmd.param2);
146 res = PyEval_CallObject(p->ob_callback, args);
147 Py_DECREF(args);
148 if (res == NULL)
149 return -1;
150 Py_DECREF(res);
151 return 0;
154 /* Routine passed to NewSndChannel -- schedule a call to SndCh_CallCallBack */
155 static pascal void
156 SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd)
158 SndChannelObject *p = (SndChannelObject *)(chan->userInfo);
159 if (p->ob_callback != NULL) {
160 long A5 = SetA5(p->ob_A5);
161 p->ob_cmd = *cmd;
162 Py_AddPendingCall(SndCh_CallCallBack, (void *)p);
163 SetA5(A5);
169 # create the module and object definition and link them
171 class SndObjectDefinition(ObjectDefinition):
173 def outputStructMembers(self):
174 ObjectDefinition.outputStructMembers(self)
175 Output("/* Members used to implement callbacks: */")
176 Output("PyObject *ob_callback;")
177 Output("long ob_A5;");
178 Output("SndCommand ob_cmd;")
180 def outputInitStructMembers(self):
181 ObjectDefinition.outputInitStructMembers(self)
182 Output("it->ob_callback = NULL;")
183 Output("it->ob_A5 = SetCurrentA5();");
185 def outputCleanupStructMembers(self):
186 ObjectDefinition.outputCleanupStructMembers(self)
187 Output("Py_XDECREF(self->ob_callback);")
189 def outputFreeIt(self, itselfname):
190 Output("SndDisposeChannel(%s, 1);", itselfname)
193 sndobject = SndObjectDefinition('SndChannel', 'SndCh', 'SndChannelPtr')
194 module = MacModule('Snd', 'Snd', includestuff, finalstuff, initstuff)
195 module.addobject(sndobject)
198 # create lists of functions and object methods
200 functions = []
201 sndmethods = []
204 # populate the lists
206 execfile('sndgen.py')
209 # add the functions and methods to the module and object, respectively
211 for f in functions: module.add(f)
212 for f in sndmethods: sndobject.add(f)
215 # generate output
217 SetOutputFileName('Sndmodule.c')
218 module.generate()