/Mac/Modules/dlg/dlgsupport.py

http://unladen-swallow.googlecode.com/ · Python · 278 lines · 238 code · 24 blank · 16 comment · 2 complexity · c9479ead2109875df22ed4cc7f632255 MD5 · raw file

  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. from macsupport import *
  6. # Create the type objects
  7. DialogPtr = OpaqueByValueType("DialogPtr", "DlgObj")
  8. DialogRef = DialogPtr
  9. # An OptHandle is either a handle or None (in case NULL is passed in).
  10. # This is needed for GetDialogItem().
  11. OptHandle = OpaqueByValueType("Handle", "OptResObj")
  12. ModalFilterProcPtr = InputOnlyType("PyObject*", "O")
  13. ModalFilterProcPtr.passInput = lambda name: "Dlg_PassFilterProc(%s)" % name
  14. ModalFilterUPP = ModalFilterProcPtr
  15. RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
  16. TEHandle = OpaqueByValueType("TEHandle", "ResObj")
  17. CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
  18. DITLMethod = Type("DITLMethod", "h")
  19. DialogItemIndex = Type("DialogItemIndex", "h")
  20. DialogItemType = Type("DialogItemType", "h")
  21. DialogItemIndexZeroBased = Type("DialogItemIndexZeroBased", "h")
  22. AlertType = Type("AlertType", "h")
  23. StringPtr = Str255
  24. EventMask = Type("EventMask", "H")
  25. includestuff = includestuff + """
  26. #include <Carbon/Carbon.h>
  27. #ifdef USE_TOOLBOX_OBJECT_GLUE
  28. extern PyObject *_DlgObj_New(DialogRef);
  29. extern PyObject *_DlgObj_WhichDialog(DialogRef);
  30. extern int _DlgObj_Convert(PyObject *, DialogRef *);
  31. #define DlgObj_New _DlgObj_New
  32. #define DlgObj_WhichDialog _DlgObj_WhichDialog
  33. #define DlgObj_Convert _DlgObj_Convert
  34. #endif
  35. /* XXX Shouldn't this be a stack? */
  36. static PyObject *Dlg_FilterProc_callback = NULL;
  37. static pascal Boolean Dlg_UnivFilterProc(DialogPtr dialog,
  38. EventRecord *event,
  39. short *itemHit)
  40. {
  41. Boolean rv;
  42. PyObject *args, *res;
  43. PyObject *callback = Dlg_FilterProc_callback;
  44. if (callback == NULL)
  45. return 0; /* Default behavior */
  46. Dlg_FilterProc_callback = NULL; /* We'll restore it when call successful */
  47. args = Py_BuildValue("O&O&", DlgObj_WhichDialog, dialog, PyMac_BuildEventRecord, event);
  48. if (args == NULL)
  49. res = NULL;
  50. else {
  51. res = PyEval_CallObject(callback, args);
  52. Py_DECREF(args);
  53. }
  54. if (res == NULL) {
  55. PySys_WriteStderr("Exception in Dialog Filter\\n");
  56. PyErr_Print();
  57. *itemHit = -1; /* Fake return item */
  58. return 1; /* We handled it */
  59. }
  60. else {
  61. Dlg_FilterProc_callback = callback;
  62. if (PyInt_Check(res)) {
  63. *itemHit = PyInt_AsLong(res);
  64. rv = 1;
  65. }
  66. else
  67. rv = PyObject_IsTrue(res);
  68. }
  69. Py_DECREF(res);
  70. return rv;
  71. }
  72. static ModalFilterUPP
  73. Dlg_PassFilterProc(PyObject *callback)
  74. {
  75. PyObject *tmp = Dlg_FilterProc_callback;
  76. static ModalFilterUPP UnivFilterUpp = NULL;
  77. Dlg_FilterProc_callback = NULL;
  78. if (callback == Py_None) {
  79. Py_XDECREF(tmp);
  80. return NULL;
  81. }
  82. Py_INCREF(callback);
  83. Dlg_FilterProc_callback = callback;
  84. Py_XDECREF(tmp);
  85. if ( UnivFilterUpp == NULL )
  86. UnivFilterUpp = NewModalFilterUPP(&Dlg_UnivFilterProc);
  87. return UnivFilterUpp;
  88. }
  89. static PyObject *Dlg_UserItemProc_callback = NULL;
  90. static pascal void Dlg_UnivUserItemProc(DialogPtr dialog,
  91. short item)
  92. {
  93. PyObject *args, *res;
  94. if (Dlg_UserItemProc_callback == NULL)
  95. return; /* Default behavior */
  96. Dlg_FilterProc_callback = NULL; /* We'll restore it when call successful */
  97. args = Py_BuildValue("O&h", DlgObj_WhichDialog, dialog, item);
  98. if (args == NULL)
  99. res = NULL;
  100. else {
  101. res = PyEval_CallObject(Dlg_UserItemProc_callback, args);
  102. Py_DECREF(args);
  103. }
  104. if (res == NULL) {
  105. PySys_WriteStderr("Exception in Dialog UserItem proc\\n");
  106. PyErr_Print();
  107. }
  108. Py_XDECREF(res);
  109. return;
  110. }
  111. #if 0
  112. /*
  113. ** Treating DialogObjects as WindowObjects is (I think) illegal under Carbon.
  114. ** However, as they are still identical under MacOS9 Carbon this is a problem, even
  115. ** if we neatly call GetDialogWindow() at the right places: there's one refcon field
  116. ** and it points to the DialogObject, so WinObj_WhichWindow will smartly return the
  117. ** dialog object, and therefore we still don't have a WindowObject.
  118. ** I'll leave the chaining code in place for now, with this comment to warn the
  119. ** unsuspecting victims (i.e. me, probably, in a few weeks:-)
  120. */
  121. extern PyMethodChain WinObj_chain;
  122. #endif
  123. """
  124. finalstuff = finalstuff + """
  125. /* Return the WindowPtr corresponding to a DialogObject */
  126. #if 0
  127. WindowPtr
  128. DlgObj_ConvertToWindow(PyObject *self)
  129. {
  130. if ( DlgObj_Check(self) )
  131. return GetDialogWindow(((DialogObject *)self)->ob_itself);
  132. return NULL;
  133. }
  134. #endif
  135. /* Return the object corresponding to the dialog, or None */
  136. PyObject *
  137. DlgObj_WhichDialog(DialogPtr d)
  138. {
  139. PyObject *it;
  140. if (d == NULL) {
  141. it = Py_None;
  142. Py_INCREF(it);
  143. } else {
  144. WindowPtr w = GetDialogWindow(d);
  145. it = (PyObject *) GetWRefCon(w);
  146. if (it == NULL || ((DialogObject *)it)->ob_itself != d || !DlgObj_Check(it)) {
  147. #if 0
  148. /* Should do this, but we don't have an ob_freeit for dialogs yet. */
  149. it = WinObj_New(w);
  150. ((WindowObject *)it)->ob_freeit = NULL;
  151. #else
  152. it = Py_None;
  153. Py_INCREF(it);
  154. #endif
  155. } else {
  156. Py_INCREF(it);
  157. }
  158. }
  159. return it;
  160. }
  161. """
  162. initstuff = initstuff + """
  163. PyMac_INIT_TOOLBOX_OBJECT_NEW(DialogPtr, DlgObj_New);
  164. PyMac_INIT_TOOLBOX_OBJECT_NEW(DialogPtr, DlgObj_WhichDialog);
  165. PyMac_INIT_TOOLBOX_OBJECT_CONVERT(DialogPtr, DlgObj_Convert);
  166. """
  167. # Define a class which specializes our object definition
  168. class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
  169. def __init__(self, name, prefix = None, itselftype = None):
  170. GlobalObjectDefinition.__init__(self, name, prefix, itselftype)
  171. ## This won't work in Carbon, so we disable it for all MacPythons:-(
  172. ## But see the comment above:-((
  173. ## self.basechain = "&WinObj_chain"
  174. def outputInitStructMembers(self):
  175. GlobalObjectDefinition.outputInitStructMembers(self)
  176. Output("SetWRefCon(GetDialogWindow(itself), (long)it);")
  177. def outputCheckNewArg(self):
  178. Output("if (itself == NULL) { Py_INCREF(Py_None); return Py_None; }")
  179. def outputCheckConvertArg(self):
  180. Output("if (v == Py_None) { *p_itself = NULL; return 1; }")
  181. Output("if (PyInt_Check(v)) { *p_itself = (DialogPtr)PyInt_AsLong(v);")
  182. Output(" return 1; }")
  183. def outputCompare(self):
  184. Output()
  185. Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype, self.objecttype)
  186. OutLbrace()
  187. Output("if ( self->ob_itself > other->ob_itself ) return 1;")
  188. Output("if ( self->ob_itself < other->ob_itself ) return -1;")
  189. Output("return 0;")
  190. OutRbrace()
  191. def outputHash(self):
  192. Output()
  193. Output("static int %s_hash(%s *self)", self.prefix, self.objecttype)
  194. OutLbrace()
  195. Output("return (int)self->ob_itself;")
  196. OutRbrace()
  197. def outputFreeIt(self, itselfname):
  198. Output("DisposeDialog(%s);", itselfname)
  199. # Create the generator groups and link them
  200. module = MacModule('_Dlg', 'Dlg', includestuff, finalstuff, initstuff)
  201. object = MyObjectDefinition('Dialog', 'DlgObj', 'DialogPtr')
  202. module.addobject(object)
  203. # Create the generator classes used to populate the lists
  204. Function = OSErrWeakLinkFunctionGenerator
  205. Method = OSErrWeakLinkMethodGenerator
  206. # Create and populate the lists
  207. functions = []
  208. methods = []
  209. execfile("dlggen.py")
  210. # add the populated lists to the generator groups
  211. for f in functions: module.add(f)
  212. for f in methods: object.add(f)
  213. setuseritembody = """
  214. PyObject *new = NULL;
  215. if (!PyArg_ParseTuple(_args, "|O", &new))
  216. return NULL;
  217. if (Dlg_UserItemProc_callback && new && new != Py_None) {
  218. PyErr_SetString(Dlg_Error, "Another UserItemProc is already installed");
  219. return NULL;
  220. }
  221. if (new == NULL || new == Py_None) {
  222. new = NULL;
  223. _res = Py_None;
  224. Py_INCREF(Py_None);
  225. } else {
  226. Py_INCREF(new);
  227. _res = Py_BuildValue("O&", ResObj_New, (Handle)NewUserItemUPP(Dlg_UnivUserItemProc));
  228. }
  229. Dlg_UserItemProc_callback = new;
  230. return _res;
  231. """
  232. f = ManualGenerator("SetUserItemHandler", setuseritembody)
  233. module.add(f)
  234. # generate output
  235. SetOutputFileName('_Dlgmodule.c')
  236. module.generate()