home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-28 | 12.9 KB | 375 lines | [TEXT/Pyth] |
- # This script generates a Python interface for an Apple Macintosh Manager.
- # It uses the "bgen" package to generate C code.
- # The function specifications are generated by scanning the mamager's header file,
- # using the "scantools" package (customized for this particular manager).
-
- import string
-
- import addpack
- addpack.addpack(':Tools:bgen:bgen')
-
- # Declarations that change for each manager
- MACHEADERFILE = 'QuickDraw.h' # The Apple header file
- MODNAME = 'Qd' # The name of the module
- OBJECTNAME = 'Graf' # The basic name of the objects used here
-
- # The following is *usually* unchanged but may still require tuning
- MODPREFIX = MODNAME # The prefix for module-wide routines
- OBJECTTYPE = OBJECTNAME + 'Ptr' # The C type used to represent them
- OBJECTPREFIX = MODPREFIX + 'Obj' # The prefix for object methods
- INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
- EXTRAFILE = string.lower(MODPREFIX) + 'edit.py' # A similar file but hand-made
- OUTPUTFILE = MODNAME + "module.c" # The file generated by this program
-
- from macsupport import *
-
- # Create the type objects
-
- class TextThingieClass(FixedInputBufferType):
- def getargsCheck(self, name):
- pass
-
- TextThingie = TextThingieClass(None)
-
- # These are temporary!
- RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
- OptRgnHandle = OpaqueByValueType("RgnHandle", "OptResObj")
- PicHandle = OpaqueByValueType("PicHandle", "ResObj")
- PolyHandle = OpaqueByValueType("PolyHandle", "ResObj")
- PixMapHandle = OpaqueByValueType("PixMapHandle", "ResObj")
- PixPatHandle = OpaqueByValueType("PixPatHandle", "ResObj")
- PatHandle = OpaqueByValueType("PatHandle", "ResObj")
- CursHandle = OpaqueByValueType("CursHandle", "ResObj")
- CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
- GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
- BitMap_ptr = OpaqueByValueType("BitMapPtr", "BMObj")
- RGBColor = OpaqueType('RGBColor', 'QdRGB')
- RGBColor_ptr = RGBColor
- FontInfo = OpaqueType('FontInfo', 'QdFI')
-
- Cursor_ptr = StructInputBufferType('Cursor')
- Pattern = StructOutputBufferType('Pattern')
- Pattern_ptr = StructInputBufferType('Pattern')
- PenState = StructOutputBufferType('PenState')
- PenState_ptr = StructInputBufferType('PenState')
-
- includestuff = includestuff + """
- #include <%s>""" % MACHEADERFILE + """
- #include <Desk.h>
-
- #define resNotFound -192 /* Can't include <Errors.h> because of Python's "errors.h" */
-
- /*
- ** Parse/generate RGB records
- */
- PyObject *QdRGB_New(itself)
- RGBColorPtr itself;
- {
-
- return Py_BuildValue("lll", (long)itself->red, (long)itself->green, (long)itself->blue);
- }
-
- QdRGB_Convert(v, p_itself)
- PyObject *v;
- RGBColorPtr p_itself;
- {
- long red, green, blue;
-
- if( !PyArg_ParseTuple(v, "lll", &red, &green, &blue) )
- return 0;
- p_itself->red = (unsigned short)red;
- p_itself->green = (unsigned short)green;
- p_itself->blue = (unsigned short)blue;
- return 1;
- }
-
- /*
- ** Generate FontInfo records
- */
- static
- PyObject *QdFI_New(itself)
- FontInfo *itself;
- {
-
- return Py_BuildValue("hhhh", itself->ascent, itself->descent,
- itself->widMax, itself->leading);
- }
-
-
- """
-
- variablestuff = """
- {
- PyObject *o;
-
- o = QDGA_New();
- if (o == NULL || PyDict_SetItemString(d, "qd", o) != 0)
- Py_FatalError("can't initialize Qd.qd");
- }
- """
-
- ## not yet...
- ##
- ##class Region_ObjectDefinition(GlobalObjectDefinition):
- ## def outputCheckNewArg(self):
- ## Output("if (itself == NULL) return PyMac_Error(resNotFound);")
- ## def outputFreeIt(self, itselfname):
- ## Output("DisposeRegion(%s);", itselfname)
- ##
- ##class Polygon_ObjectDefinition(GlobalObjectDefinition):
- ## def outputCheckNewArg(self):
- ## Output("if (itself == NULL) return PyMac_Error(resNotFound);")
- ## def outputFreeIt(self, itselfname):
- ## Output("KillPoly(%s);", itselfname)
-
- class MyGRObjectDefinition(GlobalObjectDefinition):
- def outputCheckNewArg(self):
- Output("if (itself == NULL) return PyMac_Error(resNotFound);")
- def outputCheckConvertArg(self):
- OutLbrace("if (DlgObj_Check(v) || WinObj_Check(v))")
- Output("*p_itself = ((GrafPortObject *)v)->ob_itself;")
- Output("return 1;")
- OutRbrace()
- def outputGetattrHook(self):
- Output("""
- { CGrafPtr itself_color = (CGrafPtr)self->ob_itself;
-
- if ( strcmp(name, "data") == 0 )
- return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(GrafPort));
-
- if ( (itself_color->portVersion&0xc000) == 0xc000 ) {
- /* Color-only attributes */
-
- if ( strcmp(name, "portBits") == 0 )
- /* XXXX Do we need HLock() stuff here?? */
- return BMObj_New((BitMapPtr)*itself_color->portPixMap);
- if ( strcmp(name, "grafVars") == 0 )
- return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->visRgn);
- if ( strcmp(name, "chExtra") == 0 )
- return Py_BuildValue("h", itself_color->chExtra);
- if ( strcmp(name, "pnLocHFrac") == 0 )
- return Py_BuildValue("h", itself_color->pnLocHFrac);
- if ( strcmp(name, "bkPixPat") == 0 )
- return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->bkPixPat);
- if ( strcmp(name, "rgbFgColor") == 0 )
- return Py_BuildValue("O&", QdRGB_New, &itself_color->rgbFgColor);
- if ( strcmp(name, "rgbBkColor") == 0 )
- return Py_BuildValue("O&", QdRGB_New, &itself_color->rgbBkColor);
- if ( strcmp(name, "pnPixPat") == 0 )
- return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->pnPixPat);
- if ( strcmp(name, "fillPixPat") == 0 )
- return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->fillPixPat);
- } else {
- /* Mono-only attributes */
- if ( strcmp(name, "portBits") == 0 )
- return BMObj_New(&self->ob_itself->portBits);
- if ( strcmp(name, "bkPat") == 0 )
- return Py_BuildValue("s#", (char *)&self->ob_itself->bkPat, sizeof(Pattern));
- if ( strcmp(name, "fillPat") == 0 )
- return Py_BuildValue("s#", (char *)&self->ob_itself->fillPat, sizeof(Pattern));
- if ( strcmp(name, "pnPat") == 0 )
- return Py_BuildValue("s#", (char *)&self->ob_itself->pnPat, sizeof(Pattern));
- }
- /*
- ** Accessible for both color/mono windows.
- ** portVersion is really color-only, but we put it here
- ** for convenience
- */
- if ( strcmp(name, "portVersion") == 0 )
- return Py_BuildValue("h", itself_color->portVersion);
- if ( strcmp(name, "device") == 0 )
- return PyInt_FromLong((long)self->ob_itself->device);
- if ( strcmp(name, "portRect") == 0 )
- return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->portRect);
- if ( strcmp(name, "visRgn") == 0 )
- return Py_BuildValue("O&", ResObj_New, (Handle)self->ob_itself->visRgn);
- if ( strcmp(name, "clipRgn") == 0 )
- return Py_BuildValue("O&", ResObj_New, (Handle)self->ob_itself->clipRgn);
- if ( strcmp(name, "pnLoc") == 0 )
- return Py_BuildValue("O&", PyMac_BuildPoint, self->ob_itself->pnLoc);
- if ( strcmp(name, "pnSize") == 0 )
- return Py_BuildValue("O&", PyMac_BuildPoint, self->ob_itself->pnSize);
- if ( strcmp(name, "pnMode") == 0 )
- return Py_BuildValue("h", self->ob_itself->pnMode);
- if ( strcmp(name, "pnVis") == 0 )
- return Py_BuildValue("h", self->ob_itself->pnVis);
- if ( strcmp(name, "txFont") == 0 )
- return Py_BuildValue("h", self->ob_itself->txFont);
- if ( strcmp(name, "txFace") == 0 )
- return Py_BuildValue("h", (short)self->ob_itself->txFace);
- if ( strcmp(name, "txMode") == 0 )
- return Py_BuildValue("h", self->ob_itself->txMode);
- if ( strcmp(name, "txSize") == 0 )
- return Py_BuildValue("h", self->ob_itself->txSize);
- if ( strcmp(name, "spExtra") == 0 )
- return Py_BuildValue("O&", PyMac_BuildFixed, self->ob_itself->spExtra);
- /* XXXX Add more, as needed */
- /* This one is so we can compare grafports: */
- if ( strcmp(name, "_id") == 0 )
- return Py_BuildValue("l", (long)self->ob_itself);
- }""")
-
- class MyBMObjectDefinition(GlobalObjectDefinition):
- def outputCheckNewArg(self):
- Output("if (itself == NULL) return PyMac_Error(resNotFound);")
- def outputStructMembers(self):
- # We need to more items: a pointer to privately allocated data
- # and a python object we're referring to.
- Output("%s ob_itself;", self.itselftype)
- Output("PyObject *referred_object;")
- Output("BitMap *referred_bitmap;")
- def outputInitStructMembers(self):
- Output("it->ob_itself = %sitself;", self.argref)
- Output("it->referred_object = NULL;")
- Output("it->referred_bitmap = NULL;")
- def outputCleanupStructMembers(self):
- Output("Py_XDECREF(self->referred_object);")
- Output("if (self->referred_bitmap) free(self->referred_bitmap);")
- def outputGetattrHook(self):
- Output("""if ( strcmp(name, "baseAddr") == 0 )
- return PyInt_FromLong((long)self->ob_itself->baseAddr);
- if ( strcmp(name, "rowBytes") == 0 )
- return PyInt_FromLong((long)self->ob_itself->rowBytes);
- if ( strcmp(name, "bounds") == 0 )
- return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->bounds);
- /* XXXX Add more, as needed */
- if ( strcmp(name, "bitmap_data") == 0 )
- return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(BitMap));
- if ( strcmp(name, "pixmap_data") == 0 )
- return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(PixMap));
- """)
-
- # This object is instanciated once, and will access qd globals.
- class QDGlobalsAccessObjectDefinition(ObjectDefinition):
- def outputStructMembers(self):
- pass
- def outputNew(self):
- Output()
- Output("%sPyObject *%s_New()", self.static, self.prefix)
- OutLbrace()
- Output("%s *it;", self.objecttype)
- Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename)
- Output("if (it == NULL) return NULL;")
- Output("return (PyObject *)it;")
- OutRbrace()
- def outputConvert(self):
- pass
- def outputCleanupStructMembers(self):
- pass
-
- def outputGetattrHook(self):
- Output("""
- if ( strcmp(name, "arrow") == 0 )
- return PyString_FromStringAndSize((char *)&qd.arrow, sizeof(qd.arrow));
- if ( strcmp(name, "black") == 0 )
- return PyString_FromStringAndSize((char *)&qd.black, sizeof(qd.black));
- if ( strcmp(name, "white") == 0 )
- return PyString_FromStringAndSize((char *)&qd.white, sizeof(qd.white));
- if ( strcmp(name, "gray") == 0 )
- return PyString_FromStringAndSize((char *)&qd.gray, sizeof(qd.gray));
- if ( strcmp(name, "ltGray") == 0 )
- return PyString_FromStringAndSize((char *)&qd.ltGray, sizeof(qd.ltGray));
- if ( strcmp(name, "dkGray") == 0 )
- return PyString_FromStringAndSize((char *)&qd.dkGray, sizeof(qd.dkGray));
- if ( strcmp(name, "screenBits") == 0 )
- return BMObj_New(&qd.screenBits);
- if ( strcmp(name, "thePort") == 0 )
- return GrafObj_New(qd.thePort);
- if ( strcmp(name, "randSeed") == 0 )
- return Py_BuildValue("l", &qd.randSeed);
- """)
-
- # Create the generator groups and link them
- module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff, variablestuff)
- ##r_object = Region_ObjectDefinition('Region', 'QdRgn', 'RgnHandle')
- ##po_object = Polygon_ObjectDefinition('Polygon', 'QdPgn', 'PolyHandle')
- ##module.addobject(r_object)
- ##module.addobject(po_object)
- gr_object = MyGRObjectDefinition("GrafPort", "GrafObj", "GrafPtr")
- module.addobject(gr_object)
- bm_object = MyBMObjectDefinition("BitMap", "BMObj", "BitMapPtr")
- module.addobject(bm_object)
- qd_object = QDGlobalsAccessObjectDefinition("QDGlobalsAccess", "QDGA", "XXXX")
- module.addobject(qd_object)
-
-
- # Create the generator classes used to populate the lists
- Function = OSErrFunctionGenerator
- Method = OSErrMethodGenerator
-
- # Create and populate the lists
- functions = []
- methods = []
- execfile(INPUTFILE)
- #execfile(EXTRAFILE)
-
- # add the populated lists to the generator groups
- # (in a different wordl the scan program would generate this)
- for f in functions: module.add(f)
- ##for f in r_methods: r_object.add(f)
- ##for f in po_methods: po_object.add(f)
-
- #
- # We manually generate a routine to create a BitMap from python data.
- #
- BitMap_body = """
- BitMap *ptr;
- PyObject *source;
- Rect bounds;
- int rowbytes;
- char *data;
-
- if ( !PyArg_ParseTuple(_args, "O!iO&", &PyString_Type, &source, &rowbytes, PyMac_GetRect,
- &bounds) )
- return NULL;
- data = PyString_AsString(source);
- if ((ptr=(BitMap *)malloc(sizeof(BitMap))) == NULL )
- return PyErr_NoMemory();
- ptr->baseAddr = (Ptr)data;
- ptr->rowBytes = rowbytes;
- ptr->bounds = bounds;
- if ( (_res = BMObj_New(ptr)) == NULL ) {
- free(ptr);
- return NULL;
- }
- ((BitMapObject *)_res)->referred_object = source;
- Py_INCREF(source);
- ((BitMapObject *)_res)->referred_bitmap = ptr;
- return _res;
- """
-
- f = ManualGenerator("BitMap", BitMap_body)
- f.docstring = lambda: """Take (string, int, Rect) argument and create BitMap"""
- module.add(f)
-
- #
- # And again, for turning a correctly-formatted structure into the object
- #
- RawBitMap_body = """
- BitMap *ptr;
- PyObject *source;
-
- if ( !PyArg_ParseTuple(_args, "O!", &PyString_Type, &source) )
- return NULL;
- if ( PyString_Size(source) != sizeof(BitMap) && PyString_Size(source) != sizeof(PixMap) ) {
- PyErr_BadArgument();
- return NULL;
- }
- ptr = (BitMapPtr)PyString_AsString(source);
- if ( (_res = BMObj_New(ptr)) == NULL ) {
- return NULL;
- }
- ((BitMapObject *)_res)->referred_object = source;
- Py_INCREF(source);
- return _res;
- """
-
- f = ManualGenerator("RawBitMap", RawBitMap_body)
- f.docstring = lambda: """Take string BitMap and turn into BitMap object"""
- module.add(f)
-
- # generate output (open the output file as late as possible)
- SetOutputFileName(OUTPUTFILE)
- module.generate()
- SetOutputFile() # Close it
-