Date: Sat, 03 Jul 2004 02:23:48 +0200
authorSam Lantinga <slouken@libsdl.org>
Sun, 18 Jul 2004 19:14:33 +0000
changeset 906 a48acf6ee48f
parent 905 e6ceebb0f0eb
child 907 3bd4d7a1ee04
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 :).
src/video/bwindow/SDL_BWin.h
src/video/bwindow/SDL_sysvideo.cc
src/video/bwindow/SDL_syswm.cc
src/video/bwindow/SDL_syswm_c.h
--- 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);