Date: Sat, 03 Jul 2004 02:23:48 +0200
From: Marcin Konicki
Subject: [PATCH] Add missing functions and bring back OpenGL
This patch adds missing functions:
IconifyWindow
GetWMInfo
GL_LoadLibrary
GL_GetProcAddress
GL_GetAttribute
GL_MakeCurrent
Adding GL_* functions brings back working OpenGL in SDL for BeOS :).
With addd GL_* functions there are few changes in Window class to handle
changes better.
Patch also fixes bug which freezed window when using MesaGL instead of
BeOS r5 GL - it just needed Window->Quit() added into BE_VideoQuit().
THX to Michael Weirauch (a.k.a emwe) who worked on that bug before and
found that it freezes because of lock somewhere.
THX to Matti "Mictlantecuhtli" Lev��nen for testing, Rod��ric Vicaire
(a.k.a. Ingenu) for OpenGL wisdom, and Stefano Ceccherini (a.k.a Jack
Burton) for asking me to fix SDL on BeOS :).
--- a/src/video/bwindow/SDL_BWin.h Sun Jul 18 19:05:06 2004 +0000
+++ b/src/video/bwindow/SDL_BWin.h Sun Jul 18 19:14:33 2004 +0000
@@ -99,7 +99,7 @@
else
SDL_PrivateResize((int)width, (int)height);
}
- virtual int CreateView(Uint32 flags) {
+ virtual int CreateView(Uint32 flags, Uint32 gl_flags) {
int retval;
retval = 0;
@@ -107,11 +107,9 @@
if ( flags & SDL_OPENGL ) {
#ifdef HAVE_OPENGL
if ( SDL_GLView == NULL ) {
- /* FIXME: choose BGL type via user flags */
SDL_GLView = new BGLView(Bounds(), "SDL GLView",
- B_FOLLOW_ALL_SIDES,
- (B_WILL_DRAW|B_FRAME_EVENTS),
- (BGL_RGB|BGL_DOUBLE|BGL_DEPTH));
+ B_FOLLOW_ALL_SIDES, (B_WILL_DRAW|B_FRAME_EVENTS),
+ gl_flags);
}
if ( the_view != SDL_GLView ) {
if ( the_view ) {
@@ -207,6 +205,11 @@
}
return(true); /* Close the app window */
}
+ virtual void Quit() {
+ if (!IsLocked())
+ Lock();
+ BDirectWindow::Quit();
+ }
private:
#ifdef HAVE_OPENGL
--- a/src/video/bwindow/SDL_sysvideo.cc Sun Jul 18 19:05:06 2004 +0000
+++ b/src/video/bwindow/SDL_sysvideo.cc Sun Jul 18 19:14:33 2004 +0000
@@ -71,6 +71,10 @@
/* OpenGL functions */
#ifdef HAVE_OPENGL
+static int BE_GL_LoadLibrary(_THIS, const char *path);
+static void* BE_GL_GetProcAddress(_THIS, const char *proc);
+static int BE_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
+static int BE_GL_MakeCurrent(_THIS);
static void BE_GL_SwapBuffers(_THIS);
#endif
@@ -108,13 +112,17 @@
memset(device->hidden, 0, (sizeof *device->hidden));
/* Set the function pointers */
+ /* Initialization/Query functions */
device->VideoInit = BE_VideoInit;
device->ListModes = BE_ListModes;
device->SetVideoMode = BE_SetVideoMode;
+ device->ToggleFullScreen = BE_ToggleFullScreen;
device->UpdateMouse = BE_UpdateMouse;
+ device->CreateYUVOverlay = BE_CreateYUVOverlay;
device->SetColors = BE_SetColors;
device->UpdateRects = NULL;
device->VideoQuit = BE_VideoQuit;
+ /* Hardware acceleration functions */
device->AllocHWSurface = BE_AllocHWSurface;
device->CheckHWBlit = NULL;
device->FillHWRect = NULL;
@@ -124,22 +132,33 @@
device->UnlockHWSurface = BE_UnlockHWSurface;
device->FlipHWSurface = NULL;
device->FreeHWSurface = BE_FreeHWSurface;
+ /* Gamma support */
#ifdef HAVE_OPENGL
+ /* OpenGL support */
+ device->GL_LoadLibrary = BE_GL_LoadLibrary;
+ device->GL_GetProcAddress = BE_GL_GetProcAddress;
+ device->GL_GetAttribute = BE_GL_GetAttribute;
+ device->GL_MakeCurrent = BE_GL_MakeCurrent;
device->GL_SwapBuffers = BE_GL_SwapBuffers;
#endif
- device->SetIcon = NULL;
+ /* Window manager functions */
device->SetCaption = BE_SetWMCaption;
- device->GetWMInfo = NULL;
+ device->SetIcon = NULL;
+ device->IconifyWindow = BE_IconifyWindow;
+ device->GrabInput = NULL;
+ device->GetWMInfo = BE_GetWMInfo;
+ /* Cursor manager functions */
device->FreeWMCursor = BE_FreeWMCursor;
device->CreateWMCursor = BE_CreateWMCursor;
device->ShowWMCursor = BE_ShowWMCursor;
device->WarpWMCursor = BE_WarpWMCursor;
+ device->MoveWMCursor = NULL;
+ device->CheckMouseMode = NULL;
+ /* Event manager functions */
device->InitOSKeymap = BE_InitOSKeymap;
device->PumpEvents = BE_PumpEvents;
device->free = BE_DeleteDevice;
- device->ToggleFullScreen = BE_ToggleFullScreen;
- device->CreateYUVOverlay = BE_CreateYUVOverlay;
/* Set the driver flags */
device->handles_any_size = 1;
@@ -294,6 +313,12 @@
bounds.bottom = BEOS_HIDDEN_SIZE;
SDL_Win = new SDL_BWin(bounds);
+#ifdef HAVE_OPENGL
+ /* testgl application doesn't load library, just tries to load symbols */
+ /* is it correct? if so we have to load library here */
+ BE_GL_LoadLibrary(_this, NULL);
+#endif
+
/* Create the clear cursor */
SDL_BlankCursor = BE_CreateWMCursor(_this, blank_cdata, blank_cmask,
BLANK_CWIDTH, BLANK_CHEIGHT, BLANK_CHOTX, BLANK_CHOTY);
@@ -475,9 +500,28 @@
BScreen bscreen;
BBitmap *bbitmap;
BRect bounds;
+ Uint32 gl_flags = 0;
- /* Create the view for this window */
- if ( SDL_Win->CreateView(flags) < 0 ) {
+ /* Only RGB works on r5 currently */
+ gl_flags = BGL_RGB;
+ if (_this->gl_config.double_buffer)
+ gl_flags |= BGL_DOUBLE;
+ else
+ gl_flags |= BGL_SINGLE;
+ if (_this->gl_config.alpha_size > 0 || bpp == 32)
+ gl_flags |= BGL_ALPHA;
+ if (_this->gl_config.depth_size > 0)
+ gl_flags |= BGL_DEPTH;
+ if (_this->gl_config.stencil_size > 0)
+ gl_flags |= BGL_STENCIL;
+ if (_this->gl_config.accum_red_size > 0
+ || _this->gl_config.accum_green_size > 0
+ || _this->gl_config.accum_blue_size > 0
+ || _this->gl_config.accum_alpha_size > 0)
+ gl_flags |= BGL_ACCUM;
+
+ /* Create the view for this window, using found flags */
+ if ( SDL_Win->CreateView(flags, gl_flags) < 0 ) {
return(NULL);
}
@@ -502,7 +546,7 @@
current->flags |= SDL_OPENGL;
current->pitch = 0;
current->pixels = NULL;
- _this->UpdateRects = NULL;
+ _this->UpdateRects = NULL;
} else {
/* Create the BBitmap framebuffer */
bounds.top = 0; bounds.left = 0;
@@ -591,6 +635,144 @@
}
#ifdef HAVE_OPENGL
+/* Passing a NULL path means load pointers from the application */
+int BE_GL_LoadLibrary(_THIS, const char *path)
+{
+ if (path == NULL) {
+ if (_this->gl_config.dll_handle == NULL) {
+ image_info info;
+ int32 cookie = 0;
+ while (get_next_image_info(0,&cookie,&info) == B_OK) {
+ void *location = NULL;
+ if (get_image_symbol((image_id)cookie,"glBegin",B_SYMBOL_TYPE_ANY,&location) == B_OK) {
+ _this->gl_config.dll_handle = (void*)cookie;
+ _this->gl_config.driver_loaded = 1;
+ strncpy(_this->gl_config.driver_path, "libGL.so", sizeof(_this->gl_config.driver_path)-1);
+ }
+ }
+ }
+ } else {
+ /*
+ FIXME None of BeOS libGL.so implementations have exported functions
+ to load BGLView, which should be reloaded from new lib.
+ So for now just "load" linked libGL.so :(
+ */
+ if (_this->gl_config.dll_handle == NULL) {
+ return BE_GL_LoadLibrary(_this, NULL);
+ }
+
+ /* Unload old first */
+ /*if (_this->gl_config.dll_handle != NULL) {*/
+ /* Do not try to unload application itself (if LoadLibrary was called before with NULL ;) */
+ /* image_info info;
+ if (get_image_info((image_id)_this->gl_config.dll_handle, &info) == B_OK) {
+ if (info.type != B_APP_IMAGE) {
+ unload_add_on((image_id)_this->gl_config.dll_handle);
+ }
+ }
+
+ }
+
+ if ((_this->gl_config.dll_handle = (void*)load_add_on(path)) != (void*)B_ERROR) {
+ _this->gl_config.driver_loaded = 1;
+ strncpy(_this->gl_config.driver_path, path, sizeof(_this->gl_config.driver_path)-1);
+ }*/
+ }
+
+ if (_this->gl_config.dll_handle != NULL) {
+ return 0;
+ } else {
+ _this->gl_config.dll_handle = NULL;
+ _this->gl_config.driver_loaded = 0;
+ strcpy(_this->gl_config.driver_path, "");
+ return -1;
+ }
+}
+
+void* BE_GL_GetProcAddress(_THIS, const char *proc)
+{
+ if (_this->gl_config.dll_handle != NULL) {
+ void *location = NULL;
+ status_t err;
+ if ((err = get_image_symbol((image_id)_this->gl_config.dll_handle, proc, B_SYMBOL_TYPE_ANY, &location)) == B_OK) {
+ return location;
+ } else {
+ SDL_SetError("Couldn't find OpenGL symbol");
+ return NULL;
+ }
+ } else {
+ SDL_SetError("OpenGL library not loaded");
+ return NULL;
+ }
+}
+
+int BE_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
+{
+ /*
+ FIXME? Right now BE_GL_GetAttribute shouldn't be called between glBegin() and glEnd() - it doesn't use "cached" values
+ */
+ switch (attrib)
+ {
+ case SDL_GL_RED_SIZE:
+ glGetIntegerv(GL_RED_BITS, (GLint*)value);
+ break;
+ case SDL_GL_GREEN_SIZE:
+ glGetIntegerv(GL_GREEN_BITS, (GLint*)value);
+ break;
+ case SDL_GL_BLUE_SIZE:
+ glGetIntegerv(GL_BLUE_BITS, (GLint*)value);
+ break;
+ case SDL_GL_ALPHA_SIZE:
+ glGetIntegerv(GL_ALPHA_BITS, (GLint*)value);
+ break;
+ case SDL_GL_DOUBLEBUFFER:
+ glGetBooleanv(GL_DOUBLEBUFFER, (GLboolean*)value);
+ break;
+ case SDL_GL_BUFFER_SIZE:
+ int v;
+ glGetIntegerv(GL_RED_BITS, (GLint*)&v);
+ *value = v;
+ glGetIntegerv(GL_GREEN_BITS, (GLint*)&v);
+ *value += v;
+ glGetIntegerv(GL_BLUE_BITS, (GLint*)&v);
+ *value += v;
+ glGetIntegerv(GL_ALPHA_BITS, (GLint*)&v);
+ *value += v;
+ break;
+ case SDL_GL_DEPTH_SIZE:
+ glGetIntegerv(GL_DEPTH_BITS, (GLint*)value); /* Mesa creates 16 only? r5 always 32 */
+ break;
+ case SDL_GL_STENCIL_SIZE:
+ glGetIntegerv(GL_STENCIL_BITS, (GLint*)value);
+ break;
+ case SDL_GL_ACCUM_RED_SIZE:
+ glGetIntegerv(GL_ACCUM_RED_BITS, (GLint*)value);
+ break;
+ case SDL_GL_ACCUM_GREEN_SIZE:
+ glGetIntegerv(GL_ACCUM_GREEN_BITS, (GLint*)value);
+ break;
+ case SDL_GL_ACCUM_BLUE_SIZE:
+ glGetIntegerv(GL_ACCUM_BLUE_BITS, (GLint*)value);
+ break;
+ case SDL_GL_ACCUM_ALPHA_SIZE:
+ glGetIntegerv(GL_ACCUM_ALPHA_BITS, (GLint*)value);
+ break;
+ case SDL_GL_STEREO:
+ case SDL_GL_MULTISAMPLEBUFFERS:
+ case SDL_GL_MULTISAMPLESAMPLES:
+ default:
+ *value=0;
+ return(-1);
+ }
+ return 0;
+}
+
+int BE_GL_MakeCurrent(_THIS)
+{
+ /* FIXME: should we glview->unlock and then glview->lock()? */
+ return 0;
+}
+
void BE_GL_SwapBuffers(_THIS)
{
SDL_Win->SwapBuffers();
@@ -618,6 +800,9 @@
{
int i, j;
+ SDL_Win->Quit();
+ SDL_Win = NULL;
+
if ( SDL_BlankCursor != NULL ) {
BE_FreeWMCursor(_this, SDL_BlankCursor);
SDL_BlankCursor = NULL;
@@ -639,6 +824,12 @@
}
_this->screen->pixels = NULL;
}
+
+#ifdef HAVE_OPENGL
+ if (_this->gl_config.dll_handle != NULL)
+ unload_add_on((image_id)_this->gl_config.dll_handle);
+#endif
+
SDL_QuitBeApp();
}
--- a/src/video/bwindow/SDL_syswm.cc Sun Jul 18 19:05:06 2004 +0000
+++ b/src/video/bwindow/SDL_syswm.cc Sun Jul 18 19:14:33 2004 +0000
@@ -30,10 +30,30 @@
extern "C" {
#include "SDL_syswm_c.h"
+#include "SDL_error.h"
void BE_SetWMCaption(_THIS, const char *title, const char *icon)
{
SDL_Win->SetTitle(title);
}
+int BE_IconifyWindow(_THIS)
+{
+ SDL_Win->Minimize(true);
+}
+
+int BE_GetWMInfo(_THIS, SDL_SysWMinfo *info)
+{
+ if (info->version.major <= SDL_MAJOR_VERSION)
+ {
+ return 1;
+ }
+ else
+ {
+ SDL_SetError("Application not compiled with SDL %d.%d\n",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return -1;
+ }
+}
+
}; /* Extern C */
--- a/src/video/bwindow/SDL_syswm_c.h Sun Jul 18 19:05:06 2004 +0000
+++ b/src/video/bwindow/SDL_syswm_c.h Sun Jul 18 19:14:33 2004 +0000
@@ -25,8 +25,11 @@
"@(#) $Id$";
#endif
+#include "SDL_syswm.h"
#include "SDL_lowvideo.h"
+
/* Functions to be exported */
extern void BE_SetWMCaption(_THIS, const char *title, const char *icon);
-
+extern int BE_IconifyWindow(_THIS);
+extern int BE_GetWMInfo(_THIS, SDL_SysWMinfo *info);