Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit abc411b

Browse files
committed
Started on support for callbacks for UserPane controls. Unfinished and untested.
1 parent fb4ece7 commit abc411b

2 files changed

Lines changed: 251 additions & 16 deletions

File tree

Mac/Modules/ctl/Ctlmodule.c

Lines changed: 133 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ ControlFontStyle_Convert(v, itself)
8484
/* TrackControl and HandleControlClick callback support */
8585
static PyObject *tracker;
8686
static ControlActionUPP mytracker_upp;
87+
static ControlUserPaneDrawUPP mydrawproc_upp;
88+
static ControlUserPaneIdleUPP myidleproc_upp;
8789

8890
extern int settrackfunc(PyObject *); /* forward */
8991
extern void clrtrackfunc(void); /* forward */
@@ -99,6 +101,7 @@ PyTypeObject Control_Type;
99101
typedef struct ControlObject {
100102
PyObject_HEAD
101103
ControlHandle ob_itself;
104+
PyObject *ob_callbackdict;
102105
} ControlObject;
103106

104107
PyObject *CtlObj_New(itself)
@@ -110,6 +113,7 @@ PyObject *CtlObj_New(itself)
110113
if (it == NULL) return NULL;
111114
it->ob_itself = itself;
112115
SetControlReference(itself, (long)it);
116+
it->ob_callbackdict = NULL;
113117
return (PyObject *)it;
114118
}
115119
CtlObj_Convert(v, p_itself)
@@ -128,6 +132,7 @@ CtlObj_Convert(v, p_itself)
128132
static void CtlObj_dealloc(self)
129133
ControlObject *self;
130134
{
135+
Py_XDECREF(self->ob_callbackdict);
131136
if (self->ob_itself)SetControlReference(self->ob_itself, (long)0); /* Make it forget about us */
132137
PyMem_DEL(self);
133138
}
@@ -722,19 +727,18 @@ static PyObject *CtlObj_RemoveControlProperty(_self, _args)
722727
PyObject *_args;
723728
{
724729
PyObject *_res = NULL;
725-
OSStatus _err;
730+
OSStatus _rv;
726731
OSType propertyCreator;
727732
OSType propertyTag;
728733
if (!PyArg_ParseTuple(_args, "O&O&",
729734
PyMac_GetOSType, &propertyCreator,
730735
PyMac_GetOSType, &propertyTag))
731736
return NULL;
732-
_err = RemoveControlProperty(_self->ob_itself,
733-
propertyCreator,
734-
propertyTag);
735-
if (_err != noErr) return PyMac_Error(_err);
736-
Py_INCREF(Py_None);
737-
_res = Py_None;
737+
_rv = RemoveControlProperty(_self->ob_itself,
738+
propertyCreator,
739+
propertyTag);
740+
_res = Py_BuildValue("l",
741+
_rv);
738742
return _res;
739743
}
740744

@@ -743,19 +747,18 @@ static PyObject *CtlObj_GetControlRegion(_self, _args)
743747
PyObject *_args;
744748
{
745749
PyObject *_res = NULL;
746-
OSStatus _err;
750+
OSStatus _rv;
747751
ControlPartCode inPart;
748752
RgnHandle outRegion;
749753
if (!PyArg_ParseTuple(_args, "hO&",
750754
&inPart,
751755
ResObj_Convert, &outRegion))
752756
return NULL;
753-
_err = GetControlRegion(_self->ob_itself,
754-
inPart,
755-
outRegion);
756-
if (_err != noErr) return PyMac_Error(_err);
757-
Py_INCREF(Py_None);
758-
_res = Py_None;
757+
_rv = GetControlRegion(_self->ob_itself,
758+
inPart,
759+
outRegion);
760+
_res = Py_BuildValue("l",
761+
_rv);
759762
return _res;
760763
}
761764

@@ -1255,6 +1258,39 @@ static PyObject *CtlObj_GetControlDataHandle(_self, _args)
12551258

12561259
}
12571260

1261+
static PyObject *CtlObj_SetControlDataCallback(_self, _args)
1262+
ControlObject *_self;
1263+
PyObject *_args;
1264+
{
1265+
PyObject *_res = NULL;
1266+
1267+
OSErr _err;
1268+
ControlPartCode inPart;
1269+
ResType inTagName;
1270+
PyObject *callback;
1271+
UniversalProcPtr *c_callback;
1272+
1273+
if (!PyArg_ParseTuple(_args, "hO&O",
1274+
&inPart,
1275+
PyMac_GetOSType, &inTagName,
1276+
&callback))
1277+
return NULL;
1278+
1279+
if ( setcallback(_self, inTagName, callback, &c_callback) < 0 )
1280+
return NULL;
1281+
_err = SetControlData(_self->ob_itself,
1282+
inPart,
1283+
inTagName,
1284+
sizeof(c_callback),
1285+
(Ptr)&c_callback);
1286+
1287+
if (_err != noErr)
1288+
return PyMac_Error(_err);
1289+
_res = Py_None;
1290+
return _res;
1291+
1292+
}
1293+
12581294
static PyObject *CtlObj_GetPopupData(_self, _args)
12591295
ControlObject *_self;
12601296
PyObject *_args;
@@ -1373,9 +1409,9 @@ static PyMethodDef CtlObj_methods[] = {
13731409
{"IsValidControlHandle", (PyCFunction)CtlObj_IsValidControlHandle, 1,
13741410
"() -> (Boolean _rv)"},
13751411
{"RemoveControlProperty", (PyCFunction)CtlObj_RemoveControlProperty, 1,
1376-
"(OSType propertyCreator, OSType propertyTag) -> None"},
1412+
"(OSType propertyCreator, OSType propertyTag) -> (OSStatus _rv)"},
13771413
{"GetControlRegion", (PyCFunction)CtlObj_GetControlRegion, 1,
1378-
"(ControlPartCode inPart, RgnHandle outRegion) -> None"},
1414+
"(ControlPartCode inPart, RgnHandle outRegion) -> (OSStatus _rv)"},
13791415
{"GetControlVariant", (PyCFunction)CtlObj_GetControlVariant, 1,
13801416
"() -> (ControlVariant _rv)"},
13811417
{"SetControlReference", (PyCFunction)CtlObj_SetControlReference, 1,
@@ -1420,6 +1456,8 @@ static PyMethodDef CtlObj_methods[] = {
14201456
"(ResObj) -> None"},
14211457
{"GetControlDataHandle", (PyCFunction)CtlObj_GetControlDataHandle, 1,
14221458
"(part, type) -> ResObj"},
1459+
{"SetControlDataCallback", (PyCFunction)CtlObj_SetControlDataCallback, 1,
1460+
"(callbackfunc) -> None"},
14231461
{"GetPopupData", (PyCFunction)CtlObj_GetPopupData, 1,
14241462
NULL},
14251463
{"SetPopupData", (PyCFunction)CtlObj_SetPopupData, 1,
@@ -1912,6 +1950,83 @@ mytracker(ctl, part)
19121950
PySys_WriteStderr("TrackControl or HandleControlClick: exception in tracker function\n");
19131951
}
19141952

1953+
static int
1954+
setcallback(self, which, callback, uppp)
1955+
ControlObject *self;
1956+
OSType which;
1957+
PyObject *callback;
1958+
UniversalProcPtr *uppp;
1959+
{
1960+
char keybuf[9];
1961+
1962+
if ( which == kControlUserPaneDrawProcTag )
1963+
*uppp = mydrawproc_upp;
1964+
else if ( which == kControlUserPaneIdleProcTag )
1965+
*uppp = myidleproc_upp;
1966+
else
1967+
return -1;
1968+
/* Only now do we test for clearing of the callback: */
1969+
if ( callback == Py_None )
1970+
*uppp = NULL;
1971+
/* Create the dict if it doesn't exist yet (so we don't get such a dict for every control) */
1972+
if ( self->ob_callbackdict == NULL )
1973+
if ( (self->ob_callbackdict = PyDict_New()) == NULL )
1974+
return -1;
1975+
/* And store the Python callback */
1976+
sprintf(keybuf, "%x", which);
1977+
if (PyDict_SetItemString(self->ob_callbackdict, keybuf, callback) < 0)
1978+
return -1;
1979+
return 0;
1980+
}
1981+
1982+
static PyObject *
1983+
callcallback(self, which, arglist)
1984+
ControlObject *self;
1985+
OSType which;
1986+
PyObject *arglist;
1987+
{
1988+
char keybuf[9];
1989+
PyObject *func, *rv;
1990+
1991+
sprintf(keybuf, "%x", which);
1992+
if ( self->ob_callbackdict == NULL ||
1993+
(func = PyDict_GetItemString(self->ob_callbackdict, keybuf)) == NULL ) {
1994+
PySys_WriteStderr("Control callback without callback object\n");
1995+
return NULL;
1996+
}
1997+
rv = PyEval_CallObject(func, arglist);
1998+
if ( rv == NULL )
1999+
PySys_WriteStderr("Exception in control callback handler\n");
2000+
return rv;
2001+
}
2002+
2003+
static pascal void
2004+
mydrawproc(ControlHandle control, SInt16 part)
2005+
{
2006+
ControlObject *ctl_obj;
2007+
PyObject *arglist, *rv;
2008+
2009+
ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
2010+
arglist = Py_BuildValue("Oh", ctl_obj, part);
2011+
rv = callcallback(ctl_obj, kControlUserPaneDrawProcTag, arglist);
2012+
Py_XDECREF(arglist);
2013+
Py_XDECREF(rv);
2014+
}
2015+
2016+
static pascal void
2017+
myidleproc(ControlHandle control)
2018+
{
2019+
ControlObject *ctl_obj;
2020+
PyObject *arglist, *rv;
2021+
2022+
ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
2023+
arglist = Py_BuildValue("O", ctl_obj);
2024+
rv = callcallback(ctl_obj, kControlUserPaneIdleProcTag, arglist);
2025+
Py_XDECREF(arglist);
2026+
Py_XDECREF(rv);
2027+
}
2028+
2029+
19152030

19162031
void initCtl()
19172032
{
@@ -1921,6 +2036,8 @@ void initCtl()
19212036

19222037

19232038
mytracker_upp = NewControlActionProc(mytracker);
2039+
mydrawproc_upp = NewControlUserPaneDrawProc(mydrawproc);
2040+
myidleproc_upp = NewControlUserPaneDrawProc(myidleproc);
19242041

19252042

19262043
m = Py_InitModule("Ctl", Ctl_methods);

Mac/Modules/ctl/ctlsupport.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@
8484
/* TrackControl and HandleControlClick callback support */
8585
static PyObject *tracker;
8686
static ControlActionUPP mytracker_upp;
87+
static ControlUserPaneDrawUPP mydrawproc_upp;
88+
static ControlUserPaneIdleUPP myidleproc_upp;
8789
8890
extern int settrackfunc(PyObject *); /* forward */
8991
extern void clrtrackfunc(void); /* forward */
@@ -157,19 +159,103 @@
157159
else
158160
PySys_WriteStderr("TrackControl or HandleControlClick: exception in tracker function\\n");
159161
}
162+
163+
static int
164+
setcallback(self, which, callback, uppp)
165+
ControlObject *self;
166+
OSType which;
167+
PyObject *callback;
168+
UniversalProcPtr *uppp;
169+
{
170+
char keybuf[9];
171+
172+
if ( which == kControlUserPaneDrawProcTag )
173+
*uppp = mydrawproc_upp;
174+
else if ( which == kControlUserPaneIdleProcTag )
175+
*uppp = myidleproc_upp;
176+
else
177+
return -1;
178+
/* Only now do we test for clearing of the callback: */
179+
if ( callback == Py_None )
180+
*uppp = NULL;
181+
/* Create the dict if it doesn't exist yet (so we don't get such a dict for every control) */
182+
if ( self->ob_callbackdict == NULL )
183+
if ( (self->ob_callbackdict = PyDict_New()) == NULL )
184+
return -1;
185+
/* And store the Python callback */
186+
sprintf(keybuf, "%x", which);
187+
if (PyDict_SetItemString(self->ob_callbackdict, keybuf, callback) < 0)
188+
return -1;
189+
return 0;
190+
}
191+
192+
static PyObject *
193+
callcallback(self, which, arglist)
194+
ControlObject *self;
195+
OSType which;
196+
PyObject *arglist;
197+
{
198+
char keybuf[9];
199+
PyObject *func, *rv;
200+
201+
sprintf(keybuf, "%x", which);
202+
if ( self->ob_callbackdict == NULL ||
203+
(func = PyDict_GetItemString(self->ob_callbackdict, keybuf)) == NULL ) {
204+
PySys_WriteStderr("Control callback without callback object\\n");
205+
return NULL;
206+
}
207+
rv = PyEval_CallObject(func, arglist);
208+
if ( rv == NULL )
209+
PySys_WriteStderr("Exception in control callback handler\\n");
210+
return rv;
211+
}
212+
213+
static pascal void
214+
mydrawproc(ControlHandle control, SInt16 part)
215+
{
216+
ControlObject *ctl_obj;
217+
PyObject *arglist, *rv;
218+
219+
ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
220+
arglist = Py_BuildValue("Oh", ctl_obj, part);
221+
rv = callcallback(ctl_obj, kControlUserPaneDrawProcTag, arglist);
222+
Py_XDECREF(arglist);
223+
Py_XDECREF(rv);
224+
}
225+
226+
static pascal void
227+
myidleproc(ControlHandle control)
228+
{
229+
ControlObject *ctl_obj;
230+
PyObject *arglist, *rv;
231+
232+
ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
233+
arglist = Py_BuildValue("O", ctl_obj);
234+
rv = callcallback(ctl_obj, kControlUserPaneIdleProcTag, arglist);
235+
Py_XDECREF(arglist);
236+
Py_XDECREF(rv);
237+
}
238+
160239
"""
161240

162241
initstuff = initstuff + """
163242
mytracker_upp = NewControlActionProc(mytracker);
243+
mydrawproc_upp = NewControlUserPaneDrawProc(mydrawproc);
244+
myidleproc_upp = NewControlUserPaneDrawProc(myidleproc);
164245
"""
165246

166247
class MyObjectDefinition(ObjectIdentityMixin, GlobalObjectDefinition):
248+
def outputStructMembers(self):
249+
GlobalObjectDefinition.outputStructMembers(self)
250+
Output("PyObject *ob_callbackdict;")
167251
def outputCheckNewArg(self):
168252
Output("if (itself == NULL) return PyMac_Error(resNotFound);")
169253
def outputInitStructMembers(self):
170254
GlobalObjectDefinition.outputInitStructMembers(self)
171255
Output("SetControlReference(itself, (long)it);")
256+
Output("it->ob_callbackdict = NULL;")
172257
def outputCleanupStructMembers(self):
258+
Output("Py_XDECREF(self->ob_callbackdict);")
173259
Output("if (self->ob_itself)SetControlReference(self->ob_itself, (long)0); /* Make it forget about us */")
174260

175261
# Create the generator groups and link them
@@ -404,6 +490,38 @@ def outputCleanupStructMembers(self):
404490
f.docstring = lambda: "(part, type) -> ResObj"
405491
object.add(f)
406492

493+
# Manual Generator for SetControlDataCallback
494+
setcontroldatacallback_body = """
495+
OSErr _err;
496+
ControlPartCode inPart;
497+
ResType inTagName;
498+
PyObject *callback;
499+
UniversalProcPtr *c_callback;
500+
501+
if (!PyArg_ParseTuple(_args, "hO&O",
502+
&inPart,
503+
PyMac_GetOSType, &inTagName,
504+
&callback))
505+
return NULL;
506+
507+
if ( setcallback(_self, inTagName, callback, &c_callback) < 0 )
508+
return NULL;
509+
_err = SetControlData(_self->ob_itself,
510+
inPart,
511+
inTagName,
512+
sizeof(c_callback),
513+
(Ptr)&c_callback);
514+
515+
if (_err != noErr)
516+
return PyMac_Error(_err);
517+
_res = Py_None;
518+
return _res;
519+
"""
520+
521+
f = ManualGenerator("SetControlDataCallback", setcontroldatacallback_body);
522+
f.docstring = lambda: "(callbackfunc) -> None"
523+
object.add(f)
524+
407525
# And manual generators to get/set popup menu information
408526
getpopupdata_body = """
409527
PopupPrivateDataHandle hdl;

0 commit comments

Comments
 (0)