mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 22:09:19 -07:00
394 lines
13 KiB
C++
394 lines
13 KiB
C++
|
///////////////////////////////////////////////////////////
|
||
|
/// Convert a Win32 virtual key code to a SFML key code
|
||
|
////////////////////////////////////////////////////////////
|
||
|
Key::Code VirtualKeyCodeToSF(WPARAM VirtualKey, LPARAM Flags)
|
||
|
{
|
||
|
switch (VirtualKey)
|
||
|
{
|
||
|
// VK_SHIFT is handled by the GetShiftState function
|
||
|
case VK_MENU : return (Flags & (1 << 24)) ? Key::RAlt : Key::LAlt;
|
||
|
case VK_CONTROL : return (Flags & (1 << 24)) ? Key::RControl : Key::LControl;
|
||
|
case VK_LWIN : return Key::LSystem;
|
||
|
case VK_RWIN : return Key::RSystem;
|
||
|
case VK_APPS : return Key::Menu;
|
||
|
case VK_OEM_1 : return Key::SemiColon;
|
||
|
case VK_OEM_2 : return Key::Slash;
|
||
|
case VK_OEM_PLUS : return Key::Equal;
|
||
|
case VK_OEM_MINUS : return Key::Dash;
|
||
|
case VK_OEM_4 : return Key::LBracket;
|
||
|
case VK_OEM_6 : return Key::RBracket;
|
||
|
case VK_OEM_COMMA : return Key::Comma;
|
||
|
case VK_OEM_PERIOD : return Key::Period;
|
||
|
case VK_OEM_7 : return Key::Quote;
|
||
|
case VK_OEM_5 : return Key::BackSlash;
|
||
|
case VK_OEM_3 : return Key::Tilde;
|
||
|
case VK_ESCAPE : return Key::Escape;
|
||
|
case VK_SPACE : return Key::Space;
|
||
|
case VK_RETURN : return Key::Return;
|
||
|
case VK_BACK : return Key::Back;
|
||
|
case VK_TAB : return Key::Tab;
|
||
|
case VK_PRIOR : return Key::PageUp;
|
||
|
case VK_NEXT : return Key::PageDown;
|
||
|
case VK_END : return Key::End;
|
||
|
case VK_HOME : return Key::Home;
|
||
|
case VK_INSERT : return Key::Insert;
|
||
|
case VK_DELETE : return Key::Delete;
|
||
|
case VK_ADD : return Key::Add;
|
||
|
case VK_SUBTRACT : return Key::Subtract;
|
||
|
case VK_MULTIPLY : return Key::Multiply;
|
||
|
case VK_DIVIDE : return Key::Divide;
|
||
|
case VK_PAUSE : return Key::Pause;
|
||
|
case VK_F1 : return Key::F1;
|
||
|
case VK_F2 : return Key::F2;
|
||
|
case VK_F3 : return Key::F3;
|
||
|
case VK_F4 : return Key::F4;
|
||
|
case VK_F5 : return Key::F5;
|
||
|
case VK_F6 : return Key::F6;
|
||
|
case VK_F7 : return Key::F7;
|
||
|
case VK_F8 : return Key::F8;
|
||
|
case VK_F9 : return Key::F9;
|
||
|
case VK_F10 : return Key::F10;
|
||
|
case VK_F11 : return Key::F11;
|
||
|
case VK_F12 : return Key::F12;
|
||
|
case VK_F13 : return Key::F13;
|
||
|
case VK_F14 : return Key::F14;
|
||
|
case VK_F15 : return Key::F15;
|
||
|
case VK_RIGHT : return Key::Right;
|
||
|
case VK_UP : return Key::Up;
|
||
|
case VK_DOWN : return Key::Down;
|
||
|
case VK_NUMPAD0 : return Key::Numpad0;
|
||
|
case VK_NUMPAD1 : return Key::Numpad1;
|
||
|
case VK_NUMPAD2 : return Key::Numpad2;
|
||
|
case VK_NUMPAD3 : return Key::Numpad3;
|
||
|
case VK_NUMPAD4 : return Key::Numpad4;
|
||
|
case VK_NUMPAD5 : return Key::Numpad5;
|
||
|
case VK_NUMPAD6 : return Key::Numpad6;
|
||
|
case VK_NUMPAD7 : return Key::Numpad7;
|
||
|
case VK_NUMPAD8 : return Key::Numpad8;
|
||
|
case VK_NUMPAD9 : return Key::Numpad9;
|
||
|
case 'A' : return Key::A;
|
||
|
case 'Z' : return Key::Z;
|
||
|
case 'E' : return Key::E;
|
||
|
case 'R' : return Key::R;
|
||
|
case 'T' : return Key::T;
|
||
|
case 'Y' : return Key::Y;
|
||
|
case 'U' : return Key::U;
|
||
|
case 'I' : return Key::I;
|
||
|
case 'O' : return Key::O;
|
||
|
case 'P' : return Key::P;
|
||
|
case 'Q' : return Key::Q;
|
||
|
case 'S' : return Key::S;
|
||
|
case 'D' : return Key::D;
|
||
|
case 'F' : return Key::F;
|
||
|
case 'G' : return Key::G;
|
||
|
case 'H' : return Key::H;
|
||
|
case 'J' : return Key::J;
|
||
|
case 'K' : return Key::K;
|
||
|
case 'L' : return Key::L;
|
||
|
case 'M' : return Key::M;
|
||
|
case 'W' : return Key::W;
|
||
|
case 'X' : return Key::X;
|
||
|
case 'C' : return Key::C;
|
||
|
case 'V' : return Key::V;
|
||
|
case 'B' : return Key::B;
|
||
|
case 'N' : return Key::N;
|
||
|
case '0' : return Key::Num0;
|
||
|
case '1' : return Key::Num1;
|
||
|
case '2' : return Key::Num2;
|
||
|
case '3' : return Key::Num3;
|
||
|
case '4' : return Key::Num4;
|
||
|
case '5' : return Key::Num5;
|
||
|
case '6' : return Key::Num6;
|
||
|
case '7' : return Key::Num7;
|
||
|
case '8' : return Key::Num8;
|
||
|
case '9' : return Key::Num9;
|
||
|
}
|
||
|
|
||
|
return Key::Code(0);
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////
|
||
|
/// Process a Win32 event
|
||
|
////////////////////////////////////////////////////////////
|
||
|
void ProcessEvent(UINT Message, WPARAM WParam, LPARAM LParam)
|
||
|
{
|
||
|
// Don't process any message until window is created
|
||
|
if (myHandle == NULL)
|
||
|
return;
|
||
|
|
||
|
switch (Message)
|
||
|
{
|
||
|
// Destroy event
|
||
|
case WM_DESTROY :
|
||
|
{
|
||
|
// Here we must cleanup resources !
|
||
|
Cleanup();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Set cursor event
|
||
|
case WM_SETCURSOR :
|
||
|
{
|
||
|
// The mouse has moved, if the cursor is in our window we must refresh the cursor
|
||
|
if (LOWORD(LParam) == HTCLIENT)
|
||
|
SetCursor(myCursor);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
case WM_CLOSE :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::Closed;
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Resize event
|
||
|
case WM_SIZE :
|
||
|
{
|
||
|
// Update window size
|
||
|
RECT Rect;
|
||
|
GetClientRect(myHandle, &Rect);
|
||
|
myWidth = Rect.right - Rect.left;
|
||
|
myHeight = Rect.bottom - Rect.top;
|
||
|
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::Resized;
|
||
|
Evt.Size.Width = myWidth;
|
||
|
Evt.Size.Height = myHeight;
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
// Gain focus event
|
||
|
case WM_SETFOCUS :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::GainedFocus;
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Lost focus event
|
||
|
case WM_KILLFOCUS :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::LostFocus;
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Text event
|
||
|
case WM_CHAR :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::TextEntered;
|
||
|
Evt.Text.Unicode = static_cast<Uint32>(WParam);
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
// Keydown event
|
||
|
case WM_KEYDOWN :
|
||
|
case WM_SYSKEYDOWN :
|
||
|
{
|
||
|
if (myKeyRepeatEnabled || ((LParam & (1 << 30)) == 0))
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::KeyPressed;
|
||
|
Evt.Key.Code = (WParam == VK_SHIFT) ? GetShiftState(true) : VirtualKeyCodeToSF(WParam, LParam);
|
||
|
Evt.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
|
||
|
Evt.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
|
||
|
Evt.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
|
||
|
SendEvent(Evt);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Keyup event
|
||
|
case WM_KEYUP :
|
||
|
case WM_SYSKEYUP :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::KeyReleased;
|
||
|
Evt.Key.Code = (WParam == VK_SHIFT) ? GetShiftState(false) : VirtualKeyCodeToSF(WParam, LParam);
|
||
|
Evt.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
|
||
|
Evt.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
|
||
|
Evt.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Mouse wheel event
|
||
|
case WM_MOUSEWHEEL :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::MouseWheelMoved;
|
||
|
Evt.MouseWheel.Delta = static_cast<Int16>(HIWORD(WParam)) / 120;
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Mouse left button down event
|
||
|
case WM_LBUTTONDOWN :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::MouseButtonPressed;
|
||
|
Evt.MouseButton.Button = Mouse::Left;
|
||
|
Evt.MouseButton.X = LOWORD(LParam);
|
||
|
Evt.MouseButton.Y = HIWORD(LParam);
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Mouse left button up event
|
||
|
case WM_LBUTTONUP :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::MouseButtonReleased;
|
||
|
Evt.MouseButton.Button = Mouse::Left;
|
||
|
Evt.MouseButton.X = LOWORD(LParam);
|
||
|
Evt.MouseButton.Y = HIWORD(LParam);
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Mouse right button down event
|
||
|
case WM_RBUTTONDOWN :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::MouseButtonPressed;
|
||
|
Evt.MouseButton.Button = Mouse::Right;
|
||
|
Evt.MouseButton.X = LOWORD(LParam);
|
||
|
Evt.MouseButton.Y = HIWORD(LParam);
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Mouse right button up event
|
||
|
case WM_RBUTTONUP :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::MouseButtonReleased;
|
||
|
Evt.MouseButton.Button = Mouse::Right;
|
||
|
Evt.MouseButton.X = LOWORD(LParam);
|
||
|
Evt.MouseButton.Y = HIWORD(LParam);
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Mouse wheel button down event
|
||
|
case WM_MBUTTONDOWN :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::MouseButtonPressed;
|
||
|
Evt.MouseButton.Button = Mouse::Middle;
|
||
|
Evt.MouseButton.X = LOWORD(LParam);
|
||
|
Evt.MouseButton.Y = HIWORD(LParam);
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Mouse wheel button up event
|
||
|
case WM_MBUTTONUP :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::MouseButtonReleased;
|
||
|
Evt.MouseButton.Button = Mouse::Middle;
|
||
|
Evt.MouseButton.X = LOWORD(LParam);
|
||
|
Evt.MouseButton.Y = HIWORD(LParam);
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Mouse X button down event
|
||
|
case WM_XBUTTONDOWN :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::MouseButtonPressed;
|
||
|
Evt.MouseButton.Button = HIWORD(WParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2;
|
||
|
Evt.MouseButton.X = LOWORD(LParam);
|
||
|
Evt.MouseButton.Y = HIWORD(LParam);
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Mouse X button up event
|
||
|
case WM_XBUTTONUP :
|
||
|
{
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::MouseButtonReleased;
|
||
|
Evt.MouseButton.Button = HIWORD(WParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2;
|
||
|
Evt.MouseButton.X = LOWORD(LParam);
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Mouse move event
|
||
|
case WM_MOUSEMOVE :
|
||
|
{
|
||
|
// Check if we need to generate a MouseEntered event
|
||
|
if (!myIsCursorIn)
|
||
|
{
|
||
|
TRACKMOUSEEVENT MouseEvent;
|
||
|
MouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
|
||
|
MouseEvent.hwndTrack = myHandle;
|
||
|
MouseEvent.dwFlags = TME_LEAVE;
|
||
|
TrackMouseEvent(&MouseEvent);
|
||
|
|
||
|
myIsCursorIn = true;
|
||
|
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::MouseEntered;
|
||
|
SendEvent(Evt);
|
||
|
}
|
||
|
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::MouseMoved;
|
||
|
Evt.MouseMove.X = LOWORD(LParam);
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Mouse leave event
|
||
|
case WM_MOUSELEAVE :
|
||
|
{
|
||
|
myIsCursorIn = false;
|
||
|
|
||
|
Event Evt;
|
||
|
Evt.Type = Event::MouseLeft;
|
||
|
SendEvent(Evt);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
/// Check the state of the shift keys on a key event,
|
||
|
/// and return the corresponding SF key code
|
||
|
////////////////////////////////////////////////////////////
|
||
|
Key::Code WindowImplWin32::GetShiftState(bool KeyDown)
|
||
|
{
|
||
|
static bool LShiftPrevDown = false;
|
||
|
static bool RShiftPrevDown = false;
|
||
|
|
||
|
bool LShiftDown = (HIWORD(GetAsyncKeyState(VK_LSHIFT)) != 0);
|
||
|
bool RShiftDown = (HIWORD(GetAsyncKeyState(VK_RSHIFT)) != 0);
|
||
|
|
||
|
Key::Code Code = Key::Code(0);
|
||
|
if (KeyDown)
|
||
|
{
|
||
|
if (!LShiftPrevDown && LShiftDown) Code = Key::LShift;
|
||
|
else if (!RShiftPrevDown && RShiftDown) Code = Key::RShift;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (LShiftPrevDown && !LShiftDown) Code = Key::LShift;
|
||
|
else if (RShiftPrevDown && !RShiftDown) Code = Key::RShift;
|
||
|
}
|
||
|
|
||
|
LShiftPrevDown = LShiftDown;
|
||
|
RShiftPrevDown = RShiftDown;
|
||
|
|
||
|
return Code;
|
||
|
}
|