Added test program for SDL_CreateWindowFrom()
Make sure OpenGL library is loaded before working with OpenGL windows,
even those created with SDL_CreateWindowFrom()
--- a/include/SDL_video.h Sun Feb 08 15:35:06 2009 +0000
+++ b/include/SDL_video.h Mon Feb 09 05:32:12 2009 +0000
@@ -111,7 +111,8 @@
SDL_WINDOW_MAXIMIZED = 0x00000040, /**< maximized */
SDL_WINDOW_INPUT_GRABBED = 0x00000100, /**< window has grabbed input focus */
SDL_WINDOW_INPUT_FOCUS = 0x00000200, /**< window has input focus */
- SDL_WINDOW_MOUSE_FOCUS = 0x00000400 /**< window has mouse focus */
+ SDL_WINDOW_MOUSE_FOCUS = 0x00000400, /**< window has mouse focus */
+ SDL_WINDOW_FOREIGN = 0x00000800 /**< window not created by SDL */
} SDL_WindowFlags;
/**
@@ -1363,6 +1364,7 @@
* your program from the dynamic library using SDL_GL_GetProcAddress().
*
* \sa SDL_GL_GetProcAddress()
+ * \sa SDL_GL_UnloadLibrary()
*/
extern DECLSPEC int SDLCALL SDL_GL_LoadLibrary(const char *path);
@@ -1374,6 +1376,15 @@
extern DECLSPEC void *SDLCALL SDL_GL_GetProcAddress(const char *proc);
/**
+ * \fn void SDL_GL_UnloadLibrary(void)
+ *
+ * \brief Unload the OpenGL library previously loaded by SDL_GL_LoadLibrary()
+ *
+ * \sa SDL_GL_LoadLibrary()
+ */
+extern DECLSPEC void SDLCALL SDL_GL_UnloadLibrary(void);
+
+/**
* \fn SDL_bool SDL_GL_ExtensionSupported(const char *extension)
*
* \brief Return true if an OpenGL extension is supported for the current context.
--- a/src/video/SDL_sysvideo.h Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/SDL_sysvideo.h Mon Feb 09 05:32:12 2009 +0000
@@ -260,6 +260,7 @@
*/
int (*GL_LoadLibrary) (_THIS, const char *path);
void *(*GL_GetProcAddress) (_THIS, const char *proc);
+ void (*GL_UnloadLibrary) (_THIS);
SDL_GLContext(*GL_CreateContext) (_THIS, SDL_Window * window);
int (*GL_MakeCurrent) (_THIS, SDL_Window * window, SDL_GLContext context);
int (*GL_SetSwapInterval) (_THIS, int interval);
--- a/src/video/SDL_video.c Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/SDL_video.c Mon Feb 09 05:32:12 2009 +0000
@@ -762,9 +762,12 @@
SDL_UninitializedVideo();
return 0;
}
- if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
- SDL_SetError("No OpenGL support in video driver");
- return 0;
+ if (flags & SDL_WINDOW_OPENGL) {
+ if (!_this->GL_CreateContext) {
+ SDL_SetError("No OpenGL support in video driver");
+ return 0;
+ }
+ SDL_GL_LoadLibrary(NULL);
}
SDL_zero(window);
window.id = _this->next_object_id++;
@@ -776,6 +779,9 @@
window.display = _this->current_display;
if (_this->CreateWindow && _this->CreateWindow(_this, &window) < 0) {
+ if (flags & SDL_WINDOW_OPENGL) {
+ SDL_GL_UnloadLibrary();
+ }
return 0;
}
display = &SDL_CurrentDisplay;
@@ -786,6 +792,9 @@
if (_this->DestroyWindow) {
_this->DestroyWindow(_this, &window);
}
+ if (flags & SDL_WINDOW_OPENGL) {
+ SDL_GL_UnloadLibrary();
+ }
return 0;
}
windows[num_windows] = window;
@@ -824,6 +833,7 @@
SDL_zero(window);
window.id = _this->next_object_id++;
window.display = _this->current_display;
+ window.flags = SDL_WINDOW_FOREIGN;
if (!_this->CreateWindowFrom ||
_this->CreateWindowFrom(_this, &window, data) < 0) {
@@ -852,24 +862,48 @@
int
SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
{
+ const Uint32 allowed_flags = (SDL_WINDOW_FULLSCREEN |
+ SDL_WINDOW_OPENGL |
+ SDL_WINDOW_BORDERLESS |
+ SDL_WINDOW_RESIZABLE |
+ SDL_WINDOW_INPUT_GRABBED);
char *title = window->title;
if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
SDL_SetError("No OpenGL support in video driver");
return -1;
}
- if (_this->DestroyWindow) {
+ if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) {
+ if (flags & SDL_WINDOW_OPENGL) {
+ SDL_GL_LoadLibrary(NULL);
+ } else {
+ SDL_GL_UnloadLibrary();
+ }
+ }
+
+ if (window->flags & SDL_WINDOW_FOREIGN) {
+ /* Can't destroy and re-create foreign windows, hrm */
+ flags |= SDL_WINDOW_FOREIGN;
+ } else {
+ flags &= ~SDL_WINDOW_FOREIGN;
+ }
+
+ if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) {
_this->DestroyWindow(_this, window);
}
+
window->title = NULL;
- window->flags =
- (flags &
- ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED | SDL_WINDOW_SHOWN |
- SDL_WINDOW_INPUT_GRABBED));
+ window->flags = (flags & allowed_flags);
- if (_this->CreateWindow && _this->CreateWindow(_this, window) < 0) {
- return -1;
+ if (_this->CreateWindow && !(flags & SDL_WINDOW_FOREIGN)) {
+ if (_this->CreateWindow(_this, window) < 0) {
+ if (flags & SDL_WINDOW_OPENGL) {
+ SDL_GL_UnloadLibrary();
+ }
+ return -1;
+ }
}
+
if (title) {
SDL_SetWindowTitle(window->id, title);
SDL_free(title);
@@ -1352,6 +1386,9 @@
if (_this->DestroyWindow) {
_this->DestroyWindow(_this, window);
}
+ if (window->flags & SDL_WINDOW_OPENGL) {
+ SDL_GL_UnloadLibrary();
+ }
if (j != display->num_windows - 1) {
SDL_memcpy(&display->windows[i],
&display->windows[i + 1],
@@ -1543,6 +1580,7 @@
SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
{
SDL_TextureID textureID;
+ Uint32 requested_format = format;
SDL_PixelFormat *fmt;
int bpp;
Uint32 Rmask, Gmask, Bmask, Amask;
@@ -1586,6 +1624,14 @@
textureID =
SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w,
surface->h);
+ if (!textureID && !requested_format) {
+ SDL_DisplayMode desktop_mode;
+ SDL_GetDesktopDisplayMode(&desktop_mode);
+ format = desktop_mode.format;
+ textureID =
+ SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w,
+ surface->h);
+ }
if (!textureID) {
return 0;
}
@@ -2460,11 +2506,21 @@
SDL_UninitializedVideo();
return -1;
}
- if (_this->GL_LoadLibrary) {
- retval = _this->GL_LoadLibrary(_this, path);
+ if (_this->gl_config.driver_loaded) {
+ if (path && SDL_strcmp(path, _this->gl_config.driver_path) != 0) {
+ SDL_SetError("OpenGL library already loaded");
+ return -1;
+ }
+ retval = 0;
} else {
- SDL_SetError("No dynamic GL support in video driver");
- retval = -1;
+ if (!_this->GL_LoadLibrary) {
+ SDL_SetError("No dynamic GL support in video driver");
+ return -1;
+ }
+ retval = _this->GL_LoadLibrary(_this, path);
+ }
+ if (retval == 0) {
+ ++_this->gl_config.driver_loaded;
}
return (retval);
}
@@ -2491,6 +2547,23 @@
return func;
}
+void
+SDL_GL_UnloadLibrary(void)
+{
+ if (!_this) {
+ SDL_UninitializedVideo();
+ return;
+ }
+ if (_this->gl_config.driver_loaded > 0) {
+ if (--_this->gl_config.driver_loaded > 0) {
+ return;
+ }
+ if (_this->GL_UnloadLibrary) {
+ _this->GL_UnloadLibrary(_this);
+ }
+ }
+}
+
SDL_bool
SDL_GL_ExtensionSupported(const char *extension)
{
--- a/src/video/cocoa/SDL_cocoaopengl.h Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/cocoa/SDL_cocoaopengl.h Mon Feb 09 05:32:12 2009 +0000
@@ -34,8 +34,7 @@
/* OpenGL functions */
extern int Cocoa_GL_LoadLibrary(_THIS, const char *path);
extern void *Cocoa_GL_GetProcAddress(_THIS, const char *proc);
-extern int Cocoa_GL_SetupWindow(_THIS, SDL_Window * window);
-extern void Cocoa_GL_CleanupWindow(_THIS, SDL_Window * window);
+extern void Cocoa_GL_UnloadLibrary(_THIS);
extern SDL_GLContext Cocoa_GL_CreateContext(_THIS, SDL_Window * window);
extern int Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window,
SDL_GLContext context);
--- a/src/video/cocoa/SDL_cocoaopengl.m Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/cocoa/SDL_cocoaopengl.m Mon Feb 09 05:32:12 2009 +0000
@@ -48,15 +48,7 @@
int
Cocoa_GL_LoadLibrary(_THIS, const char *path)
{
- if (_this->gl_config.driver_loaded) {
- if (path) {
- SDL_SetError("OpenGL library already loaded");
- return -1;
- } else {
- ++_this->gl_config.driver_loaded;
- return 0;
- }
- }
+ /* Load the OpenGL library */
if (path == NULL) {
path = SDL_getenv("SDL_OPENGL_LIBRARY");
}
@@ -69,7 +61,6 @@
}
SDL_strlcpy(_this->gl_config.driver_path, path,
SDL_arraysize(_this->gl_config.driver_path));
- _this->gl_config.driver_loaded = 1;
return 0;
}
@@ -79,68 +70,11 @@
return SDL_LoadFunction(_this->gl_config.dll_handle, proc);
}
-static void
+void
Cocoa_GL_UnloadLibrary(_THIS)
{
- if (_this->gl_config.driver_loaded > 0) {
- if (--_this->gl_config.driver_loaded > 0) {
- return;
- }
- SDL_UnloadObject(_this->gl_config.dll_handle);
- _this->gl_config.dll_handle = NULL;
- }
-}
-
-static int
-Cocoa_GL_Initialize(_THIS)
-{
- if (_this->gl_data) {
- ++_this->gl_data->initialized;
- return 0;
- }
-
- _this->gl_data =
- (struct SDL_GLDriverData *) SDL_calloc(1,
- sizeof(struct
- SDL_GLDriverData));
- if (!_this->gl_data) {
- SDL_OutOfMemory();
- return -1;
- }
- _this->gl_data->initialized = 1;
-
- if (Cocoa_GL_LoadLibrary(_this, NULL) < 0) {
- return -1;
- }
- return 0;
-}
-
-static void
-Cocoa_GL_Shutdown(_THIS)
-{
- if (!_this->gl_data || (--_this->gl_data->initialized > 0)) {
- return;
- }
-
- Cocoa_GL_UnloadLibrary(_this);
-
- SDL_free(_this->gl_data);
- _this->gl_data = NULL;
-}
-
-int
-Cocoa_GL_SetupWindow(_THIS, SDL_Window * window)
-{
- if (Cocoa_GL_Initialize(_this) < 0) {
- return -1;
- }
- return 0;
-}
-
-void
-Cocoa_GL_CleanupWindow(_THIS, SDL_Window * window)
-{
- Cocoa_GL_Shutdown(_this);
+ SDL_UnloadObject(_this->gl_config.dll_handle);
+ _this->gl_config.dll_handle = NULL;
}
SDL_GLContext
--- a/src/video/cocoa/SDL_cocoavideo.m Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/cocoa/SDL_cocoavideo.m Mon Feb 09 05:32:12 2009 +0000
@@ -93,6 +93,7 @@
#ifdef SDL_VIDEO_OPENGL_CGL
device->GL_LoadLibrary = Cocoa_GL_LoadLibrary;
device->GL_GetProcAddress = Cocoa_GL_GetProcAddress;
+ device->GL_UnloadLibrary = Cocoa_GL_UnloadLibrary;
device->GL_CreateContext = Cocoa_GL_CreateContext;
device->GL_MakeCurrent = Cocoa_GL_MakeCurrent;
device->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval;
--- a/src/video/cocoa/SDL_cocoawindow.m Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/cocoa/SDL_cocoawindow.m Mon Feb 09 05:32:12 2009 +0000
@@ -422,14 +422,6 @@
[nswindow release];
return -1;
}
-#ifdef SDL_VIDEO_OPENGL_CGL
- if (window->flags & SDL_WINDOW_OPENGL) {
- if (Cocoa_GL_SetupWindow(_this, window) < 0) {
- Cocoa_DestroyWindow(_this, window);
- return -1;
- }
- }
-#endif
return 0;
}
@@ -586,11 +578,6 @@
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
if (data) {
-#ifdef SDL_VIDEO_OPENGL_CGL
- if (window->flags & SDL_WINDOW_OPENGL) {
- Cocoa_GL_CleanupWindow(_this, window);
- }
-#endif
[data->listener close];
[data->listener release];
if (data->created) {
--- a/src/video/win32/SDL_win32opengl.c Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/win32/SDL_win32opengl.c Mon Feb 09 05:32:12 2009 +0000
@@ -37,15 +37,6 @@
LPTSTR wpath;
HANDLE handle;
- if (_this->gl_config.driver_loaded) {
- if (path) {
- SDL_SetError("OpenGL library already loaded");
- return -1;
- } else {
- ++_this->gl_config.driver_loaded;
- return 0;
- }
- }
if (path == NULL) {
path = SDL_getenv("SDL_OPENGL_LIBRARY");
}
@@ -53,17 +44,30 @@
path = DEFAULT_OPENGL;
}
wpath = WIN_UTF8ToString(path);
- handle = LoadLibrary(wpath);
+ _this->gl_config.dll_handle = LoadLibrary(wpath);
SDL_free(wpath);
- if (!handle) {
+ if (!_this->gl_config.dll_handle) {
char message[1024];
SDL_snprintf(message, SDL_arraysize(message), "LoadLibrary(\"%s\")",
path);
WIN_SetError(message);
return -1;
}
+ SDL_strlcpy(_this->gl_config.driver_path, path,
+ SDL_arraysize(_this->gl_config.driver_path));
+
+ /* Allocate OpenGL memory */
+ _this->gl_data =
+ (struct SDL_GLDriverData *) SDL_calloc(1,
+ sizeof(struct
+ SDL_GLDriverData));
+ if (!_this->gl_data) {
+ SDL_OutOfMemory();
+ return -1;
+ }
/* Load function pointers */
+ handle = _this->gl_config.dll_handle;
_this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
GetProcAddress(handle, "wglGetProcAddress");
_this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
@@ -86,10 +90,6 @@
return -1;
}
- _this->gl_config.dll_handle = handle;
- SDL_strlcpy(_this->gl_config.driver_path, path,
- SDL_arraysize(_this->gl_config.driver_path));
- _this->gl_config.driver_loaded = 1;
return 0;
}
@@ -107,16 +107,15 @@
return func;
}
-static void
+void
WIN_GL_UnloadLibrary(_THIS)
{
- if (_this->gl_config.driver_loaded > 0) {
- if (--_this->gl_config.driver_loaded > 0) {
- return;
- }
- FreeLibrary((HMODULE) _this->gl_config.dll_handle);
- _this->gl_config.dll_handle = NULL;
- }
+ FreeLibrary((HMODULE) _this->gl_config.dll_handle);
+ _this->gl_config.dll_handle = NULL;
+
+ /* Free OpenGL memory */
+ SDL_free(_this->gl_data);
+ _this->gl_data = NULL;
}
static void
@@ -378,44 +377,6 @@
return pixel_format;
}
-static int
-WIN_GL_Initialize(_THIS)
-{
- if (_this->gl_data) {
- ++_this->gl_data->initialized;
- return 0;
- }
-
- _this->gl_data =
- (struct SDL_GLDriverData *) SDL_calloc(1,
- sizeof(struct
- SDL_GLDriverData));
- if (!_this->gl_data) {
- SDL_OutOfMemory();
- return -1;
- }
- _this->gl_data->initialized = 1;
-
- if (WIN_GL_LoadLibrary(_this, NULL) < 0) {
- return -1;
- }
-
- return 0;
-}
-
-static void
-WIN_GL_Shutdown(_THIS)
-{
- if (!_this->gl_data || (--_this->gl_data->initialized > 0)) {
- return;
- }
-
- WIN_GL_UnloadLibrary(_this);
-
- SDL_free(_this->gl_data);
- _this->gl_data = NULL;
-}
-
int
WIN_GL_SetupWindow(_THIS, SDL_Window * window)
{
@@ -426,10 +387,6 @@
int *iAttr;
float fAttribs[1] = { 0 };
- if (WIN_GL_Initialize(_this) < 0) {
- return -1;
- }
-
WIN_GL_SetupPixelFormat(_this, &pfd);
/* setup WGL_ARB_pixel_format attribs */
@@ -522,12 +479,6 @@
return 0;
}
-void
-WIN_GL_CleanupWindow(_THIS, SDL_Window * window)
-{
- WIN_GL_Shutdown(_this);
-}
-
SDL_GLContext
WIN_GL_CreateContext(_THIS, SDL_Window * window)
{
--- a/src/video/win32/SDL_win32opengl.h Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/win32/SDL_win32opengl.h Mon Feb 09 05:32:12 2009 +0000
@@ -28,7 +28,6 @@
struct SDL_GLDriverData
{
- int initialized;
int WGL_ARB_pixel_format;
void *(WINAPI * wglGetProcAddress) (const char *proc);
@@ -53,8 +52,8 @@
/* OpenGL functions */
extern int WIN_GL_LoadLibrary(_THIS, const char *path);
extern void *WIN_GL_GetProcAddress(_THIS, const char *proc);
+extern void WIN_GL_UnloadLibrary(_THIS);
extern int WIN_GL_SetupWindow(_THIS, SDL_Window * window);
-extern void WIN_GL_CleanupWindow(_THIS, SDL_Window * window);
extern SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window * window);
extern int WIN_GL_MakeCurrent(_THIS, SDL_Window * window,
SDL_GLContext context);
--- a/src/video/win32/SDL_win32video.c Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/win32/SDL_win32video.c Mon Feb 09 05:32:12 2009 +0000
@@ -161,6 +161,7 @@
#ifdef SDL_VIDEO_OPENGL_WGL
device->GL_LoadLibrary = WIN_GL_LoadLibrary;
device->GL_GetProcAddress = WIN_GL_GetProcAddress;
+ device->GL_UnloadLibrary = WIN_GL_UnloadLibrary;
device->GL_CreateContext = WIN_GL_CreateContext;
device->GL_MakeCurrent = WIN_GL_MakeCurrent;
device->GL_SetSwapInterval = WIN_GL_SetSwapInterval;
--- a/src/video/win32/SDL_win32window.c Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/win32/SDL_win32window.c Mon Feb 09 05:32:12 2009 +0000
@@ -521,11 +521,6 @@
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
if (data) {
-#ifdef SDL_VIDEO_OPENGL_WGL
- if (window->flags & SDL_WINDOW_OPENGL) {
- WIN_GL_CleanupWindow(_this, window);
- }
-#endif
ReleaseDC(data->hwnd, data->hdc);
if (data->created) {
if (videodata->wintabDLL) {
--- a/src/video/x11/SDL_x11opengl.c Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/x11/SDL_x11opengl.c Mon Feb 09 05:32:12 2009 +0000
@@ -65,37 +65,39 @@
#define GL_UnloadObject SDL_UnloadObject
#endif
-static int X11_GL_InitializeMemory(_THIS);
+static void X11_GL_InitExtensions(_THIS);
int
X11_GL_LoadLibrary(_THIS, const char *path)
{
void *handle;
- if (_this->gl_config.driver_loaded) {
- /* do not return without reinitializing the function hooks */
- if (path) {
- SDL_SetError("OpenGL library already loaded");
- }
- handle = _this->gl_config.dll_handle;
- } else {
- if (path == NULL) {
- path = SDL_getenv("SDL_OPENGL_LIBRARY");
- }
- if (path == NULL) {
- path = DEFAULT_OPENGL;
- }
- handle = GL_LoadObject(path);
- if (!handle) {
- return -1;
- }
- _this->gl_config.dll_handle = handle;
- SDL_strlcpy(_this->gl_config.driver_path, path,
- SDL_arraysize(_this->gl_config.driver_path));
+ /* Load the OpenGL library */
+ if (path == NULL) {
+ path = SDL_getenv("SDL_OPENGL_LIBRARY");
+ }
+ if (path == NULL) {
+ path = DEFAULT_OPENGL;
+ }
+ _this->gl_config.dll_handle = SDL_LoadObject(path);
+ if (!_this->gl_config.dll_handle) {
+ return -1;
}
- X11_GL_InitializeMemory(_this);
+ SDL_strlcpy(_this->gl_config.driver_path, path,
+ SDL_arraysize(_this->gl_config.driver_path));
- /* Load new function pointers */
+ /* Allocate OpenGL memory */
+ _this->gl_data =
+ (struct SDL_GLDriverData *) SDL_calloc(1,
+ sizeof(struct
+ SDL_GLDriverData));
+ if (!_this->gl_data) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+
+ /* Load function pointers */
+ handle = _this->gl_config.dll_handle;
_this->gl_data->glXGetProcAddress =
(void *(*)(const GLubyte *)) GL_LoadFunction(handle,
"glXGetProcAddressARB");
@@ -123,7 +125,9 @@
return -1;
}
- ++_this->gl_config.driver_loaded;
+ /* Initialize extensions */
+ X11_GL_InitExtensions(_this);
+
return 0;
}
@@ -139,16 +143,21 @@
return GL_LoadFunction(handle, proc);
}
-static void
+void
X11_GL_UnloadLibrary(_THIS)
{
- if (_this->gl_config.driver_loaded > 0) {
- if (--_this->gl_config.driver_loaded > 0) {
- return;
- }
- GL_UnloadObject(_this->gl_config.dll_handle);
- _this->gl_config.dll_handle = NULL;
- }
+ /* Don't actually unload the library, since it may have registered
+ * X11 shutdown hooks, per the notes at:
+ * http://dri.sourceforge.net/doc/DRIuserguide.html
+ */
+#if 0
+ GL_UnloadObject(_this->gl_config.dll_handle);
+ _this->gl_config.dll_handle = NULL;
+#endif
+
+ /* Free OpenGL memory */
+ SDL_free(_this->gl_data);
+ _this->gl_data = NULL;
}
static SDL_bool
@@ -254,62 +263,6 @@
X11_PumpEvents(_this);
}
-static int
-X11_GL_InitializeMemory(_THIS)
-{
- if (_this->gl_data) {
- return 0;
- }
-
- _this->gl_data =
- (struct SDL_GLDriverData *) SDL_calloc(1,
- sizeof(struct
- SDL_GLDriverData));
- if (!_this->gl_data) {
- SDL_OutOfMemory();
- return -1;
- }
- _this->gl_data->initialized = 0;
-
- return 0;
-}
-
-int
-X11_GL_Initialize(_THIS)
-{
-
- if (X11_GL_InitializeMemory(_this) < 0) {
- return -1;
- }
- ++_this->gl_data->initialized;
-
- if (X11_GL_LoadLibrary(_this, NULL) < 0) {
- return -1;
- }
-
- /* Initialize extensions */
- X11_GL_InitExtensions(_this);
-
- return 0;
-}
-
-void
-X11_GL_Shutdown(_THIS)
-{
- if (!_this->gl_data || (--_this->gl_data->initialized > 0)) {
- return;
- }
-
- /* Don't actually unload the library, since it may have registered
- * X11 shutdown hooks, per the notes at:
- * http://dri.sourceforge.net/doc/DRIuserguide.html
- * //X11_GL_UnloadLibrary(_this);
- */
-
- SDL_free(_this->gl_data);
- _this->gl_data = NULL;
-}
-
XVisualInfo *
X11_GL_GetVisual(_THIS, Display * display, int screen)
{
--- a/src/video/x11/SDL_x11opengl.h Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/x11/SDL_x11opengl.h Mon Feb 09 05:32:12 2009 +0000
@@ -30,7 +30,6 @@
struct SDL_GLDriverData
{
- int initialized;
SDL_bool HAS_GLX_EXT_visual_rating;
void *(*glXGetProcAddress) (const GLubyte * procName);
@@ -58,8 +57,7 @@
/* OpenGL functions */
extern int X11_GL_LoadLibrary(_THIS, const char *path);
extern void *X11_GL_GetProcAddress(_THIS, const char *proc);
-extern int X11_GL_Initialize(_THIS);
-extern void X11_GL_Shutdown(_THIS);
+extern void X11_GL_UnloadLibrary(_THIS);
extern XVisualInfo *X11_GL_GetVisual(_THIS, Display * display, int screen);
extern SDL_GLContext X11_GL_CreateContext(_THIS, SDL_Window * window);
extern int X11_GL_MakeCurrent(_THIS, SDL_Window * window,
--- a/src/video/x11/SDL_x11video.c Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/x11/SDL_x11video.c Mon Feb 09 05:32:12 2009 +0000
@@ -190,6 +190,7 @@
#ifdef SDL_VIDEO_OPENGL_GLX
device->GL_LoadLibrary = X11_GL_LoadLibrary;
device->GL_GetProcAddress = X11_GL_GetProcAddress;
+ device->GL_UnloadLibrary = X11_GL_UnloadLibrary;
device->GL_CreateContext = X11_GL_CreateContext;
device->GL_MakeCurrent = X11_GL_MakeCurrent;
device->GL_SetSwapInterval = X11_GL_SetSwapInterval;
--- a/src/video/x11/SDL_x11window.c Sun Feb 08 15:35:06 2009 +0000
+++ b/src/video/x11/SDL_x11window.c Mon Feb 09 05:32:12 2009 +0000
@@ -188,9 +188,6 @@
if (window->flags & SDL_WINDOW_OPENGL) {
XVisualInfo *vinfo;
- if (X11_GL_Initialize(_this) < 0) {
- return -1;
- }
vinfo = X11_GL_GetVisual(_this, data->display, displaydata->screen);
if (!vinfo) {
return -1;
@@ -461,11 +458,6 @@
(CWOverrideRedirect | CWBackPixel | CWBorderPixel |
CWColormap), &xattr);
if (!w) {
-#ifdef SDL_VIDEO_OPENGL_GLX
- if (window->flags & SDL_WINDOW_OPENGL) {
- X11_GL_Shutdown(_this);
- }
-#endif
SDL_SetError("Couldn't create window");
return -1;
}
@@ -622,11 +614,6 @@
XSetWMProtocols(data->display, w, &data->WM_DELETE_WINDOW, 1);
if (SetupWindowData(_this, window, w, SDL_TRUE) < 0) {
-#ifdef SDL_VIDEO_OPENGL_GLX
- if (window->flags & SDL_WINDOW_OPENGL) {
- X11_GL_Shutdown(_this);
- }
-#endif
XDestroyWindow(data->display, w);
return -1;
}
@@ -942,11 +929,6 @@
}
}
}
-#ifdef SDL_VIDEO_OPENGL_GLX
- if (window->flags & SDL_WINDOW_OPENGL) {
- X11_GL_Shutdown(_this);
- }
-#endif
#ifdef X_HAVE_UTF8_STRING
if (data->ic) {
XDestroyIC(data->ic);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testnative.c Mon Feb 09 05:32:12 2009 +0000
@@ -0,0 +1,219 @@
+/* Simple program: Create a native window and attach an SDL renderer */
+
+#include "testnative.h"
+
+#define WINDOW_W 640
+#define WINDOW_H 480
+#define NUM_SPRITES 100
+#define MAX_SPEED 1
+
+static NativeWindowFactory *factories[] = {
+#ifdef TEST_NATIVE_WIN32
+ &Win32WindowFactory,
+#endif
+#ifdef TEST_NATIVE_X11
+ &X11WindowFactory,
+#endif
+#ifdef TEST_NATIVE_COCOA
+ &CocoaWindowFactory,
+#endif
+ NULL
+};
+static NativeWindowFactory *factory = NULL;
+static void *native_window;
+static SDL_Rect *positions, *velocities;
+
+/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
+static void
+quit(int rc)
+{
+ SDL_VideoQuit();
+ if (native_window) {
+ factory->DestroyWindow(native_window);
+ }
+ exit(rc);
+}
+
+SDL_TextureID
+LoadSprite(SDL_WindowID window, char *file)
+{
+ SDL_Surface *temp;
+ SDL_TextureID sprite;
+
+ /* Load the sprite image */
+ temp = SDL_LoadBMP(file);
+ if (temp == NULL) {
+ fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
+ return 0;
+ }
+
+ /* Set transparent pixel as the pixel at (0,0) */
+ if (temp->format->palette) {
+ SDL_SetColorKey(temp, SDL_SRCCOLORKEY, *(Uint8 *) temp->pixels);
+ }
+
+ /* Create textures from the image */
+ SDL_SelectRenderer(window);
+ sprite = SDL_CreateTextureFromSurface(0, temp);
+ if (!sprite) {
+ fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
+ SDL_FreeSurface(temp);
+ return 0;
+ }
+ SDL_FreeSurface(temp);
+
+ /* We're ready to roll. :) */
+ return sprite;
+}
+
+void
+MoveSprites(SDL_WindowID window, SDL_TextureID sprite)
+{
+ int i, n;
+ int window_w, window_h;
+ int sprite_w, sprite_h;
+ SDL_Rect *position, *velocity;
+
+ SDL_SelectRenderer(window);
+
+ /* Query the sizes */
+ SDL_GetWindowSize(window, &window_w, &window_h);
+ SDL_QueryTexture(sprite, NULL, NULL, &sprite_w, &sprite_h);
+
+ /* Move the sprite, bounce at the wall, and draw */
+ n = 0;
+ SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
+ SDL_RenderFill(NULL);
+ for (i = 0; i < NUM_SPRITES; ++i) {
+ position = &positions[i];
+ velocity = &velocities[i];
+ position->x += velocity->x;
+ if ((position->x < 0) || (position->x >= (window_w - sprite_w))) {
+ velocity->x = -velocity->x;
+ position->x += velocity->x;
+ }
+ position->y += velocity->y;
+ if ((position->y < 0) || (position->y >= (window_h - sprite_h))) {
+ velocity->y = -velocity->y;
+ position->y += velocity->y;
+ }
+
+ /* Blit the sprite onto the screen */
+ SDL_RenderCopy(sprite, NULL, position);
+ }
+
+ /* Update the screen! */
+ SDL_RenderPresent();
+}
+
+int
+main(int argc, char *argv[])
+{
+ int i, done;
+ const char *driver;
+ SDL_WindowID window;
+ SDL_TextureID sprite;
+ int window_w, window_h;
+ int sprite_w, sprite_h;
+ SDL_Event event;
+
+ if (SDL_VideoInit(NULL, 0) < 0) {
+ fprintf(stderr, "Couldn't initialize SDL video: %s\n",
+ SDL_GetError());
+ exit(1);
+ }
+ driver = SDL_GetCurrentVideoDriver();
+
+ /* Find a native window driver and create a native window */
+ for (i = 0; factories[i]; ++i) {
+ if (SDL_strcmp(driver, factories[i]->tag) == 0) {
+ factory = factories[i];
+ break;
+ }
+ }
+ if (!factory) {
+ fprintf(stderr, "Couldn't find native window code for %s driver\n",
+ driver);
+ quit(2);
+ }
+ printf("Creating native window for %s driver\n", driver);
+ native_window = factory->CreateWindow(WINDOW_W, WINDOW_H);
+ if (!native_window) {
+ fprintf(stderr, "Couldn't create native window\n");
+ quit(3);
+ }
+ window = SDL_CreateWindowFrom(native_window);
+ if (!window) {
+ fprintf(stderr, "Couldn't create SDL window: %s\n", SDL_GetError());
+ quit(4);
+ }
+ SDL_SetWindowTitle(window, "SDL Native Window Test");
+
+ /* Create the renderer */
+ if (SDL_CreateRenderer(window, -1, 0) < 0) {
+ fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError());
+ quit(5);
+ }
+
+ /* Clear the window, load the sprite and go! */
+ SDL_SelectRenderer(window);
+ SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
+ SDL_RenderFill(NULL);
+
+ sprite = LoadSprite(window, "icon.bmp");
+ if (!sprite) {
+ quit(6);
+ }
+
+ /* Allocate memory for the sprite info */
+ SDL_GetWindowSize(window, &window_w, &window_h);
+ SDL_QueryTexture(sprite, NULL, NULL, &sprite_w, &sprite_h);
+ positions = (SDL_Rect *) SDL_malloc(NUM_SPRITES * sizeof(SDL_Rect));
+ velocities = (SDL_Rect *) SDL_malloc(NUM_SPRITES * sizeof(SDL_Rect));
+ if (!positions || !velocities) {
+ fprintf(stderr, "Out of memory!\n");
+ quit(2);
+ }
+ srand(time(NULL));
+ for (i = 0; i < NUM_SPRITES; ++i) {
+ positions[i].x = rand() % (window_w - sprite_w);
+ positions[i].y = rand() % (window_h - sprite_h);
+ positions[i].w = sprite_w;
+ positions[i].h = sprite_h;
+ velocities[i].x = 0;
+ velocities[i].y = 0;
+ while (!velocities[i].x && !velocities[i].y) {
+ velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
+ velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
+ }
+ }
+
+ /* Main render loop */
+ done = 0;
+ while (!done) {
+ /* Check for events */
+ while (SDL_PollEvent(&event)) {
+ switch (event.type) {
+ case SDL_WINDOWEVENT:
+ switch (event.window.event) {
+ case SDL_WINDOWEVENT_EXPOSED:
+ SDL_SelectRenderer(event.window.windowID);
+ SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
+ SDL_RenderFill(NULL);
+ break;
+ }
+ break;
+ case SDL_QUIT:
+ done = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ MoveSprites(window, sprite);
+ }
+
+ quit(0);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testnativecocoa.m Mon Feb 09 05:32:12 2009 +0000
@@ -0,0 +1,51 @@
+
+#include "testnative.h"
+
+#ifdef TEST_NATIVE_COCOA
+
+#include <Cocoa/Cocoa.h>
+
+static void *CreateWindowCocoa(int w, int h);
+static void DestroyWindowCocoa(void *window);
+
+NativeWindowFactory CocoaWindowFactory = {
+ "cocoa",
+ CreateWindowCocoa,
+ DestroyWindowCocoa
+};
+
+static void *CreateWindowCocoa(int w, int h)
+{
+ NSAutoreleasePool *pool;
+ NSWindow *nswindow;
+ NSRect rect;
+ unsigned int style;
+
+ pool = [[NSAutoreleasePool alloc] init];
+
+ rect.origin.x = 0;
+ rect.origin.y = 0;
+ rect.size.width = w;
+ rect.size.height = h;
+ rect.origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - rect.origin.y - rect.size.height;
+
+ style = (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask);
+
+ nswindow = [[NSWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:FALSE];
+ [nswindow makeKeyAndOrderFront:nil];
+
+ [pool release];
+
+ return nswindow;
+}
+
+static void DestroyWindowCocoa(void *window)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSWindow *nswindow = (NSWindow *)window;
+
+ [nswindow close];
+ [pool release];
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testnativew32.c Mon Feb 09 05:32:12 2009 +0000
@@ -0,0 +1,28 @@
+
+#include "testnative.h"
+
+#ifdef TEST_NATIVE_WIN32
+
+static void *CreateWindowWin32(int w, int h);
+static void DestroyWindowWin32(void *window);
+
+NativeWindowFactory Win32WindowFactory = {
+ "win32",
+ CreateWindowWin32,
+ DestroyWindowWin32
+};
+
+static Display *dpy;
+
+static void *
+CreateWindowWin32(int w, int h)
+{
+ return NULL;
+}
+
+static void
+DestroyWindowWin32(void *window)
+{
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testnativex11.c Mon Feb 09 05:32:12 2009 +0000
@@ -0,0 +1,42 @@
+
+#include "testnative.h"
+
+#ifdef TEST_NATIVE_X11
+
+static void *CreateWindowX11(int w, int h);
+static void DestroyWindowX11(void *window);
+
+NativeWindowFactory X11WindowFactory = {
+ "x11",
+ CreateWindowX11,
+ DestroyWindowX11
+};
+
+static Display *dpy;
+
+static void *
+CreateWindowX11(int w, int h)
+{
+ Window window = 0;
+
+ dpy = XOpenDisplay(NULL);
+ if (dpy) {
+ window =
+ XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, w, h, 0, 0,
+ 0);
+ XMapRaised(dpy, window);
+ XSync(dpy, False);
+ }
+ return (void *) window;
+}
+
+static void
+DestroyWindowX11(void *window)
+{
+ if (dpy) {
+ XDestroyWindow(dpy, (Window) window);
+ XCloseDisplay(dpy);
+ }
+}
+
+#endif