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