CServer
 * must have connection thread in screen info map
    allows disconnect if screen map changes and screen is removed
 * put mutex locks wherever necessary (like accessing m_active)
 * must handle disconnect of screen by warping cursor off of it

CClient
 * need methods for screen event handler to call as appropriate

server						client
------						------
[accept]			<--		connect
challenge			-->		[encrypt]
[verify]			<--		response (encrypted challenge, client name)
hangup if invalid
query info			-->		
					<--		info (size)

...
enter (x,y)			-->
clipboard data		-->									optional
mouse/key events	-->									optional
query clipboard		-->									optional
					<--		clipboard data					(cont.)
leave				-->

...
grab clipboard		-->

... (on clipboard ownership stolen)
					<--		clipboard lost

... (on screen resize)
					<--		info (size)

... (on screen saver, primary screen)
saver (on/off)		-->

...
quit				-->
					<--		close

---
primary screen
	open
	close
	enter
	leave
	warp
	clipboard (get/set)
	screen saver (show/hide)
	queue events with server (including screen saver activation)

secondary screen
	open
	close
	enter
	leave
	warp
	synth mouse
	synth key
	clipboard (get/set)
	screen saver (show/hide)
	queue events with client (clipboard lost/changed, size change)

---
client:
	open
	close
	wait: server messages, clipboard taken, screen resize, quit

server:
	accept
		asynchronously accept new clients
	config
		asynchronously accept and handle config message (via HTTP)
	primary
		asynchronously handle primary screen events
	comm
		send/recv messages to/from clients

---
win32:
  double click support
  need to support window stations
    login screen on NT is a separate window station
  handle display changes

---
not sending VK_?WIN and VK_APPS.  possibly hotkeys being stolen.

VkKeyScan() doesn't get proper shift state unless we map shift
(etc?) to VK_SHIFT not VK_LSHIFT or VK_RSHIFT.

not handling international characters

X11 key translation (server)
  handle compose key?
   * don't send compose, don't send dead keys, send composed key?
   * send all keys, let client do compose

---
translate keys to keysyms
  shift state is embedded in keysym
  alt/ctrl/meta are stored separately, also caps/num/scroll lock
  shift state also stored separately

X to keysym:
  keycode + shift -> keysym via XLookupString()
X from keysym:
  keysym -> XKeysymToKeycode() or XGetKeyboardMapping() and search for index
  must synth shift key events to get correct index for key

Win32 to keysym:
  VK code + shift -> keysym via table lookup
Win32 from keysym:
  VK code and shift via table lookup
  must synth shift key events to get correct character for key

don't allow leaving screen when any key is down
  that includes shift keys
  caps lock, etc must not be down but can be on
