Implement free look on linux. Patch due to artart78.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6638 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Glenn Rice
2010-12-21 23:58:25 +00:00
parent e4269dcd65
commit c1c1f54c59
8 changed files with 183 additions and 5 deletions

View File

@ -837,12 +837,20 @@ void CFrame::OnKeyDown(wxKeyEvent& event)
X11Utils::SendKeyEvent(X11Utils::XDisplayFromHandle(GetHandle()), event.GetKeyCode());
#endif
}
#ifdef _WIN32
// Send the freelook hotkeys to the video plugin
if ((event.GetKeyCode() == '0', '9', 'W', 'S', 'A', 'D', 'R')
if ((event.GetKeyCode() == ')' || event.GetKeyCode() == '(' ||
event.GetKeyCode() == '0' || event.GetKeyCode() == '9' ||
event.GetKeyCode() == 'W' || event.GetKeyCode() == 'S' ||
event.GetKeyCode() == 'A' || event.GetKeyCode() == 'D' ||
event.GetKeyCode() == 'R')
&& event.GetModifiers() == wxMOD_SHIFT)
{
#ifdef _WIN32
PostMessage((HWND)Core::GetWindowHandle(), WM_USER, WM_USER_KEYDOWN, event.GetKeyCode());
#elif defined(HAVE_X11) && HAVE_X11
X11Utils::SendKeyEvent(X11Utils::XDisplayFromHandle(GetHandle()), event.GetKeyCode());
#endif
}
}
else
event.Skip();
@ -853,6 +861,21 @@ void CFrame::OnKeyUp(wxKeyEvent& event)
event.Skip();
}
void CFrame::OnMouse(wxMouseEvent& event)
{
#if defined(HAVE_X11) && HAVE_X11
if(Core::GetState() != Core::CORE_UNINITIALIZED)
{
if(event.Dragging())
X11Utils::SendMotionEvent(X11Utils::XDisplayFromHandle(GetHandle()),
event.GetPosition().x, event.GetPosition().y);
else
X11Utils::SendButtonEvent(X11Utils::XDisplayFromHandle(GetHandle()), event.GetButton(),
event.GetPosition().x, event.GetPosition().y, event.ButtonDown());
}
#endif
}
void CFrame::DoFullscreen(bool bF)
{
ToggleDisplayMode(bF);

View File

@ -311,8 +311,11 @@ class CFrame : public CRenderFrame
void DoToggleToolbar(bool);
void OnToggleStatusbar(wxCommandEvent& event);
void OnToggleWindow(wxCommandEvent& event);
void OnKeyDown(wxKeyEvent& event);
void OnKeyDown(wxKeyEvent& event); // Keyboard
void OnKeyUp(wxKeyEvent& event);
void OnMouse(wxMouseEvent& event); // Mouse
void OnHostMessage(wxCommandEvent& event);

View File

@ -838,6 +838,21 @@ void CFrame::StartGame(const std::string& filename)
wxTheApp->Connect(wxID_ANY, wxEVT_KEY_UP,
wxKeyEventHandler(CFrame::OnKeyUp),
(wxObject*)0, this);
wxTheApp->Connect(wxID_ANY, wxEVT_RIGHT_DOWN, // Mouse
wxMouseEventHandler(CFrame::OnMouse),
(wxObject*)0, this);
wxTheApp->Connect(wxID_ANY, wxEVT_RIGHT_UP,
wxMouseEventHandler(CFrame::OnMouse),
(wxObject*)0, this);
wxTheApp->Connect(wxID_ANY, wxEVT_MIDDLE_DOWN,
wxMouseEventHandler(CFrame::OnMouse),
(wxObject*)0, this);
wxTheApp->Connect(wxID_ANY, wxEVT_MIDDLE_UP,
wxMouseEventHandler(CFrame::OnMouse),
(wxObject*)0, this);
wxTheApp->Connect(wxID_ANY, wxEVT_MOTION,
wxMouseEventHandler(CFrame::OnMouse),
(wxObject*)0, this);
m_RenderParent->Connect(wxID_ANY, wxEVT_SIZE,
wxSizeEventHandler(CFrame::OnRenderParentResize),
(wxObject*)0, this);
@ -939,6 +954,21 @@ void CFrame::DoStop()
wxTheApp->Disconnect(wxID_ANY, wxEVT_KEY_UP,
wxKeyEventHandler(CFrame::OnKeyUp),
(wxObject*)0, this);
wxTheApp->Disconnect(wxID_ANY, wxEVT_RIGHT_DOWN, // Mouse
wxMouseEventHandler(CFrame::OnMouse),
(wxObject*)0, this);
wxTheApp->Disconnect(wxID_ANY, wxEVT_RIGHT_UP,
wxMouseEventHandler(CFrame::OnMouse),
(wxObject*)0, this);
wxTheApp->Disconnect(wxID_ANY, wxEVT_MIDDLE_DOWN,
wxMouseEventHandler(CFrame::OnMouse),
(wxObject*)0, this);
wxTheApp->Disconnect(wxID_ANY, wxEVT_MIDDLE_UP,
wxMouseEventHandler(CFrame::OnMouse),
(wxObject*)0, this);
wxTheApp->Disconnect(wxID_ANY, wxEVT_MOTION,
wxMouseEventHandler(CFrame::OnMouse),
(wxObject*)0, this);
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
m_RenderParent->SetCursor(wxCURSOR_ARROW);
DoFullscreen(FALSE);

View File

@ -64,6 +64,37 @@ void SendKeyEvent(Display *dpy, int key)
ERROR_LOG(VIDEO, "Failed to send key press event to the emulator window.");
}
void SendButtonEvent(Display *dpy, int button, int x, int y, bool pressed)
{
XEvent event;
Window win = (Window)Core::GetWindowHandle();
// Init X event structure for mouse button press event
event.xbutton.type = pressed ? ButtonPress : ButtonRelease;
event.xbutton.x = x;
event.xbutton.y = y;
event.xbutton.button = button;
// Send the event
if (!XSendEvent(dpy, win, False, False, &event))
ERROR_LOG(VIDEO, "Failed to send mouse button event to the emulator window.");
}
void SendMotionEvent(Display *dpy, int x, int y)
{
XEvent event;
Window win = (Window)Core::GetWindowHandle();
// Init X event structure for mouse motion
event.xmotion.type = MotionNotify;
event.xmotion.x = x;
event.xmotion.y = y;
// Send the event
if (!XSendEvent(dpy, win, False, False, &event))
ERROR_LOG(VIDEO, "Failed to send mouse button event to the emulator window.");
}
void EWMH_Fullscreen(Display *dpy, int action)
{
_assert_(action == _NET_WM_STATE_REMOVE || action == _NET_WM_STATE_ADD

View File

@ -46,6 +46,8 @@ namespace X11Utils
void SendClientEvent(Display *dpy, const char *message,
int data1, int data2, int data3, int data4);
void SendKeyEvent(Display *dpy, int key);
void SendButtonEvent(Display *dpy, int button, int x, int y, bool pressed);
void SendMotionEvent(Display *dpy, int x, int y);
void EWMH_Fullscreen(Display *dpy, int action);
#if defined(HAVE_WX) && HAVE_WX
Window XWindowFromHandle(void *Handle);

View File

@ -124,7 +124,9 @@ KeyboardMouse::Key::Key(Display* const display, KeyCode keycode)
ControlState KeyboardMouse::Key::GetState(const State* const state) const
{
return (state->keyboard[m_keycode/8] & (1 << (m_keycode%8))) != 0;
KeyCode shift = XKeysymToKeycode(m_display, XK_Shift_L);
return (state->keyboard[m_keycode/8] & (1 << (m_keycode%8))) != 0
&& (state->keyboard[shift/8] & (1 << (shift%8))) == 0;
}
ControlState KeyboardMouse::Button::GetState(const State* const state) const

View File

@ -4,6 +4,7 @@
#include "../ControllerInterface.h"
#include <X11/Xlib.h>
#include <X11/keysym.h>
namespace ciface
{