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
+ }
0 commit comments