Hmm, the summary of this commit is almost identical to one that was just merged: worker: move some cursor code to cursor-channel.c server: move some cursor code to cursor-channel.c it's not clear what significance the difference between "worker" and "server" is, considering both patches are moving code from red_worker.c to cursor-channel.c... This patch still seems to be doing too many things. I'll try to split it up and post a new version if nobody objects. On Thu, 2015-10-29 at 11:09 +0000, Frediano Ziglio wrote: > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > > Also fix warning due to unexpected pipe item type > > The specific item type that was not being handled was > PIPE_ITEM_TYPE_INVAL_ONE (#102). This item type is used by the cursor > channel, but the analogous item for the display channel is > PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE. Use this value instead. > > The exact warning follows: > > (/usr/bin/qemu-kvm:24458): Spice-Warning **: > ../../server/dcc-send.c:2442:dcc_send_item: should not be reached > (/usr/bin/qemu-kvm:24458): Spice-CRITICAL **: > ../../server/dcc.c:1595:release_item_before_push: invalid item > type > > Author: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > Date: Thu Feb 27 19:38:58 2014 +0200 > --- > server/cache_item.tmpl.c | 4 +- > server/cursor-channel.c | 214 ++++++++++++++++++++++++++----------- > ---------- > server/cursor-channel.h | 27 +++--- > server/red_worker.c | 194 +++++++++++++++++++------------------ > ----- > server/red_worker.h | 62 +++++--------- > 5 files changed, 245 insertions(+), 256 deletions(-) > > diff --git a/server/cache_item.tmpl.c b/server/cache_item.tmpl.c > index dc314c0..ad2b579 100644 > --- a/server/cache_item.tmpl.c > +++ b/server/cache_item.tmpl.c > @@ -21,6 +21,7 @@ > #define CACHE_HASH_KEY CURSOR_CACHE_HASH_KEY > #define CACHE_HASH_SIZE CURSOR_CACHE_HASH_SIZE > #define CACHE_INVAL_TYPE SPICE_MSG_CURSOR_INVAL_ONE > +#define PIPE_ITEM_TYPE PIPE_ITEM_TYPE_INVAL_ONE > #define FUNC_NAME(name) red_cursor_cache_##name > #define VAR_NAME(name) cursor_cache_##name > #define CHANNEL CursorChannel > @@ -32,6 +33,7 @@ > #define CACHE_HASH_KEY PALETTE_CACHE_HASH_KEY > #define CACHE_HASH_SIZE PALETTE_CACHE_HASH_SIZE > #define CACHE_INVAL_TYPE SPICE_MSG_DISPLAY_INVAL_PALETTE > +#define PIPE_ITEM_TYPE PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE > #define FUNC_NAME(name) red_palette_cache_##name > #define VAR_NAME(name) palette_cache_##name > #define CHANNEL DisplayChannel > @@ -78,7 +80,7 @@ static void FUNC_NAME(remove)(CHANNELCLIENT > *channel_client, CacheItem *item) > channel_client->VAR_NAME(items)--; > channel_client->VAR_NAME(available) += item->size; > > - red_channel_pipe_item_init(&channel->common.base, &item > ->u.pipe_data, PIPE_ITEM_TYPE_INVAL_ONE); > + red_channel_pipe_item_init(&channel->common.base, &item > ->u.pipe_data, PIPE_ITEM_TYPE); > red_channel_client_pipe_add_tail(&channel_client->common.base, > &item->u.pipe_data); // for now > } > > diff --git a/server/cursor-channel.c b/server/cursor-channel.c > index 6cc2b93..1205ed2 100644 > --- a/server/cursor-channel.c > +++ b/server/cursor-channel.c > @@ -25,55 +25,58 @@ > #include "cache_item.tmpl.c" > #undef CLIENT_CURSOR_CACHE > > -static inline CursorItem *alloc_cursor_item(void) > +CursorItem *cursor_item_new(QXLInstance *qxl, RedCursorCmd *cmd, > uint32_t group_id) > { > CursorItem *cursor_item; > > + spice_return_val_if_fail(cmd != NULL, NULL); > + > cursor_item = g_slice_new0(CursorItem); > + cursor_item->qxl = qxl; > cursor_item->refs = 1; > + cursor_item->group_id = group_id; > + cursor_item->red_cursor = cmd; > > return cursor_item; > } > > -CursorItem *cursor_item_new(RedCursorCmd *cmd, uint32_t group_id) > +CursorItem *cursor_item_ref(CursorItem *item) > { > - CursorItem *cursor_item; > + spice_return_val_if_fail(item != NULL, NULL); > + spice_return_val_if_fail(item->refs > 0, NULL); > > - spice_return_val_if_fail(cmd != NULL, NULL); > - cursor_item = alloc_cursor_item(); > - > - cursor_item->group_id = group_id; > - cursor_item->red_cursor = cmd; > + item->refs++; > > - return cursor_item; > + return item; > } > > -void cursor_item_unref(QXLInstance *qxl, CursorItem *cursor) > +void cursor_item_unref(CursorItem *item) > { > - if (!--cursor->refs) { > - QXLReleaseInfoExt release_info_ext; > - RedCursorCmd *cursor_cmd; > - > - cursor_cmd = cursor->red_cursor; > - release_info_ext.group_id = cursor->group_id; > - release_info_ext.info = cursor_cmd->release_info; > - qxl->st->qif->release_resource(qxl, release_info_ext); > - red_put_cursor_cmd(cursor_cmd); > - free(cursor_cmd); > - > - g_slice_free(CursorItem, cursor); > - } > + QXLReleaseInfoExt release_info_ext; > + RedCursorCmd *cursor_cmd; > + > + spice_return_if_fail(item != NULL); > + > + if (--item->refs) > + return; > + > + cursor_cmd = item->red_cursor; > + release_info_ext.group_id = item->group_id; > + release_info_ext.info = cursor_cmd->release_info; > + item->qxl->st->qif->release_resource(item->qxl, > release_info_ext); > + red_put_cursor_cmd(cursor_cmd); > + free(cursor_cmd); > + > + g_slice_free(CursorItem, item); > + > } > > static void cursor_set_item(CursorChannel *cursor, CursorItem *item) > { > if (cursor->item) > - cursor_item_unref(red_worker_get_qxl(cursor->common.worker), > cursor->item); > - > - if (item) > - item->refs++; > + cursor_item_unref(cursor->item); > > - cursor->item = item; > + cursor->item = item ? cursor_item_ref(item) : NULL; > } > > static PipeItem *new_cursor_pipe_item(RedChannelClient *rcc, void > *data, int num) > @@ -135,11 +138,15 @@ static void > red_reset_cursor_cache(RedChannelClient *rcc) > red_cursor_cache_reset(RCC_TO_CCC(rcc), > CLIENT_CURSOR_CACHE_SIZE); > } > > -void cursor_channel_disconnect(RedChannel *channel) > +void cursor_channel_disconnect(CursorChannel *cursor) > { > + RedChannel *channel = (RedChannel *)cursor; > + > if (!channel || !red_channel_is_connected(channel)) { > return; > } > + > + /* TODO: use a class vdispose */ > red_channel_apply_clients(channel, red_reset_cursor_cache); > red_channel_disconnect(channel); > } > @@ -147,7 +154,8 @@ void cursor_channel_disconnect(RedChannel > *channel) > > static void put_cursor_pipe_item(CursorChannelClient *ccc, > CursorPipeItem *pipe_item) > { > - spice_assert(pipe_item); > + spice_return_if_fail(pipe_item); > + spice_return_if_fail(pipe_item->refs > 0); > > if (--pipe_item->refs) { > return; > @@ -155,7 +163,7 @@ static void > put_cursor_pipe_item(CursorChannelClient *ccc, CursorPipeItem *pipe_ > > spice_assert(!pipe_item_is_linked(&pipe_item->base)); > > - cursor_item_unref(red_worker_get_qxl(ccc->common.worker), > pipe_item->cursor_item); > + cursor_item_unref(pipe_item->cursor_item); > free(pipe_item); > } > > @@ -206,37 +214,37 @@ static void > cursor_channel_client_release_item_after_push(CursorChannelClient *c > static void red_marshall_cursor_init(RedChannelClient *rcc, > SpiceMarshaller *base_marshaller, > PipeItem *pipe_item) > { > - CursorChannel *cursor_channel; > + CursorChannel *cursor; > CursorChannelClient *ccc = RCC_TO_CCC(rcc); > SpiceMsgCursorInit msg; > AddBufInfo info; > > spice_assert(rcc); > - cursor_channel = SPICE_CONTAINEROF(rcc->channel, CursorChannel, > common.base); > + cursor = SPICE_CONTAINEROF(rcc->channel, CursorChannel, > common.base); > > red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_INIT, > NULL); > - msg.visible = cursor_channel->cursor_visible; > - msg.position = cursor_channel->cursor_position; > - msg.trail_length = cursor_channel->cursor_trail_length; > - msg.trail_frequency = cursor_channel->cursor_trail_frequency; > + msg.visible = cursor->cursor_visible; > + msg.position = cursor->cursor_position; > + msg.trail_length = cursor->cursor_trail_length; > + msg.trail_frequency = cursor->cursor_trail_frequency; > > - cursor_fill(ccc, &msg.cursor, cursor_channel->item, &info); > + cursor_fill(ccc, &msg.cursor, cursor->item, &info); > spice_marshall_msg_cursor_init(base_marshaller, &msg); > add_buf_from_info(base_marshaller, &info); > } > > static void cursor_marshall(RedChannelClient *rcc, > - SpiceMarshaller *m, CursorPipeItem > *cursor_pipe_item) > + SpiceMarshaller *m, CursorPipeItem > *cursor_pipe_item) > { > - CursorChannel *cursor_channel = SPICE_CONTAINEROF(rcc->channel, > CursorChannel, common.base); > + CursorChannel *cursor = SPICE_CONTAINEROF(rcc->channel, > CursorChannel, common.base); > CursorChannelClient *ccc = RCC_TO_CCC(rcc); > - CursorItem *cursor = cursor_pipe_item->cursor_item; > + CursorItem *item = cursor_pipe_item->cursor_item; > PipeItem *pipe_item = &cursor_pipe_item->base; > RedCursorCmd *cmd; > > - spice_assert(cursor_channel); > + spice_return_if_fail(cursor); > > - cmd = cursor->red_cursor; > + cmd = item->red_cursor; > switch (cmd->type) { > case QXL_CURSOR_MOVE: > { > @@ -253,9 +261,9 @@ static void cursor_marshall(RedChannelClient > *rcc, > > red_channel_client_init_send_data(rcc, > SPICE_MSG_CURSOR_SET, pipe_item); > cursor_set.position = cmd->u.set.position; > - cursor_set.visible = cursor_channel->cursor_visible; > + cursor_set.visible = cursor->cursor_visible; > > - cursor_fill(ccc, &cursor_set.cursor, cursor, &info); > + cursor_fill(ccc, &cursor_set.cursor, item, &info); > spice_marshall_msg_cursor_set(m, &cursor_set); > add_buf_from_info(m, &info); > break; > @@ -279,7 +287,7 @@ static void cursor_marshall(RedChannelClient > *rcc, > } > > static inline void red_marshall_inval(RedChannelClient *rcc, > - SpiceMarshaller *base_marshaller, CacheItem *cach_item) > + SpiceMarshaller > *base_marshaller, CacheItem *cach_item) > { > SpiceMsgDisplayInvalOne inval_one; > > @@ -289,13 +297,6 @@ static inline void > red_marshall_inval(RedChannelClient *rcc, > spice_marshall_msg_cursor_inval_one(base_marshaller, > &inval_one); > } > > -static void red_cursor_marshall_inval(RedChannelClient *rcc, > - SpiceMarshaller *m, CacheItem *cach_item) > -{ > - spice_assert(rcc); > - red_marshall_inval(rcc, m, cach_item); > -} > - > static void cursor_channel_send_item(RedChannelClient *rcc, PipeItem > *pipe_item) > { > SpiceMarshaller *m = red_channel_client_get_marshaller(rcc); > @@ -306,10 +307,10 @@ static void > cursor_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item) > cursor_marshall(rcc, m, SPICE_CONTAINEROF(pipe_item, > CursorPipeItem, base)); > break; > case PIPE_ITEM_TYPE_INVAL_ONE: > - red_cursor_marshall_inval(rcc, m, (CacheItem *)pipe_item); > + red_marshall_inval(rcc, m, (CacheItem *)pipe_item); > break; > case PIPE_ITEM_TYPE_VERB: > - red_marshall_verb(rcc, ((VerbItem*)pipe_item)->verb); > + red_marshall_verb(rcc, (VerbItem*)pipe_item); > break; > case PIPE_ITEM_TYPE_CURSOR_INIT: > red_reset_cursor_cache(rcc); > @@ -317,7 +318,7 @@ static void > cursor_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item) > break; > case PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE: > red_reset_cursor_cache(rcc); > - red_marshall_verb(rcc, SPICE_MSG_CURSOR_INVAL_ALL); > + red_channel_client_init_send_data(rcc, > SPICE_MSG_CURSOR_INVAL_ALL, NULL); > break; > default: > spice_error("invalid pipe item type"); > @@ -329,7 +330,9 @@ static void > cursor_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item) > > static CursorPipeItem *cursor_pipe_item_ref(CursorPipeItem *item) > { > - spice_assert(item); > + spice_return_val_if_fail(item, NULL); > + spice_return_val_if_fail(item->refs > 0, NULL); > + > item->refs++; > return item; > } > @@ -338,8 +341,11 @@ static CursorPipeItem > *cursor_pipe_item_ref(CursorPipeItem *item) > static void cursor_channel_hold_pipe_item(RedChannelClient *rcc, > PipeItem *item) > { > CursorPipeItem *cursor_pipe_item; > - spice_assert(item); > + > + spice_return_if_fail(item); > + > cursor_pipe_item = SPICE_CONTAINEROF(item, CursorPipeItem, > base); > + /* TODO: refcnt at PipeItem instead ? */ > cursor_pipe_item_ref(cursor_pipe_item); > } > > @@ -357,51 +363,55 @@ static void > cursor_channel_release_item(RedChannelClient *rcc, PipeItem *item, i > } > } > > -CursorChannel* cursor_channel_new(RedWorker *worker, int migrate) > +CursorChannel* cursor_channel_new(RedWorker *worker) > { > - CursorChannel* cursor; > + CursorChannel *cursor; > + RedChannel *channel = NULL; > + ChannelCbs cbs = { > + .on_disconnect = cursor_channel_client_on_disconnect, > + .send_item = cursor_channel_send_item, > + .hold_item = cursor_channel_hold_pipe_item, > + .release_item = cursor_channel_release_item > + }; > > spice_info("create cursor channel"); > - cursor = (CursorChannel *)__new_channel( > - worker, sizeof(CursorChannel), > - SPICE_CHANNEL_CURSOR, > - 0, > - cursor_channel_client_on_disconnect, > - cursor_channel_send_item, > - cursor_channel_hold_pipe_item, > - cursor_channel_release_item, > - red_channel_client_handle_message, > - NULL, > - NULL, > - NULL); > + channel = red_worker_new_channel(worker, sizeof(CursorChannel), > + SPICE_CHANNEL_CURSOR, 0, > + &cbs, > red_channel_client_handle_message); > > + cursor = (CursorChannel *)channel; > cursor->cursor_visible = TRUE; > cursor->mouse_mode = SPICE_MOUSE_MODE_SERVER; > > return cursor; > } > > -CursorChannelClient *cursor_channel_client_new(CommonChannel > *common, > - RedClient *client, > RedsStream *stream, > +CursorChannelClient* cursor_channel_client_new(CursorChannel > *cursor, RedClient *client, RedsStream *stream, > int mig_target, > uint32_t > *common_caps, int num_common_caps, > uint32_t *caps, int > num_caps) > { > + spice_return_val_if_fail(cursor, NULL); > + spice_return_val_if_fail(client, NULL); > + spice_return_val_if_fail(stream, NULL); > + spice_return_val_if_fail(!num_common_caps || common_caps, NULL); > + spice_return_val_if_fail(!num_caps || caps, NULL); > + > CursorChannelClient *ccc = > - (CursorChannelClient*)common_channel_client_create( > - sizeof(CursorChannelClient), common, client, stream, > - mig_target, > - FALSE, > - common_caps, > - num_common_caps, > - caps, > - num_caps); > - > - if (!ccc) { > - return NULL; > - } > + (CursorChannelClient*)common_channel_new_client(&cursor > ->common, > + > sizeof(CursorChannelClient), > + client, > stream, > + mig_target, > + FALSE, > + common_caps, > + > num_common_caps, > + caps, > + num_caps); > + spice_return_val_if_fail(ccc != NULL, NULL); > + > ring_init(&ccc->cursor_cache_lru); > ccc->cursor_cache_available = CLIENT_CURSOR_CACHE_SIZE; > + > return ccc; > } > > @@ -411,7 +421,11 @@ void cursor_channel_process_cmd(CursorChannel > *cursor, RedCursorCmd *cursor_cmd, > CursorItem *cursor_item; > int cursor_show = FALSE; > > - cursor_item = cursor_item_new(cursor_cmd, group_id); > + spice_return_if_fail(cursor); > + spice_return_if_fail(cursor_cmd); > + > + cursor_item = cursor_item_new(red_worker_get_qxl(cursor > ->common.worker), > + cursor_cmd, group_id); > > switch (cursor_cmd->type) { > case QXL_CURSOR_SET: > @@ -431,34 +445,40 @@ void cursor_channel_process_cmd(CursorChannel > *cursor, RedCursorCmd *cursor_cmd, > cursor->cursor_trail_frequency = cursor_cmd > ->u.trail.frequency; > break; > default: > - spice_error("invalid cursor command %u", cursor_cmd->type); > + spice_warning("invalid cursor command %u", cursor_cmd > ->type); > + return; > } > > - if (red_channel_is_connected(&cursor->common.base) && (cursor > ->mouse_mode == SPICE_MOUSE_MODE_SERVER || > - cursor_cmd->type != > QXL_CURSOR_MOVE || cursor_show)) { > - red_channel_pipes_new_add(&cursor->common.base, > new_cursor_pipe_item, > - (void*)cursor_item); > + if (cursor->mouse_mode == SPICE_MOUSE_MODE_SERVER > + || cursor_cmd->type != QXL_CURSOR_MOVE > + || cursor_show) { > + red_channel_pipes_new_add(&cursor->common.base, > + new_cursor_pipe_item, > cursor_item); > } > - cursor_item_unref(red_worker_get_qxl(cursor->common.worker), > cursor_item); > + > + cursor_item_unref(cursor_item); > } > > void cursor_channel_reset(CursorChannel *cursor) > { > + RedChannel *channel = (RedChannel *)cursor; > + > + spice_return_if_fail(cursor); > + > cursor_set_item(cursor, NULL); > cursor->cursor_visible = TRUE; > cursor->cursor_position.x = cursor->cursor_position.y = 0; > cursor->cursor_trail_length = cursor->cursor_trail_frequency = > 0; > > - if (red_channel_is_connected(&cursor->common.base)) { > - red_channel_pipes_add_type(&cursor->common.base, > - > PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE); > + if (red_channel_is_connected(channel)) { > + red_channel_pipes_add_type(&cursor->common.base, > PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE); > if (!cursor->common.during_target_migrate) { > red_pipes_add_verb(&cursor->common.base, > SPICE_MSG_CURSOR_RESET); > } > if (!red_channel_wait_all_sent(&cursor->common.base, > DISPLAY_CLIENT_TIMEOUT)) { > red_channel_apply_clients(&cursor->common.base, > - > red_channel_client_disconnect_if_pending_send); > + > red_channel_client_disconnect_if_pending_send); > } > } > } > diff --git a/server/cursor-channel.h b/server/cursor-channel.h > index 2c19859..e1ef4b6 100644 > --- a/server/cursor-channel.h > +++ b/server/cursor-channel.h > @@ -32,7 +32,14 @@ > #define CURSOR_CACHE_HASH_MASK (CURSOR_CACHE_HASH_SIZE - 1) > #define CURSOR_CACHE_HASH_KEY(id) ((id) & CURSOR_CACHE_HASH_MASK) > > +enum { > + PIPE_ITEM_TYPE_CURSOR = PIPE_ITEM_TYPE_COMMON_LAST, > + PIPE_ITEM_TYPE_CURSOR_INIT, > + PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE, > +}; > + > typedef struct CursorItem { > + QXLInstance *qxl; > uint32_t group_id; > int refs; > RedCursorCmd *red_cursor; > @@ -77,20 +84,20 @@ typedef struct CursorChannel { > > G_STATIC_ASSERT(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE); > > -CursorChannel* cursor_channel_new (RedWorker *worker, > int migrate); > -void cursor_channel_disconnect (RedChannel > *channel); > +CursorChannel* cursor_channel_new (RedWorker *worker); > +void cursor_channel_disconnect (CursorChannel > *cursor); > void cursor_channel_reset (CursorChannel > *cursor); > void cursor_channel_process_cmd (CursorChannel > *cursor, RedCursorCmd *cursor_cmd, > uint32_t group_id); > > -CursorItem* cursor_item_new (RedCursorCmd *cmd, > uint32_t group_id); > -void cursor_item_unref (QXLInstance *qxl, > CursorItem *cursor); > - > +CursorChannelClient* cursor_channel_client_new (CursorChannel > *cursor, > + RedClient *client, > RedsStream *stream, > + int mig_target, > + uint32_t > *common_caps, int num_common_caps, > + uint32_t *caps, int > num_caps); > > -CursorChannelClient *cursor_channel_client_new(CommonChannel > *common, > - RedClient *client, > RedsStream *stream, > - int mig_target, > - uint32_t > *common_caps, int num_common_caps, > - uint32_t *caps, int > num_caps); > +CursorItem* cursor_item_new (QXLInstance *qxl, > RedCursorCmd *cmd, uint32_t group_id); > +CursorItem* cursor_item_ref (CursorItem > *cursor); > +void cursor_item_unref (CursorItem > *cursor); > > #endif /* CURSOR_CHANNEL_H_ */ > diff --git a/server/red_worker.c b/server/red_worker.c > index 0568cdf..9748e19 100644 > --- a/server/red_worker.c > +++ b/server/red_worker.c > @@ -265,6 +265,23 @@ struct SpiceWatch { > void *watch_func_opaque; > }; > > +enum { > + PIPE_ITEM_TYPE_DRAW = PIPE_ITEM_TYPE_COMMON_LAST, > + PIPE_ITEM_TYPE_IMAGE, > + PIPE_ITEM_TYPE_STREAM_CREATE, > + PIPE_ITEM_TYPE_STREAM_CLIP, > + PIPE_ITEM_TYPE_STREAM_DESTROY, > + PIPE_ITEM_TYPE_UPGRADE, > + PIPE_ITEM_TYPE_MIGRATE_DATA, > + PIPE_ITEM_TYPE_PIXMAP_SYNC, > + PIPE_ITEM_TYPE_PIXMAP_RESET, > + PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE, > + PIPE_ITEM_TYPE_CREATE_SURFACE, > + PIPE_ITEM_TYPE_DESTROY_SURFACE, > + PIPE_ITEM_TYPE_MONITORS_CONFIG, > + PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT, > +}; > + > #define MAX_LZ_ENCODERS MAX_CACHE_CLIENTS > > typedef struct SurfaceCreateItem { > @@ -4197,7 +4214,7 @@ static int red_process_cursor(RedWorker > *worker, uint32_t max_pipe_size, int *ri > break; > } > default: > - spice_error("bad command type"); > + spice_warning("bad command type"); > } > n++; > } > @@ -7918,17 +7935,6 @@ static inline void > marshall_qxl_drawable(RedChannelClient *rcc, > red_lossy_marshall_qxl_drawable(display_channel > ->common.worker, rcc, m, dpi); > } > > -static inline void red_marshall_inval(RedChannelClient *rcc, > - SpiceMarshaller > *base_marshaller, CacheItem *cach_item) > -{ > - SpiceMsgDisplayInvalOne inval_one; > - > - red_channel_client_init_send_data(rcc, cach_item->inval_type, > NULL); > - inval_one.id = *(uint64_t *)&cach_item->id; > - > - spice_marshall_msg_cursor_inval_one(base_marshaller, > &inval_one); > -} > - > static void > display_channel_marshall_migrate_data_surfaces(DisplayChannelClient > *dcc, > > SpiceMarshaller *m, > int > lossy) > @@ -8384,9 +8390,6 @@ static void > display_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item > marshall_qxl_drawable(rcc, m, dpi); > break; > } > - case PIPE_ITEM_TYPE_INVAL_ONE: > - red_marshall_inval(rcc, m, (CacheItem *)pipe_item); > - break; > case PIPE_ITEM_TYPE_STREAM_CREATE: { > StreamAgent *agent = SPICE_CONTAINEROF(pipe_item, > StreamAgent, create_item); > red_display_marshall_stream_start(rcc, m, agent); > @@ -8406,7 +8409,7 @@ static void > display_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item > red_display_marshall_upgrade(rcc, m, (UpgradeItem > *)pipe_item); > break; > case PIPE_ITEM_TYPE_VERB: > - red_marshall_verb(rcc, ((VerbItem*)pipe_item)->verb); > + red_marshall_verb(rcc, (VerbItem*)pipe_item); > break; > case PIPE_ITEM_TYPE_MIGRATE_DATA: > display_channel_marshall_migrate_data(rcc, m); > @@ -8422,7 +8425,7 @@ static void > display_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item > break; > case PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE: > red_reset_palette_cache(dcc); > - red_marshall_verb(rcc, > SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES); > + red_channel_client_init_send_data(rcc, > SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES, NULL); > break; > case PIPE_ITEM_TYPE_CREATE_SURFACE: { > SurfaceCreateItem *surface_create = > SPICE_CONTAINEROF(pipe_item, SurfaceCreateItem, > @@ -8908,7 +8911,7 @@ static inline void > flush_cursor_commands(RedWorker *worker) > red_channel_send(channel); > if (red_now() >= end_time) { > spice_warning("flush cursor timeout"); > - cursor_channel_disconnect(channel); > + cursor_channel_disconnect(worker->cursor_channel); > worker->cursor_channel = NULL; > } else { > sleep_count++; > @@ -9520,16 +9523,16 @@ SpiceCoreInterface worker_core = { > .watch_remove = worker_watch_remove, > }; > > -CommonChannelClient *common_channel_client_create(int size, > - CommonChannel > *common, > - RedClient *client, > - RedsStream > *stream, > - int mig_target, > - int > monitor_latency, > - uint32_t > *common_caps, > - int > num_common_caps, > - uint32_t *caps, > - int num_caps) > +CommonChannelClient *common_channel_new_client(CommonChannel > *common, > + int size, > + RedClient *client, > + RedsStream *stream, > + int mig_target, > + int monitor_latency, > + uint32_t > *common_caps, > + int num_common_caps, > + uint32_t *caps, > + int num_caps) > { > RedChannelClient *rcc = > red_channel_client_create(size, &common->base, client, > stream, monitor_latency, > @@ -9557,8 +9560,8 @@ DisplayChannelClient > *display_channel_client_create(CommonChannel *common, > uint32_t *caps, > int num_caps) > { > DisplayChannelClient *dcc = > - (DisplayChannelClient*)common_channel_client_create( > - sizeof(DisplayChannelClient), common, client, stream, > + (DisplayChannelClient*)common_channel_new_client( > + common, sizeof(DisplayChannelClient), client, stream, > mig_target, > TRUE, > common_caps, num_common_caps, > @@ -9572,38 +9575,30 @@ DisplayChannelClient > *display_channel_client_create(CommonChannel *common, > return dcc; > } > > -RedChannel *__new_channel(RedWorker *worker, int size, uint32_t > channel_type, > - int migration_flags, > - channel_disconnect_proc on_disconnect, > - channel_send_pipe_item_proc send_item, > - channel_hold_pipe_item_proc hold_item, > - channel_release_pipe_item_proc > release_item, > - channel_handle_parsed_proc handle_parsed, > - channel_handle_migrate_flush_mark_proc > handle_migrate_flush_mark, > - channel_handle_migrate_data_proc > handle_migrate_data, > - > channel_handle_migrate_data_get_serial_proc migrate_get_serial) > +RedChannel *red_worker_new_channel(RedWorker *worker, int size, > + uint32_t channel_type, int > migration_flags, > + ChannelCbs *channel_cbs, > + channel_handle_parsed_proc > handle_parsed) > { > RedChannel *channel = NULL; > CommonChannel *common; > - ChannelCbs channel_cbs = { NULL, }; > - > - channel_cbs.config_socket = common_channel_config_socket; > - channel_cbs.on_disconnect = on_disconnect; > - channel_cbs.send_item = send_item; > - channel_cbs.hold_item = hold_item; > - channel_cbs.release_item = release_item; > - channel_cbs.alloc_recv_buf = common_alloc_recv_buf; > - channel_cbs.release_recv_buf = common_release_recv_buf; > - channel_cbs.handle_migrate_flush_mark = > handle_migrate_flush_mark; > - channel_cbs.handle_migrate_data = handle_migrate_data; > - channel_cbs.handle_migrate_data_get_serial = migrate_get_serial; > + > + spice_return_val_if_fail(worker, NULL); > + spice_return_val_if_fail(channel_cbs, NULL); > + spice_return_val_if_fail(!channel_cbs->config_socket, NULL); > + spice_return_val_if_fail(!channel_cbs->alloc_recv_buf, NULL); > + spice_return_val_if_fail(!channel_cbs->release_recv_buf, NULL); > + > + channel_cbs->config_socket = common_channel_config_socket; > + channel_cbs->alloc_recv_buf = common_alloc_recv_buf; > + channel_cbs->release_recv_buf = common_release_recv_buf; > > channel = red_channel_create_parser(size, &worker_core, > channel_type, worker->qxl > ->id, > TRUE /* handle_acks */, > > spice_get_client_channel_parser(channel_type, NULL), > handle_parsed, > - &channel_cbs, > + channel_cbs, > migration_flags); > common = (CommonChannel *)channel; > if (!channel) { > @@ -9723,7 +9718,6 @@ static void > display_channel_client_release_item_before_push(DisplayChannelClient > free(item); > break; > } > - case PIPE_ITEM_TYPE_INVAL_ONE: > case PIPE_ITEM_TYPE_VERB: > case PIPE_ITEM_TYPE_MIGRATE_DATA: > case PIPE_ITEM_TYPE_PIXMAP_SYNC: > @@ -9753,25 +9747,26 @@ static void > display_channel_release_item(RedChannelClient *rcc, PipeItem *item, > static void display_channel_create(RedWorker *worker, int migrate) > { > DisplayChannel *display_channel; > + ChannelCbs cbs = { > + .on_disconnect = display_channel_client_on_disconnect, > + .send_item = display_channel_send_item, > + .hold_item = display_channel_hold_pipe_item, > + .release_item = display_channel_release_item, > + .handle_migrate_flush_mark = > display_channel_handle_migrate_mark, > + .handle_migrate_data = display_channel_handle_migrate_data, > + .handle_migrate_data_get_serial = > display_channel_handle_migrate_data_get_serial > + }; > > if (worker->display_channel) { > return; > } > > spice_info("create display channel"); > - if (!(worker->display_channel = (DisplayChannel *)__new_channel( > + if (!(worker->display_channel = (DisplayChannel > *)red_worker_new_channel( > worker, sizeof(*display_channel), > SPICE_CHANNEL_DISPLAY, > SPICE_MIGRATE_NEED_FLUSH | > SPICE_MIGRATE_NEED_DATA_TRANSFER, > - display_channel_client_on_disconnect, > - display_channel_send_item, > - display_channel_hold_pipe_item, > - display_channel_release_item, > - display_channel_handle_message, > - display_channel_handle_migrate_mark, > - display_channel_handle_migrate_data, > - display_channel_handle_migrate_data_get_serial > - ))) { > + &cbs, display_channel_handle_message))) { > spice_warning("failed to create display channel"); > return; > } > @@ -9906,29 +9901,6 @@ static void > handle_new_display_channel(RedWorker *worker, RedClient *client, Red > on_new_display_channel_client(dcc); > } > > -static void red_migrate_cursor(RedWorker *worker, RedChannelClient > *rcc) > -{ > - if (red_channel_client_is_connected(rcc)) { > - red_channel_client_pipe_add_type(rcc, > - > PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE); > - red_channel_client_default_migrate(rcc); > - } > -} > - > -static void on_new_cursor_channel(RedWorker *worker, > RedChannelClient *rcc) > -{ > - CursorChannel *channel = worker->cursor_channel; > - > - spice_assert(channel); > - red_channel_client_ack_zero_messages_window(rcc); > - red_channel_client_push_set_ack(rcc); > - // TODO: why do we check for context.canvas? defer this to after > display cc is connected > - // and test it's canvas? this is just a test to see if there is > an active renderer? > - if (worker->surfaces[0].context.canvas && !channel > ->common.during_target_migrate) { > - red_channel_client_pipe_add_type(rcc, > PIPE_ITEM_TYPE_CURSOR_INIT); > - } > -} > - > static void red_connect_cursor(RedWorker *worker, RedClient *client, > RedsStream *stream, > int migrate, > uint32_t *common_caps, int > num_common_caps, > @@ -9937,24 +9909,28 @@ static void red_connect_cursor(RedWorker > *worker, RedClient *client, RedsStream > CursorChannel *channel; > CursorChannelClient *ccc; > > - if (worker->cursor_channel == NULL) { > - spice_warning("cursor channel was not created"); > - return; > - } > + spice_return_if_fail(worker->cursor_channel != NULL); > + > channel = worker->cursor_channel; > spice_info("add cursor channel client"); > - ccc = cursor_channel_client_new(&channel->common, client, > stream, > + ccc = cursor_channel_client_new(channel, client, stream, > migrate, > common_caps, num_common_caps, > caps, num_caps); > - if (!ccc) { > - return; > - } > + spice_return_if_fail(ccc != NULL); > #ifdef RED_STATISTICS > channel->stat = stat_add_node(worker->stat, "cursor_channel", > TRUE); > channel->common.base.out_bytes_counter = > stat_add_counter(channel->stat, "out_bytes", TRUE); > #endif > - on_new_cursor_channel(worker, &ccc->common.base); > + > + RedChannelClient *rcc = &ccc->common.base; > + red_channel_client_ack_zero_messages_window(rcc); > + red_channel_client_push_set_ack(rcc); > + // TODO: why do we check for context.canvas? defer this to after > display cc is connected > + // and test it's canvas? this is just a test to see if there is > an active renderer? > + if (worker->surfaces[0].context.canvas && !channel > ->common.during_target_migrate) { > + red_channel_client_pipe_add_type(rcc, > PIPE_ITEM_TYPE_CURSOR_INIT); > + } > } > > static void surface_dirty_region_to_rects(RedSurface *surface, > @@ -10296,10 +10272,9 @@ static void > dev_create_primary_surface(RedWorker *worker, uint32_t surface_id, > red_channel_push(&worker->display_channel->common.base); > } > > - if (cursor_is_connected(worker) && !worker->cursor_channel > ->common.during_target_migrate) { > + if (!worker->cursor_channel->common.during_target_migrate) > red_channel_pipes_add_type(&worker->cursor_channel > ->common.base, > PIPE_ITEM_TYPE_CURSOR_INIT); > - } > } > > void handle_dev_create_primary_surface(void *opaque, void *payload) > @@ -10498,7 +10473,9 @@ void handle_dev_oom(void *opaque, void > *payload) > > void handle_dev_reset_cursor(void *opaque, void *payload) > { > - cursor_channel_reset(((RedWorker*)opaque)->cursor_channel); > + RedWorker *worker = opaque; > + > + cursor_channel_reset(worker->cursor_channel); > } > > void handle_dev_reset_image_cache(void *opaque, void *payload) > @@ -10642,10 +10619,12 @@ void handle_dev_cursor_channel_create(void > *opaque, void *payload) > RedWorker *worker = opaque; > RedChannel *red_channel; > > - // TODO: handle seemless migration. Temp, setting migrate to > FALSE > if (!worker->cursor_channel) { > - worker->cursor_channel = cursor_channel_new(worker, FALSE); > + worker->cursor_channel = cursor_channel_new(worker); > + } else { > + spice_warning("cursor channel already created"); > } > + > red_channel = &worker->cursor_channel->common.base; > send_data(worker->channel, &red_channel, sizeof(RedChannel *)); > } > @@ -10672,19 +10651,20 @@ void handle_dev_cursor_disconnect(void > *opaque, void *payload) > RedChannelClient *rcc = msg->rcc; > > spice_info("disconnect cursor client"); > - spice_assert(rcc); > red_channel_client_disconnect(rcc); > } > > void handle_dev_cursor_migrate(void *opaque, void *payload) > { > RedWorkerMessageCursorMigrate *msg = payload; > - RedWorker *worker = opaque; > RedChannelClient *rcc = msg->rcc; > > spice_info("migrate cursor client"); > - spice_assert(rcc); > - red_migrate_cursor(worker, rcc); > + if (!red_channel_client_is_connected(rcc)) > + return; > + > + red_channel_client_pipe_add_type(rcc, > PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE); > + red_channel_client_default_migrate(rcc); > } > > void handle_dev_set_compression(void *opaque, void *payload) > @@ -10761,8 +10741,10 @@ void handle_dev_set_mouse_mode(void *opaque, > void *payload) > RedWorkerMessageSetMouseMode *msg = payload; > RedWorker *worker = opaque; > > + spice_info("mouse mode %u", msg->mode); > + spice_return_if_fail(worker->cursor_channel); > + > worker->cursor_channel->mouse_mode = msg->mode; > - spice_info("mouse mode %u", worker->cursor_channel->mouse_mode); > } > > void handle_dev_add_memslot_async(void *opaque, void *payload) > diff --git a/server/red_worker.h b/server/red_worker.h > index 502283e..df52abd 100644 > --- a/server/red_worker.h > +++ b/server/red_worker.h > @@ -48,25 +48,10 @@ typedef struct CommonChannel { > } CommonChannel; > > enum { > - PIPE_ITEM_TYPE_DRAW = PIPE_ITEM_TYPE_CHANNEL_BASE, > + PIPE_ITEM_TYPE_VERB = PIPE_ITEM_TYPE_CHANNEL_BASE, > PIPE_ITEM_TYPE_INVAL_ONE, > - PIPE_ITEM_TYPE_CURSOR, > - PIPE_ITEM_TYPE_CURSOR_INIT, > - PIPE_ITEM_TYPE_IMAGE, > - PIPE_ITEM_TYPE_STREAM_CREATE, > - PIPE_ITEM_TYPE_STREAM_CLIP, > - PIPE_ITEM_TYPE_STREAM_DESTROY, > - PIPE_ITEM_TYPE_UPGRADE, > - PIPE_ITEM_TYPE_VERB, > - PIPE_ITEM_TYPE_MIGRATE_DATA, > - PIPE_ITEM_TYPE_PIXMAP_SYNC, > - PIPE_ITEM_TYPE_PIXMAP_RESET, > - PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE, > - PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE, > - PIPE_ITEM_TYPE_CREATE_SURFACE, > - PIPE_ITEM_TYPE_DESTROY_SURFACE, > - PIPE_ITEM_TYPE_MONITORS_CONFIG, > - PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT, > + > + PIPE_ITEM_TYPE_COMMON_LAST > }; > > typedef struct VerbItem { > @@ -74,10 +59,9 @@ typedef struct VerbItem { > uint16_t verb; > } VerbItem; > > -static inline void red_marshall_verb(RedChannelClient *rcc, uint16_t > verb) > +static inline void red_marshall_verb(RedChannelClient *rcc, VerbItem > *item) > { > - spice_assert(rcc); > - red_channel_client_init_send_data(rcc, verb, NULL); > + red_channel_client_init_send_data(rcc, item->verb, NULL); > } > > static inline void red_pipe_add_verb(RedChannelClient* rcc, uint16_t > verb) > @@ -118,26 +102,20 @@ RedWorker* red_worker_new(QXLInstance *qxl, > RedDispatcher *red_dispatcher); > bool red_worker_run(RedWorker *worker); > QXLInstance* red_worker_get_qxl(RedWorker *worker); > > -CommonChannelClient *common_channel_client_create(int size, > - CommonChannel > *common, > - RedClient *client, > - RedsStream > *stream, > - int mig_target, > - int > monitor_latency, > - uint32_t > *common_caps, > - int > num_common_caps, > - uint32_t *caps, > - int num_caps); > - > -RedChannel *__new_channel(RedWorker *worker, int size, uint32_t > channel_type, > - int migration_flags, > - channel_disconnect_proc on_disconnect, > - channel_send_pipe_item_proc send_item, > - channel_hold_pipe_item_proc hold_item, > - channel_release_pipe_item_proc > release_item, > - channel_handle_parsed_proc handle_parsed, > - channel_handle_migrate_flush_mark_proc > handle_migrate_flush_mark, > - channel_handle_migrate_data_proc > handle_migrate_data, > - > channel_handle_migrate_data_get_serial_proc migrate_get_serial); > +RedChannel *red_worker_new_channel(RedWorker *worker, int size, > + uint32_t channel_type, int > migration_flags, > + ChannelCbs *channel_cbs, > + channel_handle_parsed_proc > handle_parsed); > + > +CommonChannelClient *common_channel_new_client(CommonChannel > *common, > + int size, > + RedClient *client, > + RedsStream *stream, > + int mig_target, > + int monitor_latency, > + uint32_t > *common_caps, > + int num_common_caps, > + uint32_t *caps, > + int num_caps); > > #endif _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel