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

Skip to content

Commit dd4830a

Browse files
committed
More List Manager interfacing:
- CreateCustomList(): write LDEF's in Python! (carbon + classic) - list.LGetCellDataLocation() (Jack: what's with this _WIN32/pywintoolbox.h stuff?)
1 parent 7a33d8b commit dd4830a

3 files changed

Lines changed: 363 additions & 23 deletions

File tree

Mac/Modules/list/_Listmodule.c

Lines changed: 187 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,8 @@
55

66

77

8-
#ifdef _WIN32
9-
#include "pywintoolbox.h"
10-
#else
118
#include "macglue.h"
129
#include "pymactoolbox.h"
13-
#endif
1410

1511
/* Macro to test whether a weak-loaded CFM function exists */
1612
#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\
@@ -62,6 +58,42 @@ extern int _ListObj_Convert(PyObject *, ListHandle *);
6258
#define as_List(x) ((ListHandle)x)
6359
#define as_Resource(lh) ((Handle)lh)
6460

61+
static ListDefUPP myListDefFunctionUPP;
62+
63+
#if !TARGET_API_MAC_CARBON
64+
65+
#define kJumpAbs 0x4EF9
66+
67+
#pragma options align=mac68k
68+
typedef struct {
69+
short jmpabs; /* 4EF9 */
70+
ListDefUPP theUPP; /* 00000000 */
71+
} LDEFStub, **LDEFStubHandle;
72+
#pragma options align=reset
73+
74+
static OSErr installLDEFStub(ListHandle list) {
75+
LDEFStubHandle stubH;
76+
77+
stubH = (LDEFStubHandle)NewHandleClear(sizeof(LDEFStub));
78+
if (stubH == NULL)
79+
return MemError();
80+
81+
(*stubH)->jmpabs = kJumpAbs;
82+
(*stubH)->theUPP = myListDefFunctionUPP;
83+
HLock((Handle) stubH);
84+
85+
(*list)->listDefProc = (Handle)stubH;
86+
return noErr;
87+
}
88+
89+
static void removeLDEFStub(ListHandle list) {
90+
if ((*list)->listDefProc)
91+
DisposeHandle((Handle)(*list)->listDefProc);
92+
(*list)->listDefProc = NULL;
93+
}
94+
95+
#endif
96+
6597
static PyObject *List_Error;
6698

6799
/* ------------------------ Object type List ------------------------ */
@@ -73,6 +105,8 @@ PyTypeObject List_Type;
73105
typedef struct ListObject {
74106
PyObject_HEAD
75107
ListHandle ob_itself;
108+
PyObject *ob_ldef_func;
109+
int ob_have_ldef_stub;
76110
int ob_must_be_disposed;
77111
} ListObject;
78112

@@ -86,7 +120,10 @@ PyObject *ListObj_New(ListHandle itself)
86120
it = PyObject_NEW(ListObject, &List_Type);
87121
if (it == NULL) return NULL;
88122
it->ob_itself = itself;
123+
it->ob_ldef_func = NULL;
124+
it->ob_have_ldef_stub = 0;
89125
it->ob_must_be_disposed = 1;
126+
SetListRefCon(itself, (long)it);
90127
return (PyObject *)it;
91128
}
92129
int ListObj_Convert(PyObject *v, ListHandle *p_itself)
@@ -102,6 +139,12 @@ int ListObj_Convert(PyObject *v, ListHandle *p_itself)
102139

103140
static void ListObj_dealloc(ListObject *self)
104141
{
142+
Py_XDECREF(self->ob_ldef_func);
143+
self->ob_ldef_func = NULL;
144+
#if !TARGET_API_MAC_CARBON
145+
if (self->ob_have_ldef_stub) removeLDEFStub(self->ob_itself);
146+
#endif
147+
SetListRefCon(self->ob_itself, (long)0);
105148
if (self->ob_must_be_disposed && self->ob_itself) LDispose(self->ob_itself);
106149
PyMem_DEL(self);
107150
}
@@ -476,6 +519,25 @@ static PyObject *ListObj_LDraw(ListObject *_self, PyObject *_args)
476519
return _res;
477520
}
478521

522+
static PyObject *ListObj_LGetCellDataLocation(ListObject *_self, PyObject *_args)
523+
{
524+
PyObject *_res = NULL;
525+
short offset;
526+
short len;
527+
Point theCell;
528+
if (!PyArg_ParseTuple(_args, "O&",
529+
PyMac_GetPoint, &theCell))
530+
return NULL;
531+
LGetCellDataLocation(&offset,
532+
&len,
533+
theCell,
534+
_self->ob_itself);
535+
_res = Py_BuildValue("hh",
536+
offset,
537+
len);
538+
return _res;
539+
}
540+
479541
static PyObject *ListObj_as_Resource(ListObject *_self, PyObject *_args)
480542
{
481543
PyObject *_res = NULL;
@@ -533,6 +595,8 @@ static PyMethodDef ListObj_methods[] = {
533595
"(Boolean setIt, Point theCell) -> None"},
534596
{"LDraw", (PyCFunction)ListObj_LDraw, 1,
535597
"(Point theCell) -> None"},
598+
{"LGetCellDataLocation", (PyCFunction)ListObj_LGetCellDataLocation, 1,
599+
"(Point theCell) -> (short offset, short len)"},
536600
{"as_Resource", (PyCFunction)ListObj_as_Resource, 1,
537601
"() -> (Handle _rv)"},
538602
{NULL, NULL, 0}
@@ -545,9 +609,9 @@ static PyObject *ListObj_getattr(ListObject *self, char *name)
545609
{
546610
/* XXXX Should we HLock() here?? */
547611
if ( strcmp(name, "listFlags") == 0 )
548-
return Py_BuildValue("l", (long)(*self->ob_itself)->listFlags & 0xff);
612+
return Py_BuildValue("l", (long)GetListFlags(self->ob_itself) & 0xff);
549613
if ( strcmp(name, "selFlags") == 0 )
550-
return Py_BuildValue("l", (long)(*self->ob_itself)->selFlags & 0xff);
614+
return Py_BuildValue("l", (long)GetListSelectionFlags(self->ob_itself) & 0xff);
551615
}
552616
return Py_FindMethodInChain(&ListObj_chain, (PyObject *)self, name);
553617
}
@@ -561,12 +625,11 @@ ListObj_setattr(ListObject *self, char *name, PyObject *value)
561625
return -1;
562626
intval = PyInt_AsLong(value);
563627
if (strcmp(name, "listFlags") == 0 ) {
564-
/* XXXX Should we HLock the handle here?? */
565-
(*self->ob_itself)->listFlags = intval;
628+
SetListFlags(self->ob_itself, intval);
566629
return 0;
567630
}
568631
if (strcmp(name, "selFlags") == 0 ) {
569-
(*self->ob_itself)->selFlags = intval;
632+
SetListSelectionFlags(self->ob_itself, intval);
570633
return 0;
571634
}
572635
return -1;
@@ -601,6 +664,79 @@ PyTypeObject List_Type = {
601664
/* ---------------------- End object type List ---------------------- */
602665

603666

667+
static PyObject *List_CreateCustomList(PyObject *_self, PyObject *_args)
668+
{
669+
PyObject *_res = NULL;
670+
Rect rView;
671+
Rect dataBounds;
672+
Point cellSize;
673+
674+
PyObject *listDefFunc;
675+
ListDefSpec theSpec;
676+
WindowPtr theWindow;
677+
Boolean drawIt;
678+
Boolean hasGrow;
679+
Boolean scrollHoriz;
680+
Boolean scrollVert;
681+
ListHandle outList;
682+
683+
if (!PyArg_ParseTuple(_args, "O&O&O&(iO)O&bbbb",
684+
PyMac_GetRect, &rView,
685+
PyMac_GetRect, &dataBounds,
686+
PyMac_GetPoint, &cellSize,
687+
&theSpec.defType, &listDefFunc,
688+
WinObj_Convert, &theWindow,
689+
&drawIt,
690+
&hasGrow,
691+
&scrollHoriz,
692+
&scrollVert))
693+
return NULL;
694+
695+
696+
#if TARGET_API_MAC_CARBON
697+
/* Carbon applications use the CreateCustomList API */
698+
theSpec.u.userProc = myListDefFunctionUPP;
699+
CreateCustomList(&rView,
700+
&dataBounds,
701+
cellSize,
702+
&theSpec,
703+
theWindow,
704+
drawIt,
705+
hasGrow,
706+
scrollHoriz,
707+
scrollVert,
708+
&outList);
709+
710+
#else
711+
/* pre-Carbon applications set the address in the LDEF
712+
to a routine descriptor referring to their list
713+
definition routine. */
714+
outList = LNew(&rView,
715+
&dataBounds,
716+
cellSize,
717+
0,
718+
theWindow,
719+
drawIt, /* XXX must be false */
720+
hasGrow,
721+
scrollHoriz,
722+
scrollVert);
723+
if (installLDEFStub(outList) != noErr) {
724+
PyErr_SetString(PyExc_MemoryError, "can't create LDEF stub");
725+
return NULL;
726+
}
727+
#endif
728+
729+
_res = ListObj_New(outList);
730+
if (_res == NULL)
731+
return NULL;
732+
Py_INCREF(listDefFunc);
733+
((ListObject*)_res)->ob_ldef_func = listDefFunc;
734+
#if !TARGET_API_MAC_CARBON
735+
((ListObject*)_res)->ob_have_ldef_stub = 1;
736+
#endif
737+
return _res;
738+
}
739+
604740
static PyObject *List_LNew(PyObject *_self, PyObject *_args)
605741
{
606742
PyObject *_res = NULL;
@@ -937,6 +1073,8 @@ static PyObject *List_as_List(PyObject *_self, PyObject *_args)
9371073
}
9381074

9391075
static PyMethodDef List_methods[] = {
1076+
{"CreateCustomList", (PyCFunction)List_CreateCustomList, 1,
1077+
"(Rect rView, Rect dataBounds, Point cellSize, ListDefSpec theSpec, WindowPtr theWindow, Boolean drawIt, Boolean hasGrow, Boolean scrollHoriz, Boolean scrollVert) -> (ListHandle outList)"},
9401078
{"LNew", (PyCFunction)List_LNew, 1,
9411079
"(Rect rView, Rect dataBounds, Point cSize, short theProc, WindowPtr theWindow, Boolean drawIt, Boolean hasGrow, Boolean scrollHoriz, Boolean scrollVert) -> (ListHandle _rv)"},
9421080
{"GetListPort", (PyCFunction)List_GetListPort, 1,
@@ -984,6 +1122,42 @@ static PyMethodDef List_methods[] = {
9841122

9851123

9861124

1125+
static void myListDefFunction(SInt16 message,
1126+
Boolean selected,
1127+
Rect *cellRect,
1128+
Cell theCell,
1129+
SInt16 dataOffset,
1130+
SInt16 dataLen,
1131+
ListHandle theList)
1132+
{
1133+
PyObject *listDefFunc, *args, *rv=NULL;
1134+
ListObject *self;
1135+
1136+
self = (ListObject*)GetListRefCon(theList);
1137+
if (self == NULL || self->ob_itself != theList)
1138+
return; /* nothing we can do */
1139+
listDefFunc = self->ob_ldef_func;
1140+
if (listDefFunc == NULL)
1141+
return; /* nothing we can do */
1142+
args = Py_BuildValue("hbO&O&hhO", message,
1143+
selected,
1144+
PyMac_BuildRect, cellRect,
1145+
PyMac_BuildPoint, theCell,
1146+
dataOffset,
1147+
dataLen,
1148+
self);
1149+
if (args != NULL) {
1150+
rv = PyEval_CallObject(listDefFunc, args);
1151+
Py_DECREF(args);
1152+
}
1153+
if (rv == NULL) {
1154+
PySys_WriteStderr("error in list definition callback:\n");
1155+
PyErr_Print();
1156+
} else {
1157+
Py_DECREF(rv);
1158+
}
1159+
}
1160+
9871161

9881162
void init_List(void)
9891163
{
@@ -992,8 +1166,10 @@ void init_List(void)
9921166

9931167

9941168

995-
PyMac_INIT_TOOLBOX_OBJECT_NEW(ListHandle, ListObj_New);
996-
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ListHandle, ListObj_Convert);
1169+
myListDefFunctionUPP = NewListDefUPP((ListDefProcPtr)myListDefFunction);
1170+
1171+
PyMac_INIT_TOOLBOX_OBJECT_NEW(ListHandle, ListObj_New);
1172+
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ListHandle, ListObj_Convert);
9971173

9981174

9991175
m = Py_InitModule("_List", List_methods);

Mac/Modules/list/listscan.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ def makeblacklistnames(self):
3939
return [
4040
"LDispose", # Done by removing the object
4141
"LSearch", # We don't want to handle procs just yet
42-
"LGetCellDataLocation", # What does this do??
42+
"CreateCustomList", # done manually
43+
"SetListDefinitionProc",
4344

4445
# These have funny argument/return values
4546
"GetListViewBounds",
@@ -54,10 +55,7 @@ def makeblacklistnames(self):
5455

5556
def makeblacklisttypes(self):
5657
return [
57-
'ListDefSpec', # Too difficult for now
58-
'ListDefSpec_ptr', # ditto
59-
"ListDefUPP",
60-
"ListClickLoopUPP",
58+
"ListClickLoopUPP", # Too difficult for now
6159
]
6260

6361
def makerepairinstructions(self):

0 commit comments

Comments
 (0)