Commit 2aab251e authored by Sam Lantinga's avatar Sam Lantinga

Added test program for SDL_CreateWindowFrom()

Make sure OpenGL library is loaded before working with OpenGL windows,
even those created with SDL_CreateWindowFrom()

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403521
parent 0f598a33
...@@ -111,7 +111,8 @@ typedef enum ...@@ -111,7 +111,8 @@ typedef enum
SDL_WINDOW_MAXIMIZED = 0x00000040, /**< maximized */ SDL_WINDOW_MAXIMIZED = 0x00000040, /**< maximized */
SDL_WINDOW_INPUT_GRABBED = 0x00000100, /**< window has grabbed input focus */ SDL_WINDOW_INPUT_GRABBED = 0x00000100, /**< window has grabbed input focus */
SDL_WINDOW_INPUT_FOCUS = 0x00000200, /**< window has 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; } SDL_WindowFlags;
/** /**
...@@ -1363,6 +1364,7 @@ extern DECLSPEC void SDLCALL SDL_DisableScreenSaver(void); ...@@ -1363,6 +1364,7 @@ extern DECLSPEC void SDLCALL SDL_DisableScreenSaver(void);
* your program from the dynamic library using SDL_GL_GetProcAddress(). * your program from the dynamic library using SDL_GL_GetProcAddress().
* *
* \sa SDL_GL_GetProcAddress() * \sa SDL_GL_GetProcAddress()
* \sa SDL_GL_UnloadLibrary()
*/ */
extern DECLSPEC int SDLCALL SDL_GL_LoadLibrary(const char *path); extern DECLSPEC int SDLCALL SDL_GL_LoadLibrary(const char *path);
...@@ -1373,6 +1375,15 @@ extern DECLSPEC int SDLCALL SDL_GL_LoadLibrary(const char *path); ...@@ -1373,6 +1375,15 @@ extern DECLSPEC int SDLCALL SDL_GL_LoadLibrary(const char *path);
*/ */
extern DECLSPEC void *SDLCALL SDL_GL_GetProcAddress(const char *proc); 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) * \fn SDL_bool SDL_GL_ExtensionSupported(const char *extension)
* *
......
...@@ -260,6 +260,7 @@ struct SDL_VideoDevice ...@@ -260,6 +260,7 @@ struct SDL_VideoDevice
*/ */
int (*GL_LoadLibrary) (_THIS, const char *path); int (*GL_LoadLibrary) (_THIS, const char *path);
void *(*GL_GetProcAddress) (_THIS, const char *proc); void *(*GL_GetProcAddress) (_THIS, const char *proc);
void (*GL_UnloadLibrary) (_THIS);
SDL_GLContext(*GL_CreateContext) (_THIS, SDL_Window * window); SDL_GLContext(*GL_CreateContext) (_THIS, SDL_Window * window);
int (*GL_MakeCurrent) (_THIS, SDL_Window * window, SDL_GLContext context); int (*GL_MakeCurrent) (_THIS, SDL_Window * window, SDL_GLContext context);
int (*GL_SetSwapInterval) (_THIS, int interval); int (*GL_SetSwapInterval) (_THIS, int interval);
......
...@@ -762,10 +762,13 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) ...@@ -762,10 +762,13 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
SDL_UninitializedVideo(); SDL_UninitializedVideo();
return 0; return 0;
} }
if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) { if (flags & SDL_WINDOW_OPENGL) {
if (!_this->GL_CreateContext) {
SDL_SetError("No OpenGL support in video driver"); SDL_SetError("No OpenGL support in video driver");
return 0; return 0;
} }
SDL_GL_LoadLibrary(NULL);
}
SDL_zero(window); SDL_zero(window);
window.id = _this->next_object_id++; window.id = _this->next_object_id++;
window.x = x; window.x = x;
...@@ -776,6 +779,9 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) ...@@ -776,6 +779,9 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
window.display = _this->current_display; window.display = _this->current_display;
if (_this->CreateWindow && _this->CreateWindow(_this, &window) < 0) { if (_this->CreateWindow && _this->CreateWindow(_this, &window) < 0) {
if (flags & SDL_WINDOW_OPENGL) {
SDL_GL_UnloadLibrary();
}
return 0; return 0;
} }
display = &SDL_CurrentDisplay; display = &SDL_CurrentDisplay;
...@@ -786,6 +792,9 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) ...@@ -786,6 +792,9 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
if (_this->DestroyWindow) { if (_this->DestroyWindow) {
_this->DestroyWindow(_this, &window); _this->DestroyWindow(_this, &window);
} }
if (flags & SDL_WINDOW_OPENGL) {
SDL_GL_UnloadLibrary();
}
return 0; return 0;
} }
windows[num_windows] = window; windows[num_windows] = window;
...@@ -824,6 +833,7 @@ SDL_CreateWindowFrom(const void *data) ...@@ -824,6 +833,7 @@ SDL_CreateWindowFrom(const void *data)
SDL_zero(window); SDL_zero(window);
window.id = _this->next_object_id++; window.id = _this->next_object_id++;
window.display = _this->current_display; window.display = _this->current_display;
window.flags = SDL_WINDOW_FOREIGN;
if (!_this->CreateWindowFrom || if (!_this->CreateWindowFrom ||
_this->CreateWindowFrom(_this, &window, data) < 0) { _this->CreateWindowFrom(_this, &window, data) < 0) {
...@@ -852,24 +862,48 @@ SDL_CreateWindowFrom(const void *data) ...@@ -852,24 +862,48 @@ SDL_CreateWindowFrom(const void *data)
int int
SDL_RecreateWindow(SDL_Window * window, Uint32 flags) 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; char *title = window->title;
if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) { if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
SDL_SetError("No OpenGL support in video driver"); SDL_SetError("No OpenGL support in video driver");
return -1; 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); _this->DestroyWindow(_this, window);
} }
window->title = NULL; window->title = NULL;
window->flags = window->flags = (flags & allowed_flags);
(flags &
~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED | SDL_WINDOW_SHOWN |
SDL_WINDOW_INPUT_GRABBED));
if (_this->CreateWindow && _this->CreateWindow(_this, window) < 0) { if (_this->CreateWindow && !(flags & SDL_WINDOW_FOREIGN)) {
if (_this->CreateWindow(_this, window) < 0) {
if (flags & SDL_WINDOW_OPENGL) {
SDL_GL_UnloadLibrary();
}
return -1; return -1;
} }
}
if (title) { if (title) {
SDL_SetWindowTitle(window->id, title); SDL_SetWindowTitle(window->id, title);
SDL_free(title); SDL_free(title);
...@@ -1352,6 +1386,9 @@ SDL_DestroyWindow(SDL_WindowID windowID) ...@@ -1352,6 +1386,9 @@ SDL_DestroyWindow(SDL_WindowID windowID)
if (_this->DestroyWindow) { if (_this->DestroyWindow) {
_this->DestroyWindow(_this, window); _this->DestroyWindow(_this, window);
} }
if (window->flags & SDL_WINDOW_OPENGL) {
SDL_GL_UnloadLibrary();
}
if (j != display->num_windows - 1) { if (j != display->num_windows - 1) {
SDL_memcpy(&display->windows[i], SDL_memcpy(&display->windows[i],
&display->windows[i + 1], &display->windows[i + 1],
...@@ -1543,6 +1580,7 @@ SDL_TextureID ...@@ -1543,6 +1580,7 @@ SDL_TextureID
SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface) SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
{ {
SDL_TextureID textureID; SDL_TextureID textureID;
Uint32 requested_format = format;
SDL_PixelFormat *fmt; SDL_PixelFormat *fmt;
int bpp; int bpp;
Uint32 Rmask, Gmask, Bmask, Amask; Uint32 Rmask, Gmask, Bmask, Amask;
...@@ -1586,6 +1624,14 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface) ...@@ -1586,6 +1624,14 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
textureID = textureID =
SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w, SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w,
surface->h); 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) { if (!textureID) {
return 0; return 0;
} }
...@@ -2460,11 +2506,21 @@ SDL_GL_LoadLibrary(const char *path) ...@@ -2460,11 +2506,21 @@ SDL_GL_LoadLibrary(const char *path)
SDL_UninitializedVideo(); SDL_UninitializedVideo();
return -1; return -1;
} }
if (_this->GL_LoadLibrary) { if (_this->gl_config.driver_loaded) {
retval = _this->GL_LoadLibrary(_this, path); if (path && SDL_strcmp(path, _this->gl_config.driver_path) != 0) {
SDL_SetError("OpenGL library already loaded");
return -1;
}
retval = 0;
} else { } else {
if (!_this->GL_LoadLibrary) {
SDL_SetError("No dynamic GL support in video driver"); SDL_SetError("No dynamic GL support in video driver");
retval = -1; return -1;
}
retval = _this->GL_LoadLibrary(_this, path);
}
if (retval == 0) {
++_this->gl_config.driver_loaded;
} }
return (retval); return (retval);
} }
...@@ -2491,6 +2547,23 @@ SDL_GL_GetProcAddress(const char *proc) ...@@ -2491,6 +2547,23 @@ SDL_GL_GetProcAddress(const char *proc)
return func; 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_bool
SDL_GL_ExtensionSupported(const char *extension) SDL_GL_ExtensionSupported(const char *extension)
{ {
......
...@@ -34,8 +34,7 @@ struct SDL_GLDriverData ...@@ -34,8 +34,7 @@ struct SDL_GLDriverData
/* OpenGL functions */ /* OpenGL functions */
extern int Cocoa_GL_LoadLibrary(_THIS, const char *path); extern int Cocoa_GL_LoadLibrary(_THIS, const char *path);
extern void *Cocoa_GL_GetProcAddress(_THIS, const char *proc); extern void *Cocoa_GL_GetProcAddress(_THIS, const char *proc);
extern int Cocoa_GL_SetupWindow(_THIS, SDL_Window * window); extern void Cocoa_GL_UnloadLibrary(_THIS);
extern void Cocoa_GL_CleanupWindow(_THIS, SDL_Window * window);
extern SDL_GLContext Cocoa_GL_CreateContext(_THIS, SDL_Window * window); extern SDL_GLContext Cocoa_GL_CreateContext(_THIS, SDL_Window * window);
extern int Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, extern int Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window,
SDL_GLContext context); SDL_GLContext context);
......
...@@ -48,15 +48,7 @@ ...@@ -48,15 +48,7 @@
int int
Cocoa_GL_LoadLibrary(_THIS, const char *path) Cocoa_GL_LoadLibrary(_THIS, const char *path)
{ {
if (_this->gl_config.driver_loaded) { /* Load the OpenGL library */
if (path) {
SDL_SetError("OpenGL library already loaded");
return -1;
} else {
++_this->gl_config.driver_loaded;
return 0;
}
}
if (path == NULL) { if (path == NULL) {
path = SDL_getenv("SDL_OPENGL_LIBRARY"); path = SDL_getenv("SDL_OPENGL_LIBRARY");
} }
...@@ -69,7 +61,6 @@ Cocoa_GL_LoadLibrary(_THIS, const char *path) ...@@ -69,7 +61,6 @@ Cocoa_GL_LoadLibrary(_THIS, const char *path)
} }
SDL_strlcpy(_this->gl_config.driver_path, path, SDL_strlcpy(_this->gl_config.driver_path, path,
SDL_arraysize(_this->gl_config.driver_path)); SDL_arraysize(_this->gl_config.driver_path));
_this->gl_config.driver_loaded = 1;
return 0; return 0;
} }
...@@ -79,68 +70,11 @@ Cocoa_GL_GetProcAddress(_THIS, const char *proc) ...@@ -79,68 +70,11 @@ Cocoa_GL_GetProcAddress(_THIS, const char *proc)
return SDL_LoadFunction(_this->gl_config.dll_handle, proc); return SDL_LoadFunction(_this->gl_config.dll_handle, proc);
} }
static void void
Cocoa_GL_UnloadLibrary(_THIS) 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); SDL_UnloadObject(_this->gl_config.dll_handle);
_this->gl_config.dll_handle = NULL; _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_GLContext SDL_GLContext
......
...@@ -93,6 +93,7 @@ Cocoa_CreateDevice(int devindex) ...@@ -93,6 +93,7 @@ Cocoa_CreateDevice(int devindex)
#ifdef SDL_VIDEO_OPENGL_CGL #ifdef SDL_VIDEO_OPENGL_CGL
device->GL_LoadLibrary = Cocoa_GL_LoadLibrary; device->GL_LoadLibrary = Cocoa_GL_LoadLibrary;
device->GL_GetProcAddress = Cocoa_GL_GetProcAddress; device->GL_GetProcAddress = Cocoa_GL_GetProcAddress;
device->GL_UnloadLibrary = Cocoa_GL_UnloadLibrary;
device->GL_CreateContext = Cocoa_GL_CreateContext; device->GL_CreateContext = Cocoa_GL_CreateContext;
device->GL_MakeCurrent = Cocoa_GL_MakeCurrent; device->GL_MakeCurrent = Cocoa_GL_MakeCurrent;
device->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval; device->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval;
......
...@@ -422,14 +422,6 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) ...@@ -422,14 +422,6 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window)
[nswindow release]; [nswindow release];
return -1; 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; return 0;
} }
...@@ -586,11 +578,6 @@ Cocoa_DestroyWindow(_THIS, SDL_Window * window) ...@@ -586,11 +578,6 @@ Cocoa_DestroyWindow(_THIS, SDL_Window * window)
SDL_WindowData *data = (SDL_WindowData *) window->driverdata; SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
if (data) { if (data) {
#ifdef SDL_VIDEO_OPENGL_CGL
if (window->flags & SDL_WINDOW_OPENGL) {
Cocoa_GL_CleanupWindow(_this, window);
}
#endif
[data->listener close]; [data->listener close];
[data->listener release]; [data->listener release];
if (data->created) { if (data->created) {
......
...@@ -37,15 +37,6 @@ WIN_GL_LoadLibrary(_THIS, const char *path) ...@@ -37,15 +37,6 @@ WIN_GL_LoadLibrary(_THIS, const char *path)
LPTSTR wpath; LPTSTR wpath;
HANDLE handle; 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) { if (path == NULL) {
path = SDL_getenv("SDL_OPENGL_LIBRARY"); path = SDL_getenv("SDL_OPENGL_LIBRARY");
} }
...@@ -53,17 +44,30 @@ WIN_GL_LoadLibrary(_THIS, const char *path) ...@@ -53,17 +44,30 @@ WIN_GL_LoadLibrary(_THIS, const char *path)
path = DEFAULT_OPENGL; path = DEFAULT_OPENGL;
} }
wpath = WIN_UTF8ToString(path); wpath = WIN_UTF8ToString(path);
handle = LoadLibrary(wpath); _this->gl_config.dll_handle = LoadLibrary(wpath);
SDL_free(wpath); SDL_free(wpath);
if (!handle) { if (!_this->gl_config.dll_handle) {
char message[1024]; char message[1024];
SDL_snprintf(message, SDL_arraysize(message), "LoadLibrary(\"%s\")", SDL_snprintf(message, SDL_arraysize(message), "LoadLibrary(\"%s\")",
path); path);
WIN_SetError(message); WIN_SetError(message);
return -1; 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 */ /* Load function pointers */
handle = _this->gl_config.dll_handle;
_this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *)) _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
GetProcAddress(handle, "wglGetProcAddress"); GetProcAddress(handle, "wglGetProcAddress");
_this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC)) _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
...@@ -86,10 +90,6 @@ WIN_GL_LoadLibrary(_THIS, const char *path) ...@@ -86,10 +90,6 @@ WIN_GL_LoadLibrary(_THIS, const char *path)
return -1; 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; return 0;
} }
...@@ -107,16 +107,15 @@ WIN_GL_GetProcAddress(_THIS, const char *proc) ...@@ -107,16 +107,15 @@ WIN_GL_GetProcAddress(_THIS, const char *proc)
return func; return func;
} }
static void void
WIN_GL_UnloadLibrary(_THIS) 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); FreeLibrary((HMODULE) _this->gl_config.dll_handle);
_this->gl_config.dll_handle = NULL; _this->gl_config.dll_handle = NULL;
}
/* Free OpenGL memory */
SDL_free(_this->gl_data);
_this->gl_data = NULL;
} }
static void static void
...@@ -378,44 +377,6 @@ WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs) ...@@ -378,44 +377,6 @@ WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs)
return pixel_format; 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 int
WIN_GL_SetupWindow(_THIS, SDL_Window * window) WIN_GL_SetupWindow(_THIS, SDL_Window * window)
{ {
...@@ -426,10 +387,6 @@ WIN_GL_SetupWindow(_THIS, SDL_Window * window) ...@@ -426,10 +387,6 @@ WIN_GL_SetupWindow(_THIS, SDL_Window * window)
int *iAttr; int *iAttr;
float fAttribs[1] = { 0 }; float fAttribs[1] = { 0 };
if (WIN_GL_Initialize(_this) < 0) {
return -1;
}
WIN_GL_SetupPixelFormat(_this, &pfd); WIN_GL_SetupPixelFormat(_this, &pfd);
/* setup WGL_ARB_pixel_format attribs */ /* setup WGL_ARB_pixel_format attribs */
...@@ -522,12 +479,6 @@ WIN_GL_SetupWindow(_THIS, SDL_Window * window) ...@@ -522,12 +479,6 @@ WIN_GL_SetupWindow(_THIS, SDL_Window * window)
return 0; return 0;
} }
void
WIN_GL_CleanupWindow(_THIS, SDL_Window * window)
{
WIN_GL_Shutdown(_this);
}
SDL_GLContext SDL_GLContext
WIN_GL_CreateContext(_THIS, SDL_Window * window) WIN_GL_CreateContext(_THIS, SDL_Window * window)
{ {
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
struct SDL_GLDriverData struct SDL_GLDriverData
{ {
int initialized;
int WGL_ARB_pixel_format; int WGL_ARB_pixel_format;
void *(WINAPI * wglGetProcAddress) (const char *proc); void *(WINAPI * wglGetProcAddress) (const char *proc);
...@@ -53,8 +52,8 @@ struct SDL_GLDriverData ...@@ -53,8 +52,8 @@ struct SDL_GLDriverData
/* OpenGL functions */ /* OpenGL functions */
extern int WIN_GL_LoadLibrary(_THIS, const char *path); extern int WIN_GL_LoadLibrary(_THIS, const char *path);
extern void *WIN_GL_GetProcAddress(_THIS, const char *proc); 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 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 SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window * window);
extern int WIN_GL_MakeCurrent(_THIS, SDL_Window * window, extern int WIN_GL_MakeCurrent(_THIS, SDL_Window * window,
SDL_GLContext context); SDL_GLContext context);
......
...@@ -161,6 +161,7 @@ WIN_CreateDevice(int devindex) ...@@ -161,6 +161,7 @@ WIN_CreateDevice(int devindex)
#ifdef SDL_VIDEO_OPENGL_WGL #ifdef SDL_VIDEO_OPENGL_WGL
device->GL_LoadLibrary = WIN_GL_LoadLibrary; device->GL_LoadLibrary = WIN_GL_LoadLibrary;
device->GL_GetProcAddress = WIN_GL_GetProcAddress; device->GL_GetProcAddress = WIN_GL_GetProcAddress;
device->GL_UnloadLibrary = WIN_GL_UnloadLibrary;
device->GL_CreateContext = WIN_GL_CreateContext; device->GL_CreateContext = WIN_GL_CreateContext;
device->GL_MakeCurrent = WIN_GL_MakeCurrent; device->GL_MakeCurrent = WIN_GL_MakeCurrent;
device->GL_SetSwapInterval = WIN_GL_SetSwapInterval; device->GL_SetSwapInterval = WIN_GL_SetSwapInterval;
......
...@@ -521,11 +521,6 @@ WIN_DestroyWindow(_THIS, SDL_Window * window) ...@@ -521,11 +521,6 @@ WIN_DestroyWindow(_THIS, SDL_Window * window)
SDL_WindowData *data = (SDL_WindowData *) window->driverdata; SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
if (data) { if (data) {
#ifdef SDL_VIDEO_OPENGL_WGL
if (window->flags & SDL_WINDOW_OPENGL) {
WIN_GL_CleanupWindow(_this, window);
}
#endif
ReleaseDC(data->hwnd, data->hdc); ReleaseDC(data->hwnd, data->hdc);
if (data->created) { if (data->created) {
if (videodata->wintabDLL) { if (videodata->wintabDLL) {
......
...@@ -65,37 +65,39 @@ ...@@ -65,37 +65,39 @@
#define GL_UnloadObject SDL_UnloadObject #define GL_UnloadObject SDL_UnloadObject
#endif #endif
static int X11_GL_InitializeMemory(_THIS); static void X11_GL_InitExtensions(_THIS);
int int
X11_GL_LoadLibrary(_THIS, const char *path) X11_GL_LoadLibrary(_THIS, const char *path)
{ {
void *handle; void *handle;
if (_this->gl_config.driver_loaded) { /* Load the OpenGL library */
/* 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) { if (path == NULL) {
path = SDL_getenv("SDL_OPENGL_LIBRARY"); path = SDL_getenv("SDL_OPENGL_LIBRARY");
} }
if (path == NULL) { if (path == NULL) {
path = DEFAULT_OPENGL; path = DEFAULT_OPENGL;
} }
handle = GL_LoadObject(path); _this->gl_config.dll_handle = SDL_LoadObject(path);
if (!handle) { if (!_this->gl_config.dll_handle) {
return -1; return -1;
} }
_this->gl_config.dll_handle = handle;
SDL_strlcpy(_this->gl_config.driver_path, path, SDL_strlcpy(_this->gl_config.driver_path, path,
SDL_arraysize(_this->gl_config.driver_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;
} }
X11_GL_InitializeMemory(_this);
/* Load new function pointers */ /* Load function pointers */
handle = _this->gl_config.dll_handle;
_this->gl_data->glXGetProcAddress = _this->gl_data->glXGetProcAddress =
(void *(*)(const GLubyte *)) GL_LoadFunction(handle, (void *(*)(const GLubyte *)) GL_LoadFunction(handle,
"glXGetProcAddressARB"); "glXGetProcAddressARB");
...@@ -123,7 +125,9 @@ X11_GL_LoadLibrary(_THIS, const char *path) ...@@ -123,7 +125,9 @@ X11_GL_LoadLibrary(_THIS, const char *path)
return -1; return -1;
} }
++_this->gl_config.driver_loaded; /* Initialize extensions */
X11_GL_InitExtensions(_this);
return 0; return 0;
} }
...@@ -139,16 +143,21 @@ X11_GL_GetProcAddress(_THIS, const char *proc) ...@@ -139,16 +143,21 @@ X11_GL_GetProcAddress(_THIS, const char *proc)
return GL_LoadFunction(handle, proc); return GL_LoadFunction(handle, proc);
} }
static void void
X11_GL_UnloadLibrary(_THIS) X11_GL_UnloadLibrary(_THIS)
{ {
if (_this->gl_config.driver_loaded > 0) { /* Don't actually unload the library, since it may have registered
if (--_this->gl_config.driver_loaded > 0) { * X11 shutdown hooks, per the notes at:
return; * http://dri.sourceforge.net/doc/DRIuserguide.html
} */
#if 0
GL_UnloadObject(_this->gl_config.dll_handle); GL_UnloadObject(_this->gl_config.dll_handle);
_this->gl_config.dll_handle = NULL; _this->gl_config.dll_handle = NULL;
} #endif
/* Free OpenGL memory */
SDL_free(_this->gl_data);
_this->gl_data = NULL;
} }
static SDL_bool static SDL_bool
...@@ -254,62 +263,6 @@ X11_GL_InitExtensions(_THIS) ...@@ -254,62 +263,6 @@ X11_GL_InitExtensions(_THIS)
X11_PumpEvents(_this); 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 * XVisualInfo *
X11_GL_GetVisual(_THIS, Display * display, int screen) X11_GL_GetVisual(_THIS, Display * display, int screen)
{ {
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
struct SDL_GLDriverData struct SDL_GLDriverData
{ {
int initialized;
SDL_bool HAS_GLX_EXT_visual_rating; SDL_bool HAS_GLX_EXT_visual_rating;
void *(*glXGetProcAddress) (const GLubyte * procName); void *(*glXGetProcAddress) (const GLubyte * procName);
...@@ -58,8 +57,7 @@ struct SDL_GLDriverData ...@@ -58,8 +57,7 @@ struct SDL_GLDriverData
/* OpenGL functions */ /* OpenGL functions */
extern int X11_GL_LoadLibrary(_THIS, const char *path); extern int X11_GL_LoadLibrary(_THIS, const char *path);
extern void *X11_GL_GetProcAddress(_THIS, const char *proc); extern void *X11_GL_GetProcAddress(_THIS, const char *proc);
extern int X11_GL_Initialize(_THIS); extern void X11_GL_UnloadLibrary(_THIS);
extern void X11_GL_Shutdown(_THIS);
extern XVisualInfo *X11_GL_GetVisual(_THIS, Display * display, int screen); extern XVisualInfo *X11_GL_GetVisual(_THIS, Display * display, int screen);
extern SDL_GLContext X11_GL_CreateContext(_THIS, SDL_Window * window); extern SDL_GLContext X11_GL_CreateContext(_THIS, SDL_Window * window);
extern int X11_GL_MakeCurrent(_THIS, SDL_Window * window, extern int X11_GL_MakeCurrent(_THIS, SDL_Window * window,
......
...@@ -190,6 +190,7 @@ X11_CreateDevice(int devindex) ...@@ -190,6 +190,7 @@ X11_CreateDevice(int devindex)
#ifdef SDL_VIDEO_OPENGL_GLX #ifdef SDL_VIDEO_OPENGL_GLX
device->GL_LoadLibrary = X11_GL_LoadLibrary; device->GL_LoadLibrary = X11_GL_LoadLibrary;
device->GL_GetProcAddress = X11_GL_GetProcAddress; device->GL_GetProcAddress = X11_GL_GetProcAddress;
device->GL_UnloadLibrary = X11_GL_UnloadLibrary;
device->GL_CreateContext = X11_GL_CreateContext; device->GL_CreateContext = X11_GL_CreateContext;
device->GL_MakeCurrent = X11_GL_MakeCurrent; device->GL_MakeCurrent = X11_GL_MakeCurrent;
device->GL_SetSwapInterval = X11_GL_SetSwapInterval; device->GL_SetSwapInterval = X11_GL_SetSwapInterval;
......
...@@ -188,9 +188,6 @@ X11_CreateWindow(_THIS, SDL_Window * window) ...@@ -188,9 +188,6 @@ X11_CreateWindow(_THIS, SDL_Window * window)
if (window->flags & SDL_WINDOW_OPENGL) { if (window->flags & SDL_WINDOW_OPENGL) {
XVisualInfo *vinfo; XVisualInfo *vinfo;
if (X11_GL_Initialize(_this) < 0) {
return -1;
}
vinfo = X11_GL_GetVisual(_this, data->display, displaydata->screen); vinfo = X11_GL_GetVisual(_this, data->display, displaydata->screen);
if (!vinfo) { if (!vinfo) {
return -1; return -1;
...@@ -461,11 +458,6 @@ X11_CreateWindow(_THIS, SDL_Window * window) ...@@ -461,11 +458,6 @@ X11_CreateWindow(_THIS, SDL_Window * window)
(CWOverrideRedirect | CWBackPixel | CWBorderPixel | (CWOverrideRedirect | CWBackPixel | CWBorderPixel |
CWColormap), &xattr); CWColormap), &xattr);
if (!w) { if (!w) {
#ifdef SDL_VIDEO_OPENGL_GLX
if (window->flags & SDL_WINDOW_OPENGL) {
X11_GL_Shutdown(_this);
}
#endif
SDL_SetError("Couldn't create window"); SDL_SetError("Couldn't create window");
return -1; return -1;
} }
...@@ -622,11 +614,6 @@ X11_CreateWindow(_THIS, SDL_Window * window) ...@@ -622,11 +614,6 @@ X11_CreateWindow(_THIS, SDL_Window * window)
XSetWMProtocols(data->display, w, &data->WM_DELETE_WINDOW, 1); XSetWMProtocols(data->display, w, &data->WM_DELETE_WINDOW, 1);
if (SetupWindowData(_this, window, w, SDL_TRUE) < 0) { 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); XDestroyWindow(data->display, w);
return -1; return -1;
} }
...@@ -942,11 +929,6 @@ X11_DestroyWindow(_THIS, SDL_Window * window) ...@@ -942,11 +929,6 @@ X11_DestroyWindow(_THIS, SDL_Window * window)
} }
} }
} }
#ifdef SDL_VIDEO_OPENGL_GLX
if (window->flags & SDL_WINDOW_OPENGL) {
X11_GL_Shutdown(_this);
}
#endif
#ifdef X_HAVE_UTF8_STRING #ifdef X_HAVE_UTF8_STRING
if (data->ic) { if (data->ic) {
XDestroyIC(data->ic); XDestroyIC(data->ic);
......
/* 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: */
#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
#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
#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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment