143 lines
3.9 KiB
Diff
143 lines
3.9 KiB
Diff
Index: xen-3.1-testing/tools/xenfb/vncfb.c
|
|
===================================================================
|
|
--- xen-3.1-testing.orig/tools/xenfb/vncfb.c 2007-05-17 09:51:10.000000000 -0600
|
|
+++ xen-3.1-testing/tools/xenfb/vncfb.c 2007-09-14 11:59:57.000000000 -0600
|
|
@@ -55,12 +55,47 @@
|
|
unsigned char keycode_table[512];
|
|
|
|
static void *kbd_layout;
|
|
+uint8_t modifiers_state[256];
|
|
|
|
static int btnmap[] = {
|
|
BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_SIDE,
|
|
BTN_EXTRA, BTN_FORWARD, BTN_BACK, BTN_TASK
|
|
};
|
|
|
|
+static void press_key_shift_down(struct xenfb* xenfb, int down, int scancode)
|
|
+{
|
|
+ if (down)
|
|
+ xenfb_send_key(xenfb, 1, keycode_table[0x2a]);
|
|
+
|
|
+ if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0)
|
|
+ fprintf(stderr, "Key %d %s lost (%s)\n",
|
|
+ scancode, "down", strerror(errno));
|
|
+
|
|
+ if (!down)
|
|
+ xenfb_send_key(xenfb, 0, keycode_table[0x2a]);
|
|
+}
|
|
+
|
|
+static void press_key_shift_up(struct xenfb* xenfb, int down, int scancode)
|
|
+{
|
|
+ if (down) {
|
|
+ if (modifiers_state[0x2a])
|
|
+ xenfb_send_key(xenfb, 0, keycode_table[0x2a]);
|
|
+ if (modifiers_state[0x36])
|
|
+ xenfb_send_key(xenfb, 0, keycode_table[0x36]);
|
|
+ }
|
|
+
|
|
+ if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0)
|
|
+ fprintf(stderr, "Key %d %s lost (%s)\n",
|
|
+ scancode, "down", strerror(errno));
|
|
+
|
|
+ if (!down) {
|
|
+ if (modifiers_state[0x2a])
|
|
+ xenfb_send_key(xenfb, 1, keycode_table[0x2a]);
|
|
+ if (modifiers_state[0x36])
|
|
+ xenfb_send_key(xenfb, 1, keycode_table[0x36]);
|
|
+ }
|
|
+}
|
|
+
|
|
static void on_kbd_event(rfbBool down, rfbKeySym keycode, rfbClientPtr cl)
|
|
{
|
|
/*
|
|
@@ -75,14 +110,75 @@
|
|
rfbScreenInfoPtr server = cl->screen;
|
|
struct xenfb *xenfb = server->screenData;
|
|
int scancode;
|
|
+ int shift = 0;
|
|
+ int shift_keys = 0;
|
|
|
|
- if (keycode >= 'A' && keycode <= 'Z')
|
|
+ if (keycode >= 'A' && keycode <= 'Z') {
|
|
keycode += 'a' - 'A';
|
|
+ shift = 1;
|
|
+ }
|
|
+ else {
|
|
+ shift = keysymIsShift(kbd_layout, keycode);
|
|
+ }
|
|
+ shift_keys = modifiers_state[0x2a] | modifiers_state[0x36];
|
|
|
|
- scancode = keycode_table[keysym2scancode(kbd_layout, keycode)];
|
|
+ scancode = keysym2scancode(kbd_layout, keycode);
|
|
if (scancode == 0)
|
|
return;
|
|
- if (xenfb_send_key(xenfb, down, scancode) < 0)
|
|
+
|
|
+ switch(scancode) {
|
|
+ case 0x2a: /* Left Shift */
|
|
+ case 0x36: /* Right Shift */
|
|
+ case 0x1d: /* Left CTRL */
|
|
+ case 0x9d: /* Right CTRL */
|
|
+ case 0x38: /* Left ALT */
|
|
+ case 0xb8: /* Right ALT */
|
|
+ if (down)
|
|
+ modifiers_state[scancode] = 1;
|
|
+ else
|
|
+ modifiers_state[scancode] = 0;
|
|
+ xenfb_send_key(xenfb, down, keycode_table[scancode]);
|
|
+ return;
|
|
+ case 0x45: /* NumLock */
|
|
+ if (!down)
|
|
+ modifiers_state[scancode] ^= 1;
|
|
+ xenfb_send_key(xenfb, down, keycode_table[scancode]);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (keycodeIsKeypad(kbd_layout, scancode)) {
|
|
+ /* If the numlock state needs to change then simulate an additional
|
|
+ keypress before sending this one. This will happen if the user
|
|
+ toggles numlock away from the VNC window.
|
|
+ */
|
|
+ if (keysymIsNumlock(kbd_layout, keycode)) {
|
|
+ if (!modifiers_state[0x45]) {
|
|
+ modifiers_state[0x45] = 1;
|
|
+ xenfb_send_key(xenfb, 1, keycode_table[0x45]);
|
|
+ xenfb_send_key(xenfb, 0, keycode_table[0x45]);
|
|
+ }
|
|
+ } else {
|
|
+ if (modifiers_state[0x45]) {
|
|
+ modifiers_state[0x45] = 0;
|
|
+ xenfb_send_key(xenfb, 1, keycode_table[0x45]);
|
|
+ xenfb_send_key(xenfb, 0, keycode_table[0x45]);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* If the shift state needs to change then simulate an additional
|
|
+ keypress before sending this one.
|
|
+ */
|
|
+ if (shift && !shift_keys) {
|
|
+ press_key_shift_down(xenfb, down, scancode);
|
|
+ return;
|
|
+ }
|
|
+ else if (!shift && shift_keys) {
|
|
+ press_key_shift_up(xenfb, down, scancode);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0)
|
|
fprintf(stderr, "Key %d %s lost (%s)\n",
|
|
scancode, down ? "down" : "up",
|
|
strerror(errno));
|
|
@@ -314,6 +410,10 @@
|
|
atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
|
|
}
|
|
|
|
+ for (i = 0; i < 256; i++ ) {
|
|
+ modifiers_state[i] = 0;
|
|
+ }
|
|
+
|
|
fake_argv[2] = portstr;
|
|
|
|
if (title != NULL)
|