FreeRDP
Loading...
Searching...
No Matches
sdl_context.hpp
1
19#pragma once
20
21#include <map>
22#include <memory>
23#include <optional>
24#include <sstream>
25#include <vector>
26#include <mutex>
27#include <queue>
28#include <thread>
29#include <atomic>
30
31#include <freerdp/freerdp.h>
32
33#include <SDL3/SDL.h>
34
35#include <sdl_common_utils.hpp>
36
37#include "sdl_window.hpp"
38#include "sdl_disp.hpp"
39#include "sdl_clip.hpp"
40#include "sdl_input.hpp"
41#include "sdl_rail.hpp"
42
43#include "dialogs/sdl_connection_dialog_wrapper.hpp"
44
45class SdlContext
46{
47 public:
48 enum CursorType
49 {
50 CURSOR_NULL,
51 CURSOR_DEFAULT,
52 CURSOR_IMAGE
53 };
54
55 explicit SdlContext(rdpContext* context);
56 SdlContext(const SdlContext& other) = delete;
57 SdlContext(SdlContext&& other) = delete;
58 ~SdlContext() = default;
59
60 SdlContext& operator=(const SdlContext& other) = delete;
61 SdlContext& operator=(SdlContext&& other) = delete;
62
63 [[nodiscard]] bool redraw(bool suppress = false) const;
64
65 void setConnected(bool val);
66 [[nodiscard]] bool isConnected() const;
67 void cleanup();
68
69 [[nodiscard]] bool resizeable() const;
70 [[nodiscard]] bool toggleResizeable();
71 [[nodiscard]] bool setResizeable(bool enable);
72
73 [[nodiscard]] bool fullscreen() const;
74 [[nodiscard]] bool toggleFullscreen();
75 [[nodiscard]] bool setFullscreen(bool enter, bool forceOriginalDisplay = false);
76
77 [[nodiscard]] bool setMinimized();
78
79 [[nodiscard]] bool grabMouse() const;
80 [[nodiscard]] bool toggleGrabMouse();
81 [[nodiscard]] bool setGrabMouse(bool enter);
82
83 [[nodiscard]] bool grabKeyboard() const;
84 [[nodiscard]] bool toggleGrabKeyboard();
85 [[nodiscard]] bool setGrabKeyboard(bool enter);
86
87 [[nodiscard]] rdpContext* context() const;
88 [[nodiscard]] rdpClientContext* common() const;
89
90 [[nodiscard]] bool setCursor(CursorType type);
91 [[nodiscard]] bool setCursor(const rdpPointer* cursor);
92 [[nodiscard]] rdpPointer* cursor() const;
93 [[nodiscard]] bool restoreCursor();
94
95 void setMonitorIds(const std::vector<SDL_DisplayID>& ids);
96 [[nodiscard]] const std::vector<SDL_DisplayID>& monitorIds() const;
97 [[nodiscard]] int64_t monitorId(uint32_t index) const;
98
99 void push(std::vector<SDL_Rect>&& rects);
100 [[nodiscard]] std::vector<SDL_Rect> pop();
101
102 void setHasCursor(bool val);
103 [[nodiscard]] bool hasCursor() const;
104
105 void setMetadata();
106
107 [[nodiscard]] int start();
108 [[nodiscard]] int join();
109 [[nodiscard]] bool shallAbort(bool ignoreDialogs = false);
110
111 [[nodiscard]] bool createWindows();
112 [[nodiscard]] bool updateWindowList();
113 [[nodiscard]] bool updateWindow(SDL_WindowID id);
114
115 [[nodiscard]] bool drawToWindows(const std::vector<SDL_Rect>& rects = {});
116 [[nodiscard]] bool drawToWindow(SdlWindow& window, const std::vector<SDL_Rect>& rects = {});
117 [[nodiscard]] bool minimizeAllWindows();
118 [[nodiscard]] int exitCode() const;
119 [[nodiscard]] SDL_PixelFormat pixelFormat() const;
120
121 [[nodiscard]] const SdlWindow* getWindowForId(SDL_WindowID id) const;
122 [[nodiscard]] SdlWindow* getWindowForId(SDL_WindowID id);
123 [[nodiscard]] bool allWindowsHidden() const;
124 [[nodiscard]] SdlWindow* getFirstWindow();
125
126 [[nodiscard]] bool addDisplayWindow(SDL_DisplayID id);
127 [[nodiscard]] bool removeDisplayWindow(SDL_DisplayID id);
128 [[nodiscard]] bool detectDisplays();
129 [[nodiscard]] rdpMonitor getDisplay(SDL_DisplayID id) const;
130 [[nodiscard]] std::vector<SDL_DisplayID> getDisplayIds() const;
131
132 [[nodiscard]] sdlDispContext& getDisplayChannelContext();
133 [[nodiscard]] sdlInput& getInputChannelContext();
134 [[nodiscard]] sdlClip& getClipboardChannelContext();
135 [[nodiscard]] SdlRail& getRailChannelContext();
136
137 [[nodiscard]] SdlConnectionDialogWrapper& getDialog();
138
139 [[nodiscard]] wLog* getWLog();
140
141 [[nodiscard]] bool moveMouseTo(const SDL_FPoint& pos);
142
143 [[nodiscard]] SDL_FPoint screenToPixel(SDL_WindowID id, const SDL_FPoint& pos);
144
145 [[nodiscard]] SDL_FPoint pixelToScreen(SDL_WindowID id, const SDL_FPoint& pos);
146 [[nodiscard]] SDL_FRect pixelToScreen(SDL_WindowID id, const SDL_FRect& pos,
147 bool round = false);
148
149 [[nodiscard]] bool handleEvent(const SDL_Event& ev);
150
151 [[nodiscard]] COMMAND_LINE_ARGUMENT_A* args();
152 [[nodiscard]] size_t argsCount() const;
153
154 [[nodiscard]] static int argumentHandler(const COMMAND_LINE_ARGUMENT_A* arg, void* custom);
155
156 [[nodiscard]] CriticalSection& lock();
157
158 [[nodiscard]] std::vector<rdpPointer*>& pointers();
159 [[nodiscard]] bool contains(const rdpPointer* ptr) const;
160
161 [[nodiscard]] bool credentialsRead() const;
162 void setCredentialsRead();
163
164 private:
165 [[nodiscard]] bool resizeToScale(SdlWindow* window);
166 [[nodiscard]] bool useLocalScale() const;
167
168 [[nodiscard]] static BOOL preConnect(freerdp* instance);
169 [[nodiscard]] static BOOL postConnect(freerdp* instance);
170 static void postDisconnect(freerdp* instance);
171 static void postFinalDisconnect(freerdp* instance);
172 [[nodiscard]] static BOOL getAccessToken(freerdp* instance, AccessTokenType tokenType,
173 char** token, size_t count, ...);
174 [[nodiscard]] static BOOL desktopResize(rdpContext* context);
175 [[nodiscard]] static BOOL playSound(rdpContext* context, const PLAY_SOUND_UPDATE* play_sound);
176 [[nodiscard]] static BOOL beginPaint(rdpContext* context);
177 [[nodiscard]] static BOOL endPaint(rdpContext* context);
178 [[nodiscard]] static DWORD WINAPI rdpThreadRun(SdlContext* sdl);
179
180 [[nodiscard]] bool eventToPixelCoordinates(SDL_WindowID id, SDL_Event& ev);
181
182 [[nodiscard]] SDL_FPoint applyLocalScaling(const SDL_FPoint& val) const;
183 void removeLocalScaling(float& x, float& y) const;
184
185 [[nodiscard]] bool handleEvent(const SDL_WindowEvent& ev);
186 [[nodiscard]] bool handleEvent(const SDL_DisplayEvent& ev);
187 [[nodiscard]] bool handleEvent(const SDL_MouseButtonEvent& ev);
188 [[nodiscard]] bool handleEvent(const SDL_MouseMotionEvent& ev);
189 [[nodiscard]] bool handleEvent(const SDL_MouseWheelEvent& ev);
190 [[nodiscard]] bool handleEvent(const SDL_TouchFingerEvent& ev);
191
192 void addOrUpdateDisplay(SDL_DisplayID id);
193 void deleteDisplay(SDL_DisplayID id);
194
195 [[nodiscard]] bool createPrimary();
196 [[nodiscard]] std::string windowTitle() const;
197 [[nodiscard]] bool waitForWindowsCreated();
198
199 void sdl_client_cleanup(int exit_code, const std::string& error_msg);
200 [[nodiscard]] int sdl_client_thread_connect(std::string& error_msg);
201 [[nodiscard]] int sdl_client_thread_run(std::string& error_msg);
202
203 [[nodiscard]] int error_info_to_error(DWORD* pcode, char** msg, size_t* len) const;
204
205 void applyMonitorOffset(SDL_WindowID window, float& x, float& y) const;
206
207 [[nodiscard]] std::vector<SDL_DisplayID>
208 updateDisplayOffsetsForNeighbours(SDL_DisplayID id,
209 const std::vector<SDL_DisplayID>& ignore = {});
210 void updateMonitorDataFromOffsets();
211
212 rdpContext* _context = nullptr;
213 wLog* _log = nullptr;
214
215 std::atomic<bool> _connected = false;
216 bool _cursor_visible = true;
217 std::unique_ptr<rdpPointer, void (*)(rdpPointer*)> _cursor;
218 CursorType _cursorType = CURSOR_NULL;
219 std::vector<SDL_DisplayID> _monitorIds;
220 std::mutex _queue_mux;
221 std::queue<std::vector<SDL_Rect>> _queue;
222 /* SDL */
223 bool _fullscreen = false;
224 bool _resizeable = false;
225 bool _grabMouse = false;
226 bool _grabKeyboard = false;
227
228 /* RemoteApp pointer state */
229 struct
230 {
231 SDL_WindowID window = 0;
232 SDL_FPoint local = {};
233 SDL_FPoint server = {};
234 } _lastMotion; /* last motion forwarded to the server */
235 struct
236 {
237 SDL_WindowID window = 0;
238 Uint64 time = 0;
239 } _lastRelease;
240 int _exitCode = -1;
241 std::atomic<bool> _rdpThreadRunning = false;
242 SDL_PixelFormat _sdlPixelFormat = SDL_PIXELFORMAT_UNKNOWN;
243
244 CriticalSection _critical;
245
246 using SDLSurfacePtr = std::unique_ptr<SDL_Surface, decltype(&SDL_DestroySurface)>;
247
248 SDLSurfacePtr _primary;
249 SDL_FPoint _localScale{ 1.0f, 1.0f };
250
251 sdlDispContext _disp;
252 sdlInput _input;
253 sdlClip _clip;
254 SdlRail _rail;
255
257
258 std::map<SDL_DisplayID, rdpMonitor> _displays;
259 std::map<SDL_WindowID, SdlWindow> _windows;
260 std::map<SDL_DisplayID, std::pair<SDL_Rect, SDL_Rect>> _offsets;
261
262 uint32_t _windowWidth = 0;
263 uint32_t _windowHeight = 0;
264 WinPREvent _windowsCreatedEvent;
265 std::thread _thread;
266 std::vector<COMMAND_LINE_ARGUMENT_A> _args;
267 std::optional<bool> _connectionDialog;
268 std::vector<rdpPointer*> _valid_pointers;
269 bool _credentialsRead = false;
270};
object that handles clipboard context for the SDL3 client
Definition sdl_clip.hpp:77