Deskflow 1.26.0.314
Keyboard and mouse sharing utility
Loading...
Searching...
No Matches
XWindowsClipboard.h
Go to the documentation of this file.
1/*
2 * Deskflow -- mouse and keyboard sharing utility
3 * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
4 * SPDX-FileCopyrightText: (C) 2012 - 2016 Synergy App Ltd
5 * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
6 * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
7 */
8
9#pragma once
10
12#include "deskflow/IClipboard.h"
13
14#include <QString>
15
16#include <list>
17#include <map>
18#include <mutex>
19#include <vector>
20
21#include <X11/Xlib.h>
22
24
27{
28public:
33 XWindowsClipboard(Display *, Window window, ClipboardID id);
36 ~XWindowsClipboard() override;
37
40
42
45 void lost(Time);
46
48
53 void addRequest(Window owner, Window requestor, Atom target, ::Time time, Atom property);
54
56
60 bool processRequest(Window requestor, ::Time time, Atom property);
61
63
67 bool destroyRequest(Window requestor);
68
70
73 Window getWindow() const;
74
76
80 Atom getSelection() const;
81
82 // IClipboard overrides
83 bool empty() override;
84 void add(Format, const std::string &data) override;
85 bool open(Time) const override;
86 void close() const override;
87 Time getTime() const override;
88 bool has(Format) const override;
89 std::string get(Format) const override;
90
91private:
92 // remove all converters from our list
93 void clearConverters();
94
95 // get the converter for a clipboard format. returns nullptr if no
96 // suitable converter. iff onlyIfNotAdded is true then also
97 // return nullptr if a suitable converter was found but we already
98 // have data of the converter's clipboard format.
99 IXWindowsClipboardConverter *getConverter(Atom target, bool onlyIfNotAdded = false) const;
100
101 // convert target atom to clipboard format
102 Format getFormat(Atom target) const;
103
104 // add a non-MULTIPLE request. does not verify that the selection
105 // was owned at the given time. returns true if the conversion
106 // could be performed, false otherwise. in either case, the
107 // reply is inserted.
108 bool addSimpleRequest(Window requestor, Atom target, ::Time time, Atom property);
109
110 // if not already checked then see if the cache is stale and, if so,
111 // clear it. this has the side effect of updating m_timeOwned.
112 void checkCache() const;
113
114 // clear the cache, resetting the cached flag and the added flag for
115 // each format.
116 void clearCache() const;
117 void doClearCache();
118
119 // cache all formats of the selection
120 void fillCache() const;
121 void doFillCache();
122
123protected:
124 //
125 // helper classes
126 //
127
128 // read an ICCCM conforming selection
130 {
131 public:
132 CICCCMGetClipboard(Window requestor, Time time, Atom property);
134
135 // convert the given selection to the given type. returns
136 // true iff the conversion was successful or the conversion
137 // cannot be performed (in which case *actualTarget == None).
138 bool readClipboard(Display *display, Atom selection, Atom target, Atom *actualTarget, std::string *data);
139
140 private:
141 bool processEvent(Display *display, const XEvent *event);
142
143 private:
144 Window m_requestor;
145 Time m_time;
146 Atom m_property;
147 bool m_incr = false;
148 bool m_failed = false;
149 bool m_done = false;
150
151 // atoms needed for the protocol
152 Atom m_atomNone = None;
153 Atom m_atomIncr = None;
154
155 // true iff we've received the selection notify
156 bool m_reading = false;
157
158 // the converted selection data
159 std::string *m_data = nullptr;
160
161 // the actual type of the data. if this is None then the
162 // selection owner cannot convert to the requested type.
163 Atom *m_actualTarget = nullptr;
164
165 // true iff the selection owner didn't follow ICCCM conventions
166 bool m_error = false;
167
168 public:
169 bool error() const
170 {
171 return m_error;
172 }
173 };
174
175 // Motif structure IDs
176 enum class MotifClip : int32_t
177 {
179 Item = 2,
181 };
182
183 // _MOTIF_CLIP_HEADER structure
185 {
186 public:
188 int32_t m_pad1[3];
189 int32_t m_item;
190 int32_t m_pad2[4];
191 int32_t m_numItems;
192 int32_t m_pad3[3];
193 int32_t m_selectionOwner; // a Window
194 int32_t m_pad4[2];
195 };
196
197 // Motif clip item structure
199 {
200 public:
202 int32_t m_pad1[5];
203 int32_t m_size;
206 int32_t m_pad2[6];
207 };
208
209 // Motif clip format structure
211 {
212 public:
214 int32_t m_pad1[6];
215 int32_t m_length;
216 int32_t m_data;
217 int32_t m_type; // an Atom
218 int32_t m_pad2[1];
219 int32_t m_deleted;
220 int32_t m_pad3[4];
221 };
222
223 // stores data needed to respond to a selection request
224 class Reply
225 {
226 public:
227 Reply(Window, Atom target, ::Time);
228 Reply(Window, Atom target, ::Time, Atom property, const std::string &data, Atom type, int format);
229
230 public:
231 // information about the request
236
237 // true iff we've sent the notification for this reply
238 bool m_replied = false;
239
240 // true iff the reply has sent its last message
241 bool m_done = false;
242
243 // the data to send and its type and format
244 std::string m_data;
245 Atom m_type;
247
248 // index of next byte in m_data to send
249 uint32_t m_ptr = 0;
250 };
251 using ReplyList = std::list<Reply *>;
252 using ReplyMap = std::map<Window, ReplyList>;
253 using ReplyEventMask = std::map<Window, long>;
254
255 // ICCCM interoperability methods
256 void icccmFillCache();
257 bool icccmGetSelection(Atom target, Atom *actualTarget, std::string *data) const;
258 Time icccmGetTime() const;
259
260 // motif interoperability methods
261 bool motifLockClipboard() const;
262 void motifUnlockClipboard() const;
263 bool motifOwnsClipboard() const;
264 void motifFillCache();
265 bool motifGetSelection(const MotifClipFormat *, Atom *actualTarget, std::string *data) const;
266 Time motifGetTime() const;
267
268 // reply methods
269 bool insertMultipleReply(Window, ::Time, Atom);
270 void insertReply(Reply *);
271 void pushReplies();
272 void pushReplies(ReplyMap::iterator &, ReplyList &, ReplyList::iterator);
273 bool sendReply(Reply *);
274 void clearReplies();
275 void clearReplies(ReplyList &);
276 void sendNotify(Window requestor, Atom selection, Atom target, Atom property, Time time);
277 bool wasOwnedAtTime(::Time) const;
278
279 // data conversion methods
280 Atom getTargetsData(std::string &, int *format) const;
281 Atom getTimestampData(std::string &, int *format) const;
282
283private:
284 using ConverterList = std::vector<IXWindowsClipboardConverter *>;
285
286 Display *m_display;
287 Window m_window;
288 ClipboardID m_id;
289 Atom m_selection;
290 mutable std::mutex m_mutex;
291 mutable bool m_open = false;
292 mutable Time m_time = 0;
293 bool m_owner = false;
294 mutable Time m_timeOwned = 0;
295 Time m_timeLost = 0;
296
297 // true iff open and clipboard owned by a motif app
298 mutable bool m_motif;
299
300 // the added/cached clipboard data
301 mutable bool m_checkCache;
302 bool m_cached;
303 Time m_cacheTime;
304 bool m_added[static_cast<int>(IClipboard::Format::TotalFormats)];
305 std::string m_data[static_cast<int>(IClipboard::Format::TotalFormats)];
306
307 // conversion request replies
308 ReplyMap m_replies;
309 ReplyEventMask m_eventMasks;
310
311 // clipboard format converters
312 ConverterList m_converters;
313
314 // atoms we'll need
315 Atom m_atomTargets;
316 Atom m_atomMultiple;
317 Atom m_atomTimestamp;
318 Atom m_atomInteger;
319 Atom m_atomAtom;
320 Atom m_atomAtomPair;
321 Atom m_atomData;
322 Atom m_atomINCR;
323 Atom m_atomMotifClipLock;
324 Atom m_atomMotifClipHeader;
325 Atom m_atomMotifClipAccess;
326 Atom m_atomGDKSelection;
327};
328
330
335{
336public:
337 virtual ~IXWindowsClipboardConverter() = default;
339
340
342
345 virtual IClipboard::Format getFormat() const = 0;
346
348
352 virtual Atom getAtom() const = 0;
353
355
359 virtual int getDataSize() const = 0;
360
362
368 virtual std::string fromIClipboard(const std::string &) const = 0;
369
371
375 virtual std::string toIClipboard(const std::string &) const = 0;
376
378};
static int void FAR * data
Definition ArchNetworkWinsock.cpp:35
static int type
Definition ArchNetworkWinsock.cpp:45
uint8_t ClipboardID
Clipboard ID.
Definition ClipboardTypes.h:16
Clipboard interface.
Definition IClipboard.h:19
Format
Clipboard formats.
Definition IClipboard.h:50
@ TotalFormats
The number of clipboard formats supported.
Definition IClipboard.h:54
uint32_t Time
Timestamp type.
Definition IClipboard.h:28
Clipboard format converter interface.
Definition XWindowsClipboard.h:335
virtual std::string fromIClipboard(const std::string &) const =0
Convert from IClipboard format.
virtual IClipboard::Format getFormat() const =0
Get clipboard format.
virtual std::string toIClipboard(const std::string &) const =0
Convert to IClipboard format.
virtual int getDataSize() const =0
Get X11 property datum size.
virtual ~IXWindowsClipboardConverter()=default
virtual Atom getAtom() const =0
Get X11 format atom.
CICCCMGetClipboard(Window requestor, Time time, Atom property)
Definition XWindowsClipboard.cpp:1170
bool readClipboard(Display *display, Atom selection, Atom target, Atom *actualTarget, std::string *data)
Definition XWindowsClipboard.cpp:1177
bool error() const
Definition XWindowsClipboard.h:169
Definition XWindowsClipboard.h:211
MotifClip m_id
Definition XWindowsClipboard.h:213
int32_t m_length
Definition XWindowsClipboard.h:215
int32_t m_type
Definition XWindowsClipboard.h:217
int32_t m_deleted
Definition XWindowsClipboard.h:219
int32_t m_pad3[4]
Definition XWindowsClipboard.h:220
int32_t m_pad2[1]
Definition XWindowsClipboard.h:218
int32_t m_data
Definition XWindowsClipboard.h:216
int32_t m_pad1[6]
Definition XWindowsClipboard.h:214
Definition XWindowsClipboard.h:185
int32_t m_pad3[3]
Definition XWindowsClipboard.h:192
int32_t m_pad2[4]
Definition XWindowsClipboard.h:190
int32_t m_numItems
Definition XWindowsClipboard.h:191
int32_t m_selectionOwner
Definition XWindowsClipboard.h:193
MotifClip m_id
Definition XWindowsClipboard.h:187
int32_t m_pad4[2]
Definition XWindowsClipboard.h:194
int32_t m_item
Definition XWindowsClipboard.h:189
int32_t m_pad1[3]
Definition XWindowsClipboard.h:188
Definition XWindowsClipboard.h:199
int32_t m_numFormats
Definition XWindowsClipboard.h:204
int32_t m_pad2[6]
Definition XWindowsClipboard.h:206
int32_t m_numDeletedFormats
Definition XWindowsClipboard.h:205
int32_t m_size
Definition XWindowsClipboard.h:203
MotifClip m_id
Definition XWindowsClipboard.h:201
int32_t m_pad1[5]
Definition XWindowsClipboard.h:202
Definition XWindowsClipboard.h:225
bool m_replied
Definition XWindowsClipboard.h:238
Atom m_property
Definition XWindowsClipboard.h:235
Atom m_type
Definition XWindowsClipboard.h:245
int m_format
Definition XWindowsClipboard.h:246
Atom m_target
Definition XWindowsClipboard.h:233
Reply(Window, Atom target, ::Time)
Definition XWindowsClipboard.cpp:1387
::Time m_time
Definition XWindowsClipboard.h:234
uint32_t m_ptr
Definition XWindowsClipboard.h:249
std::string m_data
Definition XWindowsClipboard.h:244
Window m_requestor
Definition XWindowsClipboard.h:232
bool m_done
Definition XWindowsClipboard.h:241
bool empty() override
Empty clipboard.
Definition XWindowsClipboard.cpp:237
bool insertMultipleReply(Window, ::Time, Atom)
Definition XWindowsClipboard.cpp:779
bool sendReply(Reply *)
Definition XWindowsClipboard.cpp:916
XWindowsClipboard & operator=(XWindowsClipboard const &)=delete
bool motifGetSelection(const MotifClipFormat *, Atom *actualTarget, std::string *data) const
Definition XWindowsClipboard.cpp:748
bool has(Format) const override
Check for data.
Definition XWindowsClipboard.cpp:346
bool motifOwnsClipboard() const
Definition XWindowsClipboard.cpp:599
Time icccmGetTime() const
Definition XWindowsClipboard.cpp:545
void clearReplies()
Definition XWindowsClipboard.cpp:1071
XWindowsClipboard & operator=(XWindowsClipboard &&)=delete
void addRequest(Window owner, Window requestor, Atom target, ::Time time, Atom property)
Add clipboard request.
Definition XWindowsClipboard.cpp:96
std::string get(Format) const override
Get data.
Definition XWindowsClipboard.cpp:355
void motifFillCache()
Definition XWindowsClipboard.cpp:631
Atom getSelection() const
Get selection atom.
Definition XWindowsClipboard.cpp:232
Time motifGetTime() const
Definition XWindowsClipboard.cpp:774
Window getWindow() const
Get window.
Definition XWindowsClipboard.cpp:227
std::map< Window, long > ReplyEventMask
Definition XWindowsClipboard.h:253
bool processRequest(Window requestor, ::Time time, Atom property)
Process clipboard request.
Definition XWindowsClipboard.cpp:181
void motifUnlockClipboard() const
Definition XWindowsClipboard.cpp:585
void icccmFillCache()
Definition XWindowsClipboard.cpp:457
void pushReplies()
Definition XWindowsClipboard.cpp:869
Atom getTargetsData(std::string &, int *format) const
Definition XWindowsClipboard.cpp:1133
MotifClip
Definition XWindowsClipboard.h:177
@ Item
Definition XWindowsClipboard.h:179
@ Header
Definition XWindowsClipboard.h:180
~XWindowsClipboard() override
Definition XWindowsClipboard.cpp:78
void insertReply(Reply *)
Definition XWindowsClipboard.cpp:823
Time getTime() const override
Get time.
Definition XWindowsClipboard.cpp:339
bool motifLockClipboard() const
Definition XWindowsClipboard.cpp:560
bool destroyRequest(Window requestor)
Cancel clipboard request.
Definition XWindowsClipboard.cpp:209
void close() const override
Close clipboard.
Definition XWindowsClipboard.cpp:323
std::map< Window, ReplyList > ReplyMap
Definition XWindowsClipboard.h:252
Atom getTimestampData(std::string &, int *format) const
Definition XWindowsClipboard.cpp:1156
void add(Format, const std::string &data) override
Add data.
Definition XWindowsClipboard.cpp:270
void sendNotify(Window requestor, Atom selection, Atom target, Atom property, Time time)
Definition XWindowsClipboard.cpp:1088
void lost(Time)
Notify clipboard was lost.
Definition XWindowsClipboard.cpp:85
bool icccmGetSelection(Atom target, Atom *actualTarget, std::string *data) const
Definition XWindowsClipboard.cpp:527
XWindowsClipboard(XWindowsClipboard &&)=delete
bool open(Time) const override
Open clipboard.
Definition XWindowsClipboard.cpp:285
XWindowsClipboard(Display *, Window window, ClipboardID id)
Definition XWindowsClipboard.cpp:35
std::list< Reply * > ReplyList
Definition XWindowsClipboard.h:251
XWindowsClipboard(XWindowsClipboard const &)=delete
bool wasOwnedAtTime(::Time) const
Definition XWindowsClipboard.cpp:1102