[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]
Extended keyboard handling patch for rdesktop
- To: rdesktop@xxxxxxxx
- Subject: Extended keyboard handling patch for rdesktop
- From: Ben McKeegan <Ben.McKeegan@xxxxxxxxxxxxxx>
- Date: Wed, 1 Nov 2000 22:03:28 +0000 (GMT)
- Delivered-To: mailing list rdesktop@cifs.org
- Mailing-List: contact rdesktop-help@cifs.org; run by ezmlm
- Sender: Ben McKeegan <brsm2@xxxxxxxxxxxxx>
Hi,
I'm hoping to deploy rdesktop in a production environment as soon as
possible (to replace a rather flaky & slow Wine + MSTSC system). Our
terminals net boot linux and immediately start up X with a rdesktop window
that fills the entire screen. (We're using twm as a window manager and
have configured this to hide the window border and title bar, such that
all the user sees is a full screen windows desktop.)
rdesktop seems to be an excellant piece of software, but unfortunately I
found the keyboard support in distributed version 1.0.0 to be rather poor:
the cursor keys stop working when numlock is on and the insert, delete,
home, end, pgup, pgdn, windows and menu keys don't work at all.
Hence I have produced a patch for the key translation code, as attached,
to add support for all the keys on a standard windows keyboard. This
makes the grey cursor keys work regardless of the numlock setting. I've
even got the window keys and menu key working.
What makes this patch work is an extra flag in the protocol (which I found
via a great deal of trial and error) that allows it to send extended
keyboard scancodes, which are needed to make the extra keys work properly.
As far as can tell my keyboard now works perfectly and is fully fuctional
except for one issue: the num lock behavoir is erratic. It can take
several presses to change the num lock status. This has the side effect
that the num lock light gets out of sync with the actual numlock status.
Has anybody else observed this problem?
My patch also adds a few lines of unrelated code to set set the window
manager hints pproperty: I found it necessary to add this to make twm
position the window automatically (otherwise it gave the user an outline
and waited for them to click to place the window).
Regards,
Ben.
/ Ben McKeegan, I.T. Manager \
\ Fitzwilliam College, University of Cambridge, UK. /
diff -u rdesktop-1.0.0.orig/constants.h rdesktop-1.0.0/constants.h
--- rdesktop-1.0.0.orig/constants.h Mon Oct 16 09:44:47 2000
+++ rdesktop-1.0.0/constants.h Wed Nov 1 19:58:36 2000
@@ -146,6 +146,7 @@
/* Device flags */
#define KBD_FLAG_RIGHT 0x0001
+#define KBD_FLAG_EXT 0x0100
#define KBD_FLAG_QUIET 0x1000
#define KBD_FLAG_DOWN 0x4000
#define KBD_FLAG_UP 0x8000
diff -u rdesktop-1.0.0.orig/xwin.c rdesktop-1.0.0/xwin.c
--- rdesktop-1.0.0.orig/xwin.c Mon Oct 16 09:44:48 2000
+++ rdesktop-1.0.0/xwin.c Wed Nov 1 20:58:52 2000
@@ -19,6 +19,7 @@
*/
#include <X11/Xlib.h>
+#include <X11/Xutil.h>
#include <time.h>
#include "rdesktop.h"
@@ -36,6 +37,7 @@
{
Screen *screen;
XSetWindowAttributes attribs;
+ XSizeHints *sizehints;
unsigned long input_mask;
int i;
@@ -67,6 +69,13 @@
0, 0, width, height, 0, 8, InputOutput, visual,
CWBackingStore | CWBackPixel, &attribs);
+ sizehints = XAllocSizeHints();
+ if (sizehints) {
+ sizehints->flags=PPosition;
+ XSetWMNormalHints(display,wnd,sizehints);
+ XFree(sizehints);
+ }
+
XStoreName(display, wnd, title);
XMapWindow(display, wnd);
@@ -99,18 +108,47 @@
switch (key)
{
- case 0x62: /* left arrow */
- return 0x48;
- case 0x64: /* up arrow */
- return 0x4b;
- case 0x66: /* down arrow */
- return 0x4d;
- case 0x68: /* right arrow */
- return 0x50;
- case 0x73: /* Windows key */
- DEBUG("CHECKPOINT\n");
+ case 0x61: /* home */
+ return 0x47 | 0x80;
+ case 0x62: /* up arrow */
+ return 0x48 | 0x80;
+ case 0x63: /* page up */
+ return 0x49 | 0x80;
+ case 0x64: /* left arrow */
+ return 0x4b | 0x80;
+
+ case 0x66: /* right arrow */
+ return 0x4d | 0x80;
+ case 0x67: /* end */
+ return 0x4f | 0x80;
+ case 0x68: /* down arrow */
+ return 0x50 | 0x80;
+ case 0x69: /* page down */
+ return 0x51 | 0x80;
+ case 0x6a: /* insert */
+ return 0x52 | 0x80;
+ case 0x6b: /* delete */
+ return 0x53 | 0x80;
+ case 0x6c: /* keypad enter */
+ return 0x1c | 0x80;
+ case 0x6d: /* right ctrl */
+ return 0x1d | 0x80;
+ case 0x6f: /* ctrl - print screen */
+ return 0x37 | 0x80;
+ case 0x70: /* keypad '/' */
+ return 0x35 | 0x80;
+ case 0x71: /* right alt */
+ return 0x38 | 0x80;
+ case 0x72: /* ctrl break */
+ return 0x46 | 0x80;
+ case 0x73: /* left window key */
+ return 0xff; /* real scancode is 5b */
+ case 0x74: /* right window key */
+ return 0xff; /* real scancode is 5c */
+ case 0x75: /* menu key */
+ return 0x5d | 0x80;
}
-
+
return 0;
}
@@ -150,8 +188,22 @@
if (scancode == 0)
break;
- rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,
- scancode, 0);
+ if (scancode == 0xff) {
+ /* Window keys equivalent to ctrl-esc */
+ rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
+ 0,0x1d, 0); /* ctrl down */
+ rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
+ 0,1, 0); /* esc down */
+ break;
+ }
+
+ if (scancode & 0x80)
+ rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
+ KBD_FLAG_EXT,
+ scancode & 0x7f, 0);
+ else
+ rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,
+ scancode, 0);
break;
case KeyRelease:
@@ -159,9 +211,26 @@
if (scancode == 0)
break;
- rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
- KBD_FLAG_DOWN | KBD_FLAG_UP,
- scancode, 0);
+ if (scancode == 0xff) {
+ /* Window keys equivalent to ctrl-esc */
+ rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
+ KBD_FLAG_DOWN | KBD_FLAG_UP,
+ 0x1, 0); /* esc up */
+ rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
+ KBD_FLAG_DOWN | KBD_FLAG_UP,
+ 0x1d, 0); /* ctrl up */
+ break;
+ }
+
+ if (scancode & 0x80)
+ rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
+ KBD_FLAG_EXT |
+ KBD_FLAG_DOWN | KBD_FLAG_UP,
+ scancode & 0x7f, 0);
+ else
+ rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
+ KBD_FLAG_DOWN | KBD_FLAG_UP,
+ scancode, 0);
break;
case ButtonPress: