Hi, On Fri, 2016-10-07 at 17:01 -0500, Jonathon Jongsma wrote: > Move out of red-worker.c. This requires a little bit of minor > refactoring to avoid accessing some RedWorker internals in the > constructor function, etc. > --- > server/Makefile.am | 2 + > server/common-graphics-channel.c | 129 > +++++++++++++++++++++++++++++++++++++++ > server/common-graphics-channel.h | 89 +++++++++++++++++++++++++++ > server/cursor-channel-client.c | 1 + > server/cursor-channel.c | 11 ++-- > server/cursor-channel.h | 5 +- > server/display-channel.c | 9 +-- > server/display-channel.h | 6 +- > server/red-worker.c | 117 +++------------------------- > ------- > server/red-worker.h | 64 +------------------ > 10 files changed, 248 insertions(+), 185 deletions(-) > create mode 100644 server/common-graphics-channel.c > create mode 100644 server/common-graphics-channel.h > > diff --git a/server/Makefile.am b/server/Makefile.am > index f217399..3382946 100644 > --- a/server/Makefile.am > +++ b/server/Makefile.am > @@ -77,6 +77,8 @@ libserver_la_SOURCES = > \ > cache-item.h \ > char-device.c \ > char-device.h \ > + common-graphics-channel.c \ > + common-graphics-channel.h \ wrong indent - tab size should be 8 > demarshallers.h \ > event-loop.c \ > glz-encoder.c \ > diff --git a/server/common-graphics-channel.c b/server/common- > graphics-channel.c > new file mode 100644 > index 0000000..625162c > --- /dev/null > +++ b/server/common-graphics-channel.c > @@ -0,0 +1,129 @@ > +/* > + Copyright (C) 2009-2016 Red Hat, Inc. > + > + This library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later > version. > + > + This library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with this library; if not, see <http://www.gnu.org > /licenses/>. > +*/ > +#ifdef HAVE_CONFIG_H > +#include <config.h> > +#endif > + > +#include <fcntl.h> > +#include <sys/socket.h> > +#include <netinet/in.h> > +#include <netinet/tcp.h> > + > +#include "common-graphics-channel.h" > +#include "dcc.h" > +#include "main-channel-client.h" > + > +static uint8_t *common_alloc_recv_buf(RedChannelClient *rcc, > uint16_t type, uint32_t size) > +{ > + RedChannel *channel = red_channel_client_get_channel(rcc); > + CommonGraphicsChannel *common = SPICE_CONTAINEROF(channel, > CommonGraphicsChannel, base); > + > + /* SPICE_MSGC_MIGRATE_DATA is the only client message whose > size is dynamic */ > + if (type == SPICE_MSGC_MIGRATE_DATA) { > + return spice_malloc(size); > + } > + > + if (size > CHANNEL_RECEIVE_BUF_SIZE) { > + spice_critical("unexpected message size %u (max is %d)", > size, CHANNEL_RECEIVE_BUF_SIZE); > + return NULL; > + } > + return common->recv_buf; > +} > + > +static void common_release_recv_buf(RedChannelClient *rcc, uint16_t > type, uint32_t size, > + uint8_t* msg) > +{ > + if (type == SPICE_MSGC_MIGRATE_DATA) { > + free(msg); > + } > +} > + > +int common_channel_config_socket(RedChannelClient *rcc) > +{ > + RedClient *client = red_channel_client_get_client(rcc); > + MainChannelClient *mcc = red_client_get_main(client); > + RedsStream *stream = red_channel_client_get_stream(rcc); > + int flags; > + int delay_val; > + gboolean is_low_bandwidth; > + > + if ((flags = fcntl(stream->socket, F_GETFL)) == -1) { > + spice_warning("accept failed, %s", strerror(errno)); > + return FALSE; > + } > + > + if (fcntl(stream->socket, F_SETFL, flags | O_NONBLOCK) == -1) { > + spice_warning("accept failed, %s", strerror(errno)); > + return FALSE; > + } > + > + // TODO - this should be dynamic, not one time at channel > creation > + is_low_bandwidth = main_channel_client_is_low_bandwidth(mcc); > + delay_val = is_low_bandwidth ? 0 : 1; > + /* FIXME: Using Nagle's Algorithm can lead to apparent delays, > depending > + * on the delayed ack timeout on the other side. > + * Instead of using Nagle's, we need to implement message > buffering on > + * the application level. > + * see: http://www.stuartcheshire.org/papers/NagleDelayedAck/ > + */ > + if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY, > &delay_val, > + sizeof(delay_val)) == -1) { > + if (errno != ENOTSUP) { > + spice_warning("setsockopt failed, %s", > strerror(errno)); > + } > + } > + // TODO: move wide/narrow ack setting to red_channel. > + red_channel_client_ack_set_client_window(rcc, > + is_low_bandwidth ? > + WIDE_CLIENT_ACK_WINDOW : NARROW_CLIENT_ACK_WINDOW); > + return TRUE; > +} > + > +CommonGraphicsChannel* common_graphics_channel_new(RedsState > *server, > + QXLInstance > *qxl, > + const > SpiceCoreInterfaceInternal *core, > + int size, > uint32_t channel_type, > + int > migration_flags, > + ChannelCbs > *channel_cbs, > + channel_handle_p > arsed_proc handle_parsed) > +{ > + RedChannel *channel = NULL; > + CommonGraphicsChannel *common; > + > + spice_return_val_if_fail(channel_cbs, NULL); > + spice_return_val_if_fail(!channel_cbs->alloc_recv_buf, NULL); > + spice_return_val_if_fail(!channel_cbs->release_recv_buf, NULL); > + > + if (!channel_cbs->config_socket) > + 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, server, > + core, channel_type, > + qxl->id, TRUE /* > handle_acks */, > + spice_get_client_channel_pa > rser(channel_type, NULL), > + handle_parsed, > + channel_cbs, > + migration_flags); > + spice_return_val_if_fail(channel, NULL); > + > + common = (CommonGraphicsChannel *)channel; > + common->qxl = qxl; > + return common; > +} > + > diff --git a/server/common-graphics-channel.h b/server/common- > graphics-channel.h > new file mode 100644 > index 0000000..7b2aeff > --- /dev/null > +++ b/server/common-graphics-channel.h > @@ -0,0 +1,89 @@ > +/* > + Copyright (C) 2009-2016 Red Hat, Inc. > + > + This library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later > version. > + > + This library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with this library; if not, see <http://www.gnu.org > /licenses/>. > +*/ > + > +#ifndef _COMMON_GRAPHICS_CHANNEL_H > +#define _COMMON_GRAPHICS_CHANNEL_H > + > +#include "red-channel.h" > +#include "red-worker.h" > + > +int common_channel_config_socket(RedChannelClient *rcc); > + > +#define COMMON_CLIENT_TIMEOUT (NSEC_PER_SEC * 30) > + > +#define CHANNEL_RECEIVE_BUF_SIZE 1024 > +typedef struct CommonGraphicsChannel { > + RedChannel base; // Must be the first thing > + > + QXLInstance *qxl; > + uint8_t recv_buf[CHANNEL_RECEIVE_BUF_SIZE]; > + int during_target_migrate; /* TRUE when the client that is > associated with the channel > + is during migration. Turned off > when the vm is started. > + The flag is used to avoid sending > messages that are artifacts > + of the transition from stopped vm > to loaded vm (e.g., recreation > + of the primary surface) */ > +} CommonGraphicsChannel; > + > +#define COMMON_GRAPHICS_CHANNEL(Channel) > ((CommonGraphicsChannel*)(Channel)) > + > +enum { > + RED_PIPE_ITEM_TYPE_VERB = RED_PIPE_ITEM_TYPE_CHANNEL_BASE, > + RED_PIPE_ITEM_TYPE_INVAL_ONE, > + > + RED_PIPE_ITEM_TYPE_COMMON_LAST > +}; > + > +typedef struct RedVerbItem { > + RedPipeItem base; > + uint16_t verb; > +} RedVerbItem; > + > +static inline void red_marshall_verb(RedChannelClient *rcc, > RedVerbItem *item) > +{ > + red_channel_client_init_send_data(rcc, item->verb, NULL); > +} > + > +static inline void red_pipe_add_verb(RedChannelClient* rcc, > uint16_t verb) > +{ > + RedVerbItem *item = spice_new(RedVerbItem, 1); > + > + red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_VERB); > + item->verb = verb; > + red_channel_client_pipe_add(rcc, &item->base); > +} > + > +static inline void red_pipe_add_verb_proxy(RedChannelClient *rcc, > gpointer data) > +{ > + uint16_t verb = GPOINTER_TO_UINT(data); > + red_pipe_add_verb(rcc, verb); > +} > + > + > +static inline void red_pipes_add_verb(RedChannel *channel, uint16_t > verb) > +{ > + red_channel_apply_clients_data(channel, > red_pipe_add_verb_proxy, GUINT_TO_POINTER(verb)); > +} > + > +CommonGraphicsChannel* common_graphics_channel_new(RedsState > *server, > + QXLInstance > *qxl, > + const > SpiceCoreInterfaceInternal *core, > + int size, > uint32_t channel_type, > + int > migration_flags, > + ChannelCbs > *channel_cbs, > + channel_handle_p > arsed_proc handle_parsed); > + > +#endif /* _COMMON_GRAPHICS_CHANNEL_H */ > diff --git a/server/cursor-channel-client.c b/server/cursor-channel- > client.c > index 25082d7..90778ed 100644 > --- a/server/cursor-channel-client.c > +++ b/server/cursor-channel-client.c > @@ -21,6 +21,7 @@ > > #include <common/generated_server_marshallers.h> > > +#include "common-graphics-channel.h" > #include "red-channel-client.h" > #include "cache-item.h" > #include "cursor-channel.h" > diff --git a/server/cursor-channel.c b/server/cursor-channel.c > index b152697..c73745f 100644 > --- a/server/cursor-channel.c > +++ b/server/cursor-channel.c > @@ -22,6 +22,7 @@ > #include <glib.h> > #include <common/generated_server_marshallers.h> > > +#include "common-graphics-channel.h" > #include "cursor-channel.h" > #include "cursor-channel-client.h" > #include "reds.h" > @@ -308,7 +309,8 @@ static void > cursor_channel_send_item(RedChannelClient *rcc, RedPipeItem *pipe_it > red_channel_client_begin_send_message(rcc); > } > > -CursorChannel* cursor_channel_new(RedWorker *worker) > +CursorChannel* cursor_channel_new(RedsState *server, QXLInstance > *qxl, > + const SpiceCoreInterfaceInternal > *core) > { > CursorChannel *cursor_channel; > CommonGraphicsChannel *channel = NULL; > @@ -318,9 +320,10 @@ CursorChannel* cursor_channel_new(RedWorker > *worker) > }; > > spice_info("create cursor channel"); > - channel = red_worker_new_channel(worker, sizeof(CursorChannel), > "cursor_channel", > - SPICE_CHANNEL_CURSOR, 0, > - &cbs, > red_channel_client_handle_message); > + channel = common_graphics_channel_new(server, qxl, core, > + sizeof(CursorChannel), > + SPICE_CHANNEL_CURSOR, 0, > + &cbs, > red_channel_client_handle_message); > > cursor_channel = (CursorChannel *)channel; > cursor_channel->priv->cursor_visible = TRUE; > diff --git a/server/cursor-channel.h b/server/cursor-channel.h > index 6149e2d..a3ddaa3 100644 > --- a/server/cursor-channel.h > +++ b/server/cursor-channel.h > @@ -18,7 +18,7 @@ > #ifndef CURSOR_CHANNEL_H_ > # define CURSOR_CHANNEL_H_ > > -#include "red-worker.h" > +#include "common-graphics-channel.h" > > /** > * This type it's a RedChannel class which implement cursor (mouse) > @@ -39,7 +39,8 @@ typedef struct CursorChannel CursorChannel; > * provided as helper functions and should only be called from the > * CursorChannel thread. > */ > -CursorChannel* cursor_channel_new (RedWorker > *worker); > +CursorChannel* cursor_channel_new (RedsState *server, > QXLInstance *qxl, > + const > SpiceCoreInterfaceInternal *core); > > /** > * Cause the channel to disconnect all clients > diff --git a/server/display-channel.c b/server/display-channel.c > index b9366b5..93744a4 100644 > --- a/server/display-channel.c > +++ b/server/display-channel.c > @@ -1903,7 +1903,9 @@ static SpiceCanvas > *image_surfaces_get(SpiceImageSurfaces *surfaces, uint32_t su > return display->priv->surfaces[surface_id].context.canvas; > } > > -DisplayChannel* display_channel_new(SpiceServer *reds, RedWorker > *worker, > +DisplayChannel* display_channel_new(RedsState *reds, > + QXLInstance *qxl, > + const > SpiceCoreInterfaceInternal *core, > int migrate, int stream_video, > GArray *video_codecs, > uint32_t n_surfaces) > @@ -1922,9 +1924,8 @@ DisplayChannel* > display_channel_new(SpiceServer *reds, RedWorker *worker, > }; > > spice_info("create display channel"); > - display = (DisplayChannel *)red_worker_new_channel( > - worker, sizeof(*display), "display_channel", > - SPICE_CHANNEL_DISPLAY, > + display = (DisplayChannel *)common_graphics_channel_new( > + reds, qxl, core, sizeof(*display), SPICE_CHANNEL_DISPLAY, > SPICE_MIGRATE_NEED_FLUSH | > SPICE_MIGRATE_NEED_DATA_TRANSFER, > &cbs, dcc_handle_message); > spice_return_val_if_fail(display, NULL); > diff --git a/server/display-channel.h b/server/display-channel.h > index bbae6f1..936768e 100644 > --- a/server/display-channel.h > +++ b/server/display-channel.h > @@ -43,6 +43,7 @@ > #include "stream.h" > #include "dcc.h" > #include "image-encoders.h" > +#include "common-graphics-channel.h" > > typedef struct DependItem { > Drawable *drawable; > @@ -230,8 +231,9 @@ typedef struct RedUpgradeItem { > } RedUpgradeItem; > > > -DisplayChannel* display_channel_new > (SpiceServer *reds, > - > RedWorker *worker, > +DisplayChannel* display_channel_new > (RedsState *reds, > + > QXLInstance *qxl, > + > const SpiceCoreInterfaceInternal *core, > > int migrate, > > int stream_video, > > GArray *video_codecs, > diff --git a/server/red-worker.c b/server/red-worker.c > index b3f6c12..085f4f3 100644 > --- a/server/red-worker.c > +++ b/server/red-worker.c > @@ -91,39 +91,12 @@ struct RedWorker { > RedRecord *record; > }; > > -static RedsState* red_worker_get_server(RedWorker *worker); > - > static int display_is_connected(RedWorker *worker) > { > return (worker->display_channel && red_channel_is_connected( > &worker->display_channel->common.base)); > } > > -static uint8_t *common_alloc_recv_buf(RedChannelClient *rcc, > uint16_t type, uint32_t size) > -{ > - RedChannel *channel = red_channel_client_get_channel(rcc); > - CommonGraphicsChannel *common = SPICE_CONTAINEROF(channel, > CommonGraphicsChannel, base); > - > - /* SPICE_MSGC_MIGRATE_DATA is the only client message whose > size is dynamic */ > - if (type == SPICE_MSGC_MIGRATE_DATA) { > - return spice_malloc(size); > - } > - > - if (size > CHANNEL_RECEIVE_BUF_SIZE) { > - spice_critical("unexpected message size %u (max is %d)", > size, CHANNEL_RECEIVE_BUF_SIZE); > - return NULL; > - } > - return common->recv_buf; > -} > - > -static void common_release_recv_buf(RedChannelClient *rcc, uint16_t > type, uint32_t size, > - uint8_t* msg) > -{ > - if (type == SPICE_MSGC_MIGRATE_DATA) { > - free(msg); > - } > -} > - > void red_drawable_unref(RedDrawable *red_drawable) > { > if (--red_drawable->refs) { > @@ -401,82 +374,6 @@ static void flush_all_qxl_commands(RedWorker > *worker) > flush_cursor_commands(worker); > } > > -int common_channel_config_socket(RedChannelClient *rcc) > -{ > - RedClient *client = red_channel_client_get_client(rcc); > - MainChannelClient *mcc = red_client_get_main(client); > - RedsStream *stream = red_channel_client_get_stream(rcc); > - int flags; > - int delay_val; > - gboolean is_low_bandwidth; > - > - if ((flags = fcntl(stream->socket, F_GETFL)) == -1) { > - spice_warning("accept failed, %s", strerror(errno)); > - return FALSE; > - } > - > - if (fcntl(stream->socket, F_SETFL, flags | O_NONBLOCK) == -1) { > - spice_warning("accept failed, %s", strerror(errno)); > - return FALSE; > - } > - > - // TODO - this should be dynamic, not one time at channel > creation > - is_low_bandwidth = main_channel_client_is_low_bandwidth(mcc); > - delay_val = is_low_bandwidth ? 0 : 1; > - /* FIXME: Using Nagle's Algorithm can lead to apparent delays, > depending > - * on the delayed ack timeout on the other side. > - * Instead of using Nagle's, we need to implement message > buffering on > - * the application level. > - * see: http://www.stuartcheshire.org/papers/NagleDelayedAck/ > - */ > - if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY, > &delay_val, > - sizeof(delay_val)) == -1) { > - if (errno != ENOTSUP) { > - spice_warning("setsockopt failed, %s", > strerror(errno)); > - } > - } > - // TODO: move wide/narrow ack setting to red_channel. > - red_channel_client_ack_set_client_window(rcc, > - is_low_bandwidth ? > - WIDE_CLIENT_ACK_WINDOW : NARROW_CLIENT_ACK_WINDOW); > - return TRUE; > -} > - > -CommonGraphicsChannel *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) > -{ > - RedChannel *channel = NULL; > - CommonGraphicsChannel *common; > - > - spice_return_val_if_fail(worker, NULL); > - spice_return_val_if_fail(channel_cbs, NULL); > - spice_return_val_if_fail(!channel_cbs->alloc_recv_buf, NULL); > - spice_return_val_if_fail(!channel_cbs->release_recv_buf, NULL); > - > - if (!channel_cbs->config_socket) > - 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, > red_worker_get_server(worker), > - &worker->core, > channel_type, > - worker->qxl->id, TRUE /* > handle_acks */, > - spice_get_client_channel_pa > rser(channel_type, NULL), > - handle_parsed, > - channel_cbs, > - migration_flags); > - spice_return_val_if_fail(channel, NULL); > - red_channel_set_stat_node(channel, > stat_add_node(red_worker_get_server(worker), > - worker->stat, > name, TRUE)); > - > - common = (CommonGraphicsChannel *)channel; > - common->qxl = worker->qxl; > - return common; > -} > - > static void guest_set_client_capabilities(RedWorker *worker) > { > int i; > @@ -1465,18 +1362,23 @@ RedWorker* red_worker_new(QXLInstance *qxl, > > worker->event_timeout = INF_EVENT_WAIT; > > - worker->cursor_channel = cursor_channel_new(worker); > + worker->cursor_channel = cursor_channel_new(reds, qxl, > + &worker->core); no need for the line break > channel = RED_CHANNEL(worker->cursor_channel); > + red_channel_set_stat_node(channel, stat_add_node(reds, worker- > >stat, > + "cursor_channe > l", TRUE)); same ^ > red_channel_register_client_cbs(channel, client_cursor_cbs, > dispatcher); > reds_register_channel(reds, channel); > > // TODO: handle seemless migration. Temp, setting migrate to > FALSE > - worker->display_channel = display_channel_new(reds, worker, > FALSE, > + worker->display_channel = display_channel_new(reds, qxl, > &worker->core, FALSE, > reds_get_streamin > g_video(reds), > reds_get_video_co > decs(reds), > init_info.n_surfa > ces); > > channel = RED_CHANNEL(worker->display_channel); > + red_channel_set_stat_node(channel, stat_add_node(reds, worker- > >stat, > + "display_chann > el", TRUE)); same > red_channel_register_client_cbs(channel, client_display_cbs, > dispatcher); > red_channel_set_cap(channel, > SPICE_DISPLAY_CAP_MONITORS_CONFIG); > red_channel_set_cap(channel, > SPICE_DISPLAY_CAP_PREF_COMPRESSION); > @@ -1526,8 +1428,3 @@ bool red_worker_run(RedWorker *worker) > > return r == 0; > } > - > -static RedsState* red_worker_get_server(RedWorker *worker) > -{ > - return red_qxl_get_server(worker->qxl->st); > -} > diff --git a/server/red-worker.h b/server/red-worker.h > index 7d68678..370240f 100644 > --- a/server/red-worker.h > +++ b/server/red-worker.h > @@ -25,74 +25,12 @@ > > typedef struct RedWorker RedWorker; > > -int common_channel_config_socket(RedChannelClient *rcc); > - > -#define COMMON_CLIENT_TIMEOUT (NSEC_PER_SEC * 30) > - > -#define CHANNEL_RECEIVE_BUF_SIZE 1024 > -typedef struct CommonGraphicsChannel { > - RedChannel base; // Must be the first thing > - > - QXLInstance *qxl; > - uint8_t recv_buf[CHANNEL_RECEIVE_BUF_SIZE]; > - int during_target_migrate; /* TRUE when the client that is > associated with the channel > - is during migration. Turned off > when the vm is started. > - The flag is used to avoid sending > messages that are artifacts > - of the transition from stopped vm > to loaded vm (e.g., recreation > - of the primary surface) */ > -} CommonGraphicsChannel; > - > -#define COMMON_GRAPHICS_CHANNEL(Channel) > ((CommonGraphicsChannel*)(Channel)) > - > -enum { > - RED_PIPE_ITEM_TYPE_VERB = RED_PIPE_ITEM_TYPE_CHANNEL_BASE, > - RED_PIPE_ITEM_TYPE_INVAL_ONE, > - > - RED_PIPE_ITEM_TYPE_COMMON_LAST > -}; > - > -typedef struct RedVerbItem { > - RedPipeItem base; > - uint16_t verb; > -} RedVerbItem; > - > -static inline void red_marshall_verb(RedChannelClient *rcc, > RedVerbItem *item) > -{ > - red_channel_client_init_send_data(rcc, item->verb, NULL); > -} > - > -static inline void red_pipe_add_verb(RedChannelClient* rcc, > uint16_t verb) > -{ > - RedVerbItem *item = spice_new(RedVerbItem, 1); > - > - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_VERB); > - item->verb = verb; > - red_channel_client_pipe_add(rcc, &item->base); > -} > - > -static inline void red_pipe_add_verb_proxy(RedChannelClient *rcc, > gpointer data) > -{ > - uint16_t verb = GPOINTER_TO_UINT(data); > - red_pipe_add_verb(rcc, verb); > -} > - > - > -static inline void red_pipes_add_verb(RedChannel *channel, uint16_t > verb) > -{ > - red_channel_apply_clients_data(channel, > red_pipe_add_verb_proxy, GUINT_TO_POINTER(verb)); > -} > - > RedWorker* red_worker_new(QXLInstance *qxl, > const ClientCbs *client_cursor_cbs, > const ClientCbs *client_display_cbs); > bool red_worker_run(RedWorker *worker); > +SpiceCoreInterfaceInternal* red_worker_get_core_interface(RedWorker > *worker); declared but not used ^ > > void red_drawable_unref(RedDrawable *red_drawable); > > -CommonGraphicsChannel *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); > - > #endif > Besides that it looks good to me. If you want you can apply: https://paste.fedoraproject.org/447573/60897681/ and add Acked-by: Pavel Grunt <pgrunt@xxxxxxxxxx> Thanks, Pavel _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel