now speaks to the primary screen and secondary screens almost
everywhere the same way through an IClient interface; only
special primary screen calls are accessed through a different
interface, the CPrimaryClient interface. this simplifies the
server since it no longer needs to test whether the active screen
is the primary or a secondary in most cases.
the server no longer speaks directly to the primary screen; all
that goes through the CPrimaryClient, which often just forwards
the call. the primary screen no longer speaks directly to the
server either, again going through the CPrimaryClient via a
IPrimaryReceiver interface.
CServerProtocol classes have been replaced by CClientProxy
classes which are very similar. the name makes more sense
though.
the client screen is closed. this fixes the bug where the
client's keyboard was left with some keys logically pressed
when the client died (e.g. using ctrl+c on the client program
from the server's keyboard would leave the ctrl key logically
pressed).
init() it while it's already running. fixed an uninitialized
pointer bug in CServer and some cleanup-on-error code in
CMSWindowsPrimaryScreen. also added timeout to read() on
IInputStream and a heartbeat sent by clients so the server
can disconnect clients that are dead but never reset the TCP
connection. previously the server would keep these dead
clients around forever and if the user was locked on the
client screen for some reason then the server would have to
be rebooted (or the server would have to be killed via a
remote login).
and back to secondary when it stops. also now redirecting
keyboard input to root window when screen saver starts; this
allows the user to type in the lock dialog and also effectively
discards any input used to deactivate the screen saver.
activation. previously the timer would deactivate the screen
saver shortly after activation. job timer is restored when
the screen saver is deactivated.
installing and uninstalling the new error handler, causing
errors before the lock to be caught and errors during the lock
to not be caught. had to add Display* as argument to c'tor.
and untested. also some known problems: not detecting an
xscreensaver started after us and not detecting built-in
screen saver activation (not sure if we can without using
ugly extensions).
to the thread list: the child thread would add itself to the
list which means there could be a time interval in the parent
where the child thread exists but isn't on the list. the
parent now does the adding and removing.
multiple times is *not* the same as calling XIfEvent() because the
former will re-encounter events that it didn't process previously.
to make things simple it now pulls events off the queue and saves
them if not processed for selection transfer and puts them back
afterwards.
when it wasn't necessary. (in particular, we were getting the
clipboard update time from the owner then emptying the clipboard,
so we didn't need to get the time. worse, most owners don't
support getting the time and we often timed out.)
also fixed a multithread bug using the X display. we were using
a CThread to send an event after a timeout while we were waiting
in XIfEvent(). this necessarily involved two threads calling
into Xlib at once, which is not allowed. now using polling to
do the timeout because Xlib doesn't have a function to get
events with a timeout.
motion events relative to the previous mouse position. for
example, if two mouse events arrive, the first at x+1,y and
the second at x+2,y, we used to compute deltas of 1,0 and 2,0
instead of 1,0 and 1,0. that's fixed. also worked around a
bug (probably) in windows that caused a motion event after a
SetCursorPos() to be lost or reported one pixel off from the
correct position. now using mouse_event() which doesn't
have that problem. also fixed calculation of normalized
coordinates for mouse_event() when there are multiple
displays.