1 /* 2 * SPDX-FileCopyrightText: 2020~2020 CSSlayer <wengxt@gmail.com> 3 * 4 * SPDX-License-Identifier: LGPL-2.1-or-later 5 * 6 */ 7 #ifndef _FCITX5_FRONTEND_WAYLANDIM_WAYLANDIMSERVERV2_H_ 8 #define _FCITX5_FRONTEND_WAYLANDIM_WAYLANDIMSERVERV2_H_ 9 10 #include <fcitx-utils/event.h> 11 #include <fcitx/focusgroup.h> 12 #include <fcitx/instance.h> 13 #include <xkbcommon/xkbcommon.h> 14 #include "display.h" 15 #include "zwp_input_method_keyboard_grab_v2.h" 16 #include "zwp_input_method_manager_v2.h" 17 #include "zwp_input_method_v2.h" 18 #include "zwp_virtual_keyboard_manager_v1.h" 19 #include "zwp_virtual_keyboard_v1.h" 20 21 namespace fcitx { 22 class WaylandIMModule; 23 class WaylandIMInputContextV2; 24 25 class WaylandIMServerV2 { 26 friend class WaylandIMInputContextV2; 27 28 public: 29 WaylandIMServerV2(wl_display *display, FocusGroup *group, 30 const std::string &name, WaylandIMModule *waylandim); 31 32 ~WaylandIMServerV2(); 33 34 InputContextManager &inputContextManager(); 35 36 void init(); 37 void refreshSeat(); 38 void activate(wayland::ZwpInputMethodV2 *id); 39 void deactivate(wayland::ZwpInputMethodV2 *id); 40 void add(WaylandIMInputContextV2 *ic, wayland::WlSeat *seat); 41 void remove(wayland::WlSeat *seat); 42 Instance *instance(); group()43 FocusGroup *group() { return group_; } xkbState()44 auto *xkbState() { return state_.get(); } inputMethodManagerV2()45 auto *inputMethodManagerV2() { return inputMethodManagerV2_.get(); } 46 47 private: 48 FocusGroup *group_; 49 std::string name_; 50 bool init_ = false; 51 WaylandIMModule *parent_; 52 std::shared_ptr<wayland::ZwpInputMethodManagerV2> inputMethodManagerV2_; 53 std::shared_ptr<wayland::ZwpVirtualKeyboardManagerV1> 54 virtualKeyboardManagerV1_; 55 56 UniqueCPtr<struct xkb_context, xkb_context_unref> context_; 57 std::vector<char> keymapData_; 58 UniqueCPtr<struct xkb_keymap, xkb_keymap_unref> keymap_; 59 UniqueCPtr<struct xkb_state, xkb_state_unref> state_; 60 61 wayland::Display *display_; 62 ScopedConnection globalConn_; 63 64 struct StateMask { 65 uint32_t shift_mask = 0; 66 uint32_t lock_mask = 0; 67 uint32_t control_mask = 0; 68 uint32_t mod1_mask = 0; 69 uint32_t mod2_mask = 0; 70 uint32_t mod3_mask = 0; 71 uint32_t mod4_mask = 0; 72 uint32_t mod5_mask = 0; 73 uint32_t super_mask = 0; 74 uint32_t hyper_mask = 0; 75 uint32_t meta_mask = 0; 76 } stateMask_; 77 78 KeyStates modifiers_; 79 80 std::unordered_map<wayland::WlSeat *, WaylandIMInputContextV2 *> icMap_; 81 }; 82 83 class WaylandIMInputContextV2 : public InputContext { 84 public: 85 WaylandIMInputContextV2(InputContextManager &inputContextManager, 86 WaylandIMServerV2 *server, 87 std::shared_ptr<wayland::WlSeat> seat, 88 wayland::ZwpVirtualKeyboardV1 *vk); 89 ~WaylandIMInputContextV2(); 90 frontend()91 const char *frontend() const override { return "wayland_v2"; } 92 inputMethodV2()93 auto inputMethodV2() { return ic_.get(); } 94 95 protected: commitStringImpl(const std::string & text)96 void commitStringImpl(const std::string &text) override { 97 ic_->commitString(text.c_str()); 98 ic_->commit(serial_); 99 } deleteSurroundingTextImpl(int offset,unsigned int size)100 void deleteSurroundingTextImpl(int offset, unsigned int size) override { 101 ic_->deleteSurroundingText(-offset, offset + size); 102 ic_->commit(serial_); 103 } 104 void forwardKeyImpl(const ForwardKeyEvent &key) override; 105 106 void updatePreeditImpl() override; 107 108 private: 109 void repeat(); 110 void surroundingTextCallback(const char *text, uint32_t cursor, 111 uint32_t anchor); 112 void resetCallback(); 113 void contentTypeCallback(uint32_t hint, uint32_t purpose); 114 void commitStateCallback(uint32_t serial); 115 116 void keymapCallback(uint32_t format, int32_t fd, uint32_t size); 117 void keyCallback(uint32_t serial, uint32_t time, uint32_t key, 118 uint32_t state); 119 void modifiersCallback(uint32_t serial, uint32_t mods_depressed, 120 uint32_t mods_latched, uint32_t mods_locked, 121 uint32_t group); 122 void repeatInfoCallback(int32_t rate, int32_t delay); 123 124 WaylandIMServerV2 *server_; 125 std::shared_ptr<wayland::WlSeat> seat_; 126 std::unique_ptr<wayland::ZwpInputMethodV2> ic_; 127 std::unique_ptr<wayland::ZwpInputMethodKeyboardGrabV2> keyboardGrab_; 128 std::unique_ptr<wayland::ZwpVirtualKeyboardV1> vk_; 129 std::unique_ptr<EventSourceTime> timeEvent_; 130 131 bool pendingActivate_ = false; 132 bool pendingDeactivate_ = false; 133 134 uint32_t serial_ = 0; 135 uint32_t time_ = 0; 136 137 uint32_t repeatKey_ = 0; 138 uint32_t repeatTime_ = 0; 139 KeySym repeatSym_ = FcitxKey_None; 140 141 int32_t repeatRate_ = 40, repeatDelay_ = 400; 142 }; 143 144 } // namespace fcitx 145 146 #endif // _FCITX5_FRONTEND_WAYLANDIM_WAYLANDIMSERVERV2_H_ 147