checkpoint. working on INCR transfers.

This commit is contained in:
crs 2002-07-25 08:57:46 +00:00
parent 63b1d4397a
commit d3ea39149a
1 changed files with 25 additions and 8 deletions

View File

@ -955,15 +955,18 @@ CXWindowsClipboard::sendReply(CReply* reply)
// send using INCR if already sending incrementally or if reply
// is too large, otherwise just send it.
const UInt32 maxRequestSize = 4 * XMaxRequestSize(m_display);
const UInt32 maxRequestSize = 50000;//XXX 4 * XMaxRequestSize(m_display);
const bool useINCR = (reply->m_data.size() > maxRequestSize);
log((CLOG_INFO "useINCR: %s", useINCR ? "true" : "false"));
// send INCR reply if incremental and we haven't replied yet
if (useINCR && !reply->m_replied) {
UInt32 size = reply->m_data.size();
log((CLOG_INFO "send first INCR, size=%d", size));
if (!CXWindowsUtil::setWindowProperty(m_display,
reply->m_requestor, reply->m_property,
&size, 4, m_atomINCR, 32)) {
log((CLOG_INFO "send first INCR failed"));
failed = true;
}
}
@ -974,6 +977,8 @@ CXWindowsClipboard::sendReply(CReply* reply)
UInt32 size = reply->m_data.size() - reply->m_ptr;
if (size > maxRequestSize)
size = maxRequestSize;
if (useINCR)
log((CLOG_INFO "more INCR, size=%d, ptr=%d", size, reply->m_ptr));
// send it
if (!CXWindowsUtil::setWindowProperty(m_display,
@ -981,6 +986,8 @@ CXWindowsClipboard::sendReply(CReply* reply)
reply->m_data.data() + reply->m_ptr,
size,
reply->m_type, reply->m_format)) {
if (useINCR)
log((CLOG_INFO "more INCR failed"));
failed = true;
}
else {
@ -989,6 +996,8 @@ CXWindowsClipboard::sendReply(CReply* reply)
// we've finished the reply if we just sent the zero
// size incremental chunk or if we're not incremental.
reply->m_done = (size == 0 || !useINCR);
if (useINCR)
log((CLOG_INFO "more INCR sent, done = %s", reply->m_done ? "true" : "false"));
}
}
}
@ -1000,6 +1009,7 @@ CXWindowsClipboard::sendReply(CReply* reply)
// the final zero-length property.
// FIXME -- how do you gracefully cancel an incremental transfer?
if (failed) {
log((CLOG_INFO "clipboard: sending failure to 0x%08x,%d,%d", reply->m_requestor, reply->m_target, reply->m_property));
log((CLOG_DEBUG1 "clipboard: sending failure to 0x%08x,%d,%d", reply->m_requestor, reply->m_target, reply->m_property));
reply->m_done = true;
if (reply->m_property != None) {
@ -1030,6 +1040,7 @@ CXWindowsClipboard::sendReply(CReply* reply)
// send notification if we haven't yet
if (!reply->m_replied) {
log((CLOG_INFO "clipboard: sending notify to 0x%08x,%d,%d", reply->m_requestor, reply->m_target, reply->m_property));
log((CLOG_DEBUG1 "clipboard: sending notify to 0x%08x,%d,%d", reply->m_requestor, reply->m_target, reply->m_property));
reply->m_replied = true;
@ -1241,6 +1252,7 @@ CXWindowsClipboard::CICCCMGetClipboard::readClipboard(Display* display,
std::vector<XEvent> events;
CStopwatch timeout(true);
static const double s_timeout = 0.25; // FIXME -- is this too short?
bool noWait = false;
while (!m_done && !m_failed) {
// fail if timeout has expired
if (timeout.getTime() >= s_timeout) {
@ -1249,13 +1261,23 @@ CXWindowsClipboard::CICCCMGetClipboard::readClipboard(Display* display,
}
// process events if any otherwise sleep
if (XPending(display) > 0) {
while (!m_done && !m_failed && XPending(display) > 0) {
if (noWait || XPending(display) > 0) {
while (!m_done && !m_failed && (noWait || XPending(display) > 0)) {
XNextEvent(display, &xevent);
if (!processEvent(display, &xevent)) {
// not processed so save it
events.push_back(xevent);
}
else {
// reset timer since we've made some progress
timeout.reset();
// don't sleep anymore, just block waiting for events.
// we're assuming here that the clipboard owner will
// complete the protocol correctly. if we continue to
// sleep we'll get very bad performance.
noWait = true;
}
}
}
else {
@ -1343,19 +1365,15 @@ CXWindowsClipboard::CICCCMGetClipboard::processEvent(
// selection owner is busted. if the INCR property has no size
// then the selection owner is busted.
if (target == XInternAtom(display, "INCR", False)) {
log((CLOG_INFO " INCR")); // FIXME
if (m_incr) {
log((CLOG_INFO " INCR repeat")); // FIXME
m_failed = true;
m_error = true;
}
else if (m_data->size() == oldSize) {
log((CLOG_INFO " INCR zero size")); // FIXME
m_failed = true;
m_error = true;
}
else {
log((CLOG_INFO " INCR start")); // FIXME
m_incr = true;
// discard INCR data
@ -1373,7 +1391,6 @@ log((CLOG_INFO " INCR start")); // FIXME
// secondary chunks must have the same target
else {
log((CLOG_INFO " INCR secondary chunk")); // FIXME
if (target != *m_actualTarget) {
log((CLOG_WARN " INCR target mismatch"));
m_failed = true;