Added Windows "nmake" Makefiles and dependency files for the two "freeglut" projects...
[freeglut] / src / freeglut_window.c
index 9939e50..5ab924f 100644 (file)
 #include "freeglut_internal.h"
 
 #if defined(_WIN32_WCE)
-#include <aygshell.h>
-#pragma comment( lib, "Aygshell.lib" ) /* library pragmas are bad */
+#   include <Aygshell.h>
+#   ifdef FREEGLUT_LIB_PRAGMAS
+#       pragma comment( lib, "Aygshell.lib" )
+#   endif
 
 static wchar_t* fghWstrFromStr(const char* str)
 {
@@ -42,7 +44,6 @@ static wchar_t* fghWstrFromStr(const char* str)
     return wstr;
 }
 
-
 #endif /* defined(_WIN32_WCE) */
 
 /*
@@ -135,6 +136,8 @@ XVisualInfo* fgChooseVisual( void )
         ATTRIB_VAL( GLX_AUX_BUFFERS, 3 );
     if( fgState.DisplayMode & GLUT_AUX4 )
         ATTRIB_VAL( GLX_AUX_BUFFERS, 4 );
+    if ( fgState.DisplayMode & GLUT_MULTISAMPLE )
+        ATTRIB_VAL( GLX_SAMPLES_SGIS, 4 );
 
 
     /* Push a null at the end of the list */
@@ -170,10 +173,33 @@ XVisualInfo* fgChooseVisual( void )
  * Setup the pixel format for a Win32 window
  */
 #if TARGET_HOST_MS_WINDOWS
+/* 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
+
+
 GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
                               unsigned char layer_type )
 {
-#ifdef _WIN32_WCE
+#if defined(_WIN32_WCE)
     return GL_TRUE;
 #else
     PIXELFORMATDESCRIPTOR* ppfd, pfd;
@@ -195,15 +221,31 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
     pfd.nSize           = sizeof(PIXELFORMATDESCRIPTOR);
     pfd.nVersion        = 1;
     pfd.dwFlags         = flags;
-    pfd.iPixelType      = PFD_TYPE_RGBA;
+
+    if( fgState.DisplayMode & GLUT_INDEX )
+    {
+        pfd.iPixelType = PFD_TYPE_COLORINDEX;
+        pfd.cRedBits                = 0;
+        pfd.cGreenBits            = 0;
+        pfd.cBlueBits             = 0;
+        pfd.cAlphaBits            = 0;
+    }
+    else
+    {
+        pfd.iPixelType      = PFD_TYPE_RGBA;
+        pfd.cRedBits                = 8;
+        pfd.cGreenBits            = 8;
+        pfd.cBlueBits             = 8;
+        if ( fgState.DisplayMode & GLUT_ALPHA )
+            pfd.cAlphaBits            = 8;
+        else
+            pfd.cAlphaBits            = 0;
+    }
+
     pfd.cColorBits      = 24;
-    pfd.cRedBits        = 0;
     pfd.cRedShift       = 0;
-    pfd.cGreenBits      = 0;
     pfd.cGreenShift     = 0;
-    pfd.cBlueBits       = 0;
     pfd.cBlueShift      = 0;
-    pfd.cAlphaBits      = 0;
     pfd.cAlphaShift     = 0;
     pfd.cAccumBits      = 0;
     pfd.cAccumRedBits   = 0;
@@ -238,6 +280,80 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
     ppfd = &pfd;
 
     pixelformat = ChoosePixelFormat( window->Window.Device, ppfd );
+
+    /* windows hack for multismapling */
+    if (fgState.DisplayMode&GLUT_MULTISAMPLE)
+    {        
+        PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetEntensionsStringARB=NULL;
+        HGLRC rc, rc_before=wglGetCurrentContext();
+        HWND hWnd;
+        HDC hDC, hDC_before=wglGetCurrentDC();
+        WNDCLASS wndCls;
+        ATOM atom;
+
+        /* create a dummy window */
+        ZeroMemory(&wndCls, sizeof(wndCls));
+                wndCls.lpfnWndProc        = DefWindowProc;
+                wndCls.hInstance            = fgDisplay.Instance;
+                wndCls.style                    = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
+                wndCls.lpszClassName    = _T("FREEGLUT_dummy");
+        atom = RegisterClass( &wndCls );
+
+        hWnd=CreateWindow((LPCSTR)atom, _T(""), WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW , 0,0,0,0, 0, 0, fgDisplay.Instance, 0 );
+        hDC=GetDC(hWnd);
+        SetPixelFormat( hDC, pixelformat, ppfd );
+        
+        rc = wglCreateContext( hDC );
+        wglMakeCurrent(hDC, rc);
+        
+        wglGetEntensionsStringARB=(PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
+        if (wglGetEntensionsStringARB)
+        {
+            const char * pWglExtString=wglGetEntensionsStringARB(hDC);
+            if (pWglExtString)
+            {
+                if (strstr(pWglExtString, "WGL_ARB_multisample"))
+                {
+                    int pAttributes[100];
+                    int iCounter=0;
+                    int iPixelFormat;
+                    BOOL bValid;
+                    float fAttributes[] = {0,0};
+                    UINT numFormats;
+                    PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARBProc=NULL;
+
+                    wglChoosePixelFormatARBProc=(PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
+                    if ( wglChoosePixelFormatARBProc )
+                    {
+                        pAttributes[iCounter++]=WGL_DRAW_TO_WINDOW_ARB;        pAttributes[iCounter++]=GL_TRUE;
+                        pAttributes[iCounter++]=WGL_SUPPORT_OPENGL_ARB;        pAttributes[iCounter++]=GL_TRUE;
+                        pAttributes[iCounter++]=WGL_ACCELERATION_ARB;        pAttributes[iCounter++]=WGL_FULL_ACCELERATION_ARB;
+
+                        pAttributes[iCounter++]=WGL_COLOR_BITS_ARB;            pAttributes[iCounter++]=pfd.cColorBits ;
+                        pAttributes[iCounter++]=WGL_ALPHA_BITS_ARB;            pAttributes[iCounter++]=pfd.cAlphaBits;
+                        pAttributes[iCounter++]=WGL_DEPTH_BITS_ARB;            pAttributes[iCounter++]=pfd.cDepthBits;
+                        pAttributes[iCounter++]=WGL_STENCIL_BITS_ARB;        pAttributes[iCounter++]=pfd.cStencilBits;
+
+                        pAttributes[iCounter++]=WGL_DOUBLE_BUFFER_ARB;        pAttributes[iCounter++]=(fgState.DisplayMode & GLUT_DOUBLE)!=0;
+                        pAttributes[iCounter++]=WGL_SAMPLE_BUFFERS_ARB;        pAttributes[iCounter++]=GL_TRUE;
+                        pAttributes[iCounter++]=WGL_SAMPLES_ARB;            pAttributes[iCounter++]=4;
+                        pAttributes[iCounter++]=0;                            pAttributes[iCounter++]=0;    /* terminator */
+
+                        bValid = wglChoosePixelFormatARBProc(window->Window.Device,pAttributes,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.Instance);
+            }
+        }
+    }
+
     if( pixelformat == 0 )
         return GL_FALSE;
 
@@ -284,7 +400,8 @@ void fgSetWindow ( SFG_Window *window )
  * to the freeglut structure. OpenGL context is created here.
  */
 void fgOpenWindow( SFG_Window* window, const char* title,
-                   int x, int y, int w, int h,
+                   GLboolean positionUse, int x, int y,
+                   GLboolean sizeUse, int w, int h,
                    GLboolean gameMode, GLboolean isSubWindow )
 {
 #if TARGET_HOST_POSIX_X11
@@ -318,10 +435,12 @@ void fgOpenWindow( SFG_Window* window, const char* title,
             fgState.DisplayMode &= ~GLUT_DOUBLE;
         }
 
-        /*
-         * GLUT also checks for multi-sampling, but I don't see that
-         * anywhere else in FREEGLUT so I won't bother with it for the moment.
-         */
+        if( fgState.DisplayMode & GLUT_MULTISAMPLE )
+        {
+            fgState.DisplayMode &= ~GLUT_MULTISAMPLE ;
+            window->Window.VisualInfo = fgChooseVisual( );
+            fgState.DisplayMode |= GLUT_MULTISAMPLE;
+        }
     }
 
     FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.VisualInfo != NULL,
@@ -359,6 +478,11 @@ void fgOpenWindow( SFG_Window* window, const char* title,
         mask |= CWOverrideRedirect;
     }
 
+    if( ! positionUse )
+        x = y = -1; /* default window position */
+    if( ! sizeUse )
+        w = h = 300; /* default window size */
+
     window->Window.Handle = XCreateWindow(
         fgDisplay.Display,
         window->Parent == NULL ? fgDisplay.RootWindow :
@@ -431,9 +555,9 @@ void fgOpenWindow( SFG_Window* window, const char* title,
     window->State.Visible = GL_TRUE;
 
     sizeHints.flags = 0;
-    if ( fgState.Position.Use )
+    if ( positionUse )
         sizeHints.flags |= USPosition;
-    if ( fgState.Size.Use )
+    if ( sizeUse )
         sizeHints.flags |= USSize;
 
     /*
@@ -504,6 +628,8 @@ void fgOpenWindow( SFG_Window* window, const char* title,
     }
     else
     {
+        int worig = w, horig = h;
+
 #if !defined(_WIN32_WCE)
         if ( ( ! isSubWindow ) && ( ! window->IsMenu ) )
         {
@@ -518,15 +644,27 @@ void fgOpenWindow( SFG_Window* window, const char* title,
         }
 #endif /* defined(_WIN32_WCE) */
 
-        if( ! fgState.Position.Use )
+        if( ! positionUse )
         {
             x = CW_USEDEFAULT;
             y = CW_USEDEFAULT;
         }
-        if( ! fgState.Size.Use )
+        /* setting State.Width/Height to call resize callback later */
+        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 */
+            window->State.Width = window->State.Height = -1;
+        }
+        else
         {
-            w = CW_USEDEFAULT;
-            h = CW_USEDEFAULT;
+            window->State.Width = worig;
+            window->State.Height = horig;
         }
 
         /*
@@ -575,7 +713,7 @@ void fgOpenWindow( SFG_Window* window, const char* title,
 #else
     window->Window.Handle = CreateWindowEx(
         exFlags,
-        "FREEGLUT",
+        _T("FREEGLUT"),
         title,
         flags,
         x, y, w, h,
@@ -672,9 +810,10 @@ int FGAPIENTRY glutCreateWindow( const char* title )
      */
     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateWindow" );
 
-    return fgCreateWindow( NULL, title, fgState.Position.X, fgState.Position.Y,
-                           fgState.Size.X, fgState.Size.Y, GL_FALSE,
-                           GL_FALSE )->ID;
+    return fgCreateWindow( NULL, title, fgState.Position.Use,
+                           fgState.Position.X, fgState.Position.Y,
+                           fgState.Size.Use, fgState.Size.X, fgState.Size.Y,
+                           GL_FALSE, GL_FALSE )->ID;
 }
 
 /*
@@ -715,7 +854,7 @@ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h )
         h = -h ;
     }
 
-    window = fgCreateWindow( parent, "", x, y, w, h, GL_FALSE, GL_FALSE );
+    window = fgCreateWindow( parent, "", GL_TRUE, x, y, GL_TRUE, w, h, GL_FALSE, GL_FALSE );
     ret = window->ID;
 
     return ret;