bool
XWindowsClipboard::processRequest(Window requestor,
				::Time /*time*/, Atom property)
{
	ReplyMap::iterator index = m_replies.find(requestor);
	if (index == m_replies.end()) {
		// unknown requestor window
		return false;
	}
	LOG((CLOG_DEBUG1 "received property %s delete from 0x08%x", XWindowsUtil::atomToString(m_display, property).c_str(), requestor));

	// find the property in the known requests.  it should be the
	// first property but we'll check 'em all if we have to.
	ReplyList& replies = index->second;
	for (ReplyList::iterator index2 = replies.begin();
								index2 != replies.end(); ++index2) {
		Reply* reply = *index2;
		if (reply->m_replied && reply->m_property == property) {
			// if reply is complete then remove it and start the
			// next one.
			pushReplies(index, replies, index2);
			return true;
		}
	}

	return false;
}
void
CXWindowsClipboard::pushReplies()
{
	// send the first reply for each window if that reply hasn't
	// been sent yet.
	for (CReplyMap::iterator index = m_replies.begin();
								index != m_replies.end(); ++index) {
		assert(!index->second.empty());
		if (!index->second.front()->m_replied) {
			pushReplies(index, index->second, index->second.begin());
		}
	}
}
void
XWindowsClipboard::pushReplies()
{
	// send the first reply for each window if that reply hasn't
	// been sent yet.
	for (ReplyMap::iterator index = m_replies.begin();
								index != m_replies.end(); ) {
		assert(!index->second.empty());
		ReplyList::iterator listit = index->second.begin();
		while (listit != index->second.end()) {
			if (!(*listit)->m_replied)
				break;
			++listit;
		}
		if (listit != index->second.end() && !(*listit)->m_replied) {
			pushReplies(index, index->second, listit);
		}
		else {
			++index;
		}
	}
}
void
XWindowsClipboard::addRequest(Window owner, Window requestor,
				Atom target, ::Time time, Atom property)
{
	// must be for our window and we must have owned the selection
	// at the given time.
	bool success = false;
	if (owner == m_window) {
		LOG((CLOG_DEBUG1 "request for clipboard %d, target %s by 0x%08x (property=%s)", m_selection, XWindowsUtil::atomToString(m_display, target).c_str(), requestor, XWindowsUtil::atomToString(m_display, property).c_str()));
		if (wasOwnedAtTime(time)) {
			if (target == m_atomMultiple) {
				// add a multiple request.  property may not be None
				// according to ICCCM.
				if (property != None) {
					success = insertMultipleReply(requestor, time, property);
				}
			}
			else {
				addSimpleRequest(requestor, target, time, property);

				// addSimpleRequest() will have already handled failure
				success = true;
			}
		}
		else {
			LOG((CLOG_DEBUG1 "failed, not owned at time %d", time));
		}
	}

	if (!success) {
		// send failure
		LOG((CLOG_DEBUG1 "failed"));
		insertReply(new Reply(requestor, target, time));
	}

	// send notifications that are pending
	pushReplies();
}