diff options
-rw-r--r-- | Mac/Modules/ctl/Ctlmodule.c | 149 | ||||
-rw-r--r-- | Mac/Modules/ctl/ctlsupport.py | 118 |
2 files changed, 251 insertions, 16 deletions
diff --git a/Mac/Modules/ctl/Ctlmodule.c b/Mac/Modules/ctl/Ctlmodule.c index 9b39f1a..530904c 100644 --- a/Mac/Modules/ctl/Ctlmodule.c +++ b/Mac/Modules/ctl/Ctlmodule.c @@ -84,6 +84,8 @@ ControlFontStyle_Convert(v, itself) /* TrackControl and HandleControlClick callback support */ static PyObject *tracker; static ControlActionUPP mytracker_upp; +static ControlUserPaneDrawUPP mydrawproc_upp; +static ControlUserPaneIdleUPP myidleproc_upp; extern int settrackfunc(PyObject *); /* forward */ extern void clrtrackfunc(void); /* forward */ @@ -99,6 +101,7 @@ PyTypeObject Control_Type; typedef struct ControlObject { PyObject_HEAD ControlHandle ob_itself; + PyObject *ob_callbackdict; } ControlObject; PyObject *CtlObj_New(itself) @@ -110,6 +113,7 @@ PyObject *CtlObj_New(itself) if (it == NULL) return NULL; it->ob_itself = itself; SetControlReference(itself, (long)it); + it->ob_callbackdict = NULL; return (PyObject *)it; } CtlObj_Convert(v, p_itself) @@ -128,6 +132,7 @@ CtlObj_Convert(v, p_itself) static void CtlObj_dealloc(self) ControlObject *self; { + Py_XDECREF(self->ob_callbackdict); if (self->ob_itself)SetControlReference(self->ob_itself, (long)0); /* Make it forget about us */ PyMem_DEL(self); } @@ -722,19 +727,18 @@ static PyObject *CtlObj_RemoveControlProperty(_self, _args) PyObject *_args; { PyObject *_res = NULL; - OSStatus _err; + OSStatus _rv; OSType propertyCreator; OSType propertyTag; if (!PyArg_ParseTuple(_args, "O&O&", PyMac_GetOSType, &propertyCreator, PyMac_GetOSType, &propertyTag)) return NULL; - _err = RemoveControlProperty(_self->ob_itself, - propertyCreator, - propertyTag); - if (_err != noErr) return PyMac_Error(_err); - Py_INCREF(Py_None); - _res = Py_None; + _rv = RemoveControlProperty(_self->ob_itself, + propertyCreator, + propertyTag); + _res = Py_BuildValue("l", + _rv); return _res; } @@ -743,19 +747,18 @@ static PyObject *CtlObj_GetControlRegion(_self, _args) PyObject *_args; { PyObject *_res = NULL; - OSStatus _err; + OSStatus _rv; ControlPartCode inPart; RgnHandle outRegion; if (!PyArg_ParseTuple(_args, "hO&", &inPart, ResObj_Convert, &outRegion)) return NULL; - _err = GetControlRegion(_self->ob_itself, - inPart, - outRegion); - if (_err != noErr) return PyMac_Error(_err); - Py_INCREF(Py_None); - _res = Py_None; + _rv = GetControlRegion(_self->ob_itself, + inPart, + outRegion); + _res = Py_BuildValue("l", + _rv); return _res; } @@ -1255,6 +1258,39 @@ static PyObject *CtlObj_GetControlDataHandle(_self, _args) } +static PyObject *CtlObj_SetControlDataCallback(_self, _args) + ControlObject *_self; + PyObject *_args; +{ + PyObject *_res = NULL; + + OSErr _err; + ControlPartCode inPart; + ResType inTagName; + PyObject *callback; + UniversalProcPtr *c_callback; + + if (!PyArg_ParseTuple(_args, "hO&O", + &inPart, + PyMac_GetOSType, &inTagName, + &callback)) + return NULL; + + if ( setcallback(_self, inTagName, callback, &c_callback) < 0 ) + return NULL; + _err = SetControlData(_self->ob_itself, + inPart, + inTagName, + sizeof(c_callback), + (Ptr)&c_callback); + + if (_err != noErr) + return PyMac_Error(_err); + _res = Py_None; + return _res; + +} + static PyObject *CtlObj_GetPopupData(_self, _args) ControlObject *_self; PyObject *_args; @@ -1373,9 +1409,9 @@ static PyMethodDef CtlObj_methods[] = { {"IsValidControlHandle", (PyCFunction)CtlObj_IsValidControlHandle, 1, "() -> (Boolean _rv)"}, {"RemoveControlProperty", (PyCFunction)CtlObj_RemoveControlProperty, 1, - "(OSType propertyCreator, OSType propertyTag) -> None"}, + "(OSType propertyCreator, OSType propertyTag) -> (OSStatus _rv)"}, {"GetControlRegion", (PyCFunction)CtlObj_GetControlRegion, 1, - "(ControlPartCode inPart, RgnHandle outRegion) -> None"}, + "(ControlPartCode inPart, RgnHandle outRegion) -> (OSStatus _rv)"}, {"GetControlVariant", (PyCFunction)CtlObj_GetControlVariant, 1, "() -> (ControlVariant _rv)"}, {"SetControlReference", (PyCFunction)CtlObj_SetControlReference, 1, @@ -1420,6 +1456,8 @@ static PyMethodDef CtlObj_methods[] = { "(ResObj) -> None"}, {"GetControlDataHandle", (PyCFunction)CtlObj_GetControlDataHandle, 1, "(part, type) -> ResObj"}, + {"SetControlDataCallback", (PyCFunction)CtlObj_SetControlDataCallback, 1, + "(callbackfunc) -> None"}, {"GetPopupData", (PyCFunction)CtlObj_GetPopupData, 1, NULL}, {"SetPopupData", (PyCFunction)CtlObj_SetPopupData, 1, @@ -1912,6 +1950,83 @@ mytracker(ctl, part) PySys_WriteStderr("TrackControl or HandleControlClick: exception in tracker function\n"); } +static int +setcallback(self, which, callback, uppp) + ControlObject *self; + OSType which; + PyObject *callback; + UniversalProcPtr *uppp; +{ + char keybuf[9]; + + if ( which == kControlUserPaneDrawProcTag ) + *uppp = mydrawproc_upp; + else if ( which == kControlUserPaneIdleProcTag ) + *uppp = myidleproc_upp; + else + return -1; + /* Only now do we test for clearing of the callback: */ + if ( callback == Py_None ) + *uppp = NULL; + /* Create the dict if it doesn't exist yet (so we don't get such a dict for every control) */ + if ( self->ob_callbackdict == NULL ) + if ( (self->ob_callbackdict = PyDict_New()) == NULL ) + return -1; + /* And store the Python callback */ + sprintf(keybuf, "%x", which); + if (PyDict_SetItemString(self->ob_callbackdict, keybuf, callback) < 0) + return -1; + return 0; +} + +static PyObject * +callcallback(self, which, arglist) + ControlObject *self; + OSType which; + PyObject *arglist; +{ + char keybuf[9]; + PyObject *func, *rv; + + sprintf(keybuf, "%x", which); + if ( self->ob_callbackdict == NULL || + (func = PyDict_GetItemString(self->ob_callbackdict, keybuf)) == NULL ) { + PySys_WriteStderr("Control callback without callback object\n"); + return NULL; + } + rv = PyEval_CallObject(func, arglist); + if ( rv == NULL ) + PySys_WriteStderr("Exception in control callback handler\n"); + return rv; +} + +static pascal void +mydrawproc(ControlHandle control, SInt16 part) +{ + ControlObject *ctl_obj; + PyObject *arglist, *rv; + + ctl_obj = (ControlObject *)CtlObj_WhichControl(control); + arglist = Py_BuildValue("Oh", ctl_obj, part); + rv = callcallback(ctl_obj, kControlUserPaneDrawProcTag, arglist); + Py_XDECREF(arglist); + Py_XDECREF(rv); +} + +static pascal void +myidleproc(ControlHandle control) +{ + ControlObject *ctl_obj; + PyObject *arglist, *rv; + + ctl_obj = (ControlObject *)CtlObj_WhichControl(control); + arglist = Py_BuildValue("O", ctl_obj); + rv = callcallback(ctl_obj, kControlUserPaneIdleProcTag, arglist); + Py_XDECREF(arglist); + Py_XDECREF(rv); +} + + void initCtl() { @@ -1921,6 +2036,8 @@ void initCtl() mytracker_upp = NewControlActionProc(mytracker); + mydrawproc_upp = NewControlUserPaneDrawProc(mydrawproc); + myidleproc_upp = NewControlUserPaneDrawProc(myidleproc); m = Py_InitModule("Ctl", Ctl_methods); diff --git a/Mac/Modules/ctl/ctlsupport.py b/Mac/Modules/ctl/ctlsupport.py index 5104d05..ea9dcef 100644 --- a/Mac/Modules/ctl/ctlsupport.py +++ b/Mac/Modules/ctl/ctlsupport.py @@ -84,6 +84,8 @@ ControlFontStyle_Convert(v, itself) /* TrackControl and HandleControlClick callback support */ static PyObject *tracker; static ControlActionUPP mytracker_upp; +static ControlUserPaneDrawUPP mydrawproc_upp; +static ControlUserPaneIdleUPP myidleproc_upp; extern int settrackfunc(PyObject *); /* forward */ extern void clrtrackfunc(void); /* forward */ @@ -157,19 +159,103 @@ mytracker(ctl, part) else PySys_WriteStderr("TrackControl or HandleControlClick: exception in tracker function\\n"); } + +static int +setcallback(self, which, callback, uppp) + ControlObject *self; + OSType which; + PyObject *callback; + UniversalProcPtr *uppp; +{ + char keybuf[9]; + + if ( which == kControlUserPaneDrawProcTag ) + *uppp = mydrawproc_upp; + else if ( which == kControlUserPaneIdleProcTag ) + *uppp = myidleproc_upp; + else + return -1; + /* Only now do we test for clearing of the callback: */ + if ( callback == Py_None ) + *uppp = NULL; + /* Create the dict if it doesn't exist yet (so we don't get such a dict for every control) */ + if ( self->ob_callbackdict == NULL ) + if ( (self->ob_callbackdict = PyDict_New()) == NULL ) + return -1; + /* And store the Python callback */ + sprintf(keybuf, "%x", which); + if (PyDict_SetItemString(self->ob_callbackdict, keybuf, callback) < 0) + return -1; + return 0; +} + +static PyObject * +callcallback(self, which, arglist) + ControlObject *self; + OSType which; + PyObject *arglist; +{ + char keybuf[9]; + PyObject *func, *rv; + + sprintf(keybuf, "%x", which); + if ( self->ob_callbackdict == NULL || + (func = PyDict_GetItemString(self->ob_callbackdict, keybuf)) == NULL ) { + PySys_WriteStderr("Control callback without callback object\\n"); + return NULL; + } + rv = PyEval_CallObject(func, arglist); + if ( rv == NULL ) + PySys_WriteStderr("Exception in control callback handler\\n"); + return rv; +} + +static pascal void +mydrawproc(ControlHandle control, SInt16 part) +{ + ControlObject *ctl_obj; + PyObject *arglist, *rv; + + ctl_obj = (ControlObject *)CtlObj_WhichControl(control); + arglist = Py_BuildValue("Oh", ctl_obj, part); + rv = callcallback(ctl_obj, kControlUserPaneDrawProcTag, arglist); + Py_XDECREF(arglist); + Py_XDECREF(rv); +} + +static pascal void +myidleproc(ControlHandle control) +{ + ControlObject *ctl_obj; + PyObject *arglist, *rv; + + ctl_obj = (ControlObject *)CtlObj_WhichControl(control); + arglist = Py_BuildValue("O", ctl_obj); + rv = callcallback(ctl_obj, kControlUserPaneIdleProcTag, arglist); + Py_XDECREF(arglist); + Py_XDECREF(rv); +} + """ initstuff = initstuff + """ mytracker_upp = NewControlActionProc(mytracker); +mydrawproc_upp = NewControlUserPaneDrawProc(mydrawproc); +myidleproc_upp = NewControlUserPaneDrawProc(myidleproc); """ class MyObjectDefinition(ObjectIdentityMixin, GlobalObjectDefinition): + def outputStructMembers(self): + GlobalObjectDefinition.outputStructMembers(self) + Output("PyObject *ob_callbackdict;") def outputCheckNewArg(self): Output("if (itself == NULL) return PyMac_Error(resNotFound);") def outputInitStructMembers(self): GlobalObjectDefinition.outputInitStructMembers(self) Output("SetControlReference(itself, (long)it);") + Output("it->ob_callbackdict = NULL;") def outputCleanupStructMembers(self): + Output("Py_XDECREF(self->ob_callbackdict);") Output("if (self->ob_itself)SetControlReference(self->ob_itself, (long)0); /* Make it forget about us */") # Create the generator groups and link them @@ -404,6 +490,38 @@ f = ManualGenerator("GetControlDataHandle", getcontroldatahandle_body); f.docstring = lambda: "(part, type) -> ResObj" object.add(f) +# Manual Generator for SetControlDataCallback +setcontroldatacallback_body = """ +OSErr _err; +ControlPartCode inPart; +ResType inTagName; +PyObject *callback; +UniversalProcPtr *c_callback; + +if (!PyArg_ParseTuple(_args, "hO&O", + &inPart, + PyMac_GetOSType, &inTagName, + &callback)) + return NULL; + +if ( setcallback(_self, inTagName, callback, &c_callback) < 0 ) + return NULL; +_err = SetControlData(_self->ob_itself, + inPart, + inTagName, + sizeof(c_callback), + (Ptr)&c_callback); + +if (_err != noErr) + return PyMac_Error(_err); +_res = Py_None; +return _res; +""" + +f = ManualGenerator("SetControlDataCallback", setcontroldatacallback_body); +f.docstring = lambda: "(callbackfunc) -> None" +object.add(f) + # And manual generators to get/set popup menu information getpopupdata_body = """ PopupPrivateDataHandle hdl; |