[Spice-devel] [PATCH 07/10] server: make cursor channel private

Frediano Ziglio fziglio at redhat.com
Wed Nov 4 00:46:01 PST 2015


> 
> This patch causes my v0.30-9-g17a6b8a vintage spice-gtk client stop
> having a cursor in an Xspice session.
> 
> The spice-html5 client cursor continues to work fine.
> 
> I've bisected it, but not really explored further; if there are
> easy/obvious things for me to check, let me know.
> 
> Cheers,
> 
> Jeremy
> 

Hi Jeremy,
  do you have some logs? Hope they can shed some light.

Frediano


> On 11/02/2015 03:56 AM, Frediano Ziglio wrote:
> > From: Marc-André Lureau <marcandre.lureau at gmail.com>
> > 
> > ---
> >  server/cursor-channel.c | 24 +++++++++++-
> >  server/cursor-channel.h | 18 ++-------
> >  server/red_channel.c    | 12 ++++++
> >  server/red_channel.h    |  6 +++
> >  server/red_worker.c     | 98
> >  ++++++++++++++++++++++---------------------------
> >  server/red_worker.h     |  5 +++
> >  6 files changed, 92 insertions(+), 71 deletions(-)
> > 
> > diff --git a/server/cursor-channel.c b/server/cursor-channel.c
> > index 6a1fcea..3ae7756 100644
> > --- a/server/cursor-channel.c
> > +++ b/server/cursor-channel.c
> > @@ -19,6 +19,21 @@
> >  #include "common/generated_server_marshallers.h"
> >  #include "cursor-channel.h"
> >  
> > +struct CursorChannel {
> > +    CommonChannel common; // Must be the first thing
> > +
> > +    CursorItem *item;
> > +    int cursor_visible;
> > +    SpicePoint16 cursor_position;
> > +    uint16_t cursor_trail_length;
> > +    uint16_t cursor_trail_frequency;
> > +    uint32_t mouse_mode;
> > +
> > +#ifdef RED_STATISTICS
> > +    StatNodeRef stat;
> > +#endif
> > +};
> > +
> >  #define RCC_TO_CCC(rcc) SPICE_CONTAINEROF((rcc), CursorChannelClient,
> >  common.base)
> >  
> >  #define CLIENT_CURSOR_CACHE
> > @@ -372,7 +387,7 @@ CursorChannel* cursor_channel_new(RedWorker *worker)
> >      };
> >  
> >      spice_info("create cursor channel");
> > -    channel = red_worker_new_channel(worker, sizeof(CursorChannel),
> > +    channel = red_worker_new_channel(worker, sizeof(CursorChannel),
> > "cursor_channel",
> >                                       SPICE_CHANNEL_CURSOR, 0,
> >                                       &cbs,
> >                                       red_channel_client_handle_message);
> >  
> > @@ -480,3 +495,10 @@ void cursor_channel_reset(CursorChannel *cursor)
> >          }
> >      }
> >  }
> > +
> > +void cursor_channel_set_mouse_mode(CursorChannel *cursor, uint32_t mode)
> > +{
> > +    spice_return_if_fail(cursor);
> > +
> > +    cursor->mouse_mode = mode;
> > +}
> > diff --git a/server/cursor-channel.h b/server/cursor-channel.h
> > index 1639cf9..d5e5b13 100644
> > --- a/server/cursor-channel.h
> > +++ b/server/cursor-channel.h
> > @@ -38,6 +38,8 @@ enum {
> >      PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE,
> >  };
> >  
> > +typedef struct CursorChannel CursorChannel;
> > +
> >  typedef struct CursorItem {
> >      QXLInstance *qxl;
> >      uint32_t group_id;
> > @@ -67,21 +69,6 @@ typedef struct CursorChannelClient {
> >      uint32_t cursor_cache_items;
> >  } CursorChannelClient;
> >  
> > -typedef struct CursorChannel {
> > -    CommonChannel common; // Must be the first thing
> > -
> > -    CursorItem *item;
> > -    int cursor_visible;
> > -    SpicePoint16 cursor_position;
> > -    uint16_t cursor_trail_length;
> > -    uint16_t cursor_trail_frequency;
> > -    uint32_t mouse_mode;
> > -
> > -#ifdef RED_STATISTICS
> > -    StatNodeRef stat;
> > -#endif
> > -} CursorChannel;
> > -
> >  G_STATIC_ASSERT(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE);
> >  
> >  CursorChannel*       cursor_channel_new         (RedWorker *worker);
> > @@ -89,6 +76,7 @@ void                 cursor_channel_disconnect
> > (CursorChannel *cursor_channel);
> >  void                 cursor_channel_reset       (CursorChannel *cursor);
> >  void                 cursor_channel_process_cmd (CursorChannel *cursor,
> >  RedCursorCmd *cursor_cmd,
> >                                                   uint32_t group_id);
> > +void                 cursor_channel_set_mouse_mode(CursorChannel *cursor,
> > uint32_t mode);
> >  
> >  CursorChannelClient* cursor_channel_client_new(CursorChannel *cursor,
> >                                                 RedClient *client,
> >                                                 RedsStream *stream,
> > diff --git a/server/red_channel.c b/server/red_channel.c
> > index 34aa9dc..7330ae2 100644
> > --- a/server/red_channel.c
> > +++ b/server/red_channel.c
> > @@ -1151,9 +1151,21 @@ RedChannel *red_channel_create_parser(int size,
> >      }
> >      channel->incoming_cb.handle_parsed =
> >      (handle_parsed_proc)handle_parsed;
> >      channel->incoming_cb.parser = parser;
> > +
> >      return channel;
> >  }
> >  
> > +void red_channel_set_stat_node(RedChannel *channel, StatNodeRef stat)
> > +{
> > +    spice_return_if_fail(channel != NULL);
> > +    spice_return_if_fail(channel->stat == 0);
> > +
> > +#ifdef RED_STATISTICS
> > +    channel->stat = stat;
> > +    channel->out_bytes_counter = stat_add_counter(stat, "out_bytes",
> > TRUE);
> > +#endif
> > +}
> > +
> >  void red_channel_register_client_cbs(RedChannel *channel, ClientCbs
> >  *client_cbs)
> >  {
> >      spice_assert(client_cbs->connect || channel->type ==
> >      SPICE_CHANNEL_MAIN);
> > diff --git a/server/red_channel.h b/server/red_channel.h
> > index 1f1538e..201a4d2 100644
> > --- a/server/red_channel.h
> > +++ b/server/red_channel.h
> > @@ -32,6 +32,7 @@
> >  #include "red_common.h"
> >  #include "demarshallers.h"
> >  #include "reds_stream.h"
> > +#include "stat.h"
> >  
> >  #define MAX_SEND_BUFS 1000
> >  #define CLIENT_ACK_WINDOW 20
> > @@ -127,6 +128,7 @@ typedef struct OutgoingHandler {
> >  
> >  /* Red Channel interface */
> >  
> > +typedef struct RedsStream RedsStream;
> >  typedef struct RedChannel RedChannel;
> >  typedef struct RedChannelClient RedChannelClient;
> >  typedef struct RedClient RedClient;
> > @@ -335,10 +337,13 @@ struct RedChannel {
> >      // TODO: when different channel_clients are in different threads from
> >      Channel -> need to protect!
> >      pthread_t thread_id;
> >  #ifdef RED_STATISTICS
> > +    StatNodeRef stat;
> >      uint64_t *out_bytes_counter;
> >  #endif
> >  };
> >  
> > +#define RED_CHANNEL(Channel) ((RedChannel *)(Channel))
> > +
> >  /*
> >   * When an error occurs over a channel, we treat it as a warning
> >   * for spice-server and shutdown the channel.
> > @@ -370,6 +375,7 @@ RedChannel *red_channel_create_parser(int size,
> >                                 channel_handle_parsed_proc handle_parsed,
> >                                 ChannelCbs *channel_cbs,
> >                                 uint32_t migration_flags);
> > +void red_channel_set_stat_node(RedChannel *channel, StatNodeRef stat);
> >  
> >  void red_channel_register_client_cbs(RedChannel *channel, ClientCbs
> >  *client_cbs);
> >  // caps are freed when the channel is destroyed
> > diff --git a/server/red_worker.c b/server/red_worker.c
> > index 868de94..a99da27 100644
> > --- a/server/red_worker.c
> > +++ b/server/red_worker.c
> > @@ -390,7 +390,6 @@ struct DisplayChannel {
> >      RedCompressBuf *free_compress_bufs;
> >  
> >  #ifdef RED_STATISTICS
> > -    StatNodeRef stat;
> >      uint64_t *cache_hits_counter;
> >      uint64_t *add_to_cache_counter;
> >      uint64_t *non_cache_counter;
> > @@ -1034,8 +1033,8 @@ static int display_is_connected(RedWorker *worker)
> >  
> >  static int cursor_is_connected(RedWorker *worker)
> >  {
> > -    return (worker->cursor_channel && red_channel_is_connected(
> > -        &worker->cursor_channel->common.base));
> > +    return worker->cursor_channel &&
> > +        red_channel_is_connected(RED_CHANNEL(worker->cursor_channel));
> >  }
> >  
> >  static void put_drawable_pipe_item(DrawablePipeItem *dpi)
> > @@ -1294,7 +1293,7 @@ static inline void red_destroy_surface_item(RedWorker
> > *worker,
> >          return;
> >      }
> >      dcc->surface_client_created[surface_id] = FALSE;
> > -    channel = &worker->display_channel->common.base;
> > +    channel = RED_CHANNEL(worker->display_channel);
> >      destroy = get_surface_destroy_item(channel, surface_id);
> >      red_channel_client_pipe_add(&dcc->common.base, &destroy->pipe_item);
> >  }
> > @@ -2991,7 +2990,7 @@ static inline int red_current_add_equal(RedWorker
> > *worker, DrawItem *item, TreeI
> >  
> >              /* sending the drawable to clients that already received
> >               * (or will receive) other_drawable */
> > -            worker_ring_item =
> > ring_get_head(&worker->display_channel->common.base.clients);
> > +            worker_ring_item =
> > ring_get_head(&RED_CHANNEL(worker->display_channel)->clients);
> >              dpi_ring_item = ring_get_head(&other_drawable->pipes);
> >              /* dpi contains a sublist of dcc's, ordered the same */
> >              while (worker_ring_item) {
> > @@ -3000,7 +2999,7 @@ static inline int red_current_add_equal(RedWorker
> > *worker, DrawItem *item, TreeI
> >                  dpi = SPICE_CONTAINEROF(dpi_ring_item, DrawablePipeItem,
> >                  base);
> >                  while (worker_ring_item && (!dpi || dcc != dpi->dcc)) {
> >                      red_pipe_add_drawable(dcc, drawable);
> > -                    worker_ring_item =
> > ring_next(&worker->display_channel->common.base.clients,
> > +                    worker_ring_item =
> > ring_next(&RED_CHANNEL(worker->display_channel)->clients,
> >                                                   worker_ring_item);
> >                      dcc = SPICE_CONTAINEROF(worker_ring_item,
> >                      DisplayChannelClient,
> >                                              common.base.channel_link);
> > @@ -3010,7 +3009,7 @@ static inline int red_current_add_equal(RedWorker
> > *worker, DrawItem *item, TreeI
> >                      dpi_ring_item = ring_next(&other_drawable->pipes,
> >                      dpi_ring_item);
> >                  }
> >                  if (worker_ring_item) {
> > -                    worker_ring_item =
> > ring_next(&worker->display_channel->common.base.clients,
> > +                    worker_ring_item =
> > ring_next(&RED_CHANNEL(worker->display_channel)->clients,
> >                                                   worker_ring_item);
> >                  }
> >              }
> > @@ -4144,7 +4143,7 @@ static int red_process_cursor(RedWorker *worker,
> > uint32_t max_pipe_size, int *ri
> >  
> >      *ring_is_empty = FALSE;
> >      while (!cursor_is_connected(worker) ||
> > -           red_channel_min_pipe_size(&worker->cursor_channel->common.base)
> > <= max_pipe_size) {
> > +           red_channel_min_pipe_size(RED_CHANNEL(worker->cursor_channel))
> > <= max_pipe_size) {
> >          if (!worker->qxl->st->qif->get_cursor_command(worker->qxl,
> >          &ext_cmd)) {
> >              *ring_is_empty = TRUE;
> >              if (worker->cursor_poll_tries < CMD_RING_POLL_RETRIES) {
> > @@ -4206,7 +4205,7 @@ static int red_process_commands(RedWorker *worker,
> > uint32_t max_pipe_size, int *
> >      *ring_is_empty = FALSE;
> >      while (!display_is_connected(worker) ||
> >             // TODO: change to average pipe size?
> > -
> > red_channel_min_pipe_size(&worker->display_channel->common.base)
> > <= max_pipe_size) {
> > +           red_channel_min_pipe_size(RED_CHANNEL(worker->display_channel))
> > <= max_pipe_size) {
> >          if (!worker->qxl->st->qif->get_command(worker->qxl, &ext_cmd)) {
> >              *ring_is_empty = TRUE;;
> >              if (worker->display_poll_tries < CMD_RING_POLL_RETRIES) {
> > @@ -4351,7 +4350,7 @@ static ImageItem
> > *red_add_surface_area_image(DisplayChannelClient *dcc, int surf
> >  {
> >      DisplayChannel *display_channel = DCC_TO_DC(dcc);
> >      RedWorker *worker = display_channel->common.worker;
> > -    RedChannel *channel = &display_channel->common.base;
> > +    RedChannel *channel = RED_CHANNEL(display_channel);
> >      RedSurface *surface = &worker->surfaces[surface_id];
> >      SpiceCanvas *canvas = surface->context.canvas;
> >      ImageItem *item;
> > @@ -4530,7 +4529,7 @@ static void
> > red_display_reset_compress_buf(DisplayChannelClient *dcc)
> >  
> >  static void red_display_destroy_compress_bufs(DisplayChannel
> >  *display_channel)
> >  {
> > -
> > spice_assert(!red_channel_is_connected(&display_channel->common.base));
> > +    spice_assert(!red_channel_is_connected(RED_CHANNEL(display_channel)));
> >      while (display_channel->free_compress_bufs) {
> >          RedCompressBuf *buf = display_channel->free_compress_bufs;
> >          display_channel->free_compress_bufs = buf->next;
> > @@ -4719,7 +4718,7 @@ static void
> > red_display_clear_glz_drawables(DisplayChannel *display_channel)
> >      if (!display_channel) {
> >          return;
> >      }
> > -    DCC_FOREACH_SAFE(link, next, dcc, &display_channel->common.base) {
> > +    DCC_FOREACH_SAFE(link, next, dcc, RED_CHANNEL(display_channel)) {
> >          red_display_client_clear_glz_drawables(dcc);
> >      }
> >  }
> > @@ -8359,10 +8358,10 @@ static void
> > display_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item
> >  static inline void red_push(RedWorker *worker)
> >  {
> >      if (worker->cursor_channel) {
> > -        red_channel_push(&worker->cursor_channel->common.base);
> > +        red_channel_push(RED_CHANNEL(worker->cursor_channel));
> >      }
> >      if (worker->display_channel) {
> > -        red_channel_push(&worker->display_channel->common.base);
> > +        red_channel_push(RED_CHANNEL(worker->display_channel));
> >      }
> >  }
> >  
> > @@ -8728,7 +8727,7 @@ static inline void red_create_surface(RedWorker
> > *worker, uint32_t surface_id, ui
> >  
> >  static inline void flush_display_commands(RedWorker *worker)
> >  {
> > -    RedChannel *display_red_channel =
> > &worker->display_channel->common.base;
> > +    RedChannel *display_red_channel =
> > RED_CHANNEL(worker->display_channel);
> >  
> >      for (;;) {
> >          uint64_t end_time;
> > @@ -8740,7 +8739,7 @@ static inline void flush_display_commands(RedWorker
> > *worker)
> >          }
> >  
> >          while (red_process_commands(worker, MAX_PIPE_SIZE,
> >          &ring_is_empty)) {
> > -            red_channel_push(&worker->display_channel->common.base);
> > +            red_channel_push(RED_CHANNEL(worker->display_channel));
> >          }
> >  
> >          if (ring_is_empty) {
> > @@ -8749,7 +8748,7 @@ static inline void flush_display_commands(RedWorker
> > *worker)
> >          end_time = red_get_monotonic_time() + DISPLAY_CLIENT_TIMEOUT;
> >          int sleep_count = 0;
> >          for (;;) {
> > -            red_channel_push(&worker->display_channel->common.base);
> > +            red_channel_push(RED_CHANNEL(worker->display_channel));
> >              if (!display_is_connected(worker) ||
> >                  red_channel_max_pipe_size(display_red_channel) <=
> >                  MAX_PIPE_SIZE) {
> >                  break;
> > @@ -8772,7 +8771,7 @@ static inline void flush_display_commands(RedWorker
> > *worker)
> >  
> >  static inline void flush_cursor_commands(RedWorker *worker)
> >  {
> > -    RedChannel *cursor_red_channel = &worker->cursor_channel->common.base;
> > +    RedChannel *cursor_red_channel = RED_CHANNEL(worker->cursor_channel);
> >  
> >      for (;;) {
> >          uint64_t end_time;
> > @@ -8784,7 +8783,7 @@ static inline void flush_cursor_commands(RedWorker
> > *worker)
> >          }
> >  
> >          while (red_process_cursor(worker, MAX_PIPE_SIZE, &ring_is_empty))
> >          {
> > -            red_channel_push(&worker->cursor_channel->common.base);
> > +            red_channel_push(RED_CHANNEL(worker->cursor_channel));
> >          }
> >  
> >          if (ring_is_empty) {
> > @@ -8793,7 +8792,7 @@ static inline void flush_cursor_commands(RedWorker
> > *worker)
> >          end_time = red_get_monotonic_time() + DISPLAY_CLIENT_TIMEOUT;
> >          int sleep_count = 0;
> >          for (;;) {
> > -            red_channel_push(&worker->cursor_channel->common.base);
> > +            red_channel_push(RED_CHANNEL(worker->cursor_channel));
> >              if (!cursor_is_connected(worker)
> >                  || red_channel_min_pipe_size(cursor_red_channel) <=
> >                  || MAX_PIPE_SIZE) {
> >                  break;
> > @@ -9062,7 +9061,7 @@ static int
> > display_channel_handle_migrate_glz_dictionary(DisplayChannelClient *d
> >  static int display_channel_handle_migrate_mark(RedChannelClient *rcc)
> >  {
> >      DisplayChannel *display_channel = SPICE_CONTAINEROF(rcc->channel,
> >      DisplayChannel, common.base);
> > -    RedChannel *channel = &display_channel->common.base;
> > +    RedChannel *channel = RED_CHANNEL(display_channel);
> >  
> >      red_channel_pipes_add_type(channel, PIPE_ITEM_TYPE_MIGRATE_DATA);
> >      return TRUE;
> > @@ -9446,6 +9445,7 @@ CommonChannelClient
> > *common_channel_new_client(CommonChannel *common,
> >  
> >  
> >  RedChannel *red_worker_new_channel(RedWorker *worker, int size,
> > +                                   const char *name,
> >                                     uint32_t channel_type, int
> >                                     migration_flags,
> >                                     ChannelCbs *channel_cbs,
> >                                     channel_handle_parsed_proc
> >                                     handle_parsed)
> > @@ -9470,16 +9470,12 @@ RedChannel *red_worker_new_channel(RedWorker
> > *worker, int size,
> >                                          handle_parsed,
> >                                          channel_cbs,
> >                                          migration_flags);
> > +    spice_return_val_if_fail(channel, NULL);
> > +    red_channel_set_stat_node(channel, stat_add_node(worker->stat, name,
> > TRUE));
> > +
> >      common = (CommonChannel *)channel;
> > -    if (!channel) {
> > -        goto error;
> > -    }
> >      common->worker = worker;
> >      return channel;
> > -
> > -error:
> > -    free(channel);
> > -    return NULL;
> >  }
> >  
> >  static void display_channel_hold_pipe_item(RedChannelClient *rcc, PipeItem
> >  *item)
> > @@ -9633,7 +9629,7 @@ static void display_channel_create(RedWorker *worker,
> > int migrate)
> >  
> >      spice_info("create display channel");
> >      if (!(worker->display_channel = (DisplayChannel
> >      *)red_worker_new_channel(
> > -            worker, sizeof(*display_channel),
> > +            worker, sizeof(*display_channel), "display_channel",
> >              SPICE_CHANNEL_DISPLAY,
> >              SPICE_MIGRATE_NEED_FLUSH | SPICE_MIGRATE_NEED_DATA_TRANSFER,
> >              &cbs, display_channel_handle_message))) {
> > @@ -9642,14 +9638,12 @@ static void display_channel_create(RedWorker
> > *worker, int migrate)
> >      }
> >      display_channel = worker->display_channel;
> >  #ifdef RED_STATISTICS
> > -    display_channel->stat = stat_add_node(worker->stat, "display_channel",
> > TRUE);
> > -    display_channel->common.base.out_bytes_counter =
> > stat_add_counter(display_channel->stat,
> > -
> > "out_bytes",
> > TRUE);
> > -    display_channel->cache_hits_counter =
> > stat_add_counter(display_channel->stat,
> > +    RedChannel *channel = RED_CHANNEL(display_channel);
> > +    display_channel->cache_hits_counter = stat_add_counter(channel->stat,
> >                                                             "cache_hits",
> >                                                             TRUE);
> > -    display_channel->add_to_cache_counter =
> > stat_add_counter(display_channel->stat,
> > +    display_channel->add_to_cache_counter =
> > stat_add_counter(channel->stat,
> >                                                               "add_to_cache",
> >                                                               TRUE);
> > -    display_channel->non_cache_counter =
> > stat_add_counter(display_channel->stat,
> > +    display_channel->non_cache_counter = stat_add_counter(channel->stat,
> >                                                            "non_cache",
> >                                                            TRUE);
> >  #endif
> >      stat_compress_init(&display_channel->lz_stat, lz_stat_name);
> > @@ -9692,14 +9686,14 @@ static void guest_set_client_capabilities(RedWorker
> > *worker)
> >          return;
> >      }
> >      if ((worker->display_channel == NULL) ||
> > -        (worker->display_channel->common.base.clients_num == 0)) {
> > +        (RED_CHANNEL(worker->display_channel)->clients_num == 0)) {
> >          worker->qxl->st->qif->set_client_capabilities(worker->qxl, FALSE,
> >          caps);
> >      } else {
> >          // Take least common denominator
> >          for (i = 0 ; i < sizeof(caps_available) /
> >          sizeof(caps_available[0]); ++i) {
> >              SET_CAP(caps, caps_available[i]);
> >          }
> > -        DCC_FOREACH_SAFE(link, next, dcc,
> > &worker->display_channel->common.base) {
> > +        DCC_FOREACH_SAFE(link, next, dcc,
> > RED_CHANNEL(worker->display_channel)) {
> >              rcc = (RedChannelClient *)dcc;
> >              for (i = 0 ; i < sizeof(caps_available) /
> >              sizeof(caps_available[0]); ++i) {
> >                  if (!red_channel_client_test_remote_cap(rcc,
> >                  caps_available[i]))
> > @@ -9783,17 +9777,13 @@ static void red_connect_cursor(RedWorker *worker,
> > RedClient *client, RedsStream
> >                                      common_caps, num_common_caps,
> >                                      caps, num_caps);
> >      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
> >  
> >      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) {
> > +    if (worker->surfaces[0].context.canvas &&
> > !COMMON_CHANNEL(channel)->during_target_migrate) {
> >          red_channel_client_pipe_add_type(rcc, PIPE_ITEM_TYPE_CURSOR_INIT);
> >      }
> >  }
> > @@ -9971,9 +9961,9 @@ static inline void dev_destroy_surfaces(RedWorker
> > *worker)
> >      spice_assert(ring_is_empty(&worker->streams));
> >  
> >      if (display_is_connected(worker)) {
> > -        red_channel_pipes_add_type(&worker->display_channel->common.base,
> > +        red_channel_pipes_add_type(RED_CHANNEL(worker->display_channel),
> >                                     PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE);
> > -        red_pipes_add_verb(&worker->display_channel->common.base,
> > +        red_pipes_add_verb(RED_CHANNEL(worker->display_channel),
> >                             SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL);
> >      }
> >  
> > @@ -10138,8 +10128,8 @@ static void dev_create_primary_surface(RedWorker
> > *worker, uint32_t surface_id,
> >      }
> >  
> >      if (cursor_is_connected(worker)
> > -        && !worker->cursor_channel->common.during_target_migrate) {
> > -        red_channel_pipes_add_type(&worker->cursor_channel->common.base,
> > +        && !COMMON_CHANNEL(worker->cursor_channel)->during_target_migrate)
> > {
> > +        red_channel_pipes_add_type(RED_CHANNEL(worker->cursor_channel),
> >                                     PIPE_ITEM_TYPE_CURSOR_INIT);
> >      }
> >  }
> > @@ -10236,14 +10226,14 @@ void handle_dev_stop(void *opaque, void *payload)
> >       * purge the pipe, send destroy_all_surfaces
> >       * to the client (there is no such message right now), and start
> >       * from scratch on the destination side */
> > -    if (!red_channel_wait_all_sent(&worker->display_channel->common.base,
> > +    if (!red_channel_wait_all_sent(RED_CHANNEL(worker->display_channel),
> >                                     DISPLAY_CLIENT_TIMEOUT)) {
> > -        red_channel_apply_clients(&worker->display_channel->common.base,
> > +        red_channel_apply_clients(RED_CHANNEL(worker->display_channel),
> >                                   red_channel_client_disconnect_if_pending_send);
> >      }
> > -    if (!red_channel_wait_all_sent(&worker->cursor_channel->common.base,
> > +    if (!red_channel_wait_all_sent(RED_CHANNEL(worker->cursor_channel),
> >                                     DISPLAY_CLIENT_TIMEOUT)) {
> > -        red_channel_apply_clients(&worker->cursor_channel->common.base,
> > +        red_channel_apply_clients(RED_CHANNEL(worker->cursor_channel),
> >                                   red_channel_client_disconnect_if_pending_send);
> >      }
> >  }
> > @@ -10285,7 +10275,7 @@ void handle_dev_start(void *opaque, void *payload)
> >  
> >      spice_assert(!worker->running);
> >      if (worker->cursor_channel) {
> > -        worker->cursor_channel->common.during_target_migrate = FALSE;
> > +        COMMON_CHANNEL(worker->cursor_channel)->during_target_migrate =
> > FALSE;
> >      }
> >      if (worker->display_channel) {
> >          worker->display_channel->common.during_target_migrate = FALSE;
> > @@ -10492,7 +10482,7 @@ void handle_dev_cursor_channel_create(void *opaque,
> > void *payload)
> >          spice_warning("cursor channel already created");
> >      }
> >  
> > -    red_channel = &worker->cursor_channel->common.base;
> > +    red_channel = RED_CHANNEL(worker->cursor_channel);
> >      send_data(worker->channel, &red_channel, sizeof(RedChannel *));
> >  }
> >  
> > @@ -10609,9 +10599,7 @@ void handle_dev_set_mouse_mode(void *opaque, void
> > *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;
> > +    cursor_channel_set_mouse_mode(worker->cursor_channel, msg->mode);
> >  }
> >  
> >  void handle_dev_add_memslot_async(void *opaque, void *payload)
> > diff --git a/server/red_worker.h b/server/red_worker.h
> > index df52abd..0a3d7c6 100644
> > --- a/server/red_worker.h
> > +++ b/server/red_worker.h
> > @@ -27,6 +27,7 @@ typedef struct RedWorker RedWorker;
> >  
> >  typedef struct CommonChannelClient {
> >      RedChannelClient base;
> > +
> >      uint32_t id;
> >      struct RedWorker *worker;
> >      int is_low_bandwidth;
> > @@ -37,6 +38,7 @@ typedef struct CommonChannelClient {
> >  #define CHANNEL_RECEIVE_BUF_SIZE 1024
> >  typedef struct CommonChannel {
> >      RedChannel base; // Must be the first thing
> > +
> >      struct RedWorker *worker;
> >      uint8_t recv_buf[CHANNEL_RECEIVE_BUF_SIZE];
> >      uint32_t id_alloc; // bitfield. TODO - use this instead of shift
> >      scheme.
> > @@ -47,6 +49,8 @@ typedef struct CommonChannel {
> >                                    of the primary surface) */
> >  } CommonChannel;
> >  
> > +#define COMMON_CHANNEL(Channel) ((CommonChannel*)(Channel))
> > +
> >  enum {
> >      PIPE_ITEM_TYPE_VERB = PIPE_ITEM_TYPE_CHANNEL_BASE,
> >      PIPE_ITEM_TYPE_INVAL_ONE,
> > @@ -103,6 +107,7 @@ bool       red_worker_run(RedWorker *worker);
> >  QXLInstance* red_worker_get_qxl(RedWorker *worker);
> >  
> >  RedChannel *red_worker_new_channel(RedWorker *worker, int size,
> > +                                   const char *name,
> >                                     uint32_t channel_type, int
> >                                     migration_flags,
> >                                     ChannelCbs *channel_cbs,
> >                                     channel_handle_parsed_proc
> >                                     handle_parsed);
> > 
> 
> 


More information about the Spice-devel mailing list