• Main Page
  • Classes
  • Files
  • File List

CMSWindowsClipboard.cpp

00001 /*
00002  * synergy -- mouse and keyboard sharing utility
00003  * Copyright (C) 2012 Bolton Software Ltd.
00004  * Copyright (C) 2002 Chris Schoeneman
00005  * 
00006  * This package is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * found in the file COPYING that should have accompanied this file.
00009  * 
00010  * This package is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017  */
00018 
00019 #include "CMSWindowsClipboard.h"
00020 #include "CMSWindowsClipboardTextConverter.h"
00021 #include "CMSWindowsClipboardUTF16Converter.h"
00022 #include "CMSWindowsClipboardBitmapConverter.h"
00023 #include "CMSWindowsClipboardHTMLConverter.h"
00024 #include "CLog.h"
00025 #include "CArchMiscWindows.h"
00026 #include "CMSWindowsClipboardFacade.h"
00027 
00028 //
00029 // CMSWindowsClipboard
00030 //
00031 
00032 UINT                    CMSWindowsClipboard::s_ownershipFormat = 0;
00033 
00034 CMSWindowsClipboard::CMSWindowsClipboard(HWND window) :
00035     m_window(window),
00036     m_time(0),
00037     m_facade(new CMSWindowsClipboardFacade()),
00038     m_deleteFacade(true)
00039 {
00040     // add converters, most desired first
00041     m_converters.push_back(new CMSWindowsClipboardUTF16Converter);
00042     if (CArchMiscWindows::isWindows95Family()) {
00043         // windows nt family converts to/from unicode automatically.
00044         // let it do so to avoid text encoding issues.
00045         m_converters.push_back(new CMSWindowsClipboardTextConverter);
00046     }
00047     m_converters.push_back(new CMSWindowsClipboardBitmapConverter);
00048     m_converters.push_back(new CMSWindowsClipboardHTMLConverter);
00049 }
00050 
00051 CMSWindowsClipboard::~CMSWindowsClipboard()
00052 {
00053     clearConverters();
00054 
00055     // dependency injection causes confusion over ownership, so we need
00056     // logic to decide whether or not we delete the facade. there must
00057     // be a more elegant way of doing this.
00058     if (m_deleteFacade)
00059         delete m_facade;
00060 }
00061 
00062 void
00063 CMSWindowsClipboard::setFacade(IMSWindowsClipboardFacade& facade)
00064 {
00065     delete m_facade;
00066     m_facade = &facade;
00067     m_deleteFacade = false;
00068 }
00069 
00070 bool
00071 CMSWindowsClipboard::emptyUnowned()
00072 {
00073     LOG((CLOG_DEBUG "empty clipboard"));
00074 
00075     // empty the clipboard (and take ownership)
00076     if (!EmptyClipboard()) {
00077         // unable to cause this in integ tests, but this error has never 
00078         // actually been reported by users.
00079         LOG((CLOG_DEBUG "failed to grab clipboard"));
00080         return false;
00081     }
00082 
00083     return true;
00084 }
00085 
00086 bool
00087 CMSWindowsClipboard::empty()
00088 {
00089     if (!emptyUnowned()) {
00090         return false;
00091     }
00092 
00093     // mark clipboard as being owned by synergy
00094     HGLOBAL data = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, 1);
00095     SetClipboardData(getOwnershipFormat(), data);
00096 
00097     return true;
00098 }
00099 
00100 void
00101 CMSWindowsClipboard::add(EFormat format, const CString& data)
00102 {
00103     LOG((CLOG_DEBUG "add %d bytes to clipboard format: %d", data.size(), format));
00104 
00105     // convert data to win32 form
00106     for (ConverterList::const_iterator index = m_converters.begin();
00107                                 index != m_converters.end(); ++index) {
00108         IMSWindowsClipboardConverter* converter = *index;
00109 
00110         // skip converters for other formats
00111         if (converter->getFormat() == format) {
00112             HANDLE win32Data = converter->fromIClipboard(data);
00113             if (win32Data != NULL) {
00114                 UINT win32Format = converter->getWin32Format();
00115                 m_facade->write(win32Data, win32Format);
00116             }
00117         }
00118     }
00119 }
00120 
00121 bool
00122 CMSWindowsClipboard::open(Time time) const
00123 {
00124     LOG((CLOG_DEBUG "open clipboard"));
00125 
00126     if (!OpenClipboard(m_window)) {
00127         // unable to cause this in integ tests; but this can happen!
00128         // * http://synergy-foss.org/pm/issues/86
00129         // * http://synergy-foss.org/pm/issues/1256
00130         // logging improved to see if we can catch more info next time.
00131         LOG((CLOG_WARN "failed to open clipboard: %d", GetLastError()));
00132         return false;
00133     }
00134 
00135     m_time = time;
00136 
00137     return true;
00138 }
00139 
00140 void
00141 CMSWindowsClipboard::close() const
00142 {
00143     LOG((CLOG_DEBUG "close clipboard"));
00144     CloseClipboard();
00145 }
00146 
00147 IClipboard::Time
00148 CMSWindowsClipboard::getTime() const
00149 {
00150     return m_time;
00151 }
00152 
00153 bool
00154 CMSWindowsClipboard::has(EFormat format) const
00155 {
00156     for (ConverterList::const_iterator index = m_converters.begin();
00157                                 index != m_converters.end(); ++index) {
00158         IMSWindowsClipboardConverter* converter = *index;
00159         if (converter->getFormat() == format) {
00160             if (IsClipboardFormatAvailable(converter->getWin32Format())) {
00161                 return true;
00162             }
00163         }
00164     }
00165     return false;
00166 }
00167 
00168 CString
00169 CMSWindowsClipboard::get(EFormat format) const
00170 {
00171     // find the converter for the first clipboard format we can handle
00172     IMSWindowsClipboardConverter* converter = NULL;
00173     UINT win32Format = EnumClipboardFormats(0);
00174     while (converter == NULL && win32Format != 0) {
00175         for (ConverterList::const_iterator index = m_converters.begin();
00176                                 index != m_converters.end(); ++index) {
00177             converter = *index;
00178             if (converter->getWin32Format() == win32Format &&
00179                 converter->getFormat()      == format) {
00180                 break;
00181             }
00182             converter = NULL;
00183         }
00184         win32Format = EnumClipboardFormats(win32Format);
00185     }
00186 
00187     // if no converter then we don't recognize any formats
00188     if (converter == NULL) {
00189         return CString();
00190     }
00191 
00192     // get a handle to the clipboard data
00193     HANDLE win32Data = GetClipboardData(converter->getWin32Format());
00194     if (win32Data == NULL) {
00195         // nb: can't cause this using integ tests; this is only caused when
00196         // the selected converter returns an invalid format -- which you
00197         // cannot cause using public functions.
00198         return CString();
00199     }
00200 
00201     // convert
00202     return converter->toIClipboard(win32Data);
00203 }
00204 
00205 void
00206 CMSWindowsClipboard::clearConverters()
00207 {
00208     for (ConverterList::iterator index = m_converters.begin();
00209                                 index != m_converters.end(); ++index) {
00210         delete *index;
00211     }
00212     m_converters.clear();
00213 }
00214 
00215 bool
00216 CMSWindowsClipboard::isOwnedBySynergy()
00217 {
00218     // create ownership format if we haven't yet
00219     if (s_ownershipFormat == 0) {
00220         s_ownershipFormat = RegisterClipboardFormat(TEXT("SynergyOwnership"));
00221     }
00222     return (IsClipboardFormatAvailable(getOwnershipFormat()) != 0);
00223 }
00224 
00225 UINT
00226 CMSWindowsClipboard::getOwnershipFormat()
00227 {
00228     // create ownership format if we haven't yet
00229     if (s_ownershipFormat == 0) {
00230         s_ownershipFormat = RegisterClipboardFormat(TEXT("SynergyOwnership"));
00231     }
00232 
00233     // return the format
00234     return s_ownershipFormat;
00235 }

Generated on Wed May 22 2013 00:00:05 for Synergy by  doxygen 1.7.1