X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_window.c;h=fc9fc55d0055dabe666329941c7dc149579bdef4;hb=d4846df601fa224353c65fa332f603a85735b5d8;hp=d7f969b42ff8857f77ca5fdc22c829003c53dc41;hpb=83b18abec6d04e3cc4801305026dce26cb8d2293;p=freeglut diff --git a/src/freeglut_window.c b/src/freeglut_window.c index d7f969b..fc9fc55 100644 --- a/src/freeglut_window.c +++ b/src/freeglut_window.c @@ -31,6 +31,7 @@ #if TARGET_HOST_POSIX_X11 #include /* LONG_MAX */ +#include /* usleep */ #endif #if defined(_WIN32_WCE) @@ -220,7 +221,7 @@ static void fghContextCreationError( void ) * Chooses a visual basing on the current display mode settings */ -GLXFBConfig* fgChooseFBConfig( void ) +GLXFBConfig* fgChooseFBConfig( int *numcfgs ) { GLboolean wantIndexedMode = GL_FALSE; int attributes[ 100 ]; @@ -385,6 +386,9 @@ GLXFBConfig* fgChooseFBConfig( void ) fbconfig = NULL; } + if (numcfgs) + *numcfgs = fbconfigArraySize; + return fbconfig; } } @@ -676,7 +680,7 @@ static void fghFillPFD( PIXELFORMATDESCRIPTOR *ppfd, HDC hdc, unsigned char laye ppfd->cGreenShift = 0; ppfd->cBlueShift = 0; ppfd->cAlphaShift = 0; - ppfd->cAccumBits = 0; + ppfd->cAccumBits = ( fgState.DisplayMode & GLUT_ACCUM ) ? 1 : 0; ppfd->cAccumRedBits = 0; ppfd->cAccumGreenBits = 0; ppfd->cAccumBlueBits = 0; @@ -730,9 +734,16 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, 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.Device; - fghFillPFD( ppfd, window->Window.Device, layer_type ); - pixelformat = ChoosePixelFormat( window->Window.Device, ppfd ); + fghFillPFD( ppfd, current_hDC, layer_type ); + pixelformat = ChoosePixelFormat( current_hDC, ppfd ); /* windows hack for multismapling/sRGB */ if ( ( fgState.DisplayMode & GLUT_MULTISAMPLE ) || @@ -754,10 +765,10 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, hWnd=CreateWindow(_T("FREEGLUT_dummy"), _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); - + if ( fghIsExtensionSupported( hDC, "WGL_ARB_multisample" ) ) { PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARBProc = @@ -770,7 +781,7 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, float fAttributes[] = { 0, 0 }; UINT numFormats; fghFillPixelFormatAttributes( attributes, ppfd ); - bValid = wglChoosePixelFormatARBProc(window->Window.Device, attributes, fAttributes, 1, &iPixelFormat, &numFormats); + bValid = wglChoosePixelFormatARBProc(hDC, attributes, fAttributes, 1, &iPixelFormat, &numFormats); if ( bValid && numFormats > 0 ) { @@ -786,7 +797,12 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, UnregisterClass(_T("FREEGLUT_dummy"), fgDisplay.Instance); } - return ( pixelformat != 0 ) && ( checkOnly || SetPixelFormat( window->Window.Device, pixelformat, ppfd ) ); + success = ( pixelformat != 0 ) && ( checkOnly || SetPixelFormat( current_hDC, pixelformat, ppfd ) ); + + if (checkOnly) + DeleteDC(current_hDC); + + return success; #endif /* defined(_WIN32_WCE) */ } @@ -809,17 +825,20 @@ void fgSetWindow ( SFG_Window *window ) ); } #elif TARGET_HOST_MS_WINDOWS - if( fgStructure.CurrentWindow ) - ReleaseDC( fgStructure.CurrentWindow->Window.Handle, - fgStructure.CurrentWindow->Window.Device ); - - if ( window ) + if ( window != fgStructure.CurrentWindow ) { - window->Window.Device = GetDC( window->Window.Handle ); - wglMakeCurrent( - window->Window.Device, - window->Window.Context - ); + if( fgStructure.CurrentWindow ) + ReleaseDC( fgStructure.CurrentWindow->Window.Handle, + fgStructure.CurrentWindow->Window.Device ); + + if ( window ) + { + window->Window.Device = GetDC( window->Window.Handle ); + wglMakeCurrent( + window->Window.Device, + window->Window.Context + ); + } } #endif fgStructure.CurrentWindow = window; @@ -887,6 +906,14 @@ static void get_display_origin(int *xp,int *yp) #endif +#if TARGET_HOST_POSIX_X11 +static Bool fghWindowIsVisible( Display *display, XEvent *event, XPointer arg) +{ + Window window = arg; + return (event->type == MapNotify) && (event->xmap.window == window); +} +#endif + /* * Opens a window. Requires a SFG_Window object created and attached @@ -903,14 +930,16 @@ void fgOpenWindow( SFG_Window* window, const char* title, 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.FBConfig = fgChooseFBConfig( ); + window->Window.FBConfig = fgChooseFBConfig( &num_FBConfigs ); if( window->IsMenu && ( ! fgStructure.MenuContext ) ) fgState.DisplayMode = current_DisplayMode ; @@ -925,14 +954,14 @@ void fgOpenWindow( SFG_Window* window, const char* title, if( !( fgState.DisplayMode & GLUT_DOUBLE ) ) { fgState.DisplayMode |= GLUT_DOUBLE ; - window->Window.FBConfig = fgChooseFBConfig( ); + window->Window.FBConfig = fgChooseFBConfig( &num_FBConfigs ); fgState.DisplayMode &= ~GLUT_DOUBLE; } if( fgState.DisplayMode & GLUT_MULTISAMPLE ) { fgState.DisplayMode &= ~GLUT_MULTISAMPLE ; - window->Window.FBConfig = fgChooseFBConfig( ); + window->Window.FBConfig = fgChooseFBConfig( &num_FBConfigs ); fgState.DisplayMode |= GLUT_MULTISAMPLE; } } @@ -941,8 +970,15 @@ void fgOpenWindow( SFG_Window* window, const char* title, "FBConfig with necessary capabilities not found", "fgOpenWindow" ); /* Get the X visual. */ - visualInfo = glXGetVisualFromFBConfig( fgDisplay.Display, - *(window->Window.FBConfig) ); + for (i = 0; i < num_FBConfigs; i++) { + visualInfo = glXGetVisualFromFBConfig( fgDisplay.Display, + window->Window.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. @@ -1088,6 +1124,9 @@ void fgOpenWindow( SFG_Window* window, const char* title, XFree(visualInfo); + if( !isSubWindow) + XPeekIfEvent( fgDisplay.Display, &eventReturnBuffer, &fghWindowIsVisible, window->Window.Handle ); + #elif TARGET_HOST_MS_WINDOWS WNDCLASS wc; @@ -1277,12 +1316,21 @@ void fgOpenWindow( SFG_Window* window, const char* title, */ void fgCloseWindow( SFG_Window* window ) { + /* if we're in gamemode, call glutLeaveGameMode first to make sure the + * gamemode is properly closed before closing the window + */ + if (fgStructure.GameModeWindow != NULL) + glutLeaveGameMode(); + #if TARGET_HOST_POSIX_X11 if( window->Window.Context ) glXDestroyContext( fgDisplay.Display, window->Window.Context ); XFree( window->Window.FBConfig ); - XDestroyWindow( fgDisplay.Display, window->Window.Handle ); + + if( window->Window.Handle ) { + XDestroyWindow( fgDisplay.Display, window->Window.Handle ); + } /* XFlush( fgDisplay.Display ); */ /* XXX Shouldn't need this */ #elif TARGET_HOST_MS_WINDOWS