source: trunk/synergy/lib/platform/CXWindowsClipboard.h

Last change on this file was 2749, checked in by bird, 19 years ago

synergy v1.3.1 sources (zip).

File size: 9.7 KB
Line 
1/*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2002 Chris Schoeneman
4 *
5 * This package is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * found in the file COPYING that should have accompanied this file.
8 *
9 * This package is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#ifndef CXWINDOWSCLIPBOARD_H
16#define CXWINDOWSCLIPBOARD_H
17
18#include "IClipboard.h"
19#include "ClipboardTypes.h"
20#include "stdmap.h"
21#include "stdlist.h"
22#include "stdvector.h"
23#if X_DISPLAY_MISSING
24# error X11 is required to build synergy
25#else
26# include <X11/Xlib.h>
27#endif
28
29class IXWindowsClipboardConverter;
30
31//! X11 clipboard implementation
32class CXWindowsClipboard : public IClipboard {
33public:
34 /*!
35 Use \c window as the window that owns or interacts with the
36 clipboard identified by \c id.
37 */
38 CXWindowsClipboard(Display*, Window window, ClipboardID id);
39 virtual ~CXWindowsClipboard();
40
41 //! Notify clipboard was lost
42 /*!
43 Tells clipboard it lost ownership at the given time.
44 */
45 void lost(Time);
46
47 //! Add clipboard request
48 /*!
49 Adds a selection request to the request list. If the given
50 owner window isn't this clipboard's window then this simply
51 sends a failure event to the requestor.
52 */
53 void addRequest(Window owner,
54 Window requestor, Atom target,
55 ::Time time, Atom property);
56
57 //! Process clipboard request
58 /*!
59 Continues processing a selection request. Returns true if the
60 request was handled, false if the request was unknown.
61 */
62 bool processRequest(Window requestor,
63 ::Time time, Atom property);
64
65 //! Cancel clipboard request
66 /*!
67 Terminate a selection request. Returns true iff the request
68 was known and handled.
69 */
70 bool destroyRequest(Window requestor);
71
72 //! Get window
73 /*!
74 Returns the clipboard's window (passed the c'tor).
75 */
76 Window getWindow() const;
77
78 //! Get selection atom
79 /*!
80 Returns the selection atom that identifies the clipboard to X11
81 (e.g. XA_PRIMARY).
82 */
83 Atom getSelection() const;
84
85 // IClipboard overrides
86 virtual bool empty();
87 virtual void add(EFormat, const CString& data);
88 virtual bool open(Time) const;
89 virtual void close() const;
90 virtual Time getTime() const;
91 virtual bool has(EFormat) const;
92 virtual CString get(EFormat) const;
93
94private:
95 // remove all converters from our list
96 void clearConverters();
97
98 // get the converter for a clipboard format. returns NULL if no
99 // suitable converter. iff onlyIfNotAdded is true then also
100 // return NULL if a suitable converter was found but we already
101 // have data of the converter's clipboard format.
102 IXWindowsClipboardConverter*
103 getConverter(Atom target,
104 bool onlyIfNotAdded = false) const;
105
106 // convert target atom to clipboard format
107 EFormat getFormat(Atom target) const;
108
109 // add a non-MULTIPLE request. does not verify that the selection
110 // was owned at the given time. returns true if the conversion
111 // could be performed, false otherwise. in either case, the
112 // reply is inserted.
113 bool addSimpleRequest(
114 Window requestor, Atom target,
115 ::Time time, Atom property);
116
117 // if not already checked then see if the cache is stale and, if so,
118 // clear it. this has the side effect of updating m_timeOwned.
119 void checkCache() const;
120
121 // clear the cache, resetting the cached flag and the added flag for
122 // each format.
123 void clearCache() const;
124 void doClearCache();
125
126 // cache all formats of the selection
127 void fillCache() const;
128 void doFillCache();
129
130 //
131 // helper classes
132 //
133
134 // read an ICCCM conforming selection
135 class CICCCMGetClipboard {
136 public:
137 CICCCMGetClipboard(Window requestor, Time time, Atom property);
138 ~CICCCMGetClipboard();
139
140 // convert the given selection to the given type. returns
141 // true iff the conversion was successful or the conversion
142 // cannot be performed (in which case *actualTarget == None).
143 bool readClipboard(Display* display,
144 Atom selection, Atom target,
145 Atom* actualTarget, CString* data);
146
147 private:
148 bool processEvent(Display* display, XEvent* event);
149
150 private:
151 Window m_requestor;
152 Time m_time;
153 Atom m_property;
154 bool m_incr;
155 bool m_failed;
156 bool m_done;
157
158 // atoms needed for the protocol
159 Atom m_atomNone; // NONE, not None
160 Atom m_atomIncr;
161
162 // true iff we've received the selection notify
163 bool m_reading;
164
165 // the converted selection data
166 CString* m_data;
167
168 // the actual type of the data. if this is None then the
169 // selection owner cannot convert to the requested type.
170 Atom* m_actualTarget;
171
172 public:
173 // true iff the selection owner didn't follow ICCCM conventions
174 bool m_error;
175 };
176
177 // Motif structure IDs
178 enum { kMotifClipFormat = 1, kMotifClipItem, kMotifClipHeader };
179
180 // _MOTIF_CLIP_HEADER structure
181 class CMotifClipHeader {
182 public:
183 SInt32 m_id; // kMotifClipHeader
184 SInt32 m_pad1[3];
185 SInt32 m_item;
186 SInt32 m_pad2[4];
187 SInt32 m_numItems;
188 SInt32 m_pad3[3];
189 SInt32 m_selectionOwner; // a Window
190 SInt32 m_pad4[2];
191 };
192
193 // Motif clip item structure
194 class CMotifClipItem {
195 public:
196 SInt32 m_id; // kMotifClipItem
197 SInt32 m_pad1[5];
198 SInt32 m_size;
199 SInt32 m_numFormats;
200 SInt32 m_numDeletedFormats;
201 SInt32 m_pad2[6];
202 };
203
204 // Motif clip format structure
205 class CMotifClipFormat {
206 public:
207 SInt32 m_id; // kMotifClipFormat
208 SInt32 m_pad1[6];
209 SInt32 m_length;
210 SInt32 m_data;
211 SInt32 m_type; // an Atom
212 SInt32 m_pad2[1];
213 SInt32 m_deleted;
214 SInt32 m_pad3[4];
215 };
216
217 // stores data needed to respond to a selection request
218 class CReply {
219 public:
220 CReply(Window, Atom target, ::Time);
221 CReply(Window, Atom target, ::Time, Atom property,
222 const CString& data, Atom type, int format);
223
224 public:
225 // information about the request
226 Window m_requestor;
227 Atom m_target;
228 ::Time m_time;
229 Atom m_property;
230
231 // true iff we've sent the notification for this reply
232 bool m_replied;
233
234 // true iff the reply has sent its last message
235 bool m_done;
236
237 // the data to send and its type and format
238 CString m_data;
239 Atom m_type;
240 int m_format;
241
242 // index of next byte in m_data to send
243 UInt32 m_ptr;
244 };
245 typedef std::list<CReply*> CReplyList;
246 typedef std::map<Window, CReplyList> CReplyMap;
247 typedef std::map<Window, long> CReplyEventMask;
248
249 // ICCCM interoperability methods
250 void icccmFillCache();
251 bool icccmGetSelection(Atom target,
252 Atom* actualTarget, CString* data) const;
253 Time icccmGetTime() const;
254
255 // motif interoperability methods
256 bool motifLockClipboard() const;
257 void motifUnlockClipboard() const;
258 bool motifOwnsClipboard() const;
259 void motifFillCache();
260 bool motifGetSelection(const CMotifClipFormat*,
261 Atom* actualTarget, CString* data) const;
262 Time motifGetTime() const;
263
264 // reply methods
265 bool insertMultipleReply(Window, ::Time, Atom);
266 void insertReply(CReply*);
267 void pushReplies();
268 void pushReplies(CReplyMap::iterator,
269 CReplyList&, CReplyList::iterator);
270 bool sendReply(CReply*);
271 void clearReplies();
272 void clearReplies(CReplyList&);
273 void sendNotify(Window requestor, Atom selection,
274 Atom target, Atom property, Time time);
275 bool wasOwnedAtTime(::Time) const;
276
277 // data conversion methods
278 Atom getTargetsData(CString&, int* format) const;
279 Atom getTimestampData(CString&, int* format) const;
280
281private:
282 typedef std::vector<IXWindowsClipboardConverter*> ConverterList;
283
284 Display* m_display;
285 Window m_window;
286 ClipboardID m_id;
287 Atom m_selection;
288 mutable bool m_open;
289 mutable Time m_time;
290 bool m_owner;
291 mutable Time m_timeOwned;
292 Time m_timeLost;
293
294 // true iff open and clipboard owned by a motif app
295 mutable bool m_motif;
296
297 // the added/cached clipboard data
298 mutable bool m_checkCache;
299 bool m_cached;
300 Time m_cacheTime;
301 bool m_added[kNumFormats];
302 CString m_data[kNumFormats];
303
304 // conversion request replies
305 CReplyMap m_replies;
306 CReplyEventMask m_eventMasks;
307
308 // clipboard format converters
309 ConverterList m_converters;
310
311 // atoms we'll need
312 Atom m_atomTargets;
313 Atom m_atomMultiple;
314 Atom m_atomTimestamp;
315 Atom m_atomInteger;
316 Atom m_atomAtom;
317 Atom m_atomAtomPair;
318 Atom m_atomData;
319 Atom m_atomINCR;
320 Atom m_atomMotifClipLock;
321 Atom m_atomMotifClipHeader;
322 Atom m_atomMotifClipAccess;
323 Atom m_atomGDKSelection;
324};
325
326//! Clipboard format converter interface
327/*!
328This interface defines the methods common to all X11 clipboard format
329converters.
330*/
331class IXWindowsClipboardConverter : public IInterface {
332public:
333 //! @name accessors
334 //@{
335
336 //! Get clipboard format
337 /*!
338 Return the clipboard format this object converts from/to.
339 */
340 virtual IClipboard::EFormat
341 getFormat() const = 0;
342
343 //! Get X11 format atom
344 /*!
345 Return the atom representing the X selection format that
346 this object converts from/to.
347 */
348 virtual Atom getAtom() const = 0;
349
350 //! Get X11 property datum size
351 /*!
352 Return the size (in bits) of data elements returned by
353 toIClipboard().
354 */
355 virtual int getDataSize() const = 0;
356
357 //! Convert from IClipboard format
358 /*!
359 Convert from the IClipboard format to the X selection format.
360 The input data must be in the IClipboard format returned by
361 getFormat(). The return data will be in the X selection
362 format returned by getAtom().
363 */
364 virtual CString fromIClipboard(const CString&) const = 0;
365
366 //! Convert to IClipboard format
367 /*!
368 Convert from the X selection format to the IClipboard format
369 (i.e., the reverse of fromIClipboard()).
370 */
371 virtual CString toIClipboard(const CString&) const = 0;
372
373 //@}
374};
375
376#endif
Note: See TracBrowser for help on using the repository browser.