[Spice-devel] [spice-gtk] implement new keyval protocol

Dietmar Maurer dietmar at proxmox.com
Mon Sep 9 21:55:41 PDT 2013


Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
---
 gtk/channel-inputs.c    |   33 ++++++++++++++++++++++++++++-----
 gtk/channel-inputs.h    |    6 +++---
 gtk/spice-widget-priv.h |    1 +
 gtk/spice-widget.c      |   24 ++++++++++++++----------
 4 files changed, 46 insertions(+), 18 deletions(-)

diff --git a/gtk/channel-inputs.c b/gtk/channel-inputs.c
index ee86dc2..ce9173a 100644
--- a/gtk/channel-inputs.c
+++ b/gtk/channel-inputs.c
@@ -464,6 +464,23 @@ void spice_inputs_button_release(SpiceInputsChannel *channel, gint button,
     spice_msg_out_send(msg);
 }
 
+static void spice_inputs_key_keyval(SpiceInputsChannel *channel, guint keyval, int flags)
+{
+    g_return_if_fail(channel != NULL);
+
+    if (spice_channel_test_capability(SPICE_CHANNEL(channel), SPICE_INPUTS_CAP_KEY_KEYVAL)) {
+        SpiceMsgcKeyKeyval keyval_msg;
+        SpiceMsgOut *msg;
+ 
+        keyval_msg.keyval = keyval;
+        keyval_msg.flags = flags;
+
+        msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_INPUTS_KEY_KEYVAL);
+        msg->marshallers->msgc_inputs_key_keyval(msg->marshaller, &keyval_msg);
+        spice_msg_out_send(msg);
+    }
+}
+
 /**
  * spice_inputs_key_press:
  * @channel:
@@ -471,7 +488,7 @@ void spice_inputs_button_release(SpiceInputsChannel *channel, gint button,
  *
  * Press a key.
  **/
-void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode)
+void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode, guint keyval)
 {
     SpiceMsgcKeyDown down;
     SpiceMsgOut *msg;
@@ -487,6 +504,8 @@ void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode)
     msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_INPUTS_KEY_DOWN);
     msg->marshallers->msgc_inputs_key_down(msg->marshaller, &down);
     spice_msg_out_send(msg);
+
+    spice_inputs_key_keyval(channel, keyval, 1);
 }
 
 /**
@@ -496,7 +515,7 @@ void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode)
  *
  * Release a key.
  **/
-void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode)
+void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode, guint keyval)
 {
     SpiceMsgcKeyUp up;
     SpiceMsgOut *msg;
@@ -512,6 +531,8 @@ void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode)
     msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_INPUTS_KEY_UP);
     msg->marshallers->msgc_inputs_key_up(msg->marshaller, &up);
     spice_msg_out_send(msg);
+
+    spice_inputs_key_keyval(channel, keyval, 2);
 }
 
 /**
@@ -523,7 +544,7 @@ void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode)
  *
  * Since: 0.13
  **/
-void spice_inputs_key_press_and_release(SpiceInputsChannel *input_channel, guint scancode)
+void spice_inputs_key_press_and_release(SpiceInputsChannel *input_channel, guint scancode, guint keyval)
 {
     SpiceChannel *channel = SPICE_CHANNEL(input_channel);
 
@@ -555,11 +576,13 @@ void spice_inputs_key_press_and_release(SpiceInputsChannel *input_channel, guint
             buf[3] = code >> 8;
         }
         spice_msg_out_send(msg);
+        spice_inputs_key_keyval(input_channel, keyval, 3);
     } else {
         CHANNEL_DEBUG(channel, "The server doesn't support atomic press and release");
-        spice_inputs_key_press(input_channel, scancode);
-        spice_inputs_key_release(input_channel, scancode);
+        spice_inputs_key_press(input_channel, scancode, keyval);
+        spice_inputs_key_release(input_channel, scancode, keyval);
     }
+
 }
 
 /* main or coroutine context */
diff --git a/gtk/channel-inputs.h b/gtk/channel-inputs.h
index 3179a76..1a6bbc1 100644
--- a/gtk/channel-inputs.h
+++ b/gtk/channel-inputs.h
@@ -79,10 +79,10 @@ void spice_inputs_button_press(SpiceInputsChannel *channel, gint button,
                                gint button_state);
 void spice_inputs_button_release(SpiceInputsChannel *channel, gint button,
                                  gint button_state);
-void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode);
-void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode);
+void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode, guint keyval);
+void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode, guint keyval);
 void spice_inputs_set_key_locks(SpiceInputsChannel *channel, guint locks);
-void spice_inputs_key_press_and_release(SpiceInputsChannel *channel, guint scancode);
+void spice_inputs_key_press_and_release(SpiceInputsChannel *channel, guint scancode, guint keyval);
 
 G_END_DECLS
 
diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h
index 597ce10..6eb1c11 100644
--- a/gtk/spice-widget-priv.h
+++ b/gtk/spice-widget-priv.h
@@ -108,6 +108,7 @@ struct _SpiceDisplayPrivate {
     size_t                  keycode_maplen;
     uint32_t                key_state[512 / 32];
     int                     key_delayed_scancode;
+    uint32_t                key_delayed_keyval;
     guint                   key_delayed_id;
     SpiceGrabSequence         *grabseq; /* the configured key sequence */
     gboolean                *activeseq; /* the currently pressed keys */
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index d25edca..a739ba4 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -1153,8 +1153,9 @@ static void key_press_and_release(SpiceDisplay *display)
     if (d->key_delayed_scancode == 0)
         return;
 
-    spice_inputs_key_press_and_release(d->inputs, d->key_delayed_scancode);
+    spice_inputs_key_press_and_release(d->inputs, d->key_delayed_scancode, d->key_delayed_keyval);
     d->key_delayed_scancode = 0;
+    d->key_delayed_keyval = 0;
 
     if (d->key_delayed_id) {
         g_source_remove(d->key_delayed_id);
@@ -1169,8 +1170,9 @@ static gboolean key_press_delayed(gpointer data)
     if (d->key_delayed_scancode == 0)
         return FALSE;
 
-    spice_inputs_key_press(d->inputs, d->key_delayed_scancode);
+    spice_inputs_key_press(d->inputs, d->key_delayed_scancode, d->key_delayed_keyval);
     d->key_delayed_scancode = 0;
+    d->key_delayed_keyval = 0;
 
     if (d->key_delayed_id) {
         g_source_remove(d->key_delayed_id);
@@ -1180,7 +1182,7 @@ static gboolean key_press_delayed(gpointer data)
     return FALSE;
 }
 
-static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboolean press_delayed)
+static void send_key(SpiceDisplay *display, int scancode, guint keyval, SendKeyType type, gboolean press_delayed)
 {
     SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
     uint32_t i, b, m;
@@ -1209,8 +1211,9 @@ static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboo
             g_warn_if_fail(d->key_delayed_id == 0);
             d->key_delayed_id = g_timeout_add(d->keypress_delay, key_press_delayed, display);
             d->key_delayed_scancode = scancode;
+            d->key_delayed_keyval = keyval;
         } else
-            spice_inputs_key_press(d->inputs, scancode);
+            spice_inputs_key_press(d->inputs, scancode, keyval);
 
         d->key_state[i] |= m;
         break;
@@ -1224,7 +1227,7 @@ static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboo
         else {
             /* ensure delayed key is pressed before other key are released */
             key_press_delayed(display);
-            spice_inputs_key_release(d->inputs, scancode);
+            spice_inputs_key_release(d->inputs, scancode, keyval);
         }
 
         d->key_state[i] &= ~m;
@@ -1246,7 +1249,7 @@ static void release_keys(SpiceDisplay *display)
             continue;
         }
         for (b = 0; b < 32; b++) {
-            send_key(display, i * 32 + b, SEND_KEY_RELEASE, FALSE);
+            send_key(display, i * 32 + b, 0, SEND_KEY_RELEASE, FALSE);
         }
     }
 }
@@ -1337,10 +1340,10 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
 
     switch (key->type) {
     case GDK_KEY_PRESS:
-        send_key(display, scancode, SEND_KEY_PRESS, !key->is_modifier);
+        send_key(display, scancode, key->keyval, SEND_KEY_PRESS, !key->is_modifier);
         break;
     case GDK_KEY_RELEASE:
-        send_key(display, scancode, SEND_KEY_RELEASE, !key->is_modifier);
+        send_key(display, scancode, key->keyval, SEND_KEY_RELEASE, !key->is_modifier);
         break;
     default:
         g_warn_if_reached();
@@ -1393,12 +1396,13 @@ void spice_display_send_keys(SpiceDisplay *display, const guint *keyvals,
 
     if (kind & SPICE_DISPLAY_KEY_EVENT_PRESS) {
         for (i = 0 ; i < nkeyvals ; i++)
-            send_key(display, get_scancode_from_keyval(display, keyvals[i]), SEND_KEY_PRESS, FALSE);
+            send_key(display, get_scancode_from_keyval(display, keyvals[i]),
+                     keyvals[i], SEND_KEY_PRESS, FALSE);
     }
 
     if (kind & SPICE_DISPLAY_KEY_EVENT_RELEASE) {
         for (i = (nkeyvals-1) ; i >= 0 ; i--)
-            send_key(display, get_scancode_from_keyval(display, keyvals[i]), SEND_KEY_RELEASE, FALSE);
+            send_key(display, get_scancode_from_keyval(display, keyvals[i]), keyvals[i], SEND_KEY_RELEASE, FALSE);
     }
 }
 
-- 
1.7.10.4



More information about the Spice-devel mailing list