blob: e295c147cf5fc5b6aac1f7c8bb5bb873145d2d9a [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 Jansen04a02e71996-01-06 17:12:58 +000048
49Cursor_ptr = StructInputBufferType('Cursor')
50Pattern = StructOutputBufferType('Pattern')
51Pattern_ptr = StructInputBufferType('Pattern')
52PenState = StructOutputBufferType('PenState')
53PenState_ptr = StructInputBufferType('PenState')
Guido van Rossume56db431995-03-19 22:49:50 +000054
Guido van Rossum17448e21995-01-30 11:53:55 +000055includestuff = includestuff + """
56#include <%s>""" % MACHEADERFILE + """
57#include <Desk.h>
58
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
Guido van Rossum17448e21995-01-30 11:53:55 +000085"""
Jack Jansenb5394061996-01-05 18:06:41 +000086
87variablestuff = """
88{
89 PyObject *o;
90
91 o = PyString_FromStringAndSize((char *)&qd.arrow, sizeof(qd.arrow));
92 if (o == NULL || PyDict_SetItemString(d, "arrow", o) != 0)
93 Py_FatalError("can't initialize Qd.arrow");
Jack Jansen04a02e71996-01-06 17:12:58 +000094 o = PyString_FromStringAndSize((char *)&qd.black, sizeof(qd.black));
95 if (o == NULL || PyDict_SetItemString(d, "black", o) != 0)
96 Py_FatalError("can't initialize Qd.black");
97 o = PyString_FromStringAndSize((char *)&qd.white, sizeof(qd.white));
98 if (o == NULL || PyDict_SetItemString(d, "white", o) != 0)
99 Py_FatalError("can't initialize Qd.white");
100 o = PyString_FromStringAndSize((char *)&qd.gray, sizeof(qd.gray));
101 if (o == NULL || PyDict_SetItemString(d, "gray", o) != 0)
102 Py_FatalError("can't initialize Qd.gray");
103 o = PyString_FromStringAndSize((char *)&qd.ltGray, sizeof(qd.ltGray));
104 if (o == NULL || PyDict_SetItemString(d, "ltGray", o) != 0)
105 Py_FatalError("can't initialize Qd.ltGray");
106 o = PyString_FromStringAndSize((char *)&qd.dkGray, sizeof(qd.dkGray));
107 if (o == NULL || PyDict_SetItemString(d, "dkGray", o) != 0)
108 Py_FatalError("can't initialize Qd.dkGray");
109 /* thePort, screenBits and randSeed still missing... */
Jack Jansenb5394061996-01-05 18:06:41 +0000110}
111"""
112
Jack Jansen330381c1995-11-15 15:18:01 +0000113## not yet...
114##
115##class Region_ObjectDefinition(GlobalObjectDefinition):
116## def outputCheckNewArg(self):
117## Output("if (itself == NULL) return PyMac_Error(resNotFound);")
118## def outputFreeIt(self, itselfname):
119## Output("DisposeRegion(%s);", itselfname)
120##
121##class Polygon_ObjectDefinition(GlobalObjectDefinition):
122## def outputCheckNewArg(self):
123## Output("if (itself == NULL) return PyMac_Error(resNotFound);")
124## def outputFreeIt(self, itselfname):
125## Output("KillPoly(%s);", itselfname)
Guido van Rossum17448e21995-01-30 11:53:55 +0000126
Jack Jansen330381c1995-11-15 15:18:01 +0000127class MyGRObjectDefinition(GlobalObjectDefinition):
Guido van Rossum17448e21995-01-30 11:53:55 +0000128 def outputCheckNewArg(self):
129 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
130 def outputCheckConvertArg(self):
Jack Jansen330381c1995-11-15 15:18:01 +0000131 OutLbrace("if (DlgObj_Check(v) || WinObj_Check(v))")
132 Output("*p_itself = ((GrafPortObject *)v)->ob_itself;")
Guido van Rossum17448e21995-01-30 11:53:55 +0000133 Output("return 1;")
134 OutRbrace()
Jack Jansen330381c1995-11-15 15:18:01 +0000135 def outputGetattrHook(self):
136 Output("""if ( strcmp(name, "device") == 0 )
137 return PyInt_FromLong((long)self->ob_itself->device);
Jack Jansen425e9eb1995-12-12 15:02:03 +0000138 if ( strcmp(name, "portBits") == 0 ) {
139 CGrafPtr itself_color = (CGrafPtr)self->ob_itself;
140
141 if ( (itself_color->portVersion&0xc000) == 0xc000 )
142 /* XXXX Do we need HLock() stuff here?? */
143 return BMObj_New((BitMapPtr)*itself_color->portPixMap);
144 else
145 return BMObj_New(&self->ob_itself->portBits);
146 }
Jack Jansen330381c1995-11-15 15:18:01 +0000147 if ( strcmp(name, "portRect") == 0 )
148 return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->portRect);
149 /* XXXX Add more, as needed */
Guido van Rossum17448e21995-01-30 11:53:55 +0000150 """)
Guido van Rossum17448e21995-01-30 11:53:55 +0000151
Jack Jansen41058c01995-11-16 22:48:29 +0000152class MyBMObjectDefinition(GlobalObjectDefinition):
153 def outputCheckNewArg(self):
154 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
155 def outputStructMembers(self):
156 # We need to more items: a pointer to privately allocated data
157 # and a python object we're referring to.
158 Output("%s ob_itself;", self.itselftype)
159 Output("PyObject *referred_object;")
160 Output("BitMap *referred_bitmap;")
161 def outputInitStructMembers(self):
162 Output("it->ob_itself = %sitself;", self.argref)
163 Output("it->referred_object = NULL;")
164 Output("it->referred_bitmap = NULL;")
165 def outputCleanupStructMembers(self):
166 Output("Py_XDECREF(self->referred_object);")
167 Output("if (self->referred_bitmap) free(self->referred_bitmap);")
168 def outputGetattrHook(self):
169 Output("""if ( strcmp(name, "baseAddr") == 0 )
170 return PyInt_FromLong((long)self->ob_itself->baseAddr);
171 if ( strcmp(name, "rowBytes") == 0 )
172 return PyInt_FromLong((long)self->ob_itself->rowBytes);
173 if ( strcmp(name, "bounds") == 0 )
174 return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->bounds);
175 /* XXXX Add more, as needed */
Jack Jansen425e9eb1995-12-12 15:02:03 +0000176 if ( strcmp(name, "bitmap_data") == 0 )
177 return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(BitMap));
178 if ( strcmp(name, "pixmap_data") == 0 )
179 return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(PixMap));
Jack Jansen41058c01995-11-16 22:48:29 +0000180 """)
181
Guido van Rossum17448e21995-01-30 11:53:55 +0000182# Create the generator groups and link them
Jack Jansenb5394061996-01-05 18:06:41 +0000183module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff, variablestuff)
Jack Jansen330381c1995-11-15 15:18:01 +0000184##r_object = Region_ObjectDefinition('Region', 'QdRgn', 'RgnHandle')
185##po_object = Polygon_ObjectDefinition('Polygon', 'QdPgn', 'PolyHandle')
186##module.addobject(r_object)
187##module.addobject(po_object)
188gr_object = MyGRObjectDefinition("GrafPort", "GrafObj", "GrafPtr")
189module.addobject(gr_object)
Jack Jansen41058c01995-11-16 22:48:29 +0000190bm_object = MyBMObjectDefinition("BitMap", "BMObj", "BitMapPtr")
191module.addobject(bm_object)
Jack Jansen330381c1995-11-15 15:18:01 +0000192
Guido van Rossum17448e21995-01-30 11:53:55 +0000193
194# Create the generator classes used to populate the lists
195Function = OSErrFunctionGenerator
196Method = OSErrMethodGenerator
197
198# Create and populate the lists
199functions = []
200methods = []
Guido van Rossume56db431995-03-19 22:49:50 +0000201execfile(INPUTFILE)
202#execfile(EXTRAFILE)
Guido van Rossum17448e21995-01-30 11:53:55 +0000203
204# add the populated lists to the generator groups
205# (in a different wordl the scan program would generate this)
206for f in functions: module.add(f)
Jack Jansen330381c1995-11-15 15:18:01 +0000207##for f in r_methods: r_object.add(f)
208##for f in po_methods: po_object.add(f)
Guido van Rossum17448e21995-01-30 11:53:55 +0000209
Jack Jansen41058c01995-11-16 22:48:29 +0000210#
211# We manually generate a routine to create a BitMap from python data.
212#
213BitMap_body = """
214BitMap *ptr;
215PyObject *source;
216Rect bounds;
217int rowbytes;
218char *data;
219
220if ( !PyArg_ParseTuple(_args, "O!iO&", &PyString_Type, &source, &rowbytes, PyMac_GetRect,
221 &bounds) )
222 return NULL;
223data = PyString_AsString(source);
224if ((ptr=(BitMap *)malloc(sizeof(BitMap))) == NULL )
225 return PyErr_NoMemory();
226ptr->baseAddr = (Ptr)data;
227ptr->rowBytes = rowbytes;
228ptr->bounds = bounds;
229if ( (_res = BMObj_New(ptr)) == NULL ) {
230 free(ptr);
231 return NULL;
232}
233((BitMapObject *)_res)->referred_object = source;
234Py_INCREF(source);
235((BitMapObject *)_res)->referred_bitmap = ptr;
236return _res;
237"""
238
239f = ManualGenerator("BitMap", BitMap_body)
240f.docstring = lambda: """Take (string, int, Rect) argument and create BitMap"""
241module.add(f)
242
Jack Jansen425e9eb1995-12-12 15:02:03 +0000243#
244# And again, for turning a correctly-formatted structure into the object
245#
246RawBitMap_body = """
247BitMap *ptr;
248PyObject *source;
249
250if ( !PyArg_ParseTuple(_args, "O!", &PyString_Type, &source) )
251 return NULL;
252if ( PyString_Size(source) != sizeof(BitMap) && PyString_Size(source) != sizeof(PixMap) ) {
253 PyErr_BadArgument();
254 return NULL;
255}
256ptr = (BitMapPtr)PyString_AsString(source);
257if ( (_res = BMObj_New(ptr)) == NULL ) {
258 return NULL;
259}
260((BitMapObject *)_res)->referred_object = source;
261Py_INCREF(source);
262return _res;
263"""
264
265f = ManualGenerator("RawBitMap", RawBitMap_body)
266f.docstring = lambda: """Take string BitMap and turn into BitMap object"""
267module.add(f)
268
Guido van Rossum17448e21995-01-30 11:53:55 +0000269# generate output (open the output file as late as possible)
270SetOutputFileName(OUTPUTFILE)
271module.generate()
272SetOutputFile() # Close it