diff --git a/userspace/libraries/LibGUI/Window.cpp b/userspace/libraries/LibGUI/Window.cpp index 292ed763..607421eb 100644 --- a/userspace/libraries/LibGUI/Window.cpp +++ b/userspace/libraries/LibGUI/Window.cpp @@ -288,6 +288,12 @@ namespace LibGUI send_packet(packet, __FUNCTION__); } + void Window::query_keymap() + { + const WindowPacket::QueryKeymap packet {}; + send_packet(packet, __FUNCTION__); + } + void Window::on_socket_error(BAN::StringView function) { if (m_handling_socket_error) @@ -473,6 +479,10 @@ namespace LibGUI if (m_query_pointer_event_callback) m_query_pointer_event_callback(TRY_OR_BREAK(EventPacket::QueryPointerEvent::deserialize(packet_span)).event); break; + case PacketType::QueryKeymapEvent: + if (m_query_keymap_event_callback) + m_query_keymap_event_callback(TRY_OR_BREAK(EventPacket::QueryKeymapEvent::deserialize(packet_span)).event); + break; #undef TRY_OR_BREAK default: dprintln("unhandled packet type: {}", static_cast(header.type)); diff --git a/userspace/libraries/LibGUI/include/LibGUI/Packet.h b/userspace/libraries/LibGUI/include/LibGUI/Packet.h index a9eae34b..b33f12f0 100644 --- a/userspace/libraries/LibGUI/include/LibGUI/Packet.h +++ b/userspace/libraries/LibGUI/include/LibGUI/Packet.h @@ -214,6 +214,8 @@ namespace LibGUI QueryPointer, QueryPointerEvent, + QueryKeymap, + QueryKeymapEvent, }; struct PacketHeader @@ -310,6 +312,10 @@ namespace LibGUI QueryPointer ); + DEFINE_PACKET( + QueryKeymap + ); + } namespace EventPacket @@ -406,6 +412,15 @@ namespace LibGUI event_t, event ); + DEFINE_PACKET_EXTRA( + QueryKeymapEvent, + struct event_t { + uint16_t modifiers[4]; + uint32_t keymap[4][0x100]; + }, + event_t, event + ); + } } diff --git a/userspace/libraries/LibGUI/include/LibGUI/Window.h b/userspace/libraries/LibGUI/include/LibGUI/Window.h index 2ce5e374..9b2b6461 100644 --- a/userspace/libraries/LibGUI/include/LibGUI/Window.h +++ b/userspace/libraries/LibGUI/include/LibGUI/Window.h @@ -64,6 +64,7 @@ namespace LibGUI void request_resize(uint32_t width, uint32_t height); void query_cursor_position(); + void query_keymap(); uint32_t width() const { return m_width; } uint32_t height() const { return m_height; } @@ -83,6 +84,7 @@ namespace LibGUI void set_window_fullscreen_event_callback(BAN::Function callback) { m_window_fullscreen_event_callback = callback; } void set_window_move_event_callback(BAN::Function callback) { m_window_move_event_callback = callback; } void set_query_pointer_event_callback(BAN::Function callback) { m_query_pointer_event_callback = callback; } + void set_query_keymap_event_callback(BAN::Function callback) { m_query_keymap_event_callback = callback; } int server_fd() const { return m_server_fd; } @@ -132,6 +134,7 @@ namespace LibGUI BAN::Function m_mouse_move_event_callback; BAN::Function m_mouse_scroll_event_callback; BAN::Function m_query_pointer_event_callback; + BAN::Function m_query_keymap_event_callback; size_t m_in_buffer_size { 0 }; BAN::Array m_in_buffer; diff --git a/userspace/programs/WindowServer/WindowServer.cpp b/userspace/programs/WindowServer/WindowServer.cpp index e4b407d9..e6b01476 100644 --- a/userspace/programs/WindowServer/WindowServer.cpp +++ b/userspace/programs/WindowServer/WindowServer.cpp @@ -53,6 +53,37 @@ void WindowServer::on_query_pointer(int fd, const LibGUI::WindowPacket::QueryPoi } } +void WindowServer::on_query_keymap(int fd, const LibGUI::WindowPacket::QueryKeymap&) +{ + LibGUI::EventPacket::QueryKeymapEvent event_packet {}; + + const uint16_t modifiers[4] { + 0, + LibInput::KeyEvent::LShift, + LibInput::KeyEvent::RAlt, + LibInput::KeyEvent::LShift | LibInput::KeyEvent::RAlt, + }; + + const auto& layout = LibInput::KeyboardLayout::get(); + for (size_t i = 0; i < 4; i++) + { + event_packet.event.modifiers[i] = modifiers[i]; + for (size_t keycode = 0; keycode < 0x100; keycode++) + { + event_packet.event.keymap[i][keycode] = static_cast(layout.key_event_from_raw({ + .modifier = modifiers[i], + .keycode = static_cast(keycode), + }).key); + } + } + + if (auto ret = append_serialized_packet(event_packet, fd); ret.is_error()) + { + dwarnln("could not respond to query pointer request: {}", ret.error()); + return; + } +} + void WindowServer::on_window_create(int fd, const LibGUI::WindowPacket::WindowCreate& packet) { for (auto& window : m_client_windows) diff --git a/userspace/programs/WindowServer/WindowServer.h b/userspace/programs/WindowServer/WindowServer.h index c31ea125..9e2dc70e 100644 --- a/userspace/programs/WindowServer/WindowServer.h +++ b/userspace/programs/WindowServer/WindowServer.h @@ -32,6 +32,7 @@ public: BAN::ErrorOr set_background_image(BAN::UniqPtr); void on_query_pointer(int fd, const LibGUI::WindowPacket::QueryPointer&); + void on_query_keymap(int fd, const LibGUI::WindowPacket::QueryKeymap&); void on_window_create(int fd, const LibGUI::WindowPacket::WindowCreate&); void on_window_invalidate(int fd, const LibGUI::WindowPacket::WindowInvalidate&); diff --git a/userspace/programs/WindowServer/main.cpp b/userspace/programs/WindowServer/main.cpp index 82fcbd8e..61d10e97 100644 --- a/userspace/programs/WindowServer/main.cpp +++ b/userspace/programs/WindowServer/main.cpp @@ -474,6 +474,7 @@ int main() WINDOW_PACKET_CASE(WindowSetTitle, on_window_set_title); WINDOW_PACKET_CASE(WindowSetCursor, on_window_set_cursor); WINDOW_PACKET_CASE(QueryPointer, on_query_pointer); + WINDOW_PACKET_CASE(QueryKeymap, on_query_keymap); #undef WINDOW_PACKET_CASE default: dprintln("unhandled packet type: {}", static_cast(header.type));