winsupport.py revision 330f57699fd3e5c22c7f354ea0fb52deb47fa6a7
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 8import addpack 9addpack.addpack(':Tools:bgen:bgen') 10 11# Declarations that change for each manager 12MACHEADERFILE = 'Windows.h' # The Apple header file 13MODNAME = 'Win' # The name of the module 14OBJECTNAME = 'Window' # 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 21EDITFILE = string.lower(MODPREFIX) + 'edit.py' # The manual definitions 22OUTPUTFILE = MODNAME + "module.c" # The file generated by this program 23 24from macsupport import * 25 26# Create the type objects 27 28WindowPtr = OpaqueByValueType(OBJECTTYPE, OBJECTPREFIX) 29WindowRef = WindowPtr 30WindowPeek = OpaqueByValueType("WindowPeek", OBJECTPREFIX) 31WindowPeek.passInput = lambda name: "(WindowPeek)(%s)" % name 32CGrafPtr = WindowPtr 33 34#RgnHandle = OpaqueByValueType("RgnHandle", "RgnObj") 35PicHandle = OpaqueByValueType("PicHandle", "ResObj") 36 37includestuff = includestuff + """ 38#include <%s>""" % MACHEADERFILE + """ 39 40#define resNotFound -192 /* Can't include <Errors.h> because of Python's "errors.h" */ 41 42#ifdef HAVE_UNIVERSAL_HEADERS 43#define WindowPeek WindowPtr 44#endif 45""" 46 47finalstuff = finalstuff + """ 48/* Return the object corresponding to the window, or NULL */ 49 50PyObject * 51WinObj_WhichWindow(w) 52 WindowPtr w; 53{ 54 PyObject *it; 55 56 /* XXX What if we find a stdwin window or a window belonging 57 to some other package? */ 58 if (w == NULL) 59 it = NULL; 60 else 61 it = (PyObject *) GetWRefCon(w); 62 if (it == NULL || ((WindowObject *)it)->ob_itself != w) 63 it = Py_None; 64 Py_INCREF(it); 65 return it; 66} 67""" 68 69class MyObjectDefinition(GlobalObjectDefinition): 70 def outputCheckNewArg(self): 71 Output("if (itself == NULL) return PyMac_Error(resNotFound);") 72 def outputInitStructMembers(self): 73 GlobalObjectDefinition.outputInitStructMembers(self) 74 Output("SetWRefCon(itself, (long)it);") 75 def outputCheckConvertArg(self): 76 OutLbrace("if (DlgObj_Check(v))") 77 Output("*p_itself = ((WindowObject *)v)->ob_itself;") 78 Output("return 1;") 79 OutRbrace() 80 Out(""" 81 if (v == Py_None) { *p_itself = NULL; return 1; } 82 if (PyInt_Check(v)) { *p_itself = (WindowPtr)PyInt_AsLong(v); return 1; } 83 """) 84 def outputFreeIt(self, itselfname): 85 Output("DisposeWindow(%s);", itselfname) 86 87# From here on it's basically all boiler plate... 88 89# Create the generator groups and link them 90module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff) 91object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE) 92module.addobject(object) 93 94# Create the generator classes used to populate the lists 95Function = OSErrFunctionGenerator 96Method = OSErrMethodGenerator 97 98# Create and populate the lists 99functions = [] 100methods = [] 101execfile(INPUTFILE) 102 103# Add a manual routine for converting integer WindowPtr's (as returned by 104# various event routines) to a WindowObject. 105whichwin_body = """ 106long ptr; 107 108if ( !PyArg_ParseTuple(_args, "i", &ptr) ) 109 return NULL; 110return WinObj_WhichWindow((WindowPtr)ptr); 111""" 112 113f = ManualGenerator("WhichWindow", whichwin_body) 114f.docstring = lambda : "Resolve an integer WindowPtr address to a Window object" 115 116functions.append(f) 117 118# And add the routines that access the internal bits of a window struct. They 119# are currently #defined in Windows.h, they will be real routines in Copland 120# (at which time this execfile can go) 121execfile(EDITFILE) 122 123# add the populated lists to the generator groups 124# (in a different wordl the scan program would generate this) 125for f in functions: module.add(f) 126for f in methods: object.add(f) 127 128 129 130# generate output (open the output file as late as possible) 131SetOutputFileName(OUTPUTFILE) 132module.generate() 133