[Spice-commits] 8 commits - gtk/channel-inputs.c gtk/channel-main.c gtk/channel-record.c gtk/channel-smartcard.c gtk/channel-usbredir.c gtk/Makefile.am gtk/map-file gtk/smartcard-manager.c gtk/spice-channel.c gtk/spice-channel-priv.h gtk/spice-gtk-session.c gtk/spice-gtk-session-priv.h gtk/spice-session.c gtk/spice-session.h gtk/spice-session-priv.h gtk/spice-util.c gtk/spice-util.h gtk/spice-util-priv.h gtk/spice-widget.c gtk/spice-widget-priv.h gtk/spicy.c
Marc-André Lureau
elmarco at kemper.freedesktop.org
Thu Nov 24 04:29:35 PST 2011
gtk/Makefile.am | 6 +-
gtk/channel-inputs.c | 22 +++++++-
gtk/channel-main.c | 5 +
gtk/channel-record.c | 5 +
gtk/channel-smartcard.c | 3 +
gtk/channel-usbredir.c | 3 +
gtk/map-file | 24 ++++----
gtk/smartcard-manager.c | 2
gtk/spice-channel-priv.h | 2
gtk/spice-channel.c | 41 ++++++++++++++-
gtk/spice-gtk-session-priv.h | 1
gtk/spice-gtk-session.c | 17 +++++-
gtk/spice-session-priv.h | 1
gtk/spice-session.c | 37 +++++++++++++
gtk/spice-session.h | 1
gtk/spice-util-priv.h | 5 -
gtk/spice-util.c | 14 ++++-
gtk/spice-util.h | 5 +
gtk/spice-widget-priv.h | 1
gtk/spice-widget.c | 117 +++++++++++++++++++++++++++++++------------
gtk/spicy.c | 6 ++
21 files changed, 261 insertions(+), 57 deletions(-)
New commits:
commit b6b41fdbc37d5a83d4f89922933ae56dd867e890
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 23 01:41:57 2011 +0100
Do not send specific messages in read-only
diff --git a/gtk/channel-inputs.c b/gtk/channel-inputs.c
index f6c4a3e..bacbba3 100644
--- a/gtk/channel-inputs.c
+++ b/gtk/channel-inputs.c
@@ -215,6 +215,9 @@ static void send_position(SpiceInputsChannel *channel)
{
SpiceMsgOut *msg;
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
msg = mouse_position(channel);
if (!msg) /* if no motion */
return;
@@ -228,6 +231,9 @@ static void send_motion(SpiceInputsChannel *channel)
{
SpiceMsgOut *msg;
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
msg = mouse_motion(channel);
if (!msg) /* if no motion */
return;
@@ -382,6 +388,8 @@ void spice_inputs_button_press(SpiceInputsChannel *channel, gint button,
if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
return;
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
c = channel->priv;
switch (button) {
@@ -428,6 +436,8 @@ void spice_inputs_button_release(SpiceInputsChannel *channel, gint button,
if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
return;
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
c = channel->priv;
switch (button) {
@@ -442,7 +452,7 @@ void spice_inputs_button_release(SpiceInputsChannel *channel, gint button,
break;
}
- c->bs = button_state;
+ c->bs = button_state;
send_motion(channel);
send_position(channel);
@@ -471,6 +481,8 @@ void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode)
g_return_if_fail(SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_UNCONNECTED);
if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
return;
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
SPICE_DEBUG("%s: scancode %d", __FUNCTION__, scancode);
if (scancode < 0x100) {
@@ -502,6 +514,8 @@ void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode)
g_return_if_fail(SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_UNCONNECTED);
if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
return;
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
SPICE_DEBUG("%s: scancode %d", __FUNCTION__, scancode);
if (scancode < 0x100) {
@@ -552,6 +566,9 @@ void spice_inputs_set_key_locks(SpiceInputsChannel *channel, guint locks)
{
SpiceMsgOut *msg;
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
msg = set_key_locks(channel, locks);
if (!msg) /* you can set_key_locks() even if the channel is not ready */
return;
@@ -566,6 +583,9 @@ static void spice_inputs_channel_up(SpiceChannel *channel)
SpiceInputsChannelPrivate *c = SPICE_INPUTS_CHANNEL(channel)->priv;
SpiceMsgOut *msg;
+ if (spice_channel_get_read_only(channel))
+ return;
+
msg = set_key_locks(SPICE_INPUTS_CHANNEL(channel), c->locks);
spice_msg_out_send_internal(msg);
spice_msg_out_unref(msg);
diff --git a/gtk/channel-main.c b/gtk/channel-main.c
index 90eb0fd..b2d44b6 100644
--- a/gtk/channel-main.c
+++ b/gtk/channel-main.c
@@ -1054,11 +1054,14 @@ static void set_mouse_mode(SpiceMainChannel *channel, uint32_t supported, uint32
}
/* switch to client mode if possible */
- if ((supported & SPICE_MOUSE_MODE_CLIENT) && (current != SPICE_MOUSE_MODE_CLIENT)) {
+ if (!spice_channel_get_read_only(SPICE_CHANNEL(channel)) &&
+ supported & SPICE_MOUSE_MODE_CLIENT &&
+ current != SPICE_MOUSE_MODE_CLIENT) {
SpiceMsgcMainMouseModeRequest req = {
.mode = SPICE_MOUSE_MODE_CLIENT,
};
SpiceMsgOut *out;
+
out = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST);
out->marshallers->msgc_main_mouse_mode_request(out->marshaller, &req);
spice_msg_out_send_internal(out);
diff --git a/gtk/channel-record.c b/gtk/channel-record.c
index 443337c..bb66c3b 100644
--- a/gtk/channel-record.c
+++ b/gtk/channel-record.c
@@ -277,6 +277,8 @@ static void spice_record_mode(SpiceRecordChannel *channel, uint32_t time,
SpiceMsgOut *msg;
g_return_if_fail(channel != NULL);
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
m.mode = mode;
m.time = time;
@@ -309,6 +311,8 @@ static void spice_record_start_mark(SpiceRecordChannel *channel, uint32_t time)
SpiceMsgOut *msg;
g_return_if_fail(channel != NULL);
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
m.time = time;
@@ -336,6 +340,7 @@ void spice_record_send_data(SpiceRecordChannel *channel, gpointer data,
uint8_t *celt_buf = NULL;
g_return_if_fail(channel != NULL);
+ g_return_if_fail(spice_channel_get_read_only(SPICE_CHANNEL(channel)) == FALSE);
rc = channel->priv;
diff --git a/gtk/channel-smartcard.c b/gtk/channel-smartcard.c
index 5fec217..c5aa17b 100644
--- a/gtk/channel-smartcard.c
+++ b/gtk/channel-smartcard.c
@@ -281,6 +281,9 @@ static void smartcard_message_send(SpiceSmartcardChannel *channel,
{
SpiceSmartcardChannelMessage *message;
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
SPICE_DEBUG("smartcard: send message %d, %s",
msg_type, queue ? "queued" : "now");
if (!queue) {
diff --git a/gtk/channel-usbredir.c b/gtk/channel-usbredir.c
index 9479b6b..00647b6 100644
--- a/gtk/channel-usbredir.c
+++ b/gtk/channel-usbredir.c
@@ -350,6 +350,9 @@ void spice_usbredir_channel_do_write(SpiceUsbredirChannel *channel)
{
SpiceUsbredirChannelPrivate *priv = channel->priv;
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
/* No recursion allowed! */
g_return_if_fail(priv->msg_out == NULL);
diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h
index df661f8..83e7e25 100644
--- a/gtk/spice-channel-priv.h
+++ b/gtk/spice-channel-priv.h
@@ -167,6 +167,7 @@ gint spice_channel_get_channel_id(SpiceChannel *channel);
gint spice_channel_get_channel_type(SpiceChannel *channel);
void spice_channel_swap(SpiceChannel *channel, SpiceChannel *swap);
void spice_channel_set_common_capability(SpiceChannel *channel, guint32 cap);
+gboolean spice_channel_get_read_only(SpiceChannel *channel);
/* coroutine context */
#define emit_main_context(object, event, args...) \
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index c2133ab..c9af0ba 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -1561,6 +1561,12 @@ void spice_channel_wakeup(SpiceChannel *channel)
g_io_wakeup(&c->wait);
}
+G_GNUC_INTERNAL
+gboolean spice_channel_get_read_only(SpiceChannel *channel)
+{
+ return spice_session_get_read_only(channel->priv->session);
+}
+
/* coroutine context if @buffered is FALSE,
system context if @buffered is TRUE */
static void spice_channel_send_msg(SpiceChannel *channel, SpiceMsgOut *out, gboolean buffered)
@@ -1573,7 +1579,7 @@ static void spice_channel_send_msg(SpiceChannel *channel, SpiceMsgOut *out, gboo
g_return_if_fail(out != NULL);
if (out->ro_check &&
- spice_session_get_read_only(channel->priv->session)) {
+ spice_channel_get_read_only(channel)) {
g_warning("Try to send message while read-only. Please report a bug.");
return;
}
commit 1711687df25b02074097d8308b801bb35fd8dafd
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 23 00:32:36 2011 +0100
Check if msg are permitted to be sent in read-only
diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h
index 86b22e1..df661f8 100644
--- a/gtk/spice-channel-priv.h
+++ b/gtk/spice-channel-priv.h
@@ -46,6 +46,7 @@ struct _SpiceMsgOut {
SpiceMessageMarshallers *marshallers;
SpiceMarshaller *marshaller;
SpiceDataHeader *header;
+ gboolean ro_check;
};
struct _SpiceMsgIn {
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index 99af206..c2133ab 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -465,6 +465,30 @@ void spice_msg_out_hexdump(SpiceMsgOut *out, unsigned char *data, int len)
hexdump(">> msg", data, len);
}
+static gboolean msg_check_read_only (int channel_type, int msg_type)
+{
+ if (msg_type < 100) // those are the common messages
+ return FALSE;
+
+ switch (channel_type) {
+ /* messages allowed to be sent in read-only mode */
+ case SPICE_CHANNEL_MAIN:
+ switch (msg_type) {
+ case SPICE_MSGC_MAIN_CLIENT_INFO:
+ case SPICE_MSGC_MAIN_MIGRATE_CONNECTED:
+ case SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR:
+ case SPICE_MSGC_MAIN_ATTACH_CHANNELS:
+ case SPICE_MSGC_MAIN_MIGRATE_END:
+ return FALSE;
+ }
+ break;
+ case SPICE_CHANNEL_DISPLAY:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
G_GNUC_INTERNAL
SpiceMsgOut *spice_msg_out_new(SpiceChannel *channel, int type)
{
@@ -476,6 +500,7 @@ SpiceMsgOut *spice_msg_out_new(SpiceChannel *channel, int type)
out = spice_new0(SpiceMsgOut, 1);
out->refcount = 1;
out->channel = channel;
+ out->ro_check = msg_check_read_only(c->channel_type, type);
out->marshallers = c->marshallers;
out->marshaller = spice_marshaller_new();
@@ -1547,6 +1572,12 @@ static void spice_channel_send_msg(SpiceChannel *channel, SpiceMsgOut *out, gboo
g_return_if_fail(channel != NULL);
g_return_if_fail(out != NULL);
+ if (out->ro_check &&
+ spice_session_get_read_only(channel->priv->session)) {
+ g_warning("Try to send message while read-only. Please report a bug.");
+ return;
+ }
+
data = spice_marshaller_linearize(out->marshaller, 0,
&len, &free_data);
/* spice_msg_out_hexdump(out, data, len); */
@@ -1554,9 +1585,9 @@ static void spice_channel_send_msg(SpiceChannel *channel, SpiceMsgOut *out, gboo
spice_channel_buffered_write(channel, data, len);
else
spice_channel_write(channel, data, len);
- if (free_data) {
+
+ if (free_data)
free(data);
- }
}
/* coroutine context */
commit 222e25a02928172fa4620e94c84ba9e01b06bfbd
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Tue Nov 22 20:55:38 2011 +0100
Add read-only property on sessions
It is useful to have a way to prevent sending commands in read-only
sessions (think of multi-client)
No clipboard sharing allowed in this case in gtk-session.
diff --git a/gtk/map-file b/gtk/map-file
index 1d7a934..4b470bb 100644
--- a/gtk/map-file
+++ b/gtk/map-file
@@ -67,6 +67,7 @@ spice_record_send_data;
spice_session_connect;
spice_session_disconnect;
spice_session_get_channels;
+spice_session_get_read_only;
spice_session_get_type;
spice_session_has_channel_type;
spice_session_migration_get_type;
diff --git a/gtk/spice-gtk-session-priv.h b/gtk/spice-gtk-session-priv.h
index 19692af..21a4251 100644
--- a/gtk/spice-gtk-session-priv.h
+++ b/gtk/spice-gtk-session-priv.h
@@ -24,6 +24,7 @@ G_BEGIN_DECLS
void spice_gtk_session_update_keyboard_focus(SpiceGtkSession *self,
gboolean state);
+gboolean spice_gtk_session_get_read_only(SpiceGtkSession *self);
G_END_DECLS
diff --git a/gtk/spice-gtk-session.c b/gtk/spice-gtk-session.c
index 116eead..afabe8e 100644
--- a/gtk/spice-gtk-session.c
+++ b/gtk/spice-gtk-session.c
@@ -77,6 +77,7 @@ static void channel_new(SpiceSession *session, SpiceChannel *channel,
gpointer user_data);
static void channel_destroy(SpiceSession *session, SpiceChannel *channel,
gpointer user_data);
+static gboolean read_only(SpiceGtkSession *self);
/* ------------------------------------------------------------------ */
/* gobject glue */
@@ -477,7 +478,7 @@ static void clipboard_owner_change(GtkClipboard *clipboard,
}
s->clipboard_by_guest[selection] = FALSE;
s->clip_hasdata[selection] = TRUE;
- if (s->auto_clipboard_enable)
+ if (s->auto_clipboard_enable && !read_only(self))
gtk_clipboard_request_targets(clipboard, clipboard_get_targets,
self);
break;
@@ -620,7 +621,9 @@ static gboolean clipboard_grab(SpiceMainChannel *main, guint selection,
/* Receiving a grab implies we've released our own grab */
s->clip_grabbed[selection] = FALSE;
- if (!s->auto_clipboard_enable || s->nclip_targets[selection] == 0)
+ if (read_only(self) ||
+ !s->auto_clipboard_enable ||
+ s->nclip_targets[selection] == 0)
goto skip_grab_clipboard;
if (!gtk_clipboard_set_with_data(cb, targets, i, clipboard_get,
@@ -692,6 +695,9 @@ static gboolean clipboard_request(SpiceMainChannel *main, guint selection,
GtkClipboard* cb;
int m;
+ if (read_only(self))
+ return FALSE;
+
cb = get_clipboard_from_selection(s, selection);
g_return_val_if_fail(cb != NULL, FALSE);
@@ -771,6 +777,11 @@ static void channel_destroy(SpiceSession *session, SpiceChannel *channel,
}
}
+static gboolean read_only(SpiceGtkSession *self)
+{
+ return spice_session_get_read_only(self->priv->session);
+}
+
/* ---------------------------------------------------------------- */
/* private functions (usbredir related) */
G_GNUC_INTERNAL
@@ -841,6 +852,7 @@ SpiceGtkSession *spice_gtk_session_get(SpiceSession *session)
void spice_gtk_session_copy_to_guest(SpiceGtkSession *self)
{
g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+ g_return_if_fail(read_only(self) == FALSE);
SpiceGtkSessionPrivate *s = self->priv;
int selection = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
@@ -862,6 +874,7 @@ void spice_gtk_session_copy_to_guest(SpiceGtkSession *self)
void spice_gtk_session_paste_from_guest(SpiceGtkSession *self)
{
g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+ g_return_if_fail(read_only(self) == FALSE);
SpiceGtkSessionPrivate *s = self->priv;
int selection = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index 963735b..0851c39 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -37,6 +37,7 @@ struct _SpiceSessionPrivate {
GByteArray *pubkey;
char *cert_subject;
guint verify;
+ gboolean read_only;
/* whether to enable audio */
gboolean audio;
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 3366b58..4405fd2 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -99,6 +99,7 @@ enum {
PROP_INHIBIT_KEYBOARD_GRAB,
PROP_DISABLE_EFFECTS,
PROP_COLOR_DEPTH,
+ PROP_READ_ONLY,
};
/* signals */
@@ -373,6 +374,9 @@ static void spice_session_get_property(GObject *gobject,
case PROP_AUDIO:
g_value_set_boolean(value, s->audio);
break;
+ case PROP_READ_ONLY:
+ g_value_set_boolean(value, s->read_only);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
break;
@@ -469,6 +473,10 @@ static void spice_session_set_property(GObject *gobject,
case PROP_AUDIO:
s->audio = g_value_get_boolean(value);
break;
+ case PROP_READ_ONLY:
+ s->read_only = g_value_get_boolean(value);
+ g_object_notify(gobject, "read-only");
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
break;
@@ -858,6 +866,22 @@ static void spice_session_class_init(SpiceSessionClass *klass)
1,
SPICE_TYPE_CHANNEL);
+ /**
+ * SpiceSession:read-only:
+ *
+ * Whether this connection is read-only mode.
+ *
+ * Since: 0.8
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_READ_ONLY,
+ g_param_spec_boolean("read-only", "Read-only",
+ "Whether this connection is read-only mode",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
g_type_class_add_private(klass, sizeof(SpiceSessionPrivate));
}
@@ -1123,6 +1147,19 @@ void spice_session_channel_migrate(SpiceSession *session, SpiceChannel *channel)
}
/**
+ * spice_session_get_read_only:
+ * @session: a #SpiceSession
+ *
+ * Returns: wether the @session is in read-only mode.
+ **/
+gboolean spice_session_get_read_only(SpiceSession *self)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(self), FALSE);
+
+ return self->priv->read_only;
+}
+
+/**
* spice_session_disconnect:
* @session:
*
diff --git a/gtk/spice-session.h b/gtk/spice-session.h
index 72effce..4895288 100644
--- a/gtk/spice-session.h
+++ b/gtk/spice-session.h
@@ -93,6 +93,7 @@ gboolean spice_session_open_fd(SpiceSession *session, int fd);
void spice_session_disconnect(SpiceSession *session);
GList *spice_session_get_channels(SpiceSession *session);
gboolean spice_session_has_channel_type(SpiceSession *session, gint type);
+gboolean spice_session_get_read_only(SpiceSession *session);
G_END_DECLS
commit 1de356faf5797e8098cb4cac1894122485d3c426
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 23 02:28:25 2011 +0100
Add disable-inputs on Spice widget
diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h
index a86168d..bd5eec6 100644
--- a/gtk/spice-widget-priv.h
+++ b/gtk/spice-widget-priv.h
@@ -62,6 +62,7 @@ struct _SpiceDisplayPrivate {
bool convert;
bool have_mitshm;
gboolean allow_scaling;
+ gboolean disable_inputs;
/* TODO: make a display object instead? */
#ifdef WITH_X11
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index 0edc70f..816a3e2 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -86,6 +86,7 @@ enum {
PROP_RESIZE_GUEST,
PROP_AUTO_CLIPBOARD,
PROP_SCALING,
+ PROP_DISABLE_INPUTS,
};
/* Signals */
@@ -102,8 +103,10 @@ static guint signals[SPICE_DISPLAY_LAST_SIGNAL];
static HWND focus_window = NULL;
#endif
+static void update_keyboard_grab(SpiceDisplay *display);
static void try_keyboard_grab(SpiceDisplay *display);
static void try_keyboard_ungrab(SpiceDisplay *display);
+static void update_mouse_grab(SpiceDisplay *display);
static void try_mouse_grab(SpiceDisplay *display);
static void try_mouse_ungrab(SpiceDisplay *display);
static void recalc_geometry(GtkWidget *widget, gboolean set_display);
@@ -148,6 +151,9 @@ static void spice_display_get_property(GObject *object,
case PROP_SCALING:
g_value_set_boolean(value, d->allow_scaling);
break;
+ case PROP_DISABLE_INPUTS:
+ g_value_set_boolean(value, d->disable_inputs);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -172,17 +178,11 @@ static void spice_display_set_property(GObject *object,
break;
case PROP_KEYBOARD_GRAB:
d->keyboard_grab_enable = g_value_get_boolean(value);
- if (d->keyboard_grab_enable) {
- try_keyboard_grab(display);
- } else {
- try_keyboard_ungrab(display);
- }
+ update_keyboard_grab(display);
break;
case PROP_MOUSE_GRAB:
d->mouse_grab_enable = g_value_get_boolean(value);
- if (!d->mouse_grab_enable) {
- try_mouse_ungrab(display);
- }
+ update_mouse_grab(display);
break;
case PROP_RESIZE_GUEST:
d->resize_guest_enable = g_value_get_boolean(value);
@@ -207,6 +207,12 @@ static void spice_display_set_property(GObject *object,
g_object_set(d->gtk_session, "auto-clipboard",
g_value_get_boolean(value), NULL);
break;
+ case PROP_DISABLE_INPUTS:
+ d->disable_inputs = g_value_get_boolean(value);
+ gtk_widget_set_can_focus(GTK_WIDGET(display), !d->disable_inputs);
+ update_keyboard_grab(display);
+ update_mouse_grab(display);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -231,11 +237,7 @@ static void session_inhibit_keyboard_grab_changed(GObject *gobject,
g_object_get(d->session, "inhibit-keyboard-grab",
&d->keyboard_grab_inhibit, NULL);
- if (d->keyboard_grab_inhibit) {
- try_keyboard_ungrab(display);
- } else {
- try_keyboard_grab(display);
- }
+ update_keyboard_grab(display);
}
static void spice_display_dispose(GObject *obj)
@@ -430,14 +432,15 @@ static void try_keyboard_grab(SpiceDisplay *display)
if (g_getenv("SPICE_NOGRAB"))
return;
-
- if (d->keyboard_grab_active)
+ if (d->disable_inputs)
return;
if (d->keyboard_grab_inhibit)
return;
if (!d->keyboard_grab_enable)
return;
+ if (d->keyboard_grab_active)
+ return;
if (!d->keyboard_have_focus)
return;
if (!d->mouse_have_pointer)
@@ -463,7 +466,6 @@ static void try_keyboard_grab(SpiceDisplay *display)
}
}
-
static void try_keyboard_ungrab(SpiceDisplay *display)
{
SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
@@ -482,6 +484,18 @@ static void try_keyboard_ungrab(SpiceDisplay *display)
g_signal_emit(widget, signals[SPICE_DISPLAY_KEYBOARD_GRAB], 0, false);
}
+static void update_keyboard_grab(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+
+ if (d->keyboard_grab_enable &&
+ !d->keyboard_grab_inhibit &&
+ !d->disable_inputs)
+ try_keyboard_grab(display);
+ else
+ try_keyboard_ungrab(display);
+}
+
static GdkGrabStatus do_pointer_grab(SpiceDisplay *display)
{
SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
@@ -553,6 +567,8 @@ static void try_mouse_grab(SpiceDisplay *display)
if (g_getenv("SPICE_NOGRAB"))
return;
+ if (d->disable_inputs)
+ return;
if (!d->mouse_grab_enable)
return;
@@ -614,6 +630,16 @@ static void try_mouse_ungrab(SpiceDisplay *display)
g_signal_emit(display, signals[SPICE_DISPLAY_MOUSE_GRAB], 0, false);
}
+static void update_mouse_grab(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+
+ if (d->mouse_grab_enable && !d->disable_inputs)
+ update_mouse_pointer(display);
+ else
+ try_mouse_ungrab(display);
+}
+
static void recalc_geometry(GtkWidget *widget, gboolean set_display)
{
SpiceDisplay *display = SPICE_DISPLAY(widget);
@@ -746,6 +772,9 @@ static void send_key(SpiceDisplay *display, int scancode, int down)
if (!d->inputs)
return;
+ if (d->disable_inputs)
+ return;
+
i = scancode / 32;
b = scancode % 32;
m = (1 << b);
@@ -991,6 +1020,8 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
if (!d->inputs)
return true;
+ if (d->disable_inputs)
+ return true;
gdk_drawable_get_size(gtk_widget_get_window(widget), &ww, &wh);
if (spicex_is_scaled(display)) {
@@ -1051,6 +1082,8 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *scroll)
if (!d->inputs)
return true;
+ if (d->disable_inputs)
+ return true;
if (scroll->direction == GDK_SCROLL_UP)
button = SPICE_MOUSE_BUTTON_UP;
@@ -1077,6 +1110,9 @@ static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
button->type == GDK_BUTTON_PRESS ? "press" : "release",
button->button, button->state);
+ if (d->disable_inputs)
+ return true;
+
if (!spicex_is_scaled(display)) {
gint x, y;
@@ -1248,6 +1284,23 @@ static void spice_display_class_init(SpiceDisplayClass *klass)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceDisplay:disable-inputs:
+ *
+ * Disable all keyboard & mouse inputs.
+ *
+ * Since: 0.8
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_DISABLE_INPUTS,
+ g_param_spec_boolean("disable-inputs", "Disable inputs",
+ "Whether inputs should be disabled",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
/**
* SpiceDisplay::mouse-grab:
* @display: the #SpiceDisplay that emitted the signal
@@ -1774,6 +1827,9 @@ static void sync_keyboard_lock_modifiers(SpiceDisplay *display)
guint32 modifiers;
GdkWindow *w;
+ if (d->disable_inputs)
+ return;
+
w = gtk_widget_get_parent_window(GTK_WIDGET(display));
if (w == NULL) /* it can happen if the display is not yet shown */
return;
diff --git a/gtk/spicy.c b/gtk/spicy.c
index 6c05b1e..427b8d1 100644
--- a/gtk/spicy.c
+++ b/gtk/spicy.c
@@ -721,6 +721,7 @@ static const char *spice_display_properties[] = {
"grab-mouse",
"resize-guest",
"scaling",
+ "disable-inputs",
};
static const char *spice_gtk_session_properties[] = {
@@ -748,6 +749,10 @@ static const GtkToggleActionEntry tentries[] = {
.label = N_("Scale display"),
.callback = G_CALLBACK(menu_cb_bool_prop),
},{
+ .name = "disable-inputs",
+ .label = N_("Disable inputs"),
+ .callback = G_CALLBACK(menu_cb_bool_prop),
+ },{
.name = "auto-clipboard",
.label = N_("Automagic clipboard sharing between host and guest"),
.callback = G_CALLBACK(menu_cb_bool_prop),
@@ -798,6 +803,7 @@ static char ui_xml[] =
" <menuitem action='grab-mouse'/>\n"
" <menuitem action='resize-guest'/>\n"
" <menuitem action='scaling'/>\n"
+" <menuitem action='disable-inputs'/>\n"
" <menuitem action='auto-clipboard'/>\n"
#ifdef USE_USBREDIR
" <menuitem action='auto-usbredir'/>\n"
commit 92722df56cd9fb52a0fcdd0ddac4a3676eb8de32
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 23 16:23:03 2011 +0100
cleanup: the try_grab() functions should take a SpiceDisplay
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index f095130..0edc70f 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -104,8 +104,8 @@ static HWND focus_window = NULL;
static void try_keyboard_grab(SpiceDisplay *display);
static void try_keyboard_ungrab(SpiceDisplay *display);
-static void try_mouse_grab(GtkWidget *widget);
-static void try_mouse_ungrab(GtkWidget *widget);
+static void try_mouse_grab(SpiceDisplay *display);
+static void try_mouse_ungrab(SpiceDisplay *display);
static void recalc_geometry(GtkWidget *widget, gboolean set_display);
static void disconnect_main(SpiceDisplay *display);
static void disconnect_cursor(SpiceDisplay *display);
@@ -181,7 +181,7 @@ static void spice_display_set_property(GObject *object,
case PROP_MOUSE_GRAB:
d->mouse_grab_enable = g_value_get_boolean(value);
if (!d->mouse_grab_enable) {
- try_mouse_ungrab(GTK_WIDGET(display));
+ try_mouse_ungrab(display);
}
break;
case PROP_RESIZE_GUEST:
@@ -343,8 +343,8 @@ spice_display_constructor(GType gtype,
}
g_list_free(list);
- g_signal_connect(d->gtk_session, "notify::auto-clipboard",
- G_CALLBACK(gtk_session_property_changed), display);
+ spice_g_signal_connect_object(d->gtk_session, "notify::auto-clipboard",
+ G_CALLBACK(gtk_session_property_changed), display, 0);
g_signal_connect(d->session, "notify::inhibit-keyboard-grab",
G_CALLBACK(session_inhibit_keyboard_grab_changed),
@@ -536,8 +536,9 @@ static void update_mouse_pointer(SpiceDisplay *display)
if (!d->mouse_grab_active) {
gdk_window_set_cursor(window, NULL);
} else {
+ // FIXME: should it be transparent instead?
gdk_window_set_cursor(window, d->mouse_cursor);
- try_mouse_grab(GTK_WIDGET(display));
+ try_mouse_grab(display);
}
break;
default:
@@ -546,9 +547,8 @@ static void update_mouse_pointer(SpiceDisplay *display)
}
}
-static void try_mouse_grab(GtkWidget *widget)
+static void try_mouse_grab(SpiceDisplay *display)
{
- SpiceDisplay *display = SPICE_DISPLAY(widget);
SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
if (g_getenv("SPICE_NOGRAB"))
@@ -601,9 +601,8 @@ static void mouse_check_edges(GtkWidget *widget, GdkEventMotion *motion)
}
}
-static void try_mouse_ungrab(GtkWidget *widget)
+static void try_mouse_ungrab(SpiceDisplay *display)
{
- SpiceDisplay *display = SPICE_DISPLAY(widget);
SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
if (!d->mouse_grab_active)
@@ -612,7 +611,7 @@ static void try_mouse_ungrab(GtkWidget *widget)
gdk_pointer_ungrab(GDK_CURRENT_TIME);
d->mouse_grab_active = false;
update_mouse_pointer(display);
- g_signal_emit(widget, signals[SPICE_DISPLAY_MOUSE_GRAB], 0, false);
+ g_signal_emit(display, signals[SPICE_DISPLAY_MOUSE_GRAB], 0, false);
}
static void recalc_geometry(GtkWidget *widget, gboolean set_display)
@@ -836,11 +835,11 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
if (check_for_grab_key(display, key->type, key->keyval)) {
g_signal_emit(widget, signals[SPICE_DISPLAY_GRAB_KEY_PRESSED], 0);
if (d->mouse_grab_active)
- try_mouse_ungrab(widget);
+ try_mouse_ungrab(display);
else
/* TODO: gtk-vnc has a weird condition here
if (!d->grab_keyboard || !d->absolute) */
- try_mouse_grab(widget);
+ try_mouse_grab(display);
}
@@ -1091,7 +1090,7 @@ static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
gtk_widget_grab_focus(widget);
if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER)
- try_mouse_grab(widget);
+ try_mouse_grab(display);
else /* allow to drag and drop between windows/displays:
FIXME: should be multiple widget grab, but how?
or should now the position of the other widgets?..
@@ -1317,7 +1316,7 @@ static void mouse_update(SpiceChannel *channel, gpointer data)
d->mouse_guest_x = -1;
d->mouse_guest_y = -1;
if (d->mouse_mode == SPICE_MOUSE_MODE_CLIENT) {
- try_mouse_ungrab(GTK_WIDGET(display));
+ try_mouse_ungrab(display);
}
update_mouse_pointer(display);
}
@@ -1668,7 +1667,7 @@ SpiceDisplay *spice_display_new(SpiceSession *session, int id)
**/
void spice_display_mouse_ungrab(SpiceDisplay *display)
{
- try_mouse_ungrab(GTK_WIDGET(display));
+ try_mouse_ungrab(display);
}
/**
commit ac2b9e1e39e0f459c61a6762b3154cb3ffd9d2ff
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Tue Nov 22 22:22:24 2011 +0100
Fix a few g-ir-scanner warnings
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 8a353dc..ebf908d 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -590,6 +590,7 @@ glib_introspection_files = \
spice-channel.c \
spice-glib-enums.c \
spice-option.c \
+ spice-util.c \
channel-cursor.c \
channel-display.c \
channel-inputs.c \
@@ -598,6 +599,7 @@ glib_introspection_files = \
channel-record.c \
channel-smartcard.c \
channel-usbredir.c \
+ smartcard-manager.c \
usb-device-manager.c \
$(NULL)
diff --git a/gtk/smartcard-manager.c b/gtk/smartcard-manager.c
index df29088..d814ac3 100644
--- a/gtk/smartcard-manager.c
+++ b/gtk/smartcard-manager.c
@@ -246,7 +246,7 @@ static SpiceSmartcardManager *spice_smartcard_manager_new(void)
* to it. A new SpiceSmartcardManager instance will be created the first
* time this function is called
*
- * Returns: a pointer to the #SpiceSmartcardManager singleton
+ * Returns: (transfer none): a weak reference to the #SpiceSmartcardManager
*/
SpiceSmartcardManager *spice_smartcard_manager_get(void)
{
diff --git a/gtk/spice-util.c b/gtk/spice-util.c
index b634bf3..f2f30e8 100644
--- a/gtk/spice-util.c
+++ b/gtk/spice-util.c
@@ -148,6 +148,19 @@ closure_invalidated_cb (gpointer ctx_,
}
/* Copied from tp_g_signal_connect_object. See documentation. */
+/**
+ * spice_g_signal_connect_object: (skip)
+ * @instance: the instance to connect to.
+ * @detailed_signal: a string of the form "signal-name::detail".
+ * @c_handler: the #GCallback to connect.
+ * @gobject: the object to pass as data to @c_handler.
+ * @connect_flags: a combination of #GConnectFlags.
+ *
+ * Similar to g_signal_connect_object() but will delete connection
+ * when any of the objects is destroyed.
+ *
+ * Returns: the handler id.
+ */
gulong spice_g_signal_connect_object (gpointer instance,
const gchar *detailed_signal,
GCallback c_handler,
commit ff98834d9af6913ce1de3b6a317c614f3e1799e4
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Tue Nov 22 20:50:54 2011 +0100
Export spice_g_signal_connect_object
The helper needs to be accessible from spice-client-gtk too.
diff --git a/gtk/map-file b/gtk/map-file
index f3a6e22..1d7a934 100644
--- a/gtk/map-file
+++ b/gtk/map-file
@@ -34,6 +34,7 @@ spice_grab_sequence_free;
spice_grab_sequence_get_type;
spice_grab_sequence_new;
spice_grab_sequence_new_from_string;
+spice_g_signal_connect_object;
spice_gtk_session_copy_to_guest;
spice_gtk_session_get;
spice_gtk_session_get_type;
diff --git a/gtk/spice-util-priv.h b/gtk/spice-util-priv.h
index 1f9778c..90b437c 100644
--- a/gtk/spice-util-priv.h
+++ b/gtk/spice-util-priv.h
@@ -23,11 +23,6 @@
G_BEGIN_DECLS
gboolean spice_strv_contains(const GStrv strv, const gchar *str);
-gulong spice_g_signal_connect_object(gpointer instance,
- const gchar *detailed_signal,
- GCallback c_handler,
- gpointer gobject,
- GConnectFlags connect_flags);
G_END_DECLS
diff --git a/gtk/spice-util.c b/gtk/spice-util.c
index fb5767b..b634bf3 100644
--- a/gtk/spice-util.c
+++ b/gtk/spice-util.c
@@ -148,7 +148,6 @@ closure_invalidated_cb (gpointer ctx_,
}
/* Copied from tp_g_signal_connect_object. See documentation. */
-G_GNUC_INTERNAL
gulong spice_g_signal_connect_object (gpointer instance,
const gchar *detailed_signal,
GCallback c_handler,
diff --git a/gtk/spice-util.h b/gtk/spice-util.h
index a052ca8..5029bc1 100644
--- a/gtk/spice-util.h
+++ b/gtk/spice-util.h
@@ -25,6 +25,11 @@ G_BEGIN_DECLS
void spice_util_set_debug(gboolean enabled);
gboolean spice_util_get_debug(void);
const gchar *spice_util_get_version_string(void);
+gulong spice_g_signal_connect_object(gpointer instance,
+ const gchar *detailed_signal,
+ GCallback c_handler,
+ gpointer gobject,
+ GConnectFlags connect_flags);
#define SPICE_DEBUG(fmt, ...) \
do { \
commit e6feb40fc7f37e4d29d9e564ad75c0cf7502bcc4
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Tue Nov 22 20:48:07 2011 +0100
Regenerate map-file correctly
We should use update-map-file instead of modifying it manually
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 5dfa9f3..8a353dc 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -232,7 +232,6 @@ libspice_client_glib_2_0_la_SOURCES = \
channel-usbredir.c \
channel-usbredir-priv.h \
smartcard-manager.c \
- smartcard-manager.h \
smartcard-manager-priv.h \
usb-device-manager.c \
$(GUSB_SRCS) \
@@ -295,6 +294,7 @@ libspice_client_glibinclude_HEADERS = \
channel-smartcard.h \
channel-usbredir.h \
usb-device-manager.h \
+ smartcard-manager.h \
$(NULL)
nodist_libspice_client_glibinclude_HEADERS = \
@@ -577,7 +577,7 @@ PREFIX_ARGS = --strip-prefix=Spice
endif
INTROSPECTION_GIRS =
-INTROSPECTION_SCANNER_ARGS = --warn-all --add-include-path=$(builddir) $(PREFIX_ARGS)
+INTROSPECTION_SCANNER_ARGS = --warn-all --accept-unprefixed --add-include-path=$(builddir) $(PREFIX_ARGS)
INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir)
if HAVE_INTROSPECTION
diff --git a/gtk/map-file b/gtk/map-file
index b6b84f1..f3a6e22 100644
--- a/gtk/map-file
+++ b/gtk/map-file
@@ -1,8 +1,8 @@
SPICEGTK_1 {
global:
+spice_audio_get;
spice_audio_get_type;
spice_audio_new;
-spice_audio_get;
spice_channel_connect;
spice_channel_destroy;
spice_channel_disconnect;
@@ -34,6 +34,10 @@ spice_grab_sequence_free;
spice_grab_sequence_get_type;
spice_grab_sequence_new;
spice_grab_sequence_new_from_string;
+spice_gtk_session_copy_to_guest;
+spice_gtk_session_get;
+spice_gtk_session_get_type;
+spice_gtk_session_paste_from_guest;
spice_inputs_button_press;
spice_inputs_button_release;
spice_inputs_channel_get_type;
@@ -68,10 +72,6 @@ spice_session_migration_get_type;
spice_session_new;
spice_session_open_fd;
spice_session_verify_get_type;
-spice_gtk_session_get;
-spice_gtk_session_get_type;
-spice_gtk_session_copy_to_guest;
-spice_gtk_session_paste_from_guest;
spice_set_session_option;
spice_smartcard_channel_get_type;
spice_smartcard_manager_get;
@@ -80,16 +80,16 @@ spice_smartcard_manager_insert_card;
spice_smartcard_manager_remove_card;
spice_smartcard_reader_get_type;
spice_smartcard_reader_is_software;
-spice_usbredir_channel_get_type;
-spice_usb_device_get_type;
spice_usb_device_get_description;
-spice_usb_device_manager_get_type;
-spice_usb_device_manager_get;
-spice_usb_device_manager_get_devices;
-spice_usb_device_manager_is_device_connected;
+spice_usb_device_get_type;
spice_usb_device_manager_connect_device_async;
spice_usb_device_manager_connect_device_finish;
spice_usb_device_manager_disconnect_device;
+spice_usb_device_manager_get;
+spice_usb_device_manager_get_devices;
+spice_usb_device_manager_get_type;
+spice_usb_device_manager_is_device_connected;
+spice_usbredir_channel_get_type;
spice_util_get_debug;
spice_util_get_version_string;
spice_util_set_debug;
More information about the Spice-commits
mailing list