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