X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_window.c;h=c7a07c6ab084cbb1eef7514df31354ea7902e80c;hb=a1ff6aa662af045fc32c9241ef48a6ff019e0018;hp=f0e07544cbcdbcc25f6d119f7649c35d52e82f78;hpb=ac26c64653954569627ad5413240cbd8453cd814;p=freeglut diff --git a/src/freeglut_window.c b/src/freeglut_window.c index f0e0754..c7a07c6 100644 --- a/src/freeglut_window.c +++ b/src/freeglut_window.c @@ -38,18 +38,108 @@ # ifdef FREEGLUT_LIB_PRAGMAS # pragma comment( lib, "Aygshell.lib" ) # endif +#endif /* 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 + * 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 + +#endif /* TARGET_HOST_MS_WINDOWS */ + /* pushing attribute/value pairs into an array */ #define ATTRIB(a) attributes[where++]=(a) @@ -122,16 +212,15 @@ static void fghContextCreationError( void ) fgState.ContextProfile ); } + +/* -- SYSTEM-DEPENDENT PRIVATE FUNCTIONS ------------------------------------ */ + +#if TARGET_HOST_POSIX_X11 /* * Chooses a visual basing on the current display mode settings */ -#if TARGET_HOST_POSIX_X11 -#ifndef GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB -#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 -#endif - -GLXFBConfig* fgChooseFBConfig( void ) +GLXFBConfig* fgChooseFBConfig( int *numcfgs ) { GLboolean wantIndexedMode = GL_FALSE; int attributes[ 100 ]; @@ -296,63 +385,183 @@ GLXFBConfig* fgChooseFBConfig( void ) fbconfig = NULL; } + if (numcfgs) + *numcfgs = fbconfigArraySize; + return fbconfig; } } -#endif /* TARGET_HOST_POSIX_X11 */ -/* - * 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 - * 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); +static void fghFillContextAttributes( int *attributes ) { + int where = 0, contextFlags, contextProfile; -#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 + if ( !fghIsLegacyContextVersionRequested() ) { + ATTRIB_VAL( GLX_CONTEXT_MAJOR_VERSION_ARB, fgState.MajorVersion ); + ATTRIB_VAL( GLX_CONTEXT_MINOR_VERSION_ARB, fgState.MinorVersion ); + } -#define WGL_SAMPLE_BUFFERS_ARB 0x2041 -#define WGL_SAMPLES_ARB 0x2042 + 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 ); + } -#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 + 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.Display; + GLXFBConfig config = *(window->Window.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; + + /* If nothing fancy has been required, simply use the old context creation GLX API entry */ + if ( fghIsLegacyContextRequested() ) + { + 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 ); + + createContextAttribs = (CreateContextAttribsProc) fghGetProcAddress( "glXCreateContextAttribsARB" ); + if ( createContextAttribs == NULL ) { + fgError( "glXCreateContextAttribsARB not found" ); + } + + 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.OldWidth; + fgStructure.CurrentWindow->State.Height = win->State.OldHeight; + + } else { + /* resize the window to cover the entire screen */ + XGetWindowAttributes(fgDisplay.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.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.State || !fgDisplay.StateFullScreen) { + return -1; + } + + xev.type = ClientMessage; + xev.xclient.window = fgStructure.CurrentWindow->Window.Handle; + xev.xclient.message_type = fgDisplay.State; + xev.xclient.format = 32; + xev.xclient.data.l[0] = _NET_WM_STATE_TOGGLE; + xev.xclient.data.l[1] = fgDisplay.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.Display, fgDisplay.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; +} -#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); +#endif /* TARGET_HOST_POSIX_X11 */ -#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 +#if TARGET_HOST_MS_WINDOWS +/* + * Setup the pixel format for a Win32 window + */ -#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 -#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#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; iWindow.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 ) || @@ -548,10 +764,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 = @@ -564,7 +780,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 ) { @@ -580,10 +796,16 @@ 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) */ } -#endif /* TARGET_HOST_MS_WINDOWS */ + +#endif /* TARGET_HOST_MS_WINDOWS */ /* * Sets the OpenGL context and the fgStructure "Current Window" pointer to @@ -602,142 +824,86 @@ 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; } +#if TARGET_HOST_MS_WINDOWS - -#if TARGET_HOST_POSIX_X11 - -#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 - -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 ); +#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) ) + { + *(dp->x)=info.rcMonitor.left; + *(dp->y)=info.rcMonitor.top; + return FALSE; + } + } + return TRUE; } -typedef GLXContext (*CreateContextAttribsProc)(Display *dpy, GLXFBConfig config, - GLXContext share_list, Bool direct, - const int *attrib_list); +/* + * this function is only used in fgOpenWindow. Currently it only sets + * its output parameters, if the DisplayName is set in fgDisplay + * (and if it is able to recognize the display) + */ -static GLXContext fghCreateNewContext( SFG_Window* window ) +static void get_display_origin(int *xp,int *yp) { - /* for color model calculation */ - int menu = ( window->IsMenu && !fgStructure.MenuContext ); - int index_mode = ( fgState.DisplayMode & GLUT_INDEX ); - - /* "classic" context creation */ - Display *dpy = fgDisplay.Display; - GLXFBConfig config = *(window->Window.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; + if( fgDisplay.DisplayName ) + { + m_proc_t st; + st.x=xp; + st.y=yp; + st.name=fgDisplay.DisplayName; + EnumDisplayMonitors(0,0,m_proc,(LPARAM)&st); + } +} +#else +#pragma message( "-display parameter only works if compiled with WINVER >= 0x0500") - /* If nothing fancy has been required, simply use the old context creation GLX API entry */ - if ( fghIsLegacyContextRequested() ) - { - context = glXCreateNewContext( dpy, config, render_type, share_list, direct ); - if ( context == NULL ) { - fghContextCreationError(); +static void get_display_origin(int *xp,int *yp) +{ + if( fgDisplay.DisplayName ) + { + fgWarning( "for working -display support FreeGLUT must be compiled with WINVER >= 0x0500"); } - 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 ); - - createContextAttribs = (CreateContextAttribsProc) fghGetProcAddress( "glXCreateContextAttribsARB" ); - if ( createContextAttribs == NULL ) { - fgError( "glXCreateContextAttribsARB not found" ); - } - - context = createContextAttribs( dpy, config, share_list, direct, attributes ); - if ( context == NULL ) { - fghContextCreationError(); - } - return context; } #endif +#endif + /* @@ -756,13 +922,14 @@ void fgOpenWindow( SFG_Window* window, const char* title, XSizeHints sizeHints; XWMHints wmHints; 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 ; @@ -777,14 +944,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; } } @@ -793,8 +960,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. @@ -1050,17 +1224,24 @@ void fgOpenWindow( SFG_Window* window, const char* title, 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.Instance, - (LPVOID) window - ); + { + /* xoff and yoff are used to place window relative to current display */ + /* The operation of gamemode also depends on this */ + int xoff=0,yoff=0; + get_display_origin(&xoff,&yoff); + + window->Window.Handle = CreateWindowEx( + exFlags, + _T("FREEGLUT"), + title, + flags, + x+xoff, y+yoff, w, h, + (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle, + (HMENU) NULL, + fgDisplay.Instance, + (LPVOID) window + ); + } #endif /* defined(_WIN32_WCE) */ if( !( window->Window.Handle ) ) @@ -1127,7 +1308,10 @@ void fgCloseWindow( SFG_Window* window ) 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 @@ -1556,83 +1740,6 @@ void FGAPIENTRY glutPopWindow( void ) #endif } -#if TARGET_HOST_POSIX_X11 -static int ewmh_fullscr_toggle(void); -static int resize_fullscr_toogle(void); - -static int toggle_fullscreen(void) -{ - /* first try the EWMH (_NET_WM_STATE) method ... */ - if(ewmh_fullscr_toggle() != -1) { - return 0; - } - - /* fall back to resizing the window */ - if(resize_fullscr_toogle() != -1) { - return 0; - } - return -1; -} - -#define _NET_WM_STATE_TOGGLE 2 -static int ewmh_fullscr_toggle(void) -{ - XEvent xev; - long evmask = SubstructureRedirectMask | SubstructureNotifyMask; - - if(!fgDisplay.State || !fgDisplay.StateFullScreen) { - return -1; - } - - xev.type = ClientMessage; - xev.xclient.window = fgStructure.CurrentWindow->Window.Handle; - xev.xclient.message_type = fgDisplay.State; - xev.xclient.format = 32; - xev.xclient.data.l[0] = _NET_WM_STATE_TOGGLE; - xev.xclient.data.l[1] = fgDisplay.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.Display, fgDisplay.RootWindow, 0, evmask, &xev)) { - return -1; - } - return 0; -} - -static int resize_fullscr_toogle(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.OldWidth; - fgStructure.CurrentWindow->State.Height = win->State.OldHeight; - - } else { - /* resize the window to cover the entire screen */ - XGetWindowAttributes(fgDisplay.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.Display, - fgStructure.CurrentWindow->Window.Handle, - -attributes.x, - -attributes.y, - fgDisplay.ScreenWidth, - fgDisplay.ScreenHeight); - } - return 0; -} -#endif /* TARGET_HOST_POSIX_X11 */ - - /* * Resize the current window so that it fits the whole screen */ @@ -1647,7 +1754,7 @@ void FGAPIENTRY glutFullScreen( void ) #if TARGET_HOST_POSIX_X11 if(!glutGet(GLUT_FULL_SCREEN)) { - if(toggle_fullscreen() != -1) { + if(fghToggleFullscreen() != -1) { win->State.IsFullscreen = GL_TRUE; } } @@ -1670,8 +1777,9 @@ void FGAPIENTRY glutFullScreen( void ) rect.left = 0; rect.top = 0; - rect.right = fgDisplay.ScreenWidth; - rect.bottom = fgDisplay.ScreenHeight; + get_display_origin(&rect.left,&rect.top); + rect.right = fgDisplay.ScreenWidth+rect.left; + rect.bottom = fgDisplay.ScreenHeight+rect.top; AdjustWindowRect ( &rect, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, FALSE ); @@ -1711,7 +1819,7 @@ void FGAPIENTRY glutFullScreenToggle( void ) win = fgStructure.CurrentWindow; #if TARGET_HOST_POSIX_X11 - if(toggle_fullscreen() != -1) { + if(fghToggleFullscreen() != -1) { win->State.IsFullscreen = !win->State.IsFullscreen; } #elif TARGET_HOST_MS_WINDOWS