Deskflow 1.24.0.365
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 Symless 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 <vector>
19
20#include <X11/Xlib.h>
21
23
26{
27public:
32 XWindowsClipboard(Display *, Window window, ClipboardID id);
35 ~XWindowsClipboard() override;
36
39
41
44 void lost(Time);
45
47
52 void addRequest(Window owner, Window requestor, Atom target, ::Time time, Atom property);
53
55
59 bool processRequest(Window requestor, ::Time time, Atom property);
60
62
66 bool destroyRequest(Window requestor);
67
69
72 Window getWindow() const;
73
75
79 Atom getSelection() const;
80
81 // IClipboard overrides
82 bool empty() override;
83 void add(Format, const std::string &data) override;
84 bool open(Time) const override;
85 void close() const override;
86 Time getTime() const override;
87 bool has(Format) const override;
88 std::string get(Format) const override;
89
90private:
91 // remove all converters from our list
92 void clearConverters();
93
94 // get the converter for a clipboard format. returns nullptr if no
95 // suitable converter. iff onlyIfNotAdded is true then also
96 // return nullptr if a suitable converter was found but we already
97 // have data of the converter's clipboard format.
98 IXWindowsClipboardConverter *getConverter(Atom target, bool onlyIfNotAdded = false) const;
99
100 // convert target atom to clipboard format
101 Format getFormat(Atom target) const;
102
103 // add a non-MULTIPLE request. does not verify that the selection
104 // was owned at the given time. returns true if the conversion
105 // could be performed, false otherwise. in either case, the
106 // reply is inserted.
107 bool addSimpleRequest(Window requestor, Atom target, ::Time time, Atom property);
108
109 // if not already checked then see if the cache is stale and, if so,
110 // clear it. this has the side effect of updating m_timeOwned.
111 void checkCache() const;
112
113 // clear the cache, resetting the cached flag and the added flag for
114 // each format.
115 void clearCache() const;
116 void doClearCache();
117
118 // cache all formats of the selection
119 void fillCache() const;
120 void doFillCache();
121
122protected:
123 //
124 // helper classes
125 //
126
127 // read an ICCCM conforming selection
129 {
130 public:
131 CICCCMGetClipboard(Window requestor, Time time, Atom property);
133
134 // convert the given selection to the given type. returns
135 // true iff the conversion was successful or the conversion
136 // cannot be performed (in which case *actualTarget == None).
137 bool readClipboard(Display *display, Atom selection, Atom target, Atom *actualTarget, std::string *data);
138
139 private:
140 bool processEvent(Display *display, const XEvent *event);
141
142 private:
143 Window m_requestor;
144 Time m_time;
145 Atom m_property;
146 bool m_incr = false;
147 bool m_failed = false;
148 bool m_done = false;
149
150 // atoms needed for the protocol
151 Atom m_atomNone = None;
152 Atom m_atomIncr = None;
153
154 // true iff we've received the selection notify
155 bool m_reading = false;
156
157 // the converted selection data
158 std::string *m_data = nullptr;
159
160 // the actual type of the data. if this is None then the
161 // selection owner cannot convert to the requested type.
162 Atom *m_actualTarget = nullptr;
163
164 // true iff the selection owner didn't follow ICCCM conventions
165 bool m_error = false;
166
167 public:
168 bool error() const
169 {
170 return m_error;
171 }
172 };
173
174 // Motif structure IDs
175 enum class MotifClip : int32_t
176 {
178 Item = 2,
180 };
181
182 // _MOTIF_CLIP_HEADER structure
184 {
185 public:
187 int32_t m_pad1[3];
188 int32_t m_item;
189 int32_t m_pad2[4];
190 int32_t m_numItems;
191 int32_t m_pad3[3];
192 int32_t m_selectionOwner; // a Window
193 int32_t m_pad4[2];
194 };
195
196 // Motif clip item structure
198 {
199 public:
201 int32_t m_pad1[5];
202 int32_t m_size;
205 int32_t m_pad2[6];
206 };
207
208 // Motif clip format structure
210 {
211 public:
213 int32_t m_pad1[6];
214 int32_t m_length;
215 int32_t m_data;
216 int32_t m_type; // an Atom
217 int32_t m_pad2[1];
218 int32_t m_deleted;
219 int32_t m_pad3[4];
220 };
221
222 // stores data needed to respond to a selection request
223 class Reply
224 {
225 public:
226 Reply(Window, Atom target, ::Time);
227 Reply(Window, Atom target, ::Time, Atom property, const std::string &data, Atom type, int format);
228
229 public:
230 // information about the request
235
236 // true iff we've sent the notification for this reply
237 bool m_replied = false;
238
239 // true iff the reply has sent its last message
240 bool m_done = false;
241
242 // the data to send and its type and format
243 std::string m_data;
244 Atom m_type;
246
247 // index of next byte in m_data to send
248 uint32_t m_ptr = 0;
249 };
250 using ReplyList = std::list<Reply *>;
251 using ReplyMap = std::map<Window, ReplyList>;
252 using ReplyEventMask = std::map<Window, long>;
253
254 // ICCCM interoperability methods
255 void icccmFillCache();
256 bool icccmGetSelection(Atom target, Atom *actualTarget, std::string *data) const;
257 Time icccmGetTime() const;
258
259 // motif interoperability methods
260 bool motifLockClipboard() const;
261 void motifUnlockClipboard() const;
262 bool motifOwnsClipboard() const;
263 void motifFillCache();
264 bool motifGetSelection(const MotifClipFormat *, Atom *actualTarget, std::string *data) const;
265 Time motifGetTime() const;
266
267 // reply methods
268 bool insertMultipleReply(Window, ::Time, Atom);
269 void insertReply(Reply *);
270 void pushReplies();
271 void pushReplies(ReplyMap::iterator &, ReplyList &, ReplyList::iterator);
272 bool sendReply(Reply *);
273 void clearReplies();
274 void clearReplies(ReplyList &);
275 void sendNotify(Window requestor, Atom selection, Atom target, Atom property, Time time);
276 bool wasOwnedAtTime(::Time) const;
277
278 // data conversion methods
279 Atom getTargetsData(std::string &, int *format) const;
280 Atom getTimestampData(std::string &, int *format) const;
281
282private:
283 using ConverterList = std::vector<IXWindowsClipboardConverter *>;
284
285 Display *m_display;
286 Window m_window;
287 ClipboardID m_id;
288 Atom m_selection;
289 mutable bool m_open = false;
290 mutable Time m_time = 0;
291 bool m_owner = false;
292 mutable Time m_timeOwned = 0;
293 Time m_timeLost = 0;
294
295 // true iff open and clipboard owned by a motif app
296 mutable bool m_motif;
297
298 // the added/cached clipboard data
299 mutable bool m_checkCache;
300 bool m_cached;
301 Time m_cacheTime;
302 bool m_added[static_cast<int>(IClipboard::Format::TotalFormats)];
303 std::string m_data[static_cast<int>(IClipboard::Format::TotalFormats)];
304
305 // conversion request replies
306 ReplyMap m_replies;
307 ReplyEventMask m_eventMasks;
308
309 // clipboard format converters
310 ConverterList m_converters;
311
312 // atoms we'll need
313 Atom m_atomTargets;
314 Atom m_atomMultiple;
315 Atom m_atomTimestamp;
316 Atom m_atomInteger;
317 Atom m_atomAtom;
318 Atom m_atomAtomPair;
319 Atom m_atomData;
320 Atom m_atomINCR;
321 Atom m_atomMotifClipLock;
322 Atom m_atomMotifClipHeader;
323 Atom m_atomMotifClipAccess;
324 Atom m_atomGDKSelection;
325};
326
328
333{
334public:
335 virtual ~IXWindowsClipboardConverter() = default;
337
338
340
343 virtual IClipboard::Format getFormat() const = 0;
344
346
350 virtual Atom getAtom() const = 0;
351
353
357 virtual int getDataSize() const = 0;
358
360
366 virtual std::string fromIClipboard(const std::string &) const = 0;
367
369
373 virtual std::string toIClipboard(const std::string &) const = 0;
374
376};
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:333
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:1157
bool readClipboard(Display *display, Atom selection, Atom target, Atom *actualTarget, std::string *data)
Definition XWindowsClipboard.cpp:1164
bool error() const
Definition XWindowsClipboard.h:168
Definition XWindowsClipboard.h:210
MotifClip m_id
Definition XWindowsClipboard.h:212
int32_t m_length
Definition XWindowsClipboard.h:214
int32_t m_type
Definition XWindowsClipboard.h:216
int32_t m_deleted
Definition XWindowsClipboard.h:218
int32_t m_pad3[4]
Definition XWindowsClipboard.h:219
int32_t m_pad2[1]
Definition XWindowsClipboard.h:217
int32_t m_data
Definition XWindowsClipboard.h:215
int32_t m_pad1[6]
Definition XWindowsClipboard.h:213
Definition XWindowsClipboard.h:184
int32_t m_pad3[3]
Definition XWindowsClipboard.h:191
int32_t m_pad2[4]
Definition XWindowsClipboard.h:189
int32_t m_numItems
Definition XWindowsClipboard.h:190
int32_t m_selectionOwner
Definition XWindowsClipboard.h:192
MotifClip m_id
Definition XWindowsClipboard.h:186
int32_t m_pad4[2]
Definition XWindowsClipboard.h:193
int32_t m_item
Definition XWindowsClipboard.h:188
int32_t m_pad1[3]
Definition XWindowsClipboard.h:187
Definition XWindowsClipboard.h:198
int32_t m_numFormats
Definition XWindowsClipboard.h:203
int32_t m_pad2[6]
Definition XWindowsClipboard.h:205
int32_t m_numDeletedFormats
Definition XWindowsClipboard.h:204
int32_t m_size
Definition XWindowsClipboard.h:202
MotifClip m_id
Definition XWindowsClipboard.h:200
int32_t m_pad1[5]
Definition XWindowsClipboard.h:201
Definition XWindowsClipboard.h:224
bool m_replied
Definition XWindowsClipboard.h:237
Atom m_property
Definition XWindowsClipboard.h:234
Atom m_type
Definition XWindowsClipboard.h:244
int m_format
Definition XWindowsClipboard.h:245
Atom m_target
Definition XWindowsClipboard.h:232
Reply(Window, Atom target, ::Time)
Definition XWindowsClipboard.cpp:1374
::Time m_time
Definition XWindowsClipboard.h:233
uint32_t m_ptr
Definition XWindowsClipboard.h:248
std::string m_data
Definition XWindowsClipboard.h:243
Window m_requestor
Definition XWindowsClipboard.h:231
bool m_done
Definition XWindowsClipboard.h:240
bool empty() override
Empty clipboard.
Definition XWindowsClipboard.cpp:231
bool insertMultipleReply(Window, ::Time, Atom)
Definition XWindowsClipboard.cpp:766
bool sendReply(Reply *)
Definition XWindowsClipboard.cpp:903
XWindowsClipboard & operator=(XWindowsClipboard const &)=delete
bool motifGetSelection(const MotifClipFormat *, Atom *actualTarget, std::string *data) const
Definition XWindowsClipboard.cpp:735
bool has(Format) const override
Check for data.
Definition XWindowsClipboard.cpp:335
bool motifOwnsClipboard() const
Definition XWindowsClipboard.cpp:586
Time icccmGetTime() const
Definition XWindowsClipboard.cpp:532
void clearReplies()
Definition XWindowsClipboard.cpp:1058
XWindowsClipboard & operator=(XWindowsClipboard &&)=delete
void addRequest(Window owner, Window requestor, Atom target, ::Time time, Atom property)
Add clipboard request.
Definition XWindowsClipboard.cpp:92
std::string get(Format) const override
Get data.
Definition XWindowsClipboard.cpp:343
void motifFillCache()
Definition XWindowsClipboard.cpp:618
Atom getSelection() const
Get selection atom.
Definition XWindowsClipboard.cpp:226
Time motifGetTime() const
Definition XWindowsClipboard.cpp:761
Window getWindow() const
Get window.
Definition XWindowsClipboard.cpp:221
std::map< Window, long > ReplyEventMask
Definition XWindowsClipboard.h:252
bool processRequest(Window requestor, ::Time time, Atom property)
Process clipboard request.
Definition XWindowsClipboard.cpp:176
void motifUnlockClipboard() const
Definition XWindowsClipboard.cpp:572
void icccmFillCache()
Definition XWindowsClipboard.cpp:444
void pushReplies()
Definition XWindowsClipboard.cpp:856
Atom getTargetsData(std::string &, int *format) const
Definition XWindowsClipboard.cpp:1120
MotifClip
Definition XWindowsClipboard.h:176
@ Item
Definition XWindowsClipboard.h:178
@ Header
Definition XWindowsClipboard.h:179
~XWindowsClipboard() override
Definition XWindowsClipboard.cpp:76
void insertReply(Reply *)
Definition XWindowsClipboard.cpp:810
Time getTime() const override
Get time.
Definition XWindowsClipboard.cpp:329
bool motifLockClipboard() const
Definition XWindowsClipboard.cpp:547
bool destroyRequest(Window requestor)
Cancel clipboard request.
Definition XWindowsClipboard.cpp:203
void close() const override
Close clipboard.
Definition XWindowsClipboard.cpp:314
std::map< Window, ReplyList > ReplyMap
Definition XWindowsClipboard.h:251
Atom getTimestampData(std::string &, int *format) const
Definition XWindowsClipboard.cpp:1143
void add(Format, const std::string &data) override
Add data.
Definition XWindowsClipboard.cpp:263
void sendNotify(Window requestor, Atom selection, Atom target, Atom property, Time time)
Definition XWindowsClipboard.cpp:1075
void lost(Time)
Notify clipboard was lost.
Definition XWindowsClipboard.cpp:82
bool icccmGetSelection(Atom target, Atom *actualTarget, std::string *data) const
Definition XWindowsClipboard.cpp:514
XWindowsClipboard(XWindowsClipboard &&)=delete
bool open(Time) const override
Open clipboard.
Definition XWindowsClipboard.cpp:277
XWindowsClipboard(Display *, Window window, ClipboardID id)
Definition XWindowsClipboard.cpp:34
std::list< Reply * > ReplyList
Definition XWindowsClipboard.h:250
XWindowsClipboard(XWindowsClipboard const &)=delete
bool wasOwnedAtTime(::Time) const
Definition XWindowsClipboard.cpp:1089