Skip to content

Commit

Permalink
feat: implemented Moonlight keyboard modifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
ABeltramo committed Jul 23, 2024
1 parent 832d959 commit ade86cc
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/moonlight-protocol/moonlight/control.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,21 @@ enum CONTROLLER_BTN : unsigned int {
Y = 0x8000
};

enum KEYBOARD_MODIFIERS : char {
NONE = 0x00,
SHIFT = 0x01,
CTRL = 0x02,
ALT = 0x04,
META = 0x08
};

enum MOONLIGHT_MODIFIERS : short {
M_SHIFT = 0x10,
M_CTRL = 0x11,
M_ALT = 0xA4,
M_META = 0x5B
};

// make sure these structs are allocated in 1-byte blocks so the data aligns
// right
#pragma pack(push, 1)
Expand Down Expand Up @@ -141,7 +156,7 @@ struct MOUSE_HSCROLL_PACKET : INPUT_PKT {
struct KEYBOARD_PACKET : INPUT_PKT {
unsigned char flags;
short key_code;
unsigned char modifiers;
char modifiers;
short zero1;
};

Expand Down
22 changes: 22 additions & 0 deletions src/moonlight-server/control/input_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,29 @@ void keyboard_key(const KEYBOARD_PACKET &pkt, state::StreamSession &session) {
short moonlight_key = (short)boost::endian::little_to_native(pkt.key_code) & (short)0x7fff;
if (session.keyboard->has_value()) {
if (pkt.type == KEY_PRESS) {
// Press the virtual modifiers
if (pkt.modifiers & KEYBOARD_MODIFIERS::SHIFT && moonlight_key != M_SHIFT)
std::visit([](auto &keyboard) { keyboard.press(M_SHIFT); }, session.keyboard->value());
if (pkt.modifiers & KEYBOARD_MODIFIERS::CTRL && moonlight_key != M_CTRL)
std::visit([](auto &keyboard) { keyboard.press(M_CTRL); }, session.keyboard->value());
if (pkt.modifiers & KEYBOARD_MODIFIERS::ALT && moonlight_key != M_ALT)
std::visit([](auto &keyboard) { keyboard.press(M_ALT); }, session.keyboard->value());
if (pkt.modifiers & KEYBOARD_MODIFIERS::META && moonlight_key != M_META)
std::visit([](auto &keyboard) { keyboard.press(M_META); }, session.keyboard->value());

// Press the actual key
std::visit([moonlight_key](auto &keyboard) { keyboard.press(moonlight_key); }, session.keyboard->value());

// Release the virtual modifiers
if (pkt.modifiers & KEYBOARD_MODIFIERS::SHIFT && moonlight_key != M_SHIFT)
std::visit([](auto &keyboard) { keyboard.release(M_SHIFT); }, session.keyboard->value());
if (pkt.modifiers & KEYBOARD_MODIFIERS::CTRL && moonlight_key != M_CTRL)
std::visit([](auto &keyboard) { keyboard.release(M_CTRL); }, session.keyboard->value());
if (pkt.modifiers & KEYBOARD_MODIFIERS::ALT && moonlight_key != M_ALT)
std::visit([](auto &keyboard) { keyboard.release(M_ALT); }, session.keyboard->value());
if (pkt.modifiers & KEYBOARD_MODIFIERS::META && moonlight_key != M_META)
std::visit([](auto &keyboard) { keyboard.release(M_META); }, session.keyboard->value());

} else {
std::visit([moonlight_key](auto &keyboard) { keyboard.release(moonlight_key); }, session.keyboard->value());
}
Expand Down
26 changes: 26 additions & 0 deletions tests/platforms/linux/wayland-display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,32 @@ TEST_CASE("Wayland virtual inputs", "[WAYLAND]") {
REQUIRE(!k_ev->pressed);
}

{ // Testing modifiers
auto press_SHIFT_A =
pkts::KEYBOARD_PACKET{.key_code = boost::endian::native_to_little((short)0x41), .modifiers = pkts::SHIFT};
press_SHIFT_A.type = pkts::KEY_PRESS;
control::handle_input(session, {}, &press_SHIFT_A);
wl_display_roundtrip(wd.get());

auto k_ev = kb_events_q->pop();
// Press SHIFT
REQUIRE(k_ev.has_value());
REQUIRE(k_ev->keycode == 42);
REQUIRE(k_ev->pressed);

// Press A
k_ev = kb_events_q->pop();
REQUIRE(k_ev.has_value());
REQUIRE(k_ev->keycode == 30);
REQUIRE(k_ev->pressed);

// Release SHIFT
k_ev = kb_events_q->pop();
REQUIRE(k_ev.has_value());
REQUIRE(k_ev->keycode == 42);
REQUIRE(!k_ev->pressed);
}

// Mouse tests: scroll
{
short scroll_amt = 10;
Expand Down

0 comments on commit ade86cc

Please sign in to comment.