summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2010-09-27 12:56:29 +0200
committerGerd Hoffmann <kraxel@redhat.com>2010-09-27 12:56:29 +0200
commitec92ad9d3a921f57ef421600c6aedde219465f34 (patch)
tree63bbcfb36f9c9c9b016d4126ffbd21ef8621af24
parent54fdb3c9727ad93502557323820b13c413fa7d4e (diff)
g-objectify cursor channel
-rw-r--r--gtk/channel-base.c8
-rw-r--r--gtk/channel-cursor.c150
-rw-r--r--gtk/channel-cursor.h42
-rw-r--r--gtk/channel-display.c1
-rw-r--r--gtk/channel-inputs.c1
-rw-r--r--gtk/channel-main.c1
-rw-r--r--gtk/channel-playback.c1
-rw-r--r--gtk/spice-channel-priv.h13
-rw-r--r--gtk/spice-channel.c141
-rw-r--r--gtk/spice-channel.h13
-rw-r--r--gtk/spice-client.h2
-rw-r--r--gtk/spice-types.h3
-rw-r--r--gtk/spice-widget.c45
13 files changed, 253 insertions, 168 deletions
diff --git a/gtk/channel-base.c b/gtk/channel-base.c
index d1aef33..7501f97 100644
--- a/gtk/channel-base.c
+++ b/gtk/channel-base.c
@@ -50,11 +50,9 @@ void base_handle_notify(SpiceChannel *channel, spice_msg_in *in)
message_str = (char*)notify->message;
}
- fprintf(stderr, "%s: channel %u:%u -- %s%s #%u%s%.*s\n", __FUNCTION__,
- c->info->type, c->channel_id,
- severity, visibility, notify->what,
- message_str ? ": " : "",
- notify->message_len,
+ fprintf(stderr, "%s: channel %s -- %s%s #%u%s%.*s\n", __FUNCTION__,
+ c->name, severity, visibility, notify->what,
+ message_str ? ": " : "", notify->message_len,
message_str ? message_str : "");
}
diff --git a/gtk/channel-cursor.c b/gtk/channel-cursor.c
index 5568d1f..e6c8be9 100644
--- a/gtk/channel-cursor.c
+++ b/gtk/channel-cursor.c
@@ -3,6 +3,110 @@
#include "spice-client.h"
#include "spice-channel-priv.h"
#include "spice-channel-cache.h"
+#include "spice-marshal.h"
+
+#define SPICE_CURSOR_CHANNEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_CURSOR_CHANNEL, spice_cursor_channel))
+
+struct spice_cursor_channel {
+ display_cache cursors;
+};
+
+G_DEFINE_TYPE(SpiceCursorChannel, spice_cursor_channel, SPICE_TYPE_CHANNEL)
+
+enum {
+ SPICE_CURSOR_SET,
+ SPICE_CURSOR_MOVE,
+ SPICE_CURSOR_HIDE,
+ SPICE_CURSOR_RESET,
+
+ SPICE_CURSOR_LAST_SIGNAL,
+};
+
+static guint signals[SPICE_CURSOR_LAST_SIGNAL];
+
+static void spice_cursor_handle_msg(SpiceChannel *channel, spice_msg_in *msg);
+
+/* ------------------------------------------------------------------ */
+
+static void spice_cursor_channel_init(SpiceCursorChannel *channel)
+{
+ spice_cursor_channel *c;
+
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ c = channel->priv = SPICE_CURSOR_CHANNEL_GET_PRIVATE(channel);
+ memset(c, 0, sizeof(*c));
+
+ cache_init(&c->cursors, "cursor");
+}
+
+static void spice_cursor_channel_finalize(GObject *obj)
+{
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ if (G_OBJECT_CLASS(spice_cursor_channel_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_cursor_channel_parent_class)->finalize(obj);
+}
+
+static void spice_cursor_channel_class_init(SpiceCursorChannelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
+
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ gobject_class->finalize = spice_cursor_channel_finalize;
+ channel_class->handle_msg = spice_cursor_handle_msg;
+
+ signals[SPICE_CURSOR_SET] =
+ g_signal_new("spice-cursor-set",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceCursorChannelClass, spice_cursor_set),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__INT_INT_INT_INT_POINTER,
+ G_TYPE_NONE,
+ 5,
+ G_TYPE_INT, G_TYPE_INT,
+ G_TYPE_INT, G_TYPE_INT,
+ G_TYPE_POINTER);
+
+ signals[SPICE_CURSOR_MOVE] =
+ g_signal_new("spice-cursor-move",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceCursorChannelClass, spice_cursor_move),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__INT_INT,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_INT, G_TYPE_INT);
+
+ signals[SPICE_CURSOR_HIDE] =
+ g_signal_new("spice-cursor-hide",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceCursorChannelClass, spice_cursor_hide),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ signals[SPICE_CURSOR_RESET] =
+ g_signal_new("spice-cursor-reset",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceCursorChannelClass, spice_cursor_reset),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ g_type_class_add_private(klass, sizeof(spice_cursor_channel));
+}
+
+/* ------------------------------------------------------------------ */
static void mono_cursor(display_cursor *cursor, uint8_t *data)
{
@@ -57,7 +161,7 @@ static void mono_cursor(display_cursor *cursor, uint8_t *data)
static display_cursor *set_cursor(SpiceChannel *channel, SpiceCursor *scursor)
{
- spice_channel *c = SPICE_CHANNEL_GET_PRIVATE(channel);
+ spice_cursor_channel *c = SPICE_CURSOR_CHANNEL(channel)->priv;
SpiceCursorHeader *hdr = &scursor->header;
display_cache_item *item;
display_cursor *cursor;
@@ -70,7 +174,7 @@ static display_cursor *set_cursor(SpiceChannel *channel, SpiceCursor *scursor)
#endif
if (scursor->flags & SPICE_CURSOR_FLAGS_FROM_CACHE) {
- item = cache_find(&c->cursor.cursors, hdr->unique);
+ item = cache_find(&c->cursors, hdr->unique);
if (!item) {
return NULL;
}
@@ -100,7 +204,7 @@ static display_cursor *set_cursor(SpiceChannel *channel, SpiceCursor *scursor)
}
if (cursor && (scursor->flags & SPICE_CURSOR_FLAGS_CACHE_ME)) {
- item = cache_add(&c->cursor.cursors, hdr->unique);
+ item = cache_add(&c->cursors, hdr->unique);
item->ptr.cursor = cursor;
}
@@ -109,19 +213,19 @@ static display_cursor *set_cursor(SpiceChannel *channel, SpiceCursor *scursor)
static void delete_cursor_one(SpiceChannel *channel, display_cache_item *item)
{
- spice_channel *c = SPICE_CHANNEL_GET_PRIVATE(channel);
+ spice_cursor_channel *c = SPICE_CURSOR_CHANNEL(channel)->priv;
free(item->ptr.cursor);
- cache_del(&c->cursor.cursors, item);
+ cache_del(&c->cursors, item);
}
static void delete_cursor_all(SpiceChannel *channel)
{
- spice_channel *c = SPICE_CHANNEL_GET_PRIVATE(channel);
+ spice_cursor_channel *c = SPICE_CURSOR_CHANNEL(channel)->priv;
display_cache_item *item;
for (;;) {
- item = cache_get_lru(&c->cursor.cursors);
+ item = cache_get_lru(&c->cursors);
if (item == NULL) {
return;
}
@@ -133,7 +237,7 @@ static void emit_cursor_set(SpiceChannel *channel, display_cursor *cursor)
{
if (!cursor)
return;
- g_signal_emit(channel, channel_signals[SPICE_CURSOR_SET], 0,
+ g_signal_emit(channel, signals[SPICE_CURSOR_SET], 0,
cursor->hdr.width, cursor->hdr.height,
cursor->hdr.hot_spot_x, cursor->hdr.hot_spot_y,
cursor->data);
@@ -152,7 +256,7 @@ static void cursor_handle_init(SpiceChannel *channel, spice_msg_in *in)
static void cursor_handle_reset(SpiceChannel *channel, spice_msg_in *in)
{
delete_cursor_all(channel);
- g_signal_emit(channel, channel_signals[SPICE_CURSOR_RESET], 0);
+ g_signal_emit(channel, signals[SPICE_CURSOR_RESET], 0);
}
static void cursor_handle_set(SpiceChannel *channel, spice_msg_in *in)
@@ -168,13 +272,13 @@ static void cursor_handle_move(SpiceChannel *channel, spice_msg_in *in)
{
SpiceMsgCursorMove *move = spice_msg_in_parsed(in);
- g_signal_emit(channel, channel_signals[SPICE_CURSOR_MOVE], 0,
+ g_signal_emit(channel, signals[SPICE_CURSOR_MOVE], 0,
move->position.x, move->position.y);
}
static void cursor_handle_hide(SpiceChannel *channel, spice_msg_in *in)
{
- g_signal_emit(channel, channel_signals[SPICE_CURSOR_HIDE], 0);
+ g_signal_emit(channel, signals[SPICE_CURSOR_HIDE], 0);
}
static void cursor_handle_trail(SpiceChannel *channel, spice_msg_in *in)
@@ -184,11 +288,11 @@ static void cursor_handle_trail(SpiceChannel *channel, spice_msg_in *in)
static void cursor_handle_inval_one(SpiceChannel *channel, spice_msg_in *in)
{
- spice_channel *c = SPICE_CHANNEL_GET_PRIVATE(channel);
+ spice_cursor_channel *c = SPICE_CURSOR_CHANNEL(channel)->priv;
SpiceMsgDisplayInvalOne *zap = spice_msg_in_parsed(in);
display_cache_item *item;
- item = cache_find(&c->cursor.cursors, zap->id);
+ item = cache_find(&c->cursors, zap->id);
delete_cursor_one(channel, item);
}
@@ -197,13 +301,6 @@ static void cursor_handle_inval_all(SpiceChannel *channel, spice_msg_in *in)
delete_cursor_all(channel);
}
-static void cursor_alloc(SpiceChannel *channel)
-{
- spice_channel *c = SPICE_CHANNEL_GET_PRIVATE(channel);
-
- cache_init(&c->cursor.cursors, "cursor");
-}
-
static spice_msg_handler cursor_handlers[] = {
[ SPICE_MSG_SET_ACK ] = base_handle_set_ack,
[ SPICE_MSG_PING ] = base_handle_ping,
@@ -219,10 +316,9 @@ static spice_msg_handler cursor_handlers[] = {
[ SPICE_MSG_CURSOR_INVAL_ALL ] = cursor_handle_inval_all,
};
-spice_channel_info cursor_channel_info = {
- .type = SPICE_CHANNEL_CURSOR,
- .name = "cursor",
- .alloc = cursor_alloc,
- .handlers = cursor_handlers,
- .nhandlers = SPICE_N_ELEMENTS(cursor_handlers),
-};
+static void spice_cursor_handle_msg(SpiceChannel *channel, spice_msg_in *msg)
+{
+ assert(msg->header.type < SPICE_N_ELEMENTS(cursor_handlers));
+ assert(cursor_handlers[msg->header.type] != NULL);
+ cursor_handlers[msg->header.type](channel, msg);
+}
diff --git a/gtk/channel-cursor.h b/gtk/channel-cursor.h
new file mode 100644
index 0000000..d6af6ab
--- /dev/null
+++ b/gtk/channel-cursor.h
@@ -0,0 +1,42 @@
+#ifndef __SPICE_CLIENT_CURSOR_CHANNEL_H__
+#define __SPICE_CLIENT_CURSOR_CHANNEL_H__
+
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_CURSOR_CHANNEL (spice_cursor_channel_get_type())
+#define SPICE_CURSOR_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_CURSOR_CHANNEL, SpiceCursorChannel))
+#define SPICE_CURSOR_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_CURSOR_CHANNEL, SpiceCursorChannelClass))
+#define SPICE_IS_CURSOR_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_CURSOR_CHANNEL))
+#define SPICE_IS_CURSOR_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_CURSOR_CHANNEL))
+#define SPICE_CURSOR_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_CURSOR_CHANNEL, SpiceCursorChannelClass))
+
+typedef struct _SpiceCursorChannel SpiceCursorChannel;
+typedef struct _SpiceCursorChannelClass SpiceCursorChannelClass;
+typedef struct spice_cursor_channel spice_cursor_channel;
+
+struct _SpiceCursorChannel {
+ SpiceChannel parent;
+ spice_cursor_channel *priv;
+ /* Do not add fields to this struct */
+};
+
+struct _SpiceCursorChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+ void (*spice_cursor_set)(SpiceCursorChannel *channel, gint width, gint height,
+ gint hot_x, gint hot_y, gpointer rgba);
+ void (*spice_cursor_move)(SpiceCursorChannel *channel, gint x, gint y);
+ void (*spice_cursor_hide)(SpiceCursorChannel *channel);
+ void (*spice_cursor_reset)(SpiceCursorChannel *channel);
+
+ /* Do not add fields to this struct */
+};
+
+GType spice_cursor_channel_get_type(void);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_CURSOR_CHANNEL_H__ */
diff --git a/gtk/channel-display.c b/gtk/channel-display.c
index 7e80b71..c3e2793 100644
--- a/gtk/channel-display.c
+++ b/gtk/channel-display.c
@@ -567,7 +567,6 @@ static spice_msg_handler display_handlers[] = {
};
spice_channel_info display_channel_info = {
- .type = SPICE_CHANNEL_DISPLAY,
.name = "display",
.alloc = display_alloc,
.ready = display_ready,
diff --git a/gtk/channel-inputs.c b/gtk/channel-inputs.c
index c679d91..643c5f4 100644
--- a/gtk/channel-inputs.c
+++ b/gtk/channel-inputs.c
@@ -76,7 +76,6 @@ static spice_msg_handler inputs_handlers[] = {
};
spice_channel_info inputs_channel_info = {
- .type = SPICE_CHANNEL_INPUTS,
.name = "inputs",
.handlers = inputs_handlers,
.nhandlers = SPICE_N_ELEMENTS(inputs_handlers),
diff --git a/gtk/channel-main.c b/gtk/channel-main.c
index 81bc4b2..2c310f6 100644
--- a/gtk/channel-main.c
+++ b/gtk/channel-main.c
@@ -225,7 +225,6 @@ static spice_msg_handler main_handlers[] = {
};
spice_channel_info main_channel_info = {
- .type = SPICE_CHANNEL_MAIN,
.name = "main",
.handlers = main_handlers,
.nhandlers = SPICE_N_ELEMENTS(main_handlers),
diff --git a/gtk/channel-playback.c b/gtk/channel-playback.c
index 0e3b0b8..0071e0a 100644
--- a/gtk/channel-playback.c
+++ b/gtk/channel-playback.c
@@ -82,7 +82,6 @@ static spice_msg_handler playback_handlers[] = {
};
spice_channel_info playback_channel_info = {
- .type = SPICE_CHANNEL_PLAYBACK,
.name = "playback",
.handlers = playback_handlers,
.nhandlers = SPICE_N_ELEMENTS(playback_handlers),
diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h
index 061d405..3d569ea 100644
--- a/gtk/spice-channel-priv.h
+++ b/gtk/spice-channel-priv.h
@@ -127,10 +127,6 @@ struct display_channel {
display_stream *streams[128];
};
-struct cursor_channel {
- display_cache cursors;
-};
-
struct inputs_channel {
int bs;
int dx, dy;
@@ -158,6 +154,7 @@ struct spice_channel {
int connection_id;
int channel_id;
+ int channel_type;
int serial;
spice_channel_info *info;
SpiceLinkHeader link_hdr;
@@ -172,7 +169,6 @@ struct spice_channel {
union {
struct main_channel main;
struct display_channel display;
- struct cursor_channel cursor;
struct inputs_channel inputs;
struct playback_channel playback;
};
@@ -188,11 +184,6 @@ enum {
SPICE_DISPLAY_PRIMARY_DESTROY,
SPICE_DISPLAY_INVALIDATE,
- SPICE_CURSOR_SET,
- SPICE_CURSOR_MOVE,
- SPICE_CURSOR_HIDE,
- SPICE_CURSOR_RESET,
-
SPICE_PLAYBACK_START,
SPICE_PLAYBACK_DATA,
SPICE_PLAYBACK_STOP,
@@ -213,7 +204,6 @@ void base_handle_ping(SpiceChannel *channel, spice_msg_in *in);
void base_handle_notify(SpiceChannel *channel, spice_msg_in *in);
struct spice_channel_info {
- int type;
char *name;
spice_channel_func alloc;
spice_channel_func ready;
@@ -223,7 +213,6 @@ struct spice_channel_info {
extern spice_channel_info main_channel_info;
extern spice_channel_info display_channel_info;
-extern spice_channel_info cursor_channel_info;
extern spice_channel_info inputs_channel_info;
extern spice_channel_info playback_channel_info;
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index cc7caa6..92ccde5 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -19,7 +19,6 @@ static void spice_channel_send_link(SpiceChannel *channel);
static spice_channel_info *type2info[] = {
[ SPICE_CHANNEL_MAIN ] = &main_channel_info,
[ SPICE_CHANNEL_DISPLAY ] = &display_channel_info,
- [ SPICE_CHANNEL_CURSOR ] = &cursor_channel_info,
[ SPICE_CHANNEL_INPUTS ] = &inputs_channel_info,
[ SPICE_CHANNEL_PLAYBACK ] = &playback_channel_info,
};
@@ -33,7 +32,7 @@ G_DEFINE_TYPE (SpiceChannel, spice_channel, G_TYPE_OBJECT);
enum {
PROP_0,
PROP_SESSION,
- PROP_TYPE,
+ PROP_CHANNEL_TYPE,
PROP_CHANNEL_ID,
};
@@ -62,16 +61,8 @@ static void spice_channel_constructed(GObject *gobject)
c->info ? c->info->name : "unknown", c->channel_id);
fprintf(stderr, "%s %s\n", __FUNCTION__, c->name);
- if (c->info == NULL) {
- /* Hmm ... */
-#if 0 /* FIXME: causes trouble, to be debugged */
- g_object_unref(gobject);
-#endif
- return;
- }
-
c->connection_id = spice_session_get_connection_id(c->session);
- if (c->info->alloc)
+ if (c->info && c->info->alloc)
c->info->alloc(channel);
spice_session_channel_new(c->session, channel);
@@ -118,12 +109,8 @@ static void spice_channel_get_property(GObject *gobject,
case PROP_SESSION:
g_value_set_object(value, c->session);
break;
- case PROP_TYPE:
- if (c->info) {
- g_value_set_int(value, c->info->type);
- } else {
- g_value_set_int(value, -1);
- }
+ case PROP_CHANNEL_TYPE:
+ g_value_set_int(value, c->channel_type);
break;
case PROP_CHANNEL_ID:
g_value_set_int(value, c->channel_id);
@@ -141,20 +128,17 @@ static void spice_channel_set_property(GObject *gobject,
{
SpiceChannel *channel = SPICE_CHANNEL(gobject);
spice_channel *c = SPICE_CHANNEL_GET_PRIVATE(channel);
- spice_channel_info *info = NULL;
- int type;
switch (prop_id) {
case PROP_SESSION:
c->session = g_value_get_object(value);
break;
- case PROP_TYPE:
- type = g_value_get_int(value);
- if (type >= 0 && type < SPICE_N_ELEMENTS(type2info)) {
- info = type2info[type];
- }
- if (info != NULL) {
- c->info = info;
+ case PROP_CHANNEL_TYPE:
+ c->channel_type = g_value_get_int(value);
+ c->info = NULL;
+ if (c->channel_type >= 0 &&
+ c->channel_type < SPICE_N_ELEMENTS(type2info)) {
+ c->info = type2info[c->channel_type];
}
break;
case PROP_CHANNEL_ID:
@@ -166,16 +150,32 @@ static void spice_channel_set_property(GObject *gobject,
}
}
+static void spice_channel_handle_msg(SpiceChannel *channel, spice_msg_in *msg)
+{
+ spice_channel *c = SPICE_CHANNEL_GET_PRIVATE(channel);
+ spice_msg_handler func = NULL;
+
+ if (msg->header.type < c->info->nhandlers)
+ func = c->info->handlers[msg->header.type];
+ if (!func)
+ PANIC("no message handler: %s type %d",
+ c->name, msg->header.type);
+ func(channel, msg);
+}
+
static void spice_channel_class_init(SpiceChannelClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
+
+ fprintf(stderr, "%s\n", __FUNCTION__);
gobject_class->constructed = spice_channel_constructed;
gobject_class->dispose = spice_channel_dispose;
gobject_class->finalize = spice_channel_finalize;
-
gobject_class->get_property = spice_channel_get_property;
gobject_class->set_property = spice_channel_set_property;
+ channel_class->handle_msg = spice_channel_handle_msg;
g_object_class_install_property
(gobject_class, PROP_SESSION,
@@ -190,7 +190,7 @@ static void spice_channel_class_init(SpiceChannelClass *klass)
G_PARAM_STATIC_BLURB));
g_object_class_install_property
- (gobject_class, PROP_TYPE,
+ (gobject_class, PROP_CHANNEL_TYPE,
g_param_spec_int("channel-type",
"Channel type",
"",
@@ -279,50 +279,6 @@ static void spice_channel_class_init(SpiceChannelClass *klass)
4,
G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
- channel_signals[SPICE_CURSOR_SET] =
- g_signal_new("spice-cursor-set",
- G_OBJECT_CLASS_TYPE(gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(SpiceChannelClass, spice_cursor_set),
- NULL, NULL,
- g_cclosure_user_marshal_VOID__INT_INT_INT_INT_POINTER,
- G_TYPE_NONE,
- 5,
- G_TYPE_INT, G_TYPE_INT,
- G_TYPE_INT, G_TYPE_INT,
- G_TYPE_POINTER);
-
- channel_signals[SPICE_CURSOR_MOVE] =
- g_signal_new("spice-cursor-move",
- G_OBJECT_CLASS_TYPE(gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(SpiceChannelClass, spice_cursor_move),
- NULL, NULL,
- g_cclosure_user_marshal_VOID__INT_INT,
- G_TYPE_NONE,
- 2,
- G_TYPE_INT, G_TYPE_INT);
-
- channel_signals[SPICE_CURSOR_HIDE] =
- g_signal_new("spice-cursor-hide",
- G_OBJECT_CLASS_TYPE(gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(SpiceChannelClass, spice_cursor_hide),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- channel_signals[SPICE_CURSOR_RESET] =
- g_signal_new("spice-cursor-reset",
- G_OBJECT_CLASS_TYPE(gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(SpiceChannelClass, spice_cursor_reset),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
channel_signals[SPICE_PLAYBACK_START] =
g_signal_new("spice-playback-start",
G_OBJECT_CLASS_TYPE(gobject_class),
@@ -425,9 +381,8 @@ void spice_msg_in_hexdump(spice_msg_in *in)
{
spice_channel *c = SPICE_CHANNEL_GET_PRIVATE(in->channel);
- fprintf(stderr, "--\n<< hdr: %d:%d serial %ld type %d size %d sub-list %d\n",
- c->info->type, c->channel_id,
- in->header.serial, in->header.type,
+ fprintf(stderr, "--\n<< hdr: %s serial %ld type %d size %d sub-list %d\n",
+ c->name, in->header.serial, in->header.type,
in->header.size, in->header.sub_list);
hexdump("<< msg", in->data, in->dpos);
}
@@ -436,9 +391,8 @@ void spice_msg_out_hexdump(spice_msg_out *out, unsigned char *data, int len)
{
spice_channel *c = SPICE_CHANNEL_GET_PRIVATE(out->channel);
- fprintf(stderr, "--\n>> hdr: %d:%d serial %ld type %d size %d sub-list %d\n",
- c->info->type, c->channel_id,
- out->header->serial, out->header->type,
+ fprintf(stderr, "--\n>> hdr: %s serial %ld type %d size %d sub-list %d\n",
+ c->name, out->header->serial, out->header->type,
out->header->size, out->header->sub_list);
hexdump(">> msg", data, len);
}
@@ -613,7 +567,7 @@ static void spice_channel_recv_auth(SpiceChannel *channel)
fprintf(stderr, "channel up: %s\n", c->name);
c->state = SPICE_CHANNEL_STATE_READY;
- if (c->info->ready)
+ if (c->info && c->info->ready)
c->info->ready(channel);
spice_channel_emit_event(channel, SPICE_CHANNEL_OPENED);
}
@@ -630,13 +584,13 @@ static void spice_channel_send_link(SpiceChannel *channel)
case 1: /* protocol 1 == major 1, old 0.4 protocol, last active minor */
c->link_hdr.major_version = 1;
c->link_hdr.minor_version = 3;
- c->parser = spice_get_server_channel_parser1(c->info->type, NULL);
+ c->parser = spice_get_server_channel_parser1(c->channel_type, NULL);
c->marshallers = spice_message_marshallers_get1();
break;
case SPICE_VERSION_MAJOR: /* protocol 2 == current */
c->link_hdr.major_version = SPICE_VERSION_MAJOR;
c->link_hdr.minor_version = SPICE_VERSION_MINOR;
- c->parser = spice_get_server_channel_parser(c->info->type, NULL);
+ c->parser = spice_get_server_channel_parser(c->channel_type, NULL);
c->marshallers = spice_message_marshallers_get();
break;
default:
@@ -644,7 +598,7 @@ static void spice_channel_send_link(SpiceChannel *channel)
}
c->link_msg.connection_id = c->connection_id;
- c->link_msg.channel_type = c->info->type;
+ c->link_msg.channel_type = c->channel_type;
c->link_msg.channel_id = c->channel_id;
c->link_msg.caps_offset = sizeof(c->link_msg);
@@ -782,7 +736,6 @@ void spice_channel_send_msg(SpiceChannel *channel, spice_msg_out *out)
static void spice_channel_recv_msg(SpiceChannel *channel)
{
spice_channel *c = SPICE_CHANNEL_GET_PRIVATE(channel);
- spice_msg_handler func;
spice_msg_in *in;
int rc;
@@ -840,13 +793,9 @@ static void spice_channel_recv_msg(SpiceChannel *channel)
c->name, in->header.type);
/* process message */
- if (in->header.type < c->info->nhandlers)
- func = c->info->handlers[in->header.type];
- if (!func)
- PANIC("no message handler: %s type %d",
- c->name, in->header.type);
- func(channel, in);
+ SPICE_CHANNEL_GET_CLASS(channel)->handle_msg(channel, in);
+ /* release message */
spice_msg_in_put(c->msg_in);
c->msg_in = NULL;
}
@@ -880,8 +829,17 @@ static void spice_channel_data(int event, void *opaque)
SpiceChannel *spice_channel_new(SpiceSession *s, int type, int id)
{
SpiceChannel *channel;
+ GType gtype = 0;
- channel = SPICE_CHANNEL(g_object_new(SPICE_TYPE_CHANNEL,
+ switch (type) {
+ case SPICE_CHANNEL_CURSOR:
+ gtype = SPICE_TYPE_CURSOR_CHANNEL;
+ break;
+ default:
+ gtype = SPICE_TYPE_CHANNEL;
+ break;
+ }
+ channel = SPICE_CHANNEL(g_object_new(gtype,
"spice-session", s,
"channel-type", type,
"channel-id", id,
@@ -933,8 +891,9 @@ gboolean spice_channel_connect(SpiceChannel *channel)
spice_channel *c = SPICE_CHANNEL_GET_PRIVATE(channel);
int rc, err;
- if (c->info == NULL || c->session == NULL || c->channel_id == -1) {
+ if (c->session == NULL || c->channel_type == -1 || c->channel_id == -1) {
/* unset properties or unknown channel type */
+ fprintf(stderr, "%s: channel setup incomplete\n", __FUNCTION__);
return false;
}
if (c->state != SPICE_CHANNEL_STATE_UNCONNECTED) {
diff --git a/gtk/spice-channel.h b/gtk/spice-channel.h
index 9aed447..b12b698 100644
--- a/gtk/spice-channel.h
+++ b/gtk/spice-channel.h
@@ -38,6 +38,9 @@ struct _SpiceChannelClass
{
GObjectClass parent_class;
+ /* virtual methods */
+ void (*handle_msg)(SpiceChannel *channel, spice_msg_in *msg);
+
/* common signals */
void (*spice_channel_event)(SpiceChannel *channel, enum SpiceChannelEvent event);
@@ -53,13 +56,6 @@ struct _SpiceChannelClass
void (*spice_display_invalidate)(SpiceChannel *channel,
gint x, gint y, gint w, gint h);
- /* cursor signals */
- void (*spice_cursor_set)(SpiceChannel *channel, gint width, gint height,
- gint hot_x, gint hot_y, gpointer rgba);
- void (*spice_cursor_move)(SpiceChannel *channel, gint x, gint y);
- void (*spice_cursor_hide)(SpiceChannel *channel);
- void (*spice_cursor_reset)(SpiceChannel *channel);
-
/* playback signals */
void (*spice_playback_start)(SpiceChannel *channel,
gint format, gint channels, gint freq);
@@ -79,9 +75,6 @@ GType spice_channel_get_type(void) G_GNUC_CONST;
G_END_DECLS
-typedef struct spice_msg_in spice_msg_in;
-typedef struct spice_msg_out spice_msg_out;
-
typedef void (*spice_msg_handler)(SpiceChannel *channel, spice_msg_in *in);
typedef void (*spice_channel_func)(SpiceChannel *channel);
typedef struct spice_channel_info spice_channel_info;
diff --git a/gtk/spice-client.h b/gtk/spice-client.h
index 0cc7906..bc7492d 100644
--- a/gtk/spice-client.h
+++ b/gtk/spice-client.h
@@ -33,6 +33,8 @@
#include "spice-session.h"
#include "spice-channel.h"
+#include "channel-cursor.h"
+
/* debug bits */
#define PANIC(fmt, ...) \
{ fprintf(stderr, "%s:%d " fmt "\n", \
diff --git a/gtk/spice-types.h b/gtk/spice-types.h
index 76db5a9..e07a924 100644
--- a/gtk/spice-types.h
+++ b/gtk/spice-types.h
@@ -11,4 +11,7 @@ typedef struct _SpiceChannel SpiceChannel;
typedef struct _SpiceChannelClass SpiceChannelClass;
typedef struct spice_channel spice_channel;
+typedef struct spice_msg_in spice_msg_in;
+typedef struct spice_msg_out spice_msg_out;
+
#endif /* __SPICE_CLIENT_TYPES_H__ */
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index 199ec40..8078686 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -41,7 +41,7 @@ struct spice_display {
SpiceSession *session;
SpiceChannel *main;
SpiceChannel *display;
- SpiceChannel *cursor;
+ SpiceCursorChannel *cursor;
SpiceChannel *inputs;
enum SpiceMouseMode mouse_mode;
@@ -907,7 +907,7 @@ static void invalidate(SpiceChannel *channel,
x + d->mx, y + d->my, w, h);
}
-static void cursor_set(SpiceChannel *channel,
+static void cursor_set(SpiceCursorChannel *channel,
gint width, gint height, gint hot_x, gint hot_y,
gpointer rgba, gpointer data)
{
@@ -935,7 +935,7 @@ static void cursor_set(SpiceChannel *channel,
gdk_window_set_cursor(window, d->mouse_cursor);
}
-static void cursor_hide(SpiceChannel *channel, gpointer data)
+static void cursor_hide(SpiceCursorChannel *channel, gpointer data)
{
SpiceDisplay *display = data;
spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display);
@@ -949,12 +949,12 @@ static void cursor_hide(SpiceChannel *channel, gpointer data)
gdk_window_set_cursor(window, d->mouse_cursor);
}
-static void cursor_move(SpiceChannel *channel, gint x, gint y, gpointer data)
+static void cursor_move(SpiceCursorChannel *channel, gint x, gint y, gpointer data)
{
fprintf(stderr, "%s: TODO (+%d+%d)\n", __FUNCTION__, x, y);
}
-static void cursor_reset(SpiceChannel *channel, gpointer data)
+static void cursor_reset(SpiceCursorChannel *channel, gpointer data)
{
fprintf(stderr, "%s: TODO\n", __FUNCTION__);
}
@@ -966,8 +966,26 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data)
int type = spice_channel_type(channel);
int id = spice_channel_id(channel);
+ if (SPICE_IS_CURSOR_CHANNEL(channel)) {
+ fprintf(stderr, "%s: cursor channel\n", __FUNCTION__);
+ if (id != d->channel_id)
+ return;
+ d->cursor = SPICE_CURSOR_CHANNEL(channel);
+ g_signal_connect(channel, "spice-cursor-set",
+ G_CALLBACK(cursor_set), display);
+ g_signal_connect(channel, "spice-cursor-move",
+ G_CALLBACK(cursor_move), display);
+ g_signal_connect(channel, "spice-cursor-hide",
+ G_CALLBACK(cursor_hide), display);
+ g_signal_connect(channel, "spice-cursor-reset",
+ G_CALLBACK(cursor_reset), display);
+ spice_channel_connect(channel);
+ return;
+ }
+
switch (type) {
case SPICE_CHANNEL_DISPLAY:
+ fprintf(stderr, "%s: display channel\n", __FUNCTION__);
if (id != d->channel_id)
return;
d->display = channel;
@@ -979,31 +997,20 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data)
G_CALLBACK(invalidate), display);
spice_channel_connect(channel);
break;
- case SPICE_CHANNEL_CURSOR:
- if (id != d->channel_id)
- return;
- d->cursor = channel;
- g_signal_connect(channel, "spice-cursor-set",
- G_CALLBACK(cursor_set), display);
- g_signal_connect(channel, "spice-cursor-move",
- G_CALLBACK(cursor_move), display);
- g_signal_connect(channel, "spice-cursor-hide",
- G_CALLBACK(cursor_hide), display);
- g_signal_connect(channel, "spice-cursor-reset",
- G_CALLBACK(cursor_reset), display);
- spice_channel_connect(channel);
- break;
case SPICE_CHANNEL_INPUTS:
+ fprintf(stderr, "%s: inputs channel\n", __FUNCTION__);
d->inputs = channel;
spice_channel_connect(channel);
break;
case SPICE_CHANNEL_MAIN:
+ fprintf(stderr, "%s: main channel\n", __FUNCTION__);
d->main = channel;
g_signal_connect(channel, "spice-main-mouse-mode",
G_CALLBACK(mouse_mode), display);
mouse_mode(channel, spice_main_get_mouse_mode(channel), display);
break;
default:
+ fprintf(stderr, "%s: other channel (type %d)\n", __FUNCTION__, type);
return;
}
}