Main Page   Class Hierarchy   Compound List   File List   Compound Members  

gfxGLWindowGLUT.cpp

00001 //////////////////////////////////////////////////////////////////////
00002 // Copyright (c) 2002 David Pritchard <drpritch@alumni.uwaterloo.ca>
00003 // 
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License
00006 // as published by the Free Software Foundation; either
00007 // version 2 of the License, or (at your option) any later
00008 // version.
00009 // 
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 
00019 #include <freecloth/gfx/gfxGLWindowGLUT.h>
00020 #include <freecloth/gfx/gfxConfig.h>
00021 #include <freecloth/resmgt/rcShdPtr.h>
00022 #include <freecloth/base/GL_glut.h>
00023 
00024 ////////////////////////////////////////////////////////////////////////////////
00025 // CLASS GfxGLWindowGLUT
00026 
00027 GfxGLWindowGLUT::WindowMap GfxGLWindowGLUT::_windowMap;
00028 UInt32 GfxGLWindowGLUT::_nbIdleRegistered = 0;
00029 
00030 //------------------------------------------------------------------------------
00031 
00032 GfxGLWindowGLUT::GfxGLWindowGLUT(
00033     const GfxConfig& config,
00034     const String& title
00035 ) : _idleEvents( false ),
00036     _closeReceived( false )
00037 {
00038     // FIXME: need some way of getting argc, argv to glutInit
00039     ::glutInitDisplayMode(
00040         GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE
00041     );
00042 
00043     ::glutInitWindowSize( 
00044         config.getWindowInfo()._width, config.getWindowInfo()._height
00045     );
00046     _width = config.getWindowInfo()._width;
00047     _height = config.getWindowInfo()._height;
00048     ::glutInitWindowPosition( 
00049         config.getWindowInfo()._x, config.getWindowInfo()._y
00050     );
00051 
00052     _windowId = ::glutCreateWindow( title.c_str() );
00053     _windowMap[ _windowId ] = this;
00054 
00055     // FIXME: need a way to select the video mode for fullscreen...
00056     if ( config.getFullscreen() ) {
00057         ::glutFullScreen();
00058     }
00059 }
00060 
00061 //------------------------------------------------------------------------------
00062 
00063 GfxGLWindowGLUT::~GfxGLWindowGLUT()
00064 {
00065     DGFX_ASSERT( _closeReceived );
00066     if ( _idleEvents && --_nbIdleRegistered == 0 ) {
00067         unregisterIdleCB();
00068     }
00069 }
00070 
00071 //------------------------------------------------------------------------------
00072 
00073 void GfxGLWindowGLUT::enableIdleEvents( bool idleEvents )
00074 {
00075     if ( idleEvents == _idleEvents ) {
00076         return;
00077     }
00078     _idleEvents = idleEvents;
00079     if ( _idleEvents && _nbIdleRegistered++ == 0 ) {
00080         registerIdleCB();
00081     }
00082     else if ( ! _idleEvents && --_nbIdleRegistered == 0 ) {
00083         unregisterIdleCB();
00084     }
00085 }
00086 
00087 //------------------------------------------------------------------------------
00088 
00089 void GfxGLWindowGLUT::close()
00090 {
00091     // This will be handled later
00092     // FIXME: does it really *need* to be handled later?
00093     _closeReceived = true;
00094 }
00095 
00096 //------------------------------------------------------------------------------
00097 
00098 void GfxGLWindowGLUT::handleEvents()
00099 {
00100 }
00101 
00102 //------------------------------------------------------------------------------
00103 
00104 void GfxGLWindowGLUT::eventLoop()
00105 {
00106     registerCBs();
00107     ::glutMainLoop();
00108 }
00109 
00110 //------------------------------------------------------------------------------
00111 
00112 void GfxGLWindowGLUT::swapBuffers()
00113 {
00114     ::glutSwapBuffers();
00115 }
00116 
00117 //------------------------------------------------------------------------------
00118 
00119 UInt32 GfxGLWindowGLUT::getWidth() const
00120 {
00121     return _width;
00122 }
00123 
00124 //------------------------------------------------------------------------------
00125 
00126 UInt32 GfxGLWindowGLUT::getHeight() const
00127 {
00128     return _height;
00129 }
00130 
00131 //------------------------------------------------------------------------------
00132 
00133 void GfxGLWindowGLUT::postRedisplay()
00134 {
00135     ::glutSetWindow( _windowId );
00136     ::glutPostRedisplay();
00137 }
00138 
00139 //------------------------------------------------------------------------------
00140 
00141 void GfxGLWindowGLUT::registerIdleCB()
00142 {
00143     ::glutIdleFunc( idleCB );
00144 }
00145 
00146 //------------------------------------------------------------------------------
00147 
00148 void GfxGLWindowGLUT::unregisterIdleCB()
00149 {
00150     ::glutIdleFunc( 0 );
00151 }
00152 
00153 //------------------------------------------------------------------------------
00154 
00155 void GfxGLWindowGLUT::registerCBs()
00156 {
00157     ::glutDisplayFunc( displayCB );
00158     ::glutKeyboardFunc( keyboardCB );
00159     ::glutMouseFunc( mouseCB );
00160     ::glutMotionFunc( motionCB );
00161     ::glutPassiveMotionFunc( passiveMotionCB );
00162     ::glutSpecialFunc( specialCB );
00163     ::glutReshapeFunc( reshapeCB );
00164     // Idle is registered later, to allow a virtual method
00165 }
00166 
00167 //------------------------------------------------------------------------------
00168 
00169 void GfxGLWindowGLUT::closeReceived()
00170 {
00171     BaseClass::closeReceived();
00172     if ( _windowId >= 0 ) {
00173         _windowMap.erase( _windowId );
00174         ::glutDestroyWindow( _windowId );
00175         _windowId = -1;
00176     }
00177 }
00178 
00179 //------------------------------------------------------------------------------
00180 
00181 GfxGLWindowGLUT& GfxGLWindowGLUT::getWindow()
00182 {
00183     WindowMap::iterator wi = _windowMap.find( ::glutGetWindow() );
00184     DGFX_ASSERT( wi != _windowMap.end() );
00185     return *(wi->second);
00186 }
00187 
00188 //------------------------------------------------------------------------------
00189 
00190 void GfxGLWindowGLUT::displayCB()
00191 {
00192     GfxGLWindowGLUT& window = getWindow();
00193     window.displayReceived();
00194     window.handleMiscEvents();
00195 }
00196 
00197 //------------------------------------------------------------------------------
00198 
00199 void GfxGLWindowGLUT::idleCB()
00200 {
00201     WindowMap::iterator wi;
00202     UInt32 size = _windowMap.size();
00203     for ( wi = _windowMap.begin(); wi != _windowMap.end(); ++wi ) {
00204         wi->second->idleReceived();
00205         wi->second->handleMiscEvents();
00206         if ( size != _windowMap.size() ) {
00207             // If the size changes, the iterators are invalid and bad
00208             // things we likely happen.
00209             return;
00210         }
00211     }
00212 }
00213 
00214 //------------------------------------------------------------------------------
00215 
00216 void GfxGLWindowGLUT::keyboardCB( unsigned char key, int x, int y )
00217 {
00218     GfxGLWindowGLUT& window = getWindow();
00219 
00220     KeyID keyId = translateKey( key );
00221     ModBitfield mods = getModifiers();
00222 
00223     // FIXME: what does GLUT's key CB correspond to? keydown, or 
00224     // key press?
00225     //window.keyDownReceived( keyId, mods );
00226     window.keyPressed( keyId, mods );
00227     window.handleMiscEvents();
00228 }
00229 
00230 //------------------------------------------------------------------------------
00231 
00232 void GfxGLWindowGLUT::mouseCB( int button, int state, int x, int y )
00233 {
00234     GfxGLWindowGLUT& window = getWindow();
00235 
00236     ButtonID buttonId = translateButton( button );
00237     if ( buttonId == MBN_NONE ) {
00238         return;
00239     }
00240     if ( state == GLUT_DOWN ) {
00241         window.mouseDownReceived( x, y, buttonId );
00242     }
00243     else {
00244         DGFX_ASSERT( state == GLUT_UP );
00245         window.mouseUpReceived( x, y, buttonId );
00246     }
00247     window.handleMiscEvents();
00248 }
00249 
00250 //------------------------------------------------------------------------------
00251 
00252 void GfxGLWindowGLUT::motionCB( int x, int y )
00253 {
00254     GfxGLWindowGLUT& window = getWindow();
00255     window.mouseMoveReceived( x, y );
00256     window.handleMiscEvents();
00257 }
00258 
00259 //------------------------------------------------------------------------------
00260 
00261 void GfxGLWindowGLUT::passiveMotionCB( int x, int y )
00262 {
00263     GfxGLWindowGLUT& window = getWindow();
00264     window.mouseMoveReceived( x, y );
00265     window.handleMiscEvents();
00266 }
00267 
00268 //------------------------------------------------------------------------------
00269 
00270 void GfxGLWindowGLUT::specialCB( int key, int x, int y )
00271 {
00272     GfxGLWindowGLUT& window = getWindow();
00273     // FIXME: add extended key handling
00274     window.handleMiscEvents();
00275 }
00276 
00277 //------------------------------------------------------------------------------
00278 
00279 void GfxGLWindowGLUT::reshapeCB( int width, int height )
00280 {
00281     GfxGLWindowGLUT& window = getWindow();
00282     window.windowResized( 0, 0, width, height );
00283     window.handleMiscEvents();
00284     window._width = width;
00285     window._height = height;
00286 }
00287 
00288 //------------------------------------------------------------------------------
00289 
00290 void GfxGLWindowGLUT::handleMiscEvents()
00291 {
00292     if ( _closeReceived ) {
00293         closeReceived();
00294     }
00295 }
00296 
00297 //------------------------------------------------------------------------------
00298 
00299 GfxWindow::KeyID GfxGLWindowGLUT::translateKey(
00300     unsigned char key
00301 ) {
00302     // As it happens, our key map is *exactly* like ASCII... funny how that
00303     // accidentally happens.
00304     return static_cast<KeyID>( key );
00305 }
00306 
00307 //------------------------------------------------------------------------------
00308 
00309 GfxWindow::ModBitfield GfxGLWindowGLUT::getModifiers()
00310 {
00311     ModBitfield result = 0;
00312     int mod = ::glutGetModifiers();
00313     // FIXME: GLUT counts capslock as shift...
00314     if ( mod & GLUT_ACTIVE_SHIFT ) {
00315         result |= KBM_SHIFT;
00316     }
00317     if ( mod & GLUT_ACTIVE_CTRL ) {
00318         result |= KBM_CONTROL;
00319     }
00320     if ( mod & GLUT_ACTIVE_ALT ) {
00321         result |= KBM_ALT;
00322     }
00323     return result;
00324 }
00325 
00326 //------------------------------------------------------------------------------
00327 
00328 GfxWindow::ButtonID GfxGLWindowGLUT::translateButton(
00329     Int32 button
00330 ) {
00331     switch( button ) {
00332         case GLUT_LEFT_BUTTON:
00333             return MBN_LEFT;
00334         case GLUT_MIDDLE_BUTTON:
00335             return MBN_MIDDLE;
00336         case GLUT_RIGHT_BUTTON:
00337             return MBN_RIGHT;
00338     }
00339     return MBN_NONE;
00340 }

Generated on Wed Apr 23 15:58:52 2003 for Freecloth by doxygen1.3-rc3