From a5edf59787d0b1fd501540faec9ac49ca5bce348 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Sat, 10 Apr 2010 20:44:56 +0000 Subject: [PATCH] Get GCPadNew keyboard working in linux. Also some code cleanup. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5320 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/DolphinWX/Src/Frame.cpp | 51 +++++++------- .../Plugin_GCPadNew/Src/ConfigDiag.cpp | 20 +++--- .../ControllerInterface.cpp | 8 +-- .../ControllerInterface/ControllerInterface.h | 1 + .../Src/ControllerInterface/Xlib/Xlib.cpp | 66 +++++++++++-------- .../Src/ControllerInterface/Xlib/Xlib.h | 46 +++++++------ .../Plugins/Plugin_GCPadNew/Src/GCPadNew.cpp | 29 ++++++-- 7 files changed, 128 insertions(+), 93 deletions(-) diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp index aebf9d8f24..83fe319a64 100644 --- a/Source/Core/DolphinWX/Src/Frame.cpp +++ b/Source/Core/DolphinWX/Src/Frame.cpp @@ -805,38 +805,39 @@ void CFrame::OnGameListCtrl_ItemActivated(wxListEvent& WXUNUSED (event)) void CFrame::OnKeyDown(wxKeyEvent& event) { - // Toggle fullscreen - if (event.GetKeyCode() == WXK_RETURN && event.GetModifiers() == wxMOD_ALT) + if(Core::GetState() != Core::CORE_UNINITIALIZED) { - DoFullscreen(!IsFullScreen()); + // Toggle fullscreen + if (event.GetKeyCode() == WXK_RETURN && event.GetModifiers() == wxMOD_ALT) + { + DoFullscreen(!IsFullScreen()); - // We do that to avoid the event to be double processed (which would cause the window to be stuck in fullscreen) - event.StopPropagation(); - } - else if(event.GetKeyCode() == WXK_ESCAPE) - { - main_frame->DoPause(); - } - // event.Skip() allows the event to propagate to the gamelist for example - else if (! (Core::GetState() == Core::CORE_RUN && bRenderToMain && event.GetEventObject() == this)) - event.Skip(); + // We do that to avoid the event to be double processed (which would cause the window to be stuck in fullscreen) + event.StopPropagation(); + } + else if(event.GetKeyCode() == WXK_ESCAPE) + { + main_frame->DoPause(); + } + // event.Skip() allows the event to propagate to the gamelist for example + else if (! (Core::GetState() == Core::CORE_RUN && bRenderToMain && event.GetEventObject() == this)) + event.Skip(); #ifdef _WIN32 - if(event.GetKeyCode() == 'M', '3', '4', '5', '6', '7') // Send this to the video plugin WndProc - { - PostMessage((HWND)Core::GetWindowHandle(), WM_USER, WM_USER_KEYDOWN, event.GetKeyCode()); - } + if(event.GetKeyCode() == 'M', '3', '4', '5', '6', '7') // Send this to the video plugin WndProc + { + PostMessage((HWND)Core::GetWindowHandle(), WM_USER, WM_USER_KEYDOWN, event.GetKeyCode()); + } #elif defined(HAVE_X11) && HAVE_X11 && defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK) - if (event.GetKeyCode() >= '3' && event.GetKeyCode() <= '7') // Send this to the video plugin - { - X11_SendKeyEvent(event.GetKeyCode()); - } + if (event.GetKeyCode() >= '3' && event.GetKeyCode() <= '7') // Send this to the video plugin + { + X11_SendKeyEvent(event.GetKeyCode()); + } #endif - - // Send the keyboard status to the Input plugin - if(Core::GetState() != Core::CORE_UNINITIALIZED) - CPluginManager::GetInstance().GetPad(0)->PAD_Input(event.GetKeyCode(), 1); // 1 = Down + // Send the keyboard status to the Input plugin + CPluginManager::GetInstance().GetPad(0)->PAD_Input(event.GetKeyCode(), 1); // 1 = Down + } } void CFrame::OnKeyUp(wxKeyEvent& event) diff --git a/Source/Plugins/Plugin_GCPadNew/Src/ConfigDiag.cpp b/Source/Plugins/Plugin_GCPadNew/Src/ConfigDiag.cpp index b7356d3631..cd68081381 100644 --- a/Source/Plugins/Plugin_GCPadNew/Src/ConfigDiag.cpp +++ b/Source/Plugins/Plugin_GCPadNew/Src/ConfigDiag.cpp @@ -2,8 +2,8 @@ #include "ConfigDiag.h" PadSettingCheckBox::PadSettingCheckBox( wxWindow* const parent, ControlState& _value, const char* const label ) - : wxCheckBox( parent, -1, wxString::FromAscii( label ), wxDefaultPosition ) - , PadSetting(_value) + : PadSetting(_value) + , wxCheckBox( parent, -1, wxString::FromAscii( label ), wxDefaultPosition ) { UpdateGUI(); } @@ -20,8 +20,8 @@ void PadSettingCheckBox::UpdateValue() } PadSettingChoice::PadSettingChoice( wxWindow* const parent, ControlState& _value, int min, int max ) - : wxChoice( parent, -1, wxDefaultPosition, wxSize( 48, -1 ) ) - , PadSetting(_value) + : PadSetting(_value) + , wxChoice( parent, -1, wxDefaultPosition, wxSize( 48, -1 ) ) { Append( wxT("0") ); for ( ; min<=max; ++min ) @@ -362,17 +362,19 @@ void ControlDialog::SelectControl( wxCommandEvent& event ) // final_label = "||"; else { - final_label = wxT('|'); - for ( unsigned int i=0; itextctrl->SetLabel( final_label ); // kinda dumb wxCommandEvent nullevent; ((GamepadPage*)m_parent)->SetControl( nullevent ); - + } ControlChooser::ControlChooser( wxWindow* const parent, ControllerInterface::ControlReference* const ref, wxWindow* const eventsink ) @@ -422,7 +424,7 @@ ControlChooser::ControlChooser( wxWindow* const parent, ControllerInterface::Con txtbox_szr->Add( textctrl, 1, wxEXPAND, 0 ); - wxBoxSizer* mode_szr; + wxBoxSizer* mode_szr = NULL; if ( control_reference->is_input ) { mode_cbox = new wxChoice( parent, -1 ); diff --git a/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/ControllerInterface.cpp b/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/ControllerInterface.cpp index d1b97c7e37..bec1b6e58c 100644 --- a/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/ControllerInterface.cpp +++ b/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/ControllerInterface.cpp @@ -238,7 +238,7 @@ ControlState ControllerInterface::InputReference::State( const ControlState igno if ( NULL == device ) return 0; - ControlState state; + ControlState state = 0; // this mode thing will be turned into a switch statement switch ( mode ) { @@ -360,11 +360,7 @@ void ControllerInterface::DeviceQualifier::FromDevice(const ControllerInterface: // bool ControllerInterface::DeviceQualifier::operator==(const ControllerInterface::Device* const dev) const { - if ( dev->GetName() == name ) - if ( dev->GetId() == cid ) - if ( dev->GetSource() == source ) - return true; - return false; + return (dev->GetName() == name) && (dev->GetId() == cid) && (dev->GetSource() == source); } // diff --git a/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/ControllerInterface.h b/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/ControllerInterface.h index f75f5863a9..f7a34e982f 100644 --- a/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/ControllerInterface.h +++ b/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/ControllerInterface.h @@ -6,6 +6,7 @@ #include #include #include +#include "Common.h" // enable disable sources #ifdef _WIN32 diff --git a/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/Xlib/Xlib.cpp b/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/Xlib/Xlib.cpp index a1189a0cf2..9a4d5d3d53 100644 --- a/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/Xlib/Xlib.cpp +++ b/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/Xlib/Xlib.cpp @@ -1,7 +1,3 @@ -#include "../ControllerInterface.h" - -#ifdef CIFACE_USE_XLIB - #include "Xlib.h" namespace ciface @@ -9,48 +5,48 @@ namespace ciface namespace Xlib { - -void Init( std::vector& devices, void* const hwnd ) +void Init(std::vector& devices, void* const hwnd) { // mouse will be added to this, Keyboard class will be turned into KeyboardMouse // single device for combined keyboard/mouse, this will allow combinations like shift+click more easily - devices.push_back( new Keyboard( (Display*)hwnd ) ); + devices.push_back(new Keyboard((Display*)hwnd)); } -Keyboard::Keyboard( Display* const display ) : m_display(display) +Keyboard::Keyboard(Display* display) : m_display(display) { + memset(&m_state, 0, sizeof(m_state)); - memset( &m_state, 0, sizeof(m_state) ); - - // this is probably dumb - for ( KeySym i = 0; i < 1024; ++i ) + int min_keycode, max_keycode; + XDisplayKeycodes(m_display, &min_keycode, &max_keycode); + + for (int i = min_keycode; i <= max_keycode; ++i) { - if ( XKeysymToString( m_keysym ) ) // if it isnt NULL - inputs.push_back( new Key( i ) ); + Key *temp_key = new Key(m_display, i); + if (temp_key->m_keyname.length()) + inputs.push_back(temp_key); + else + delete temp_key; } - } - Keyboard::~Keyboard() { - // might not need this func } -ControlState Keyboard::GetInputState( const ControllerInterface::Device::Input* const input ) +ControlState Keyboard::GetInputState(const ControllerInterface::Device::Input* const input) { - return ((Input*)input)->GetState( &m_state ); + return ((Input*)input)->GetState(&m_state); } -void Keyboard::SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state ) +void Keyboard::SetOutputState(const ControllerInterface::Device::Output* const output, const ControlState state) { } bool Keyboard::UpdateInput() { - XQueryKeymap( m_display, m_state.keyboard ); + XQueryKeymap(m_display, m_state.keyboard); // mouse stuff in here too @@ -80,19 +76,33 @@ int Keyboard::GetId() const } -ControlState Keyboard::Key::GetState( const State* const state ) +Keyboard::Key::Key(Display* const display, KeyCode keycode) + : m_display(display), m_keycode(keycode) { - key_code = XKeysymToKeycode(m_display, m_keysym ); - return (state->keyboard[key_code/8] & (1 << (key_code%8))); // need >0 ? + int i = 0; + KeySym keysym = 0; + do + { + keysym = XKeycodeToKeysym(m_display, keycode, i); + i++; + } + while (keysym == NoSymbol && i < 8); + + if (keysym == NoSymbol) + m_keyname = std::string(); + else + m_keyname = std::string(XKeysymToString(keysym)); +} + +ControlState Keyboard::Key::GetState(const State* const state) +{ + return state->keyboard[m_keycode/8] & (1 << (m_keycode%8)); } std::string Keyboard::Key::GetName() const { - return XKeysymToString( m_keysym ); + return m_keyname; } - } } - -#endif diff --git a/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/Xlib/Xlib.h b/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/Xlib/Xlib.h index 35a88b8be9..2b9f9f9a6a 100644 --- a/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/Xlib/Xlib.h +++ b/Source/Plugins/Plugin_GCPadNew/Src/ControllerInterface/Xlib/Xlib.h @@ -7,17 +7,17 @@ namespace ciface { -namespace XInput +namespace Xlib { -void Init( std::vector& devices, void* const hwnd ); +void Init(std::vector& devices, void* const hwnd); class Keyboard : public ControllerInterface::Device { friend class ControllerInterface; friend class ControllerInterface::ControlReference; -protected: + protected: struct State { @@ -25,42 +25,48 @@ protected: // mouse crap will go here }; - class Input : public ControllerInterface::Input + class Input : public ControllerInterface::Device::Input { friend class Keyboard; - protected: - ControlState GetState( const State* const state ) = 0; - } + + protected: + virtual ControlState GetState(const State* const state) = 0; + }; class Key : public Input { friend class Keyboard; - public: + + public: std::string GetName() const; - protected: - Key( KeySym keysym ) : m_keysym(keysym) {} - ControlState GetState( const State* const state ); - private: - const KeySym m_keysym - + + protected: + Key(Display* const display, KeyCode keycode); + ControlState GetState(const State* const state); + + private: + Display* const m_display; + const KeyCode m_keycode; + std::string m_keyname; + }; bool UpdateInput(); bool UpdateOutput(); - ControlState Keyboard::GetInputState( const ControllerInterface::Device::Input* const input ); - void Keyboard::SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state ); + ControlState GetInputState(const ControllerInterface::Device::Input* const input); + void SetOutputState(const ControllerInterface::Device::Output* const output, const ControlState state); -public: - Keyboard( Display* const display ); + public: + Keyboard(Display* display); ~Keyboard(); std::string GetName() const; std::string GetSource() const; int GetId() const; -private: - Display* const m_display; + private: + Display* m_display; State m_state; }; diff --git a/Source/Plugins/Plugin_GCPadNew/Src/GCPadNew.cpp b/Source/Plugins/Plugin_GCPadNew/Src/GCPadNew.cpp index bc6d7c4862..620df031fd 100644 --- a/Source/Plugins/Plugin_GCPadNew/Src/GCPadNew.cpp +++ b/Source/Plugins/Plugin_GCPadNew/Src/GCPadNew.cpp @@ -56,12 +56,14 @@ bool IsFocus() #elif defined HAVE_X11 && HAVE_X11 Display* GCdisplay = (Display*)g_PADInitialize->hWnd; Window GLWin = *(Window *)g_PADInitialize->pXWindow; + bool bFocus = False; +#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK) + bFocus = (wxPanel *)g_PADInitialize->pPanel == wxWindow::FindFocus(); +#endif Window FocusWin; int Revert; XGetInputFocus(GCdisplay, &FocusWin, &Revert); - XWindowAttributes WinAttribs; - XGetWindowAttributes (GCdisplay, GLWin, &WinAttribs); - return (GLWin != 0 && (GLWin == FocusWin || WinAttribs.override_redirect)); + return (GLWin == FocusWin || bFocus); #else return true; #endif @@ -181,8 +183,10 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) // if we want background input or have focus if ( g_plugin.controllers[_numPAD]->options[0].settings[0]->value || IsFocus() ) + { // get input ((GCPad*)g_plugin.controllers[ _numPAD ])->GetInput( _pPADStatus ); + } else { // center sticks @@ -256,10 +260,20 @@ void GetDllInfo(PLUGIN_INFO* _pPluginInfo) void DllConfig(HWND _hParent) { bool was_init = false; +#if defined(HAVE_X11) && HAVE_X11 + Display *dpy = NULL; +#endif if ( g_plugin.controller_interface.IsInit() ) // hack for showing dialog when game isnt running was_init = true; else - InitPlugin( _hParent ); + { +#if defined(HAVE_X11) && HAVE_X11 + dpy = XOpenDisplay(0); + InitPlugin(dpy); +#else + InitPlugin(_hParent); +#endif + } // copied from GCPad #if defined(HAVE_WX) && HAVE_WX @@ -286,8 +300,13 @@ void DllConfig(HWND _hParent) #endif // / - if ( false == was_init ) // hack for showing dialog when game isnt running + if ( !was_init ) // hack for showing dialog when game isnt running + { +#if defined(HAVE_X11) && HAVE_X11 + XCloseDisplay(dpy); +#endif g_plugin.controller_interface.DeInit(); + } } // ___________________________________________________________________________