/*
- * freeglut_main_mswin.c
+ * fg_main_mswin.c
*
* The Windows-specific mouse cursor related stuff.
*
-# if(_WIN32_WINNT >= 0x0500)
+# if(_WIN32_WINNT >= 0x0500) && defined(WM_NCXBUTTONDOWN)
DEFINE_MESSAGE(WM_NCXBUTTONDOWN),
DEFINE_MESSAGE(WM_NCXBUTTONUP),
DEFINE_MESSAGE(WM_NCXBUTTONDBLCLK),
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),
# 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),
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 */
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 */
/* Check whether a button (VK_*BUTTON) is currently depressed. Returns
* non-zero (not necessarily 1) if yes. */
-static SHORT fgGetAsyncKeyState(int vKey)
+static SHORT fgGetKeyState(int vKey)
{
- /* MSDN says: "If the most significant bit is set, the key is down, and if
- * the least significant bit is set, the key was pressed after the previous
- * call to GetAsyncKeyState." This behavior cannot be relied upon however.
- * Remove this bit so that we can simply test with ! if key is up.
- */
- return GetAsyncKeyState(vKey) & ~1;
+ /* 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)
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 && fgGetAsyncKeyState ( winKey ))\
+#define FG_KEY_EVENT(winKey,glutKey,keyStateVar)\
+ if (!keyStateVar && fgGetKeyState ( winKey ))\
{\
keypress = glutKey;\
keyStateVar = 1;\
}\
- else if (keyStateVar && !fgGetAsyncKeyState ( 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: */
/* 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);
/* 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;
SetCapture ( window->Window.Handle ) ;
setCaptureActive = 1; /* Set to false in WM_CAPTURECHANGED handler */
}
- else if (!fgGetAsyncKeyState(VK_LBUTTON) && !fgGetAsyncKeyState(VK_MBUTTON) && !fgGetAsyncKeyState(VK_RBUTTON))
+ else if (!fgGetKeyState(VK_LBUTTON) && !fgGetKeyState(VK_MBUTTON) && !fgGetKeyState(VK_RBUTTON))
/* Make sure all mouse buttons are released before releasing capture */
ReleaseCapture () ;
*/
#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 );
break;
}
#endif
+ //Added by Jinrong Xie (stonexjr@gmail.com) 12/24/2014
+ //for SpaceNavigator support on Windows.
+ case WM_INPUT:
+ if (fgHasSpaceball())
+ {
+ fgSpaceballHandleWinEvent(hWnd, wParam, lParam);
+ }
+ break;
default:
/* Handle unhandled messages */
lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
/* 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;
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
+}