checkpoint. turned off nagle and send buffering. also
added test to skip clipboard conversion if a previous conversion from that owner failed.
This commit is contained in:
parent
59c5e4bf13
commit
f2e83e607d
|
@ -13,7 +13,7 @@ RMR = /bin/rm -rf
|
||||||
#
|
#
|
||||||
# compiler options
|
# compiler options
|
||||||
#
|
#
|
||||||
GCXXDEFS = -D_XOPEN_SOURCE=600
|
GCXXDEFS = -D_XOPEN_SOURCE=600 -D_SVID_SOURCE
|
||||||
GCXXINCS = -I$(DEPTH)/include -I/usr/X11R6/include
|
GCXXINCS = -I$(DEPTH)/include -I/usr/X11R6/include
|
||||||
GCXXOPTS = -Wall -W -fexceptions
|
GCXXOPTS = -Wall -W -fexceptions
|
||||||
CXXOPTIMIZER = -g
|
CXXOPTIMIZER = -g
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
# define INCL_WINSOCK_API_TYPEDEFS 0
|
# define INCL_WINSOCK_API_TYPEDEFS 0
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
typedef int ssize_t;
|
typedef int ssize_t;
|
||||||
|
# if !defined(SOL_TCP)
|
||||||
|
# define SOL_TCP IPPROTO_TCP
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
# define FAR
|
# define FAR
|
||||||
# define PASCAL
|
# define PASCAL
|
||||||
|
@ -21,6 +24,9 @@ typedef int ssize_t;
|
||||||
# include <netdb.h>
|
# include <netdb.h>
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
|
# if !defined(TCP_NODELAY) || !defined(SOL_TCP)
|
||||||
|
# include <netinet/tcp.h>
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME -- must handle htonl and ilk when defined as macros
|
// FIXME -- must handle htonl and ilk when defined as macros
|
||||||
|
@ -31,6 +37,7 @@ public:
|
||||||
typedef SOCKET Socket;
|
typedef SOCKET Socket;
|
||||||
typedef struct sockaddr Address;
|
typedef struct sockaddr Address;
|
||||||
typedef int AddressLength;
|
typedef int AddressLength;
|
||||||
|
typedef BOOL TCPNoDelayType;
|
||||||
struct PollEntry {
|
struct PollEntry {
|
||||||
Socket fd;
|
Socket fd;
|
||||||
short events;
|
short events;
|
||||||
|
@ -47,6 +54,7 @@ public:
|
||||||
typedef struct sockaddr Address;
|
typedef struct sockaddr Address;
|
||||||
typedef socklen_t AddressLength;
|
typedef socklen_t AddressLength;
|
||||||
typedef struct pollfd PollEntry;
|
typedef struct pollfd PollEntry;
|
||||||
|
typedef int TCPNoDelayType;
|
||||||
enum {
|
enum {
|
||||||
kPOLLIN = POLLIN,
|
kPOLLIN = POLLIN,
|
||||||
kPOLLOUT = POLLOUT,
|
kPOLLOUT = POLLOUT,
|
||||||
|
|
|
@ -128,6 +128,16 @@ void CTCPSocket::init()
|
||||||
m_output = new CBufferedOutputStream(m_mutex,
|
m_output = new CBufferedOutputStream(m_mutex,
|
||||||
new TMethodJob<CTCPSocket>(
|
new TMethodJob<CTCPSocket>(
|
||||||
this, &CTCPSocket::closeOutput));
|
this, &CTCPSocket::closeOutput));
|
||||||
|
|
||||||
|
// turn off Nagle algorithm. we send lots of very short messages
|
||||||
|
// that should be sent without (much) delay. for example, the
|
||||||
|
// mouse motion messages are much less useful if they're delayed.
|
||||||
|
CNetwork::TCPNoDelayType flag = 1;
|
||||||
|
CNetwork::setsockopt(m_fd, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));
|
||||||
|
|
||||||
|
// don't buffer sends, we merge messages ourself
|
||||||
|
int data = 0;
|
||||||
|
CNetwork::setsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, &data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTCPSocket::ioThread(void*)
|
void CTCPSocket::ioThread(void*)
|
||||||
|
|
|
@ -261,6 +261,23 @@ void CXWindowsScreen::getDisplayClipboard(
|
||||||
CLock lock(&m_mutex);
|
CLock lock(&m_mutex);
|
||||||
Atom selection = m_atomClipboard[id];
|
Atom selection = m_atomClipboard[id];
|
||||||
|
|
||||||
|
// if we're trying to request the clipboard from the same
|
||||||
|
// unresponsive owner then immediately give up. this is lame
|
||||||
|
// because we can't be sure the owner won't become responsive;
|
||||||
|
// we can only ask the X server for the current owner, not the
|
||||||
|
// owner at time timestamp, allowing a race condition; and we
|
||||||
|
// don't detect if the owner window is destroyed in order to
|
||||||
|
// reset the unresponsive flag.
|
||||||
|
Window owner = XGetSelectionOwner(m_display, selection);
|
||||||
|
if (m_clipboards[id].m_unresponsive) {
|
||||||
|
if (owner != None && owner == m_clipboards[id].m_owner) {
|
||||||
|
clipboard->close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CClipboardInfo& clipboardInfo =
|
||||||
|
const_cast<CClipboardInfo&>(m_clipboards[id]);
|
||||||
|
|
||||||
// ask the selection for all the formats it has. some owners return
|
// ask the selection for all the formats it has. some owners return
|
||||||
// the TARGETS atom and some the ATOM atom when TARGETS is requested.
|
// the TARGETS atom and some the ATOM atom when TARGETS is requested.
|
||||||
Atom format;
|
Atom format;
|
||||||
|
@ -268,6 +285,10 @@ void CXWindowsScreen::getDisplayClipboard(
|
||||||
if (getDisplayClipboard(selection, m_atomTargets,
|
if (getDisplayClipboard(selection, m_atomTargets,
|
||||||
requestor, timestamp, &format, &targets) &&
|
requestor, timestamp, &format, &targets) &&
|
||||||
(format == m_atomTargets || format == XA_ATOM)) {
|
(format == m_atomTargets || format == XA_ATOM)) {
|
||||||
|
// save owner info
|
||||||
|
clipboardInfo.m_owner = owner;
|
||||||
|
clipboardInfo.m_unresponsive = false;
|
||||||
|
|
||||||
// get each target (that we can interpret). some owners return
|
// get each target (that we can interpret). some owners return
|
||||||
// some targets multiple times in the list so don't try to get
|
// some targets multiple times in the list so don't try to get
|
||||||
// those multiple times.
|
// those multiple times.
|
||||||
|
@ -330,6 +351,11 @@ void CXWindowsScreen::getDisplayClipboard(
|
||||||
else {
|
else {
|
||||||
// non-ICCCM conforming selection owner. try TEXT format.
|
// non-ICCCM conforming selection owner. try TEXT format.
|
||||||
// FIXME
|
// FIXME
|
||||||
|
|
||||||
|
// save owner info
|
||||||
|
clipboardInfo.m_owner = owner;
|
||||||
|
clipboardInfo.m_unresponsive = true;
|
||||||
|
|
||||||
log((CLOG_DEBUG1 "selection doesn't support TARGETS, format is %d", format));
|
log((CLOG_DEBUG1 "selection doesn't support TARGETS, format is %d", format));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,7 +1040,9 @@ Time CXWindowsScreen::getCurrentTimeNoLock(
|
||||||
CXWindowsScreen::CClipboardInfo::CClipboardInfo() :
|
CXWindowsScreen::CClipboardInfo::CClipboardInfo() :
|
||||||
m_clipboard(),
|
m_clipboard(),
|
||||||
m_lostClipboard(CurrentTime),
|
m_lostClipboard(CurrentTime),
|
||||||
m_requests()
|
m_requests(),
|
||||||
|
m_owner(None),
|
||||||
|
m_unresponsive(false)
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,6 +161,12 @@ private:
|
||||||
|
|
||||||
// the request queues
|
// the request queues
|
||||||
CRequestMap m_requests;
|
CRequestMap m_requests;
|
||||||
|
|
||||||
|
// owner of clipboard when we last asked for it
|
||||||
|
Window m_owner;
|
||||||
|
|
||||||
|
// true iff the previous request to m_owner got no reply
|
||||||
|
bool m_unresponsive;
|
||||||
};
|
};
|
||||||
|
|
||||||
Display* m_display;
|
Display* m_display;
|
||||||
|
|
Loading…
Reference in New Issue