Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

CXWindowsClipboard.h

00001 /*
00002  * synergy -- mouse and keyboard sharing utility
00003  * Copyright (C) 2002 Chris Schoeneman
00004  * 
00005  * This package is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * found in the file COPYING that should have accompanied this file.
00008  * 
00009  * This package is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  */
00014 
00015 #ifndef CXWINDOWSCLIPBOARD_H
00016 #define CXWINDOWSCLIPBOARD_H
00017 
00018 #include "IClipboard.h"
00019 #include "ClipboardTypes.h"
00020 #include "stdmap.h"
00021 #include "stdlist.h"
00022 #include "stdvector.h"
00023 #if X_DISPLAY_MISSING
00024 #   error X11 is required to build synergy
00025 #else
00026 #   include <X11/Xlib.h>
00027 #endif
00028 
00029 class IXWindowsClipboardConverter;
00030 
00032 class CXWindowsClipboard : public IClipboard {
00033 public:
00038     CXWindowsClipboard(Display*, Window window, ClipboardID id);
00039     virtual ~CXWindowsClipboard();
00040 
00042 
00045     void                lost(Time);
00046 
00048 
00053     void                addRequest(Window owner,
00054                             Window requestor, Atom target,
00055                             ::Time time, Atom property);
00056 
00058 
00062     bool                processRequest(Window requestor,
00063                             ::Time time, Atom property);
00064 
00066 
00070     bool                destroyRequest(Window requestor);
00071 
00073 
00076     Window              getWindow() const;
00077 
00079 
00083     Atom                getSelection() const;
00084 
00085     // IClipboard overrides
00086     virtual bool        empty();
00087     virtual void        add(EFormat, const CString& data);
00088     virtual bool        open(Time) const;
00089     virtual void        close() const;
00090     virtual Time        getTime() const;
00091     virtual bool        has(EFormat) const;
00092     virtual CString     get(EFormat) const;
00093 
00094 private:
00095     // remove all converters from our list
00096     void                clearConverters();
00097 
00098     // get the converter for a clipboard format.  returns NULL if no
00099     // suitable converter.  iff onlyIfNotAdded is true then also
00100     // return NULL if a suitable converter was found but we already
00101     // have data of the converter's clipboard format.
00102     IXWindowsClipboardConverter*
00103                         getConverter(Atom target,
00104                             bool onlyIfNotAdded = false) const;
00105 
00106     // convert target atom to clipboard format
00107     EFormat             getFormat(Atom target) const;
00108 
00109     // add a non-MULTIPLE request.  does not verify that the selection
00110     // was owned at the given time.  returns true if the conversion
00111     // could be performed, false otherwise.  in either case, the
00112     // reply is inserted.
00113     bool                addSimpleRequest(
00114                             Window requestor, Atom target,
00115                             ::Time time, Atom property);
00116 
00117     // if not already checked then see if the cache is stale and, if so,
00118     // clear it.  this has the side effect of updating m_timeOwned.
00119     void                checkCache() const;
00120 
00121     // clear the cache, resetting the cached flag and the added flag for
00122     // each format.
00123     void                clearCache() const;
00124     void                doClearCache();
00125 
00126     // cache all formats of the selection
00127     void                fillCache() const;
00128     void                doFillCache();
00129 
00130     //
00131     // helper classes
00132     //
00133 
00134     // read an ICCCM conforming selection
00135     class CICCCMGetClipboard {
00136     public:
00137         CICCCMGetClipboard(Window requestor, Time time, Atom property);
00138         ~CICCCMGetClipboard();
00139 
00140         // convert the given selection to the given type.  returns
00141         // true iff the conversion was successful or the conversion
00142         // cannot be performed (in which case *actualTarget == None).
00143         bool            readClipboard(Display* display,
00144                             Atom selection, Atom target,
00145                             Atom* actualTarget, CString* data);
00146 
00147     private:
00148         bool            processEvent(Display* display, XEvent* event);
00149 
00150     private:
00151         Window          m_requestor;
00152         Time            m_time;
00153         Atom            m_property;
00154         bool            m_incr;
00155         bool            m_failed;
00156         bool            m_done;
00157 
00158         // atoms needed for the protocol
00159         Atom            m_atomNone;     // NONE, not None
00160         Atom            m_atomIncr;
00161 
00162         // true iff we've received the selection notify
00163         bool            m_reading;
00164 
00165         // the converted selection data
00166         CString*        m_data;
00167 
00168         // the actual type of the data.  if this is None then the
00169         // selection owner cannot convert to the requested type.
00170         Atom*           m_actualTarget;
00171 
00172     public:
00173         // true iff the selection owner didn't follow ICCCM conventions
00174         bool            m_error;
00175     };
00176 
00177     // Motif structure IDs
00178     enum { kMotifClipFormat = 1, kMotifClipItem, kMotifClipHeader };
00179 
00180     // _MOTIF_CLIP_HEADER structure
00181     class CMotifClipHeader {
00182     public:
00183         SInt32          m_id;           // kMotifClipHeader
00184         SInt32          m_pad1[3];
00185         SInt32          m_item;
00186         SInt32          m_pad2[4];
00187         SInt32          m_numItems;
00188         SInt32          m_pad3[3];
00189         SInt32          m_selectionOwner;   // a Window
00190         SInt32          m_pad4[2];
00191     };
00192 
00193     // Motif clip item structure
00194     class CMotifClipItem {
00195     public:
00196         SInt32          m_id;           // kMotifClipItem
00197         SInt32          m_pad1[5];
00198         SInt32          m_size;
00199         SInt32          m_numFormats;
00200         SInt32          m_numDeletedFormats;
00201         SInt32          m_pad2[6];
00202     };
00203 
00204     // Motif clip format structure
00205     class CMotifClipFormat {
00206     public:
00207         SInt32          m_id;           // kMotifClipFormat
00208         SInt32          m_pad1[6];
00209         SInt32          m_length;
00210         SInt32          m_data;
00211         SInt32          m_type;         // an Atom
00212         SInt32          m_pad2[1];
00213         SInt32          m_deleted;
00214         SInt32          m_pad3[4];
00215     };
00216 
00217     // stores data needed to respond to a selection request
00218     class CReply {
00219     public:
00220         CReply(Window, Atom target, ::Time);
00221         CReply(Window, Atom target, ::Time, Atom property,
00222                             const CString& data, Atom type, int format);
00223 
00224     public:
00225         // information about the request
00226         Window          m_requestor;
00227         Atom            m_target;
00228         ::Time          m_time;
00229         Atom            m_property;
00230 
00231         // true iff we've sent the notification for this reply
00232         bool            m_replied;
00233 
00234         // true iff the reply has sent its last message
00235         bool            m_done;
00236 
00237         // the data to send and its type and format
00238         CString         m_data;
00239         Atom            m_type;
00240         int             m_format;
00241 
00242         // index of next byte in m_data to send
00243         UInt32          m_ptr;
00244     };
00245     typedef std::list<CReply*> CReplyList;
00246     typedef std::map<Window, CReplyList> CReplyMap;
00247     typedef std::map<Window, long> CReplyEventMask;
00248 
00249     // ICCCM interoperability methods
00250     void                icccmFillCache();
00251     bool                icccmGetSelection(Atom target,
00252                             Atom* actualTarget, CString* data) const;
00253     Time                icccmGetTime() const;
00254 
00255     // motif interoperability methods
00256     bool                motifLockClipboard() const;
00257     void                motifUnlockClipboard() const;
00258     bool                motifOwnsClipboard() const;
00259     void                motifFillCache();
00260     bool                motifGetSelection(const CMotifClipFormat*,
00261                             Atom* actualTarget, CString* data) const;
00262     Time                motifGetTime() const;
00263 
00264     // reply methods
00265     bool                insertMultipleReply(Window, ::Time, Atom);
00266     void                insertReply(CReply*);
00267     void                pushReplies();
00268     void                pushReplies(CReplyMap::iterator&,
00269                             CReplyList&, CReplyList::iterator);
00270     bool                sendReply(CReply*);
00271     void                clearReplies();
00272     void                clearReplies(CReplyList&);
00273     void                sendNotify(Window requestor, Atom selection,
00274                             Atom target, Atom property, Time time);
00275     bool                wasOwnedAtTime(::Time) const;
00276 
00277     // data conversion methods
00278     Atom                getTargetsData(CString&, int* format) const;
00279     Atom                getTimestampData(CString&, int* format) const;
00280 
00281 private:
00282     typedef std::vector<IXWindowsClipboardConverter*> ConverterList;
00283 
00284     Display*            m_display;
00285     Window              m_window;
00286     ClipboardID         m_id;
00287     Atom                m_selection;
00288     mutable bool        m_open;
00289     mutable Time        m_time;
00290     bool                m_owner;
00291     mutable Time        m_timeOwned;
00292     Time                m_timeLost;
00293 
00294     // true iff open and clipboard owned by a motif app
00295     mutable bool        m_motif;
00296 
00297     // the added/cached clipboard data
00298     mutable bool        m_checkCache;
00299     bool                m_cached;
00300     Time                m_cacheTime;
00301     bool                m_added[kNumFormats];
00302     CString             m_data[kNumFormats];
00303 
00304     // conversion request replies
00305     CReplyMap           m_replies;
00306     CReplyEventMask     m_eventMasks;
00307 
00308     // clipboard format converters
00309     ConverterList       m_converters;
00310 
00311     // atoms we'll need
00312     Atom                m_atomTargets;
00313     Atom                m_atomMultiple;
00314     Atom                m_atomTimestamp;
00315     Atom                m_atomInteger;
00316     Atom                m_atomAtom;
00317     Atom                m_atomAtomPair;
00318     Atom                m_atomData;
00319     Atom                m_atomINCR;
00320     Atom                m_atomMotifClipLock;
00321     Atom                m_atomMotifClipHeader;
00322     Atom                m_atomMotifClipAccess;
00323     Atom                m_atomGDKSelection;
00324 };
00325 
00327 
00331 class IXWindowsClipboardConverter : public IInterface {
00332 public:
00334 
00335 
00337 
00340     virtual IClipboard::EFormat
00341                         getFormat() const = 0;
00342 
00344 
00348     virtual Atom        getAtom() const = 0;
00349 
00351 
00355     virtual int         getDataSize() const = 0;
00356 
00358 
00364     virtual CString     fromIClipboard(const CString&) const = 0;
00365 
00367 
00371     virtual CString     toIClipboard(const CString&) const = 0;
00372 
00374 };
00375 
00376 #endif

Generated on Fri Nov 6 00:21:14 2009 for synergy-plus by  doxygen 1.3.9.1