cloudstack/thirdparty/vnc/viewer/AxVncViewer/ClientConnectionClipboard.cpp
2011-01-28 16:07:46 -08:00

144 lines
4.7 KiB
C++

// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
//
// This file is part of the VNC system.
//
// The VNC system is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//
// If the source code for the VNC system is not available from the place
// whence you received this file, check http://www.uk.research.att.com/vnc or
// contact the authors on vnc@uk.research.att.com for information on obtaining it.
//
#include "stdhdrs.h"
#include "vncviewer.h"
#include "ClientConnection.h"
#include "Exception.h"
extern char sz_C1[64];
extern char sz_C2[64];
extern char sz_C3[64];
// This file contains the code for getting text from, and putting text into
// the Windows clipboard.
//
// ProcessClipboardChange
// Called by ClientConnection::WndProc.
// We've been informed that the local clipboard has been updated.
// If it's text we want to send it to the server.
//
void ClientConnection::ProcessLocalClipboardChange()
{
vnclog.Print(2, _T("Clipboard changed\n"));
HWND hOwner = GetClipboardOwner();
if (hOwner == m_hwnd) {
vnclog.Print(2, _T("We changed it - ignore!\n"));
} else if (!m_initialClipboardSeen) {
vnclog.Print(2, _T("Don't send initial clipboard!\n"));
m_initialClipboardSeen = true;
} else if (!m_opts.m_DisableClipboard) {
// The clipboard should not be modified by more than one thread at once
omni_mutex_lock l(m_clipMutex);
if (OpenClipboard(m_hwnd)) {
HGLOBAL hglb = GetClipboardData(CF_TEXT);
if (hglb == NULL) {
CloseClipboard();
} else {
LPSTR lpstr = (LPSTR) GlobalLock(hglb);
char *contents = new char[strlen(lpstr) + 1];
char *unixcontents = new char[strlen(lpstr) + 1];
strcpy(contents,lpstr);
GlobalUnlock(hglb);
CloseClipboard();
// Translate to Unix-format lines before sending
int j = 0;
for (int i = 0; contents[i] != '\0'; i++) {
if (contents[i] != '\x0d') {
unixcontents[j++] = contents[i];
}
}
unixcontents[j] = '\0';
try {
SendClientCutText(unixcontents, strlen(unixcontents));
} catch (WarningException &e) {
vnclog.Print(0, _T("Exception while sending clipboard text : %s\n"), e.m_info);
DestroyWindow(m_hwnd);
}
delete [] contents;
delete [] unixcontents;
}
}
}
// Pass the message to the next window in clipboard viewer chain
::SendMessage(m_hwndNextViewer, WM_DRAWCLIPBOARD , 0,0);
}
// We've read some text from the remote server, and
// we need to copy it into the local clipboard.
// Called by ClientConnection::ReadServerCutText()
void ClientConnection::UpdateLocalClipboard(char *buf, int len) {
if (m_opts.m_DisableClipboard)
return;
// Copy to wincontents replacing LF with CR-LF
char *wincontents = new char[len * 2 + 1];
int j = 0;;
for (int i = 0; m_netbuf[i] != 0; i++, j++) {
if (buf[i] == '\x0a') {
wincontents[j++] = '\x0d';
len++;
}
wincontents[j] = buf[i];
}
wincontents[j] = '\0';
// The clipboard should not be modified by more than one thread at once
{
omni_mutex_lock l(m_clipMutex);
if (!OpenClipboard(m_hwnd)) {
throw WarningException(sz_C1);
}
if (! ::EmptyClipboard()) {
throw WarningException(sz_C2);
}
// Allocate a global memory object for the text.
HGLOBAL hglbCopy = GlobalAlloc(GMEM_DDESHARE, (len +1) * sizeof(TCHAR));
if (hglbCopy != NULL) {
// Lock the handle and copy the text to the buffer.
LPTSTR lptstrCopy = (LPTSTR) GlobalLock(hglbCopy);
memcpy(lptstrCopy, wincontents, len * sizeof(TCHAR));
lptstrCopy[len] = (TCHAR) 0; // null character
GlobalUnlock(hglbCopy); // Place the handle on the clipboard.
SetClipboardData(CF_TEXT, hglbCopy);
}
delete [] wincontents;
if (! ::CloseClipboard()) {
throw WarningException(sz_C3);
}
}
}