mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-31 02:41:52 +00:00
Merge remote-tracking branch 'origin/master' into 0.10
This commit is contained in:
commit
2f4115e52e
2
.gitignore
vendored
2
.gitignore
vendored
@ -17,7 +17,9 @@ depcomp
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
m4/
|
||||
missing
|
||||
Makefile
|
||||
Makefile.in
|
||||
spice-server.pc
|
||||
stamp-h1
|
||||
|
||||
8
NEWS
8
NEWS
@ -1,3 +1,11 @@
|
||||
Major changes in 0.10.1:
|
||||
========================
|
||||
* Mini header support
|
||||
* Add server API for injecting a client connection socket
|
||||
* Add Xinerama support to spicec
|
||||
* Many bugfixes / code cleanups
|
||||
* Requires spice-protocol >= 0.10.1
|
||||
|
||||
Major changes in 0.10.0:
|
||||
========================
|
||||
* 32 bit (little endian) server builds.
|
||||
|
||||
1
client/.gitignore
vendored
1
client/.gitignore
vendored
@ -10,3 +10,4 @@ generated_demarshallers.cpp
|
||||
generated_demarshallers1.cpp
|
||||
generated_marshallers.cpp
|
||||
generated_marshallers1.cpp
|
||||
spicec
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
|
||||
#ifdef WIN32
|
||||
#define PIPE_NAME "SpiceForeignMenu-%lu"
|
||||
#elif defined(__i386__)
|
||||
#elif defined(__i386__) || __SIZEOF_LONG__ == 4
|
||||
#define PIPE_NAME "/tmp/SpiceForeignMenu-%llu.uds"
|
||||
#else
|
||||
#define PIPE_NAME "/tmp/SpiceForeignMenu-%lu.uds"
|
||||
|
||||
@ -45,7 +45,7 @@ SoftRenderer::SoftRenderer(uint8_t* surface, uint width, uint height, uint strid
|
||||
, _image_codec_module (NULL)
|
||||
, _queueing(true)
|
||||
{
|
||||
assert(stride == _width * 4); //for now
|
||||
assert(stride == width * 4); //for now
|
||||
if (!_image_codec) {
|
||||
setupImageCodec();
|
||||
}
|
||||
|
||||
1
client/x11/.gitignore
vendored
1
client/x11/.gitignore
vendored
@ -3,6 +3,7 @@
|
||||
*.loT
|
||||
*.o
|
||||
.deps
|
||||
.dirstamp
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
|
||||
@ -119,7 +119,7 @@ bool EventSources::wait_events(int timeout_msec)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < _events.size(); i++) {
|
||||
for (unsigned int i = 0; i < _events.size(); i++) {
|
||||
if (FD_ISSET(_fds[i], &rfds)) {
|
||||
_events[i]->action();
|
||||
/* The action may have removed / added event sources changing
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/un.h>
|
||||
#include "named_pipe.h"
|
||||
#include "utils.h"
|
||||
|
||||
@ -34,7 +34,6 @@
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/syscall.h>
|
||||
@ -136,7 +135,7 @@ static struct clipboard_format_info clipboard_formats[] = {
|
||||
{ VD_AGENT_CLIPBOARD_IMAGE_JPG, { "image/jpeg", NULL }, },
|
||||
};
|
||||
|
||||
#define clipboard_format_count (sizeof(clipboard_formats)/sizeof(clipboard_formats[0]))
|
||||
#define clipboard_format_count ((int)(sizeof(clipboard_formats)/sizeof(clipboard_formats[0])))
|
||||
|
||||
struct selection_request {
|
||||
XEvent event;
|
||||
@ -146,11 +145,11 @@ struct selection_request {
|
||||
static int expected_targets_notifies = 0;
|
||||
static bool waiting_for_property_notify = false;
|
||||
static uint8_t* clipboard_data = NULL;
|
||||
static int32_t clipboard_data_size = 0;
|
||||
static int32_t clipboard_data_space = 0;
|
||||
static uint32_t clipboard_data_size = 0;
|
||||
static uint32_t clipboard_data_space = 0;
|
||||
static Atom clipboard_request_target = None;
|
||||
static selection_request *next_selection_request = NULL;
|
||||
static uint32_t clipboard_type_count = 0;
|
||||
static int clipboard_type_count = 0;
|
||||
static uint32_t clipboard_agent_types[256];
|
||||
static Atom clipboard_x11_targets[256];
|
||||
static Mutex clipboard_lock;
|
||||
@ -1243,7 +1242,7 @@ private:
|
||||
void update_position();
|
||||
bool find_mode_in_outputs(RRMode mode, int start_index, XRRScreenResources* res);
|
||||
bool find_mode_in_clones(RRMode mode, XRRScreenResources* res);
|
||||
XRRModeInfo* find_mode(int width, int height, XRRScreenResources* res);
|
||||
XRRModeInfo* find_mode(unsigned int width, unsigned int height, XRRScreenResources* res);
|
||||
|
||||
private:
|
||||
MultyMonScreen& _container;
|
||||
@ -2182,7 +2181,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
XRRModeInfo* XMonitor::find_mode(int width, int height, XRRScreenResources* res)
|
||||
XRRModeInfo* XMonitor::find_mode(unsigned int width, unsigned int height, XRRScreenResources* res)
|
||||
{
|
||||
typedef std::set<ModeInfo, ModeCompare> ModesSet;
|
||||
ModesSet modes_set;
|
||||
|
||||
@ -922,7 +922,7 @@ void RedWindow_p::win_proc(XEvent& event)
|
||||
case ClientMessage:
|
||||
if (event.xclient.message_type == wm_protocol_atom) {
|
||||
ASSERT(event.xclient.format == 32);
|
||||
if (event.xclient.data.l[0] == wm_delete_window_atom) {
|
||||
if ((Atom)event.xclient.data.l[0] == wm_delete_window_atom) {
|
||||
DBG(0, "wm_delete_window");
|
||||
Platform::send_quit_request();
|
||||
}
|
||||
|
||||
1
common/.gitignore
vendored
1
common/.gitignore
vendored
@ -3,6 +3,7 @@
|
||||
*.loT
|
||||
*.o
|
||||
.deps
|
||||
.dirstamp
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
|
||||
@ -2,7 +2,7 @@ AC_PREREQ([2.57])
|
||||
|
||||
m4_define([SPICE_MAJOR], 0)
|
||||
m4_define([SPICE_MINOR], 10)
|
||||
m4_define([SPICE_MICRO], 0)
|
||||
m4_define([SPICE_MICRO], 1)
|
||||
|
||||
AC_INIT(spice, [SPICE_MAJOR.SPICE_MINOR.SPICE_MICRO], [], spice)
|
||||
|
||||
@ -217,7 +217,7 @@ SPICE_REQUIRES+=" celt051 >= 0.5.1.1"
|
||||
|
||||
if test ! -e client/generated_marshallers.cpp; then
|
||||
AC_MSG_CHECKING([for pyparsing python module])
|
||||
echo "import pyparsing" | python - >/dev/null 2>&1
|
||||
echo "import pyparsing" | ${PYTHON} - >/dev/null 2>&1
|
||||
if test $? -ne 0 ; then
|
||||
AC_MSG_RESULT([not found])
|
||||
AC_MSG_ERROR([pyparsing python module is required to compile this package])
|
||||
@ -531,6 +531,7 @@ echo "
|
||||
prefix: ${prefix}
|
||||
c compiler: ${CC}
|
||||
c++ compiler: ${CXX}
|
||||
python: ${PYTHON}
|
||||
|
||||
Build Spice client: ${enable_client}
|
||||
|
||||
|
||||
BIN
docs/Spice_for_newbies.odt
Normal file
BIN
docs/Spice_for_newbies.odt
Normal file
Binary file not shown.
BIN
docs/Spice_protocol.odt
Normal file
BIN
docs/Spice_protocol.odt
Normal file
Binary file not shown.
BIN
docs/Spice_style.odt
Normal file
BIN
docs/Spice_style.odt
Normal file
Binary file not shown.
BIN
docs/Spice_user_manual.odt
Normal file
BIN
docs/Spice_user_manual.odt
Normal file
Binary file not shown.
BIN
docs/Vd_interfaces.odt
Normal file
BIN
docs/Vd_interfaces.odt
Normal file
Binary file not shown.
@ -282,7 +282,8 @@ static void inputs_channel_send_item(RedChannelClient *rcc, PipeItem *base)
|
||||
red_channel_client_begin_send_message(rcc);
|
||||
}
|
||||
|
||||
static int inputs_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint16_t type, void *message)
|
||||
static int inputs_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint16_t type,
|
||||
void *message)
|
||||
{
|
||||
InputsChannel *inputs_channel = (InputsChannel *)rcc->channel;
|
||||
InputsChannelClient *icc = (InputsChannelClient *)rcc;
|
||||
@ -464,7 +465,6 @@ static void inputs_pipe_add_init(RedChannelClient *rcc)
|
||||
|
||||
static int inputs_channel_config_socket(RedChannelClient *rcc)
|
||||
{
|
||||
int flags;
|
||||
int delay_val = 1;
|
||||
RedsStream *stream = red_channel_client_get_stream(rcc);
|
||||
|
||||
@ -476,11 +476,6 @@ static int inputs_channel_config_socket(RedChannelClient *rcc)
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags = fcntl(stream->socket, F_GETFL)) == -1 ||
|
||||
fcntl(stream->socket, F_SETFL, flags | O_ASYNC) == -1) {
|
||||
red_printf("fcntl failed, %s", strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -360,7 +360,8 @@ void main_channel_push_mouse_mode(MainChannel *main_chan, int current_mode,
|
||||
main_mouse_mode_item_new, &info);
|
||||
}
|
||||
|
||||
static void main_channel_marshall_mouse_mode(SpiceMarshaller *m, int current_mode, int is_client_mouse_allowed)
|
||||
static void main_channel_marshall_mouse_mode(SpiceMarshaller *m, int current_mode,
|
||||
int is_client_mouse_allowed)
|
||||
{
|
||||
SpiceMsgMainMouseMode mouse_mode;
|
||||
mouse_mode.supported_modes = SPICE_MOUSE_MODE_SERVER;
|
||||
@ -435,7 +436,8 @@ static void main_channel_push_migrate_data_item(MainChannel *main_chan)
|
||||
|
||||
static void main_channel_marshall_migrate_data_item(SpiceMarshaller *m, int serial, int ping_id)
|
||||
{
|
||||
MainMigrateData *data = (MainMigrateData *)spice_marshaller_reserve_space(m, sizeof(MainMigrateData));
|
||||
MainMigrateData *data = (MainMigrateData *)
|
||||
spice_marshaller_reserve_space(m, sizeof(MainMigrateData));
|
||||
|
||||
reds_marshall_migrate_data_item(m, data); // TODO: from reds split. ugly separation.
|
||||
data->serial = serial;
|
||||
@ -755,7 +757,8 @@ void main_channel_client_handle_migrate_end(MainChannelClient *mcc)
|
||||
mcc->mig_wait_prev_complete = FALSE;
|
||||
}
|
||||
}
|
||||
static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint16_t type, void *message)
|
||||
static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint16_t type,
|
||||
void *message)
|
||||
{
|
||||
MainChannel *main_chan = SPICE_CONTAINEROF(rcc->channel, MainChannel, base);
|
||||
MainChannelClient *mcc = SPICE_CONTAINEROF(rcc, MainChannelClient, base);
|
||||
@ -927,13 +930,10 @@ static MainChannelClient *main_channel_client_create(MainChannel *main_chan, Red
|
||||
int num_common_caps, uint32_t *common_caps,
|
||||
int num_caps, uint32_t *caps)
|
||||
{
|
||||
MainChannelClient *mcc = (MainChannelClient*)red_channel_client_create(sizeof(MainChannelClient),
|
||||
&main_chan->base,
|
||||
client, stream,
|
||||
num_common_caps,
|
||||
common_caps,
|
||||
num_caps,
|
||||
caps);
|
||||
MainChannelClient *mcc = (MainChannelClient*)
|
||||
red_channel_client_create(sizeof(MainChannelClient), &main_chan->base,
|
||||
client, stream, num_common_caps,
|
||||
common_caps, num_caps, caps);
|
||||
|
||||
mcc->connection_id = connection_id;
|
||||
mcc->bitrate_per_sec = ~0;
|
||||
@ -1039,7 +1039,8 @@ int main_channel_migrate_connect(MainChannel *main_channel, RedsMigSpice *mig_ta
|
||||
main_channel->num_clients_mig_wait = 0;
|
||||
|
||||
RING_FOREACH(client_link, &main_channel->base.clients) {
|
||||
MainChannelClient * mcc = SPICE_CONTAINEROF(client_link, MainChannelClient, base.channel_link);
|
||||
MainChannelClient * mcc = SPICE_CONTAINEROF(client_link, MainChannelClient,
|
||||
base.channel_link);
|
||||
if (red_channel_client_test_remote_cap(&mcc->base,
|
||||
SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE)) {
|
||||
if (red_client_during_migrate_at_target(mcc->base.client)) {
|
||||
|
||||
@ -162,6 +162,12 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle
|
||||
uint16_t msg_type;
|
||||
uint32_t msg_size;
|
||||
|
||||
/* XXX: This needs further investigation as to the underlying cause, it happened
|
||||
* after spicec disconnect (but not with spice-gtk) repeatedly. */
|
||||
if (!stream) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int ret_handle;
|
||||
if (handler->header_pos < handler->header.header_size) {
|
||||
|
||||
@ -3365,7 +3365,9 @@ static int tunnel_channel_config_socket(RedChannelClient *rcc)
|
||||
|
||||
if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val,
|
||||
sizeof(delay_val)) == -1) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
if (errno != ENOTSUP) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
@ -1043,14 +1043,17 @@ static void dump_bitmap(RedWorker *worker, SpiceBitmap *bitmap, uint32_t group_i
|
||||
|
||||
#define DCC_FOREACH(link, dcc, channel) \
|
||||
for (link = channel ? ring_get_head(&(channel)->clients) : NULL,\
|
||||
dcc = link ? SPICE_CONTAINEROF((link), DisplayChannelClient, common.base.channel_link) : NULL;\
|
||||
dcc = link ? SPICE_CONTAINEROF((link), DisplayChannelClient,\
|
||||
common.base.channel_link) : NULL;\
|
||||
(link); \
|
||||
(link) = ring_next(&(channel)->clients, link),\
|
||||
dcc = SPICE_CONTAINEROF((link), DisplayChannelClient, common.base.channel_link))
|
||||
|
||||
#define WORKER_FOREACH_DCC(worker, link, dcc) \
|
||||
for (link = ((worker) && (worker)->display_channel) ? ring_get_head(&(worker)->display_channel->common.base.clients) : NULL,\
|
||||
dcc = link ? SPICE_CONTAINEROF((link), DisplayChannelClient, common.base.channel_link) : NULL;\
|
||||
for (link = ((worker) && (worker)->display_channel) ?\
|
||||
ring_get_head(&(worker)->display_channel->common.base.clients) : NULL,\
|
||||
dcc = link ? SPICE_CONTAINEROF((link), DisplayChannelClient,\
|
||||
common.base.channel_link) : NULL;\
|
||||
(link); \
|
||||
(link) = ring_next(&(worker)->display_channel->common.base.clients, link),\
|
||||
dcc = SPICE_CONTAINEROF((link), DisplayChannelClient, common.base.channel_link))
|
||||
@ -1090,7 +1093,8 @@ static void dump_bitmap(RedWorker *worker, SpiceBitmap *bitmap, uint32_t group_i
|
||||
|
||||
// TODO: replace with DCC_FOREACH when it is introduced
|
||||
#define WORKER_TO_DCC(worker) \
|
||||
(worker->display_channel ? SPICE_CONTAINEROF(worker->display_channel->common.base.rcc, DisplayChannelClient, common.base) : NULL)
|
||||
(worker->display_channel ? SPICE_CONTAINEROF(worker->display_channel->common.base.rcc,\
|
||||
DisplayChannelClient, common.base) : NULL)
|
||||
|
||||
#define DCC_TO_DC(dcc) SPICE_CONTAINEROF((dcc)->common.base.channel,\
|
||||
DisplayChannel, common.base)
|
||||
@ -1481,7 +1485,8 @@ static inline void red_pipes_remove_drawable(Drawable *drawable)
|
||||
RING_FOREACH_SAFE(item, next, &drawable->pipes) {
|
||||
dpi = SPICE_CONTAINEROF(item, DrawablePipeItem, base);
|
||||
if (pipe_item_is_linked(&dpi->dpi_pipe_item)) {
|
||||
red_channel_client_pipe_remove_and_release(&dpi->dcc->common.base, &dpi->dpi_pipe_item);
|
||||
red_channel_client_pipe_remove_and_release(&dpi->dcc->common.base,
|
||||
&dpi->dpi_pipe_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1934,7 +1939,8 @@ static void red_current_clear(RedWorker *worker, int surface_id)
|
||||
}
|
||||
}
|
||||
|
||||
static void red_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surface_id, int force)
|
||||
static void red_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surface_id,
|
||||
int force)
|
||||
{
|
||||
Ring *ring;
|
||||
PipeItem *item;
|
||||
@ -2340,7 +2346,9 @@ static int is_equal_path(RedWorker *worker, SpicePath *path1, SpicePath *path2)
|
||||
// partial imp
|
||||
static int is_equal_brush(SpiceBrush *b1, SpiceBrush *b2)
|
||||
{
|
||||
return b1->type == b2->type && b1->type == SPICE_BRUSH_TYPE_SOLID && b1->u.color == b1->u.color;
|
||||
return b1->type == b2->type &&
|
||||
b1->type == SPICE_BRUSH_TYPE_SOLID &&
|
||||
b1->u.color == b1->u.color;
|
||||
}
|
||||
|
||||
// partial imp
|
||||
@ -2379,9 +2387,11 @@ static int is_same_drawable(RedWorker *worker, Drawable *d1, Drawable *d2)
|
||||
|
||||
switch (d1->red_drawable->type) {
|
||||
case QXL_DRAW_STROKE:
|
||||
return is_equal_brush(&d1->red_drawable->u.stroke.brush, &d2->red_drawable->u.stroke.brush);
|
||||
return is_equal_brush(&d1->red_drawable->u.stroke.brush,
|
||||
&d2->red_drawable->u.stroke.brush);
|
||||
case QXL_DRAW_FILL:
|
||||
return is_equal_brush(&d1->red_drawable->u.fill.brush, &d2->red_drawable->u.fill.brush);
|
||||
return is_equal_brush(&d1->red_drawable->u.fill.brush,
|
||||
&d2->red_drawable->u.fill.brush);
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
@ -2936,7 +2946,8 @@ static inline void pre_stream_item_swap(RedWorker *worker, Stream *stream)
|
||||
return;
|
||||
}
|
||||
|
||||
double drop_factor = ((double)agent->frames - (double)agent->drops) / (double)agent->frames;
|
||||
double drop_factor = ((double)agent->frames - (double)agent->drops) /
|
||||
(double)agent->frames;
|
||||
|
||||
if (drop_factor == 1) {
|
||||
if (agent->fps < MAX_FPS) {
|
||||
@ -3072,7 +3083,8 @@ static inline int red_current_add_equal(RedWorker *worker, DrawItem *item, TreeI
|
||||
other_drawable = SPICE_CONTAINEROF(other_draw_item, Drawable, tree_item);
|
||||
|
||||
if (item->effect == QXL_EFFECT_OPAQUE) {
|
||||
int add_after = !!other_drawable->stream && is_drawable_independent_from_surfaces(drawable);
|
||||
int add_after = !!other_drawable->stream &&
|
||||
is_drawable_independent_from_surfaces(drawable);
|
||||
red_stream_maintenance(worker, drawable, other_drawable);
|
||||
__current_add_drawable(worker, drawable, &other->siblings_link);
|
||||
other_drawable->refs++;
|
||||
@ -3355,7 +3367,8 @@ static inline Shadow *__new_shadow(RedWorker *worker, Drawable *item, SpicePoint
|
||||
return shadow;
|
||||
}
|
||||
|
||||
static inline int red_current_add_with_shadow(RedWorker *worker, Ring *ring, Drawable *item, SpicePoint *delta)
|
||||
static inline int red_current_add_with_shadow(RedWorker *worker, Ring *ring, Drawable *item,
|
||||
SpicePoint *delta)
|
||||
{
|
||||
#ifdef RED_WORKER_STAT
|
||||
stat_time_t start_time = stat_now();
|
||||
@ -3737,7 +3750,8 @@ static inline void red_inc_surfaces_drawable_dependencies(RedWorker *worker, Dra
|
||||
}
|
||||
}
|
||||
|
||||
static inline void red_process_drawable(RedWorker *worker, RedDrawable *drawable, uint32_t group_id)
|
||||
static inline void red_process_drawable(RedWorker *worker, RedDrawable *drawable,
|
||||
uint32_t group_id)
|
||||
{
|
||||
int surface_id;
|
||||
Drawable *item = get_drawable(worker, drawable->effect, drawable, group_id);
|
||||
@ -3810,7 +3824,8 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id,uin
|
||||
uint32_t height, int32_t stride, uint32_t format,
|
||||
void *line_0, int data_is_valid, int send_client);
|
||||
|
||||
static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface, uint32_t group_id, int loadvm)
|
||||
static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface,
|
||||
uint32_t group_id, int loadvm)
|
||||
{
|
||||
int surface_id;
|
||||
RedSurface *red_surface;
|
||||
@ -4818,8 +4833,8 @@ static void red_current_flush(RedWorker *worker, int surface_id)
|
||||
}
|
||||
|
||||
// adding the pipe item after pos. If pos == NULL, adding to head.
|
||||
static ImageItem *red_add_surface_area_image(DisplayChannelClient *dcc, int surface_id, SpiceRect *area,
|
||||
PipeItem *pos, int can_lossy)
|
||||
static ImageItem *red_add_surface_area_image(DisplayChannelClient *dcc, int surface_id,
|
||||
SpiceRect *area, PipeItem *pos, int can_lossy)
|
||||
{
|
||||
DisplayChannel *display_channel = DCC_TO_DC(dcc);
|
||||
RedWorker *worker = display_channel->common.worker;
|
||||
@ -5049,7 +5064,7 @@ static RedGlzDrawable *red_display_get_glz_drawable(DisplayChannelClient *dcc, D
|
||||
RedGlzDrawable *ret;
|
||||
RingItem *item;
|
||||
|
||||
// TODO - I don't really understand what's going on here, so just doing the technical equivalent
|
||||
// TODO - I don't really understand what's going on here, so doing the technical equivalent
|
||||
// now that we have multiple glz_dicts, so the only way to go from dcc to drawable glz is to go
|
||||
// over the glz_ring (unless adding some better data structure then a ring)
|
||||
DRAWABLE_FOREACH_GLZ(drawable, item, ret) {
|
||||
@ -6164,7 +6179,8 @@ static inline int red_compress_image(DisplayChannelClient *dcc,
|
||||
} else {
|
||||
if (drawable->copy_bitmap_graduality == BITMAP_GRADUAL_INVALID) {
|
||||
quic_compress = BITMAP_FMT_IS_RGB[src->format] &&
|
||||
(_get_bitmap_graduality_level(display_channel->common.worker, src, drawable->group_id) ==
|
||||
(_get_bitmap_graduality_level(display_channel->common.worker, src,
|
||||
drawable->group_id) ==
|
||||
BITMAP_GRADUAL_HIGH);
|
||||
} else {
|
||||
quic_compress = (drawable->copy_bitmap_graduality == BITMAP_GRADUAL_HIGH);
|
||||
@ -7094,7 +7110,8 @@ static void red_marshall_qxl_draw_transparent(RedWorker *worker,
|
||||
SpiceMarshaller *src_bitmap_out;
|
||||
SpiceTransparent transparent;
|
||||
|
||||
red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_DRAW_TRANSPARENT, &dpi->dpi_pipe_item);
|
||||
red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_DRAW_TRANSPARENT,
|
||||
&dpi->dpi_pipe_item);
|
||||
fill_base(base_marshaller, item);
|
||||
transparent = drawable->u.transparent;
|
||||
spice_marshall_Transparent(base_marshaller,
|
||||
@ -7144,13 +7161,15 @@ static FillBitsType red_marshall_qxl_draw_alpha_blend(RedWorker *worker,
|
||||
SpiceAlphaBlend alpha_blend;
|
||||
FillBitsType src_send_type;
|
||||
|
||||
red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND, &dpi->dpi_pipe_item);
|
||||
red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND,
|
||||
&dpi->dpi_pipe_item);
|
||||
fill_base(base_marshaller, item);
|
||||
alpha_blend = drawable->u.alpha_blend;
|
||||
spice_marshall_AlphaBlend(base_marshaller,
|
||||
&alpha_blend,
|
||||
&src_bitmap_out);
|
||||
src_send_type = fill_bits(dcc, src_bitmap_out, alpha_blend.src_bitmap, item, src_allowed_lossy);
|
||||
src_send_type = fill_bits(dcc, src_bitmap_out, alpha_blend.src_bitmap, item,
|
||||
src_allowed_lossy);
|
||||
|
||||
return src_send_type;
|
||||
}
|
||||
@ -8766,7 +8785,8 @@ static void red_migrate_display(RedWorker *worker, RedChannelClient *rcc)
|
||||
red_pipe_add_verb(rcc, PIPE_ITEM_TYPE_MIGRATE);
|
||||
// red_pipes_add_verb(&worker->display_channel->common.base,
|
||||
// SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL);
|
||||
// red_channel_pipes_add_type(&worker->display_channel->common.base, PIPE_ITEM_TYPE_MIGRATE);
|
||||
// red_channel_pipes_add_type(&worker->display_channel->common.base,
|
||||
// PIPE_ITEM_TYPE_MIGRATE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9068,8 +9088,8 @@ static inline void flush_cursor_commands(RedWorker *worker)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: on timeout, don't disconnect all channeld immeduiatly - try to disconnect the slowest ones first
|
||||
// and maybe turn timeouts to several timeouts in order to disconnect channels gradually.
|
||||
// TODO: on timeout, don't disconnect all channeld immeduiatly - try to disconnect the slowest ones
|
||||
// first and maybe turn timeouts to several timeouts in order to disconnect channels gradually.
|
||||
// Should use disconnect or shutdown?
|
||||
static inline void flush_all_qxl_commands(RedWorker *worker)
|
||||
{
|
||||
@ -9404,7 +9424,8 @@ static uint64_t display_channel_handle_migrate_data_get_serial(
|
||||
return migrate_data->message_serial;
|
||||
}
|
||||
|
||||
static uint64_t display_channel_handle_migrate_data(RedChannelClient *rcc, uint32_t size, void *message)
|
||||
static uint64_t display_channel_handle_migrate_data(RedChannelClient *rcc, uint32_t size,
|
||||
void *message)
|
||||
{
|
||||
DisplayChannelMigrateData *migrate_data;
|
||||
DisplayChannel *display_channel = SPICE_CONTAINEROF(rcc->channel, DisplayChannel, common.base);
|
||||
@ -9461,7 +9482,8 @@ static uint64_t display_channel_handle_migrate_data(RedChannelClient *rcc, uint3
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int display_channel_handle_message(RedChannelClient *rcc, uint32_t size, uint16_t type, void *message)
|
||||
static int display_channel_handle_message(RedChannelClient *rcc, uint32_t size, uint16_t type,
|
||||
void *message)
|
||||
{
|
||||
DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
|
||||
switch (type) {
|
||||
@ -9497,8 +9519,11 @@ static int common_channel_config_socket(RedChannelClient *rcc)
|
||||
|
||||
// TODO - this should be dynamic, not one time at channel creation
|
||||
delay_val = main_channel_client_is_low_bandwidth(mcc) ? 0 : 1;
|
||||
if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val, sizeof(delay_val)) == -1) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val,
|
||||
sizeof(delay_val)) == -1) {
|
||||
if (errno != ENOTSUP) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -9623,7 +9648,7 @@ static RedChannel *__new_channel(RedWorker *worker, int size, uint32_t channel_t
|
||||
channel_handle_parsed_proc handle_parsed,
|
||||
channel_handle_migrate_flush_mark_proc handle_migrate_flush_mark,
|
||||
channel_handle_migrate_data_proc handle_migrate_data,
|
||||
channel_handle_migrate_data_get_serial_proc handle_migrate_data_get_serial)
|
||||
channel_handle_migrate_data_get_serial_proc migrate_get_serial)
|
||||
{
|
||||
RedChannel *channel = NULL;
|
||||
CommonChannel *common;
|
||||
@ -9638,7 +9663,7 @@ static RedChannel *__new_channel(RedWorker *worker, int size, uint32_t channel_t
|
||||
channel_cbs.release_recv_buf = common_release_recv_buf;
|
||||
channel_cbs.handle_migrate_flush_mark = handle_migrate_flush_mark;
|
||||
channel_cbs.handle_migrate_data = handle_migrate_data;
|
||||
channel_cbs.handle_migrate_data_get_serial = handle_migrate_data_get_serial;
|
||||
channel_cbs.handle_migrate_data_get_serial = migrate_get_serial;
|
||||
|
||||
channel = red_channel_create_parser(size, &worker_core,
|
||||
channel_type, worker->id,
|
||||
@ -10348,7 +10373,8 @@ static inline void red_cursor_reset(RedWorker *worker)
|
||||
worker->cursor_trail_length = worker->cursor_trail_frequency = 0;
|
||||
|
||||
if (cursor_is_connected(worker)) {
|
||||
red_channel_pipes_add_type(&worker->cursor_channel->common.base, PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE);
|
||||
red_channel_pipes_add_type(&worker->cursor_channel->common.base,
|
||||
PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE);
|
||||
if (!worker->cursor_channel->common.base.migrate) {
|
||||
red_pipes_add_verb(&worker->cursor_channel->common.base, SPICE_MSG_CURSOR_RESET);
|
||||
}
|
||||
@ -10405,8 +10431,8 @@ static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id,
|
||||
PANIC_ON(((uint64_t)abs(surface.stride) * (uint64_t)surface.height) !=
|
||||
abs(surface.stride) * surface.height);
|
||||
|
||||
line_0 = (uint8_t*)get_virt(&worker->mem_slots, surface.mem, surface.height * abs(surface.stride),
|
||||
surface.group_id);
|
||||
line_0 = (uint8_t*)get_virt(&worker->mem_slots, surface.mem,
|
||||
surface.height * abs(surface.stride), surface.group_id);
|
||||
if (surface.stride < 0) {
|
||||
line_0 -= (int32_t)(surface.stride * (surface.height -1));
|
||||
}
|
||||
|
||||
@ -2706,7 +2706,9 @@ static RedLinkInfo *reds_init_client_connection(int socket)
|
||||
}
|
||||
|
||||
if (setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &delay_val, sizeof(delay_val)) == -1) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
if (errno != ENOTSUP) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
link = spice_new0(RedLinkInfo, 1);
|
||||
|
||||
@ -902,7 +902,9 @@ static SndChannel *__new_channel(SndWorker *worker, int size, uint32_t channel_i
|
||||
SndChannel *channel;
|
||||
int delay_val;
|
||||
int flags;
|
||||
#ifdef SO_PRIORITY
|
||||
int priority;
|
||||
#endif
|
||||
int tos;
|
||||
MainChannelClient *mcc = red_client_get_main(client);
|
||||
|
||||
@ -911,20 +913,28 @@ static SndChannel *__new_channel(SndWorker *worker, int size, uint32_t channel_i
|
||||
goto error1;
|
||||
}
|
||||
|
||||
#ifdef SO_PRIORITY
|
||||
priority = 6;
|
||||
if (setsockopt(stream->socket, SOL_SOCKET, SO_PRIORITY, (void*)&priority,
|
||||
sizeof(priority)) == -1) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
if (errno != ENOTSUP) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
tos = IPTOS_LOWDELAY;
|
||||
if (setsockopt(stream->socket, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) == -1) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
if (errno != ENOTSUP) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
delay_val = main_channel_client_is_low_bandwidth(mcc) ? 0 : 1;
|
||||
if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val, sizeof(delay_val)) == -1) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
if (errno != ENOTSUP) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (fcntl(stream->socket, F_SETFL, flags | O_NONBLOCK) == -1) {
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <spice/qxl_dev.h>
|
||||
|
||||
#define SPICE_SERVER_VERSION 0x000901 /* release 0.9.1 */
|
||||
#define SPICE_SERVER_VERSION 0x000a01 /* release 0.10.1 */
|
||||
|
||||
/* interface base type */
|
||||
|
||||
|
||||
@ -92,8 +92,10 @@ static int spicevmc_red_channel_client_config_socket(RedChannelClient *rcc)
|
||||
if (rcc->channel->type == SPICE_CHANNEL_USBREDIR) {
|
||||
if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY,
|
||||
&delay_val, sizeof(delay_val)) != 0) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
return FALSE;
|
||||
if (errno != ENOTSUP) {
|
||||
red_printf("setsockopt failed, %s", strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
server/tests/.gitignore
vendored
2
server/tests/.gitignore
vendored
@ -1,4 +1,6 @@
|
||||
test_display_no_ssl
|
||||
test_display_streaming
|
||||
test_empty_success
|
||||
test_just_sockets_no_ssl
|
||||
test_fail_on_null_core_interface
|
||||
test_playback
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include <spice.h>
|
||||
|
||||
SpiceTimer* timer_add(SpiceTimerFunc func, void *opaque)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user