diff --git a/libs/core/CMakeLists.txt b/libs/core/CMakeLists.txt index 23f68beb..902079de 100644 --- a/libs/core/CMakeLists.txt +++ b/libs/core/CMakeLists.txt @@ -49,6 +49,7 @@ target_sources( include/quite/value/generic_value_class.hpp include/quite/value/object_query.hpp include/quite/injectors/mouse_injector.hpp + include/quite/injectors/keyboard_injector.hpp FILE_SET export_config TYPE HEADERS BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR} diff --git a/libs/core/include/quite/injectors/keyboard.hpp b/libs/core/include/quite/injectors/keyboard.hpp new file mode 100644 index 00000000..829c0c43 --- /dev/null +++ b/libs/core/include/quite/injectors/keyboard.hpp @@ -0,0 +1,8 @@ +#pragma once + +namespace quite::core +{ +enum class KeyboardKey +{ +}; +} // namespace quite::core diff --git a/libs/core/include/quite/injectors/keyboard_injector.hpp b/libs/core/include/quite/injectors/keyboard_injector.hpp new file mode 100644 index 00000000..ce28cac9 --- /dev/null +++ b/libs/core/include/quite/injectors/keyboard_injector.hpp @@ -0,0 +1,21 @@ +#pragma once +#include +#include "keyboard.hpp" +#include "quite/async_result.hpp" +#include "quite/quite_core_export.hpp" +#include "quite/value/object_id.hpp" + +namespace quite::core +{ + +class QUITE_CORE_EXPORT IKeyboardInjector +{ + public: + using KeyStates = std::unordered_set; + virtual ~IKeyboardInjector() = default; + virtual AsyncResult press(ObjectId target_id, KeyboardKey key) = 0; + virtual AsyncResult release(ObjectId target_id, KeyboardKey key) = 0; + virtual AsyncResult press_and_release(ObjectId target_id, KeyboardKey key) = 0; + virtual AsyncResult press_and_release_each(ObjectId target_id, std::string keys) = 0; +}; +} // namespace quite::core diff --git a/libs/probeqt/injector/keyboard_injector.cpp b/libs/probeqt/injector/keyboard_injector.cpp new file mode 100644 index 00000000..c5a08629 --- /dev/null +++ b/libs/probeqt/injector/keyboard_injector.cpp @@ -0,0 +1,12 @@ +#include "keyboard_injector.hpp" +#include +namespace quite::probe +{ +KeyboardInjector::KeyboardInjector() +{ + // https://codebrowser.dev/qt6/qtbase/src/testlib/qasciikey.cpp.html#_ZN5QTest10asciiToKeyEc + QKeyEvent{QEvent::Type::KeyPress, Qt::Key_Shift, {}}; + QKeyEvent{QEvent::Type::KeyPress, Qt::Key_A, {}}; + QKeyEvent{QEvent::Type::KeyPress, Qt::Key_A, {}}; +} +} // namespace quite::probe diff --git a/libs/probeqt/injector/keyboard_injector.hpp b/libs/probeqt/injector/keyboard_injector.hpp index e69de29b..9f50a6ba 100644 --- a/libs/probeqt/injector/keyboard_injector.hpp +++ b/libs/probeqt/injector/keyboard_injector.hpp @@ -0,0 +1,11 @@ +#pragma once +#include + +namespace quite::probe +{ +class KeyboardInjector : public core::IKeyboardInjector +{ + public: + KeyboardInjector(); +}; +} // namespace quite::probe diff --git a/libs/protocol/CMakeLists.txt b/libs/protocol/CMakeLists.txt index ef7200dd..fc10919b 100644 --- a/libs/protocol/CMakeLists.txt +++ b/libs/protocol/CMakeLists.txt @@ -24,6 +24,7 @@ asio_grpc_protobuf_generate( "${proto_inc_dir}/common.proto" "${proto_inc_dir}/probe.proto" "${proto_inc_dir}/keyboard.proto" + "${proto_inc_dir}/keyboard_service.proto" "${proto_inc_dir}/mouse.proto" "${proto_inc_dir}/types.proto" "${proto_inc_dir}/methods.proto" diff --git a/libs/protocol/include/quite/proto/probe/server.hpp b/libs/protocol/include/quite/proto/probe/server.hpp index 3e4ea4cd..cd582276 100644 --- a/libs/protocol/include/quite/proto/probe/server.hpp +++ b/libs/protocol/include/quite/proto/probe/server.hpp @@ -12,7 +12,8 @@ class ValueRegistry; namespace quite::core { class IMouseInjector; -} +class IKeyboardInjector; +} // namespace quite::core namespace quite::meta { class MetaRegistry; @@ -30,7 +31,8 @@ class QUITE_PROTOCOL_EXPORT Server final ServiceHandle probe_handler, ServiceHandle mouse_injector, ServiceHandle meta_registry, - ServiceHandle value_registry); + ServiceHandle value_registry, + ServiceHandle keyboard_injector = {}); Server(Server &&server) noexcept; Server &operator=(Server &&server) noexcept; ~Server(); diff --git a/libs/protocol/quite/proto/keyboard.proto b/libs/protocol/quite/proto/keyboard.proto index 7ffcc2b3..74959f97 100644 --- a/libs/protocol/quite/proto/keyboard.proto +++ b/libs/protocol/quite/proto/keyboard.proto @@ -2,19 +2,14 @@ syntax = "proto3"; package quite.proto; -enum KeyboardModifierKey { - no_mod = 0; - shift = 1; - crtl = 2; - alt = 3; - meta = 4; - keypad = 5; -} - enum KeyboardKey { no_key = 0; escape = 1; tab = 2; backspace = 3; return = 4; + shift = 5; + crtl = 6; + alt = 7; + meta = 8; } diff --git a/libs/protocol/quite/proto/keyboard_service.proto b/libs/protocol/quite/proto/keyboard_service.proto new file mode 100644 index 00000000..71f18488 --- /dev/null +++ b/libs/protocol/quite/proto/keyboard_service.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; +package quite.proto; +import "quite/proto/keyboard.proto"; + +service KeyboardService { + rpc PressKey(KeyRequest) returns (KeyResponse) {} + rpc ReleaseKey(KeyRequest) returns (KeyResponse) {} + rpc PressAndReleaseKey(KeyRequest) returns (KeyResponse) {} + rpc PressAndReleaseEach(KeySequenceRequest) returns (KeyResponse) {} +} + +message KeyRequest { + KeyboardKey key = 1; +} + +message KeySequenceRequest { + KeyboardKey key = 1; +} + +message KeyResponse { + // the list of keys which are currently in pressed state + repeated KeyboardKey pressed_keys = 1; +} diff --git a/libs/protocol/quite/proto/probe.proto b/libs/protocol/quite/proto/probe.proto index 3f6c54e8..6d4d6fd2 100644 --- a/libs/protocol/quite/proto/probe.proto +++ b/libs/protocol/quite/proto/probe.proto @@ -52,7 +52,7 @@ message MouseActionRequest { uint64 object_id = 1; MouseAction mouse_action = 2; MouseButton mouse_button = 3; - optional KeyboardModifierKey modifier_key = 4; + optional KeyboardKey modifier_key = 4; // delay between press and release optional uint32 delay_ms = 5; // the (click) point relative to the object coordinates. diff --git a/libs/protocol/src/probe/rpc_mouse_injection.cpp b/libs/protocol/src/probe/rpc_mouse_injection.cpp index bd0a7486..b607cf88 100644 --- a/libs/protocol/src/probe/rpc_mouse_injection.cpp +++ b/libs/protocol/src/probe/rpc_mouse_injection.cpp @@ -55,7 +55,7 @@ quite::core::MouseAction mouse_action_from_request(const quite::proto::MouseActi [modifier = request.modifier_key()]() { switch (modifier) { - case quite::proto::no_mod: + case quite::proto::no_key: return quite::core::KeyboardModifier::none; case quite::proto::shift: return quite::core::KeyboardModifier::shift; @@ -65,9 +65,7 @@ quite::core::MouseAction mouse_action_from_request(const quite::proto::MouseActi return quite::core::KeyboardModifier::alt; case quite::proto::meta: return quite::core::KeyboardModifier::meta; - case quite::proto::keypad: - case quite::proto::KeyboardModifierKey_INT_MIN_SENTINEL_DO_NOT_USE_: - case quite::proto::KeyboardModifierKey_INT_MAX_SENTINEL_DO_NOT_USE_: + default: break; } return quite::core::KeyboardModifier::none; diff --git a/libs/protocol/src/probe/server.cpp b/libs/protocol/src/probe/server.cpp index 6148719f..28a7fb6b 100644 --- a/libs/protocol/src/probe/server.cpp +++ b/libs/protocol/src/probe/server.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include "rpc_fetch_windows.hpp" @@ -26,6 +27,7 @@ class Server::Impl stdexec::inplace_stop_source ssource_; ServiceHandle probe_handler_; ServiceHandle mouse_injector_; + ServiceHandle keyboard_injector_; ServiceHandle meta_registry_; ServiceHandle value_registry_; grpc::ServerBuilder builder_; @@ -37,10 +39,12 @@ class Server::Impl Impl(std::string server_address, ServiceHandle probe_handler, ServiceHandle mouse_injector, + ServiceHandle keyboard_injector, ServiceHandle meta_registry, ServiceHandle value_registry) : probe_handler_{std::move(probe_handler)} , mouse_injector_{std::move(mouse_injector)} + , keyboard_injector_{std::move(keyboard_injector)} , meta_registry_{std::move(meta_registry)} , value_registry_{std::move(value_registry)} , grpc_runner_{[this, server_address = std::move(server_address)]() { @@ -68,9 +72,11 @@ class Server::Impl ProbeService::AsyncService object_service; MetaService::AsyncService meta_service; + KeyboardService::AsyncService keyboard_service; builder_.RegisterService(std::addressof(object_service)); builder_.RegisterService(std::addressof(meta_service)); + builder_.RegisterService(std::addressof(keyboard_service)); agrpc::add_health_check_service(builder_); grpc_server_ = builder_.BuildAndStart(); @@ -123,10 +129,12 @@ Server::Server(std::string server_address, ServiceHandle probe_handler, ServiceHandle mouse_injector, ServiceHandle meta_registry, - ServiceHandle value_registry) + ServiceHandle value_registry, + ServiceHandle keyboard_injector) : impl_{std::make_unique(std::move(server_address), std::move(probe_handler), std::move(mouse_injector), + std::move(keyboard_injector), std::move(meta_registry), std::move(value_registry))} {} diff --git a/libs/protocol/src/probe/service_keyboard_press_key.cpp b/libs/protocol/src/probe/service_keyboard_press_key.cpp new file mode 100644 index 00000000..e69de29b diff --git a/libs/protocol/src/probe/service_keyboard_press_key.hpp b/libs/protocol/src/probe/service_keyboard_press_key.hpp new file mode 100644 index 00000000..e69de29b