dlgsupport.py revision 74a1e63a89cdaad288260600cf77e3a20811f49b
1# This script generates the Dialogs interface for Python.
2# It uses the "bgen" package to generate C code.
3# It execs the file dlggen.py which contain the function definitions
4# (dlggen.py was generated by dlgscan.py, scanning the <Dialogs.h> header file).
5
6from macsupport import *
7
8# Create the type objects
9
10DialogPtr = OpaqueByValueType("DialogPtr", "DlgObj")
11DialogRef = DialogPtr
12
13# An OptHandle is either a handle or None (in case NULL is passed in).
14# This is needed for GetDialogItem().
15OptHandle = OpaqueByValueType("Handle", "OptResObj")
16
17ModalFilterProcPtr = InputOnlyType("PyObject*", "O")
18ModalFilterProcPtr.passInput = lambda name: "NewModalFilterProc(Dlg_PassFilterProc(%s))" % name
19ModalFilterUPP = ModalFilterProcPtr
20
21RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
22
23DITLMethod = Type("DITLMethod", "h")
24DialogItemIndex = Type("DialogItemIndex", "h")
25DialogItemType = Type("DialogItemType", "h")
26DialogItemIndexZeroBased = Type("DialogItemIndexZeroBased", "h")
27AlertType = Type("AlertType", "h")
28StringPtr = Str255
29EventMask = Type("EventMask", "H")
30
31includestuff = includestuff + """
32#include <Dialogs.h>
33
34#ifndef HAVE_UNIVERSAL_HEADERS
35#define NewModalFilterProc(x) (x)
36#endif
37
38/* XXX Shouldn't this be a stack? */
39static PyObject *Dlg_FilterProc_callback = NULL;
40
41static pascal Boolean Dlg_UnivFilterProc(DialogPtr dialog,
42                                         EventRecord *event,
43                                         short *itemHit)
44{
45	Boolean rv;
46	PyObject *args, *res;
47	PyObject *callback = Dlg_FilterProc_callback;
48	if (callback == NULL)
49		return 0; /* Default behavior */
50	Dlg_FilterProc_callback = NULL; /* We'll restore it when call successful */
51	args = Py_BuildValue("O&O&", WinObj_WhichWindow, dialog, PyMac_BuildEventRecord, event);
52	if (args == NULL)
53		res = NULL;
54	else {
55		res = PyEval_CallObject(callback, args);
56		Py_DECREF(args);
57	}
58	if (res == NULL) {
59		PySys_WriteStderr("Exception in Dialog Filter\\n");
60		PyErr_Print();
61		*itemHit = -1; /* Fake return item */
62		return 1; /* We handled it */
63	}
64	else {
65		Dlg_FilterProc_callback = callback;
66		if (PyInt_Check(res)) {
67			*itemHit = PyInt_AsLong(res);
68			rv = 1;
69		}
70		else
71			rv = PyObject_IsTrue(res);
72	}
73	Py_DECREF(res);
74	return rv;
75}
76
77static ModalFilterProcPtr
78Dlg_PassFilterProc(PyObject *callback)
79{
80	PyObject *tmp = Dlg_FilterProc_callback;
81	Dlg_FilterProc_callback = NULL;
82	if (callback == Py_None) {
83		Py_XDECREF(tmp);
84		return NULL;
85	}
86	Py_INCREF(callback);
87	Dlg_FilterProc_callback = callback;
88	Py_XDECREF(tmp);
89	return &Dlg_UnivFilterProc;
90}
91
92static PyObject *Dlg_UserItemProc_callback = NULL;
93
94static pascal void Dlg_UnivUserItemProc(DialogPtr dialog,
95                                         short item)
96{
97	PyObject *args, *res;
98
99	if (Dlg_UserItemProc_callback == NULL)
100		return; /* Default behavior */
101	Dlg_FilterProc_callback = NULL; /* We'll restore it when call successful */
102	args = Py_BuildValue("O&h", WinObj_WhichWindow, dialog, item);
103	if (args == NULL)
104		res = NULL;
105	else {
106		res = PyEval_CallObject(Dlg_UserItemProc_callback, args);
107		Py_DECREF(args);
108	}
109	if (res == NULL) {
110		PySys_WriteStderr("Exception in Dialog UserItem proc\\n");
111		PyErr_Print();
112	}
113	Py_XDECREF(res);
114	return;
115}
116
117extern PyMethodChain WinObj_chain;
118"""
119
120
121# Define a class which specializes our object definition
122class MyObjectDefinition(GlobalObjectDefinition):
123	def __init__(self, name, prefix = None, itselftype = None):
124		GlobalObjectDefinition.__init__(self, name, prefix, itselftype)
125		self.basechain = "&WinObj_chain"
126	def outputInitStructMembers(self):
127		GlobalObjectDefinition.outputInitStructMembers(self)
128		Output("SetWRefCon(GetDialogWindow(itself), (long)it);")
129	def outputCheckNewArg(self):
130		Output("if (itself == NULL) return Py_None;")
131	def outputCheckConvertArg(self):
132		Output("if (v == Py_None) { *p_itself = NULL; return 1; }")
133		Output("if (PyInt_Check(v)) { *p_itself = (DialogPtr)PyInt_AsLong(v);")
134		Output("                      return 1; }")
135	def outputFreeIt(self, itselfname):
136		Output("DisposeDialog(%s);", itselfname)
137
138# Create the generator groups and link them
139module = MacModule('Dlg', 'Dlg', includestuff, finalstuff, initstuff)
140object = MyObjectDefinition('Dialog', 'DlgObj', 'DialogPtr')
141module.addobject(object)
142
143# Create the generator classes used to populate the lists
144Function = OSErrFunctionGenerator
145Method = OSErrMethodGenerator
146
147# Create and populate the lists
148functions = []
149methods = []
150execfile("dlggen.py")
151
152# add the populated lists to the generator groups
153for f in functions: module.add(f)
154for f in methods: object.add(f)
155
156# Some methods that are currently macro's in C, but will be real routines
157# in MacOS 8.
158
159f = Method(WindowPtr, 'GetDialogWindow', (DialogRef, 'dialog', InMode))
160object.add(f)
161f = Method(SInt16, 'GetDialogDefaultItem', (DialogRef, 'dialog', InMode))
162object.add(f)
163f = Method(SInt16, 'GetDialogCancelItem', (DialogRef, 'dialog', InMode))
164object.add(f)
165f = Method(SInt16, 'GetDialogKeyboardFocusItem', (DialogRef, 'dialog', InMode))
166object.add(f)
167f = Method(void, 'SetGrafPortOfDialog', (DialogRef, 'dialog', InMode),
168	condition='#if !TARGET_API_MAC_CARBON')
169object.add(f)
170
171setuseritembody = """
172	PyObject *new = NULL;
173
174
175	if (!PyArg_ParseTuple(_args, "|O", &new))
176		return NULL;
177
178	if (Dlg_UserItemProc_callback && new && new != Py_None) {
179		PyErr_SetString(Dlg_Error, "Another UserItemProc is already installed");
180		return NULL;
181	}
182
183	if (new == Py_None) {
184		new = NULL;
185		_res = Py_None;
186		Py_INCREF(Py_None);
187	} else {
188		Py_INCREF(new);
189		_res = Py_BuildValue("O&", ResObj_New, (Handle)NewUserItemProc(Dlg_UnivUserItemProc));
190	}
191
192	Dlg_UserItemProc_callback = new;
193	return _res;
194"""
195f = ManualGenerator("SetUserItemHandler", setuseritembody)
196module.add(f)
197
198# generate output
199SetOutputFileName('Dlgmodule.c')
200module.generate()
201