diff --git a/input.cpp b/input.cpp index 24a3e00..cb8f8b9 100644 --- a/input.cpp +++ b/input.cpp @@ -6,6 +6,12 @@ #include +#define KEY_PREFIX 0x80 + +#define KEY_CODE_ALT 18 +#define KEY_CODE_CTRL 17 +#define KEY_CODE_SHIFT 16 + static int ConvertPPButtonToLiButton(PP_InputEvent_MouseButton ppButton) { switch (ppButton) { case PP_INPUTEVENT_MOUSEBUTTON_LEFT: @@ -27,6 +33,37 @@ void MoonlightInstance::MouseLockLost() { m_MouseLocked = false; } +void MoonlightInstance::UpdateModifiers(PP_InputEvent_Type eventType, short keyCode) { + switch (keyCode) { + case KEY_CODE_ALT: + if (eventType == PP_INPUTEVENT_TYPE_KEYDOWN) { + m_KeyModifiers |= MODIFIER_ALT; + } + else { + m_KeyModifiers &= ~MODIFIER_ALT; + } + break; + + case KEY_CODE_CTRL: + if (eventType == PP_INPUTEVENT_TYPE_KEYDOWN) { + m_KeyModifiers |= MODIFIER_CTRL; + } + else { + m_KeyModifiers &= ~MODIFIER_CTRL; + } + break; + + case KEY_CODE_SHIFT: + if (eventType == PP_INPUTEVENT_TYPE_KEYDOWN) { + m_KeyModifiers |= MODIFIER_SHIFT; + } + else { + m_KeyModifiers &= ~MODIFIER_SHIFT; + } + break; + } +} + bool MoonlightInstance::HandleInputEvent(const pp::InputEvent& event) { switch (event.GetType()) { case PP_INPUTEVENT_TYPE_MOUSEDOWN: { @@ -80,6 +117,36 @@ bool MoonlightInstance::HandleInputEvent(const pp::InputEvent& event) { return true; } + case PP_INPUTEVENT_TYPE_KEYDOWN: { + if (!m_MouseLocked) { + return false; + } + + pp::KeyboardInputEvent keyboardEvent(event); + + // Update modifier state before sending the key event + UpdateModifiers(event.GetType(), keyboardEvent.GetKeyCode()); + + LiSendKeyboardEvent(KEY_PREFIX << 8 | keyboardEvent.GetKeyCode(), + KEY_ACTION_DOWN, m_KeyModifiers); + return true; + } + + case PP_INPUTEVENT_TYPE_KEYUP: { + if (!m_MouseLocked) { + return false; + } + + pp::KeyboardInputEvent keyboardEvent(event); + + // Update modifier state before sending the key event + UpdateModifiers(event.GetType(), keyboardEvent.GetKeyCode()); + + LiSendKeyboardEvent(KEY_PREFIX << 8 | keyboardEvent.GetKeyCode(), + KEY_ACTION_UP, m_KeyModifiers); + return true; + } + default: { return false; } diff --git a/moonlight.hpp b/moonlight.hpp index 8773c28..27f3dd3 100644 --- a/moonlight.hpp +++ b/moonlight.hpp @@ -6,6 +6,7 @@ #include "ppapi/cpp/video_decoder.h" #include "ppapi/c/ppb_gamepad.h" +#include "ppapi/c/pp_input_event.h" #include "ppapi/c/ppb_opengles2.h" #include "ppapi/cpp/graphics_3d.h" #include "ppapi/cpp/graphics_3d_client.h" @@ -36,7 +37,8 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock { pp::MouseLock(this), m_IsPainting(false), m_CallbackFactory(this), - m_MouseLocked(false) { + m_MouseLocked(false), + m_KeyModifiers(0) { // This function MUST be used otherwise sockets don't work (nacl_io_init() doesn't work!) nacl_io_init_ppapi(pp_instance(), pp::Module::Get()->get_browser_interface()); @@ -49,6 +51,7 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock { void HandleMessage(const pp::Var& var_message); + void UpdateModifiers(PP_InputEvent_Type eventType, short keyCode); bool HandleInputEvent(const pp::InputEvent& event); void PollGamepads(); @@ -100,6 +103,7 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock { const PPB_Gamepad* m_GamepadApi; pp::CompletionCallbackFactory m_CallbackFactory; bool m_MouseLocked; + char m_KeyModifiers; }; extern MoonlightInstance* g_Instance; \ No newline at end of file