X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_main_mswin.c;h=6d286e75142f2225d7e5c0178647791f0f5cdd56;hb=226cd5ccd0f86cc1f2741e686fcf8e4846acf867;hp=8162a5fbe8aca5ee1dad8ddec0edb81f19da5d46;hpb=c2de6d3474dc0c697fa0d5c9fd84988896a077ef;p=freeglut diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c index 8162a5f..6d286e7 100644 --- a/src/mswin/fg_main_mswin.c +++ b/src/mswin/fg_main_mswin.c @@ -1,5 +1,5 @@ /* - * freeglut_main_mswin.c + * fg_main_mswin.c * * The Windows-specific mouse cursor related stuff. * @@ -63,7 +63,7 @@ struct GXKeyList gxKeyList; #endif /* _WIN32_WCE */ #ifdef _DEBUG -/* +/* * WM_ message to string, for debugging * This is taken from the 8.0 SDK, so Windows 8 API and everything earlier is included */ @@ -184,7 +184,7 @@ static struct WM_MESSAGE_MAP allMessages[] = -# if(_WIN32_WINNT >= 0x0500) +# if(_WIN32_WINNT >= 0x0500) && defined(WM_NCXBUTTONDOWN) DEFINE_MESSAGE(WM_NCXBUTTONDOWN), DEFINE_MESSAGE(WM_NCXBUTTONUP), DEFINE_MESSAGE(WM_NCXBUTTONDBLCLK), @@ -241,7 +241,7 @@ static struct WM_MESSAGE_MAP allMessages[] = DEFINE_MESSAGE(WM_UNINITMENUPOPUP), DEFINE_MESSAGE(WM_MENUCOMMAND), -# if(_WIN32_WINNT >= 0x0500) +# if(_WIN32_WINNT >= 0x0500) && defined(WM_CHANGEUISTATE) DEFINE_MESSAGE(WM_CHANGEUISTATE), DEFINE_MESSAGE(WM_UPDATEUISTATE), DEFINE_MESSAGE(WM_QUERYUISTATE), @@ -272,7 +272,7 @@ static struct WM_MESSAGE_MAP allMessages[] = # if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) DEFINE_MESSAGE(WM_MOUSEWHEEL), # endif -# if (_WIN32_WINNT >= 0x0500) +# if (_WIN32_WINNT >= 0x0500) && defined(WM_XBUTTONDOWN) DEFINE_MESSAGE(WM_XBUTTONDOWN), DEFINE_MESSAGE(WM_XBUTTONUP), DEFINE_MESSAGE(WM_XBUTTONDBLCLK), @@ -364,7 +364,7 @@ static struct WM_MESSAGE_MAP allMessages[] = DEFINE_MESSAGE(WM_MOUSEHOVER), DEFINE_MESSAGE(WM_MOUSELEAVE), # endif -# if(WINVER >= 0x0500) +# if(WINVER >= 0x0500) && defined(WM_NCMOUSEHOVER) DEFINE_MESSAGE(WM_NCMOUSEHOVER), DEFINE_MESSAGE(WM_NCMOUSELEAVE), # endif /* WINVER >= 0x0500 */ @@ -398,7 +398,7 @@ static struct WM_MESSAGE_MAP allMessages[] = DEFINE_MESSAGE(WM_PRINTCLIENT), # endif /* WINVER >= 0x0400 */ -# if(_WIN32_WINNT >= 0x0500) +# if(_WIN32_WINNT >= 0x0500) && defined(WM_APPCOMMAND) DEFINE_MESSAGE(WM_APPCOMMAND), # endif /* _WIN32_WINNT >= 0x0500 */ @@ -474,7 +474,7 @@ fg_time_t fgPlatformSystemTime ( void ) /* Check if we just wrapped */ if (currTime32 < lastTime32) timeEpoch++; - + lastTime32 = currTime32; return currTime32 | timeEpoch << 32; @@ -542,7 +542,7 @@ static void fghPlatformOnWindowStatusNotify(SFG_Window *window, GLboolean visSta { SFG_Window *saved_window = fgStructure.CurrentWindow; - /* On win32 we only have two states, window displayed and window not displayed (iconified) + /* On win32 we only have two states, window displayed and window not displayed (iconified) * We map these to GLUT_FULLY_RETAINED and GLUT_HIDDEN respectively. */ INVOKE_WCB( *window, WindowStatus, ( visState ? GLUT_FULLY_RETAINED:GLUT_HIDDEN ) ); @@ -578,13 +578,21 @@ static int fgPlatformGetModifiers (void) ( GetKeyState( VK_RMENU ) < 0 )) ? GLUT_ACTIVE_ALT : 0 ); } +/* Check whether a button (VK_*BUTTON) is currently depressed. Returns + * non-zero (not necessarily 1) if yes. */ +static SHORT fgGetKeyState(int vKey) +{ + /* MSDN says: "If the high-order bit is 1, the key is down; otherwise, it is up". */ + return GetKeyState(vKey) & 0xFF00; +} + static LRESULT fghWindowProcKeyPress(SFG_Window *window, UINT uMsg, GLboolean keydown, WPARAM wParam, LPARAM lParam) { static unsigned char lControl = 0, lShift = 0, lAlt = 0, rControl = 0, rShift = 0, rAlt = 0; int keypress = -1; - + /* if keydown, check for repeat */ /* If repeat is globally switched off, it cannot be switched back on per window. * But if it is globally switched on, it can be switched off per window. This matches @@ -593,65 +601,65 @@ static LRESULT fghWindowProcKeyPress(SFG_Window *window, UINT uMsg, GLboolean ke */ if( keydown && ( fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE ) && (HIWORD(lParam) & KF_REPEAT) ) return 1; - + /* Remember the current modifiers state so user can query it from their callback */ fgState.Modifiers = fgPlatformGetModifiers( ); /* Convert the Win32 keystroke codes to GLUTtish way */ -# define KEY(a,b) case a: keypress = b; break; +# define FG_KEY(a,b) case a: keypress = b; break; switch( wParam ) { - KEY( VK_F1, GLUT_KEY_F1 ); - KEY( VK_F2, GLUT_KEY_F2 ); - KEY( VK_F3, GLUT_KEY_F3 ); - KEY( VK_F4, GLUT_KEY_F4 ); - KEY( VK_F5, GLUT_KEY_F5 ); - KEY( VK_F6, GLUT_KEY_F6 ); - KEY( VK_F7, GLUT_KEY_F7 ); - KEY( VK_F8, GLUT_KEY_F8 ); - KEY( VK_F9, GLUT_KEY_F9 ); - KEY( VK_F10, GLUT_KEY_F10 ); - KEY( VK_F11, GLUT_KEY_F11 ); - KEY( VK_F12, GLUT_KEY_F12 ); - KEY( VK_PRIOR, GLUT_KEY_PAGE_UP ); - KEY( VK_NEXT, GLUT_KEY_PAGE_DOWN ); - KEY( VK_HOME, GLUT_KEY_HOME ); - KEY( VK_END, GLUT_KEY_END ); - KEY( VK_LEFT, GLUT_KEY_LEFT ); - KEY( VK_UP, GLUT_KEY_UP ); - KEY( VK_RIGHT, GLUT_KEY_RIGHT ); - KEY( VK_DOWN, GLUT_KEY_DOWN ); - KEY( VK_INSERT, GLUT_KEY_INSERT ); + FG_KEY( VK_F1, GLUT_KEY_F1 ); + FG_KEY( VK_F2, GLUT_KEY_F2 ); + FG_KEY( VK_F3, GLUT_KEY_F3 ); + FG_KEY( VK_F4, GLUT_KEY_F4 ); + FG_KEY( VK_F5, GLUT_KEY_F5 ); + FG_KEY( VK_F6, GLUT_KEY_F6 ); + FG_KEY( VK_F7, GLUT_KEY_F7 ); + FG_KEY( VK_F8, GLUT_KEY_F8 ); + FG_KEY( VK_F9, GLUT_KEY_F9 ); + FG_KEY( VK_F10, GLUT_KEY_F10 ); + FG_KEY( VK_F11, GLUT_KEY_F11 ); + FG_KEY( VK_F12, GLUT_KEY_F12 ); + FG_KEY( VK_PRIOR, GLUT_KEY_PAGE_UP ); + FG_KEY( VK_NEXT, GLUT_KEY_PAGE_DOWN ); + FG_KEY( VK_HOME, GLUT_KEY_HOME ); + FG_KEY( VK_END, GLUT_KEY_END ); + FG_KEY( VK_LEFT, GLUT_KEY_LEFT ); + FG_KEY( VK_UP, GLUT_KEY_UP ); + FG_KEY( VK_RIGHT, GLUT_KEY_RIGHT ); + FG_KEY( VK_DOWN, GLUT_KEY_DOWN ); + FG_KEY( VK_INSERT, GLUT_KEY_INSERT ); /* handle control, alt and shift. For GLUT, we want to distinguish between left and right presses. * The VK_L* & VK_R* left and right Alt, Ctrl and Shift virtual keys are however only used as parameters to GetAsyncKeyState() and GetKeyState() * so when we get an alt, shift or control keypress here, we manually check whether it was the left or the right */ -#define ASYNC_KEY_EVENT(winKey,glutKey,keyStateVar)\ - if (!keyStateVar && GetAsyncKeyState ( winKey ))\ +#define FG_KEY_EVENT(winKey,glutKey,keyStateVar)\ + if (!keyStateVar && fgGetKeyState ( winKey ))\ {\ keypress = glutKey;\ keyStateVar = 1;\ }\ - else if (keyStateVar && !GetAsyncKeyState ( winKey ))\ + else if (keyStateVar && !fgGetKeyState ( winKey ))\ {\ keypress = glutKey;\ keyStateVar = 0;\ } case VK_CONTROL: - ASYNC_KEY_EVENT(VK_LCONTROL,GLUT_KEY_CTRL_L,lControl); - ASYNC_KEY_EVENT(VK_RCONTROL,GLUT_KEY_CTRL_R,rControl); + FG_KEY_EVENT(VK_LCONTROL,GLUT_KEY_CTRL_L,lControl); + FG_KEY_EVENT(VK_RCONTROL,GLUT_KEY_CTRL_R,rControl); break; case VK_SHIFT: - ASYNC_KEY_EVENT(VK_LSHIFT,GLUT_KEY_SHIFT_L,lShift); - ASYNC_KEY_EVENT(VK_RSHIFT,GLUT_KEY_SHIFT_R,rShift); + FG_KEY_EVENT(VK_LSHIFT,GLUT_KEY_SHIFT_L,lShift); + FG_KEY_EVENT(VK_RSHIFT,GLUT_KEY_SHIFT_R,rShift); break; case VK_MENU: - ASYNC_KEY_EVENT(VK_LMENU,GLUT_KEY_ALT_L,lAlt); - ASYNC_KEY_EVENT(VK_RMENU,GLUT_KEY_ALT_R,rAlt); + FG_KEY_EVENT(VK_LMENU,GLUT_KEY_ALT_L,lAlt); + FG_KEY_EVENT(VK_RMENU,GLUT_KEY_ALT_R,rAlt); break; -#undef ASYNC_KEY_EVENT +#undef KEY_EVENT case VK_DELETE: /* The delete key should be treated as an ASCII keypress: */ @@ -707,7 +715,7 @@ static LRESULT fghWindowProcKeyPress(SFG_Window *window, UINT uMsg, GLboolean ke keypress = GLUT_KEY_F4; } #endif - + if( keypress != -1 ) if (keydown) INVOKE_WCB( *window, Special, @@ -744,9 +752,11 @@ SFG_Window* fghWindowUnderCursor(SFG_Window *window) /* Get mouse position at time of message */ DWORD mouse_pos_dw = GetMessagePos(); - POINT mouse_pos = {GET_X_LPARAM(mouse_pos_dw), GET_Y_LPARAM(mouse_pos_dw)}; + POINT mouse_pos; + mouse_pos.x = GET_X_LPARAM(mouse_pos_dw); + mouse_pos.y = GET_Y_LPARAM(mouse_pos_dw); ScreenToClient( window->Window.Handle, &mouse_pos ); - + hwnd = ChildWindowFromPoint(window->Window.Handle, mouse_pos); if (hwnd && hwnd!=window->Window.Handle) /* can be NULL if mouse outside parent by the time we get here, or can be same as parent if we didn't find a child */ { @@ -864,7 +874,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR /* Update visibility state of the window */ if (wParam==SIZE_MINIMIZED) fghPlatformOnWindowStatusNotify(window,GL_FALSE,GL_FALSE); - else if (wParam==SIZE_RESTORED && !window->State.Visible) + else if ((wParam==SIZE_RESTORED || wParam == SIZE_MAXIMIZED) && !window->State.Visible) fghPlatformOnWindowStatusNotify(window,GL_TRUE,GL_FALSE); /* Check window visible, we don't want do anything when we get a WM_SIZE because the user or glutIconifyWindow minimized the window */ @@ -878,7 +888,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR width = LOWORD(lParam); height = HIWORD(lParam); #endif /* defined(_WIN32_WCE) */ - + /* Update state and call callback, if there was a change */ fghOnReshapeNotify(window, width, height, GL_FALSE); } @@ -925,21 +935,23 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR if (!IsIconic(window->Window.Handle)) { RECT windowRect; - + /* lParam contains coordinates of top-left of client area. * Get top-left of non-client area of window, matching coordinates of - * glutInitPosition and glutPositionWindow, but not those of + * glutInitPosition and glutPositionWindow, but not those of * glutGet(GLUT_WINDOW_X) and glutGet(GLUT_WINDOW_Y), which return * top-left of client area. */ GetWindowRect( window->Window.Handle, &windowRect ); - + if (window->Parent) { /* For child window, we should return relative to upper-left * of parent's client area. */ - POINT topleft = {windowRect.left,windowRect.top}; + POINT topleft; + topleft.x = windowRect.left; + topleft.y = windowRect.top; ScreenToClient(window->Parent->Window.Handle,&topleft); windowRect.left = topleft.x; @@ -1019,7 +1031,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR { TRACKMOUSEEVENT tme; - /* Cursor just entered window, set cursor look */ + /* Cursor just entered window, set cursor look */ fgSetCursor ( window, window->State.Cursor ) ; /* If an EntryFunc callback is specified by the user, also @@ -1078,7 +1090,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR case WM_PAINT: { RECT rect; - + /* As per docs, upon receiving WM_PAINT, first check if the update region is not empty before you call BeginPaint */ if (GetUpdateRect(hWnd,&rect,FALSE)) { @@ -1237,7 +1249,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR SetCapture ( window->Window.Handle ) ; setCaptureActive = 1; /* Set to false in WM_CAPTURECHANGED handler */ } - else if (!GetAsyncKeyState(VK_LBUTTON) && !GetAsyncKeyState(VK_MBUTTON) && !GetAsyncKeyState(VK_RBUTTON)) + else if (!fgGetKeyState(VK_LBUTTON) && !fgGetKeyState(VK_MBUTTON) && !fgGetKeyState(VK_RBUTTON)) /* Make sure all mouse buttons are released before releasing capture */ ReleaseCapture () ; @@ -1267,7 +1279,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR { int wheel_number = 0; /* Only one scroll wheel on windows */ #if defined(_WIN32_WCE) - int modkeys = LOWORD(wParam); + int modkeys = LOWORD(wParam); short ticks = (short)HIWORD(wParam); /* commented out as should not be needed here, mouse motion is processed in WM_MOUSEMOVE first: xPos = LOWORD(lParam); -- straight from docs, not consistent with mouse nutton and mouse motion above (which i think is wrong) @@ -1275,7 +1287,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR */ #else /* int modkeys = GET_KEYSTATE_WPARAM( wParam ); */ - short ticks = GET_WHEEL_DELTA_WPARAM( wParam ); + short ticks = HIWORD( wParam ); /* commented out as should not be needed here, mouse motion is processed in WM_MOUSEMOVE first: window->State.MouseX = GET_X_LPARAM( lParam ); window->State.MouseY = GET_Y_LPARAM( lParam ); @@ -1284,10 +1296,10 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR window = fghWindowUnderCursor(window); - fgState.MouseWheelTicks += ticks; + fgState.MouseWheelTicks += ticks; if ( abs ( fgState.MouseWheelTicks ) >= WHEEL_DELTA ) - { - int direction = ( fgState.MouseWheelTicks > 0 ) ? 1 : -1; + { + int direction = ( fgState.MouseWheelTicks > 0 ) ? 1 : -1; if( ! FETCH_WCB( *window, MouseWheel ) && ! FETCH_WCB( *window, Mouse ) ) @@ -1297,7 +1309,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR fgState.Modifiers = fgPlatformGetModifiers( ); while( abs ( fgState.MouseWheelTicks ) >= WHEEL_DELTA ) - { + { if( FETCH_WCB( *window, MouseWheel ) ) INVOKE_WCB( *window, MouseWheel, ( wheel_number, @@ -1307,7 +1319,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR ) ); else /* No mouse wheel, call the mouse button callback twice */ - { + { /* * Map wheel zero to button 3 and 4; +1 to 3, -1 to 4 * " " one +1 to 5, -1 to 6, ... @@ -1326,13 +1338,13 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR ( button, GLUT_UP, window->State.MouseX, window->State.MouseY ) ); - } + } - fgState.MouseWheelTicks -= WHEEL_DELTA * direction; - } + fgState.MouseWheelTicks -= WHEEL_DELTA * direction; + } fgState.Modifiers = INVALID_MODIFIERS; - } + } /* Per docs, should return zero */ lRet = 0; } @@ -1486,50 +1498,60 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR break; #ifdef WM_TOUCH - /* handle multi-touch messages */ - case WM_TOUCH: - { - unsigned int numInputs = (unsigned int)wParam; - unsigned int i = 0; - TOUCHINPUT* ti = (TOUCHINPUT*)malloc( sizeof(TOUCHINPUT)*numInputs); - - if (fghGetTouchInputInfo == (pGetTouchInputInfo)0xDEADBEEF) { - fghGetTouchInputInfo = (pGetTouchInputInfo)GetProcAddress(GetModuleHandle("user32"),"GetTouchInputInfo"); - fghCloseTouchInputHandle = (pCloseTouchInputHandle)GetProcAddress(GetModuleHandle("user32"),"CloseTouchInputHandle"); - } - - if (!fghGetTouchInputInfo) { - free( (void*)ti ); - break; - } - - if (fghGetTouchInputInfo( (HTOUCHINPUT)lParam, numInputs, ti, sizeof(TOUCHINPUT) )) { - /* Handle each contact point */ - for (i = 0; i < numInputs; ++i ) { - - POINT tp; - tp.x = TOUCH_COORD_TO_PIXEL(ti[i].x); - tp.y = TOUCH_COORD_TO_PIXEL(ti[i].y); - ScreenToClient( hWnd, &tp ); - - ti[i].dwID = ti[i].dwID * 2; - - if (ti[i].dwFlags & TOUCHEVENTF_DOWN) { - INVOKE_WCB( *window, MultiEntry, ( ti[i].dwID, GLUT_ENTERED ) ); - INVOKE_WCB( *window, MultiButton, ( ti[i].dwID, tp.x, tp.y, 0, GLUT_DOWN ) ); - } else if (ti[i].dwFlags & TOUCHEVENTF_MOVE) { - INVOKE_WCB( *window, MultiMotion, ( ti[i].dwID, tp.x, tp.y ) ); - } else if (ti[i].dwFlags & TOUCHEVENTF_UP) { - INVOKE_WCB( *window, MultiButton, ( ti[i].dwID, tp.x, tp.y, 0, GLUT_UP ) ); - INVOKE_WCB( *window, MultiEntry, ( ti[i].dwID, GLUT_LEFT ) ); - } - } - } - fghCloseTouchInputHandle((HTOUCHINPUT)lParam); - free( (void*)ti ); - lRet = 0; /*DefWindowProc( hWnd, uMsg, wParam, lParam );*/ - break; - } + /* handle multi-touch messages */ + case WM_TOUCH: + { + unsigned int numInputs = (unsigned int)wParam; + unsigned int i = 0; + TOUCHINPUT* ti = (TOUCHINPUT*)malloc( sizeof(TOUCHINPUT)*numInputs); + + if (fghGetTouchInputInfo == (pGetTouchInputInfo)0xDEADBEEF) { + fghGetTouchInputInfo = (pGetTouchInputInfo)GetProcAddress(GetModuleHandle("user32"),"GetTouchInputInfo"); + fghCloseTouchInputHandle = (pCloseTouchInputHandle)GetProcAddress(GetModuleHandle("user32"),"CloseTouchInputHandle"); + } + + if (!fghGetTouchInputInfo) { + free( (void*)ti ); + break; + } + + if (fghGetTouchInputInfo( (HTOUCHINPUT)lParam, numInputs, ti, sizeof(TOUCHINPUT) )) { + /* Handle each contact point */ + for (i = 0; i < numInputs; ++i ) { + + POINT tp; + tp.x = TOUCH_COORD_TO_PIXEL(ti[i].x); + tp.y = TOUCH_COORD_TO_PIXEL(ti[i].y); + ScreenToClient( hWnd, &tp ); + + ti[i].dwID = ti[i].dwID * 2; + + if (ti[i].dwFlags & TOUCHEVENTF_DOWN) { + INVOKE_WCB( *window, MultiEntry, ( ti[i].dwID, GLUT_ENTERED ) ); + INVOKE_WCB( *window, MultiButton, ( ti[i].dwID, tp.x, tp.y, 0, GLUT_DOWN ) ); + } else if (ti[i].dwFlags & TOUCHEVENTF_MOVE) { + INVOKE_WCB( *window, MultiMotion, ( ti[i].dwID, tp.x, tp.y ) ); + } else if (ti[i].dwFlags & TOUCHEVENTF_UP) { + INVOKE_WCB( *window, MultiButton, ( ti[i].dwID, tp.x, tp.y, 0, GLUT_UP ) ); + INVOKE_WCB( *window, MultiEntry, ( ti[i].dwID, GLUT_LEFT ) ); + } + } + } + fghCloseTouchInputHandle((HTOUCHINPUT)lParam); + free( (void*)ti ); + lRet = 0; /*DefWindowProc( hWnd, uMsg, wParam, lParam );*/ + break; + } +#endif + +#ifdef WM_INPUT + case WM_INPUT: + /* Added by Jinrong Xie for SpaceNavigator support on Windows. Dec 2014 */ + if (fgHasSpaceball()) + { + fgSpaceballHandleWinEvent(hWnd, wParam, lParam); + } + break; #endif default: /* Handle unhandled messages */ @@ -1593,7 +1615,7 @@ void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask) window->State.DesiredWidth = window->State.pWState.OldRect.right - window->State.pWState.OldRect.left; window->State.DesiredHeight = window->State.pWState.OldRect.bottom - window->State.pWState.OldRect.top; } - + /* We'll finish off the fullscreen operation below after the other GLUT_POSITION_WORK|GLUT_SIZE_WORK|GLUT_ZORDER_WORK */ } else @@ -1604,7 +1626,8 @@ void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask) RECT rect; HMONITOR hMonitor; MONITORINFO mi; - + DWORD newStyle; + /* save current window rect, style, exstyle and maximized state */ window->State.pWState.OldMaximized = !!IsZoomed(window->Window.Handle); if (window->State.pWState.OldMaximized) @@ -1619,17 +1642,22 @@ void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask) window->State.pWState.OldStyleEx = GetWindowLong(window->Window.Handle, GWL_EXSTYLE); /* remove decorations from style */ - SetWindowLong(window->Window.Handle, GWL_STYLE, - window->State.pWState.OldStyle & ~(WS_CAPTION | WS_THICKFRAME)); + newStyle = window->State.pWState.OldStyle & ~(WS_CAPTION | WS_THICKFRAME); + if (fgState.DisplayMode & GLUT_STEREO) + { + /* stereo mode does not engage on nVidia stereo buffers. This kills child + windows, but we make the guess that those are rare for stereo windows. */ + newStyle |= WS_POPUP; + } + SetWindowLong(window->Window.Handle, GWL_STYLE, newStyle); SetWindowLong(window->Window.Handle, GWL_EXSTYLE, window->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. - */ - GetWindowRect(window->Window.Handle, &rect); - hMonitor= MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST); + */ + hMonitor= MonitorFromWindow(window->Window.Handle, MONITOR_DEFAULTTONEAREST); mi.cbSize = sizeof(mi); GetMonitorInfo(hMonitor, &mi); rect = mi.rcMonitor; @@ -1647,7 +1675,7 @@ void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask) /* Now deal with normal position, reshape and z order requests (some might have been set when handling GLUT_FULLSCREEN_WORK above */ { - /* get rect describing window's current position and size, + /* get rect describing window's current position and size, * in screen coordinates and in FreeGLUT format * (size (right-left, bottom-top) is client area size, top and left * are outside of window including decorations). @@ -1657,7 +1685,7 @@ void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask) if (workMask & GLUT_POSITION_WORK) { flags &= ~SWP_NOMOVE; - + /* Move rect so that top-left is at requested position */ /* This also automatically makes sure that child window requested coordinates are relative * to top-left of parent's client area (needed input for SetWindowPos on child windows), @@ -1668,7 +1696,7 @@ void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask) if (workMask & GLUT_SIZE_WORK) { flags &= ~SWP_NOSIZE; - + /* 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 @@ -1703,7 +1731,7 @@ void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask) if (!window->Parent) /* get the window rect from this to feed to SetWindowPos, correct for window decorations */ fghComputeWindowRectFromClientArea_QueryWindow(&clientRect,window,TRUE); - + /* Do the requested positioning, moving, and z order push/pop. */ SetWindowPos( window->Window.Handle, insertAfter, @@ -1747,12 +1775,12 @@ void fgPlatformVisibilityWork(SFG_Window* window) win = win->Parent; break; case DesireNormalState: - if (win->IsMenu && (!fgStructure.GameModeWindow || win->ActiveMenu->ParentWindow != fgStructure.GameModeWindow)) - cmdShow = SW_SHOWNA; /* Just show, don't activate window if its a menu. Only exception is when the parent is a gamemode window as the menu would pop under it when we do this... */ + if (win->IsMenu && !fgStructure.GameModeWindow) + cmdShow = SW_SHOWNA; /* Just show, don't activate window if its a menu. Only exception is when there is a gamemode window as the menu would pop under it when we do this... */ else cmdShow = SW_SHOW; break; } ShowWindow( win->Window.Handle, cmdShow ); -} \ No newline at end of file +}