blob: 13689ff40a265bab4f43a922506af1b188a0016b [file] [log] [blame]
Guido van Rossum17448e21995-01-30 11:53:55 +00001# 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
Guido van Rossume56db431995-03-19 22:49:50 +00008import addpack
Jack Jansenb81cf9d1995-06-06 13:08:40 +00009addpack.addpack(':Tools:bgen:bgen')
Guido van Rossume56db431995-03-19 22:49:50 +000010
Guido van Rossum17448e21995-01-30 11:53:55 +000011# Declarations that change for each manager
12MACHEADERFILE = 'QuickDraw.h' # The Apple header file
13MODNAME = 'Qd' # The name of the module
14OBJECTNAME = 'Graf' # The basic name of the objects used here
15
16# The following is *usually* unchanged but may still require tuning
17MODPREFIX = MODNAME # The prefix for module-wide routines
18OBJECTTYPE = OBJECTNAME + 'Ptr' # The C type used to represent them
19OBJECTPREFIX = MODPREFIX + 'Obj' # The prefix for object methods
20INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
21EXTRAFILE = string.lower(MODPREFIX) + 'edit.py' # A similar file but hand-made
22OUTPUTFILE = MODNAME + "module.c" # The file generated by this program
23
24from macsupport import *
25
26# Create the type objects
27
Guido van Rossume56db431995-03-19 22:49:50 +000028class TextThingieClass(FixedInputBufferType):
29 def getargsCheck(self, name):
30 pass
31
32TextThingie = TextThingieClass(None)
33
34# These are temporary!
Guido van Rossume56db431995-03-19 22:49:50 +000035RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
Jack Jansen425e9eb1995-12-12 15:02:03 +000036OptRgnHandle = OpaqueByValueType("RgnHandle", "OptResObj")
Guido van Rossume56db431995-03-19 22:49:50 +000037PicHandle = OpaqueByValueType("PicHandle", "ResObj")
38PolyHandle = OpaqueByValueType("PolyHandle", "ResObj")
39PixMapHandle = OpaqueByValueType("PixMapHandle", "ResObj")
40PixPatHandle = OpaqueByValueType("PixPatHandle", "ResObj")
Jack Jansen54c8f7e1995-11-14 10:46:01 +000041PatHandle = OpaqueByValueType("PatHandle", "ResObj")
42CursHandle = OpaqueByValueType("CursHandle", "ResObj")
Jack Jansen330381c1995-11-15 15:18:01 +000043CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
44GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
Jack Jansen41058c01995-11-16 22:48:29 +000045BitMap_ptr = OpaqueByValueType("BitMapPtr", "BMObj")
Jack Jansen232f3cd1995-12-09 14:04:31 +000046RGBColor = OpaqueType('RGBColor', 'QdRGB')
47RGBColor_ptr = RGBColor
Jack Jansen3a50f8a1996-01-11 16:17:14 +000048FontInfo = OpaqueType('FontInfo', 'QdFI')
Jack Jansen04a02e71996-01-06 17:12:58 +000049
50Cursor_ptr = StructInputBufferType('Cursor')
51Pattern = StructOutputBufferType('Pattern')
52Pattern_ptr = StructInputBufferType('Pattern')
53PenState = StructOutputBufferType('PenState')
54PenState_ptr = StructInputBufferType('PenState')
Guido van Rossume56db431995-03-19 22:49:50 +000055
Guido van Rossum17448e21995-01-30 11:53:55 +000056includestuff = includestuff + """
57#include <%s>""" % MACHEADERFILE + """
Guido van Rossum17448e21995-01-30 11:53:55 +000058
59#define resNotFound -192 /* Can't include <Errors.h> because of Python's "errors.h" */
Jack Jansen232f3cd1995-12-09 14:04:31 +000060
61/*
62** Parse/generate RGB records
63*/
64PyObject *QdRGB_New(itself)
65 RGBColorPtr itself;
66{
67
68 return Py_BuildValue("lll", (long)itself->red, (long)itself->green, (long)itself->blue);
69}
70
71QdRGB_Convert(v, p_itself)
72 PyObject *v;
73 RGBColorPtr p_itself;
74{
75 long red, green, blue;
76
77 if( !PyArg_ParseTuple(v, "lll", &red, &green, &blue) )
78 return 0;
79 p_itself->red = (unsigned short)red;
80 p_itself->green = (unsigned short)green;
81 p_itself->blue = (unsigned short)blue;
82 return 1;
83}
84
Jack Jansen3a50f8a1996-01-11 16:17:14 +000085/*
86** Generate FontInfo records
87*/
88static
89PyObject *QdFI_New(itself)
90 FontInfo *itself;
91{
92
93 return Py_BuildValue("hhhh", itself->ascent, itself->descent,
94 itself->widMax, itself->leading);
95}
96
97
Guido van Rossum17448e21995-01-30 11:53:55 +000098"""
Jack Jansenb5394061996-01-05 18:06:41 +000099
100variablestuff = """
101{
102 PyObject *o;
Jack Jansenbdd07471996-01-29 15:44:03 +0000103
104 o = QDGA_New();
105 if (o == NULL || PyDict_SetItemString(d, "qd", o) != 0)
106 Py_FatalError("can't initialize Qd.qd");
Jack Jansenb5394061996-01-05 18:06:41 +0000107}
108"""
109
Jack Jansen330381c1995-11-15 15:18:01 +0000110## not yet...
111##
112##class Region_ObjectDefinition(GlobalObjectDefinition):
113## def outputCheckNewArg(self):
114## Output("if (itself == NULL) return PyMac_Error(resNotFound);")
115## def outputFreeIt(self, itselfname):
116## Output("DisposeRegion(%s);", itselfname)
117##
118##class Polygon_ObjectDefinition(GlobalObjectDefinition):
119## def outputCheckNewArg(self):
120## Output("if (itself == NULL) return PyMac_Error(resNotFound);")
121## def outputFreeIt(self, itselfname):
122## Output("KillPoly(%s);", itselfname)
Guido van Rossum17448e21995-01-30 11:53:55 +0000123
Jack Jansen330381c1995-11-15 15:18:01 +0000124class MyGRObjectDefinition(GlobalObjectDefinition):
Guido van Rossum17448e21995-01-30 11:53:55 +0000125 def outputCheckNewArg(self):
126 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
127 def outputCheckConvertArg(self):
Jack Jansen330381c1995-11-15 15:18:01 +0000128 OutLbrace("if (DlgObj_Check(v) || WinObj_Check(v))")
129 Output("*p_itself = ((GrafPortObject *)v)->ob_itself;")
Guido van Rossum17448e21995-01-30 11:53:55 +0000130 Output("return 1;")
131 OutRbrace()
Jack Jansen330381c1995-11-15 15:18:01 +0000132 def outputGetattrHook(self):
Jack Jansen3a50f8a1996-01-11 16:17:14 +0000133 Output("""
134 { CGrafPtr itself_color = (CGrafPtr)self->ob_itself;
135
136 if ( strcmp(name, "data") == 0 )
137 return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(GrafPort));
138
139 if ( (itself_color->portVersion&0xc000) == 0xc000 ) {
140 /* Color-only attributes */
Jack Jansen425e9eb1995-12-12 15:02:03 +0000141
Jack Jansen3a50f8a1996-01-11 16:17:14 +0000142 if ( strcmp(name, "portBits") == 0 )
143 /* XXXX Do we need HLock() stuff here?? */
144 return BMObj_New((BitMapPtr)*itself_color->portPixMap);
145 if ( strcmp(name, "grafVars") == 0 )
146 return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->visRgn);
147 if ( strcmp(name, "chExtra") == 0 )
148 return Py_BuildValue("h", itself_color->chExtra);
149 if ( strcmp(name, "pnLocHFrac") == 0 )
150 return Py_BuildValue("h", itself_color->pnLocHFrac);
Jack Jansen61f3df41996-01-15 14:39:56 +0000151 if ( strcmp(name, "bkPixPat") == 0 )
152 return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->bkPixPat);
153 if ( strcmp(name, "rgbFgColor") == 0 )
154 return Py_BuildValue("O&", QdRGB_New, &itself_color->rgbFgColor);
155 if ( strcmp(name, "rgbBkColor") == 0 )
156 return Py_BuildValue("O&", QdRGB_New, &itself_color->rgbBkColor);
157 if ( strcmp(name, "pnPixPat") == 0 )
158 return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->pnPixPat);
159 if ( strcmp(name, "fillPixPat") == 0 )
160 return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->fillPixPat);
Jack Jansen3a50f8a1996-01-11 16:17:14 +0000161 } else {
162 /* Mono-only attributes */
163 if ( strcmp(name, "portBits") == 0 )
164 return BMObj_New(&self->ob_itself->portBits);
Jack Jansen61f3df41996-01-15 14:39:56 +0000165 if ( strcmp(name, "bkPat") == 0 )
166 return Py_BuildValue("s#", (char *)&self->ob_itself->bkPat, sizeof(Pattern));
167 if ( strcmp(name, "fillPat") == 0 )
168 return Py_BuildValue("s#", (char *)&self->ob_itself->fillPat, sizeof(Pattern));
169 if ( strcmp(name, "pnPat") == 0 )
170 return Py_BuildValue("s#", (char *)&self->ob_itself->pnPat, sizeof(Pattern));
Jack Jansen3a50f8a1996-01-11 16:17:14 +0000171 }
172 /*
173 ** Accessible for both color/mono windows.
174 ** portVersion is really color-only, but we put it here
175 ** for convenience
176 */
177 if ( strcmp(name, "portVersion") == 0 )
178 return Py_BuildValue("h", itself_color->portVersion);
179 if ( strcmp(name, "device") == 0 )
180 return PyInt_FromLong((long)self->ob_itself->device);
181 if ( strcmp(name, "portRect") == 0 )
182 return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->portRect);
183 if ( strcmp(name, "visRgn") == 0 )
184 return Py_BuildValue("O&", ResObj_New, (Handle)self->ob_itself->visRgn);
185 if ( strcmp(name, "clipRgn") == 0 )
186 return Py_BuildValue("O&", ResObj_New, (Handle)self->ob_itself->clipRgn);
Jack Jansen3a50f8a1996-01-11 16:17:14 +0000187 if ( strcmp(name, "pnLoc") == 0 )
188 return Py_BuildValue("O&", PyMac_BuildPoint, self->ob_itself->pnLoc);
189 if ( strcmp(name, "pnSize") == 0 )
190 return Py_BuildValue("O&", PyMac_BuildPoint, self->ob_itself->pnSize);
191 if ( strcmp(name, "pnMode") == 0 )
192 return Py_BuildValue("h", self->ob_itself->pnMode);
Jack Jansen3a50f8a1996-01-11 16:17:14 +0000193 if ( strcmp(name, "pnVis") == 0 )
194 return Py_BuildValue("h", self->ob_itself->pnVis);
195 if ( strcmp(name, "txFont") == 0 )
196 return Py_BuildValue("h", self->ob_itself->txFont);
197 if ( strcmp(name, "txFace") == 0 )
198 return Py_BuildValue("h", (short)self->ob_itself->txFace);
199 if ( strcmp(name, "txMode") == 0 )
200 return Py_BuildValue("h", self->ob_itself->txMode);
201 if ( strcmp(name, "txSize") == 0 )
202 return Py_BuildValue("h", self->ob_itself->txSize);
203 if ( strcmp(name, "spExtra") == 0 )
204 return Py_BuildValue("O&", PyMac_BuildFixed, self->ob_itself->spExtra);
205 /* XXXX Add more, as needed */
Jack Jansen3355be31996-05-08 15:33:20 +0000206 /* This one is so we can compare grafports: */
207 if ( strcmp(name, "_id") == 0 )
208 return Py_BuildValue("l", (long)self->ob_itself);
Jack Jansen3a50f8a1996-01-11 16:17:14 +0000209 }""")
Guido van Rossum17448e21995-01-30 11:53:55 +0000210
Jack Jansen41058c01995-11-16 22:48:29 +0000211class MyBMObjectDefinition(GlobalObjectDefinition):
212 def outputCheckNewArg(self):
213 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
214 def outputStructMembers(self):
215 # We need to more items: a pointer to privately allocated data
216 # and a python object we're referring to.
217 Output("%s ob_itself;", self.itselftype)
218 Output("PyObject *referred_object;")
219 Output("BitMap *referred_bitmap;")
220 def outputInitStructMembers(self):
221 Output("it->ob_itself = %sitself;", self.argref)
222 Output("it->referred_object = NULL;")
223 Output("it->referred_bitmap = NULL;")
224 def outputCleanupStructMembers(self):
225 Output("Py_XDECREF(self->referred_object);")
226 Output("if (self->referred_bitmap) free(self->referred_bitmap);")
227 def outputGetattrHook(self):
228 Output("""if ( strcmp(name, "baseAddr") == 0 )
229 return PyInt_FromLong((long)self->ob_itself->baseAddr);
230 if ( strcmp(name, "rowBytes") == 0 )
231 return PyInt_FromLong((long)self->ob_itself->rowBytes);
232 if ( strcmp(name, "bounds") == 0 )
233 return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->bounds);
234 /* XXXX Add more, as needed */
Jack Jansen425e9eb1995-12-12 15:02:03 +0000235 if ( strcmp(name, "bitmap_data") == 0 )
236 return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(BitMap));
237 if ( strcmp(name, "pixmap_data") == 0 )
238 return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(PixMap));
Jack Jansen41058c01995-11-16 22:48:29 +0000239 """)
Jack Jansenbdd07471996-01-29 15:44:03 +0000240
241# This object is instanciated once, and will access qd globals.
242class QDGlobalsAccessObjectDefinition(ObjectDefinition):
243 def outputStructMembers(self):
244 pass
245 def outputNew(self):
246 Output()
247 Output("%sPyObject *%s_New()", self.static, self.prefix)
248 OutLbrace()
249 Output("%s *it;", self.objecttype)
250 Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename)
251 Output("if (it == NULL) return NULL;")
252 Output("return (PyObject *)it;")
253 OutRbrace()
254 def outputConvert(self):
255 pass
256 def outputCleanupStructMembers(self):
257 pass
258
259 def outputGetattrHook(self):
260 Output("""
261 if ( strcmp(name, "arrow") == 0 )
262 return PyString_FromStringAndSize((char *)&qd.arrow, sizeof(qd.arrow));
263 if ( strcmp(name, "black") == 0 )
264 return PyString_FromStringAndSize((char *)&qd.black, sizeof(qd.black));
265 if ( strcmp(name, "white") == 0 )
266 return PyString_FromStringAndSize((char *)&qd.white, sizeof(qd.white));
267 if ( strcmp(name, "gray") == 0 )
268 return PyString_FromStringAndSize((char *)&qd.gray, sizeof(qd.gray));
269 if ( strcmp(name, "ltGray") == 0 )
270 return PyString_FromStringAndSize((char *)&qd.ltGray, sizeof(qd.ltGray));
271 if ( strcmp(name, "dkGray") == 0 )
272 return PyString_FromStringAndSize((char *)&qd.dkGray, sizeof(qd.dkGray));
273 if ( strcmp(name, "screenBits") == 0 )
274 return BMObj_New(&qd.screenBits);
275 if ( strcmp(name, "thePort") == 0 )
276 return GrafObj_New(qd.thePort);
277 if ( strcmp(name, "randSeed") == 0 )
278 return Py_BuildValue("l", &qd.randSeed);
279 """)
Jack Jansen41058c01995-11-16 22:48:29 +0000280
Guido van Rossum17448e21995-01-30 11:53:55 +0000281# Create the generator groups and link them
Jack Jansenb5394061996-01-05 18:06:41 +0000282module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff, variablestuff)
Jack Jansen330381c1995-11-15 15:18:01 +0000283##r_object = Region_ObjectDefinition('Region', 'QdRgn', 'RgnHandle')
284##po_object = Polygon_ObjectDefinition('Polygon', 'QdPgn', 'PolyHandle')
285##module.addobject(r_object)
286##module.addobject(po_object)
287gr_object = MyGRObjectDefinition("GrafPort", "GrafObj", "GrafPtr")
288module.addobject(gr_object)
Jack Jansen41058c01995-11-16 22:48:29 +0000289bm_object = MyBMObjectDefinition("BitMap", "BMObj", "BitMapPtr")
290module.addobject(bm_object)
Jack Jansenbdd07471996-01-29 15:44:03 +0000291qd_object = QDGlobalsAccessObjectDefinition("QDGlobalsAccess", "QDGA", "XXXX")
292module.addobject(qd_object)
Jack Jansen330381c1995-11-15 15:18:01 +0000293
Guido van Rossum17448e21995-01-30 11:53:55 +0000294
295# Create the generator classes used to populate the lists
296Function = OSErrFunctionGenerator
297Method = OSErrMethodGenerator
298
299# Create and populate the lists
300functions = []
301methods = []
Guido van Rossume56db431995-03-19 22:49:50 +0000302execfile(INPUTFILE)
303#execfile(EXTRAFILE)
Guido van Rossum17448e21995-01-30 11:53:55 +0000304
305# add the populated lists to the generator groups
306# (in a different wordl the scan program would generate this)
307for f in functions: module.add(f)
Jack Jansen330381c1995-11-15 15:18:01 +0000308##for f in r_methods: r_object.add(f)
309##for f in po_methods: po_object.add(f)
Guido van Rossum17448e21995-01-30 11:53:55 +0000310
Jack Jansen41058c01995-11-16 22:48:29 +0000311#
312# We manually generate a routine to create a BitMap from python data.
313#
314BitMap_body = """
315BitMap *ptr;
316PyObject *source;
317Rect bounds;
318int rowbytes;
319char *data;
320
321if ( !PyArg_ParseTuple(_args, "O!iO&", &PyString_Type, &source, &rowbytes, PyMac_GetRect,
322 &bounds) )
323 return NULL;
324data = PyString_AsString(source);
325if ((ptr=(BitMap *)malloc(sizeof(BitMap))) == NULL )
326 return PyErr_NoMemory();
327ptr->baseAddr = (Ptr)data;
328ptr->rowBytes = rowbytes;
329ptr->bounds = bounds;
330if ( (_res = BMObj_New(ptr)) == NULL ) {
331 free(ptr);
332 return NULL;
333}
334((BitMapObject *)_res)->referred_object = source;
335Py_INCREF(source);
336((BitMapObject *)_res)->referred_bitmap = ptr;
337return _res;
338"""
339
340f = ManualGenerator("BitMap", BitMap_body)
341f.docstring = lambda: """Take (string, int, Rect) argument and create BitMap"""
342module.add(f)
343
Jack Jansen425e9eb1995-12-12 15:02:03 +0000344#
345# And again, for turning a correctly-formatted structure into the object
346#
347RawBitMap_body = """
348BitMap *ptr;
349PyObject *source;
350
351if ( !PyArg_ParseTuple(_args, "O!", &PyString_Type, &source) )
352 return NULL;
353if ( PyString_Size(source) != sizeof(BitMap) && PyString_Size(source) != sizeof(PixMap) ) {
354 PyErr_BadArgument();
355 return NULL;
356}
357ptr = (BitMapPtr)PyString_AsString(source);
358if ( (_res = BMObj_New(ptr)) == NULL ) {
359 return NULL;
360}
361((BitMapObject *)_res)->referred_object = source;
362Py_INCREF(source);
363return _res;
364"""
365
366f = ManualGenerator("RawBitMap", RawBitMap_body)
367f.docstring = lambda: """Take string BitMap and turn into BitMap object"""
368module.add(f)
369
Guido van Rossum17448e21995-01-30 11:53:55 +0000370# generate output (open the output file as late as possible)
371SetOutputFileName(OUTPUTFILE)
372module.generate()
373SetOutputFile() # Close it