Oops -- Lib/Test should be Lib/test, of course!
[python/dscho.git] / Mac / Modules / qd / qdsupport.py
blob461d27f0ff469dab64261db4d0eb1269b49f8985
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).
6 import string
8 import addpack
9 addpack.addpack(':Tools:bgen:bgen')
11 # Declarations that change for each manager
12 MACHEADERFILE = 'QuickDraw.h' # The Apple header file
13 MODNAME = 'Qd' # The name of the module
14 OBJECTNAME = 'Graf' # The basic name of the objects used here
16 # The following is *usually* unchanged but may still require tuning
17 MODPREFIX = MODNAME # The prefix for module-wide routines
18 OBJECTTYPE = OBJECTNAME + 'Ptr' # The C type used to represent them
19 OBJECTPREFIX = MODPREFIX + 'Obj' # The prefix for object methods
20 INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
21 EXTRAFILE = string.lower(MODPREFIX) + 'edit.py' # A similar file but hand-made
22 OUTPUTFILE = MODNAME + "module.c" # The file generated by this program
24 from macsupport import *
26 # Create the type objects
28 class TextThingieClass(FixedInputBufferType):
29 def getargsCheck(self, name):
30 pass
32 TextThingie = TextThingieClass(None)
34 # These are temporary!
35 RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
36 OptRgnHandle = OpaqueByValueType("RgnHandle", "OptResObj")
37 PicHandle = OpaqueByValueType("PicHandle", "ResObj")
38 PolyHandle = OpaqueByValueType("PolyHandle", "ResObj")
39 PixMapHandle = OpaqueByValueType("PixMapHandle", "ResObj")
40 PixPatHandle = OpaqueByValueType("PixPatHandle", "ResObj")
41 PatHandle = OpaqueByValueType("PatHandle", "ResObj")
42 CursHandle = OpaqueByValueType("CursHandle", "ResObj")
43 CCrsrHandle = OpaqueByValueType("CCrsrHandle", "ResObj")
44 CIconHandle = OpaqueByValueType("CIconHandle", "ResObj")
45 CTabHandle = OpaqueByValueType("CTabHandle", "ResObj")
46 ITabHandle = OpaqueByValueType("ITabHandle", "ResObj")
47 GDHandle = OpaqueByValueType("GDHandle", "ResObj")
48 CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
49 GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
50 BitMap_ptr = OpaqueByValueType("BitMapPtr", "BMObj")
51 RGBColor = OpaqueType('RGBColor', 'QdRGB')
52 RGBColor_ptr = RGBColor
53 FontInfo = OpaqueType('FontInfo', 'QdFI')
55 Cursor_ptr = StructInputBufferType('Cursor')
56 Pattern = StructOutputBufferType('Pattern')
57 Pattern_ptr = StructInputBufferType('Pattern')
58 PenState = StructOutputBufferType('PenState')
59 PenState_ptr = StructInputBufferType('PenState')
61 includestuff = includestuff + """
62 #include <%s>""" % MACHEADERFILE + """
64 #define resNotFound -192 /* Can't include <Errors.h> because of Python's "errors.h" */
67 ** Parse/generate RGB records
69 PyObject *QdRGB_New(itself)
70 RGBColorPtr itself;
73 return Py_BuildValue("lll", (long)itself->red, (long)itself->green, (long)itself->blue);
76 QdRGB_Convert(v, p_itself)
77 PyObject *v;
78 RGBColorPtr p_itself;
80 long red, green, blue;
82 if( !PyArg_ParseTuple(v, "lll", &red, &green, &blue) )
83 return 0;
84 p_itself->red = (unsigned short)red;
85 p_itself->green = (unsigned short)green;
86 p_itself->blue = (unsigned short)blue;
87 return 1;
91 ** Generate FontInfo records
93 static
94 PyObject *QdFI_New(itself)
95 FontInfo *itself;
98 return Py_BuildValue("hhhh", itself->ascent, itself->descent,
99 itself->widMax, itself->leading);
105 variablestuff = """
107 PyObject *o;
109 o = QDGA_New();
110 if (o == NULL || PyDict_SetItemString(d, "qd", o) != 0)
111 Py_FatalError("can't initialize Qd.qd");
115 ## not yet...
117 ##class Region_ObjectDefinition(GlobalObjectDefinition):
118 ## def outputCheckNewArg(self):
119 ## Output("if (itself == NULL) return PyMac_Error(resNotFound);")
120 ## def outputFreeIt(self, itselfname):
121 ## Output("DisposeRegion(%s);", itselfname)
123 ##class Polygon_ObjectDefinition(GlobalObjectDefinition):
124 ## def outputCheckNewArg(self):
125 ## Output("if (itself == NULL) return PyMac_Error(resNotFound);")
126 ## def outputFreeIt(self, itselfname):
127 ## Output("KillPoly(%s);", itselfname)
129 class MyGRObjectDefinition(GlobalObjectDefinition):
130 def outputCheckNewArg(self):
131 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
132 def outputCheckConvertArg(self):
133 OutLbrace("if (DlgObj_Check(v) || WinObj_Check(v))")
134 Output("*p_itself = ((GrafPortObject *)v)->ob_itself;")
135 Output("return 1;")
136 OutRbrace()
137 def outputGetattrHook(self):
138 Output("""
139 { CGrafPtr itself_color = (CGrafPtr)self->ob_itself;
141 if ( strcmp(name, "data") == 0 )
142 return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(GrafPort));
144 if ( (itself_color->portVersion&0xc000) == 0xc000 ) {
145 /* Color-only attributes */
147 if ( strcmp(name, "portBits") == 0 )
148 /* XXXX Do we need HLock() stuff here?? */
149 return BMObj_New((BitMapPtr)*itself_color->portPixMap);
150 if ( strcmp(name, "grafVars") == 0 )
151 return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->visRgn);
152 if ( strcmp(name, "chExtra") == 0 )
153 return Py_BuildValue("h", itself_color->chExtra);
154 if ( strcmp(name, "pnLocHFrac") == 0 )
155 return Py_BuildValue("h", itself_color->pnLocHFrac);
156 if ( strcmp(name, "bkPixPat") == 0 )
157 return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->bkPixPat);
158 if ( strcmp(name, "rgbFgColor") == 0 )
159 return Py_BuildValue("O&", QdRGB_New, &itself_color->rgbFgColor);
160 if ( strcmp(name, "rgbBkColor") == 0 )
161 return Py_BuildValue("O&", QdRGB_New, &itself_color->rgbBkColor);
162 if ( strcmp(name, "pnPixPat") == 0 )
163 return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->pnPixPat);
164 if ( strcmp(name, "fillPixPat") == 0 )
165 return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->fillPixPat);
166 } else {
167 /* Mono-only attributes */
168 if ( strcmp(name, "portBits") == 0 )
169 return BMObj_New(&self->ob_itself->portBits);
170 if ( strcmp(name, "bkPat") == 0 )
171 return Py_BuildValue("s#", (char *)&self->ob_itself->bkPat, sizeof(Pattern));
172 if ( strcmp(name, "fillPat") == 0 )
173 return Py_BuildValue("s#", (char *)&self->ob_itself->fillPat, sizeof(Pattern));
174 if ( strcmp(name, "pnPat") == 0 )
175 return Py_BuildValue("s#", (char *)&self->ob_itself->pnPat, sizeof(Pattern));
178 ** Accessible for both color/mono windows.
179 ** portVersion is really color-only, but we put it here
180 ** for convenience
182 if ( strcmp(name, "portVersion") == 0 )
183 return Py_BuildValue("h", itself_color->portVersion);
184 if ( strcmp(name, "device") == 0 )
185 return PyInt_FromLong((long)self->ob_itself->device);
186 if ( strcmp(name, "portRect") == 0 )
187 return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->portRect);
188 if ( strcmp(name, "visRgn") == 0 )
189 return Py_BuildValue("O&", ResObj_New, (Handle)self->ob_itself->visRgn);
190 if ( strcmp(name, "clipRgn") == 0 )
191 return Py_BuildValue("O&", ResObj_New, (Handle)self->ob_itself->clipRgn);
192 if ( strcmp(name, "pnLoc") == 0 )
193 return Py_BuildValue("O&", PyMac_BuildPoint, self->ob_itself->pnLoc);
194 if ( strcmp(name, "pnSize") == 0 )
195 return Py_BuildValue("O&", PyMac_BuildPoint, self->ob_itself->pnSize);
196 if ( strcmp(name, "pnMode") == 0 )
197 return Py_BuildValue("h", self->ob_itself->pnMode);
198 if ( strcmp(name, "pnVis") == 0 )
199 return Py_BuildValue("h", self->ob_itself->pnVis);
200 if ( strcmp(name, "txFont") == 0 )
201 return Py_BuildValue("h", self->ob_itself->txFont);
202 if ( strcmp(name, "txFace") == 0 )
203 return Py_BuildValue("h", (short)self->ob_itself->txFace);
204 if ( strcmp(name, "txMode") == 0 )
205 return Py_BuildValue("h", self->ob_itself->txMode);
206 if ( strcmp(name, "txSize") == 0 )
207 return Py_BuildValue("h", self->ob_itself->txSize);
208 if ( strcmp(name, "spExtra") == 0 )
209 return Py_BuildValue("O&", PyMac_BuildFixed, self->ob_itself->spExtra);
210 /* XXXX Add more, as needed */
211 /* This one is so we can compare grafports: */
212 if ( strcmp(name, "_id") == 0 )
213 return Py_BuildValue("l", (long)self->ob_itself);
214 }""")
216 class MyBMObjectDefinition(GlobalObjectDefinition):
217 def outputCheckNewArg(self):
218 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
219 def outputStructMembers(self):
220 # We need to more items: a pointer to privately allocated data
221 # and a python object we're referring to.
222 Output("%s ob_itself;", self.itselftype)
223 Output("PyObject *referred_object;")
224 Output("BitMap *referred_bitmap;")
225 def outputInitStructMembers(self):
226 Output("it->ob_itself = %sitself;", self.argref)
227 Output("it->referred_object = NULL;")
228 Output("it->referred_bitmap = NULL;")
229 def outputCleanupStructMembers(self):
230 Output("Py_XDECREF(self->referred_object);")
231 Output("if (self->referred_bitmap) free(self->referred_bitmap);")
232 def outputGetattrHook(self):
233 Output("""if ( strcmp(name, "baseAddr") == 0 )
234 return PyInt_FromLong((long)self->ob_itself->baseAddr);
235 if ( strcmp(name, "rowBytes") == 0 )
236 return PyInt_FromLong((long)self->ob_itself->rowBytes);
237 if ( strcmp(name, "bounds") == 0 )
238 return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->bounds);
239 /* XXXX Add more, as needed */
240 if ( strcmp(name, "bitmap_data") == 0 )
241 return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(BitMap));
242 if ( strcmp(name, "pixmap_data") == 0 )
243 return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(PixMap));
244 """)
246 # This object is instanciated once, and will access qd globals.
247 class QDGlobalsAccessObjectDefinition(ObjectDefinition):
248 def outputStructMembers(self):
249 pass
250 def outputNew(self):
251 Output()
252 Output("%sPyObject *%s_New()", self.static, self.prefix)
253 OutLbrace()
254 Output("%s *it;", self.objecttype)
255 Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename)
256 Output("if (it == NULL) return NULL;")
257 Output("return (PyObject *)it;")
258 OutRbrace()
259 def outputConvert(self):
260 pass
261 def outputCleanupStructMembers(self):
262 pass
264 def outputGetattrHook(self):
265 Output("""
266 if ( strcmp(name, "arrow") == 0 )
267 return PyString_FromStringAndSize((char *)&qd.arrow, sizeof(qd.arrow));
268 if ( strcmp(name, "black") == 0 )
269 return PyString_FromStringAndSize((char *)&qd.black, sizeof(qd.black));
270 if ( strcmp(name, "white") == 0 )
271 return PyString_FromStringAndSize((char *)&qd.white, sizeof(qd.white));
272 if ( strcmp(name, "gray") == 0 )
273 return PyString_FromStringAndSize((char *)&qd.gray, sizeof(qd.gray));
274 if ( strcmp(name, "ltGray") == 0 )
275 return PyString_FromStringAndSize((char *)&qd.ltGray, sizeof(qd.ltGray));
276 if ( strcmp(name, "dkGray") == 0 )
277 return PyString_FromStringAndSize((char *)&qd.dkGray, sizeof(qd.dkGray));
278 if ( strcmp(name, "screenBits") == 0 )
279 return BMObj_New(&qd.screenBits);
280 if ( strcmp(name, "thePort") == 0 )
281 return GrafObj_New(qd.thePort);
282 if ( strcmp(name, "randSeed") == 0 )
283 return Py_BuildValue("l", &qd.randSeed);
284 """)
286 # Create the generator groups and link them
287 module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff, variablestuff)
288 ##r_object = Region_ObjectDefinition('Region', 'QdRgn', 'RgnHandle')
289 ##po_object = Polygon_ObjectDefinition('Polygon', 'QdPgn', 'PolyHandle')
290 ##module.addobject(r_object)
291 ##module.addobject(po_object)
292 gr_object = MyGRObjectDefinition("GrafPort", "GrafObj", "GrafPtr")
293 module.addobject(gr_object)
294 bm_object = MyBMObjectDefinition("BitMap", "BMObj", "BitMapPtr")
295 module.addobject(bm_object)
296 qd_object = QDGlobalsAccessObjectDefinition("QDGlobalsAccess", "QDGA", "XXXX")
297 module.addobject(qd_object)
300 # Create the generator classes used to populate the lists
301 Function = OSErrFunctionGenerator
302 Method = OSErrMethodGenerator
304 # Create and populate the lists
305 functions = []
306 methods = []
307 execfile(INPUTFILE)
308 #execfile(EXTRAFILE)
310 # add the populated lists to the generator groups
311 # (in a different wordl the scan program would generate this)
312 for f in functions: module.add(f)
313 ##for f in r_methods: r_object.add(f)
314 ##for f in po_methods: po_object.add(f)
317 # We manually generate a routine to create a BitMap from python data.
319 BitMap_body = """
320 BitMap *ptr;
321 PyObject *source;
322 Rect bounds;
323 int rowbytes;
324 char *data;
326 if ( !PyArg_ParseTuple(_args, "O!iO&", &PyString_Type, &source, &rowbytes, PyMac_GetRect,
327 &bounds) )
328 return NULL;
329 data = PyString_AsString(source);
330 if ((ptr=(BitMap *)malloc(sizeof(BitMap))) == NULL )
331 return PyErr_NoMemory();
332 ptr->baseAddr = (Ptr)data;
333 ptr->rowBytes = rowbytes;
334 ptr->bounds = bounds;
335 if ( (_res = BMObj_New(ptr)) == NULL ) {
336 free(ptr);
337 return NULL;
339 ((BitMapObject *)_res)->referred_object = source;
340 Py_INCREF(source);
341 ((BitMapObject *)_res)->referred_bitmap = ptr;
342 return _res;
345 f = ManualGenerator("BitMap", BitMap_body)
346 f.docstring = lambda: """Take (string, int, Rect) argument and create BitMap"""
347 module.add(f)
350 # And again, for turning a correctly-formatted structure into the object
352 RawBitMap_body = """
353 BitMap *ptr;
354 PyObject *source;
356 if ( !PyArg_ParseTuple(_args, "O!", &PyString_Type, &source) )
357 return NULL;
358 if ( PyString_Size(source) != sizeof(BitMap) && PyString_Size(source) != sizeof(PixMap) ) {
359 PyErr_BadArgument();
360 return NULL;
362 ptr = (BitMapPtr)PyString_AsString(source);
363 if ( (_res = BMObj_New(ptr)) == NULL ) {
364 return NULL;
366 ((BitMapObject *)_res)->referred_object = source;
367 Py_INCREF(source);
368 return _res;
371 f = ManualGenerator("RawBitMap", RawBitMap_body)
372 f.docstring = lambda: """Take string BitMap and turn into BitMap object"""
373 module.add(f)
375 # generate output (open the output file as late as possible)
376 SetOutputFileName(OUTPUTFILE)
377 module.generate()
378 SetOutputFile() # Close it