and some more renames
authorDiederick Niehorster <dcnieho@gmail.com>
Sun, 11 Mar 2012 15:14:33 +0000 (15:14 +0000)
committerDiederick Niehorster <dcnieho@gmail.com>
Sun, 11 Mar 2012 15:14:33 +0000 (15:14 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1112 7f0cb862-5218-0410-a997-914c9d46530a

61 files changed:
CMakeLists.txt
src/mswin/fg_cursor_mswin.c [new file with mode: 0644]
src/mswin/fg_display_mswin.c [new file with mode: 0644]
src/mswin/fg_ext_mswin.c [new file with mode: 0644]
src/mswin/fg_gamemode_mswin.c [new file with mode: 0644]
src/mswin/fg_init_mswin.c [new file with mode: 0644]
src/mswin/fg_input_devices_mswin.c [new file with mode: 0644]
src/mswin/fg_internal_mswin.h [new file with mode: 0644]
src/mswin/fg_joystick_mswin.c [new file with mode: 0644]
src/mswin/fg_main_mswin.c [new file with mode: 0644]
src/mswin/fg_menu_mswin.c [new file with mode: 0644]
src/mswin/fg_spaceball_mswin.c [new file with mode: 0644]
src/mswin/fg_state_mswin.c [new file with mode: 0644]
src/mswin/fg_structure_mswin.c [new file with mode: 0644]
src/mswin/fg_window_mswin.c [new file with mode: 0644]
src/mswin/freeglut_cursor_mswin.c [deleted file]
src/mswin/freeglut_display_mswin.c [deleted file]
src/mswin/freeglut_ext_mswin.c [deleted file]
src/mswin/freeglut_gamemode_mswin.c [deleted file]
src/mswin/freeglut_init_mswin.c [deleted file]
src/mswin/freeglut_input_devices_mswin.c [deleted file]
src/mswin/freeglut_internal_mswin.h [deleted file]
src/mswin/freeglut_joystick_mswin.c [deleted file]
src/mswin/freeglut_main_mswin.c [deleted file]
src/mswin/freeglut_menu_mswin.c [deleted file]
src/mswin/freeglut_spaceball_mswin.c [deleted file]
src/mswin/freeglut_state_mswin.c [deleted file]
src/mswin/freeglut_structure_mswin.c [deleted file]
src/mswin/freeglut_window_mswin.c [deleted file]
src/x11/fg_cursor_x11.c [new file with mode: 0644]
src/x11/fg_display_x11.c [new file with mode: 0644]
src/x11/fg_ext_x11.c [new file with mode: 0644]
src/x11/fg_gamemode_x11.c [new file with mode: 0644]
src/x11/fg_glutfont_definitions_x11.c [new file with mode: 0644]
src/x11/fg_init_x11.c [new file with mode: 0644]
src/x11/fg_input_devices_x11.c [new file with mode: 0644]
src/x11/fg_internal_x11.h [new file with mode: 0644]
src/x11/fg_joystick_x11.c [new file with mode: 0644]
src/x11/fg_main_x11.c [new file with mode: 0644]
src/x11/fg_menu_x11.c [new file with mode: 0644]
src/x11/fg_spaceball_x11.c [new file with mode: 0644]
src/x11/fg_state_x11.c [new file with mode: 0644]
src/x11/fg_structure_x11.c [new file with mode: 0644]
src/x11/fg_window_x11.c [new file with mode: 0644]
src/x11/fg_xinput_x11.c [new file with mode: 0644]
src/x11/freeglut_cursor_x11.c [deleted file]
src/x11/freeglut_display_x11.c [deleted file]
src/x11/freeglut_ext_x11.c [deleted file]
src/x11/freeglut_gamemode_x11.c [deleted file]
src/x11/freeglut_glutfont_definitions_x11.c [deleted file]
src/x11/freeglut_init_x11.c [deleted file]
src/x11/freeglut_input_devices_x11.c [deleted file]
src/x11/freeglut_internal_x11.h [deleted file]
src/x11/freeglut_joystick_x11.c [deleted file]
src/x11/freeglut_main_x11.c [deleted file]
src/x11/freeglut_menu_x11.c [deleted file]
src/x11/freeglut_spaceball_x11.c [deleted file]
src/x11/freeglut_state_x11.c [deleted file]
src/x11/freeglut_structure_x11.c [deleted file]
src/x11/freeglut_window_x11.c [deleted file]
src/x11/freeglut_xinput_x11.c [deleted file]

index 8b9d568..08ef46a 100644 (file)
@@ -9,97 +9,97 @@ SET(FREEGLUT_HEADERS
 )
 SET(FREEGLUT_SRCS
        ${FREEGLUT_HEADERS}
-       src/Common/freeglut_callbacks.c
-       src/Common/freeglut_cursor.c
-       src/Common/freeglut_display.c
-       src/Common/freeglut_ext.c
-       src/Common/freeglut_font_data.c
-       src/Common/freeglut_gamemode.c
-       src/Common/freeglut_init.c
-       src/Common/freeglut_internal.h
-       src/Common/freeglut_input_devices.c
-       src/Common/freeglut_joystick.c
-       src/Common/freeglut_main.c
-       src/Common/freeglut_misc.c
-       src/Common/freeglut_overlay.c
-       src/Common/freeglut_spaceball.c
-       src/Common/freeglut_state.c
-       src/Common/freeglut_stroke_mono_roman.c
-       src/Common/freeglut_stroke_roman.c
-       src/Common/freeglut_structure.c
-       src/Common/freeglut_videoresize.c
-       src/Common/freeglut_window.c
+       src/fg_callbacks.c
+       src/fg_cursor.c
+       src/fg_display.c
+       src/fg_ext.c
+       src/fg_font_data.c
+       src/fg_gamemode.c
+       src/fg_init.c
+       src/fg_internal.h
+       src/fg_input_devices.c
+       src/fg_joystick.c
+       src/fg_main.c
+       src/fg_misc.c
+       src/fg_overlay.c
+       src/fg_spaceball.c
+       src/fg_state.c
+       src/fg_stroke_mono_roman.c
+       src/fg_stroke_roman.c
+       src/fg_structure.c
+       src/fg_videoresize.c
+       src/fg_window.c
 )
 # Android port requires adding a version of these compatible with
 # OpenGL ES (TODO):
 IF(NOT ANDROID)
        LIST(APPEND FREEGLUT_SRCS
-               src/Common/freeglut_font.c
-               src/Common/freeglut_geometry.c
-               src/Common/freeglut_menu.c
-               src/Common/freeglut_teapot.c
+               src/fg_font.c
+               src/fg_geometry.c
+               src/fg_menu.c
+               src/fg_teapot.c
 )
 ENDIF()
 
-IF(WIN32)
+IF(WIN32)   # TODO: is this true for 64 bit as well? Chaneg to WINDOWS?
        LIST(APPEND FREEGLUT_SRCS
-               src/Common/xparsegeometry_repl.c
-               src/Common/xparsegeometry_repl.h
-               src/mswin/freeglut_cursor_mswin.c
-               src/mswin/freeglut_display_mswin.c
-               src/mswin/freeglut_ext_mswin.c
-               src/mswin/freeglut_gamemode_mswin.c
-               src/mswin/freeglut_init_mswin.c
-               src/mswin/freeglut_internal_mswin.h
-               src/mswin/freeglut_input_devices_mswin.c
-               src/mswin/freeglut_joystick_mswin.c
-               src/mswin/freeglut_main_mswin.c
-               src/mswin/freeglut_menu_mswin.c
-               src/mswin/freeglut_spaceball_mswin.c
-               src/mswin/freeglut_state_mswin.c
-               src/mswin/freeglut_structure_mswin.c
-               src/mswin/freeglut_window_mswin.c
+               src/util/xparsegeometry_repl.c  # TODO: instead of this, detect if function is available and include if not
+               src/util/xparsegeometry_repl.h
+               src/mswin/fg_cursor_mswin.c
+               src/mswin/fg_display_mswin.c
+               src/mswin/fg_ext_mswin.c
+               src/mswin/fg_gamemode_mswin.c
+               src/mswin/fg_init_mswin.c
+               src/mswin/fg_internal_mswin.h
+               src/mswin/fg_input_devices_mswin.c
+               src/mswin/fg_joystick_mswin.c
+               src/mswin/fg_main_mswin.c
+               src/mswin/fg_menu_mswin.c
+               src/mswin/fg_spaceball_mswin.c
+               src/mswin/fg_state_mswin.c
+               src/mswin/fg_structure_mswin.c
+               src/mswin/fg_window_mswin.c
 )
 ELSEIF(ANDROID)
        LIST(APPEND FREEGLUT_SRCS
-               src/Common/xparsegeometry_repl.c
-               src/Common/xparsegeometry_repl.h
-               src/egl/freeglut_internal_egl.h
-               src/egl/freeglut_display_egl.c
-               src/egl/freeglut_init_egl.c
-               src/egl/freeglut_structure_egl.c
-               src/egl/freeglut_window_egl.c
+               src/util/xparsegeometry_repl.c
+               src/util/xparsegeometry_repl.h
+               src/egl/fg_internal_egl.h
+               src/egl/fg_display_egl.c
+               src/egl/fg_init_egl.c
+               src/egl/fg_structure_egl.c
+               src/egl/fg_window_egl.c
                src/android/native_app_glue/android_native_app_glue.c
                src/android/native_app_glue/android_native_app_glue.h
-               src/android/freeglut_runtime_android.c
-               src/android/freeglut_gamemode_android.c
-               src/android/freeglut_input_devices_android.c
-               src/android/freeglut_joystick_android.c
-               src/android/freeglut_main_android.c
-               src/android/freeglut_spaceball_android.c
-               src/android/freeglut_state_android.c
-               src/android/freeglut_window_android.c
+               src/android/fg_runtime_android.c
+               src/android/fg_gamemode_android.c
+               src/android/fg_input_devices_android.c
+               src/android/fg_joystick_android.c
+               src/android/fg_main_android.c
+               src/android/fg_spaceball_android.c
+               src/android/fg_state_android.c
+               src/android/fg_window_android.c
                src/android/opengles_stubs.c
-               src/android/freeglut_internal_android.h
+               src/android/fg_internal_android.h
 )
 ELSE()
        LIST(APPEND FREEGLUT_SRCS
-               src/x11/freeglut_cursor_x11.c
-               src/x11/freeglut_display_x11.c
-               src/x11/freeglut_ext_x11.c
-               src/x11/freeglut_gamemode_x11.c
-               src/x11/freeglut_glutfont_definitions_x11.c
-               src/x11/freeglut_init_x11.c
-               src/x11/freeglut_internal_x11.h
-               src/x11/freeglut_input_devices_x11.c
-               src/x11/freeglut_joystick_x11.c
-               src/x11/freeglut_main_x11.c
-               src/x11/freeglut_menu_x11.c
-               src/x11/freeglut_spaceball_x11.c
-               src/x11/freeglut_state_x11.c
-               src/x11/freeglut_structure_x11.c
-               src/x11/freeglut_window_x11.c
-               src/x11/freeglut_xinput_x11.c
+               src/x11/fg_cursor_x11.c
+               src/x11/fg_display_x11.c
+               src/x11/fg_ext_x11.c
+               src/x11/fg_gamemode_x11.c
+               src/x11/fg_glutfont_definitions_x11.c
+               src/x11/fg_init_x11.c
+               src/x11/fg_internal_x11.h
+               src/x11/fg_input_devices_x11.c
+               src/x11/fg_joystick_x11.c
+               src/x11/fg_main_x11.c
+               src/x11/fg_menu_x11.c
+               src/x11/fg_spaceball_x11.c
+               src/x11/fg_state_x11.c
+               src/x11/fg_structure_x11.c
+               src/x11/fg_window_x11.c
+               src/x11/fg_xinput_x11.c
 )
 
 
diff --git a/src/mswin/fg_cursor_mswin.c b/src/mswin/fg_cursor_mswin.c
new file mode 100644 (file)
index 0000000..b0eda70
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * freeglut_cursor_mswin.c
+ *
+ * The Windows-specific mouse cursor related stuff.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Thu Jan 19, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+
+
+void fgPlatformSetCursor ( SFG_Window *window, int cursorID )
+{
+    /*
+     * Joe Krahn is re-writing the following code.
+     */
+    /* Set the cursor AND change it for this window class. */
+#if !defined(__MINGW64__) && _MSC_VER <= 1200
+#       define MAP_CURSOR(a,b)                                   \
+        case a:                                                  \
+            SetCursor( LoadCursor( NULL, b ) );                  \
+            SetClassLong( window->Window.Handle,                 \
+                          GCL_HCURSOR,                           \
+                          ( LONG )LoadCursor( NULL, b ) );       \
+        break;
+    /* Nuke the cursor AND change it for this window class. */
+#       define ZAP_CURSOR(a,b)                                   \
+        case a:                                                  \
+            SetCursor( NULL );                                   \
+            SetClassLong( window->Window.Handle,                 \
+                          GCL_HCURSOR, ( LONG )NULL );           \
+        break;
+#else
+#       define MAP_CURSOR(a,b)                                   \
+        case a:                                                  \
+            SetCursor( LoadCursor( NULL, b ) );                  \
+            SetClassLongPtr( window->Window.Handle,              \
+                          GCLP_HCURSOR,                          \
+                          ( LONG )( LONG_PTR )LoadCursor( NULL, b ) );       \
+        break;
+    /* Nuke the cursor AND change it for this window class. */
+#       define ZAP_CURSOR(a,b)                                   \
+        case a:                                                  \
+            SetCursor( NULL );                                   \
+            SetClassLongPtr( window->Window.Handle,              \
+                          GCLP_HCURSOR, ( LONG )( LONG_PTR )NULL );          \
+        break;
+#endif
+
+    switch( cursorID )
+    {
+        MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW,         IDC_ARROW     );
+        MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW,          IDC_ARROW     );
+        MAP_CURSOR( GLUT_CURSOR_INFO,                IDC_HELP      );
+        MAP_CURSOR( GLUT_CURSOR_DESTROY,             IDC_CROSS     );
+        MAP_CURSOR( GLUT_CURSOR_HELP,                IDC_HELP      );
+        MAP_CURSOR( GLUT_CURSOR_CYCLE,               IDC_SIZEALL   );
+        MAP_CURSOR( GLUT_CURSOR_SPRAY,               IDC_CROSS     );
+        MAP_CURSOR( GLUT_CURSOR_WAIT,                IDC_WAIT      );
+        MAP_CURSOR( GLUT_CURSOR_TEXT,                IDC_IBEAM     );
+        MAP_CURSOR( GLUT_CURSOR_CROSSHAIR,           IDC_CROSS     );
+        MAP_CURSOR( GLUT_CURSOR_UP_DOWN,             IDC_SIZENS    );
+        MAP_CURSOR( GLUT_CURSOR_LEFT_RIGHT,          IDC_SIZEWE    );
+        MAP_CURSOR( GLUT_CURSOR_TOP_SIDE,            IDC_ARROW     ); /* XXX ToDo */
+        MAP_CURSOR( GLUT_CURSOR_BOTTOM_SIDE,         IDC_ARROW     ); /* XXX ToDo */
+        MAP_CURSOR( GLUT_CURSOR_LEFT_SIDE,           IDC_ARROW     ); /* XXX ToDo */
+        MAP_CURSOR( GLUT_CURSOR_RIGHT_SIDE,          IDC_ARROW     ); /* XXX ToDo */
+        MAP_CURSOR( GLUT_CURSOR_TOP_LEFT_CORNER,     IDC_SIZENWSE  );
+        MAP_CURSOR( GLUT_CURSOR_TOP_RIGHT_CORNER,    IDC_SIZENESW  );
+        MAP_CURSOR( GLUT_CURSOR_BOTTOM_RIGHT_CORNER, IDC_SIZENWSE  );
+        MAP_CURSOR( GLUT_CURSOR_BOTTOM_LEFT_CORNER,  IDC_SIZENESW  );
+        MAP_CURSOR( GLUT_CURSOR_INHERIT,             IDC_ARROW     ); /* XXX ToDo */
+        ZAP_CURSOR( GLUT_CURSOR_NONE,                NULL          );
+        MAP_CURSOR( GLUT_CURSOR_FULL_CROSSHAIR,      IDC_CROSS     ); /* XXX ToDo */
+
+    default:
+        fgError( "Unknown cursor type: %d", cursorID );
+        break;
+    }
+}
+
+
+void fgPlatformWarpPointer ( int x, int y )
+{
+    POINT coords;
+    coords.x = x;
+    coords.y = y;
+
+    /* ClientToScreen() translates {coords} for us. */
+    ClientToScreen( fgStructure.CurrentWindow->Window.Handle, &coords );
+    SetCursorPos( coords.x, coords.y );
+}
+
+
diff --git a/src/mswin/fg_display_mswin.c b/src/mswin/fg_display_mswin.c
new file mode 100644 (file)
index 0000000..6a58412
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * freeglut_display_mswin.c
+ *
+ * The Windows-specific mouse cursor related stuff.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Sat Jan 28, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+
+
+
+void fgPlatformGlutSwapBuffers( SFG_PlatformDisplay *pDisplayPtr, SFG_Window* CurrentWindow )
+{
+    SwapBuffers( CurrentWindow->Window.pContext.Device );
+}
diff --git a/src/mswin/fg_ext_mswin.c b/src/mswin/fg_ext_mswin.c
new file mode 100644 (file)
index 0000000..efc2fa9
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * freeglut_ext_mswin.c
+ *
+ * The Windows-specific mouse cursor related stuff.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Thu Jan 19, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+GLUTproc fgPlatformGetGLUTProcAddress( const char* procName )
+{
+#if !defined(_WIN32_WCE)
+    /* optimization: quick initial check */
+    if( strncmp( procName, "glut", 4 ) != 0 )
+        return NULL;
+
+#define CHECK_NAME(x) if( strcmp( procName, #x ) == 0) return (GLUTproc)x;
+    CHECK_NAME(glutJoystickFunc);
+    CHECK_NAME(glutForceJoystickFunc);
+    CHECK_NAME(glutGameModeString);
+    CHECK_NAME(glutEnterGameMode);
+    CHECK_NAME(glutLeaveGameMode);
+    CHECK_NAME(glutGameModeGet);
+#undef CHECK_NAME
+#endif /* !defined(_WIN32_WCE) */
+
+    return NULL;
+}
+
+
+
+SFG_Proc fgPlatformGetProcAddress( const char *procName )
+{
+    return (SFG_Proc)wglGetProcAddress( ( LPCSTR )procName );
+}
diff --git a/src/mswin/fg_gamemode_mswin.c b/src/mswin/fg_gamemode_mswin.c
new file mode 100644 (file)
index 0000000..3e5228d
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * freeglut_gamemode_mswin.c
+ *
+ * The Windows-specific mouse cursor related stuff.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Thu Jan 19, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+/*
+ * Remembers the current visual settings, so that
+ * we can change them and restore later...
+ */
+void fgPlatformRememberState( void )
+{
+    /* Grab the current desktop settings... */
+
+    /* hack to get around my stupid cross-gcc headers */
+    #define FREEGLUT_ENUM_CURRENT_SETTINGS -1
+
+    EnumDisplaySettings( fgDisplay.pDisplay.DisplayName, FREEGLUT_ENUM_CURRENT_SETTINGS,
+                         &fgDisplay.pDisplay.DisplayMode );
+
+    /* Make sure we will be restoring all settings needed */
+    fgDisplay.pDisplay.DisplayMode.dmFields |=
+        DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
+
+}
+
+/*
+ * Restores the previously remembered visual settings
+ */
+void fgPlatformRestoreState( void )
+{
+    /* Restore the previously remembered desktop display settings */
+    ChangeDisplaySettingsEx( fgDisplay.pDisplay.DisplayName,&fgDisplay.pDisplay.DisplayMode, 0,0,0 );
+}
+
+
+
+
+/*
+ * Changes the current display mode to match user's settings
+ */
+GLboolean fgPlatformChangeDisplayMode( GLboolean haveToTest )
+{
+    GLboolean success = GL_FALSE;
+    DEVMODE  devMode;
+    char *fggmstr = NULL;
+    char displayMode[300];
+
+    success = GL_FALSE;
+
+    EnumDisplaySettings( fgDisplay.pDisplay.DisplayName, -1, &devMode ); 
+    devMode.dmFields = 0;
+
+    if (fgState.GameModeSize.X!=-1)
+    {
+        devMode.dmPelsWidth  = fgState.GameModeSize.X;
+        devMode.dmFields |= DM_PELSWIDTH;
+    }
+    if (fgState.GameModeSize.Y!=-1)
+    {
+        devMode.dmPelsHeight  = fgState.GameModeSize.Y;
+        devMode.dmFields |= DM_PELSHEIGHT;
+    }
+    if (fgState.GameModeDepth!=-1)
+    {
+        devMode.dmBitsPerPel  = fgState.GameModeDepth;
+        devMode.dmFields |= DM_BITSPERPEL;
+    }
+    if (fgState.GameModeRefresh!=-1)
+    {
+        devMode.dmDisplayFrequency  = fgState.GameModeRefresh;
+        devMode.dmFields |= DM_DISPLAYFREQUENCY;
+    }
+
+    switch ( ChangeDisplaySettingsEx(fgDisplay.pDisplay.DisplayName, &devMode, NULL, haveToTest ? CDS_TEST : CDS_FULLSCREEN , NULL) )
+    {
+    case DISP_CHANGE_SUCCESSFUL:
+        success = GL_TRUE;
+
+        if (!haveToTest)
+        {
+            /* update vars in case if windows switched to proper mode */
+            EnumDisplaySettings( fgDisplay.pDisplay.DisplayName, 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 )
+    {
+        /* 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 ;) */
+        
+        /* append display mode to error to make things more informative */
+        sprintf(displayMode,"%s Problem with requested mode: %ix%i:%i@%i", fggmstr, devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmBitsPerPel, devMode.dmDisplayFrequency);
+        fgWarning(displayMode);
+    }
+
+    return success;
+}
+
+void fgPlatformEnterGameMode( void ) 
+{
+}
+
+void fgPlatformLeaveGameMode( void ) 
+{
+}
diff --git a/src/mswin/fg_init_mswin.c b/src/mswin/fg_init_mswin.c
new file mode 100644 (file)
index 0000000..f80fe78
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * freeglut_init_mswin.c
+ *
+ * The Windows-specific mouse cursor related stuff.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Thu Jan 19, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define FREEGLUT_BUILDING_LIB
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+
+
+extern LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg,
+                               WPARAM wParam, LPARAM lParam );
+
+
+/*
+ * A call to this function should initialize all the display stuff...
+ */
+void fgPlatformInitialize( const char* displayName )
+{
+    WNDCLASS wc;
+    ATOM atom;
+
+    /* What we need to do is to initialize the fgDisplay global structure here. */
+    fgDisplay.pDisplay.Instance = GetModuleHandle( NULL );
+    fgDisplay.pDisplay.DisplayName= displayName ? strdup(displayName) : 0 ;
+    atom = GetClassInfo( fgDisplay.pDisplay.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    = fgPlatformWindowProc;
+        wc.cbClsExtra     = 0;
+        wc.cbWndExtra     = 0;
+        wc.hInstance      = fgDisplay.pDisplay.Instance;
+        wc.hIcon          = LoadIcon( fgDisplay.pDisplay.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", "fgPlatformInitialize" );
+    }
+
+    /* 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.pDisplay.DisplayName )
+    {
+        HDC context = CreateDC(fgDisplay.pDisplay.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("fgPlatformInitialize: "
+                     "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 );
+
+
+    fgState.Initialised = GL_TRUE;
+
+    /* Avoid registering atexit callback on Win32 as it can result 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.
+     * see: http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx
+     */
+/*    atexit(fgDeinitialize); */
+
+    /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */
+    fgInitialiseInputDevices();
+}
+
+
+
+/* Platform-Specific Deinitialization Functions: */
+extern void fghCloseInputDevices ( void );
+
+void fgPlatformDeinitialiseInputDevices ( void )
+{
+#if !defined(_WIN32_WCE)
+       fghCloseInputDevices ();
+#endif /* !defined(_WIN32_WCE) */
+    fgState.JoysticksInitialised = GL_FALSE;
+    fgState.InputDevsInitialised = GL_FALSE;
+}
+
+void fgPlatformCloseDisplay ( void )
+{
+    if( fgDisplay.pDisplay.DisplayName )
+    {
+        free( fgDisplay.pDisplay.DisplayName );
+        fgDisplay.pDisplay.DisplayName = NULL;
+    }
+
+    /* Reset the timer granularity */
+    timeEndPeriod ( 1 );
+}
+
+void fgPlatformDestroyContext ( SFG_PlatformDisplay pDisplay, SFG_WindowContextType MContext )
+{
+       /* Do nothing -- this is required for X11 */
+}
+
+/* -- PLATFORM-SPECIFIC INTERFACE FUNCTION -------------------------------------------------- */
+
+void (__cdecl *__glutExitFunc)( int return_value ) = NULL;
+
+void FGAPIENTRY __glutInitWithExit( int *pargc, char **argv, void (__cdecl *exit_function)(int) )
+{
+  __glutExitFunc = exit_function;
+  glutInit(pargc, argv);
+}
+
diff --git a/src/mswin/fg_input_devices_mswin.c b/src/mswin/fg_input_devices_mswin.c
new file mode 100644 (file)
index 0000000..ba230d4
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * freeglut_input_devices_mswin.c
+ *
+ * The Windows-specific mouse cursor related stuff.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Sat Jan 21, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+#include <sys/types.h>
+#include <winbase.h>
+
+typedef struct {
+   HANDLE fh;
+   COMMTIMEOUTS timeouts_save;
+   DCB dcb_save;
+} SERIALPORT;
+
+/* Serial Port Prototypes */
+SERIALPORT *serial_open ( const char *device );
+void serial_close ( SERIALPORT *port );
+int serial_getchar ( SERIALPORT *port );
+int serial_putchar ( SERIALPORT *port, unsigned char ch );
+void serial_flush ( SERIALPORT *port );
+
+
+void fgPlatformRegisterDialDevice ( const char *dial_device )
+{
+        if (!dial_device){
+            static char devname[256];
+            DWORD size=sizeof(devname);
+            DWORD type = REG_SZ;
+            HKEY key;
+            if (RegOpenKeyA(HKEY_LOCAL_MACHINE,"SOFTWARE\\FreeGLUT",&key)==ERROR_SUCCESS) {
+                if (RegQueryValueExA(key,"DialboxSerialPort",NULL,&type,(LPBYTE)devname,&size)==ERROR_SUCCESS){
+                    dial_device=devname;
+                }
+                RegCloseKey(key);
+            }
+        }
+}
+
+
+/*  Serial Port Functions */
+SERIALPORT *serial_open(const char *device){
+    HANDLE fh;
+    DCB dcb={sizeof(DCB)};
+    COMMTIMEOUTS timeouts;
+    SERIALPORT *port;
+
+    fh = CreateFile(device,GENERIC_READ|GENERIC_WRITE,0,NULL,
+      OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
+    if (!fh) return NULL;
+
+    port = malloc(sizeof(SERIALPORT));
+    ZeroMemory(port, sizeof(SERIALPORT));
+    port->fh = fh;
+
+    /* save current port settings */
+    GetCommState(fh,&port->dcb_save);
+    GetCommTimeouts(fh,&port->timeouts_save);
+
+    dcb.DCBlength=sizeof(DCB);
+    BuildCommDCB("96,n,8,1",&dcb);
+    SetCommState(fh,&dcb);
+
+    ZeroMemory(&timeouts,sizeof(timeouts));
+    timeouts.ReadTotalTimeoutConstant=1;
+    timeouts.WriteTotalTimeoutConstant=1;
+    SetCommTimeouts(fh,&timeouts);
+
+    serial_flush(port);
+
+    return port;
+}
+
+void serial_close(SERIALPORT *port){
+    if (port){
+        /* restore old port settings */
+        SetCommState(port->fh,&port->dcb_save);
+        SetCommTimeouts(port->fh,&port->timeouts_save);
+        CloseHandle(port->fh);
+        free(port);
+    }
+}
+
+int serial_getchar(SERIALPORT *port){
+    DWORD n;
+    unsigned char ch;
+    if (!port) return EOF;
+    if (!ReadFile(port->fh,&ch,1,&n,NULL)) return EOF;
+    if (n==1) return ch;
+    return EOF;
+}
+
+int serial_putchar(SERIALPORT *port, unsigned char ch){
+    DWORD n;
+    if (!port) return 0;
+    return WriteFile(port->fh,&ch,1,&n,NULL);
+}
+
+void serial_flush ( SERIALPORT *port )
+{
+    FlushFileBuffers(port->fh);
+}
+
diff --git a/src/mswin/fg_internal_mswin.h b/src/mswin/fg_internal_mswin.h
new file mode 100644 (file)
index 0000000..571db40
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * freeglut_internal_mswin.h
+ *
+ * The freeglut library private include file.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Thu Jan 19, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef  FREEGLUT_INTERNAL_MSWIN_H
+#define  FREEGLUT_INTERNAL_MSWIN_H
+
+
+/* All Win32 headers depend on the huge windows.h recursive include.
+ * Note: Lower-case header names are used, for best cross-platform
+ * compatibility.
+ */
+#if !defined(_WIN32_WCE)
+#   include <windows.h>
+#   include <windowsx.h>
+#   include <mmsystem.h>
+/* CYGWIN does not have tchar.h, but has TEXT(x), defined in winnt.h. */
+#   ifndef __CYGWIN__
+#       include <tchar.h>
+#   else
+#       define _TEXT(x) TEXT(x)
+#       define _T(x)    TEXT(x)
+#   endif
+
+#endif
+
+
+#ifndef HAVE_VFPRINTF
+#define  HAVE_VFPRINTF 1
+#endif
+
+/* MinGW may lack a prototype for ChangeDisplaySettingsEx() (depending on the version?) */
+#if !defined(ChangeDisplaySettingsEx)
+LONG WINAPI ChangeDisplaySettingsExA(LPCSTR,LPDEVMODEA,HWND,DWORD,LPVOID);
+LONG WINAPI ChangeDisplaySettingsExW(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID);
+#   ifdef UNICODE
+#       define ChangeDisplaySettingsEx ChangeDisplaySettingsExW
+#   else
+#       define ChangeDisplaySettingsEx ChangeDisplaySettingsExA
+#   endif
+#endif
+
+
+/* Structure Definitions */
+
+typedef struct tagSFG_PlatformDisplay SFG_PlatformDisplay;
+struct tagSFG_PlatformDisplay
+{
+    HINSTANCE       Instance;           /* The application's instance */
+    DEVMODE         DisplayMode;        /* Desktop's display settings */
+    char           *DisplayName;        /* Display name for multi display support*/ 
+};
+
+/*
+ * Make "freeglut" window handle and context types so that we don't need so
+ * much conditionally-compiled code later in the library.
+ */
+typedef HWND    SFG_WindowHandleType;
+typedef HGLRC   SFG_WindowContextType;
+typedef struct tagSFG_PlatformContext SFG_PlatformContext;
+struct tagSFG_PlatformContext
+{
+    HDC             Device;             /* The window's device context */
+};
+
+
+/* Window's state description. This structure should be kept portable. */
+typedef struct tagSFG_PlatformWindowState SFG_PlatformWindowState;
+struct tagSFG_PlatformWindowState
+{
+    RECT            OldRect;            /* window rect  - stored before the window is made fullscreen */
+    DWORD           OldStyle;           /* window style - stored before the window is made fullscreen */
+};
+
+
+
+/* Joystick-Specific Definitions */
+#if !defined(_WIN32_WCE)
+#   define _JS_MAX_AXES  8
+typedef struct tagSFG_PlatformJoystick SFG_PlatformJoystick;
+struct tagSFG_PlatformJoystick
+{
+    JOYCAPS     jsCaps;
+    JOYINFOEX   js;
+    UINT        js_id;
+};
+#endif
+
+
+/* Menu font and color definitions */
+#define  FREEGLUT_MENU_FONT    GLUT_BITMAP_8_BY_13
+
+#define  FREEGLUT_MENU_PEN_FORE_COLORS   {0.0f,  0.0f,  0.0f,  1.0f}
+#define  FREEGLUT_MENU_PEN_BACK_COLORS   {0.85f, 0.85f, 0.85f, 1.0f}
+#define  FREEGLUT_MENU_PEN_HFORE_COLORS  {1.0f,  1.0f,  1.0f,  1.0f}
+#define  FREEGLUT_MENU_PEN_HBACK_COLORS  {0.15f, 0.15f, 0.45f, 1.0f}
+
+
+/* Function to be called on exit */
+extern void (__cdecl *__glutExitFunc)( int return_value );
+
+
+#endif  /* FREEGLUT_INTERNAL_MSWIN_H */
diff --git a/src/mswin/fg_joystick_mswin.c b/src/mswin/fg_joystick_mswin.c
new file mode 100644 (file)
index 0000000..aefa192
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * freeglut_joystick_mswin.c
+ *
+ * The Windows-specific mouse cursor related stuff.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Sat Jan 28, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+
+#if !defined(_WIN32_WCE)
+#    include <windows.h>
+#    include <mmsystem.h>
+#    include <regstr.h>
+
+
+
+
+void fgPlatformJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes )
+{
+    MMRESULT status;
+
+    status = joyGetPosEx( joy->pJoystick.js_id, &joy->pJoystick.js );
+
+    if ( status != JOYERR_NOERROR )
+    {
+        joy->error = GL_TRUE;
+        return;
+    }
+
+    if ( buttons )
+        *buttons = joy->pJoystick.js.dwButtons;
+
+    if ( axes )
+    {
+        /*
+         * WARNING - Fall through case clauses!!
+         */
+        switch ( joy->num_axes )
+        {
+        case 8:
+            /* Generate two POV axes from the POV hat angle.
+             * Low 16 bits of js.dwPOV gives heading (clockwise from ahead) in
+             *   hundredths of a degree, or 0xFFFF when idle.
+             */
+            if ( ( joy->pJoystick.js.dwPOV & 0xFFFF ) == 0xFFFF )
+            {
+              axes [ 6 ] = 0.0;
+              axes [ 7 ] = 0.0;
+            }
+            else
+            {
+              /* This is the contentious bit: how to convert angle to X/Y.
+               *    wk: I know of no define for PI that we could use here:
+               *    SG_PI would pull in sg, M_PI is undefined for MSVC
+               * But the accuracy of the value of PI is very unimportant at
+               * this point.
+               */
+              float s = (float) sin ( ( joy->pJoystick.js.dwPOV & 0xFFFF ) * ( 0.01 * 3.1415926535f / 180.0f ) );
+              float c = (float) cos ( ( joy->pJoystick.js.dwPOV & 0xFFFF ) * ( 0.01 * 3.1415926535f / 180.0f ) );
+
+              /* Convert to coordinates on a square so that North-East
+               * is (1,1) not (.7,.7), etc.
+               * s and c cannot both be zero so we won't divide by zero.
+               */
+              if ( fabs ( s ) < fabs ( c ) )
+              {
+                axes [ 6 ] = ( c < 0.0 ) ? -s/c  : s/c ;
+                axes [ 7 ] = ( c < 0.0 ) ? -1.0f : 1.0f;
+              }
+              else
+              {
+                axes [ 6 ] = ( s < 0.0 ) ? -1.0f : 1.0f;
+                axes [ 7 ] = ( s < 0.0 ) ? -c/s  : c/s ;
+              }
+            }
+
+        case 6: axes[5] = (float) joy->pJoystick.js.dwVpos;
+        case 5: axes[4] = (float) joy->pJoystick.js.dwUpos;
+        case 4: axes[3] = (float) joy->pJoystick.js.dwRpos;
+        case 3: axes[2] = (float) joy->pJoystick.js.dwZpos;
+        case 2: axes[1] = (float) joy->pJoystick.js.dwYpos;
+        case 1: axes[0] = (float) joy->pJoystick.js.dwXpos;
+        }
+    }
+}
+
+
+
+/* Inspired by
+   http://msdn.microsoft.com/archive/en-us/dnargame/html/msdn_sidewind3d.asp
+ */
+#  if FREEGLUT_LIB_PRAGMAS
+#      pragma comment (lib, "advapi32.lib")
+#  endif
+
+static int fghJoystickGetOEMProductName ( SFG_Joystick* joy, char *buf, int buf_sz )
+{
+    char buffer [ 256 ];
+
+    char OEMKey [ 256 ];
+
+    HKEY  hKey;
+    DWORD dwcb;
+    LONG  lr;
+
+    if ( joy->error )
+        return 0;
+
+    /* Open .. MediaResources\CurrentJoystickSettings */
+    _snprintf ( buffer, sizeof(buffer), "%s\\%s\\%s",
+                REGSTR_PATH_JOYCONFIG, joy->pJoystick.jsCaps.szRegKey,
+                REGSTR_KEY_JOYCURR );
+
+    lr = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey);
+
+    if ( lr != ERROR_SUCCESS ) return 0;
+
+    /* Get OEM Key name */
+    dwcb = sizeof(OEMKey);
+
+    /* JOYSTICKID1-16 is zero-based; registry entries for VJOYD are 1-based. */
+    _snprintf ( buffer, sizeof(buffer), "Joystick%d%s", joy->pJoystick.js_id + 1, REGSTR_VAL_JOYOEMNAME );
+
+    lr = RegQueryValueEx ( hKey, buffer, 0, 0, (LPBYTE) OEMKey, &dwcb);
+    RegCloseKey ( hKey );
+
+    if ( lr != ERROR_SUCCESS ) return 0;
+
+    /* Open OEM Key from ...MediaProperties */
+    _snprintf ( buffer, sizeof(buffer), "%s\\%s", REGSTR_PATH_JOYOEM, OEMKey );
+
+    lr = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey );
+
+    if ( lr != ERROR_SUCCESS ) return 0;
+
+    /* Get OEM Name */
+    dwcb = buf_sz;
+
+    lr = RegQueryValueEx ( hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, (LPBYTE) buf,
+                             &dwcb );
+    RegCloseKey ( hKey );
+
+    if ( lr != ERROR_SUCCESS ) return 0;
+
+    return 1;
+}
+
+
+void fgPlatformJoystickOpen( SFG_Joystick* joy )
+{
+       int i = 0;
+
+    joy->pJoystick.js.dwFlags = JOY_RETURNALL;
+    joy->pJoystick.js.dwSize  = sizeof( joy->pJoystick.js );
+
+    memset( &joy->pJoystick.jsCaps, 0, sizeof( joy->pJoystick.jsCaps ) );
+
+    joy->error =
+        ( joyGetDevCaps( joy->pJoystick.js_id, &joy->pJoystick.jsCaps, sizeof( joy->pJoystick.jsCaps ) ) !=
+          JOYERR_NOERROR );
+
+    if( joy->pJoystick.jsCaps.wNumAxes == 0 )
+    {
+        joy->num_axes = 0;
+        joy->error = GL_TRUE;
+    }
+    else
+    {
+        /* Device name from jsCaps is often "Microsoft PC-joystick driver",
+         * at least for USB.  Try to get the real name from the registry.
+         */
+        if ( ! fghJoystickGetOEMProductName( joy, joy->name,
+                                             sizeof( joy->name ) ) )
+        {
+            fgWarning( "JS: Failed to read joystick name from registry" );
+            strncpy( joy->name, joy->pJoystick.jsCaps.szPname, sizeof( joy->name ) );
+        }
+
+        /* Windows joystick drivers may provide any combination of
+         * X,Y,Z,R,U,V,POV - not necessarily the first n of these.
+         */
+        if( joy->pJoystick.jsCaps.wCaps & JOYCAPS_HASPOV )
+        {
+            joy->num_axes = _JS_MAX_AXES;
+            joy->min[ 7 ] = -1.0; joy->max[ 7 ] = 1.0;  /* POV Y */
+            joy->min[ 6 ] = -1.0; joy->max[ 6 ] = 1.0;  /* POV X */
+        }
+        else
+            joy->num_axes = 6;
+
+        joy->min[ 5 ] = ( float )joy->pJoystick.jsCaps.wVmin;
+        joy->max[ 5 ] = ( float )joy->pJoystick.jsCaps.wVmax;
+        joy->min[ 4 ] = ( float )joy->pJoystick.jsCaps.wUmin;
+        joy->max[ 4 ] = ( float )joy->pJoystick.jsCaps.wUmax;
+        joy->min[ 3 ] = ( float )joy->pJoystick.jsCaps.wRmin;
+        joy->max[ 3 ] = ( float )joy->pJoystick.jsCaps.wRmax;
+        joy->min[ 2 ] = ( float )joy->pJoystick.jsCaps.wZmin;
+        joy->max[ 2 ] = ( float )joy->pJoystick.jsCaps.wZmax;
+        joy->min[ 1 ] = ( float )joy->pJoystick.jsCaps.wYmin;
+        joy->max[ 1 ] = ( float )joy->pJoystick.jsCaps.wYmax;
+        joy->min[ 0 ] = ( float )joy->pJoystick.jsCaps.wXmin;
+        joy->max[ 0 ] = ( float )joy->pJoystick.jsCaps.wXmax;
+    }
+
+    /* Guess all the rest judging on the axes extremals */
+    for( i = 0; i < joy->num_axes; i++ )
+    {
+        joy->center   [ i ] = ( joy->max[ i ] + joy->min[ i ] ) * 0.5f;
+        joy->dead_band[ i ] = 0.0f;
+        joy->saturate [ i ] = 1.0f;
+    }
+}
+
+
+
+void fgPlatformJoystickInit( SFG_Joystick *fgJoystick[], int ident )
+{
+    switch( ident )
+    {
+    case 0:
+        fgJoystick[ ident ]->pJoystick.js_id = JOYSTICKID1;
+        fgJoystick[ ident ]->error = GL_FALSE;
+        break;
+    case 1:
+        fgJoystick[ ident ]->pJoystick.js_id = JOYSTICKID2;
+        fgJoystick[ ident ]->error = GL_FALSE;
+        break;
+    default:
+        fgJoystick[ ident ]->num_axes = 0;
+        fgJoystick[ ident ]->error = GL_TRUE;
+        return;
+    }
+}
+
+
+
+void fgPlatformJoystickClose ( int ident )
+{
+    /* Do nothing special */
+}
+#endif
+
diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c
new file mode 100644 (file)
index 0000000..d84940f
--- /dev/null
@@ -0,0 +1,1131 @@
+/*
+ * freeglut_main_mswin.c
+ *
+ * The Windows-specific mouse cursor related stuff.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Sat Jan 21, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+
+extern void fghRedrawWindow ( SFG_Window *window );
+
+extern void fgNewWGLCreateContext( SFG_Window* window );
+extern GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
+                                     unsigned char layer_type );
+
+#ifdef WM_TOUCH
+typedef BOOL (WINAPI *pGetTouchInputInfo)(HTOUCHINPUT,UINT,PTOUCHINPUT,int);
+typedef BOOL (WINAPI *pCloseTouchInputHandle)(HTOUCHINPUT);
+static pGetTouchInputInfo fghGetTouchInputInfo = (pGetTouchInputInfo)0xDEADBEEF;
+static pCloseTouchInputHandle fghCloseTouchInputHandle = (pCloseTouchInputHandle)0xDEADBEEF;
+#endif
+
+#ifdef _WIN32_WCE
+typedef struct GXDisplayProperties GXDisplayProperties;
+typedef struct GXKeyList GXKeyList;
+#include <gx.h>
+
+typedef struct GXKeyList (*GXGETDEFAULTKEYS)(int);
+typedef int (*GXOPENINPUT)();
+
+GXGETDEFAULTKEYS GXGetDefaultKeys_ = NULL;
+GXOPENINPUT GXOpenInput_ = NULL;
+
+struct GXKeyList gxKeyList;
+#endif /* _WIN32_WCE */
+
+/* 
+ * Helper functions for getting client area from the window rect
+ * and the window rect from the client area given the style of the window
+ * (or a valid window pointer from which the style can be queried).
+ */
+extern void fghComputeWindowRectFromClientArea_QueryWindow( const SFG_Window *window, RECT *clientRect, BOOL posIsOutside );
+extern RECT fghGetClientArea                              ( const SFG_Window *window,                   BOOL wantPosOutside );
+
+
+void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height )
+{
+    RECT windowRect;
+
+    /*
+     * For windowed mode, get the current position of the
+     * window and resize taking the size of the frame
+     * decorations into account.
+     */
+
+    /* "GetWindowRect" returns the pixel coordinates of the outside of the window */
+    GetWindowRect( window->Window.Handle, &windowRect );
+
+    /* Create rect in FreeGLUT format, (X,Y) topleft outside window, WxH of client area */
+    windowRect.right    = windowRect.left+width;
+    windowRect.bottom   = windowRect.top+height;
+
+    if (window->Parent == NULL)
+        /* get the window rect from this to feed to SetWindowPos, correct for window decorations */
+        fghComputeWindowRectFromClientArea_QueryWindow(window,&windowRect,TRUE);
+    else
+    {
+        /* correct rect for position client area of parent window
+         * (SetWindowPos input for child windows is in coordinates
+         * relative to the parent's client area).
+         * Child windows don't have decoration, so no need to correct
+         * for them.
+         */
+        RECT parentRect;
+        parentRect = fghGetClientArea( window->Parent, FALSE );
+        windowRect.left   -= parentRect.left;
+        windowRect.right  -= parentRect.left;
+        windowRect.top    -= parentRect.top;
+        windowRect.bottom -= parentRect.top;
+    }
+    
+    /* Do the actual resizing */
+    SetWindowPos( window->Window.Handle,
+                  HWND_TOP,
+                  windowRect.left, windowRect.top,
+                  windowRect.right - windowRect.left,
+                  windowRect.bottom- windowRect.top,
+                  SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING |
+                  SWP_NOZORDER
+    );
+}
+
+
+void fgPlatformDisplayWindow ( SFG_Window *window )
+{
+    RedrawWindow(
+        window->Window.Handle, NULL, NULL,
+        RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_UPDATENOW
+    );
+}
+
+
+fg_time_t fgPlatformSystemTime ( void )
+{
+#if defined(_WIN32_WCE)
+    return GetTickCount();
+#else
+    /* TODO: do this with QueryPerformanceCounter as timeGetTime has
+     * insufficient resolution (only about 5 ms on system under low load).
+     * See:
+     * http://msdn.microsoft.com/en-us/library/windows/desktop/dd757629(v=vs.85).aspx
+     * Or maybe QueryPerformanceCounter is not a good idea either, see
+     * http://old.nabble.com/Re%3A-glutTimerFunc-does-not-detect-if-system-time-moved-backward-p33479674.html
+     * for some other ideas (at bottom)...
+     */
+    return timeGetTime();
+#endif
+}
+
+
+void fgPlatformSleepForEvents( fg_time_t msec )
+{
+    MsgWaitForMultipleObjects( 0, NULL, FALSE, (DWORD) msec, QS_ALLINPUT );
+}
+
+
+void fgPlatformProcessSingleEvent ( void )
+{
+    MSG stMsg;
+
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMainLoopEvent" );
+
+    while( PeekMessage( &stMsg, NULL, 0, 0, PM_NOREMOVE ) )
+    {
+        if( GetMessage( &stMsg, NULL, 0, 0 ) == 0 )
+        {
+            if( fgState.ActionOnWindowClose == GLUT_ACTION_EXIT )
+            {
+                fgDeinitialize( );
+                exit( 0 );
+            }
+            else if( fgState.ActionOnWindowClose == GLUT_ACTION_GLUTMAINLOOP_RETURNS )
+                fgState.ExecState = GLUT_EXEC_STATE_STOP;
+
+            return;
+        }
+
+        TranslateMessage( &stMsg );
+        DispatchMessage( &stMsg );
+    }
+}
+
+
+
+void fgPlatformMainLoopPreliminaryWork ( void )
+{
+    SFG_Window *window = (SFG_Window *)fgStructure.Windows.First ;
+
+    /*
+     * Processing before the main loop:  If there is a window which is open and
+     * which has a visibility callback, call it.  I know this is an ugly hack,
+     * but I'm not sure what else to do about it.  Ideally we should leave
+     * something uninitialized in the create window code and initialize it in
+     * the main loop, and have that initialization create a "WM_ACTIVATE"
+     * message.  Then we would put the visibility callback code in the
+     * "case WM_ACTIVATE" block below.         - John Fay -- 10/24/02
+     */
+    while( window )
+    {
+        if ( FETCH_WCB( *window, Visibility ) )
+        {
+            SFG_Window *current_window = fgStructure.CurrentWindow ;
+
+            INVOKE_WCB( *window, Visibility, ( window->State.Visible ) );
+            fgSetWindow( current_window );
+        }
+
+        window = (SFG_Window *)window->Node.Next ;
+    }
+}
+
+
+/*
+ * Determine a GLUT modifer mask based on MS-WINDOWS system info.
+ */
+static int fgPlatformGetModifiers (void)
+{
+    return
+        ( ( ( GetKeyState( VK_LSHIFT   ) < 0 ) ||
+            ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
+        ( ( ( GetKeyState( VK_LCONTROL ) < 0 ) ||
+            ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
+        ( ( ( GetKeyState( VK_LMENU    ) < 0 ) ||
+            ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 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;
+}
diff --git a/src/mswin/fg_menu_mswin.c b/src/mswin/fg_menu_mswin.c
new file mode 100644 (file)
index 0000000..d198cca
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * freeglut_menu_mswin.c
+ *
+ * The Windows-specific mouse cursor related stuff.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Sun Jan 22, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define FREEGLUT_BUILDING_LIB
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+
+GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y )
+{
+    *x = glutGet ( GLUT_SCREEN_WIDTH );
+    *y = glutGet ( GLUT_SCREEN_HEIGHT );
+}
+
+
+
+/* -- PLATFORM-SPECIFIC INTERFACE FUNCTION -------------------------------------------------- */
+
+int FGAPIENTRY __glutCreateMenuWithExit( void(* callback)( int ), void (__cdecl *exit_function)(int) )
+{
+  __glutExitFunc = exit_function;
+  return glutCreateMenu( callback );
+}
+
diff --git a/src/mswin/fg_spaceball_mswin.c b/src/mswin/fg_spaceball_mswin.c
new file mode 100644 (file)
index 0000000..3a7af46
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * freeglut_spaceball_mswin.c
+ *
+ * Spaceball support for Windows
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by Evan Felix <karcaw at gmail.com>
+ * Creation date: Sat Feb 4, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * This code is a very complicated way of doing nothing.  
+ * But is needed for mswindows platform builds.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+void fgPlatformInitializeSpaceball(void)
+{
+       return;
+}
+
+void fgPlatformSpaceballClose(void)
+{
+       return;
+}
+
+int fgPlatformHasSpaceball(void)
+{
+       return 0;
+}
+
+int fgPlatformSpaceballNumButtons(void)
+{
+       return 0;
+}
+
+void fgPlatformSpaceballSetWindow(SFG_Window *window)
+{
+       return;
+}
diff --git a/src/mswin/fg_state_mswin.c b/src/mswin/fg_state_mswin.c
new file mode 100644 (file)
index 0000000..07ffdb1
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * freeglut_state_mswin.c
+ *
+ * The Windows-specific state query methods.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Sun Jan 22, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+
+extern GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
+                                     unsigned char layer_type );
+
+/* 
+ * Helper functions for getting client area from the window rect
+ * and the window rect from the client area given the style of the window
+ * (or a valid window pointer from which the style can be queried).
+ */
+extern RECT fghGetClientArea( const SFG_Window *window, BOOL wantPosOutside );
+extern void fghGetBorderWidth(const DWORD windowStyle, int* xBorderWidth, int* yBorderWidth);
+
+
+/* The following include file is available from SGI but is not standard:
+ *   #include <GL/wglext.h>
+ * So we copy the necessary parts out of it to support the multisampling query
+ */
+#define WGL_SAMPLES_ARB                0x2042
+
+#if defined(_WIN32_WCE)
+#   include <Aygshell.h>
+#   ifdef FREEGLUT_LIB_PRAGMAS
+#       pragma comment( lib, "Aygshell.lib" )
+#   endif
+#endif /* defined(_WIN32_WCE) */
+
+
+
+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;
+}
+
+
+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;
+}
+
+/*
+ * This is for querying the number of supported auxiliary or multisample
+ * buffers for a (the current?) display mode.
+ * see http://old.nabble.com/-GLX--glutGetModeValues-to13514723.html#a13514723
+ * Not currently implemented, but we should be able to query the relevant
+ * info using
+ * http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt
+ * (if supported on the executing machine!)
+ */
+int *fgPlatformGlutGetModeValues(GLenum eWhat, int *size)
+{
+  *size = 0;
+  return NULL;
+}
\ No newline at end of file
diff --git a/src/mswin/fg_structure_mswin.c b/src/mswin/fg_structure_mswin.c
new file mode 100644 (file)
index 0000000..8ccb33d
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * freeglut_structure_mswin.c
+ *
+ * The Windows-specific mouse cursor related stuff.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Sun Jan 22, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+
+void fgPlatformCreateWindow ( SFG_Window *window )
+{
+}
diff --git a/src/mswin/fg_window_mswin.c b/src/mswin/fg_window_mswin.c
new file mode 100644 (file)
index 0000000..6515063
--- /dev/null
@@ -0,0 +1,1078 @@
+/*
+ * freeglut_window_mswin.c
+ *
+ * The Windows-specific mouse cursor related stuff.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Sun Jan 22, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define FREEGLUT_BUILDING_LIB
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+
+/* The following include file is available from SGI but is not standard:
+ *   #include <GL/wglext.h>
+ * So we copy the necessary parts out of it.
+ * XXX: should local definitions for extensions be put in a separate include file?
+ */
+typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
+
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+
+#define WGL_DRAW_TO_WINDOW_ARB         0x2001
+#define WGL_ACCELERATION_ARB           0x2003
+#define WGL_SUPPORT_OPENGL_ARB         0x2010
+#define WGL_DOUBLE_BUFFER_ARB          0x2011
+#define WGL_COLOR_BITS_ARB             0x2014
+#define WGL_ALPHA_BITS_ARB             0x201B
+#define WGL_DEPTH_BITS_ARB             0x2022
+#define WGL_STENCIL_BITS_ARB           0x2023
+#define WGL_FULL_ACCELERATION_ARB      0x2027
+
+#define WGL_SAMPLE_BUFFERS_ARB         0x2041
+#define WGL_SAMPLES_ARB                0x2042
+
+#define WGL_TYPE_RGBA_FLOAT_ARB        0x21A0
+
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
+
+#ifndef WGL_ARB_create_context
+#define WGL_ARB_create_context 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HGLRC WINAPI wglCreateContextAttribsARB (HDC, HGLRC, const int *);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
+
+#define WGL_CONTEXT_MAJOR_VERSION_ARB  0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB  0x2092
+#define WGL_CONTEXT_LAYER_PLANE_ARB    0x2093
+#define WGL_CONTEXT_FLAGS_ARB          0x2094
+#define WGL_CONTEXT_PROFILE_MASK_ARB   0x9126
+
+#define WGL_CONTEXT_DEBUG_BIT_ARB      0x0001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+
+#define ERROR_INVALID_VERSION_ARB      0x2095
+#define ERROR_INVALID_PROFILE_ARB      0x2096
+#endif
+/* End of copying the necessary parts out of it. */
+
+#ifdef WM_TOUCH
+typedef BOOL (WINAPI *pRegisterTouchWindow)(HWND,ULONG);
+static pRegisterTouchWindow fghRegisterTouchWindow = (pRegisterTouchWindow)0xDEADBEEF;
+#endif
+
+/* 
+ * Helper functions for getting client area from the window rect
+ * and the window rect from the client area given the style of the window
+ * (or a valid window pointer from which the style can be queried).
+ */
+extern void fghGetBorderWidth(const DWORD windowStyle, int* xBorderWidth, int* yBorderWidth);
+
+
+/*
+ * Setup the pixel format for a Win32 window
+ */
+
+#if defined(_WIN32_WCE)
+static wchar_t* fghWstrFromStr(const char* str)
+{
+    int i,len=strlen(str);
+    wchar_t* wstr = (wchar_t*)malloc(2*len+2);
+    for(i=0; i<len; i++)
+        wstr[i] = str[i];
+    wstr[len] = 0;
+    return wstr;
+}
+#endif /* defined(_WIN32_WCE) */
+
+
+static void fghFillContextAttributes( int *attributes ) {
+  int where = 0, contextFlags, contextProfile;
+
+  if ( !fghIsLegacyContextVersionRequested() ) {
+    ATTRIB_VAL( WGL_CONTEXT_MAJOR_VERSION_ARB, fgState.MajorVersion );
+    ATTRIB_VAL( WGL_CONTEXT_MINOR_VERSION_ARB, fgState.MinorVersion );
+  }
+
+  contextFlags =
+    fghMapBit( fgState.ContextFlags, GLUT_DEBUG, WGL_CONTEXT_DEBUG_BIT_ARB ) |
+    fghMapBit( fgState.ContextFlags, GLUT_FORWARD_COMPATIBLE, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB );
+  if ( contextFlags != 0 ) {
+    ATTRIB_VAL( WGL_CONTEXT_FLAGS_ARB, contextFlags );
+  }
+
+  contextProfile =
+    fghMapBit( fgState.ContextProfile, GLUT_CORE_PROFILE, WGL_CONTEXT_CORE_PROFILE_BIT_ARB ) |
+    fghMapBit( fgState.ContextProfile, GLUT_COMPATIBILITY_PROFILE, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB );
+  if ( contextProfile != 0 ) {
+    ATTRIB_VAL( WGL_CONTEXT_PROFILE_MASK_ARB, contextProfile );
+  }
+
+  ATTRIB( 0 );
+}
+
+static int fghIsExtensionSupported( HDC hdc, const char *extension ) {
+    const char *pWglExtString;
+    PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetEntensionsStringARB =
+      (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
+    if ( wglGetEntensionsStringARB == NULL )
+    {
+      return FALSE;
+    }
+    pWglExtString = wglGetEntensionsStringARB( hdc );
+    return ( pWglExtString != NULL ) && ( strstr(pWglExtString, extension) != NULL );
+}
+
+void fgNewWGLCreateContext( SFG_Window* window )
+{
+    HGLRC context;
+    int attributes[9];
+    PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
+
+    /* If nothing fancy has been required, leave the context as it is */
+    if ( fghIsLegacyContextRequested() )
+    {
+        return;
+    }
+
+    wglMakeCurrent( window->Window.pContext.Device, window->Window.Context );
+
+    if ( !fghIsExtensionSupported( window->Window.pContext.Device, "WGL_ARB_create_context" ) )
+    {
+        return;
+    }
+
+    /* new context creation */
+    fghFillContextAttributes( attributes );
+
+    wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress( "wglCreateContextAttribsARB" );
+    if ( wglCreateContextAttribsARB == NULL )
+    {
+        fgError( "wglCreateContextAttribsARB not found" );
+    }
+
+    context = wglCreateContextAttribsARB( window->Window.pContext.Device, 0, attributes );
+    if ( context == NULL )
+    {
+        fghContextCreationError();
+    }
+
+    wglMakeCurrent( NULL, NULL );
+    wglDeleteContext( window->Window.Context );
+    window->Window.Context = context;
+}
+
+#if !defined(_WIN32_WCE)
+
+static void fghFillPFD( PIXELFORMATDESCRIPTOR *ppfd, HDC hdc, unsigned char layer_type )
+{
+  int flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
+  if ( fgState.DisplayMode & GLUT_DOUBLE ) {
+        flags |= PFD_DOUBLEBUFFER;
+  }
+  if ( fgState.DisplayMode & GLUT_STEREO ) {
+    flags |= PFD_STEREO;
+  }
+
+#if defined(_MSC_VER)
+#pragma message( "fgSetupPixelFormat(): there is still some work to do here!" )
+#endif
+
+  /* Specify which pixel format do we opt for... */
+  ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
+  ppfd->nVersion = 1;
+  ppfd->dwFlags = flags;
+
+  if( fgState.DisplayMode & GLUT_INDEX ) {
+    ppfd->iPixelType = PFD_TYPE_COLORINDEX;
+    ppfd->cRedBits = 0;
+    ppfd->cGreenBits = 0;
+    ppfd->cBlueBits = 0;
+    ppfd->cAlphaBits = 0;
+  } else {
+    ppfd->iPixelType = PFD_TYPE_RGBA;
+    ppfd->cRedBits = 8;
+    ppfd->cGreenBits = 8;
+    ppfd->cBlueBits = 8;
+    ppfd->cAlphaBits = ( fgState.DisplayMode & GLUT_ALPHA ) ? 8 : 0;
+  }
+
+  ppfd->cColorBits = 24;
+  ppfd->cRedShift = 0;
+  ppfd->cGreenShift = 0;
+  ppfd->cBlueShift = 0;
+  ppfd->cAlphaShift = 0;
+  ppfd->cAccumBits = ( fgState.DisplayMode & GLUT_ACCUM ) ? 1 : 0;
+  ppfd->cAccumRedBits = 0;
+  ppfd->cAccumGreenBits = 0;
+  ppfd->cAccumBlueBits = 0;
+  ppfd->cAccumAlphaBits = 0;
+
+  /* Hmmm, or 32/0 instead of 24/8? */
+  ppfd->cDepthBits = 24;
+  ppfd->cStencilBits = 8;
+
+  ppfd->cAuxBuffers = fghNumberOfAuxBuffersRequested();
+  ppfd->iLayerType = layer_type;
+  ppfd->bReserved = 0;
+  ppfd->dwLayerMask = 0;
+  ppfd->dwVisibleMask = 0;
+  ppfd->dwDamageMask = 0;
+  
+  ppfd->cColorBits = (BYTE) GetDeviceCaps( hdc, BITSPIXEL );
+}
+
+static void fghFillPixelFormatAttributes( int *attributes, const PIXELFORMATDESCRIPTOR *ppfd )
+{
+  int where = 0;
+
+  ATTRIB_VAL( WGL_DRAW_TO_WINDOW_ARB, GL_TRUE );
+  ATTRIB_VAL( WGL_SUPPORT_OPENGL_ARB, GL_TRUE );
+  ATTRIB_VAL( WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB );
+
+  ATTRIB_VAL( WGL_COLOR_BITS_ARB, ppfd->cColorBits );
+  ATTRIB_VAL( WGL_ALPHA_BITS_ARB, ppfd->cAlphaBits );
+  ATTRIB_VAL( WGL_DEPTH_BITS_ARB, ppfd->cDepthBits );
+  ATTRIB_VAL( WGL_STENCIL_BITS_ARB, ppfd->cStencilBits );
+
+  ATTRIB_VAL( WGL_DOUBLE_BUFFER_ARB, ( fgState.DisplayMode & GLUT_DOUBLE ) != 0 );
+
+  if ( fgState.DisplayMode & GLUT_SRGB ) {
+    ATTRIB_VAL( WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, TRUE );
+  }
+
+  ATTRIB_VAL( WGL_SAMPLE_BUFFERS_ARB, GL_TRUE );
+  ATTRIB_VAL( WGL_SAMPLES_ARB, fgState.SampleNumber );
+  ATTRIB( 0 );
+}
+#endif
+
+GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
+                              unsigned char layer_type )
+{
+#if defined(_WIN32_WCE)
+    return GL_TRUE;
+#else
+    PIXELFORMATDESCRIPTOR pfd;
+    PIXELFORMATDESCRIPTOR* ppfd = &pfd;
+    int pixelformat;
+    HDC current_hDC;
+    GLboolean success;
+
+    if (checkOnly)
+      current_hDC = CreateDC(TEXT("DISPLAY"), NULL ,NULL ,NULL);
+    else
+      current_hDC = window->Window.pContext.Device;
+
+    fghFillPFD( ppfd, current_hDC, layer_type );
+    pixelformat = ChoosePixelFormat( current_hDC, ppfd );
+
+    /* windows hack for multismapling/sRGB */
+    if ( ( fgState.DisplayMode & GLUT_MULTISAMPLE ) ||
+         ( fgState.DisplayMode & GLUT_SRGB ) )
+    {        
+        HGLRC rc, rc_before=wglGetCurrentContext();
+        HWND hWnd;
+        HDC hDC, hDC_before=wglGetCurrentDC();
+        WNDCLASS wndCls;
+
+        /* create a dummy window */
+        ZeroMemory(&wndCls, sizeof(wndCls));
+        wndCls.lpfnWndProc = DefWindowProc;
+        wndCls.hInstance = fgDisplay.pDisplay.Instance;
+        wndCls.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
+        wndCls.lpszClassName = _T("FREEGLUT_dummy");
+        RegisterClass( &wndCls );
+
+        hWnd=CreateWindow(_T("FREEGLUT_dummy"), _T(""), WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW , 0,0,0,0, 0, 0, fgDisplay.pDisplay.Instance, 0 );
+        hDC=GetDC(hWnd);
+        SetPixelFormat( hDC, pixelformat, ppfd );
+
+        rc = wglCreateContext( hDC );
+        wglMakeCurrent(hDC, rc);
+
+        if ( fghIsExtensionSupported( hDC, "WGL_ARB_multisample" ) )
+        {
+            PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARBProc =
+              (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");
+            if ( wglChoosePixelFormatARBProc )
+            {
+                int attributes[100];
+                int iPixelFormat;
+                BOOL bValid;
+                float fAttributes[] = { 0, 0 };
+                UINT numFormats;
+                fghFillPixelFormatAttributes( attributes, ppfd );
+                bValid = wglChoosePixelFormatARBProc(hDC, attributes, fAttributes, 1, &iPixelFormat, &numFormats);
+
+                if ( bValid && numFormats > 0 )
+                {
+                    pixelformat = iPixelFormat;
+                }
+            }
+        }
+
+        wglMakeCurrent( hDC_before, rc_before);
+        wglDeleteContext(rc);
+        ReleaseDC(hWnd, hDC);
+        DestroyWindow(hWnd);
+        UnregisterClass(_T("FREEGLUT_dummy"), fgDisplay.pDisplay.Instance);
+    }
+
+    success = ( pixelformat != 0 ) && ( checkOnly || SetPixelFormat( current_hDC, pixelformat, ppfd ) );
+
+    if (checkOnly)
+        DeleteDC(current_hDC);
+
+    return success;
+#endif /* defined(_WIN32_WCE) */
+}
+
+
+
+void fgPlatformSetWindow ( SFG_Window *window )
+{
+    if ( window != fgStructure.CurrentWindow )
+    {
+        if( fgStructure.CurrentWindow )
+            ReleaseDC( fgStructure.CurrentWindow->Window.Handle,
+                       fgStructure.CurrentWindow->Window.pContext.Device );
+
+        if ( window )
+        {
+            window->Window.pContext.Device = GetDC( window->Window.Handle );
+            wglMakeCurrent(
+                window->Window.pContext.Device,
+                window->Window.Context
+            );
+        }
+    }
+}
+
+
+
+/* Computes position of corners of window Rect (outer position including
+ * decorations) based on the provided client rect and based on the style
+ * of the window in question.
+ * If posIsOutside is set to true, the input client Rect is taken to follow
+ * freeGLUT's window specification convention in which the top-left corner
+ * is at the outside of the window, while the size
+ * (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable
+ * area.
+ */
+void fghComputeWindowRectFromClientArea_UseStyle( const DWORD windowStyle, RECT *clientRect, BOOL posIsOutside )
+{
+    int xBorderWidth = 0, yBorderWidth = 0;
+
+    /* If window has title bar, correct rect for it */
+    if (windowStyle & WS_MAXIMIZEBOX) /* 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... */
+        if (posIsOutside)
+            clientRect->bottom += GetSystemMetrics( SM_CYCAPTION );
+        else
+            clientRect->top -= GetSystemMetrics( SM_CYCAPTION );
+
+    /* get width of window's borders (frame), correct rect for it.
+     * Note, borders can be of zero width if style does not specify borders
+     */
+    fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth);
+    if (posIsOutside)
+    {
+        clientRect->right  += xBorderWidth * 2;
+        clientRect->bottom += yBorderWidth * 2;
+    }
+    else
+    {
+        clientRect->left   -= xBorderWidth;
+        clientRect->right  += xBorderWidth;
+        clientRect->top    -= yBorderWidth;
+        clientRect->bottom += yBorderWidth;
+    }
+}
+
+/* Computes position of corners of window Rect (outer position including
+ * decorations) based on the provided client rect and based on the style
+ * of the window in question. If the window pointer or the window handle
+ * is NULL, a fully decorated window (caption and border) is assumed.
+ * Furthermore, if posIsOutside is set to true, the input client Rect is
+ * taken to follow freeGLUT's window specification convention in which the
+ * top-left corner is at the outside of the window, while the size
+ * (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable
+ * area.
+*/
+void fghComputeWindowRectFromClientArea_QueryWindow( const SFG_Window *window, RECT *clientRect, BOOL posIsOutside )
+{
+    DWORD windowStyle = 0;
+
+    if (window && window->Window.Handle)
+        windowStyle = GetWindowLong(window->Window.Handle, GWL_STYLE);
+    else
+        windowStyle = WS_OVERLAPPEDWINDOW;
+
+    fghComputeWindowRectFromClientArea_UseStyle(windowStyle, clientRect, posIsOutside);
+}
+
+/* Computes position of corners of client area (drawable area) of a window
+ * based on the provided window Rect (outer position including decorations)
+ * and based on the style of the window in question. If the window pointer
+ * or the window handle is NULL, a fully decorated window (caption and
+ * border) is assumed.
+ * Furthermore, if wantPosOutside is set to true, the output client Rect
+ * will follow freeGLUT's window specification convention in which the
+ * top-left corner is at the outside of the window, the size
+ * (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable
+ * area.
+ */
+void fghComputeClientAreaFromWindowRect( const SFG_Window *window, RECT *windowRect, BOOL wantPosOutside )
+{
+    DWORD windowStyle = 0;
+    int xBorderWidth = 0, yBorderWidth = 0;
+
+    if (window && window->Window.Handle)
+        windowStyle = GetWindowLong(window->Window.Handle, GWL_STYLE);
+    else
+        windowStyle = WS_OVERLAPPEDWINDOW;
+
+    /* If window has title bar, correct rect for it */
+    if (windowStyle & WS_MAXIMIZEBOX) /* 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... */
+        if (wantPosOutside)
+            windowRect->bottom -= GetSystemMetrics( SM_CYCAPTION );
+        else
+            windowRect->top    += GetSystemMetrics( SM_CYCAPTION );
+
+    /* get width of window's borders (frame), correct rect for it.
+     * Note, borders can be of zero width if style does not specify borders
+     */
+    fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth);
+    if (wantPosOutside)
+    {
+        windowRect->right  -= xBorderWidth * 2;
+        windowRect->bottom -= yBorderWidth * 2;
+    }
+    else
+    {
+        windowRect->left   += xBorderWidth;
+        windowRect->right  -= xBorderWidth;
+        windowRect->top    += yBorderWidth;
+        windowRect->bottom -= yBorderWidth;
+    }
+}
+
+/* Gets the rect describing the client area (drawable area) of the
+ * specified window.
+ * Returns an empty rect if window pointer or window handle is NULL.
+ * If wantPosOutside is set to true, the output client Rect
+ * will follow freeGLUT's window specification convention in which the
+ * top-left corner is at the outside of the window, while the size
+ * (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable
+ * area.
+ */
+RECT fghGetClientArea( const SFG_Window *window, BOOL wantPosOutside )
+{
+    RECT windowRect = {0,0,0,0};
+
+    freeglut_return_val_if_fail((window && window->Window.Handle),windowRect);
+    
+    /*
+     * call GetWindowRect()
+     * (this returns the pixel coordinates of the outside of the window)
+     */
+    GetWindowRect( window->Window.Handle, &windowRect );
+
+    /* Then correct the results */
+    fghComputeClientAreaFromWindowRect(window, &windowRect, wantPosOutside);
+
+    return windowRect;
+}
+
+/* Returns the width of the window borders based on the window's style.
+ */
+void fghGetBorderWidth(const DWORD windowStyle, int* xBorderWidth, int* yBorderWidth)
+{
+    if (windowStyle & WS_THICKFRAME)
+    {
+        *xBorderWidth = GetSystemMetrics(SM_CXSIZEFRAME);
+        *yBorderWidth = GetSystemMetrics(SM_CYSIZEFRAME);
+    }
+    else if (windowStyle & WS_DLGFRAME)
+    {
+        *xBorderWidth = GetSystemMetrics(SM_CXFIXEDFRAME);
+        *yBorderWidth = GetSystemMetrics(SM_CYFIXEDFRAME);
+    }
+    else
+    {
+        *xBorderWidth = 0;
+        *yBorderWidth = 0;
+    }
+}
+
+#if(WINVER >= 0x500)
+typedef struct
+{
+      int *x;
+      int *y;
+      const char *name;
+} m_proc_t;
+
+static BOOL CALLBACK m_proc(HMONITOR mon,
+                           HDC hdc,
+                           LPRECT rect,
+                           LPARAM data)
+{
+      m_proc_t *dp=(m_proc_t *)data;
+      MONITORINFOEX info;
+      BOOL res;
+      info.cbSize=sizeof(info);
+      res=GetMonitorInfo(mon,(LPMONITORINFO)&info);
+      if( res )
+      {
+          if( strcmp(dp->name,info.szDevice)==0 )
+          {
+              *(dp->x)=info.rcMonitor.left;
+              *(dp->y)=info.rcMonitor.top;
+              return FALSE;
+          }
+      }
+      return TRUE;
+}
+
+/* 
+ * this function returns the origin of the screen identified by
+ * fgDisplay.pDisplay.DisplayName, and 0 otherwise.
+ * This is used in fgOpenWindow to open the gamemode window on the screen
+ * identified by the -display command line argument. The function should
+ * not be called otherwise.
+ */
+
+static void get_display_origin(int *xp,int *yp)
+{
+    *xp = 0;
+    *yp = 0;
+
+    if( fgDisplay.pDisplay.DisplayName )
+    {
+        m_proc_t st;
+        st.x=xp;
+        st.y=yp;
+        st.name=fgDisplay.pDisplay.DisplayName;
+        EnumDisplayMonitors(0,0,m_proc,(LPARAM)&st);
+    }
+}
+#else
+#pragma message( "-display parameter only works if compiled with WINVER >= 0x0500")
+
+static void get_display_origin(int *xp,int *yp)
+{
+    *xp = 0;
+    *yp = 0;
+
+    if( fgDisplay.pDisplay.DisplayName )
+    {
+        fgWarning( "for working -display support FreeGLUT must be compiled with WINVER >= 0x0500");
+    }
+}
+#endif
+
+
+
+/*
+ * Opens a window. Requires a SFG_Window object created and attached
+ * to the freeglut structure. OpenGL context is created here.
+ */
+void fgPlatformOpenWindow( SFG_Window* window, const char* title,
+                           GLboolean positionUse, int x, int y,
+                           GLboolean sizeUse, int w, int h,
+                           GLboolean gameMode, GLboolean isSubWindow )
+{
+
+    WNDCLASS wc;
+    DWORD flags   = 0;
+    DWORD exFlags = 0;
+    ATOM atom;
+
+    /* Grab the window class we have registered on glutInit(): */
+    atom = GetClassInfo( fgDisplay.pDisplay.Instance, _T("FREEGLUT"), &wc );
+    FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Info Not Found",
+                                   "fgOpenWindow" );
+
+    /* Determine window style flags*/
+    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
+    {
+        flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
+
+        /*
+         * There's a small difference between creating the top, child and
+         * menu windows
+         */
+        if ( window->IsMenu )
+        {
+            flags |= WS_POPUP;
+            exFlags |= WS_EX_TOOLWINDOW;
+        }
+#if defined(_WIN32_WCE)
+        /* no decorations for windows CE */
+#else
+        /* if this is not a subwindow (child), set its style based on the requested display mode */
+        else if( window->Parent == NULL )
+            if ( fgState.DisplayMode & GLUT_BORDERLESS )
+            {
+                /* no window decorations needed */
+            }
+            else if ( fgState.DisplayMode & GLUT_CAPTIONLESS )
+                /* only window decoration is a border, no title bar or buttons */
+                flags |= WS_DLGFRAME;
+            else
+                /* window decoration are a border, title bar and buttons.
+                 * NB: we later query whether the window has a title bar or
+                 * not by testing for the maximize button, as the test for
+                 * WS_CAPTION can be true without the window having a title
+                 * bar. This style WS_OVERLAPPEDWINDOW gives you a maximize
+                 * button. */
+                flags |= WS_OVERLAPPEDWINDOW;
+#endif
+        else
+            /* subwindows always have no decoration, but are marked as a child window to the OS */
+            flags |= WS_CHILD;
+    }
+
+    /* determine window size and position */
+    if( gameMode )
+    {
+        /* if in gamemode, query the origin of specified by the -display
+         * command line parameter (if any) and offset the upper-left corner
+         * of the window so we create the window on that screen.
+         * The -display argument doesn't do anything if not trying to enter
+         * gamemode.
+         */
+        int xoff=0, yoff=0;
+        get_display_origin(&xoff,&yoff);
+        x += xoff;
+        y += yoff;
+    }
+    if( !positionUse )
+    {
+        x = CW_USEDEFAULT;
+        y = CW_USEDEFAULT;
+    }
+    if( !sizeUse )
+    {
+        if( ! window->IsMenu )
+        {
+            w = CW_USEDEFAULT;
+            h = CW_USEDEFAULT;
+        }
+        else /* fail safe - Windows can make a window of size (0, 0) */
+            w = h = 300; /* default window size */
+    }
+    /* store requested client area width and height */
+    window->State.Width = w;
+    window->State.Height = h;
+
+#if !defined(_WIN32_WCE)    /* no decorations for windows CE */
+    if( sizeUse )
+    {
+        RECT windowRect;
+        /*
+         * Update the window dimensions, taking the window decorations
+         * into account.  FreeGLUT is to create the window with the
+         * topleft outside corner at (x,y) and with client area
+         * dimensions (w,h).
+         * note: don't need to do this when w=h=CW_USEDEFAULT, so in the
+         * if( sizeUse ) here is convenient.
+         */
+        windowRect.left     = x;
+        windowRect.top      = y;
+        windowRect.right    = x+w;
+        windowRect.bottom   = y+h;
+
+        fghComputeWindowRectFromClientArea_UseStyle(flags,&windowRect,TRUE);
+
+        w = windowRect.right - windowRect.left;
+        h = windowRect.bottom- windowRect.top;
+    }
+#endif /* !defined(_WIN32_WCE) */
+
+#if defined(_WIN32_WCE)
+    {
+        wchar_t* wstr = fghWstrFromStr(title);
+
+        window->Window.Handle = CreateWindow(
+            _T("FREEGLUT"),
+            wstr,
+            WS_VISIBLE | WS_POPUP,
+            0,0, 240,320,
+            NULL,
+            NULL,
+            fgDisplay.pDisplay.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 = CreateWindowEx(
+        exFlags,
+        _T("FREEGLUT"),
+        title,
+        flags,
+        x, y, w, h,
+        (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle,
+        (HMENU) NULL,
+        fgDisplay.pDisplay.Instance,
+        (LPVOID) window
+    );
+#endif /* defined(_WIN32_WCE) */
+
+    if( !( window->Window.Handle ) )
+        fgError( "Failed to create a window (%s)!", title );
+
+#if !defined(_WIN32_WCE)
+    /* Need to set requested style again, apparently Windows doesn't listen when requesting windows without title bar or borders */
+    SetWindowLong(window->Window.Handle, GWL_STYLE, flags);
+    SetWindowPos(window->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
+#endif /* defined(_WIN32_WCE) */
+
+    /* Make a menu window always on top - fix Feature Request 947118 */
+    if( window->IsMenu || gameMode )
+        SetWindowPos(
+                        window->Window.Handle,
+                        HWND_TOPMOST,
+                        0, 0, 0, 0,
+                        SWP_NOMOVE | SWP_NOSIZE
+                    );
+
+    /* Enable multitouch: additional flag TWF_FINETOUCH, TWF_WANTPALM */
+    #ifdef WM_TOUCH
+        if (fghRegisterTouchWindow == (pRegisterTouchWindow)0xDEADBEEF) 
+                       fghRegisterTouchWindow = (pRegisterTouchWindow)GetProcAddress(GetModuleHandle("user32"),"RegisterTouchWindow");
+               if (fghRegisterTouchWindow)
+             fghRegisterTouchWindow( window->Window.Handle, TWF_FINETOUCH | TWF_WANTPALM );
+    #endif
+
+#if defined(_WIN32_WCE)
+    ShowWindow( window->Window.Handle, SW_SHOW );
+#else
+    ShowWindow( window->Window.Handle,
+                fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW );
+#endif /* defined(_WIN32_WCE) */
+
+    UpdateWindow( window->Window.Handle );
+    ShowCursor( TRUE );  /* XXX Old comments say "hide cursor"! */
+
+}
+
+
+/*
+ * Closes a window, destroying the frame and OpenGL context
+ */
+void fgPlatformCloseWindow( SFG_Window* window )
+{
+    /* Make sure we don't close a window with current context active */
+    if( fgStructure.CurrentWindow == window )
+        wglMakeCurrent( NULL, NULL );
+
+    /*
+     * Step through the list of windows.  If the rendering context
+     * is not being used by another window, then we delete it.
+     */
+    {
+        int used = FALSE ;
+        SFG_Window *iter ;
+
+        for( iter = (SFG_Window *)fgStructure.Windows.First;
+             iter;
+             iter = (SFG_Window *)iter->Node.Next )
+        {
+            if( ( iter->Window.Context == window->Window.Context ) &&
+                ( iter != window ) )
+                used = TRUE;
+        }
+
+        if( ! used )
+            wglDeleteContext( window->Window.Context );
+    }
+
+    DestroyWindow( window->Window.Handle );
+}
+
+
+
+/*
+ * This function makes the current window visible
+ */
+void fgPlatformGlutShowWindow( void )
+{
+    ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_SHOW );
+}
+
+/*
+ * This function hides the current window
+ */
+void fgPlatformGlutHideWindow( void )
+{
+    ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_HIDE );
+}
+
+/*
+ * Iconify the current window (top-level windows only)
+ */
+void fgPlatformGlutIconifyWindow( void )
+{
+    ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_MINIMIZE );
+}
+
+/*
+ * Set the current window's title
+ */
+void fgPlatformGlutSetWindowTitle( const char* title )
+{
+#ifdef _WIN32_WCE
+    {
+        wchar_t* wstr = fghWstrFromStr(title);
+        SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr );
+        free(wstr);
+    }
+#else
+    SetWindowText( fgStructure.CurrentWindow->Window.Handle, title );
+#endif
+}
+
+/*
+ * Set the current window's iconified title
+ */
+void fgPlatformGlutSetIconTitle( const char* title )
+{
+#ifdef _WIN32_WCE
+    {
+        wchar_t* wstr = fghWstrFromStr(title);
+        SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr );
+        free(wstr);
+    }
+#else
+    SetWindowText( fgStructure.CurrentWindow->Window.Handle, title );
+#endif
+}
+
+/*
+ * Change the current window's position
+ */
+void fgPlatformGlutPositionWindow( int x, int y )
+{
+    RECT winRect;
+
+    /* "GetWindowRect" returns the pixel coordinates of the outside of the window */
+    GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect );
+    MoveWindow(
+        fgStructure.CurrentWindow->Window.Handle,
+        x,
+        y,
+        winRect.right - winRect.left,
+        winRect.bottom - winRect.top,
+        TRUE
+    );
+}
+
+/*
+ * Lowers the current window (by Z order change)
+ */
+void fgPlatformGlutPushWindow( void )
+{
+    SetWindowPos(
+        fgStructure.CurrentWindow->Window.Handle,
+        HWND_BOTTOM,
+        0, 0, 0, 0,
+        SWP_NOSIZE | SWP_NOMOVE
+    );
+}
+
+/*
+ * Raises the current window (by Z order change)
+ */
+void fgPlatformGlutPopWindow( void )
+{
+    SetWindowPos(
+        fgStructure.CurrentWindow->Window.Handle,
+        HWND_TOP,
+        0, 0, 0, 0,
+        SWP_NOSIZE | SWP_NOMOVE
+    );
+}
+
+/*
+ * Resize the current window so that it fits the whole screen
+ */
+void fgPlatformGlutFullScreen( SFG_Window *win )
+{
+#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */
+
+    if (glutGet(GLUT_FULL_SCREEN))
+    {
+        /*  Leave full screen state before entering fullscreen again (resizing?) */
+        glutLeaveFullScreen();
+    }
+
+    {
+#if(WINVER >= 0x0500) /* Windows 2000 or later */
+        DWORD s;
+        RECT rect;
+        HMONITOR hMonitor;
+        MONITORINFO mi;
+
+        /* For fullscreen mode, first remove all window decoration
+         * and set style to popup so it will overlap the taskbar
+         * then force to maximize on the screen on which it has the most
+         * overlap.
+         */
+
+        
+        /* store current window rect */
+        GetWindowRect( win->Window.Handle, &win->State.pWState.OldRect );
+
+        /* store current window style */
+        win->State.pWState.OldStyle = s = GetWindowLong(win->Window.Handle, GWL_STYLE);
+
+        /* remove decorations from style and add popup style*/
+        s &= ~WS_OVERLAPPEDWINDOW;
+        s |= WS_POPUP;
+        SetWindowLong(win->Window.Handle, GWL_STYLE, s);
+        SetWindowPos(win->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
+
+        /* For fullscreen mode, find the monitor that is covered the most
+         * by the window and get its rect as the resize target.
+            */
+        hMonitor= MonitorFromRect(&win->State.pWState.OldRect, MONITOR_DEFAULTTONEAREST);
+        mi.cbSize = sizeof(mi);
+        GetMonitorInfo(hMonitor, &mi);
+        rect = mi.rcMonitor;
+#else   /* if (WINVER >= 0x0500) */
+        RECT rect;
+
+        /* For fullscreen mode, force the top-left corner to 0,0
+         * and adjust the window rectangle so that the client area
+         * covers the whole screen.
+         */
+
+        rect.left   = 0;
+        rect.top    = 0;
+        rect.right  = fgDisplay.ScreenWidth;
+        rect.bottom = fgDisplay.ScreenHeight;
+
+        AdjustWindowRect ( &rect, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |
+                                  WS_CLIPCHILDREN, FALSE );
+#endif  /* (WINVER >= 0x0500) */
+
+        /*
+         * then resize window
+         * SWP_NOACTIVATE     Do not activate the window
+         * SWP_NOOWNERZORDER  Do not change position in z-order
+         * SWP_NOSENDCHANGING Suppress WM_WINDOWPOSCHANGING message
+         * SWP_NOZORDER       Retains the current Z order (ignore 2nd param)
+         */
+        SetWindowPos( fgStructure.CurrentWindow->Window.Handle,
+                      HWND_TOP,
+                      rect.left,
+                      rect.top,
+                      rect.right  - rect.left,
+                      rect.bottom - rect.top,
+                      SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING |
+                      SWP_NOZORDER
+                    );
+
+        win->State.IsFullscreen = GL_TRUE;
+    }
+#endif
+}
+
+/*
+ * If we are fullscreen, resize the current window back to its original size
+ */
+void fgPlatformGlutLeaveFullScreen( SFG_Window *win )
+{
+#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */
+    if (!glutGet(GLUT_FULL_SCREEN))
+    {
+        /* nothing to do */
+        return;
+    }
+
+    /* restore style of window before making it fullscreen */
+    SetWindowLong(win->Window.Handle, GWL_STYLE, win->State.pWState.OldStyle);
+    SetWindowPos(win->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
+
+    /* Then resize */
+    SetWindowPos(win->Window.Handle,
+        HWND_TOP,
+        win->State.pWState.OldRect.left,
+        win->State.pWState.OldRect.top,
+        win->State.pWState.OldRect.right  - win->State.pWState.OldRect.left,
+        win->State.pWState.OldRect.bottom - win->State.pWState.OldRect.top,
+        SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING |
+        SWP_NOZORDER
+        );
+
+    win->State.IsFullscreen = GL_FALSE;
+#endif
+}
+
+/*
+ * Toggle the window's full screen state.
+ */
+void fgPlatformGlutFullScreenToggle( SFG_Window *win )
+{
+    if (!win->State.IsFullscreen)
+        glutFullScreen();
+    else
+        glutLeaveFullScreen();
+}
+
+
+/* -- PLATFORM-SPECIFIC INTERFACE FUNCTION -------------------------------------------------- */
+
+int FGAPIENTRY __glutCreateWindowWithExit( const char *title, void (__cdecl *exit_function)(int) )
+{
+  __glutExitFunc = exit_function;
+  return glutCreateWindow( title );
+}
+
diff --git a/src/mswin/freeglut_cursor_mswin.c b/src/mswin/freeglut_cursor_mswin.c
deleted file mode 100644 (file)
index b0eda70..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * freeglut_cursor_mswin.c
- *
- * The Windows-specific mouse cursor related stuff.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Thu Jan 19, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-
-
-void fgPlatformSetCursor ( SFG_Window *window, int cursorID )
-{
-    /*
-     * Joe Krahn is re-writing the following code.
-     */
-    /* Set the cursor AND change it for this window class. */
-#if !defined(__MINGW64__) && _MSC_VER <= 1200
-#       define MAP_CURSOR(a,b)                                   \
-        case a:                                                  \
-            SetCursor( LoadCursor( NULL, b ) );                  \
-            SetClassLong( window->Window.Handle,                 \
-                          GCL_HCURSOR,                           \
-                          ( LONG )LoadCursor( NULL, b ) );       \
-        break;
-    /* Nuke the cursor AND change it for this window class. */
-#       define ZAP_CURSOR(a,b)                                   \
-        case a:                                                  \
-            SetCursor( NULL );                                   \
-            SetClassLong( window->Window.Handle,                 \
-                          GCL_HCURSOR, ( LONG )NULL );           \
-        break;
-#else
-#       define MAP_CURSOR(a,b)                                   \
-        case a:                                                  \
-            SetCursor( LoadCursor( NULL, b ) );                  \
-            SetClassLongPtr( window->Window.Handle,              \
-                          GCLP_HCURSOR,                          \
-                          ( LONG )( LONG_PTR )LoadCursor( NULL, b ) );       \
-        break;
-    /* Nuke the cursor AND change it for this window class. */
-#       define ZAP_CURSOR(a,b)                                   \
-        case a:                                                  \
-            SetCursor( NULL );                                   \
-            SetClassLongPtr( window->Window.Handle,              \
-                          GCLP_HCURSOR, ( LONG )( LONG_PTR )NULL );          \
-        break;
-#endif
-
-    switch( cursorID )
-    {
-        MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW,         IDC_ARROW     );
-        MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW,          IDC_ARROW     );
-        MAP_CURSOR( GLUT_CURSOR_INFO,                IDC_HELP      );
-        MAP_CURSOR( GLUT_CURSOR_DESTROY,             IDC_CROSS     );
-        MAP_CURSOR( GLUT_CURSOR_HELP,                IDC_HELP      );
-        MAP_CURSOR( GLUT_CURSOR_CYCLE,               IDC_SIZEALL   );
-        MAP_CURSOR( GLUT_CURSOR_SPRAY,               IDC_CROSS     );
-        MAP_CURSOR( GLUT_CURSOR_WAIT,                IDC_WAIT      );
-        MAP_CURSOR( GLUT_CURSOR_TEXT,                IDC_IBEAM     );
-        MAP_CURSOR( GLUT_CURSOR_CROSSHAIR,           IDC_CROSS     );
-        MAP_CURSOR( GLUT_CURSOR_UP_DOWN,             IDC_SIZENS    );
-        MAP_CURSOR( GLUT_CURSOR_LEFT_RIGHT,          IDC_SIZEWE    );
-        MAP_CURSOR( GLUT_CURSOR_TOP_SIDE,            IDC_ARROW     ); /* XXX ToDo */
-        MAP_CURSOR( GLUT_CURSOR_BOTTOM_SIDE,         IDC_ARROW     ); /* XXX ToDo */
-        MAP_CURSOR( GLUT_CURSOR_LEFT_SIDE,           IDC_ARROW     ); /* XXX ToDo */
-        MAP_CURSOR( GLUT_CURSOR_RIGHT_SIDE,          IDC_ARROW     ); /* XXX ToDo */
-        MAP_CURSOR( GLUT_CURSOR_TOP_LEFT_CORNER,     IDC_SIZENWSE  );
-        MAP_CURSOR( GLUT_CURSOR_TOP_RIGHT_CORNER,    IDC_SIZENESW  );
-        MAP_CURSOR( GLUT_CURSOR_BOTTOM_RIGHT_CORNER, IDC_SIZENWSE  );
-        MAP_CURSOR( GLUT_CURSOR_BOTTOM_LEFT_CORNER,  IDC_SIZENESW  );
-        MAP_CURSOR( GLUT_CURSOR_INHERIT,             IDC_ARROW     ); /* XXX ToDo */
-        ZAP_CURSOR( GLUT_CURSOR_NONE,                NULL          );
-        MAP_CURSOR( GLUT_CURSOR_FULL_CROSSHAIR,      IDC_CROSS     ); /* XXX ToDo */
-
-    default:
-        fgError( "Unknown cursor type: %d", cursorID );
-        break;
-    }
-}
-
-
-void fgPlatformWarpPointer ( int x, int y )
-{
-    POINT coords;
-    coords.x = x;
-    coords.y = y;
-
-    /* ClientToScreen() translates {coords} for us. */
-    ClientToScreen( fgStructure.CurrentWindow->Window.Handle, &coords );
-    SetCursorPos( coords.x, coords.y );
-}
-
-
diff --git a/src/mswin/freeglut_display_mswin.c b/src/mswin/freeglut_display_mswin.c
deleted file mode 100644 (file)
index 6a58412..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * freeglut_display_mswin.c
- *
- * The Windows-specific mouse cursor related stuff.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Sat Jan 28, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-
-
-
-void fgPlatformGlutSwapBuffers( SFG_PlatformDisplay *pDisplayPtr, SFG_Window* CurrentWindow )
-{
-    SwapBuffers( CurrentWindow->Window.pContext.Device );
-}
diff --git a/src/mswin/freeglut_ext_mswin.c b/src/mswin/freeglut_ext_mswin.c
deleted file mode 100644 (file)
index efc2fa9..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * freeglut_ext_mswin.c
- *
- * The Windows-specific mouse cursor related stuff.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Thu Jan 19, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-GLUTproc fgPlatformGetGLUTProcAddress( const char* procName )
-{
-#if !defined(_WIN32_WCE)
-    /* optimization: quick initial check */
-    if( strncmp( procName, "glut", 4 ) != 0 )
-        return NULL;
-
-#define CHECK_NAME(x) if( strcmp( procName, #x ) == 0) return (GLUTproc)x;
-    CHECK_NAME(glutJoystickFunc);
-    CHECK_NAME(glutForceJoystickFunc);
-    CHECK_NAME(glutGameModeString);
-    CHECK_NAME(glutEnterGameMode);
-    CHECK_NAME(glutLeaveGameMode);
-    CHECK_NAME(glutGameModeGet);
-#undef CHECK_NAME
-#endif /* !defined(_WIN32_WCE) */
-
-    return NULL;
-}
-
-
-
-SFG_Proc fgPlatformGetProcAddress( const char *procName )
-{
-    return (SFG_Proc)wglGetProcAddress( ( LPCSTR )procName );
-}
diff --git a/src/mswin/freeglut_gamemode_mswin.c b/src/mswin/freeglut_gamemode_mswin.c
deleted file mode 100644 (file)
index 3e5228d..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * freeglut_gamemode_mswin.c
- *
- * The Windows-specific mouse cursor related stuff.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Thu Jan 19, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-/*
- * Remembers the current visual settings, so that
- * we can change them and restore later...
- */
-void fgPlatformRememberState( void )
-{
-    /* Grab the current desktop settings... */
-
-    /* hack to get around my stupid cross-gcc headers */
-    #define FREEGLUT_ENUM_CURRENT_SETTINGS -1
-
-    EnumDisplaySettings( fgDisplay.pDisplay.DisplayName, FREEGLUT_ENUM_CURRENT_SETTINGS,
-                         &fgDisplay.pDisplay.DisplayMode );
-
-    /* Make sure we will be restoring all settings needed */
-    fgDisplay.pDisplay.DisplayMode.dmFields |=
-        DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
-
-}
-
-/*
- * Restores the previously remembered visual settings
- */
-void fgPlatformRestoreState( void )
-{
-    /* Restore the previously remembered desktop display settings */
-    ChangeDisplaySettingsEx( fgDisplay.pDisplay.DisplayName,&fgDisplay.pDisplay.DisplayMode, 0,0,0 );
-}
-
-
-
-
-/*
- * Changes the current display mode to match user's settings
- */
-GLboolean fgPlatformChangeDisplayMode( GLboolean haveToTest )
-{
-    GLboolean success = GL_FALSE;
-    DEVMODE  devMode;
-    char *fggmstr = NULL;
-    char displayMode[300];
-
-    success = GL_FALSE;
-
-    EnumDisplaySettings( fgDisplay.pDisplay.DisplayName, -1, &devMode ); 
-    devMode.dmFields = 0;
-
-    if (fgState.GameModeSize.X!=-1)
-    {
-        devMode.dmPelsWidth  = fgState.GameModeSize.X;
-        devMode.dmFields |= DM_PELSWIDTH;
-    }
-    if (fgState.GameModeSize.Y!=-1)
-    {
-        devMode.dmPelsHeight  = fgState.GameModeSize.Y;
-        devMode.dmFields |= DM_PELSHEIGHT;
-    }
-    if (fgState.GameModeDepth!=-1)
-    {
-        devMode.dmBitsPerPel  = fgState.GameModeDepth;
-        devMode.dmFields |= DM_BITSPERPEL;
-    }
-    if (fgState.GameModeRefresh!=-1)
-    {
-        devMode.dmDisplayFrequency  = fgState.GameModeRefresh;
-        devMode.dmFields |= DM_DISPLAYFREQUENCY;
-    }
-
-    switch ( ChangeDisplaySettingsEx(fgDisplay.pDisplay.DisplayName, &devMode, NULL, haveToTest ? CDS_TEST : CDS_FULLSCREEN , NULL) )
-    {
-    case DISP_CHANGE_SUCCESSFUL:
-        success = GL_TRUE;
-
-        if (!haveToTest)
-        {
-            /* update vars in case if windows switched to proper mode */
-            EnumDisplaySettings( fgDisplay.pDisplay.DisplayName, 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 )
-    {
-        /* 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 ;) */
-        
-        /* append display mode to error to make things more informative */
-        sprintf(displayMode,"%s Problem with requested mode: %ix%i:%i@%i", fggmstr, devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmBitsPerPel, devMode.dmDisplayFrequency);
-        fgWarning(displayMode);
-    }
-
-    return success;
-}
-
-void fgPlatformEnterGameMode( void ) 
-{
-}
-
-void fgPlatformLeaveGameMode( void ) 
-{
-}
diff --git a/src/mswin/freeglut_init_mswin.c b/src/mswin/freeglut_init_mswin.c
deleted file mode 100644 (file)
index f80fe78..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * freeglut_init_mswin.c
- *
- * The Windows-specific mouse cursor related stuff.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Thu Jan 19, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#define FREEGLUT_BUILDING_LIB
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-
-
-extern LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg,
-                               WPARAM wParam, LPARAM lParam );
-
-
-/*
- * A call to this function should initialize all the display stuff...
- */
-void fgPlatformInitialize( const char* displayName )
-{
-    WNDCLASS wc;
-    ATOM atom;
-
-    /* What we need to do is to initialize the fgDisplay global structure here. */
-    fgDisplay.pDisplay.Instance = GetModuleHandle( NULL );
-    fgDisplay.pDisplay.DisplayName= displayName ? strdup(displayName) : 0 ;
-    atom = GetClassInfo( fgDisplay.pDisplay.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    = fgPlatformWindowProc;
-        wc.cbClsExtra     = 0;
-        wc.cbWndExtra     = 0;
-        wc.hInstance      = fgDisplay.pDisplay.Instance;
-        wc.hIcon          = LoadIcon( fgDisplay.pDisplay.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", "fgPlatformInitialize" );
-    }
-
-    /* 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.pDisplay.DisplayName )
-    {
-        HDC context = CreateDC(fgDisplay.pDisplay.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("fgPlatformInitialize: "
-                     "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 );
-
-
-    fgState.Initialised = GL_TRUE;
-
-    /* Avoid registering atexit callback on Win32 as it can result 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.
-     * see: http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx
-     */
-/*    atexit(fgDeinitialize); */
-
-    /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */
-    fgInitialiseInputDevices();
-}
-
-
-
-/* Platform-Specific Deinitialization Functions: */
-extern void fghCloseInputDevices ( void );
-
-void fgPlatformDeinitialiseInputDevices ( void )
-{
-#if !defined(_WIN32_WCE)
-       fghCloseInputDevices ();
-#endif /* !defined(_WIN32_WCE) */
-    fgState.JoysticksInitialised = GL_FALSE;
-    fgState.InputDevsInitialised = GL_FALSE;
-}
-
-void fgPlatformCloseDisplay ( void )
-{
-    if( fgDisplay.pDisplay.DisplayName )
-    {
-        free( fgDisplay.pDisplay.DisplayName );
-        fgDisplay.pDisplay.DisplayName = NULL;
-    }
-
-    /* Reset the timer granularity */
-    timeEndPeriod ( 1 );
-}
-
-void fgPlatformDestroyContext ( SFG_PlatformDisplay pDisplay, SFG_WindowContextType MContext )
-{
-       /* Do nothing -- this is required for X11 */
-}
-
-/* -- PLATFORM-SPECIFIC INTERFACE FUNCTION -------------------------------------------------- */
-
-void (__cdecl *__glutExitFunc)( int return_value ) = NULL;
-
-void FGAPIENTRY __glutInitWithExit( int *pargc, char **argv, void (__cdecl *exit_function)(int) )
-{
-  __glutExitFunc = exit_function;
-  glutInit(pargc, argv);
-}
-
diff --git a/src/mswin/freeglut_input_devices_mswin.c b/src/mswin/freeglut_input_devices_mswin.c
deleted file mode 100644 (file)
index ba230d4..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * freeglut_input_devices_mswin.c
- *
- * The Windows-specific mouse cursor related stuff.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Sat Jan 21, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-#include <sys/types.h>
-#include <winbase.h>
-
-typedef struct {
-   HANDLE fh;
-   COMMTIMEOUTS timeouts_save;
-   DCB dcb_save;
-} SERIALPORT;
-
-/* Serial Port Prototypes */
-SERIALPORT *serial_open ( const char *device );
-void serial_close ( SERIALPORT *port );
-int serial_getchar ( SERIALPORT *port );
-int serial_putchar ( SERIALPORT *port, unsigned char ch );
-void serial_flush ( SERIALPORT *port );
-
-
-void fgPlatformRegisterDialDevice ( const char *dial_device )
-{
-        if (!dial_device){
-            static char devname[256];
-            DWORD size=sizeof(devname);
-            DWORD type = REG_SZ;
-            HKEY key;
-            if (RegOpenKeyA(HKEY_LOCAL_MACHINE,"SOFTWARE\\FreeGLUT",&key)==ERROR_SUCCESS) {
-                if (RegQueryValueExA(key,"DialboxSerialPort",NULL,&type,(LPBYTE)devname,&size)==ERROR_SUCCESS){
-                    dial_device=devname;
-                }
-                RegCloseKey(key);
-            }
-        }
-}
-
-
-/*  Serial Port Functions */
-SERIALPORT *serial_open(const char *device){
-    HANDLE fh;
-    DCB dcb={sizeof(DCB)};
-    COMMTIMEOUTS timeouts;
-    SERIALPORT *port;
-
-    fh = CreateFile(device,GENERIC_READ|GENERIC_WRITE,0,NULL,
-      OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
-    if (!fh) return NULL;
-
-    port = malloc(sizeof(SERIALPORT));
-    ZeroMemory(port, sizeof(SERIALPORT));
-    port->fh = fh;
-
-    /* save current port settings */
-    GetCommState(fh,&port->dcb_save);
-    GetCommTimeouts(fh,&port->timeouts_save);
-
-    dcb.DCBlength=sizeof(DCB);
-    BuildCommDCB("96,n,8,1",&dcb);
-    SetCommState(fh,&dcb);
-
-    ZeroMemory(&timeouts,sizeof(timeouts));
-    timeouts.ReadTotalTimeoutConstant=1;
-    timeouts.WriteTotalTimeoutConstant=1;
-    SetCommTimeouts(fh,&timeouts);
-
-    serial_flush(port);
-
-    return port;
-}
-
-void serial_close(SERIALPORT *port){
-    if (port){
-        /* restore old port settings */
-        SetCommState(port->fh,&port->dcb_save);
-        SetCommTimeouts(port->fh,&port->timeouts_save);
-        CloseHandle(port->fh);
-        free(port);
-    }
-}
-
-int serial_getchar(SERIALPORT *port){
-    DWORD n;
-    unsigned char ch;
-    if (!port) return EOF;
-    if (!ReadFile(port->fh,&ch,1,&n,NULL)) return EOF;
-    if (n==1) return ch;
-    return EOF;
-}
-
-int serial_putchar(SERIALPORT *port, unsigned char ch){
-    DWORD n;
-    if (!port) return 0;
-    return WriteFile(port->fh,&ch,1,&n,NULL);
-}
-
-void serial_flush ( SERIALPORT *port )
-{
-    FlushFileBuffers(port->fh);
-}
-
diff --git a/src/mswin/freeglut_internal_mswin.h b/src/mswin/freeglut_internal_mswin.h
deleted file mode 100644 (file)
index 571db40..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * freeglut_internal_mswin.h
- *
- * The freeglut library private include file.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Thu Jan 19, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef  FREEGLUT_INTERNAL_MSWIN_H
-#define  FREEGLUT_INTERNAL_MSWIN_H
-
-
-/* All Win32 headers depend on the huge windows.h recursive include.
- * Note: Lower-case header names are used, for best cross-platform
- * compatibility.
- */
-#if !defined(_WIN32_WCE)
-#   include <windows.h>
-#   include <windowsx.h>
-#   include <mmsystem.h>
-/* CYGWIN does not have tchar.h, but has TEXT(x), defined in winnt.h. */
-#   ifndef __CYGWIN__
-#       include <tchar.h>
-#   else
-#       define _TEXT(x) TEXT(x)
-#       define _T(x)    TEXT(x)
-#   endif
-
-#endif
-
-
-#ifndef HAVE_VFPRINTF
-#define  HAVE_VFPRINTF 1
-#endif
-
-/* MinGW may lack a prototype for ChangeDisplaySettingsEx() (depending on the version?) */
-#if !defined(ChangeDisplaySettingsEx)
-LONG WINAPI ChangeDisplaySettingsExA(LPCSTR,LPDEVMODEA,HWND,DWORD,LPVOID);
-LONG WINAPI ChangeDisplaySettingsExW(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID);
-#   ifdef UNICODE
-#       define ChangeDisplaySettingsEx ChangeDisplaySettingsExW
-#   else
-#       define ChangeDisplaySettingsEx ChangeDisplaySettingsExA
-#   endif
-#endif
-
-
-/* Structure Definitions */
-
-typedef struct tagSFG_PlatformDisplay SFG_PlatformDisplay;
-struct tagSFG_PlatformDisplay
-{
-    HINSTANCE       Instance;           /* The application's instance */
-    DEVMODE         DisplayMode;        /* Desktop's display settings */
-    char           *DisplayName;        /* Display name for multi display support*/ 
-};
-
-/*
- * Make "freeglut" window handle and context types so that we don't need so
- * much conditionally-compiled code later in the library.
- */
-typedef HWND    SFG_WindowHandleType;
-typedef HGLRC   SFG_WindowContextType;
-typedef struct tagSFG_PlatformContext SFG_PlatformContext;
-struct tagSFG_PlatformContext
-{
-    HDC             Device;             /* The window's device context */
-};
-
-
-/* Window's state description. This structure should be kept portable. */
-typedef struct tagSFG_PlatformWindowState SFG_PlatformWindowState;
-struct tagSFG_PlatformWindowState
-{
-    RECT            OldRect;            /* window rect  - stored before the window is made fullscreen */
-    DWORD           OldStyle;           /* window style - stored before the window is made fullscreen */
-};
-
-
-
-/* Joystick-Specific Definitions */
-#if !defined(_WIN32_WCE)
-#   define _JS_MAX_AXES  8
-typedef struct tagSFG_PlatformJoystick SFG_PlatformJoystick;
-struct tagSFG_PlatformJoystick
-{
-    JOYCAPS     jsCaps;
-    JOYINFOEX   js;
-    UINT        js_id;
-};
-#endif
-
-
-/* Menu font and color definitions */
-#define  FREEGLUT_MENU_FONT    GLUT_BITMAP_8_BY_13
-
-#define  FREEGLUT_MENU_PEN_FORE_COLORS   {0.0f,  0.0f,  0.0f,  1.0f}
-#define  FREEGLUT_MENU_PEN_BACK_COLORS   {0.85f, 0.85f, 0.85f, 1.0f}
-#define  FREEGLUT_MENU_PEN_HFORE_COLORS  {1.0f,  1.0f,  1.0f,  1.0f}
-#define  FREEGLUT_MENU_PEN_HBACK_COLORS  {0.15f, 0.15f, 0.45f, 1.0f}
-
-
-/* Function to be called on exit */
-extern void (__cdecl *__glutExitFunc)( int return_value );
-
-
-#endif  /* FREEGLUT_INTERNAL_MSWIN_H */
diff --git a/src/mswin/freeglut_joystick_mswin.c b/src/mswin/freeglut_joystick_mswin.c
deleted file mode 100644 (file)
index aefa192..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * freeglut_joystick_mswin.c
- *
- * The Windows-specific mouse cursor related stuff.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Sat Jan 28, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-
-#if !defined(_WIN32_WCE)
-#    include <windows.h>
-#    include <mmsystem.h>
-#    include <regstr.h>
-
-
-
-
-void fgPlatformJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes )
-{
-    MMRESULT status;
-
-    status = joyGetPosEx( joy->pJoystick.js_id, &joy->pJoystick.js );
-
-    if ( status != JOYERR_NOERROR )
-    {
-        joy->error = GL_TRUE;
-        return;
-    }
-
-    if ( buttons )
-        *buttons = joy->pJoystick.js.dwButtons;
-
-    if ( axes )
-    {
-        /*
-         * WARNING - Fall through case clauses!!
-         */
-        switch ( joy->num_axes )
-        {
-        case 8:
-            /* Generate two POV axes from the POV hat angle.
-             * Low 16 bits of js.dwPOV gives heading (clockwise from ahead) in
-             *   hundredths of a degree, or 0xFFFF when idle.
-             */
-            if ( ( joy->pJoystick.js.dwPOV & 0xFFFF ) == 0xFFFF )
-            {
-              axes [ 6 ] = 0.0;
-              axes [ 7 ] = 0.0;
-            }
-            else
-            {
-              /* This is the contentious bit: how to convert angle to X/Y.
-               *    wk: I know of no define for PI that we could use here:
-               *    SG_PI would pull in sg, M_PI is undefined for MSVC
-               * But the accuracy of the value of PI is very unimportant at
-               * this point.
-               */
-              float s = (float) sin ( ( joy->pJoystick.js.dwPOV & 0xFFFF ) * ( 0.01 * 3.1415926535f / 180.0f ) );
-              float c = (float) cos ( ( joy->pJoystick.js.dwPOV & 0xFFFF ) * ( 0.01 * 3.1415926535f / 180.0f ) );
-
-              /* Convert to coordinates on a square so that North-East
-               * is (1,1) not (.7,.7), etc.
-               * s and c cannot both be zero so we won't divide by zero.
-               */
-              if ( fabs ( s ) < fabs ( c ) )
-              {
-                axes [ 6 ] = ( c < 0.0 ) ? -s/c  : s/c ;
-                axes [ 7 ] = ( c < 0.0 ) ? -1.0f : 1.0f;
-              }
-              else
-              {
-                axes [ 6 ] = ( s < 0.0 ) ? -1.0f : 1.0f;
-                axes [ 7 ] = ( s < 0.0 ) ? -c/s  : c/s ;
-              }
-            }
-
-        case 6: axes[5] = (float) joy->pJoystick.js.dwVpos;
-        case 5: axes[4] = (float) joy->pJoystick.js.dwUpos;
-        case 4: axes[3] = (float) joy->pJoystick.js.dwRpos;
-        case 3: axes[2] = (float) joy->pJoystick.js.dwZpos;
-        case 2: axes[1] = (float) joy->pJoystick.js.dwYpos;
-        case 1: axes[0] = (float) joy->pJoystick.js.dwXpos;
-        }
-    }
-}
-
-
-
-/* Inspired by
-   http://msdn.microsoft.com/archive/en-us/dnargame/html/msdn_sidewind3d.asp
- */
-#  if FREEGLUT_LIB_PRAGMAS
-#      pragma comment (lib, "advapi32.lib")
-#  endif
-
-static int fghJoystickGetOEMProductName ( SFG_Joystick* joy, char *buf, int buf_sz )
-{
-    char buffer [ 256 ];
-
-    char OEMKey [ 256 ];
-
-    HKEY  hKey;
-    DWORD dwcb;
-    LONG  lr;
-
-    if ( joy->error )
-        return 0;
-
-    /* Open .. MediaResources\CurrentJoystickSettings */
-    _snprintf ( buffer, sizeof(buffer), "%s\\%s\\%s",
-                REGSTR_PATH_JOYCONFIG, joy->pJoystick.jsCaps.szRegKey,
-                REGSTR_KEY_JOYCURR );
-
-    lr = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey);
-
-    if ( lr != ERROR_SUCCESS ) return 0;
-
-    /* Get OEM Key name */
-    dwcb = sizeof(OEMKey);
-
-    /* JOYSTICKID1-16 is zero-based; registry entries for VJOYD are 1-based. */
-    _snprintf ( buffer, sizeof(buffer), "Joystick%d%s", joy->pJoystick.js_id + 1, REGSTR_VAL_JOYOEMNAME );
-
-    lr = RegQueryValueEx ( hKey, buffer, 0, 0, (LPBYTE) OEMKey, &dwcb);
-    RegCloseKey ( hKey );
-
-    if ( lr != ERROR_SUCCESS ) return 0;
-
-    /* Open OEM Key from ...MediaProperties */
-    _snprintf ( buffer, sizeof(buffer), "%s\\%s", REGSTR_PATH_JOYOEM, OEMKey );
-
-    lr = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey );
-
-    if ( lr != ERROR_SUCCESS ) return 0;
-
-    /* Get OEM Name */
-    dwcb = buf_sz;
-
-    lr = RegQueryValueEx ( hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, (LPBYTE) buf,
-                             &dwcb );
-    RegCloseKey ( hKey );
-
-    if ( lr != ERROR_SUCCESS ) return 0;
-
-    return 1;
-}
-
-
-void fgPlatformJoystickOpen( SFG_Joystick* joy )
-{
-       int i = 0;
-
-    joy->pJoystick.js.dwFlags = JOY_RETURNALL;
-    joy->pJoystick.js.dwSize  = sizeof( joy->pJoystick.js );
-
-    memset( &joy->pJoystick.jsCaps, 0, sizeof( joy->pJoystick.jsCaps ) );
-
-    joy->error =
-        ( joyGetDevCaps( joy->pJoystick.js_id, &joy->pJoystick.jsCaps, sizeof( joy->pJoystick.jsCaps ) ) !=
-          JOYERR_NOERROR );
-
-    if( joy->pJoystick.jsCaps.wNumAxes == 0 )
-    {
-        joy->num_axes = 0;
-        joy->error = GL_TRUE;
-    }
-    else
-    {
-        /* Device name from jsCaps is often "Microsoft PC-joystick driver",
-         * at least for USB.  Try to get the real name from the registry.
-         */
-        if ( ! fghJoystickGetOEMProductName( joy, joy->name,
-                                             sizeof( joy->name ) ) )
-        {
-            fgWarning( "JS: Failed to read joystick name from registry" );
-            strncpy( joy->name, joy->pJoystick.jsCaps.szPname, sizeof( joy->name ) );
-        }
-
-        /* Windows joystick drivers may provide any combination of
-         * X,Y,Z,R,U,V,POV - not necessarily the first n of these.
-         */
-        if( joy->pJoystick.jsCaps.wCaps & JOYCAPS_HASPOV )
-        {
-            joy->num_axes = _JS_MAX_AXES;
-            joy->min[ 7 ] = -1.0; joy->max[ 7 ] = 1.0;  /* POV Y */
-            joy->min[ 6 ] = -1.0; joy->max[ 6 ] = 1.0;  /* POV X */
-        }
-        else
-            joy->num_axes = 6;
-
-        joy->min[ 5 ] = ( float )joy->pJoystick.jsCaps.wVmin;
-        joy->max[ 5 ] = ( float )joy->pJoystick.jsCaps.wVmax;
-        joy->min[ 4 ] = ( float )joy->pJoystick.jsCaps.wUmin;
-        joy->max[ 4 ] = ( float )joy->pJoystick.jsCaps.wUmax;
-        joy->min[ 3 ] = ( float )joy->pJoystick.jsCaps.wRmin;
-        joy->max[ 3 ] = ( float )joy->pJoystick.jsCaps.wRmax;
-        joy->min[ 2 ] = ( float )joy->pJoystick.jsCaps.wZmin;
-        joy->max[ 2 ] = ( float )joy->pJoystick.jsCaps.wZmax;
-        joy->min[ 1 ] = ( float )joy->pJoystick.jsCaps.wYmin;
-        joy->max[ 1 ] = ( float )joy->pJoystick.jsCaps.wYmax;
-        joy->min[ 0 ] = ( float )joy->pJoystick.jsCaps.wXmin;
-        joy->max[ 0 ] = ( float )joy->pJoystick.jsCaps.wXmax;
-    }
-
-    /* Guess all the rest judging on the axes extremals */
-    for( i = 0; i < joy->num_axes; i++ )
-    {
-        joy->center   [ i ] = ( joy->max[ i ] + joy->min[ i ] ) * 0.5f;
-        joy->dead_band[ i ] = 0.0f;
-        joy->saturate [ i ] = 1.0f;
-    }
-}
-
-
-
-void fgPlatformJoystickInit( SFG_Joystick *fgJoystick[], int ident )
-{
-    switch( ident )
-    {
-    case 0:
-        fgJoystick[ ident ]->pJoystick.js_id = JOYSTICKID1;
-        fgJoystick[ ident ]->error = GL_FALSE;
-        break;
-    case 1:
-        fgJoystick[ ident ]->pJoystick.js_id = JOYSTICKID2;
-        fgJoystick[ ident ]->error = GL_FALSE;
-        break;
-    default:
-        fgJoystick[ ident ]->num_axes = 0;
-        fgJoystick[ ident ]->error = GL_TRUE;
-        return;
-    }
-}
-
-
-
-void fgPlatformJoystickClose ( int ident )
-{
-    /* Do nothing special */
-}
-#endif
-
diff --git a/src/mswin/freeglut_main_mswin.c b/src/mswin/freeglut_main_mswin.c
deleted file mode 100644 (file)
index a1c5c8c..0000000
+++ /dev/null
@@ -1,1131 +0,0 @@
-/*
- * freeglut_main_mswin.c
- *
- * The Windows-specific mouse cursor related stuff.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Sat Jan 21, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-
-extern void fghRedrawWindow ( SFG_Window *window );
-
-extern void fgNewWGLCreateContext( SFG_Window* window );
-extern GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
-                                     unsigned char layer_type );
-
-#ifdef WM_TOUCH
-typedef BOOL (WINAPI *pGetTouchInputInfo)(HTOUCHINPUT,UINT,PTOUCHINPUT,int);
-typedef BOOL (WINAPI *pCloseTouchInputHandle)(HTOUCHINPUT);
-static pGetTouchInputInfo fghGetTouchInputInfo = (pGetTouchInputInfo)0xDEADBEEF;
-static pCloseTouchInputHandle fghCloseTouchInputHandle = (pCloseTouchInputHandle)0xDEADBEEF;
-#endif
-
-#ifdef _WIN32_WCE
-typedef struct GXDisplayProperties GXDisplayProperties;
-typedef struct GXKeyList GXKeyList;
-#include <gx.h>
-
-typedef struct GXKeyList (*GXGETDEFAULTKEYS)(int);
-typedef int (*GXOPENINPUT)();
-
-GXGETDEFAULTKEYS GXGetDefaultKeys_ = NULL;
-GXOPENINPUT GXOpenInput_ = NULL;
-
-struct GXKeyList gxKeyList;
-#endif /* _WIN32_WCE */
-
-/* 
- * Helper functions for getting client area from the window rect
- * and the window rect from the client area given the style of the window
- * (or a valid window pointer from which the style can be queried).
- */
-extern void fghComputeWindowRectFromClientArea_QueryWindow( const SFG_Window *window, RECT *clientRect, BOOL posIsOutside );
-extern RECT fghGetClientArea                              ( const SFG_Window *window,                   BOOL wantPosOutside );
-
-
-void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height )
-{
-    RECT windowRect;
-
-    /*
-     * For windowed mode, get the current position of the
-     * window and resize taking the size of the frame
-     * decorations into account.
-     */
-
-    /* "GetWindowRect" returns the pixel coordinates of the outside of the window */
-    GetWindowRect( window->Window.Handle, &windowRect );
-
-    /* Create rect in FreeGLUT format, (X,Y) topleft outside window, WxH of client area */
-    windowRect.right    = windowRect.left+width;
-    windowRect.bottom   = windowRect.top+height;
-
-    if (window->Parent == NULL)
-        /* get the window rect from this to feed to SetWindowPos, correct for window decorations */
-        fghComputeWindowRectFromClientArea_QueryWindow(window,&windowRect,TRUE);
-    else
-    {
-        /* correct rect for position client area of parent window
-         * (SetWindowPos input for child windows is in coordinates
-         * relative to the parent's client area).
-         * Child windows don't have decoration, so no need to correct
-         * for them.
-         */
-        RECT parentRect;
-        parentRect = fghGetClientArea( window->Parent, FALSE );
-        windowRect.left   -= parentRect.left;
-        windowRect.right  -= parentRect.left;
-        windowRect.top    -= parentRect.top;
-        windowRect.bottom -= parentRect.top;
-    }
-    
-    /* Do the actual resizing */
-    SetWindowPos( window->Window.Handle,
-                  HWND_TOP,
-                  windowRect.left, windowRect.top,
-                  windowRect.right - windowRect.left,
-                  windowRect.bottom- windowRect.top,
-                  SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING |
-                  SWP_NOZORDER
-    );
-}
-
-
-void fgPlatformDisplayWindow ( SFG_Window *window )
-{
-    RedrawWindow(
-        window->Window.Handle, NULL, NULL,
-        RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_UPDATENOW
-    );
-}
-
-
-fg_time_t fgPlatformSystemTime ( void )
-{
-#if defined(_WIN32_WCE)
-    return GetTickCount();
-#else
-    /* TODO: do this with QueryPerformanceCounter as timeGetTime has
-     * insufficient resolution (only about 5 ms on system under low load).
-     * See:
-     * http://msdn.microsoft.com/en-us/library/windows/desktop/dd757629(v=vs.85).aspx
-     * Or maybe QueryPerformanceCounter is not a good idea either, see
-     * http://old.nabble.com/Re%3A-glutTimerFunc-does-not-detect-if-system-time-moved-backward-p33479674.html
-     * for some other ideas (at bottom)...
-     */
-    return timeGetTime();
-#endif
-}
-
-
-void fgPlatformSleepForEvents( fg_time_t msec )
-{
-    MsgWaitForMultipleObjects( 0, NULL, FALSE, msec, QS_ALLINPUT );
-}
-
-
-void fgPlatformProcessSingleEvent ( void )
-{
-    MSG stMsg;
-
-    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMainLoopEvent" );
-
-    while( PeekMessage( &stMsg, NULL, 0, 0, PM_NOREMOVE ) )
-    {
-        if( GetMessage( &stMsg, NULL, 0, 0 ) == 0 )
-        {
-            if( fgState.ActionOnWindowClose == GLUT_ACTION_EXIT )
-            {
-                fgDeinitialize( );
-                exit( 0 );
-            }
-            else if( fgState.ActionOnWindowClose == GLUT_ACTION_GLUTMAINLOOP_RETURNS )
-                fgState.ExecState = GLUT_EXEC_STATE_STOP;
-
-            return;
-        }
-
-        TranslateMessage( &stMsg );
-        DispatchMessage( &stMsg );
-    }
-}
-
-
-
-void fgPlatformMainLoopPreliminaryWork ( void )
-{
-    SFG_Window *window = (SFG_Window *)fgStructure.Windows.First ;
-
-    /*
-     * Processing before the main loop:  If there is a window which is open and
-     * which has a visibility callback, call it.  I know this is an ugly hack,
-     * but I'm not sure what else to do about it.  Ideally we should leave
-     * something uninitialized in the create window code and initialize it in
-     * the main loop, and have that initialization create a "WM_ACTIVATE"
-     * message.  Then we would put the visibility callback code in the
-     * "case WM_ACTIVATE" block below.         - John Fay -- 10/24/02
-     */
-    while( window )
-    {
-        if ( FETCH_WCB( *window, Visibility ) )
-        {
-            SFG_Window *current_window = fgStructure.CurrentWindow ;
-
-            INVOKE_WCB( *window, Visibility, ( window->State.Visible ) );
-            fgSetWindow( current_window );
-        }
-
-        window = (SFG_Window *)window->Node.Next ;
-    }
-}
-
-
-/*
- * Determine a GLUT modifer mask based on MS-WINDOWS system info.
- */
-static int fgPlatformGetModifiers (void)
-{
-    return
-        ( ( ( GetKeyState( VK_LSHIFT   ) < 0 ) ||
-            ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
-        ( ( ( GetKeyState( VK_LCONTROL ) < 0 ) ||
-            ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
-        ( ( ( GetKeyState( VK_LMENU    ) < 0 ) ||
-            ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 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;
-}
diff --git a/src/mswin/freeglut_menu_mswin.c b/src/mswin/freeglut_menu_mswin.c
deleted file mode 100644 (file)
index d198cca..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * freeglut_menu_mswin.c
- *
- * The Windows-specific mouse cursor related stuff.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Sun Jan 22, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#define FREEGLUT_BUILDING_LIB
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-
-GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y )
-{
-    *x = glutGet ( GLUT_SCREEN_WIDTH );
-    *y = glutGet ( GLUT_SCREEN_HEIGHT );
-}
-
-
-
-/* -- PLATFORM-SPECIFIC INTERFACE FUNCTION -------------------------------------------------- */
-
-int FGAPIENTRY __glutCreateMenuWithExit( void(* callback)( int ), void (__cdecl *exit_function)(int) )
-{
-  __glutExitFunc = exit_function;
-  return glutCreateMenu( callback );
-}
-
diff --git a/src/mswin/freeglut_spaceball_mswin.c b/src/mswin/freeglut_spaceball_mswin.c
deleted file mode 100644 (file)
index 3a7af46..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * freeglut_spaceball_mswin.c
- *
- * Spaceball support for Windows
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by Evan Felix <karcaw at gmail.com>
- * Creation date: Sat Feb 4, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-/*
- * This code is a very complicated way of doing nothing.  
- * But is needed for mswindows platform builds.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-void fgPlatformInitializeSpaceball(void)
-{
-       return;
-}
-
-void fgPlatformSpaceballClose(void)
-{
-       return;
-}
-
-int fgPlatformHasSpaceball(void)
-{
-       return 0;
-}
-
-int fgPlatformSpaceballNumButtons(void)
-{
-       return 0;
-}
-
-void fgPlatformSpaceballSetWindow(SFG_Window *window)
-{
-       return;
-}
diff --git a/src/mswin/freeglut_state_mswin.c b/src/mswin/freeglut_state_mswin.c
deleted file mode 100644 (file)
index 07ffdb1..0000000
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * freeglut_state_mswin.c
- *
- * The Windows-specific state query methods.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Sun Jan 22, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-
-extern GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
-                                     unsigned char layer_type );
-
-/* 
- * Helper functions for getting client area from the window rect
- * and the window rect from the client area given the style of the window
- * (or a valid window pointer from which the style can be queried).
- */
-extern RECT fghGetClientArea( const SFG_Window *window, BOOL wantPosOutside );
-extern void fghGetBorderWidth(const DWORD windowStyle, int* xBorderWidth, int* yBorderWidth);
-
-
-/* The following include file is available from SGI but is not standard:
- *   #include <GL/wglext.h>
- * So we copy the necessary parts out of it to support the multisampling query
- */
-#define WGL_SAMPLES_ARB                0x2042
-
-#if defined(_WIN32_WCE)
-#   include <Aygshell.h>
-#   ifdef FREEGLUT_LIB_PRAGMAS
-#       pragma comment( lib, "Aygshell.lib" )
-#   endif
-#endif /* defined(_WIN32_WCE) */
-
-
-
-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;
-}
-
-
-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;
-}
-
-/*
- * This is for querying the number of supported auxiliary or multisample
- * buffers for a (the current?) display mode.
- * see http://old.nabble.com/-GLX--glutGetModeValues-to13514723.html#a13514723
- * Not currently implemented, but we should be able to query the relevant
- * info using
- * http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt
- * (if supported on the executing machine!)
- */
-int *fgPlatformGlutGetModeValues(GLenum eWhat, int *size)
-{
-  *size = 0;
-  return NULL;
-}
\ No newline at end of file
diff --git a/src/mswin/freeglut_structure_mswin.c b/src/mswin/freeglut_structure_mswin.c
deleted file mode 100644 (file)
index 8ccb33d..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * freeglut_structure_mswin.c
- *
- * The Windows-specific mouse cursor related stuff.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Sun Jan 22, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-
-void fgPlatformCreateWindow ( SFG_Window *window )
-{
-}
diff --git a/src/mswin/freeglut_window_mswin.c b/src/mswin/freeglut_window_mswin.c
deleted file mode 100644 (file)
index 6515063..0000000
+++ /dev/null
@@ -1,1078 +0,0 @@
-/*
- * freeglut_window_mswin.c
- *
- * The Windows-specific mouse cursor related stuff.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Sun Jan 22, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#define FREEGLUT_BUILDING_LIB
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-
-/* The following include file is available from SGI but is not standard:
- *   #include <GL/wglext.h>
- * So we copy the necessary parts out of it.
- * XXX: should local definitions for extensions be put in a separate include file?
- */
-typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
-
-typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
-
-#define WGL_DRAW_TO_WINDOW_ARB         0x2001
-#define WGL_ACCELERATION_ARB           0x2003
-#define WGL_SUPPORT_OPENGL_ARB         0x2010
-#define WGL_DOUBLE_BUFFER_ARB          0x2011
-#define WGL_COLOR_BITS_ARB             0x2014
-#define WGL_ALPHA_BITS_ARB             0x201B
-#define WGL_DEPTH_BITS_ARB             0x2022
-#define WGL_STENCIL_BITS_ARB           0x2023
-#define WGL_FULL_ACCELERATION_ARB      0x2027
-
-#define WGL_SAMPLE_BUFFERS_ARB         0x2041
-#define WGL_SAMPLES_ARB                0x2042
-
-#define WGL_TYPE_RGBA_FLOAT_ARB        0x21A0
-
-#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
-
-#ifndef WGL_ARB_create_context
-#define WGL_ARB_create_context 1
-#ifdef WGL_WGLEXT_PROTOTYPES
-extern HGLRC WINAPI wglCreateContextAttribsARB (HDC, HGLRC, const int *);
-#endif /* WGL_WGLEXT_PROTOTYPES */
-typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
-
-#define WGL_CONTEXT_MAJOR_VERSION_ARB  0x2091
-#define WGL_CONTEXT_MINOR_VERSION_ARB  0x2092
-#define WGL_CONTEXT_LAYER_PLANE_ARB    0x2093
-#define WGL_CONTEXT_FLAGS_ARB          0x2094
-#define WGL_CONTEXT_PROFILE_MASK_ARB   0x9126
-
-#define WGL_CONTEXT_DEBUG_BIT_ARB      0x0001
-#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
-
-#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
-#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
-
-#define ERROR_INVALID_VERSION_ARB      0x2095
-#define ERROR_INVALID_PROFILE_ARB      0x2096
-#endif
-/* End of copying the necessary parts out of it. */
-
-#ifdef WM_TOUCH
-typedef BOOL (WINAPI *pRegisterTouchWindow)(HWND,ULONG);
-static pRegisterTouchWindow fghRegisterTouchWindow = (pRegisterTouchWindow)0xDEADBEEF;
-#endif
-
-/* 
- * Helper functions for getting client area from the window rect
- * and the window rect from the client area given the style of the window
- * (or a valid window pointer from which the style can be queried).
- */
-extern void fghGetBorderWidth(const DWORD windowStyle, int* xBorderWidth, int* yBorderWidth);
-
-
-/*
- * Setup the pixel format for a Win32 window
- */
-
-#if defined(_WIN32_WCE)
-static wchar_t* fghWstrFromStr(const char* str)
-{
-    int i,len=strlen(str);
-    wchar_t* wstr = (wchar_t*)malloc(2*len+2);
-    for(i=0; i<len; i++)
-        wstr[i] = str[i];
-    wstr[len] = 0;
-    return wstr;
-}
-#endif /* defined(_WIN32_WCE) */
-
-
-static void fghFillContextAttributes( int *attributes ) {
-  int where = 0, contextFlags, contextProfile;
-
-  if ( !fghIsLegacyContextVersionRequested() ) {
-    ATTRIB_VAL( WGL_CONTEXT_MAJOR_VERSION_ARB, fgState.MajorVersion );
-    ATTRIB_VAL( WGL_CONTEXT_MINOR_VERSION_ARB, fgState.MinorVersion );
-  }
-
-  contextFlags =
-    fghMapBit( fgState.ContextFlags, GLUT_DEBUG, WGL_CONTEXT_DEBUG_BIT_ARB ) |
-    fghMapBit( fgState.ContextFlags, GLUT_FORWARD_COMPATIBLE, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB );
-  if ( contextFlags != 0 ) {
-    ATTRIB_VAL( WGL_CONTEXT_FLAGS_ARB, contextFlags );
-  }
-
-  contextProfile =
-    fghMapBit( fgState.ContextProfile, GLUT_CORE_PROFILE, WGL_CONTEXT_CORE_PROFILE_BIT_ARB ) |
-    fghMapBit( fgState.ContextProfile, GLUT_COMPATIBILITY_PROFILE, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB );
-  if ( contextProfile != 0 ) {
-    ATTRIB_VAL( WGL_CONTEXT_PROFILE_MASK_ARB, contextProfile );
-  }
-
-  ATTRIB( 0 );
-}
-
-static int fghIsExtensionSupported( HDC hdc, const char *extension ) {
-    const char *pWglExtString;
-    PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetEntensionsStringARB =
-      (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
-    if ( wglGetEntensionsStringARB == NULL )
-    {
-      return FALSE;
-    }
-    pWglExtString = wglGetEntensionsStringARB( hdc );
-    return ( pWglExtString != NULL ) && ( strstr(pWglExtString, extension) != NULL );
-}
-
-void fgNewWGLCreateContext( SFG_Window* window )
-{
-    HGLRC context;
-    int attributes[9];
-    PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
-
-    /* If nothing fancy has been required, leave the context as it is */
-    if ( fghIsLegacyContextRequested() )
-    {
-        return;
-    }
-
-    wglMakeCurrent( window->Window.pContext.Device, window->Window.Context );
-
-    if ( !fghIsExtensionSupported( window->Window.pContext.Device, "WGL_ARB_create_context" ) )
-    {
-        return;
-    }
-
-    /* new context creation */
-    fghFillContextAttributes( attributes );
-
-    wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress( "wglCreateContextAttribsARB" );
-    if ( wglCreateContextAttribsARB == NULL )
-    {
-        fgError( "wglCreateContextAttribsARB not found" );
-    }
-
-    context = wglCreateContextAttribsARB( window->Window.pContext.Device, 0, attributes );
-    if ( context == NULL )
-    {
-        fghContextCreationError();
-    }
-
-    wglMakeCurrent( NULL, NULL );
-    wglDeleteContext( window->Window.Context );
-    window->Window.Context = context;
-}
-
-#if !defined(_WIN32_WCE)
-
-static void fghFillPFD( PIXELFORMATDESCRIPTOR *ppfd, HDC hdc, unsigned char layer_type )
-{
-  int flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
-  if ( fgState.DisplayMode & GLUT_DOUBLE ) {
-        flags |= PFD_DOUBLEBUFFER;
-  }
-  if ( fgState.DisplayMode & GLUT_STEREO ) {
-    flags |= PFD_STEREO;
-  }
-
-#if defined(_MSC_VER)
-#pragma message( "fgSetupPixelFormat(): there is still some work to do here!" )
-#endif
-
-  /* Specify which pixel format do we opt for... */
-  ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
-  ppfd->nVersion = 1;
-  ppfd->dwFlags = flags;
-
-  if( fgState.DisplayMode & GLUT_INDEX ) {
-    ppfd->iPixelType = PFD_TYPE_COLORINDEX;
-    ppfd->cRedBits = 0;
-    ppfd->cGreenBits = 0;
-    ppfd->cBlueBits = 0;
-    ppfd->cAlphaBits = 0;
-  } else {
-    ppfd->iPixelType = PFD_TYPE_RGBA;
-    ppfd->cRedBits = 8;
-    ppfd->cGreenBits = 8;
-    ppfd->cBlueBits = 8;
-    ppfd->cAlphaBits = ( fgState.DisplayMode & GLUT_ALPHA ) ? 8 : 0;
-  }
-
-  ppfd->cColorBits = 24;
-  ppfd->cRedShift = 0;
-  ppfd->cGreenShift = 0;
-  ppfd->cBlueShift = 0;
-  ppfd->cAlphaShift = 0;
-  ppfd->cAccumBits = ( fgState.DisplayMode & GLUT_ACCUM ) ? 1 : 0;
-  ppfd->cAccumRedBits = 0;
-  ppfd->cAccumGreenBits = 0;
-  ppfd->cAccumBlueBits = 0;
-  ppfd->cAccumAlphaBits = 0;
-
-  /* Hmmm, or 32/0 instead of 24/8? */
-  ppfd->cDepthBits = 24;
-  ppfd->cStencilBits = 8;
-
-  ppfd->cAuxBuffers = fghNumberOfAuxBuffersRequested();
-  ppfd->iLayerType = layer_type;
-  ppfd->bReserved = 0;
-  ppfd->dwLayerMask = 0;
-  ppfd->dwVisibleMask = 0;
-  ppfd->dwDamageMask = 0;
-  
-  ppfd->cColorBits = (BYTE) GetDeviceCaps( hdc, BITSPIXEL );
-}
-
-static void fghFillPixelFormatAttributes( int *attributes, const PIXELFORMATDESCRIPTOR *ppfd )
-{
-  int where = 0;
-
-  ATTRIB_VAL( WGL_DRAW_TO_WINDOW_ARB, GL_TRUE );
-  ATTRIB_VAL( WGL_SUPPORT_OPENGL_ARB, GL_TRUE );
-  ATTRIB_VAL( WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB );
-
-  ATTRIB_VAL( WGL_COLOR_BITS_ARB, ppfd->cColorBits );
-  ATTRIB_VAL( WGL_ALPHA_BITS_ARB, ppfd->cAlphaBits );
-  ATTRIB_VAL( WGL_DEPTH_BITS_ARB, ppfd->cDepthBits );
-  ATTRIB_VAL( WGL_STENCIL_BITS_ARB, ppfd->cStencilBits );
-
-  ATTRIB_VAL( WGL_DOUBLE_BUFFER_ARB, ( fgState.DisplayMode & GLUT_DOUBLE ) != 0 );
-
-  if ( fgState.DisplayMode & GLUT_SRGB ) {
-    ATTRIB_VAL( WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, TRUE );
-  }
-
-  ATTRIB_VAL( WGL_SAMPLE_BUFFERS_ARB, GL_TRUE );
-  ATTRIB_VAL( WGL_SAMPLES_ARB, fgState.SampleNumber );
-  ATTRIB( 0 );
-}
-#endif
-
-GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
-                              unsigned char layer_type )
-{
-#if defined(_WIN32_WCE)
-    return GL_TRUE;
-#else
-    PIXELFORMATDESCRIPTOR pfd;
-    PIXELFORMATDESCRIPTOR* ppfd = &pfd;
-    int pixelformat;
-    HDC current_hDC;
-    GLboolean success;
-
-    if (checkOnly)
-      current_hDC = CreateDC(TEXT("DISPLAY"), NULL ,NULL ,NULL);
-    else
-      current_hDC = window->Window.pContext.Device;
-
-    fghFillPFD( ppfd, current_hDC, layer_type );
-    pixelformat = ChoosePixelFormat( current_hDC, ppfd );
-
-    /* windows hack for multismapling/sRGB */
-    if ( ( fgState.DisplayMode & GLUT_MULTISAMPLE ) ||
-         ( fgState.DisplayMode & GLUT_SRGB ) )
-    {        
-        HGLRC rc, rc_before=wglGetCurrentContext();
-        HWND hWnd;
-        HDC hDC, hDC_before=wglGetCurrentDC();
-        WNDCLASS wndCls;
-
-        /* create a dummy window */
-        ZeroMemory(&wndCls, sizeof(wndCls));
-        wndCls.lpfnWndProc = DefWindowProc;
-        wndCls.hInstance = fgDisplay.pDisplay.Instance;
-        wndCls.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
-        wndCls.lpszClassName = _T("FREEGLUT_dummy");
-        RegisterClass( &wndCls );
-
-        hWnd=CreateWindow(_T("FREEGLUT_dummy"), _T(""), WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW , 0,0,0,0, 0, 0, fgDisplay.pDisplay.Instance, 0 );
-        hDC=GetDC(hWnd);
-        SetPixelFormat( hDC, pixelformat, ppfd );
-
-        rc = wglCreateContext( hDC );
-        wglMakeCurrent(hDC, rc);
-
-        if ( fghIsExtensionSupported( hDC, "WGL_ARB_multisample" ) )
-        {
-            PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARBProc =
-              (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");
-            if ( wglChoosePixelFormatARBProc )
-            {
-                int attributes[100];
-                int iPixelFormat;
-                BOOL bValid;
-                float fAttributes[] = { 0, 0 };
-                UINT numFormats;
-                fghFillPixelFormatAttributes( attributes, ppfd );
-                bValid = wglChoosePixelFormatARBProc(hDC, attributes, fAttributes, 1, &iPixelFormat, &numFormats);
-
-                if ( bValid && numFormats > 0 )
-                {
-                    pixelformat = iPixelFormat;
-                }
-            }
-        }
-
-        wglMakeCurrent( hDC_before, rc_before);
-        wglDeleteContext(rc);
-        ReleaseDC(hWnd, hDC);
-        DestroyWindow(hWnd);
-        UnregisterClass(_T("FREEGLUT_dummy"), fgDisplay.pDisplay.Instance);
-    }
-
-    success = ( pixelformat != 0 ) && ( checkOnly || SetPixelFormat( current_hDC, pixelformat, ppfd ) );
-
-    if (checkOnly)
-        DeleteDC(current_hDC);
-
-    return success;
-#endif /* defined(_WIN32_WCE) */
-}
-
-
-
-void fgPlatformSetWindow ( SFG_Window *window )
-{
-    if ( window != fgStructure.CurrentWindow )
-    {
-        if( fgStructure.CurrentWindow )
-            ReleaseDC( fgStructure.CurrentWindow->Window.Handle,
-                       fgStructure.CurrentWindow->Window.pContext.Device );
-
-        if ( window )
-        {
-            window->Window.pContext.Device = GetDC( window->Window.Handle );
-            wglMakeCurrent(
-                window->Window.pContext.Device,
-                window->Window.Context
-            );
-        }
-    }
-}
-
-
-
-/* Computes position of corners of window Rect (outer position including
- * decorations) based on the provided client rect and based on the style
- * of the window in question.
- * If posIsOutside is set to true, the input client Rect is taken to follow
- * freeGLUT's window specification convention in which the top-left corner
- * is at the outside of the window, while the size
- * (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable
- * area.
- */
-void fghComputeWindowRectFromClientArea_UseStyle( const DWORD windowStyle, RECT *clientRect, BOOL posIsOutside )
-{
-    int xBorderWidth = 0, yBorderWidth = 0;
-
-    /* If window has title bar, correct rect for it */
-    if (windowStyle & WS_MAXIMIZEBOX) /* 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... */
-        if (posIsOutside)
-            clientRect->bottom += GetSystemMetrics( SM_CYCAPTION );
-        else
-            clientRect->top -= GetSystemMetrics( SM_CYCAPTION );
-
-    /* get width of window's borders (frame), correct rect for it.
-     * Note, borders can be of zero width if style does not specify borders
-     */
-    fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth);
-    if (posIsOutside)
-    {
-        clientRect->right  += xBorderWidth * 2;
-        clientRect->bottom += yBorderWidth * 2;
-    }
-    else
-    {
-        clientRect->left   -= xBorderWidth;
-        clientRect->right  += xBorderWidth;
-        clientRect->top    -= yBorderWidth;
-        clientRect->bottom += yBorderWidth;
-    }
-}
-
-/* Computes position of corners of window Rect (outer position including
- * decorations) based on the provided client rect and based on the style
- * of the window in question. If the window pointer or the window handle
- * is NULL, a fully decorated window (caption and border) is assumed.
- * Furthermore, if posIsOutside is set to true, the input client Rect is
- * taken to follow freeGLUT's window specification convention in which the
- * top-left corner is at the outside of the window, while the size
- * (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable
- * area.
-*/
-void fghComputeWindowRectFromClientArea_QueryWindow( const SFG_Window *window, RECT *clientRect, BOOL posIsOutside )
-{
-    DWORD windowStyle = 0;
-
-    if (window && window->Window.Handle)
-        windowStyle = GetWindowLong(window->Window.Handle, GWL_STYLE);
-    else
-        windowStyle = WS_OVERLAPPEDWINDOW;
-
-    fghComputeWindowRectFromClientArea_UseStyle(windowStyle, clientRect, posIsOutside);
-}
-
-/* Computes position of corners of client area (drawable area) of a window
- * based on the provided window Rect (outer position including decorations)
- * and based on the style of the window in question. If the window pointer
- * or the window handle is NULL, a fully decorated window (caption and
- * border) is assumed.
- * Furthermore, if wantPosOutside is set to true, the output client Rect
- * will follow freeGLUT's window specification convention in which the
- * top-left corner is at the outside of the window, the size
- * (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable
- * area.
- */
-void fghComputeClientAreaFromWindowRect( const SFG_Window *window, RECT *windowRect, BOOL wantPosOutside )
-{
-    DWORD windowStyle = 0;
-    int xBorderWidth = 0, yBorderWidth = 0;
-
-    if (window && window->Window.Handle)
-        windowStyle = GetWindowLong(window->Window.Handle, GWL_STYLE);
-    else
-        windowStyle = WS_OVERLAPPEDWINDOW;
-
-    /* If window has title bar, correct rect for it */
-    if (windowStyle & WS_MAXIMIZEBOX) /* 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... */
-        if (wantPosOutside)
-            windowRect->bottom -= GetSystemMetrics( SM_CYCAPTION );
-        else
-            windowRect->top    += GetSystemMetrics( SM_CYCAPTION );
-
-    /* get width of window's borders (frame), correct rect for it.
-     * Note, borders can be of zero width if style does not specify borders
-     */
-    fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth);
-    if (wantPosOutside)
-    {
-        windowRect->right  -= xBorderWidth * 2;
-        windowRect->bottom -= yBorderWidth * 2;
-    }
-    else
-    {
-        windowRect->left   += xBorderWidth;
-        windowRect->right  -= xBorderWidth;
-        windowRect->top    += yBorderWidth;
-        windowRect->bottom -= yBorderWidth;
-    }
-}
-
-/* Gets the rect describing the client area (drawable area) of the
- * specified window.
- * Returns an empty rect if window pointer or window handle is NULL.
- * If wantPosOutside is set to true, the output client Rect
- * will follow freeGLUT's window specification convention in which the
- * top-left corner is at the outside of the window, while the size
- * (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable
- * area.
- */
-RECT fghGetClientArea( const SFG_Window *window, BOOL wantPosOutside )
-{
-    RECT windowRect = {0,0,0,0};
-
-    freeglut_return_val_if_fail((window && window->Window.Handle),windowRect);
-    
-    /*
-     * call GetWindowRect()
-     * (this returns the pixel coordinates of the outside of the window)
-     */
-    GetWindowRect( window->Window.Handle, &windowRect );
-
-    /* Then correct the results */
-    fghComputeClientAreaFromWindowRect(window, &windowRect, wantPosOutside);
-
-    return windowRect;
-}
-
-/* Returns the width of the window borders based on the window's style.
- */
-void fghGetBorderWidth(const DWORD windowStyle, int* xBorderWidth, int* yBorderWidth)
-{
-    if (windowStyle & WS_THICKFRAME)
-    {
-        *xBorderWidth = GetSystemMetrics(SM_CXSIZEFRAME);
-        *yBorderWidth = GetSystemMetrics(SM_CYSIZEFRAME);
-    }
-    else if (windowStyle & WS_DLGFRAME)
-    {
-        *xBorderWidth = GetSystemMetrics(SM_CXFIXEDFRAME);
-        *yBorderWidth = GetSystemMetrics(SM_CYFIXEDFRAME);
-    }
-    else
-    {
-        *xBorderWidth = 0;
-        *yBorderWidth = 0;
-    }
-}
-
-#if(WINVER >= 0x500)
-typedef struct
-{
-      int *x;
-      int *y;
-      const char *name;
-} m_proc_t;
-
-static BOOL CALLBACK m_proc(HMONITOR mon,
-                           HDC hdc,
-                           LPRECT rect,
-                           LPARAM data)
-{
-      m_proc_t *dp=(m_proc_t *)data;
-      MONITORINFOEX info;
-      BOOL res;
-      info.cbSize=sizeof(info);
-      res=GetMonitorInfo(mon,(LPMONITORINFO)&info);
-      if( res )
-      {
-          if( strcmp(dp->name,info.szDevice)==0 )
-          {
-              *(dp->x)=info.rcMonitor.left;
-              *(dp->y)=info.rcMonitor.top;
-              return FALSE;
-          }
-      }
-      return TRUE;
-}
-
-/* 
- * this function returns the origin of the screen identified by
- * fgDisplay.pDisplay.DisplayName, and 0 otherwise.
- * This is used in fgOpenWindow to open the gamemode window on the screen
- * identified by the -display command line argument. The function should
- * not be called otherwise.
- */
-
-static void get_display_origin(int *xp,int *yp)
-{
-    *xp = 0;
-    *yp = 0;
-
-    if( fgDisplay.pDisplay.DisplayName )
-    {
-        m_proc_t st;
-        st.x=xp;
-        st.y=yp;
-        st.name=fgDisplay.pDisplay.DisplayName;
-        EnumDisplayMonitors(0,0,m_proc,(LPARAM)&st);
-    }
-}
-#else
-#pragma message( "-display parameter only works if compiled with WINVER >= 0x0500")
-
-static void get_display_origin(int *xp,int *yp)
-{
-    *xp = 0;
-    *yp = 0;
-
-    if( fgDisplay.pDisplay.DisplayName )
-    {
-        fgWarning( "for working -display support FreeGLUT must be compiled with WINVER >= 0x0500");
-    }
-}
-#endif
-
-
-
-/*
- * Opens a window. Requires a SFG_Window object created and attached
- * to the freeglut structure. OpenGL context is created here.
- */
-void fgPlatformOpenWindow( SFG_Window* window, const char* title,
-                           GLboolean positionUse, int x, int y,
-                           GLboolean sizeUse, int w, int h,
-                           GLboolean gameMode, GLboolean isSubWindow )
-{
-
-    WNDCLASS wc;
-    DWORD flags   = 0;
-    DWORD exFlags = 0;
-    ATOM atom;
-
-    /* Grab the window class we have registered on glutInit(): */
-    atom = GetClassInfo( fgDisplay.pDisplay.Instance, _T("FREEGLUT"), &wc );
-    FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Info Not Found",
-                                   "fgOpenWindow" );
-
-    /* Determine window style flags*/
-    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
-    {
-        flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
-
-        /*
-         * There's a small difference between creating the top, child and
-         * menu windows
-         */
-        if ( window->IsMenu )
-        {
-            flags |= WS_POPUP;
-            exFlags |= WS_EX_TOOLWINDOW;
-        }
-#if defined(_WIN32_WCE)
-        /* no decorations for windows CE */
-#else
-        /* if this is not a subwindow (child), set its style based on the requested display mode */
-        else if( window->Parent == NULL )
-            if ( fgState.DisplayMode & GLUT_BORDERLESS )
-            {
-                /* no window decorations needed */
-            }
-            else if ( fgState.DisplayMode & GLUT_CAPTIONLESS )
-                /* only window decoration is a border, no title bar or buttons */
-                flags |= WS_DLGFRAME;
-            else
-                /* window decoration are a border, title bar and buttons.
-                 * NB: we later query whether the window has a title bar or
-                 * not by testing for the maximize button, as the test for
-                 * WS_CAPTION can be true without the window having a title
-                 * bar. This style WS_OVERLAPPEDWINDOW gives you a maximize
-                 * button. */
-                flags |= WS_OVERLAPPEDWINDOW;
-#endif
-        else
-            /* subwindows always have no decoration, but are marked as a child window to the OS */
-            flags |= WS_CHILD;
-    }
-
-    /* determine window size and position */
-    if( gameMode )
-    {
-        /* if in gamemode, query the origin of specified by the -display
-         * command line parameter (if any) and offset the upper-left corner
-         * of the window so we create the window on that screen.
-         * The -display argument doesn't do anything if not trying to enter
-         * gamemode.
-         */
-        int xoff=0, yoff=0;
-        get_display_origin(&xoff,&yoff);
-        x += xoff;
-        y += yoff;
-    }
-    if( !positionUse )
-    {
-        x = CW_USEDEFAULT;
-        y = CW_USEDEFAULT;
-    }
-    if( !sizeUse )
-    {
-        if( ! window->IsMenu )
-        {
-            w = CW_USEDEFAULT;
-            h = CW_USEDEFAULT;
-        }
-        else /* fail safe - Windows can make a window of size (0, 0) */
-            w = h = 300; /* default window size */
-    }
-    /* store requested client area width and height */
-    window->State.Width = w;
-    window->State.Height = h;
-
-#if !defined(_WIN32_WCE)    /* no decorations for windows CE */
-    if( sizeUse )
-    {
-        RECT windowRect;
-        /*
-         * Update the window dimensions, taking the window decorations
-         * into account.  FreeGLUT is to create the window with the
-         * topleft outside corner at (x,y) and with client area
-         * dimensions (w,h).
-         * note: don't need to do this when w=h=CW_USEDEFAULT, so in the
-         * if( sizeUse ) here is convenient.
-         */
-        windowRect.left     = x;
-        windowRect.top      = y;
-        windowRect.right    = x+w;
-        windowRect.bottom   = y+h;
-
-        fghComputeWindowRectFromClientArea_UseStyle(flags,&windowRect,TRUE);
-
-        w = windowRect.right - windowRect.left;
-        h = windowRect.bottom- windowRect.top;
-    }
-#endif /* !defined(_WIN32_WCE) */
-
-#if defined(_WIN32_WCE)
-    {
-        wchar_t* wstr = fghWstrFromStr(title);
-
-        window->Window.Handle = CreateWindow(
-            _T("FREEGLUT"),
-            wstr,
-            WS_VISIBLE | WS_POPUP,
-            0,0, 240,320,
-            NULL,
-            NULL,
-            fgDisplay.pDisplay.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 = CreateWindowEx(
-        exFlags,
-        _T("FREEGLUT"),
-        title,
-        flags,
-        x, y, w, h,
-        (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle,
-        (HMENU) NULL,
-        fgDisplay.pDisplay.Instance,
-        (LPVOID) window
-    );
-#endif /* defined(_WIN32_WCE) */
-
-    if( !( window->Window.Handle ) )
-        fgError( "Failed to create a window (%s)!", title );
-
-#if !defined(_WIN32_WCE)
-    /* Need to set requested style again, apparently Windows doesn't listen when requesting windows without title bar or borders */
-    SetWindowLong(window->Window.Handle, GWL_STYLE, flags);
-    SetWindowPos(window->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
-#endif /* defined(_WIN32_WCE) */
-
-    /* Make a menu window always on top - fix Feature Request 947118 */
-    if( window->IsMenu || gameMode )
-        SetWindowPos(
-                        window->Window.Handle,
-                        HWND_TOPMOST,
-                        0, 0, 0, 0,
-                        SWP_NOMOVE | SWP_NOSIZE
-                    );
-
-    /* Enable multitouch: additional flag TWF_FINETOUCH, TWF_WANTPALM */
-    #ifdef WM_TOUCH
-        if (fghRegisterTouchWindow == (pRegisterTouchWindow)0xDEADBEEF) 
-                       fghRegisterTouchWindow = (pRegisterTouchWindow)GetProcAddress(GetModuleHandle("user32"),"RegisterTouchWindow");
-               if (fghRegisterTouchWindow)
-             fghRegisterTouchWindow( window->Window.Handle, TWF_FINETOUCH | TWF_WANTPALM );
-    #endif
-
-#if defined(_WIN32_WCE)
-    ShowWindow( window->Window.Handle, SW_SHOW );
-#else
-    ShowWindow( window->Window.Handle,
-                fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW );
-#endif /* defined(_WIN32_WCE) */
-
-    UpdateWindow( window->Window.Handle );
-    ShowCursor( TRUE );  /* XXX Old comments say "hide cursor"! */
-
-}
-
-
-/*
- * Closes a window, destroying the frame and OpenGL context
- */
-void fgPlatformCloseWindow( SFG_Window* window )
-{
-    /* Make sure we don't close a window with current context active */
-    if( fgStructure.CurrentWindow == window )
-        wglMakeCurrent( NULL, NULL );
-
-    /*
-     * Step through the list of windows.  If the rendering context
-     * is not being used by another window, then we delete it.
-     */
-    {
-        int used = FALSE ;
-        SFG_Window *iter ;
-
-        for( iter = (SFG_Window *)fgStructure.Windows.First;
-             iter;
-             iter = (SFG_Window *)iter->Node.Next )
-        {
-            if( ( iter->Window.Context == window->Window.Context ) &&
-                ( iter != window ) )
-                used = TRUE;
-        }
-
-        if( ! used )
-            wglDeleteContext( window->Window.Context );
-    }
-
-    DestroyWindow( window->Window.Handle );
-}
-
-
-
-/*
- * This function makes the current window visible
- */
-void fgPlatformGlutShowWindow( void )
-{
-    ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_SHOW );
-}
-
-/*
- * This function hides the current window
- */
-void fgPlatformGlutHideWindow( void )
-{
-    ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_HIDE );
-}
-
-/*
- * Iconify the current window (top-level windows only)
- */
-void fgPlatformGlutIconifyWindow( void )
-{
-    ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_MINIMIZE );
-}
-
-/*
- * Set the current window's title
- */
-void fgPlatformGlutSetWindowTitle( const char* title )
-{
-#ifdef _WIN32_WCE
-    {
-        wchar_t* wstr = fghWstrFromStr(title);
-        SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr );
-        free(wstr);
-    }
-#else
-    SetWindowText( fgStructure.CurrentWindow->Window.Handle, title );
-#endif
-}
-
-/*
- * Set the current window's iconified title
- */
-void fgPlatformGlutSetIconTitle( const char* title )
-{
-#ifdef _WIN32_WCE
-    {
-        wchar_t* wstr = fghWstrFromStr(title);
-        SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr );
-        free(wstr);
-    }
-#else
-    SetWindowText( fgStructure.CurrentWindow->Window.Handle, title );
-#endif
-}
-
-/*
- * Change the current window's position
- */
-void fgPlatformGlutPositionWindow( int x, int y )
-{
-    RECT winRect;
-
-    /* "GetWindowRect" returns the pixel coordinates of the outside of the window */
-    GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect );
-    MoveWindow(
-        fgStructure.CurrentWindow->Window.Handle,
-        x,
-        y,
-        winRect.right - winRect.left,
-        winRect.bottom - winRect.top,
-        TRUE
-    );
-}
-
-/*
- * Lowers the current window (by Z order change)
- */
-void fgPlatformGlutPushWindow( void )
-{
-    SetWindowPos(
-        fgStructure.CurrentWindow->Window.Handle,
-        HWND_BOTTOM,
-        0, 0, 0, 0,
-        SWP_NOSIZE | SWP_NOMOVE
-    );
-}
-
-/*
- * Raises the current window (by Z order change)
- */
-void fgPlatformGlutPopWindow( void )
-{
-    SetWindowPos(
-        fgStructure.CurrentWindow->Window.Handle,
-        HWND_TOP,
-        0, 0, 0, 0,
-        SWP_NOSIZE | SWP_NOMOVE
-    );
-}
-
-/*
- * Resize the current window so that it fits the whole screen
- */
-void fgPlatformGlutFullScreen( SFG_Window *win )
-{
-#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */
-
-    if (glutGet(GLUT_FULL_SCREEN))
-    {
-        /*  Leave full screen state before entering fullscreen again (resizing?) */
-        glutLeaveFullScreen();
-    }
-
-    {
-#if(WINVER >= 0x0500) /* Windows 2000 or later */
-        DWORD s;
-        RECT rect;
-        HMONITOR hMonitor;
-        MONITORINFO mi;
-
-        /* For fullscreen mode, first remove all window decoration
-         * and set style to popup so it will overlap the taskbar
-         * then force to maximize on the screen on which it has the most
-         * overlap.
-         */
-
-        
-        /* store current window rect */
-        GetWindowRect( win->Window.Handle, &win->State.pWState.OldRect );
-
-        /* store current window style */
-        win->State.pWState.OldStyle = s = GetWindowLong(win->Window.Handle, GWL_STYLE);
-
-        /* remove decorations from style and add popup style*/
-        s &= ~WS_OVERLAPPEDWINDOW;
-        s |= WS_POPUP;
-        SetWindowLong(win->Window.Handle, GWL_STYLE, s);
-        SetWindowPos(win->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
-
-        /* For fullscreen mode, find the monitor that is covered the most
-         * by the window and get its rect as the resize target.
-            */
-        hMonitor= MonitorFromRect(&win->State.pWState.OldRect, MONITOR_DEFAULTTONEAREST);
-        mi.cbSize = sizeof(mi);
-        GetMonitorInfo(hMonitor, &mi);
-        rect = mi.rcMonitor;
-#else   /* if (WINVER >= 0x0500) */
-        RECT rect;
-
-        /* For fullscreen mode, force the top-left corner to 0,0
-         * and adjust the window rectangle so that the client area
-         * covers the whole screen.
-         */
-
-        rect.left   = 0;
-        rect.top    = 0;
-        rect.right  = fgDisplay.ScreenWidth;
-        rect.bottom = fgDisplay.ScreenHeight;
-
-        AdjustWindowRect ( &rect, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |
-                                  WS_CLIPCHILDREN, FALSE );
-#endif  /* (WINVER >= 0x0500) */
-
-        /*
-         * then resize window
-         * SWP_NOACTIVATE     Do not activate the window
-         * SWP_NOOWNERZORDER  Do not change position in z-order
-         * SWP_NOSENDCHANGING Suppress WM_WINDOWPOSCHANGING message
-         * SWP_NOZORDER       Retains the current Z order (ignore 2nd param)
-         */
-        SetWindowPos( fgStructure.CurrentWindow->Window.Handle,
-                      HWND_TOP,
-                      rect.left,
-                      rect.top,
-                      rect.right  - rect.left,
-                      rect.bottom - rect.top,
-                      SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING |
-                      SWP_NOZORDER
-                    );
-
-        win->State.IsFullscreen = GL_TRUE;
-    }
-#endif
-}
-
-/*
- * If we are fullscreen, resize the current window back to its original size
- */
-void fgPlatformGlutLeaveFullScreen( SFG_Window *win )
-{
-#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */
-    if (!glutGet(GLUT_FULL_SCREEN))
-    {
-        /* nothing to do */
-        return;
-    }
-
-    /* restore style of window before making it fullscreen */
-    SetWindowLong(win->Window.Handle, GWL_STYLE, win->State.pWState.OldStyle);
-    SetWindowPos(win->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
-
-    /* Then resize */
-    SetWindowPos(win->Window.Handle,
-        HWND_TOP,
-        win->State.pWState.OldRect.left,
-        win->State.pWState.OldRect.top,
-        win->State.pWState.OldRect.right  - win->State.pWState.OldRect.left,
-        win->State.pWState.OldRect.bottom - win->State.pWState.OldRect.top,
-        SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING |
-        SWP_NOZORDER
-        );
-
-    win->State.IsFullscreen = GL_FALSE;
-#endif
-}
-
-/*
- * Toggle the window's full screen state.
- */
-void fgPlatformGlutFullScreenToggle( SFG_Window *win )
-{
-    if (!win->State.IsFullscreen)
-        glutFullScreen();
-    else
-        glutLeaveFullScreen();
-}
-
-
-/* -- PLATFORM-SPECIFIC INTERFACE FUNCTION -------------------------------------------------- */
-
-int FGAPIENTRY __glutCreateWindowWithExit( const char *title, void (__cdecl *exit_function)(int) )
-{
-  __glutExitFunc = exit_function;
-  return glutCreateWindow( title );
-}
-
diff --git a/src/x11/fg_cursor_x11.c b/src/x11/fg_cursor_x11.c
new file mode 100644 (file)
index 0000000..3098e53
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * freeglut_cursor_x11.c
+ *
+ * The Windows-specific mouse cursor related stuff.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Sun Feb 5, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+/* This code is for Posix/X11, Solaris, and OSX */
+#include <X11/cursorfont.h>
+
+/*
+ * A factory method for an empty cursor
+ */
+static Cursor getEmptyCursor( void )
+{
+    static Cursor cursorNone = None;
+    if( cursorNone == None ) {
+        char cursorNoneBits[ 32 ];
+        XColor dontCare;
+        Pixmap cursorNonePixmap;
+        memset( cursorNoneBits, 0, sizeof( cursorNoneBits ) );
+        memset( &dontCare, 0, sizeof( dontCare ) );
+        cursorNonePixmap = XCreateBitmapFromData ( fgDisplay.pDisplay.Display,
+                                                   fgDisplay.pDisplay.RootWindow,
+                                                   cursorNoneBits, 16, 16 );
+        if( cursorNonePixmap != None ) {
+            cursorNone = XCreatePixmapCursor( fgDisplay.pDisplay.Display,
+                                              cursorNonePixmap, cursorNonePixmap,
+                                              &dontCare, &dontCare, 0, 0 );
+            XFreePixmap( fgDisplay.pDisplay.Display, cursorNonePixmap );
+        }
+    }
+    return cursorNone;
+}
+
+typedef struct tag_cursorCacheEntry cursorCacheEntry;
+struct tag_cursorCacheEntry {
+    unsigned int cursorShape;    /* an XC_foo value */
+    Cursor cachedCursor;         /* None if the corresponding cursor has
+                                    not been created yet */
+};
+
+/*
+ * Note: The arrangement of the table below depends on the fact that
+ * the "normal" GLUT_CURSOR_* values start a 0 and are consecutive.
+ */ 
+static cursorCacheEntry cursorCache[] = {
+    { XC_arrow,               None }, /* GLUT_CURSOR_RIGHT_ARROW */
+    { XC_top_left_arrow,      None }, /* GLUT_CURSOR_LEFT_ARROW */
+    { XC_hand1,               None }, /* GLUT_CURSOR_INFO */
+    { XC_pirate,              None }, /* GLUT_CURSOR_DESTROY */
+    { XC_question_arrow,      None }, /* GLUT_CURSOR_HELP */
+    { XC_exchange,            None }, /* GLUT_CURSOR_CYCLE */
+    { XC_spraycan,            None }, /* GLUT_CURSOR_SPRAY */
+    { XC_watch,               None }, /* GLUT_CURSOR_WAIT */
+    { XC_xterm,               None }, /* GLUT_CURSOR_TEXT */
+    { XC_crosshair,           None }, /* GLUT_CURSOR_CROSSHAIR */
+    { XC_sb_v_double_arrow,   None }, /* GLUT_CURSOR_UP_DOWN */
+    { XC_sb_h_double_arrow,   None }, /* GLUT_CURSOR_LEFT_RIGHT */
+    { XC_top_side,            None }, /* GLUT_CURSOR_TOP_SIDE */
+    { XC_bottom_side,         None }, /* GLUT_CURSOR_BOTTOM_SIDE */
+    { XC_left_side,           None }, /* GLUT_CURSOR_LEFT_SIDE */
+    { XC_right_side,          None }, /* GLUT_CURSOR_RIGHT_SIDE */
+    { XC_top_left_corner,     None }, /* GLUT_CURSOR_TOP_LEFT_CORNER */
+    { XC_top_right_corner,    None }, /* GLUT_CURSOR_TOP_RIGHT_CORNER */
+    { XC_bottom_right_corner, None }, /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */
+    { XC_bottom_left_corner,  None }  /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */
+};
+
+void fgPlatformSetCursor ( SFG_Window *window, int cursorID )
+{
+    Cursor cursor;
+    /*
+     * XXX FULL_CROSSHAIR demotes to plain CROSSHAIR. Old GLUT allows
+     * for this, but if there is a system that easily supports a full-
+     * window (or full-screen) crosshair, we might consider it.
+     */
+    int cursorIDToUse =
+        ( cursorID == GLUT_CURSOR_FULL_CROSSHAIR ) ? GLUT_CURSOR_CROSSHAIR : cursorID;
+
+    if( ( cursorIDToUse >= 0 ) &&
+        ( cursorIDToUse < sizeof( cursorCache ) / sizeof( cursorCache[0] ) ) ) {
+        cursorCacheEntry *entry = &cursorCache[ cursorIDToUse ];
+        if( entry->cachedCursor == None ) {
+            entry->cachedCursor =
+                XCreateFontCursor( fgDisplay.pDisplay.Display, entry->cursorShape );
+        }
+        cursor = entry->cachedCursor;
+    } else {
+        switch( cursorIDToUse )
+        {
+        case GLUT_CURSOR_NONE:
+            cursor = getEmptyCursor( );
+            break;
+
+        case GLUT_CURSOR_INHERIT:
+            cursor = None;
+            break;
+
+        default:
+            fgError( "Unknown cursor type: %d", cursorIDToUse );
+            return;
+        }
+    }
+
+    if ( cursorIDToUse == GLUT_CURSOR_INHERIT ) {
+        XUndefineCursor( fgDisplay.pDisplay.Display, window->Window.Handle );
+    } else if ( cursor != None ) {
+        XDefineCursor( fgDisplay.pDisplay.Display, window->Window.Handle, cursor );
+    } else if ( cursorIDToUse != GLUT_CURSOR_NONE ) {
+        fgError( "Failed to create cursor" );
+    }
+}
+
+
+void fgPlatformWarpPointer ( int x, int y )
+{
+    XWarpPointer(
+        fgDisplay.pDisplay.Display,
+        None,
+        fgStructure.CurrentWindow->Window.Handle,
+        0, 0, 0, 0,
+        x, y
+    );
+    /* Make the warp visible immediately. */
+    XFlush( fgDisplay.pDisplay.Display );
+}
+
diff --git a/src/x11/fg_display_x11.c b/src/x11/fg_display_x11.c
new file mode 100644 (file)
index 0000000..bbf9061
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * freeglut_display_x11.c
+ *
+ * Display message posting, context buffer swapping.
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ * Copied for Platform code by Evan Felix <karcaw at gmail.com>
+ * Creation date: Thur Feb 2 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+void fgPlatformGlutSwapBuffers( SFG_PlatformDisplay *pDisplayPtr, SFG_Window* CurrentWindow )
+{
+    glXSwapBuffers( pDisplayPtr->Display, CurrentWindow->Window.Handle );
+}
+
diff --git a/src/x11/fg_ext_x11.c b/src/x11/fg_ext_x11.c
new file mode 100644 (file)
index 0000000..d243cfd
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * freeglut_ext.c
+ *
+ * Functions related to OpenGL extensions.
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ * Copied for Platform code by Evan Felix <karcaw at gmail.com>
+ * Creation date: Thur Feb 2 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define GLX_GLXEXT_PROTOTYPES
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+GLUTproc fgPlatformGetGLUTProcAddress( const char* procName )
+{
+    /* optimization: quick initial check */
+    if( strncmp( procName, "glut", 4 ) != 0 )
+        return NULL;
+
+#define CHECK_NAME(x) if( strcmp( procName, #x ) == 0) return (GLUTproc)x;
+    CHECK_NAME(glutJoystickFunc);
+    CHECK_NAME(glutForceJoystickFunc);
+    CHECK_NAME(glutGameModeString);
+    CHECK_NAME(glutEnterGameMode);
+    CHECK_NAME(glutLeaveGameMode);
+    CHECK_NAME(glutGameModeGet);
+#undef CHECK_NAME
+
+    return NULL;
+}
+
+
+SFG_Proc fgPlatformGetProcAddress( const char *procName )
+{
+#if defined( GLX_ARB_get_proc_address )
+    return (SFG_Proc)glXGetProcAddressARB( ( const GLubyte * )procName );
+#else
+    return NULL;
+#endif
+}
+
diff --git a/src/x11/fg_gamemode_x11.c b/src/x11/fg_gamemode_x11.c
new file mode 100644 (file)
index 0000000..6130aeb
--- /dev/null
@@ -0,0 +1,571 @@
+/*
+ * freeglut_gamemode_x11.c
+ *
+ * The game mode handling code.
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ * Copied for Platform code by Evan Felix <karcaw at gmail.com>
+ * Creation date: Thur Feb 2 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+static int xrandr_resize(int xsz, int ysz, int rate, int just_checking)
+{
+#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
+    int event_base, error_base, ver_major, ver_minor, use_rate;
+    XRRScreenConfiguration *xrr_config = 0;
+    Status result = -1;
+
+    /* must check at runtime for the availability of the extension */
+    if(!XRRQueryExtension(fgDisplay.pDisplay.Display, &event_base, &error_base)) {
+        return -1;
+    }
+
+    XRRQueryVersion(fgDisplay.pDisplay.Display, &ver_major, &ver_minor);
+
+    /* we only heed the rate if we CAN actually use it (Xrandr >= 1.1) and
+     * the user actually cares about it (rate > 0)
+     */
+    use_rate = ( rate > 0 ) && ( ( ver_major >= 1 ) ||
+                                        ( ( ver_major == 1 ) && ( ver_minor >= 1 ) ) );
+
+    /* this loop is only so that the whole thing will be repeated if someone
+     * else changes video mode between our query of the current information and
+     * the attempt to change it.
+     */
+    do {
+        XRRScreenSize *ssizes;
+        short *rates;
+        Rotation rot;
+        int i, ssizes_count, rates_count, curr, res_idx = -1;
+        Time timestamp, cfg_timestamp;
+
+        if(xrr_config) {
+            XRRFreeScreenConfigInfo(xrr_config);
+        }
+
+        if(!(xrr_config = XRRGetScreenInfo(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow))) {
+            fgWarning("XRRGetScreenInfo failed");
+            break;
+        }
+        ssizes = XRRConfigSizes(xrr_config, &ssizes_count);
+        curr = XRRConfigCurrentConfiguration(xrr_config, &rot);
+        timestamp = XRRConfigTimes(xrr_config, &cfg_timestamp);
+
+        /* if either of xsz or ysz are unspecified, use the current values */
+        if(xsz <= 0)
+            xsz = fgState.GameModeSize.X = ssizes[curr].width;
+        if(ysz <= 0)
+            ysz = fgState.GameModeSize.Y = ssizes[curr].height;
+
+
+        if(xsz == ssizes[curr].width && ysz == ssizes[curr].height) {
+            /* no need to switch, we're already in the requested resolution */
+            res_idx = curr;
+        } else {
+            for(i=0; i<ssizes_count; i++) {
+                if(ssizes[i].width == xsz && ssizes[i].height == ysz) {
+                    res_idx = i;
+                    break;  /* found it */
+                }
+            }
+        }
+        if(res_idx == -1)
+            break;  /* no matching resolution */
+
+#if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
+        if(use_rate) {
+            rate = fgState.GameModeRefresh;
+
+            /* for the selected resolution, let's find out if there is
+             * a matching refresh rate available.
+             */
+            rates = XRRConfigRates(xrr_config, res_idx, &rates_count);
+
+            for(i=0; i<rates_count; i++) {
+                if(rates[i] == rate) {
+                    break;
+                }
+            }
+            if(i == rates_count) {
+                break; /* no matching rate */
+            }
+        }
+#endif
+
+        if(just_checking) {
+            result = 0;
+            break;
+        }
+
+#if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
+        if(use_rate)
+            result = XRRSetScreenConfigAndRate(fgDisplay.pDisplay.Display, xrr_config,
+                    fgDisplay.pDisplay.RootWindow, res_idx, rot, rate, timestamp);
+        else
+#endif
+            result = XRRSetScreenConfig(fgDisplay.pDisplay.Display, xrr_config,
+                    fgDisplay.pDisplay.RootWindow, res_idx, rot, timestamp);
+
+    } while(result == RRSetConfigInvalidTime);
+
+    if(xrr_config) {
+        XRRFreeScreenConfigInfo(xrr_config);
+    }
+
+    if(result == 0) {
+        return 0;
+    }
+
+#endif  /* HAVE_X11_EXTENSIONS_XRANDR_H */
+    return -1;
+}
+
+/*
+ * Remembers the current visual settings, so that
+ * we can change them and restore later...
+ */
+void fgPlatformRememberState( void )
+{
+    int event_base, error_base;
+
+    /*
+     * Remember the current pointer location before going fullscreen
+     * for restoring it later:
+     */
+    Window junk_window;
+    unsigned int junk_mask;
+
+    XQueryPointer(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow,
+            &junk_window, &junk_window,
+            &fgDisplay.pDisplay.DisplayPointerX, &fgDisplay.pDisplay.DisplayPointerY,
+            &fgDisplay.pDisplay.DisplayPointerX, &fgDisplay.pDisplay.DisplayPointerY, &junk_mask);
+
+#   ifdef HAVE_X11_EXTENSIONS_XRANDR_H
+    if(XRRQueryExtension(fgDisplay.pDisplay.Display, &event_base, &error_base)) {
+        XRRScreenConfiguration *xrr_config;
+        XRRScreenSize *ssizes;
+        Rotation rot;
+        int ssize_count, curr;
+
+        if((xrr_config = XRRGetScreenInfo(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow))) {
+            ssizes = XRRConfigSizes(xrr_config, &ssize_count);
+            curr = XRRConfigCurrentConfiguration(xrr_config, &rot);
+
+            fgDisplay.pDisplay.prev_xsz = ssizes[curr].width;
+            fgDisplay.pDisplay.prev_ysz = ssizes[curr].height;
+            fgDisplay.pDisplay.prev_refresh = -1;
+
+#       if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
+            if(fgState.GameModeRefresh != -1) {
+                fgDisplay.pDisplay.prev_refresh = XRRConfigCurrentRate(xrr_config);
+            }
+#       endif
+
+            fgDisplay.pDisplay.prev_size_valid = 1;
+
+            XRRFreeScreenConfigInfo(xrr_config);
+        }
+    }
+#   endif
+
+    /*
+     * This highly depends on the XFree86 extensions,
+     * not approved as X Consortium standards
+     */
+#   ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
+    if(!XF86VidModeQueryExtension(fgDisplay.pDisplay.Display, &event_base, &error_base)) {
+        return;
+    }
+
+    /*
+     * Remember the current ViewPort location of the screen to be able to
+     * restore the ViewPort on LeaveGameMode():
+     */
+    if( !XF86VidModeGetViewPort(
+             fgDisplay.pDisplay.Display,
+             fgDisplay.pDisplay.Screen,
+             &fgDisplay.pDisplay.DisplayViewPortX,
+             &fgDisplay.pDisplay.DisplayViewPortY ) )
+        fgWarning( "XF86VidModeGetViewPort failed" );
+
+
+    /* Query the current display settings: */
+    fgDisplay.pDisplay.DisplayModeValid =
+      XF86VidModeGetModeLine(
+        fgDisplay.pDisplay.Display,
+        fgDisplay.pDisplay.Screen,
+        &fgDisplay.pDisplay.DisplayModeClock,
+        &fgDisplay.pDisplay.DisplayMode
+    );
+
+    if( !fgDisplay.pDisplay.DisplayModeValid )
+        fgWarning( "XF86VidModeGetModeLine failed" );
+#   endif
+
+}
+
+/*
+ * Restores the previously remembered visual settings
+ */
+void fgPlatformRestoreState( void )
+{
+    /* Restore the remembered pointer position: */
+    XWarpPointer(
+        fgDisplay.pDisplay.Display, None, fgDisplay.pDisplay.RootWindow, 0, 0, 0, 0,
+        fgDisplay.pDisplay.DisplayPointerX, fgDisplay.pDisplay.DisplayPointerY
+    );
+
+
+#   ifdef HAVE_X11_EXTENSIONS_XRANDR_H
+    if(fgDisplay.pDisplay.prev_size_valid) {
+        if(xrandr_resize(fgDisplay.pDisplay.prev_xsz, fgDisplay.pDisplay.prev_ysz, fgDisplay.pDisplay.prev_refresh, 0) != -1) {
+            fgDisplay.pDisplay.prev_size_valid = 0;
+#       ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
+            fgDisplay.pDisplay.DisplayModeValid = 0;
+#       endif
+            return;
+        }
+    }
+#   endif
+
+
+
+#   ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
+    /*
+     * This highly depends on the XFree86 extensions,
+     * not approved as X Consortium standards
+     */
+
+    if( fgDisplay.pDisplay.DisplayModeValid )
+    {
+        XF86VidModeModeInfo** displayModes;
+        int i, displayModesCount;
+
+        if( !XF86VidModeGetAllModeLines(
+                 fgDisplay.pDisplay.Display,
+                 fgDisplay.pDisplay.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.pDisplay.DisplayMode.hdisplay &&
+               displayModes[ i ]->vdisplay == fgDisplay.pDisplay.DisplayMode.vdisplay &&
+               displayModes[ i ]->dotclock == fgDisplay.pDisplay.DisplayModeClock )
+            {
+                if( !XF86VidModeSwitchToMode(
+                         fgDisplay.pDisplay.Display,
+                         fgDisplay.pDisplay.Screen,
+                         displayModes[ i ] ) )
+                {
+                    fgWarning( "XF86VidModeSwitchToMode failed" );
+                    break;
+                }
+
+                if( !XF86VidModeSetViewPort(
+                         fgDisplay.pDisplay.Display,
+                         fgDisplay.pDisplay.Screen,
+                         fgDisplay.pDisplay.DisplayViewPortX,
+                         fgDisplay.pDisplay.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.pDisplay.Display );
+
+                fgDisplay.pDisplay.DisplayModeValid = 0;
+#       ifdef HAVE_X11_EXTENSIONS_XRANDR_H
+                fgDisplay.pDisplay.prev_size_valid = 0;
+#       endif
+
+                break;
+            }
+        }
+        XFree( displayModes );
+    }
+
+#   endif
+
+}
+
+#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
+
+/*
+ * Checks a single display mode settings against user's preferences.
+ */
+static GLboolean fghCheckDisplayMode( int width, int height, int depth, int refresh )
+{
+    /* The desired values should be stored in fgState structure... */
+    return ( width == fgState.GameModeSize.X ) &&
+           ( height == fgState.GameModeSize.Y ) &&
+           ( depth == fgState.GameModeDepth ) &&
+           ( refresh == fgState.GameModeRefresh );
+}
+
+/*
+ * Checks all display modes settings against user's preferences.
+ * Returns the mode number found or -1 if none could be found.
+ */
+static int fghCheckDisplayModes( GLboolean exactMatch, int displayModesCount, XF86VidModeModeInfo** displayModes )
+{
+    int i;
+    for( i = 0; i < displayModesCount; i++ )
+    {
+        /* Compute the displays refresh rate, dotclock comes in kHz. */
+        int refresh = ( displayModes[ i ]->dotclock * 1000 ) /
+                      ( displayModes[ i ]->htotal * displayModes[ i ]->vtotal );
+
+        if( fghCheckDisplayMode( displayModes[ i ]->hdisplay,
+                                 displayModes[ i ]->vdisplay,
+                                 fgState.GameModeDepth,
+                                 ( exactMatch ? refresh : fgState.GameModeRefresh ) ) ) {
+            if (!exactMatch)
+            {
+                /* Update the chosen refresh rate, otherwise a
+                 * glutGameModeGet(GLUT_GAME_MODE_REFRESH_RATE) would not
+                 * return the right values
+                 */
+                fgState.GameModeRefresh = refresh;
+            }
+
+            return i;
+        }
+    }
+    return -1;
+}
+
+#endif
+
+/*
+ * Changes the current display mode to match user's settings
+ */
+GLboolean fgPlatformChangeDisplayMode( GLboolean haveToTest )
+{
+    GLboolean success = GL_FALSE;
+    /* first try to use XRandR, then fallback to XF86VidMode */
+#   ifdef HAVE_X11_EXTENSIONS_XRANDR_H
+    if(xrandr_resize(fgState.GameModeSize.X, fgState.GameModeSize.Y,
+                fgState.GameModeRefresh, haveToTest) != -1) {
+        return GL_TRUE;
+    }
+#   endif
+
+
+    /*
+     * This highly depends on the XFree86 extensions,
+     * not approved as X Consortium standards
+     */
+#   ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
+
+    /*
+     * This is also used by applications which check modes by calling
+     * glutGameModeGet(GLUT_GAME_MODE_POSSIBLE), so allow the check:
+     */
+    if( haveToTest || fgDisplay.pDisplay.DisplayModeValid )
+    {
+        XF86VidModeModeInfo** displayModes;
+        int i, displayModesCount;
+
+        /* If we don't have a valid modeline in the display structure, which
+         * can happen if this is called from glutGameModeGet instead of
+         * glutEnterGameMode, then we need to query the current mode, to make
+         * unspecified settings to default to their current values.
+         */
+        if(!fgDisplay.pDisplay.DisplayModeValid) {
+            if(!XF86VidModeGetModeLine(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen,
+                    &fgDisplay.pDisplay.DisplayModeClock, &fgDisplay.pDisplay.DisplayMode)) {
+                return success;
+            }
+        }
+
+        if (fgState.GameModeSize.X == -1)
+        {
+            fgState.GameModeSize.X = fgDisplay.pDisplay.DisplayMode.hdisplay;
+        }
+        if (fgState.GameModeSize.Y == -1)
+        {
+            fgState.GameModeSize.Y = fgDisplay.pDisplay.DisplayMode.vdisplay;
+        }
+        if (fgState.GameModeDepth == -1)
+        {
+            /* can't get color depth from this, nor can we change it, do nothing
+             * TODO: get with XGetVisualInfo()? but then how to set?
+             */
+        }
+        if (fgState.GameModeRefresh == -1)
+        {
+            /* Compute the displays refresh rate, dotclock comes in kHz. */
+            int refresh = ( fgDisplay.pDisplay.DisplayModeClock * 1000 ) /
+                ( fgDisplay.pDisplay.DisplayMode.htotal * fgDisplay.pDisplay.DisplayMode.vtotal );
+
+            fgState.GameModeRefresh = refresh;
+        }
+
+        /* query all possible display modes */
+        if( !XF86VidModeGetAllModeLines(
+                 fgDisplay.pDisplay.Display,
+                 fgDisplay.pDisplay.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.pDisplay.Display,
+                     fgDisplay.pDisplay.Screen,
+                     displayModes[ i ] ) )
+                fgWarning( "XF86VidModeSwitchToMode failed" );
+        }
+
+        XFree( displayModes );
+    }
+
+#   endif
+
+    return success;
+}
+
+
+void fgPlatformEnterGameMode( void ) 
+{
+
+    /*
+     * 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.pDisplay.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.pDisplay.Display, fgStructure.GameModeWindow->Window.Handle,
+               TRUE,
+               ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
+               | PointerMotionMask,
+               GrabModeAsync, GrabModeAsync,
+               fgStructure.GameModeWindow->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.pDisplay.Display,
+        fgStructure.GameModeWindow->Window.Handle,
+        RevertToNone,
+        CurrentTime
+    );
+
+    /* Move the Pointer to the middle of the fullscreen window */
+    XWarpPointer(
+        fgDisplay.pDisplay.Display,
+        None,
+        fgDisplay.pDisplay.RootWindow,
+        0, 0, 0, 0,
+        fgState.GameModeSize.X/2, fgState.GameModeSize.Y/2
+    );
+
+#   ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
+
+    if( fgDisplay.pDisplay.DisplayModeValid )
+    {
+        int x, y;
+        Window child;
+
+        /* Change to viewport to the window topleft edge: */
+        if( !XF86VidModeSetViewPort( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.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.pDisplay.Display,
+            fgStructure.CurrentWindow->Window.Handle,
+            fgDisplay.pDisplay.RootWindow,
+            0, 0, &x, &y,
+            &child
+        );
+
+        /* Move the decorataions out of the topleft corner of the display */
+        XMoveWindow( fgDisplay.pDisplay.Display, fgStructure.CurrentWindow->Window.Handle,
+                     -x, -y);
+    }
+
+#endif
+
+    /* Grab the keyboard, too */
+    XGrabKeyboard(
+        fgDisplay.pDisplay.Display,
+        fgStructure.GameModeWindow->Window.Handle,
+        FALSE,
+        GrabModeAsync, GrabModeAsync,
+        CurrentTime
+    );
+
+}
+
+void fgPlatformLeaveGameMode( void ) 
+{
+    XUngrabPointer( fgDisplay.pDisplay.Display, CurrentTime );
+    XUngrabKeyboard( fgDisplay.pDisplay.Display, CurrentTime );
+}
+
diff --git a/src/x11/fg_glutfont_definitions_x11.c b/src/x11/fg_glutfont_definitions_x11.c
new file mode 100644 (file)
index 0000000..f2519c5
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * freeglut_glutfont_definitions_x11.c
+ *
+ * Bitmap and stroke fonts displaying.
+ *
+ * Copyright (c) 2003 Stephen J. Baker (whether he wants it or not).
+ * All Rights Reserved.
+ * Written by John F. Fay <fayjf@sourceforge.net>, who releases the
+ * copyright over to the "freeglut" project lead.
+ * Creation date: Mon July 21 2003
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * This file is necessary for the *nix version of "freeglut" because the
+ * original GLUT defined its font variables in rather an unusual way.
+ * Publicly, in "glut.h", they were defined as "void *".  Privately,
+ * in one of the source code files, they were defined as pointers to a
+ * structure.  Most compilers and linkers are satisfied with the "void *"
+ * and don't go any farther, but some of them balked.  In particular,
+ * when compiling with "freeglut" and then trying to run using the GLUT
+ * ".so" library, some of them would give an error.  So we are having to
+ * create this file to define the variables as pointers to an unusual
+ * structure to match GLUT.
+ */
+
+/*
+ * freeglut_internal.h uses some GL types, but including the GL header portably
+ * is a bit tricky, so we include freeglut_std.h here, which contains the
+ * necessary machinery. But this poses another problem, caused by the ugly
+ * original defintion of the font constants in "classic" GLUT: They are defined
+ * as void* externally, so we move them temporarily out of the way by AN EXTREME
+ * CPP HACK.
+ */
+
+#define glutStrokeRoman glutStrokeRomanIGNOREME
+#define glutStrokeMonoRoman glutStrokeMonoRomanIGNOREME
+#define glutBitmap9By15 glutBitmap9By15IGNOREME
+#define glutBitmap8By13 glutBitmap8By13IGNOREME
+#define glutBitmapTimesRoman10 glutBitmapTimesRoman10IGNOREME
+#define glutBitmapTimesRoman24 glutBitmapTimesRoman24IGNOREME
+#define glutBitmapHelvetica10 glutBitmapHelvetica10IGNOREME
+#define glutBitmapHelvetica12 glutBitmapHelvetica12IGNOREME
+#define glutBitmapHelvetica18 glutBitmapHelvetica18IGNOREME
+
+#include <GL/freeglut_std.h>
+
+#undef glutStrokeRoman
+#undef glutStrokeMonoRoman
+#undef glutBitmap9By15
+#undef glutBitmap8By13
+#undef glutBitmapTimesRoman10
+#undef glutBitmapTimesRoman24
+#undef glutBitmapHelvetica10
+#undef glutBitmapHelvetica12
+#undef glutBitmapHelvetica18
+
+#include "../fg_internal.h"
+
+struct freeglutStrokeFont
+{
+  const char *name ;
+  int num_chars ;
+  void *ch ;
+  float top ;
+  float bottom ;
+};
+
+struct freeglutBitmapFont
+{
+  const char *name ;
+  const int num_chars ;
+  const int first ;
+  const void *ch ;
+};
+
+
+struct freeglutStrokeFont glutStrokeRoman ;
+struct freeglutStrokeFont glutStrokeMonoRoman ;
+
+struct freeglutBitmapFont glutBitmap9By15 ;
+struct freeglutBitmapFont glutBitmap8By13 ;
+struct freeglutBitmapFont glutBitmapTimesRoman10 ;
+struct freeglutBitmapFont glutBitmapTimesRoman24 ;
+struct freeglutBitmapFont glutBitmapHelvetica10 ;
+struct freeglutBitmapFont glutBitmapHelvetica12 ;
+struct freeglutBitmapFont glutBitmapHelvetica18 ;
+
diff --git a/src/x11/fg_init_x11.c b/src/x11/fg_init_x11.c
new file mode 100644 (file)
index 0000000..83fe287
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * freeglut_init_x11.c
+ *
+ * Various freeglut initialization functions.
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ * Copied for Platform code by Evan Felix <karcaw at gmail.com>
+ * Creation date: Thur Feb 2 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define FREEGLUT_BUILDING_LIB
+#include <limits.h>  /* LONG_MAX */
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+/* Return the atom associated with "name". */
+static Atom fghGetAtom(const char * name)
+{
+  return XInternAtom(fgDisplay.pDisplay.Display, name, False);
+}
+
+/*
+ * Check if "property" is set on "window".  The property's values are returned
+ * through "data".  If the property is set and is of type "type", return the
+ * number of elements in "data".  Return zero otherwise.  In both cases, use
+ * "Xfree()" to free "data".
+ */
+static int fghGetWindowProperty(Window window,
+                               Atom property,
+                               Atom type,
+                               unsigned char ** data)
+{
+  /*
+   * Caller always has to use "Xfree()" to free "data", since
+   * "XGetWindowProperty() always allocates one extra byte in prop_return
+   * [i.e. "data"] (even if the property is zero length) [..]".
+   */
+
+  int status;  /*  Returned by "XGetWindowProperty". */
+
+  Atom          type_returned;
+  int           temp_format;             /*  Not used. */
+  unsigned long number_of_elements;
+  unsigned long temp_bytes_after;        /*  Not used. */
+
+
+  status = XGetWindowProperty(fgDisplay.pDisplay.Display,
+                             window,
+                             property,
+                             0,
+                             LONG_MAX,
+                             False,
+                             type,
+                             &type_returned,
+                             &temp_format,
+                             &number_of_elements,
+                             &temp_bytes_after,
+                             data);
+
+  FREEGLUT_INTERNAL_ERROR_EXIT(status == Success,
+                              "XGetWindowProperty failled",
+                              "fghGetWindowProperty");
+
+  if (type_returned != type)
+    {
+      number_of_elements = 0;
+    }
+
+  return number_of_elements;
+}
+
+/*  Check if the window manager is NET WM compliant. */
+static int fghNetWMSupported(void)
+{
+  Atom wm_check;
+  Window ** window_ptr_1;
+
+  int number_of_windows;
+  int net_wm_supported;
+
+
+  net_wm_supported = 0;
+
+  wm_check = fghGetAtom("_NET_SUPPORTING_WM_CHECK");
+  window_ptr_1 = malloc(sizeof(Window *));
+
+  /*
+   * Check that the window manager has set this property on the root window.
+   * The property must be the ID of a child window.
+   */
+  number_of_windows = fghGetWindowProperty(fgDisplay.pDisplay.RootWindow,
+                                           wm_check,
+                                           XA_WINDOW,
+                                           (unsigned char **) window_ptr_1);
+  if (number_of_windows == 1)
+    {
+      Window ** window_ptr_2;
+
+      window_ptr_2 = malloc(sizeof(Window *));
+
+      /* Check that the window has the same property set to the same value. */
+      number_of_windows = fghGetWindowProperty(**window_ptr_1,
+                                               wm_check,
+                                               XA_WINDOW,
+                                               (unsigned char **) window_ptr_2);
+      if ((number_of_windows == 1) && (**window_ptr_1 == **window_ptr_2))
+      {
+        /* NET WM compliant */
+        net_wm_supported = 1;
+      }
+
+      XFree(*window_ptr_2);
+      free(window_ptr_2);
+    }
+
+        XFree(*window_ptr_1);
+        free(window_ptr_1);
+
+        return net_wm_supported;
+}
+
+/*  Check if "hint" is present in "property" for "window". */
+int fgHintPresent(Window window, Atom property, Atom hint)
+{
+  Atom *atoms;
+  int number_of_atoms;
+  int supported;
+  int i;
+
+  supported = 0;
+
+  number_of_atoms = fghGetWindowProperty(window,
+                                        property,
+                                        XA_ATOM,
+                                        (unsigned char **) &atoms);
+  for (i = 0; i < number_of_atoms; i++)
+  {
+      if (atoms[i] == hint)
+      {
+          supported = 1;
+          break;
+      }
+  }
+
+  XFree(atoms);
+  return supported;
+}
+
+/*
+ * A call to this function should initialize all the display stuff...
+ */
+void fgPlatformInitialize( const char* displayName )
+{
+    fgDisplay.pDisplay.Display = XOpenDisplay( displayName );
+
+    if( fgDisplay.pDisplay.Display == NULL )
+        fgError( "failed to open display '%s'", XDisplayName( displayName ) );
+
+    if( !glXQueryExtension( fgDisplay.pDisplay.Display, NULL, NULL ) )
+        fgError( "OpenGL GLX extension not supported by display '%s'",
+            XDisplayName( displayName ) );
+
+    fgDisplay.pDisplay.Screen = DefaultScreen( fgDisplay.pDisplay.Display );
+    fgDisplay.pDisplay.RootWindow = RootWindow(
+        fgDisplay.pDisplay.Display,
+        fgDisplay.pDisplay.Screen
+    );
+
+    fgDisplay.ScreenWidth  = DisplayWidth(
+        fgDisplay.pDisplay.Display,
+        fgDisplay.pDisplay.Screen
+    );
+    fgDisplay.ScreenHeight = DisplayHeight(
+        fgDisplay.pDisplay.Display,
+        fgDisplay.pDisplay.Screen
+    );
+
+    fgDisplay.ScreenWidthMM = DisplayWidthMM(
+        fgDisplay.pDisplay.Display,
+        fgDisplay.pDisplay.Screen
+    );
+    fgDisplay.ScreenHeightMM = DisplayHeightMM(
+        fgDisplay.pDisplay.Display,
+        fgDisplay.pDisplay.Screen
+    );
+
+    fgDisplay.pDisplay.Connection = ConnectionNumber( fgDisplay.pDisplay.Display );
+
+    /* Create the window deletion atom */
+    fgDisplay.pDisplay.DeleteWindow = fghGetAtom("WM_DELETE_WINDOW");
+
+    /* Create the state and full screen atoms */
+    fgDisplay.pDisplay.State           = None;
+    fgDisplay.pDisplay.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.pDisplay.RootWindow, supported, state))
+      {
+        const Atom full_screen = fghGetAtom("_NET_WM_STATE_FULLSCREEN");
+        
+        fgDisplay.pDisplay.State = state;
+        
+        /* Check if the window manager supports full screen. */
+        /**  Check "_NET_WM_ALLOWED_ACTIONS" on our window instead? **/
+        if (fgHintPresent(fgDisplay.pDisplay.RootWindow, supported, full_screen))
+        {
+          fgDisplay.pDisplay.StateFullScreen = full_screen;
+        }
+      }
+    }
+
+
+    fgState.Initialised = GL_TRUE;
+
+    atexit(fgDeinitialize);
+
+    /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */
+    fgInitialiseInputDevices();
+}
+
+void fgPlatformDeinitialiseInputDevices ( void )
+{
+       fghCloseInputDevices ();
+
+    fgState.JoysticksInitialised = GL_FALSE;
+    fgState.InputDevsInitialised = GL_FALSE;
+}
+
+
+void fgPlatformCloseDisplay ( void )
+{
+    /*
+     * Make sure all X-client data we have created will be destroyed on
+     * display closing
+     */
+    XSetCloseDownMode( fgDisplay.pDisplay.Display, DestroyAll );
+
+    /*
+     * Close the display connection, destroying all windows we have
+     * created so far
+     */
+    XCloseDisplay( fgDisplay.pDisplay.Display );
+}
+
+
+void fgPlatformDestroyContext ( SFG_PlatformDisplay pDisplay, SFG_WindowContextType MContext )
+{
+    /* Note that the MVisualInfo is not owned by the MenuContext! */
+    glXDestroyContext( pDisplay.Display, MContext );
+}
diff --git a/src/x11/fg_input_devices_x11.c b/src/x11/fg_input_devices_x11.c
new file mode 100644 (file)
index 0000000..a94e52a
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * freeglut_input_devices_x11.c
+ *
+ * Handles miscellaneous input devices via direct serial-port access.
+ * Proper X11 XInput device support is not yet supported.
+ * Also lacks Mac support.
+ *
+ * Written by Joe Krahn <krahn@niehs.nih.gov> 2005
+ *
+ * Copyright (c) 2005 Stephen J. Baker. All Rights Reserved.
+ * Copied for Platform code by Evan Felix <karcaw at gmail.com>
+ * Creation date: Thur Feb 2 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA OR STEPHEN J. BAKER BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#    include "config.h"
+#endif
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <fcntl.h>
+
+struct _serialport {
+   int fd;
+   struct termios termio, termio_save;
+};
+
+typedef struct _serialport SERIALPORT;
+
+void serial_flush ( SERIALPORT *port );
+
+/* local variables */
+static SERIALPORT *dialbox_port=NULL;
+
+/*****************************************************************/
+
+/*
+ * Try initializing the input device(s)
+ */
+void fgPlatformRegisterDialDevice ( const char *dial_device )
+{
+}
+
+SERIALPORT *serial_open ( const char *device )
+{
+    int fd;
+    struct termios termio;
+    SERIALPORT *port;
+
+    fd = open(device, O_RDWR | O_NONBLOCK );
+    if (fd <0) {
+        perror(device);
+        return NULL;
+    }
+
+    port = malloc(sizeof(SERIALPORT));
+    memset(port, 0, sizeof(SERIALPORT));
+    port->fd = fd;
+
+    /* save current port settings */
+    tcgetattr(fd,&port->termio_save);
+
+    memset(&termio, 0, sizeof(termio));
+    termio.c_cflag = CS8 | CREAD | HUPCL ;
+    termio.c_iflag = IGNPAR | IGNBRK ;
+    termio.c_cc[VTIME]    = 0;   /* inter-character timer */
+    termio.c_cc[VMIN]     = 1;   /* block read until 1 chars received, when blocking I/O */
+
+    cfsetispeed(&termio, B9600);
+    cfsetospeed(&termio, B9600);
+    tcsetattr(fd,TCSANOW,&termio);
+
+    serial_flush(port);
+    return port;
+}
+
+void serial_close(SERIALPORT *port)
+{
+    if (port)
+    {
+        /* restore old port settings */
+        tcsetattr(port->fd,TCSANOW,&port->termio_save);
+        close(port->fd);
+        free(port);
+    }
+}
+
+int serial_getchar(SERIALPORT *port)
+{
+    unsigned char ch;
+    if (!port) return EOF;
+    if (read(port->fd,&ch,1)) return ch;
+    return EOF;
+}
+
+int serial_putchar(SERIALPORT *port, unsigned char ch)
+{
+    if (!port) return 0;
+    return write(port->fd,&ch,1);
+}
+
+void serial_flush ( SERIALPORT *port )
+{
+    tcflush ( port->fd, TCIOFLUSH );
+}
diff --git a/src/x11/fg_internal_x11.h b/src/x11/fg_internal_x11.h
new file mode 100644 (file)
index 0000000..8a8e197
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * freeglut_internal_x11.h
+ *
+ * The freeglut library private include file.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by Diederick C. Niehorster, <dcnieho@gmail.com>
+ * Creation date: Fri Jan 20, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef  FREEGLUT_INTERNAL_X11_H
+#define  FREEGLUT_INTERNAL_X11_H
+
+
+/* -- PLATFORM-SPECIFIC INCLUDES ------------------------------------------- */
+#include <GL/glx.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+#include <X11/extensions/XInput.h>
+#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
+#    include <X11/extensions/xf86vmode.h>
+#endif
+#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
+#    include <X11/extensions/Xrandr.h>
+#endif
+/* If GLX is too old, we will fail during runtime when multisampling
+   is requested, but at least freeglut compiles. */
+#ifndef GLX_SAMPLE_BUFFERS
+#    define GLX_SAMPLE_BUFFERS 0x80A8
+#endif
+#ifndef GLX_SAMPLES
+#    define GLX_SAMPLES 0x80A9
+#endif
+
+
+
+/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */
+/* The structure used by display initialization in freeglut_init.c */
+typedef struct tagSFG_PlatformDisplay SFG_PlatformDisplay;
+struct tagSFG_PlatformDisplay
+{
+    Display*        Display;            /* The display we are being run in.  */
+    int             Screen;             /* The screen we are about to use.   */
+    Window          RootWindow;         /* The screen's root window.         */
+    int             Connection;         /* The display's connection number   */
+    Atom            DeleteWindow;       /* The window deletion atom          */
+    Atom            State;              /* The state atom                    */
+    Atom            StateFullScreen;    /* The full screen atom              */
+
+#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
+    int prev_xsz, prev_ysz;
+    int prev_refresh;
+    int prev_size_valid;
+#endif /* HAVE_X11_EXTENSIONS_XRANDR_H */
+
+#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
+    /*
+     * XF86VidMode may be compilable even if it fails at runtime.  Therefore,
+     * the validity of the VidMode has to be tracked
+     */
+    int             DisplayModeValid;   /* Flag that indicates runtime status*/
+    XF86VidModeModeLine DisplayMode;    /* Current screen's display settings */
+    int             DisplayModeClock;   /* The display mode's refresh rate   */
+    int             DisplayViewPortX;   /* saved X location of the viewport  */
+    int             DisplayViewPortY;   /* saved Y location of the viewport  */
+#endif /* HAVE_X11_EXTENSIONS_XF86VMODE_H */
+
+    int             DisplayPointerX;    /* saved X location of the pointer   */
+    int             DisplayPointerY;    /* saved Y location of the pointer   */
+};
+
+
+/*
+ * Make "freeglut" window handle and context types so that we don't need so
+ * much conditionally-compiled code later in the library.
+ */
+typedef Window     SFG_WindowHandleType ;
+typedef GLXContext SFG_WindowContextType ;
+typedef struct tagSFG_PlatformContext SFG_PlatformContext;
+struct tagSFG_PlatformContext
+{
+    GLXFBConfig*    FBConfig;        /* The window's FBConfig               */
+};
+
+
+/* Window's state description. This structure should be kept portable. */
+typedef struct tagSFG_PlatformWindowState SFG_PlatformWindowState;
+struct tagSFG_PlatformWindowState
+{
+    int             OldWidth;           /* Window width from before a resize */
+    int             OldHeight;          /*   "    height  "    "    "   "    */
+};
+
+
+/* -- JOYSTICK-SPECIFIC STRUCTURES AND TYPES ------------------------------- */
+/*
+ * Initial defines from "js.h" starting around line 33 with the existing "freeglut_joystick.c"
+ * interspersed
+ */
+#    ifdef HAVE_SYS_IOCTL_H
+#        include <sys/ioctl.h>
+#    endif
+#    ifdef HAVE_FCNTL_H
+#        include <fcntl.h>
+#    endif
+#    ifdef HAVE_ERRNO_H
+#        include <errno.h>
+#        include <string.h>
+#    endif
+#    if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
+/* XXX The below hack is done until freeglut's autoconf is updated. */
+#        define HAVE_USB_JS    1
+
+#        if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#            include <sys/joystick.h>
+#        else
+/*
+ * XXX NetBSD/amd64 systems may find that they have to steal the
+ * XXX /usr/include/machine/joystick.h from a NetBSD/i386 system.
+ * XXX I cannot comment whether that works for the interface, but
+ * XXX it lets you compile...(^&  I do not think that we can do away
+ * XXX with this header.
+ */
+#            include <machine/joystick.h>         /* For analog joysticks */
+#        endif
+#        define JS_DATA_TYPE joystick
+#        define JS_RETURN (sizeof(struct JS_DATA_TYPE))
+#    endif
+
+#    if defined(__linux__)
+#        include <linux/joystick.h>
+
+/* check the joystick driver version */
+#        if defined(JS_VERSION) && JS_VERSION >= 0x010000
+#            define JS_NEW
+#        endif
+#    else  /* Not BSD or Linux */
+#        ifndef JS_RETURN
+
+  /*
+   * We'll put these values in and that should
+   * allow the code to at least compile when there is
+   * no support. The JS open routine should error out
+   * and shut off all the code downstream anyway and if
+   * the application doesn't use a joystick we'll be fine.
+   */
+
+  struct JS_DATA_TYPE
+  {
+    int buttons;
+    int x;
+    int y;
+  };
+
+#            define JS_RETURN (sizeof(struct JS_DATA_TYPE))
+#        endif
+#    endif
+
+/* XXX It might be better to poll the operating system for the numbers of buttons and
+ * XXX axes and then dynamically allocate the arrays.
+ */
+#    define _JS_MAX_AXES 16
+typedef struct tagSFG_PlatformJoystick SFG_PlatformJoystick;
+struct tagSFG_PlatformJoystick
+{
+#   if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
+       struct os_specific_s *os;
+#   endif
+
+#   ifdef JS_NEW
+       struct js_event     js;
+       int          tmp_buttons;
+       float        tmp_axes [ _JS_MAX_AXES ];
+#   else
+       struct JS_DATA_TYPE js;
+#   endif
+
+    char         fname [ 128 ];
+    int          fd;
+};
+
+
+/* Menu font and color definitions */
+#define  FREEGLUT_MENU_FONT    GLUT_BITMAP_HELVETICA_18
+
+#define  FREEGLUT_MENU_PEN_FORE_COLORS   {0.0f,  0.0f,  0.0f,  1.0f}
+#define  FREEGLUT_MENU_PEN_BACK_COLORS   {0.70f, 0.70f, 0.70f, 1.0f}
+#define  FREEGLUT_MENU_PEN_HFORE_COLORS  {0.0f,  0.0f,  0.0f,  1.0f}
+#define  FREEGLUT_MENU_PEN_HBACK_COLORS  {1.0f,  1.0f,  1.0f,  1.0f}
+
+
+
+
+/* -- PRIVATE FUNCTION DECLARATIONS ---------------------------------------- */
+/* spaceball device functions, defined in freeglut_spaceball.c */
+int             fgIsSpaceballXEvent( const XEvent *ev );
+void            fgSpaceballHandleXEvent( const XEvent *ev );
+
+/*
+ * Check if "hint" is present in "property" for "window".  See freeglut_init.c
+ */
+int             fgHintPresent(Window window, Atom property, Atom hint);
+
+/* Handler for X extension Events */
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
+  void          fgHandleExtensionEvents( XEvent * ev );
+  void          fgRegisterDevices( Display* dpy, Window* win );
+#endif
+
+
+#endif  /* FREEGLUT_INTERNAL_X11_H */
diff --git a/src/x11/fg_joystick_x11.c b/src/x11/fg_joystick_x11.c
new file mode 100644 (file)
index 0000000..5d686b5
--- /dev/null
@@ -0,0 +1,465 @@
+/*
+ * freeglut_joystick_x11.c
+ *
+ * Joystick handling code
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Steve Baker, <sjbaker1@airmail.net>
+ * Copied for Platform code by Evan Felix <karcaw at gmail.com>
+ * Creation date: Thur Feb 2 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * FreeBSD port by Stephen Montgomery-Smith <stephen@math.missouri.edu>
+ *
+ * Redone by John Fay 2/4/04 with another look from the PLIB "js" library.
+ *  Many thanks for Steve Baker for permission to pull from that library.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+#ifdef HAVE_SYS_PARAM_H
+#    include <sys/param.h>
+#endif
+
+
+/*this should be defined in a header file */
+#define MAX_NUM_JOYSTICKS  2   
+extern SFG_Joystick *fgJoystick [ MAX_NUM_JOYSTICKS ];
+
+void fgPlatformJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes )
+{
+    int status;
+
+    int i;
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
+    int len;
+
+    if ( joy->pJoystick.os->is_analog )
+    {
+        int status = read ( joy->pJoystick.os->fd, &joy->pJoystick.os->ajs, sizeof(joy->pJoystick.os->ajs) );
+        if ( status != sizeof(joy->pJoystick.os->ajs) ) {
+            perror ( joy->pJoystick.os->fname );
+            joy->error = GL_TRUE;
+            return;
+        }
+        if ( buttons != NULL )
+            *buttons = ( joy->pJoystick.os->ajs.b1 ? 1 : 0 ) | ( joy->pJoystick.os->ajs.b2 ? 2 : 0 );
+
+        if ( axes != NULL )
+        {
+            axes[0] = (float) joy->pJoystick.os->ajs.x;
+            axes[1] = (float) joy->pJoystick.os->ajs.y;
+        }
+
+        return;
+    }
+
+#  ifdef HAVE_USB_JS
+    while ( ( len = read ( joy->pJoystick.os->fd, joy->pJoystick.os->hid_data_buf, joy->pJoystick.os->hid_dlen ) ) == joy->pJoystick.os->hid_dlen )
+    {
+        struct hid_item *h;
+
+        for  ( h = joy->pJoystick.os->hids; h; h = h->next )
+        {
+            int d = hid_get_data ( joy->pJoystick.os->hid_data_buf, h );
+
+            int page = HID_PAGE ( h->usage );
+            int usage = HID_USAGE ( h->usage );
+
+            if ( page == HUP_GENERIC_DESKTOP )
+            {
+                int i;
+                for ( i = 0; i < joy->num_axes; i++ )
+                    if (joy->pJoystick.os->axes_usage[i] == usage)
+                    {
+                        if (usage == HUG_HAT_SWITCH)
+                        {
+                            if (d < 0 || d > 8)
+                                d = 0;  /* safety */
+                            joy->pJoystick.os->cache_axes[i] = (float)hatmap_x[d];
+                            joy->pJoystick.os->cache_axes[i + 1] = (float)hatmap_y[d];
+                        }
+                        else
+                        {
+                            joy->pJoystick.os->cache_axes[i] = (float)d;
+                        }
+                        break;
+                    }
+            }
+            else if (page == HUP_BUTTON)
+            {
+               if (usage > 0 && usage < _JS_MAX_BUTTONS + 1)
+               {
+                   if (d)
+                       joy->pJoystick.os->cache_buttons |=  (1 << ( usage - 1 ));
+                   else
+                       joy->pJoystick.os->cache_buttons &= ~(1 << ( usage - 1 ));
+               }
+            }
+        }
+    }
+#    ifdef HAVE_ERRNO_H
+    if ( len < 0 && errno != EAGAIN )
+#    else
+    if ( len < 0 )
+#    endif
+    {
+        perror( joy->pJoystick.os->fname );
+        joy->error = 1;
+    }
+    if ( buttons != NULL ) *buttons = joy->pJoystick.os->cache_buttons;
+    if ( axes    != NULL )
+        memcpy ( axes, joy->pJoystick.os->cache_axes, sizeof(float) * joy->num_axes );
+#  endif
+#endif
+
+#ifdef JS_NEW
+
+    while ( 1 )
+    {
+        status = read ( joy->pJoystick.fd, &joy->pJoystick.js, sizeof(struct js_event) );
+
+        if ( status != sizeof( struct js_event ) )
+        {
+#  ifdef HAVE_ERRNO_H
+            if ( errno == EAGAIN )
+            {
+                /* Use the old values */
+                if ( buttons )
+                    *buttons = joy->pJoystick.tmp_buttons;
+                if ( axes )
+                    memcpy( axes, joy->pJoystick.tmp_axes,
+                            sizeof( float ) * joy->num_axes );
+                return;
+            }
+#  endif
+
+            fgWarning ( "%s", joy->pJoystick.fname );
+            joy->error = GL_TRUE;
+            return;
+        }
+
+        switch ( joy->pJoystick.js.type & ~JS_EVENT_INIT )
+        {
+        case JS_EVENT_BUTTON:
+            if( joy->pJoystick.js.value == 0 ) /* clear the flag */
+                joy->pJoystick.tmp_buttons &= ~( 1 << joy->pJoystick.js.number );
+            else
+                joy->pJoystick.tmp_buttons |= ( 1 << joy->pJoystick.js.number );
+            break;
+
+        case JS_EVENT_AXIS:
+            if ( joy->pJoystick.js.number < joy->num_axes )
+            {
+                joy->pJoystick.tmp_axes[ joy->pJoystick.js.number ] = ( float )joy->pJoystick.js.value;
+
+                if( axes )
+                    memcpy( axes, joy->pJoystick.tmp_axes, sizeof(float) * joy->num_axes );
+            }
+            break;
+
+        default:
+            fgWarning ( "PLIB_JS: Unrecognised /dev/js return!?!" );
+
+            /* use the old values */
+
+            if ( buttons != NULL ) *buttons = joy->pJoystick.tmp_buttons;
+            if ( axes    != NULL )
+                memcpy ( axes, joy->pJoystick.tmp_axes, sizeof(float) * joy->num_axes );
+
+            return;
+        }
+
+        if( buttons )
+            *buttons = joy->pJoystick.tmp_buttons;
+    }
+#else
+
+    status = read( joy->pJoystick.fd, &joy->pJoystick.js, JS_RETURN );
+
+    if ( status != JS_RETURN )
+    {
+        fgWarning( "%s", joy->pJoystick.fname );
+        joy->error = GL_TRUE;
+        return;
+    }
+
+    if ( buttons )
+#    if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )
+        *buttons = ( joy->pJoystick.js.b1 ? 1 : 0 ) | ( joy->pJoystick.js.b2 ? 2 : 0 );  /* XXX Should not be here -- BSD is handled earlier */
+#    else
+        *buttons = joy->pJoystick.js.buttons;
+#    endif
+
+    if ( axes )
+    {
+        axes[ 0 ] = (float) joy->pJoystick.js.x;
+        axes[ 1 ] = (float) joy->pJoystick.js.y;
+    }
+#endif
+}
+
+
+void fgPlatformJoystickOpen( SFG_Joystick* joy )
+{
+#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )
+       int i = 0;
+       char *cp;
+#endif
+#ifdef JS_NEW
+       unsigned char u;
+       int i=0;
+#else
+#  if defined( __linux__ ) || TARGET_HOST_SOLARIS
+       int i = 0;
+    int counter = 0;
+#  endif
+#endif
+
+#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )
+    for( i = 0; i < _JS_MAX_AXES; i++ )
+        joy->pJoystick.os->cache_axes[ i ] = 0.0f;
+
+    joy->pJoystick.os->cache_buttons = 0;
+
+    joy->pJoystick.os->fd = open( joy->pJoystick.os->fname, O_RDONLY | O_NONBLOCK);
+
+#ifdef HAVE_ERRNO_H
+    if( joy->pJoystick.os->fd < 0 && errno == EACCES )
+        fgWarning ( "%s exists but is not readable by you", joy->pJoystick.os->fname );
+#endif
+
+    joy->error =( joy->pJoystick.os->fd < 0 );
+
+    if( joy->error )
+        return;
+
+    joy->num_axes = 0;
+    joy->num_buttons = 0;
+    if( joy->pJoystick.os->is_analog )
+    {
+        FILE *joyfile;
+        char joyfname[ 1024 ];
+        int noargs, in_no_axes;
+
+        float axes [ _JS_MAX_AXES ];
+        int buttons[ _JS_MAX_AXES ];
+
+        joy->num_axes    =  2;
+        joy->num_buttons = 32;
+
+        fghJoystickRawRead( joy, buttons, axes );
+        joy->error = axes[ 0 ] < -1000000000.0f;
+        if( joy->error )
+            return;
+
+        snprintf( joyfname, sizeof(joyfname), "%s/.joy%drc", getenv( "HOME" ), joy->id );
+
+        joyfile = fopen( joyfname, "r" );
+        joy->error =( joyfile == NULL );
+        if( joy->error )
+            return;
+
+        noargs = fscanf( joyfile, "%d%f%f%f%f%f%f", &in_no_axes,
+                         &joy->min[ 0 ], &joy->center[ 0 ], &joy->max[ 0 ],
+                         &joy->min[ 1 ], &joy->center[ 1 ], &joy->max[ 1 ] );
+        joy->error = noargs != 7 || in_no_axes != _JS_MAX_AXES;
+        fclose( joyfile );
+        if( joy->error )
+            return;
+
+        for( i = 0; i < _JS_MAX_AXES; i++ )
+        {
+            joy->dead_band[ i ] = 0.0f;
+            joy->saturate [ i ] = 1.0f;
+        }
+
+        return;    /* End of analog code */
+    }
+
+#    ifdef HAVE_USB_JS
+    if( ! fghJoystickInitializeHID( joy->pJoystick.os, &joy->num_axes,
+                                    &joy->num_buttons ) )
+    {
+        close( joy->pJoystick.os->fd );
+        joy->error = GL_TRUE;
+        return;
+    }
+
+    cp = strrchr( joy->pJoystick.os->fname, '/' );
+    if( cp )
+    {
+        if( fghJoystickFindUSBdev( &cp[1], joy->name, sizeof( joy->name ) ) ==
+            0 )
+            strcpy( joy->name, &cp[1] );
+    }
+
+    if( joy->num_axes > _JS_MAX_AXES )
+        joy->num_axes = _JS_MAX_AXES;
+
+    for( i = 0; i < _JS_MAX_AXES; i++ )
+    {
+        /* We really should get this from the HID, but that data seems
+         * to be quite unreliable for analog-to-USB converters. Punt for
+         * now.
+         */
+        if( joy->pJoystick.os->axes_usage[ i ] == HUG_HAT_SWITCH )
+        {
+            joy->max   [ i ] = 1.0f;
+            joy->center[ i ] = 0.0f;
+            joy->min   [ i ] = -1.0f;
+        }
+        else
+        {
+            joy->max   [ i ] = 255.0f;
+            joy->center[ i ] = 127.0f;
+            joy->min   [ i ] = 0.0f;
+        }
+
+        joy->dead_band[ i ] = 0.0f;
+        joy->saturate[ i ] = 1.0f;
+    }
+#    endif
+#endif
+
+#if defined( __linux__ ) || TARGET_HOST_SOLARIS
+    /* Default for older Linux systems. */
+    joy->num_axes    =  2;
+    joy->num_buttons = 32;
+
+#    ifdef JS_NEW
+    for( i = 0; i < _JS_MAX_AXES; i++ )
+        joy->pJoystick.tmp_axes[ i ] = 0.0f;
+
+    joy->pJoystick.tmp_buttons = 0;
+#    endif
+
+    joy->pJoystick.fd = open( joy->pJoystick.fname, O_RDONLY );
+
+    joy->error =( joy->pJoystick.fd < 0 );
+
+    if( joy->error )
+        return;
+
+    /* Set the correct number of axes for the linux driver */
+#    ifdef JS_NEW
+    /* Melchior Franz's fixes for big-endian Linuxes since writing
+     *  to the upper byte of an uninitialized word doesn't work.
+     *  9 April 2003
+     */
+    ioctl( joy->pJoystick.fd, JSIOCGAXES, &u );
+    joy->num_axes = u;
+    ioctl( joy->pJoystick.fd, JSIOCGBUTTONS, &u );
+    joy->num_buttons = u;
+    ioctl( joy->pJoystick.fd, JSIOCGNAME( sizeof( joy->name ) ), joy->name );
+    fcntl( joy->pJoystick.fd, F_SETFL, O_NONBLOCK );
+#    endif
+
+    /*
+     * The Linux driver seems to return 512 for all axes
+     * when no stick is present - but there is a chance
+     * that could happen by accident - so it's gotta happen
+     * on both axes for at least 100 attempts.
+     *
+     * PWO: shouldn't be that done somehow wiser on the kernel level?
+     */
+#    ifndef JS_NEW
+    counter = 0;
+
+    do
+    {
+        fghJoystickRawRead( joy, NULL, joy->center );
+        counter++;
+    } while( !joy->error &&
+             counter < 100 &&
+             joy->center[ 0 ] == 512.0f &&
+             joy->center[ 1 ] == 512.0f );
+
+    if ( counter >= 100 )
+        joy->error = GL_TRUE;
+#    endif
+
+    for( i = 0; i < _JS_MAX_AXES; i++ )
+    {
+#    ifdef JS_NEW
+        joy->max   [ i ] =  32767.0f;
+        joy->center[ i ] =      0.0f;
+        joy->min   [ i ] = -32767.0f;
+#    else
+        joy->max[ i ] = joy->center[ i ] * 2.0f;
+        joy->min[ i ] = 0.0f;
+#    endif
+        joy->dead_band[ i ] = 0.0f;
+        joy->saturate [ i ] = 1.0f;
+    }
+#endif
+}
+
+
+void fgPlatformJoystickInit( SFG_Joystick *fgJoystick[], int ident )
+{
+#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )
+    fgJoystick[ ident ]->id = ident;
+    fgJoystick[ ident ]->error = GL_FALSE;
+
+    fgJoystick[ ident ]->pJoystick.os = calloc( 1, sizeof( struct os_specific_s ) );
+    memset( fgJoystick[ ident ]->pJoystick.os, 0, sizeof( struct os_specific_s ) );
+    if( ident < USB_IDENT_OFFSET )
+        fgJoystick[ ident ]->pJoystick.os->is_analog = 1;
+    if( fgJoystick[ ident ]->pJoystick.os->is_analog )
+        snprintf( fgJoystick[ ident ]->pJoystick.os->fname, sizeof(fgJoystick[ ident ]->pJoystick.os->fname), "%s%d", AJSDEV, ident );
+    else
+        snprintf( fgJoystick[ ident ]->pJoystick.os->fname, sizeof(fgJoystick[ ident ]->pJoystick.os->fname), "%s%d", UHIDDEV,
+                 ident - USB_IDENT_OFFSET );
+#elif defined( __linux__ )
+    fgJoystick[ ident ]->id = ident;
+    fgJoystick[ ident ]->error = GL_FALSE;
+
+    snprintf( fgJoystick[ident]->pJoystick.fname, sizeof(fgJoystick[ident]->pJoystick.fname), "/dev/input/js%d", ident );
+
+    if( access( fgJoystick[ ident ]->pJoystick.fname, F_OK ) != 0 )
+        snprintf( fgJoystick[ ident ]->pJoystick.fname, sizeof(fgJoystick[ ident ]->pJoystick.fname), "/dev/js%d", ident );
+#endif
+}
+
+
+void fgPlatformJoystickClose ( int ident )
+{
+#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )
+    if( fgJoystick[ident]->pJoystick.os )
+    {
+        if( ! fgJoystick[ ident ]->error )
+            close( fgJoystick[ ident ]->pJoystick.os->fd );
+#ifdef HAVE_USB_JS
+        if( fgJoystick[ ident ]->pJoystick.os->hids )
+            free (fgJoystick[ ident ]->pJoystick.os->hids);
+        if( fgJoystick[ ident ]->pJoystick.os->hid_data_buf )
+            free( fgJoystick[ ident ]->pJoystick.os->hid_data_buf );
+#endif
+        free( fgJoystick[ident]->pJoystick.os );
+       }
+#endif
+
+    if( ! fgJoystick[ident]->error )
+         close( fgJoystick[ ident ]->pJoystick.fd );
+}
+
diff --git a/src/x11/fg_main_x11.c b/src/x11/fg_main_x11.c
new file mode 100644 (file)
index 0000000..e72db37
--- /dev/null
@@ -0,0 +1,1083 @@
+/*
+ * freeglut_main_x11.c
+ *
+ * The X11-specific windows message processing methods.
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ * Copied for Platform code by Evan Felix <karcaw at gmail.com>
+ * Creation date: Thur Feb 2 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+#ifdef HAVE_ERRNO_H
+#    include <errno.h>
+#endif
+#include <stdarg.h>
+#ifdef  HAVE_VFPRINTF
+#    define VFPRINTF(s,f,a) vfprintf((s),(f),(a))
+#elif defined(HAVE__DOPRNT)
+#    define VFPRINTF(s,f,a) _doprnt((f),(a),(s))
+#else
+#    define VFPRINTF(s,f,a)
+#endif
+
+/*
+ * Try to get the maximum value allowed for ints, falling back to the minimum
+ * guaranteed by ISO C99 if there is no suitable header.
+ */
+#ifdef HAVE_LIMITS_H
+#    include <limits.h>
+#endif
+#ifndef INT_MAX
+#    define INT_MAX 32767
+#endif
+
+#ifndef MIN
+#    define MIN(a,b) (((a)<(b)) ? (a) : (b))
+#endif
+
+/*
+ * TODO BEFORE THE STABLE RELEASE:
+ *
+ * There are some issues concerning window redrawing under X11, and maybe
+ * some events are not handled. The Win32 version lacks some more features,
+ * but seems acceptable for not demanding purposes.
+ *
+ * Need to investigate why the X11 version breaks out with an error when
+ * closing a window (using the window manager, not glutDestroyWindow)...
+ */
+/*
+ * Handle a window configuration change. When no reshape
+ * callback is hooked, the viewport size is updated to
+ * match the new window size.
+ */
+void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height )
+{
+    XResizeWindow( fgDisplay.pDisplay.Display, window->Window.Handle,
+                   width, height );
+    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
+}
+
+
+/*
+ * A static helper function to execute display callback for a window
+ */
+void fgPlatformDisplayWindow ( SFG_Window *window )
+{
+        fghRedrawWindow ( window ) ;
+}
+
+
+fg_time_t fgPlatformSystemTime ( void )
+{
+#ifdef CLOCK_MONOTONIC
+    struct timespec now;
+    clock_gettime(CLOCK_MONOTONIC, &now);
+    return now.tv_nsec/1000000 + now.tv_sec*1000;
+#elif defined(HAVE_GETTIMEOFDAY)
+    struct timeval now;
+    gettimeofday( &now, NULL );
+    return now.tv_usec/1000 + now.tv_sec*1000;
+#endif
+}
+
+/*
+ * Does the magic required to relinquish the CPU until something interesting
+ * happens.
+ */
+
+void fgPlatformSleepForEvents( fg_time_t msec )
+{
+    /*
+     * Possibly due to aggressive use of XFlush() and friends,
+     * it is possible to have our socket drained but still have
+     * unprocessed events.  (Or, this may just be normal with
+     * X, anyway?)  We do non-trivial processing of X events
+     * after the event-reading loop, in any case, so we
+     * need to allow that we may have an empty socket but non-
+     * empty event queue.
+     */
+    if( ! XPending( fgDisplay.pDisplay.Display ) )
+    {
+        fd_set fdset;
+        int err;
+        int socket;
+        struct timeval wait;
+
+        socket = ConnectionNumber( fgDisplay.pDisplay.Display );
+        FD_ZERO( &fdset );
+        FD_SET( socket, &fdset );
+        wait.tv_sec = msec / 1000;
+        wait.tv_usec = (msec % 1000) * 1000;
+        err = select( socket+1, &fdset, NULL, NULL, &wait );
+
+#ifdef HAVE_ERRNO_H
+        if( ( -1 == err ) && ( errno != EINTR ) )
+            fgWarning ( "freeglut select() error: %d", errno );
+#endif
+    }
+}
+
+
+/*
+ * Returns GLUT modifier mask for the state field of an X11 event.
+ */
+int fgPlatformGetModifiers( int state )
+{
+    int ret = 0;
+
+    if( state & ( ShiftMask | LockMask ) )
+        ret |= GLUT_ACTIVE_SHIFT;
+    if( state & ControlMask )
+        ret |= GLUT_ACTIVE_CTRL;
+    if( state & Mod1Mask )
+        ret |= GLUT_ACTIVE_ALT;
+
+    return ret;
+}
+
+static const char* fghTypeToString( int type )
+{
+    switch( type ) {
+    case KeyPress: return "KeyPress";
+    case KeyRelease: return "KeyRelease";
+    case ButtonPress: return "ButtonPress";
+    case ButtonRelease: return "ButtonRelease";
+    case MotionNotify: return "MotionNotify";
+    case EnterNotify: return "EnterNotify";
+    case LeaveNotify: return "LeaveNotify";
+    case FocusIn: return "FocusIn";
+    case FocusOut: return "FocusOut";
+    case KeymapNotify: return "KeymapNotify";
+    case Expose: return "Expose";
+    case GraphicsExpose: return "GraphicsExpose";
+    case NoExpose: return "NoExpose";
+    case VisibilityNotify: return "VisibilityNotify";
+    case CreateNotify: return "CreateNotify";
+    case DestroyNotify: return "DestroyNotify";
+    case UnmapNotify: return "UnmapNotify";
+    case MapNotify: return "MapNotify";
+    case MapRequest: return "MapRequest";
+    case ReparentNotify: return "ReparentNotify";
+    case ConfigureNotify: return "ConfigureNotify";
+    case ConfigureRequest: return "ConfigureRequest";
+    case GravityNotify: return "GravityNotify";
+    case ResizeRequest: return "ResizeRequest";
+    case CirculateNotify: return "CirculateNotify";
+    case CirculateRequest: return "CirculateRequest";
+    case PropertyNotify: return "PropertyNotify";
+    case SelectionClear: return "SelectionClear";
+    case SelectionRequest: return "SelectionRequest";
+    case SelectionNotify: return "SelectionNotify";
+    case ColormapNotify: return "ColormapNotify";
+    case ClientMessage: return "ClientMessage";
+    case MappingNotify: return "MappingNotify";
+    default: return "UNKNOWN";
+    }
+}
+
+static const char* fghBoolToString( Bool b )
+{
+    return b == False ? "False" : "True";
+}
+
+static const char* fghNotifyHintToString( char is_hint )
+{
+    switch( is_hint ) {
+    case NotifyNormal: return "NotifyNormal";
+    case NotifyHint: return "NotifyHint";
+    default: return "UNKNOWN";
+    }
+}
+
+static const char* fghNotifyModeToString( int mode )
+{
+    switch( mode ) {
+    case NotifyNormal: return "NotifyNormal";
+    case NotifyGrab: return "NotifyGrab";
+    case NotifyUngrab: return "NotifyUngrab";
+    case NotifyWhileGrabbed: return "NotifyWhileGrabbed";
+    default: return "UNKNOWN";
+    }
+}
+
+static const char* fghNotifyDetailToString( int detail )
+{
+    switch( detail ) {
+    case NotifyAncestor: return "NotifyAncestor";
+    case NotifyVirtual: return "NotifyVirtual";
+    case NotifyInferior: return "NotifyInferior";
+    case NotifyNonlinear: return "NotifyNonlinear";
+    case NotifyNonlinearVirtual: return "NotifyNonlinearVirtual";
+    case NotifyPointer: return "NotifyPointer";
+    case NotifyPointerRoot: return "NotifyPointerRoot";
+    case NotifyDetailNone: return "NotifyDetailNone";
+    default: return "UNKNOWN";
+    }
+}
+
+static const char* fghVisibilityToString( int state ) {
+    switch( state ) {
+    case VisibilityUnobscured: return "VisibilityUnobscured";
+    case VisibilityPartiallyObscured: return "VisibilityPartiallyObscured";
+    case VisibilityFullyObscured: return "VisibilityFullyObscured";
+    default: return "UNKNOWN";
+    }
+}
+
+static const char* fghConfigureDetailToString( int detail )
+{
+    switch( detail ) {
+    case Above: return "Above";
+    case Below: return "Below";
+    case TopIf: return "TopIf";
+    case BottomIf: return "BottomIf";
+    case Opposite: return "Opposite";
+    default: return "UNKNOWN";
+    }
+}
+
+static const char* fghPlaceToString( int place )
+{
+    switch( place ) {
+    case PlaceOnTop: return "PlaceOnTop";
+    case PlaceOnBottom: return "PlaceOnBottom";
+    default: return "UNKNOWN";
+    }
+}
+
+static const char* fghMappingRequestToString( int request )
+{
+    switch( request ) {
+    case MappingModifier: return "MappingModifier";
+    case MappingKeyboard: return "MappingKeyboard";
+    case MappingPointer: return "MappingPointer";
+    default: return "UNKNOWN";
+    }
+}
+
+static const char* fghPropertyStateToString( int state )
+{
+    switch( state ) {
+    case PropertyNewValue: return "PropertyNewValue";
+    case PropertyDelete: return "PropertyDelete";
+    default: return "UNKNOWN";
+    }
+}
+
+static const char* fghColormapStateToString( int state )
+{
+    switch( state ) {
+    case ColormapUninstalled: return "ColormapUninstalled";
+    case ColormapInstalled: return "ColormapInstalled";
+    default: return "UNKNOWN";
+    }
+}
+
+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;
+    }
+    }
+}
+
+
+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(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;
+                if( event.type == CreateNotify ) {
+                    GETWINDOW( xcreatewindow );
+                    width = event.xcreatewindow.width;
+                    height = event.xcreatewindow.height;
+                } else {
+                    GETWINDOW( xconfigure );
+                    width = event.xconfigure.width;
+                    height = event.xconfigure.height;
+                }
+
+                if( ( width != window->State.pWState.OldWidth ) ||
+                    ( height != window->State.pWState.OldHeight ) )
+                {
+                    SFG_Window *current_window = fgStructure.CurrentWindow;
+
+                    window->State.pWState.OldWidth = width;
+                    window->State.pWState.OldHeight = height;
+                    if( FETCH_WCB( *window, Reshape ) )
+                        INVOKE_WCB( *window, Reshape, ( width, height ) );
+                    else
+                    {
+                        fgSetWindow( window );
+                        glViewport( 0, 0, width, height );
+                    }
+                    glutPostRedisplay( );
+                    if( window->IsMenu )
+                        fgSetWindow( current_window );
+                }
+            }
+            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.Redisplay = GL_TRUE;
+            }
+            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:
+        {
+            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_root, event.xbutton.y_root ) )
+                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.KeyRepeating = GL_TRUE;
+                        else
+                            window->State.KeyRepeating = GL_FALSE;
+                    }
+                }
+            }
+            else
+                window->State.KeyRepeating = GL_FALSE;
+
+            /* Cease processing this event if it is auto repeated */
+
+            if (window->State.KeyRepeating)
+            {
+                if (event.type == KeyPress) window->State.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;
+                    }
+                }
+            }
+        }
+        break;
+
+        case ReparentNotify:
+            break; /* XXX Should disable this event */
+
+        /* Not handled */
+        case GravityNotify:
+            break;
+
+        default:
+            /* enter handling of Extension Events here */
+            #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
+                fgHandleExtensionEvents( &event );
+            #endif
+            break;
+        }
+    }
+}
+
+
+void fgPlatformMainLoopPreliminaryWork ( void )
+{
+}
+
diff --git a/src/x11/fg_menu_x11.c b/src/x11/fg_menu_x11.c
new file mode 100644 (file)
index 0000000..0443dcd
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * freeglut_menu_x11.c
+ *
+ * Pull-down menu creation and handling.
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ * Copied for Platform code by Evan Felix <karcaw at gmail.com>
+ * Creation date: Wed Feb 1, 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+/*
+ *  * Private function to get the virtual maximum screen extent
+ *   */
+GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y )
+{
+    int wx, wy;
+    Window w;
+
+    XTranslateCoordinates(
+        fgDisplay.pDisplay.Display,
+        window->Window.Handle,
+        fgDisplay.pDisplay.RootWindow,
+        0, 0, &wx, &wy, &w);
+
+    *x = fgState.GameModeSize.X + wx;
+    *y = fgState.GameModeSize.Y + wy;
+}
+
diff --git a/src/x11/fg_spaceball_x11.c b/src/x11/fg_spaceball_x11.c
new file mode 100644 (file)
index 0000000..582a926
--- /dev/null
@@ -0,0 +1,415 @@
+/* Spaceball support for Linux.
+ * Written by John Tsiombikas <nuclear@member.fsf.org>
+ * Copied for Platform code by Evan Felix <karcaw at gmail.com>
+ * Creation date: Thur Feb 2 2012
+ *
+ * This code supports 3Dconnexion's 6-dof space-whatever devices.
+ * It can communicate with either the proprietary 3Dconnexion daemon (3dxsrv)
+ * free spacenavd (http://spacenav.sourceforge.net), through the "standard"
+ * magellan X-based protocol.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+#include <X11/Xlib.h>
+
+extern int sball_initialized;
+
+enum {
+    SPNAV_EVENT_ANY,  /* used by spnav_remove_events() */
+    SPNAV_EVENT_MOTION,
+    SPNAV_EVENT_BUTTON  /* includes both press and release */
+};
+
+struct spnav_event_motion {
+    int type;
+    int x, y, z;
+    int rx, ry, rz;
+    unsigned int period;
+    int *data;
+};
+
+struct spnav_event_button {
+    int type;
+    int press;
+    int bnum;
+};
+
+typedef union spnav_event {
+    int type;
+    struct spnav_event_motion motion;
+    struct spnav_event_button button;
+} spnav_event;
+
+
+static int spnav_x11_open(Display *dpy, Window win);
+static int spnav_x11_window(Window win);
+static int spnav_x11_event(const XEvent *xev, spnav_event *event);
+static int spnav_close(void);
+static int spnav_fd(void);
+static int spnav_remove_events(int type);
+
+static SFG_Window *spnav_win;
+
+void fgPlatformInitializeSpaceball(void)
+{
+    Window w;
+
+    sball_initialized = 1;
+    if(!fgStructure.CurrentWindow)
+    {
+        sball_initialized = -1;
+        return;
+    }
+
+    w = fgStructure.CurrentWindow->Window.Handle;
+    if(spnav_x11_open(fgDisplay.pDisplay.Display, w) == -1)
+    {
+        sball_initialized = -1;
+        return;
+    }
+}
+
+void fgPlatformSpaceballClose(void) 
+{
+    spnav_close();
+}
+
+int fgPlatformHasSpaceball(void) 
+{
+    /* 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;
+}
+
+int fgPlatformSpaceballNumButtons(void) {
+    return 2;
+}
+
+void fgPlatformSpaceballSetWindow(SFG_Window *window) 
+{
+       if(spnav_win != window) {
+        spnav_x11_window(window->Window.Handle);
+        spnav_win = window;
+    }
+}
+
+int fgIsSpaceballXEvent(const XEvent *xev)
+{
+    spnav_event sev;
+
+    if(spnav_win != fgStructure.CurrentWindow) {
+        /* this will also initialize spaceball if needed (first call) */
+        fgSpaceballSetWindow(fgStructure.CurrentWindow);
+    }
+
+    if(sball_initialized != 1) {
+        return 0;
+    }
+
+    return spnav_x11_event(xev, &sev);
+}
+
+void fgSpaceballHandleXEvent(const XEvent *xev)
+{
+    spnav_event sev;
+
+    if(sball_initialized == 0) {
+        fgInitialiseSpaceball();
+        if(sball_initialized != 1) {
+            return;
+        }
+    }
+
+    if(spnav_x11_event(xev, &sev)) {
+        switch(sev.type) {
+        case SPNAV_EVENT_MOTION:
+            if(sev.motion.x | sev.motion.y | sev.motion.z) {
+                INVOKE_WCB(*spnav_win, SpaceMotion, (sev.motion.x, sev.motion.y, sev.motion.z));
+            }
+            if(sev.motion.rx | sev.motion.ry | sev.motion.rz) {
+                INVOKE_WCB(*spnav_win, SpaceRotation, (sev.motion.rx, sev.motion.ry, sev.motion.rz));
+            }
+            spnav_remove_events(SPNAV_EVENT_MOTION);
+            break;
+
+        case SPNAV_EVENT_BUTTON:
+            INVOKE_WCB(*spnav_win, SpaceButton, (sev.button.bnum, sev.button.press ? GLUT_DOWN : GLUT_UP));
+            break;
+
+        default:
+            break;
+        }
+    }
+}
+
+/*
+The following code is part of libspnav, part of the spacenav project (spacenav.sf.net)
+Copyright (C) 2007-2009 John Tsiombikas <nuclear@member.fsf.org>
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGE.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+static Window get_daemon_window(Display *dpy);
+static int catch_badwin(Display *dpy, XErrorEvent *err);
+
+static Display *dpy;
+static Window app_win;
+static Atom motion_event, button_press_event, button_release_event, command_event;
+
+enum {
+  CMD_APP_WINDOW = 27695,
+  CMD_APP_SENS
+};
+
+#define IS_OPEN    dpy
+
+struct event_node {
+  spnav_event event;
+  struct event_node *next;
+};
+
+static int spnav_x11_open(Display *display, Window win)
+{
+  if(IS_OPEN) {
+    return -1;
+  }
+
+  dpy = display;
+
+  motion_event = XInternAtom(dpy, "MotionEvent", True);
+  button_press_event = XInternAtom(dpy, "ButtonPressEvent", True);
+  button_release_event = XInternAtom(dpy, "ButtonReleaseEvent", True);
+  command_event = XInternAtom(dpy, "CommandEvent", True);
+
+  if(!motion_event || !button_press_event || !button_release_event || !command_event) {
+    dpy = 0;
+    return -1;  /* daemon not started */
+  }
+
+  if(spnav_x11_window(win) == -1) {
+    dpy = 0;
+    return -1;  /* daemon not started */
+  }
+
+  app_win = win;
+  return 0;
+}
+
+static int spnav_close(void)
+{
+  if(dpy) {
+    spnav_x11_window(DefaultRootWindow(dpy));
+    app_win = 0;
+    dpy = 0;
+    return 0;
+  }
+  return -1;
+}
+
+static int spnav_x11_window(Window win)
+{
+  int (*prev_xerr_handler)(Display*, XErrorEvent*);
+  XEvent xev;
+  Window daemon_win;
+
+  if(!IS_OPEN) {
+    return -1;
+  }
+
+  if(!(daemon_win = get_daemon_window(dpy))) {
+    return -1;
+  }
+
+  prev_xerr_handler = XSetErrorHandler(catch_badwin);
+
+  xev.type = ClientMessage;
+  xev.xclient.send_event = False;
+  xev.xclient.display = dpy;
+  xev.xclient.window = win;
+  xev.xclient.message_type = command_event;
+  xev.xclient.format = 16;
+  xev.xclient.data.s[0] = ((unsigned int)win & 0xffff0000) >> 16;
+  xev.xclient.data.s[1] = (unsigned int)win & 0xffff;
+  xev.xclient.data.s[2] = CMD_APP_WINDOW;
+
+  XSendEvent(dpy, daemon_win, False, 0, &xev);
+  XSync(dpy, False);
+
+  XSetErrorHandler(prev_xerr_handler);
+  return 0;
+}
+
+static int spnav_fd(void)
+{
+  if(dpy) {
+    return ConnectionNumber(dpy);
+  }
+  return -1;
+}
+
+/*static int spnav_wait_event(spnav_event *event)
+{
+  if(dpy) {
+    for(;;) {
+      XEvent xev;
+      XNextEvent(dpy, &xev);
+
+      if(spnav_x11_event(&xev, event) > 0) {
+        return event->type;
+      }
+    }
+  }
+  return 0;
+}
+
+static int spnav_poll_event(spnav_event *event)
+{
+  if(dpy) {
+    if(XPending(dpy)) {
+      XEvent xev;
+      XNextEvent(dpy, &xev);
+
+      return spnav_x11_event(&xev, event);
+    }
+  }
+  return 0;
+}*/
+
+static Bool match_events(Display *dpy, XEvent *xev, char *arg)
+{
+  int evtype = *(int*)arg;
+
+  if(xev->type != ClientMessage) {
+    return False;
+  }
+
+  if(xev->xclient.message_type == motion_event) {
+    return !evtype || evtype == SPNAV_EVENT_MOTION ? True : False;
+  }
+  if(xev->xclient.message_type == button_press_event ||
+      xev->xclient.message_type == button_release_event) {
+    return !evtype || evtype == SPNAV_EVENT_BUTTON ? True : False;
+  }
+  return False;
+}
+
+static int spnav_remove_events(int type)
+{
+  int rm_count = 0;
+
+  if(dpy) {
+    XEvent xev;
+
+    while(XCheckIfEvent(dpy, &xev, match_events, (char*)&type)) {
+      rm_count++;
+    }
+    return rm_count;
+  }
+  return 0;
+}
+
+static int spnav_x11_event(const XEvent *xev, spnav_event *event)
+{
+  int i;
+  int xmsg_type;
+
+  if(xev->type != ClientMessage) {
+    return 0;
+  }
+
+  xmsg_type = xev->xclient.message_type;
+
+  if(xmsg_type != motion_event && xmsg_type != button_press_event &&
+      xmsg_type != button_release_event) {
+    return 0;
+  }
+
+  if(xmsg_type == motion_event) {
+    event->type = SPNAV_EVENT_MOTION;
+    event->motion.data = &event->motion.x;
+
+    for(i=0; i<6; i++) {
+      event->motion.data[i] = xev->xclient.data.s[i + 2];
+    }
+    event->motion.period = xev->xclient.data.s[8];
+  } else {
+    event->type = SPNAV_EVENT_BUTTON;
+    event->button.press = xmsg_type == button_press_event ? 1 : 0;
+    event->button.bnum = xev->xclient.data.s[2];
+  }
+  return event->type;
+}
+
+
+static Window get_daemon_window(Display *dpy)
+{
+  Window win, root_win;
+  XTextProperty wname;
+  Atom type;
+  int fmt;
+  unsigned long nitems, bytes_after;
+  unsigned char *prop;
+
+  root_win = DefaultRootWindow(dpy);
+
+  XGetWindowProperty(dpy, root_win, command_event, 0, 1, False, AnyPropertyType, &type, &fmt, &nitems, &bytes_after, &prop);
+  if(!prop) {
+    return 0;
+  }
+
+  win = *(Window*)prop;
+  XFree(prop);
+
+  if(!XGetWMName(dpy, win, &wname) || strcmp("Magellan Window", (char*)wname.value) != 0) {
+    return 0;
+  }
+
+  return win;
+}
+
+static int catch_badwin(Display *dpy, XErrorEvent *err)
+{
+  char buf[256];
+
+  if(err->error_code == BadWindow) {
+    /* do nothing? */
+  } else {
+    XGetErrorText(dpy, err->error_code, buf, sizeof buf);
+    fprintf(stderr, "Caught unexpected X error: %s\n", buf);
+  }
+  return 0;
+}
+
diff --git a/src/x11/fg_state_x11.c b/src/x11/fg_state_x11.c
new file mode 100644 (file)
index 0000000..3523477
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ * freeglut_state_x11.c
+ *
+ * X11-specific freeglut state query methods.
+ *
+ * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
+ * Written by John F. Fay, <fayjf@sourceforge.net>
+ * Creation date: Sat Feb 4 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+/*
+ * TODO BEFORE THE STABLE RELEASE:
+ *
+ *  fgPlatformChooseFBConfig()      -- OK, but what about glutInitDisplayString()?
+ */
+
+/* A helper function to check if a display mode is possible to use */
+GLXFBConfig* fgPlatformChooseFBConfig( int* numcfgs );
+
+/*
+ * Queries the GL context about some attributes
+ */
+int fgPlatformGetConfig( int attribute )
+{
+  int returnValue = 0;
+  int result;  /*  Not checked  */
+
+  if( fgStructure.CurrentWindow )
+      result = glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
+                                     *(fgStructure.CurrentWindow->Window.pContext.FBConfig),
+                                     attribute,
+                                     &returnValue );
+
+  return returnValue;
+}
+
+int fgPlatformGlutGet ( GLenum eWhat )
+{
+    int nsamples = 0;
+
+    switch( eWhat )
+    {
+    /*
+     * The window/context specific queries are handled mostly by
+     * fgPlatformGetConfig().
+     */
+    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 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
+
+    /* Colormap size is handled in a bit different way than all the rest */
+    case GLUT_WINDOW_COLORMAP_SIZE:
+        if( (fgPlatformGetConfig( 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.pContext.FBConfig;
+
+          XVisualInfo * visualInfo =
+                glXGetVisualFromFBConfig( fgDisplay.pDisplay.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.pDisplay.Display,
+            fgStructure.CurrentWindow->Window.Handle,
+            fgDisplay.pDisplay.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.pDisplay.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.pDisplay.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 fgPlatformChooseFBConfig again here.  */
+        GLXFBConfig * fbconfig;
+        int isPossible;
+
+        fbconfig = fgPlatformChooseFBConfig(NULL);
+
+        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 fgPlatformGetConfig( GLX_VISUAL_ID );
+
+    default:
+        fgWarning( "glutGet(): missing enum handle %d", eWhat );
+        break;
+    }
+
+       return -1;
+}
+
+
+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;
+}
+
+
+int *fgPlatformGlutGetModeValues(GLenum eWhat, int *size)
+{
+  int *array;
+
+  int attributes[9];
+  GLXFBConfig * fbconfigArray;  /*  Array of FBConfigs  */
+  int fbconfigArraySize;        /*  Number of FBConfigs in the array  */
+  int attribute_name = 0;
+
+  array = NULL;
+  *size = 0;
+
+  switch (eWhat)
+    {
+    case GLUT_AUX:
+    case GLUT_MULTISAMPLE:
+
+      attributes[0] = GLX_BUFFER_SIZE;
+      attributes[1] = GLX_DONT_CARE;
+
+      switch (eWhat)
+        {
+        case GLUT_AUX:
+          /*
+            FBConfigs are now sorted by increasing number of auxiliary
+            buffers.  We want at least one buffer.
+          */
+          attributes[2] = GLX_AUX_BUFFERS;
+          attributes[3] = 1;
+          attributes[4] = None;
+
+          attribute_name = GLX_AUX_BUFFERS;
+
+          break;
+
+
+        case GLUT_MULTISAMPLE:
+          attributes[2] = GLX_AUX_BUFFERS;
+          attributes[3] = GLX_DONT_CARE;
+          attributes[4] = GLX_SAMPLE_BUFFERS;
+          attributes[5] = 1;
+          /*
+            FBConfigs are now sorted by increasing number of samples per
+            pixel.  We want at least one sample.
+          */
+          attributes[6] = GLX_SAMPLES;
+          attributes[7] = 1;
+          attributes[8] = None;
+
+          attribute_name = GLX_SAMPLES;
+
+          break;
+        }
+
+      fbconfigArray = glXChooseFBConfig(fgDisplay.pDisplay.Display,
+                                        fgDisplay.pDisplay.Screen,
+                                        attributes,
+                                        &fbconfigArraySize);
+
+      if (fbconfigArray != NULL)
+        {
+          int * temp_array;
+          int result;   /*  Returned by glXGetFBConfigAttrib. Not checked.  */
+          int previous_value;
+          int i;
+
+          temp_array = malloc(sizeof(int) * fbconfigArraySize);
+          previous_value = 0;
+
+          for (i = 0; i < fbconfigArraySize; i++)
+            {
+              int value;
+
+              result = glXGetFBConfigAttrib(fgDisplay.pDisplay.Display,
+                                            fbconfigArray[i],
+                                            attribute_name,
+                                            &value);
+              if (value > previous_value)
+                {
+                  temp_array[*size] = value;
+                  previous_value = value;
+                  (*size)++;
+                }
+            }
+
+          array = malloc(sizeof(int) * (*size));
+          for (i = 0; i < *size; i++)
+            {
+              array[i] = temp_array[i];
+            }
+
+          free(temp_array);
+          XFree(fbconfigArray);
+        }
+
+      break;
+
+    default:
+      break;
+    }
+
+  return array;
+}
+
+
diff --git a/src/x11/fg_structure_x11.c b/src/x11/fg_structure_x11.c
new file mode 100644 (file)
index 0000000..cbc9129
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * freeglut_structure.c
+ *
+ * Windows and menus need tree structure
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ * Copied for Platform code by Evan Felix <karcaw at gmail.com>
+ * Creation date: Thur Feb 2 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <GL/freeglut.h>
+#include "../fg_internal.h"
+
+extern SFG_Structure fgStructure;
+
+void fgPlatformCreateWindow ( SFG_Window *window )
+{
+    window->Window.pContext.FBConfig = NULL;
+
+    window->State.pWState.OldHeight = window->State.pWState.OldWidth = -1;
+}
+
diff --git a/src/x11/fg_window_x11.c b/src/x11/fg_window_x11.c
new file mode 100644 (file)
index 0000000..44c9952
--- /dev/null
@@ -0,0 +1,800 @@
+/*
+ * freeglut_window_x11.c
+ *
+ * Window management methods for X11
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ * Copied for Platform code by Evan Felix <karcaw at gmail.com>
+ * Creation date: Thur Feb 2 2012
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define FREEGLUT_BUILDING_LIB
+#include <GL/freeglut.h>
+#include <limits.h>  /* LONG_MAX */
+#include <unistd.h>  /* usleep */
+#include "../fg_internal.h"
+
+/* pushing attribute/value pairs into an array */
+#define ATTRIB(a) attributes[where++]=(a)
+#define ATTRIB_VAL(a,v) {ATTRIB(a); ATTRIB(v);}
+
+
+#ifndef GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB
+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
+#endif
+
+#ifndef GLX_CONTEXT_MAJOR_VERSION_ARB
+#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#endif
+
+#ifndef GLX_CONTEXT_MINOR_VERSION_ARB
+#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
+#endif
+
+#ifndef GLX_CONTEXT_FLAGS_ARB
+#define GLX_CONTEXT_FLAGS_ARB 0x2094
+#endif
+
+#ifndef GLX_CONTEXT_PROFILE_MASK_ARB
+#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
+#endif
+
+#ifndef GLX_CONTEXT_DEBUG_BIT_ARB
+#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001
+#endif
+
+#ifndef GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
+#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+#endif
+
+#ifndef GLX_CONTEXT_CORE_PROFILE_BIT_ARB
+#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#endif
+
+#ifndef GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
+#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#endif
+
+#ifndef GLX_RGBA_FLOAT_TYPE
+#define GLX_RGBA_FLOAT_TYPE 0x20B9
+#endif
+
+#ifndef GLX_RGBA_FLOAT_BIT
+#define GLX_RGBA_FLOAT_BIT 0x00000004
+#endif
+
+
+/*
+ * Chooses a visual basing on the current display mode settings
+ */
+
+GLXFBConfig* fgPlatformChooseFBConfig( int *numcfgs )
+{
+  GLboolean wantIndexedMode = GL_FALSE;
+  int attributes[ 100 ];
+  int where = 0, numAuxBuffers;
+
+  /* First we have to process the display mode settings... */
+  if( fgState.DisplayMode & GLUT_INDEX ) {
+    ATTRIB_VAL( GLX_BUFFER_SIZE, 8 );
+    /*  Buffer size is selected later.  */
+
+    ATTRIB_VAL( GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT );
+    wantIndexedMode = GL_TRUE;
+  } else {
+    ATTRIB_VAL( GLX_RED_SIZE,   1 );
+    ATTRIB_VAL( GLX_GREEN_SIZE, 1 );
+    ATTRIB_VAL( GLX_BLUE_SIZE,  1 );
+    if( fgState.DisplayMode & GLUT_ALPHA ) {
+      ATTRIB_VAL( GLX_ALPHA_SIZE, 1 );
+    }
+  }
+
+  if( fgState.DisplayMode & GLUT_DOUBLE ) {
+    ATTRIB_VAL( GLX_DOUBLEBUFFER, True );
+  }
+
+  if( fgState.DisplayMode & GLUT_STEREO ) {
+    ATTRIB_VAL( GLX_STEREO, True );
+  }
+
+  if( fgState.DisplayMode & GLUT_DEPTH ) {
+    ATTRIB_VAL( GLX_DEPTH_SIZE, 1 );
+  }
+
+  if( fgState.DisplayMode & GLUT_STENCIL ) {
+    ATTRIB_VAL( GLX_STENCIL_SIZE, 1 );
+  }
+
+  if( fgState.DisplayMode & GLUT_ACCUM ) {
+    ATTRIB_VAL( GLX_ACCUM_RED_SIZE, 1 );
+    ATTRIB_VAL( GLX_ACCUM_GREEN_SIZE, 1 );
+    ATTRIB_VAL( GLX_ACCUM_BLUE_SIZE, 1 );
+    if( fgState.DisplayMode & GLUT_ALPHA ) {
+      ATTRIB_VAL( GLX_ACCUM_ALPHA_SIZE, 1 );
+    }
+  }
+
+  numAuxBuffers = fghNumberOfAuxBuffersRequested();
+  if ( numAuxBuffers > 0 ) {
+    ATTRIB_VAL( GLX_AUX_BUFFERS, numAuxBuffers );
+  }
+
+  if( fgState.DisplayMode & GLUT_SRGB ) {
+    ATTRIB_VAL( GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, True );
+  }
+
+  if (fgState.DisplayMode & GLUT_MULTISAMPLE) {
+    ATTRIB_VAL(GLX_SAMPLE_BUFFERS, 1);
+    ATTRIB_VAL(GLX_SAMPLES, fgState.SampleNumber);
+  }
+
+  /* Push a terminator at the end of the list */
+  ATTRIB( None );
+
+    {
+        GLXFBConfig * fbconfigArray;  /*  Array of FBConfigs  */
+        GLXFBConfig * fbconfig;       /*  The FBConfig we want  */
+        int fbconfigArraySize;        /*  Number of FBConfigs in the array  */
+
+
+        /*  Get all FBConfigs that match "attributes".  */
+        fbconfigArray = glXChooseFBConfig( fgDisplay.pDisplay.Display,
+                                           fgDisplay.pDisplay.Screen,
+                                           attributes,
+                                           &fbconfigArraySize );
+
+        if (fbconfigArray != NULL)
+        {
+            int result;  /* Returned by glXGetFBConfigAttrib, not checked. */
+
+
+            if( wantIndexedMode )
+            {
+                /*
+                 * In index mode, we want the largest buffer size, i.e. visual
+                 * depth.  Here, FBConfigs are sorted by increasing buffer size
+                 * first, so FBConfigs with the largest size come last.
+                 */
+
+                int bufferSizeMin, bufferSizeMax;
+
+                /*  Get bufferSizeMin.  */
+                result =
+                  glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
+                                        fbconfigArray[0],
+                                        GLX_BUFFER_SIZE,
+                                        &bufferSizeMin );
+                /*  Get bufferSizeMax.  */
+                result =
+                  glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
+                                        fbconfigArray[fbconfigArraySize - 1],
+                                        GLX_BUFFER_SIZE,
+                                        &bufferSizeMax );
+
+                if (bufferSizeMax > bufferSizeMin)
+                {
+                    /* 
+                     * Free and reallocate fbconfigArray, keeping only FBConfigs
+                     * with the largest buffer size.
+                     */
+                    XFree(fbconfigArray);
+
+                    /*  Add buffer size token at the end of the list.  */
+                    where--;
+                    ATTRIB_VAL( GLX_BUFFER_SIZE, bufferSizeMax );
+                    ATTRIB( None );
+
+                    fbconfigArray = glXChooseFBConfig( fgDisplay.pDisplay.Display,
+                                                       fgDisplay.pDisplay.Screen,
+                                                       attributes,
+                                                       &fbconfigArraySize );
+                }
+            }
+
+            /*
+             * We now have an array of FBConfigs, the first one being the "best"
+             * one.  So we should return only this FBConfig:
+             *
+             * int fbconfigXID;
+             *
+             *  - pick the XID of the FBConfig we want
+             * result = glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
+             *                                fbconfigArray[0],
+             *                                GLX_FBCONFIG_ID,
+             *                                &fbconfigXID );
+             *
+             * - free the array
+             * XFree(fbconfigArray);
+             *
+             * - reset "attributes" with the XID
+             * where = 0;
+             * ATTRIB_VAL( GLX_FBCONFIG_ID, fbconfigXID );
+             * ATTRIB( None );
+             *
+             * - get our FBConfig only
+             * fbconfig = glXChooseFBConfig( fgDisplay.pDisplay.Display,
+             *                               fgDisplay.pDisplay.Screen,
+             *                               attributes,
+             *                               &fbconfigArraySize );
+             *
+             * However, for some configurations (for instance multisampling with
+             * Mesa 6.5.2 and ATI drivers), this does not work:
+             * glXChooseFBConfig returns NULL, whereas fbconfigXID is a valid
+             * XID.  Further investigation is needed.
+             *
+             * So, for now, we return the whole array of FBConfigs.  This should
+             * not produce any side effects elsewhere.
+             */
+            fbconfig = fbconfigArray;
+        }
+        else
+        {
+           fbconfig = NULL;
+        }
+
+       if (numcfgs)
+               *numcfgs = fbconfigArraySize;
+
+        return fbconfig;
+    }
+}
+
+
+static void fghFillContextAttributes( int *attributes ) {
+  int where = 0, contextFlags, contextProfile;
+
+  if ( !fghIsLegacyContextVersionRequested() ) {
+    ATTRIB_VAL( GLX_CONTEXT_MAJOR_VERSION_ARB, fgState.MajorVersion );
+    ATTRIB_VAL( GLX_CONTEXT_MINOR_VERSION_ARB, fgState.MinorVersion );
+  }
+
+  contextFlags =
+    fghMapBit( fgState.ContextFlags, GLUT_DEBUG, GLX_CONTEXT_DEBUG_BIT_ARB ) |
+    fghMapBit( fgState.ContextFlags, GLUT_FORWARD_COMPATIBLE, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB );
+  if ( contextFlags != 0 ) {
+    ATTRIB_VAL( GLX_CONTEXT_FLAGS_ARB, contextFlags );
+  }
+
+  contextProfile =
+    fghMapBit( fgState.ContextProfile, GLUT_CORE_PROFILE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB ) |
+    fghMapBit( fgState.ContextProfile, GLUT_COMPATIBILITY_PROFILE, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB );
+  if ( contextProfile != 0 ) {
+    ATTRIB_VAL( GLX_CONTEXT_PROFILE_MASK_ARB, contextProfile );
+  }
+
+  ATTRIB( 0 );
+}
+
+typedef GLXContext (*CreateContextAttribsProc)(Display *dpy, GLXFBConfig config,
+                                              GLXContext share_list, Bool direct,
+                                              const int *attrib_list);
+
+static GLXContext fghCreateNewContext( SFG_Window* window )
+{
+  /* for color model calculation */
+  int menu = ( window->IsMenu && !fgStructure.MenuContext );
+  int index_mode = ( fgState.DisplayMode & GLUT_INDEX );
+
+  /* "classic" context creation */
+  Display *dpy = fgDisplay.pDisplay.Display;
+  GLXFBConfig config = *(window->Window.pContext.FBConfig);
+  int render_type = ( !menu && index_mode ) ? GLX_COLOR_INDEX_TYPE : GLX_RGBA_TYPE;
+  GLXContext share_list = NULL;
+  Bool direct = ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT );
+  GLXContext context;
+
+  /* new context creation */
+  int attributes[9];
+  CreateContextAttribsProc createContextAttribs = (CreateContextAttribsProc) fgPlatformGetProcAddress( "glXCreateContextAttribsARB" );
+  /* glXCreateContextAttribsARB not found, yet the user has requested the new context creation */
+  if ( !createContextAttribs && !fghIsLegacyContextRequested() ) {
+    fgWarning( "OpenGL >2.1 context requested but glXCreateContextAttribsARB is not available! Falling back to legacy context creation" );
+       fgState.MajorVersion = 2;
+       fgState.MinorVersion = 1;
+  }
+
+  /* If nothing fancy has been required, simply use the old context creation GLX API entry */
+  if ( fghIsLegacyContextRequested() || !createContextAttribs )
+  {
+    context = glXCreateNewContext( dpy, config, render_type, share_list, direct );
+    if ( context == NULL ) {
+      fghContextCreationError();
+    }
+    return context;
+  }
+
+  /* color index mode is not available anymore with OpenGL 3.0 */
+  if ( render_type == GLX_COLOR_INDEX_TYPE ) {
+    fgWarning( "color index mode is deprecated, using RGBA mode" );
+  }
+
+  fghFillContextAttributes( attributes );
+
+  context = createContextAttribs( dpy, config, share_list, direct, attributes );
+  if ( context == NULL ) {
+    fghContextCreationError();
+  }
+  return context;
+}
+
+
+#define _NET_WM_STATE_TOGGLE    2
+static int fghResizeFullscrToggle(void)
+{
+    XWindowAttributes attributes;
+
+    if(glutGet(GLUT_FULL_SCREEN)) {
+        /* restore original window size */
+        SFG_Window *win = fgStructure.CurrentWindow;
+        fgStructure.CurrentWindow->State.NeedToResize = GL_TRUE;
+        fgStructure.CurrentWindow->State.Width  = win->State.pWState.OldWidth;
+        fgStructure.CurrentWindow->State.Height = win->State.pWState.OldHeight;
+
+    } else {
+        /* resize the window to cover the entire screen */
+        XGetWindowAttributes(fgDisplay.pDisplay.Display,
+                fgStructure.CurrentWindow->Window.Handle,
+                &attributes);
+        
+        /*
+         * The "x" and "y" members of "attributes" are the window's coordinates
+         * relative to its parent, i.e. to the decoration window.
+         */
+        XMoveResizeWindow(fgDisplay.pDisplay.Display,
+                fgStructure.CurrentWindow->Window.Handle,
+                -attributes.x,
+                -attributes.y,
+                fgDisplay.ScreenWidth,
+                fgDisplay.ScreenHeight);
+    }
+    return 0;
+}
+
+static int fghEwmhFullscrToggle(void)
+{
+    XEvent xev;
+    long evmask = SubstructureRedirectMask | SubstructureNotifyMask;
+
+    if(!fgDisplay.pDisplay.State || !fgDisplay.pDisplay.StateFullScreen) {
+        return -1;
+    }
+
+    xev.type = ClientMessage;
+    xev.xclient.window = fgStructure.CurrentWindow->Window.Handle;
+    xev.xclient.message_type = fgDisplay.pDisplay.State;
+    xev.xclient.format = 32;
+    xev.xclient.data.l[0] = _NET_WM_STATE_TOGGLE;
+    xev.xclient.data.l[1] = fgDisplay.pDisplay.StateFullScreen;
+    xev.xclient.data.l[2] = 0; /* no second property to toggle */
+    xev.xclient.data.l[3] = 1; /* source indication: application */
+    xev.xclient.data.l[4] = 0; /* unused */
+
+    if(!XSendEvent(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow, 0, evmask, &xev)) {
+        return -1;
+    }
+    return 0;
+}
+
+static int fghToggleFullscreen(void)
+{
+    /* first try the EWMH (_NET_WM_STATE) method ... */
+    if(fghEwmhFullscrToggle() != -1) {
+        return 0;
+    }
+
+    /* fall back to resizing the window */
+    if(fghResizeFullscrToggle() != -1) {
+        return 0;
+    }
+    return -1;
+}
+
+void fgPlatformSetWindow ( SFG_Window *window )
+{
+    if ( window )
+    {
+        glXMakeContextCurrent(
+            fgDisplay.pDisplay.Display,
+            window->Window.Handle,
+            window->Window.Handle,
+            window->Window.Context
+        );
+    }
+}
+
+static Bool fghWindowIsVisible( Display *display, XEvent *event, XPointer arg)
+{
+    Window window = (Window)arg;
+    return (event->type == MapNotify) && (event->xmap.window == window);
+}
+
+/*
+ * Opens a window. Requires a SFG_Window object created and attached
+ * to the freeglut structure. OpenGL context is created here.
+ */
+void fgPlatformOpenWindow( SFG_Window* window, const char* title,
+                           GLboolean positionUse, int x, int y,
+                           GLboolean sizeUse, int w, int h,
+                           GLboolean gameMode, GLboolean isSubWindow )
+{
+    XVisualInfo * visualInfo = NULL;
+    XSetWindowAttributes winAttr;
+    XTextProperty textProperty;
+    XSizeHints sizeHints;
+    XWMHints wmHints;
+    XEvent eventReturnBuffer; /* return buffer required for a call */
+    unsigned long mask;
+    int num_FBConfigs, i;
+    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.pContext.FBConfig = fgPlatformChooseFBConfig( &num_FBConfigs );
+
+    if( window->IsMenu && ( ! fgStructure.MenuContext ) )
+        fgState.DisplayMode = current_DisplayMode ;
+
+    if( ! window->Window.pContext.FBConfig )
+    {
+        /*
+         * The "fgPlatformChooseFBConfig" 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.pContext.FBConfig = fgPlatformChooseFBConfig( &num_FBConfigs );
+            fgState.DisplayMode &= ~GLUT_DOUBLE;
+        }
+
+        if( fgState.DisplayMode & GLUT_MULTISAMPLE )
+        {
+            fgState.DisplayMode &= ~GLUT_MULTISAMPLE ;
+            window->Window.pContext.FBConfig = fgPlatformChooseFBConfig( &num_FBConfigs );
+            fgState.DisplayMode |= GLUT_MULTISAMPLE;
+        }
+    }
+
+    FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.pContext.FBConfig != NULL,
+                                  "FBConfig with necessary capabilities not found", "fgOpenWindow" );
+
+    /*  Get the X visual.  */
+    for (i = 0; i < num_FBConfigs; i++) {
+           visualInfo = glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display,
+                                                  window->Window.pContext.FBConfig[i] );
+           if (visualInfo)
+               break;
+    }
+
+    FREEGLUT_INTERNAL_ERROR_EXIT( visualInfo != NULL,
+                                  "visualInfo could not be retrieved from FBConfig", "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.pDisplay.Display, fgDisplay.pDisplay.RootWindow,
+        visualInfo->visual, AllocNone
+    );
+
+    mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
+
+    if( window->IsMenu || ( gameMode == GL_TRUE ) )
+    {
+        winAttr.override_redirect = True;
+        mask |= CWOverrideRedirect;
+    }
+
+    if( ! positionUse )
+        x = y = -1; /* default window position */
+    if( ! sizeUse )
+        w = h = 300; /* default window size */
+
+    window->Window.Handle = XCreateWindow(
+        fgDisplay.pDisplay.Display,
+        window->Parent == NULL ? fgDisplay.pDisplay.RootWindow :
+        window->Parent->Window.Handle,
+        x, y, w, h, 0,
+        visualInfo->depth, InputOutput,
+        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->MContext = fghCreateNewContext( window );
+        }
+
+        /* window->Window.Context = fgStructure.MenuContext->MContext; */
+        window->Window.Context = fghCreateNewContext( window );
+    }
+    else if( fgState.UseCurrentContext )
+    {
+        window->Window.Context = glXGetCurrentContext( );
+
+        if( ! window->Window.Context )
+            window->Window.Context = fghCreateNewContext( window );
+    }
+    else
+        window->Window.Context = fghCreateNewContext( window );
+
+#if !defined( __FreeBSD__ ) && !defined( __NetBSD__ )
+    if(  !glXIsDirect( fgDisplay.pDisplay.Display, window->Window.Context ) )
+    {
+      if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT )
+        fgError( "Unable to force direct context rendering for window '%s'",
+                 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 ( positionUse )
+        sizeHints.flags |= USPosition;
+    if ( sizeUse )
+        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.pDisplay.Display,
+        window->Window.Handle,
+        &textProperty,
+        &textProperty,
+        0,
+        0,
+        &sizeHints,
+        &wmHints,
+        NULL
+    );
+    XFree( textProperty.value );
+
+    XSetWMProtocols( fgDisplay.pDisplay.Display, window->Window.Handle,
+                     &fgDisplay.pDisplay.DeleteWindow, 1 );
+
+    glXMakeContextCurrent(
+        fgDisplay.pDisplay.Display,
+        window->Window.Handle,
+        window->Window.Handle,
+        window->Window.Context
+    );
+
+    /* register extension events _before_ window is mapped */
+    #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
+       fgRegisterDevices( fgDisplay.pDisplay.Display, &(window->Window.Handle) );
+    #endif
+
+    XMapWindow( fgDisplay.pDisplay.Display, window->Window.Handle );
+
+    XFree(visualInfo);
+
+    if( !isSubWindow)
+        XPeekIfEvent( fgDisplay.pDisplay.Display, &eventReturnBuffer, &fghWindowIsVisible, (XPointer)(window->Window.Handle) );
+}
+
+
+/*
+ * Closes a window, destroying the frame and OpenGL context
+ */
+void fgPlatformCloseWindow( SFG_Window* window )
+{
+    if( window->Window.Context )
+        glXDestroyContext( fgDisplay.pDisplay.Display, window->Window.Context );
+    XFree( window->Window.pContext.FBConfig );
+
+    if( window->Window.Handle ) {
+        XDestroyWindow( fgDisplay.pDisplay.Display, window->Window.Handle );
+    }
+    /* XFlush( fgDisplay.pDisplay.Display ); */ /* XXX Shouldn't need this */
+}
+
+
+/*
+ * This function makes the current window visible
+ */
+void fgPlatformGlutShowWindow( void )
+{
+    XMapWindow( fgDisplay.pDisplay.Display, fgStructure.CurrentWindow->Window.Handle );
+    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
+}
+
+/*
+ * This function hides the current window
+ */
+void fgPlatformGlutHideWindow( void )
+{
+    if( fgStructure.CurrentWindow->Parent == NULL )
+        XWithdrawWindow( fgDisplay.pDisplay.Display,
+                         fgStructure.CurrentWindow->Window.Handle,
+                         fgDisplay.pDisplay.Screen );
+    else
+        XUnmapWindow( fgDisplay.pDisplay.Display,
+                      fgStructure.CurrentWindow->Window.Handle );
+    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
+}
+
+/*
+ * Iconify the current window (top-level windows only)
+ */
+void fgPlatformGlutIconifyWindow( void )
+{
+    XIconifyWindow( fgDisplay.pDisplay.Display, fgStructure.CurrentWindow->Window.Handle,
+                    fgDisplay.pDisplay.Screen );
+    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
+}
+
+/*
+ * Set the current window's title
+ */
+void fgPlatformGlutSetWindowTitle( const char* title )
+{
+    XTextProperty text;
+
+    text.value = (unsigned char *) title;
+    text.encoding = XA_STRING;
+    text.format = 8;
+    text.nitems = strlen( title );
+
+    XSetWMName(
+        fgDisplay.pDisplay.Display,
+        fgStructure.CurrentWindow->Window.Handle,
+        &text
+    );
+
+    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
+}
+
+/*
+ * Set the current window's iconified title
+ */
+void fgPlatformGlutSetIconTitle( const char* title )
+{
+    XTextProperty text;
+
+    text.value = (unsigned char *) title;
+    text.encoding = XA_STRING;
+    text.format = 8;
+    text.nitems = strlen( title );
+
+    XSetWMIconName(
+        fgDisplay.pDisplay.Display,
+        fgStructure.CurrentWindow->Window.Handle,
+        &text
+    );
+
+    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
+}
+
+/*
+ * Change the current window's position
+ */
+void fgPlatformGlutPositionWindow( int x, int y )
+{
+    XMoveWindow( fgDisplay.pDisplay.Display, fgStructure.CurrentWindow->Window.Handle,
+                 x, y );
+    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
+}
+
+/*
+ * Lowers the current window (by Z order change)
+ */
+void fgPlatformGlutPushWindow( void )
+{
+    XLowerWindow( fgDisplay.pDisplay.Display, fgStructure.CurrentWindow->Window.Handle );
+}
+
+/*
+ * Raises the current window (by Z order change)
+ */
+void fgPlatformGlutPopWindow( void )
+{
+    XRaiseWindow( fgDisplay.pDisplay.Display, fgStructure.CurrentWindow->Window.Handle );
+}
+
+/*
+ * Resize the current window so that it fits the whole screen
+ */
+void fgPlatformGlutFullScreen( SFG_Window *win )
+{
+    if(!glutGet(GLUT_FULL_SCREEN)) {
+        if(fghToggleFullscreen() != -1) {
+            win->State.IsFullscreen = GL_TRUE;
+        }
+    }
+}
+
+/*
+ * If we are fullscreen, resize the current window back to its original size
+ */
+void fgPlatformGlutLeaveFullScreen( SFG_Window *win )
+{
+    if(glutGet(GLUT_FULL_SCREEN)) {
+        if(fghToggleFullscreen() != -1) {
+            win->State.IsFullscreen = GL_FALSE;
+        }
+    }
+}
+
+/*
+ * Toggle the window's full screen state.
+ */
+void fgPlatformGlutFullScreenToggle( SFG_Window *win )
+{
+    if(fghToggleFullscreen() != -1) {
+        win->State.IsFullscreen = !win->State.IsFullscreen;
+    }
+}
+
diff --git a/src/x11/fg_xinput_x11.c b/src/x11/fg_xinput_x11.c
new file mode 100644 (file)
index 0000000..fac1bf7
--- /dev/null
@@ -0,0 +1,219 @@
+/* Written for XI1 by Nikolas Doerfler <doerflen@in.tum.de> (c) 2008 *
+ * Rewritten for XI2 by Florian Echtler <echtler@in.tum.de> (c) 2009 */
+
+#include <GL/freeglut.h>
+
+#include "../fg_internal.h"
+
+#if HAVE_X11_EXTENSIONS_XINPUT2_H
+
+#include <errno.h>
+#include <stdarg.h>
+
+#include <X11/Xlib.h>
+#include <X11/extensions/XInput2.h>
+
+/* import function from freeglut_main.c */
+extern int fgPlatformGetModifiers( int state );
+
+/* extension opcode for XInput */
+int xi_opcode = -1;
+
+/**
+ * \brief Sets window up for XI2 events.
+ */
+void fgRegisterDevices( Display* dpy, Window* win ) {
+
+       XIEventMask mask;
+       unsigned char flags[2] = { 0, 0 };
+       int event, error;
+
+       /*Display* dpy = fgDisplay.pDisplay.Display;
+       Window* win = glutGetXWindow();*/
+
+       /* get XInput extension opcode */
+       if (!XQueryExtension( dpy, "XInputExtension", &xi_opcode, &event, &error )) { xi_opcode = -1; }
+
+       /* Select for motion events */
+       mask.deviceid = XIAllMasterDevices;
+       mask.mask_len = 2;
+       mask.mask = flags;
+
+       XISetMask(mask.mask, XI_Enter);
+       XISetMask(mask.mask, XI_Motion);
+       XISetMask(mask.mask, XI_ButtonPress);
+       XISetMask(mask.mask, XI_ButtonRelease);
+       XISetMask(mask.mask, XI_Leave);
+       /*XISetMask(mask.mask, XI_KeyPress);
+       XISetMask(mask.mask, XI_KeyRelease);
+       XISetMask(mask.mask, XI_DeviceChanged);
+       XISetMask(mask.mask, XI_RawEvent);
+       XISetMask(mask.mask, XI_FocusIn);
+       XISetMask(mask.mask, XI_FocusOut);
+       XISetMask(mask.mask, XI_HierarchyChanged);*/
+
+       XISelectEvents( dpy, *win, &mask, 1 );
+}
+
+
+void fgPrintXILeaveEvent(XILeaveEvent* event)
+{
+    char* mode = "";
+               char* detail = "";
+    int i;
+
+    printf("    windows: root 0x%lx event 0x%lx child 0x%ld\n",
+            event->root, event->event, event->child);
+    switch(event->mode)
+    {
+        case NotifyNormal:       mode = "NotifyNormal"; break;
+        case NotifyGrab:         mode = "NotifyGrab"; break;
+        case NotifyUngrab:       mode = "NotifyUngrab"; break;
+        case NotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break;
+    }
+    switch (event->detail)
+    {
+        case NotifyAncestor: detail = "NotifyAncestor"; break;
+        case NotifyVirtual: detail = "NotifyVirtual"; break;
+        case NotifyInferior: detail = "NotifyInferior"; break;
+        case NotifyNonlinear: detail = "NotifyNonlinear"; break;
+        case NotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break;
+        case NotifyPointer: detail = "NotifyPointer"; break;
+        case NotifyPointerRoot: detail = "NotifyPointerRoot"; break;
+        case NotifyDetailNone: detail = "NotifyDetailNone"; break;
+    }
+    printf("    mode: %s (detail %s)\n", mode, detail);
+    printf("    flags: %s %s\n", event->focus ? "[focus]" : "",
+                                 event->same_screen ? "[same screen]" : "");
+    printf("    buttons:");
+    for (i = 0; i < event->buttons.mask_len * 8; i++)
+        if (XIMaskIsSet(event->buttons.mask, i))
+            printf(" %d", i);
+    printf("\n");
+
+    printf("    modifiers: locked 0x%x latched 0x%x base 0x%x\n",
+            event->mods.locked, event->mods.latched,
+            event->mods.base);
+    printf("    group: locked 0x%x latched 0x%x base 0x%x\n",
+            event->group.locked, event->group.latched,
+            event->group.base);
+
+    printf("    root x/y:  %.2f / %.2f\n", event->root_x, event->root_y);
+    printf("    event x/y: %.2f / %.2f\n", event->event_x, event->event_y);
+
+}
+
+
+void fgPrintXIDeviceEvent(XIDeviceEvent* event)
+{
+    double *val;
+    int i;
+
+    printf("    device: %d (%d)\n", event->deviceid, event->sourceid);
+    printf("    detail: %d\n", event->detail);
+    printf("    buttons:");
+         for (i = 0; i < event->buttons.mask_len * 8; i++)
+           if (XIMaskIsSet(event->buttons.mask, i))
+             printf(" %d", i);
+    printf("\n");
+
+    printf("    modifiers: locked 0x%x latched 0x%x base 0x%x\n",
+            event->mods.locked, event->mods.latched,
+            event->mods.base);
+    printf("    group: locked 0x%x latched 0x%x base 0x%x\n",
+            event->group.locked, event->group.latched,
+            event->group.base);
+    printf("    valuators:");
+
+    val = event->valuators.values;
+    for (i = 0; i < event->valuators.mask_len * 8; i++)
+        if (XIMaskIsSet(event->valuators.mask, i))
+            printf(" %d: %.2f", i, *val++);
+    printf("\n");
+
+    printf("    windows: root 0x%lx event 0x%lx child 0x%ld\n",
+            event->root, event->event, event->child);
+    printf("    root x/y:  %.2f / %.2f\n", event->root_x, event->root_y);
+    printf("    event x/y: %.2f / %.2f\n", event->event_x, event->event_y);
+
+}
+
+
+/**
+ * \brief This function is called when an Extension Event is received
+ * and calls the corresponding callback functions for these events.
+ */
+void fgHandleExtensionEvents( XEvent* base_ev ) {
+
+       int i, button = 0;
+       XGenericEventCookie* cookie = (XGenericEventCookie*)&(base_ev->xcookie);
+
+       if ( XGetEventData( fgDisplay.pDisplay.Display, cookie ) && (cookie->type == GenericEvent) && (cookie->extension == xi_opcode) ) {
+
+               XIDeviceEvent* event = (XIDeviceEvent*)(cookie->data);
+               /*printf("XI2 event type: %d - %d\n", cookie->evtype, event->type );*/
+
+               SFG_Window* window = fgWindowByHandle( event->event );
+               if (!window) return;
+
+               switch (cookie->evtype) {
+
+                       case XI_Enter:
+                       case XI_Leave:
+                               fgState.Modifiers = fgPlatformGetModifiers( ((XIEnterEvent*)event)->mods.base );
+                               INVOKE_WCB( *window, MultiEntry, (
+                                       event->deviceid, 
+                                       (event->evtype == XI_Enter ? GLUT_ENTERED : GLUT_LEFT)
+                               ));
+                               #if _DEBUG
+                                       fgPrintXILeaveEvent((XILeaveEvent*)event);
+                               #endif
+                               break;
+
+                       case XI_ButtonPress:
+                       case XI_ButtonRelease:
+                               fgState.Modifiers = fgPlatformGetModifiers( event->mods.base );
+                               INVOKE_WCB( *window, MultiButton, (
+                                       event->deviceid, 
+                                       event->event_x,
+                                       event->event_y,
+                                       (event->detail)-1, 
+                                       (event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP)
+                               ));
+                               INVOKE_WCB( *window, Mouse, (
+                                       (event->detail)-1, 
+                                       (event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP),
+                                       event->event_x,
+                                       event->event_y
+                               ));
+                               break;
+
+                       case XI_Motion:
+                               fgState.Modifiers = fgPlatformGetModifiers( event->mods.base );
+                               for (i = 0; i < event->buttons.mask_len; i++) if (event->buttons.mask[i]) button = 1;
+                               if (button) {
+                                       INVOKE_WCB( *window, MultiMotion,  ( event->deviceid, event->event_x, event->event_y ) );
+                                       INVOKE_WCB( *window,           Motion,  (                  event->event_x, event->event_y ) );
+                               } else {
+                                       INVOKE_WCB( *window, MultiPassive, ( event->deviceid, event->event_x, event->event_y ) );
+                                       INVOKE_WCB( *window,           Passive, (                  event->event_x, event->event_y ) );
+                               }
+                               #if _DEBUG
+                                       fgPrintXIDeviceEvent(event);
+                               #endif
+                               break;
+
+                       default:
+                               #if _DEBUG
+                                       fgWarning( "Unknown XI2 device event:" );
+                                       fgPrintXIDeviceEvent( event );
+                               #endif
+                               break;
+               }
+               fgState.Modifiers = INVALID_MODIFIERS;
+       }
+       XFreeEventData( fgDisplay.pDisplay.Display, cookie );
+}
+
+#endif\r
+\r
diff --git a/src/x11/freeglut_cursor_x11.c b/src/x11/freeglut_cursor_x11.c
deleted file mode 100644 (file)
index 3098e53..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * freeglut_cursor_x11.c
- *
- * The Windows-specific mouse cursor related stuff.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Sun Feb 5, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-/* This code is for Posix/X11, Solaris, and OSX */
-#include <X11/cursorfont.h>
-
-/*
- * A factory method for an empty cursor
- */
-static Cursor getEmptyCursor( void )
-{
-    static Cursor cursorNone = None;
-    if( cursorNone == None ) {
-        char cursorNoneBits[ 32 ];
-        XColor dontCare;
-        Pixmap cursorNonePixmap;
-        memset( cursorNoneBits, 0, sizeof( cursorNoneBits ) );
-        memset( &dontCare, 0, sizeof( dontCare ) );
-        cursorNonePixmap = XCreateBitmapFromData ( fgDisplay.pDisplay.Display,
-                                                   fgDisplay.pDisplay.RootWindow,
-                                                   cursorNoneBits, 16, 16 );
-        if( cursorNonePixmap != None ) {
-            cursorNone = XCreatePixmapCursor( fgDisplay.pDisplay.Display,
-                                              cursorNonePixmap, cursorNonePixmap,
-                                              &dontCare, &dontCare, 0, 0 );
-            XFreePixmap( fgDisplay.pDisplay.Display, cursorNonePixmap );
-        }
-    }
-    return cursorNone;
-}
-
-typedef struct tag_cursorCacheEntry cursorCacheEntry;
-struct tag_cursorCacheEntry {
-    unsigned int cursorShape;    /* an XC_foo value */
-    Cursor cachedCursor;         /* None if the corresponding cursor has
-                                    not been created yet */
-};
-
-/*
- * Note: The arrangement of the table below depends on the fact that
- * the "normal" GLUT_CURSOR_* values start a 0 and are consecutive.
- */ 
-static cursorCacheEntry cursorCache[] = {
-    { XC_arrow,               None }, /* GLUT_CURSOR_RIGHT_ARROW */
-    { XC_top_left_arrow,      None }, /* GLUT_CURSOR_LEFT_ARROW */
-    { XC_hand1,               None }, /* GLUT_CURSOR_INFO */
-    { XC_pirate,              None }, /* GLUT_CURSOR_DESTROY */
-    { XC_question_arrow,      None }, /* GLUT_CURSOR_HELP */
-    { XC_exchange,            None }, /* GLUT_CURSOR_CYCLE */
-    { XC_spraycan,            None }, /* GLUT_CURSOR_SPRAY */
-    { XC_watch,               None }, /* GLUT_CURSOR_WAIT */
-    { XC_xterm,               None }, /* GLUT_CURSOR_TEXT */
-    { XC_crosshair,           None }, /* GLUT_CURSOR_CROSSHAIR */
-    { XC_sb_v_double_arrow,   None }, /* GLUT_CURSOR_UP_DOWN */
-    { XC_sb_h_double_arrow,   None }, /* GLUT_CURSOR_LEFT_RIGHT */
-    { XC_top_side,            None }, /* GLUT_CURSOR_TOP_SIDE */
-    { XC_bottom_side,         None }, /* GLUT_CURSOR_BOTTOM_SIDE */
-    { XC_left_side,           None }, /* GLUT_CURSOR_LEFT_SIDE */
-    { XC_right_side,          None }, /* GLUT_CURSOR_RIGHT_SIDE */
-    { XC_top_left_corner,     None }, /* GLUT_CURSOR_TOP_LEFT_CORNER */
-    { XC_top_right_corner,    None }, /* GLUT_CURSOR_TOP_RIGHT_CORNER */
-    { XC_bottom_right_corner, None }, /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */
-    { XC_bottom_left_corner,  None }  /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */
-};
-
-void fgPlatformSetCursor ( SFG_Window *window, int cursorID )
-{
-    Cursor cursor;
-    /*
-     * XXX FULL_CROSSHAIR demotes to plain CROSSHAIR. Old GLUT allows
-     * for this, but if there is a system that easily supports a full-
-     * window (or full-screen) crosshair, we might consider it.
-     */
-    int cursorIDToUse =
-        ( cursorID == GLUT_CURSOR_FULL_CROSSHAIR ) ? GLUT_CURSOR_CROSSHAIR : cursorID;
-
-    if( ( cursorIDToUse >= 0 ) &&
-        ( cursorIDToUse < sizeof( cursorCache ) / sizeof( cursorCache[0] ) ) ) {
-        cursorCacheEntry *entry = &cursorCache[ cursorIDToUse ];
-        if( entry->cachedCursor == None ) {
-            entry->cachedCursor =
-                XCreateFontCursor( fgDisplay.pDisplay.Display, entry->cursorShape );
-        }
-        cursor = entry->cachedCursor;
-    } else {
-        switch( cursorIDToUse )
-        {
-        case GLUT_CURSOR_NONE:
-            cursor = getEmptyCursor( );
-            break;
-
-        case GLUT_CURSOR_INHERIT:
-            cursor = None;
-            break;
-
-        default:
-            fgError( "Unknown cursor type: %d", cursorIDToUse );
-            return;
-        }
-    }
-
-    if ( cursorIDToUse == GLUT_CURSOR_INHERIT ) {
-        XUndefineCursor( fgDisplay.pDisplay.Display, window->Window.Handle );
-    } else if ( cursor != None ) {
-        XDefineCursor( fgDisplay.pDisplay.Display, window->Window.Handle, cursor );
-    } else if ( cursorIDToUse != GLUT_CURSOR_NONE ) {
-        fgError( "Failed to create cursor" );
-    }
-}
-
-
-void fgPlatformWarpPointer ( int x, int y )
-{
-    XWarpPointer(
-        fgDisplay.pDisplay.Display,
-        None,
-        fgStructure.CurrentWindow->Window.Handle,
-        0, 0, 0, 0,
-        x, y
-    );
-    /* Make the warp visible immediately. */
-    XFlush( fgDisplay.pDisplay.Display );
-}
-
diff --git a/src/x11/freeglut_display_x11.c b/src/x11/freeglut_display_x11.c
deleted file mode 100644 (file)
index bbf9061..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * freeglut_display_x11.c
- *
- * Display message posting, context buffer swapping.
- *
- * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
- * Written by Pawel W. Olszta, <olszta@sourceforge.net>
- * Copied for Platform code by Evan Felix <karcaw at gmail.com>
- * Creation date: Thur Feb 2 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-void fgPlatformGlutSwapBuffers( SFG_PlatformDisplay *pDisplayPtr, SFG_Window* CurrentWindow )
-{
-    glXSwapBuffers( pDisplayPtr->Display, CurrentWindow->Window.Handle );
-}
-
diff --git a/src/x11/freeglut_ext_x11.c b/src/x11/freeglut_ext_x11.c
deleted file mode 100644 (file)
index d243cfd..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * freeglut_ext.c
- *
- * Functions related to OpenGL extensions.
- *
- * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
- * Written by Pawel W. Olszta, <olszta@sourceforge.net>
- * Copied for Platform code by Evan Felix <karcaw at gmail.com>
- * Creation date: Thur Feb 2 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#define GLX_GLXEXT_PROTOTYPES
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-GLUTproc fgPlatformGetGLUTProcAddress( const char* procName )
-{
-    /* optimization: quick initial check */
-    if( strncmp( procName, "glut", 4 ) != 0 )
-        return NULL;
-
-#define CHECK_NAME(x) if( strcmp( procName, #x ) == 0) return (GLUTproc)x;
-    CHECK_NAME(glutJoystickFunc);
-    CHECK_NAME(glutForceJoystickFunc);
-    CHECK_NAME(glutGameModeString);
-    CHECK_NAME(glutEnterGameMode);
-    CHECK_NAME(glutLeaveGameMode);
-    CHECK_NAME(glutGameModeGet);
-#undef CHECK_NAME
-
-    return NULL;
-}
-
-
-SFG_Proc fgPlatformGetProcAddress( const char *procName )
-{
-#if defined( GLX_ARB_get_proc_address )
-    return (SFG_Proc)glXGetProcAddressARB( ( const GLubyte * )procName );
-#else
-    return NULL;
-#endif
-}
-
diff --git a/src/x11/freeglut_gamemode_x11.c b/src/x11/freeglut_gamemode_x11.c
deleted file mode 100644 (file)
index 6130aeb..0000000
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * freeglut_gamemode_x11.c
- *
- * The game mode handling code.
- *
- * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
- * Written by Pawel W. Olszta, <olszta@sourceforge.net>
- * Copied for Platform code by Evan Felix <karcaw at gmail.com>
- * Creation date: Thur Feb 2 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-static int xrandr_resize(int xsz, int ysz, int rate, int just_checking)
-{
-#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
-    int event_base, error_base, ver_major, ver_minor, use_rate;
-    XRRScreenConfiguration *xrr_config = 0;
-    Status result = -1;
-
-    /* must check at runtime for the availability of the extension */
-    if(!XRRQueryExtension(fgDisplay.pDisplay.Display, &event_base, &error_base)) {
-        return -1;
-    }
-
-    XRRQueryVersion(fgDisplay.pDisplay.Display, &ver_major, &ver_minor);
-
-    /* we only heed the rate if we CAN actually use it (Xrandr >= 1.1) and
-     * the user actually cares about it (rate > 0)
-     */
-    use_rate = ( rate > 0 ) && ( ( ver_major >= 1 ) ||
-                                        ( ( ver_major == 1 ) && ( ver_minor >= 1 ) ) );
-
-    /* this loop is only so that the whole thing will be repeated if someone
-     * else changes video mode between our query of the current information and
-     * the attempt to change it.
-     */
-    do {
-        XRRScreenSize *ssizes;
-        short *rates;
-        Rotation rot;
-        int i, ssizes_count, rates_count, curr, res_idx = -1;
-        Time timestamp, cfg_timestamp;
-
-        if(xrr_config) {
-            XRRFreeScreenConfigInfo(xrr_config);
-        }
-
-        if(!(xrr_config = XRRGetScreenInfo(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow))) {
-            fgWarning("XRRGetScreenInfo failed");
-            break;
-        }
-        ssizes = XRRConfigSizes(xrr_config, &ssizes_count);
-        curr = XRRConfigCurrentConfiguration(xrr_config, &rot);
-        timestamp = XRRConfigTimes(xrr_config, &cfg_timestamp);
-
-        /* if either of xsz or ysz are unspecified, use the current values */
-        if(xsz <= 0)
-            xsz = fgState.GameModeSize.X = ssizes[curr].width;
-        if(ysz <= 0)
-            ysz = fgState.GameModeSize.Y = ssizes[curr].height;
-
-
-        if(xsz == ssizes[curr].width && ysz == ssizes[curr].height) {
-            /* no need to switch, we're already in the requested resolution */
-            res_idx = curr;
-        } else {
-            for(i=0; i<ssizes_count; i++) {
-                if(ssizes[i].width == xsz && ssizes[i].height == ysz) {
-                    res_idx = i;
-                    break;  /* found it */
-                }
-            }
-        }
-        if(res_idx == -1)
-            break;  /* no matching resolution */
-
-#if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
-        if(use_rate) {
-            rate = fgState.GameModeRefresh;
-
-            /* for the selected resolution, let's find out if there is
-             * a matching refresh rate available.
-             */
-            rates = XRRConfigRates(xrr_config, res_idx, &rates_count);
-
-            for(i=0; i<rates_count; i++) {
-                if(rates[i] == rate) {
-                    break;
-                }
-            }
-            if(i == rates_count) {
-                break; /* no matching rate */
-            }
-        }
-#endif
-
-        if(just_checking) {
-            result = 0;
-            break;
-        }
-
-#if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
-        if(use_rate)
-            result = XRRSetScreenConfigAndRate(fgDisplay.pDisplay.Display, xrr_config,
-                    fgDisplay.pDisplay.RootWindow, res_idx, rot, rate, timestamp);
-        else
-#endif
-            result = XRRSetScreenConfig(fgDisplay.pDisplay.Display, xrr_config,
-                    fgDisplay.pDisplay.RootWindow, res_idx, rot, timestamp);
-
-    } while(result == RRSetConfigInvalidTime);
-
-    if(xrr_config) {
-        XRRFreeScreenConfigInfo(xrr_config);
-    }
-
-    if(result == 0) {
-        return 0;
-    }
-
-#endif  /* HAVE_X11_EXTENSIONS_XRANDR_H */
-    return -1;
-}
-
-/*
- * Remembers the current visual settings, so that
- * we can change them and restore later...
- */
-void fgPlatformRememberState( void )
-{
-    int event_base, error_base;
-
-    /*
-     * Remember the current pointer location before going fullscreen
-     * for restoring it later:
-     */
-    Window junk_window;
-    unsigned int junk_mask;
-
-    XQueryPointer(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow,
-            &junk_window, &junk_window,
-            &fgDisplay.pDisplay.DisplayPointerX, &fgDisplay.pDisplay.DisplayPointerY,
-            &fgDisplay.pDisplay.DisplayPointerX, &fgDisplay.pDisplay.DisplayPointerY, &junk_mask);
-
-#   ifdef HAVE_X11_EXTENSIONS_XRANDR_H
-    if(XRRQueryExtension(fgDisplay.pDisplay.Display, &event_base, &error_base)) {
-        XRRScreenConfiguration *xrr_config;
-        XRRScreenSize *ssizes;
-        Rotation rot;
-        int ssize_count, curr;
-
-        if((xrr_config = XRRGetScreenInfo(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow))) {
-            ssizes = XRRConfigSizes(xrr_config, &ssize_count);
-            curr = XRRConfigCurrentConfiguration(xrr_config, &rot);
-
-            fgDisplay.pDisplay.prev_xsz = ssizes[curr].width;
-            fgDisplay.pDisplay.prev_ysz = ssizes[curr].height;
-            fgDisplay.pDisplay.prev_refresh = -1;
-
-#       if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
-            if(fgState.GameModeRefresh != -1) {
-                fgDisplay.pDisplay.prev_refresh = XRRConfigCurrentRate(xrr_config);
-            }
-#       endif
-
-            fgDisplay.pDisplay.prev_size_valid = 1;
-
-            XRRFreeScreenConfigInfo(xrr_config);
-        }
-    }
-#   endif
-
-    /*
-     * This highly depends on the XFree86 extensions,
-     * not approved as X Consortium standards
-     */
-#   ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
-    if(!XF86VidModeQueryExtension(fgDisplay.pDisplay.Display, &event_base, &error_base)) {
-        return;
-    }
-
-    /*
-     * Remember the current ViewPort location of the screen to be able to
-     * restore the ViewPort on LeaveGameMode():
-     */
-    if( !XF86VidModeGetViewPort(
-             fgDisplay.pDisplay.Display,
-             fgDisplay.pDisplay.Screen,
-             &fgDisplay.pDisplay.DisplayViewPortX,
-             &fgDisplay.pDisplay.DisplayViewPortY ) )
-        fgWarning( "XF86VidModeGetViewPort failed" );
-
-
-    /* Query the current display settings: */
-    fgDisplay.pDisplay.DisplayModeValid =
-      XF86VidModeGetModeLine(
-        fgDisplay.pDisplay.Display,
-        fgDisplay.pDisplay.Screen,
-        &fgDisplay.pDisplay.DisplayModeClock,
-        &fgDisplay.pDisplay.DisplayMode
-    );
-
-    if( !fgDisplay.pDisplay.DisplayModeValid )
-        fgWarning( "XF86VidModeGetModeLine failed" );
-#   endif
-
-}
-
-/*
- * Restores the previously remembered visual settings
- */
-void fgPlatformRestoreState( void )
-{
-    /* Restore the remembered pointer position: */
-    XWarpPointer(
-        fgDisplay.pDisplay.Display, None, fgDisplay.pDisplay.RootWindow, 0, 0, 0, 0,
-        fgDisplay.pDisplay.DisplayPointerX, fgDisplay.pDisplay.DisplayPointerY
-    );
-
-
-#   ifdef HAVE_X11_EXTENSIONS_XRANDR_H
-    if(fgDisplay.pDisplay.prev_size_valid) {
-        if(xrandr_resize(fgDisplay.pDisplay.prev_xsz, fgDisplay.pDisplay.prev_ysz, fgDisplay.pDisplay.prev_refresh, 0) != -1) {
-            fgDisplay.pDisplay.prev_size_valid = 0;
-#       ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
-            fgDisplay.pDisplay.DisplayModeValid = 0;
-#       endif
-            return;
-        }
-    }
-#   endif
-
-
-
-#   ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
-    /*
-     * This highly depends on the XFree86 extensions,
-     * not approved as X Consortium standards
-     */
-
-    if( fgDisplay.pDisplay.DisplayModeValid )
-    {
-        XF86VidModeModeInfo** displayModes;
-        int i, displayModesCount;
-
-        if( !XF86VidModeGetAllModeLines(
-                 fgDisplay.pDisplay.Display,
-                 fgDisplay.pDisplay.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.pDisplay.DisplayMode.hdisplay &&
-               displayModes[ i ]->vdisplay == fgDisplay.pDisplay.DisplayMode.vdisplay &&
-               displayModes[ i ]->dotclock == fgDisplay.pDisplay.DisplayModeClock )
-            {
-                if( !XF86VidModeSwitchToMode(
-                         fgDisplay.pDisplay.Display,
-                         fgDisplay.pDisplay.Screen,
-                         displayModes[ i ] ) )
-                {
-                    fgWarning( "XF86VidModeSwitchToMode failed" );
-                    break;
-                }
-
-                if( !XF86VidModeSetViewPort(
-                         fgDisplay.pDisplay.Display,
-                         fgDisplay.pDisplay.Screen,
-                         fgDisplay.pDisplay.DisplayViewPortX,
-                         fgDisplay.pDisplay.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.pDisplay.Display );
-
-                fgDisplay.pDisplay.DisplayModeValid = 0;
-#       ifdef HAVE_X11_EXTENSIONS_XRANDR_H
-                fgDisplay.pDisplay.prev_size_valid = 0;
-#       endif
-
-                break;
-            }
-        }
-        XFree( displayModes );
-    }
-
-#   endif
-
-}
-
-#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
-
-/*
- * Checks a single display mode settings against user's preferences.
- */
-static GLboolean fghCheckDisplayMode( int width, int height, int depth, int refresh )
-{
-    /* The desired values should be stored in fgState structure... */
-    return ( width == fgState.GameModeSize.X ) &&
-           ( height == fgState.GameModeSize.Y ) &&
-           ( depth == fgState.GameModeDepth ) &&
-           ( refresh == fgState.GameModeRefresh );
-}
-
-/*
- * Checks all display modes settings against user's preferences.
- * Returns the mode number found or -1 if none could be found.
- */
-static int fghCheckDisplayModes( GLboolean exactMatch, int displayModesCount, XF86VidModeModeInfo** displayModes )
-{
-    int i;
-    for( i = 0; i < displayModesCount; i++ )
-    {
-        /* Compute the displays refresh rate, dotclock comes in kHz. */
-        int refresh = ( displayModes[ i ]->dotclock * 1000 ) /
-                      ( displayModes[ i ]->htotal * displayModes[ i ]->vtotal );
-
-        if( fghCheckDisplayMode( displayModes[ i ]->hdisplay,
-                                 displayModes[ i ]->vdisplay,
-                                 fgState.GameModeDepth,
-                                 ( exactMatch ? refresh : fgState.GameModeRefresh ) ) ) {
-            if (!exactMatch)
-            {
-                /* Update the chosen refresh rate, otherwise a
-                 * glutGameModeGet(GLUT_GAME_MODE_REFRESH_RATE) would not
-                 * return the right values
-                 */
-                fgState.GameModeRefresh = refresh;
-            }
-
-            return i;
-        }
-    }
-    return -1;
-}
-
-#endif
-
-/*
- * Changes the current display mode to match user's settings
- */
-GLboolean fgPlatformChangeDisplayMode( GLboolean haveToTest )
-{
-    GLboolean success = GL_FALSE;
-    /* first try to use XRandR, then fallback to XF86VidMode */
-#   ifdef HAVE_X11_EXTENSIONS_XRANDR_H
-    if(xrandr_resize(fgState.GameModeSize.X, fgState.GameModeSize.Y,
-                fgState.GameModeRefresh, haveToTest) != -1) {
-        return GL_TRUE;
-    }
-#   endif
-
-
-    /*
-     * This highly depends on the XFree86 extensions,
-     * not approved as X Consortium standards
-     */
-#   ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
-
-    /*
-     * This is also used by applications which check modes by calling
-     * glutGameModeGet(GLUT_GAME_MODE_POSSIBLE), so allow the check:
-     */
-    if( haveToTest || fgDisplay.pDisplay.DisplayModeValid )
-    {
-        XF86VidModeModeInfo** displayModes;
-        int i, displayModesCount;
-
-        /* If we don't have a valid modeline in the display structure, which
-         * can happen if this is called from glutGameModeGet instead of
-         * glutEnterGameMode, then we need to query the current mode, to make
-         * unspecified settings to default to their current values.
-         */
-        if(!fgDisplay.pDisplay.DisplayModeValid) {
-            if(!XF86VidModeGetModeLine(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen,
-                    &fgDisplay.pDisplay.DisplayModeClock, &fgDisplay.pDisplay.DisplayMode)) {
-                return success;
-            }
-        }
-
-        if (fgState.GameModeSize.X == -1)
-        {
-            fgState.GameModeSize.X = fgDisplay.pDisplay.DisplayMode.hdisplay;
-        }
-        if (fgState.GameModeSize.Y == -1)
-        {
-            fgState.GameModeSize.Y = fgDisplay.pDisplay.DisplayMode.vdisplay;
-        }
-        if (fgState.GameModeDepth == -1)
-        {
-            /* can't get color depth from this, nor can we change it, do nothing
-             * TODO: get with XGetVisualInfo()? but then how to set?
-             */
-        }
-        if (fgState.GameModeRefresh == -1)
-        {
-            /* Compute the displays refresh rate, dotclock comes in kHz. */
-            int refresh = ( fgDisplay.pDisplay.DisplayModeClock * 1000 ) /
-                ( fgDisplay.pDisplay.DisplayMode.htotal * fgDisplay.pDisplay.DisplayMode.vtotal );
-
-            fgState.GameModeRefresh = refresh;
-        }
-
-        /* query all possible display modes */
-        if( !XF86VidModeGetAllModeLines(
-                 fgDisplay.pDisplay.Display,
-                 fgDisplay.pDisplay.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.pDisplay.Display,
-                     fgDisplay.pDisplay.Screen,
-                     displayModes[ i ] ) )
-                fgWarning( "XF86VidModeSwitchToMode failed" );
-        }
-
-        XFree( displayModes );
-    }
-
-#   endif
-
-    return success;
-}
-
-
-void fgPlatformEnterGameMode( void ) 
-{
-
-    /*
-     * 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.pDisplay.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.pDisplay.Display, fgStructure.GameModeWindow->Window.Handle,
-               TRUE,
-               ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
-               | PointerMotionMask,
-               GrabModeAsync, GrabModeAsync,
-               fgStructure.GameModeWindow->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.pDisplay.Display,
-        fgStructure.GameModeWindow->Window.Handle,
-        RevertToNone,
-        CurrentTime
-    );
-
-    /* Move the Pointer to the middle of the fullscreen window */
-    XWarpPointer(
-        fgDisplay.pDisplay.Display,
-        None,
-        fgDisplay.pDisplay.RootWindow,
-        0, 0, 0, 0,
-        fgState.GameModeSize.X/2, fgState.GameModeSize.Y/2
-    );
-
-#   ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
-
-    if( fgDisplay.pDisplay.DisplayModeValid )
-    {
-        int x, y;
-        Window child;
-
-        /* Change to viewport to the window topleft edge: */
-        if( !XF86VidModeSetViewPort( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.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.pDisplay.Display,
-            fgStructure.CurrentWindow->Window.Handle,
-            fgDisplay.pDisplay.RootWindow,
-            0, 0, &x, &y,
-            &child
-        );
-
-        /* Move the decorataions out of the topleft corner of the display */
-        XMoveWindow( fgDisplay.pDisplay.Display, fgStructure.CurrentWindow->Window.Handle,
-                     -x, -y);
-    }
-
-#endif
-
-    /* Grab the keyboard, too */
-    XGrabKeyboard(
-        fgDisplay.pDisplay.Display,
-        fgStructure.GameModeWindow->Window.Handle,
-        FALSE,
-        GrabModeAsync, GrabModeAsync,
-        CurrentTime
-    );
-
-}
-
-void fgPlatformLeaveGameMode( void ) 
-{
-    XUngrabPointer( fgDisplay.pDisplay.Display, CurrentTime );
-    XUngrabKeyboard( fgDisplay.pDisplay.Display, CurrentTime );
-}
-
diff --git a/src/x11/freeglut_glutfont_definitions_x11.c b/src/x11/freeglut_glutfont_definitions_x11.c
deleted file mode 100644 (file)
index f2519c5..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * freeglut_glutfont_definitions_x11.c
- *
- * Bitmap and stroke fonts displaying.
- *
- * Copyright (c) 2003 Stephen J. Baker (whether he wants it or not).
- * All Rights Reserved.
- * Written by John F. Fay <fayjf@sourceforge.net>, who releases the
- * copyright over to the "freeglut" project lead.
- * Creation date: Mon July 21 2003
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * This file is necessary for the *nix version of "freeglut" because the
- * original GLUT defined its font variables in rather an unusual way.
- * Publicly, in "glut.h", they were defined as "void *".  Privately,
- * in one of the source code files, they were defined as pointers to a
- * structure.  Most compilers and linkers are satisfied with the "void *"
- * and don't go any farther, but some of them balked.  In particular,
- * when compiling with "freeglut" and then trying to run using the GLUT
- * ".so" library, some of them would give an error.  So we are having to
- * create this file to define the variables as pointers to an unusual
- * structure to match GLUT.
- */
-
-/*
- * freeglut_internal.h uses some GL types, but including the GL header portably
- * is a bit tricky, so we include freeglut_std.h here, which contains the
- * necessary machinery. But this poses another problem, caused by the ugly
- * original defintion of the font constants in "classic" GLUT: They are defined
- * as void* externally, so we move them temporarily out of the way by AN EXTREME
- * CPP HACK.
- */
-
-#define glutStrokeRoman glutStrokeRomanIGNOREME
-#define glutStrokeMonoRoman glutStrokeMonoRomanIGNOREME
-#define glutBitmap9By15 glutBitmap9By15IGNOREME
-#define glutBitmap8By13 glutBitmap8By13IGNOREME
-#define glutBitmapTimesRoman10 glutBitmapTimesRoman10IGNOREME
-#define glutBitmapTimesRoman24 glutBitmapTimesRoman24IGNOREME
-#define glutBitmapHelvetica10 glutBitmapHelvetica10IGNOREME
-#define glutBitmapHelvetica12 glutBitmapHelvetica12IGNOREME
-#define glutBitmapHelvetica18 glutBitmapHelvetica18IGNOREME
-
-#include <GL/freeglut_std.h>
-
-#undef glutStrokeRoman
-#undef glutStrokeMonoRoman
-#undef glutBitmap9By15
-#undef glutBitmap8By13
-#undef glutBitmapTimesRoman10
-#undef glutBitmapTimesRoman24
-#undef glutBitmapHelvetica10
-#undef glutBitmapHelvetica12
-#undef glutBitmapHelvetica18
-
-#include "../fg_internal.h"
-
-struct freeglutStrokeFont
-{
-  const char *name ;
-  int num_chars ;
-  void *ch ;
-  float top ;
-  float bottom ;
-};
-
-struct freeglutBitmapFont
-{
-  const char *name ;
-  const int num_chars ;
-  const int first ;
-  const void *ch ;
-};
-
-
-struct freeglutStrokeFont glutStrokeRoman ;
-struct freeglutStrokeFont glutStrokeMonoRoman ;
-
-struct freeglutBitmapFont glutBitmap9By15 ;
-struct freeglutBitmapFont glutBitmap8By13 ;
-struct freeglutBitmapFont glutBitmapTimesRoman10 ;
-struct freeglutBitmapFont glutBitmapTimesRoman24 ;
-struct freeglutBitmapFont glutBitmapHelvetica10 ;
-struct freeglutBitmapFont glutBitmapHelvetica12 ;
-struct freeglutBitmapFont glutBitmapHelvetica18 ;
-
diff --git a/src/x11/freeglut_init_x11.c b/src/x11/freeglut_init_x11.c
deleted file mode 100644 (file)
index 83fe287..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * freeglut_init_x11.c
- *
- * Various freeglut initialization functions.
- *
- * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
- * Written by Pawel W. Olszta, <olszta@sourceforge.net>
- * Copied for Platform code by Evan Felix <karcaw at gmail.com>
- * Creation date: Thur Feb 2 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#define FREEGLUT_BUILDING_LIB
-#include <limits.h>  /* LONG_MAX */
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-/* Return the atom associated with "name". */
-static Atom fghGetAtom(const char * name)
-{
-  return XInternAtom(fgDisplay.pDisplay.Display, name, False);
-}
-
-/*
- * Check if "property" is set on "window".  The property's values are returned
- * through "data".  If the property is set and is of type "type", return the
- * number of elements in "data".  Return zero otherwise.  In both cases, use
- * "Xfree()" to free "data".
- */
-static int fghGetWindowProperty(Window window,
-                               Atom property,
-                               Atom type,
-                               unsigned char ** data)
-{
-  /*
-   * Caller always has to use "Xfree()" to free "data", since
-   * "XGetWindowProperty() always allocates one extra byte in prop_return
-   * [i.e. "data"] (even if the property is zero length) [..]".
-   */
-
-  int status;  /*  Returned by "XGetWindowProperty". */
-
-  Atom          type_returned;
-  int           temp_format;             /*  Not used. */
-  unsigned long number_of_elements;
-  unsigned long temp_bytes_after;        /*  Not used. */
-
-
-  status = XGetWindowProperty(fgDisplay.pDisplay.Display,
-                             window,
-                             property,
-                             0,
-                             LONG_MAX,
-                             False,
-                             type,
-                             &type_returned,
-                             &temp_format,
-                             &number_of_elements,
-                             &temp_bytes_after,
-                             data);
-
-  FREEGLUT_INTERNAL_ERROR_EXIT(status == Success,
-                              "XGetWindowProperty failled",
-                              "fghGetWindowProperty");
-
-  if (type_returned != type)
-    {
-      number_of_elements = 0;
-    }
-
-  return number_of_elements;
-}
-
-/*  Check if the window manager is NET WM compliant. */
-static int fghNetWMSupported(void)
-{
-  Atom wm_check;
-  Window ** window_ptr_1;
-
-  int number_of_windows;
-  int net_wm_supported;
-
-
-  net_wm_supported = 0;
-
-  wm_check = fghGetAtom("_NET_SUPPORTING_WM_CHECK");
-  window_ptr_1 = malloc(sizeof(Window *));
-
-  /*
-   * Check that the window manager has set this property on the root window.
-   * The property must be the ID of a child window.
-   */
-  number_of_windows = fghGetWindowProperty(fgDisplay.pDisplay.RootWindow,
-                                           wm_check,
-                                           XA_WINDOW,
-                                           (unsigned char **) window_ptr_1);
-  if (number_of_windows == 1)
-    {
-      Window ** window_ptr_2;
-
-      window_ptr_2 = malloc(sizeof(Window *));
-
-      /* Check that the window has the same property set to the same value. */
-      number_of_windows = fghGetWindowProperty(**window_ptr_1,
-                                               wm_check,
-                                               XA_WINDOW,
-                                               (unsigned char **) window_ptr_2);
-      if ((number_of_windows == 1) && (**window_ptr_1 == **window_ptr_2))
-      {
-        /* NET WM compliant */
-        net_wm_supported = 1;
-      }
-
-      XFree(*window_ptr_2);
-      free(window_ptr_2);
-    }
-
-        XFree(*window_ptr_1);
-        free(window_ptr_1);
-
-        return net_wm_supported;
-}
-
-/*  Check if "hint" is present in "property" for "window". */
-int fgHintPresent(Window window, Atom property, Atom hint)
-{
-  Atom *atoms;
-  int number_of_atoms;
-  int supported;
-  int i;
-
-  supported = 0;
-
-  number_of_atoms = fghGetWindowProperty(window,
-                                        property,
-                                        XA_ATOM,
-                                        (unsigned char **) &atoms);
-  for (i = 0; i < number_of_atoms; i++)
-  {
-      if (atoms[i] == hint)
-      {
-          supported = 1;
-          break;
-      }
-  }
-
-  XFree(atoms);
-  return supported;
-}
-
-/*
- * A call to this function should initialize all the display stuff...
- */
-void fgPlatformInitialize( const char* displayName )
-{
-    fgDisplay.pDisplay.Display = XOpenDisplay( displayName );
-
-    if( fgDisplay.pDisplay.Display == NULL )
-        fgError( "failed to open display '%s'", XDisplayName( displayName ) );
-
-    if( !glXQueryExtension( fgDisplay.pDisplay.Display, NULL, NULL ) )
-        fgError( "OpenGL GLX extension not supported by display '%s'",
-            XDisplayName( displayName ) );
-
-    fgDisplay.pDisplay.Screen = DefaultScreen( fgDisplay.pDisplay.Display );
-    fgDisplay.pDisplay.RootWindow = RootWindow(
-        fgDisplay.pDisplay.Display,
-        fgDisplay.pDisplay.Screen
-    );
-
-    fgDisplay.ScreenWidth  = DisplayWidth(
-        fgDisplay.pDisplay.Display,
-        fgDisplay.pDisplay.Screen
-    );
-    fgDisplay.ScreenHeight = DisplayHeight(
-        fgDisplay.pDisplay.Display,
-        fgDisplay.pDisplay.Screen
-    );
-
-    fgDisplay.ScreenWidthMM = DisplayWidthMM(
-        fgDisplay.pDisplay.Display,
-        fgDisplay.pDisplay.Screen
-    );
-    fgDisplay.ScreenHeightMM = DisplayHeightMM(
-        fgDisplay.pDisplay.Display,
-        fgDisplay.pDisplay.Screen
-    );
-
-    fgDisplay.pDisplay.Connection = ConnectionNumber( fgDisplay.pDisplay.Display );
-
-    /* Create the window deletion atom */
-    fgDisplay.pDisplay.DeleteWindow = fghGetAtom("WM_DELETE_WINDOW");
-
-    /* Create the state and full screen atoms */
-    fgDisplay.pDisplay.State           = None;
-    fgDisplay.pDisplay.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.pDisplay.RootWindow, supported, state))
-      {
-        const Atom full_screen = fghGetAtom("_NET_WM_STATE_FULLSCREEN");
-        
-        fgDisplay.pDisplay.State = state;
-        
-        /* Check if the window manager supports full screen. */
-        /**  Check "_NET_WM_ALLOWED_ACTIONS" on our window instead? **/
-        if (fgHintPresent(fgDisplay.pDisplay.RootWindow, supported, full_screen))
-        {
-          fgDisplay.pDisplay.StateFullScreen = full_screen;
-        }
-      }
-    }
-
-
-    fgState.Initialised = GL_TRUE;
-
-    atexit(fgDeinitialize);
-
-    /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */
-    fgInitialiseInputDevices();
-}
-
-void fgPlatformDeinitialiseInputDevices ( void )
-{
-       fghCloseInputDevices ();
-
-    fgState.JoysticksInitialised = GL_FALSE;
-    fgState.InputDevsInitialised = GL_FALSE;
-}
-
-
-void fgPlatformCloseDisplay ( void )
-{
-    /*
-     * Make sure all X-client data we have created will be destroyed on
-     * display closing
-     */
-    XSetCloseDownMode( fgDisplay.pDisplay.Display, DestroyAll );
-
-    /*
-     * Close the display connection, destroying all windows we have
-     * created so far
-     */
-    XCloseDisplay( fgDisplay.pDisplay.Display );
-}
-
-
-void fgPlatformDestroyContext ( SFG_PlatformDisplay pDisplay, SFG_WindowContextType MContext )
-{
-    /* Note that the MVisualInfo is not owned by the MenuContext! */
-    glXDestroyContext( pDisplay.Display, MContext );
-}
diff --git a/src/x11/freeglut_input_devices_x11.c b/src/x11/freeglut_input_devices_x11.c
deleted file mode 100644 (file)
index a94e52a..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * freeglut_input_devices_x11.c
- *
- * Handles miscellaneous input devices via direct serial-port access.
- * Proper X11 XInput device support is not yet supported.
- * Also lacks Mac support.
- *
- * Written by Joe Krahn <krahn@niehs.nih.gov> 2005
- *
- * Copyright (c) 2005 Stephen J. Baker. All Rights Reserved.
- * Copied for Platform code by Evan Felix <karcaw at gmail.com>
- * Creation date: Thur Feb 2 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA OR STEPHEN J. BAKER BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#    include "config.h"
-#endif
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <sys/ioctl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <fcntl.h>
-
-struct _serialport {
-   int fd;
-   struct termios termio, termio_save;
-};
-
-typedef struct _serialport SERIALPORT;
-
-void serial_flush ( SERIALPORT *port );
-
-/* local variables */
-static SERIALPORT *dialbox_port=NULL;
-
-/*****************************************************************/
-
-/*
- * Try initializing the input device(s)
- */
-void fgPlatformRegisterDialDevice ( const char *dial_device )
-{
-}
-
-SERIALPORT *serial_open ( const char *device )
-{
-    int fd;
-    struct termios termio;
-    SERIALPORT *port;
-
-    fd = open(device, O_RDWR | O_NONBLOCK );
-    if (fd <0) {
-        perror(device);
-        return NULL;
-    }
-
-    port = malloc(sizeof(SERIALPORT));
-    memset(port, 0, sizeof(SERIALPORT));
-    port->fd = fd;
-
-    /* save current port settings */
-    tcgetattr(fd,&port->termio_save);
-
-    memset(&termio, 0, sizeof(termio));
-    termio.c_cflag = CS8 | CREAD | HUPCL ;
-    termio.c_iflag = IGNPAR | IGNBRK ;
-    termio.c_cc[VTIME]    = 0;   /* inter-character timer */
-    termio.c_cc[VMIN]     = 1;   /* block read until 1 chars received, when blocking I/O */
-
-    cfsetispeed(&termio, B9600);
-    cfsetospeed(&termio, B9600);
-    tcsetattr(fd,TCSANOW,&termio);
-
-    serial_flush(port);
-    return port;
-}
-
-void serial_close(SERIALPORT *port)
-{
-    if (port)
-    {
-        /* restore old port settings */
-        tcsetattr(port->fd,TCSANOW,&port->termio_save);
-        close(port->fd);
-        free(port);
-    }
-}
-
-int serial_getchar(SERIALPORT *port)
-{
-    unsigned char ch;
-    if (!port) return EOF;
-    if (read(port->fd,&ch,1)) return ch;
-    return EOF;
-}
-
-int serial_putchar(SERIALPORT *port, unsigned char ch)
-{
-    if (!port) return 0;
-    return write(port->fd,&ch,1);
-}
-
-void serial_flush ( SERIALPORT *port )
-{
-    tcflush ( port->fd, TCIOFLUSH );
-}
diff --git a/src/x11/freeglut_internal_x11.h b/src/x11/freeglut_internal_x11.h
deleted file mode 100644 (file)
index 8a8e197..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * freeglut_internal_x11.h
- *
- * The freeglut library private include file.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by Diederick C. Niehorster, <dcnieho@gmail.com>
- * Creation date: Fri Jan 20, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef  FREEGLUT_INTERNAL_X11_H
-#define  FREEGLUT_INTERNAL_X11_H
-
-
-/* -- PLATFORM-SPECIFIC INCLUDES ------------------------------------------- */
-#include <GL/glx.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-#include <X11/extensions/XInput.h>
-#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
-#    include <X11/extensions/xf86vmode.h>
-#endif
-#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
-#    include <X11/extensions/Xrandr.h>
-#endif
-/* If GLX is too old, we will fail during runtime when multisampling
-   is requested, but at least freeglut compiles. */
-#ifndef GLX_SAMPLE_BUFFERS
-#    define GLX_SAMPLE_BUFFERS 0x80A8
-#endif
-#ifndef GLX_SAMPLES
-#    define GLX_SAMPLES 0x80A9
-#endif
-
-
-
-/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */
-/* The structure used by display initialization in freeglut_init.c */
-typedef struct tagSFG_PlatformDisplay SFG_PlatformDisplay;
-struct tagSFG_PlatformDisplay
-{
-    Display*        Display;            /* The display we are being run in.  */
-    int             Screen;             /* The screen we are about to use.   */
-    Window          RootWindow;         /* The screen's root window.         */
-    int             Connection;         /* The display's connection number   */
-    Atom            DeleteWindow;       /* The window deletion atom          */
-    Atom            State;              /* The state atom                    */
-    Atom            StateFullScreen;    /* The full screen atom              */
-
-#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
-    int prev_xsz, prev_ysz;
-    int prev_refresh;
-    int prev_size_valid;
-#endif /* HAVE_X11_EXTENSIONS_XRANDR_H */
-
-#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
-    /*
-     * XF86VidMode may be compilable even if it fails at runtime.  Therefore,
-     * the validity of the VidMode has to be tracked
-     */
-    int             DisplayModeValid;   /* Flag that indicates runtime status*/
-    XF86VidModeModeLine DisplayMode;    /* Current screen's display settings */
-    int             DisplayModeClock;   /* The display mode's refresh rate   */
-    int             DisplayViewPortX;   /* saved X location of the viewport  */
-    int             DisplayViewPortY;   /* saved Y location of the viewport  */
-#endif /* HAVE_X11_EXTENSIONS_XF86VMODE_H */
-
-    int             DisplayPointerX;    /* saved X location of the pointer   */
-    int             DisplayPointerY;    /* saved Y location of the pointer   */
-};
-
-
-/*
- * Make "freeglut" window handle and context types so that we don't need so
- * much conditionally-compiled code later in the library.
- */
-typedef Window     SFG_WindowHandleType ;
-typedef GLXContext SFG_WindowContextType ;
-typedef struct tagSFG_PlatformContext SFG_PlatformContext;
-struct tagSFG_PlatformContext
-{
-    GLXFBConfig*    FBConfig;        /* The window's FBConfig               */
-};
-
-
-/* Window's state description. This structure should be kept portable. */
-typedef struct tagSFG_PlatformWindowState SFG_PlatformWindowState;
-struct tagSFG_PlatformWindowState
-{
-    int             OldWidth;           /* Window width from before a resize */
-    int             OldHeight;          /*   "    height  "    "    "   "    */
-};
-
-
-/* -- JOYSTICK-SPECIFIC STRUCTURES AND TYPES ------------------------------- */
-/*
- * Initial defines from "js.h" starting around line 33 with the existing "freeglut_joystick.c"
- * interspersed
- */
-#    ifdef HAVE_SYS_IOCTL_H
-#        include <sys/ioctl.h>
-#    endif
-#    ifdef HAVE_FCNTL_H
-#        include <fcntl.h>
-#    endif
-#    ifdef HAVE_ERRNO_H
-#        include <errno.h>
-#        include <string.h>
-#    endif
-#    if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
-/* XXX The below hack is done until freeglut's autoconf is updated. */
-#        define HAVE_USB_JS    1
-
-#        if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#            include <sys/joystick.h>
-#        else
-/*
- * XXX NetBSD/amd64 systems may find that they have to steal the
- * XXX /usr/include/machine/joystick.h from a NetBSD/i386 system.
- * XXX I cannot comment whether that works for the interface, but
- * XXX it lets you compile...(^&  I do not think that we can do away
- * XXX with this header.
- */
-#            include <machine/joystick.h>         /* For analog joysticks */
-#        endif
-#        define JS_DATA_TYPE joystick
-#        define JS_RETURN (sizeof(struct JS_DATA_TYPE))
-#    endif
-
-#    if defined(__linux__)
-#        include <linux/joystick.h>
-
-/* check the joystick driver version */
-#        if defined(JS_VERSION) && JS_VERSION >= 0x010000
-#            define JS_NEW
-#        endif
-#    else  /* Not BSD or Linux */
-#        ifndef JS_RETURN
-
-  /*
-   * We'll put these values in and that should
-   * allow the code to at least compile when there is
-   * no support. The JS open routine should error out
-   * and shut off all the code downstream anyway and if
-   * the application doesn't use a joystick we'll be fine.
-   */
-
-  struct JS_DATA_TYPE
-  {
-    int buttons;
-    int x;
-    int y;
-  };
-
-#            define JS_RETURN (sizeof(struct JS_DATA_TYPE))
-#        endif
-#    endif
-
-/* XXX It might be better to poll the operating system for the numbers of buttons and
- * XXX axes and then dynamically allocate the arrays.
- */
-#    define _JS_MAX_AXES 16
-typedef struct tagSFG_PlatformJoystick SFG_PlatformJoystick;
-struct tagSFG_PlatformJoystick
-{
-#   if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
-       struct os_specific_s *os;
-#   endif
-
-#   ifdef JS_NEW
-       struct js_event     js;
-       int          tmp_buttons;
-       float        tmp_axes [ _JS_MAX_AXES ];
-#   else
-       struct JS_DATA_TYPE js;
-#   endif
-
-    char         fname [ 128 ];
-    int          fd;
-};
-
-
-/* Menu font and color definitions */
-#define  FREEGLUT_MENU_FONT    GLUT_BITMAP_HELVETICA_18
-
-#define  FREEGLUT_MENU_PEN_FORE_COLORS   {0.0f,  0.0f,  0.0f,  1.0f}
-#define  FREEGLUT_MENU_PEN_BACK_COLORS   {0.70f, 0.70f, 0.70f, 1.0f}
-#define  FREEGLUT_MENU_PEN_HFORE_COLORS  {0.0f,  0.0f,  0.0f,  1.0f}
-#define  FREEGLUT_MENU_PEN_HBACK_COLORS  {1.0f,  1.0f,  1.0f,  1.0f}
-
-
-
-
-/* -- PRIVATE FUNCTION DECLARATIONS ---------------------------------------- */
-/* spaceball device functions, defined in freeglut_spaceball.c */
-int             fgIsSpaceballXEvent( const XEvent *ev );
-void            fgSpaceballHandleXEvent( const XEvent *ev );
-
-/*
- * Check if "hint" is present in "property" for "window".  See freeglut_init.c
- */
-int             fgHintPresent(Window window, Atom property, Atom hint);
-
-/* Handler for X extension Events */
-#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
-  void          fgHandleExtensionEvents( XEvent * ev );
-  void          fgRegisterDevices( Display* dpy, Window* win );
-#endif
-
-
-#endif  /* FREEGLUT_INTERNAL_X11_H */
diff --git a/src/x11/freeglut_joystick_x11.c b/src/x11/freeglut_joystick_x11.c
deleted file mode 100644 (file)
index 5d686b5..0000000
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * freeglut_joystick_x11.c
- *
- * Joystick handling code
- *
- * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
- * Written by Steve Baker, <sjbaker1@airmail.net>
- * Copied for Platform code by Evan Felix <karcaw at gmail.com>
- * Creation date: Thur Feb 2 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * FreeBSD port by Stephen Montgomery-Smith <stephen@math.missouri.edu>
- *
- * Redone by John Fay 2/4/04 with another look from the PLIB "js" library.
- *  Many thanks for Steve Baker for permission to pull from that library.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-#ifdef HAVE_SYS_PARAM_H
-#    include <sys/param.h>
-#endif
-
-
-/*this should be defined in a header file */
-#define MAX_NUM_JOYSTICKS  2   
-extern SFG_Joystick *fgJoystick [ MAX_NUM_JOYSTICKS ];
-
-void fgPlatformJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes )
-{
-    int status;
-
-    int i;
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
-    int len;
-
-    if ( joy->pJoystick.os->is_analog )
-    {
-        int status = read ( joy->pJoystick.os->fd, &joy->pJoystick.os->ajs, sizeof(joy->pJoystick.os->ajs) );
-        if ( status != sizeof(joy->pJoystick.os->ajs) ) {
-            perror ( joy->pJoystick.os->fname );
-            joy->error = GL_TRUE;
-            return;
-        }
-        if ( buttons != NULL )
-            *buttons = ( joy->pJoystick.os->ajs.b1 ? 1 : 0 ) | ( joy->pJoystick.os->ajs.b2 ? 2 : 0 );
-
-        if ( axes != NULL )
-        {
-            axes[0] = (float) joy->pJoystick.os->ajs.x;
-            axes[1] = (float) joy->pJoystick.os->ajs.y;
-        }
-
-        return;
-    }
-
-#  ifdef HAVE_USB_JS
-    while ( ( len = read ( joy->pJoystick.os->fd, joy->pJoystick.os->hid_data_buf, joy->pJoystick.os->hid_dlen ) ) == joy->pJoystick.os->hid_dlen )
-    {
-        struct hid_item *h;
-
-        for  ( h = joy->pJoystick.os->hids; h; h = h->next )
-        {
-            int d = hid_get_data ( joy->pJoystick.os->hid_data_buf, h );
-
-            int page = HID_PAGE ( h->usage );
-            int usage = HID_USAGE ( h->usage );
-
-            if ( page == HUP_GENERIC_DESKTOP )
-            {
-                int i;
-                for ( i = 0; i < joy->num_axes; i++ )
-                    if (joy->pJoystick.os->axes_usage[i] == usage)
-                    {
-                        if (usage == HUG_HAT_SWITCH)
-                        {
-                            if (d < 0 || d > 8)
-                                d = 0;  /* safety */
-                            joy->pJoystick.os->cache_axes[i] = (float)hatmap_x[d];
-                            joy->pJoystick.os->cache_axes[i + 1] = (float)hatmap_y[d];
-                        }
-                        else
-                        {
-                            joy->pJoystick.os->cache_axes[i] = (float)d;
-                        }
-                        break;
-                    }
-            }
-            else if (page == HUP_BUTTON)
-            {
-               if (usage > 0 && usage < _JS_MAX_BUTTONS + 1)
-               {
-                   if (d)
-                       joy->pJoystick.os->cache_buttons |=  (1 << ( usage - 1 ));
-                   else
-                       joy->pJoystick.os->cache_buttons &= ~(1 << ( usage - 1 ));
-               }
-            }
-        }
-    }
-#    ifdef HAVE_ERRNO_H
-    if ( len < 0 && errno != EAGAIN )
-#    else
-    if ( len < 0 )
-#    endif
-    {
-        perror( joy->pJoystick.os->fname );
-        joy->error = 1;
-    }
-    if ( buttons != NULL ) *buttons = joy->pJoystick.os->cache_buttons;
-    if ( axes    != NULL )
-        memcpy ( axes, joy->pJoystick.os->cache_axes, sizeof(float) * joy->num_axes );
-#  endif
-#endif
-
-#ifdef JS_NEW
-
-    while ( 1 )
-    {
-        status = read ( joy->pJoystick.fd, &joy->pJoystick.js, sizeof(struct js_event) );
-
-        if ( status != sizeof( struct js_event ) )
-        {
-#  ifdef HAVE_ERRNO_H
-            if ( errno == EAGAIN )
-            {
-                /* Use the old values */
-                if ( buttons )
-                    *buttons = joy->pJoystick.tmp_buttons;
-                if ( axes )
-                    memcpy( axes, joy->pJoystick.tmp_axes,
-                            sizeof( float ) * joy->num_axes );
-                return;
-            }
-#  endif
-
-            fgWarning ( "%s", joy->pJoystick.fname );
-            joy->error = GL_TRUE;
-            return;
-        }
-
-        switch ( joy->pJoystick.js.type & ~JS_EVENT_INIT )
-        {
-        case JS_EVENT_BUTTON:
-            if( joy->pJoystick.js.value == 0 ) /* clear the flag */
-                joy->pJoystick.tmp_buttons &= ~( 1 << joy->pJoystick.js.number );
-            else
-                joy->pJoystick.tmp_buttons |= ( 1 << joy->pJoystick.js.number );
-            break;
-
-        case JS_EVENT_AXIS:
-            if ( joy->pJoystick.js.number < joy->num_axes )
-            {
-                joy->pJoystick.tmp_axes[ joy->pJoystick.js.number ] = ( float )joy->pJoystick.js.value;
-
-                if( axes )
-                    memcpy( axes, joy->pJoystick.tmp_axes, sizeof(float) * joy->num_axes );
-            }
-            break;
-
-        default:
-            fgWarning ( "PLIB_JS: Unrecognised /dev/js return!?!" );
-
-            /* use the old values */
-
-            if ( buttons != NULL ) *buttons = joy->pJoystick.tmp_buttons;
-            if ( axes    != NULL )
-                memcpy ( axes, joy->pJoystick.tmp_axes, sizeof(float) * joy->num_axes );
-
-            return;
-        }
-
-        if( buttons )
-            *buttons = joy->pJoystick.tmp_buttons;
-    }
-#else
-
-    status = read( joy->pJoystick.fd, &joy->pJoystick.js, JS_RETURN );
-
-    if ( status != JS_RETURN )
-    {
-        fgWarning( "%s", joy->pJoystick.fname );
-        joy->error = GL_TRUE;
-        return;
-    }
-
-    if ( buttons )
-#    if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )
-        *buttons = ( joy->pJoystick.js.b1 ? 1 : 0 ) | ( joy->pJoystick.js.b2 ? 2 : 0 );  /* XXX Should not be here -- BSD is handled earlier */
-#    else
-        *buttons = joy->pJoystick.js.buttons;
-#    endif
-
-    if ( axes )
-    {
-        axes[ 0 ] = (float) joy->pJoystick.js.x;
-        axes[ 1 ] = (float) joy->pJoystick.js.y;
-    }
-#endif
-}
-
-
-void fgPlatformJoystickOpen( SFG_Joystick* joy )
-{
-#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )
-       int i = 0;
-       char *cp;
-#endif
-#ifdef JS_NEW
-       unsigned char u;
-       int i=0;
-#else
-#  if defined( __linux__ ) || TARGET_HOST_SOLARIS
-       int i = 0;
-    int counter = 0;
-#  endif
-#endif
-
-#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )
-    for( i = 0; i < _JS_MAX_AXES; i++ )
-        joy->pJoystick.os->cache_axes[ i ] = 0.0f;
-
-    joy->pJoystick.os->cache_buttons = 0;
-
-    joy->pJoystick.os->fd = open( joy->pJoystick.os->fname, O_RDONLY | O_NONBLOCK);
-
-#ifdef HAVE_ERRNO_H
-    if( joy->pJoystick.os->fd < 0 && errno == EACCES )
-        fgWarning ( "%s exists but is not readable by you", joy->pJoystick.os->fname );
-#endif
-
-    joy->error =( joy->pJoystick.os->fd < 0 );
-
-    if( joy->error )
-        return;
-
-    joy->num_axes = 0;
-    joy->num_buttons = 0;
-    if( joy->pJoystick.os->is_analog )
-    {
-        FILE *joyfile;
-        char joyfname[ 1024 ];
-        int noargs, in_no_axes;
-
-        float axes [ _JS_MAX_AXES ];
-        int buttons[ _JS_MAX_AXES ];
-
-        joy->num_axes    =  2;
-        joy->num_buttons = 32;
-
-        fghJoystickRawRead( joy, buttons, axes );
-        joy->error = axes[ 0 ] < -1000000000.0f;
-        if( joy->error )
-            return;
-
-        snprintf( joyfname, sizeof(joyfname), "%s/.joy%drc", getenv( "HOME" ), joy->id );
-
-        joyfile = fopen( joyfname, "r" );
-        joy->error =( joyfile == NULL );
-        if( joy->error )
-            return;
-
-        noargs = fscanf( joyfile, "%d%f%f%f%f%f%f", &in_no_axes,
-                         &joy->min[ 0 ], &joy->center[ 0 ], &joy->max[ 0 ],
-                         &joy->min[ 1 ], &joy->center[ 1 ], &joy->max[ 1 ] );
-        joy->error = noargs != 7 || in_no_axes != _JS_MAX_AXES;
-        fclose( joyfile );
-        if( joy->error )
-            return;
-
-        for( i = 0; i < _JS_MAX_AXES; i++ )
-        {
-            joy->dead_band[ i ] = 0.0f;
-            joy->saturate [ i ] = 1.0f;
-        }
-
-        return;    /* End of analog code */
-    }
-
-#    ifdef HAVE_USB_JS
-    if( ! fghJoystickInitializeHID( joy->pJoystick.os, &joy->num_axes,
-                                    &joy->num_buttons ) )
-    {
-        close( joy->pJoystick.os->fd );
-        joy->error = GL_TRUE;
-        return;
-    }
-
-    cp = strrchr( joy->pJoystick.os->fname, '/' );
-    if( cp )
-    {
-        if( fghJoystickFindUSBdev( &cp[1], joy->name, sizeof( joy->name ) ) ==
-            0 )
-            strcpy( joy->name, &cp[1] );
-    }
-
-    if( joy->num_axes > _JS_MAX_AXES )
-        joy->num_axes = _JS_MAX_AXES;
-
-    for( i = 0; i < _JS_MAX_AXES; i++ )
-    {
-        /* We really should get this from the HID, but that data seems
-         * to be quite unreliable for analog-to-USB converters. Punt for
-         * now.
-         */
-        if( joy->pJoystick.os->axes_usage[ i ] == HUG_HAT_SWITCH )
-        {
-            joy->max   [ i ] = 1.0f;
-            joy->center[ i ] = 0.0f;
-            joy->min   [ i ] = -1.0f;
-        }
-        else
-        {
-            joy->max   [ i ] = 255.0f;
-            joy->center[ i ] = 127.0f;
-            joy->min   [ i ] = 0.0f;
-        }
-
-        joy->dead_band[ i ] = 0.0f;
-        joy->saturate[ i ] = 1.0f;
-    }
-#    endif
-#endif
-
-#if defined( __linux__ ) || TARGET_HOST_SOLARIS
-    /* Default for older Linux systems. */
-    joy->num_axes    =  2;
-    joy->num_buttons = 32;
-
-#    ifdef JS_NEW
-    for( i = 0; i < _JS_MAX_AXES; i++ )
-        joy->pJoystick.tmp_axes[ i ] = 0.0f;
-
-    joy->pJoystick.tmp_buttons = 0;
-#    endif
-
-    joy->pJoystick.fd = open( joy->pJoystick.fname, O_RDONLY );
-
-    joy->error =( joy->pJoystick.fd < 0 );
-
-    if( joy->error )
-        return;
-
-    /* Set the correct number of axes for the linux driver */
-#    ifdef JS_NEW
-    /* Melchior Franz's fixes for big-endian Linuxes since writing
-     *  to the upper byte of an uninitialized word doesn't work.
-     *  9 April 2003
-     */
-    ioctl( joy->pJoystick.fd, JSIOCGAXES, &u );
-    joy->num_axes = u;
-    ioctl( joy->pJoystick.fd, JSIOCGBUTTONS, &u );
-    joy->num_buttons = u;
-    ioctl( joy->pJoystick.fd, JSIOCGNAME( sizeof( joy->name ) ), joy->name );
-    fcntl( joy->pJoystick.fd, F_SETFL, O_NONBLOCK );
-#    endif
-
-    /*
-     * The Linux driver seems to return 512 for all axes
-     * when no stick is present - but there is a chance
-     * that could happen by accident - so it's gotta happen
-     * on both axes for at least 100 attempts.
-     *
-     * PWO: shouldn't be that done somehow wiser on the kernel level?
-     */
-#    ifndef JS_NEW
-    counter = 0;
-
-    do
-    {
-        fghJoystickRawRead( joy, NULL, joy->center );
-        counter++;
-    } while( !joy->error &&
-             counter < 100 &&
-             joy->center[ 0 ] == 512.0f &&
-             joy->center[ 1 ] == 512.0f );
-
-    if ( counter >= 100 )
-        joy->error = GL_TRUE;
-#    endif
-
-    for( i = 0; i < _JS_MAX_AXES; i++ )
-    {
-#    ifdef JS_NEW
-        joy->max   [ i ] =  32767.0f;
-        joy->center[ i ] =      0.0f;
-        joy->min   [ i ] = -32767.0f;
-#    else
-        joy->max[ i ] = joy->center[ i ] * 2.0f;
-        joy->min[ i ] = 0.0f;
-#    endif
-        joy->dead_band[ i ] = 0.0f;
-        joy->saturate [ i ] = 1.0f;
-    }
-#endif
-}
-
-
-void fgPlatformJoystickInit( SFG_Joystick *fgJoystick[], int ident )
-{
-#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )
-    fgJoystick[ ident ]->id = ident;
-    fgJoystick[ ident ]->error = GL_FALSE;
-
-    fgJoystick[ ident ]->pJoystick.os = calloc( 1, sizeof( struct os_specific_s ) );
-    memset( fgJoystick[ ident ]->pJoystick.os, 0, sizeof( struct os_specific_s ) );
-    if( ident < USB_IDENT_OFFSET )
-        fgJoystick[ ident ]->pJoystick.os->is_analog = 1;
-    if( fgJoystick[ ident ]->pJoystick.os->is_analog )
-        snprintf( fgJoystick[ ident ]->pJoystick.os->fname, sizeof(fgJoystick[ ident ]->pJoystick.os->fname), "%s%d", AJSDEV, ident );
-    else
-        snprintf( fgJoystick[ ident ]->pJoystick.os->fname, sizeof(fgJoystick[ ident ]->pJoystick.os->fname), "%s%d", UHIDDEV,
-                 ident - USB_IDENT_OFFSET );
-#elif defined( __linux__ )
-    fgJoystick[ ident ]->id = ident;
-    fgJoystick[ ident ]->error = GL_FALSE;
-
-    snprintf( fgJoystick[ident]->pJoystick.fname, sizeof(fgJoystick[ident]->pJoystick.fname), "/dev/input/js%d", ident );
-
-    if( access( fgJoystick[ ident ]->pJoystick.fname, F_OK ) != 0 )
-        snprintf( fgJoystick[ ident ]->pJoystick.fname, sizeof(fgJoystick[ ident ]->pJoystick.fname), "/dev/js%d", ident );
-#endif
-}
-
-
-void fgPlatformJoystickClose ( int ident )
-{
-#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )
-    if( fgJoystick[ident]->pJoystick.os )
-    {
-        if( ! fgJoystick[ ident ]->error )
-            close( fgJoystick[ ident ]->pJoystick.os->fd );
-#ifdef HAVE_USB_JS
-        if( fgJoystick[ ident ]->pJoystick.os->hids )
-            free (fgJoystick[ ident ]->pJoystick.os->hids);
-        if( fgJoystick[ ident ]->pJoystick.os->hid_data_buf )
-            free( fgJoystick[ ident ]->pJoystick.os->hid_data_buf );
-#endif
-        free( fgJoystick[ident]->pJoystick.os );
-       }
-#endif
-
-    if( ! fgJoystick[ident]->error )
-         close( fgJoystick[ ident ]->pJoystick.fd );
-}
-
diff --git a/src/x11/freeglut_main_x11.c b/src/x11/freeglut_main_x11.c
deleted file mode 100644 (file)
index e72db37..0000000
+++ /dev/null
@@ -1,1083 +0,0 @@
-/*
- * freeglut_main_x11.c
- *
- * The X11-specific windows message processing methods.
- *
- * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
- * Written by Pawel W. Olszta, <olszta@sourceforge.net>
- * Copied for Platform code by Evan Felix <karcaw at gmail.com>
- * Creation date: Thur Feb 2 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-#ifdef HAVE_ERRNO_H
-#    include <errno.h>
-#endif
-#include <stdarg.h>
-#ifdef  HAVE_VFPRINTF
-#    define VFPRINTF(s,f,a) vfprintf((s),(f),(a))
-#elif defined(HAVE__DOPRNT)
-#    define VFPRINTF(s,f,a) _doprnt((f),(a),(s))
-#else
-#    define VFPRINTF(s,f,a)
-#endif
-
-/*
- * Try to get the maximum value allowed for ints, falling back to the minimum
- * guaranteed by ISO C99 if there is no suitable header.
- */
-#ifdef HAVE_LIMITS_H
-#    include <limits.h>
-#endif
-#ifndef INT_MAX
-#    define INT_MAX 32767
-#endif
-
-#ifndef MIN
-#    define MIN(a,b) (((a)<(b)) ? (a) : (b))
-#endif
-
-/*
- * TODO BEFORE THE STABLE RELEASE:
- *
- * There are some issues concerning window redrawing under X11, and maybe
- * some events are not handled. The Win32 version lacks some more features,
- * but seems acceptable for not demanding purposes.
- *
- * Need to investigate why the X11 version breaks out with an error when
- * closing a window (using the window manager, not glutDestroyWindow)...
- */
-/*
- * Handle a window configuration change. When no reshape
- * callback is hooked, the viewport size is updated to
- * match the new window size.
- */
-void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height )
-{
-    XResizeWindow( fgDisplay.pDisplay.Display, window->Window.Handle,
-                   width, height );
-    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
-}
-
-
-/*
- * A static helper function to execute display callback for a window
- */
-void fgPlatformDisplayWindow ( SFG_Window *window )
-{
-        fghRedrawWindow ( window ) ;
-}
-
-
-fg_time_t fgPlatformSystemTime ( void )
-{
-#ifdef CLOCK_MONOTONIC
-    struct timespec now;
-    clock_gettime(CLOCK_MONOTONIC, &now);
-    return now.tv_nsec/1000000 + now.tv_sec*1000;
-#elif defined(HAVE_GETTIMEOFDAY)
-    struct timeval now;
-    gettimeofday( &now, NULL );
-    return now.tv_usec/1000 + now.tv_sec*1000;
-#endif
-}
-
-/*
- * Does the magic required to relinquish the CPU until something interesting
- * happens.
- */
-
-void fgPlatformSleepForEvents( fg_time_t msec )
-{
-    /*
-     * Possibly due to aggressive use of XFlush() and friends,
-     * it is possible to have our socket drained but still have
-     * unprocessed events.  (Or, this may just be normal with
-     * X, anyway?)  We do non-trivial processing of X events
-     * after the event-reading loop, in any case, so we
-     * need to allow that we may have an empty socket but non-
-     * empty event queue.
-     */
-    if( ! XPending( fgDisplay.pDisplay.Display ) )
-    {
-        fd_set fdset;
-        int err;
-        int socket;
-        struct timeval wait;
-
-        socket = ConnectionNumber( fgDisplay.pDisplay.Display );
-        FD_ZERO( &fdset );
-        FD_SET( socket, &fdset );
-        wait.tv_sec = msec / 1000;
-        wait.tv_usec = (msec % 1000) * 1000;
-        err = select( socket+1, &fdset, NULL, NULL, &wait );
-
-#ifdef HAVE_ERRNO_H
-        if( ( -1 == err ) && ( errno != EINTR ) )
-            fgWarning ( "freeglut select() error: %d", errno );
-#endif
-    }
-}
-
-
-/*
- * Returns GLUT modifier mask for the state field of an X11 event.
- */
-int fgPlatformGetModifiers( int state )
-{
-    int ret = 0;
-
-    if( state & ( ShiftMask | LockMask ) )
-        ret |= GLUT_ACTIVE_SHIFT;
-    if( state & ControlMask )
-        ret |= GLUT_ACTIVE_CTRL;
-    if( state & Mod1Mask )
-        ret |= GLUT_ACTIVE_ALT;
-
-    return ret;
-}
-
-static const char* fghTypeToString( int type )
-{
-    switch( type ) {
-    case KeyPress: return "KeyPress";
-    case KeyRelease: return "KeyRelease";
-    case ButtonPress: return "ButtonPress";
-    case ButtonRelease: return "ButtonRelease";
-    case MotionNotify: return "MotionNotify";
-    case EnterNotify: return "EnterNotify";
-    case LeaveNotify: return "LeaveNotify";
-    case FocusIn: return "FocusIn";
-    case FocusOut: return "FocusOut";
-    case KeymapNotify: return "KeymapNotify";
-    case Expose: return "Expose";
-    case GraphicsExpose: return "GraphicsExpose";
-    case NoExpose: return "NoExpose";
-    case VisibilityNotify: return "VisibilityNotify";
-    case CreateNotify: return "CreateNotify";
-    case DestroyNotify: return "DestroyNotify";
-    case UnmapNotify: return "UnmapNotify";
-    case MapNotify: return "MapNotify";
-    case MapRequest: return "MapRequest";
-    case ReparentNotify: return "ReparentNotify";
-    case ConfigureNotify: return "ConfigureNotify";
-    case ConfigureRequest: return "ConfigureRequest";
-    case GravityNotify: return "GravityNotify";
-    case ResizeRequest: return "ResizeRequest";
-    case CirculateNotify: return "CirculateNotify";
-    case CirculateRequest: return "CirculateRequest";
-    case PropertyNotify: return "PropertyNotify";
-    case SelectionClear: return "SelectionClear";
-    case SelectionRequest: return "SelectionRequest";
-    case SelectionNotify: return "SelectionNotify";
-    case ColormapNotify: return "ColormapNotify";
-    case ClientMessage: return "ClientMessage";
-    case MappingNotify: return "MappingNotify";
-    default: return "UNKNOWN";
-    }
-}
-
-static const char* fghBoolToString( Bool b )
-{
-    return b == False ? "False" : "True";
-}
-
-static const char* fghNotifyHintToString( char is_hint )
-{
-    switch( is_hint ) {
-    case NotifyNormal: return "NotifyNormal";
-    case NotifyHint: return "NotifyHint";
-    default: return "UNKNOWN";
-    }
-}
-
-static const char* fghNotifyModeToString( int mode )
-{
-    switch( mode ) {
-    case NotifyNormal: return "NotifyNormal";
-    case NotifyGrab: return "NotifyGrab";
-    case NotifyUngrab: return "NotifyUngrab";
-    case NotifyWhileGrabbed: return "NotifyWhileGrabbed";
-    default: return "UNKNOWN";
-    }
-}
-
-static const char* fghNotifyDetailToString( int detail )
-{
-    switch( detail ) {
-    case NotifyAncestor: return "NotifyAncestor";
-    case NotifyVirtual: return "NotifyVirtual";
-    case NotifyInferior: return "NotifyInferior";
-    case NotifyNonlinear: return "NotifyNonlinear";
-    case NotifyNonlinearVirtual: return "NotifyNonlinearVirtual";
-    case NotifyPointer: return "NotifyPointer";
-    case NotifyPointerRoot: return "NotifyPointerRoot";
-    case NotifyDetailNone: return "NotifyDetailNone";
-    default: return "UNKNOWN";
-    }
-}
-
-static const char* fghVisibilityToString( int state ) {
-    switch( state ) {
-    case VisibilityUnobscured: return "VisibilityUnobscured";
-    case VisibilityPartiallyObscured: return "VisibilityPartiallyObscured";
-    case VisibilityFullyObscured: return "VisibilityFullyObscured";
-    default: return "UNKNOWN";
-    }
-}
-
-static const char* fghConfigureDetailToString( int detail )
-{
-    switch( detail ) {
-    case Above: return "Above";
-    case Below: return "Below";
-    case TopIf: return "TopIf";
-    case BottomIf: return "BottomIf";
-    case Opposite: return "Opposite";
-    default: return "UNKNOWN";
-    }
-}
-
-static const char* fghPlaceToString( int place )
-{
-    switch( place ) {
-    case PlaceOnTop: return "PlaceOnTop";
-    case PlaceOnBottom: return "PlaceOnBottom";
-    default: return "UNKNOWN";
-    }
-}
-
-static const char* fghMappingRequestToString( int request )
-{
-    switch( request ) {
-    case MappingModifier: return "MappingModifier";
-    case MappingKeyboard: return "MappingKeyboard";
-    case MappingPointer: return "MappingPointer";
-    default: return "UNKNOWN";
-    }
-}
-
-static const char* fghPropertyStateToString( int state )
-{
-    switch( state ) {
-    case PropertyNewValue: return "PropertyNewValue";
-    case PropertyDelete: return "PropertyDelete";
-    default: return "UNKNOWN";
-    }
-}
-
-static const char* fghColormapStateToString( int state )
-{
-    switch( state ) {
-    case ColormapUninstalled: return "ColormapUninstalled";
-    case ColormapInstalled: return "ColormapInstalled";
-    default: return "UNKNOWN";
-    }
-}
-
-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;
-    }
-    }
-}
-
-
-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(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;
-                if( event.type == CreateNotify ) {
-                    GETWINDOW( xcreatewindow );
-                    width = event.xcreatewindow.width;
-                    height = event.xcreatewindow.height;
-                } else {
-                    GETWINDOW( xconfigure );
-                    width = event.xconfigure.width;
-                    height = event.xconfigure.height;
-                }
-
-                if( ( width != window->State.pWState.OldWidth ) ||
-                    ( height != window->State.pWState.OldHeight ) )
-                {
-                    SFG_Window *current_window = fgStructure.CurrentWindow;
-
-                    window->State.pWState.OldWidth = width;
-                    window->State.pWState.OldHeight = height;
-                    if( FETCH_WCB( *window, Reshape ) )
-                        INVOKE_WCB( *window, Reshape, ( width, height ) );
-                    else
-                    {
-                        fgSetWindow( window );
-                        glViewport( 0, 0, width, height );
-                    }
-                    glutPostRedisplay( );
-                    if( window->IsMenu )
-                        fgSetWindow( current_window );
-                }
-            }
-            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.Redisplay = GL_TRUE;
-            }
-            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:
-        {
-            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_root, event.xbutton.y_root ) )
-                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.KeyRepeating = GL_TRUE;
-                        else
-                            window->State.KeyRepeating = GL_FALSE;
-                    }
-                }
-            }
-            else
-                window->State.KeyRepeating = GL_FALSE;
-
-            /* Cease processing this event if it is auto repeated */
-
-            if (window->State.KeyRepeating)
-            {
-                if (event.type == KeyPress) window->State.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;
-                    }
-                }
-            }
-        }
-        break;
-
-        case ReparentNotify:
-            break; /* XXX Should disable this event */
-
-        /* Not handled */
-        case GravityNotify:
-            break;
-
-        default:
-            /* enter handling of Extension Events here */
-            #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
-                fgHandleExtensionEvents( &event );
-            #endif
-            break;
-        }
-    }
-}
-
-
-void fgPlatformMainLoopPreliminaryWork ( void )
-{
-}
-
diff --git a/src/x11/freeglut_menu_x11.c b/src/x11/freeglut_menu_x11.c
deleted file mode 100644 (file)
index 0443dcd..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * freeglut_menu_x11.c
- *
- * Pull-down menu creation and handling.
- *
- * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
- * Written by Pawel W. Olszta, <olszta@sourceforge.net>
- * Copied for Platform code by Evan Felix <karcaw at gmail.com>
- * Creation date: Wed Feb 1, 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-/*
- *  * Private function to get the virtual maximum screen extent
- *   */
-GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y )
-{
-    int wx, wy;
-    Window w;
-
-    XTranslateCoordinates(
-        fgDisplay.pDisplay.Display,
-        window->Window.Handle,
-        fgDisplay.pDisplay.RootWindow,
-        0, 0, &wx, &wy, &w);
-
-    *x = fgState.GameModeSize.X + wx;
-    *y = fgState.GameModeSize.Y + wy;
-}
-
diff --git a/src/x11/freeglut_spaceball_x11.c b/src/x11/freeglut_spaceball_x11.c
deleted file mode 100644 (file)
index 582a926..0000000
+++ /dev/null
@@ -1,415 +0,0 @@
-/* Spaceball support for Linux.
- * Written by John Tsiombikas <nuclear@member.fsf.org>
- * Copied for Platform code by Evan Felix <karcaw at gmail.com>
- * Creation date: Thur Feb 2 2012
- *
- * This code supports 3Dconnexion's 6-dof space-whatever devices.
- * It can communicate with either the proprietary 3Dconnexion daemon (3dxsrv)
- * free spacenavd (http://spacenav.sourceforge.net), through the "standard"
- * magellan X-based protocol.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-#include <X11/Xlib.h>
-
-extern int sball_initialized;
-
-enum {
-    SPNAV_EVENT_ANY,  /* used by spnav_remove_events() */
-    SPNAV_EVENT_MOTION,
-    SPNAV_EVENT_BUTTON  /* includes both press and release */
-};
-
-struct spnav_event_motion {
-    int type;
-    int x, y, z;
-    int rx, ry, rz;
-    unsigned int period;
-    int *data;
-};
-
-struct spnav_event_button {
-    int type;
-    int press;
-    int bnum;
-};
-
-typedef union spnav_event {
-    int type;
-    struct spnav_event_motion motion;
-    struct spnav_event_button button;
-} spnav_event;
-
-
-static int spnav_x11_open(Display *dpy, Window win);
-static int spnav_x11_window(Window win);
-static int spnav_x11_event(const XEvent *xev, spnav_event *event);
-static int spnav_close(void);
-static int spnav_fd(void);
-static int spnav_remove_events(int type);
-
-static SFG_Window *spnav_win;
-
-void fgPlatformInitializeSpaceball(void)
-{
-    Window w;
-
-    sball_initialized = 1;
-    if(!fgStructure.CurrentWindow)
-    {
-        sball_initialized = -1;
-        return;
-    }
-
-    w = fgStructure.CurrentWindow->Window.Handle;
-    if(spnav_x11_open(fgDisplay.pDisplay.Display, w) == -1)
-    {
-        sball_initialized = -1;
-        return;
-    }
-}
-
-void fgPlatformSpaceballClose(void) 
-{
-    spnav_close();
-}
-
-int fgPlatformHasSpaceball(void) 
-{
-    /* 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;
-}
-
-int fgPlatformSpaceballNumButtons(void) {
-    return 2;
-}
-
-void fgPlatformSpaceballSetWindow(SFG_Window *window) 
-{
-       if(spnav_win != window) {
-        spnav_x11_window(window->Window.Handle);
-        spnav_win = window;
-    }
-}
-
-int fgIsSpaceballXEvent(const XEvent *xev)
-{
-    spnav_event sev;
-
-    if(spnav_win != fgStructure.CurrentWindow) {
-        /* this will also initialize spaceball if needed (first call) */
-        fgSpaceballSetWindow(fgStructure.CurrentWindow);
-    }
-
-    if(sball_initialized != 1) {
-        return 0;
-    }
-
-    return spnav_x11_event(xev, &sev);
-}
-
-void fgSpaceballHandleXEvent(const XEvent *xev)
-{
-    spnav_event sev;
-
-    if(sball_initialized == 0) {
-        fgInitialiseSpaceball();
-        if(sball_initialized != 1) {
-            return;
-        }
-    }
-
-    if(spnav_x11_event(xev, &sev)) {
-        switch(sev.type) {
-        case SPNAV_EVENT_MOTION:
-            if(sev.motion.x | sev.motion.y | sev.motion.z) {
-                INVOKE_WCB(*spnav_win, SpaceMotion, (sev.motion.x, sev.motion.y, sev.motion.z));
-            }
-            if(sev.motion.rx | sev.motion.ry | sev.motion.rz) {
-                INVOKE_WCB(*spnav_win, SpaceRotation, (sev.motion.rx, sev.motion.ry, sev.motion.rz));
-            }
-            spnav_remove_events(SPNAV_EVENT_MOTION);
-            break;
-
-        case SPNAV_EVENT_BUTTON:
-            INVOKE_WCB(*spnav_win, SpaceButton, (sev.button.bnum, sev.button.press ? GLUT_DOWN : GLUT_UP));
-            break;
-
-        default:
-            break;
-        }
-    }
-}
-
-/*
-The following code is part of libspnav, part of the spacenav project (spacenav.sf.net)
-Copyright (C) 2007-2009 John Tsiombikas <nuclear@member.fsf.org>
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
-   list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
-   derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-static Window get_daemon_window(Display *dpy);
-static int catch_badwin(Display *dpy, XErrorEvent *err);
-
-static Display *dpy;
-static Window app_win;
-static Atom motion_event, button_press_event, button_release_event, command_event;
-
-enum {
-  CMD_APP_WINDOW = 27695,
-  CMD_APP_SENS
-};
-
-#define IS_OPEN    dpy
-
-struct event_node {
-  spnav_event event;
-  struct event_node *next;
-};
-
-static int spnav_x11_open(Display *display, Window win)
-{
-  if(IS_OPEN) {
-    return -1;
-  }
-
-  dpy = display;
-
-  motion_event = XInternAtom(dpy, "MotionEvent", True);
-  button_press_event = XInternAtom(dpy, "ButtonPressEvent", True);
-  button_release_event = XInternAtom(dpy, "ButtonReleaseEvent", True);
-  command_event = XInternAtom(dpy, "CommandEvent", True);
-
-  if(!motion_event || !button_press_event || !button_release_event || !command_event) {
-    dpy = 0;
-    return -1;  /* daemon not started */
-  }
-
-  if(spnav_x11_window(win) == -1) {
-    dpy = 0;
-    return -1;  /* daemon not started */
-  }
-
-  app_win = win;
-  return 0;
-}
-
-static int spnav_close(void)
-{
-  if(dpy) {
-    spnav_x11_window(DefaultRootWindow(dpy));
-    app_win = 0;
-    dpy = 0;
-    return 0;
-  }
-  return -1;
-}
-
-static int spnav_x11_window(Window win)
-{
-  int (*prev_xerr_handler)(Display*, XErrorEvent*);
-  XEvent xev;
-  Window daemon_win;
-
-  if(!IS_OPEN) {
-    return -1;
-  }
-
-  if(!(daemon_win = get_daemon_window(dpy))) {
-    return -1;
-  }
-
-  prev_xerr_handler = XSetErrorHandler(catch_badwin);
-
-  xev.type = ClientMessage;
-  xev.xclient.send_event = False;
-  xev.xclient.display = dpy;
-  xev.xclient.window = win;
-  xev.xclient.message_type = command_event;
-  xev.xclient.format = 16;
-  xev.xclient.data.s[0] = ((unsigned int)win & 0xffff0000) >> 16;
-  xev.xclient.data.s[1] = (unsigned int)win & 0xffff;
-  xev.xclient.data.s[2] = CMD_APP_WINDOW;
-
-  XSendEvent(dpy, daemon_win, False, 0, &xev);
-  XSync(dpy, False);
-
-  XSetErrorHandler(prev_xerr_handler);
-  return 0;
-}
-
-static int spnav_fd(void)
-{
-  if(dpy) {
-    return ConnectionNumber(dpy);
-  }
-  return -1;
-}
-
-/*static int spnav_wait_event(spnav_event *event)
-{
-  if(dpy) {
-    for(;;) {
-      XEvent xev;
-      XNextEvent(dpy, &xev);
-
-      if(spnav_x11_event(&xev, event) > 0) {
-        return event->type;
-      }
-    }
-  }
-  return 0;
-}
-
-static int spnav_poll_event(spnav_event *event)
-{
-  if(dpy) {
-    if(XPending(dpy)) {
-      XEvent xev;
-      XNextEvent(dpy, &xev);
-
-      return spnav_x11_event(&xev, event);
-    }
-  }
-  return 0;
-}*/
-
-static Bool match_events(Display *dpy, XEvent *xev, char *arg)
-{
-  int evtype = *(int*)arg;
-
-  if(xev->type != ClientMessage) {
-    return False;
-  }
-
-  if(xev->xclient.message_type == motion_event) {
-    return !evtype || evtype == SPNAV_EVENT_MOTION ? True : False;
-  }
-  if(xev->xclient.message_type == button_press_event ||
-      xev->xclient.message_type == button_release_event) {
-    return !evtype || evtype == SPNAV_EVENT_BUTTON ? True : False;
-  }
-  return False;
-}
-
-static int spnav_remove_events(int type)
-{
-  int rm_count = 0;
-
-  if(dpy) {
-    XEvent xev;
-
-    while(XCheckIfEvent(dpy, &xev, match_events, (char*)&type)) {
-      rm_count++;
-    }
-    return rm_count;
-  }
-  return 0;
-}
-
-static int spnav_x11_event(const XEvent *xev, spnav_event *event)
-{
-  int i;
-  int xmsg_type;
-
-  if(xev->type != ClientMessage) {
-    return 0;
-  }
-
-  xmsg_type = xev->xclient.message_type;
-
-  if(xmsg_type != motion_event && xmsg_type != button_press_event &&
-      xmsg_type != button_release_event) {
-    return 0;
-  }
-
-  if(xmsg_type == motion_event) {
-    event->type = SPNAV_EVENT_MOTION;
-    event->motion.data = &event->motion.x;
-
-    for(i=0; i<6; i++) {
-      event->motion.data[i] = xev->xclient.data.s[i + 2];
-    }
-    event->motion.period = xev->xclient.data.s[8];
-  } else {
-    event->type = SPNAV_EVENT_BUTTON;
-    event->button.press = xmsg_type == button_press_event ? 1 : 0;
-    event->button.bnum = xev->xclient.data.s[2];
-  }
-  return event->type;
-}
-
-
-static Window get_daemon_window(Display *dpy)
-{
-  Window win, root_win;
-  XTextProperty wname;
-  Atom type;
-  int fmt;
-  unsigned long nitems, bytes_after;
-  unsigned char *prop;
-
-  root_win = DefaultRootWindow(dpy);
-
-  XGetWindowProperty(dpy, root_win, command_event, 0, 1, False, AnyPropertyType, &type, &fmt, &nitems, &bytes_after, &prop);
-  if(!prop) {
-    return 0;
-  }
-
-  win = *(Window*)prop;
-  XFree(prop);
-
-  if(!XGetWMName(dpy, win, &wname) || strcmp("Magellan Window", (char*)wname.value) != 0) {
-    return 0;
-  }
-
-  return win;
-}
-
-static int catch_badwin(Display *dpy, XErrorEvent *err)
-{
-  char buf[256];
-
-  if(err->error_code == BadWindow) {
-    /* do nothing? */
-  } else {
-    XGetErrorText(dpy, err->error_code, buf, sizeof buf);
-    fprintf(stderr, "Caught unexpected X error: %s\n", buf);
-  }
-  return 0;
-}
-
diff --git a/src/x11/freeglut_state_x11.c b/src/x11/freeglut_state_x11.c
deleted file mode 100644 (file)
index 3523477..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * freeglut_state_x11.c
- *
- * X11-specific freeglut state query methods.
- *
- * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
- * Written by John F. Fay, <fayjf@sourceforge.net>
- * Creation date: Sat Feb 4 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-/*
- * TODO BEFORE THE STABLE RELEASE:
- *
- *  fgPlatformChooseFBConfig()      -- OK, but what about glutInitDisplayString()?
- */
-
-/* A helper function to check if a display mode is possible to use */
-GLXFBConfig* fgPlatformChooseFBConfig( int* numcfgs );
-
-/*
- * Queries the GL context about some attributes
- */
-int fgPlatformGetConfig( int attribute )
-{
-  int returnValue = 0;
-  int result;  /*  Not checked  */
-
-  if( fgStructure.CurrentWindow )
-      result = glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
-                                     *(fgStructure.CurrentWindow->Window.pContext.FBConfig),
-                                     attribute,
-                                     &returnValue );
-
-  return returnValue;
-}
-
-int fgPlatformGlutGet ( GLenum eWhat )
-{
-    int nsamples = 0;
-
-    switch( eWhat )
-    {
-    /*
-     * The window/context specific queries are handled mostly by
-     * fgPlatformGetConfig().
-     */
-    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 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
-
-    /* Colormap size is handled in a bit different way than all the rest */
-    case GLUT_WINDOW_COLORMAP_SIZE:
-        if( (fgPlatformGetConfig( 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.pContext.FBConfig;
-
-          XVisualInfo * visualInfo =
-                glXGetVisualFromFBConfig( fgDisplay.pDisplay.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.pDisplay.Display,
-            fgStructure.CurrentWindow->Window.Handle,
-            fgDisplay.pDisplay.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.pDisplay.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.pDisplay.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 fgPlatformChooseFBConfig again here.  */
-        GLXFBConfig * fbconfig;
-        int isPossible;
-
-        fbconfig = fgPlatformChooseFBConfig(NULL);
-
-        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 fgPlatformGetConfig( GLX_VISUAL_ID );
-
-    default:
-        fgWarning( "glutGet(): missing enum handle %d", eWhat );
-        break;
-    }
-
-       return -1;
-}
-
-
-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;
-}
-
-
-int *fgPlatformGlutGetModeValues(GLenum eWhat, int *size)
-{
-  int *array;
-
-  int attributes[9];
-  GLXFBConfig * fbconfigArray;  /*  Array of FBConfigs  */
-  int fbconfigArraySize;        /*  Number of FBConfigs in the array  */
-  int attribute_name = 0;
-
-  array = NULL;
-  *size = 0;
-
-  switch (eWhat)
-    {
-    case GLUT_AUX:
-    case GLUT_MULTISAMPLE:
-
-      attributes[0] = GLX_BUFFER_SIZE;
-      attributes[1] = GLX_DONT_CARE;
-
-      switch (eWhat)
-        {
-        case GLUT_AUX:
-          /*
-            FBConfigs are now sorted by increasing number of auxiliary
-            buffers.  We want at least one buffer.
-          */
-          attributes[2] = GLX_AUX_BUFFERS;
-          attributes[3] = 1;
-          attributes[4] = None;
-
-          attribute_name = GLX_AUX_BUFFERS;
-
-          break;
-
-
-        case GLUT_MULTISAMPLE:
-          attributes[2] = GLX_AUX_BUFFERS;
-          attributes[3] = GLX_DONT_CARE;
-          attributes[4] = GLX_SAMPLE_BUFFERS;
-          attributes[5] = 1;
-          /*
-            FBConfigs are now sorted by increasing number of samples per
-            pixel.  We want at least one sample.
-          */
-          attributes[6] = GLX_SAMPLES;
-          attributes[7] = 1;
-          attributes[8] = None;
-
-          attribute_name = GLX_SAMPLES;
-
-          break;
-        }
-
-      fbconfigArray = glXChooseFBConfig(fgDisplay.pDisplay.Display,
-                                        fgDisplay.pDisplay.Screen,
-                                        attributes,
-                                        &fbconfigArraySize);
-
-      if (fbconfigArray != NULL)
-        {
-          int * temp_array;
-          int result;   /*  Returned by glXGetFBConfigAttrib. Not checked.  */
-          int previous_value;
-          int i;
-
-          temp_array = malloc(sizeof(int) * fbconfigArraySize);
-          previous_value = 0;
-
-          for (i = 0; i < fbconfigArraySize; i++)
-            {
-              int value;
-
-              result = glXGetFBConfigAttrib(fgDisplay.pDisplay.Display,
-                                            fbconfigArray[i],
-                                            attribute_name,
-                                            &value);
-              if (value > previous_value)
-                {
-                  temp_array[*size] = value;
-                  previous_value = value;
-                  (*size)++;
-                }
-            }
-
-          array = malloc(sizeof(int) * (*size));
-          for (i = 0; i < *size; i++)
-            {
-              array[i] = temp_array[i];
-            }
-
-          free(temp_array);
-          XFree(fbconfigArray);
-        }
-
-      break;
-
-    default:
-      break;
-    }
-
-  return array;
-}
-
-
diff --git a/src/x11/freeglut_structure_x11.c b/src/x11/freeglut_structure_x11.c
deleted file mode 100644 (file)
index cbc9129..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * freeglut_structure.c
- *
- * Windows and menus need tree structure
- *
- * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
- * Written by Pawel W. Olszta, <olszta@sourceforge.net>
- * Copied for Platform code by Evan Felix <karcaw at gmail.com>
- * Creation date: Thur Feb 2 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-extern SFG_Structure fgStructure;
-
-void fgPlatformCreateWindow ( SFG_Window *window )
-{
-    window->Window.pContext.FBConfig = NULL;
-
-    window->State.pWState.OldHeight = window->State.pWState.OldWidth = -1;
-}
-
diff --git a/src/x11/freeglut_window_x11.c b/src/x11/freeglut_window_x11.c
deleted file mode 100644 (file)
index 44c9952..0000000
+++ /dev/null
@@ -1,800 +0,0 @@
-/*
- * freeglut_window_x11.c
- *
- * Window management methods for X11
- *
- * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
- * Written by Pawel W. Olszta, <olszta@sourceforge.net>
- * Copied for Platform code by Evan Felix <karcaw at gmail.com>
- * Creation date: Thur Feb 2 2012
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#define FREEGLUT_BUILDING_LIB
-#include <GL/freeglut.h>
-#include <limits.h>  /* LONG_MAX */
-#include <unistd.h>  /* usleep */
-#include "../fg_internal.h"
-
-/* pushing attribute/value pairs into an array */
-#define ATTRIB(a) attributes[where++]=(a)
-#define ATTRIB_VAL(a,v) {ATTRIB(a); ATTRIB(v);}
-
-
-#ifndef GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB
-#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
-#endif
-
-#ifndef GLX_CONTEXT_MAJOR_VERSION_ARB
-#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#endif
-
-#ifndef GLX_CONTEXT_MINOR_VERSION_ARB
-#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
-#endif
-
-#ifndef GLX_CONTEXT_FLAGS_ARB
-#define GLX_CONTEXT_FLAGS_ARB 0x2094
-#endif
-
-#ifndef GLX_CONTEXT_PROFILE_MASK_ARB
-#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
-#endif
-
-#ifndef GLX_CONTEXT_DEBUG_BIT_ARB
-#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001
-#endif
-
-#ifndef GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
-#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
-#endif
-
-#ifndef GLX_CONTEXT_CORE_PROFILE_BIT_ARB
-#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
-#endif
-
-#ifndef GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
-#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
-#endif
-
-#ifndef GLX_RGBA_FLOAT_TYPE
-#define GLX_RGBA_FLOAT_TYPE 0x20B9
-#endif
-
-#ifndef GLX_RGBA_FLOAT_BIT
-#define GLX_RGBA_FLOAT_BIT 0x00000004
-#endif
-
-
-/*
- * Chooses a visual basing on the current display mode settings
- */
-
-GLXFBConfig* fgPlatformChooseFBConfig( int *numcfgs )
-{
-  GLboolean wantIndexedMode = GL_FALSE;
-  int attributes[ 100 ];
-  int where = 0, numAuxBuffers;
-
-  /* First we have to process the display mode settings... */
-  if( fgState.DisplayMode & GLUT_INDEX ) {
-    ATTRIB_VAL( GLX_BUFFER_SIZE, 8 );
-    /*  Buffer size is selected later.  */
-
-    ATTRIB_VAL( GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT );
-    wantIndexedMode = GL_TRUE;
-  } else {
-    ATTRIB_VAL( GLX_RED_SIZE,   1 );
-    ATTRIB_VAL( GLX_GREEN_SIZE, 1 );
-    ATTRIB_VAL( GLX_BLUE_SIZE,  1 );
-    if( fgState.DisplayMode & GLUT_ALPHA ) {
-      ATTRIB_VAL( GLX_ALPHA_SIZE, 1 );
-    }
-  }
-
-  if( fgState.DisplayMode & GLUT_DOUBLE ) {
-    ATTRIB_VAL( GLX_DOUBLEBUFFER, True );
-  }
-
-  if( fgState.DisplayMode & GLUT_STEREO ) {
-    ATTRIB_VAL( GLX_STEREO, True );
-  }
-
-  if( fgState.DisplayMode & GLUT_DEPTH ) {
-    ATTRIB_VAL( GLX_DEPTH_SIZE, 1 );
-  }
-
-  if( fgState.DisplayMode & GLUT_STENCIL ) {
-    ATTRIB_VAL( GLX_STENCIL_SIZE, 1 );
-  }
-
-  if( fgState.DisplayMode & GLUT_ACCUM ) {
-    ATTRIB_VAL( GLX_ACCUM_RED_SIZE, 1 );
-    ATTRIB_VAL( GLX_ACCUM_GREEN_SIZE, 1 );
-    ATTRIB_VAL( GLX_ACCUM_BLUE_SIZE, 1 );
-    if( fgState.DisplayMode & GLUT_ALPHA ) {
-      ATTRIB_VAL( GLX_ACCUM_ALPHA_SIZE, 1 );
-    }
-  }
-
-  numAuxBuffers = fghNumberOfAuxBuffersRequested();
-  if ( numAuxBuffers > 0 ) {
-    ATTRIB_VAL( GLX_AUX_BUFFERS, numAuxBuffers );
-  }
-
-  if( fgState.DisplayMode & GLUT_SRGB ) {
-    ATTRIB_VAL( GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, True );
-  }
-
-  if (fgState.DisplayMode & GLUT_MULTISAMPLE) {
-    ATTRIB_VAL(GLX_SAMPLE_BUFFERS, 1);
-    ATTRIB_VAL(GLX_SAMPLES, fgState.SampleNumber);
-  }
-
-  /* Push a terminator at the end of the list */
-  ATTRIB( None );
-
-    {
-        GLXFBConfig * fbconfigArray;  /*  Array of FBConfigs  */
-        GLXFBConfig * fbconfig;       /*  The FBConfig we want  */
-        int fbconfigArraySize;        /*  Number of FBConfigs in the array  */
-
-
-        /*  Get all FBConfigs that match "attributes".  */
-        fbconfigArray = glXChooseFBConfig( fgDisplay.pDisplay.Display,
-                                           fgDisplay.pDisplay.Screen,
-                                           attributes,
-                                           &fbconfigArraySize );
-
-        if (fbconfigArray != NULL)
-        {
-            int result;  /* Returned by glXGetFBConfigAttrib, not checked. */
-
-
-            if( wantIndexedMode )
-            {
-                /*
-                 * In index mode, we want the largest buffer size, i.e. visual
-                 * depth.  Here, FBConfigs are sorted by increasing buffer size
-                 * first, so FBConfigs with the largest size come last.
-                 */
-
-                int bufferSizeMin, bufferSizeMax;
-
-                /*  Get bufferSizeMin.  */
-                result =
-                  glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
-                                        fbconfigArray[0],
-                                        GLX_BUFFER_SIZE,
-                                        &bufferSizeMin );
-                /*  Get bufferSizeMax.  */
-                result =
-                  glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
-                                        fbconfigArray[fbconfigArraySize - 1],
-                                        GLX_BUFFER_SIZE,
-                                        &bufferSizeMax );
-
-                if (bufferSizeMax > bufferSizeMin)
-                {
-                    /* 
-                     * Free and reallocate fbconfigArray, keeping only FBConfigs
-                     * with the largest buffer size.
-                     */
-                    XFree(fbconfigArray);
-
-                    /*  Add buffer size token at the end of the list.  */
-                    where--;
-                    ATTRIB_VAL( GLX_BUFFER_SIZE, bufferSizeMax );
-                    ATTRIB( None );
-
-                    fbconfigArray = glXChooseFBConfig( fgDisplay.pDisplay.Display,
-                                                       fgDisplay.pDisplay.Screen,
-                                                       attributes,
-                                                       &fbconfigArraySize );
-                }
-            }
-
-            /*
-             * We now have an array of FBConfigs, the first one being the "best"
-             * one.  So we should return only this FBConfig:
-             *
-             * int fbconfigXID;
-             *
-             *  - pick the XID of the FBConfig we want
-             * result = glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
-             *                                fbconfigArray[0],
-             *                                GLX_FBCONFIG_ID,
-             *                                &fbconfigXID );
-             *
-             * - free the array
-             * XFree(fbconfigArray);
-             *
-             * - reset "attributes" with the XID
-             * where = 0;
-             * ATTRIB_VAL( GLX_FBCONFIG_ID, fbconfigXID );
-             * ATTRIB( None );
-             *
-             * - get our FBConfig only
-             * fbconfig = glXChooseFBConfig( fgDisplay.pDisplay.Display,
-             *                               fgDisplay.pDisplay.Screen,
-             *                               attributes,
-             *                               &fbconfigArraySize );
-             *
-             * However, for some configurations (for instance multisampling with
-             * Mesa 6.5.2 and ATI drivers), this does not work:
-             * glXChooseFBConfig returns NULL, whereas fbconfigXID is a valid
-             * XID.  Further investigation is needed.
-             *
-             * So, for now, we return the whole array of FBConfigs.  This should
-             * not produce any side effects elsewhere.
-             */
-            fbconfig = fbconfigArray;
-        }
-        else
-        {
-           fbconfig = NULL;
-        }
-
-       if (numcfgs)
-               *numcfgs = fbconfigArraySize;
-
-        return fbconfig;
-    }
-}
-
-
-static void fghFillContextAttributes( int *attributes ) {
-  int where = 0, contextFlags, contextProfile;
-
-  if ( !fghIsLegacyContextVersionRequested() ) {
-    ATTRIB_VAL( GLX_CONTEXT_MAJOR_VERSION_ARB, fgState.MajorVersion );
-    ATTRIB_VAL( GLX_CONTEXT_MINOR_VERSION_ARB, fgState.MinorVersion );
-  }
-
-  contextFlags =
-    fghMapBit( fgState.ContextFlags, GLUT_DEBUG, GLX_CONTEXT_DEBUG_BIT_ARB ) |
-    fghMapBit( fgState.ContextFlags, GLUT_FORWARD_COMPATIBLE, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB );
-  if ( contextFlags != 0 ) {
-    ATTRIB_VAL( GLX_CONTEXT_FLAGS_ARB, contextFlags );
-  }
-
-  contextProfile =
-    fghMapBit( fgState.ContextProfile, GLUT_CORE_PROFILE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB ) |
-    fghMapBit( fgState.ContextProfile, GLUT_COMPATIBILITY_PROFILE, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB );
-  if ( contextProfile != 0 ) {
-    ATTRIB_VAL( GLX_CONTEXT_PROFILE_MASK_ARB, contextProfile );
-  }
-
-  ATTRIB( 0 );
-}
-
-typedef GLXContext (*CreateContextAttribsProc)(Display *dpy, GLXFBConfig config,
-                                              GLXContext share_list, Bool direct,
-                                              const int *attrib_list);
-
-static GLXContext fghCreateNewContext( SFG_Window* window )
-{
-  /* for color model calculation */
-  int menu = ( window->IsMenu && !fgStructure.MenuContext );
-  int index_mode = ( fgState.DisplayMode & GLUT_INDEX );
-
-  /* "classic" context creation */
-  Display *dpy = fgDisplay.pDisplay.Display;
-  GLXFBConfig config = *(window->Window.pContext.FBConfig);
-  int render_type = ( !menu && index_mode ) ? GLX_COLOR_INDEX_TYPE : GLX_RGBA_TYPE;
-  GLXContext share_list = NULL;
-  Bool direct = ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT );
-  GLXContext context;
-
-  /* new context creation */
-  int attributes[9];
-  CreateContextAttribsProc createContextAttribs = (CreateContextAttribsProc) fgPlatformGetProcAddress( "glXCreateContextAttribsARB" );
-  /* glXCreateContextAttribsARB not found, yet the user has requested the new context creation */
-  if ( !createContextAttribs && !fghIsLegacyContextRequested() ) {
-    fgWarning( "OpenGL >2.1 context requested but glXCreateContextAttribsARB is not available! Falling back to legacy context creation" );
-       fgState.MajorVersion = 2;
-       fgState.MinorVersion = 1;
-  }
-
-  /* If nothing fancy has been required, simply use the old context creation GLX API entry */
-  if ( fghIsLegacyContextRequested() || !createContextAttribs )
-  {
-    context = glXCreateNewContext( dpy, config, render_type, share_list, direct );
-    if ( context == NULL ) {
-      fghContextCreationError();
-    }
-    return context;
-  }
-
-  /* color index mode is not available anymore with OpenGL 3.0 */
-  if ( render_type == GLX_COLOR_INDEX_TYPE ) {
-    fgWarning( "color index mode is deprecated, using RGBA mode" );
-  }
-
-  fghFillContextAttributes( attributes );
-
-  context = createContextAttribs( dpy, config, share_list, direct, attributes );
-  if ( context == NULL ) {
-    fghContextCreationError();
-  }
-  return context;
-}
-
-
-#define _NET_WM_STATE_TOGGLE    2
-static int fghResizeFullscrToggle(void)
-{
-    XWindowAttributes attributes;
-
-    if(glutGet(GLUT_FULL_SCREEN)) {
-        /* restore original window size */
-        SFG_Window *win = fgStructure.CurrentWindow;
-        fgStructure.CurrentWindow->State.NeedToResize = GL_TRUE;
-        fgStructure.CurrentWindow->State.Width  = win->State.pWState.OldWidth;
-        fgStructure.CurrentWindow->State.Height = win->State.pWState.OldHeight;
-
-    } else {
-        /* resize the window to cover the entire screen */
-        XGetWindowAttributes(fgDisplay.pDisplay.Display,
-                fgStructure.CurrentWindow->Window.Handle,
-                &attributes);
-        
-        /*
-         * The "x" and "y" members of "attributes" are the window's coordinates
-         * relative to its parent, i.e. to the decoration window.
-         */
-        XMoveResizeWindow(fgDisplay.pDisplay.Display,
-                fgStructure.CurrentWindow->Window.Handle,
-                -attributes.x,
-                -attributes.y,
-                fgDisplay.ScreenWidth,
-                fgDisplay.ScreenHeight);
-    }
-    return 0;
-}
-
-static int fghEwmhFullscrToggle(void)
-{
-    XEvent xev;
-    long evmask = SubstructureRedirectMask | SubstructureNotifyMask;
-
-    if(!fgDisplay.pDisplay.State || !fgDisplay.pDisplay.StateFullScreen) {
-        return -1;
-    }
-
-    xev.type = ClientMessage;
-    xev.xclient.window = fgStructure.CurrentWindow->Window.Handle;
-    xev.xclient.message_type = fgDisplay.pDisplay.State;
-    xev.xclient.format = 32;
-    xev.xclient.data.l[0] = _NET_WM_STATE_TOGGLE;
-    xev.xclient.data.l[1] = fgDisplay.pDisplay.StateFullScreen;
-    xev.xclient.data.l[2] = 0; /* no second property to toggle */
-    xev.xclient.data.l[3] = 1; /* source indication: application */
-    xev.xclient.data.l[4] = 0; /* unused */
-
-    if(!XSendEvent(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow, 0, evmask, &xev)) {
-        return -1;
-    }
-    return 0;
-}
-
-static int fghToggleFullscreen(void)
-{
-    /* first try the EWMH (_NET_WM_STATE) method ... */
-    if(fghEwmhFullscrToggle() != -1) {
-        return 0;
-    }
-
-    /* fall back to resizing the window */
-    if(fghResizeFullscrToggle() != -1) {
-        return 0;
-    }
-    return -1;
-}
-
-void fgPlatformSetWindow ( SFG_Window *window )
-{
-    if ( window )
-    {
-        glXMakeContextCurrent(
-            fgDisplay.pDisplay.Display,
-            window->Window.Handle,
-            window->Window.Handle,
-            window->Window.Context
-        );
-    }
-}
-
-static Bool fghWindowIsVisible( Display *display, XEvent *event, XPointer arg)
-{
-    Window window = (Window)arg;
-    return (event->type == MapNotify) && (event->xmap.window == window);
-}
-
-/*
- * Opens a window. Requires a SFG_Window object created and attached
- * to the freeglut structure. OpenGL context is created here.
- */
-void fgPlatformOpenWindow( SFG_Window* window, const char* title,
-                           GLboolean positionUse, int x, int y,
-                           GLboolean sizeUse, int w, int h,
-                           GLboolean gameMode, GLboolean isSubWindow )
-{
-    XVisualInfo * visualInfo = NULL;
-    XSetWindowAttributes winAttr;
-    XTextProperty textProperty;
-    XSizeHints sizeHints;
-    XWMHints wmHints;
-    XEvent eventReturnBuffer; /* return buffer required for a call */
-    unsigned long mask;
-    int num_FBConfigs, i;
-    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.pContext.FBConfig = fgPlatformChooseFBConfig( &num_FBConfigs );
-
-    if( window->IsMenu && ( ! fgStructure.MenuContext ) )
-        fgState.DisplayMode = current_DisplayMode ;
-
-    if( ! window->Window.pContext.FBConfig )
-    {
-        /*
-         * The "fgPlatformChooseFBConfig" 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.pContext.FBConfig = fgPlatformChooseFBConfig( &num_FBConfigs );
-            fgState.DisplayMode &= ~GLUT_DOUBLE;
-        }
-
-        if( fgState.DisplayMode & GLUT_MULTISAMPLE )
-        {
-            fgState.DisplayMode &= ~GLUT_MULTISAMPLE ;
-            window->Window.pContext.FBConfig = fgPlatformChooseFBConfig( &num_FBConfigs );
-            fgState.DisplayMode |= GLUT_MULTISAMPLE;
-        }
-    }
-
-    FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.pContext.FBConfig != NULL,
-                                  "FBConfig with necessary capabilities not found", "fgOpenWindow" );
-
-    /*  Get the X visual.  */
-    for (i = 0; i < num_FBConfigs; i++) {
-           visualInfo = glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display,
-                                                  window->Window.pContext.FBConfig[i] );
-           if (visualInfo)
-               break;
-    }
-
-    FREEGLUT_INTERNAL_ERROR_EXIT( visualInfo != NULL,
-                                  "visualInfo could not be retrieved from FBConfig", "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.pDisplay.Display, fgDisplay.pDisplay.RootWindow,
-        visualInfo->visual, AllocNone
-    );
-
-    mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
-
-    if( window->IsMenu || ( gameMode == GL_TRUE ) )
-    {
-        winAttr.override_redirect = True;
-        mask |= CWOverrideRedirect;
-    }
-
-    if( ! positionUse )
-        x = y = -1; /* default window position */
-    if( ! sizeUse )
-        w = h = 300; /* default window size */
-
-    window->Window.Handle = XCreateWindow(
-        fgDisplay.pDisplay.Display,
-        window->Parent == NULL ? fgDisplay.pDisplay.RootWindow :
-        window->Parent->Window.Handle,
-        x, y, w, h, 0,
-        visualInfo->depth, InputOutput,
-        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->MContext = fghCreateNewContext( window );
-        }
-
-        /* window->Window.Context = fgStructure.MenuContext->MContext; */
-        window->Window.Context = fghCreateNewContext( window );
-    }
-    else if( fgState.UseCurrentContext )
-    {
-        window->Window.Context = glXGetCurrentContext( );
-
-        if( ! window->Window.Context )
-            window->Window.Context = fghCreateNewContext( window );
-    }
-    else
-        window->Window.Context = fghCreateNewContext( window );
-
-#if !defined( __FreeBSD__ ) && !defined( __NetBSD__ )
-    if(  !glXIsDirect( fgDisplay.pDisplay.Display, window->Window.Context ) )
-    {
-      if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT )
-        fgError( "Unable to force direct context rendering for window '%s'",
-                 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 ( positionUse )
-        sizeHints.flags |= USPosition;
-    if ( sizeUse )
-        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.pDisplay.Display,
-        window->Window.Handle,
-        &textProperty,
-        &textProperty,
-        0,
-        0,
-        &sizeHints,
-        &wmHints,
-        NULL
-    );
-    XFree( textProperty.value );
-
-    XSetWMProtocols( fgDisplay.pDisplay.Display, window->Window.Handle,
-                     &fgDisplay.pDisplay.DeleteWindow, 1 );
-
-    glXMakeContextCurrent(
-        fgDisplay.pDisplay.Display,
-        window->Window.Handle,
-        window->Window.Handle,
-        window->Window.Context
-    );
-
-    /* register extension events _before_ window is mapped */
-    #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
-       fgRegisterDevices( fgDisplay.pDisplay.Display, &(window->Window.Handle) );
-    #endif
-
-    XMapWindow( fgDisplay.pDisplay.Display, window->Window.Handle );
-
-    XFree(visualInfo);
-
-    if( !isSubWindow)
-        XPeekIfEvent( fgDisplay.pDisplay.Display, &eventReturnBuffer, &fghWindowIsVisible, (XPointer)(window->Window.Handle) );
-}
-
-
-/*
- * Closes a window, destroying the frame and OpenGL context
- */
-void fgPlatformCloseWindow( SFG_Window* window )
-{
-    if( window->Window.Context )
-        glXDestroyContext( fgDisplay.pDisplay.Display, window->Window.Context );
-    XFree( window->Window.pContext.FBConfig );
-
-    if( window->Window.Handle ) {
-        XDestroyWindow( fgDisplay.pDisplay.Display, window->Window.Handle );
-    }
-    /* XFlush( fgDisplay.pDisplay.Display ); */ /* XXX Shouldn't need this */
-}
-
-
-/*
- * This function makes the current window visible
- */
-void fgPlatformGlutShowWindow( void )
-{
-    XMapWindow( fgDisplay.pDisplay.Display, fgStructure.CurrentWindow->Window.Handle );
-    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
-}
-
-/*
- * This function hides the current window
- */
-void fgPlatformGlutHideWindow( void )
-{
-    if( fgStructure.CurrentWindow->Parent == NULL )
-        XWithdrawWindow( fgDisplay.pDisplay.Display,
-                         fgStructure.CurrentWindow->Window.Handle,
-                         fgDisplay.pDisplay.Screen );
-    else
-        XUnmapWindow( fgDisplay.pDisplay.Display,
-                      fgStructure.CurrentWindow->Window.Handle );
-    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
-}
-
-/*
- * Iconify the current window (top-level windows only)
- */
-void fgPlatformGlutIconifyWindow( void )
-{
-    XIconifyWindow( fgDisplay.pDisplay.Display, fgStructure.CurrentWindow->Window.Handle,
-                    fgDisplay.pDisplay.Screen );
-    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
-}
-
-/*
- * Set the current window's title
- */
-void fgPlatformGlutSetWindowTitle( const char* title )
-{
-    XTextProperty text;
-
-    text.value = (unsigned char *) title;
-    text.encoding = XA_STRING;
-    text.format = 8;
-    text.nitems = strlen( title );
-
-    XSetWMName(
-        fgDisplay.pDisplay.Display,
-        fgStructure.CurrentWindow->Window.Handle,
-        &text
-    );
-
-    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
-}
-
-/*
- * Set the current window's iconified title
- */
-void fgPlatformGlutSetIconTitle( const char* title )
-{
-    XTextProperty text;
-
-    text.value = (unsigned char *) title;
-    text.encoding = XA_STRING;
-    text.format = 8;
-    text.nitems = strlen( title );
-
-    XSetWMIconName(
-        fgDisplay.pDisplay.Display,
-        fgStructure.CurrentWindow->Window.Handle,
-        &text
-    );
-
-    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
-}
-
-/*
- * Change the current window's position
- */
-void fgPlatformGlutPositionWindow( int x, int y )
-{
-    XMoveWindow( fgDisplay.pDisplay.Display, fgStructure.CurrentWindow->Window.Handle,
-                 x, y );
-    XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
-}
-
-/*
- * Lowers the current window (by Z order change)
- */
-void fgPlatformGlutPushWindow( void )
-{
-    XLowerWindow( fgDisplay.pDisplay.Display, fgStructure.CurrentWindow->Window.Handle );
-}
-
-/*
- * Raises the current window (by Z order change)
- */
-void fgPlatformGlutPopWindow( void )
-{
-    XRaiseWindow( fgDisplay.pDisplay.Display, fgStructure.CurrentWindow->Window.Handle );
-}
-
-/*
- * Resize the current window so that it fits the whole screen
- */
-void fgPlatformGlutFullScreen( SFG_Window *win )
-{
-    if(!glutGet(GLUT_FULL_SCREEN)) {
-        if(fghToggleFullscreen() != -1) {
-            win->State.IsFullscreen = GL_TRUE;
-        }
-    }
-}
-
-/*
- * If we are fullscreen, resize the current window back to its original size
- */
-void fgPlatformGlutLeaveFullScreen( SFG_Window *win )
-{
-    if(glutGet(GLUT_FULL_SCREEN)) {
-        if(fghToggleFullscreen() != -1) {
-            win->State.IsFullscreen = GL_FALSE;
-        }
-    }
-}
-
-/*
- * Toggle the window's full screen state.
- */
-void fgPlatformGlutFullScreenToggle( SFG_Window *win )
-{
-    if(fghToggleFullscreen() != -1) {
-        win->State.IsFullscreen = !win->State.IsFullscreen;
-    }
-}
-
diff --git a/src/x11/freeglut_xinput_x11.c b/src/x11/freeglut_xinput_x11.c
deleted file mode 100644 (file)
index fac1bf7..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/* Written for XI1 by Nikolas Doerfler <doerflen@in.tum.de> (c) 2008 *
- * Rewritten for XI2 by Florian Echtler <echtler@in.tum.de> (c) 2009 */
-
-#include <GL/freeglut.h>
-
-#include "../fg_internal.h"
-
-#if HAVE_X11_EXTENSIONS_XINPUT2_H
-
-#include <errno.h>
-#include <stdarg.h>
-
-#include <X11/Xlib.h>
-#include <X11/extensions/XInput2.h>
-
-/* import function from freeglut_main.c */
-extern int fgPlatformGetModifiers( int state );
-
-/* extension opcode for XInput */
-int xi_opcode = -1;
-
-/**
- * \brief Sets window up for XI2 events.
- */
-void fgRegisterDevices( Display* dpy, Window* win ) {
-
-       XIEventMask mask;
-       unsigned char flags[2] = { 0, 0 };
-       int event, error;
-
-       /*Display* dpy = fgDisplay.pDisplay.Display;
-       Window* win = glutGetXWindow();*/
-
-       /* get XInput extension opcode */
-       if (!XQueryExtension( dpy, "XInputExtension", &xi_opcode, &event, &error )) { xi_opcode = -1; }
-
-       /* Select for motion events */
-       mask.deviceid = XIAllMasterDevices;
-       mask.mask_len = 2;
-       mask.mask = flags;
-
-       XISetMask(mask.mask, XI_Enter);
-       XISetMask(mask.mask, XI_Motion);
-       XISetMask(mask.mask, XI_ButtonPress);
-       XISetMask(mask.mask, XI_ButtonRelease);
-       XISetMask(mask.mask, XI_Leave);
-       /*XISetMask(mask.mask, XI_KeyPress);
-       XISetMask(mask.mask, XI_KeyRelease);
-       XISetMask(mask.mask, XI_DeviceChanged);
-       XISetMask(mask.mask, XI_RawEvent);
-       XISetMask(mask.mask, XI_FocusIn);
-       XISetMask(mask.mask, XI_FocusOut);
-       XISetMask(mask.mask, XI_HierarchyChanged);*/
-
-       XISelectEvents( dpy, *win, &mask, 1 );
-}
-
-
-void fgPrintXILeaveEvent(XILeaveEvent* event)
-{
-    char* mode = "";
-               char* detail = "";
-    int i;
-
-    printf("    windows: root 0x%lx event 0x%lx child 0x%ld\n",
-            event->root, event->event, event->child);
-    switch(event->mode)
-    {
-        case NotifyNormal:       mode = "NotifyNormal"; break;
-        case NotifyGrab:         mode = "NotifyGrab"; break;
-        case NotifyUngrab:       mode = "NotifyUngrab"; break;
-        case NotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break;
-    }
-    switch (event->detail)
-    {
-        case NotifyAncestor: detail = "NotifyAncestor"; break;
-        case NotifyVirtual: detail = "NotifyVirtual"; break;
-        case NotifyInferior: detail = "NotifyInferior"; break;
-        case NotifyNonlinear: detail = "NotifyNonlinear"; break;
-        case NotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break;
-        case NotifyPointer: detail = "NotifyPointer"; break;
-        case NotifyPointerRoot: detail = "NotifyPointerRoot"; break;
-        case NotifyDetailNone: detail = "NotifyDetailNone"; break;
-    }
-    printf("    mode: %s (detail %s)\n", mode, detail);
-    printf("    flags: %s %s\n", event->focus ? "[focus]" : "",
-                                 event->same_screen ? "[same screen]" : "");
-    printf("    buttons:");
-    for (i = 0; i < event->buttons.mask_len * 8; i++)
-        if (XIMaskIsSet(event->buttons.mask, i))
-            printf(" %d", i);
-    printf("\n");
-
-    printf("    modifiers: locked 0x%x latched 0x%x base 0x%x\n",
-            event->mods.locked, event->mods.latched,
-            event->mods.base);
-    printf("    group: locked 0x%x latched 0x%x base 0x%x\n",
-            event->group.locked, event->group.latched,
-            event->group.base);
-
-    printf("    root x/y:  %.2f / %.2f\n", event->root_x, event->root_y);
-    printf("    event x/y: %.2f / %.2f\n", event->event_x, event->event_y);
-
-}
-
-
-void fgPrintXIDeviceEvent(XIDeviceEvent* event)
-{
-    double *val;
-    int i;
-
-    printf("    device: %d (%d)\n", event->deviceid, event->sourceid);
-    printf("    detail: %d\n", event->detail);
-    printf("    buttons:");
-         for (i = 0; i < event->buttons.mask_len * 8; i++)
-           if (XIMaskIsSet(event->buttons.mask, i))
-             printf(" %d", i);
-    printf("\n");
-
-    printf("    modifiers: locked 0x%x latched 0x%x base 0x%x\n",
-            event->mods.locked, event->mods.latched,
-            event->mods.base);
-    printf("    group: locked 0x%x latched 0x%x base 0x%x\n",
-            event->group.locked, event->group.latched,
-            event->group.base);
-    printf("    valuators:");
-
-    val = event->valuators.values;
-    for (i = 0; i < event->valuators.mask_len * 8; i++)
-        if (XIMaskIsSet(event->valuators.mask, i))
-            printf(" %d: %.2f", i, *val++);
-    printf("\n");
-
-    printf("    windows: root 0x%lx event 0x%lx child 0x%ld\n",
-            event->root, event->event, event->child);
-    printf("    root x/y:  %.2f / %.2f\n", event->root_x, event->root_y);
-    printf("    event x/y: %.2f / %.2f\n", event->event_x, event->event_y);
-
-}
-
-
-/**
- * \brief This function is called when an Extension Event is received
- * and calls the corresponding callback functions for these events.
- */
-void fgHandleExtensionEvents( XEvent* base_ev ) {
-
-       int i, button = 0;
-       XGenericEventCookie* cookie = (XGenericEventCookie*)&(base_ev->xcookie);
-
-       if ( XGetEventData( fgDisplay.pDisplay.Display, cookie ) && (cookie->type == GenericEvent) && (cookie->extension == xi_opcode) ) {
-
-               XIDeviceEvent* event = (XIDeviceEvent*)(cookie->data);
-               /*printf("XI2 event type: %d - %d\n", cookie->evtype, event->type );*/
-
-               SFG_Window* window = fgWindowByHandle( event->event );
-               if (!window) return;
-
-               switch (cookie->evtype) {
-
-                       case XI_Enter:
-                       case XI_Leave:
-                               fgState.Modifiers = fgPlatformGetModifiers( ((XIEnterEvent*)event)->mods.base );
-                               INVOKE_WCB( *window, MultiEntry, (
-                                       event->deviceid, 
-                                       (event->evtype == XI_Enter ? GLUT_ENTERED : GLUT_LEFT)
-                               ));
-                               #if _DEBUG
-                                       fgPrintXILeaveEvent((XILeaveEvent*)event);
-                               #endif
-                               break;
-
-                       case XI_ButtonPress:
-                       case XI_ButtonRelease:
-                               fgState.Modifiers = fgPlatformGetModifiers( event->mods.base );
-                               INVOKE_WCB( *window, MultiButton, (
-                                       event->deviceid, 
-                                       event->event_x,
-                                       event->event_y,
-                                       (event->detail)-1, 
-                                       (event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP)
-                               ));
-                               INVOKE_WCB( *window, Mouse, (
-                                       (event->detail)-1, 
-                                       (event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP),
-                                       event->event_x,
-                                       event->event_y
-                               ));
-                               break;
-
-                       case XI_Motion:
-                               fgState.Modifiers = fgPlatformGetModifiers( event->mods.base );
-                               for (i = 0; i < event->buttons.mask_len; i++) if (event->buttons.mask[i]) button = 1;
-                               if (button) {
-                                       INVOKE_WCB( *window, MultiMotion,  ( event->deviceid, event->event_x, event->event_y ) );
-                                       INVOKE_WCB( *window,           Motion,  (                  event->event_x, event->event_y ) );
-                               } else {
-                                       INVOKE_WCB( *window, MultiPassive, ( event->deviceid, event->event_x, event->event_y ) );
-                                       INVOKE_WCB( *window,           Passive, (                  event->event_x, event->event_y ) );
-                               }
-                               #if _DEBUG
-                                       fgPrintXIDeviceEvent(event);
-                               #endif
-                               break;
-
-                       default:
-                               #if _DEBUG
-                                       fgWarning( "Unknown XI2 device event:" );
-                                       fgPrintXIDeviceEvent( event );
-                               #endif
-                               break;
-               }
-               fgState.Modifiers = INVALID_MODIFIERS;
-       }
-       XFreeEventData( fgDisplay.pDisplay.Display, cookie );
-}
-
-#endif\r
-\r