We automatically call the standard callbacks if a server does not implement
this new callback.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>

Index: new/server/inputs_channel.c
===================================================================
--- new.orig/server/inputs_channel.c	2013-10-14 10:27:27.000000000 +0200
+++ new/server/inputs_channel.c	2013-10-14 10:29:08.000000000 +0200
@@ -224,6 +224,26 @@
     sif->push_scan_freg(sin, scan);
 }
 
+static void kbd_push_x11_keysym(SpiceKbdInstance *sin, uint32_t keysym,
+                                uint32_t flags, uint8_t code_len, uint8_t *code)
+{
+    SpiceKbdInterface *sif;
+    int i;
+
+    if (!sin) {
+        return;
+    }
+    sif = SPICE_CONTAINEROF(sin->base.sif, SpiceKbdInterface, base);
+
+    if (sif->push_x11_keysym) {
+        sif->push_x11_keysym(sin, keysym, flags, code_len, code);
+    } else {
+        for (i = 0; i < code_len; i++) {
+            kbd_push_scan(sin, code[i]);
+        }
+    }
+}
+
 static uint8_t kbd_get_leds(SpiceKbdInstance *sin)
 {
     SpiceKbdInterface *sif;
@@ -339,6 +359,11 @@
         }
         break;
     }
+    case SPICE_MSGC_INPUTS_KEY_X11_KEYSYM: {
+        SpiceMsgcKeyX11KeySym *msg = (SpiceMsgcKeyX11KeySym *)buf;
+        kbd_push_x11_keysym(keyboard, msg->keysym, msg->flags, msg->code_len, msg->code);
+        break;
+    }
     case SPICE_MSGC_INPUTS_MOUSE_MOTION: {
         SpiceMsgcMouseMotion *mouse_motion = (SpiceMsgcMouseMotion *)buf;
 
@@ -440,18 +465,18 @@
         leds = kbd_get_leds(keyboard);
         if ((modifiers->modifiers & SPICE_KEYBOARD_MODIFIER_FLAGS_SCROLL_LOCK) !=
             (leds & SPICE_KEYBOARD_MODIFIER_FLAGS_SCROLL_LOCK)) {
-            kbd_push_scan(keyboard, SCROLL_LOCK_SCAN_CODE);
-            kbd_push_scan(keyboard, SCROLL_LOCK_SCAN_CODE | 0x80);
+            uint8_t code[] = { SCROLL_LOCK_SCAN_CODE, SCROLL_LOCK_SCAN_CODE | 0x80 };
+            kbd_push_x11_keysym(keyboard, 0xff14, SPICE_KEYBOARD_FLAG_DOWN|SPICE_KEYBOARD_FLAG_UP, 2, code);
         }
         if ((modifiers->modifiers & SPICE_KEYBOARD_MODIFIER_FLAGS_NUM_LOCK) !=
             (leds & SPICE_KEYBOARD_MODIFIER_FLAGS_NUM_LOCK)) {
-            kbd_push_scan(keyboard, NUM_LOCK_SCAN_CODE);
-            kbd_push_scan(keyboard, NUM_LOCK_SCAN_CODE | 0x80);
+            uint8_t code[] = { NUM_LOCK_SCAN_CODE, NUM_LOCK_SCAN_CODE | 0x8 };
+            kbd_push_x11_keysym(keyboard, 0xff7f, SPICE_KEYBOARD_FLAG_DOWN|SPICE_KEYBOARD_FLAG_UP, 2, code);
         }
         if ((modifiers->modifiers & SPICE_KEYBOARD_MODIFIER_FLAGS_CAPS_LOCK) !=
             (leds & SPICE_KEYBOARD_MODIFIER_FLAGS_CAPS_LOCK)) {
-            kbd_push_scan(keyboard, CAPS_LOCK_SCAN_CODE);
-            kbd_push_scan(keyboard, CAPS_LOCK_SCAN_CODE | 0x80);
+            uint8_t code[] = { CAPS_LOCK_SCAN_CODE, CAPS_LOCK_SCAN_CODE | 0x80 };
+            kbd_push_x11_keysym(keyboard, 0xffe5, SPICE_KEYBOARD_FLAG_DOWN|SPICE_KEYBOARD_FLAG_UP, 2, code);
         }
         activate_modifiers_watch();
         break;
@@ -466,12 +491,31 @@
 
 static void inputs_relase_keys(void)
 {
-    kbd_push_scan(keyboard, 0x2a | 0x80); //LSHIFT
-    kbd_push_scan(keyboard, 0x36 | 0x80); //RSHIFT
-    kbd_push_scan(keyboard, 0xe0); kbd_push_scan(keyboard, 0x1d | 0x80); //RCTRL
-    kbd_push_scan(keyboard, 0x1d | 0x80); //LCTRL
-    kbd_push_scan(keyboard, 0xe0); kbd_push_scan(keyboard, 0x38 | 0x80); //RALT
-    kbd_push_scan(keyboard, 0x38 | 0x80); //LALT
+    uint8_t code[2];
+
+    static uint8_t code_lshift[] = { 0x2a | 0x80 };
+    kbd_push_x11_keysym(keyboard, 0xffe1, SPICE_KEYBOARD_FLAG_UP,
+                        sizeof(code_lshift), code_lshift);
+
+    static uint8_t code_rshift[] =  { 0x36 | 0x80 };
+    kbd_push_x11_keysym(keyboard, 0xffe2, SPICE_KEYBOARD_FLAG_UP,
+                        sizeof(code_rshift), code_rshift);
+
+    static uint8_t code_lctrl[] = { 0x1d | 0x80 };
+    kbd_push_x11_keysym(keyboard, 0xffe3, SPICE_KEYBOARD_FLAG_UP,
+                        sizeof(code_lctrl), code_lctrl);
+
+    static uint8_t code_rctl[] = { 0xe0, 0x1d | 0x80 };
+    kbd_push_x11_keysym(keyboard, 0xffe4, SPICE_KEYBOARD_FLAG_UP,
+                        sizeof(code_rctl), code_rctl);
+
+    static uint8_t code_lalt[] = { 0x38 | 0x80 };
+    kbd_push_x11_keysym(keyboard, 0xffe9, SPICE_KEYBOARD_FLAG_UP,
+                        sizeof(code_lalt), code_lalt);
+
+    static uint8_t code_ralt[] = { 0xe0, 0x38 | 0x80 };
+    kbd_push_x11_keysym(keyboard, 0xfe03, SPICE_KEYBOARD_FLAG_UP,
+                        sizeof(code_ralt), code_ralt);
 }
 
 static void inputs_channel_on_disconnect(RedChannelClient *rcc)
@@ -637,6 +681,8 @@
     red_channel_register_client_cbs(&g_inputs_channel->base, &client_cbs);
 
     red_channel_set_cap(&g_inputs_channel->base, SPICE_INPUTS_CAP_KEY_SCANCODE);
+    red_channel_set_cap(&g_inputs_channel->base, SPICE_INPUTS_CAP_KEY_X11_KEYSYM);
+
     reds_register_channel(&g_inputs_channel->base);
 
     if (!(key_modifiers_timer = core->timer_add(key_modifiers_sender, NULL))) {
Index: new/server/spice.h
===================================================================
--- new.orig/server/spice.h	2013-10-14 10:27:27.000000000 +0200
+++ new/server/spice.h	2013-10-14 10:28:32.000000000 +0200
@@ -272,6 +272,8 @@
 
     void (*push_scan_freg)(SpiceKbdInstance *sin, uint8_t frag);
     uint8_t (*get_leds)(SpiceKbdInstance *sin);
+    void (*push_x11_keysym)(SpiceKbdInstance *sin, uint32_t keysym, uint32_t flags, 
+                            uint8_t code_len, uint8_t *code);
 };
 
 struct SpiceKbdInstance {

