spice/server/dcc.c
Marc-André Lureau 85920bb2e9 worker: start a DisplayChannelClient unit
Signed-off-by: Marc-André Lureau <marcandre.lureau@gmail.com>
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
2015-11-19 12:43:02 +00:00

142 lines
4.7 KiB
C

/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
Copyright (C) 2009-2015 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 "dcc.h"
#include "display-channel.h"
DisplayChannelClient *dcc_new(DisplayChannel *display,
RedClient *client, RedsStream *stream,
int mig_target,
uint32_t *common_caps, int num_common_caps,
uint32_t *caps, int num_caps,
SpiceImageCompression image_compression,
spice_wan_compression_t jpeg_state,
spice_wan_compression_t zlib_glz_state)
{
DisplayChannelClient *dcc;
dcc = (DisplayChannelClient*)common_channel_new_client(
COMMON_CHANNEL(display), sizeof(DisplayChannelClient),
client, stream, mig_target, TRUE,
common_caps, num_common_caps,
caps, num_caps);
spice_return_val_if_fail(dcc, NULL);
ring_init(&dcc->palette_cache_lru);
dcc->palette_cache_available = CLIENT_PALETTE_CACHE_SIZE;
dcc->image_compression = image_compression;
dcc->jpeg_state = jpeg_state;
dcc->zlib_glz_state = zlib_glz_state;
// TODO: tune quality according to bandwidth
dcc->jpeg_quality = 85;
dcc_encoders_init(dcc);
return dcc;
}
void dcc_stream_agent_clip(DisplayChannelClient* dcc, StreamAgent *agent)
{
StreamClipItem *item = stream_clip_item_new(dcc, agent);
int n_rects;
item->clip_type = SPICE_CLIP_TYPE_RECTS;
n_rects = pixman_region32_n_rects(&agent->clip);
item->rects = spice_malloc_n_m(n_rects, sizeof(SpiceRect), sizeof(SpiceClipRects));
item->rects->num_rects = n_rects;
region_ret_rects(&agent->clip, item->rects->rects, n_rects);
red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), (PipeItem *)item);
}
static MonitorsConfigItem *monitors_config_item_new(RedChannel* channel,
MonitorsConfig *monitors_config)
{
MonitorsConfigItem *mci;
mci = (MonitorsConfigItem *)spice_malloc(sizeof(*mci));
mci->monitors_config = monitors_config;
red_channel_pipe_item_init(channel,
&mci->pipe_item, PIPE_ITEM_TYPE_MONITORS_CONFIG);
return mci;
}
void dcc_push_monitors_config(DisplayChannelClient *dcc)
{
DisplayChannel *dc = DCC_TO_DC(dcc);
MonitorsConfig *monitors_config = dc->monitors_config;
MonitorsConfigItem *mci;
if (monitors_config == NULL) {
spice_warning("monitors_config is NULL");
return;
}
if (!red_channel_client_test_remote_cap(&dcc->common.base,
SPICE_DISPLAY_CAP_MONITORS_CONFIG)) {
return;
}
mci = monitors_config_item_new(dcc->common.base.channel,
monitors_config_ref(dc->monitors_config));
red_channel_client_pipe_add(&dcc->common.base, &mci->pipe_item);
red_channel_client_push(&dcc->common.base);
}
static SurfaceDestroyItem *surface_destroy_item_new(RedChannel *channel,
uint32_t surface_id)
{
SurfaceDestroyItem *destroy;
destroy = spice_malloc(sizeof(SurfaceDestroyItem));
destroy->surface_destroy.surface_id = surface_id;
red_channel_pipe_item_init(channel, &destroy->pipe_item,
PIPE_ITEM_TYPE_DESTROY_SURFACE);
return destroy;
}
void dcc_destroy_surface(DisplayChannelClient *dcc, uint32_t surface_id)
{
DisplayChannel *display;
RedChannel *channel;
SurfaceDestroyItem *destroy;
if (!dcc) {
return;
}
display = DCC_TO_DC(dcc);
channel = RED_CHANNEL(display);
if (COMMON_CHANNEL(display)->during_target_migrate ||
!dcc->surface_client_created[surface_id]) {
return;
}
dcc->surface_client_created[surface_id] = FALSE;
destroy = surface_destroy_item_new(channel, surface_id);
red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &destroy->pipe_item);
}