mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-25 22:18:58 +00:00
red-pipe-item: Use inheritance on RedPipeItem
This allows to: - reuse reference counting; - avoid having to manually call g_free to release item memory; - assure item is initialized; - avoids some manual casts. It will also allows to use smart pointers. Signed-off-by: Frediano Ziglio <freddy77@gmail.com> Acked-by: Julien Ropé <jrope@gmail.com>
This commit is contained in:
parent
45e964dc5a
commit
a30df693cf
@ -76,9 +76,9 @@ static void FUNC_NAME(remove)(CHANNELCLIENT *channel_client, RedCacheItem *item)
|
||||
auto id = item->id;
|
||||
RedCachePipeItem *pipe_item = reinterpret_cast<RedCachePipeItem*>(item);
|
||||
|
||||
red_pipe_item_init(&pipe_item->base, RED_PIPE_ITEM_TYPE_INVAL_ONE);
|
||||
new (pipe_item) RedCachePipeItem();
|
||||
pipe_item->inval_one.id = id;
|
||||
channel_client->pipe_add_tail(&pipe_item->base); // for now
|
||||
channel_client->pipe_add_tail(pipe_item); // for now
|
||||
}
|
||||
|
||||
static int FUNC_NAME(add)(CHANNELCLIENT *channel_client, uint64_t id, size_t size)
|
||||
|
||||
@ -65,3 +65,8 @@ bool CommonGraphicsChannelClient::config_socket()
|
||||
ack_set_client_window(is_low_bandwidth ? WIDE_CLIENT_ACK_WINDOW : NARROW_CLIENT_ACK_WINDOW);
|
||||
return true;
|
||||
}
|
||||
|
||||
RedCachePipeItem::RedCachePipeItem():
|
||||
RedPipeItem(RED_PIPE_ITEM_TYPE_INVAL_ONE)
|
||||
{
|
||||
}
|
||||
|
||||
@ -69,8 +69,8 @@ protected:
|
||||
};
|
||||
|
||||
/* pipe item used to release a specific cached item on the client */
|
||||
struct RedCachePipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedCachePipeItem final: public RedPipeItem {
|
||||
RedCachePipeItem();
|
||||
SpiceMsgDisplayInvalOne inval_one;
|
||||
};
|
||||
|
||||
|
||||
@ -25,41 +25,35 @@
|
||||
#include "cursor-channel-client.h"
|
||||
#include "reds.h"
|
||||
|
||||
typedef struct RedCursorPipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedCursorPipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
~RedCursorPipeItem();
|
||||
RedCursorCmd *red_cursor;
|
||||
} RedCursorPipeItem;
|
||||
|
||||
static void cursor_pipe_item_free(RedPipeItem *pipe_item);
|
||||
};
|
||||
|
||||
static RedCursorPipeItem *cursor_pipe_item_new(RedCursorCmd *cmd)
|
||||
{
|
||||
RedCursorPipeItem *item = g_new0(RedCursorPipeItem, 1);
|
||||
RedCursorPipeItem *item = new RedCursorPipeItem(RED_PIPE_ITEM_TYPE_CURSOR);
|
||||
|
||||
spice_return_val_if_fail(cmd != NULL, NULL);
|
||||
|
||||
red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_CURSOR,
|
||||
cursor_pipe_item_free);
|
||||
item->red_cursor = red_cursor_cmd_ref(cmd);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
static void cursor_pipe_item_free(RedPipeItem *base)
|
||||
RedCursorPipeItem::~RedCursorPipeItem()
|
||||
{
|
||||
RedCursorPipeItem *pipe_item = SPICE_UPCAST(RedCursorPipeItem, base);
|
||||
|
||||
red_cursor_cmd_unref(pipe_item->red_cursor);
|
||||
g_free(pipe_item);
|
||||
red_cursor_cmd_unref(red_cursor);
|
||||
}
|
||||
|
||||
static void cursor_channel_set_item(CursorChannel *cursor, RedCursorPipeItem *item)
|
||||
{
|
||||
if (item) {
|
||||
red_pipe_item_ref(&item->base);
|
||||
red_pipe_item_ref(item);
|
||||
}
|
||||
if (cursor->item) {
|
||||
red_pipe_item_unref(&cursor->item->base);
|
||||
red_pipe_item_unref(cursor->item);
|
||||
}
|
||||
cursor->item = item;
|
||||
}
|
||||
@ -89,7 +83,7 @@ static void cursor_fill(CursorChannelClient *ccc, RedCursorPipeItem *cursor,
|
||||
|
||||
if (red_cursor->data_size) {
|
||||
SpiceMarshaller *m2 = spice_marshaller_get_submarshaller(m);
|
||||
cursor->base.add_to_marshaller(m2, red_cursor->data, red_cursor->data_size);
|
||||
cursor->add_to_marshaller(m2, red_cursor->data, red_cursor->data_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,10 +172,10 @@ void CursorChannelClient::send_item(RedPipeItem *pipe_item)
|
||||
|
||||
switch (pipe_item->type) {
|
||||
case RED_PIPE_ITEM_TYPE_CURSOR:
|
||||
red_marshall_cursor(ccc, m, SPICE_UPCAST(RedCursorPipeItem, pipe_item));
|
||||
red_marshall_cursor(ccc, m, static_cast<RedCursorPipeItem*>(pipe_item));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_INVAL_ONE:
|
||||
red_marshall_inval(this, m, SPICE_UPCAST(RedCachePipeItem, pipe_item));
|
||||
red_marshall_inval(this, m, static_cast<RedCachePipeItem*>(pipe_item));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_CURSOR_INIT:
|
||||
reset_cursor_cache();
|
||||
@ -235,7 +229,7 @@ void CursorChannel::process_cmd(RedCursorCmd *cursor_cmd)
|
||||
break;
|
||||
default:
|
||||
spice_warning("invalid cursor command %u", cursor_cmd->type);
|
||||
red_pipe_item_unref(&cursor_pipe_item->base);
|
||||
red_pipe_item_unref(cursor_pipe_item);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -243,9 +237,9 @@ void CursorChannel::process_cmd(RedCursorCmd *cursor_cmd)
|
||||
(mouse_mode == SPICE_MOUSE_MODE_SERVER
|
||||
|| cursor_cmd->type != QXL_CURSOR_MOVE
|
||||
|| cursor_show)) {
|
||||
pipes_add(&cursor_pipe_item->base);
|
||||
pipes_add(cursor_pipe_item);
|
||||
} else {
|
||||
red_pipe_item_unref(&cursor_pipe_item->base);
|
||||
red_pipe_item_unref(cursor_pipe_item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -316,7 +310,7 @@ void CursorChannel::on_connect(RedClient *client, RedStream *stream, int migrati
|
||||
CursorChannel::~CursorChannel()
|
||||
{
|
||||
if (item) {
|
||||
red_pipe_item_unref(&item->base);
|
||||
red_pipe_item_unref(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -626,7 +626,7 @@ static bool pipe_rendered_drawables_intersect_with_areas(DisplayChannelClient *d
|
||||
|
||||
if (pipe_item->type != RED_PIPE_ITEM_TYPE_DRAW)
|
||||
continue;
|
||||
drawable = SPICE_UPCAST(RedDrawablePipeItem, pipe_item)->drawable;
|
||||
drawable = static_cast<RedDrawablePipeItem*>(pipe_item)->drawable;
|
||||
|
||||
if (ring_item_is_linked(&drawable->list_link))
|
||||
continue; // item hasn't been rendered
|
||||
@ -719,7 +719,7 @@ static void red_pipe_replace_rendered_drawables_with_images(DisplayChannelClient
|
||||
prev = l->prev;
|
||||
if (pipe_item->type != RED_PIPE_ITEM_TYPE_DRAW)
|
||||
continue;
|
||||
dpi = SPICE_UPCAST(RedDrawablePipeItem, pipe_item);
|
||||
dpi = static_cast<RedDrawablePipeItem*>(pipe_item);
|
||||
drawable = dpi->drawable;
|
||||
if (ring_item_is_linked(&drawable->list_link))
|
||||
continue; // item hasn't been rendered
|
||||
@ -1969,8 +1969,8 @@ static void red_marshall_image(DisplayChannelClient *dcc,
|
||||
|
||||
spice_marshall_Image(src_bitmap_out, &red_image,
|
||||
&bitmap_palette_out, &lzplt_palette_out);
|
||||
item->base.add_to_marshaller(src_bitmap_out, item->data,
|
||||
bitmap.y * bitmap.stride);
|
||||
item->add_to_marshaller(src_bitmap_out, item->data,
|
||||
bitmap.y * bitmap.stride);
|
||||
region_remove(surface_lossy_region, ©.base.box);
|
||||
}
|
||||
spice_chunks_destroy(chunks);
|
||||
@ -2286,7 +2286,7 @@ static void marshall_gl_draw(RedChannelClient *rcc,
|
||||
SpiceMarshaller *m,
|
||||
RedPipeItem *item)
|
||||
{
|
||||
RedGlDrawItem *p = SPICE_UPCAST(RedGlDrawItem, item);
|
||||
RedGlDrawItem *p = static_cast<RedGlDrawItem*>(item);
|
||||
|
||||
rcc->init_send_data(SPICE_MSG_DISPLAY_GL_DRAW);
|
||||
spice_marshall_msg_display_gl_draw(m, &p->draw);
|
||||
@ -2335,34 +2335,34 @@ void DisplayChannelClient::send_item(RedPipeItem *pipe_item)
|
||||
::reset_send_data(dcc);
|
||||
switch (pipe_item->type) {
|
||||
case RED_PIPE_ITEM_TYPE_DRAW: {
|
||||
RedDrawablePipeItem *dpi = SPICE_UPCAST(RedDrawablePipeItem, pipe_item);
|
||||
RedDrawablePipeItem *dpi = static_cast<RedDrawablePipeItem*>(pipe_item);
|
||||
marshall_qxl_drawable(this, m, dpi);
|
||||
break;
|
||||
}
|
||||
case RED_PIPE_ITEM_TYPE_INVAL_ONE:
|
||||
marshall_inval_palette(this, m, SPICE_UPCAST(RedCachePipeItem, pipe_item));
|
||||
marshall_inval_palette(this, m, static_cast<RedCachePipeItem*>(pipe_item));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_STREAM_CREATE: {
|
||||
StreamCreateDestroyItem *item = SPICE_UPCAST(StreamCreateDestroyItem, pipe_item);
|
||||
StreamCreateDestroyItem *item = static_cast<StreamCreateDestroyItem*>(pipe_item);
|
||||
marshall_stream_start(this, m, item->agent);
|
||||
break;
|
||||
}
|
||||
case RED_PIPE_ITEM_TYPE_STREAM_CLIP:
|
||||
marshall_stream_clip(this, m, SPICE_UPCAST(VideoStreamClipItem, pipe_item));
|
||||
marshall_stream_clip(this, m, static_cast<VideoStreamClipItem*>(pipe_item));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_STREAM_DESTROY: {
|
||||
StreamCreateDestroyItem *item = SPICE_UPCAST(StreamCreateDestroyItem, pipe_item);
|
||||
StreamCreateDestroyItem *item = static_cast<StreamCreateDestroyItem*>(pipe_item);
|
||||
marshall_stream_end(this, m, item->agent);
|
||||
break;
|
||||
}
|
||||
case RED_PIPE_ITEM_TYPE_UPGRADE:
|
||||
marshall_upgrade(this, m, SPICE_UPCAST(RedUpgradeItem, pipe_item));
|
||||
marshall_upgrade(this, m, static_cast<RedUpgradeItem*>(pipe_item));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MIGRATE_DATA:
|
||||
display_channel_marshall_migrate_data(this, m);
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_IMAGE:
|
||||
red_marshall_image(this, m, SPICE_UPCAST(RedImageItem, pipe_item));
|
||||
red_marshall_image(this, m, static_cast<RedImageItem*>(pipe_item));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_PIXMAP_SYNC:
|
||||
display_channel_marshall_pixmap_sync(this, m);
|
||||
@ -2375,23 +2375,23 @@ void DisplayChannelClient::send_item(RedPipeItem *pipe_item)
|
||||
init_send_data(SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES);
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_CREATE_SURFACE: {
|
||||
RedSurfaceCreateItem *surface_create = SPICE_UPCAST(RedSurfaceCreateItem, pipe_item);
|
||||
RedSurfaceCreateItem *surface_create = static_cast<RedSurfaceCreateItem*>(pipe_item);
|
||||
marshall_surface_create(this, m, &surface_create->surface_create);
|
||||
break;
|
||||
}
|
||||
case RED_PIPE_ITEM_TYPE_DESTROY_SURFACE: {
|
||||
RedSurfaceDestroyItem *surface_destroy = SPICE_UPCAST(RedSurfaceDestroyItem, pipe_item);
|
||||
RedSurfaceDestroyItem *surface_destroy = static_cast<RedSurfaceDestroyItem*>(pipe_item);
|
||||
marshall_surface_destroy(this, m, surface_destroy->surface_destroy.surface_id);
|
||||
break;
|
||||
}
|
||||
case RED_PIPE_ITEM_TYPE_MONITORS_CONFIG: {
|
||||
RedMonitorsConfigItem *monconf_item = SPICE_UPCAST(RedMonitorsConfigItem, pipe_item);
|
||||
RedMonitorsConfigItem *monconf_item = static_cast<RedMonitorsConfigItem*>(pipe_item);
|
||||
marshall_monitors_config(this, m, monconf_item->monitors_config);
|
||||
break;
|
||||
}
|
||||
case RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT: {
|
||||
RedStreamActivateReportItem *report_item =
|
||||
SPICE_UPCAST(RedStreamActivateReportItem, pipe_item);
|
||||
static_cast<RedStreamActivateReportItem*>(pipe_item);
|
||||
marshall_stream_activate_report(this, m, report_item);
|
||||
break;
|
||||
}
|
||||
|
||||
132
server/dcc.cpp
132
server/dcc.cpp
@ -70,25 +70,18 @@ DisplayChannelClient::~DisplayChannelClient()
|
||||
g_clear_pointer(&priv->client_preferred_video_codecs, g_array_unref);
|
||||
}
|
||||
|
||||
static RedSurfaceCreateItem *red_surface_create_item_new(RedChannel* channel,
|
||||
uint32_t surface_id,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t format,
|
||||
uint32_t flags)
|
||||
RedSurfaceCreateItem::RedSurfaceCreateItem(uint32_t surface_id,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t format,
|
||||
uint32_t flags):
|
||||
RedPipeItem(RED_PIPE_ITEM_TYPE_CREATE_SURFACE)
|
||||
{
|
||||
RedSurfaceCreateItem *create;
|
||||
|
||||
create = g_new(RedSurfaceCreateItem, 1);
|
||||
|
||||
create->surface_create.surface_id = surface_id;
|
||||
create->surface_create.width = width;
|
||||
create->surface_create.height = height;
|
||||
create->surface_create.flags = flags;
|
||||
create->surface_create.format = format;
|
||||
|
||||
red_pipe_item_init(&create->base, RED_PIPE_ITEM_TYPE_CREATE_SURFACE);
|
||||
return create;
|
||||
surface_create.surface_id = surface_id;
|
||||
surface_create.width = width;
|
||||
surface_create.height = height;
|
||||
surface_create.flags = flags;
|
||||
surface_create.format = format;
|
||||
}
|
||||
|
||||
bool dcc_drawable_is_in_pipe(DisplayChannelClient *dcc, Drawable *drawable)
|
||||
@ -129,10 +122,10 @@ bool dcc_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surfac
|
||||
|
||||
l = l->next;
|
||||
if (item->type == RED_PIPE_ITEM_TYPE_DRAW) {
|
||||
dpi = SPICE_UPCAST(RedDrawablePipeItem, item);
|
||||
dpi = static_cast<RedDrawablePipeItem*>(item);
|
||||
drawable = dpi->drawable;
|
||||
} else if (item->type == RED_PIPE_ITEM_TYPE_UPGRADE) {
|
||||
drawable = SPICE_UPCAST(RedUpgradeItem, item)->drawable;
|
||||
drawable = static_cast<RedUpgradeItem*>(item)->drawable;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@ -189,12 +182,16 @@ void dcc_create_surface(DisplayChannelClient *dcc, int surface_id)
|
||||
return;
|
||||
}
|
||||
surface = &display->priv->surfaces[surface_id];
|
||||
create = red_surface_create_item_new(display,
|
||||
surface_id, surface->context.width,
|
||||
surface->context.height,
|
||||
surface->context.format, flags);
|
||||
create = new RedSurfaceCreateItem(surface_id, surface->context.width,
|
||||
surface->context.height,
|
||||
surface->context.format, flags);
|
||||
dcc->priv->surface_client_created[surface_id] = TRUE;
|
||||
dcc->pipe_add(&create->base);
|
||||
dcc->pipe_add(create);
|
||||
}
|
||||
|
||||
RedImageItem::RedImageItem():
|
||||
RedPipeItem(RED_PIPE_ITEM_TYPE_IMAGE)
|
||||
{
|
||||
}
|
||||
|
||||
// adding the pipe item after pos. If pos == NULL, adding to head.
|
||||
@ -219,9 +216,7 @@ dcc_add_surface_area_image(DisplayChannelClient *dcc, int surface_id,
|
||||
bpp = SPICE_SURFACE_FMT_DEPTH(surface->context.format) / 8;
|
||||
stride = width * bpp;
|
||||
|
||||
item = (RedImageItem *)g_malloc(height * stride + sizeof(RedImageItem));
|
||||
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_IMAGE);
|
||||
item = new (height * stride) RedImageItem();
|
||||
|
||||
item->surface_id = surface_id;
|
||||
item->image_format =
|
||||
@ -250,9 +245,9 @@ dcc_add_surface_area_image(DisplayChannelClient *dcc, int surface_id,
|
||||
}
|
||||
|
||||
if (pipe_item_pos) {
|
||||
dcc->pipe_add_after_pos(&item->base, pipe_item_pos);
|
||||
dcc->pipe_add_after_pos(item, pipe_item_pos);
|
||||
} else {
|
||||
dcc->pipe_add(&item->base);
|
||||
dcc->pipe_add(item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,14 +303,15 @@ static void add_drawable_surface_images(DisplayChannelClient *dcc, Drawable *dra
|
||||
dcc_push_surface_image(dcc, drawable->surface_id);
|
||||
}
|
||||
|
||||
static void red_drawable_pipe_item_free(RedPipeItem *item)
|
||||
RedDrawablePipeItem::RedDrawablePipeItem():
|
||||
RedPipeItem(RED_PIPE_ITEM_TYPE_DRAW)
|
||||
{
|
||||
RedDrawablePipeItem *dpi = SPICE_UPCAST(RedDrawablePipeItem, item);
|
||||
spice_assert(item->refcount == 0);
|
||||
}
|
||||
|
||||
dpi->drawable->pipes = g_list_remove(dpi->drawable->pipes, dpi);
|
||||
drawable_unref(dpi->drawable);
|
||||
g_free(dpi);
|
||||
RedDrawablePipeItem::~RedDrawablePipeItem()
|
||||
{
|
||||
drawable->pipes = g_list_remove(drawable->pipes, this);
|
||||
drawable_unref(drawable);
|
||||
}
|
||||
|
||||
static RedDrawablePipeItem *red_drawable_pipe_item_new(DisplayChannelClient *dcc,
|
||||
@ -323,12 +319,10 @@ static RedDrawablePipeItem *red_drawable_pipe_item_new(DisplayChannelClient *dcc
|
||||
{
|
||||
RedDrawablePipeItem *dpi;
|
||||
|
||||
dpi = g_new0(RedDrawablePipeItem, 1);
|
||||
dpi = new RedDrawablePipeItem;
|
||||
dpi->drawable = drawable;
|
||||
dpi->dcc = dcc;
|
||||
drawable->pipes = g_list_prepend(drawable->pipes, dpi);
|
||||
red_pipe_item_init_full(&dpi->base, RED_PIPE_ITEM_TYPE_DRAW,
|
||||
red_drawable_pipe_item_free);
|
||||
drawable->refs++;
|
||||
return dpi;
|
||||
}
|
||||
@ -338,7 +332,7 @@ void dcc_prepend_drawable(DisplayChannelClient *dcc, Drawable *drawable)
|
||||
RedDrawablePipeItem *dpi = red_drawable_pipe_item_new(dcc, drawable);
|
||||
|
||||
add_drawable_surface_images(dcc, drawable);
|
||||
dcc->pipe_add(&dpi->base);
|
||||
dcc->pipe_add(dpi);
|
||||
}
|
||||
|
||||
void dcc_append_drawable(DisplayChannelClient *dcc, Drawable *drawable)
|
||||
@ -346,7 +340,7 @@ void dcc_append_drawable(DisplayChannelClient *dcc, Drawable *drawable)
|
||||
RedDrawablePipeItem *dpi = red_drawable_pipe_item_new(dcc, drawable);
|
||||
|
||||
add_drawable_surface_images(dcc, drawable);
|
||||
dcc->pipe_add_tail(&dpi->base);
|
||||
dcc->pipe_add_tail(dpi);
|
||||
}
|
||||
|
||||
void dcc_add_drawable_after(DisplayChannelClient *dcc, Drawable *drawable, RedPipeItem *pos)
|
||||
@ -354,7 +348,7 @@ void dcc_add_drawable_after(DisplayChannelClient *dcc, Drawable *drawable, RedPi
|
||||
RedDrawablePipeItem *dpi = red_drawable_pipe_item_new(dcc, drawable);
|
||||
|
||||
add_drawable_surface_images(dcc, drawable);
|
||||
dcc->pipe_add_after(&dpi->base, pos);
|
||||
dcc->pipe_add_after(dpi, pos);
|
||||
}
|
||||
|
||||
static void dcc_init_stream_agents(DisplayChannelClient *dcc)
|
||||
@ -498,28 +492,18 @@ void dcc_video_stream_agent_clip(DisplayChannelClient* dcc, VideoStreamAgent *ag
|
||||
{
|
||||
VideoStreamClipItem *item = video_stream_clip_item_new(agent);
|
||||
|
||||
dcc->pipe_add(&item->base);
|
||||
dcc->pipe_add(item);
|
||||
}
|
||||
|
||||
static void red_monitors_config_item_free(RedPipeItem *pipe_item)
|
||||
RedMonitorsConfigItem::~RedMonitorsConfigItem()
|
||||
{
|
||||
RedMonitorsConfigItem *item = SPICE_UPCAST(RedMonitorsConfigItem, pipe_item);
|
||||
|
||||
monitors_config_unref(item->monitors_config);
|
||||
g_free(item);
|
||||
monitors_config_unref(monitors_config);
|
||||
}
|
||||
|
||||
static RedMonitorsConfigItem *red_monitors_config_item_new(RedChannel* channel,
|
||||
MonitorsConfig *monitors_config)
|
||||
RedMonitorsConfigItem::RedMonitorsConfigItem(MonitorsConfig *init_monitors_config):
|
||||
RedPipeItem(RED_PIPE_ITEM_TYPE_MONITORS_CONFIG)
|
||||
{
|
||||
RedMonitorsConfigItem *mci;
|
||||
|
||||
mci = g_new(RedMonitorsConfigItem, 1);
|
||||
mci->monitors_config = monitors_config_ref(monitors_config);
|
||||
|
||||
red_pipe_item_init_full(&mci->base, RED_PIPE_ITEM_TYPE_MONITORS_CONFIG,
|
||||
red_monitors_config_item_free);
|
||||
return mci;
|
||||
monitors_config = monitors_config_ref(init_monitors_config);
|
||||
}
|
||||
|
||||
void dcc_push_monitors_config(DisplayChannelClient *dcc)
|
||||
@ -537,26 +521,18 @@ void dcc_push_monitors_config(DisplayChannelClient *dcc)
|
||||
return;
|
||||
}
|
||||
|
||||
mci = red_monitors_config_item_new(dcc->get_channel(),
|
||||
monitors_config);
|
||||
dcc->pipe_add(&mci->base);
|
||||
mci = new RedMonitorsConfigItem(monitors_config);
|
||||
dcc->pipe_add(mci);
|
||||
}
|
||||
|
||||
static RedSurfaceDestroyItem *red_surface_destroy_item_new(uint32_t surface_id)
|
||||
RedSurfaceDestroyItem::RedSurfaceDestroyItem(uint32_t surface_id):
|
||||
RedPipeItem(RED_PIPE_ITEM_TYPE_DESTROY_SURFACE)
|
||||
{
|
||||
RedSurfaceDestroyItem *destroy;
|
||||
|
||||
destroy = g_new(RedSurfaceDestroyItem, 1);
|
||||
destroy->surface_destroy.surface_id = surface_id;
|
||||
red_pipe_item_init(&destroy->base, RED_PIPE_ITEM_TYPE_DESTROY_SURFACE);
|
||||
|
||||
return destroy;
|
||||
surface_destroy.surface_id = surface_id;
|
||||
}
|
||||
|
||||
RedPipeItem *dcc_gl_scanout_item_new(RedChannelClient *rcc, void *data, int num)
|
||||
{
|
||||
RedGlScanoutUnixItem *item;
|
||||
|
||||
/* FIXME: on !unix peer, start streaming with a video codec */
|
||||
if (!red_stream_is_plain_unix(rcc->get_stream()) ||
|
||||
!rcc->test_remote_cap(SPICE_DISPLAY_CAP_GL_SCANOUT)) {
|
||||
@ -566,10 +542,7 @@ RedPipeItem *dcc_gl_scanout_item_new(RedChannelClient *rcc, void *data, int num)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item = g_new(RedGlScanoutUnixItem, 1);
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_GL_SCANOUT);
|
||||
|
||||
return &item->base;
|
||||
return new RedGlScanoutUnixItem(RED_PIPE_ITEM_TYPE_GL_SCANOUT);
|
||||
}
|
||||
|
||||
XXX_CAST(RedChannelClient, DisplayChannelClient, DISPLAY_CHANNEL_CLIENT);
|
||||
@ -589,11 +562,10 @@ RedPipeItem *dcc_gl_draw_item_new(RedChannelClient *rcc, void *data, int num)
|
||||
}
|
||||
|
||||
dcc->priv->gl_draw_ongoing = TRUE;
|
||||
item = g_new(RedGlDrawItem, 1);
|
||||
item = new RedGlDrawItem(RED_PIPE_ITEM_TYPE_GL_DRAW);
|
||||
item->draw = *draw;
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_GL_DRAW);
|
||||
|
||||
return &item->base;
|
||||
return item;
|
||||
}
|
||||
|
||||
void dcc_destroy_surface(DisplayChannelClient *dcc, uint32_t surface_id)
|
||||
@ -613,8 +585,8 @@ void dcc_destroy_surface(DisplayChannelClient *dcc, uint32_t surface_id)
|
||||
}
|
||||
|
||||
dcc->priv->surface_client_created[surface_id] = FALSE;
|
||||
destroy = red_surface_destroy_item_new(surface_id);
|
||||
dcc->pipe_add(&destroy->base);
|
||||
destroy = new RedSurfaceDestroyItem(surface_id);
|
||||
dcc->pipe_add(destroy);
|
||||
}
|
||||
|
||||
#define MIN_DIMENSION_TO_QUIC 3
|
||||
|
||||
35
server/dcc.h
35
server/dcc.h
@ -96,22 +96,26 @@ typedef struct FreeList {
|
||||
|
||||
#define DCC_TO_DC(dcc) ((DisplayChannel*) dcc->get_channel())
|
||||
|
||||
typedef struct RedSurfaceCreateItem {
|
||||
RedPipeItem base;
|
||||
struct RedSurfaceCreateItem: public RedPipeItem {
|
||||
RedSurfaceCreateItem(uint32_t surface_id,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t format,
|
||||
uint32_t flags);
|
||||
SpiceMsgSurfaceCreate surface_create;
|
||||
} RedSurfaceCreateItem;
|
||||
};
|
||||
|
||||
typedef struct RedGlScanoutUnixItem {
|
||||
RedPipeItem base;
|
||||
} RedGlScanoutUnixItem;
|
||||
struct RedGlScanoutUnixItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
};
|
||||
|
||||
typedef struct RedGlDrawItem {
|
||||
RedPipeItem base;
|
||||
struct RedGlDrawItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
SpiceMsgDisplayGlDraw draw;
|
||||
} RedGlDrawItem;
|
||||
};
|
||||
|
||||
typedef struct RedImageItem {
|
||||
RedPipeItem base;
|
||||
struct RedImageItem final: public RedPipeItem {
|
||||
RedImageItem();
|
||||
SpicePoint pos;
|
||||
int width;
|
||||
int height;
|
||||
@ -122,13 +126,14 @@ typedef struct RedImageItem {
|
||||
uint32_t image_flags;
|
||||
int can_lossy;
|
||||
uint8_t data[0];
|
||||
} RedImageItem;
|
||||
};
|
||||
|
||||
typedef struct RedDrawablePipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedDrawablePipeItem: public RedPipeItem {
|
||||
RedDrawablePipeItem();
|
||||
~RedDrawablePipeItem();
|
||||
Drawable *drawable;
|
||||
DisplayChannelClient *dcc;
|
||||
} RedDrawablePipeItem;
|
||||
};
|
||||
|
||||
DisplayChannelClient* dcc_new (DisplayChannel *display,
|
||||
RedClient *client,
|
||||
|
||||
@ -139,10 +139,11 @@ struct DisplayChannelPrivate
|
||||
GLIST_FOREACH((_channel ? _channel->get_clients() : NULL), \
|
||||
DisplayChannelClient, _data)
|
||||
|
||||
typedef struct RedMonitorsConfigItem {
|
||||
RedPipeItem base;
|
||||
struct RedMonitorsConfigItem: public RedPipeItem {
|
||||
RedMonitorsConfigItem(MonitorsConfig *monitors_config);
|
||||
~RedMonitorsConfigItem();
|
||||
MonitorsConfig *monitors_config;
|
||||
} RedMonitorsConfigItem;
|
||||
};
|
||||
|
||||
enum {
|
||||
RED_PIPE_ITEM_TYPE_DRAW = RED_PIPE_ITEM_TYPE_COMMON_LAST,
|
||||
@ -181,10 +182,10 @@ uint32_t display_channel_generate_uid(DisplayChannel *display);
|
||||
int display_channel_get_video_stream_id(DisplayChannel *display, VideoStream *stream);
|
||||
VideoStream *display_channel_get_nth_video_stream(DisplayChannel *display, gint i);
|
||||
|
||||
typedef struct RedSurfaceDestroyItem {
|
||||
RedPipeItem base;
|
||||
struct RedSurfaceDestroyItem: public RedPipeItem {
|
||||
RedSurfaceDestroyItem(uint32_t surface_id);
|
||||
SpiceMsgSurfaceDestroy surface_destroy;
|
||||
} RedSurfaceDestroyItem;
|
||||
};
|
||||
|
||||
static inline int is_equal_path(SpicePath *path1, SpicePath *path2)
|
||||
{
|
||||
|
||||
@ -327,7 +327,7 @@ static void pipes_add_drawable_after(DisplayChannel *display,
|
||||
dpi_pos_after = (RedDrawablePipeItem*) l->data;
|
||||
|
||||
num_other_linked++;
|
||||
dcc_add_drawable_after(dpi_pos_after->dcc, drawable, &dpi_pos_after->base);
|
||||
dcc_add_drawable_after(dpi_pos_after->dcc, drawable, dpi_pos_after);
|
||||
}
|
||||
|
||||
if (num_other_linked == 0) {
|
||||
@ -387,7 +387,7 @@ static void drawable_remove_from_pipes(Drawable *drawable)
|
||||
RedChannelClient *rcc;
|
||||
|
||||
rcc = dpi->dcc;
|
||||
rcc->pipe_remove_and_release(&dpi->base);
|
||||
rcc->pipe_remove_and_release(dpi);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -86,15 +86,15 @@ RedsState* spice_tablet_state_get_server(SpiceTabletState *st)
|
||||
return st->reds;
|
||||
}
|
||||
|
||||
typedef struct RedKeyModifiersPipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedKeyModifiersPipeItem: public RedPipeItem {
|
||||
RedKeyModifiersPipeItem(uint8_t modifiers);
|
||||
uint8_t modifiers;
|
||||
} RedKeyModifiersPipeItem;
|
||||
};
|
||||
|
||||
typedef struct RedInputsInitPipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedInputsInitPipeItem: public RedPipeItem {
|
||||
RedInputsInitPipeItem(uint8_t modifiers);
|
||||
uint8_t modifiers;
|
||||
} RedInputsInitPipeItem;
|
||||
};
|
||||
|
||||
|
||||
#define KEY_MODIFIERS_TTL (MSEC_PER_SEC * 2)
|
||||
@ -194,13 +194,10 @@ static uint8_t kbd_get_leds(SpiceKbdInstance *sin)
|
||||
return sif->get_leds(sin);
|
||||
}
|
||||
|
||||
static RedPipeItem *red_inputs_key_modifiers_item_new(uint8_t modifiers)
|
||||
RedKeyModifiersPipeItem::RedKeyModifiersPipeItem(uint8_t init_modifiers):
|
||||
RedPipeItem(RED_PIPE_ITEM_KEY_MODIFIERS),
|
||||
modifiers(init_modifiers)
|
||||
{
|
||||
RedKeyModifiersPipeItem *item = g_new(RedKeyModifiersPipeItem, 1);
|
||||
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_KEY_MODIFIERS);
|
||||
item->modifiers = modifiers;
|
||||
return &item->base;
|
||||
}
|
||||
|
||||
void InputsChannelClient::send_item(RedPipeItem *base)
|
||||
@ -214,7 +211,7 @@ void InputsChannelClient::send_item(RedPipeItem *base)
|
||||
|
||||
init_send_data(SPICE_MSG_INPUTS_KEY_MODIFIERS);
|
||||
key_modifiers.modifiers =
|
||||
SPICE_UPCAST(RedKeyModifiersPipeItem, base)->modifiers;
|
||||
static_cast<RedKeyModifiersPipeItem*>(base)->modifiers;
|
||||
spice_marshall_msg_inputs_key_modifiers(m, &key_modifiers);
|
||||
break;
|
||||
}
|
||||
@ -224,7 +221,7 @@ void InputsChannelClient::send_item(RedPipeItem *base)
|
||||
|
||||
init_send_data(SPICE_MSG_INPUTS_INIT);
|
||||
inputs_init.keyboard_modifiers =
|
||||
SPICE_UPCAST(RedInputsInitPipeItem, base)->modifiers;
|
||||
static_cast<RedInputsInitPipeItem*>(base)->modifiers;
|
||||
spice_marshall_msg_inputs_init(m, &inputs_init);
|
||||
break;
|
||||
}
|
||||
@ -432,14 +429,16 @@ void InputsChannel::release_keys()
|
||||
}
|
||||
}
|
||||
|
||||
RedInputsInitPipeItem::RedInputsInitPipeItem(uint8_t init_modifiers):
|
||||
RedPipeItem(RED_PIPE_ITEM_INPUTS_INIT),
|
||||
modifiers(init_modifiers)
|
||||
{
|
||||
}
|
||||
|
||||
void InputsChannelClient::pipe_add_init()
|
||||
{
|
||||
RedInputsInitPipeItem *item = g_new(RedInputsInitPipeItem, 1);
|
||||
InputsChannel *inputs = get_channel();
|
||||
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_INPUTS_INIT);
|
||||
item->modifiers = kbd_get_leds(inputs->keyboard);
|
||||
pipe_add_push(&item->base);
|
||||
auto modifiers = kbd_get_leds(get_channel()->keyboard);
|
||||
pipe_add_push(new RedInputsInitPipeItem(modifiers));
|
||||
}
|
||||
|
||||
void InputsChannel::on_connect(RedClient *client, RedStream *stream, int migration,
|
||||
@ -464,7 +463,7 @@ void InputsChannel::push_keyboard_modifiers()
|
||||
if (!is_connected() || src_during_migrate) {
|
||||
return;
|
||||
}
|
||||
pipes_add(red_inputs_key_modifiers_item_new(modifiers));
|
||||
pipes_add(new RedKeyModifiersPipeItem(modifiers));
|
||||
}
|
||||
|
||||
SPICE_GNUC_VISIBLE int spice_server_kbd_leds(SpiceKbdInstance *sin, int leds)
|
||||
|
||||
@ -61,65 +61,67 @@ struct MainChannelClientPrivate {
|
||||
uint8_t recv_buf[MAIN_CHANNEL_RECEIVE_BUF_SIZE];
|
||||
};
|
||||
|
||||
typedef struct RedPingPipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedPingPipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
int size;
|
||||
} RedPingPipeItem;
|
||||
};
|
||||
|
||||
typedef struct RedTokensPipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedTokensPipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
int tokens;
|
||||
} RedTokensPipeItem;
|
||||
};
|
||||
|
||||
typedef struct RedAgentDataPipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedAgentDataPipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
~RedAgentDataPipeItem();
|
||||
uint8_t* data;
|
||||
size_t len;
|
||||
spice_marshaller_item_free_func free_data;
|
||||
void *opaque;
|
||||
} RedAgentDataPipeItem;
|
||||
};
|
||||
|
||||
typedef struct RedInitPipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedInitPipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
int connection_id;
|
||||
int display_channels_hint;
|
||||
int current_mouse_mode;
|
||||
int is_client_mouse_allowed;
|
||||
int multi_media_time;
|
||||
int ram_hint;
|
||||
} RedInitPipeItem;
|
||||
};
|
||||
|
||||
typedef struct RedNamePipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedNamePipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
SpiceMsgMainName msg;
|
||||
} RedNamePipeItem;
|
||||
};
|
||||
|
||||
typedef struct RedUuidPipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedUuidPipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
SpiceMsgMainUuid msg;
|
||||
} RedUuidPipeItem;
|
||||
};
|
||||
|
||||
typedef struct RedNotifyPipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedNotifyPipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
~RedNotifyPipeItem();
|
||||
char *msg;
|
||||
} RedNotifyPipeItem;
|
||||
};
|
||||
|
||||
typedef struct RedMouseModePipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedMouseModePipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
SpiceMouseMode current_mode;
|
||||
int is_client_mouse_allowed;
|
||||
} RedMouseModePipeItem;
|
||||
};
|
||||
|
||||
typedef struct RedMultiMediaTimePipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedMultiMediaTimePipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
uint32_t time;
|
||||
} RedMultiMediaTimePipeItem;
|
||||
};
|
||||
|
||||
typedef struct RedRegisteredChannelPipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedRegisteredChannelPipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
uint32_t channel_type;
|
||||
uint32_t channel_id;
|
||||
} RedRegisteredChannelPipeItem;
|
||||
};
|
||||
|
||||
#define ZERO_BUF_SIZE 4096
|
||||
|
||||
@ -157,21 +159,17 @@ void MainChannelClient::on_disconnect()
|
||||
|
||||
static void main_channel_client_push_ping(MainChannelClient *mcc, int size);
|
||||
|
||||
static void main_notify_item_free(RedPipeItem *base)
|
||||
RedNotifyPipeItem::~RedNotifyPipeItem()
|
||||
{
|
||||
RedNotifyPipeItem *data = SPICE_UPCAST(RedNotifyPipeItem, base);
|
||||
g_free(data->msg);
|
||||
g_free(data);
|
||||
g_free(msg);
|
||||
}
|
||||
|
||||
static RedPipeItem *main_notify_item_new(const char *msg, int num)
|
||||
{
|
||||
RedNotifyPipeItem *item = g_new(RedNotifyPipeItem, 1);
|
||||
RedNotifyPipeItem *item = new RedNotifyPipeItem(RED_PIPE_ITEM_TYPE_MAIN_NOTIFY);
|
||||
|
||||
red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_MAIN_NOTIFY,
|
||||
main_notify_item_free);
|
||||
item->msg = g_strdup(msg);
|
||||
return &item->base;
|
||||
return item;
|
||||
}
|
||||
|
||||
void MainChannelClient::start_net_test(int test_rate)
|
||||
@ -195,11 +193,10 @@ void MainChannelClient::start_net_test(int test_rate)
|
||||
|
||||
static RedPipeItem *red_ping_item_new(int size)
|
||||
{
|
||||
RedPingPipeItem *item = g_new(RedPingPipeItem, 1);
|
||||
RedPingPipeItem *item = new RedPingPipeItem(RED_PIPE_ITEM_TYPE_MAIN_PING);
|
||||
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_PING);
|
||||
item->size = size;
|
||||
return &item->base;
|
||||
return item;
|
||||
}
|
||||
|
||||
static void main_channel_client_push_ping(MainChannelClient *mcc, int size)
|
||||
@ -210,11 +207,10 @@ static void main_channel_client_push_ping(MainChannelClient *mcc, int size)
|
||||
|
||||
static RedPipeItem *main_agent_tokens_item_new(uint32_t num_tokens)
|
||||
{
|
||||
RedTokensPipeItem *item = g_new(RedTokensPipeItem, 1);
|
||||
RedTokensPipeItem *item = new RedTokensPipeItem(RED_PIPE_ITEM_TYPE_MAIN_AGENT_TOKEN);
|
||||
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_AGENT_TOKEN);
|
||||
item->tokens = num_tokens;
|
||||
return &item->base;
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
@ -225,26 +221,22 @@ void MainChannelClient::push_agent_tokens(uint32_t num_tokens)
|
||||
pipe_add_push(item);
|
||||
}
|
||||
|
||||
static void main_agent_data_item_free(RedPipeItem *base)
|
||||
RedAgentDataPipeItem::~RedAgentDataPipeItem()
|
||||
{
|
||||
RedAgentDataPipeItem *item = SPICE_UPCAST(RedAgentDataPipeItem, base);
|
||||
item->free_data(item->data, item->opaque);
|
||||
g_free(item);
|
||||
free_data(data, opaque);
|
||||
}
|
||||
|
||||
static RedPipeItem *main_agent_data_item_new(uint8_t* data, size_t len,
|
||||
spice_marshaller_item_free_func free_data,
|
||||
void *opaque)
|
||||
{
|
||||
RedAgentDataPipeItem *item = g_new(RedAgentDataPipeItem, 1);
|
||||
RedAgentDataPipeItem *item = new RedAgentDataPipeItem(RED_PIPE_ITEM_TYPE_MAIN_AGENT_DATA);
|
||||
|
||||
red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_MAIN_AGENT_DATA,
|
||||
main_agent_data_item_free);
|
||||
item->data = data;
|
||||
item->len = len;
|
||||
item->free_data = free_data;
|
||||
item->opaque = opaque;
|
||||
return &item->base;
|
||||
return item;
|
||||
}
|
||||
|
||||
void MainChannelClient::push_agent_data(uint8_t *data, size_t len,
|
||||
@ -264,16 +256,15 @@ static RedPipeItem *main_init_item_new(int connection_id,
|
||||
int multi_media_time,
|
||||
int ram_hint)
|
||||
{
|
||||
RedInitPipeItem *item = g_new(RedInitPipeItem, 1);
|
||||
RedInitPipeItem *item = new RedInitPipeItem(RED_PIPE_ITEM_TYPE_MAIN_INIT);
|
||||
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_INIT);
|
||||
item->connection_id = connection_id;
|
||||
item->display_channels_hint = display_channels_hint;
|
||||
item->current_mouse_mode = current_mouse_mode;
|
||||
item->is_client_mouse_allowed = is_client_mouse_allowed;
|
||||
item->multi_media_time = multi_media_time;
|
||||
item->ram_hint = ram_hint;
|
||||
return &item->base;
|
||||
return item;
|
||||
}
|
||||
|
||||
void MainChannelClient::push_init(int display_channels_hint,
|
||||
@ -291,13 +282,11 @@ void MainChannelClient::push_init(int display_channels_hint,
|
||||
|
||||
static RedPipeItem *main_name_item_new(const char *name)
|
||||
{
|
||||
RedNamePipeItem *item = (RedNamePipeItem*) g_malloc(sizeof(RedNamePipeItem) + strlen(name) + 1);
|
||||
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_NAME);
|
||||
RedNamePipeItem *item = new (strlen(name) + 1) RedNamePipeItem(RED_PIPE_ITEM_TYPE_MAIN_NAME);
|
||||
item->msg.name_len = strlen(name) + 1;
|
||||
memcpy(&item->msg.name, name, item->msg.name_len);
|
||||
|
||||
return &item->base;
|
||||
return item;
|
||||
}
|
||||
|
||||
void MainChannelClient::push_name(const char *name)
|
||||
@ -313,12 +302,11 @@ void MainChannelClient::push_name(const char *name)
|
||||
|
||||
static RedPipeItem *main_uuid_item_new(const uint8_t uuid[16])
|
||||
{
|
||||
RedUuidPipeItem *item = g_new(RedUuidPipeItem, 1);
|
||||
RedUuidPipeItem *item = new RedUuidPipeItem(RED_PIPE_ITEM_TYPE_MAIN_UUID);
|
||||
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_UUID);
|
||||
memcpy(item->msg.uuid, uuid, sizeof(item->msg.uuid));
|
||||
|
||||
return &item->base;
|
||||
return item;
|
||||
}
|
||||
|
||||
void MainChannelClient::push_uuid(const uint8_t uuid[16])
|
||||
@ -340,34 +328,31 @@ void MainChannelClient::push_notify(const char *msg)
|
||||
|
||||
RedPipeItem *main_mouse_mode_item_new(SpiceMouseMode current_mode, int is_client_mouse_allowed)
|
||||
{
|
||||
RedMouseModePipeItem *item = g_new(RedMouseModePipeItem, 1);
|
||||
RedMouseModePipeItem *item = new RedMouseModePipeItem(RED_PIPE_ITEM_TYPE_MAIN_MOUSE_MODE);
|
||||
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_MOUSE_MODE);
|
||||
item->current_mode = current_mode;
|
||||
item->is_client_mouse_allowed = is_client_mouse_allowed;
|
||||
return &item->base;
|
||||
return item;
|
||||
}
|
||||
|
||||
RedPipeItem *main_multi_media_time_item_new(uint32_t mm_time)
|
||||
{
|
||||
RedMultiMediaTimePipeItem *item;
|
||||
|
||||
item = g_new(RedMultiMediaTimePipeItem, 1);
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_MULTI_MEDIA_TIME);
|
||||
item = new RedMultiMediaTimePipeItem(RED_PIPE_ITEM_TYPE_MAIN_MULTI_MEDIA_TIME);
|
||||
item->time = mm_time;
|
||||
return &item->base;
|
||||
return item;
|
||||
}
|
||||
|
||||
RedPipeItem *registered_channel_item_new(RedChannel *channel)
|
||||
{
|
||||
RedRegisteredChannelPipeItem *item;
|
||||
|
||||
item = g_new0(RedRegisteredChannelPipeItem, 1);
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_REGISTERED_CHANNEL);
|
||||
item = new RedRegisteredChannelPipeItem(RED_PIPE_ITEM_TYPE_MAIN_REGISTERED_CHANNEL);
|
||||
|
||||
item->channel_type = channel->type();
|
||||
item->channel_id = channel->id();
|
||||
return &item->base;
|
||||
return item;
|
||||
}
|
||||
|
||||
void MainChannelClient::handle_migrate_connected(int success, int seamless)
|
||||
@ -684,7 +669,7 @@ static void main_channel_marshall_agent_data(RedChannelClient *rcc,
|
||||
{
|
||||
rcc->init_send_data(SPICE_MSG_MAIN_AGENT_DATA);
|
||||
/* since pipe item owns the data, keep it alive until it's sent */
|
||||
item->base.add_to_marshaller(m, item->data, item->len);
|
||||
item->add_to_marshaller(m, item->data, item->len);
|
||||
}
|
||||
|
||||
static void main_channel_marshall_migrate_data_item(RedChannelClient *rcc,
|
||||
@ -863,22 +848,22 @@ void MainChannelClient::send_item(RedPipeItem *base)
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_PING:
|
||||
main_channel_marshall_ping(this, m,
|
||||
SPICE_UPCAST(RedPingPipeItem, base));
|
||||
static_cast<RedPingPipeItem*>(base));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_MOUSE_MODE:
|
||||
main_channel_marshall_mouse_mode(this, m,
|
||||
SPICE_UPCAST(RedMouseModePipeItem, base));
|
||||
static_cast<RedMouseModePipeItem*>(base));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_AGENT_DISCONNECTED:
|
||||
main_channel_marshall_agent_disconnected(this, m, base);
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_AGENT_TOKEN:
|
||||
main_channel_marshall_tokens(this, m,
|
||||
SPICE_UPCAST(RedTokensPipeItem, base));
|
||||
static_cast<RedTokensPipeItem*>(base));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_AGENT_DATA:
|
||||
main_channel_marshall_agent_data(this, m,
|
||||
SPICE_UPCAST(RedAgentDataPipeItem, base));
|
||||
static_cast<RedAgentDataPipeItem*>(base));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_DATA:
|
||||
main_channel_marshall_migrate_data_item(this, m, base);
|
||||
@ -886,11 +871,11 @@ void MainChannelClient::send_item(RedPipeItem *base)
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_INIT:
|
||||
priv->init_sent = TRUE;
|
||||
main_channel_marshall_init(this, m,
|
||||
SPICE_UPCAST(RedInitPipeItem, base));
|
||||
static_cast<RedInitPipeItem*>(base));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_NOTIFY:
|
||||
main_channel_marshall_notify(this, m,
|
||||
SPICE_UPCAST(RedNotifyPipeItem, base));
|
||||
static_cast<RedNotifyPipeItem*>(base));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_BEGIN:
|
||||
main_channel_marshall_migrate_begin(m, this, base);
|
||||
@ -900,18 +885,18 @@ void MainChannelClient::send_item(RedPipeItem *base)
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_MULTI_MEDIA_TIME:
|
||||
main_channel_marshall_multi_media_time(this, m,
|
||||
SPICE_UPCAST(RedMultiMediaTimePipeItem, base));
|
||||
static_cast<RedMultiMediaTimePipeItem*>(base));
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_SWITCH_HOST:
|
||||
main_channel_marshall_migrate_switch(m, this, base);
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_NAME:
|
||||
init_send_data(SPICE_MSG_MAIN_NAME);
|
||||
spice_marshall_msg_main_name(m, &SPICE_UPCAST(RedNamePipeItem, base)->msg);
|
||||
spice_marshall_msg_main_name(m, &static_cast<RedNamePipeItem*>(base)->msg);
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_UUID:
|
||||
init_send_data(SPICE_MSG_MAIN_UUID);
|
||||
spice_marshall_msg_main_uuid(m, &SPICE_UPCAST(RedUuidPipeItem, base)->msg);
|
||||
spice_marshall_msg_main_uuid(m, &static_cast<RedUuidPipeItem*>(base)->msg);
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MAIN_AGENT_CONNECTED_TOKENS:
|
||||
main_channel_marshall_agent_connected(m, this, base);
|
||||
@ -925,7 +910,7 @@ void MainChannelClient::send_item(RedPipeItem *base)
|
||||
return;
|
||||
}
|
||||
main_channel_marshall_registered_channel(this, m,
|
||||
SPICE_UPCAST(RedRegisteredChannelPipeItem, base));
|
||||
static_cast<RedRegisteredChannelPipeItem*>(base));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -239,15 +239,15 @@ static const SpiceDataHeaderOpaque mini_header_wrapper = {NULL, sizeof(SpiceMini
|
||||
#define PING_TEST_LONG_TIMEOUT_MS (MSEC_PER_SEC * 60 * 5)
|
||||
#define PING_TEST_IDLE_NET_TIMEOUT_MS (MSEC_PER_SEC / 10)
|
||||
|
||||
typedef struct RedEmptyMsgPipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedEmptyMsgPipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
int msg;
|
||||
} RedEmptyMsgPipeItem;
|
||||
};
|
||||
|
||||
typedef struct MarkerPipeItem {
|
||||
RedPipeItem base;
|
||||
struct MarkerPipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
bool item_sent;
|
||||
} MarkerPipeItem;
|
||||
};
|
||||
|
||||
void RedChannelClientPrivate::start_ping_timer(uint32_t timeout)
|
||||
{
|
||||
@ -488,7 +488,7 @@ void RedChannelClient::send_ping()
|
||||
|
||||
void RedChannelClient::send_empty_msg(RedPipeItem *base)
|
||||
{
|
||||
RedEmptyMsgPipeItem *msg_pipe_item = SPICE_UPCAST(RedEmptyMsgPipeItem, base);
|
||||
RedEmptyMsgPipeItem *msg_pipe_item = static_cast<RedEmptyMsgPipeItem*>(base);
|
||||
|
||||
init_send_data(msg_pipe_item->msg);
|
||||
begin_send_message();
|
||||
@ -512,7 +512,7 @@ void RedChannelClient::send_any_item(RedPipeItem *item)
|
||||
send_ping();
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MARKER:
|
||||
SPICE_UPCAST(MarkerPipeItem, item)->item_sent = true;
|
||||
static_cast<MarkerPipeItem*>(item)->item_sent = true;
|
||||
break;
|
||||
default:
|
||||
send_item(item);
|
||||
@ -1428,19 +1428,17 @@ void RedChannelClient::pipe_add_tail(RedPipeItem *item)
|
||||
|
||||
void RedChannelClient::pipe_add_type(int pipe_item_type)
|
||||
{
|
||||
RedPipeItem *item = g_new(RedPipeItem, 1);
|
||||
RedPipeItem *item = new RedPipeItem(pipe_item_type);
|
||||
|
||||
red_pipe_item_init(item, pipe_item_type);
|
||||
pipe_add(item);
|
||||
}
|
||||
|
||||
RedPipeItem *RedChannelClient::new_empty_msg(int msg_type)
|
||||
{
|
||||
RedEmptyMsgPipeItem *item = g_new(RedEmptyMsgPipeItem, 1);
|
||||
RedEmptyMsgPipeItem *item = new RedEmptyMsgPipeItem(RED_PIPE_ITEM_TYPE_EMPTY_MSG);
|
||||
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_EMPTY_MSG);
|
||||
item->msg = msg_type;
|
||||
return &item->base;
|
||||
return item;
|
||||
}
|
||||
|
||||
void RedChannelClient::pipe_add_empty_msg(int msg_type)
|
||||
@ -1578,12 +1576,11 @@ bool RedChannelClient::wait_pipe_item_sent(GList *item_pos, int64_t timeout)
|
||||
end_time = UINT64_MAX;
|
||||
}
|
||||
|
||||
MarkerPipeItem *mark_item = g_new0(MarkerPipeItem, 1);
|
||||
MarkerPipeItem *mark_item = new MarkerPipeItem(RED_PIPE_ITEM_TYPE_MARKER);
|
||||
|
||||
red_pipe_item_init(&mark_item->base, RED_PIPE_ITEM_TYPE_MARKER);
|
||||
mark_item->item_sent = false;
|
||||
red_pipe_item_ref(&mark_item->base);
|
||||
pipe_add_before_pos(&mark_item->base, item_pos);
|
||||
red_pipe_item_ref(mark_item);
|
||||
pipe_add_before_pos(mark_item, item_pos);
|
||||
|
||||
for (;;) {
|
||||
receive();
|
||||
@ -1596,7 +1593,7 @@ bool RedChannelClient::wait_pipe_item_sent(GList *item_pos, int64_t timeout)
|
||||
}
|
||||
|
||||
item_sent = mark_item->item_sent;
|
||||
red_pipe_item_unref(&mark_item->base);
|
||||
red_pipe_item_unref(mark_item);
|
||||
|
||||
if (!item_sent) {
|
||||
// still on the queue
|
||||
|
||||
@ -280,9 +280,7 @@ void RedChannel::pipes_add(RedPipeItem *item)
|
||||
|
||||
void RedChannel::pipes_add_type(int pipe_item_type)
|
||||
{
|
||||
RedPipeItem *item = g_new(RedPipeItem, 1);
|
||||
|
||||
red_pipe_item_init(item, pipe_item_type);
|
||||
RedPipeItem *item = new RedPipeItem(pipe_item_type);
|
||||
|
||||
pipes_add(item);
|
||||
}
|
||||
|
||||
@ -20,31 +20,25 @@
|
||||
#include "red-channel.h"
|
||||
#include "red-pipe-item.h"
|
||||
|
||||
RedPipeItem::RedPipeItem(int init_type):
|
||||
type(init_type)
|
||||
{
|
||||
// compatibility with no shared_ptr reference counting
|
||||
shared_ptr_add_ref(this);
|
||||
}
|
||||
|
||||
RedPipeItem *red_pipe_item_ref(RedPipeItem *item)
|
||||
{
|
||||
g_return_val_if_fail(item->refcount > 0, NULL);
|
||||
|
||||
g_atomic_int_inc(&item->refcount);
|
||||
// this call should be replaced by shared_ptr instead
|
||||
shared_ptr_add_ref(item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void red_pipe_item_unref(RedPipeItem *item)
|
||||
{
|
||||
g_return_if_fail(item->refcount > 0);
|
||||
|
||||
if (g_atomic_int_dec_and_test(&item->refcount)) {
|
||||
item->free_func(item);
|
||||
}
|
||||
}
|
||||
|
||||
void red_pipe_item_init_full(RedPipeItem *item,
|
||||
gint type,
|
||||
red_pipe_item_free_t *free_func)
|
||||
{
|
||||
item->type = type;
|
||||
item->refcount = 1;
|
||||
item->free_func = free_func ? free_func : (red_pipe_item_free_t *)g_free;
|
||||
// this call should be replaced by shared_ptr instead
|
||||
shared_ptr_unref(item);
|
||||
}
|
||||
|
||||
static void marshaller_unref_pipe_item(uint8_t *, void *opaque)
|
||||
|
||||
@ -16,40 +16,57 @@
|
||||
License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file red-pipe-item.h
|
||||
* Generic declaration for objects contained in RedChannelClient pipe.
|
||||
*/
|
||||
#ifndef RED_PIPE_ITEM_H_
|
||||
#define RED_PIPE_ITEM_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "common/marshaller.h"
|
||||
#include "red-common.h"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include "push-visibility.h"
|
||||
|
||||
typedef struct RedPipeItem RedPipeItem;
|
||||
/**
|
||||
* Base class for objects contained in RedChannelClient pipe
|
||||
*/
|
||||
struct RedPipeItem: public red::shared_ptr_counted
|
||||
{
|
||||
SPICE_CXX_GLIB_ALLOCATOR
|
||||
void *operator new(size_t len, void *p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
typedef void red_pipe_item_free_t(RedPipeItem *item);
|
||||
/**
|
||||
* Allows to allocate a pipe item with additional space at the end.
|
||||
*
|
||||
* Used with structures like
|
||||
* @code{.cpp}
|
||||
* struct NameItem: public RedPipeItem {
|
||||
* ...
|
||||
* char name[];
|
||||
* }
|
||||
* ...
|
||||
* auto name_item = red::shared_ptr<NameItem>(new (6) NameItem(...));
|
||||
* strcpy(name_item->name, "hello");
|
||||
* @endcode
|
||||
*/
|
||||
void *operator new(size_t size, size_t additional)
|
||||
{
|
||||
return g_malloc(size + additional);
|
||||
}
|
||||
|
||||
struct RedPipeItem {
|
||||
int type;
|
||||
RedPipeItem(int type);
|
||||
const int type;
|
||||
|
||||
void add_to_marshaller(SpiceMarshaller *m, uint8_t *data, size_t size);
|
||||
|
||||
/* private */
|
||||
int refcount;
|
||||
|
||||
red_pipe_item_free_t *free_func;
|
||||
};
|
||||
|
||||
void red_pipe_item_init_full(RedPipeItem *item, int type, red_pipe_item_free_t free_func);
|
||||
RedPipeItem *red_pipe_item_ref(RedPipeItem *item);
|
||||
void red_pipe_item_unref(RedPipeItem *item);
|
||||
|
||||
static inline void red_pipe_item_init(RedPipeItem *item, int type)
|
||||
{
|
||||
red_pipe_item_init_full(item, type, NULL);
|
||||
}
|
||||
|
||||
#include "pop-visibility.h"
|
||||
|
||||
#endif /* RED_PIPE_ITEM_H_ */
|
||||
|
||||
@ -153,13 +153,15 @@ struct ChannelSecurityOptions {
|
||||
ChannelSecurityOptions *next;
|
||||
};
|
||||
|
||||
typedef struct RedVDIReadBuf {
|
||||
RedPipeItem base;
|
||||
struct RedVDIReadBuf final: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
~RedVDIReadBuf();
|
||||
|
||||
RedCharDeviceVDIPort *dev;
|
||||
|
||||
int len;
|
||||
uint8_t data[SPICE_AGENT_MAX_DATA_SIZE];
|
||||
} RedVDIReadBuf;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
VDI_PORT_READ_STATE_READ_HEADER,
|
||||
@ -238,7 +240,6 @@ static uint32_t reds_qxl_ram_size(RedsState *reds);
|
||||
static int calc_compression_level(RedsState *reds);
|
||||
|
||||
static RedVDIReadBuf *vdi_port_get_read_buf(RedCharDeviceVDIPort *dev);
|
||||
static red_pipe_item_free_t vdi_port_read_buf_free;
|
||||
|
||||
static ChannelSecurityOptions *reds_find_channel_security(RedsState *reds, int id)
|
||||
{
|
||||
@ -405,7 +406,7 @@ static void reds_reset_vdp(RedsState *reds)
|
||||
dev->priv->receive_len = sizeof(dev->priv->vdi_chunk_header);
|
||||
dev->priv->message_receive_len = 0;
|
||||
if (dev->priv->current_read_buf) {
|
||||
red_pipe_item_unref(&dev->priv->current_read_buf->base);
|
||||
red_pipe_item_unref(dev->priv->current_read_buf);
|
||||
dev->priv->current_read_buf = NULL;
|
||||
}
|
||||
/* Reset read filter to start with clean state when the agent reconnects */
|
||||
@ -658,7 +659,7 @@ static void reds_agent_remove(RedsState *reds)
|
||||
static void vdi_port_read_buf_release(uint8_t *data, void *opaque)
|
||||
{
|
||||
RedVDIReadBuf *read_buf = (RedVDIReadBuf *)opaque;
|
||||
red_pipe_item_unref(&read_buf->base);
|
||||
red_pipe_item_unref(read_buf);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -681,15 +682,25 @@ static AgentMsgFilterResult vdi_port_read_buf_process(RedCharDeviceVDIPort *dev,
|
||||
}
|
||||
}
|
||||
|
||||
RedVDIReadBuf::~RedVDIReadBuf()
|
||||
{
|
||||
dev->priv->num_read_buf--;
|
||||
|
||||
/* read_one_msg_from_vdi_port may have never completed because we
|
||||
reached buffer limit. So we call it again so it can complete its work if
|
||||
necessary. Note that since we can be called from red_char_device_wakeup
|
||||
this can cause recursion, but we have protection for that */
|
||||
if (dev->priv->agent_attached) {
|
||||
dev->wakeup();
|
||||
}
|
||||
}
|
||||
|
||||
static RedVDIReadBuf *vdi_read_buf_new(RedCharDeviceVDIPort *dev)
|
||||
{
|
||||
RedVDIReadBuf *buf = g_new(RedVDIReadBuf, 1);
|
||||
|
||||
/* Bogus pipe item type, we only need the RingItem and refcounting
|
||||
* from the base class and are not going to use the type
|
||||
*/
|
||||
red_pipe_item_init_full(&buf->base, -1,
|
||||
vdi_port_read_buf_free);
|
||||
RedVDIReadBuf *buf = new RedVDIReadBuf(-1);
|
||||
buf->dev = dev;
|
||||
buf->len = 0;
|
||||
return buf;
|
||||
@ -705,23 +716,6 @@ static RedVDIReadBuf *vdi_port_get_read_buf(RedCharDeviceVDIPort *dev)
|
||||
return vdi_read_buf_new(dev);
|
||||
}
|
||||
|
||||
static void vdi_port_read_buf_free(RedPipeItem *base)
|
||||
{
|
||||
RedVDIReadBuf *buf = SPICE_UPCAST(RedVDIReadBuf, base);
|
||||
|
||||
g_warn_if_fail(buf->base.refcount == 0);
|
||||
buf->dev->priv->num_read_buf--;
|
||||
|
||||
/* read_one_msg_from_vdi_port may have never completed because we
|
||||
reached buffer limit. So we call it again so it can complete its work if
|
||||
necessary. Note that since we can be called from red_char_device_wakeup
|
||||
this can cause recursion, but we have protection for that */
|
||||
if (buf->dev->priv->agent_attached) {
|
||||
buf->dev->wakeup();
|
||||
}
|
||||
g_free(buf);
|
||||
}
|
||||
|
||||
/* certain agent capabilities can be overridden and disabled in the server. In these cases, unset
|
||||
* these capabilities before sending them on to the client */
|
||||
static void reds_adjust_agent_capabilities(RedsState *reds, VDAgentMessage *message)
|
||||
@ -807,14 +801,14 @@ RedCharDeviceVDIPort::read_one_msg_from_device()
|
||||
switch (vdi_port_read_buf_process(this, dispatch_buf)) {
|
||||
case AGENT_MSG_FILTER_OK:
|
||||
reds_adjust_agent_capabilities(reds, (VDAgentMessage *) dispatch_buf->data);
|
||||
return &dispatch_buf->base;
|
||||
return dispatch_buf;
|
||||
case AGENT_MSG_FILTER_PROTO_ERROR:
|
||||
reds_agent_remove(reds);
|
||||
/* fall through */
|
||||
case AGENT_MSG_FILTER_MONITORS_CONFIG:
|
||||
/* fall through */
|
||||
case AGENT_MSG_FILTER_DISCARD:
|
||||
red_pipe_item_unref(&dispatch_buf->base);
|
||||
red_pipe_item_unref(dispatch_buf);
|
||||
}
|
||||
}
|
||||
} /* END switch */
|
||||
@ -911,7 +905,7 @@ void reds_send_device_display_info(RedsState *reds)
|
||||
void RedCharDeviceVDIPort::send_msg_to_client(RedPipeItem *msg, RedCharDeviceClientOpaque *opaque)
|
||||
{
|
||||
RedClient *client = (RedClient *) opaque;
|
||||
RedVDIReadBuf *agent_data_buf = (RedVDIReadBuf *)msg;
|
||||
RedVDIReadBuf *agent_data_buf = static_cast<RedVDIReadBuf*>(msg);
|
||||
|
||||
red_pipe_item_ref(msg);
|
||||
client->get_main()->push_agent_data(agent_data_buf->data,
|
||||
@ -1283,7 +1277,7 @@ void reds_on_main_channel_migrate(RedsState *reds, MainChannelClient *mcc)
|
||||
case AGENT_MSG_FILTER_MONITORS_CONFIG:
|
||||
/* fall through */
|
||||
case AGENT_MSG_FILTER_DISCARD:
|
||||
red_pipe_item_unref(&read_buf->base);
|
||||
red_pipe_item_unref(read_buf);
|
||||
}
|
||||
|
||||
spice_assert(agent_dev->priv->receive_len);
|
||||
@ -4472,7 +4466,7 @@ RedCharDeviceVDIPort::~RedCharDeviceVDIPort()
|
||||
/* make sure we have no other references to RedVDIReadBuf buffers */
|
||||
reset();
|
||||
if (priv->current_read_buf) {
|
||||
red_pipe_item_unref(&priv->current_read_buf->base);
|
||||
red_pipe_item_unref(priv->current_read_buf);
|
||||
priv->current_read_buf = NULL;
|
||||
}
|
||||
g_free(priv->mig_data);
|
||||
|
||||
@ -32,11 +32,11 @@ struct SmartCardChannelClientPrivate
|
||||
bool msg_in_write_buf = false;
|
||||
};
|
||||
|
||||
typedef struct RedErrorItem {
|
||||
RedPipeItem base;
|
||||
struct RedErrorItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
VSCMsgHeader vheader;
|
||||
VSCMsgError error;
|
||||
} RedErrorItem;
|
||||
};
|
||||
|
||||
SmartCardChannelClient::SmartCardChannelClient(RedChannel *channel,
|
||||
RedClient *client,
|
||||
@ -129,7 +129,7 @@ void smartcard_channel_client_send_data(RedChannelClient *rcc,
|
||||
|
||||
void smartcard_channel_client_send_error(RedChannelClient *rcc, SpiceMarshaller *m, RedPipeItem *item)
|
||||
{
|
||||
RedErrorItem* error_item = SPICE_UPCAST(RedErrorItem, item);
|
||||
RedErrorItem* error_item = static_cast<RedErrorItem*>(item);
|
||||
|
||||
smartcard_channel_client_send_data(rcc, m, item, &error_item->vheader);
|
||||
}
|
||||
@ -138,15 +138,13 @@ static void smartcard_channel_client_push_error(RedChannelClient *rcc,
|
||||
uint32_t reader_id,
|
||||
VSCErrorCode error)
|
||||
{
|
||||
RedErrorItem *error_item = g_new0(RedErrorItem, 1);
|
||||
|
||||
red_pipe_item_init(&error_item->base, RED_PIPE_ITEM_TYPE_ERROR);
|
||||
RedErrorItem *error_item = new RedErrorItem(RED_PIPE_ITEM_TYPE_ERROR);
|
||||
|
||||
error_item->vheader.reader_id = reader_id;
|
||||
error_item->vheader.type = VSC_Error;
|
||||
error_item->vheader.length = sizeof(error_item->error);
|
||||
error_item->error.code = error;
|
||||
rcc->pipe_add_push(&error_item->base);
|
||||
rcc->pipe_add_push(error_item);
|
||||
}
|
||||
|
||||
static void smartcard_channel_client_add_reader(SmartCardChannelClient *scc)
|
||||
|
||||
@ -67,11 +67,11 @@ struct RedCharDeviceSmartcardPrivate {
|
||||
int reader_added; // has reader_add been sent to the device
|
||||
};
|
||||
|
||||
typedef struct RedMsgItem {
|
||||
RedPipeItem base;
|
||||
|
||||
struct RedMsgItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
~RedMsgItem();
|
||||
VSCMsgHeader* vheader;
|
||||
} RedMsgItem;
|
||||
};
|
||||
|
||||
static RedMsgItem *smartcard_new_vsc_msg_item(unsigned int reader_id, const VSCMsgHeader *vheader);
|
||||
|
||||
@ -138,9 +138,9 @@ RedCharDeviceSmartcard::read_one_msg_from_device()
|
||||
dev->priv->buf_used = remaining;
|
||||
if (msg_to_client) {
|
||||
if (dev->priv->scc) {
|
||||
dev->priv->scc->pipe_add_push(&msg_to_client->base);
|
||||
dev->priv->scc->pipe_add_push(msg_to_client);
|
||||
} else {
|
||||
red_pipe_item_unref(&msg_to_client->base);
|
||||
red_pipe_item_unref(msg_to_client);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -338,7 +338,7 @@ SmartCardChannelClient* smartcard_char_device_get_client(RedCharDeviceSmartcard
|
||||
static void smartcard_channel_send_msg(RedChannelClient *rcc,
|
||||
SpiceMarshaller *m, RedPipeItem *item)
|
||||
{
|
||||
RedMsgItem* msg_item = SPICE_UPCAST(RedMsgItem, item);
|
||||
RedMsgItem* msg_item = static_cast<RedMsgItem*>(item);
|
||||
|
||||
smartcard_channel_client_send_data(rcc, m, item, msg_item->vheader);
|
||||
}
|
||||
@ -390,19 +390,15 @@ void SmartCardChannelClient::send_item(RedPipeItem *item)
|
||||
begin_send_message();
|
||||
}
|
||||
|
||||
static void smartcard_free_vsc_msg_item(RedPipeItem *base)
|
||||
RedMsgItem::~RedMsgItem()
|
||||
{
|
||||
RedMsgItem *item = SPICE_UPCAST(RedMsgItem, base);
|
||||
g_free(item->vheader);
|
||||
g_free(item);
|
||||
g_free(vheader);
|
||||
}
|
||||
|
||||
static RedMsgItem *smartcard_new_vsc_msg_item(unsigned int reader_id, const VSCMsgHeader *vheader)
|
||||
{
|
||||
RedMsgItem *msg_item = g_new0(RedMsgItem, 1);
|
||||
RedMsgItem *msg_item = new RedMsgItem(RED_PIPE_ITEM_TYPE_SMARTCARD_DATA);
|
||||
|
||||
red_pipe_item_init_full(&msg_item->base, RED_PIPE_ITEM_TYPE_SMARTCARD_DATA,
|
||||
smartcard_free_vsc_msg_item);
|
||||
msg_item->vheader = (VSCMsgHeader*) g_memdup(vheader, sizeof(*vheader) + vheader->length);
|
||||
/* We patch the reader_id, since the device only knows about itself, and
|
||||
* we know about the sum of readers. */
|
||||
|
||||
@ -74,11 +74,17 @@ struct RecordChannelClient;
|
||||
struct AudioFrame;
|
||||
struct AudioFrameContainer;
|
||||
|
||||
struct PersistentPipeItem: public RedPipeItem
|
||||
/* This pipe item is never deleted and added to the queue when messages
|
||||
* have to be sent.
|
||||
* This is used to have a simple item in RedChannelClient queue but to send
|
||||
* multiple messages in a row if possible.
|
||||
* During realtime sound transmission you usually don't want to queue too
|
||||
* much data or having retransmission preferring instead loosing some
|
||||
* samples.
|
||||
*/
|
||||
struct PersistentPipeItem final: public RedPipeItem
|
||||
{
|
||||
PersistentPipeItem();
|
||||
private:
|
||||
static void item_free(RedPipeItem *item);
|
||||
};
|
||||
|
||||
/* Connects an audio client to a Spice client */
|
||||
@ -610,21 +616,8 @@ static bool playback_send_mode(PlaybackChannelClient *playback_client)
|
||||
return true;
|
||||
}
|
||||
|
||||
PersistentPipeItem::PersistentPipeItem()
|
||||
{
|
||||
red_pipe_item_init_full(this, RED_PIPE_ITEM_PERSISTENT, item_free);
|
||||
}
|
||||
|
||||
/* This function is called when the "persistent" item is removed from the
|
||||
* queue. Note that there is not free call as the item is allocated into
|
||||
* SndChannelClient.
|
||||
* This is used to have a simple item in RedChannelClient queue but to send
|
||||
* multiple messages in a row if possible.
|
||||
* During realtime sound transmission you usually don't want to queue too
|
||||
* much data or having retransmission preferring instead loosing some
|
||||
* samples.
|
||||
*/
|
||||
void PersistentPipeItem::item_free(RedPipeItem *item)
|
||||
PersistentPipeItem::PersistentPipeItem():
|
||||
RedPipeItem(RED_PIPE_ITEM_PERSISTENT)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -45,15 +45,15 @@
|
||||
struct RedVmcChannel;
|
||||
class VmcChannelClient;
|
||||
|
||||
typedef struct RedVmcPipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedVmcPipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
|
||||
SpiceDataCompressionType type;
|
||||
uint32_t uncompressed_data_size;
|
||||
/* writes which don't fit this will get split, this is not a problem */
|
||||
uint8_t buf[BUF_SIZE];
|
||||
uint32_t buf_used;
|
||||
} RedVmcPipeItem;
|
||||
};
|
||||
|
||||
struct RedCharDeviceSpiceVmc: public RedCharDevice
|
||||
{
|
||||
@ -158,7 +158,7 @@ RedVmcChannel::~RedVmcChannel()
|
||||
{
|
||||
RedCharDevice::write_buffer_release(chardev, &recv_from_client_buf);
|
||||
if (pipe_item) {
|
||||
red_pipe_item_unref(&pipe_item->base);
|
||||
red_pipe_item_unref(pipe_item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,16 +183,19 @@ static red::shared_ptr<RedVmcChannel> red_vmc_channel_new(RedsState *reds, uint8
|
||||
return red::make_shared<RedVmcChannel>(reds, channel_type, id);
|
||||
}
|
||||
|
||||
typedef struct RedPortInitPipeItem {
|
||||
RedPipeItem base;
|
||||
struct RedPortInitPipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
~RedPortInitPipeItem();
|
||||
|
||||
char* name;
|
||||
uint8_t opened;
|
||||
} RedPortInitPipeItem;
|
||||
};
|
||||
|
||||
struct RedPortEventPipeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
|
||||
typedef struct RedPortEventPipeItem {
|
||||
RedPipeItem base;
|
||||
uint8_t event;
|
||||
} RedPortEventPipeItem;
|
||||
};
|
||||
|
||||
enum {
|
||||
RED_PIPE_ITEM_TYPE_SPICEVMC_DATA = RED_PIPE_ITEM_TYPE_CHANNEL_BASE,
|
||||
@ -225,8 +228,7 @@ static RedVmcPipeItem* try_compress_lz4(RedVmcChannel *channel, int n, RedVmcPip
|
||||
/* Client doesn't have compression cap - data will not be compressed */
|
||||
return NULL;
|
||||
}
|
||||
msg_item_compressed = g_new0(RedVmcPipeItem, 1);
|
||||
red_pipe_item_init(&msg_item_compressed->base, RED_PIPE_ITEM_TYPE_SPICEVMC_DATA);
|
||||
msg_item_compressed = new RedVmcPipeItem(RED_PIPE_ITEM_TYPE_SPICEVMC_DATA);
|
||||
compressed_data_count = LZ4_compress_default((char*)&msg_item->buf,
|
||||
(char*)&msg_item_compressed->buf,
|
||||
n,
|
||||
@ -258,9 +260,8 @@ RedPipeItem* RedCharDeviceSpiceVmc::read_one_msg_from_device()
|
||||
}
|
||||
|
||||
if (!channel->pipe_item) {
|
||||
msg_item = g_new0(RedVmcPipeItem, 1);
|
||||
msg_item = new RedVmcPipeItem(RED_PIPE_ITEM_TYPE_SPICEVMC_DATA);
|
||||
msg_item->type = SPICE_DATA_COMPRESSION_TYPE_NONE;
|
||||
red_pipe_item_init(&msg_item->base, RED_PIPE_ITEM_TYPE_SPICEVMC_DATA);
|
||||
} else {
|
||||
spice_assert(channel->pipe_item->buf_used == 0);
|
||||
msg_item = channel->pipe_item;
|
||||
@ -289,33 +290,28 @@ RedPipeItem* RedCharDeviceSpiceVmc::read_one_msg_from_device()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void red_port_init_item_free(struct RedPipeItem *base)
|
||||
RedPortInitPipeItem::~RedPortInitPipeItem()
|
||||
{
|
||||
RedPortInitPipeItem *item = SPICE_UPCAST(RedPortInitPipeItem, base);
|
||||
|
||||
g_free(item->name);
|
||||
g_free(item);
|
||||
g_free(name);
|
||||
}
|
||||
|
||||
static void spicevmc_port_send_init(VmcChannelClient *rcc)
|
||||
{
|
||||
RedVmcChannel *channel = rcc->get_channel();
|
||||
SpiceCharDeviceInstance *sin = channel->chardev_sin;
|
||||
RedPortInitPipeItem *item = g_new(RedPortInitPipeItem, 1);
|
||||
RedPortInitPipeItem *item = new RedPortInitPipeItem(RED_PIPE_ITEM_TYPE_PORT_INIT);
|
||||
|
||||
red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_PORT_INIT, red_port_init_item_free);
|
||||
item->name = g_strdup(sin->portname);
|
||||
item->opened = channel->port_opened;
|
||||
rcc->pipe_add_push(&item->base);
|
||||
rcc->pipe_add_push(item);
|
||||
}
|
||||
|
||||
static void spicevmc_port_send_event(RedChannelClient *rcc, uint8_t event)
|
||||
{
|
||||
RedPortEventPipeItem *item = g_new(RedPortEventPipeItem, 1);
|
||||
RedPortEventPipeItem *item = new RedPortEventPipeItem(RED_PIPE_ITEM_TYPE_PORT_EVENT);
|
||||
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_PORT_EVENT);
|
||||
item->event = event;
|
||||
rcc->pipe_add_push(&item->base);
|
||||
rcc->pipe_add_push(item);
|
||||
}
|
||||
|
||||
void RedCharDeviceSpiceVmc::remove_client(RedCharDeviceClientOpaque *opaque)
|
||||
@ -510,14 +506,14 @@ static void
|
||||
spicevmc_red_channel_queue_data(RedVmcChannel *channel, RedVmcPipeItem *item)
|
||||
{
|
||||
channel->queued_data += item->buf_used;
|
||||
channel->rcc->pipe_add_push(&item->base);
|
||||
channel->rcc->pipe_add_push(item);
|
||||
}
|
||||
|
||||
static void spicevmc_red_channel_send_data(VmcChannelClient *rcc,
|
||||
SpiceMarshaller *m,
|
||||
RedPipeItem *item)
|
||||
{
|
||||
RedVmcPipeItem *i = SPICE_UPCAST(RedVmcPipeItem, item);
|
||||
RedVmcPipeItem *i = static_cast<RedVmcPipeItem*>(item);
|
||||
RedVmcChannel *channel = rcc->get_channel();
|
||||
|
||||
/* for compatibility send using not compressed data message */
|
||||
@ -561,7 +557,7 @@ static void spicevmc_red_channel_send_port_init(RedChannelClient *rcc,
|
||||
SpiceMarshaller *m,
|
||||
RedPipeItem *item)
|
||||
{
|
||||
RedPortInitPipeItem *i = SPICE_UPCAST(RedPortInitPipeItem, item);
|
||||
RedPortInitPipeItem *i = static_cast<RedPortInitPipeItem*>(item);
|
||||
SpiceMsgPortInit init;
|
||||
|
||||
rcc->init_send_data(SPICE_MSG_PORT_INIT);
|
||||
@ -575,7 +571,7 @@ static void spicevmc_red_channel_send_port_event(RedChannelClient *rcc,
|
||||
SpiceMarshaller *m,
|
||||
RedPipeItem *item)
|
||||
{
|
||||
RedPortEventPipeItem *i = SPICE_UPCAST(RedPortEventPipeItem, item);
|
||||
RedPortEventPipeItem *i = static_cast<RedPortEventPipeItem*>(item);
|
||||
SpiceMsgPortEvent event;
|
||||
|
||||
rcc->init_send_data(SPICE_MSG_PORT_EVENT);
|
||||
|
||||
@ -67,17 +67,19 @@ enum {
|
||||
RED_PIPE_ITEM_TYPE_MONITORS_CONFIG,
|
||||
};
|
||||
|
||||
typedef struct StreamCreateItem {
|
||||
RedPipeItem base;
|
||||
struct StreamCreateItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
SpiceMsgDisplayStreamCreate stream_create;
|
||||
} StreamCreateItem;
|
||||
};
|
||||
|
||||
struct StreamDataItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
~StreamDataItem();
|
||||
|
||||
typedef struct StreamDataItem {
|
||||
RedPipeItem base;
|
||||
StreamChannel *channel;
|
||||
// NOTE: this must be the last field in the structure
|
||||
SpiceMsgDisplayStreamData data;
|
||||
} StreamDataItem;
|
||||
};
|
||||
|
||||
#define PRIMARY_SURFACE_ID 0
|
||||
|
||||
@ -210,7 +212,7 @@ void StreamChannelClient::send_item(RedPipeItem *pipe_item)
|
||||
break;
|
||||
}
|
||||
case RED_PIPE_ITEM_TYPE_STREAM_CREATE: {
|
||||
StreamCreateItem *item = SPICE_UPCAST(StreamCreateItem, pipe_item);
|
||||
StreamCreateItem *item = static_cast<StreamCreateItem*>(pipe_item);
|
||||
stream_id = item->stream_create.id;
|
||||
init_send_data(SPICE_MSG_DISPLAY_STREAM_CREATE);
|
||||
spice_marshall_msg_display_stream_create(m, &item->stream_create);
|
||||
@ -231,7 +233,7 @@ void StreamChannelClient::send_item(RedPipeItem *pipe_item)
|
||||
break;
|
||||
}
|
||||
case RED_PIPE_ITEM_TYPE_STREAM_DATA: {
|
||||
StreamDataItem *item = SPICE_UPCAST(StreamDataItem, pipe_item);
|
||||
StreamDataItem *item = static_cast<StreamDataItem*>(pipe_item);
|
||||
init_send_data(SPICE_MSG_DISPLAY_STREAM_DATA);
|
||||
spice_marshall_msg_display_stream_data(m, &item->data);
|
||||
pipe_item->add_to_marshaller(m, item->data.data, item->data.data_size);
|
||||
@ -424,8 +426,7 @@ StreamChannel::change_format(const StreamMsgFormat *fmt)
|
||||
stream_id = (stream_id + 1) % NUM_STREAMS;
|
||||
|
||||
// send create stream
|
||||
StreamCreateItem *item = g_new0(StreamCreateItem, 1);
|
||||
red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_STREAM_CREATE);
|
||||
StreamCreateItem *item = new StreamCreateItem(RED_PIPE_ITEM_TYPE_STREAM_CREATE);
|
||||
item->stream_create.id = stream_id;
|
||||
item->stream_create.flags = SPICE_STREAM_FLAGS_TOP_DOWN;
|
||||
item->stream_create.codec_type = fmt->codec;
|
||||
@ -435,7 +436,7 @@ StreamChannel::change_format(const StreamMsgFormat *fmt)
|
||||
item->stream_create.src_height = fmt->height;
|
||||
item->stream_create.dest = (SpiceRect) { 0, 0, fmt->width, fmt->height };
|
||||
item->stream_create.clip = (SpiceClip) { SPICE_CLIP_TYPE_NONE, NULL };
|
||||
pipes_add(&item->base);
|
||||
pipes_add(item);
|
||||
|
||||
// activate stream report if possible
|
||||
pipes_add_type(RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT);
|
||||
@ -451,14 +452,9 @@ StreamChannel::update_queue_stat(int32_t num_diff, int32_t size_diff)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamChannel::data_item_free(RedPipeItem *base)
|
||||
StreamDataItem::~StreamDataItem()
|
||||
{
|
||||
StreamDataItem *pipe_item = SPICE_UPCAST(StreamDataItem, base);
|
||||
|
||||
pipe_item->channel->update_queue_stat(-1, -pipe_item->data.data_size);
|
||||
|
||||
g_free(pipe_item);
|
||||
channel->update_queue_stat(-1, -data.data_size);
|
||||
}
|
||||
|
||||
void
|
||||
@ -471,9 +467,7 @@ StreamChannel::send_data(const void *data, size_t size, uint32_t mm_time)
|
||||
return;
|
||||
}
|
||||
|
||||
StreamDataItem *item = (StreamDataItem*) g_malloc(sizeof(*item) + size);
|
||||
red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_STREAM_DATA,
|
||||
data_item_free);
|
||||
StreamDataItem *item = new (size) StreamDataItem(RED_PIPE_ITEM_TYPE_STREAM_DATA);
|
||||
item->data.base.id = stream_id;
|
||||
item->data.base.multi_media_time = mm_time;
|
||||
item->data.data_size = size;
|
||||
@ -481,7 +475,7 @@ StreamChannel::send_data(const void *data, size_t size, uint32_t mm_time)
|
||||
update_queue_stat(1, size);
|
||||
// TODO try to optimize avoiding the copy
|
||||
memcpy(item->data.data, data, size);
|
||||
pipes_add(&item->base);
|
||||
pipes_add(item);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -50,10 +50,12 @@ struct StreamQueueStat {
|
||||
typedef void (*stream_channel_queue_stat_proc)(void *opaque, const StreamQueueStat *stats,
|
||||
StreamChannel *channel);
|
||||
|
||||
struct StreamDataItem;
|
||||
struct StreamChannelClient;
|
||||
struct StreamChannel final: public RedChannel
|
||||
{
|
||||
friend struct StreamChannelClient;
|
||||
friend struct StreamDataItem;
|
||||
StreamChannel(RedsState *reds, uint32_t id);
|
||||
|
||||
/**
|
||||
@ -73,7 +75,6 @@ private:
|
||||
|
||||
inline void update_queue_stat(int32_t num_diff, int32_t size_diff);
|
||||
void request_new_stream(StreamMsgStartStop *start);
|
||||
static void data_item_free(RedPipeItem *base);
|
||||
|
||||
/* current video stream id, <0 if not initialized or
|
||||
* we are not sending a stream */
|
||||
|
||||
@ -64,24 +64,20 @@ static void video_stream_agent_stats_print(VideoStreamAgent *agent)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void video_stream_create_destroy_item_release(RedPipeItem *base)
|
||||
StreamCreateDestroyItem::~StreamCreateDestroyItem()
|
||||
{
|
||||
StreamCreateDestroyItem *item = SPICE_UPCAST(StreamCreateDestroyItem, base);
|
||||
DisplayChannel *display = DCC_TO_DC(item->agent->dcc);
|
||||
video_stream_agent_unref(display, item->agent);
|
||||
g_free(item);
|
||||
DisplayChannel *display = DCC_TO_DC(agent->dcc);
|
||||
video_stream_agent_unref(display, agent);
|
||||
}
|
||||
|
||||
static RedPipeItem *video_stream_create_destroy_item_new(VideoStreamAgent *agent,
|
||||
gint type)
|
||||
int type)
|
||||
{
|
||||
StreamCreateDestroyItem *item = g_new0(StreamCreateDestroyItem, 1);
|
||||
StreamCreateDestroyItem *item = new StreamCreateDestroyItem(type);
|
||||
|
||||
red_pipe_item_init_full(&item->base, type,
|
||||
video_stream_create_destroy_item_release);
|
||||
agent->stream->refs++;
|
||||
item->agent = agent;
|
||||
return &item->base;
|
||||
return item;
|
||||
}
|
||||
|
||||
static RedPipeItem *video_stream_create_item_new(VideoStreamAgent *agent)
|
||||
@ -163,24 +159,17 @@ void video_stream_agent_unref(DisplayChannel *display, VideoStreamAgent *agent)
|
||||
video_stream_unref(display, agent->stream);
|
||||
}
|
||||
|
||||
static void video_stream_clip_item_free(RedPipeItem *base)
|
||||
VideoStreamClipItem::~VideoStreamClipItem()
|
||||
{
|
||||
g_return_if_fail(base != NULL);
|
||||
VideoStreamClipItem *item = SPICE_UPCAST(VideoStreamClipItem, base);
|
||||
DisplayChannel *display = DCC_TO_DC(item->stream_agent->dcc);
|
||||
DisplayChannel *display = DCC_TO_DC(stream_agent->dcc);
|
||||
|
||||
g_return_if_fail(item->base.refcount == 0);
|
||||
|
||||
video_stream_agent_unref(display, item->stream_agent);
|
||||
g_free(item->rects);
|
||||
g_free(item);
|
||||
video_stream_agent_unref(display, stream_agent);
|
||||
g_free(rects);
|
||||
}
|
||||
|
||||
VideoStreamClipItem *video_stream_clip_item_new(VideoStreamAgent *agent)
|
||||
{
|
||||
VideoStreamClipItem *item = g_new(VideoStreamClipItem, 1);
|
||||
red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_STREAM_CLIP,
|
||||
video_stream_clip_item_free);
|
||||
VideoStreamClipItem *item = new VideoStreamClipItem(RED_PIPE_ITEM_TYPE_STREAM_CLIP);
|
||||
|
||||
item->stream_agent = agent;
|
||||
agent->stream->refs++;
|
||||
@ -364,7 +353,7 @@ static void before_reattach_stream(DisplayChannel *display,
|
||||
dcc = dpi->dcc;
|
||||
agent = dcc_get_video_stream_agent(dcc, index);
|
||||
|
||||
if (dcc->pipe_item_is_linked(&dpi->base)) {
|
||||
if (dcc->pipe_item_is_linked(dpi)) {
|
||||
#ifdef STREAM_STATS
|
||||
agent->stats.num_drops_pipe++;
|
||||
#endif
|
||||
@ -784,14 +773,13 @@ void dcc_create_stream(DisplayChannelClient *dcc, VideoStream *stream)
|
||||
dcc->pipe_add(video_stream_create_item_new(agent));
|
||||
|
||||
if (dcc->test_remote_cap(SPICE_DISPLAY_CAP_STREAM_REPORT)) {
|
||||
RedStreamActivateReportItem *report_pipe_item = g_new0(RedStreamActivateReportItem, 1);
|
||||
RedStreamActivateReportItem *report_pipe_item =
|
||||
new RedStreamActivateReportItem(RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT);
|
||||
|
||||
agent->report_id = rand();
|
||||
red_pipe_item_init(&report_pipe_item->base,
|
||||
RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT);
|
||||
report_pipe_item->stream_id = stream_id;
|
||||
report_pipe_item->report_id = agent->report_id;
|
||||
dcc->pipe_add(&report_pipe_item->base);
|
||||
dcc->pipe_add(report_pipe_item);
|
||||
}
|
||||
#ifdef STREAM_STATS
|
||||
memset(&agent->stats, 0, sizeof(StreamStats));
|
||||
@ -812,17 +800,10 @@ void video_stream_agent_stop(VideoStreamAgent *agent)
|
||||
}
|
||||
}
|
||||
|
||||
static void red_upgrade_item_free(RedPipeItem *base)
|
||||
RedUpgradeItem::~RedUpgradeItem()
|
||||
{
|
||||
g_return_if_fail(base != NULL);
|
||||
|
||||
RedUpgradeItem *item = SPICE_UPCAST(RedUpgradeItem, base);
|
||||
|
||||
g_return_if_fail(item->base.refcount == 0);
|
||||
|
||||
drawable_unref(item->drawable);
|
||||
g_free(item->rects);
|
||||
g_free(item);
|
||||
drawable_unref(drawable);
|
||||
g_free(rects);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -861,9 +842,7 @@ static void dcc_detach_stream_gracefully(DisplayChannelClient *dcc,
|
||||
}
|
||||
spice_debug("stream %d: upgrade by drawable. box ==>", stream_id);
|
||||
rect_debug(&stream->current->red_drawable->bbox);
|
||||
upgrade_item = g_new(RedUpgradeItem, 1);
|
||||
red_pipe_item_init_full(&upgrade_item->base, RED_PIPE_ITEM_TYPE_UPGRADE,
|
||||
red_upgrade_item_free);
|
||||
upgrade_item = new RedUpgradeItem(RED_PIPE_ITEM_TYPE_UPGRADE);
|
||||
upgrade_item->drawable = stream->current;
|
||||
upgrade_item->drawable->refs++;
|
||||
n_rects = pixman_region32_n_rects(&upgrade_item->drawable->tree_item.base.rgn);
|
||||
@ -871,7 +850,7 @@ static void dcc_detach_stream_gracefully(DisplayChannelClient *dcc,
|
||||
upgrade_item->rects->num_rects = n_rects;
|
||||
region_ret_rects(&upgrade_item->drawable->tree_item.base.rgn,
|
||||
upgrade_item->rects->rects, n_rects);
|
||||
dcc->pipe_add(&upgrade_item->base);
|
||||
dcc->pipe_add(upgrade_item);
|
||||
|
||||
} else {
|
||||
SpiceRect upgrade_area;
|
||||
|
||||
@ -49,17 +49,18 @@ typedef struct VideoStream VideoStream;
|
||||
|
||||
/* This item is used to send a full quality image (lossless) of the area where the stream was.
|
||||
* This to avoid the artifacts due to the lossy compression. */
|
||||
typedef struct RedUpgradeItem {
|
||||
RedPipeItem base;
|
||||
struct RedUpgradeItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
~RedUpgradeItem();
|
||||
Drawable *drawable;
|
||||
SpiceClipRects *rects;
|
||||
} RedUpgradeItem;
|
||||
};
|
||||
|
||||
typedef struct RedStreamActivateReportItem {
|
||||
RedPipeItem base;
|
||||
struct RedStreamActivateReportItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
uint32_t stream_id;
|
||||
uint32_t report_id;
|
||||
} RedStreamActivateReportItem;
|
||||
};
|
||||
|
||||
#ifdef STREAM_STATS
|
||||
typedef struct StreamStats {
|
||||
@ -95,19 +96,21 @@ typedef struct VideoStreamAgent {
|
||||
#endif
|
||||
} VideoStreamAgent;
|
||||
|
||||
typedef struct VideoStreamClipItem {
|
||||
RedPipeItem base;
|
||||
struct VideoStreamClipItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
~VideoStreamClipItem();
|
||||
VideoStreamAgent *stream_agent;
|
||||
int clip_type;
|
||||
SpiceClipRects *rects;
|
||||
} VideoStreamClipItem;
|
||||
};
|
||||
|
||||
VideoStreamClipItem *video_stream_clip_item_new(VideoStreamAgent *agent);
|
||||
|
||||
typedef struct StreamCreateDestroyItem {
|
||||
RedPipeItem base;
|
||||
struct StreamCreateDestroyItem: public RedPipeItem {
|
||||
using RedPipeItem::RedPipeItem;
|
||||
~StreamCreateDestroyItem();
|
||||
VideoStreamAgent *agent;
|
||||
} StreamCreateDestroyItem;
|
||||
};
|
||||
|
||||
typedef struct ItemTrace {
|
||||
red_time_t time;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user