Line data Source code
1 : /** 2 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev> 3 : 4 : Permission is hereby granted, free of charge, to any person obtaining a copy 5 : of this software and associated documentation files (the "Software"), to deal 6 : in the Software without restriction, including without limitation the rights 7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 : copies of the Software, and to permit persons to whom the Software is 9 : furnished to do so, subject to the following conditions: 10 : 11 : The above copyright notice and this permission notice shall be included in 12 : all copies or substantial portions of the Software. 13 : 14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 : THE SOFTWARE. 21 : **/ 22 : 23 : #ifndef XENOLITH_PLATFORM_LINUX_XLPLATFORMLINUXXCBVIEW_H_ 24 : #define XENOLITH_PLATFORM_LINUX_XLPLATFORMLINUXXCBVIEW_H_ 25 : 26 : #include "XLPlatformLinuxXcb.h" 27 : #include "XLPlatformLinuxXkb.h" 28 : #include "XLPlatformLinuxView.h" 29 : 30 : #if LINUX 31 : 32 : namespace STAPPLER_VERSIONIZED stappler::xenolith::platform { 33 : 34 : class XcbView : public LinuxViewInterface { 35 : public: 36 : struct ScreenInfo { 37 : uint16_t width; 38 : uint16_t height; 39 : uint16_t mwidth; 40 : uint16_t mheight; 41 : Vector<uint16_t> rates; 42 : }; 43 : 44 : struct ModeInfo { 45 : uint32_t id; 46 : uint16_t width; 47 : uint16_t height; 48 : uint16_t rate; 49 : String name; 50 : }; 51 : 52 : struct CrtcInfo { 53 : xcb_randr_crtc_t crtc; 54 : int16_t x; 55 : int16_t y; 56 : uint16_t width; 57 : uint16_t height; 58 : xcb_randr_mode_t mode; 59 : uint16_t rotation; 60 : uint16_t rotations; 61 : Vector<xcb_randr_output_t> outputs; 62 : Vector<xcb_randr_output_t> possible; 63 : }; 64 : 65 : struct OutputInfo { 66 : xcb_randr_output_t output; 67 : xcb_randr_crtc_t crtc; 68 : Vector<xcb_randr_mode_t> modes; 69 : String name; 70 : }; 71 : 72 : struct ScreenInfoData { 73 : Vector<xcb_randr_crtc_t> currentCrtcs; 74 : Vector<xcb_randr_output_t> currentOutputs; 75 : Vector<ModeInfo> currentModeInfo; 76 : Vector<ModeInfo> modeInfo; 77 : Vector<ScreenInfo> screenInfo; 78 : Vector<CrtcInfo> crtcInfo; 79 : 80 : OutputInfo primaryOutput; 81 : CrtcInfo primaryCrtc; 82 : ModeInfo primaryMode; 83 : xcb_timestamp_t config; 84 : }; 85 : 86 : static void ReportError(int error); 87 : 88 : XcbView(XcbLibrary *, ViewInterface *, StringView, StringView bundleId, URect); 89 : virtual ~XcbView(); 90 : 91 : bool valid() const; 92 : 93 : virtual bool poll(bool frameReady) override; 94 : 95 25 : virtual int getSocketFd() const override { return _socket; } 96 : 97 : virtual uint64_t getScreenFrameInterval() const override; 98 : 99 : virtual void mapWindow() override; 100 : 101 10 : xcb_connection_t *getConnection() const { return _connection; } 102 10 : uint32_t getWindow() const { return _window; } 103 : 104 : virtual void readFromClipboard(Function<void(BytesView, StringView)> &&, Ref *) override; 105 : virtual void writeToClipboard(BytesView, StringView contentType) override; 106 : 107 : protected: 108 : ScreenInfoData getScreenInfo() const; 109 : 110 : void initXkb(); 111 : 112 : void updateXkbMapping(); 113 : void updateKeysymMapping(); 114 : xcb_keysym_t getKeysym(xcb_keycode_t code, uint16_t state, bool resolveMods = true); 115 : xkb_keysym_t composeSymbol(xkb_keysym_t sym, core::InputKeyComposeState &compose) const; 116 : 117 : void updateXkbKey(xcb_keycode_t code); 118 : 119 : // get code from keysym mapping table 120 : core::InputKeyCode getKeyCode(xcb_keycode_t code) const; 121 : 122 : // map keysym to InputKeyCode 123 : core::InputKeyCode getKeysymCode(xcb_keysym_t sym) const; 124 : 125 : void notifyClipboard(BytesView); 126 : 127 : xcb_atom_t writeTargetToProperty(xcb_selection_request_event_t *request); 128 : void handleSelectionRequest(xcb_selection_request_event_t *e); 129 : 130 : Rc<XcbLibrary> _xcb; 131 : Rc<XkbLibrary> _xkb; 132 : ViewInterface *_view = nullptr; 133 : xcb_connection_t *_connection = nullptr; 134 : xcb_screen_t *_defaultScreen = nullptr; 135 : xcb_key_symbols_t *_keysyms = nullptr; 136 : uint32_t _window = 0; 137 : 138 : xcb_atom_t _atoms[sizeof(s_atomRequests) / sizeof(XcbAtomRequest)]; 139 : 140 : uint16_t _width = 0; 141 : uint16_t _height = 0; 142 : uint16_t _rate = 60; 143 : 144 : int _socket = -1; 145 : 146 : uint16_t _numlock = 0; 147 : uint16_t _shiftlock = 0; 148 : uint16_t _capslock = 0; 149 : uint16_t _modeswitch = 0; 150 : 151 : bool _xcbSetup = false; 152 : bool _randrEnabled = true; 153 : int32_t _xkbDeviceId = 0; 154 : uint8_t _xkbFirstEvent = 0; 155 : uint8_t _xkbFirstError = 0; 156 : uint8_t _randrFirstEvent = 0; 157 : xkb_keymap *_xkbKeymap = nullptr; 158 : xkb_state *_xkbState = nullptr; 159 : xkb_compose_state *_xkbCompose = nullptr; 160 : core::InputKeyCode _keycodes[256] = { core::InputKeyCode::Unknown }; 161 : 162 : String _wmClass; 163 : ScreenInfoData _screenInfo; 164 : 165 : Function<void(BytesView, StringView)> _clipboardCallback; 166 : Rc<Ref> _clipboardTarget; 167 : Bytes _clipboardSelection; 168 : }; 169 : 170 : } 171 : 172 : #endif 173 : 174 : #endif /* XENOLITH_PLATFORM_LINUX_XLPLATFORMLINUXXCBVIEW_H_ */