2002-08-02 23:57:46 +04:00
|
|
|
/*
|
|
|
|
* synergy -- mouse and keyboard sharing utility
|
|
|
|
* Copyright (C) 2002 Chris Schoeneman
|
|
|
|
*
|
|
|
|
* This package is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* found in the file COPYING that should have accompanied this file.
|
|
|
|
*
|
|
|
|
* This package is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*/
|
|
|
|
|
2001-11-19 03:33:36 +03:00
|
|
|
#include "CMSWindowsClipboard.h"
|
2002-07-23 19:26:40 +04:00
|
|
|
#include "CMSWindowsClipboardTextConverter.h"
|
|
|
|
#include "CMSWindowsClipboardUTF16Converter.h"
|
2001-11-19 03:33:36 +03:00
|
|
|
#include "CLog.h"
|
2003-05-26 13:49:38 +04:00
|
|
|
#include "CArchMiscWindows.h"
|
2001-11-19 03:33:36 +03:00
|
|
|
|
|
|
|
//
|
|
|
|
// CMSWindowsClipboard
|
|
|
|
//
|
|
|
|
|
Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar.
Second, windows key processing was fixed. Previously pressing and
release the key would only send a press event, locking the user onto
the client window; also, the win32 server treated as a Meta modifier
instead of a Super modifier, which broke any use of it as any kind of
modifier key. Third, added hacks to support several key combinations
on windows 95/98/me that are treated specially by windows, including
Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any
combination using the windows key like Win+E and Win+F but not
Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which
only happened when using a synergy server on windows) has been fixed;
unfortunately the solution causes a lot of screen redraws for some
reason. Finally, there's been a fix to clipboard handling that may
or may not fix a problem where the clipboard would stop transferring
between systems after a little while. I can't be sure if it fixes
the problem because I can't reproduce the problem.
2003-04-13 18:59:53 +04:00
|
|
|
UINT CMSWindowsClipboard::s_ownershipFormat = 0;
|
|
|
|
|
2002-06-17 17:31:21 +04:00
|
|
|
CMSWindowsClipboard::CMSWindowsClipboard(HWND window) :
|
2002-06-11 02:06:45 +04:00
|
|
|
m_window(window),
|
|
|
|
m_time(0)
|
2001-11-19 03:33:36 +03:00
|
|
|
{
|
2002-07-23 19:26:40 +04:00
|
|
|
// add converters, most desired first
|
|
|
|
m_converters.push_back(new CMSWindowsClipboardUTF16Converter);
|
2003-05-26 13:49:38 +04:00
|
|
|
if (CArchMiscWindows::isWindows95Family()) {
|
|
|
|
// windows nt family converts to/from unicode automatically.
|
|
|
|
// let it do so to avoid text encoding issues.
|
|
|
|
m_converters.push_back(new CMSWindowsClipboardTextConverter);
|
|
|
|
}
|
2001-11-19 03:33:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
CMSWindowsClipboard::~CMSWindowsClipboard()
|
|
|
|
{
|
2002-07-23 19:26:40 +04:00
|
|
|
clearConverters();
|
2001-11-19 03:33:36 +03:00
|
|
|
}
|
|
|
|
|
2002-06-11 02:06:45 +04:00
|
|
|
bool
|
|
|
|
CMSWindowsClipboard::empty()
|
2001-11-19 03:33:36 +03:00
|
|
|
{
|
2002-10-16 01:29:44 +04:00
|
|
|
LOG((CLOG_DEBUG "empty clipboard"));
|
2001-11-25 21:32:41 +03:00
|
|
|
|
Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar.
Second, windows key processing was fixed. Previously pressing and
release the key would only send a press event, locking the user onto
the client window; also, the win32 server treated as a Meta modifier
instead of a Super modifier, which broke any use of it as any kind of
modifier key. Third, added hacks to support several key combinations
on windows 95/98/me that are treated specially by windows, including
Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any
combination using the windows key like Win+E and Win+F but not
Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which
only happened when using a synergy server on windows) has been fixed;
unfortunately the solution causes a lot of screen redraws for some
reason. Finally, there's been a fix to clipboard handling that may
or may not fix a problem where the clipboard would stop transferring
between systems after a little while. I can't be sure if it fixes
the problem because I can't reproduce the problem.
2003-04-13 18:59:53 +04:00
|
|
|
// empty the clipboard (and take ownership)
|
2002-05-27 22:55:51 +04:00
|
|
|
if (!EmptyClipboard()) {
|
2002-10-16 01:29:44 +04:00
|
|
|
LOG((CLOG_DEBUG "failed to grab clipboard"));
|
2002-04-30 20:23:03 +04:00
|
|
|
return false;
|
2001-11-25 21:32:41 +03:00
|
|
|
}
|
2002-04-30 20:23:03 +04:00
|
|
|
|
Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar.
Second, windows key processing was fixed. Previously pressing and
release the key would only send a press event, locking the user onto
the client window; also, the win32 server treated as a Meta modifier
instead of a Super modifier, which broke any use of it as any kind of
modifier key. Third, added hacks to support several key combinations
on windows 95/98/me that are treated specially by windows, including
Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any
combination using the windows key like Win+E and Win+F but not
Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which
only happened when using a synergy server on windows) has been fixed;
unfortunately the solution causes a lot of screen redraws for some
reason. Finally, there's been a fix to clipboard handling that may
or may not fix a problem where the clipboard would stop transferring
between systems after a little while. I can't be sure if it fixes
the problem because I can't reproduce the problem.
2003-04-13 18:59:53 +04:00
|
|
|
// mark clipboard as being owned by synergy
|
|
|
|
HGLOBAL data = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, 1);
|
|
|
|
SetClipboardData(getOwnershipFormat(), data);
|
|
|
|
|
2001-11-25 21:32:41 +03:00
|
|
|
return true;
|
2001-11-19 03:33:36 +03:00
|
|
|
}
|
|
|
|
|
2002-06-11 02:06:45 +04:00
|
|
|
void
|
2002-06-17 17:31:21 +04:00
|
|
|
CMSWindowsClipboard::add(EFormat format, const CString& data)
|
2001-11-19 03:33:36 +03:00
|
|
|
{
|
2002-10-16 01:29:44 +04:00
|
|
|
LOG((CLOG_DEBUG "add %d bytes to clipboard format: %d", data.size(), format));
|
2001-11-25 21:32:41 +03:00
|
|
|
|
2002-07-23 19:26:40 +04:00
|
|
|
// convert data to win32 form
|
|
|
|
for (ConverterList::const_iterator index = m_converters.begin();
|
|
|
|
index != m_converters.end(); ++index) {
|
|
|
|
IMSWindowsClipboardConverter* converter = *index;
|
|
|
|
|
|
|
|
// skip converters for other formats
|
|
|
|
if (converter->getFormat() == format) {
|
|
|
|
HANDLE win32Data = converter->fromIClipboard(data);
|
|
|
|
if (win32Data != NULL) {
|
|
|
|
UINT win32Format = converter->getWin32Format();
|
|
|
|
if (SetClipboardData(win32Format, win32Data) == NULL) {
|
|
|
|
// free converted data if we couldn't put it on
|
|
|
|
// the clipboard
|
|
|
|
GlobalFree(win32Data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-11-25 21:32:41 +03:00
|
|
|
}
|
2002-05-27 22:55:51 +04:00
|
|
|
}
|
|
|
|
|
2002-06-11 02:06:45 +04:00
|
|
|
bool
|
2002-06-17 17:31:21 +04:00
|
|
|
CMSWindowsClipboard::open(Time time) const
|
2002-05-27 22:55:51 +04:00
|
|
|
{
|
2002-10-16 01:29:44 +04:00
|
|
|
LOG((CLOG_DEBUG "open clipboard"));
|
2002-05-27 22:55:51 +04:00
|
|
|
|
|
|
|
if (!OpenClipboard(m_window)) {
|
2002-10-16 01:29:44 +04:00
|
|
|
LOG((CLOG_WARN "failed to open clipboard"));
|
2002-05-27 22:55:51 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_time = time;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2001-11-25 21:32:41 +03:00
|
|
|
|
2002-06-11 02:06:45 +04:00
|
|
|
void
|
|
|
|
CMSWindowsClipboard::close() const
|
2002-05-27 22:55:51 +04:00
|
|
|
{
|
2002-10-16 01:29:44 +04:00
|
|
|
LOG((CLOG_DEBUG "close clipboard"));
|
2001-11-25 21:32:41 +03:00
|
|
|
CloseClipboard();
|
|
|
|
}
|
|
|
|
|
2002-06-11 02:06:45 +04:00
|
|
|
IClipboard::Time
|
|
|
|
CMSWindowsClipboard::getTime() const
|
2002-04-30 20:23:03 +04:00
|
|
|
{
|
|
|
|
return m_time;
|
|
|
|
}
|
|
|
|
|
2002-06-11 02:06:45 +04:00
|
|
|
bool
|
2002-06-17 17:31:21 +04:00
|
|
|
CMSWindowsClipboard::has(EFormat format) const
|
2001-11-25 21:32:41 +03:00
|
|
|
{
|
2002-07-23 19:26:40 +04:00
|
|
|
for (ConverterList::const_iterator index = m_converters.begin();
|
|
|
|
index != m_converters.end(); ++index) {
|
|
|
|
IMSWindowsClipboardConverter* converter = *index;
|
|
|
|
if (converter->getFormat() == format) {
|
|
|
|
if (IsClipboardFormatAvailable(converter->getWin32Format())) {
|
|
|
|
return true;
|
|
|
|
}
|
2001-11-25 21:32:41 +03:00
|
|
|
}
|
|
|
|
}
|
2002-07-23 19:26:40 +04:00
|
|
|
return false;
|
2001-11-19 03:33:36 +03:00
|
|
|
}
|
|
|
|
|
2002-07-23 19:26:40 +04:00
|
|
|
CString
|
|
|
|
CMSWindowsClipboard::get(EFormat format) const
|
2001-11-19 03:33:36 +03:00
|
|
|
{
|
2002-07-23 19:26:40 +04:00
|
|
|
// find the converter for the first clipboard format we can handle
|
|
|
|
IMSWindowsClipboardConverter* converter = NULL;
|
|
|
|
UINT win32Format = EnumClipboardFormats(0);
|
2002-07-23 22:59:44 +04:00
|
|
|
while (converter == NULL && win32Format != 0) {
|
2002-07-23 19:26:40 +04:00
|
|
|
for (ConverterList::const_iterator index = m_converters.begin();
|
|
|
|
index != m_converters.end(); ++index) {
|
|
|
|
converter = *index;
|
|
|
|
if (converter->getWin32Format() == win32Format &&
|
|
|
|
converter->getFormat() == format) {
|
|
|
|
break;
|
2001-11-25 21:32:41 +03:00
|
|
|
}
|
2002-07-23 19:26:40 +04:00
|
|
|
converter = NULL;
|
2001-11-25 21:32:41 +03:00
|
|
|
}
|
2002-07-23 19:26:40 +04:00
|
|
|
win32Format = EnumClipboardFormats(win32Format);
|
2001-11-25 21:32:41 +03:00
|
|
|
}
|
2001-11-19 03:33:36 +03:00
|
|
|
|
2002-07-23 19:26:40 +04:00
|
|
|
// if no converter then we don't recognize any formats
|
|
|
|
if (converter == NULL) {
|
2001-11-25 21:32:41 +03:00
|
|
|
return CString();
|
2002-06-11 02:06:45 +04:00
|
|
|
}
|
2001-11-25 21:32:41 +03:00
|
|
|
|
2002-07-23 19:26:40 +04:00
|
|
|
// get a handle to the clipboard data
|
|
|
|
HANDLE win32Data = GetClipboardData(converter->getWin32Format());
|
|
|
|
if (win32Data == NULL) {
|
|
|
|
return CString();
|
2001-11-25 21:32:41 +03:00
|
|
|
}
|
|
|
|
|
2002-07-23 19:26:40 +04:00
|
|
|
// convert
|
|
|
|
return converter->toIClipboard(win32Data);
|
|
|
|
}
|
2001-11-25 21:32:41 +03:00
|
|
|
|
2002-07-23 19:26:40 +04:00
|
|
|
void
|
|
|
|
CMSWindowsClipboard::clearConverters()
|
|
|
|
{
|
|
|
|
for (ConverterList::iterator index = m_converters.begin();
|
|
|
|
index != m_converters.end(); ++index) {
|
|
|
|
delete *index;
|
2001-11-25 21:32:41 +03:00
|
|
|
}
|
2002-07-23 19:26:40 +04:00
|
|
|
m_converters.clear();
|
2001-11-19 03:33:36 +03:00
|
|
|
}
|
Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar.
Second, windows key processing was fixed. Previously pressing and
release the key would only send a press event, locking the user onto
the client window; also, the win32 server treated as a Meta modifier
instead of a Super modifier, which broke any use of it as any kind of
modifier key. Third, added hacks to support several key combinations
on windows 95/98/me that are treated specially by windows, including
Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any
combination using the windows key like Win+E and Win+F but not
Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which
only happened when using a synergy server on windows) has been fixed;
unfortunately the solution causes a lot of screen redraws for some
reason. Finally, there's been a fix to clipboard handling that may
or may not fix a problem where the clipboard would stop transferring
between systems after a little while. I can't be sure if it fixes
the problem because I can't reproduce the problem.
2003-04-13 18:59:53 +04:00
|
|
|
|
|
|
|
bool
|
|
|
|
CMSWindowsClipboard::isOwnedBySynergy()
|
|
|
|
{
|
|
|
|
// create ownership format if we haven't yet
|
|
|
|
if (s_ownershipFormat == 0) {
|
|
|
|
s_ownershipFormat = RegisterClipboardFormat(TEXT("SynergyOwnership"));
|
|
|
|
}
|
|
|
|
return (IsClipboardFormatAvailable(getOwnershipFormat()) != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
UINT
|
|
|
|
CMSWindowsClipboard::getOwnershipFormat()
|
|
|
|
{
|
|
|
|
// create ownership format if we haven't yet
|
|
|
|
if (s_ownershipFormat == 0) {
|
|
|
|
s_ownershipFormat = RegisterClipboardFormat(TEXT("SynergyOwnership"));
|
|
|
|
}
|
|
|
|
|
|
|
|
// return the format
|
|
|
|
return s_ownershipFormat;
|
|
|
|
}
|