[gtk-vnc-devel] [RFT] Experiment scancode VNC extension
- From: Anthony Liguori <anthony codemonkey ws>
- To: soren ubuntu com
- Cc: gtk-vnc-devel List <gtk-vnc-devel lists sourceforge net>
- Subject: [gtk-vnc-devel] [RFT] Experiment scancode VNC extension
- Date: Sat, 12 Jan 2008 16:46:36 -0600
The following two patches implement a very rough interface for passing
raw scan codes directly from gtk-vnc to QEMU. This is not at all ready
for committing as it doesn't properly negotiate support or anything. I
don't own a non-US keyboard though so I wanted some basic validation
that this addresses the problem before moving forward.
With these two patches applied to qemu (or KVM) and gtk-vnc, you should
be able to send key presses from a non-US keyboard to a guest with the
same keymap as the host without specifying a '-k XX' option to QEMU.
Please let me know if either of these patches are helpful.
Regards,
Anthony Liguori
diff -r 55e935408794 src/gvnc.c
--- a/src/gvnc.c Sat Jan 12 16:04:53 2008 -0600
+++ b/src/gvnc.c Sat Jan 12 16:42:57 2008 -0600
@@ -887,6 +887,17 @@ gboolean gvnc_key_event(struct gvnc *gvn
gvnc_buffered_write_u8(gvnc, down_flag);
gvnc_buffered_write(gvnc, pad, 2);
gvnc_buffered_write_u32(gvnc, key);
+ gvnc_buffered_flush(gvnc);
+ return !gvnc_has_error(gvnc);
+}
+
+gboolean gvnc_key_event_scancode(struct gvnc *gvnc, uint8_t down_flag,
+ uint16_t scancode)
+{
+ gvnc_buffered_write_u8(gvnc, 255);
+ gvnc_buffered_write_u8(gvnc, 0);
+ gvnc_buffered_write_u16(gvnc, down_flag);
+ gvnc_buffered_write_u16(gvnc, scancode);
gvnc_buffered_flush(gvnc);
return !gvnc_has_error(gvnc);
}
diff -r 55e935408794 src/gvnc.h
--- a/src/gvnc.h Sat Jan 12 16:04:53 2008 -0600
+++ b/src/gvnc.h Sat Jan 12 16:42:57 2008 -0600
@@ -150,6 +150,8 @@ gboolean gvnc_pointer_event(struct gvnc
uint16_t x, uint16_t y);
gboolean gvnc_key_event(struct gvnc *gvnc, uint8_t down_flag, uint32_t key);
+gboolean gvnc_key_event_scancode(struct gvnc *gvnc, uint8_t down_flag,
+ uint16_t scancode);
gboolean gvnc_framebuffer_update_request(struct gvnc *gvnc,
uint8_t incremental,
diff -r 55e935408794 src/vncdisplay.c
--- a/src/vncdisplay.c Sat Jan 12 16:04:53 2008 -0600
+++ b/src/vncdisplay.c Sat Jan 12 16:42:57 2008 -0600
@@ -419,7 +419,7 @@ static gboolean key_event(GtkWidget *wid
if (priv->down_keyval[i] == 0) {
priv->down_keyval[i] = keyval;
/* Send the actual key event we're dealing with */
- gvnc_key_event(priv->gvnc, 1, keyval);
+ gvnc_key_event_scancode(priv->gvnc, 1, key->hardware_keycode);
break;
} else if (priv->down_keyval[i] == keyval) {
/* Got an press when we're already pressed ! Why ... ?
@@ -431,9 +431,9 @@ static gboolean key_event(GtkWidget *wid
* them into a sensible stream of press+release pairs
*/
/* Fake an up event for the previous down event */
- gvnc_key_event(priv->gvnc, 0, keyval);
+ gvnc_key_event_scancode(priv->gvnc, 0, key->hardware_keycode);
/* Now send our actual ldown event */
- gvnc_key_event(priv->gvnc, 1, keyval);
+ gvnc_key_event_scancode(priv->gvnc, 1, key->hardware_keycode);
}
}
} else {
@@ -443,7 +443,7 @@ static gboolean key_event(GtkWidget *wid
if (priv->down_keyval[i] == keyval) {
priv->down_keyval[i] = 0;
/* ..send the key releae event we're dealing with */
- gvnc_key_event(priv->gvnc, 0, keyval);
+ gvnc_key_event_scancode(priv->gvnc, 0, key->hardware_keycode);
break;
}
}
? .pc
? dev.img
? extboot
? patches
Index: vnc.c
===================================================================
RCS file: /sources/qemu/qemu/vnc.c,v
retrieving revision 1.31
diff -u -r1.31 vnc.c
--- vnc.c 16 Dec 2007 03:02:08 -0000 1.31
+++ vnc.c 12 Jan 2008 22:42:41 -0000
@@ -927,12 +927,8 @@
kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
}
-static void do_key_event(VncState *vs, int down, uint32_t sym)
+static void do_key_event(VncState *vs, int down, int keycode, int sym)
{
- int keycode;
-
- keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
-
/* QEMU console switch */
switch(keycode) {
case 0x2a: /* Left Shift */
@@ -960,7 +956,7 @@
break;
}
- if (keycode_is_keypad(vs->kbd_layout, keycode)) {
+ if (sym != -1 && keycode_is_keypad(vs->kbd_layout, keycode)) {
/* 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.
@@ -1033,9 +1029,31 @@
static void key_event(VncState *vs, int down, uint32_t sym)
{
+ int keycode;
+
if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
sym = sym - 'A' + 'a';
- do_key_event(vs, down, sym);
+
+ keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
+ do_key_event(vs, down, keycode, sym);
+}
+
+static void key_event_scancode(VncState *vs, int down, uint16_t scancode)
+{
+ int keycode;
+
+ keycode = scancode;
+ if (keycode < 9)
+ keycode = 0;
+ else if (keycode < 97)
+ keycode -= 8;
+ else if (keycode < 212)
+ keycode = _translate_keycode(keycode - 97);
+ else
+ keycode = 0;
+
+ do_key_event(vs, down, keycode, -1);
+
}
static void framebuffer_update_request(VncState *vs, int incremental,
@@ -1245,6 +1263,23 @@
client_cut_text(vs, read_u32(data, 4), data + 8);
break;
+ case 255:
+ if (len == 1)
+ return 2;
+
+ switch (read_u8(data, 1)) {
+ case 0:
+ if (len == 2)
+ return 6;
+
+ key_event_scancode(vs, read_u16(data, 2), read_u16(data, 4));
+ break;
+ default:
+ printf("Msg: %d\n", read_u16(data, 0));
+ vnc_client_error(vs);
+ break;
+ }
+ break;
default:
printf("Msg: %d\n", data[0]);
vnc_client_error(vs);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]