barrier/synergy/CClipboard.cpp
crs 854d2c7fbf checkpoint. changed clipboard model. the clipboard can only
be accessed now between open()/close().  ownership of the
clipboard is asserted via the empty() method.  this parallels
the win32 model (but the win32 code hasn't been updated yet).

refactored X11 clipboard code.  moved the bulk of it into
CXWindowsClipboard and moved some comment event handling into
CXWindowsScreen.  changed how requests are processed into a
hopefully easier to understand model.  added support for getting
clipboard from and sending clipboard to motif (or at least
lesstif) clients.  sending to lesstif required a hack to work
around an apparent bug in lesstif.
2002-05-27 16:22:59 +00:00

196 lines
3.5 KiB
C++

#include "CClipboard.h"
#include <assert.h>
//
// CClipboard
//
CClipboard::CClipboard() : m_open(false), m_owner(false)
{
open(0);
empty();
close();
}
CClipboard::~CClipboard()
{
// do nothing
}
bool CClipboard::empty()
{
assert(m_open);
// clear all data
for (SInt32 index = 0; index < kNumFormats; ++index) {
m_data[index] = "";
m_added[index] = false;
}
// save time
m_timeOwned = m_time;
// we're the owner now
m_owner = true;
return true;
}
void CClipboard::add(EFormat format, const CString& data)
{
assert(m_open);
assert(m_owner);
m_data[format] = data;
m_added[format] = true;
}
bool CClipboard::open(Time time) const
{
assert(!m_open);
m_open = true;
m_time = time;
return true;
}
void CClipboard::close() const
{
assert(m_open);
m_open = false;
}
CClipboard::Time CClipboard::getTime() const
{
return m_timeOwned;
}
bool CClipboard::has(EFormat format) const
{
assert(m_open);
return m_added[format];
}
CString CClipboard::get(EFormat format) const
{
assert(m_open);
return m_data[format];
}
bool CClipboard::copy(IClipboard* dst, const IClipboard* src)
{
assert(dst != NULL);
assert(src != NULL);
return copy(dst, src, src->getTime());
}
bool CClipboard::copy(IClipboard* dst,
const IClipboard* src, Time time)
{
assert(dst != NULL);
assert(src != NULL);
bool success = false;
if (src->open(time)) {
if (dst->open(time)) {
if (dst->empty()) {
for (SInt32 format = 0;
format != IClipboard::kNumFormats; ++format) {
IClipboard::EFormat eFormat = (IClipboard::EFormat)format;
if (src->has(eFormat)) {
dst->add(eFormat, src->get(eFormat));
}
}
success = true;
}
dst->close();
}
src->close();
}
return success;
}
void CClipboard::unmarshall(const CString& data, Time time)
{
const char* index = data.data();
// clear existing data
open(time);
empty();
// read the number of formats
const UInt32 numFormats = readUInt32(index);
index += 4;
// read each format
for (UInt32 i = 0; i < numFormats; ++i) {
// get the format id
UInt32 format = readUInt32(index);
index += 4;
// get the size of the format data
UInt32 size = readUInt32(index);
index += 4;
// save the data
m_added[format] = true;
m_data[format] = CString(index, size);
index += size;
}
// done
close();
}
CString CClipboard::marshall() const
{
CString data;
// compute size of marshalled data
UInt32 size = 4;
UInt32 numFormats = 0;
UInt32 format;
for (format = 0; format != IClipboard::kNumFormats; ++format) {
if (m_added[format]) {
++numFormats;
size += 4 + 4 + m_data[format].size();
}
}
// allocate space
data.reserve(size);
// marshall the data
writeUInt32(&data, numFormats);
for (format = 0; format != IClipboard::kNumFormats; ++format) {
if (m_added[format]) {
writeUInt32(&data, format);
writeUInt32(&data, m_data[format].size());
data += m_data[format];
}
}
return data;
}
UInt32 CClipboard::readUInt32(const char* buf) const
{
const unsigned char* ubuf = reinterpret_cast<const unsigned char*>(buf);
return (static_cast<UInt32>(ubuf[0]) << 24) |
(static_cast<UInt32>(ubuf[1]) << 16) |
(static_cast<UInt32>(ubuf[2]) << 8) |
static_cast<UInt32>(ubuf[3]);
}
void CClipboard::writeUInt32(CString* buf, UInt32 v) const
{
*buf += static_cast<UInt8>((v >> 24) & 0xff);
*buf += static_cast<UInt8>((v >> 16) & 0xff);
*buf += static_cast<UInt8>((v >> 8) & 0xff);
*buf += static_cast<UInt8>( v & 0xff);
}