X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_window_mswin.c;h=69a698da296de7c272d44b317fe799686d91e9a2;hb=b1ed93dd348f7b8f3bd2c75474f5d4151d502f1f;hp=ae30001537e14affce9f5f26f6673840ed13aa7a;hpb=9a83e1923241a52132e87f333184433067456097;p=freeglut diff --git a/src/mswin/fg_window_mswin.c b/src/mswin/fg_window_mswin.c index ae30001..69a698d 100644 --- a/src/mswin/fg_window_mswin.c +++ b/src/mswin/fg_window_mswin.c @@ -1,5 +1,5 @@ /* - * freeglut_window_mswin.c + * fg_window_mswin.c * * The Windows-specific mouse cursor related stuff. * @@ -233,13 +233,13 @@ static void fghFillPFD( PIXELFORMATDESCRIPTOR *ppfd, HDC hdc, unsigned char laye ppfd->cDepthBits = 24; ppfd->cStencilBits = 8; - ppfd->cAuxBuffers = fghNumberOfAuxBuffersRequested(); + ppfd->cAuxBuffers = (BYTE) fghNumberOfAuxBuffersRequested(); ppfd->iLayerType = layer_type; ppfd->bReserved = 0; ppfd->dwLayerMask = 0; ppfd->dwVisibleMask = 0; ppfd->dwDamageMask = 0; - + ppfd->cColorBits = (BYTE) GetDeviceCaps( hdc, BITSPIXEL ); } @@ -291,7 +291,7 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, /* windows hack for multismapling/sRGB */ if ( ( fgState.DisplayMode & GLUT_MULTISAMPLE ) || ( fgState.DisplayMode & GLUT_SRGB ) ) - { + { HGLRC rc, rc_before=wglGetCurrentContext(); HWND hWnd; HDC hDC, hDC_before=wglGetCurrentDC(); @@ -405,7 +405,6 @@ void fghGetStyleFromWindow( const SFG_Window *window, DWORD *windowStyle, DWORD } } - /* Computes position of corners of window Rect (outer position including * decorations) based on the provided client rect and based on the style * of the window in question. @@ -431,7 +430,7 @@ void fghComputeWindowRectFromClientArea_UseStyle( RECT *clientRect, const DWORD windowRect.left = clientRect->left; windowRect.top = clientRect->top; } - + /* done, copy windowRect to output */ CopyRect(clientRect,&windowRect); } @@ -454,50 +453,41 @@ void fghComputeWindowRectFromClientArea_QueryWindow( RECT *clientRect, const SFG fghComputeWindowRectFromClientArea_UseStyle(clientRect, windowStyle, windowExStyle, posIsOutside); } - /* 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. + * if posIsOutside is 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) remains to be the + * size of the drawable area. */ -void fghGetClientArea( RECT *clientRect, const SFG_Window *window, BOOL wantPosOutside ) +void fghGetClientArea( RECT *clientRect, const SFG_Window *window, BOOL posIsOutside ) { 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) + if (posIsOutside) { - clientRect->left = topLeftWindow.x; - clientRect->top = topLeftWindow.y; + RECT windowRect; + /* Get position of outside of window, including decorations */ + GetWindowRect(window->Window.Handle,&windowRect); + /* Add top-left offset */ + OffsetRect(clientRect,windowRect.left,windowRect.top); + } + else + { + /* 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); } } + #if(WINVER >= 0x500) typedef struct { @@ -507,9 +497,9 @@ typedef struct } m_proc_t; static BOOL CALLBACK m_proc(HMONITOR mon, - HDC hdc, - LPRECT rect, - LPARAM data) + HDC hdc, + LPRECT rect, + LPARAM data) { m_proc_t *dp=(m_proc_t *)data; MONITORINFOEX info; @@ -528,7 +518,7 @@ static BOOL CALLBACK m_proc(HMONITOR mon, return TRUE; } -/* +/* * this function returns the origin of the screen identified by * fgDisplay.pDisplay.DisplayName, and 0 otherwise. * This is used in fgOpenWindow to open the gamemode window on the screen @@ -580,7 +570,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, WNDCLASS wc; DWORD flags = 0; DWORD exFlags = 0; - ATOM atom; + BOOL atom; /* Grab the window class we have registered on glutInit(): */ atom = GetClassInfo( fgDisplay.pDisplay.Instance, _T("FREEGLUT"), &wc ); @@ -646,20 +636,11 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, } 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 */ + w = CW_USEDEFAULT; + h = CW_USEDEFAULT; } - /* store requested client area width and height */ - window->State.Width = w; - window->State.Height = h; - -#if !defined(_WIN32_WCE) /* no decorations for windows CE */ - if( sizeUse ) +#if !defined(_WIN32_WCE) /* no decorations for windows CE, so nothing to do */ + else { RECT windowRect; /* @@ -721,9 +702,14 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, ); #endif /* defined(_WIN32_WCE) */ + /* WM_CREATE message got sent and was handled by window proc */ + if( !( window->Window.Handle ) ) fgError( "Failed to create a window (%s)!", title ); + /* Store title */ + window->State.pWState.WindowTitle = strdup(title); + #if !defined(_WIN32_WCE) /* Need to set requested style again, apparently Windows doesn't listen when requesting windows without title bar or borders */ SetWindowLong(window->Window.Handle, GWL_STYLE, flags); @@ -741,89 +727,24 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, /* Enable multitouch: additional flag TWF_FINETOUCH, TWF_WANTPALM */ #ifdef WM_TOUCH - if (fghRegisterTouchWindow == (pRegisterTouchWindow)0xDEADBEEF) - fghRegisterTouchWindow = (pRegisterTouchWindow)GetProcAddress(GetModuleHandle("user32"),"RegisterTouchWindow"); - if (fghRegisterTouchWindow) + if (fghRegisterTouchWindow == (pRegisterTouchWindow)0xDEADBEEF) + fghRegisterTouchWindow = (pRegisterTouchWindow)GetProcAddress(GetModuleHandle("user32"),"RegisterTouchWindow"); + if (fghRegisterTouchWindow) fghRegisterTouchWindow( window->Window.Handle, TWF_FINETOUCH | TWF_WANTPALM ); #endif #if defined(_WIN32_WCE) ShowWindow( window->Window.Handle, SW_SHOW ); #else - ShowWindow( window->Window.Handle, - fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW ); -#endif /* defined(_WIN32_WCE) */ - - UpdateWindow( window->Window.Handle ); - ShowCursor( TRUE ); /* XXX Old comments say "hide cursor"! */ -} - - -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 + if (!window->IsMenu) /* Don't show window after creation if its a menu */ { - /* 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, FALSE ); - OffsetRect(&windowRect,-parentRect.left,-parentRect.top); + BOOL iconic = fgState.ForceIconic && !gameMode && !isSubWindow; + ShowWindow( window->Window.Handle, + iconic ? SW_SHOWMINIMIZED : SW_SHOWNORMAL ); } - - /* 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 - ); +#endif /* defined(_WIN32_WCE) */ - /* 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; + ShowCursor( TRUE ); } @@ -858,33 +779,23 @@ void fgPlatformCloseWindow( SFG_Window* window ) } DestroyWindow( window->Window.Handle ); -} - - -/* - * This function makes the current window visible - */ -void fgPlatformGlutShowWindow( void ) -{ - ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_SHOW ); + /* clean up copied title text(s) */ + if (window->State.pWState.WindowTitle) + free(window->State.pWState.WindowTitle); + if (window->State.pWState.IconTitle) + free(window->State.pWState.IconTitle); } /* - * This function hides the current window + * Hide's specified window. For windows, currently only used + * to immediately hide menu windows... */ -void fgPlatformGlutHideWindow( void ) +void fgPlatformHideWindow( SFG_Window* window ) { - ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_HIDE ); + ShowWindow(window->Window.Handle, SW_HIDE); } -/* - * Iconify the current window (top-level windows only) - */ -void fgPlatformGlutIconifyWindow( void ) -{ - ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_MINIMIZE ); -} /* * Set the current window's title @@ -898,208 +809,30 @@ void fgPlatformGlutSetWindowTitle( const char* title ) free(wstr); } #else - SetWindowText( fgStructure.CurrentWindow->Window.Handle, title ); + if (!IsIconic(fgStructure.CurrentWindow->Window.Handle)) + SetWindowText( fgStructure.CurrentWindow->Window.Handle, title ); #endif + + /* Make copy of string to refer to later */ + if (fgStructure.CurrentWindow->State.pWState.WindowTitle) + free(fgStructure.CurrentWindow->State.pWState.WindowTitle); + fgStructure.CurrentWindow->State.pWState.WindowTitle = strdup(title); } /* * Set the current window's iconified title - * There really isn't a way to set the icon name separate from the - * windows name in Win32, so, just set the windows name. */ void fgPlatformGlutSetIconTitle( const char* title ) { -#ifdef _WIN32_WCE - { - wchar_t* wstr = fghWstrFromStr(title); - SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr ); - free(wstr); - } -#else - SetWindowText( fgStructure.CurrentWindow->Window.Handle, title ); -#endif -} - -/* - * Change the current window's position - */ -void fgPlatformGlutPositionWindow( int x, int y ) -{ - RECT winRect; - - /* "GetWindowRect" returns the pixel coordinates of the outside of the window */ - GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect ); - MoveWindow( - fgStructure.CurrentWindow->Window.Handle, - x, - y, - winRect.right - winRect.left, - winRect.bottom - winRect.top, - TRUE - ); -} - -/* - * Lowers the current window (by Z order change) - */ -void fgPlatformGlutPushWindow( void ) -{ - SetWindowPos( - fgStructure.CurrentWindow->Window.Handle, - HWND_BOTTOM, - 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE - ); -} - -/* - * Raises the current window (by Z order change) - */ -void fgPlatformGlutPopWindow( void ) -{ - SetWindowPos( - fgStructure.CurrentWindow->Window.Handle, - HWND_TOP, - 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE - ); -} - -/* - * Resize the current window so that it fits the whole screen - */ -void fgPlatformGlutFullScreen( SFG_Window *win ) -{ -#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */ - - if (glutGet(GLUT_FULL_SCREEN)) - { - /* Leave full screen state before entering fullscreen again (resizing?) */ - glutLeaveFullScreen(); - } - - { -#if(WINVER >= 0x0500) /* Windows 2000 or later */ - RECT rect; - HMONITOR hMonitor; - MONITORINFO mi; - - /* For fullscreen mode, first remove all window decoration - * and set style to popup so it will overlap the taskbar - * then force to maximize on the screen on which it has the most - * overlap. - */ - - - /* 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); - - 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 */ - 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. - */ - hMonitor= MonitorFromRect(&win->State.pWState.OldRect, MONITOR_DEFAULTTONEAREST); - mi.cbSize = sizeof(mi); - GetMonitorInfo(hMonitor, &mi); - rect = mi.rcMonitor; -#else /* if (WINVER >= 0x0500) */ - RECT rect; - - /* For fullscreen mode, force the top-left corner to 0,0 - * and adjust the window rectangle so that the client area - * covers the whole screen. - */ - - rect.left = 0; - rect.top = 0; - rect.right = fgDisplay.ScreenWidth; - rect.bottom = fgDisplay.ScreenHeight; - - AdjustWindowRect ( &rect, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | - WS_CLIPCHILDREN, FALSE ); -#endif /* (WINVER >= 0x0500) */ - - /* - * then resize window - * SWP_NOACTIVATE Do not activate the window - * SWP_NOOWNERZORDER Do not change position in z-order - * SWP_NOSENDCHANGING Suppress WM_WINDOWPOSCHANGING message - * SWP_NOZORDER Retains the current Z order (ignore 2nd param) - */ - SetWindowPos( fgStructure.CurrentWindow->Window.Handle, - HWND_TOP, - rect.left, - rect.top, - rect.right - rect.left, - rect.bottom - rect.top, - SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | - SWP_NOZORDER - ); - - win->State.IsFullscreen = GL_TRUE; - } -#endif -} - -/* - * If we are fullscreen, resize the current window back to its original size - */ -void fgPlatformGlutLeaveFullScreen( SFG_Window *win ) -{ -#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */ - if (!glutGet(GLUT_FULL_SCREEN)) - { - /* nothing to do */ - return; - } - - /* restore style of window before making it fullscreen */ - SetWindowLong(win->Window.Handle, GWL_STYLE, win->State.pWState.OldStyle); - SetWindowLong(win->Window.Handle, GWL_EXSTYLE, win->State.pWState.OldStyleEx); - - /* Then resize */ - SetWindowPos(win->Window.Handle, - HWND_TOP, - win->State.pWState.OldRect.left, - win->State.pWState.OldRect.top, - win->State.pWState.OldRect.right - win->State.pWState.OldRect.left, - win->State.pWState.OldRect.bottom - win->State.pWState.OldRect.top, - SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | - SWP_NOZORDER - ); - - if (win->State.pWState.OldMaximized) - SendMessage(win->Window.Handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0); - - win->State.IsFullscreen = GL_FALSE; +#ifndef _WIN32_WCE + if (IsIconic(fgStructure.CurrentWindow->Window.Handle)) + SetWindowText( fgStructure.CurrentWindow->Window.Handle, title ); #endif -} -/* - * Toggle the window's full screen state. - */ -void fgPlatformGlutFullScreenToggle( SFG_Window *win ) -{ - if (!win->State.IsFullscreen) - glutFullScreen(); - else - glutLeaveFullScreen(); + /* Make copy of string to refer to later */ + if (fgStructure.CurrentWindow->State.pWState.IconTitle) + free(fgStructure.CurrentWindow->State.pWState.IconTitle); + fgStructure.CurrentWindow->State.pWState.IconTitle = strdup(title); }