Ejemplo n.º 1
0
int fgHasSpaceball(void)
{
    if(sball_initialized == 0) {
        fgInitialiseSpaceball();
        if(sball_initialized != 1) {
            fgWarning("fgInitialiseSpaceball failed\n");
            return 0;
        }
    }

#if TARGET_HOST_POSIX_X11
    /* XXX this function should somehow query the driver if there's a device
     * plugged in, as opposed to just checking if there's a driver to talk to.
     */
    return spnav_fd() == -1 ? 0 : 1;
#else
    return 0;
#endif
}
Ejemplo n.º 2
0
/*
 * Return the width in pixels of a stroke character
 */
int FGAPIENTRY glutStrokeWidth( void* fontID, int character )
{
    const SFG_StrokeChar *schar;
    SFG_StrokeFont* font;
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeWidth" );
    font = fghStrokeByID( fontID );
    if (!font)
    {
        fgWarning("glutStrokeWidth: stroke font 0x%08x not found. Make sure you're not passing a bitmap font.\n",fontID);
        return 0;
    }
    freeglut_return_val_if_fail( ( character >= 0 ) &&
                                 ( character < font->Quantity ),
                                 0
    );
    schar = font->Characters[ character ];
    freeglut_return_val_if_fail( schar, 0 );

    return ( int )( schar->Right + 0.5 );
}
Ejemplo n.º 3
0
/*
 * Matches a font ID with a SFG_Font structure pointer.
 * This was changed to match the GLUT header style.
 */
static SFG_Font* fghFontByID( void* font )
{
    if( font == GLUT_BITMAP_8_BY_13        )
        return &fgFontFixed8x13;
    if( font == GLUT_BITMAP_9_BY_15        )
        return &fgFontFixed9x15;
    if( font == GLUT_BITMAP_HELVETICA_10   )
        return &fgFontHelvetica10;
    if( font == GLUT_BITMAP_HELVETICA_12   )
        return &fgFontHelvetica12;
    if( font == GLUT_BITMAP_HELVETICA_18   )
        return &fgFontHelvetica18;
    if( font == GLUT_BITMAP_TIMES_ROMAN_10 )
        return &fgFontTimesRoman10;
    if( font == GLUT_BITMAP_TIMES_ROMAN_24 )
        return &fgFontTimesRoman24;

    fgWarning( "font 0x%08x not found", font );
    return 0;
}
Ejemplo n.º 4
0
/*
 * Changes the current menu's font
 */
void FGAPIENTRY glutSetMenuFont( int menuID, void* fontID )
{
    SFG_Font* font;
    SFG_Menu* menu;
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetMenuFont" );
    menu = fgMenuByID( menuID );
    freeglut_return_if_fail( menu );

    if (fgState.ActiveMenus)
        fgError("Menu manipulation not allowed while menus in use.");

    font = fghFontByID( fontID );
    if (!font)
    {
        fgWarning("glutChangeMenuFont: bitmap font 0x%08x not found. Make sure you're not passing a stroke font. Ignoring...\n",fontID);
        return;
    }

    fgStructure.CurrentMenu->Font = fontID;
    fghCalculateMenuBoxSize( );
}
Ejemplo n.º 5
0
int fgPlatformGlutDeviceGet ( GLenum eWhat )
{
    switch( eWhat )
    {
    case GLUT_HAS_KEYBOARD:
        /*
         * Win32 is assumed a keyboard, and this cannot be queried,
         * except for WindowsCE.
         */
#if defined(_WIN32_CE)
        return ( GetKeyboardStatus() & KBDI_KEYBOARD_PRESENT ) ? 1 : 0;
#   if FREEGLUT_LIB_PRAGMAS
#       pragma comment (lib,"Kbdui.lib")
#   endif

#else
        return 1;
#endif

    case GLUT_HAS_MOUSE:
        /*
         * MS Windows can be booted without a mouse.
         */
        return GetSystemMetrics( SM_MOUSEPRESENT );

    case GLUT_NUM_MOUSE_BUTTONS:
#  if defined(_WIN32_WCE)
        return 1;
#  else
        return GetSystemMetrics( SM_CMOUSEBUTTONS );
#  endif

    default:
        fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
        break;
    }

    /* And now -- the failure. */
    return -1;
}
Ejemplo n.º 6
0
int fgPlatformGlutDeviceGet ( GLenum eWhat )
{
    switch( eWhat )
    {
    case GLUT_HAS_KEYBOARD:
        if( fgDisplay.pDisplay.keyboard )
          return 1;
        else
          return 0;

    case GLUT_HAS_MOUSE:
        /* we want the touchscreen to behave like a mouse,
         * so let us pretend it is one.
         */
        if( fgDisplay.pDisplay.pointer ||
            fgDisplay.pDisplay.touch )
          return 1;
        else
          return 0;

    case GLUT_NUM_MOUSE_BUTTONS:
        /* Wayland has no way of telling us how much buttons
         * a mouse has, unless the actual event gets sent to
         * the client. As we are only handling 3 buttons
         * currently, return this fixed number for now.
         */
        if( fgDisplay.pDisplay.pointer )
          return 3;
        /* touchscreen is considered as having one button */
        else if( fgDisplay.pDisplay.touch )
          return 1;
        else
          return 0;

    default:
        fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
        return -1;
    }
}
Ejemplo n.º 7
0
int fgPlatformGlutDeviceGet ( GLenum eWhat )
{
    switch( eWhat )
    {
    case GLUT_HAS_KEYBOARD:
        /*
         * X11 has a core keyboard by definition, although it can
         * be present as a virtual/dummy keyboard. For now, there
         * is no reliable way to tell if a real keyboard is present.
         */
        return 1;

    /* X11 has a mouse by definition */
    case GLUT_HAS_MOUSE:
        return 1 ;

    case GLUT_NUM_MOUSE_BUTTONS:
        /* We should be able to pass NULL when the last argument is zero,
         * but at least one X server has a bug where this causes a segfault.
         *
         * In XFree86/Xorg servers, a mouse wheel is seen as two buttons
         * rather than an Axis; "freeglut_main.c" expects this when
         * checking for a wheel event.
         */
        {
            unsigned char map;
            int nbuttons = XGetPointerMapping(fgDisplay.pDisplay.Display, &map,0);
            return nbuttons;
        }

    default:
        fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
        break;
    }

    /* And now -- the failure. */
    return -1;
}
Ejemplo n.º 8
0
int fgGetCursorError( Cursor cursor )
{
    int ret = 0;
    char buf[ 256 ];

    switch( cursor )
    {
    case BadAlloc:
    case BadFont:
    case BadMatch:
    case BadPixmap:
    case BadValue:
        XGetErrorText( fgDisplay.Display, cursor, buf, sizeof buf );
        fgWarning( "Error in setting cursor:\n %s.", buf );
        ret = cursor;
        break;
    default:
        /* no error */
        break;
    }

    return ret;
}
Ejemplo n.º 9
0
/*
 * Return the width of a string drawn using a stroke font
 */
int FGAPIENTRY glutStrokeLength( void* fontID, const unsigned char* string )
{
    unsigned char c;
    float length = 0.0;
    float this_line_length = 0.0;
    SFG_StrokeFont* font;
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeLength" );
    font = fghStrokeByID( fontID );
    if (!font)
    {
        fgWarning("glutStrokeLength: stroke font 0x%08x not found. Make sure you're not passing a bitmap font.\n",fontID);
        return 0;
    }
    if ( !string || ! *string )
        return 0;

    while( ( c = *string++) )
        if( c < font->Quantity )
        {
            if( c == '\n' ) /* EOL; reset the length of this line */
            {
                if( length < this_line_length )
                    length = this_line_length;
                this_line_length = 0.0;
            }
            else  /* Not an EOL, increment the length of this line */
            {
                const SFG_StrokeChar *schar = font->Characters[ c ];
                if( schar )
                    this_line_length += schar->Right;
            }
        }
    if( length < this_line_length )
        length = this_line_length;
    return( int )( length + 0.5 );
}
Ejemplo n.º 10
0
/*
 * Returns various device information.
 */
int FGAPIENTRY glutDeviceGet( GLenum eWhat )
{
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDeviceGet" );

    /* XXX WARNING: we are mostly lying in this function. */
    switch( eWhat )
    {
    case GLUT_HAS_KEYBOARD:
        /*
         * Win32 is assumed a keyboard, and this cannot be queried,
         * except for WindowsCE.
         *
         * X11 has a core keyboard by definition, although it can
         * be present as a virtual/dummy keyboard. For now, there
         * is no reliable way to tell if a real keyboard is present.
         */
#if defined(_WIN32_CE)
        return ( GetKeyboardStatus() & KBDI_KEYBOARD_PRESENT ) ? 1 : 0;
#   if FREEGLUT_LIB_PRAGMAS
#       pragma comment (lib,"Kbdui.lib")
#   endif

#else
        return 1;
#endif

#if TARGET_HOST_POSIX_X11

    /* X11 has a mouse by definition */
    case GLUT_HAS_MOUSE:
        return 1 ;

    case GLUT_NUM_MOUSE_BUTTONS:
        /* We should be able to pass NULL when the last argument is zero,
         * but at least one X server has a bug where this causes a segfault.
         *
         * In XFree86/Xorg servers, a mouse wheel is seen as two buttons
         * rather than an Axis; "freeglut_main.c" expects this when
         * checking for a wheel event.
         */
        {
            unsigned char map;
            int nbuttons = XGetPointerMapping(fgDisplay.Display, &map,0);
            return nbuttons;
        }

#elif TARGET_HOST_MS_WINDOWS

    case GLUT_HAS_MOUSE:
        /*
         * MS Windows can be booted without a mouse.
         */
        return GetSystemMetrics( SM_MOUSEPRESENT );

    case GLUT_NUM_MOUSE_BUTTONS:
#  if defined(_WIN32_WCE)
        return 1;
#  else
        return GetSystemMetrics( SM_CMOUSEBUTTONS );
#  endif
#endif

    case GLUT_HAS_JOYSTICK:
        return fgJoystickDetect ();

    case GLUT_OWNS_JOYSTICK:
        return fgState.JoysticksInitialised;

    case GLUT_JOYSTICK_POLL_RATE:
        return fgStructure.CurrentWindow ? fgStructure.CurrentWindow->State.JoystickPollRate : 0;

    /* XXX The following two are only for Joystick 0 but this is an improvement */
    case GLUT_JOYSTICK_BUTTONS:
        return glutJoystickGetNumButtons ( 0 );

    case GLUT_JOYSTICK_AXES:
        return glutJoystickGetNumAxes ( 0 );

    case GLUT_HAS_DIAL_AND_BUTTON_BOX:
        return fgInputDeviceDetect ();

    case GLUT_NUM_DIALS:
        if ( fgState.InputDevsInitialised ) return 8;
        return 0;

    case GLUT_NUM_BUTTON_BOX_BUTTONS:
        return 0;

    case GLUT_HAS_SPACEBALL:
        return fgHasSpaceball();

    case GLUT_HAS_TABLET:
        return 0;

    case GLUT_NUM_SPACEBALL_BUTTONS:
        return fgSpaceballNumButtons();

    case GLUT_NUM_TABLET_BUTTONS:
        return 0;

    case GLUT_DEVICE_IGNORE_KEY_REPEAT:
        return fgStructure.CurrentWindow ? fgStructure.CurrentWindow->State.IgnoreKeyRepeat : 0;

    case GLUT_DEVICE_KEY_REPEAT:
        return fgState.KeyRepeat;

    default:
        fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
        break;
    }

    /* And now -- the failure. */
    return -1;
}
Ejemplo n.º 11
0
/*
 * General settings query method
 */
int FGAPIENTRY glutGet( GLenum eWhat )
{
#if TARGET_HOST_MS_WINDOWS
    int returnValue ;
    GLboolean boolValue ;
#endif

    int nsamples = 0;

    switch (eWhat)
    {
    case GLUT_INIT_STATE:
        return fgState.Initialised;

    case GLUT_ELAPSED_TIME:
        return fgElapsedTime();
    }

    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGet" );

    /* XXX In chronological code add order.  (WHY in that order?) */
    switch( eWhat )
    {
    /* Following values are stored in fgState and fgDisplay global structures */
    case GLUT_SCREEN_WIDTH:         return fgDisplay.ScreenWidth   ;
    case GLUT_SCREEN_HEIGHT:        return fgDisplay.ScreenHeight  ;
    case GLUT_SCREEN_WIDTH_MM:      return fgDisplay.ScreenWidthMM ;
    case GLUT_SCREEN_HEIGHT_MM:     return fgDisplay.ScreenHeightMM;
    case GLUT_INIT_WINDOW_X:        return fgState.Position.Use ?
                                           fgState.Position.X : -1 ;
    case GLUT_INIT_WINDOW_Y:        return fgState.Position.Use ?
                                           fgState.Position.Y : -1 ;
    case GLUT_INIT_WINDOW_WIDTH:    return fgState.Size.Use ?
                                           fgState.Size.X : -1     ;
    case GLUT_INIT_WINDOW_HEIGHT:   return fgState.Size.Use ?
                                           fgState.Size.Y : -1     ;
    case GLUT_INIT_DISPLAY_MODE:    return fgState.DisplayMode     ;
    case GLUT_INIT_MAJOR_VERSION:   return fgState.MajorVersion    ;
    case GLUT_INIT_MINOR_VERSION:   return fgState.MinorVersion    ;
    case GLUT_INIT_FLAGS:           return fgState.ContextFlags    ;
    case GLUT_INIT_PROFILE:         return fgState.ContextProfile  ;

#if TARGET_HOST_POSIX_X11
    /*
     * The window/context specific queries are handled mostly by
     * fghGetConfig().
     */
    case GLUT_WINDOW_NUM_SAMPLES:
#ifdef GLX_VERSION_1_3
        glGetIntegerv(GL_SAMPLES, &nsamples);
#endif
        return nsamples;

    /*
     * The rest of GLX queries under X are general enough to use a macro to
     * check them
     */
#   define GLX_QUERY(a,b) case a: return fghGetConfig( b );

    GLX_QUERY( GLUT_WINDOW_RGBA,                GLX_RGBA                );
    GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER,        GLX_DOUBLEBUFFER        );
    GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE,         GLX_BUFFER_SIZE         );
    GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE,        GLX_STENCIL_SIZE        );
    GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE,          GLX_DEPTH_SIZE          );
    GLX_QUERY( GLUT_WINDOW_RED_SIZE,            GLX_RED_SIZE            );
    GLX_QUERY( GLUT_WINDOW_GREEN_SIZE,          GLX_GREEN_SIZE          );
    GLX_QUERY( GLUT_WINDOW_BLUE_SIZE,           GLX_BLUE_SIZE           );
    GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE,          GLX_ALPHA_SIZE          );
    GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE,      GLX_ACCUM_RED_SIZE      );
    GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE,    GLX_ACCUM_GREEN_SIZE    );
    GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE,     GLX_ACCUM_BLUE_SIZE     );
    GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE,    GLX_ACCUM_ALPHA_SIZE    );
    GLX_QUERY( GLUT_WINDOW_STEREO,              GLX_STEREO              );

#   undef GLX_QUERY

    /* Colormap size is handled in a bit different way than all the rest */
    case GLUT_WINDOW_COLORMAP_SIZE:
        if( (fghGetConfig( GLX_RGBA )) || (fgStructure.CurrentWindow == NULL) )
        {
            /*
             * We've got a RGBA visual, so there is no colormap at all.
             * The other possibility is that we have no current window set.
             */
            return 0;
        }
        else
        {
          const GLXFBConfig * fbconfig =
                fgStructure.CurrentWindow->Window.FBConfig;

          XVisualInfo * visualInfo =
                glXGetVisualFromFBConfig( fgDisplay.Display, *fbconfig );

          const int result = visualInfo->visual->map_entries;

          XFree(visualInfo);

          return result;
        }

    /*
     * Those calls are somewhat similiar, as they use XGetWindowAttributes()
     * function
     */
    case GLUT_WINDOW_X:
    case GLUT_WINDOW_Y:
    case GLUT_WINDOW_BORDER_WIDTH:
    case GLUT_WINDOW_HEADER_HEIGHT:
    {
        int x, y;
        Window w;

        if( fgStructure.CurrentWindow == NULL )
            return 0;

        XTranslateCoordinates(
            fgDisplay.Display,
            fgStructure.CurrentWindow->Window.Handle,
            fgDisplay.RootWindow,
            0, 0, &x, &y, &w);

        switch ( eWhat )
        {
        case GLUT_WINDOW_X: return x;
        case GLUT_WINDOW_Y: return y;
        }

        if ( w == 0 )
            return 0;
        XTranslateCoordinates(
            fgDisplay.Display,
            fgStructure.CurrentWindow->Window.Handle,
            w, 0, 0, &x, &y, &w);

        switch ( eWhat )
        {
        case GLUT_WINDOW_BORDER_WIDTH:  return x;
        case GLUT_WINDOW_HEADER_HEIGHT: return y;
        }
    }

    case GLUT_WINDOW_WIDTH:
    case GLUT_WINDOW_HEIGHT:
    {
        XWindowAttributes winAttributes;

        if( fgStructure.CurrentWindow == NULL )
            return 0;
        XGetWindowAttributes(
            fgDisplay.Display,
            fgStructure.CurrentWindow->Window.Handle,
            &winAttributes
        );
        switch ( eWhat )
        {
        case GLUT_WINDOW_WIDTH:            return winAttributes.width ;
        case GLUT_WINDOW_HEIGHT:           return winAttributes.height ;
        }
    }

    /* I do not know yet if there will be a fgChooseVisual() function for Win32 */
    case GLUT_DISPLAY_MODE_POSSIBLE:
    {
        /*  We should not have to call fgChooseFBConfig again here.  */
        GLXFBConfig * fbconfig;
        int isPossible;

        fbconfig = fgChooseFBConfig();

        if (fbconfig == NULL)
        {
            isPossible = 0;
        }
        else
        {
            isPossible = 1;
            XFree(fbconfig);
        }

        return isPossible;
    }

    /* This is system-dependant */
    case GLUT_WINDOW_FORMAT_ID:
        if( fgStructure.CurrentWindow == NULL )
            return 0;

        return fghGetConfig( GLX_VISUAL_ID );

#elif TARGET_HOST_MS_WINDOWS

    case GLUT_WINDOW_NUM_SAMPLES:
      glGetIntegerv(WGL_SAMPLES_ARB, &nsamples);
      return nsamples;

    /* Handle the OpenGL inquiries */
    case GLUT_WINDOW_RGBA:
#if defined(_WIN32_WCE)
      boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */
#else
      glGetBooleanv ( GL_RGBA_MODE, &boolValue );
      returnValue = boolValue ? 1 : 0;
#endif
      return returnValue;
    case GLUT_WINDOW_DOUBLEBUFFER:
#if defined(_WIN32_WCE)
      boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */
#else
      glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue );
      returnValue = boolValue ? 1 : 0;
#endif
      return returnValue;
    case GLUT_WINDOW_STEREO:
#if defined(_WIN32_WCE)
      boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */
#else
      glGetBooleanv ( GL_STEREO, &boolValue );
      returnValue = boolValue ? 1 : 0;
#endif
      return returnValue;

    case GLUT_WINDOW_RED_SIZE:
      glGetIntegerv ( GL_RED_BITS, &returnValue );
      return returnValue;
    case GLUT_WINDOW_GREEN_SIZE:
      glGetIntegerv ( GL_GREEN_BITS, &returnValue );
      return returnValue;
    case GLUT_WINDOW_BLUE_SIZE:
      glGetIntegerv ( GL_BLUE_BITS, &returnValue );
      return returnValue;
    case GLUT_WINDOW_ALPHA_SIZE:
      glGetIntegerv ( GL_ALPHA_BITS, &returnValue );
      return returnValue;
    case GLUT_WINDOW_ACCUM_RED_SIZE:
#if defined(_WIN32_WCE)
      returnValue = 0;  /* WinCE doesn't support this feature */
#else
      glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue );
#endif
      return returnValue;
    case GLUT_WINDOW_ACCUM_GREEN_SIZE:
#if defined(_WIN32_WCE)
      returnValue = 0;  /* WinCE doesn't support this feature */
#else
      glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue );
#endif
      return returnValue;
    case GLUT_WINDOW_ACCUM_BLUE_SIZE:
#if defined(_WIN32_WCE)
      returnValue = 0;  /* WinCE doesn't support this feature */
#else
      glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue );
#endif
      return returnValue;
    case GLUT_WINDOW_ACCUM_ALPHA_SIZE:
#if defined(_WIN32_WCE)
      returnValue = 0;  /* WinCE doesn't support this feature */
#else
      glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue );
#endif
      return returnValue;
    case GLUT_WINDOW_DEPTH_SIZE:
      glGetIntegerv ( GL_DEPTH_BITS, &returnValue );
      return returnValue;

    case GLUT_WINDOW_BUFFER_SIZE:
      returnValue = 1 ;                                      /* ????? */
      return returnValue;
    case GLUT_WINDOW_STENCIL_SIZE:
      returnValue = 0 ;                                      /* ????? */
      return returnValue;

    case GLUT_WINDOW_X:
    case GLUT_WINDOW_Y:
    case GLUT_WINDOW_WIDTH:
    case GLUT_WINDOW_HEIGHT:
    {
        /*
         *  There is considerable confusion about the "right thing to
         *  do" concerning window  size and position.  GLUT itself is
         *  not consistent between Windows and UNIX/X11; since
         *  platform independence is a virtue for "freeglut", we
         *  decided to break with GLUT's behaviour.
         *
         *  Under UNIX/X11, it is apparently not possible to get the
         *  window border sizes in order to subtract them off the
         *  window's initial position until some time after the window
         *  has been created.  Therefore we decided on the following
         *  behaviour, both under Windows and under UNIX/X11:
         *  - When you create a window with position (x,y) and size
         *    (w,h), the upper left hand corner of the outside of the
         *    window is at (x,y) and the size of the drawable area  is
         *    (w,h).
         *  - When you query the size and position of the window--as
         *    is happening here for Windows--"freeglut" will return
         *    the size of the drawable area--the (w,h) that you
         *    specified when you created the window--and the coordinates
         *    of the upper left hand corner of the drawable
         *    area--which is NOT the (x,y) you specified.
         */

        RECT winRect;

        freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 );

        /*
         * We need to call GetWindowRect() first...
         *  (this returns the pixel coordinates of the outside of the window)
         */
        GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect );

        /* ...then we've got to correct the results we've just received... */

#if !defined(_WIN32_WCE)
        if ( ( fgStructure.GameModeWindow != fgStructure.CurrentWindow ) && ( fgStructure.CurrentWindow->Parent == NULL ) &&
             ( ! fgStructure.CurrentWindow->IsMenu ) )
        {
          winRect.left   += GetSystemMetrics( SM_CXSIZEFRAME );
          winRect.right  -= GetSystemMetrics( SM_CXSIZEFRAME );
          winRect.top    += GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION );
          winRect.bottom -= GetSystemMetrics( SM_CYSIZEFRAME );
        }
#endif /* !defined(_WIN32_WCE) */

        switch( eWhat )
        {
        case GLUT_WINDOW_X:      return winRect.left                ;
        case GLUT_WINDOW_Y:      return winRect.top                 ;
        case GLUT_WINDOW_WIDTH:  return winRect.right - winRect.left;
        case GLUT_WINDOW_HEIGHT: return winRect.bottom - winRect.top;
        }
    }
    break;

    case GLUT_WINDOW_BORDER_WIDTH :
#if defined(_WIN32_WCE)
        return 0;
#else
        return GetSystemMetrics( SM_CXSIZEFRAME );
#endif /* !defined(_WIN32_WCE) */

    case GLUT_WINDOW_HEADER_HEIGHT :
#if defined(_WIN32_WCE)
        return 0;
#else
        return GetSystemMetrics( SM_CYCAPTION );
#endif /* defined(_WIN32_WCE) */

    case GLUT_DISPLAY_MODE_POSSIBLE:
#if defined(_WIN32_WCE)
        return 0;
#else
        return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE,
                                    PFD_MAIN_PLANE );
#endif /* defined(_WIN32_WCE) */


    case GLUT_WINDOW_FORMAT_ID:
#if !defined(_WIN32_WCE)
        if( fgStructure.CurrentWindow != NULL )
            return GetPixelFormat( fgStructure.CurrentWindow->Window.Device );
#endif /* defined(_WIN32_WCE) */
        return 0;

#endif

    /* The window structure queries */
    case GLUT_WINDOW_PARENT:
        if( fgStructure.CurrentWindow         == NULL ) return 0;
        if( fgStructure.CurrentWindow->Parent == NULL ) return 0;
        return fgStructure.CurrentWindow->Parent->ID;

    case GLUT_WINDOW_NUM_CHILDREN:
        if( fgStructure.CurrentWindow == NULL )
            return 0;
        return fgListLength( &fgStructure.CurrentWindow->Children );

    case GLUT_WINDOW_CURSOR:
        if( fgStructure.CurrentWindow == NULL )
            return 0;
        return fgStructure.CurrentWindow->State.Cursor;

    case GLUT_MENU_NUM_ITEMS:
        if( fgStructure.CurrentMenu == NULL )
            return 0;
        return fgListLength( &fgStructure.CurrentMenu->Entries );

    case GLUT_ACTION_ON_WINDOW_CLOSE:
        return fgState.ActionOnWindowClose;

    case GLUT_VERSION :
        return VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH;

    case GLUT_RENDERING_CONTEXT:
        return fgState.UseCurrentContext ? GLUT_USE_CURRENT_CONTEXT
                                         : GLUT_CREATE_NEW_CONTEXT;

    case GLUT_DIRECT_RENDERING:
        return fgState.DirectContext;

    case GLUT_FULL_SCREEN:
        return fghCheckFullScreen();

    case GLUT_AUX:
      return fgState.AuxiliaryBufferNumber;

    case GLUT_MULTISAMPLE:
      return fgState.SampleNumber;

    default:
        fgWarning( "glutGet(): missing enum handle %d", eWhat );
        break;
    }
    return -1;
}
Ejemplo n.º 12
0
/*
 * General settings assignment method
 */
void FGAPIENTRY glutSetOption( GLenum eWhat, int value )
{
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetOption" );

    /*
     * XXX In chronological code add order.  (WHY in that order?)
     */
    switch( eWhat )
    {
    case GLUT_INIT_WINDOW_X:
        fgState.Position.X = (GLint)value;
        break;

    case GLUT_INIT_WINDOW_Y:
        fgState.Position.Y = (GLint)value;
        break;

    case GLUT_INIT_WINDOW_WIDTH:
        fgState.Size.X = (GLint)value;
        break;

    case GLUT_INIT_WINDOW_HEIGHT:
        fgState.Size.Y = (GLint)value;
        break;

    case GLUT_INIT_DISPLAY_MODE:
        fgState.DisplayMode = (unsigned int)value;
        break;

    case GLUT_ACTION_ON_WINDOW_CLOSE:
        fgState.ActionOnWindowClose = value;
        break;

    case GLUT_RENDERING_CONTEXT:
        fgState.UseCurrentContext =
            ( value == GLUT_USE_CURRENT_CONTEXT ) ? GL_TRUE : GL_FALSE;
        break;

    case GLUT_DIRECT_RENDERING:
        fgState.DirectContext = value;
        break;

    case GLUT_WINDOW_CURSOR:
        if( fgStructure.CurrentWindow != NULL )
            fgStructure.CurrentWindow->State.Cursor = value;
        break;

    case GLUT_AUX:
      fgState.AuxiliaryBufferNumber = value;
      break;

    case GLUT_MULTISAMPLE:
      fgState.SampleNumber = value;
      break;

	case GLUT_DEPTH:
      fgState.DepthBits = value;
      break;

	case GLUT_RGB:
		fgState.GameModeDepth = value;
      break;

    default:
        fgWarning( "glutSetOption(): missing enum handle %d", eWhat );
        break;
    }
}
Ejemplo n.º 13
0
/*
 * The window procedure for handling Win32 events
 */
LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    SFG_Window *window;
    LRESULT lRet = 1;
    static int setCaptureActive = 0;

    FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Event Handler" ) ;

    window = fgWindowByHandle( hWnd );

    if ( ( window == NULL ) && ( uMsg != WM_CREATE ) )
      return DefWindowProc( hWnd, uMsg, wParam, lParam );

    /* printf ( "Window %3d message <%04x> %12d %12d\n", window?window->ID:0,
             uMsg, wParam, lParam ); */

    switch( uMsg )
    {
    case WM_CREATE:
        /* The window structure is passed as the creation structure parameter... */
        window = (SFG_Window *) (((LPCREATESTRUCT) lParam)->lpCreateParams);
        FREEGLUT_INTERNAL_ERROR_EXIT ( ( window != NULL ), "Cannot create window",
                                       "fgPlatformWindowProc" );

        window->Window.Handle = hWnd;
        window->Window.pContext.Device = GetDC( hWnd );
        if( window->IsMenu )
        {
            unsigned int current_DisplayMode = fgState.DisplayMode;
            fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH;
#if !defined(_WIN32_WCE)
            fgSetupPixelFormat( window, GL_FALSE, PFD_MAIN_PLANE );
#endif
            fgState.DisplayMode = current_DisplayMode;

            if( fgStructure.MenuContext )
                wglMakeCurrent( window->Window.pContext.Device,
                                fgStructure.MenuContext->MContext
                );
            else
            {
                fgStructure.MenuContext =
                    (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) );
                fgStructure.MenuContext->MContext =
                    wglCreateContext( window->Window.pContext.Device );
            }

            /* window->Window.Context = wglGetCurrentContext ();   */
            window->Window.Context = wglCreateContext( window->Window.pContext.Device );
        }
        else
        {
#if !defined(_WIN32_WCE)
            fgSetupPixelFormat( window, GL_FALSE, PFD_MAIN_PLANE );
#endif

            if( ! fgState.UseCurrentContext )
                window->Window.Context =
                    wglCreateContext( window->Window.pContext.Device );
            else
            {
                window->Window.Context = wglGetCurrentContext( );
                if( ! window->Window.Context )
                    window->Window.Context =
                        wglCreateContext( window->Window.pContext.Device );
            }

#if !defined(_WIN32_WCE)
            fgNewWGLCreateContext( window );
#endif
        }

        window->State.NeedToResize = GL_TRUE;
        /* if we used CW_USEDEFAULT (thats a negative value) for the size
         * of the window, query the window now for the size at which it
         * was created.
         */
        if( ( window->State.Width < 0 ) || ( window->State.Height < 0 ) )
        {
            SFG_Window *current_window = fgStructure.CurrentWindow;

            fgSetWindow( window );
            window->State.Width = glutGet( GLUT_WINDOW_WIDTH );
            window->State.Height = glutGet( GLUT_WINDOW_HEIGHT );
            fgSetWindow( current_window );
        }

        ReleaseDC( window->Window.Handle, window->Window.pContext.Device );

#if defined(_WIN32_WCE)
        /* Take over button handling */
        {
            HINSTANCE dxDllLib=LoadLibrary(_T("gx.dll"));
            if (dxDllLib)
            {
                GXGetDefaultKeys_=(GXGETDEFAULTKEYS)GetProcAddress(dxDllLib, _T("?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z"));
                GXOpenInput_=(GXOPENINPUT)GetProcAddress(dxDllLib, _T("?GXOpenInput@@YAHXZ"));
            }

            if(GXOpenInput_)
                (*GXOpenInput_)();
            if(GXGetDefaultKeys_)
                gxKeyList = (*GXGetDefaultKeys_)(GX_LANDSCAPEKEYS);
        }

#endif /* defined(_WIN32_WCE) */
        break;

    case WM_SIZE:
        /* printf("WM_SIZE (ID: %i): wParam: %i, new size: %ix%i \n",window->ID,wParam,LOWORD(lParam),HIWORD(lParam)); */

        /* Update visibility state of the window */
        if (wParam==SIZE_MINIMIZED)
            fghUpdateWindowStatus(window,GL_FALSE);
        else if (wParam==SIZE_RESTORED && !window->State.Visible)
            fghUpdateWindowStatus(window,GL_TRUE);

        /* Check window visible, we don't want to resize when the user or glutIconifyWindow minimized the window */
        if( window->State.Visible )
        {
            /* get old values first to compare to below */
            int width = window->State.Width, height=window->State.Height;
#if defined(_WIN32_WCE)
            window->State.Width  = HIWORD(lParam);
            window->State.Height = LOWORD(lParam);
#else
            window->State.Width  = LOWORD(lParam);
            window->State.Height = HIWORD(lParam);
#endif /* defined(_WIN32_WCE) */
            
            if (width!=window->State.Width || height!=window->State.Height)
            {
                SFG_Window* saved_window = fgStructure.CurrentWindow;
                
                /* size changed, call reshape callback */
                INVOKE_WCB( *window, Reshape, ( width, height ) );
                glutPostRedisplay( );
                if( window->IsMenu )
                    fgSetWindow( saved_window );
            }
        }

        /* according to docs, should return 0 */
        lRet = 0;
        break;

    case WM_MOVE:
        {
            SFG_Window* saved_window = fgStructure.CurrentWindow;
            RECT windowRect;

            /* Check window is minimized, we don't want to call the position callback when the user or glutIconifyWindow minimized the window */
            if (!IsIconic(window->Window.Handle))
            {
                /* Get top-left of non-client area of window, matching coordinates of
                 * glutInitPosition and glutPositionWindow, but not those of 
                 * glutGet(GLUT_WINDOW_X) and glutGet(GLUT_WINDOW_Y), which return
                 * top-left of client area.
                 */
                GetWindowRect( window->Window.Handle, &windowRect );
            
                if (window->Parent)
                {
                    /* For child window, we should return relative to upper-left
                     * of parent's client area.
                     */
                    POINT topleft = {windowRect.left,windowRect.top};

                    ScreenToClient(window->Parent->Window.Handle,&topleft);
                    windowRect.left = topleft.x;
                    windowRect.top  = topleft.y;
                }

                INVOKE_WCB( *window, Position, ( windowRect.left, windowRect.top ) );
                fgSetWindow(saved_window);
            }
        }

        /* according to docs, should return 0 */
        lRet = 0;
        break;

    case WM_SETFOCUS:
        /*printf("WM_SETFOCUS: %p\n", window );*/
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );

        SetActiveWindow( window->Window.Handle );
        UpdateWindow ( hWnd );

        break;

    case WM_KILLFOCUS:
        /*printf("WM_KILLFOCUS: %p\n", window ); */
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );

        /* Check if there are any open menus that need to be closed */
        fgPlatformCheckMenuDeactivate();
        break;

#if 0
    case WM_ACTIVATE:
        //printf("WM_ACTIVATE: %x (ID: %i) %d %d\n",lParam, window->ID, HIWORD(wParam), LOWORD(wParam));
        if (LOWORD(wParam) != WA_INACTIVE)
        {
/*            printf("WM_ACTIVATE: fgSetCursor( %p, %d)\n", window,
                   window->State.Cursor ); */
            fgSetCursor( window, window->State.Cursor );
        }

        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        break;
#endif

    case WM_SETCURSOR:
/*      printf ( "Cursor event %x %x %x %x\n", window, window->State.Cursor, lParam, wParam ) ; */
        if( LOWORD( lParam ) == HTCLIENT )
        {
            if (!window->State.pWState.MouseTracking)
            {
                TRACKMOUSEEVENT tme;

                /* Cursor just entered window, set cursor look */ 
                fgSetCursor ( window, window->State.Cursor ) ;

                /* If an EntryFunc callback is specified by the user, also
                 * invoke that callback and start mouse tracking so that
                 * we get a WM_MOUSELEAVE message
                 */
                if (FETCH_WCB( *window, Entry ))
                {
                    SFG_Window* saved_window = fgStructure.CurrentWindow;
                    INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) );
                    fgSetWindow(saved_window);

                    tme.cbSize = sizeof(TRACKMOUSEEVENT);
                    tme.dwFlags = TME_LEAVE;
                    tme.hwndTrack = window->Window.Handle;
                    TrackMouseEvent(&tme);

                    window->State.pWState.MouseTracking = GL_TRUE;
                }
            }
        }
        else
            /* Only pass non-client WM_SETCURSOR to DefWindowProc, or we get WM_SETCURSOR on parents of children as well */
            lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        break;

    case WM_MOUSELEAVE:
        {
            /* NB: This message is only received when a EntryFunc callback
             * is specified by the user, as that is the only condition under
             * which mouse tracking is setup in WM_SETCURSOR handler above
             */
            SFG_Window* saved_window = fgStructure.CurrentWindow;
            INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) );
            fgSetWindow(saved_window);

            window->State.pWState.MouseTracking = GL_FALSE;
            lRet = 0;   /* As per docs, must return zero */
        }
        break;

    case WM_SHOWWINDOW:
        /* printf("WM_SHOWWINDOW, shown? %i, source: %i\n",wParam,lParam); */
        if (wParam)
        {
            fghUpdateWindowStatus(window, GL_TRUE);
            window->State.Redisplay = GL_TRUE;
        }
        else
        {
            fghUpdateWindowStatus(window, GL_FALSE);
            window->State.Redisplay = GL_FALSE;
        }
        break;

    case WM_PAINT:
    {
        RECT rect;

        if (GetUpdateRect(hWnd,&rect,FALSE))
        {
            /* As per docs, upon receiving WM_PAINT, first check if the update region is not empty before you call BeginPaint */
            PAINTSTRUCT ps;

            /* Turn on the visibility in case it was turned off somehow */
            window->State.Visible = GL_TRUE;

            InvalidateRect( hWnd, NULL, GL_FALSE );
            BeginPaint( hWnd, &ps );
            fghRedrawWindow( window );
            EndPaint( hWnd, &ps );
        }
        lRet = 0;   /* As per docs, should return 0 */
    }
    break;

    case WM_CLOSE:
        fgDestroyWindow ( window );
        if ( fgState.ActionOnWindowClose != GLUT_ACTION_CONTINUE_EXECUTION )
            PostQuitMessage(0);
        break;

    case WM_DESTROY:
        /*
         * The window already got destroyed, so don't bother with it.
         */
        return 0;

    case WM_MOUSEMOVE:
    {
        /* Per docs, use LOWORD/HIWORD for WinCE and GET_X_LPARAM/GET_Y_LPARAM for desktop windows */
#if defined(_WIN32_WCE)
        window->State.MouseX = 320-HIWORD( lParam );    /* XXX: Docs say x should be loword and y hiword? */
        window->State.MouseY = LOWORD( lParam );
#else
        window->State.MouseX = GET_X_LPARAM( lParam );
        window->State.MouseY = GET_Y_LPARAM( lParam );
#endif /* defined(_WIN32_WCE) */
        /* Restrict to [-32768, 32767] to match X11 behaviour       */
        /* See comment in "freeglut_developer" mailing list 10/4/04 */
        if ( window->State.MouseX > 32767 ) window->State.MouseX -= 65536;
        if ( window->State.MouseY > 32767 ) window->State.MouseY -= 65536;

        if ( window->ActiveMenu )
        {
            fgUpdateMenuHighlight( window->ActiveMenu );
            break;
        }

        fgState.Modifiers = fgPlatformGetModifiers( );

        if( ( wParam & MK_LBUTTON ) ||
            ( wParam & MK_MBUTTON ) ||
            ( wParam & MK_RBUTTON ) )
            INVOKE_WCB( *window, Motion, ( window->State.MouseX,
                                           window->State.MouseY ) );
        else
            INVOKE_WCB( *window, Passive, ( window->State.MouseX,
                                            window->State.MouseY ) );

        fgState.Modifiers = INVALID_MODIFIERS;
    }
    break;

    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
    {
        GLboolean pressed = GL_TRUE;
        int button;

        /* Per docs, use LOWORD/HIWORD for WinCE and GET_X_LPARAM/GET_Y_LPARAM for desktop windows */
#if defined(_WIN32_WCE)
        window->State.MouseX = 320-HIWORD( lParam );    /* XXX: Docs say x should be loword and y hiword? */
        window->State.MouseY = LOWORD( lParam );
#else
        window->State.MouseX = GET_X_LPARAM( lParam );
        window->State.MouseY = GET_Y_LPARAM( lParam );
#endif /* defined(_WIN32_WCE) */

        /* Restrict to [-32768, 32767] to match X11 behaviour       */
        /* See comment in "freeglut_developer" mailing list 10/4/04 */
        if ( window->State.MouseX > 32767 ) window->State.MouseX -= 65536;
        if ( window->State.MouseY > 32767 ) window->State.MouseY -= 65536;

        switch( uMsg )
        {
        case WM_LBUTTONDOWN:
            pressed = GL_TRUE;
            button = GLUT_LEFT_BUTTON;
            break;
        case WM_MBUTTONDOWN:
            pressed = GL_TRUE;
            button = GLUT_MIDDLE_BUTTON;
            break;
        case WM_RBUTTONDOWN:
            pressed = GL_TRUE;
            button = GLUT_RIGHT_BUTTON;
            break;
        case WM_LBUTTONUP:
            pressed = GL_FALSE;
            button = GLUT_LEFT_BUTTON;
            break;
        case WM_MBUTTONUP:
            pressed = GL_FALSE;
            button = GLUT_MIDDLE_BUTTON;
            break;
        case WM_RBUTTONUP:
            pressed = GL_FALSE;
            button = GLUT_RIGHT_BUTTON;
            break;
        default:
            pressed = GL_FALSE;
            button = -1;
            break;
        }

#if !defined(_WIN32_WCE)
        if( GetSystemMetrics( SM_SWAPBUTTON ) )
        {
            if( button == GLUT_LEFT_BUTTON )
                button = GLUT_RIGHT_BUTTON;
            else
                if( button == GLUT_RIGHT_BUTTON )
                    button = GLUT_LEFT_BUTTON;
        }
#endif /* !defined(_WIN32_WCE) */

        if( button == -1 )
            return DefWindowProc( hWnd, uMsg, lParam, wParam );

        /*
         * Do not execute the application's mouse callback if a menu
         * is hooked to this button.  In that case an appropriate
         * private call should be generated.
         */
        if( fgCheckActiveMenu( window, button, pressed,
                               window->State.MouseX, window->State.MouseY ) )
            break;

        /* Set capture so that the window captures all the mouse messages
         *
         * The mouse is not released from the window until all buttons have
         * been released, even if the user presses a button in another window.
         * This is consistent with the behavior on X11.
         */
        if ( pressed == GL_TRUE )
        {
            if (!setCaptureActive)
                SetCapture ( window->Window.Handle ) ;
            setCaptureActive = 1; /* Set to false in WM_CAPTURECHANGED handler */
        }
        else if (!GetAsyncKeyState(VK_LBUTTON) && !GetAsyncKeyState(VK_MBUTTON) && !GetAsyncKeyState(VK_RBUTTON))
          /* Make sure all mouse buttons are released before releasing capture */
          ReleaseCapture () ;

        if( ! FETCH_WCB( *window, Mouse ) )
            break;

        fgSetWindow( window );
        fgState.Modifiers = fgPlatformGetModifiers( );

        INVOKE_WCB(
            *window, Mouse,
            ( button,
              pressed ? GLUT_DOWN : GLUT_UP,
              window->State.MouseX,
              window->State.MouseY
            )
        );

        fgState.Modifiers = INVALID_MODIFIERS;

        /* As per docs, should return zero */
        lRet = 0;
    }
    break;

    case WM_MOUSEWHEEL:
    {
        int wheel_number = 0;   /* Only one scroll wheel on windows */
#if defined(_WIN32_WCE)
        int modkeys = LOWORD(wParam); 
        short ticks = (short)HIWORD(wParam);
        /* commented out as should not be needed here, mouse motion is processed in WM_MOUSEMOVE first:
        xPos = LOWORD(lParam);  -- straight from docs, not consistent with mouse nutton and mouse motion above (which i think is wrong)
        yPos = HIWORD(lParam);
        */
#else
        /* int modkeys = GET_KEYSTATE_WPARAM( wParam ); */
        short ticks = GET_WHEEL_DELTA_WPARAM( wParam );
        /* commented out as should not be needed here, mouse motion is processed in WM_MOUSEMOVE first:
        window->State.MouseX = GET_X_LPARAM( lParam );
        window->State.MouseY = GET_Y_LPARAM( lParam );
        */
#endif /* defined(_WIN32_WCE) */

        window = fghWindowUnderCursor(window);

		fgState.MouseWheelTicks += ticks;
        if ( abs ( fgState.MouseWheelTicks ) >= WHEEL_DELTA )
		{
			int direction = ( fgState.MouseWheelTicks > 0 ) ? 1 : -1;

            if( ! FETCH_WCB( *window, MouseWheel ) &&
                ! FETCH_WCB( *window, Mouse ) )
                break;

            fgSetWindow( window );
            fgState.Modifiers = fgPlatformGetModifiers( );

            while( abs ( fgState.MouseWheelTicks ) >= WHEEL_DELTA )
			{
                if( FETCH_WCB( *window, MouseWheel ) )
                    INVOKE_WCB( *window, MouseWheel,
                                ( wheel_number,
                                  direction,
                                  window->State.MouseX,
                                  window->State.MouseY
                                )
                    );
                else  /* No mouse wheel, call the mouse button callback twice */
				{
                    /*
                     * Map wheel zero to button 3 and 4; +1 to 3, -1 to 4
                     *  "    "   one                     +1 to 5, -1 to 6, ...
                     *
                     * XXX The below assumes that you have no more than 3 mouse
                     * XXX buttons.  Sorry.
                     */
                    int button = wheel_number * 2 + 3;
                    if( direction < 0 )
                        ++button;
                    INVOKE_WCB( *window, Mouse,
                                ( button, GLUT_DOWN,
                                  window->State.MouseX, window->State.MouseY )
                    );
                    INVOKE_WCB( *window, Mouse,
                                ( button, GLUT_UP,
                                  window->State.MouseX, window->State.MouseY )
                    );
				}

				fgState.MouseWheelTicks -= WHEEL_DELTA * direction;
			}

            fgState.Modifiers = INVALID_MODIFIERS;
		}
        /* Per docs, should return zero */
        lRet = 0;
    }
    break ;

    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
    {
        window = fghWindowUnderCursor(window);
        lRet = fghWindowProcKeyPress(window,uMsg,GL_TRUE,wParam,lParam);
    }
    break;

    case WM_SYSKEYUP:
    case WM_KEYUP:
    {
        window = fghWindowUnderCursor(window);
        lRet = fghWindowProcKeyPress(window,uMsg,GL_FALSE,wParam,lParam);
    }
    break;

    case WM_SYSCHAR:
    case WM_CHAR:
    {
      window = fghWindowUnderCursor(window);

      if( (fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE) && (HIWORD(lParam) & KF_REPEAT) )
            break;

        fgState.Modifiers = fgPlatformGetModifiers( );
        INVOKE_WCB( *window, Keyboard,
                    ( (char)wParam,
                      window->State.MouseX, window->State.MouseY )
        );
        fgState.Modifiers = INVALID_MODIFIERS;
    }
    break;

    case WM_CAPTURECHANGED:
        if (!lParam || !fgWindowByHandle((HWND)lParam))
            /* Capture released or capture taken by non-FreeGLUT window */
            setCaptureActive = 0;
        /* Docs advise a redraw */
        InvalidateRect( hWnd, NULL, GL_FALSE );
        UpdateWindow(hWnd);
        lRet = 0;   /* Per docs, should return zero */
        break;

#if !defined(_WIN32_WCE)
    case WM_SYNCPAINT:  /* 0x0088 */
        /* Another window has moved, need to update this one */
        window->State.Redisplay = GL_TRUE;
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        /* Help screen says this message must be passed to "DefWindowProc" */
        break;

    case WM_SYSCOMMAND :  /* 0x0112 */
        {
          /*
           * We have received a system command message.  Try to act on it.
           * The commands are passed in through the "wParam" parameter:
           * The least significant digit seems to be which edge of the window
           * is being used for a resize event:
           *     4  3  5
           *     1     2
           *     7  6  8
           * Congratulations and thanks to Richard Rauch for figuring this out..
           */
            switch ( wParam & 0xfff0 )
            {
            case SC_SIZE       :
                break ;

            case SC_MOVE       :
                break ;

            case SC_MINIMIZE   :
                /* User has clicked on the "-" to minimize the window */
                /* Turning off the visibility is handled in WM_SIZE handler */

                break ;

            case SC_MAXIMIZE   :
                break ;

            case SC_NEXTWINDOW :
                break ;

            case SC_PREVWINDOW :
                break ;

            case SC_CLOSE      :
                /* Followed very closely by a WM_CLOSE message */
                break ;

            case SC_VSCROLL    :
                break ;

            case SC_HSCROLL    :
                break ;

            case SC_MOUSEMENU  :
                break ;

            case SC_KEYMENU    :
                break ;

            case SC_ARRANGE    :
                break ;

            case SC_RESTORE    :
                break ;

            case SC_TASKLIST   :
                break ;

            case SC_SCREENSAVE :
                break ;

            case SC_HOTKEY     :
                break ;

#if(WINVER >= 0x0400)
            case SC_DEFAULT    :
                break ;

            case SC_MONITORPOWER    :
                break ;

            case SC_CONTEXTHELP    :
                break ;
#endif /* WINVER >= 0x0400 */

            default:
#if _DEBUG
                fgWarning( "Unknown wParam type 0x%x", wParam );
#endif
                break;
            }
        }
#endif /* !defined(_WIN32_WCE) */

        /* We need to pass the message on to the operating system as well */
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        break;

#ifdef WM_TOUCH
	/* handle multi-touch messages */
	case WM_TOUCH:
	{
		unsigned int numInputs = (unsigned int)wParam;
		unsigned int i = 0;
		TOUCHINPUT* ti = (TOUCHINPUT*)malloc( sizeof(TOUCHINPUT)*numInputs);

		if (fghGetTouchInputInfo == (pGetTouchInputInfo)0xDEADBEEF) {
		    fghGetTouchInputInfo = (pGetTouchInputInfo)GetProcAddress(GetModuleHandle("user32"),"GetTouchInputInfo");
		    fghCloseTouchInputHandle = (pCloseTouchInputHandle)GetProcAddress(GetModuleHandle("user32"),"CloseTouchInputHandle");
		}

		if (!fghGetTouchInputInfo) { 
			free( (void*)ti );
			break;
		}

		if (fghGetTouchInputInfo( (HTOUCHINPUT)lParam, numInputs, ti, sizeof(TOUCHINPUT) )) {
			/* Handle each contact point */
			for (i = 0; i < numInputs; ++i ) {

				POINT tp;
				tp.x = TOUCH_COORD_TO_PIXEL(ti[i].x);
				tp.y = TOUCH_COORD_TO_PIXEL(ti[i].y);
				ScreenToClient( hWnd, &tp );

				ti[i].dwID = ti[i].dwID * 2;

				if (ti[i].dwFlags & TOUCHEVENTF_DOWN) {
					INVOKE_WCB( *window, MultiEntry,  ( ti[i].dwID, GLUT_ENTERED ) );
					INVOKE_WCB( *window, MultiButton, ( ti[i].dwID, tp.x, tp.y, 0, GLUT_DOWN ) );
				} else if (ti[i].dwFlags & TOUCHEVENTF_MOVE) {
					INVOKE_WCB( *window, MultiMotion, ( ti[i].dwID, tp.x, tp.y ) );
				} else if (ti[i].dwFlags & TOUCHEVENTF_UP)   { 
					INVOKE_WCB( *window, MultiButton, ( ti[i].dwID, tp.x, tp.y, 0, GLUT_UP ) );
					INVOKE_WCB( *window, MultiEntry,  ( ti[i].dwID, GLUT_LEFT ) );
				}
			}
		}
		fghCloseTouchInputHandle((HTOUCHINPUT)lParam);
		free( (void*)ti );
		lRet = 0; /*DefWindowProc( hWnd, uMsg, wParam, lParam );*/
		break;
	}
#endif
    default:
        /* Handle unhandled messages */
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        break;
    }

    return lRet;
}
Ejemplo n.º 14
0
/*
 * Remembers the current visual settings, so that
 * we can change them and restore later...
 */
static void fghRememberState( void )
{
#if TARGET_HOST_UNIX_X11

    /*
     * This highly depends on the XFree86 extensions,
     * not approved as X Consortium standards
     */
#   ifdef X_XF86VidModeGetModeLine


    /*
     * Remember the current ViewPort location of the screen to be able to
     * restore the ViewPort on LeaveGameMode():
     */
    if( !XF86VidModeGetViewPort(
             fgDisplay.Display,
             fgDisplay.Screen,
             &fgDisplay.DisplayViewPortX,
             &fgDisplay.DisplayViewPortY ) )
        fgWarning( "XF86VidModeGetViewPort failed" );

    /*
     * Remember the current pointer location before going fullscreen
     * for restoring it later:
     */
    {
        Window junk_window;
        unsigned int mask;

        XQueryPointer(
            fgDisplay.Display, fgDisplay.RootWindow,
            &junk_window, &junk_window,
            &fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY,
            &fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY, &mask
        );
    }

    /* Query the current display settings: */
    fgDisplay.DisplayModeValid =
      XF86VidModeGetModeLine(
        fgDisplay.Display,
        fgDisplay.Screen,
        &fgDisplay.DisplayModeClock,
        &fgDisplay.DisplayMode
    );

    if( !fgDisplay.DisplayModeValid )
            fgWarning( "XF86VidModeGetModeLine failed" );

#   else
    /*
     * XXX warning fghRememberState: missing XFree86 video mode extensions,
     * XXX game mode will not change screen resolution when activated
     */
#   endif

#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE

/*    DEVMODE devMode; */

    /* Grab the current desktop settings... */

/* hack to get around my stupid cross-gcc headers */
#define FREEGLUT_ENUM_CURRENT_SETTINGS -1

    EnumDisplaySettings( NULL, FREEGLUT_ENUM_CURRENT_SETTINGS,
                         &fgDisplay.DisplayMode );

    /* Make sure we will be restoring all settings needed */
    fgDisplay.DisplayMode.dmFields |=
        DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;

#endif
}
Ejemplo n.º 15
0
/*
 * Enters the game mode
 */
int FGAPIENTRY glutEnterGameMode( void )
{
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutEnterGameMode" );

    if( fgStructure.GameMode )
        fgAddToWindowDestroyList( fgStructure.GameMode );
    else
        fghRememberState( );

    if( ! fghChangeDisplayMode( GL_FALSE ) )
    {
        fgWarning( "failed to change screen settings" );
        return 0;
    }

    fgStructure.GameMode = fgCreateWindow(
        NULL, "FREEGLUT", 0, 0,
        fgState.GameModeSize.X, fgState.GameModeSize.Y, GL_TRUE, GL_FALSE
    );

    fgStructure.GameMode->State.Width  = fgState.GameModeSize.X;
    fgStructure.GameMode->State.Height = fgState.GameModeSize.Y;
    fgStructure.GameMode->State.NeedToResize = GL_TRUE;

    fgStructure.GameMode->State.IsGameMode = GL_TRUE;

#if TARGET_HOST_UNIX_X11

    /*
     * Sync needed to avoid a real race, the Xserver must have really created
     * the window before we can grab the pointer into it:
     */
    XSync( fgDisplay.Display, False );

    /*
     * Grab the pointer to confine it into the window after the calls to
     * XWrapPointer() which ensure that the pointer really enters the window.
     *
     * We also need to wait here until XGrabPointer() returns GrabSuccess,
     * otherwise the new window is not viewable yet and if the next function
     * (XSetInputFocus) is called with a not yet viewable window, it will exit
     * the application which we have to aviod, so wait until it's viewable:
     */
    while( GrabSuccess != XGrabPointer(
               fgDisplay.Display, fgStructure.GameMode->Window.Handle,
               TRUE,
               ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
               | PointerMotionMask,
               GrabModeAsync, GrabModeAsync,
               fgStructure.GameMode->Window.Handle, None, CurrentTime) )
        usleep( 100 );

    /*
     * Change input focus to the new window. This will exit the application
     * if the new window is not viewable yet, see the XGrabPointer loop above.
     */
    XSetInputFocus(
        fgDisplay.Display,
        fgStructure.GameMode->Window.Handle,
        RevertToNone,
        CurrentTime
    );

    /* Move the Pointer to the middle of the fullscreen window */
    XWarpPointer(
        fgDisplay.Display,
        None,
        fgDisplay.RootWindow,
        0, 0, 0, 0,
        fgState.GameModeSize.X/2, fgState.GameModeSize.Y/2
    );

#   ifdef X_XF86VidModeSetViewPort

    if( fgDisplay.DisplayModeValid )
    {
        int x, y;
        Window child;

        /* Change to viewport to the window topleft edge: */
        if( !XF86VidModeSetViewPort( fgDisplay.Display, fgDisplay.Screen, 0, 0 ) )
            fgWarning( "XF86VidModeSetViewPort failed" );

        /*
         * Final window repositioning: It could be avoided using an undecorated
         * window using override_redirect, but this * would possily require
         * more changes and investigation.
         */

        /* Get the current postion of the drawable area on screen */
        XTranslateCoordinates(
            fgDisplay.Display,
            fgStructure.CurrentWindow->Window.Handle,
            fgDisplay.RootWindow,
            0, 0, &x, &y,
            &child
        );

        /* Move the decorataions out of the topleft corner of the display */
        XMoveWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle,
                     -x, -y);
    }

#endif

    /* Grab the keyboard, too */
    XGrabKeyboard(
        fgDisplay.Display,
        fgStructure.GameMode->Window.Handle,
        FALSE,
        GrabModeAsync, GrabModeAsync,
        CurrentTime
    );

#endif

    return fgStructure.GameMode->ID;
}
Ejemplo n.º 16
0
/*
 * Perform the freeglut deinitialization...
 */
void fgDeinitialize( void )
{
    SFG_Timer *timer;

    if( !fgState.Initialised )
    {
        fgWarning( "fgDeinitialize(): "
                   "no valid initialization has been performed" );
        return;
    }

    /* fgState.Initialised = GL_FALSE; */

    /*
     * If there was a menu created, destroy the rendering context
     */
    if( fgStructure.MenuContext )
    {
        free( fgStructure.MenuContext );
        fgStructure.MenuContext = NULL;
    }

    fgDestroyStructure( );

    while( (timer = fgState.Timers.First) )
    {
        fgListRemove( &fgState.Timers, &timer->Node );
        free( timer );
    }

    while( (timer = fgState.FreeTimers.First) )
    {
        fgListRemove( &fgState.FreeTimers, &timer->Node );
        free( timer );
    }

#ifndef _WIN32_WCE
    fgJoystickClose( );
#endif

    fgState.Initialised = GL_FALSE;

    fgState.Position.X = -1;
    fgState.Position.Y = -1;
    fgState.Position.Use = GL_FALSE;

    fgState.Size.X = 240;
    fgState.Size.Y = 320;
    fgState.Size.Use = GL_TRUE;

    fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;

    fgState.ForceDirectContext  = GL_FALSE;
    fgState.TryDirectContext    = GL_TRUE;
    fgState.ForceIconic         = GL_FALSE;
    fgState.UseCurrentContext   = GL_FALSE;
    fgState.GLDebugSwitch       = GL_FALSE;
    fgState.XSyncSwitch         = GL_FALSE;
    fgState.ActionOnWindowClose = GLUT_ACTION_EXIT;
    fgState.ExecState           = GLUT_EXEC_STATE_INIT;

    fgState.IgnoreKeyRepeat = GL_TRUE;
    fgState.Modifiers       = 0xffffffff;

    fgState.GameModeSize.X  = 240;
    fgState.GameModeSize.Y  = 320;
    fgState.GameModeDepth   =  16;
    fgState.GameModeRefresh =  72;

    fgState.Time.Set = GL_FALSE;

    fgListInit( &fgState.Timers );
    fgListInit( &fgState.FreeTimers );

    fgState.IdleCallback = NULL;
    fgState.MenuStateCallback = ( FGCBMenuState )NULL;
    fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;

    fgState.SwapCount   = 0;
    fgState.SwapTime    = 0;
    fgState.FPSInterval = 0;

    if( fgState.ProgramName )
    {
        free( fgState.ProgramName );
        fgState.ProgramName = NULL;
    }
    
	__glDestroy();

#if TARGET_HOST_UNIX_X11

    /*
     * Make sure all X-client data we have created will be destroyed on
     * display closing
     */
    XSetCloseDownMode( fgDisplay.Display, DestroyAll );

    /*
     * Close the display connection, destroying all windows we have
     * created so far
     */
    XCloseDisplay( fgDisplay.Display );

#endif
}
Ejemplo n.º 17
0
/*
 * Read the raw joystick data
 */
static void fghJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes )
{
#ifdef WIN32
    MMRESULT status;
#else
    int status;
#endif

    int i;

    if( joy->error )
    {
        if( buttons )
            *buttons = 0;

        if( axes )
            for( i=0; i<joy->num_axes; i++ )
                axes[ i ] = 1500.0f;

        return;
    }

#ifdef WIN32
    status = joyGetPosEx( joy->js_id, &joy->js );

    if( status != JOYERR_NOERROR )
    {
        joy->error = GL_TRUE;
        return;
    }

    if( buttons )
        *buttons = joy->js.dwButtons;

    if( axes )
    {
        /*
         * WARNING - Fall through case clauses!!
         */
        switch( joy->num_axes )
        {
        case 6: axes[5] = (float) joy->js.dwVpos;
        case 5: axes[4] = (float) joy->js.dwUpos;
        case 4: axes[3] = (float) joy->js.dwRpos;
        case 3: axes[2] = (float) joy->js.dwZpos;
        case 2: axes[1] = (float) joy->js.dwYpos;
        case 1: axes[0] = (float) joy->js.dwXpos;
        }
    }
#else
#   ifdef JS_NEW

    while( 1 )
    {
        status = read( joy->fd, &joy->js, sizeof(struct js_event) );

        if( status != sizeof( struct js_event ) )
        {
            if( errno == EAGAIN )
            {
                /*
                 * Use the old values
                 */
                if( buttons )
                    *buttons = joy->tmp_buttons;
                if( axes )
                    memcpy( axes, joy->tmp_axes,
                            sizeof( float ) * joy->num_axes );
                return;
            }

            fgWarning( "%s", joy->fname );
            joy->error = GL_TRUE;
            return;
        }

        switch( joy->js.type & ~JS_EVENT_INIT )
        {
        case JS_EVENT_BUTTON:
            if( joy->js.value == 0 ) /* clear the flag */
                joy->tmp_buttons &= ~( 1 << joy->js.number );
            else
                joy->tmp_buttons |= ( 1 << joy->js.number );
            break;

        case JS_EVENT_AXIS:
            joy->tmp_axes[ joy->js.number ] = ( float )joy->js.value;
            
            if( axes )
                memcpy( axes, joy->tmp_axes, sizeof(float) * joy->num_axes );
            break;
        }

        if( buttons )
            *buttons = joy->tmp_buttons;
    }
#   else

    status = read( joy->fd, &joy->js, JS_RETURN );

    if( status != JS_RETURN )
    {
        fgWarning( "%s", joy->fname );
        joy->error = GL_TRUE;
        return;
    }

    if( buttons )
#       if defined( __FreeBSD__ ) || defined( __NetBSD__ )
        *buttons = ( joy->js.b1 ? 1 : 0 ) | ( joy->js.b2 ? 2 : 0 );
#       else
        *buttons = joy->js.buttons;
#       endif

    if( axes )
    {
        axes[ 0 ] = (float) joy->js.x;
        axes[ 1 ] = (float) joy->js.y;
    }
#   endif
#endif
}
Ejemplo n.º 18
0
void fgPlatformProcessSingleEvent ( void )
{
    SFG_Window* window;
    XEvent event;

    /* This code was repeated constantly, so here it goes into a definition: */
#define GETWINDOW(a)                             \
    window = fgWindowByHandle( event.a.window ); \
    if( window == NULL )                         \
        break;

#define GETMOUSE(a)                              \
    window->State.MouseX = event.a.x;            \
    window->State.MouseY = event.a.y;

    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMainLoopEvent" );

    while( XPending( fgDisplay.pDisplay.Display ) )
    {
        XNextEvent( fgDisplay.pDisplay.Display, &event );
#if _DEBUG
        fghPrintEvent( &event );
#endif

        switch( event.type )
        {
        case ClientMessage:
            if (fgStructure.CurrentWindow)
                if(fgIsSpaceballXEvent(&event)) {
                    fgSpaceballHandleXEvent(&event);
                    break;
                }
            /* Destroy the window when the WM_DELETE_WINDOW message arrives */
            if( (Atom) event.xclient.data.l[ 0 ] == fgDisplay.pDisplay.DeleteWindow )
            {
                GETWINDOW( xclient );

                fgDestroyWindow ( window );

                if( fgState.ActionOnWindowClose == GLUT_ACTION_EXIT )
                {
                    fgDeinitialize( );
                    exit( 0 );
                }
                else if( fgState.ActionOnWindowClose == GLUT_ACTION_GLUTMAINLOOP_RETURNS )
                    fgState.ExecState = GLUT_EXEC_STATE_STOP;

                return;
            }
            break;

            /*
             * CreateNotify causes a configure-event so that sub-windows are
             * handled compatibly with GLUT.  Otherwise, your sub-windows
             * (in freeglut only) will not get an initial reshape event,
             * which can break things.
             *
             * GLUT presumably does this because it generally tries to treat
             * sub-windows the same as windows.
             */
        case CreateNotify:
        case ConfigureNotify:
            {
                int width, height, x, y;
                if( event.type == CreateNotify ) {
                    GETWINDOW( xcreatewindow );
                    width = event.xcreatewindow.width;
                    height = event.xcreatewindow.height;
                    x = event.xcreatewindow.x;
                    y = event.xcreatewindow.y;
                } else {
                    GETWINDOW( xconfigure );
                    width = event.xconfigure.width;
                    height = event.xconfigure.height;
                    x = event.xconfigure.x;
                    y = event.xconfigure.y;
                }

                /* Update state and call callback, if there was a change */
                fghOnPositionNotify(window, x, y, GL_FALSE);
                /* Update state and call callback, if there was a change */
                fghOnReshapeNotify(window, width, height, GL_FALSE);
            }
            break;

        case DestroyNotify:
            /*
             * This is sent to confirm the XDestroyWindow call.
             *
             * XXX WHY is this commented out?  Should we re-enable it?
             */
            /* fgAddToWindowDestroyList ( window ); */
            break;

        case Expose:
            /*
             * We are too dumb to process partial exposes...
             *
             * XXX Well, we could do it.  However, it seems to only
             * XXX be potentially useful for single-buffered (since
             * XXX double-buffered does not respect viewport when we
             * XXX do a buffer-swap).
             *
             */
            if( event.xexpose.count == 0 )
            {
                GETWINDOW( xexpose );
                window->State.WorkMask |= GLUT_DISPLAY_WORK;
            }
            break;

        case MapNotify:
            break;

        case UnmapNotify:
            /* We get this when iconifying a window. */ 
            GETWINDOW( xunmap );
            INVOKE_WCB( *window, WindowStatus, ( GLUT_HIDDEN ) );
            window->State.Visible = GL_FALSE;
            break;

        case MappingNotify:
            /*
             * Have the client's keyboard knowledge updated (xlib.ps,
             * page 206, says that's a good thing to do)
             */
            XRefreshKeyboardMapping( (XMappingEvent *) &event );
            break;

        case VisibilityNotify:
        {
            /*
             * Sending this event, the X server can notify us that the window
             * has just acquired one of the three possible visibility states:
             * VisibilityUnobscured, VisibilityPartiallyObscured or
             * VisibilityFullyObscured. Note that we DO NOT receive a
             * VisibilityNotify event when iconifying a window, we only get an
             * UnmapNotify then.
             */
            GETWINDOW( xvisibility );
            switch( event.xvisibility.state )
            {
            case VisibilityUnobscured:
                INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_RETAINED ) );
                window->State.Visible = GL_TRUE;
                break;

            case VisibilityPartiallyObscured:
                INVOKE_WCB( *window, WindowStatus,
                            ( GLUT_PARTIALLY_RETAINED ) );
                window->State.Visible = GL_TRUE;
                break;

            case VisibilityFullyObscured:
                INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_COVERED ) );
                window->State.Visible = GL_FALSE;
                break;

            default:
                fgWarning( "Unknown X visibility state: %d",
                           event.xvisibility.state );
                break;
            }
        }
        break;

        case EnterNotify:
        case LeaveNotify:
            GETWINDOW( xcrossing );
            GETMOUSE( xcrossing );
            if( ( event.type == LeaveNotify ) && window->IsMenu &&
                window->ActiveMenu && window->ActiveMenu->IsActive )
                fgUpdateMenuHighlight( window->ActiveMenu );

            INVOKE_WCB( *window, Entry, ( ( EnterNotify == event.type ) ?
                                          GLUT_ENTERED :
                                          GLUT_LEFT ) );
            break;

        case MotionNotify:
        {
            /* if GLUT_SKIP_STALE_MOTION_EVENTS is true, then discard all but
             * the last motion event from the queue
             */
            if(fgState.SkipStaleMotion) {
                while(XCheckIfEvent(fgDisplay.pDisplay.Display, &event, match_motion, 0));
            }

            GETWINDOW( xmotion );
            GETMOUSE( xmotion );

            if( window->ActiveMenu )
            {
                if( window == window->ActiveMenu->ParentWindow )
                {
                    window->ActiveMenu->Window->State.MouseX =
                        event.xmotion.x_root - window->ActiveMenu->X;
                    window->ActiveMenu->Window->State.MouseY =
                        event.xmotion.y_root - window->ActiveMenu->Y;
                }

                fgUpdateMenuHighlight( window->ActiveMenu );

                break;
            }

            /*
             * XXX For more than 5 buttons, just check {event.xmotion.state},
             * XXX rather than a host of bit-masks?  Or maybe we need to
             * XXX track ButtonPress/ButtonRelease events in our own
             * XXX bit-mask?
             */
            fgState.Modifiers = fgPlatformGetModifiers( event.xmotion.state );
            if ( event.xmotion.state & ( Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) ) {
                INVOKE_WCB( *window, Motion, ( event.xmotion.x,
                                               event.xmotion.y ) );
            } else {
                INVOKE_WCB( *window, Passive, ( event.xmotion.x,
                                                event.xmotion.y ) );
            }
            fgState.Modifiers = INVALID_MODIFIERS;
        }
        break;

        case ButtonRelease:
        case ButtonPress:
        {
            GLboolean pressed = GL_TRUE;
            int button;

            if( event.type == ButtonRelease )
                pressed = GL_FALSE ;

            /*
             * A mouse button has been pressed or released. Traditionally,
             * break if the window was found within the freeglut structures.
             */
            GETWINDOW( xbutton );
            GETMOUSE( xbutton );

            /*
             * An X button (at least in XFree86) is numbered from 1.
             * A GLUT button is numbered from 0.
             * Old GLUT passed through buttons other than just the first
             * three, though it only gave symbolic names and official
             * support to the first three.
             */
            button = event.xbutton.button - 1;

            /*
             * Do not execute the application's mouse callback if a menu
             * is hooked to this button.  In that case an appropriate
             * private call should be generated.
             */
            if( fgCheckActiveMenu( window, button, pressed,
                                   event.xbutton.x, event.xbutton.y ) )
                break;

            /*
             * Check if there is a mouse or mouse wheel callback hooked to the
             * window
             */
            if( ! FETCH_WCB( *window, Mouse ) &&
                ! FETCH_WCB( *window, MouseWheel ) )
                break;

            fgState.Modifiers = fgPlatformGetModifiers( event.xbutton.state );

            /* Finally execute the mouse or mouse wheel callback */
            if( ( button < glutDeviceGet ( GLUT_NUM_MOUSE_BUTTONS ) ) || ( ! FETCH_WCB( *window, MouseWheel ) ) )
                INVOKE_WCB( *window, Mouse, ( button,
                                              pressed ? GLUT_DOWN : GLUT_UP,
                                              event.xbutton.x,
                                              event.xbutton.y )
                );
            else
            {
                /*
                 * Map 4 and 5 to wheel zero; EVEN to +1, ODD to -1
                 *  "  6 and 7 "    "   one; ...
                 *
                 * XXX This *should* be behind some variables/macros,
                 * XXX since the order and numbering isn't certain
                 * XXX See XFree86 configuration docs (even back in the
                 * XXX 3.x days, and especially with 4.x).
                 *
                 * XXX Note that {button} has already been decremented
                 * XXX in mapping from X button numbering to GLUT.
				 *
				 * XXX Should add support for partial wheel turns as Windows does -- 5/27/11
                 */
                int wheel_number = (button - glutDeviceGet ( GLUT_NUM_MOUSE_BUTTONS )) / 2;
                int direction = -1;
                if( button % 2 )
                    direction = 1;

                if( pressed )
                    INVOKE_WCB( *window, MouseWheel, ( wheel_number,
                                                       direction,
                                                       event.xbutton.x,
                                                       event.xbutton.y )
                    );
            }
            fgState.Modifiers = INVALID_MODIFIERS;
        }
        break;

        case KeyRelease:
        case KeyPress:
        {
            FGCBKeyboard keyboard_cb;
            FGCBSpecial special_cb;

            GETWINDOW( xkey );
            GETMOUSE( xkey );

            /* Detect auto repeated keys, if configured globally or per-window */

            if ( fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE )
            {
                if (event.type==KeyRelease)
                {
                    /*
                     * Look at X11 keystate to detect repeat mode.
                     * While X11 says the key is actually held down, we'll ignore KeyRelease/KeyPress pairs.
                     */

                    char keys[32];
                    XQueryKeymap( fgDisplay.pDisplay.Display, keys ); /* Look at X11 keystate to detect repeat mode */

                    if ( event.xkey.keycode<256 )            /* XQueryKeymap is limited to 256 keycodes    */
                    {
                        if ( keys[event.xkey.keycode>>3] & (1<<(event.xkey.keycode%8)) )
                            window->State.pWState.KeyRepeating = GL_TRUE;
                        else
                            window->State.pWState.KeyRepeating = GL_FALSE;
                    }
                }
            }
            else
                window->State.pWState.KeyRepeating = GL_FALSE;

            /* Cease processing this event if it is auto repeated */

            if (window->State.pWState.KeyRepeating)
            {
                if (event.type == KeyPress) window->State.pWState.KeyRepeating = GL_FALSE;
                break;
            }

            if( event.type == KeyPress )
            {
                keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, Keyboard ));
                special_cb  = (FGCBSpecial) ( FETCH_WCB( *window, Special  ));
            }
            else
            {
                keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, KeyboardUp ));
                special_cb  = (FGCBSpecial) ( FETCH_WCB( *window, SpecialUp  ));
            }

            /* Is there a keyboard/special callback hooked for this window? */
            if( keyboard_cb || special_cb )
            {
                XComposeStatus composeStatus;
                char asciiCode[ 32 ];
                KeySym keySym;
                int len;

                /* Check for the ASCII/KeySym codes associated with the event: */
                len = XLookupString( &event.xkey, asciiCode, sizeof(asciiCode),
                                     &keySym, &composeStatus
                );

                /* GLUT API tells us to have two separate callbacks... */
                if( len > 0 )
                {
                    /* ...one for the ASCII translateable keypresses... */
                    if( keyboard_cb )
                    {
                        fgSetWindow( window );
                        fgState.Modifiers = fgPlatformGetModifiers( event.xkey.state );
                        keyboard_cb( asciiCode[ 0 ],
                                     event.xkey.x, event.xkey.y
                        );
                        fgState.Modifiers = INVALID_MODIFIERS;
                    }
                }
                else
                {
                    int special = -1;

                    /*
                     * ...and one for all the others, which need to be
                     * translated to GLUT_KEY_Xs...
                     */
                    switch( keySym )
                    {
                    case XK_F1:     special = GLUT_KEY_F1;     break;
                    case XK_F2:     special = GLUT_KEY_F2;     break;
                    case XK_F3:     special = GLUT_KEY_F3;     break;
                    case XK_F4:     special = GLUT_KEY_F4;     break;
                    case XK_F5:     special = GLUT_KEY_F5;     break;
                    case XK_F6:     special = GLUT_KEY_F6;     break;
                    case XK_F7:     special = GLUT_KEY_F7;     break;
                    case XK_F8:     special = GLUT_KEY_F8;     break;
                    case XK_F9:     special = GLUT_KEY_F9;     break;
                    case XK_F10:    special = GLUT_KEY_F10;    break;
                    case XK_F11:    special = GLUT_KEY_F11;    break;
                    case XK_F12:    special = GLUT_KEY_F12;    break;

                    case XK_KP_Left:
                    case XK_Left:   special = GLUT_KEY_LEFT;   break;
                    case XK_KP_Right:
                    case XK_Right:  special = GLUT_KEY_RIGHT;  break;
                    case XK_KP_Up:
                    case XK_Up:     special = GLUT_KEY_UP;     break;
                    case XK_KP_Down:
                    case XK_Down:   special = GLUT_KEY_DOWN;   break;

                    case XK_KP_Prior:
                    case XK_Prior:  special = GLUT_KEY_PAGE_UP; break;
                    case XK_KP_Next:
                    case XK_Next:   special = GLUT_KEY_PAGE_DOWN; break;
                    case XK_KP_Home:
                    case XK_Home:   special = GLUT_KEY_HOME;   break;
                    case XK_KP_End:
                    case XK_End:    special = GLUT_KEY_END;    break;
                    case XK_KP_Insert:
                    case XK_Insert: special = GLUT_KEY_INSERT; break;

                    case XK_Num_Lock :  special = GLUT_KEY_NUM_LOCK;  break;
                    case XK_KP_Begin :  special = GLUT_KEY_BEGIN;     break;
                    case XK_KP_Delete:  special = GLUT_KEY_DELETE;    break;

                    case XK_Shift_L:   special = GLUT_KEY_SHIFT_L;    break;
                    case XK_Shift_R:   special = GLUT_KEY_SHIFT_R;    break;
                    case XK_Control_L: special = GLUT_KEY_CTRL_L;     break;
                    case XK_Control_R: special = GLUT_KEY_CTRL_R;     break;
                    case XK_Alt_L:     special = GLUT_KEY_ALT_L;      break;
                    case XK_Alt_R:     special = GLUT_KEY_ALT_R;      break;
                    }

                    /*
                     * Execute the callback (if one has been specified),
                     * given that the special code seems to be valid...
                     */
                    if( special_cb && (special != -1) )
                    {
                        fgSetWindow( window );
                        fgState.Modifiers = fgPlatformGetModifiers( event.xkey.state );
                        special_cb( special, event.xkey.x, event.xkey.y );
                        fgState.Modifiers = INVALID_MODIFIERS;
                    }
                }
            }
        }
Ejemplo n.º 19
0
/*
 * Perform the freeglut deinitialization...
 */
void fgDeinitialize( void )
{
    SFG_Timer *timer;

    if( !fgState.Initialised )
    {
        fgWarning( "fgDeinitialize(): "
                   "no valid initialization has been performed" );
        return;
    }

    /* If there was a menu created, destroy the rendering context */
    if( fgStructure.MenuContext )
    {
#if TARGET_HOST_POSIX_X11
        /* Note that the MVisualInfo is not owned by the MenuContext! */
        glXDestroyContext( fgDisplay.Display, fgStructure.MenuContext->MContext );
#endif
        free( fgStructure.MenuContext );
        fgStructure.MenuContext = NULL;
    }

    fgDestroyStructure( );

    while( ( timer = fgState.Timers.First) )
    {
        fgListRemove( &fgState.Timers, &timer->Node );
        free( timer );
    }

    while( ( timer = fgState.FreeTimers.First) )
    {
        fgListRemove( &fgState.FreeTimers, &timer->Node );
        free( timer );
    }

#if !defined(_WIN32_WCE)
    if ( fgState.JoysticksInitialised )
        fgJoystickClose( );

    if ( fgState.InputDevsInitialised )
        fgInputDeviceClose( );
#endif /* !defined(_WIN32_WCE) */
    fgState.JoysticksInitialised = GL_FALSE;
    fgState.InputDevsInitialised = GL_FALSE;

    fgState.Initialised = GL_FALSE;

    fgState.Position.X = -1;
    fgState.Position.Y = -1;
    fgState.Position.Use = GL_FALSE;

    fgState.Size.X = 300;
    fgState.Size.Y = 300;
    fgState.Size.Use = GL_TRUE;

    fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;

    fgState.DirectContext  = GLUT_TRY_DIRECT_CONTEXT;
    fgState.ForceIconic         = GL_FALSE;
    fgState.UseCurrentContext   = GL_FALSE;
    fgState.GLDebugSwitch       = GL_FALSE;
    fgState.XSyncSwitch         = GL_FALSE;
    fgState.ActionOnWindowClose = GLUT_ACTION_EXIT;
    fgState.ExecState           = GLUT_EXEC_STATE_INIT;

    fgState.KeyRepeat       = GLUT_KEY_REPEAT_ON;
    fgState.Modifiers       = INVALID_MODIFIERS;

    fgState.GameModeSize.X  = 640;
    fgState.GameModeSize.Y  = 480;
    fgState.GameModeDepth   =  16;
    fgState.GameModeRefresh =  72;

    fgListInit( &fgState.Timers );
    fgListInit( &fgState.FreeTimers );

    fgState.IdleCallback = NULL;
    fgState.MenuStateCallback = ( FGCBMenuState )NULL;
    fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;

    fgState.SwapCount   = 0;
    fgState.SwapTime    = 0;
    fgState.FPSInterval = 0;

    if( fgState.ProgramName )
    {
        free( fgState.ProgramName );
        fgState.ProgramName = NULL;
    }

#if TARGET_HOST_POSIX_X11

    /*
     * Make sure all X-client data we have created will be destroyed on
     * display closing
     */
    XSetCloseDownMode( fgDisplay.Display, DestroyAll );

    /*
     * Close the display connection, destroying all windows we have
     * created so far
     */
    XCloseDisplay( fgDisplay.Display );

#elif TARGET_HOST_MS_WINDOWS

    /* Reset the timer granularity */
    timeEndPeriod ( 1 );

#endif

    fgState.Initialised = GL_FALSE;
}
Ejemplo n.º 20
0
int fgPlatformGlutGet ( GLenum eWhat )
{
    int returnValue ;
    GLboolean boolValue ;

    int nsamples = 0;

    switch( eWhat )
    {
    case GLUT_WINDOW_NUM_SAMPLES:
      glGetIntegerv(WGL_SAMPLES_ARB, &nsamples);
      return nsamples;

    /* Handle the OpenGL inquiries */
    case GLUT_WINDOW_RGBA:
#if defined(_WIN32_WCE)
      boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */
#else
      glGetBooleanv ( GL_RGBA_MODE, &boolValue );
      returnValue = boolValue ? 1 : 0;
#endif
      return returnValue;
    case GLUT_WINDOW_DOUBLEBUFFER:
#if defined(_WIN32_WCE)
      boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */
#else
      glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue );
      returnValue = boolValue ? 1 : 0;
#endif
      return returnValue;
    case GLUT_WINDOW_STEREO:
#if defined(_WIN32_WCE)
      boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */
#else
      glGetBooleanv ( GL_STEREO, &boolValue );
      returnValue = boolValue ? 1 : 0;
#endif
      return returnValue;

    case GLUT_WINDOW_RED_SIZE:
      glGetIntegerv ( GL_RED_BITS, &returnValue );
      return returnValue;
    case GLUT_WINDOW_GREEN_SIZE:
      glGetIntegerv ( GL_GREEN_BITS, &returnValue );
      return returnValue;
    case GLUT_WINDOW_BLUE_SIZE:
      glGetIntegerv ( GL_BLUE_BITS, &returnValue );
      return returnValue;
    case GLUT_WINDOW_ALPHA_SIZE:
      glGetIntegerv ( GL_ALPHA_BITS, &returnValue );
      return returnValue;
    case GLUT_WINDOW_ACCUM_RED_SIZE:
#if defined(_WIN32_WCE)
      returnValue = 0;  /* WinCE doesn't support this feature */
#else
      glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue );
#endif
      return returnValue;
    case GLUT_WINDOW_ACCUM_GREEN_SIZE:
#if defined(_WIN32_WCE)
      returnValue = 0;  /* WinCE doesn't support this feature */
#else
      glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue );
#endif
      return returnValue;
    case GLUT_WINDOW_ACCUM_BLUE_SIZE:
#if defined(_WIN32_WCE)
      returnValue = 0;  /* WinCE doesn't support this feature */
#else
      glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue );
#endif
      return returnValue;
    case GLUT_WINDOW_ACCUM_ALPHA_SIZE:
#if defined(_WIN32_WCE)
      returnValue = 0;  /* WinCE doesn't support this feature */
#else
      glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue );
#endif
      return returnValue;
    case GLUT_WINDOW_DEPTH_SIZE:
      glGetIntegerv ( GL_DEPTH_BITS, &returnValue );
      return returnValue;

    case GLUT_WINDOW_BUFFER_SIZE:
      returnValue = 1 ;                                      /* ????? */
      return returnValue;
    case GLUT_WINDOW_STENCIL_SIZE:
      returnValue = 0 ;                                      /* ????? */
      return returnValue;

    case GLUT_WINDOW_X:
    case GLUT_WINDOW_Y:
    case GLUT_WINDOW_WIDTH:
    case GLUT_WINDOW_HEIGHT:
    {
        /*
         *  There is considerable confusion about the "right thing to
         *  do" concerning window  size and position.  GLUT itself is
         *  not consistent between Windows and UNIX/X11; since
         *  platform independence is a virtue for "freeglut", we
         *  decided to break with GLUT's behaviour.
         *
         *  Under UNIX/X11, it is apparently not possible to get the
         *  window border sizes in order to subtract them off the
         *  window's initial position until some time after the window
         *  has been created.  Therefore we decided on the following
         *  behaviour, both under Windows and under UNIX/X11:
         *  - When you create a window with position (x,y) and size
         *    (w,h), the upper left hand corner of the outside of the
         *    window is at (x,y) and the size of the drawable area  is
         *    (w,h).
         *  - When you query the size and position of the window--as
         *    is happening here for Windows--"freeglut" will return
         *    the size of the drawable area--the (w,h) that you
         *    specified when you created the window--and the coordinates
         *    of the upper left hand corner of the drawable
         *    area--which is NOT the (x,y) you specified.
         */

        RECT winRect;

        freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 );

#if defined(_WIN32_WCE)
        GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect );
#else
        winRect = fghGetClientArea(fgStructure.CurrentWindow, FALSE);
#endif /* defined(_WIN32_WCE) */

        switch( eWhat )
        {
        case GLUT_WINDOW_X:      return winRect.left                ;
        case GLUT_WINDOW_Y:      return winRect.top                 ;
        case GLUT_WINDOW_WIDTH:  return winRect.right - winRect.left;
        case GLUT_WINDOW_HEIGHT: return winRect.bottom - winRect.top;
        }
    }
    break;

    case GLUT_WINDOW_BORDER_WIDTH :
    case GLUT_WINDOW_HEADER_HEIGHT :
#if defined(_WIN32_WCE)
        return 0;
#else
        {
            DWORD windowStyle;

            if (fgStructure.CurrentWindow && fgStructure.CurrentWindow->Window.Handle)
                windowStyle = GetWindowLong(fgStructure.CurrentWindow->Window.Handle, GWL_STYLE);
            else
                /* If no window, return sizes for a default window with title bar and border */
                windowStyle = WS_OVERLAPPEDWINDOW;
            
            switch( eWhat )
            {
            case GLUT_WINDOW_BORDER_WIDTH:
                {
                    int xBorderWidth, yBorderWidth;
                    fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth);
                    return xBorderWidth;
                }
            case GLUT_WINDOW_HEADER_HEIGHT:
                /* Need to query for WS_MAXIMIZEBOX to see if we have a title bar, the WS_CAPTION query is also true for a WS_DLGFRAME only... */
                return (windowStyle & WS_MAXIMIZEBOX)? GetSystemMetrics( SM_CYCAPTION ) : 0;
            }
        }
#endif /* defined(_WIN32_WCE) */

    case GLUT_DISPLAY_MODE_POSSIBLE:
#if defined(_WIN32_WCE)
        return 0;
#else
        return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE,
                                    PFD_MAIN_PLANE );
#endif /* defined(_WIN32_WCE) */


    case GLUT_WINDOW_FORMAT_ID:
#if !defined(_WIN32_WCE)
        if( fgStructure.CurrentWindow != NULL )
            return GetPixelFormat( fgStructure.CurrentWindow->Window.pContext.Device );
#endif /* defined(_WIN32_WCE) */
        return 0;

    default:
        fgWarning( "glutGet(): missing enum handle %d", eWhat );
        break;
    }

	return -1;
}
Ejemplo n.º 21
0
int fghPlatformGlutGetGLX ( GLenum eWhat )
{
    switch( eWhat )
    {
    /*
     * The window/context specific queries are handled mostly by
     * fgPlatformGetConfig().
     */
    case GLUT_WINDOW_NUM_SAMPLES:
      {
	int nsamples = 0;
#ifdef GLX_VERSION_1_3
        glGetIntegerv(GL_SAMPLES, &nsamples);
#endif
        return nsamples;
      }

    /*
     * The rest of GLX queries under X are general enough to use a macro to
     * check them
     */
#   define GLX_QUERY(a,b) case a: return fgPlatformGetConfig( b );

    GLX_QUERY( GLUT_WINDOW_RGBA,                GLX_RGBA                );
    GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER,        GLX_DOUBLEBUFFER        );
    GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE,         GLX_BUFFER_SIZE         );
    GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE,        GLX_STENCIL_SIZE        );
    GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE,          GLX_DEPTH_SIZE          );
    GLX_QUERY( GLUT_WINDOW_RED_SIZE,            GLX_RED_SIZE            );
    GLX_QUERY( GLUT_WINDOW_GREEN_SIZE,          GLX_GREEN_SIZE          );
    GLX_QUERY( GLUT_WINDOW_BLUE_SIZE,           GLX_BLUE_SIZE           );
    GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE,          GLX_ALPHA_SIZE          );
    GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE,      GLX_ACCUM_RED_SIZE      );
    GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE,    GLX_ACCUM_GREEN_SIZE    );
    GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE,     GLX_ACCUM_BLUE_SIZE     );
    GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE,    GLX_ACCUM_ALPHA_SIZE    );
    GLX_QUERY( GLUT_WINDOW_STEREO,              GLX_STEREO              );

#   undef GLX_QUERY

    /* I do not know yet if there will be a fgChooseVisual() function for Win32 */
    case GLUT_DISPLAY_MODE_POSSIBLE:
    {
        /*  We should not have to call fghChooseConfig again here.  */
        GLXFBConfig config;
        return fghChooseConfig(&config);
    }

    /* This is system-dependent */
    case GLUT_WINDOW_FORMAT_ID:
        if( fgStructure.CurrentWindow == NULL )
            return 0;

        return fgPlatformGetConfig( GLX_VISUAL_ID );

    default:
        fgWarning( "glutGet(): missing enum handle %d", eWhat );
        break;
    }

	return -1;
}
Ejemplo n.º 22
0
/*
 * Return the state of the GLUT API overlay subsystem. A misery ;-)
 */
int FGAPIENTRY glutLayerGet( GLenum eWhat )
{
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutLayerGet" );

    /*
     * This is easy as layers are not implemented ;-)
     *
     * XXX Can we merge the UNIX/X11 and WIN32 sections?  Or
     * XXX is overlay support planned?
     */
    switch( eWhat )
    {

#if TARGET_HOST_POSIX_X11

    case GLUT_OVERLAY_POSSIBLE:
        return 0;

    case GLUT_LAYER_IN_USE:
        return GLUT_NORMAL;

    case GLUT_HAS_OVERLAY:
        return 0;

    case GLUT_TRANSPARENT_INDEX:
        /*
         * Return just anything, which is always defined as zero
         *
         * XXX HUH?
         */
        return 0;

    case GLUT_NORMAL_DAMAGED:
        /* XXX Actually I do not know. Maybe. */
        return 0;

    case GLUT_OVERLAY_DAMAGED:
        return -1;

#elif TARGET_HOST_MS_WINDOWS

    case GLUT_OVERLAY_POSSIBLE:
/*      return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE,
                                   PFD_OVERLAY_PLANE ); */
      return 0 ;

    case GLUT_LAYER_IN_USE:
        return GLUT_NORMAL;

    case GLUT_HAS_OVERLAY:
        return 0;

    case GLUT_TRANSPARENT_INDEX:
        /*
         * Return just anything, which is always defined as zero
         *
         * XXX HUH?
         */
        return 0;

    case GLUT_NORMAL_DAMAGED:
        /* XXX Actually I do not know. Maybe. */
        return 0;

    case GLUT_OVERLAY_DAMAGED:
        return -1;
#endif

    default:
        fgWarning( "glutLayerGet(): missing enum handle %d", eWhat );
        break;
    }

    /* And fail. That's good. Programs do love failing. */
    return -1;
}
Ejemplo n.º 23
0
__fg_unused static void fghPrintEvent( XEvent *event )
{
    switch( event->type ) {

    case KeyPress:
    case KeyRelease: {
        XKeyEvent *e = &event->xkey;
        fgWarning( "%s: window=0x%x, root=0x%x, subwindow=0x%x, time=%lu, "
                   "(x,y)=(%d,%d), (x_root,y_root)=(%d,%d), state=0x%x, "
                   "keycode=%u, same_screen=%s", fghTypeToString( e->type ),
                   e->window, e->root, e->subwindow, (unsigned long)e->time,
                   e->x, e->y, e->x_root, e->y_root, e->state, e->keycode,
                   fghBoolToString( e->same_screen ) );
        break;
    }

    case ButtonPress:
    case ButtonRelease: {
        XButtonEvent *e = &event->xbutton;
        fgWarning( "%s: window=0x%x, root=0x%x, subwindow=0x%x, time=%lu, "
                   "(x,y)=(%d,%d), (x_root,y_root)=(%d,%d), state=0x%x, "
                   "button=%u, same_screen=%d", fghTypeToString( e->type ),
                   e->window, e->root, e->subwindow, (unsigned long)e->time,
                   e->x, e->y, e->x_root, e->y_root, e->state, e->button,
                   fghBoolToString( e->same_screen ) );
        break;
    }

    case MotionNotify: {
        XMotionEvent *e = &event->xmotion;
        fgWarning( "%s: window=0x%x, root=0x%x, subwindow=0x%x, time=%lu, "
                   "(x,y)=(%d,%d), (x_root,y_root)=(%d,%d), state=0x%x, "
                   "is_hint=%s, same_screen=%d", fghTypeToString( e->type ),
                   e->window, e->root, e->subwindow, (unsigned long)e->time,
                   e->x, e->y, e->x_root, e->y_root, e->state,
                   fghNotifyHintToString( e->is_hint ),
                   fghBoolToString( e->same_screen ) );
        break;
    }

    case EnterNotify:
    case LeaveNotify: {
        XCrossingEvent *e = &event->xcrossing;
        fgWarning( "%s: window=0x%x, root=0x%x, subwindow=0x%x, time=%lu, "
                   "(x,y)=(%d,%d), mode=%s, detail=%s, same_screen=%d, "
                   "focus=%d, state=0x%x", fghTypeToString( e->type ),
                   e->window, e->root, e->subwindow, (unsigned long)e->time,
                   e->x, e->y, fghNotifyModeToString( e->mode ),
                   fghNotifyDetailToString( e->detail ), (int)e->same_screen,
                   (int)e->focus, e->state );
        break;
    }

    case FocusIn:
    case FocusOut: {
        XFocusChangeEvent *e = &event->xfocus;
        fgWarning( "%s: window=0x%x, mode=%s, detail=%s",
                   fghTypeToString( e->type ), e->window,
                   fghNotifyModeToString( e->mode ),
                   fghNotifyDetailToString( e->detail ) );
        break;
    }

    case KeymapNotify: {
        XKeymapEvent *e = &event->xkeymap;
        char buf[32 * 2 + 1];
        int i;
        for ( i = 0; i < 32; i++ ) {
            snprintf( &buf[ i * 2 ], sizeof( buf ) - i * 2,
                      "%02x", e->key_vector[ i ] );
        }
        buf[ i ] = '\0';
        fgWarning( "%s: window=0x%x, %s", fghTypeToString( e->type ), e->window,
                   buf );
        break;
    }

    case Expose: {
        XExposeEvent *e = &event->xexpose;
        fgWarning( "%s: window=0x%x, (x,y)=(%d,%d), (width,height)=(%d,%d), "
                   "count=%d", fghTypeToString( e->type ), e->window, e->x,
                   e->y, e->width, e->height, e->count );
        break;
    }

    case GraphicsExpose: {
        XGraphicsExposeEvent *e = &event->xgraphicsexpose;
        fgWarning( "%s: drawable=0x%x, (x,y)=(%d,%d), (width,height)=(%d,%d), "
                   "count=%d, (major_code,minor_code)=(%d,%d)",
                   fghTypeToString( e->type ), e->drawable, e->x, e->y,
                   e->width, e->height, e->count, e->major_code,
                   e->minor_code );
        break;
    }

    case NoExpose: {
        XNoExposeEvent *e = &event->xnoexpose;
        fgWarning( "%s: drawable=0x%x, (major_code,minor_code)=(%d,%d)",
                   fghTypeToString( e->type ), e->drawable, e->major_code,
                   e->minor_code );
        break;
    }

    case VisibilityNotify: {
        XVisibilityEvent *e = &event->xvisibility;
        fgWarning( "%s: window=0x%x, state=%s", fghTypeToString( e->type ),
                   e->window, fghVisibilityToString( e->state) );
        break;
    }

    case CreateNotify: {
        XCreateWindowEvent *e = &event->xcreatewindow;
        fgWarning( "%s: (x,y)=(%d,%d), (width,height)=(%d,%d), border_width=%d, "
                   "window=0x%x, override_redirect=%s",
                   fghTypeToString( e->type ), e->x, e->y, e->width, e->height,
                   e->border_width, e->window,
                   fghBoolToString( e->override_redirect ) );
        break;
    }

    case DestroyNotify: {
        XDestroyWindowEvent *e = &event->xdestroywindow;
        fgWarning( "%s: event=0x%x, window=0x%x",
                   fghTypeToString( e->type ), e->event, e->window );
        break;
    }

    case UnmapNotify: {
        XUnmapEvent *e = &event->xunmap;
        fgWarning( "%s: event=0x%x, window=0x%x, from_configure=%s",
                   fghTypeToString( e->type ), e->event, e->window,
                   fghBoolToString( e->from_configure ) );
        break;
    }

    case MapNotify: {
        XMapEvent *e = &event->xmap;
        fgWarning( "%s: event=0x%x, window=0x%x, override_redirect=%s",
                   fghTypeToString( e->type ), e->event, e->window,
                   fghBoolToString( e->override_redirect ) );
        break;
    }

    case MapRequest: {
        XMapRequestEvent *e = &event->xmaprequest;
        fgWarning( "%s: parent=0x%x, window=0x%x",
                   fghTypeToString( event->type ), e->parent, e->window );
        break;
    }

    case ReparentNotify: {
        XReparentEvent *e = &event->xreparent;
        fgWarning( "%s: event=0x%x, window=0x%x, parent=0x%x, (x,y)=(%d,%d), "
                   "override_redirect=%s", fghTypeToString( e->type ),
                   e->event, e->window, e->parent, e->x, e->y,
                   fghBoolToString( e->override_redirect ) );
        break;
    }

    case ConfigureNotify: {
        XConfigureEvent *e = &event->xconfigure;
        fgWarning( "%s: event=0x%x, window=0x%x, (x,y)=(%d,%d), "
                   "(width,height)=(%d,%d), border_width=%d, above=0x%x, "
                   "override_redirect=%s", fghTypeToString( e->type ), e->event,
                   e->window, e->x, e->y, e->width, e->height, e->border_width,
                   e->above, fghBoolToString( e->override_redirect ) );
        break;
    }

    case ConfigureRequest: {
        XConfigureRequestEvent *e = &event->xconfigurerequest;
        fgWarning( "%s: parent=0x%x, window=0x%x, (x,y)=(%d,%d), "
                   "(width,height)=(%d,%d), border_width=%d, above=0x%x, "
                   "detail=%s, value_mask=%lx", fghTypeToString( e->type ),
                   e->parent, e->window, e->x, e->y, e->width, e->height,
                   e->border_width, e->above,
                   fghConfigureDetailToString( e->detail ), e->value_mask );
        break;
    }

    case GravityNotify: {
        XGravityEvent *e = &event->xgravity;
        fgWarning( "%s: event=0x%x, window=0x%x, (x,y)=(%d,%d)",
                   fghTypeToString( e->type ), e->event, e->window, e->x, e->y );
        break;
    }

    case ResizeRequest: {
        XResizeRequestEvent *e = &event->xresizerequest;
        fgWarning( "%s: window=0x%x, (width,height)=(%d,%d)",
                   fghTypeToString( e->type ), e->window, e->width, e->height );
        break;
    }

    case CirculateNotify: {
        XCirculateEvent *e = &event->xcirculate;
        fgWarning( "%s: event=0x%x, window=0x%x, place=%s",
                   fghTypeToString( e->type ), e->event, e->window,
                   fghPlaceToString( e->place ) );
        break;
    }

    case CirculateRequest: {
        XCirculateRequestEvent *e = &event->xcirculaterequest;
        fgWarning( "%s: parent=0x%x, window=0x%x, place=%s",
                   fghTypeToString( e->type ), e->parent, e->window,
                   fghPlaceToString( e->place ) );
        break;
    }

    case PropertyNotify: {
        XPropertyEvent *e = &event->xproperty;
        fgWarning( "%s: window=0x%x, atom=%lu, time=%lu, state=%s",
                   fghTypeToString( e->type ), e->window,
                   (unsigned long)e->atom, (unsigned long)e->time,
                   fghPropertyStateToString( e->state ) );
        break;
    }

    case SelectionClear: {
        XSelectionClearEvent *e = &event->xselectionclear;
        fgWarning( "%s: window=0x%x, selection=%lu, time=%lu",
                   fghTypeToString( e->type ), e->window,
                   (unsigned long)e->selection, (unsigned long)e->time );
        break;
    }

    case SelectionRequest: {
        XSelectionRequestEvent *e = &event->xselectionrequest;
        fgWarning( "%s: owner=0x%x, requestor=0x%x, selection=0x%x, "
                   "target=0x%x, property=%lu, time=%lu",
                   fghTypeToString( e->type ), e->owner, e->requestor,
                   (unsigned long)e->selection, (unsigned long)e->target,
                   (unsigned long)e->property, (unsigned long)e->time );
        break;
    }

    case SelectionNotify: {
        XSelectionEvent *e = &event->xselection;
        fgWarning( "%s: requestor=0x%x, selection=0x%x, target=0x%x, "
                   "property=%lu, time=%lu", fghTypeToString( e->type ),
                   e->requestor, (unsigned long)e->selection,
                   (unsigned long)e->target, (unsigned long)e->property,
                   (unsigned long)e->time );
        break;
    }

    case ColormapNotify: {
        XColormapEvent *e = &event->xcolormap;
        fgWarning( "%s: window=0x%x, colormap=%lu, new=%s, state=%s",
                   fghTypeToString( e->type ), e->window,
                   (unsigned long)e->colormap, fghBoolToString( e->new ),
                   fghColormapStateToString( e->state ) );
        break;
    }

    case ClientMessage: {
        XClientMessageEvent *e = &event->xclient;
        char buf[ 61 ];
        char* p = buf;
        char* end = buf + sizeof( buf );
        int i;
        switch( e->format ) {
        case 8:
          for ( i = 0; i < 20; i++, p += 3 ) {
                snprintf( p, end - p, " %02x", e->data.b[ i ] );
            }
            break;
        case 16:
            for ( i = 0; i < 10; i++, p += 5 ) {
                snprintf( p, end - p, " %04x", e->data.s[ i ] );
            }
            break;
        case 32:
            for ( i = 0; i < 5; i++, p += 9 ) {
                snprintf( p, end - p, " %08lx", e->data.l[ i ] );
            }
            break;
        }
        *p = '\0';
        fgWarning( "%s: window=0x%x, message_type=%lu, format=%d, data=(%s )",
                   fghTypeToString( e->type ), e->window,
                   (unsigned long)e->message_type, e->format, buf );
        break;
    }

    case MappingNotify: {
        XMappingEvent *e = &event->xmapping;
        fgWarning( "%s: window=0x%x, request=%s, first_keycode=%d, count=%d",
                   fghTypeToString( e->type ), e->window,
                   fghMappingRequestToString( e->request ), e->first_keycode,
                   e->count );
        break;
    }

    default: {
        fgWarning( "%s", fghTypeToString( event->type ) );
        break;
    }
    }
}
Ejemplo n.º 24
0
/*
 * The window procedure for handling Win32 events
 */
LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
                                       LPARAM lParam )
{
    static unsigned char lControl = 0, rControl = 0, lShift = 0,
                         rShift = 0, lAlt = 0, rAlt = 0;

    SFG_Window* window;
    PAINTSTRUCT ps;
    LRESULT lRet = 1;

    FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Event Handler" ) ;

    window = fgWindowByHandle( hWnd );

    if ( ( window == NULL ) && ( uMsg != WM_CREATE ) )
      return DefWindowProc( hWnd, uMsg, wParam, lParam );

    /* printf ( "Window %3d message <%04x> %12d %12d\n", window?window->ID:0,
             uMsg, wParam, lParam ); */

    if ( window )
    {
      /* Checking for CTRL, ALT, and SHIFT key positions:  Key Down! */
      if ( !lControl && GetAsyncKeyState ( VK_LCONTROL ) )
      {
          INVOKE_WCB	( *window, Special,
                        ( GLUT_KEY_CTRL_L, window->State.MouseX, window->State.MouseY )
                      );

          lControl = 1;
      }

      if ( !rControl && GetAsyncKeyState ( VK_RCONTROL ) )
      {
          INVOKE_WCB ( *window, Special,
                       ( GLUT_KEY_CTRL_R, window->State.MouseX, window->State.MouseY )
                     );

          rControl = 1;
      }

      if ( !lShift && GetAsyncKeyState ( VK_LSHIFT ) )
      {
          INVOKE_WCB ( *window, Special,
                       ( GLUT_KEY_SHIFT_L, window->State.MouseX, window->State.MouseY )
                     );

          lShift = 1;
      }

      if ( !rShift && GetAsyncKeyState ( VK_RSHIFT ) )
      {
          INVOKE_WCB ( *window, Special,
                       ( GLUT_KEY_SHIFT_R, window->State.MouseX, window->State.MouseY )
                     );

          rShift = 1;
      }

      if ( !lAlt && GetAsyncKeyState ( VK_LMENU ) )
      {
          INVOKE_WCB ( *window, Special,
                       ( GLUT_KEY_ALT_L, window->State.MouseX, window->State.MouseY )
                     );

          lAlt = 1;
      }

      if ( !rAlt && GetAsyncKeyState ( VK_RMENU ) )
      {
          INVOKE_WCB ( *window, Special,
                       ( GLUT_KEY_ALT_R, window->State.MouseX, window->State.MouseY )
                     );

          rAlt = 1;
      }

      /* Checking for CTRL, ALT, and SHIFT key positions:  Key Up! */
      if ( lControl && !GetAsyncKeyState ( VK_LCONTROL ) )
      {
          INVOKE_WCB ( *window, SpecialUp,
                       ( GLUT_KEY_CTRL_L, window->State.MouseX, window->State.MouseY )
                     );

          lControl = 0;
      }

      if ( rControl && !GetAsyncKeyState ( VK_RCONTROL ) )
      {
          INVOKE_WCB ( *window, SpecialUp,
                       ( GLUT_KEY_CTRL_R, window->State.MouseX, window->State.MouseY )
                     );

          rControl = 0;
      }

      if ( lShift && !GetAsyncKeyState ( VK_LSHIFT ) )
      {
          INVOKE_WCB ( *window, SpecialUp,
                       ( GLUT_KEY_SHIFT_L, window->State.MouseX, window->State.MouseY )
                     );

          lShift = 0;
      }

      if ( rShift && !GetAsyncKeyState ( VK_RSHIFT ) )
      {
          INVOKE_WCB ( *window, SpecialUp,
                       ( GLUT_KEY_SHIFT_R, window->State.MouseX, window->State.MouseY )
                     );

          rShift = 0;
      }

      if ( lAlt && !GetAsyncKeyState ( VK_LMENU ) )
      {
          INVOKE_WCB ( *window, SpecialUp,
                       ( GLUT_KEY_ALT_L, window->State.MouseX, window->State.MouseY )
                     );

          lAlt = 0;
      }

      if ( rAlt && !GetAsyncKeyState ( VK_RMENU ) )
      {
          INVOKE_WCB ( *window, SpecialUp,
                       ( GLUT_KEY_ALT_R, window->State.MouseX, window->State.MouseY )
                     );

          rAlt = 0;
      }
    }

    switch( uMsg )
    {
    case WM_CREATE:
        /* The window structure is passed as the creation structure parameter... */
        window = (SFG_Window *) (((LPCREATESTRUCT) lParam)->lpCreateParams);
        FREEGLUT_INTERNAL_ERROR_EXIT ( ( window != NULL ), "Cannot create window",
                                       "fgPlatformWindowProc" );

        window->Window.Handle = hWnd;
        window->Window.pContext.Device = GetDC( hWnd );
        if( window->IsMenu )
        {
            unsigned int current_DisplayMode = fgState.DisplayMode;
            fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH;
#if !defined(_WIN32_WCE)
            fgSetupPixelFormat( window, GL_FALSE, PFD_MAIN_PLANE );
#endif
            fgState.DisplayMode = current_DisplayMode;

            if( fgStructure.MenuContext )
                wglMakeCurrent( window->Window.pContext.Device,
                                fgStructure.MenuContext->MContext
                );
            else
            {
                fgStructure.MenuContext =
                    (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) );
                fgStructure.MenuContext->MContext =
                    wglCreateContext( window->Window.pContext.Device );
            }

            /* window->Window.Context = wglGetCurrentContext ();   */
            window->Window.Context = wglCreateContext( window->Window.pContext.Device );
        }
        else
        {
#if !defined(_WIN32_WCE)
            fgSetupPixelFormat( window, GL_FALSE, PFD_MAIN_PLANE );
#endif

            if( ! fgState.UseCurrentContext )
                window->Window.Context =
                    wglCreateContext( window->Window.pContext.Device );
            else
            {
                window->Window.Context = wglGetCurrentContext( );
                if( ! window->Window.Context )
                    window->Window.Context =
                        wglCreateContext( window->Window.pContext.Device );
            }

#if !defined(_WIN32_WCE)
            fgNewWGLCreateContext( window );
#endif
        }

        window->State.NeedToResize = GL_TRUE;
        /* if we used CW_USEDEFAULT (thats a negative value) for the size
         * of the window, query the window now for the size at which it
         * was created.
         */
        if( ( window->State.Width < 0 ) || ( window->State.Height < 0 ) )
        {
            SFG_Window *current_window = fgStructure.CurrentWindow;

            fgSetWindow( window );
            window->State.Width = glutGet( GLUT_WINDOW_WIDTH );
            window->State.Height = glutGet( GLUT_WINDOW_HEIGHT );
            fgSetWindow( current_window );
        }

        ReleaseDC( window->Window.Handle, window->Window.pContext.Device );

#if defined(_WIN32_WCE)
        /* Take over button handling */
        {
            HINSTANCE dxDllLib=LoadLibrary(_T("gx.dll"));
            if (dxDllLib)
            {
                GXGetDefaultKeys_=(GXGETDEFAULTKEYS)GetProcAddress(dxDllLib, _T("?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z"));
                GXOpenInput_=(GXOPENINPUT)GetProcAddress(dxDllLib, _T("?GXOpenInput@@YAHXZ"));
            }

            if(GXOpenInput_)
                (*GXOpenInput_)();
            if(GXGetDefaultKeys_)
                gxKeyList = (*GXGetDefaultKeys_)(GX_LANDSCAPEKEYS);
        }

#endif /* defined(_WIN32_WCE) */
        break;

    case WM_SIZE:
        /*
         * If the window is visible, then it is the user manually resizing it.
         * If it is not, then it is the system sending us a dummy resize with
         * zero dimensions on a "glutIconifyWindow" call.
         */
        if( window->State.Visible )
        {
            window->State.NeedToResize = GL_TRUE;
#if defined(_WIN32_WCE)
            window->State.Width  = HIWORD(lParam);
            window->State.Height = LOWORD(lParam);
#else
            window->State.Width  = LOWORD(lParam);
            window->State.Height = HIWORD(lParam);
#endif /* defined(_WIN32_WCE) */
        }

        break;

    case WM_SETFOCUS:
/*        printf("WM_SETFOCUS: %p\n", window ); */
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) );

		UpdateWindow ( hWnd );
        break;

    case WM_KILLFOCUS:
/*        printf("WM_KILLFOCUS: %p\n", window ); */
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) );

        if( window->IsMenu &&
            window->ActiveMenu && window->ActiveMenu->IsActive )
            fgUpdateMenuHighlight( window->ActiveMenu );

        break;

#if 0
    case WM_ACTIVATE:
        if (LOWORD(wParam) != WA_INACTIVE)
        {
/*            printf("WM_ACTIVATE: fgSetCursor( %p, %d)\n", window,
                   window->State.Cursor ); */
            fgSetCursor( window, window->State.Cursor );
        }

        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        break;
#endif

    case WM_SETCURSOR:
/*      printf ( "Cursor event %x %x %x %x\n", window, window->State.Cursor, lParam, wParam ) ; */
        if( LOWORD( lParam ) == HTCLIENT )
            fgSetCursor ( window, window->State.Cursor ) ;
        else
            lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        break;

    case WM_SHOWWINDOW:
        window->State.Visible = GL_TRUE;
        window->State.Redisplay = GL_TRUE;
        break;

    case WM_PAINT:
        /* Turn on the visibility in case it was turned off somehow */
        window->State.Visible = GL_TRUE;
        BeginPaint( hWnd, &ps );
        fghRedrawWindow( window );
        EndPaint( hWnd, &ps );
        break;

    case WM_CLOSE:
        fgDestroyWindow ( window );
        if ( fgState.ActionOnWindowClose != GLUT_ACTION_CONTINUE_EXECUTION )
            PostQuitMessage(0);
        break;

    case WM_DESTROY:
        /*
         * The window already got destroyed, so don't bother with it.
         */
        return 0;

    case WM_MOUSEMOVE:
    {
#if defined(_WIN32_WCE)
        window->State.MouseX = 320-HIWORD( lParam );
        window->State.MouseY = LOWORD( lParam );
#else
        window->State.MouseX = LOWORD( lParam );
        window->State.MouseY = HIWORD( lParam );
#endif /* defined(_WIN32_WCE) */
        /* Restrict to [-32768, 32767] to match X11 behaviour       */
        /* See comment in "freeglut_developer" mailing list 10/4/04 */
        if ( window->State.MouseX > 32767 ) window->State.MouseX -= 65536;
        if ( window->State.MouseY > 32767 ) window->State.MouseY -= 65536;

        if ( window->ActiveMenu )
        {
            fgUpdateMenuHighlight( window->ActiveMenu );
            break;
        }
        SetFocus(window->Window.Handle);

        fgState.Modifiers = fgPlatformGetModifiers( );

        if( ( wParam & MK_LBUTTON ) ||
            ( wParam & MK_MBUTTON ) ||
            ( wParam & MK_RBUTTON ) )
            INVOKE_WCB( *window, Motion, ( window->State.MouseX,
                                           window->State.MouseY ) );
        else
            INVOKE_WCB( *window, Passive, ( window->State.MouseX,
                                            window->State.MouseY ) );

        fgState.Modifiers = INVALID_MODIFIERS;
    }
    break;

    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
    {
        GLboolean pressed = GL_TRUE;
        int button;

#if defined(_WIN32_WCE)
        window->State.MouseX = 320-HIWORD( lParam );
        window->State.MouseY = LOWORD( lParam );
#else
        window->State.MouseX = LOWORD( lParam );
        window->State.MouseY = HIWORD( lParam );
#endif /* defined(_WIN32_WCE) */

        /* Restrict to [-32768, 32767] to match X11 behaviour       */
        /* See comment in "freeglut_developer" mailing list 10/4/04 */
        if ( window->State.MouseX > 32767 ) window->State.MouseX -= 65536;
        if ( window->State.MouseY > 32767 ) window->State.MouseY -= 65536;

        switch( uMsg )
        {
        case WM_LBUTTONDOWN:
            pressed = GL_TRUE;
            button = GLUT_LEFT_BUTTON;
            break;
        case WM_MBUTTONDOWN:
            pressed = GL_TRUE;
            button = GLUT_MIDDLE_BUTTON;
            break;
        case WM_RBUTTONDOWN:
            pressed = GL_TRUE;
            button = GLUT_RIGHT_BUTTON;
            break;
        case WM_LBUTTONUP:
            pressed = GL_FALSE;
            button = GLUT_LEFT_BUTTON;
            break;
        case WM_MBUTTONUP:
            pressed = GL_FALSE;
            button = GLUT_MIDDLE_BUTTON;
            break;
        case WM_RBUTTONUP:
            pressed = GL_FALSE;
            button = GLUT_RIGHT_BUTTON;
            break;
        default:
            pressed = GL_FALSE;
            button = -1;
            break;
        }

#if !defined(_WIN32_WCE)
        if( GetSystemMetrics( SM_SWAPBUTTON ) )
        {
            if( button == GLUT_LEFT_BUTTON )
                button = GLUT_RIGHT_BUTTON;
            else
                if( button == GLUT_RIGHT_BUTTON )
                    button = GLUT_LEFT_BUTTON;
        }
#endif /* !defined(_WIN32_WCE) */

        if( button == -1 )
            return DefWindowProc( hWnd, uMsg, lParam, wParam );

        /*
         * Do not execute the application's mouse callback if a menu
         * is hooked to this button.  In that case an appropriate
         * private call should be generated.
         */
        if( fgCheckActiveMenu( window, button, pressed,
                               window->State.MouseX, window->State.MouseY ) )
            break;

        /* Set capture so that the window captures all the mouse messages */
        /*
         * XXX - Multiple button support:  Under X11, the mouse is not released
         * XXX - from the window until all buttons have been released, even if the
         * XXX - user presses a button in another window.  This will take more
         * XXX - code changes than I am up to at the moment (10/5/04).  The present
         * XXX - is a 90 percent solution.
         */
        if ( pressed == GL_TRUE )
          SetCapture ( window->Window.Handle ) ;
        else
          ReleaseCapture () ;

        if( ! FETCH_WCB( *window, Mouse ) )
            break;

        fgSetWindow( window );
        fgState.Modifiers = fgPlatformGetModifiers( );

        INVOKE_WCB(
            *window, Mouse,
            ( button,
              pressed ? GLUT_DOWN : GLUT_UP,
              window->State.MouseX,
              window->State.MouseY
            )
        );

        fgState.Modifiers = INVALID_MODIFIERS;
    }
    break;

    case 0x020a:
        /* Should be WM_MOUSEWHEEL but my compiler doesn't recognize it */
    {
        int wheel_number = LOWORD( wParam );
        short ticks = ( short )HIWORD( wParam );
		fgState.MouseWheelTicks += ticks;

        /*
         * XXX Should use WHEEL_DELTA instead of 120
         */
		if ( abs ( fgState.MouseWheelTicks ) > 120 )
		{
			int direction = ( fgState.MouseWheelTicks > 0 ) ? 1 : -1;

            if( ! FETCH_WCB( *window, MouseWheel ) &&
                ! FETCH_WCB( *window, Mouse ) )
                break;

            fgSetWindow( window );
            fgState.Modifiers = fgPlatformGetModifiers( );

            /*
             * XXX Should use WHEEL_DELTA instead of 120
             */
            while( abs ( fgState.MouseWheelTicks ) > 120 )
			{
                if( FETCH_WCB( *window, MouseWheel ) )
                    INVOKE_WCB( *window, MouseWheel,
                                ( wheel_number,
                                  direction,
                                  window->State.MouseX,
                                  window->State.MouseY
                                )
                    );
                else  /* No mouse wheel, call the mouse button callback twice */
				{
                    /*
                     * Map wheel zero to button 3 and 4; +1 to 3, -1 to 4
                     *  "    "   one                     +1 to 5, -1 to 6, ...
                     *
                     * XXX The below assumes that you have no more than 3 mouse
                     * XXX buttons.  Sorry.
                     */
                    int button = wheel_number * 2 + 3;
                    if( direction < 0 )
                        ++button;
                    INVOKE_WCB( *window, Mouse,
                                ( button, GLUT_DOWN,
                                  window->State.MouseX, window->State.MouseY )
                    );
                    INVOKE_WCB( *window, Mouse,
                                ( button, GLUT_UP,
                                  window->State.MouseX, window->State.MouseY )
                    );
				}

                /*
                 * XXX Should use WHEEL_DELTA instead of 120
                 */
				fgState.MouseWheelTicks -= 120 * direction;
			}

            fgState.Modifiers = INVALID_MODIFIERS;
		}
    }
    break ;

    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
    {
        int keypress = -1;
        POINT mouse_pos ;

        if( ( fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE ) && (HIWORD(lParam) & KF_REPEAT) )
            break;

        /*
         * Remember the current modifiers state. This is done here in order
         * to make sure the VK_DELETE keyboard callback is executed properly.
         */
        fgState.Modifiers = fgPlatformGetModifiers( );

        GetCursorPos( &mouse_pos );
        ScreenToClient( window->Window.Handle, &mouse_pos );

        window->State.MouseX = mouse_pos.x;
        window->State.MouseY = mouse_pos.y;

        /* Convert the Win32 keystroke codes to GLUTtish way */
#       define KEY(a,b) case a: keypress = b; break;

        switch( wParam )
        {
            KEY( VK_F1,     GLUT_KEY_F1        );
            KEY( VK_F2,     GLUT_KEY_F2        );
            KEY( VK_F3,     GLUT_KEY_F3        );
            KEY( VK_F4,     GLUT_KEY_F4        );
            KEY( VK_F5,     GLUT_KEY_F5        );
            KEY( VK_F6,     GLUT_KEY_F6        );
            KEY( VK_F7,     GLUT_KEY_F7        );
            KEY( VK_F8,     GLUT_KEY_F8        );
            KEY( VK_F9,     GLUT_KEY_F9        );
            KEY( VK_F10,    GLUT_KEY_F10       );
            KEY( VK_F11,    GLUT_KEY_F11       );
            KEY( VK_F12,    GLUT_KEY_F12       );
            KEY( VK_PRIOR,  GLUT_KEY_PAGE_UP   );
            KEY( VK_NEXT,   GLUT_KEY_PAGE_DOWN );
            KEY( VK_HOME,   GLUT_KEY_HOME      );
            KEY( VK_END,    GLUT_KEY_END       );
            KEY( VK_LEFT,   GLUT_KEY_LEFT      );
            KEY( VK_UP,     GLUT_KEY_UP        );
            KEY( VK_RIGHT,  GLUT_KEY_RIGHT     );
            KEY( VK_DOWN,   GLUT_KEY_DOWN      );
            KEY( VK_INSERT, GLUT_KEY_INSERT    );
            KEY( VK_LCONTROL, GLUT_KEY_CTRL_L  );
            KEY( VK_RCONTROL, GLUT_KEY_CTRL_R  );
            KEY( VK_LSHIFT, GLUT_KEY_SHIFT_L   );
            KEY( VK_RSHIFT, GLUT_KEY_SHIFT_R   );
            KEY( VK_LMENU,  GLUT_KEY_ALT_L     );
            KEY( VK_RMENU,  GLUT_KEY_ALT_R     );

        case VK_DELETE:
            /* The delete key should be treated as an ASCII keypress: */
            INVOKE_WCB( *window, Keyboard,
                        ( 127, window->State.MouseX, window->State.MouseY )
            );
        }

#if defined(_WIN32_WCE)
        if(!(lParam & 0x40000000)) /* Prevent auto-repeat */
        {
            if(wParam==(unsigned)gxKeyList.vkRight)
                keypress = GLUT_KEY_RIGHT;
            else if(wParam==(unsigned)gxKeyList.vkLeft)
                keypress = GLUT_KEY_LEFT;
            else if(wParam==(unsigned)gxKeyList.vkUp)
                keypress = GLUT_KEY_UP;
            else if(wParam==(unsigned)gxKeyList.vkDown)
                keypress = GLUT_KEY_DOWN;
            else if(wParam==(unsigned)gxKeyList.vkA)
                keypress = GLUT_KEY_F1;
            else if(wParam==(unsigned)gxKeyList.vkB)
                keypress = GLUT_KEY_F2;
            else if(wParam==(unsigned)gxKeyList.vkC)
                keypress = GLUT_KEY_F3;
            else if(wParam==(unsigned)gxKeyList.vkStart)
                keypress = GLUT_KEY_F4;
        }
#endif

        if( keypress != -1 )
            INVOKE_WCB( *window, Special,
                        ( keypress,
                          window->State.MouseX, window->State.MouseY )
            );

        fgState.Modifiers = INVALID_MODIFIERS;
    }
    break;

    case WM_SYSKEYUP:
    case WM_KEYUP:
    {
        int keypress = -1;
        POINT mouse_pos;

        /*
         * Remember the current modifiers state. This is done here in order
         * to make sure the VK_DELETE keyboard callback is executed properly.
         */
        fgState.Modifiers = fgPlatformGetModifiers( );

        GetCursorPos( &mouse_pos );
        ScreenToClient( window->Window.Handle, &mouse_pos );

        window->State.MouseX = mouse_pos.x;
        window->State.MouseY = mouse_pos.y;

        /*
         * Convert the Win32 keystroke codes to GLUTtish way.
         * "KEY(a,b)" was defined under "WM_KEYDOWN"
         */

        switch( wParam )
        {
            KEY( VK_F1,     GLUT_KEY_F1        );
            KEY( VK_F2,     GLUT_KEY_F2        );
            KEY( VK_F3,     GLUT_KEY_F3        );
            KEY( VK_F4,     GLUT_KEY_F4        );
            KEY( VK_F5,     GLUT_KEY_F5        );
            KEY( VK_F6,     GLUT_KEY_F6        );
            KEY( VK_F7,     GLUT_KEY_F7        );
            KEY( VK_F8,     GLUT_KEY_F8        );
            KEY( VK_F9,     GLUT_KEY_F9        );
            KEY( VK_F10,    GLUT_KEY_F10       );
            KEY( VK_F11,    GLUT_KEY_F11       );
            KEY( VK_F12,    GLUT_KEY_F12       );
            KEY( VK_PRIOR,  GLUT_KEY_PAGE_UP   );
            KEY( VK_NEXT,   GLUT_KEY_PAGE_DOWN );
            KEY( VK_HOME,   GLUT_KEY_HOME      );
            KEY( VK_END,    GLUT_KEY_END       );
            KEY( VK_LEFT,   GLUT_KEY_LEFT      );
            KEY( VK_UP,     GLUT_KEY_UP        );
            KEY( VK_RIGHT,  GLUT_KEY_RIGHT     );
            KEY( VK_DOWN,   GLUT_KEY_DOWN      );
            KEY( VK_INSERT, GLUT_KEY_INSERT    );
            KEY( VK_LCONTROL, GLUT_KEY_CTRL_L  );
            KEY( VK_RCONTROL, GLUT_KEY_CTRL_R  );
            KEY( VK_LSHIFT, GLUT_KEY_SHIFT_L   );
            KEY( VK_RSHIFT, GLUT_KEY_SHIFT_R   );
            KEY( VK_LMENU,  GLUT_KEY_ALT_L     );
            KEY( VK_RMENU,  GLUT_KEY_ALT_R     );

          case VK_DELETE:
              /* The delete key should be treated as an ASCII keypress: */
              INVOKE_WCB( *window, KeyboardUp,
                          ( 127, window->State.MouseX, window->State.MouseY )
              );
              break;

        default:
        {
#if !defined(_WIN32_WCE)
            BYTE state[ 256 ];
            WORD code[ 2 ];

            GetKeyboardState( state );

            if( ToAscii( (UINT)wParam, 0, state, code, 0 ) == 1 )
                wParam=code[ 0 ];

            INVOKE_WCB( *window, KeyboardUp,
                        ( (char)wParam,
                          window->State.MouseX, window->State.MouseY )
            );
#endif /* !defined(_WIN32_WCE) */
        }
        }

        if( keypress != -1 )
            INVOKE_WCB( *window, SpecialUp,
                        ( keypress,
                          window->State.MouseX, window->State.MouseY )
            );

        fgState.Modifiers = INVALID_MODIFIERS;
    }
    break;

    case WM_SYSCHAR:
    case WM_CHAR:
    {
      if( (fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE) && (HIWORD(lParam) & KF_REPEAT) )
            break;

        fgState.Modifiers = fgPlatformGetModifiers( );
        INVOKE_WCB( *window, Keyboard,
                    ( (char)wParam,
                      window->State.MouseX, window->State.MouseY )
        );
        fgState.Modifiers = INVALID_MODIFIERS;
    }
    break;

    case WM_CAPTURECHANGED:
        /* User has finished resizing the window, force a redraw */
        INVOKE_WCB( *window, Display, ( ) );

        /*lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); */
        break;

        /* Other messages that I have seen and which are not handled already */
    case WM_SETTEXT:  /* 0x000c */
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        /* Pass it on to "DefWindowProc" to set the window text */
        break;

    case WM_GETTEXT:  /* 0x000d */
        /* Ideally we would copy the title of the window into "lParam" */
        /* strncpy ( (char *)lParam, "Window Title", wParam );
           lRet = ( wParam > 12 ) ? 12 : wParam;  */
        /* the number of characters copied */
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        break;

    case WM_GETTEXTLENGTH:  /* 0x000e */
        /* Ideally we would get the length of the title of the window */
        lRet = 12;
        /* the number of characters in "Window Title\0" (see above) */
        break;

    case WM_ERASEBKGND:  /* 0x0014 */
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        break;

#if !defined(_WIN32_WCE)
    case WM_SYNCPAINT:  /* 0x0088 */
        /* Another window has moved, need to update this one */
        window->State.Redisplay = GL_TRUE;
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        /* Help screen says this message must be passed to "DefWindowProc" */
        break;

    case WM_NCPAINT:  /* 0x0085 */
      /* Need to update the border of this window */
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        /* Pass it on to "DefWindowProc" to repaint a standard border */
        break;

    case WM_SYSCOMMAND :  /* 0x0112 */
        {
          /*
           * We have received a system command message.  Try to act on it.
           * The commands are passed in through the "wParam" parameter:
           * The least significant digit seems to be which edge of the window
           * is being used for a resize event:
           *     4  3  5
           *     1     2
           *     7  6  8
           * Congratulations and thanks to Richard Rauch for figuring this out..
           */
            switch ( wParam & 0xfff0 )
            {
            case SC_SIZE       :
                break ;

            case SC_MOVE       :
                break ;

            case SC_MINIMIZE   :
                /* User has clicked on the "-" to minimize the window */
                /* Turn off the visibility */
                window->State.Visible = GL_FALSE ;

                break ;

            case SC_MAXIMIZE   :
                break ;

            case SC_NEXTWINDOW :
                break ;

            case SC_PREVWINDOW :
                break ;

            case SC_CLOSE      :
                /* Followed very closely by a WM_CLOSE message */
                break ;

            case SC_VSCROLL    :
                break ;

            case SC_HSCROLL    :
                break ;

            case SC_MOUSEMENU  :
                break ;

            case SC_KEYMENU    :
                break ;

            case SC_ARRANGE    :
                break ;

            case SC_RESTORE    :
                break ;

            case SC_TASKLIST   :
                break ;

            case SC_SCREENSAVE :
                break ;

            case SC_HOTKEY     :
                break ;

#if(WINVER >= 0x0400)
            case SC_DEFAULT    :
                break ;

            case SC_MONITORPOWER    :
                break ;

            case SC_CONTEXTHELP    :
                break ;
#endif /* WINVER >= 0x0400 */

            default:
#if _DEBUG
                fgWarning( "Unknown wParam type 0x%x", wParam );
#endif
                break;
            }
        }
#endif /* !defined(_WIN32_WCE) */

        /* We need to pass the message on to the operating system as well */
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        break;

#ifdef WM_TOUCH
	/* handle multi-touch messages */
	case WM_TOUCH:
	{
		unsigned int numInputs = (unsigned int)wParam;
		unsigned int i = 0;
		TOUCHINPUT* ti = (TOUCHINPUT*)malloc( sizeof(TOUCHINPUT)*numInputs);

		if (fghGetTouchInputInfo == (pGetTouchInputInfo)0xDEADBEEF) {
		    fghGetTouchInputInfo = (pGetTouchInputInfo)GetProcAddress(GetModuleHandle("user32"),"GetTouchInputInfo");
		    fghCloseTouchInputHandle = (pCloseTouchInputHandle)GetProcAddress(GetModuleHandle("user32"),"CloseTouchInputHandle");
		}

		if (!fghGetTouchInputInfo) { 
			free( (void*)ti );
			break;
		}

		if (fghGetTouchInputInfo( (HTOUCHINPUT)lParam, numInputs, ti, sizeof(TOUCHINPUT) )) {
			/* Handle each contact point */
			for (i = 0; i < numInputs; ++i ) {

				POINT tp;
				tp.x = TOUCH_COORD_TO_PIXEL(ti[i].x);
				tp.y = TOUCH_COORD_TO_PIXEL(ti[i].y);
				ScreenToClient( hWnd, &tp );

				ti[i].dwID = ti[i].dwID * 2;

				if (ti[i].dwFlags & TOUCHEVENTF_DOWN) {
					INVOKE_WCB( *window, MultiEntry,  ( ti[i].dwID, GLUT_ENTERED ) );
					INVOKE_WCB( *window, MultiButton, ( ti[i].dwID, tp.x, tp.y, 0, GLUT_DOWN ) );
				} else if (ti[i].dwFlags & TOUCHEVENTF_MOVE) {
					INVOKE_WCB( *window, MultiMotion, ( ti[i].dwID, tp.x, tp.y ) );
				} else if (ti[i].dwFlags & TOUCHEVENTF_UP)   { 
					INVOKE_WCB( *window, MultiButton, ( ti[i].dwID, tp.x, tp.y, 0, GLUT_UP ) );
					INVOKE_WCB( *window, MultiEntry,  ( ti[i].dwID, GLUT_LEFT ) );
				}
			}
		}
		fghCloseTouchInputHandle((HTOUCHINPUT)lParam);
		free( (void*)ti );
		lRet = 0; /*DefWindowProc( hWnd, uMsg, wParam, lParam );*/
		break;
	}
#endif
    default:
        /* Handle unhandled messages */
        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
        break;
    }

    return lRet;
}
Ejemplo n.º 25
0
/*
 * This is only used if the user calls:
 * glutDeviceGet(GLUT_HAS_DIAL_AND_BUTTON_BOX)
 * and has old hardware called 'dials&buttons box'.
 * http://www.reputable.com/sgipix/sgi-dialnbutton1.jpg
 * 
 * Not implemented on Android :)
 * http://sourceforge.net/mailarchive/message.php?msg_id=29209505
 */
void fgPlatformRegisterDialDevice ( const char *dial_device ) {
    fgWarning("GLUT_HAS_DIAL_AND_BUTTON_BOX: not implemented");
}
Ejemplo n.º 26
0
/*
 * Opens a window. Requires a SFG_Window object created and attached
 * to the freeglut structure. OpenGL context is created here.
 */
void fgOpenWindow( SFG_Window* window, const char* title,
                   int x, int y, int w, int h,
                   GLboolean gameMode, GLboolean isSubWindow )
{
#if TARGET_HOST_UNIX_X11
    XSetWindowAttributes winAttr;
    XTextProperty textProperty;
    XSizeHints sizeHints;
    XWMHints wmHints;
    unsigned long mask;
    unsigned int current_DisplayMode = fgState.DisplayMode ;

    /* Save the display mode if we are creating a menu window */
    if( window->IsMenu && ( ! fgStructure.MenuContext ) )
        fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ;

    window->Window.VisualInfo = fgChooseVisual( );

    if( window->IsMenu && ( ! fgStructure.MenuContext ) )
        fgState.DisplayMode = current_DisplayMode ;

    if( ! window->Window.VisualInfo )
    {
        /*
         * The "fgChooseVisual" returned a null meaning that the visual
         * context is not available.
         * Try a couple of variations to see if they will work.
         */
        if( !( fgState.DisplayMode & GLUT_DOUBLE ) )
        {
            fgState.DisplayMode |= GLUT_DOUBLE ;
            window->Window.VisualInfo = fgChooseVisual( );
            fgState.DisplayMode &= ~GLUT_DOUBLE;
        }

        /*
         * GLUT also checks for multi-sampling, but I don't see that
         * anywhere else in FREEGLUT so I won't bother with it for the moment.
         */
    }

    FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.VisualInfo != NULL,
                                  "Visual with necessary capabilities not found", "fgOpenWindow" );

    /*
     * XXX HINT: the masks should be updated when adding/removing callbacks.
     * XXX       This might speed up message processing. Is that true?
     * XXX
     * XXX A: Not appreciably, but it WILL make it easier to debug.
     * XXX    Try tracing old GLUT and try tracing freeglut.  Old GLUT
     * XXX    turns off events that it doesn't need and is a whole lot
     * XXX    more pleasant to trace.  (Think mouse-motion!  Tons of
     * XXX    ``bonus'' GUI events stream in.)
     */
    winAttr.event_mask        =
        StructureNotifyMask | SubstructureNotifyMask | ExposureMask |
        ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask |
        VisibilityChangeMask | EnterWindowMask | LeaveWindowMask |
        PointerMotionMask | ButtonMotionMask;
    winAttr.background_pixmap = None;
    winAttr.background_pixel  = 0;
    winAttr.border_pixel      = 0;

    winAttr.colormap = XCreateColormap(
        fgDisplay.Display, fgDisplay.RootWindow,
        window->Window.VisualInfo->visual, AllocNone
    );

    mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;

    if( window->IsMenu || ( gameMode == GL_TRUE ) )
    {
        winAttr.override_redirect = True;
        mask |= CWOverrideRedirect;
    }

    window->Window.Handle = XCreateWindow(
        fgDisplay.Display,
        window->Parent == NULL ? fgDisplay.RootWindow :
        window->Parent->Window.Handle,
        x, y, w, h, 0,
        window->Window.VisualInfo->depth, InputOutput,
        window->Window.VisualInfo->visual, mask,
        &winAttr
    );

    /*
     * The GLX context creation, possibly trying the direct context rendering
     *  or else use the current context if the user has so specified
     */
    if( window->IsMenu )
    {
        /*
         * If there isn't already an OpenGL rendering context for menu
         * windows, make one
         */
        if( !fgStructure.MenuContext )
        {
            fgStructure.MenuContext =
                (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) );
            fgStructure.MenuContext->VisualInfo = window->Window.VisualInfo;
            fgStructure.MenuContext->Context = glXCreateContext(
                fgDisplay.Display, fgStructure.MenuContext->VisualInfo,
                NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
            );
        }

        /* window->Window.Context = fgStructure.MenuContext->Context; */
        window->Window.Context = glXCreateContext(
            fgDisplay.Display, window->Window.VisualInfo,
            NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
        );
    }
    else if( fgState.UseCurrentContext )
    {
        window->Window.Context = glXGetCurrentContext( );

        if( ! window->Window.Context )
            window->Window.Context = glXCreateContext(
                fgDisplay.Display, window->Window.VisualInfo,
                NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
            );
    }
    else
        window->Window.Context = glXCreateContext(
            fgDisplay.Display, window->Window.VisualInfo,
            NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
        );

#if !defined( __FreeBSD__ ) && !defined( __NetBSD__ )
    if(  !glXIsDirect( fgDisplay.Display, window->Window.Context ) )
    {
      if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT )
        fgError( "Unable to force direct context rendering for window '%s'",
                 title );
      else if( fgState.DirectContext == GLUT_TRY_DIRECT_CONTEXT )
        fgWarning( "Unable to create direct context rendering for window '%s'\nThis may hurt performance.",
                 title );
    }
#endif

    /*
     * XXX Assume the new window is visible by default
     * XXX Is this a  safe assumption?
     */
    window->State.Visible = GL_TRUE;

    sizeHints.flags = 0;
    if ( fgState.Position.Use )
        sizeHints.flags |= USPosition;
    if ( fgState.Size.Use )
        sizeHints.flags |= USSize;

    /*
     * Fill in the size hints values now (the x, y, width and height
     * settings are obsolete, are there any more WMs that support them?)
     * Unless the X servers actually stop supporting these, we should
     * continue to fill them in.  It is *not* our place to tell the user
     * that they should replace a window manager that they like, and which
     * works, just because *we* think that it's not "modern" enough.
     */
    sizeHints.x      = x;
    sizeHints.y      = y;
    sizeHints.width  = w;
    sizeHints.height = h;

    wmHints.flags = StateHint;
    wmHints.initial_state = fgState.ForceIconic ? IconicState : NormalState;
    /* Prepare the window and iconified window names... */
    XStringListToTextProperty( (char **) &title, 1, &textProperty );

    XSetWMProperties(
        fgDisplay.Display,
        window->Window.Handle,
        &textProperty,
        &textProperty,
        0,
        0,
        &sizeHints,
        &wmHints,
        NULL
    );
    XFree( textProperty.value );

    XSetWMProtocols( fgDisplay.Display, window->Window.Handle,
                     &fgDisplay.DeleteWindow, 1 );

    glXMakeCurrent(
        fgDisplay.Display,
        window->Window.Handle,
        window->Window.Context
    );

    XMapWindow( fgDisplay.Display, window->Window.Handle );

#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE

    WNDCLASS wc;
    DWORD flags;
    DWORD exFlags = 0;
    ATOM atom;

    /* Grab the window class we have registered on glutInit(): */
    atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc );
    FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Info Not Found",
                                   "fgOpenWindow" );

    if( gameMode )
    {
        FREEGLUT_INTERNAL_ERROR_EXIT ( window->Parent == NULL,
                                       "Game mode being invoked on a subwindow",
                                       "fgOpenWindow" );

        /*
         * Set the window creation flags appropriately to make the window
         * entirely visible:
         */
        flags = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
    }
    else
    {
#if !TARGET_HOST_WINCE
        if ( ( ! isSubWindow ) && ( ! window->IsMenu ) )
        {
            /*
             * Update the window dimensions, taking account of window
             * decorations.  "freeglut" is to create the window with the
             * outside of its border at (x,y) and with dimensions (w,h).
             */
            w += (GetSystemMetrics( SM_CXSIZEFRAME ) )*2;
            h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 +
                GetSystemMetrics( SM_CYCAPTION );
        }
#endif /* TARGET_HOST_WINCE */

        if( ! fgState.Position.Use )
        {
            x = CW_USEDEFAULT;
            y = CW_USEDEFAULT;
        }
        if( ! fgState.Size.Use )
        {
            w = CW_USEDEFAULT;
            h = CW_USEDEFAULT;
        }

        /*
         * There's a small difference between creating the top, child and
         * game mode windows
         */
        flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;

        if ( window->IsMenu )
        {
            flags |= WS_POPUP;
            exFlags |= WS_EX_TOOLWINDOW;
        }
#if !TARGET_HOST_WINCE
        else if( window->Parent == NULL )
            flags |= WS_OVERLAPPEDWINDOW;
#endif
        else
            flags |= WS_CHILD;
    }

#if TARGET_HOST_WINCE
    {
        wchar_t* wstr = fghWstrFromStr(title);

        window->Window.Handle = CreateWindow(
            _T("FREEGLUT"),
            wstr,
            WS_VISIBLE | WS_POPUP,
            0,0, 240,320,
            NULL,
            NULL,
            fgDisplay.Instance,
            (LPVOID) window
        );

        free(wstr);

        SHFullScreen(window->Window.Handle, SHFS_HIDESTARTICON);
        SHFullScreen(window->Window.Handle, SHFS_HIDESIPBUTTON);
        SHFullScreen(window->Window.Handle, SHFS_HIDETASKBAR);
        MoveWindow(window->Window.Handle, 0, 0, 240, 320, TRUE);
        ShowWindow(window->Window.Handle, SW_SHOW);
        UpdateWindow(window->Window.Handle);
    }
#else
    window->Window.Handle = CreateWindowExA(
        exFlags,
        "FREEGLUT",
        title,
        flags,
        x, y, w, h,
        (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle,
        (HMENU) NULL,
        fgDisplay.Instance,
        (LPVOID) window
    );
#endif /* TARGET_HOST_WINCE */

    if( !( window->Window.Handle ) )
        fgError( "Failed to create a window (%s)!", title );

#if TARGET_HOST_WINCE
    ShowWindow( window->Window.Handle, SW_SHOW );
#else
    ShowWindow( window->Window.Handle,
                fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW );
#endif /* TARGET_HOST_WINCE */

    UpdateWindow( window->Window.Handle );
    ShowCursor( TRUE );  /* XXX Old comments say "hide cursor"! */

#endif

    fgSetWindow( window );

    window->Window.DoubleBuffered =
        ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0;

    if ( ! window->Window.DoubleBuffered )
    {
        glDrawBuffer ( GL_FRONT );
        glReadBuffer ( GL_FRONT );
    }
}
Ejemplo n.º 27
0
/*
 * A call to this function should initialize all the display stuff...
 */
static void fghInitialize( const char* displayName )
{
#if TARGET_HOST_POSIX_X11
    fgDisplay.Display = XOpenDisplay( displayName );

    if( fgDisplay.Display == NULL )
        fgError( "failed to open display '%s'", XDisplayName( displayName ) );

    if( !glXQueryExtension( fgDisplay.Display, NULL, NULL ) )
        fgError( "OpenGL GLX extension not supported by display '%s'",
            XDisplayName( displayName ) );

    fgDisplay.Screen = DefaultScreen( fgDisplay.Display );
    fgDisplay.RootWindow = RootWindow(
        fgDisplay.Display,
        fgDisplay.Screen
    );

    fgDisplay.ScreenWidth  = DisplayWidth(
        fgDisplay.Display,
        fgDisplay.Screen
    );
    fgDisplay.ScreenHeight = DisplayHeight(
        fgDisplay.Display,
        fgDisplay.Screen
    );

    fgDisplay.ScreenWidthMM = DisplayWidthMM(
        fgDisplay.Display,
        fgDisplay.Screen
    );
    fgDisplay.ScreenHeightMM = DisplayHeightMM(
        fgDisplay.Display,
        fgDisplay.Screen
    );

    fgDisplay.Connection = ConnectionNumber( fgDisplay.Display );

    /* Create the window deletion atom */
    fgDisplay.DeleteWindow = fghGetAtom("WM_DELETE_WINDOW");

    /* Create the state and full screen atoms */
    fgDisplay.State           = None;
    fgDisplay.StateFullScreen = None;

    if (fghNetWMSupported())
    {
      const Atom supported = fghGetAtom("_NET_SUPPORTED");
      const Atom state     = fghGetAtom("_NET_WM_STATE");
      
      /* Check if the state hint is supported. */
      if (fgHintPresent(fgDisplay.RootWindow, supported, state))
      {
        const Atom full_screen = fghGetAtom("_NET_WM_STATE_FULLSCREEN");
        
        fgDisplay.State = state;
        
        /* Check if the window manager supports full screen. */
        /**  Check "_NET_WM_ALLOWED_ACTIONS" on our window instead? **/
        if (fgHintPresent(fgDisplay.RootWindow, supported, full_screen))
        {
          fgDisplay.StateFullScreen = full_screen;
        }
      }
    }

#elif TARGET_HOST_MS_WINDOWS

    WNDCLASS wc;
    ATOM atom;

    /* What we need to do is to initialize the fgDisplay global structure here. */
    fgDisplay.Instance = GetModuleHandle( NULL );
    fgDisplay.DisplayName= displayName ? strdup(displayName) : 0 ;
    atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc );

    if( atom == 0 )
    {
        ZeroMemory( &wc, sizeof(WNDCLASS) );

        /*
         * Each of the windows should have its own device context, and we
         * want redraw events during Vertical and Horizontal Resizes by
         * the user.
         *
         * XXX Old code had "| CS_DBCLCKS" commented out.  Plans for the
         * XXX future?  Dead-end idea?
         */
        wc.lpfnWndProc    = fgWindowProc;
        wc.cbClsExtra     = 0;
        wc.cbWndExtra     = 0;
        wc.hInstance      = fgDisplay.Instance;
        wc.hIcon          = LoadIcon( fgDisplay.Instance, _T("GLUT_ICON") );

#if defined(_WIN32_WCE)
        wc.style          = CS_HREDRAW | CS_VREDRAW;
#else
        wc.style          = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
        if (!wc.hIcon)
          wc.hIcon        = LoadIcon( NULL, IDI_WINLOGO );
#endif

        wc.hCursor        = LoadCursor( NULL, IDC_ARROW );
        wc.hbrBackground  = NULL;
        wc.lpszMenuName   = NULL;
        wc.lpszClassName  = _T("FREEGLUT");

        /* Register the window class */
        atom = RegisterClass( &wc );
        FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Not Registered", "fghInitialize" );
    }

    /* The screen dimensions can be obtained via GetSystemMetrics() calls */
    fgDisplay.ScreenWidth  = GetSystemMetrics( SM_CXSCREEN );
    fgDisplay.ScreenHeight = GetSystemMetrics( SM_CYSCREEN );

    {
        HWND desktop = GetDesktopWindow( );
        HDC  context = GetDC( desktop );

        fgDisplay.ScreenWidthMM  = GetDeviceCaps( context, HORZSIZE );
        fgDisplay.ScreenHeightMM = GetDeviceCaps( context, VERTSIZE );

        ReleaseDC( desktop, context );
    }
    /* If we have a DisplayName try to use it for metrics */
    if( fgDisplay.DisplayName )
    {
        HDC context = CreateDC(fgDisplay.DisplayName,0,0,0);
        if( context )
        {
	    fgDisplay.ScreenWidth  = GetDeviceCaps( context, HORZRES );
	    fgDisplay.ScreenHeight = GetDeviceCaps( context, VERTRES );
	    fgDisplay.ScreenWidthMM  = GetDeviceCaps( context, HORZSIZE );
	    fgDisplay.ScreenHeightMM = GetDeviceCaps( context, VERTSIZE );
	    DeleteDC(context);
        }
        else
	    fgWarning("fghInitialize: "
		      "CreateDC failed, Screen size info may be incorrect\n"
          "This is quite likely caused by a bad '-display' parameter");
      
    }
    /* Set the timer granularity to 1 ms */
    timeBeginPeriod ( 1 );

#endif

    fgState.Initialised = GL_TRUE;

    /* Avoid registering atexit callback on Win32 as it results in an access
     * violation due to calling into a module which has been unloaded.
     * Any cleanup isn't needed on Windows anyway, the OS takes care of it.c
     * see: http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx
     */
#if ( TARGET_HOST_MS_WINDOWS == 0 )
    atexit(fgDeinitialize);
#endif

    /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */
    fgInitialiseInputDevices();
}
Ejemplo n.º 28
0
/*
 * Restores the previously remembered visual settings
 */
static void fghRestoreState( void )
{
#if TARGET_HOST_UNIX_X11

#   ifdef X_XF86VidModeGetAllModeLines
    /* Restore the remembered pointer position: */
    XWarpPointer(
        fgDisplay.Display, None, fgDisplay.RootWindow, 0, 0, 0, 0,
        fgDisplay.DisplayPointerX, fgDisplay.DisplayPointerY
    );

    /*
     * This highly depends on the XFree86 extensions,
     * not approved as X Consortium standards
     */

    if( fgDisplay.DisplayModeValid )
    {
        XF86VidModeModeInfo** displayModes;
        int i, displayModesCount;

        if( !XF86VidModeGetAllModeLines(
                 fgDisplay.Display,
                 fgDisplay.Screen,
                 &displayModesCount,
                 &displayModes ) )
        {
            fgWarning( "XF86VidModeGetAllModeLines failed" );
            return;
        }


        /*
         * Check every of the modes looking for one that matches our demands.
         * If we find one, switch to it and restore the remembered viewport.
         */
        for( i = 0; i < displayModesCount; i++ )
        {
            if(displayModes[ i ]->hdisplay == fgDisplay.DisplayMode.hdisplay &&
               displayModes[ i ]->vdisplay == fgDisplay.DisplayMode.vdisplay &&
               displayModes[ i ]->dotclock == fgDisplay.DisplayModeClock )
            {
                if( !XF86VidModeSwitchToMode(
                         fgDisplay.Display,
                         fgDisplay.Screen,
                         displayModes[ i ] ) )
                {
                    fgWarning( "XF86VidModeSwitchToMode failed" );
                    break;
                }

                if( !XF86VidModeSetViewPort(
                         fgDisplay.Display,
                         fgDisplay.Screen,
                         fgDisplay.DisplayViewPortX,
                         fgDisplay.DisplayViewPortY ) )
                    fgWarning( "XF86VidModeSetViewPort failed" );


                /*
                 * For the case this would be the last X11 call the application
                 * calls exit() we've to flush the X11 output queue to have the
                 * commands sent to the X server before the application exits.
                 */
                XFlush( fgDisplay.Display );

                break;
            }
        }
        XFree( displayModes );
    }

#   else
    /*
     * XXX warning fghRestoreState: missing XFree86 video mode extensions,
     * XXX game mode will not change screen resolution when activated
     */
#   endif

#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE

    /* Restore the previously rememebered desktop display settings */
    ChangeDisplaySettings( &fgDisplay.DisplayMode, 0 );

#endif
}
Ejemplo n.º 29
0
Archivo: fg_init.c Proyecto: d3x0r/SACK
void FGAPIENTRY glutInitDisplayString( const char* displayMode )
{
    int glut_state_flag = 0 ;
    /*
     * Unpack a lot of options from a character string.  The options are
     * delimited by blanks or tabs.
     */
    char *token ;
    size_t len = strlen ( displayMode );
    char *buffer = (char *)malloc ( (len+1) * sizeof(char) );
    memcpy ( buffer, displayMode, len );
    buffer[len] = '\0';

    token = strtok ( buffer, " \t" );

    while ( token )
    {
        /* Process this token */
        int i ;

        /* Temporary fix:  Ignore any length specifications and at least
         * process the basic token
         * TODO:  Fix this permanently
         */
        size_t cleanlength = strcspn ( token, "=<>~!" );

        for ( i = 0; i < NUM_TOKENS; i++ )
        {
            if ( strncmp ( token, Tokens[i], cleanlength ) == 0 ) break ;
        }

        switch ( i )
        {
        case 0 :  /* "alpha":  Alpha color buffer precision in bits */
            glut_state_flag |= GLUT_ALPHA ;  /* Somebody fix this for me! */
            break ;

        case 1 :  /* "acca":  Red, green, blue, and alpha accumulation buffer
                     precision in bits */
            break ;

        case 2 :  /* "acc":  Red, green, and blue accumulation buffer precision
                     in bits with zero bits alpha */
            glut_state_flag |= GLUT_ACCUM ;  /* Somebody fix this for me! */
            break ;

        case 3 :  /* "blue":  Blue color buffer precision in bits */
            break ;

        case 4 :  /* "buffer":  Number of bits in the color index color buffer
                   */
            break ;

        case 5 :  /* "conformant":  Boolean indicating if the frame buffer
                     configuration is conformant or not */
            break ;

        case 6 : /* "depth":  Number of bits of precision in the depth buffer */
            glut_state_flag |= GLUT_DEPTH ;  /* Somebody fix this for me! */
            break ;

        case 7 :  /* "double":  Boolean indicating if the color buffer is
                     double buffered */
            glut_state_flag |= GLUT_DOUBLE ;
            break ;

        case 8 :  /* "green":  Green color buffer precision in bits */
            break ;

        case 9 :  /* "index":  Boolean if the color model is color index or not
                   */
            glut_state_flag |= GLUT_INDEX ;
            break ;

        case 10 :  /* "num":  A special capability  name indicating where the
                      value represents the Nth frame buffer configuration
                      matching the description string */
            break ;

        case 11 :  /* "red":  Red color buffer precision in bits */
            break ;

        case 12 :  /* "rgba":  Number of bits of red, green, blue, and alpha in
                      the RGBA color buffer */
            glut_state_flag |= GLUT_RGBA ;  /* Somebody fix this for me! */
            break ;

        case 13 :  /* "rgb":  Number of bits of red, green, and blue in the
                      RGBA color buffer with zero bits alpha */
            glut_state_flag |= GLUT_RGB ;  /* Somebody fix this for me! */
            break ;

        case 14 :  /* "luminance":  Number of bits of red in the RGBA and zero
                      bits of green, blue (alpha not specified) of color buffer
                      precision */
            glut_state_flag |= GLUT_LUMINANCE ; /* Somebody fix this for me! */
            break ;

        case 15 :  /* "stencil":  Number of bits in the stencil buffer */
            glut_state_flag |= GLUT_STENCIL;  /* Somebody fix this for me! */
            break ;

        case 16 :  /* "single":  Boolean indicate the color buffer is single
                      buffered */
            glut_state_flag |= GLUT_SINGLE ;
            break ;

        case 17 :  /* "stereo":  Boolean indicating the color buffer supports
                      OpenGL-style stereo */
            glut_state_flag |= GLUT_STEREO ;
            break ;

        case 18 :  /* "samples":  Indicates the number of multisamples to use
                      based on GLX's SGIS_multisample extension (for
                      antialiasing) */
            glut_state_flag |= GLUT_MULTISAMPLE ; /*Somebody fix this for me!*/
            break ;

        case 19 :  /* "slow":  Boolean indicating if the frame buffer
                      configuration is slow or not */
            break ;

        case 20 :  /* "win32pdf": (incorrect spelling but was there before */
        case 21 :  /* "win32pfd":  matches the Win32 Pixel Format Descriptor by
                      number */
#if TARGET_HOST_MS_WINDOWS
#endif
            break ;

        case 22 :  /* "xvisual":  matches the X visual ID by number */
#if TARGET_HOST_POSIX_X11
#endif
            break ;

        case 23 :  /* "xstaticgray": */
        case 29 :  /* "xstaticgrey":  boolean indicating if the frame buffer
                      configuration's X visual is of type StaticGray */
#if TARGET_HOST_POSIX_X11
#endif
            break ;

        case 24 :  /* "xgrayscale": */
        case 30 :  /* "xgreyscale":  boolean indicating if the frame buffer
                      configuration's X visual is of type GrayScale */
#if TARGET_HOST_POSIX_X11
#endif
            break ;

        case 25 :  /* "xstaticcolor": */
        case 31 :  /* "xstaticcolour":  boolean indicating if the frame buffer
                      configuration's X visual is of type StaticColor */
#if TARGET_HOST_POSIX_X11
#endif
            break ;

        case 26 :  /* "xpseudocolor": */
        case 32 :  /* "xpseudocolour":  boolean indicating if the frame buffer
                      configuration's X visual is of type PseudoColor */
#if TARGET_HOST_POSIX_X11
#endif
            break ;

        case 27 :  /* "xtruecolor": */
        case 33 :  /* "xtruecolour":  boolean indicating if the frame buffer
                      configuration's X visual is of type TrueColor */
#if TARGET_HOST_POSIX_X11
#endif
            break ;

        case 28 :  /* "xdirectcolor": */
        case 34 :  /* "xdirectcolour":  boolean indicating if the frame buffer
                      configuration's X visual is of type DirectColor */
#if TARGET_HOST_POSIX_X11
#endif
            break ;

        case 35 :  /* "borderless":  windows should not have borders */
            glut_state_flag |= GLUT_BORDERLESS;
            break ;

        case 36 :  /* "aux":  some number of aux buffers */
            glut_state_flag |= GLUT_AUX;
            break ;

        case 37 :  /* Unrecognized */
            fgWarning ( "WARNING - Display string token not recognized:  %s",
                        token );
            break ;
        }

        token = strtok ( NULL, " \t" );
    }

    free ( buffer );

    /* We will make use of this value when creating a new OpenGL context... */
    fgState.DisplayMode = glut_state_flag;
}
Ejemplo n.º 30
0
/*
 * Changes the current display mode to match user's settings
 */
static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
{
    GLboolean success = GL_FALSE;
#if TARGET_HOST_UNIX_X11

    /*
     * This highly depends on the XFree86 extensions,
     * not approved as X Consortium standards
     */
#   ifdef X_XF86VidModeGetAllModeLines

    /*
     * This is also used by applcations which check modes by calling
     * glutGameModeGet(GLUT_GAME_MODE_POSSIBLE), so allow the check:
     */
    if( haveToTest || fgDisplay.DisplayModeValid )
    {
        XF86VidModeModeInfo** displayModes;
        int i, displayModesCount;

        if( !XF86VidModeGetAllModeLines(
                 fgDisplay.Display,
                 fgDisplay.Screen,
                 &displayModesCount,
                 &displayModes ) )
        {
            fgWarning( "XF86VidModeGetAllModeLines failed" );
            return success;
        }


        /*
         * Check every of the modes looking for one that matches our demands,
         * ignoring the refresh rate if no exact match could be found.
         */
        i = fghCheckDisplayModes( GL_TRUE, displayModesCount, displayModes );
        if( i < 0 ) {
            i = fghCheckDisplayModes( GL_FALSE, displayModesCount, displayModes );
        }
        success = ( i < 0 ) ? GL_FALSE : GL_TRUE;

        if( !haveToTest && success ) {
            if( !XF86VidModeSwitchToMode(
                     fgDisplay.Display,
                     fgDisplay.Screen,
                     displayModes[ i ] ) )
                fgWarning( "XF86VidModeSwitchToMode failed" );
        }

        XFree( displayModes );
    }

#   else

    /*
     * XXX warning fghChangeDisplayMode: missing XFree86 video mode extensions,
     * XXX game mode will not change screen resolution when activated
     */
    success = GL_TRUE;

#   endif

#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE

    DEVMODE  devMode;
    char *fggmstr = NULL;

    success = GL_FALSE;

    EnumDisplaySettings( NULL, -1, &devMode ); 
    devMode.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;

    devMode.dmPelsWidth  = fgState.GameModeSize.X;
    devMode.dmPelsHeight = fgState.GameModeSize.Y;
    devMode.dmBitsPerPel = fgState.GameModeDepth;
    devMode.dmDisplayFrequency = fgState.GameModeRefresh;
    devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;

    switch ( ChangeDisplaySettingsEx(NULL, &devMode, NULL, haveToTest ? CDS_TEST : CDS_FULLSCREEN , NULL) )
    {
    case DISP_CHANGE_SUCCESSFUL:
        success = GL_TRUE;

        /* update vars in case if windows switched to proper mode */
        EnumDisplaySettings( NULL, FREEGLUT_ENUM_CURRENT_SETTINGS, &devMode );
        fgState.GameModeSize.X  = devMode.dmPelsWidth;        
        fgState.GameModeSize.Y  = devMode.dmPelsHeight;
        fgState.GameModeDepth   = devMode.dmBitsPerPel;
        fgState.GameModeRefresh = devMode.dmDisplayFrequency;
		break;
    case DISP_CHANGE_RESTART:
        fggmstr = "The computer must be restarted for the graphics mode to work.";
        break;
    case DISP_CHANGE_BADFLAGS:
        fggmstr = "An invalid set of flags was passed in.";
        break;
    case DISP_CHANGE_BADPARAM:
        fggmstr = "An invalid parameter was passed in. This can include an invalid flag or combination of flags.";
        break;
    case DISP_CHANGE_FAILED:
        fggmstr = "The display driver failed the specified graphics mode.";
        break;
    case DISP_CHANGE_BADMODE:
        fggmstr = "The graphics mode is not supported.";
        break;
    default:
        fggmstr = "Unknown error in graphics mode???"; /* dunno if it is possible,MSDN does not mention any other error */
        break;
    }

    if ( !success )
        fgWarning(fggmstr); /* I'd rather get info whats going on in my program than wonder about */
                            /* magic happenings behind my back, its lib for devels at last ;) */
#endif

    return success;
}