Showing posts with label glut. Show all posts
Showing posts with label glut. Show all posts

Friday, February 1, 2008

New extension: gluttonGetOption

In GLUT, there is a handy-dandy function for setting various global options:

void glutSetOption( GLenum eWhat , int value );


This is great, but what if you want to change things temporarily and you don't know what the original settings are? This could happen, for example, if you're writing a library function that sits between GLUT and the rest of your application.

What you need is a reading analogue to glutSetOption, something like a glutGetOption. Unfortunately, there is no glutGetOption.

Fortunately, there is a gluttonGetOption in the extended GLUT-like library I'm working on, glutton.

To make this function, I first added the declaration in freeglut_ext.h (glutton is based upon the marvelous freeglut library):

int FGAPIENTRY gluttonGetOption( GLenum eWhat );


Then, in freeglut_state.c, I copied the glutSetOption implementation and reversed the data flow:

int FGAPIENTRY gluttonGetOption( GLenum eWhat )
  {
  FREEGLUT_EXIT_IF_NOT_INITIALISED ( "gluttonGetOption" );
  
    switch( eWhat )
    {
    case GLUT_INIT_WINDOW_X:
        return fgState.Position.X;
        break;

    case GLUT_INIT_WINDOW_Y:
        return fgState.Position.Y;
        break;

    case GLUT_INIT_WINDOW_WIDTH:
        return fgState.Size.X;
        break;

    case GLUT_INIT_WINDOW_HEIGHT:
        return fgState.Size.Y;
        break;

    case GLUT_INIT_DISPLAY_MODE:
        return (int)fgState.DisplayMode;
        break;

    case GLUT_ACTION_ON_WINDOW_CLOSE:
        return fgState.ActionOnWindowClose;
        break;

    case GLUT_RENDERING_CONTEXT:
        return fgState.UseCurrentContext;
        break;

    case GLUT_DIRECT_RENDERING:
        return fgState.DirectContext;
        break;

    case GLUT_WINDOW_CURSOR:
        return fgStructure.CurrentWindow->State.Cursor;
        break;

    case GLUT_AUX:
      return fgState.AuxiliaryBufferNumber;
      break;

    case GLUT_MULTISAMPLE:
      return fgState.SampleNumber;
      break;

    default:
      fgWarning( "glutGetOption(): missing enum handle %d", eWhat );
      return 0xDeadBeef;
      break;
    }
  }


It doesn't get much easier than that.

Thursday, January 31, 2008

Extension Revisited For Linux: gluttonCloseRequestedFunc

A few days ago I posted that I had written a glutton extension for the GLUT api called gluttonCloseRequestedFunc. The intended purpose of this function is to provide a callback function that is called when a user has decided to close a window. During this function, the application has the opportunity to do things like display a dialog box to ask the user to confirm the close. In the event the callback function determines that the close should be canceled, it can set the parameter "*Action" to the value gluttonCloseRequestedIgnore, and glutton will then ignore the close request rather than close the window.

At the time, I had only implemented the extension for Windows, and promised to revisit this one for Linux. As it turns out, implementing it on Linux was extremely simple, because the Linux implementation of freeglut already had 99% of what was necessary to get this to work. This means that it is very likely that this will work for other *nix/X11 implementations with no additional work, but I don't have access to such environments, so I cannot tell with certainty.

Anyway, as I said, the implementation is very simple. I merely copied the Windows portion that does the callback into glutMainLoopEvent's handler for ClientMessage events. More specifically, for fgDisplay.DeleteWindow ClientMessage events:



case ClientMessage:
/* Destroy the window when the WM_DELETE_WINDOW message arrives */
if( (Atom) event.xclient.data.l[ 0 ] == fgDisplay.DeleteWindow )
{
GETWINDOW( xclient );
#ifdef GLUTTON
{
int Action = gluttonCloseRequestedDefault;
INVOKE_WCB( *window , GluttonCloseRequested , ( &Action ) );
switch( Action )
{
case gluttonCloseRequestedDefault: break;
/* proceed to close the window (fgDestroyWindow, below) */
case gluttonCloseRequestedIgnore: return;
/* ignore the message. */
}
}
#endif

fgDestroyWindow ( window );



I honestly didn't expect this to be as easy as it was. I was expecting to have to go through the pain of telling X that I wanted it to send a ClientMessage to glutton, and to deal with finding all of the "atoms" involved. Many thanks to the freeglut developers for relieving me of /that/ burden!

Next time: keystroke management for linux. [ Edit: No need - I cannot reproduce the keystroke bug on Fedora 8, so I won't be spending my time on trying to fix it :-) ]