Skip to content

Commit a7bea2e

Browse files
committed
Add basic platform and plugin handlers
refactor keyboard
1 parent fc19ae7 commit a7bea2e

File tree

7 files changed

+580
-391
lines changed

7 files changed

+580
-391
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ pkg_check_modules(RAPIDJSON REQUIRED "RapidJSON>=1.1.0")
5454
set(FLUTTER_WAYLAND_SRC
5555
flutter/standard_codec.cc
5656
src/wayland_display.cc
57+
src/keyboard.cc
58+
src/platform_channel.cc
5759
src/utils.cc
5860
src/main.cc
5961
)

src/keyboard.cc

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#include "keyboard.h"
2+
3+
#include <wayland-client-protocol-extra.hpp>
4+
#include <rapidjson/document.h>
5+
#include <rapidjson/stringbuffer.h>
6+
#include <rapidjson/writer.h>
7+
#include <xkbcommon/xkbcommon.h>
8+
#include <flutter_embedder.h>
9+
#include <sys/mman.h>
10+
11+
#include <sys/wait.h>
12+
#include <unistd.h>
13+
14+
#include "macros.h"
15+
16+
namespace flutter {
17+
18+
Keyboard::Keyboard(FlutterEngine engine, wayland::keyboard_t& keyb) : engine_(engine), keyb_(keyb)
19+
{
20+
static wayland::keyboard_keymap_format keyb_format =
21+
wayland::keyboard_keymap_format::no_keymap;
22+
static struct xkb_context* xkb_context =
23+
xkb_context_new(XKB_CONTEXT_NO_FLAGS);
24+
static struct xkb_keymap* keymap = NULL;
25+
static struct xkb_state* xkb_state = NULL;
26+
27+
keyb_.on_keymap() = [&](wayland::keyboard_keymap_format format, int fd,
28+
uint32_t size) {
29+
keyb_format = format;
30+
if (format == wayland::keyboard_keymap_format::xkb_v1) {
31+
char* keymap_string = reinterpret_cast<char*>(
32+
mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0));
33+
xkb_keymap_unref(keymap);
34+
keymap = xkb_keymap_new_from_string(xkb_context, keymap_string,
35+
XKB_KEYMAP_FORMAT_TEXT_V1,
36+
XKB_KEYMAP_COMPILE_NO_FLAGS);
37+
munmap(keymap_string, size);
38+
close(fd);
39+
xkb_state_unref(xkb_state);
40+
xkb_state = xkb_state_new(keymap);
41+
}
42+
};
43+
44+
keyb_.on_key() = [&](uint32_t, uint32_t, uint32_t key,
45+
wayland::keyboard_key_state state) {
46+
if (keyb_format == wayland::keyboard_keymap_format::xkb_v1) {
47+
xkb_keysym_t keysym = xkb_state_key_get_one_sym(xkb_state, key + 8);
48+
uint32_t utf32 = xkb_keysym_to_utf32(keysym);
49+
if (utf32) {
50+
static constexpr char kChannelName[] = "flutter/keyevent";
51+
52+
static constexpr char kKeyCodeKey[] = "keyCode";
53+
static constexpr char kKeyMapKey[] = "keymap";
54+
static constexpr char kLinuxKeyMap[] = "linux";
55+
static constexpr char kScanCodeKey[] = "scanCode";
56+
static constexpr char kModifiersKey[] = "modifiers";
57+
static constexpr char kTypeKey[] = "type";
58+
static constexpr char kToolkitKey[] = "toolkit";
59+
static constexpr char kGLFWKey[] = "glfw";
60+
static constexpr char kUnicodeScalarValues[] = "unicodeScalarValues";
61+
static constexpr char kKeyUp[] = "keyup";
62+
static constexpr char kKeyDown[] = "keydown";
63+
64+
rapidjson::Document document;
65+
auto& allocator = document.GetAllocator();
66+
document.SetObject();
67+
document.AddMember(kKeyCodeKey, key, allocator);
68+
document.AddMember(kKeyMapKey, kLinuxKeyMap, allocator);
69+
document.AddMember(kScanCodeKey, key + 8, allocator);
70+
document.AddMember(kModifiersKey, 0, allocator);
71+
document.AddMember(kToolkitKey, kGLFWKey, allocator);
72+
document.AddMember(kUnicodeScalarValues, utf32, allocator);
73+
74+
switch (state) {
75+
case wayland::keyboard_key_state::pressed:
76+
document.AddMember(kTypeKey, kKeyDown, allocator);
77+
break;
78+
case wayland::keyboard_key_state::released:
79+
document.AddMember(kTypeKey, kKeyUp, allocator);
80+
break;
81+
}
82+
83+
rapidjson::StringBuffer buffer;
84+
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
85+
document.Accept(writer);
86+
std::cout << buffer.GetString() << std::endl;
87+
88+
FlutterPlatformMessage message = {};
89+
message.struct_size = sizeof(FlutterPlatformMessage);
90+
message.channel = kChannelName;
91+
message.message =
92+
reinterpret_cast<const uint8_t*>(buffer.GetString());
93+
message.message_size = buffer.GetSize();
94+
message.response_handle = nullptr;
95+
96+
auto result = FlutterEngineSendPlatformMessage(engine_, &message);
97+
if (result != kSuccess)
98+
FLWAY_LOG << "FlutterEngineSendPlatformMessage Result: " << result
99+
<< std::endl;
100+
} else {
101+
char name[64];
102+
xkb_keysym_get_name(keysym, name, 64);
103+
FLWAY_LOG << "the key " << name << " was "
104+
<< ((state == wayland::keyboard_key_state::pressed) ? "pressed"
105+
: "released")
106+
<< std::endl;
107+
}
108+
}
109+
};
110+
111+
keyb_.on_modifiers() = [&](uint32_t serial, uint32_t mods_depressed,
112+
uint32_t mods_latched, uint32_t mods_locked,
113+
uint32_t group) {
114+
xkb_state_update_mask(xkb_state, mods_depressed, mods_latched,
115+
mods_locked, 0, 0, group);
116+
};
117+
}
118+
119+
}

src/keyboard.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
#include <wayland-client-protocol-extra.hpp>
4+
#include <flutter_embedder.h>
5+
6+
7+
namespace flutter {
8+
9+
class Keyboard
10+
{
11+
public:
12+
Keyboard(FlutterEngine engine, wayland::keyboard_t& keyb);
13+
14+
private:
15+
FlutterEngine engine_;
16+
wayland::keyboard_t keyb_;
17+
18+
};
19+
20+
}

0 commit comments

Comments
 (0)