mirror of
https://github.com/python/cpython.git
synced 2025-07-23 03:05:38 +00:00
Started on support for callbacks for UserPane controls. Unfinished and untested.
This commit is contained in:
parent
fb4ece7fea
commit
abc411bac8
2 changed files with 251 additions and 16 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue