[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