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 8# Declarations that change for each manager 9MACHEADERFILE = 'Lists.h' # The Apple header file 10MODNAME = '_List' # The name of the module 11OBJECTNAME = 'List' # The basic name of the objects used here 12KIND = 'Handle' # Usually 'Ptr' or 'Handle' 13 14# The following is *usually* unchanged but may still require tuning 15MODPREFIX = 'List' # The prefix for module-wide routines 16OBJECTTYPE = "ListHandle" # The C type used to represent them 17OBJECTPREFIX = MODPREFIX + 'Obj' # The prefix for object methods 18INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner 19OUTPUTFILE = MODNAME + "module.c" # The file generated by this program 20 21from macsupport import * 22 23# Create the type objects 24ListHandle = OpaqueByValueType("ListHandle", "ListObj") 25ListRef = ListHandle # Obsolete, but used in Lists.h 26Cell = Point 27ListBounds = Rect 28ListBounds_ptr = Rect_ptr 29 30ListDefSpec = ListDefSpec_ptr = OpaqueType("ListDefSpec", "PyMac_BuildListDefSpec", "PyMac_GetListDefSpec") 31 32VarOutBufferShortsize = VarHeapOutputBufferType('char', 'short', 's') # (buf, &len) 33InBufferShortsize = VarInputBufferType('char', 'short', 's') # (buf, len) 34 35RgnHandle = OpaqueByValueType("RgnHandle", "ResObj") 36DataHandle = OpaqueByValueType("DataHandle", "ResObj") 37Handle = OpaqueByValueType("Handle", "ResObj") 38CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj") 39EventModifiers = Type("EventModifiers", "H") 40 41includestuff = includestuff + """ 42#include <Carbon/Carbon.h> 43 44#ifdef USE_TOOLBOX_OBJECT_GLUE 45extern PyObject *_ListObj_New(ListHandle); 46extern int _ListObj_Convert(PyObject *, ListHandle *); 47 48#define ListObj_New _ListObj_New 49#define ListObj_Convert _ListObj_Convert 50#endif 51 52#define as_List(x) ((ListHandle)x) 53#define as_Resource(lh) ((Handle)lh) 54 55static ListDefUPP myListDefFunctionUPP; 56 57""" 58 59initstuff = initstuff + """ 60myListDefFunctionUPP = NewListDefUPP((ListDefProcPtr)myListDefFunction); 61 62PyMac_INIT_TOOLBOX_OBJECT_NEW(ListHandle, ListObj_New); 63PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ListHandle, ListObj_Convert); 64""" 65 66class ListMethodGenerator(MethodGenerator): 67 """Similar to MethodGenerator, but has self as last argument""" 68 69 def parseArgumentList(self, args): 70 args, a0 = args[:-1], args[-1] 71 t0, n0, m0 = a0 72 if m0 != InMode: 73 raise ValueError, "method's 'self' must be 'InMode'" 74 self.itself = Variable(t0, "_self->ob_itself", SelfMode) 75 FunctionGenerator.parseArgumentList(self, args) 76 self.argumentList.append(self.itself) 77 78class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition): 79 # XXXX Should inherit from Resource 80 getsetlist = [( 81 'listFlags', 82 'return Py_BuildValue("l", (long)GetListFlags(self->ob_itself) & 0xff);', 83 'if (!PyArg_Parse(v, "B", &(*self->ob_itself)->listFlags)) return -1;', 84 None, 85 ), ( 86 'selFlags', 87 'return Py_BuildValue("l", (long)GetListSelectionFlags(self->ob_itself) & 0xff);', 88 'if (!PyArg_Parse(v, "B", &(*self->ob_itself)->selFlags)) return -1;', 89 None, 90 ), ( 91 'cellSize', 92 'return Py_BuildValue("O&", PyMac_BuildPoint, (*self->ob_itself)->cellSize);', 93 'if (!PyArg_Parse(v, "O&", PyMac_GetPoint, &(*self->ob_itself)->cellSize)) return -1;', 94 None 95 )] 96 97 def outputStructMembers(self): 98 ObjectDefinition.outputStructMembers(self) 99 Output("PyObject *ob_ldef_func;") 100 Output("int ob_must_be_disposed;") 101 102 def outputCheckNewArg(self): 103 Output("""if (itself == NULL) { 104 PyErr_SetString(List_Error,"Cannot create null List"); 105 return NULL; 106 }""") 107 108 def outputInitStructMembers(self): 109 ObjectDefinition.outputInitStructMembers(self) 110 Output("it->ob_ldef_func = NULL;") 111 Output("it->ob_must_be_disposed = 1;") 112 Output("SetListRefCon(itself, (long)it);") 113 114 def outputFreeIt(self, itselfname): 115 Output("Py_XDECREF(self->ob_ldef_func);") 116 Output("self->ob_ldef_func = NULL;") 117 Output("SetListRefCon(self->ob_itself, (long)0);") 118 Output("if (self->ob_must_be_disposed && %s) LDispose(%s);", itselfname, itselfname) 119 120# From here on it's basically all boiler plate... 121 122finalstuff = finalstuff + """ 123static void myListDefFunction(SInt16 message, 124 Boolean selected, 125 Rect *cellRect, 126 Cell theCell, 127 SInt16 dataOffset, 128 SInt16 dataLen, 129 ListHandle theList) 130{ 131 PyObject *listDefFunc, *args, *rv=NULL; 132 ListObject *self; 133 134 self = (ListObject*)GetListRefCon(theList); 135 if (self == NULL || self->ob_itself != theList) 136 return; /* nothing we can do */ 137 listDefFunc = self->ob_ldef_func; 138 if (listDefFunc == NULL) 139 return; /* nothing we can do */ 140 args = Py_BuildValue("hbO&O&hhO", message, 141 selected, 142 PyMac_BuildRect, cellRect, 143 PyMac_BuildPoint, theCell, 144 dataOffset, 145 dataLen, 146 self); 147 if (args != NULL) { 148 rv = PyEval_CallObject(listDefFunc, args); 149 Py_DECREF(args); 150 } 151 if (rv == NULL) { 152 PySys_WriteStderr("error in list definition callback:\\n"); 153 PyErr_Print(); 154 } else { 155 Py_DECREF(rv); 156 } 157} 158""" 159 160# Create the generator groups and link them 161module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff) 162object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE) 163module.addobject(object) 164 165# Create the generator classes used to populate the lists 166Function = FunctionGenerator 167Method = ListMethodGenerator 168 169# Create and populate the lists 170functions = [] 171methods = [] 172execfile(INPUTFILE) 173 174# Function to convert any handle to a list and vv. 175##f = Function(ListHandle, 'as_List', (Handle, 'h', InMode)) 176as_List_body = """ 177Handle h; 178ListObject *l; 179if (!PyArg_ParseTuple(_args, "O&", ResObj_Convert, &h)) 180 return NULL; 181l = (ListObject *)ListObj_New(as_List(h)); 182l->ob_must_be_disposed = 0; 183_res = Py_BuildValue("O", l); 184return _res; 185""" 186f = ManualGenerator("as_List", as_List_body) 187f.docstring = lambda: "(Resource)->List.\nReturns List object (which is not auto-freed!)" 188functions.append(f) 189 190f = Method(Handle, 'as_Resource', (ListHandle, 'lh', InMode)) 191methods.append(f) 192 193# Manual generator for CreateCustomList, due to callback ideosyncracies 194CreateCustomList_body = """\ 195Rect rView; 196Rect dataBounds; 197Point cellSize; 198 199PyObject *listDefFunc; 200ListDefSpec theSpec; 201WindowPtr theWindow; 202Boolean drawIt; 203Boolean hasGrow; 204Boolean scrollHoriz; 205Boolean scrollVert; 206ListHandle outList; 207 208if (!PyArg_ParseTuple(_args, "O&O&O&(iO)O&bbbb", 209 PyMac_GetRect, &rView, 210 PyMac_GetRect, &dataBounds, 211 PyMac_GetPoint, &cellSize, 212 &theSpec.defType, &listDefFunc, 213 WinObj_Convert, &theWindow, 214 &drawIt, 215 &hasGrow, 216 &scrollHoriz, 217 &scrollVert)) 218 return NULL; 219 220 221/* Carbon applications use the CreateCustomList API */ 222theSpec.u.userProc = myListDefFunctionUPP; 223CreateCustomList(&rView, 224 &dataBounds, 225 cellSize, 226 &theSpec, 227 theWindow, 228 drawIt, 229 hasGrow, 230 scrollHoriz, 231 scrollVert, 232 &outList); 233 234 235_res = ListObj_New(outList); 236if (_res == NULL) 237 return NULL; 238Py_INCREF(listDefFunc); 239((ListObject*)_res)->ob_ldef_func = listDefFunc; 240return _res;\ 241""" 242 243f = ManualGenerator("CreateCustomList", CreateCustomList_body); 244f.docstring = lambda: "(Rect rView, Rect dataBounds, Point cellSize, ListDefSpec theSpec, WindowPtr theWindow, Boolean drawIt, Boolean hasGrow, Boolean scrollHoriz, Boolean scrollVert) -> (ListHandle outList)" 245module.add(f) 246 247# add the populated lists to the generator groups 248# (in a different wordl the scan program would generate this) 249for f in functions: module.add(f) 250for f in methods: object.add(f) 251 252 253# generate output (open the output file as late as possible) 254SetOutputFileName(OUTPUTFILE) 255module.generate() 256