X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_window.c;h=c60aee0a22231eb84f8a51e1294d84f05f847bd8;hb=f2afa8e09dc46f89642a9cbbbc19250554c7ec5f;hp=a469866a8c5351c26514c15eaebfd7dea4dba51f;hpb=80f6de57f5364e1bfabb9650d20e970ea8ef5c81;p=freeglut diff --git a/src/freeglut_window.c b/src/freeglut_window.c index a469866..c60aee0 100644 --- a/src/freeglut_window.c +++ b/src/freeglut_window.c @@ -28,9 +28,9 @@ #include #include "freeglut_internal.h" -#if TARGET_HOST_WINCE +#if defined(_WIN32_WCE) #include -#pragma comment( lib, "Aygshell.lib" ) +#pragma comment( lib, "Aygshell.lib" ) /* library pragmas are bad */ static wchar_t* fghWstrFromStr(const char* str) { @@ -43,7 +43,7 @@ static wchar_t* fghWstrFromStr(const char* str) } -#endif /* TARGET_HOST_WINCE */ +#endif /* defined(_WIN32_WCE) */ /* * TODO BEFORE THE STABLE RELEASE: @@ -73,7 +73,7 @@ static wchar_t* fghWstrFromStr(const char* str) /* * Chooses a visual basing on the current display mode settings */ -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 XVisualInfo* fgChooseVisual( void ) { @@ -135,6 +135,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 */ @@ -169,11 +171,34 @@ XVisualInfo* fgChooseVisual( void ) /* * Setup the pixel format for a Win32 window */ -#if TARGET_HOST_WIN32 +#if TARGET_HOST_MS_WINDOWS +/* WRONG-- FIXME */ +/* The following include file is available from SGI but is not standard: + * #include + * So we copy the necessary parts out of it. + */ +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 ) { -#if TARGET_HOST_WINCE +#if defined(_WIN32_WCE) return GL_TRUE; #else PIXELFORMATDESCRIPTOR* ppfd, pfd; @@ -184,6 +209,9 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, 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 @@ -192,15 +220,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; @@ -235,15 +279,89 @@ 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; if( checkOnly ) return GL_TRUE; return SetPixelFormat( window->Window.Device, pixelformat, ppfd ); -#endif /* TARGET_HOST_WINCE */ +#endif /* defined(_WIN32_WCE) */ } -#endif +#endif /* TARGET_HOST_MS_WINDOWS */ /* * Sets the OpenGL context and the fgStructure "Current Window" pointer to @@ -251,14 +369,14 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, */ void fgSetWindow ( SFG_Window *window ) { -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 if ( window ) glXMakeCurrent( fgDisplay.Display, window->Window.Handle, window->Window.Context ); -#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE +#elif TARGET_HOST_MS_WINDOWS if( fgStructure.CurrentWindow ) ReleaseDC( fgStructure.CurrentWindow->Window.Handle, fgStructure.CurrentWindow->Window.Device ); @@ -284,7 +402,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode, GLboolean isSubWindow ) { -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 XSetWindowAttributes winAttr; XTextProperty textProperty; XSizeHints sizeHints; @@ -315,10 +433,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, @@ -475,7 +595,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, XMapWindow( fgDisplay.Display, window->Window.Handle ); -#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE +#elif TARGET_HOST_MS_WINDOWS WNDCLASS wc; DWORD flags; @@ -501,7 +621,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, } else { -#if !TARGET_HOST_WINCE +#if !defined(_WIN32_WCE) if ( ( ! isSubWindow ) && ( ! window->IsMenu ) ) { /* @@ -513,7 +633,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 + GetSystemMetrics( SM_CYCAPTION ); } -#endif /* TARGET_HOST_WINCE */ +#endif /* defined(_WIN32_WCE) */ if( ! fgState.Position.Use ) { @@ -537,7 +657,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, flags |= WS_POPUP; exFlags |= WS_EX_TOOLWINDOW; } -#if !TARGET_HOST_WINCE +#if !defined(_WIN32_WCE) else if( window->Parent == NULL ) flags |= WS_OVERLAPPEDWINDOW; #endif @@ -545,7 +665,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, flags |= WS_CHILD; } -#if TARGET_HOST_WINCE +#if defined(_WIN32_WCE) { wchar_t* wstr = fghWstrFromStr(title); @@ -581,17 +701,17 @@ void fgOpenWindow( SFG_Window* window, const char* title, fgDisplay.Instance, (LPVOID) window ); -#endif /* TARGET_HOST_WINCE */ +#endif /* defined(_WIN32_WCE) */ if( !( window->Window.Handle ) ) fgError( "Failed to create a window (%s)!", title ); -#if TARGET_HOST_WINCE +#if defined(_WIN32_WCE) ShowWindow( window->Window.Handle, SW_SHOW ); #else ShowWindow( window->Window.Handle, fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW ); -#endif /* TARGET_HOST_WINCE */ +#endif /* defined(_WIN32_WCE) */ UpdateWindow( window->Window.Handle ); ShowCursor( TRUE ); /* XXX Old comments say "hide cursor"! */ @@ -615,14 +735,14 @@ void fgOpenWindow( SFG_Window* window, const char* title, */ void fgCloseWindow( SFG_Window* window ) { -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 glXDestroyContext( fgDisplay.Display, window->Window.Context ); XFree( window->Window.VisualInfo ); XDestroyWindow( fgDisplay.Display, window->Window.Handle ); XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */ -#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE +#elif TARGET_HOST_MS_WINDOWS /* Make sure we don't close a window with current context active */ if( fgStructure.CurrentWindow == window ) @@ -761,10 +881,11 @@ void FGAPIENTRY glutSetWindow( int ID ) */ int FGAPIENTRY glutGetWindow( void ) { + SFG_Window *win = fgStructure.CurrentWindow; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetWindow" ); - if( fgStructure.CurrentWindow == NULL ) - return 0; - return fgStructure.CurrentWindow->ID; + while ( win && win->IsMenu ) + win = win->Parent; + return win ? win->ID : 0; } /* @@ -775,12 +896,12 @@ void FGAPIENTRY glutShowWindow( void ) FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutShowWindow" ); FREEGLUT_EXIT_IF_NO_WINDOW ( "glutShowWindow" ); -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 XMapWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle ); XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */ -#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE +#elif TARGET_HOST_MS_WINDOWS ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_SHOW ); @@ -797,7 +918,7 @@ void FGAPIENTRY glutHideWindow( void ) FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutHideWindow" ); FREEGLUT_EXIT_IF_NO_WINDOW ( "glutHideWindow" ); -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 if( fgStructure.CurrentWindow->Parent == NULL ) XWithdrawWindow( fgDisplay.Display, @@ -808,7 +929,7 @@ void FGAPIENTRY glutHideWindow( void ) fgStructure.CurrentWindow->Window.Handle ); XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */ -#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE +#elif TARGET_HOST_MS_WINDOWS ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_HIDE ); @@ -826,13 +947,13 @@ void FGAPIENTRY glutIconifyWindow( void ) FREEGLUT_EXIT_IF_NO_WINDOW ( "glutIconifyWindow" ); fgStructure.CurrentWindow->State.Visible = GL_FALSE; -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 XIconifyWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle, fgDisplay.Screen ); XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */ -#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE +#elif TARGET_HOST_MS_WINDOWS ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_MINIMIZE ); @@ -850,7 +971,7 @@ void FGAPIENTRY glutSetWindowTitle( const char* title ) FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetWindowTitle" ); if( ! fgStructure.CurrentWindow->Parent ) { -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 XTextProperty text; @@ -867,18 +988,17 @@ void FGAPIENTRY glutSetWindowTitle( const char* title ) XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */ -#elif TARGET_HOST_WIN32 - - SetWindowText( fgStructure.CurrentWindow->Window.Handle, title ); - -#elif TARGET_HOST_WINCE +#elif TARGET_HOST_MS_WINDOWS +# ifdef _WIN32_WCE { wchar_t* wstr = fghWstrFromStr(title); - SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr ); - free(wstr); } +# else + SetWindowText( fgStructure.CurrentWindow->Window.Handle, title ); +# endif + #endif } } @@ -893,7 +1013,7 @@ void FGAPIENTRY glutSetIconTitle( const char* title ) if( ! fgStructure.CurrentWindow->Parent ) { -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 XTextProperty text; @@ -910,18 +1030,17 @@ void FGAPIENTRY glutSetIconTitle( const char* title ) XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */ -#elif TARGET_HOST_WIN32 - - SetWindowText( fgStructure.CurrentWindow->Window.Handle, title ); - -#elif TARGET_HOST_WINCE +#elif TARGET_HOST_MS_WINDOWS +# ifdef _WIN32_WCE { wchar_t* wstr = fghWstrFromStr(title); - SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr ); - free(wstr); } +# else + SetWindowText( fgStructure.CurrentWindow->Window.Handle, title ); +# endif + #endif } } @@ -947,13 +1066,13 @@ void FGAPIENTRY glutPositionWindow( int x, int y ) FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPositionWindow" ); FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPositionWindow" ); -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 XMoveWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle, x, y ); XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */ -#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE +#elif TARGET_HOST_MS_WINDOWS { RECT winRect; @@ -981,11 +1100,11 @@ void FGAPIENTRY glutPushWindow( void ) FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPushWindow" ); FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPushWindow" ); -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 XLowerWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle ); -#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE +#elif TARGET_HOST_MS_WINDOWS SetWindowPos( fgStructure.CurrentWindow->Window.Handle, @@ -1005,11 +1124,11 @@ void FGAPIENTRY glutPopWindow( void ) FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPopWindow" ); FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPopWindow" ); -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 XRaiseWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle ); -#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE +#elif TARGET_HOST_MS_WINDOWS SetWindowPos( fgStructure.CurrentWindow->Window.Handle, @@ -1030,7 +1149,7 @@ void FGAPIENTRY glutFullScreen( void ) FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreen" ); { -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 int x, y; Window w; @@ -1060,7 +1179,7 @@ void FGAPIENTRY glutFullScreen( void ) ); XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */ } -#elif TARGET_HOST_WIN32 +#elif TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE) /* FIXME: what about WinCE */ RECT rect; /* For fullscreen mode, force the top-left corner to 0,0