X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_window_mswin.c;h=6a86848222e82173ec4af0ef25096d9b95d05a19;hb=af4474129987c478bad43ff0b4f44c2470298a8d;hp=7720929364c1c551ba2272f4939aa06c15a8f1b0;hpb=637e1260edb9068591665330c32407549ca36535;p=freeglut diff --git a/src/mswin/fg_window_mswin.c b/src/mswin/fg_window_mswin.c index 7720929..6a86848 100644 --- a/src/mswin/fg_window_mswin.c +++ b/src/mswin/fg_window_mswin.c @@ -371,6 +371,20 @@ void fgPlatformSetWindow ( SFG_Window *window ) } +void fghGetDefaultWindowStyle(DWORD *flags) +{ + if ( fgState.DisplayMode & GLUT_BORDERLESS ) + { + /* no window decorations needed, no-op */ + } + 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. */ + (*flags) |= WS_OVERLAPPEDWINDOW; +} + /* Get window style and extended window style of a FreeGLUT window * If the window pointer or the window handle is NULL, a fully * decorated window (caption and border) is assumed. @@ -384,8 +398,9 @@ void fghGetStyleFromWindow( const SFG_Window *window, DWORD *windowStyle, DWORD } else { + *windowStyle = 0; + fghGetDefaultWindowStyle(windowStyle); /* WindowExStyle==0 is fine/default, exStyle is currently only used for menu windows */ - *windowStyle = WS_OVERLAPPEDWINDOW; *windowExStyle = 0; } } @@ -442,45 +457,22 @@ void fghComputeWindowRectFromClientArea_QueryWindow( RECT *clientRect, const SFG /* Gets the rect describing the client area (drawable area) of the * specified window. Output is position of corners of client area (drawable area) on the screen. - * 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. + * Does not touch clientRect if window pointer or window handle is NULL. + * (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable area. */ -void fghGetClientArea( RECT *clientRect, const SFG_Window *window, BOOL wantPosOutside ) +void fghGetClientArea( RECT *clientRect, const SFG_Window *window ) { POINT topLeftClient = {0,0}; POINT topLeftWindow = {0,0}; freeglut_return_if_fail((window && window->Window.Handle)); - /* - * call GetWindowRect() - * (this returns the pixel coordinates of the outside of the window) - * cannot use GetClientRect as it returns a rect relative to - * the top-left point of the client area (.top and .left are thus always 0) - * and is thus only useful for querying the size of the client area, not - * its position. - */ - GetWindowRect( window->Window.Handle, clientRect ); - topLeftWindow.x = clientRect->top; - topLeftWindow.y = clientRect->left; - /* Get size of client rect */ GetClientRect(window->Window.Handle, clientRect); /* Get position of top-left of client area on the screen */ ClientToScreen(window->Window.Handle,&topLeftClient); /* Add top-left offset */ OffsetRect(clientRect,topLeftClient.x,topLeftClient.y); - - /* replace top and left with top and left of window, if wanted */ - if (wantPosOutside) - { - clientRect->left = topLeftWindow.x; - clientRect->top = topLeftWindow.y; - } } #if(WINVER >= 0x500) @@ -601,23 +593,9 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, #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 */ + /* if this is not a subwindow (child), set its style based on the requested window decorations */ 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; + fghGetDefaultWindowStyle(&flags); #endif else /* subwindows always have no decoration, but are marked as a child window to the OS */ @@ -750,7 +728,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, ShowWindow( window->Window.Handle, SW_SHOW ); #else ShowWindow( window->Window.Handle, - fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW ); + fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOWNORMAL ); #endif /* defined(_WIN32_WCE) */ UpdateWindow( window->Window.Handle ); @@ -758,6 +736,74 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, } +void fgPlatformDisplayWindow ( SFG_Window *window ) +{ + RedrawWindow( + window->Window.Handle, NULL, NULL, + RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_UPDATENOW + ); +} + + +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. + * + * Note on maximizing behavior of Windows: the resize borders are off + * the screen such that the client area extends all the way from the + * leftmost corner to the rightmost corner to maximize screen real + * estate. A caption is still shown however to allow interaction with + * the window controls. This is default behavior of Windows that + * FreeGLUT sticks with. To alter, one would have to check if + * WS_MAXIMIZE style is set when a resize event is triggered, and + * then manually correct the windowRect to put the borders back on + * screen. + */ + + /* "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(&windowRect,window,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; + fghGetClientArea( &parentRect, window->Parent ); + OffsetRect(&windowRect,-parentRect.left,-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 + ); + + /* Set new width and height so we can test for that in WM_SIZE message handler and don't do anything if not needed */ + window->State.Width = width; + window->State.Height = height; +} + + /* * Closes a window, destroying the frame and OpenGL context */ @@ -911,7 +957,6 @@ void fgPlatformGlutFullScreen( SFG_Window *win ) { #if(WINVER >= 0x0500) /* Windows 2000 or later */ - DWORD s; RECT rect; HMONITOR hMonitor; MONITORINFO mi; @@ -923,17 +968,25 @@ void fgPlatformGlutFullScreen( SFG_Window *win ) */ - /* store current window rect */ - GetWindowRect( win->Window.Handle, &win->State.pWState.OldRect ); + /* save current window rect, style, exstyle and maximized state */ + win->State.pWState.OldMaximized = !!IsZoomed(win->Window.Handle); + if (win->State.pWState.OldMaximized) + /* We force the window into restored mode before going + * fullscreen because Windows doesn't seem to hide the + * taskbar if the window is in the maximized state. + */ + SendMessage(win->Window.Handle, WM_SYSCOMMAND, SC_RESTORE, 0); - /* store current window style */ - win->State.pWState.OldStyle = s = GetWindowLong(win->Window.Handle, GWL_STYLE); + GetWindowRect( win->Window.Handle, &win->State.pWState.OldRect ); + win->State.pWState.OldStyle = GetWindowLong(win->Window.Handle, GWL_STYLE); + win->State.pWState.OldStyleEx = GetWindowLong(win->Window.Handle, GWL_EXSTYLE); - /* 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); + /* remove decorations from style */ + SetWindowLong(win->Window.Handle, GWL_STYLE, + win->State.pWState.OldStyle & ~(WS_CAPTION | WS_THICKFRAME)); + SetWindowLong(win->Window.Handle, GWL_EXSTYLE, + win->State.pWState.OldStyleEx & ~(WS_EX_DLGMODALFRAME | + WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); /* For fullscreen mode, find the monitor that is covered the most * by the window and get its rect as the resize target. @@ -995,7 +1048,7 @@ void fgPlatformGlutLeaveFullScreen( SFG_Window *win ) /* 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); + SetWindowLong(win->Window.Handle, GWL_EXSTYLE, win->State.pWState.OldStyleEx); /* Then resize */ SetWindowPos(win->Window.Handle, @@ -1008,6 +1061,9 @@ void fgPlatformGlutLeaveFullScreen( SFG_Window *win ) SWP_NOZORDER ); + if (win->State.pWState.OldMaximized) + SendMessage(win->Window.Handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0); + win->State.IsFullscreen = GL_FALSE; #endif }