* Minor cleanup - this stuff really has "reimplement me" written all over it...

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27901 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-10-07 11:43:15 +00:00
parent 044627ee89
commit 5007e8e478
2 changed files with 336 additions and 326 deletions
+310 -291
View File
@@ -5,88 +5,76 @@
* and is provided without guarantee or warrantee expressed or * and is provided without guarantee or warrantee expressed or
* implied. This program is -not- in the public domain. * implied. This program is -not- in the public domain.
* *
*
* FILE: glutWindow.cpp
*
* DESCRIPTION: all the routines for dealing with GlutWindows * DESCRIPTION: all the routines for dealing with GlutWindows
***********************************************************/ ***********************************************************/
/***********************************************************
* Headers
***********************************************************/
#include <GL/glut.h>
#include <stdlib.h> #include <stdlib.h>
#include <GL/glut.h>
#include "glutint.h" #include "glutint.h"
#include "glutState.h" #include "glutState.h"
#include "glutBlocker.h" #include "glutBlocker.h"
/***********************************************************
* FUNCTION: getUnusedWindowSlot /*! Helper function to get a new window slot */
*
* DESCRIPTION: helper function to get a new window slot
***********************************************************/
static int static int
getUnusedWindowSlot() getUnusedWindowSlot()
{ {
int i; int i;
/* Look for allocated, unused slot. */ /* Look for allocated, unused slot. */
for (i = 0; i < gState.windowListSize; i++) { for (i = 0; i < gState.windowListSize; i++) {
if (!gState.windowList[i]) { if (!gState.windowList[i])
return i; return i;
} }
}
/* Allocate a new slot. */
gState.windowListSize++;
gState.windowList = (GlutWindow **)
realloc(gState.windowList,
gState.windowListSize * sizeof(GlutWindow *));
if (!gState.windowList) /* Allocate a new slot. */
__glutFatalError("out of memory."); gState.windowListSize++;
gState.windowList[gState.windowListSize - 1] = NULL; gState.windowList = (GlutWindow **)realloc(gState.windowList,
return gState.windowListSize - 1; gState.windowListSize * sizeof(GlutWindow *));
if (gState.windowList == NULL)
__glutFatalError("out of memory.");
gState.windowList[gState.windowListSize - 1] = NULL;
return gState.windowListSize - 1;
} }
/***********************************************************
* FUNCTION: __glutDefaultDisplay /*! Default display function */
* __glutDefaultReshape
*
* DESCRIPTION: default display and reshape functions
***********************************************************/
static void static void
__glutDefaultDisplay(void) __glutDefaultDisplay(void)
{ {
/* XXX Remove the warning after GLUT 3.0. */ /* XXX Remove the warning after GLUT 3.0. */
__glutWarning("The following is a new check for GLUT 3.0; update your code."); __glutWarning("The following is a new check for GLUT 3.0; update your "
__glutFatalError( "code.");
"redisplay needed for window %d, but no display callback.", __glutFatalError("redisplay needed for window %d, but no display callback.",
gState.currentWindow->num + 1); gState.currentWindow->num + 1);
} }
/*! Default reshape function */
void void
__glutDefaultReshape(int width, int height) __glutDefaultReshape(int width, int height)
{ {
/* Adjust the viewport of the window */ /* Adjust the viewport of the window */
glViewport(0, 0, (GLsizei) width, (GLsizei) height); glViewport(0, 0, (GLsizei) width, (GLsizei) height);
} }
/***********************************************************
* CLASS: GlutWindow // #pragma mark -
*
* FUNCTION: (constructor)
* /*! Creates a new GLUT window
* DESCRIPTION: creates a new GLUT window Note: subwindows don't resize, but top-level windows
* note: subwindows don't resize, but top-level windows follow all sides.
* follow all sides */
***********************************************************/ GlutWindow::GlutWindow(GlutWindow *nparent, const char *name,
GlutWindow::GlutWindow(GlutWindow *nparent, char *name, int x, int y, int width, int height, ulong options)
int x, int y, int width, int height, ulong options) : : BGLView(nparent != NULL ? BRect(x, y, x + width - 1, y + height - 1)
BGLView( : BRect(0, 0, width - 1, height - 1), const_cast<char*>(name),
(nparent ? BRect(x,y,x+width-1,y+height-1) : nparent != NULL ? B_FOLLOW_NONE : B_FOLLOW_ALL_SIDES,
BRect(0,0,width-1,height-1)), name, B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED,
(nparent ? B_FOLLOW_NONE : B_FOLLOW_ALL_SIDES),
B_WILL_DRAW|B_FRAME_EVENTS|B_FULL_UPDATE_ON_RESIZE|B_PULSE_NEEDED,
options) options)
{ {
// add myself to window list // add myself to window list
@@ -102,7 +90,7 @@ GlutWindow::GlutWindow(GlutWindow *nparent, char *name,
siblings = 0; siblings = 0;
} }
children = 0; children = 0;
// initialize variables // initialize variables
cursor = GLUT_CURSOR_INHERIT; // default cursor cursor = GLUT_CURSOR_INHERIT; // default cursor
for (int i = 0; i < GLUT_MAX_MENUS; i++) { for (int i = 0; i < GLUT_MAX_MENUS; i++) {
@@ -111,7 +99,7 @@ GlutWindow::GlutWindow(GlutWindow *nparent, char *name,
m_width = width; m_width = width;
m_height = height; m_height = height;
m_buttons = 0; m_buttons = 0;
// clear callbacks // clear callbacks
display = __glutDefaultDisplay; display = __glutDefaultDisplay;
reshape = __glutDefaultReshape; reshape = __glutDefaultReshape;
@@ -125,7 +113,7 @@ GlutWindow::GlutWindow(GlutWindow *nparent, char *name,
special = 0; special = 0;
specialUp = 0; specialUp = 0;
windowStatus = 0; windowStatus = 0;
// clear event counters // clear event counters
anyevents = 1; anyevents = 1;
displayEvent = 1; // get a reshape and a display event right away displayEvent = 1; // get a reshape and a display event right away
@@ -144,7 +132,7 @@ GlutWindow::GlutWindow(GlutWindow *nparent, char *name,
menuEvent = 0; menuEvent = 0;
visible = true; visible = true;
gBlock.QuickNewEvent(); gBlock.QuickNewEvent();
// if i'm a subwindow, add me to my parent view // if i'm a subwindow, add me to my parent view
if (parent) { if (parent) {
parent->Window()->Lock(); parent->Window()->Lock();
@@ -153,28 +141,27 @@ GlutWindow::GlutWindow(GlutWindow *nparent, char *name,
} else { } else {
// if I'm a top-level window, create my BWindow // if I'm a top-level window, create my BWindow
GlutBWindow *mybwindow = new GlutBWindow( GlutBWindow *mybwindow = new GlutBWindow(
BRect(x,y,x+width-1,y+height-1), name); BRect(x, y, x + width - 1, y + height - 1), name);
mybwindow->AddChild(this); mybwindow->AddChild(this);
mybwindow->bgl = this; mybwindow->bgl = this;
mybwindow->Show(); mybwindow->Show();
} }
// give me the keyboard focus (focus follows mouse, X style, as // give me the keyboard focus (focus follows mouse, X style, as
// implemented in GlutWindow::MouseMoved()) // implemented in GlutWindow::MouseMoved())
Window()->Lock(); Window()->Lock();
MakeFocus(); MakeFocus();
Window()->Unlock(); Window()->Unlock();
// make myself the default window // make myself the default window
__glutSetWindow(this); __glutSetWindow(this);
} }
/***********************************************************
* FUNCTION: glutCreateWindow (4.1) /*! Creates a new GLUT window */
* int
* DESCRIPTION: creates a new GLUT window glutCreateWindow(const char *name)
***********************************************************/ {
int glutCreateWindow(const char *name) {
if (!be_app) if (!be_app)
__glutInit(); __glutInit();
@@ -182,86 +169,82 @@ int glutCreateWindow(const char *name) {
if (!__glutConvertDisplayMode(&options)) { if (!__glutConvertDisplayMode(&options)) {
__glutWarning("visual with necessary capabilities not found."); __glutWarning("visual with necessary capabilities not found.");
} }
// if X or Y is negative, then start at a reasonable position // if X or Y is negative, then start at a reasonable position
bool defaultxy = (gState.initX < 0) || (gState.initY < 0); bool defaultxy = gState.initX < 0 || gState.initY < 0;
GlutWindow *window = new GlutWindow(0, const_cast<char*>(name), GlutWindow *window = new GlutWindow(0, name,
(defaultxy ? 50 : gState.initX), (defaultxy ? 50 : gState.initY), defaultxy ? 50 : gState.initX, defaultxy ? 50 : gState.initY,
gState.initWidth, gState.initHeight, options); gState.initWidth, gState.initHeight, options);
return window->num + 1; return window->num + 1;
} }
/***********************************************************
* FUNCTION: glutCreateSubWindow (4.2) /*! Creates a new GLUT subwindow
* Note: a subwindow is a GlutWindow (which is actually
* DESCRIPTION: creates a new GLUT subwindow a BGLView) without its own BWindow
* Note: a subwindow is a GlutWindow (which is actually */
* a BGLView) without its own BWindow int
***********************************************************/ glutCreateSubWindow(int win, int x, int y, int width, int height)
int glutCreateSubWindow(int win, int x, int y, int width, int height) { {
ulong options; ulong options;
if (!__glutConvertDisplayMode(&options)) { if (!__glutConvertDisplayMode(&options)) {
__glutFatalError("visual with necessary capabilities not found."); __glutFatalError("visual with necessary capabilities not found.");
} }
GlutWindow *window = new GlutWindow(gState.windowList[win-1], "child", GlutWindow *window = new GlutWindow(gState.windowList[win-1], "child",
x, y, width, height, options); x, y, width, height, options);
return window->num + 1; return window->num + 1;
} }
/***********************************************************
* FUNCTION: __glutSetWindow /*! Set the current window (utility function) */
*
* DESCRIPTION: set the current window (utility function)
***********************************************************/
void void
__glutSetWindow(GlutWindow * window) __glutSetWindow(GlutWindow *window)
{ {
if (gState.currentWindow) if (gState.currentWindow)
gState.currentWindow->UnlockGL(); gState.currentWindow->UnlockGL();
gState.currentWindow = window; gState.currentWindow = window;
gState.currentWindow->LockGL(); gState.currentWindow->LockGL();
} }
/***********************************************************
* FUNCTION: glutSetWindow (4.3)
* glutGetWindow
*
* DESCRIPTION: set and get the current window
***********************************************************/
void glutSetWindow(int win) {
GlutWindow *window;
if (win < 1 || win > gState.windowListSize) { /*! Set and get the current window */
__glutWarning("glutSetWindow attempted on bogus window."); void
return; glutSetWindow(int win)
} {
window = gState.windowList[win - 1]; GlutWindow *window;
if (!window) {
__glutWarning("glutSetWindow attempted on bogus window."); if (win < 1 || win > gState.windowListSize) {
return; __glutWarning("glutSetWindow attempted on bogus window.");
} return;
__glutSetWindow(window); }
window = gState.windowList[win - 1];
if (!window) {
__glutWarning("glutSetWindow attempted on bogus window.");
return;
}
__glutSetWindow(window);
} }
int glutGetWindow() {
if (gState.currentWindow) { int
return gState.currentWindow->num + 1; glutGetWindow()
} else { {
return 0; if (gState.currentWindow)
} return gState.currentWindow->num + 1;
return 0;
} }
/***********************************************************
* FUNCTION: __glutDestroyWindow /*! Recursively set entries to 0. */
*
* DESCRIPTION: recursively set entries to 0
***********************************************************/
static void static void
__glutDestroyWindow(GlutWindow *window, GlutWindow *initialWindow) { __glutDestroyWindow(GlutWindow *window, GlutWindow *initialWindow)
{
// first, find all children recursively and set their entries to 0 // first, find all children recursively and set their entries to 0
GlutWindow *cur = window->children; GlutWindow *cur = window->children;
while (cur) { while (cur) {
@@ -269,49 +252,47 @@ __glutDestroyWindow(GlutWindow *window, GlutWindow *initialWindow) {
__glutDestroyWindow(cur, initialWindow); __glutDestroyWindow(cur, initialWindow);
cur = siblings; cur = siblings;
} }
/* Remove from parent's children list (only necessary for
non-initial windows and subwindows!). */
GlutWindow *parent = window->parent;
if (parent && parent == initialWindow->parent) {
GlutWindow **prev = &parent->children;
cur = parent->children;
while (cur) {
if (cur == window) {
*prev = cur->siblings;
break;
}
prev = &(cur->siblings);
cur = cur->siblings;
}
}
/* Remove from parent's children list (only necessary for // finally, check if we are the current window, and set to 0
non-initial windows and subwindows!). */ if (gState.currentWindow == window)
GlutWindow *parent = window->parent; gState.currentWindow = 0;
if (parent && parent == initialWindow->parent) {
GlutWindow **prev = &parent->children; gState.windowList[window->num] = 0;
cur = parent->children;
while (cur) {
if (cur == window) {
*prev = cur->siblings;
break;
}
prev = &(cur->siblings);
cur = cur->siblings;
}
}
// finally, check if we are the current window, and set to 0
if (gState.currentWindow == window) {
gState.currentWindow = 0;
}
gState.windowList[window->num] = 0;
} }
/***********************************************************
* FUNCTION: glutDestroyWindow (4.4) /*! Destroy window and all its children. */
* void
* DESCRIPTION: destroy window and all its children glutDestroyWindow(int win)
***********************************************************/ {
void glutDestroyWindow(int win) {
// can't destroy a window if another window has the GL context // can't destroy a window if another window has the GL context
if (gState.currentWindow) if (gState.currentWindow)
gState.currentWindow->UnlockGL(); gState.currentWindow->UnlockGL();
// lock the window // lock the window
GlutWindow *window = gState.windowList[win-1]; GlutWindow *window = gState.windowList[win - 1];
BWindow *bwindow = window->Window(); BWindow *bwindow = window->Window();
bwindow->Lock(); bwindow->Lock();
// if win is the current window, set current window to 0 // if win is the current window, set current window to 0
if (gState.currentWindow == window) { if (gState.currentWindow == window)
gState.currentWindow = 0; gState.currentWindow = 0;
}
// recursively set child entries to 0 // recursively set child entries to 0
__glutDestroyWindow(window, window); __glutDestroyWindow(window, window);
@@ -322,7 +303,7 @@ void glutDestroyWindow(int win) {
window->UnlockGL(); window->UnlockGL();
// now, if the window was top-level, delete its BWindow // now, if the window was top-level, delete its BWindow
if(!window->parent) { if (!window->parent) {
bwindow->Quit(); bwindow->Quit();
} else { } else {
// else, detach it from the BWindow and delete it // else, detach it from the BWindow and delete it
@@ -330,36 +311,35 @@ void glutDestroyWindow(int win) {
delete window; delete window;
bwindow->Unlock(); bwindow->Unlock();
} }
// relock GL if the current window is still valid // relock GL if the current window is still valid
if(gState.currentWindow) if (gState.currentWindow)
gState.currentWindow->LockGL(); gState.currentWindow->LockGL();
} }
/***********************************************************
* FUNCTION: __glutDestroyAllWindows /*! Destroy all windows when exit() is called this seems to be necessary
* to avoid delays and crashes when using BDirectWindow.
* DESCRIPTION: destroy all windows when exit() is called */
* this seems to be necessary to avoid delays void
* and crashes when using BDirectWindow __glutDestroyAllWindows()
***********************************************************/ {
void __glutDestroyAllWindows() { for (int i = 0; i < gState.windowListSize; i++) {
for(int i=0; i<gState.windowListSize; i++) { if (gState.windowList[i])
if (gState.windowList[i]) {
glutDestroyWindow(i + 1); glutDestroyWindow(i + 1);
}
} }
gState.display->Lock(); gState.display->Lock();
gState.display->Quit(); gState.display->Quit();
status_t ignored; status_t ignored;
wait_for_thread(gState.appthread, &ignored); wait_for_thread(gState.appthread, &ignored);
} }
/***********************************************************
* FUNCTION: glutPostRedisplay (4.5) /*! Mark window as needing redisplay */
* void
* DESCRIPTION: mark window as needing redisplay glutPostRedisplay()
***********************************************************/ {
void glutPostRedisplay() {
gState.currentWindow->Window()->Lock(); gState.currentWindow->Window()->Lock();
gState.currentWindow->anyevents = true; gState.currentWindow->anyevents = true;
gState.currentWindow->displayEvent = true; gState.currentWindow->displayEvent = true;
@@ -367,12 +347,11 @@ void glutPostRedisplay() {
gBlock.QuickNewEvent(); gBlock.QuickNewEvent();
} }
/***********************************************************
* FUNCTION: glutPostWindowRedisplay /*! Mark window as needing redisplay */
* void
* DESCRIPTION: mark window as needing redisplay glutPostWindowRedisplay(int win)
***********************************************************/ {
void glutPostWindowRedisplay(int win) {
GlutWindow *gwin = gState.windowList[win - 1]; GlutWindow *gwin = gState.windowList[win - 1];
gwin->Window()->Lock(); gwin->Window()->Lock();
gwin->anyevents = true; gwin->anyevents = true;
@@ -381,86 +360,95 @@ void glutPostWindowRedisplay(int win) {
gBlock.QuickNewEvent(); gBlock.QuickNewEvent();
} }
/***********************************************************
* FUNCTION: glutSwapBuffers (4.6) void
* glutSwapBuffers()
* DESCRIPTION: swap buffers {
***********************************************************/
void glutSwapBuffers() {
gState.currentWindow->SwapBuffers(); gState.currentWindow->SwapBuffers();
} }
/***********************************************************
* FUNCTION: glutPositionWindow (4.7) /*! Move window */
* void
* DESCRIPTION: move window glutPositionWindow(int x, int y)
***********************************************************/ {
void glutPositionWindow(int x, int y) {
BDirectWindow *win = dynamic_cast<BDirectWindow*>(gState.currentWindow->Window()); BDirectWindow *win = dynamic_cast<BDirectWindow*>(gState.currentWindow->Window());
if (win == NULL)
return;
win->Lock(); win->Lock();
if (gState.currentWindow->parent) if (gState.currentWindow->parent)
gState.currentWindow->MoveTo(x, y); // move the child view gState.currentWindow->MoveTo(x, y); // move the child view
else { else {
if(win->IsFullScreen()) { if (win->IsFullScreen())
win->SetFullScreen(false); win->SetFullScreen(false);
}
win->MoveTo(x, y); // move the window win->MoveTo(x, y); // move the window
} }
win->Unlock(); win->Unlock();
} }
/***********************************************************
* FUNCTION: glutReshapeWindow (4.8) /*! Reshape window (we'll catch the callback when the view gets
* a Draw() message).
* DESCRIPTION: reshape window (we'll catch the callback */
* when the view gets a Draw() message void
***********************************************************/ glutReshapeWindow(int width, int height)
void glutReshapeWindow(int width, int height) { {
BDirectWindow *win = dynamic_cast<BDirectWindow*>(gState.currentWindow->Window()); BDirectWindow *win = dynamic_cast<BDirectWindow*>(gState.currentWindow->Window());
if (win == NULL)
return;
win->Lock(); win->Lock();
if (gState.currentWindow->parent) if (gState.currentWindow->parent) {
gState.currentWindow->ResizeTo(width-1, height-1); // resize the child // resize the child
else { gState.currentWindow->ResizeTo(width - 1, height - 1);
if(win->IsFullScreen()) { } else {
if (win->IsFullScreen())
win->SetFullScreen(false); win->SetFullScreen(false);
}
win->ResizeTo(width-1, height-1); // resize the parent // resize the parent
win->ResizeTo(width - 1, height - 1);
} }
win->Unlock(); win->Unlock();
} }
/***********************************************************
* FUNCTION: glutFullScreen (4.9) /*! Makes the window full screen */
* void
* DESCRIPTION: makes the window full screen glutFullScreen()
***********************************************************/ {
void glutFullScreen() {
BDirectWindow *win = dynamic_cast<BDirectWindow*>(gState.currentWindow->Window()); BDirectWindow *win = dynamic_cast<BDirectWindow*>(gState.currentWindow->Window());
if (win == NULL)
return;
win->Lock(); win->Lock();
win->SetFullScreen(true); win->SetFullScreen(true);
win->Unlock(); win->Unlock();
} }
/***********************************************************
* FUNCTION: glutPopWindow (4.10)
* glutPushWindow
*
* DESCRIPTION: change the stacking order of the current window
* NOTE: I can't figure out how to do this for windows,
* and there is no concept of "stacking order" for
* subwindows, so these are currently no-ops.
***********************************************************/
void glutPopWindow() { }
void glutPushWindow() { }
/*********************************************************** /*! Supposed to change the stacking order of the current window
* FUNCTION: glutShowWindow (4.11) NOTE: I can't figure out how to do this for windows,
* glutHideWindow and there is no concept of "stacking order" for
* glutIconifyWindow subwindows, so these are currently no-ops.
* */
* DESCRIPTION: change display status of current window void
***********************************************************/ glutPopWindow()
void glutShowWindow() { {
}
/*! Same problem as glutPopWindow() */
void
glutPushWindow()
{
}
void
glutShowWindow()
{
gState.currentWindow->Window()->Lock(); gState.currentWindow->Window()->Lock();
if (gState.currentWindow->parent) // subwindow if (gState.currentWindow->parent) // subwindow
gState.currentWindow->Show(); gState.currentWindow->Show();
@@ -472,17 +460,26 @@ void glutShowWindow() {
gState.currentWindow->Window()->Unlock(); gState.currentWindow->Window()->Unlock();
} }
void glutHideWindow() {
void
glutHideWindow()
{
gState.currentWindow->Window()->Lock(); gState.currentWindow->Window()->Lock();
if (gState.currentWindow->parent) // subwindow if (gState.currentWindow->parent) // subwindow
gState.currentWindow->Hide(); gState.currentWindow->Hide();
else else
gState.currentWindow->Window()->Hide(); // show the actual BWindow gState.currentWindow->Window()->Hide(); // show the actual BWindow
gState.currentWindow->Window()->Unlock(); gState.currentWindow->Window()->Unlock();
} }
void glutIconifyWindow() {
if(gState.currentWindow->parent) /*! Minimizes window */
void
glutIconifyWindow()
{
if (gState.currentWindow->parent)
__glutFatalError("can't iconify a subwindow"); __glutFatalError("can't iconify a subwindow");
gState.currentWindow->Window()->Lock(); gState.currentWindow->Window()->Lock();
@@ -490,37 +487,38 @@ void glutIconifyWindow() {
gState.currentWindow->Window()->Unlock(); gState.currentWindow->Window()->Unlock();
} }
/***********************************************************
* FUNCTION: glutSetWindowTitle (4.12) /*! Sets the window title */
* glutSetIconTitle void
* glutSetWindowTitle(const char *name)
* DESCRIPTION: set the window title (icon title is same) {
***********************************************************/
void glutSetWindowTitle(const char *name) {
if (gState.currentWindow->parent) if (gState.currentWindow->parent)
__glutFatalError("glutSetWindowTitle: isn't a top-level window"); __glutFatalError("glutSetWindowTitle: isn't a top-level window");
gState.currentWindow->Window()->Lock(); gState.currentWindow->Window()->Lock();
gState.currentWindow->Window()->SetTitle(name); gState.currentWindow->Window()->SetTitle(name);
gState.currentWindow->Window()->Unlock(); gState.currentWindow->Window()->Unlock();
} }
void glutSetIconTitle(const char *name) {
/*! Same as glutSetWindowTitle() */
void
glutSetIconTitle(const char *name)
{
glutSetWindowTitle(name); glutSetWindowTitle(name);
} }
/***********************************************************
* FUNCTION: __glutConvertDisplayMode /*! Converts the current display mode into a BGLView
* display mode, printing warnings as appropriate.
* DESCRIPTION: converts the current display mode into a BGLView
* display mode, printing warnings as appropriate. \param options if non-NULL, the current display mode is
* returned in it.
* PARAMETERS: if options is non-NULL, the current display mode is \return 1 if the current display mode is possible, else 0
* returned in it. */
* int
* RETURNS: 1 if the current display mode is possible, else 0 __glutConvertDisplayMode(unsigned long *options)
***********************************************************/ {
int __glutConvertDisplayMode(unsigned long *options) {
if (gState.displayString) { if (gState.displayString) {
/* __glutDisplayString should be NULL except if /* __glutDisplayString should be NULL except if
glutInitDisplayString has been called to register a glutInitDisplayString has been called to register a
@@ -530,68 +528,72 @@ int __glutConvertDisplayMode(unsigned long *options) {
return __glutConvertDisplayModeFromString(options); return __glutConvertDisplayModeFromString(options);
} }
if(options) { if (options) {
ulong newoptions = 0; ulong newoptions = 0;
if(gState.displayMode & GLUT_ACCUM) if (gState.displayMode & GLUT_ACCUM)
newoptions |= BGL_ACCUM; newoptions |= BGL_ACCUM;
if(gState.displayMode & GLUT_ALPHA) if (gState.displayMode & GLUT_ALPHA)
newoptions |= BGL_ALPHA; newoptions |= BGL_ALPHA;
if(gState.displayMode & GLUT_DEPTH) if (gState.displayMode & GLUT_DEPTH)
newoptions |= BGL_DEPTH; newoptions |= BGL_DEPTH;
if(gState.displayMode & GLUT_DOUBLE) if (gState.displayMode & GLUT_DOUBLE)
newoptions |= BGL_DOUBLE; newoptions |= BGL_DOUBLE;
if(gState.displayMode & GLUT_STENCIL) if (gState.displayMode & GLUT_STENCIL)
newoptions |= BGL_STENCIL; newoptions |= BGL_STENCIL;
*options = newoptions; *options = newoptions;
} }
if(gState.displayMode & GLUT_INDEX) { if (gState.displayMode & GLUT_INDEX) {
__glutWarning("BeOS doesn't support indexed color"); __glutWarning("BeOS doesn't support indexed color");
return 0; return 0;
} }
if(gState.displayMode & GLUT_MULTISAMPLE) { if (gState.displayMode & GLUT_MULTISAMPLE) {
return 1; // try to go without multisampling return 1; // try to go without multisampling
} }
if(gState.displayMode & GLUT_STEREO) { if (gState.displayMode & GLUT_STEREO) {
__glutWarning("BeOS doesn't support stereo windows"); __glutWarning("BeOS doesn't support stereo windows");
return 0; return 0;
} }
if(gState.displayMode & GLUT_LUMINANCE) { if (gState.displayMode & GLUT_LUMINANCE) {
__glutWarning("BeOS doesn't support luminance color model"); __glutWarning("BeOS doesn't support luminance color model");
return 0; return 0;
} }
return 1; // visual supported return 1; // visual supported
} }
/***********************************************************
* CLASS: GlutBWindow // #pragma mark -
*
* DESCRIPTION: very thin wrapper around BWindow
***********************************************************/ /*! Very thin wrapper around BWindow */
GlutBWindow::GlutBWindow(BRect frame, char *name) : GlutBWindow::GlutBWindow(BRect frame, const char *name)
BDirectWindow(frame, name, B_TITLED_WINDOW, 0) { : BDirectWindow(frame, name, B_TITLED_WINDOW, 0)
{
fConnectionDisabled = false; fConnectionDisabled = false;
bgl = 0; bgl = 0;
SetPulseRate(100000); SetPulseRate(100000);
if (!SupportsWindowMode()) { if (!SupportsWindowMode()) {
__glutFatalError("video card doesn't support windowed operation"); __glutFatalError("video card doesn't support windowed operation");
} }
} }
void GlutBWindow::DirectConnected( direct_buffer_info *info ) {
void
GlutBWindow::DirectConnected(direct_buffer_info *info)
{
if (!bgl) if (!bgl)
return; return;
bgl->DirectConnected(info); bgl->DirectConnected(info);
if(!fConnectionDisabled) { if (!fConnectionDisabled)
bgl->EnableDirectMode(true); bgl->EnableDirectMode(true);
}
int newVisState; int newVisState;
if((info->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_START) { if ((info->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_START)
bgl->visible = true; bgl->visible = true;
}
if(!bgl->visible || info->buffer_state == B_DIRECT_STOP) if (!bgl->visible || info->buffer_state == B_DIRECT_STOP)
newVisState = GLUT_HIDDEN; newVisState = GLUT_HIDDEN;
else { else {
if (info->clip_list_count == 0) if (info->clip_list_count == 0)
@@ -601,40 +603,57 @@ void GlutBWindow::DirectConnected( direct_buffer_info *info ) {
else else
newVisState = GLUT_PARTIALLY_RETAINED; newVisState = GLUT_PARTIALLY_RETAINED;
} }
if(newVisState != bgl->visState) {
if (newVisState != bgl->visState) {
bgl->visState = newVisState; bgl->visState = newVisState;
bgl->anyevents = bgl->windowStatusEvent = true; bgl->anyevents = bgl->windowStatusEvent = true;
gBlock.NewEvent(); gBlock.NewEvent();
} }
} }
GlutBWindow::~GlutBWindow() {
GlutBWindow::~GlutBWindow()
{
fConnectionDisabled = true; fConnectionDisabled = true;
if(bgl) { if (bgl)
bgl->EnableDirectMode(false); bgl->EnableDirectMode(false);
}
if(!IsHidden()) if (!IsHidden())
Hide(); Hide();
Sync(); Sync();
} }
bool GlutBWindow::QuitRequested() {
bool
GlutBWindow::QuitRequested()
{
gState.quitAll = true; gState.quitAll = true;
gBlock.NewEvent(); gBlock.NewEvent();
return false; // don't quit now, wait for main thread to do it return false;
// don't quit now, wait for main thread to do it
} }
void GlutBWindow::Minimize(bool minimize) {
void
GlutBWindow::Minimize(bool minimize)
{
bgl->visible = !minimize; bgl->visible = !minimize;
BWindow::Minimize(minimize); BWindow::Minimize(minimize);
} }
void GlutBWindow::Hide() {
void
GlutBWindow::Hide()
{
BWindow::Hide(); BWindow::Hide();
bgl->visible = false; bgl->visible = false;
} }
void GlutBWindow::Show() {
void
GlutBWindow::Show()
{
BWindow::Show(); BWindow::Show();
bgl->visible = true; bgl->visible = true;
} }
+26 -35
View File
@@ -5,33 +5,23 @@
* and is provided without guarantee or warrantee expressed or * and is provided without guarantee or warrantee expressed or
* implied. This program is -not- in the public domain. * implied. This program is -not- in the public domain.
* *
*
* FILE: glutWindow.h
*
* DESCRIPTION: the GlutWindow class saves all events for * DESCRIPTION: the GlutWindow class saves all events for
* handling by main thread * handling by main thread
***********************************************************/ ***********************************************************/
/***********************************************************
* Headers
***********************************************************/
#include <GL/glut.h> #include <GL/glut.h>
#include <Window.h> #include <Window.h>
#include <GLView.h> #include <GLView.h>
/***********************************************************
* CLASS: GlutWindow /*! All information needed for windows and
* subwindows (handled as similarly as possible).
* INHERITS FROM: BGLView (NOT BWindow!) */
*
* DESCRIPTION: all information needed for windows and
* subwindows (handled as similarly as possible)
***********************************************************/
class GlutWindow : public BGLView { class GlutWindow : public BGLView {
public: public:
GlutWindow(GlutWindow *nparent, char *name, int x, int y, int width, GlutWindow(GlutWindow *nparent, const char *name, int x, int y, int width,
int height, ulong options); int height, ulong options);
virtual void MessageReceived(BMessage *message); virtual void MessageReceived(BMessage *message);
void KeyDown(const char *bytes, int32 numBytes); void KeyDown(const char *bytes, int32 numBytes);
void KeyUp(const char *bytes, int32 numBytes); void KeyUp(const char *bytes, int32 numBytes);
@@ -44,7 +34,7 @@ public:
void ErrorCallback(GLenum errorCode); void ErrorCallback(GLenum errorCode);
static long MenuThread(void *menu); static long MenuThread(void *menu);
int num; // window number returned to user int num; // window number returned to user
int cursor; // my cursor int cursor; // my cursor
#define GLUT_MAX_MENUS 3 #define GLUT_MAX_MENUS 3
@@ -53,23 +43,23 @@ public:
uint32 m_buttons; // the last mouse button state uint32 m_buttons; // the last mouse button state
/* Window relationship state. */ /* Window relationship state. */
GlutWindow *parent; /* parent window */ GlutWindow *parent; /* parent window */
GlutWindow *children; /* first child window */ GlutWindow *children; /* first child window */
GlutWindow *siblings; /* next sibling */ GlutWindow *siblings; /* next sibling */
// leave out buttons and dials callbacks that we don't support // leave out buttons and dials callbacks that we don't support
GLUTdisplayCB display; /* redraw */ GLUTdisplayCB display; /* redraw */
GLUTreshapeCB reshape; /* resize (width,height) */ GLUTreshapeCB reshape; /* resize (width,height) */
GLUTmouseCB mouse; /* mouse (button,state,x,y) */ GLUTmouseCB mouse; /* mouse (button,state,x,y) */
GLUTmotionCB motion; /* motion (x,y) */ GLUTmotionCB motion; /* motion (x,y) */
GLUTpassiveCB passive; /* passive motion (x,y) */ GLUTpassiveCB passive; /* passive motion (x,y) */
GLUTentryCB entry; /* window entry/exit (state) */ GLUTentryCB entry; /* window entry/exit (state) */
GLUTkeyboardCB keyboard; /* keyboard (ASCII,x,y) */ GLUTkeyboardCB keyboard; /* keyboard (ASCII,x,y) */
GLUTkeyboardCB keyboardUp; /* keyboard up (ASCII,x,y) */ GLUTkeyboardCB keyboardUp; /* keyboard up (ASCII,x,y) */
GLUTvisibilityCB visibility; /* visibility */ GLUTvisibilityCB visibility; /* visibility */
GLUTspecialCB special; /* special key */ GLUTspecialCB special; /* special key */
GLUTspecialCB specialUp; /* special key up */ GLUTspecialCB specialUp; /* special key up */
GLUTwindowStatusCB windowStatus; /* window status */ GLUTwindowStatusCB windowStatus; /* window status */
bool anyevents; // were any events received? bool anyevents; // were any events received?
bool displayEvent; // call display bool displayEvent; // call display
@@ -85,7 +75,7 @@ public:
bool specialUpEvent; // call special bool specialUpEvent; // call special
bool statusEvent; // menu status changed bool statusEvent; // menu status changed
bool menuEvent; // menu selected bool menuEvent; // menu selected
int button, mouseState; // for mouse callback int button, mouseState; // for mouse callback
int mouseX, mouseY; // for mouse callback int mouseX, mouseY; // for mouse callback
int motionX, motionY; // for motion callback int motionX, motionY; // for motion callback
@@ -113,8 +103,9 @@ public:
***********************************************************/ ***********************************************************/
class GlutBWindow : public BDirectWindow { class GlutBWindow : public BDirectWindow {
public: public:
GlutBWindow(BRect frame, char *name); GlutBWindow(BRect frame, const char *name);
~GlutBWindow(); ~GlutBWindow();
void DirectConnected(direct_buffer_info *info); void DirectConnected(direct_buffer_info *info);
bool QuitRequested(); // exits app bool QuitRequested(); // exits app
void Minimize(bool minimized); // minimized windows are not visible void Minimize(bool minimized); // minimized windows are not visible