• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# This script generates a Python interface for an Apple Macintosh Manager.
2# It uses the "bgen" package to generate C code.
3# The function specifications are generated by scanning the mamager's header file,
4# using the "scantools" package (customized for this particular manager).
5
6import string
7
8# Declarations that change for each manager
9MACHEADERFILE = 'Lists.h'               # The Apple header file
10MODNAME = '_List'                               # The name of the module
11OBJECTNAME = 'List'                     # The basic name of the objects used here
12KIND = 'Handle'                         # Usually 'Ptr' or 'Handle'
13
14# The following is *usually* unchanged but may still require tuning
15MODPREFIX = 'List'                      # The prefix for module-wide routines
16OBJECTTYPE = "ListHandle"               # The C type used to represent them
17OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
18INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
19OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
20
21from macsupport import *
22
23# Create the type objects
24ListHandle = OpaqueByValueType("ListHandle", "ListObj")
25ListRef = ListHandle # Obsolete, but used in Lists.h
26Cell = Point
27ListBounds = Rect
28ListBounds_ptr = Rect_ptr
29
30ListDefSpec = ListDefSpec_ptr = OpaqueType("ListDefSpec", "PyMac_BuildListDefSpec", "PyMac_GetListDefSpec")
31
32VarOutBufferShortsize = VarHeapOutputBufferType('char', 'short', 's')   # (buf, &len)
33InBufferShortsize = VarInputBufferType('char', 'short', 's')            # (buf, len)
34
35RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
36DataHandle = OpaqueByValueType("DataHandle", "ResObj")
37Handle = OpaqueByValueType("Handle", "ResObj")
38CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
39EventModifiers = Type("EventModifiers", "H")
40
41includestuff = includestuff + """
42#include <Carbon/Carbon.h>
43
44#ifdef USE_TOOLBOX_OBJECT_GLUE
45extern PyObject *_ListObj_New(ListHandle);
46extern int _ListObj_Convert(PyObject *, ListHandle *);
47
48#define ListObj_New _ListObj_New
49#define ListObj_Convert _ListObj_Convert
50#endif
51
52#define as_List(x) ((ListHandle)x)
53#define as_Resource(lh) ((Handle)lh)
54
55static ListDefUPP myListDefFunctionUPP;
56
57"""
58
59initstuff = initstuff + """
60myListDefFunctionUPP = NewListDefUPP((ListDefProcPtr)myListDefFunction);
61
62PyMac_INIT_TOOLBOX_OBJECT_NEW(ListHandle, ListObj_New);
63PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ListHandle, ListObj_Convert);
64"""
65
66class ListMethodGenerator(MethodGenerator):
67    """Similar to MethodGenerator, but has self as last argument"""
68
69    def parseArgumentList(self, args):
70        args, a0 = args[:-1], args[-1]
71        t0, n0, m0 = a0
72        if m0 != InMode:
73            raise ValueError, "method's 'self' must be 'InMode'"
74        self.itself = Variable(t0, "_self->ob_itself", SelfMode)
75        FunctionGenerator.parseArgumentList(self, args)
76        self.argumentList.append(self.itself)
77
78class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
79    # XXXX Should inherit from Resource
80    getsetlist = [(
81            'listFlags',
82            'return Py_BuildValue("l", (long)GetListFlags(self->ob_itself) & 0xff);',
83            'if (!PyArg_Parse(v, "B", &(*self->ob_itself)->listFlags)) return -1;',
84            None,
85            ), (
86            'selFlags',
87            'return Py_BuildValue("l", (long)GetListSelectionFlags(self->ob_itself) & 0xff);',
88            'if (!PyArg_Parse(v, "B", &(*self->ob_itself)->selFlags)) return -1;',
89            None,
90            ), (
91            'cellSize',
92            'return Py_BuildValue("O&", PyMac_BuildPoint, (*self->ob_itself)->cellSize);',
93            'if (!PyArg_Parse(v, "O&", PyMac_GetPoint, &(*self->ob_itself)->cellSize)) return -1;',
94            None
95            )]
96
97    def outputStructMembers(self):
98        ObjectDefinition.outputStructMembers(self)
99        Output("PyObject *ob_ldef_func;")
100        Output("int ob_must_be_disposed;")
101
102    def outputCheckNewArg(self):
103        Output("""if (itself == NULL) {
104                                PyErr_SetString(List_Error,"Cannot create null List");
105                                return NULL;
106                        }""")
107
108    def outputInitStructMembers(self):
109        ObjectDefinition.outputInitStructMembers(self)
110        Output("it->ob_ldef_func = NULL;")
111        Output("it->ob_must_be_disposed = 1;")
112        Output("SetListRefCon(itself, (long)it);")
113
114    def outputFreeIt(self, itselfname):
115        Output("Py_XDECREF(self->ob_ldef_func);")
116        Output("self->ob_ldef_func = NULL;")
117        Output("SetListRefCon(self->ob_itself, (long)0);")
118        Output("if (self->ob_must_be_disposed && %s) LDispose(%s);", itselfname, itselfname)
119
120# From here on it's basically all boiler plate...
121
122finalstuff = finalstuff + """
123static void myListDefFunction(SInt16 message,
124                       Boolean selected,
125                       Rect *cellRect,
126                       Cell theCell,
127                       SInt16 dataOffset,
128                       SInt16 dataLen,
129                       ListHandle theList)
130{
131        PyObject *listDefFunc, *args, *rv=NULL;
132        ListObject *self;
133
134        self = (ListObject*)GetListRefCon(theList);
135        if (self == NULL || self->ob_itself != theList)
136                return;  /* nothing we can do */
137        listDefFunc = self->ob_ldef_func;
138        if (listDefFunc == NULL)
139                return;  /* nothing we can do */
140        args = Py_BuildValue("hbO&O&hhO", message,
141                                          selected,
142                                          PyMac_BuildRect, cellRect,
143                                          PyMac_BuildPoint, theCell,
144                                          dataOffset,
145                                          dataLen,
146                                          self);
147        if (args != NULL) {
148                rv = PyEval_CallObject(listDefFunc, args);
149                Py_DECREF(args);
150        }
151        if (rv == NULL) {
152                PySys_WriteStderr("error in list definition callback:\\n");
153                PyErr_Print();
154        } else {
155                Py_DECREF(rv);
156        }
157}
158"""
159
160# Create the generator groups and link them
161module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
162object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
163module.addobject(object)
164
165# Create the generator classes used to populate the lists
166Function = FunctionGenerator
167Method = ListMethodGenerator
168
169# Create and populate the lists
170functions = []
171methods = []
172execfile(INPUTFILE)
173
174# Function to convert any handle to a list and vv.
175##f = Function(ListHandle, 'as_List', (Handle, 'h', InMode))
176as_List_body = """
177Handle h;
178ListObject *l;
179if (!PyArg_ParseTuple(_args, "O&", ResObj_Convert, &h))
180        return NULL;
181l = (ListObject *)ListObj_New(as_List(h));
182l->ob_must_be_disposed = 0;
183_res = Py_BuildValue("O", l);
184return _res;
185"""
186f = ManualGenerator("as_List", as_List_body)
187f.docstring = lambda: "(Resource)->List.\nReturns List object (which is not auto-freed!)"
188functions.append(f)
189
190f = Method(Handle, 'as_Resource', (ListHandle, 'lh', InMode))
191methods.append(f)
192
193# Manual generator for CreateCustomList, due to callback ideosyncracies
194CreateCustomList_body = """\
195Rect rView;
196Rect dataBounds;
197Point cellSize;
198
199PyObject *listDefFunc;
200ListDefSpec theSpec;
201WindowPtr theWindow;
202Boolean drawIt;
203Boolean hasGrow;
204Boolean scrollHoriz;
205Boolean scrollVert;
206ListHandle outList;
207
208if (!PyArg_ParseTuple(_args, "O&O&O&(iO)O&bbbb",
209                      PyMac_GetRect, &rView,
210                      PyMac_GetRect, &dataBounds,
211                      PyMac_GetPoint, &cellSize,
212                      &theSpec.defType, &listDefFunc,
213                      WinObj_Convert, &theWindow,
214                      &drawIt,
215                      &hasGrow,
216                      &scrollHoriz,
217                      &scrollVert))
218        return NULL;
219
220
221/* Carbon applications use the CreateCustomList API */
222theSpec.u.userProc = myListDefFunctionUPP;
223CreateCustomList(&rView,
224                 &dataBounds,
225                 cellSize,
226                 &theSpec,
227                 theWindow,
228                 drawIt,
229                 hasGrow,
230                 scrollHoriz,
231                 scrollVert,
232                 &outList);
233
234
235_res = ListObj_New(outList);
236if (_res == NULL)
237        return NULL;
238Py_INCREF(listDefFunc);
239((ListObject*)_res)->ob_ldef_func = listDefFunc;
240return _res;\
241"""
242
243f = ManualGenerator("CreateCustomList", CreateCustomList_body);
244f.docstring = lambda: "(Rect rView, Rect dataBounds, Point cellSize, ListDefSpec theSpec, WindowPtr theWindow, Boolean drawIt, Boolean hasGrow, Boolean scrollHoriz, Boolean scrollVert) -> (ListHandle outList)"
245module.add(f)
246
247# add the populated lists to the generator groups
248# (in a different wordl the scan program would generate this)
249for f in functions: module.add(f)
250for f in methods: object.add(f)
251
252
253# generate output (open the output file as late as possible)
254SetOutputFileName(OUTPUTFILE)
255module.generate()
256