diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f069ff33d..9b21bb524 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -499,6 +499,10 @@ target_link_libraries(citra_core PUBLIC citra_common PRIVATE audio_core network target_link_libraries(citra_core PRIVATE Boost::boost Boost::serialization Boost::iostreams httplib) target_link_libraries(citra_core PUBLIC dds-ktx PRIVATE cryptopp fmt lodepng open_source_archives) +if (NOT ANDROID) + target_link_libraries(citra_core PUBLIC input_common) +endif() + if (ENABLE_WEB_SERVICE) target_link_libraries(citra_core PRIVATE web_service) endif() diff --git a/src/core/rpc/packet.h b/src/core/rpc/packet.h index c68200834..9144a2982 100644 --- a/src/core/rpc/packet.h +++ b/src/core/rpc/packet.h @@ -1,4 +1,4 @@ -// Copyright 2018 Citra Emulator Project +// Copyright Citra Emulator Project / Lime3DS Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -15,6 +15,8 @@ enum class PacketType : u32 { Undefined = 0, ReadMemory = 1, WriteMemory = 2, + SendKey = 3, + SendSignal = 4 }; struct PacketHeader { @@ -69,9 +71,6 @@ public: } private: - void HandleReadMemory(u32 address, u32 data_size); - void HandleWriteMemory(u32 address, std::span data); - struct PacketHeader header; std::array packet_data; diff --git a/src/core/rpc/rpc_server.cpp b/src/core/rpc/rpc_server.cpp index 4dd9c2e76..17f971b02 100644 --- a/src/core/rpc/rpc_server.cpp +++ b/src/core/rpc/rpc_server.cpp @@ -1,4 +1,4 @@ -// Copyright 2019 Citra Emulator Project +// Copyright Citra Emulator Project / Lime3DS Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -8,6 +8,11 @@ #include "core/rpc/packet.h" #include "core/rpc/rpc_server.h" +#ifndef ANDROID +#include "input_common/keyboard.h" +#include "input_common/main.h" +#endif + namespace Core::RPC { RPCServer::RPCServer(Core::System& system_) : system{system_} { @@ -45,6 +50,25 @@ void RPCServer::HandleWriteMemory(Packet& packet, u32 address, std::spanReleaseKey(key_code); + } else if (state == 1) { + InputCommon::GetKeyboard()->PressKey(key_code); + } + packet.SetPacketDataSize(0); + packet.SendReply(); +} + +void RPCServer::HandleSendSignal(Packet& packet, u32 signal_code, u32 signal_parameter) { + system.SendSignal(static_cast(signal_code), signal_parameter); + + packet.SetPacketDataSize(0); + packet.SendReply(); +} +#endif + bool RPCServer::ValidatePacket(const PacketHeader& packet_header) { if (packet_header.version <= CURRENT_VERSION) { switch (packet_header.packet_type) { @@ -54,6 +78,20 @@ bool RPCServer::ValidatePacket(const PacketHeader& packet_header) { return true; } break; + +#ifndef ANDROID + case PacketType::SendKey: + if (packet_header.packet_size >= (sizeof(u32) + sizeof(u8))) { + return true; + } + break; + case PacketType::SendSignal: + if (packet_header.packet_size >= sizeof(u32)) { + return true; + } + break; +#endif + default: break; } @@ -66,26 +104,49 @@ void RPCServer::HandleSingleRequest(std::unique_ptr request_packet) { const auto packet_data = request_packet->GetPacketData(); if (ValidatePacket(request_packet->GetHeader())) { - // Currently, all request types use the address/data_size wire format u32 address = 0; u32 data_size = 0; - std::memcpy(&address, packet_data.data(), sizeof(address)); - std::memcpy(&data_size, packet_data.data() + sizeof(address), sizeof(data_size)); + +#ifndef ANDROID + u32 key_code = 0; + u8 key_state = 0; + u32 signal_code = 0; + u32 signal_parameter = 0; +#endif switch (request_packet->GetPacketType()) { case PacketType::ReadMemory: + std::memcpy(&address, packet_data.data(), sizeof(address)); + std::memcpy(&data_size, packet_data.data() + sizeof(address), sizeof(data_size)); if (data_size > 0 && data_size <= MAX_READ_SIZE) { HandleReadMemory(*request_packet, address, data_size); success = true; } - break; case PacketType::WriteMemory: + std::memcpy(&address, packet_data.data(), sizeof(address)); + std::memcpy(&data_size, packet_data.data() + sizeof(address), sizeof(data_size)); if (data_size > 0 && data_size <= MAX_PACKET_DATA_SIZE - (sizeof(u32) * 2)) { const auto data = packet_data.subspan(sizeof(u32) * 2, data_size); HandleWriteMemory(*request_packet, address, data); success = true; } break; + +#ifndef ANDROID + case PacketType::SendKey: + std::memcpy(&key_code, packet_data.data(), sizeof(key_code)); + std::memcpy(&key_state, packet_data.data() + sizeof(key_code), sizeof(key_state)); + HandleSendKey(*request_packet, key_code, key_state); + success = true; + break; + case PacketType::SendSignal: + std::memcpy(&signal_code, packet_data.data(), sizeof(signal_code)); + std::memcpy(&signal_parameter, packet_data.data() + sizeof(signal_code), + sizeof(signal_parameter)); + HandleSendSignal(*request_packet, signal_code, signal_parameter); + break; +#endif + default: break; } diff --git a/src/core/rpc/rpc_server.h b/src/core/rpc/rpc_server.h index f34d97059..97a426c49 100644 --- a/src/core/rpc/rpc_server.h +++ b/src/core/rpc/rpc_server.h @@ -1,4 +1,4 @@ -// Copyright 2018 Citra Emulator Project +// Copyright Citra Emulator Project / Lime3DS Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -29,6 +29,12 @@ public: private: void HandleReadMemory(Packet& packet, u32 address, u32 data_size); void HandleWriteMemory(Packet& packet, u32 address, std::span data); + +#ifndef ANDROID + void HandleSendKey(Packet& packet, u32 key_code, u8 state); + void HandleSendSignal(Packet& packet, u32 signal_code, u32 signal_parameter); +#endif + bool ValidatePacket(const PacketHeader& packet_header); void HandleSingleRequest(std::unique_ptr request); void HandleRequestsLoop(std::stop_token stop_token);