Window objects now also have an AutoDispose funcpointer (set for our windows, cleared for foreign windows). Needed mainly for Carbon (where we don't know about the windows belonging to our dialogs).

Fixed a few calls that return an ExistingWindow.
This commit is contained in:
Jack Jansen 2000-08-25 22:17:51 +00:00
parent 0c1836f13b
commit 0aee0e61f8
3 changed files with 61 additions and 23 deletions

View File

@ -9,6 +9,12 @@
#include "pymactoolbox.h" #include "pymactoolbox.h"
#include <Windows.h> #include <Windows.h>
/* Function to dispose a window, with a "normal" calling sequence */
static void
PyMac_AutoDisposeWindow(WindowPtr w)
{
DisposeWindow(w);
}
static PyObject *Win_Error; static PyObject *Win_Error;
@ -21,6 +27,7 @@ PyTypeObject Window_Type;
typedef struct WindowObject { typedef struct WindowObject {
PyObject_HEAD PyObject_HEAD
WindowPtr ob_itself; WindowPtr ob_itself;
void (*ob_freeit)(WindowPtr ptr);
} WindowObject; } WindowObject;
PyObject *WinObj_New(itself) PyObject *WinObj_New(itself)
@ -32,6 +39,7 @@ PyObject *WinObj_New(itself)
if (it == NULL) return NULL; if (it == NULL) return NULL;
it->ob_itself = itself; it->ob_itself = itself;
SetWRefCon(itself, (long)it); SetWRefCon(itself, (long)it);
it->ob_freeit = PyMac_AutoDisposeWindow;
return (PyObject *)it; return (PyObject *)it;
} }
WinObj_Convert(v, p_itself) WinObj_Convert(v, p_itself)
@ -60,7 +68,12 @@ WinObj_Convert(v, p_itself)
static void WinObj_dealloc(self) static void WinObj_dealloc(self)
WindowObject *self; WindowObject *self;
{ {
DisposeWindow(self->ob_itself); if (self->ob_itself) SetWRefCon(self->ob_itself, 0);
if (self->ob_freeit && self->ob_itself)
{
self->ob_freeit(self->ob_itself);
}
self->ob_itself = NULL;
PyMem_DEL(self); PyMem_DEL(self);
} }
@ -2079,7 +2092,7 @@ static PyObject *Win_FrontNonFloatingWindow(_self, _args)
return NULL; return NULL;
_rv = FrontNonFloatingWindow(); _rv = FrontNonFloatingWindow();
_res = Py_BuildValue("O&", _res = Py_BuildValue("O&",
WinObj_New, _rv); WinObj_WhichWindow, _rv);
return _res; return _res;
} }
@ -2492,15 +2505,18 @@ WinObj_WhichWindow(w)
{ {
PyObject *it; PyObject *it;
/* XXX What if we find a stdwin window or a window belonging if (w == NULL) {
to some other package? */
if (w == NULL)
it = NULL;
else
it = (PyObject *) GetWRefCon(w);
if (it == NULL || ((WindowObject *)it)->ob_itself != w)
it = Py_None; it = Py_None;
Py_INCREF(it); Py_INCREF(it);
} else {
it = (PyObject *) GetWRefCon(w);
if (it == NULL || ((WindowObject *)it)->ob_itself != w) {
it = WinObj_New(w);
((WindowObject *)it)->ob_freeit = NULL;
} else {
Py_INCREF(it);
}
}
return it; return it;
} }

View File

@ -100,6 +100,10 @@ class MyScanner(Scanner):
[("ExistingWindowPtr", "*", "*")]), [("ExistingWindowPtr", "*", "*")]),
([("WindowRef", "FrontWindow", "ReturnMode")], # Ditto ([("WindowRef", "FrontWindow", "ReturnMode")], # Ditto
[("ExistingWindowPtr", "*", "*")]), [("ExistingWindowPtr", "*", "*")]),
([("WindowPtr", "FrontNonFloatingWindow", "ReturnMode")],
[("ExistingWindowPtr", "*", "*")]),
([("WindowRef", "FrontNonFloatingWindow", "ReturnMode")], # Ditto
[("ExistingWindowPtr", "*", "*")]),
] ]
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -49,6 +49,12 @@ PropertyTag = OSTypeType("PropertyTag")
includestuff = includestuff + """ includestuff = includestuff + """
#include <%s>""" % MACHEADERFILE + """ #include <%s>""" % MACHEADERFILE + """
/* Function to dispose a window, with a "normal" calling sequence */
static void
PyMac_AutoDisposeWindow(WindowPtr w)
{
DisposeWindow(w);
}
""" """
finalstuff = finalstuff + """ finalstuff = finalstuff + """
@ -60,15 +66,18 @@ WinObj_WhichWindow(w)
{ {
PyObject *it; PyObject *it;
/* XXX What if we find a stdwin window or a window belonging if (w == NULL) {
to some other package? */
if (w == NULL)
it = NULL;
else
it = (PyObject *) GetWRefCon(w);
if (it == NULL || ((WindowObject *)it)->ob_itself != w)
it = Py_None; it = Py_None;
Py_INCREF(it); Py_INCREF(it);
} else {
it = (PyObject *) GetWRefCon(w);
if (it == NULL || ((WindowObject *)it)->ob_itself != w) {
it = WinObj_New(w);
((WindowObject *)it)->ob_freeit = NULL;
} else {
Py_INCREF(it);
}
}
return it; return it;
} }
""" """
@ -76,22 +85,31 @@ WinObj_WhichWindow(w)
class MyObjectDefinition(GlobalObjectDefinition): class MyObjectDefinition(GlobalObjectDefinition):
def outputCheckNewArg(self): def outputCheckNewArg(self):
Output("if (itself == NULL) return PyMac_Error(resNotFound);") Output("if (itself == NULL) return PyMac_Error(resNotFound);")
def outputStructMembers(self):
GlobalObjectDefinition.outputStructMembers(self)
Output("void (*ob_freeit)(%s ptr);", self.itselftype)
def outputInitStructMembers(self): def outputInitStructMembers(self):
GlobalObjectDefinition.outputInitStructMembers(self) GlobalObjectDefinition.outputInitStructMembers(self)
Output("SetWRefCon(itself, (long)it);") Output("SetWRefCon(itself, (long)it);")
Output("it->ob_freeit = PyMac_AutoDisposeWindow;")
def outputCheckConvertArg(self): def outputCheckConvertArg(self):
Output("#if !TARGET_API_MAC_CARBON")
OutLbrace("if (DlgObj_Check(v))") OutLbrace("if (DlgObj_Check(v))")
Output("*p_itself = ((WindowObject *)v)->ob_itself;") Output("*p_itself = DlgObj_ConvertToWindow(v);")
Output("return 1;") Output("return 1;")
OutRbrace() OutRbrace()
Output("#endif")
Out(""" Out("""
if (v == Py_None) { *p_itself = NULL; return 1; } if (v == Py_None) { *p_itself = NULL; return 1; }
if (PyInt_Check(v)) { *p_itself = (WindowPtr)PyInt_AsLong(v); return 1; } if (PyInt_Check(v)) { *p_itself = (WindowPtr)PyInt_AsLong(v); return 1; }
""") """)
def outputFreeIt(self, itselfname): def outputCleanupStructMembers(self):
Output("DisposeWindow(%s);", itselfname) Output("if (self->ob_itself) SetWRefCon(self->ob_itself, 0);")
Output("if (self->ob_freeit && self->ob_itself)")
OutLbrace()
Output("self->ob_freeit(self->ob_itself);")
OutRbrace()
Output("self->ob_itself = NULL;")
## def outputFreeIt(self, itselfname):
## Output("DisposeWindow(%s);", itselfname)
# From here on it's basically all boiler plate... # From here on it's basically all boiler plate...
# Create the generator groups and link them # Create the generator groups and link them