|
| 1 | +// Copyright 2020 Samsung Electronics Co., Ltd. All rights reserved. |
| 2 | +// Use of this source code is governed by a BSD-style license that can be |
| 3 | +// found in the LICENSE file. |
| 4 | + |
| 5 | +#include "key_event_channel.h" |
| 6 | + |
| 7 | +#include <map> |
| 8 | + |
| 9 | +#include "flutter/shell/platform/tizen/logger.h" |
| 10 | + |
| 11 | +static constexpr char kChannelName[] = "flutter/keyevent"; |
| 12 | + |
| 13 | +static constexpr char kKeyMapKey[] = "keymap"; |
| 14 | +static constexpr char kKeyCodeKey[] = "keyCode"; |
| 15 | +static constexpr char kScanCodeKey[] = "scanCode"; |
| 16 | +static constexpr char kTypeKey[] = "type"; |
| 17 | +static constexpr char kModifiersKey[] = "modifiers"; |
| 18 | +static constexpr char kToolkitKey[] = "toolkit"; |
| 19 | +static constexpr char kUnicodeScalarValuesKey[] = "unicodeScalarValues"; |
| 20 | + |
| 21 | +static constexpr char kKeyUp[] = "keyup"; |
| 22 | +static constexpr char kKeyDown[] = "keydown"; |
| 23 | +static constexpr char kGtkToolkit[] = "gtk"; |
| 24 | +static constexpr char kLinuxKeyMap[] = "linux"; |
| 25 | + |
| 26 | +// Mapping from physical (xkb) to logical (GTK) key codes. |
| 27 | +// The values are defined in: |
| 28 | +// - flutter/keyboard_maps.dart (kLinuxToPhysicalKey, kGtkToLogicalKey) |
| 29 | +static const std::map<int, int> kKeyCodeMap = { |
| 30 | + {0x00000009, 65307}, // LogicalKeyboardKey.escape |
| 31 | + {0x0000000a, 49}, // LogicalKeyboardKey.digit1 |
| 32 | + {0x0000000b, 50}, // LogicalKeyboardKey.digit2 |
| 33 | + {0x0000000c, 51}, // LogicalKeyboardKey.digit3 |
| 34 | + {0x0000000d, 52}, // LogicalKeyboardKey.digit4 |
| 35 | + {0x0000000e, 53}, // LogicalKeyboardKey.digit5 |
| 36 | + {0x0000000f, 54}, // LogicalKeyboardKey.digit6 |
| 37 | + {0x00000010, 55}, // LogicalKeyboardKey.digit7 |
| 38 | + {0x00000011, 56}, // LogicalKeyboardKey.digit8 |
| 39 | + {0x00000012, 57}, // LogicalKeyboardKey.digit9 |
| 40 | + {0x00000013, 48}, // LogicalKeyboardKey.digit0 |
| 41 | + {0x00000014, 45}, // LogicalKeyboardKey.minus |
| 42 | + {0x00000015, 61}, // LogicalKeyboardKey.equal |
| 43 | + {0x00000016, 65288}, // LogicalKeyboardKey.backspace |
| 44 | + {0x00000017, 65289}, // LogicalKeyboardKey.tab |
| 45 | + {0x00000018, 81}, // LogicalKeyboardKey.keyQ |
| 46 | + {0x00000019, 87}, // LogicalKeyboardKey.keyW |
| 47 | + {0x0000001a, 69}, // LogicalKeyboardKey.keyE |
| 48 | + {0x0000001b, 82}, // LogicalKeyboardKey.keyR |
| 49 | + {0x0000001c, 84}, // LogicalKeyboardKey.keyT |
| 50 | + {0x0000001d, 89}, // LogicalKeyboardKey.keyY |
| 51 | + {0x0000001e, 85}, // LogicalKeyboardKey.keyU |
| 52 | + {0x0000001f, 73}, // LogicalKeyboardKey.keyI |
| 53 | + {0x00000020, 79}, // LogicalKeyboardKey.keyO |
| 54 | + {0x00000021, 80}, // LogicalKeyboardKey.keyP |
| 55 | + {0x00000022, 91}, // LogicalKeyboardKey.bracketLeft |
| 56 | + {0x00000023, 93}, // LogicalKeyboardKey.bracketRight |
| 57 | + {0x00000024, 65293}, // LogicalKeyboardKey.enter |
| 58 | + {0x00000025, 65507}, // LogicalKeyboardKey.controlLeft |
| 59 | + {0x00000026, 65}, // LogicalKeyboardKey.keyA |
| 60 | + {0x00000027, 83}, // LogicalKeyboardKey.keyS |
| 61 | + {0x00000028, 68}, // LogicalKeyboardKey.keyD |
| 62 | + {0x00000029, 70}, // LogicalKeyboardKey.keyF |
| 63 | + {0x0000002a, 71}, // LogicalKeyboardKey.keyG |
| 64 | + {0x0000002b, 72}, // LogicalKeyboardKey.keyH |
| 65 | + {0x0000002c, 74}, // LogicalKeyboardKey.keyJ |
| 66 | + {0x0000002d, 75}, // LogicalKeyboardKey.keyK |
| 67 | + {0x0000002e, 76}, // LogicalKeyboardKey.keyL |
| 68 | + {0x0000002f, 59}, // LogicalKeyboardKey.semicolon |
| 69 | + {0x00000030, 39}, // LogicalKeyboardKey.quote |
| 70 | + {0x00000031, 96}, // LogicalKeyboardKey.backquote |
| 71 | + {0x00000032, 65505}, // LogicalKeyboardKey.shiftLeft |
| 72 | + {0x00000033, 92}, // LogicalKeyboardKey.backslash |
| 73 | + {0x00000034, 90}, // LogicalKeyboardKey.keyZ |
| 74 | + {0x00000035, 88}, // LogicalKeyboardKey.keyX |
| 75 | + {0x00000036, 67}, // LogicalKeyboardKey.keyC |
| 76 | + {0x00000037, 86}, // LogicalKeyboardKey.keyV |
| 77 | + {0x00000038, 66}, // LogicalKeyboardKey.keyB |
| 78 | + {0x00000039, 78}, // LogicalKeyboardKey.keyN |
| 79 | + {0x0000003a, 77}, // LogicalKeyboardKey.keyM |
| 80 | + {0x0000003b, 44}, // LogicalKeyboardKey.comma |
| 81 | + {0x0000003c, 46}, // LogicalKeyboardKey.period |
| 82 | + {0x0000003d, 47}, // LogicalKeyboardKey.slash |
| 83 | + {0x0000003e, 65506}, // LogicalKeyboardKey.shiftRight |
| 84 | + {0x0000003f, 65450}, // LogicalKeyboardKey.numpadMultiply |
| 85 | + {0x00000040, 65513}, // LogicalKeyboardKey.altLeft |
| 86 | + {0x00000041, 32}, // LogicalKeyboardKey.space |
| 87 | + {0x00000042, 65509}, // LogicalKeyboardKey.capsLock |
| 88 | + {0x00000043, 65470}, // LogicalKeyboardKey.f1 |
| 89 | + {0x00000044, 65471}, // LogicalKeyboardKey.f2 |
| 90 | + {0x00000045, 65472}, // LogicalKeyboardKey.f3 |
| 91 | + {0x00000046, 65473}, // LogicalKeyboardKey.f4 |
| 92 | + {0x00000047, 65474}, // LogicalKeyboardKey.f5 |
| 93 | + {0x00000048, 65475}, // LogicalKeyboardKey.f6 |
| 94 | + {0x00000049, 65476}, // LogicalKeyboardKey.f7 |
| 95 | + {0x0000004a, 65477}, // LogicalKeyboardKey.f8 |
| 96 | + {0x0000004b, 65478}, // LogicalKeyboardKey.f9 |
| 97 | + {0x0000004c, 65479}, // LogicalKeyboardKey.f10 |
| 98 | + {0x0000004d, 65407}, // LogicalKeyboardKey.numLock |
| 99 | + {0x0000004e, 65300}, // LogicalKeyboardKey.scrollLock |
| 100 | + {0x0000004f, 65463}, // LogicalKeyboardKey.numpad7 |
| 101 | + {0x00000050, 65464}, // LogicalKeyboardKey.numpad8 |
| 102 | + {0x00000051, 65465}, // LogicalKeyboardKey.numpad9 |
| 103 | + {0x00000052, 65453}, // LogicalKeyboardKey.numpadSubtract |
| 104 | + {0x00000053, 65460}, // LogicalKeyboardKey.numpad4 |
| 105 | + {0x00000054, 65461}, // LogicalKeyboardKey.numpad5 |
| 106 | + {0x00000055, 65462}, // LogicalKeyboardKey.numpad6 |
| 107 | + {0x00000056, 65451}, // LogicalKeyboardKey.numpadAdd |
| 108 | + {0x00000057, 65457}, // LogicalKeyboardKey.numpad1 |
| 109 | + {0x00000058, 65458}, // LogicalKeyboardKey.numpad2 |
| 110 | + {0x00000059, 65459}, // LogicalKeyboardKey.numpad3 |
| 111 | + {0x0000005a, 65456}, // LogicalKeyboardKey.numpad0 |
| 112 | + {0x0000005b, 65454}, // LogicalKeyboardKey.numpadDecimal |
| 113 | + {0x0000005f, 65480}, // LogicalKeyboardKey.f11 |
| 114 | + {0x00000060, 65481}, // LogicalKeyboardKey.f12 |
| 115 | + {0x00000065, 65406}, // LogicalKeyboardKey.kanaMode |
| 116 | + {0x00000068, 65421}, // LogicalKeyboardKey.numpadEnter |
| 117 | + {0x00000069, 65508}, // LogicalKeyboardKey.controlRight |
| 118 | + {0x0000006a, 65455}, // LogicalKeyboardKey.numpadDivide |
| 119 | + {0x0000006b, 64797}, // LogicalKeyboardKey.printScreen |
| 120 | + {0x0000006c, 65514}, // LogicalKeyboardKey.altRight |
| 121 | + {0x0000006e, 65360}, // LogicalKeyboardKey.home |
| 122 | + {0x0000006f, 65362}, // LogicalKeyboardKey.arrowUp |
| 123 | + {0x00000070, 65365}, // LogicalKeyboardKey.pageUp |
| 124 | + {0x00000071, 65361}, // LogicalKeyboardKey.arrowLeft |
| 125 | + {0x00000072, 65363}, // LogicalKeyboardKey.arrowRight |
| 126 | + {0x00000073, 65367}, // LogicalKeyboardKey.end |
| 127 | + {0x00000074, 65364}, // LogicalKeyboardKey.arrowDown |
| 128 | + {0x00000075, 65366}, // LogicalKeyboardKey.pageDown |
| 129 | + {0x00000076, 65379}, // LogicalKeyboardKey.insert |
| 130 | + {0x00000077, 65535}, // LogicalKeyboardKey.delete |
| 131 | + {0x00000079, 269025042}, // LogicalKeyboardKey.audioVolumeMute |
| 132 | + {0x0000007a, 269025041}, // LogicalKeyboardKey.audioVolumeDown |
| 133 | + {0x0000007b, 269025043}, // LogicalKeyboardKey.audioVolumeUp |
| 134 | + {0x0000007c, 269025066}, // LogicalKeyboardKey.power |
| 135 | + {0x0000007d, 65469}, // LogicalKeyboardKey.numpadEqual |
| 136 | + {0x0000007f, 65299}, // LogicalKeyboardKey.pause |
| 137 | + {0x00000084, 165}, // LogicalKeyboardKey.intlYen |
| 138 | + {0x00000085, 65511}, // LogicalKeyboardKey.metaLeft |
| 139 | + {0x00000086, 65512}, // LogicalKeyboardKey.metaRight |
| 140 | + {0x00000087, 65383}, // LogicalKeyboardKey.contextMenu |
| 141 | + {0x00000088, 269025064}, // LogicalKeyboardKey.browserStop |
| 142 | + {0x0000008b, 65381}, // LogicalKeyboardKey.undo |
| 143 | + {0x0000008c, 65376}, // LogicalKeyboardKey.select |
| 144 | + {0x0000008d, 269025111}, // LogicalKeyboardKey.copy |
| 145 | + {0x0000008e, 269025131}, // LogicalKeyboardKey.open |
| 146 | + {0x0000008f, 269025133}, // LogicalKeyboardKey.paste |
| 147 | + {0x00000090, 65384}, // LogicalKeyboardKey.find |
| 148 | + {0x00000092, 65386}, // LogicalKeyboardKey.help |
| 149 | + {0x00000096, 269025071}, // LogicalKeyboardKey.sleep |
| 150 | + {0x00000097, 269025067}, // LogicalKeyboardKey.wakeUp |
| 151 | + {0x0000009e, 269025070}, // LogicalKeyboardKey.launchInternetBrowser |
| 152 | + {0x000000a3, 269025049}, // LogicalKeyboardKey.launchMail |
| 153 | + {0x000000a4, 269025072}, // LogicalKeyboardKey.browserFavorites |
| 154 | + {0x000000a6, 269025062}, // LogicalKeyboardKey.browserBack |
| 155 | + {0x000000a7, 269025063}, // LogicalKeyboardKey.browserForward |
| 156 | + {0x000000a9, 269025068}, // LogicalKeyboardKey.eject |
| 157 | + {0x000000ab, 269025047}, // LogicalKeyboardKey.mediaTrackNext |
| 158 | + {0x000000ad, 269025046}, // LogicalKeyboardKey.mediaTrackPrevious |
| 159 | + {0x000000ae, 269025045}, // LogicalKeyboardKey.mediaStop |
| 160 | + {0x000000af, 269025052}, // LogicalKeyboardKey.mediaRecord |
| 161 | + {0x000000b0, 269025086}, // LogicalKeyboardKey.mediaRewind |
| 162 | + {0x000000b1, 269025134}, // LogicalKeyboardKey.launchPhone |
| 163 | + {0x000000b4, 269025048}, // LogicalKeyboardKey.browserHome |
| 164 | + {0x000000b5, 269025065}, // LogicalKeyboardKey.browserRefresh |
| 165 | + {0x000000bd, 269025128}, // LogicalKeyboardKey.newKey |
| 166 | + {0x000000be, 65382}, // LogicalKeyboardKey.redo |
| 167 | + {0x000000bf, 65482}, // LogicalKeyboardKey.f13 |
| 168 | + {0x000000c0, 65483}, // LogicalKeyboardKey.f14 |
| 169 | + {0x000000c1, 65484}, // LogicalKeyboardKey.f15 |
| 170 | + {0x000000c2, 65485}, // LogicalKeyboardKey.f16 |
| 171 | + {0x000000c3, 65486}, // LogicalKeyboardKey.f17 |
| 172 | + {0x000000c4, 65487}, // LogicalKeyboardKey.f18 |
| 173 | + {0x000000c5, 65488}, // LogicalKeyboardKey.f19 |
| 174 | + {0x000000c6, 65489}, // LogicalKeyboardKey.f20 |
| 175 | + {0x000000c7, 65490}, // LogicalKeyboardKey.f21 |
| 176 | + {0x000000c8, 65491}, // LogicalKeyboardKey.f22 |
| 177 | + {0x000000c9, 65492}, // LogicalKeyboardKey.f23 |
| 178 | + {0x000000ca, 65493}, // LogicalKeyboardKey.f24 |
| 179 | + {0x000000d1, 269025073}, // LogicalKeyboardKey.mediaPause |
| 180 | + {0x000000d6, 269025110}, // LogicalKeyboardKey.close |
| 181 | + {0x000000d7, 269025044}, // LogicalKeyboardKey.mediaPlay |
| 182 | + {0x000000d8, 269025175}, // LogicalKeyboardKey.mediaFastForward |
| 183 | + {0x000000da, 65377}, // LogicalKeyboardKey.print |
| 184 | + {0x000000e1, 269025051}, // LogicalKeyboardKey.browserSearch |
| 185 | + {0x000000e8, 269025027}, // LogicalKeyboardKey.brightnessDown |
| 186 | + {0x000000e9, 269025026}, // LogicalKeyboardKey.brightnessUp |
| 187 | + {0x000000ed, 269025030}, // LogicalKeyboardKey.kbdIllumDown |
| 188 | + {0x000000ee, 269025029}, // LogicalKeyboardKey.kbdIllumUp |
| 189 | + {0x000000ef, 269025147}, // LogicalKeyboardKey.mailSend |
| 190 | + {0x000000f0, 269025138}, // LogicalKeyboardKey.mailReply |
| 191 | + {0x000000f1, 269025168}, // LogicalKeyboardKey.mailForward |
| 192 | + {0x000000f2, 269025143}, // LogicalKeyboardKey.save |
| 193 | + {0x00000190, 269025170}, // LogicalKeyboardKey.launchAudioBrowser |
| 194 | + {0x00000195, 269025056}, // LogicalKeyboardKey.launchCalendar |
| 195 | + {0x000001aa, 269025163}, // LogicalKeyboardKey.zoomIn |
| 196 | + {0x000001ab, 269025164}, // LogicalKeyboardKey.zoomOut |
| 197 | + {0x000001b8, 269025148}, // LogicalKeyboardKey.spellCheck |
| 198 | + {0x000001b9, 269025121}, // LogicalKeyboardKey.logOff |
| 199 | + {0x0000024d, 269025069}, // LogicalKeyboardKey.launchScreenSaver |
| 200 | +}; |
| 201 | + |
| 202 | +// The values are defined in: |
| 203 | +// - efl/Ecore_Input.h |
| 204 | +// - flutter/raw_keyboard_linux.dart (GtkKeyHelper) |
| 205 | +static const std::map<int, int> kModifierMap = { |
| 206 | + {0x0001, 1 << 0}, // SHIFT (modifierShift) |
| 207 | + {0x0002, 1 << 2}, // CTRL (modifierControl) |
| 208 | + {0x0004, 1 << 3}, // ALT (modifierMod1) |
| 209 | + {0x0008, 1 << 28}, // WIN (modifierMeta) |
| 210 | + {0x0010, 0}, // SCROLL (undefined) |
| 211 | + {0x0020, 1 << 4}, // NUM (modifierMod2) |
| 212 | + {0x0040, 1 << 1}, // CAPS (modifierCapsLock) |
| 213 | +}; |
| 214 | + |
| 215 | +KeyEventChannel::KeyEventChannel(flutter::BinaryMessenger* messenger) |
| 216 | + : channel_( |
| 217 | + std::make_unique<flutter::BasicMessageChannel<rapidjson::Document>>( |
| 218 | + messenger, kChannelName, |
| 219 | + &flutter::JsonMessageCodec::GetInstance())) {} |
| 220 | + |
| 221 | +KeyEventChannel::~KeyEventChannel() {} |
| 222 | + |
| 223 | +void KeyEventChannel::SendKeyEvent(Ecore_Event_Key* key, bool is_down) { |
| 224 | + LoggerD("code: %d, name: %s, mods: %d, type: %s", key->keycode, key->keyname, |
| 225 | + key->modifiers, is_down ? kKeyDown : kKeyUp); |
| 226 | + |
| 227 | + int gtk_keycode = 0; |
| 228 | + if (kKeyCodeMap.count(key->keycode) > 0) { |
| 229 | + gtk_keycode = kKeyCodeMap.at(key->keycode); |
| 230 | + } |
| 231 | + int gtk_modifiers = 0; |
| 232 | + for (auto element : kModifierMap) { |
| 233 | + if (element.first & key->modifiers) { |
| 234 | + gtk_modifiers |= element.second; |
| 235 | + } |
| 236 | + } |
| 237 | + |
| 238 | + rapidjson::Document event(rapidjson::kObjectType); |
| 239 | + auto& allocator = event.GetAllocator(); |
| 240 | + event.AddMember(kKeyMapKey, kLinuxKeyMap, allocator); |
| 241 | + event.AddMember(kToolkitKey, kGtkToolkit, allocator); |
| 242 | + event.AddMember(kUnicodeScalarValuesKey, 0, allocator); |
| 243 | + event.AddMember(kKeyCodeKey, gtk_keycode, allocator); |
| 244 | + event.AddMember(kScanCodeKey, key->keycode, allocator); |
| 245 | + event.AddMember(kModifiersKey, gtk_modifiers, allocator); |
| 246 | + if (is_down) { |
| 247 | + event.AddMember(kTypeKey, kKeyDown, allocator); |
| 248 | + } else { |
| 249 | + event.AddMember(kTypeKey, kKeyUp, allocator); |
| 250 | + } |
| 251 | + channel_->Send(event); |
| 252 | +} |
0 commit comments