Multiple client modifier inconsistencies

Roland Kay rols "at" localhost.hack
Mon, 06 Nov 2000 11:34:53 +0000


I've recently switched to using VNC instead of "X -query ..." to access
my desktops. I tend to run vncviewer fullscreen on my Linux laptop and 
simultaneously connect from a unix desktop machine (with a nicer keyboard :)
It didn't take long to discover that if I switched VT on the laptop 
(with a CTRL+ALT+Fx key-press) and tried to type anything on the
desktop machine all I got was frantic beeping.

After digging around in the vnc sources for a bit, I discovered that this
problem is actually the one alluded to by Q.35 of the FAQ. Namely, the Xvnc
server has received CTRL+ALT key press events but not the corresponding key
release events. It, therefore, still thinks that these keys are held down.

The following modification to the function SendKeyEvent() in
vnc_unixscr/vncviewer/rfbproto.c seems to solve the problem.
The idea being that vncviewer checks the status of the Ctrl and Alt keys
and and sends release events if they're not held down.
	
I freely admit that this is a bit of a quick hack; still it might prove
useful.

R.

            ---------------------->8 snip 8<-----------------------
	
diff -uNr vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncviewer/rfbproto.c
--- vnc_unixsrc.orig/vncviewer/rfbproto.c	Thu Aug 12 12:07:48 1999
+++ vnc_unixsrc/vncviewer/rfbproto.c	Sun Nov  5 09:57:29 2000
@@ -363,15 +363,37 @@
   return WriteExact(rfbsock, (char *)&pe, sz_rfbPointerEventMsg);
 }
 
-
 /*
- * SendKeyEvent.
+ * SendKeyEvent (Modified).
+ *
+ * If two or more clients are connected to the same display then problems
+ * can arise if one sends key press events for modifier keys but never sends
+ * the corresponding release events. This can happen, for instance, when
+ * switching virtual terminals (CTRL+ALT+Fx) under Linux.
+ *
+ * The modified SendKeyEvent() checks the state of the CTRL and ALT keys
+ * clientside and sends (possibly redundant) key release events to the server
+ * if they are not held down.
+ * A better solution would be to extended the protocol to include a bitfield
+ * describing the state of the modifier keys clientside. The server could then
+ * ensure that it's description of the keyboard was consistent with this.
+ *
+ *                                                   -- R.Kay (5-11-2000)
  */
 
 Bool
 SendKeyEvent(CARD32 key, Bool down)
 {
   rfbKeyEventMsg ke;
+  char buf[32];       /* Used for keyboard description vector. */
+
+  if ((key != 0xffe3) && (key != 0xffe9)) { /* If not Ctrl or Alt... */
+    XQueryKeymap(dpy , buf);
+    if (!(buf[8] & 0x01)) /* If ALT wasn't held down, fake a release event. */
+      SendKeyEvent(0xffe9, 0);
+    if (!(buf[4] & 0x20)) /* If CTRL wasn't held down, fake a release event. */
+      SendKeyEvent(0xffe3, 0);
+  }
 
   ke.type = rfbKeyEvent;
   ke.down = down ? 1 : 0;
@@ -379,6 +401,23 @@
   return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg);
 }
 
+
+/*
+ * SendKeyEvent (Original).
+ */
+
+/*
+Bool
+SendKeyEvent(CARD32 key, Bool down)
+{
+  rfbKeyEventMsg ke;
+
+  ke.type = rfbKeyEvent;
+  ke.down = down ? 1 : 0;
+  ke.key = Swap32IfLE(key);
+  return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg);
+}
+*/
 
 /*
  * SendClientCutText.
---------------------------------------------------------------------
To unsubscribe, send a message with the line: unsubscribe vnc-list
to majordomo "at" uk.research.att.com
See also: http://www.uk.research.att.com/vnc/intouch.html
---------------------------------------------------------------------