-
-
Notifications
You must be signed in to change notification settings - Fork 192
Add get_surface()
for Window class
#2350
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
21bd3ba
b16dbb7
e49540f
a4ceb6b
50d733d
4e937e7
7783bc1
c586b88
4b787f1
48b7fa6
5af5e6a
892e8dc
f998095
8086695
23aa287
025aaec
018b27c
146bd31
e48d714
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -119,9 +119,89 @@ window_destroy(pgWindowObject *self, PyObject *_null) | |
SDL_DestroyWindow(self->_win); | ||
self->_win = NULL; | ||
} | ||
if (self->surf) { | ||
// Set the internal surface to NULL to make pygame surface invalid | ||
// since this surface will be deallocated by SDL when the window is | ||
// destroyed. | ||
self->surf->surf = NULL; | ||
yunline marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Py_DECREF(self->surf); | ||
self->surf = NULL; | ||
} | ||
Py_RETURN_NONE; | ||
} | ||
|
||
static PyObject * | ||
window_get_surface(pgWindowObject *self) | ||
{ | ||
PyObject *surf = NULL; | ||
SDL_Surface *_surf; | ||
|
||
if (self->_is_borrowed) { | ||
surf = (PyObject *)pg_GetDefaultWindowSurface(); | ||
if (!surf) { | ||
return RAISE(pgExc_SDLError, | ||
"display.set_mode has not been called yet."); | ||
} | ||
Py_INCREF(surf); | ||
return surf; | ||
} | ||
|
||
_surf = SDL_GetWindowSurface(self->_win); | ||
if (!_surf) { | ||
return RAISE(pgExc_SDLError, SDL_GetError()); | ||
} | ||
if (self->surf == NULL) { | ||
self->surf = pgSurface_New2(_surf, SDL_FALSE); | ||
if (!self->surf) | ||
return NULL; | ||
} | ||
self->surf->surf = _surf; | ||
Py_INCREF(self->surf); | ||
return (PyObject *)self->surf; | ||
} | ||
|
||
static PyObject * | ||
window_update_from_surface(pgWindowObject *self) | ||
{ | ||
int result; | ||
|
||
Py_BEGIN_ALLOW_THREADS; | ||
result = SDL_UpdateWindowSurface(self->_win); | ||
Py_END_ALLOW_THREADS; | ||
if (result) | ||
return RAISE(pgExc_SDLError, SDL_GetError()); | ||
Py_RETURN_NONE; | ||
} | ||
|
||
// Callback function for surface auto resize | ||
static int SDLCALL | ||
_resize_event_watch(void *userdata, SDL_Event *event) | ||
{ | ||
pgWindowObject *event_window_pg; | ||
SDL_Window *event_window; | ||
if ((event->type != SDL_WINDOWEVENT)) | ||
return 0; | ||
if (event->window.event != SDL_WINDOWEVENT_SIZE_CHANGED) | ||
return 0; | ||
event_window = SDL_GetWindowFromID(event->window.windowID); | ||
event_window_pg = SDL_GetWindowData(event_window, "pg_window"); | ||
|
||
if (!event_window_pg) | ||
return 0; | ||
|
||
if (event_window_pg->_is_borrowed) { | ||
// have been handled by event watch in display.c | ||
return 0; | ||
} | ||
|
||
if (!event_window_pg->surf) | ||
return 0; | ||
|
||
event_window_pg->surf->surf = SDL_GetWindowSurface(event_window); | ||
return 0; | ||
} | ||
|
||
static PyObject * | ||
window_set_windowed(pgWindowObject *self, PyObject *_null) | ||
{ | ||
|
@@ -615,6 +695,15 @@ window_dealloc(pgWindowObject *self, PyObject *_null) | |
SDL_SetWindowData(self->_win, "pg_window", NULL); | ||
} | ||
} | ||
if (self->surf) { | ||
// Set the internal surface to NULL to make pygame surface invalid | ||
// since this surface will be deallocated by SDL when the window is | ||
// destroyed. | ||
self->surf->surf = NULL; | ||
|
||
Py_DECREF(self->surf); | ||
} | ||
|
||
Py_TYPE(self)->tp_free(self); | ||
} | ||
|
||
|
@@ -815,6 +904,7 @@ window_init(pgWindowObject *self, PyObject *args, PyObject *kwargs) | |
} | ||
self->_win = _win; | ||
self->_is_borrowed = SDL_FALSE; | ||
self->surf = NULL; | ||
|
||
SDL_SetWindowData(_win, "pg_window", self); | ||
|
||
|
@@ -880,6 +970,20 @@ window_repr(pgWindowObject *self) | |
return PyUnicode_FromFormat("<Window(title='%s', id=%d)>", title, win_id); | ||
} | ||
|
||
static PyObject * | ||
_window_internal_mod_init(PyObject *self, PyObject *_null) | ||
{ | ||
SDL_AddEventWatch(_resize_event_watch, NULL); | ||
Py_RETURN_NONE; | ||
} | ||
|
||
static PyObject * | ||
_window_internal_mod_quit(PyObject *self, PyObject *_null) | ||
{ | ||
SDL_DelEventWatch(_resize_event_watch, NULL); | ||
Py_RETURN_NONE; | ||
} | ||
|
||
static PyMethodDef window_methods[] = { | ||
{"destroy", (PyCFunction)window_destroy, METH_NOARGS, | ||
DOC_SDL2_VIDEO_WINDOW_DESTROY}, | ||
|
@@ -903,6 +1007,10 @@ static PyMethodDef window_methods[] = { | |
DOC_SDL2_VIDEO_WINDOW_SETMODALFOR}, | ||
{"set_icon", (PyCFunction)window_set_icon, METH_O, | ||
DOC_SDL2_VIDEO_WINDOW_SETICON}, | ||
{"update_from_surface", (PyCFunction)window_update_from_surface, | ||
METH_NOARGS, DOC_SDL2_VIDEO_WINDOW_UPDATEFROMSURFACE}, | ||
{"get_surface", (PyCFunction)window_get_surface, METH_NOARGS, | ||
DOC_SDL2_VIDEO_WINDOW_GETSURFACE}, | ||
{"from_display_module", (PyCFunction)window_from_display_module, | ||
METH_CLASS | METH_NOARGS, DOC_SDL2_VIDEO_WINDOW_FROMDISPLAYMODULE}, | ||
{NULL, NULL, 0, NULL}}; | ||
|
@@ -959,6 +1067,10 @@ static PyTypeObject pgWindow_Type = { | |
static PyMethodDef _window_methods[] = { | ||
{"get_grabbed_window", (PyCFunction)get_grabbed_window, METH_NOARGS, | ||
DOC_SDL2_VIDEO_GETGRABBEDWINDOW}, | ||
{"_internal_mod_init", (PyCFunction)_window_internal_mod_init, METH_NOARGS, | ||
"auto initialize for _window module"}, | ||
{"_internal_mod_quit", (PyCFunction)_window_internal_mod_quit, METH_NOARGS, | ||
"auto quit for _window module"}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes these hooks look good, but I think they should be called from the display init/quit hook instead of the base pygame init/quit function (like how event and time are handled right now). This is so that if someone only does There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
{NULL, NULL, 0, NULL}}; | ||
|
||
MODINIT_DEFINE(_window) | ||
|
Uh oh!
There was an error while loading. Please reload this page.