Client: Use the autogenerated demarshallers

When a message has been read from the network we now pass it into
the generated demarshaller for the channel. The demarshaller converts
the network data to in-memory structures that is passed on to the
spice internals.

Additionally it also:
* Converts endianness
* Validates sizes of message and any pointers in it
* Localizes offsets (converts them to pointers)
* Checks for zero offsets in messages where they are not supported

Some of this was previously done using custom code in the client, this
is now removed.
This commit is contained in:
Alexander Larsson 2010-05-25 16:01:18 +02:00
parent 17bbef4df3
commit 4154d70289
20 changed files with 229 additions and 444 deletions

View File

@ -27,6 +27,8 @@ RED_COMMON_SRCS = \
cmd_line_parser.cpp \
cmd_line_parser.h \
common.h \
demarshallers.h \
generated_demarshallers.cpp \
cursor_channel.cpp \
cursor_channel.h \
cursor.cpp \

View File

@ -44,95 +44,14 @@ void Canvas::clear()
}
}
inline void Canvas::access_test(void *ptr, size_t size)
{
if ((unsigned long)ptr < _base || (unsigned long)ptr + size > _max) {
THROW("access violation %p %lu", ptr, size);
}
}
void Canvas::localalize_ptr(SPICE_ADDRESS* data)
{
if (*data) {
*data += _base;
}
}
void Canvas::localalize_image(SPICE_ADDRESS* in_bitmap)
{
SpiceImageDescriptor* image;
ASSERT(*in_bitmap);
localalize_ptr(in_bitmap);
image = (SpiceImageDescriptor*)SPICE_GET_ADDRESS(*in_bitmap);
switch (image->type) {
case SPICE_IMAGE_TYPE_SURFACE:
break;
case SPICE_IMAGE_TYPE_BITMAP: {
SpiceBitmapImage *bitmap = (SpiceBitmapImage *)image;
localalize_ptr(&bitmap->bitmap.data);
if (bitmap->bitmap.palette && !(bitmap->bitmap.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
localalize_ptr(&bitmap->bitmap.palette);
}
break;
}
case SPICE_IMAGE_TYPE_LZ_PLT: {
SpiceLZPLTImage *lzImage = (SpiceLZPLTImage *)image;
ASSERT(lzImage->lz_plt.palette);
if (!(lzImage->lz_plt.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
localalize_ptr(&lzImage->lz_plt.palette);
}
break;
}
case SPICE_IMAGE_TYPE_LZ_RGB:
case SPICE_IMAGE_TYPE_GLZ_RGB:
case SPICE_IMAGE_TYPE_QUIC:
case SPICE_IMAGE_TYPE_JPEG:
break;
case SPICE_IMAGE_TYPE_FROM_CACHE:
case SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS:
break;
default:
THROW("invalid image type %u", image->type);
}
}
void Canvas::localalize_brush(SpiceBrush& brush)
{
if (brush.type == SPICE_BRUSH_TYPE_PATTERN) {
localalize_image(&brush.u.pattern.pat);
}
}
void Canvas::localalize_attr(SpiceLineAttr& attr)
{
if (attr.style_nseg) {
localalize_ptr(&attr.style);
}
}
void Canvas::localalize_mask(SpiceQMask& mask)
{
if (mask.bitmap) {
localalize_image(&mask.bitmap);
}
}
void Canvas::begin_draw(SpiceMsgDisplayBase& base, int size, size_t min_size)
{
_base = (unsigned long)&base;
_max = _base + size;
_canvas->ops->set_access_params(_canvas, _base, _max);
access_test(&base, min_size);
localalize_ptr(&base.clip.data);
}
void Canvas::draw_fill(SpiceMsgDisplayDrawFill& fill, int size)
{
begin_draw(fill.base, size, sizeof(SpiceMsgDisplayDrawFill));
localalize_brush(fill.data.brush);
localalize_mask(fill.data.mask);
_canvas->ops->draw_fill(_canvas, &fill.base.box, &fill.base.clip, &fill.data);
touched_bbox(&fill.base.box);
}
@ -140,9 +59,6 @@ void Canvas::draw_fill(SpiceMsgDisplayDrawFill& fill, int size)
void Canvas::draw_text(SpiceMsgDisplayDrawText& text, int size)
{
begin_draw(text.base, size, sizeof(SpiceMsgDisplayDrawText));
localalize_brush(text.data.fore_brush);
localalize_brush(text.data.back_brush);
localalize_ptr(&text.data.str);
_canvas->ops->draw_text(_canvas, &text.base.box, &text.base.clip, &text.data);
touched_bbox(&text.base.box);
}
@ -150,9 +66,6 @@ void Canvas::draw_text(SpiceMsgDisplayDrawText& text, int size)
void Canvas::draw_opaque(SpiceMsgDisplayDrawOpaque& opaque, int size)
{
begin_draw(opaque.base, size, sizeof(SpiceMsgDisplayDrawOpaque));
localalize_brush(opaque.data.brush);
localalize_image(&opaque.data.src_bitmap);
localalize_mask(opaque.data.mask);
_canvas->ops->draw_opaque(_canvas, &opaque.base.box, &opaque.base.clip, &opaque.data);
touched_bbox(&opaque.base.box);
}
@ -160,8 +73,6 @@ void Canvas::draw_opaque(SpiceMsgDisplayDrawOpaque& opaque, int size)
void Canvas::draw_copy(SpiceMsgDisplayDrawCopy& copy, int size)
{
begin_draw(copy.base, size, sizeof(SpiceMsgDisplayDrawCopy));
localalize_image(&copy.data.src_bitmap);
localalize_mask(copy.data.mask);
_canvas->ops->draw_copy(_canvas, &copy.base.box, &copy.base.clip, &copy.data);
touched_bbox(&copy.base.box);
}
@ -169,7 +80,6 @@ void Canvas::draw_copy(SpiceMsgDisplayDrawCopy& copy, int size)
void Canvas::draw_transparent(SpiceMsgDisplayDrawTransparent& transparent, int size)
{
begin_draw(transparent.base, size, sizeof(SpiceMsgDisplayDrawTransparent));
localalize_image(&transparent.data.src_bitmap);
_canvas->ops->draw_transparent(_canvas, &transparent.base.box, &transparent.base.clip, &transparent.data);
touched_bbox(&transparent.base.box);
}
@ -177,7 +87,6 @@ void Canvas::draw_transparent(SpiceMsgDisplayDrawTransparent& transparent, int s
void Canvas::draw_alpha_blend(SpiceMsgDisplayDrawAlphaBlend& alpha_blend, int size)
{
begin_draw(alpha_blend.base, size, sizeof(SpiceMsgDisplayDrawAlphaBlend));
localalize_image(&alpha_blend.data.src_bitmap);
_canvas->ops->draw_alpha_blend(_canvas, &alpha_blend.base.box, &alpha_blend.base.clip, &alpha_blend.data);
touched_bbox(&alpha_blend.base.box);
}
@ -192,8 +101,6 @@ void Canvas::copy_bits(SpiceMsgDisplayCopyBits& copy, int size)
void Canvas::draw_blend(SpiceMsgDisplayDrawBlend& blend, int size)
{
begin_draw(blend.base, size, sizeof(SpiceMsgDisplayDrawBlend));
localalize_image(&blend.data.src_bitmap);
localalize_mask(blend.data.mask);
_canvas->ops->draw_blend(_canvas, &blend.base.box, &blend.base.clip, &blend.data);
touched_bbox(&blend.base.box);
}
@ -201,7 +108,6 @@ void Canvas::draw_blend(SpiceMsgDisplayDrawBlend& blend, int size)
void Canvas::draw_blackness(SpiceMsgDisplayDrawBlackness& blackness, int size)
{
begin_draw(blackness.base, size, sizeof(SpiceMsgDisplayDrawBlackness));
localalize_mask(blackness.data.mask);
_canvas->ops->draw_blackness(_canvas, &blackness.base.box, &blackness.base.clip, &blackness.data);
touched_bbox(&blackness.base.box);
}
@ -209,7 +115,6 @@ void Canvas::draw_blackness(SpiceMsgDisplayDrawBlackness& blackness, int size)
void Canvas::draw_whiteness(SpiceMsgDisplayDrawWhiteness& whiteness, int size)
{
begin_draw(whiteness.base, size, sizeof(SpiceMsgDisplayDrawWhiteness));
localalize_mask(whiteness.data.mask);
_canvas->ops->draw_whiteness(_canvas, &whiteness.base.box, &whiteness.base.clip, &whiteness.data);
touched_bbox(&whiteness.base.box);
}
@ -217,7 +122,6 @@ void Canvas::draw_whiteness(SpiceMsgDisplayDrawWhiteness& whiteness, int size)
void Canvas::draw_invers(SpiceMsgDisplayDrawInvers& invers, int size)
{
begin_draw(invers.base, size, sizeof(SpiceMsgDisplayDrawInvers));
localalize_mask(invers.data.mask);
_canvas->ops->draw_invers(_canvas, &invers.base.box, &invers.base.clip, &invers.data);
touched_bbox(&invers.base.box);
}
@ -225,9 +129,6 @@ void Canvas::draw_invers(SpiceMsgDisplayDrawInvers& invers, int size)
void Canvas::draw_rop3(SpiceMsgDisplayDrawRop3& rop3, int size)
{
begin_draw(rop3.base, size, sizeof(SpiceMsgDisplayDrawRop3));
localalize_brush(rop3.data.brush);
localalize_image(&rop3.data.src_bitmap);
localalize_mask(rop3.data.mask);
_canvas->ops->draw_rop3(_canvas, &rop3.base.box, &rop3.base.clip, &rop3.data);
touched_bbox(&rop3.base.box);
}
@ -235,9 +136,6 @@ void Canvas::draw_rop3(SpiceMsgDisplayDrawRop3& rop3, int size)
void Canvas::draw_stroke(SpiceMsgDisplayDrawStroke& stroke, int size)
{
begin_draw(stroke.base, size, sizeof(SpiceMsgDisplayDrawStroke));
localalize_brush(stroke.data.brush);
localalize_ptr(&stroke.data.path);
localalize_attr(stroke.data.attr);
_canvas->ops->draw_stroke(_canvas, &stroke.base.box, &stroke.base.clip, &stroke.data);
touched_bbox(&stroke.base.box);
}

View File

@ -452,7 +452,6 @@ private:
void localalize_ptr(SPICE_ADDRESS* data);
void localalize_image(SPICE_ADDRESS* in_bitmap);
void localalize_brush(SpiceBrush& brush);
void localalize_attr(SpiceLineAttr& attr);
void localalize_mask(SpiceQMask& mask);
void begin_draw(SpiceMsgDisplayBase& base, int size, size_t min_size);

View File

@ -348,10 +348,10 @@ private:
CursorChannel& _channel;
};
class CursorHandler: public MessageHandlerImp<CursorChannel, SPICE_MSG_END_CURSOR> {
class CursorHandler: public MessageHandlerImp<CursorChannel, SPICE_CHANNEL_CURSOR> {
public:
CursorHandler(CursorChannel& channel)
: MessageHandlerImp<CursorChannel, SPICE_MSG_END_CURSOR>(channel) {}
: MessageHandlerImp<CursorChannel, SPICE_CHANNEL_CURSOR>(channel) {}
};
CursorChannel::CursorChannel(RedClient& client, uint32_t id)
@ -363,27 +363,21 @@ CursorChannel::CursorChannel(RedClient& client, uint32_t id)
{
CursorHandler* handler = static_cast<CursorHandler*>(get_message_handler());
handler->set_handler(SPICE_MSG_MIGRATE, &CursorChannel::handle_migrate, 0);
handler->set_handler(SPICE_MSG_SET_ACK, &CursorChannel::handle_set_ack, sizeof(SpiceMsgSetAck));
handler->set_handler(SPICE_MSG_PING, &CursorChannel::handle_ping, sizeof(SpiceMsgPing));
handler->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &CursorChannel::handle_wait_for_channels,
sizeof(SpiceMsgWaitForChannels));
handler->set_handler(SPICE_MSG_DISCONNECTING, &CursorChannel::handle_disconnect,
sizeof(SpiceMsgDisconnect));
handler->set_handler(SPICE_MSG_NOTIFY, &CursorChannel::handle_notify, sizeof(SpiceMsgNotify));
handler->set_handler(SPICE_MSG_MIGRATE, &CursorChannel::handle_migrate);
handler->set_handler(SPICE_MSG_SET_ACK, &CursorChannel::handle_set_ack);
handler->set_handler(SPICE_MSG_PING, &CursorChannel::handle_ping);
handler->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &CursorChannel::handle_wait_for_channels);
handler->set_handler(SPICE_MSG_DISCONNECTING, &CursorChannel::handle_disconnect);
handler->set_handler(SPICE_MSG_NOTIFY, &CursorChannel::handle_notify);
handler->set_handler(SPICE_MSG_CURSOR_INIT, &CursorChannel::handle_init, sizeof(SpiceMsgCursorInit));
handler->set_handler(SPICE_MSG_CURSOR_RESET, &CursorChannel::handle_reset, 0);
handler->set_handler(SPICE_MSG_CURSOR_SET, &CursorChannel::handle_cursor_set,
sizeof(SpiceMsgCursorSet));
handler->set_handler(SPICE_MSG_CURSOR_MOVE, &CursorChannel::handle_cursor_move,
sizeof(SpiceMsgCursorMove));
handler->set_handler(SPICE_MSG_CURSOR_HIDE, &CursorChannel::handle_cursor_hide, 0);
handler->set_handler(SPICE_MSG_CURSOR_TRAIL, &CursorChannel::handle_cursor_trail,
sizeof(SpiceMsgCursorTrail));
handler->set_handler(SPICE_MSG_CURSOR_INVAL_ONE, &CursorChannel::handle_inval_one,
sizeof(SpiceMsgDisplayInvalOne));
handler->set_handler(SPICE_MSG_CURSOR_INVAL_ALL, &CursorChannel::handle_inval_all, 0);
handler->set_handler(SPICE_MSG_CURSOR_INIT, &CursorChannel::handle_init);
handler->set_handler(SPICE_MSG_CURSOR_RESET, &CursorChannel::handle_reset);
handler->set_handler(SPICE_MSG_CURSOR_SET, &CursorChannel::handle_cursor_set);
handler->set_handler(SPICE_MSG_CURSOR_MOVE, &CursorChannel::handle_cursor_move);
handler->set_handler(SPICE_MSG_CURSOR_HIDE, &CursorChannel::handle_cursor_hide);
handler->set_handler(SPICE_MSG_CURSOR_TRAIL, &CursorChannel::handle_cursor_trail);
handler->set_handler(SPICE_MSG_CURSOR_INVAL_ONE, &CursorChannel::handle_inval_one);
handler->set_handler(SPICE_MSG_CURSOR_INVAL_ALL, &CursorChannel::handle_inval_all);
}
CursorChannel::~CursorChannel()

25
client/demarshallers.h Normal file
View File

@ -0,0 +1,25 @@
/*
Copyright (C) 2010 Red Hat, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _H_DEMARSHAL
#define _H_DEMARSHAL
typedef uint8_t * (*spice_parse_channel_func_t)(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, int minor, size_t *size_out);
spice_parse_channel_func_t spice_get_server_channel_parser(uint32_t channel, unsigned int *max_message_type);
#endif

View File

@ -578,10 +578,10 @@ Canvas* DisplaySurfacesManger::get_canvas(int surface_id)
return canvases.get(surface_id);
}
class DisplayHandler: public MessageHandlerImp<DisplayChannel, SPICE_MSG_END_DISPLAY> {
class DisplayHandler: public MessageHandlerImp<DisplayChannel, SPICE_CHANNEL_DISPLAY> {
public:
DisplayHandler(DisplayChannel& channel)
: MessageHandlerImp<DisplayChannel, SPICE_MSG_END_DISPLAY>(channel) {}
: MessageHandlerImp<DisplayChannel, SPICE_CHANNEL_DISPLAY>(channel) {}
};
DisplayChannel::DisplayChannel(RedClient& client, uint32_t id,
@ -608,42 +608,33 @@ DisplayChannel::DisplayChannel(RedClient& client, uint32_t id,
{
DisplayHandler* handler = static_cast<DisplayHandler*>(get_message_handler());
handler->set_handler(SPICE_MSG_MIGRATE, &DisplayChannel::handle_migrate, 0);
handler->set_handler(SPICE_MSG_SET_ACK, &DisplayChannel::handle_set_ack, sizeof(SpiceMsgSetAck));
handler->set_handler(SPICE_MSG_PING, &DisplayChannel::handle_ping, sizeof(SpiceMsgPing));
handler->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &DisplayChannel::handle_wait_for_channels,
sizeof(SpiceMsgWaitForChannels));
handler->set_handler(SPICE_MSG_DISCONNECTING, &DisplayChannel::handle_disconnect,
sizeof(SpiceMsgDisconnect));
handler->set_handler(SPICE_MSG_NOTIFY, &DisplayChannel::handle_notify, sizeof(SpiceMsgNotify));
handler->set_handler(SPICE_MSG_MIGRATE, &DisplayChannel::handle_migrate);
handler->set_handler(SPICE_MSG_SET_ACK, &DisplayChannel::handle_set_ack);
handler->set_handler(SPICE_MSG_PING, &DisplayChannel::handle_ping);
handler->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &DisplayChannel::handle_wait_for_channels);
handler->set_handler(SPICE_MSG_DISCONNECTING, &DisplayChannel::handle_disconnect);
handler->set_handler(SPICE_MSG_NOTIFY, &DisplayChannel::handle_notify);
handler->set_handler(SPICE_MSG_DISPLAY_MARK, &DisplayChannel::handle_mark, 0);
handler->set_handler(SPICE_MSG_DISPLAY_RESET, &DisplayChannel::handle_reset, 0);
handler->set_handler(SPICE_MSG_DISPLAY_MARK, &DisplayChannel::handle_mark);
handler->set_handler(SPICE_MSG_DISPLAY_RESET, &DisplayChannel::handle_reset);
handler->set_handler(SPICE_MSG_DISPLAY_INVAL_LIST,
&DisplayChannel::handle_inval_list,
sizeof(SpiceResourceList));
&DisplayChannel::handle_inval_list);
handler->set_handler(SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS,
&DisplayChannel::handle_inval_all_pixmaps,
sizeof(SpiceMsgWaitForChannels));
&DisplayChannel::handle_inval_all_pixmaps);
handler->set_handler(SPICE_MSG_DISPLAY_INVAL_PALETTE,
&DisplayChannel::handle_inval_palette, sizeof(SpiceMsgDisplayInvalOne));
&DisplayChannel::handle_inval_palette);
handler->set_handler(SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES,
&DisplayChannel::handle_inval_all_palettes, 0);
&DisplayChannel::handle_inval_all_palettes);
handler->set_handler(SPICE_MSG_DISPLAY_STREAM_CREATE, &DisplayChannel::handle_stream_create,
sizeof(SpiceMsgDisplayStreamCreate));
handler->set_handler(SPICE_MSG_DISPLAY_STREAM_CLIP, &DisplayChannel::handle_stream_clip,
sizeof(SpiceMsgDisplayStreamClip));
handler->set_handler(SPICE_MSG_DISPLAY_STREAM_DESTROY, &DisplayChannel::handle_stream_destroy,
sizeof(SpiceMsgDisplayStreamDestroy));
handler->set_handler(SPICE_MSG_DISPLAY_STREAM_CREATE, &DisplayChannel::handle_stream_create);
handler->set_handler(SPICE_MSG_DISPLAY_STREAM_CLIP, &DisplayChannel::handle_stream_clip);
handler->set_handler(SPICE_MSG_DISPLAY_STREAM_DESTROY, &DisplayChannel::handle_stream_destroy);
handler->set_handler(SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL,
&DisplayChannel::handle_stream_destroy_all, 0);
&DisplayChannel::handle_stream_destroy_all);
handler->set_handler(SPICE_MSG_DISPLAY_SURFACE_CREATE, &DisplayChannel::handle_surface_create,
sizeof(SpiceMsgSurfaceCreate));
handler->set_handler(SPICE_MSG_DISPLAY_SURFACE_DESTROY, &DisplayChannel::handle_surface_destroy,
sizeof(SpiceMsgSurfaceDestroy));
handler->set_handler(SPICE_MSG_DISPLAY_SURFACE_CREATE, &DisplayChannel::handle_surface_create);
handler->set_handler(SPICE_MSG_DISPLAY_SURFACE_DESTROY, &DisplayChannel::handle_surface_destroy);
get_process_loop().add_trigger(_streams_trigger);
#ifdef USE_OGL
@ -678,55 +669,43 @@ void DisplayChannel::set_draw_handlers()
{
DisplayHandler* handler = static_cast<DisplayHandler*>(get_message_handler());
handler->set_handler(SPICE_MSG_DISPLAY_COPY_BITS, &DisplayChannel::handle_copy_bits,
sizeof(SpiceMsgDisplayCopyBits));
handler->set_handler(SPICE_MSG_DISPLAY_COPY_BITS, &DisplayChannel::handle_copy_bits);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_FILL, &DisplayChannel::handle_draw_fill,
sizeof(SpiceMsgDisplayDrawFill));
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_OPAQUE, &DisplayChannel::handle_draw_opaque,
sizeof(SpiceMsgDisplayDrawOpaque));
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_COPY, &DisplayChannel::handle_draw_copy,
sizeof(SpiceMsgDisplayDrawCopy));
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_BLEND, &DisplayChannel::handle_draw_blend,
sizeof(SpiceMsgDisplayDrawBlend));
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_BLACKNESS, &DisplayChannel::handle_draw_blackness,
sizeof(SpiceMsgDisplayDrawBlackness));
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_WHITENESS, &DisplayChannel::handle_draw_whiteness,
sizeof(SpiceMsgDisplayDrawWhiteness));
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_INVERS, &DisplayChannel::handle_draw_invers,
sizeof(SpiceMsgDisplayDrawInvers));
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_ROP3, &DisplayChannel::handle_draw_rop3,
sizeof(SpiceMsgDisplayDrawRop3));
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_STROKE, &DisplayChannel::handle_draw_stroke,
sizeof(SpiceMsgDisplayDrawStroke));
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_TEXT, &DisplayChannel::handle_draw_text,
sizeof(SpiceMsgDisplayDrawText));
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_FILL, &DisplayChannel::handle_draw_fill);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_OPAQUE, &DisplayChannel::handle_draw_opaque);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_COPY, &DisplayChannel::handle_draw_copy);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_BLEND, &DisplayChannel::handle_draw_blend);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_BLACKNESS, &DisplayChannel::handle_draw_blackness);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_WHITENESS, &DisplayChannel::handle_draw_whiteness);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_INVERS, &DisplayChannel::handle_draw_invers);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_ROP3, &DisplayChannel::handle_draw_rop3);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_STROKE, &DisplayChannel::handle_draw_stroke);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_TEXT, &DisplayChannel::handle_draw_text);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_TRANSPARENT,
&DisplayChannel::handle_draw_transparent, sizeof(SpiceMsgDisplayDrawTransparent));
&DisplayChannel::handle_draw_transparent);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND,
&DisplayChannel::handle_draw_alpha_blend, sizeof(SpiceMsgDisplayDrawAlphaBlend));
handler->set_handler(SPICE_MSG_DISPLAY_STREAM_DATA, &DisplayChannel::handle_stream_data,
sizeof(SpiceMsgDisplayStreamData));
&DisplayChannel::handle_draw_alpha_blend);
handler->set_handler(SPICE_MSG_DISPLAY_STREAM_DATA, &DisplayChannel::handle_stream_data);
}
void DisplayChannel::clear_draw_handlers()
{
DisplayHandler* handler = static_cast<DisplayHandler*>(get_message_handler());
handler->set_handler(SPICE_MSG_DISPLAY_COPY_BITS, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_FILL, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_OPAQUE, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_COPY, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_BLEND, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_BLACKNESS, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_WHITENESS, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_INVERS, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_ROP3, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_STROKE, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_TEXT, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_TRANSPARENT, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_STREAM_DATA, NULL, 0);
handler->set_handler(SPICE_MSG_DISPLAY_COPY_BITS, NULL);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_FILL, NULL);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_OPAQUE, NULL);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_COPY, NULL);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_BLEND, NULL);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_BLACKNESS, NULL);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_WHITENESS, NULL);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_INVERS, NULL);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_ROP3, NULL);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_STROKE, NULL);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_TEXT, NULL);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_TRANSPARENT, NULL);
handler->set_handler(SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND, NULL);
handler->set_handler(SPICE_MSG_DISPLAY_STREAM_DATA, NULL);
}
void DisplayChannel::copy_pixels(const QRegion& dest_region,
@ -1289,20 +1268,13 @@ void DisplayChannel::handle_inval_all_palettes(RedPeer::InMessage* message)
}
void DisplayChannel::set_clip_rects(const SpiceClip& clip, uint32_t& num_clip_rects,
SpiceRect*& clip_rects, unsigned long addr_offset,
uint8_t *min, uint8_t *max)
SpiceRect*& clip_rects)
{
switch (clip.type) {
case SPICE_CLIP_TYPE_RECTS: {
uint32_t* n = (uint32_t*)SPICE_GET_ADDRESS(clip.data + addr_offset);
if (n < (uint32_t*)min || n + 1 > (uint32_t*)max) {
THROW("access violation");
}
uint32_t* n = (uint32_t*)SPICE_GET_ADDRESS(clip.data);
num_clip_rects = *n;
clip_rects = (SpiceRect *)(n + 1);
if (clip_rects + num_clip_rects > (SpiceRect*)max) {
THROW("access violation");
}
break;
}
case SPICE_CLIP_TYPE_NONE:
@ -1330,9 +1302,7 @@ void DisplayChannel::handle_stream_create(RedPeer::InMessage* message)
uint32_t num_clip_rects;
SpiceRect* clip_rects;
set_clip_rects(stream_create->clip, num_clip_rects, clip_rects,
(unsigned long)message->data(), (uint8_t*)(stream_create + 1),
message->data() + message->size());
set_clip_rects(stream_create->clip, num_clip_rects, clip_rects);
_streams[stream_create->id] = new VideoStream(get_client(), *surfaces_mngr.get_canvas(surface_id),
*this, stream_create->codec_type,
!!(stream_create->flags & SPICE_STREAM_FLAGS_TOP_DOWN),
@ -1379,9 +1349,7 @@ void DisplayChannel::handle_stream_clip(RedPeer::InMessage* message)
if (message->size() < sizeof(SpiceMsgDisplayStreamClip)) {
THROW("access violation");
}
set_clip_rects(clip_data->clip, num_clip_rects, clip_rects,
(unsigned long)message->data(), (uint8_t*)(clip_data + 1),
message->data() + message->size());
set_clip_rects(clip_data->clip, num_clip_rects, clip_rects);
Lock lock(_streams_lock);
stream->set_clip(clip_data->clip.type, num_clip_rects, clip_rects);
}

View File

@ -189,8 +189,7 @@ private:
void activate_streams_timer();
void stream_update_request(uint32_t update_time);
static void set_clip_rects(const SpiceClip& clip, uint32_t& num_clip_rects, SpiceRect*& clip_rects,
unsigned long addr_offset, uint8_t *min, uint8_t *max);
static void set_clip_rects(const SpiceClip& clip, uint32_t& num_clip_rects, SpiceRect*& clip_rects);
private:
DisplaySurfacesManger surfaces_mngr;
PixmapCache& _pixmap_cache;

View File

@ -158,10 +158,10 @@ RedPeer::OutMessage& PositionMessage::peer_message()
return *this;
}
class InputsMessHandler: public MessageHandlerImp<InputsChannel, SPICE_MSG_END_INPUTS> {
class InputsMessHandler: public MessageHandlerImp<InputsChannel, SPICE_CHANNEL_INPUTS> {
public:
InputsMessHandler(InputsChannel& channel)
: MessageHandlerImp<InputsChannel, SPICE_MSG_END_INPUTS>(channel) {}
: MessageHandlerImp<InputsChannel, SPICE_CHANNEL_INPUTS>(channel) {}
};
InputsChannel::InputsChannel(RedClient& client, uint32_t id)
@ -177,19 +177,16 @@ InputsChannel::InputsChannel(RedClient& client, uint32_t id)
, _active_modifiers_event (false)
{
InputsMessHandler* handler = static_cast<InputsMessHandler*>(get_message_handler());
handler->set_handler(SPICE_MSG_MIGRATE, &InputsChannel::handle_migrate, 0);
handler->set_handler(SPICE_MSG_SET_ACK, &InputsChannel::handle_set_ack, sizeof(SpiceMsgSetAck));
handler->set_handler(SPICE_MSG_PING, &InputsChannel::handle_ping, sizeof(SpiceMsgPing));
handler->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &InputsChannel::handle_wait_for_channels,
sizeof(SpiceMsgWaitForChannels));
handler->set_handler(SPICE_MSG_DISCONNECTING, &InputsChannel::handle_disconnect,
sizeof(SpiceMsgDisconnect));
handler->set_handler(SPICE_MSG_NOTIFY, &InputsChannel::handle_notify, sizeof(SpiceMsgNotify));
handler->set_handler(SPICE_MSG_MIGRATE, &InputsChannel::handle_migrate);
handler->set_handler(SPICE_MSG_SET_ACK, &InputsChannel::handle_set_ack);
handler->set_handler(SPICE_MSG_PING, &InputsChannel::handle_ping);
handler->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &InputsChannel::handle_wait_for_channels);
handler->set_handler(SPICE_MSG_DISCONNECTING, &InputsChannel::handle_disconnect);
handler->set_handler(SPICE_MSG_NOTIFY, &InputsChannel::handle_notify);
handler->set_handler(SPICE_MSG_INPUTS_INIT, &InputsChannel::handle_init, sizeof(SpiceMsgInputsInit));
handler->set_handler(SPICE_MSG_INPUTS_KEY_MODIFIERS, &InputsChannel::handle_modifaiers,
sizeof(SpiceMsgInputsKeyModifiers));
handler->set_handler(SPICE_MSG_INPUTS_MOUSE_MOTION_ACK, &InputsChannel::handle_motion_ack, 0);
handler->set_handler(SPICE_MSG_INPUTS_INIT, &InputsChannel::handle_init);
handler->set_handler(SPICE_MSG_INPUTS_KEY_MODIFIERS, &InputsChannel::handle_modifaiers);
handler->set_handler(SPICE_MSG_INPUTS_MOUSE_MOTION_ACK, &InputsChannel::handle_motion_ack);
}
InputsChannel::~InputsChannel()

View File

@ -137,10 +137,10 @@ static void end_wave()
#endif
class PlaybackHandler: public MessageHandlerImp<PlaybackChannel, SPICE_MSG_END_PLAYBACK> {
class PlaybackHandler: public MessageHandlerImp<PlaybackChannel, SPICE_CHANNEL_PLAYBACK> {
public:
PlaybackHandler(PlaybackChannel& channel)
: MessageHandlerImp<PlaybackChannel, SPICE_MSG_END_PLAYBACK>(channel) {}
: MessageHandlerImp<PlaybackChannel, SPICE_CHANNEL_PLAYBACK>(channel) {}
};
PlaybackChannel::PlaybackChannel(RedClient& client, uint32_t id)
@ -157,17 +157,14 @@ PlaybackChannel::PlaybackChannel(RedClient& client, uint32_t id)
#endif
PlaybackHandler* handler = static_cast<PlaybackHandler*>(get_message_handler());
handler->set_handler(SPICE_MSG_MIGRATE, &PlaybackChannel::handle_migrate, 0);
handler->set_handler(SPICE_MSG_SET_ACK, &PlaybackChannel::handle_set_ack, sizeof(SpiceMsgSetAck));
handler->set_handler(SPICE_MSG_PING, &PlaybackChannel::handle_ping, sizeof(SpiceMsgPing));
handler->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &PlaybackChannel::handle_wait_for_channels,
sizeof(SpiceMsgWaitForChannels));
handler->set_handler(SPICE_MSG_DISCONNECTING, &PlaybackChannel::handle_disconnect,
sizeof(SpiceMsgDisconnect));
handler->set_handler(SPICE_MSG_NOTIFY, &PlaybackChannel::handle_notify, sizeof(SpiceMsgNotify));
handler->set_handler(SPICE_MSG_MIGRATE, &PlaybackChannel::handle_migrate);
handler->set_handler(SPICE_MSG_SET_ACK, &PlaybackChannel::handle_set_ack);
handler->set_handler(SPICE_MSG_PING, &PlaybackChannel::handle_ping);
handler->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &PlaybackChannel::handle_wait_for_channels);
handler->set_handler(SPICE_MSG_DISCONNECTING, &PlaybackChannel::handle_disconnect);
handler->set_handler(SPICE_MSG_NOTIFY, &PlaybackChannel::handle_notify);
handler->set_handler(SPICE_MSG_PLAYBACK_MODE, &PlaybackChannel::handle_mode,
sizeof(SpiceMsgPlaybackMode));
handler->set_handler(SPICE_MSG_PLAYBACK_MODE, &PlaybackChannel::handle_mode);
set_capability(SPICE_PLAYBACK_CAP_CELT_0_5_1);
}
@ -195,9 +192,9 @@ void PlaybackChannel::set_data_handler()
PlaybackHandler* handler = static_cast<PlaybackHandler*>(get_message_handler());
if (_mode == SPICE_AUDIO_DATA_MODE_RAW) {
handler->set_handler(SPICE_MSG_PLAYBACK_DATA, &PlaybackChannel::handle_raw_data, 0);
handler->set_handler(SPICE_MSG_PLAYBACK_DATA, &PlaybackChannel::handle_raw_data);
} else if (_mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1) {
handler->set_handler(SPICE_MSG_PLAYBACK_DATA, &PlaybackChannel::handle_celt_data, 0);
handler->set_handler(SPICE_MSG_PLAYBACK_DATA, &PlaybackChannel::handle_celt_data);
} else {
THROW("invalid mode");
}
@ -218,8 +215,7 @@ void PlaybackChannel::handle_mode(RedPeer::InMessage* message)
}
PlaybackHandler* handler = static_cast<PlaybackHandler*>(get_message_handler());
handler->set_handler(SPICE_MSG_PLAYBACK_START, &PlaybackChannel::handle_start,
sizeof(SpiceMsgPlaybackStart));
handler->set_handler(SPICE_MSG_PLAYBACK_START, &PlaybackChannel::handle_start);
}
void PlaybackChannel::null_handler(RedPeer::InMessage* message)
@ -230,10 +226,10 @@ void PlaybackChannel::disable()
{
PlaybackHandler* handler = static_cast<PlaybackHandler*>(get_message_handler());
handler->set_handler(SPICE_MSG_PLAYBACK_START, &PlaybackChannel::null_handler, 0);
handler->set_handler(SPICE_MSG_PLAYBACK_STOP, &PlaybackChannel::null_handler, 0);
handler->set_handler(SPICE_MSG_PLAYBACK_MODE, &PlaybackChannel::null_handler, 0);
handler->set_handler(SPICE_MSG_PLAYBACK_DATA, &PlaybackChannel::null_handler, 0);
handler->set_handler(SPICE_MSG_PLAYBACK_START, &PlaybackChannel::null_handler);
handler->set_handler(SPICE_MSG_PLAYBACK_STOP, &PlaybackChannel::null_handler);
handler->set_handler(SPICE_MSG_PLAYBACK_MODE, &PlaybackChannel::null_handler);
handler->set_handler(SPICE_MSG_PLAYBACK_DATA, &PlaybackChannel::null_handler);
}
void PlaybackChannel::handle_start(RedPeer::InMessage* message)
@ -241,8 +237,8 @@ void PlaybackChannel::handle_start(RedPeer::InMessage* message)
PlaybackHandler* handler = static_cast<PlaybackHandler*>(get_message_handler());
SpiceMsgPlaybackStart* start = (SpiceMsgPlaybackStart*)message->data();
handler->set_handler(SPICE_MSG_PLAYBACK_START, NULL, 0);
handler->set_handler(SPICE_MSG_PLAYBACK_STOP, &PlaybackChannel::handle_stop, 0);
handler->set_handler(SPICE_MSG_PLAYBACK_START, NULL);
handler->set_handler(SPICE_MSG_PLAYBACK_STOP, &PlaybackChannel::handle_stop);
#ifdef WAVE_CAPTURE
start_wave();
@ -285,10 +281,9 @@ void PlaybackChannel::handle_stop(RedPeer::InMessage* message)
{
PlaybackHandler* handler = static_cast<PlaybackHandler*>(get_message_handler());
handler->set_handler(SPICE_MSG_PLAYBACK_STOP, NULL, 0);
handler->set_handler(SPICE_MSG_PLAYBACK_DATA, NULL, 0);
handler->set_handler(SPICE_MSG_PLAYBACK_START, &PlaybackChannel::handle_start,
sizeof(SpiceMsgPlaybackStart));
handler->set_handler(SPICE_MSG_PLAYBACK_STOP, NULL);
handler->set_handler(SPICE_MSG_PLAYBACK_DATA, NULL);
handler->set_handler(SPICE_MSG_PLAYBACK_START, &PlaybackChannel::handle_start);
#ifdef WAVE_CAPTURE
end_wave();

View File

@ -59,10 +59,10 @@ void RecordSamplesMessage::release()
int RecordChannel::data_mode = SPICE_AUDIO_DATA_MODE_CELT_0_5_1;
class RecordHandler: public MessageHandlerImp<RecordChannel, SPICE_MSGC_END_RECORD> {
class RecordHandler: public MessageHandlerImp<RecordChannel, SPICE_CHANNEL_RECORD> {
public:
RecordHandler(RecordChannel& channel)
: MessageHandlerImp<RecordChannel, SPICE_MSGC_END_RECORD>(channel) {}
: MessageHandlerImp<RecordChannel, SPICE_CHANNEL_RECORD>(channel) {}
};
RecordChannel::RecordChannel(RedClient& client, uint32_t id)
@ -78,16 +78,14 @@ RecordChannel::RecordChannel(RedClient& client, uint32_t id)
RecordHandler* handler = static_cast<RecordHandler*>(get_message_handler());
handler->set_handler(SPICE_MSG_MIGRATE, &RecordChannel::handle_migrate, 0);
handler->set_handler(SPICE_MSG_SET_ACK, &RecordChannel::handle_set_ack, sizeof(SpiceMsgSetAck));
handler->set_handler(SPICE_MSG_PING, &RecordChannel::handle_ping, sizeof(SpiceMsgPing));
handler->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &RecordChannel::handle_wait_for_channels,
sizeof(SpiceMsgWaitForChannels));
handler->set_handler(SPICE_MSG_DISCONNECTING, &RecordChannel::handle_disconnect,
sizeof(SpiceMsgDisconnect));
handler->set_handler(SPICE_MSG_NOTIFY, &RecordChannel::handle_notify, sizeof(SpiceMsgNotify));
handler->set_handler(SPICE_MSG_MIGRATE, &RecordChannel::handle_migrate);
handler->set_handler(SPICE_MSG_SET_ACK, &RecordChannel::handle_set_ack);
handler->set_handler(SPICE_MSG_PING, &RecordChannel::handle_ping);
handler->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &RecordChannel::handle_wait_for_channels);
handler->set_handler(SPICE_MSG_DISCONNECTING, &RecordChannel::handle_disconnect);
handler->set_handler(SPICE_MSG_NOTIFY, &RecordChannel::handle_notify);
handler->set_handler(SPICE_MSG_RECORD_START, &RecordChannel::handle_start, sizeof(SpiceMsgRecordStart));
handler->set_handler(SPICE_MSG_RECORD_START, &RecordChannel::handle_start);
set_capability(SPICE_RECORD_CAP_CELT_0_5_1);
}
@ -138,8 +136,8 @@ void RecordChannel::handle_start(RedPeer::InMessage* message)
RecordHandler* handler = static_cast<RecordHandler*>(get_message_handler());
SpiceMsgRecordStart* start = (SpiceMsgRecordStart*)message->data();
handler->set_handler(SPICE_MSG_RECORD_START, NULL, 0);
handler->set_handler(SPICE_MSG_RECORD_STOP, &RecordChannel::handle_stop, 0);
handler->set_handler(SPICE_MSG_RECORD_START, NULL);
handler->set_handler(SPICE_MSG_RECORD_STOP, &RecordChannel::handle_stop);
ASSERT(!_wave_recorder && !_celt_mode && !_celt_encoder);
// for now support only one setting
@ -176,8 +174,8 @@ void RecordChannel::handle_start(RedPeer::InMessage* message)
void RecordChannel::handle_stop(RedPeer::InMessage* message)
{
RecordHandler* handler = static_cast<RecordHandler*>(get_message_handler());
handler->set_handler(SPICE_MSG_RECORD_START, &RecordChannel::handle_start, sizeof(SpiceMsgRecordStart));
handler->set_handler(SPICE_MSG_RECORD_STOP, NULL, 0);
handler->set_handler(SPICE_MSG_RECORD_START, &RecordChannel::handle_start);
handler->set_handler(SPICE_MSG_RECORD_STOP, NULL);
if (!_wave_recorder) {
return;
}

View File

@ -24,6 +24,7 @@
#include "red_peer.h"
#include "platform.h"
#include "process_loop.h"
#include "demarshallers.h"
enum {
PASSIVE_STATE,
@ -230,67 +231,83 @@ public:
};
template <class HandlerClass, unsigned int end_message>
template <class HandlerClass, unsigned int channel_id>
class MessageHandlerImp: public RedChannel::MessageHandler {
public:
MessageHandlerImp(HandlerClass& obj);
virtual ~MessageHandlerImp() {}
~MessageHandlerImp() { delete [] _handlers; };
virtual void handle_message(RedPeer::CompundInMessage& message);
typedef void (HandlerClass::*Handler)(RedPeer::InMessage* message);
void set_handler(unsigned int id, Handler handler, size_t mess_size);
void set_handler(unsigned int id, Handler handler);
private:
HandlerClass& _obj;
struct HandlerInfo {
Handler handler;
size_t mess_size;
};
HandlerInfo _handlers[end_message];
unsigned int _max_messages;
spice_parse_channel_func_t _parser;
Handler *_handlers;
};
template <class HandlerClass, unsigned int end_message>
MessageHandlerImp<HandlerClass, end_message>::MessageHandlerImp(HandlerClass& obj)
template <class HandlerClass, unsigned int channel_id>
MessageHandlerImp<HandlerClass, channel_id>::MessageHandlerImp(HandlerClass& obj)
: _obj (obj)
{
memset(_handlers, 0, sizeof(_handlers));
_parser = spice_get_server_channel_parser(channel_id, &_max_messages);
_handlers = new Handler[_max_messages + 1];
memset(_handlers, 0, sizeof(Handler) * (_max_messages + 1));
}
template <class HandlerClass, unsigned int end_message>
void MessageHandlerImp<HandlerClass, end_message>::handle_message(RedPeer::CompundInMessage&
message)
template <class HandlerClass, unsigned int channel_id>
void MessageHandlerImp<HandlerClass, channel_id>::handle_message(RedPeer::CompundInMessage&
message)
{
if (message.type() >= end_message || !_handlers[message.type()].handler) {
THROW("bad message type %d", message.type());
}
if (message.size() < _handlers[message.type()].mess_size) {
THROW("bad message size, type %d size %d expected %d",
message.type(),
message.size(),
_handlers[message.type()].mess_size);
}
uint8_t *msg;
uint8_t *parsed;
uint16_t type;
uint32_t size;
size_t parsed_size;
if (message.sub_list()) {
SpiceSubMessageList *sub_list;
sub_list = (SpiceSubMessageList *)(message.data() + message.sub_list());
for (int i = 0; i < sub_list->size; i++) {
SpicedSubMessage *sub = (SpicedSubMessage *)(message.data() + sub_list->sub_messages[i]);
//todo: test size
RedPeer::InMessage sub_message(sub->type, sub->size, (uint8_t *)(sub + 1));
(_obj.*_handlers[sub_message.type()].handler)(&sub_message);
msg = (uint8_t *)(sub + 1);
type = sub->type;
size = sub->size;
parsed = _parser(msg, msg + size, type, _obj.get_peer_minor(), &parsed_size);
if (parsed == NULL) {
THROW("failed to parse message type %d", type);
}
RedPeer::InMessage sub_message(type, parsed_size, parsed);
(_obj.*_handlers[type])(&sub_message);
free(parsed);
}
}
(_obj.*_handlers[message.type()].handler)(&message);
msg = message.data();
type = message.type();
size = message.size();
parsed = _parser(msg, msg + size, type, _obj.get_peer_minor(), &parsed_size);
RedPeer::InMessage main_message(type, parsed_size, parsed);
if (parsed == NULL) {
THROW("failed to parse message channel %d type %d", channel_id, type);
}
(_obj.*_handlers[type])(&main_message);
free(parsed);
}
template <class HandlerClass, unsigned int end_message>
void MessageHandlerImp<HandlerClass, end_message>::set_handler(unsigned int id, Handler handler,
size_t mess_size)
template <class HandlerClass, unsigned int channel_id>
void MessageHandlerImp<HandlerClass, channel_id>::set_handler(unsigned int id, Handler handler)
{
if (id >= end_message) {
if (id > _max_messages) {
THROW("bad handler id");
}
_handlers[id].handler = handler;
_handlers[id].mess_size = mess_size;
_handlers[id] = handler;
}
#endif

View File

@ -293,9 +293,9 @@ void AgentTimer::response(AbstractProcessLoop& events_loop)
THROW_ERR(SPICEC_ERROR_CODE_AGENT_TIMEOUT, "vdagent timeout");
}
class MainChannelLoop: public MessageHandlerImp<RedClient, SPICE_MSG_END_MAIN> {
class MainChannelLoop: public MessageHandlerImp<RedClient, SPICE_CHANNEL_MAIN> {
public:
MainChannelLoop(RedClient& client): MessageHandlerImp<RedClient, SPICE_MSG_END_MAIN>(client) {}
MainChannelLoop(RedClient& client): MessageHandlerImp<RedClient, SPICE_CHANNEL_MAIN>(client) {}
};
RedClient::RedClient(Application& application)
@ -320,35 +320,26 @@ RedClient::RedClient(Application& application)
{
MainChannelLoop* message_loop = static_cast<MainChannelLoop*>(get_message_handler());
message_loop->set_handler(SPICE_MSG_MIGRATE, &RedClient::handle_migrate, 0);
message_loop->set_handler(SPICE_MSG_SET_ACK, &RedClient::handle_set_ack, sizeof(SpiceMsgSetAck));
message_loop->set_handler(SPICE_MSG_PING, &RedClient::handle_ping, sizeof(SpiceMsgPing));
message_loop->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &RedClient::handle_wait_for_channels,
sizeof(SpiceMsgWaitForChannels));
message_loop->set_handler(SPICE_MSG_DISCONNECTING, &RedClient::handle_disconnect,
sizeof(SpiceMsgDisconnect));
message_loop->set_handler(SPICE_MSG_NOTIFY, &RedClient::handle_notify, sizeof(SpiceMsgNotify));
message_loop->set_handler(SPICE_MSG_MIGRATE, &RedClient::handle_migrate);
message_loop->set_handler(SPICE_MSG_SET_ACK, &RedClient::handle_set_ack);
message_loop->set_handler(SPICE_MSG_PING, &RedClient::handle_ping);
message_loop->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &RedClient::handle_wait_for_channels);
message_loop->set_handler(SPICE_MSG_DISCONNECTING, &RedClient::handle_disconnect);
message_loop->set_handler(SPICE_MSG_NOTIFY, &RedClient::handle_notify);
message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_BEGIN, &RedClient::handle_migrate_begin,
sizeof(SpiceMsgMainMigrationBegin));
message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_CANCEL, &RedClient::handle_migrate_cancel, 0);
message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_BEGIN, &RedClient::handle_migrate_begin);
message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_CANCEL, &RedClient::handle_migrate_cancel);
message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST,
&RedClient::handle_migrate_switch_host,
sizeof(SpiceMsgMainMigrationSwitchHost));
message_loop->set_handler(SPICE_MSG_MAIN_INIT, &RedClient::handle_init, sizeof(SpiceMsgMainInit));
message_loop->set_handler(SPICE_MSG_MAIN_CHANNELS_LIST, &RedClient::handle_channels,
sizeof(SpiceMsgChannels));
message_loop->set_handler(SPICE_MSG_MAIN_MOUSE_MODE, &RedClient::handle_mouse_mode,
sizeof(SpiceMsgMainMouseMode));
message_loop->set_handler(SPICE_MSG_MAIN_MULTI_MEDIA_TIME, &RedClient::handle_mm_time,
sizeof(SpiceMsgMainMultiMediaTime));
&RedClient::handle_migrate_switch_host);
message_loop->set_handler(SPICE_MSG_MAIN_INIT, &RedClient::handle_init);
message_loop->set_handler(SPICE_MSG_MAIN_CHANNELS_LIST, &RedClient::handle_channels);
message_loop->set_handler(SPICE_MSG_MAIN_MOUSE_MODE, &RedClient::handle_mouse_mode);
message_loop->set_handler(SPICE_MSG_MAIN_MULTI_MEDIA_TIME, &RedClient::handle_mm_time);
message_loop->set_handler(SPICE_MSG_MAIN_AGENT_CONNECTED, &RedClient::handle_agent_connected, 0);
message_loop->set_handler(SPICE_MSG_MAIN_AGENT_DISCONNECTED, &RedClient::handle_agent_disconnected,
sizeof(SpiceMsgMainAgentDisconnect));
message_loop->set_handler(SPICE_MSG_MAIN_AGENT_DATA, &RedClient::handle_agent_data, 0);
message_loop->set_handler(SPICE_MSG_MAIN_AGENT_TOKEN, &RedClient::handle_agent_tokens,
sizeof(SpiceMsgMainAgentTokens));
message_loop->set_handler(SPICE_MSG_MAIN_AGENT_CONNECTED, &RedClient::handle_agent_connected);
message_loop->set_handler(SPICE_MSG_MAIN_AGENT_DISCONNECTED, &RedClient::handle_agent_disconnected);
message_loop->set_handler(SPICE_MSG_MAIN_AGENT_DATA, &RedClient::handle_agent_data);
message_loop->set_handler(SPICE_MSG_MAIN_AGENT_TOKEN, &RedClient::handle_agent_tokens);
start();
}

View File

@ -219,10 +219,10 @@ TunnelChannel::TunnelSocket::TunnelSocket(uint16_t id, TunnelService& dst_servic
{
}
class TunnelHandler: public MessageHandlerImp<TunnelChannel, SPICE_MSG_END_TUNNEL> {
class TunnelHandler: public MessageHandlerImp<TunnelChannel, SPICE_CHANNEL_TUNNEL> {
public:
TunnelHandler(TunnelChannel& channel)
: MessageHandlerImp<TunnelChannel, SPICE_MSG_END_TUNNEL>(channel) {}
: MessageHandlerImp<TunnelChannel, SPICE_CHANNEL_TUNNEL>(channel) {}
};
TunnelChannel::TunnelChannel(RedClient& client, uint32_t id)
@ -236,29 +236,27 @@ TunnelChannel::TunnelChannel(RedClient& client, uint32_t id)
{
TunnelHandler* handler = static_cast<TunnelHandler*>(get_message_handler());
handler->set_handler(SPICE_MSG_MIGRATE, &TunnelChannel::handle_migrate, 0);
handler->set_handler(SPICE_MSG_SET_ACK, &TunnelChannel::handle_set_ack, sizeof(SpiceMsgSetAck));
handler->set_handler(SPICE_MSG_PING, &TunnelChannel::handle_ping, sizeof(SpiceMsgPing));
handler->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &TunnelChannel::handle_wait_for_channels,
sizeof(SpiceMsgWaitForChannels));
handler->set_handler(SPICE_MSG_MIGRATE, &TunnelChannel::handle_migrate);
handler->set_handler(SPICE_MSG_SET_ACK, &TunnelChannel::handle_set_ack);
handler->set_handler(SPICE_MSG_PING, &TunnelChannel::handle_ping);
handler->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &TunnelChannel::handle_wait_for_channels);
handler->set_handler(SPICE_MSG_TUNNEL_INIT,
&TunnelChannel::handle_init, sizeof(SpiceMsgTunnelInit));
&TunnelChannel::handle_init);
handler->set_handler(SPICE_MSG_TUNNEL_SERVICE_IP_MAP,
&TunnelChannel::handle_service_ip_map, sizeof(SpiceMsgTunnelServiceIpMap));
&TunnelChannel::handle_service_ip_map);
handler->set_handler(SPICE_MSG_TUNNEL_SOCKET_OPEN,
&TunnelChannel::handle_socket_open, sizeof(SpiceMsgTunnelSocketOpen));
&TunnelChannel::handle_socket_open);
handler->set_handler(SPICE_MSG_TUNNEL_SOCKET_CLOSE,
&TunnelChannel::handle_socket_close, sizeof(SpiceMsgTunnelSocketClose));
&TunnelChannel::handle_socket_close);
handler->set_handler(SPICE_MSG_TUNNEL_SOCKET_FIN,
&TunnelChannel::handle_socket_fin, sizeof(SpiceMsgTunnelSocketFin));
&TunnelChannel::handle_socket_fin);
handler->set_handler(SPICE_MSG_TUNNEL_SOCKET_TOKEN,
&TunnelChannel::handle_socket_token, sizeof(SpiceMsgTunnelSocketTokens));
&TunnelChannel::handle_socket_token);
handler->set_handler(SPICE_MSG_TUNNEL_SOCKET_CLOSED_ACK,
&TunnelChannel::handle_socket_closed_ack,
sizeof(SpiceMsgTunnelSocketClosedAck));
&TunnelChannel::handle_socket_closed_ack);
handler->set_handler(SPICE_MSG_TUNNEL_SOCKET_DATA,
&TunnelChannel::handle_socket_data, sizeof(SpiceMsgTunnelSocketData));
&TunnelChannel::handle_socket_data);
}
TunnelChannel::~TunnelChannel()

View File

@ -43,7 +43,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".;..;..\..\common;..\..\..\spice-protocol;..\..\common\win;&quot;..\..\common\win\my_getopt-1.5&quot;;&quot;$(SPICE_LIBS)\include&quot;;&quot;$(SPICE_LIBS)\include\pixman-1&quot;;&quot;$(SPICE_LIBS)\include\CEGUI-0.6.2&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;SW_CANVAS_ACCESS_TEST;SW_CANVAS_CACHE;RED_DEBUG;SW_CANVAS_NO_CHUNKS;_WIN32_WINNT=0x0500;LOG4CPLUS_STATIC;USE_GLZ;PTW32_STATIC_LIB;CEGUI_STATIC"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;SW_CANVAS_CACHE;RED_DEBUG;SW_CANVAS_NO_CHUNKS;_WIN32_WINNT=0x0500;LOG4CPLUS_STATIC;USE_GLZ;PTW32_STATIC_LIB;CEGUI_STATIC"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@ -125,7 +125,7 @@
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=".;..;..\..\..\spice-protocol;..\..\common;..\..\common\win;&quot;..\..\common\win\my_getopt-1.5&quot;;&quot;$(SPICE_LIBS)\include&quot;;&quot;$(SPICE_LIBS)\include\pixman-1&quot;;&quot;$(SPICE_LIBS)\include\CEGUI-0.6.2&quot;"
PreprocessorDefinitions="WIN32;_WINDOWS;SW_CANVAS_ACCESS_TEST;SW_CANVAS_CACHE;SW_CANVAS_NO_CHUNKS;_WIN32_WINNT=0x0500;LOG4CPLUS_STATIC;USE_GLZ;PTW32_STATIC_LIB;CEGUI_STATIC"
PreprocessorDefinitions="WIN32;_WINDOWS;SW_CANVAS_CACHE;SW_CANVAS_NO_CHUNKS;_WIN32_WINNT=0x0500;LOG4CPLUS_STATIC;USE_GLZ;PTW32_STATIC_LIB;CEGUI_STATIC"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"

View File

@ -6,7 +6,6 @@ CLIENT_DIR=$(top_srcdir)/client
SUBDIRS = images
INCLUDES = \
-DSW_CANVAS_ACCESS_TEST \
-DSW_CANVAS_CACHE \
-DSW_CANVAS_NO_CHUNKS \
-DUSE_GLZ \
@ -38,6 +37,8 @@ RED_COMMON_SRCS = \
$(CLIENT_DIR)/audio_channels.h \
$(CLIENT_DIR)/audio_devices.h \
$(CLIENT_DIR)/cache.hpp \
$(CLIENT_DIR)/demarshallers.h \
$(CLIENT_DIR)/generated_demarshallers.cpp \
$(CLIENT_DIR)/sw_canvas.cpp \
$(CLIENT_DIR)/canvas.cpp \
$(CLIENT_DIR)/canvas.h \

View File

@ -43,16 +43,6 @@
}
#endif
#ifdef SW_CANVAS_ACCESS_TEST
#define access_test(cancas, ptr, size) \
if ((unsigned long)(ptr) < (cancas)->base || \
(unsigned long)(ptr) + (size) > (cancas)->max) { \
CANVAS_ERROR("access violation 0x%lx %lu", (unsigned long)ptr, (unsigned long)(size)); \
}
#else
#define access_test(cancas, base, size)
#endif
#ifndef ASSERT
#define ASSERT(x) if (!(x)) { \
printf("%s: ASSERT %s failed\n", __FUNCTION__, #x); \
@ -175,10 +165,6 @@ typedef struct CanvasBase {
uint32_t color_shift;
uint32_t color_mask;
QuicData quic_data;
#ifdef SW_CANVAS_ACCESS_TEST
unsigned long base;
unsigned long max;
#endif
uint32_t format;
int width;
@ -630,7 +616,6 @@ static pixman_image_t *canvas_bitmap_to_surface(CanvasBase *canvas, SpiceBitmap*
src = (uint8_t *)SPICE_GET_ADDRESS(bitmap->data);
src_stride = bitmap->stride;
access_test(canvas, src, bitmap->y * src_stride);
if (want_original) {
format = spice_bitmap_format_to_pixman(bitmap->format, canvas->format);
@ -672,8 +657,6 @@ static inline SpicePalette *canvas_get_palette(CanvasBase *canvas, SPICE_ADDRESS
palette = canvas->palette_cache->ops->get(canvas->palette_cache, base_palette);
} else if (flags & SPICE_BITMAP_FLAGS_PAL_CACHE_ME) {
palette = (SpicePalette *)SPICE_GET_ADDRESS(base_palette);
access_test(canvas, palette, sizeof(SpicePalette));
access_test(canvas, palette, sizeof(SpicePalette) + palette->num_ents * sizeof(uint32_t));
canvas->palette_cache->ops->put(canvas->palette_cache, palette);
} else {
palette = (SpicePalette *)SPICE_GET_ADDRESS(base_palette);
@ -990,11 +973,9 @@ static void dump_surface(pixman_image_t *surface, int cache)
static SpiceCanvas *canvas_get_surface_internal(CanvasBase *canvas, SPICE_ADDRESS addr)
{
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
access_test(canvas, descriptor, sizeof(SpiceImageDescriptor));
if (descriptor->type == SPICE_IMAGE_TYPE_SURFACE) {
SpiceSurfaceImage *surface = (SpiceSurfaceImage *)descriptor;
access_test(canvas, descriptor, sizeof(SpiceSurfaceImage));
return canvas->surfaces->ops->get(canvas->surfaces, surface->surface.surface_id);
}
return NULL;
@ -1005,11 +986,9 @@ static SpiceCanvas *canvas_get_surface_mask_internal(CanvasBase *canvas, SPICE_A
SpiceImageDescriptor *descriptor;
descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
access_test(canvas, descriptor, sizeof(SpiceImageDescriptor));
if (descriptor->type == SPICE_IMAGE_TYPE_SURFACE) {
SpiceSurfaceImage *surface = (SpiceSurfaceImage *)descriptor;
access_test(canvas, descriptor, sizeof(SpiceSurfaceImage));
return canvas->surfaces->ops->get(canvas->surfaces, surface->surface.surface_id);
}
return NULL;
@ -1034,7 +1013,6 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE
pixman_image_t *surface, *converted;
pixman_format_code_t wanted_format, surface_format;
int saved_want_original;
access_test(canvas, descriptor, sizeof(SpiceImageDescriptor));
#ifdef DEBUG_LZ
LOG_DEBUG("canvas_get_image image type: " << (int)descriptor->type);
#endif
@ -1063,19 +1041,16 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE
switch (descriptor->type) {
case SPICE_IMAGE_TYPE_QUIC: {
SpiceQUICImage *image = (SpiceQUICImage *)descriptor;
access_test(canvas, descriptor, sizeof(SpiceQUICImage));
surface = canvas_get_quic(canvas, image, 0, want_original);
break;
}
#ifdef SW_CANVAS_NO_CHUNKS
case SPICE_IMAGE_TYPE_LZ_PLT: {
access_test(canvas, descriptor, sizeof(SpiceLZPLTImage));
LZImage *image = (LZImage *)descriptor;
surface = canvas_get_lz(canvas, image, 0, want_original);
break;
}
case SPICE_IMAGE_TYPE_LZ_RGB: {
access_test(canvas, descriptor, sizeof(SpiceLZRGBImage));
LZImage *image = (LZImage *)descriptor;
surface = canvas_get_lz(canvas, image, 0, want_original);
break;
@ -1083,13 +1058,11 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE
#endif
case SPICE_IMAGE_TYPE_JPEG: {
SpiceJPEGImage *image = (SpiceJPEGImage *)descriptor;
access_test(canvas, descriptor, sizeof(SpiceJPEGImage));
surface = canvas_get_jpeg(canvas, image, 0);
break;
}
#if defined(SW_CANVAS_CACHE)
case SPICE_IMAGE_TYPE_GLZ_RGB: {
access_test(canvas, descriptor, sizeof(SpiceLZRGBImage));
LZImage *image = (LZImage *)descriptor;
surface = canvas_get_glz(canvas, image, want_original);
break;
@ -1106,7 +1079,6 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE
#endif
case SPICE_IMAGE_TYPE_BITMAP: {
SpiceBitmapImage *bitmap = (SpiceBitmapImage *)descriptor;
access_test(canvas, descriptor, sizeof(SpiceBitmapImage));
surface = canvas_get_bits(canvas, &bitmap->bitmap, want_original);
break;
}
@ -1213,8 +1185,6 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
pixman_format_code_t format;
access_test(canvas, descriptor, sizeof(SpiceImageDescriptor));
/* When touching, never load image. */
if (!real_get) {
return NULL;
@ -1223,12 +1193,10 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE
switch (descriptor->type) {
case SPICE_IMAGE_TYPE_QUIC: {
SpiceQUICImage *image = (SpiceQUICImage *)descriptor;
access_test(canvas, descriptor, sizeof(SpiceQUICImage));
return canvas_get_quic(canvas, image, 0);
}
case SPICE_IMAGE_TYPE_BITMAP: {
SpiceBitmapImage *bitmap = (SpiceBitmapImage *)descriptor;
access_test(canvas, descriptor, sizeof(SpiceBitmapImage));
return canvas_get_bits(canvas, &bitmap->bitmap, want_original, &format);
}
default:
@ -1323,7 +1291,6 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b
src_line = (uint8_t *)SPICE_GET_ADDRESS(bitmap->data);
src_stride = bitmap->stride;
end_line = src_line + (bitmap->y * src_stride);
access_test(canvas, src_line, end_line - src_line);
line_size = SPICE_ALIGN(bitmap->x, 8) >> 3;
dest_stride = pixman_image_get_stride(surface);
@ -1455,7 +1422,6 @@ static pixman_image_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask, int
}
descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(mask->bitmap);
access_test(canvas, descriptor, sizeof(SpiceImageDescriptor));
need_invers = mask->flags & SPICE_MASK_FLAGS_INVERS;
#ifdef SW_CANVAS_CACHE
@ -1467,7 +1433,6 @@ static pixman_image_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask, int
switch (descriptor->type) {
case SPICE_IMAGE_TYPE_BITMAP: {
SpiceBitmapImage *bitmap = (SpiceBitmapImage *)descriptor;
access_test(canvas, descriptor, sizeof(SpiceBitmapImage));
is_invers = need_invers && !cache_me;
surface = canvas_get_bitmap_mask(canvas, &bitmap->bitmap, is_invers);
break;
@ -1668,18 +1633,14 @@ static pixman_image_t *canvas_get_str_mask(CanvasBase *canvas, SpiceString *str,
ASSERT(str->length > 0);
access_test(canvas, glyph, sizeof(SpiceRasterGlyph));
next_glyph = canvas_next_raster_glyph(glyph, bpp);
access_test(canvas, glyph, (uint8_t*)next_glyph - (uint8_t*)glyph);
canvas_raster_glyph_box(glyph, &bounds);
for (i = 1; i < str->length; i++) {
SpiceRect glyph_box;
glyph = next_glyph;
access_test(canvas, glyph, sizeof(SpiceRasterGlyph));
next_glyph = canvas_next_raster_glyph(glyph, bpp);
access_test(canvas, glyph, (uint8_t*)next_glyph - (uint8_t*)glyph);
canvas_raster_glyph_box(glyph, &glyph_box);
rect_union(&bounds, &glyph_box);
}
@ -1860,14 +1821,6 @@ static int quic_usr_more_lines(QuicUsrContext *usr, uint8_t **lines)
return 0;
}
#ifdef SW_CANVAS_ACCESS_TEST
static void __canvas_set_access_params(CanvasBase *canvas, unsigned long base, unsigned long max)
{
canvas->base = base;
canvas->max = max;
}
#endif
static void canvas_base_destroy(CanvasBase *canvas)
{
quic_destroy(canvas->quic_data.quic);
@ -1920,10 +1873,8 @@ static void canvas_clip_pixman(CanvasBase *canvas,
break;
case SPICE_CLIP_TYPE_RECTS: {
uint32_t *n = (uint32_t *)SPICE_GET_ADDRESS(clip->data);
access_test(canvas, n, sizeof(uint32_t));
SpiceRect *now = (SpiceRect *)(n + 1);
access_test(canvas, now, (unsigned long)(now + *n) - (unsigned long)now);
pixman_region32_t clip;
@ -3073,7 +3024,6 @@ static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
gc.base.lineStyle = LineOnOffDash;
gc.base.dash = (unsigned char *)spice_malloc(nseg);
gc.base.numInDashList = nseg;
access_test(canvas, style, nseg * sizeof(*style));
if (stroke->attr.flags & SPICE_LINE_FLAGS_START_WITH_GAP) {
gc.base.dash[stroke->attr.style_nseg - 1] = fix_to_int(style[0]);
@ -3118,19 +3068,15 @@ static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
}
data_size = (uint32_t*)SPICE_GET_ADDRESS(stroke->path);
access_test(canvas, data_size, sizeof(uint32_t));
more = *data_size;
seg = (SpicePathSeg*)(data_size + 1);
stroke_lines_init(&lines);
do {
access_test(canvas, seg, sizeof(SpicePathSeg));
uint32_t flags = seg->flags;
SpicePointFix* point = (SpicePointFix*)seg->data;
SpicePointFix* end_point = point + seg->count;
access_test(canvas, point, (unsigned long)end_point - (unsigned long)point);
ASSERT(point < end_point);
more -= ((unsigned long)end_point - (unsigned long)seg);
seg = (SpicePathSeg*)end_point;

View File

@ -142,7 +142,6 @@ typedef struct {
void (*read_bits)(SpiceCanvas *canvas, uint8_t *dest, int dest_stride, const SpiceRect *area);
void (*group_start)(SpiceCanvas *canvas, QRegion *region);
void (*group_end)(SpiceCanvas *canvas);
void (*set_access_params)(SpiceCanvas *canvas, unsigned long base, unsigned long max);
void (*destroy)(SpiceCanvas *canvas);
/* Implementation vfuncs */

View File

@ -311,18 +311,14 @@ uint32_t raster_ops[] = {
static void set_path(GdiCanvas *canvas, void *addr)
{
uint32_t* data_size = (uint32_t*)addr;
access_test(&canvas->base, data_size, sizeof(uint32_t));
uint32_t more = *data_size;
SpicePathSeg* seg = (SpicePathSeg*)(data_size + 1);
do {
access_test(&canvas->base, seg, sizeof(SpicePathSeg));
uint32_t flags = seg->flags;
SpicePointFix* point = (SpicePointFix*)seg->data;
SpicePointFix* end_point = point + seg->count;
access_test(&canvas->base, point, (unsigned long)end_point - (unsigned long)point);
ASSERT(point < end_point);
more -= ((unsigned long)end_point - (unsigned long)seg);
seg = (SpicePathSeg*)end_point;
@ -399,11 +395,9 @@ static void set_clip(GdiCanvas *canvas, SpiceClip *clip)
break;
case SPICE_CLIP_TYPE_RECTS: {
uint32_t *n = (uint32_t *)SPICE_GET_ADDRESS(clip->data);
access_test(&canvas->base, n, sizeof(uint32_t));
SpiceRect *now = (SpiceRect *)(n + 1);
SpiceRect *end = now + *n;
access_test(&canvas->base, now, (unsigned long)end - (unsigned long)now);
if (now < end) {
HRGN main_hrgn;
@ -1643,8 +1637,6 @@ static uint32_t *gdi_get_userstyle(GdiCanvas *canvas, uint8_t nseg, SPICE_ADDRES
uint32_t *local_style;
int i;
access_test(&canvas->base, style, nseg * sizeof(*style));
if (nseg == 0) {
CANVAS_ERROR("bad nseg");
}
@ -1835,14 +1827,6 @@ static void gdi_canvas_clear(SpiceCanvas *spice_canvas)
{
}
static void gdi_canvas_set_access_params(SpiceCanvas *spice_canvas, unsigned long base, unsigned long max)
{
#ifdef SW_CANVAS_ACCESS_TEST
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
__canvas_set_access_params(&canvas->base, base, max);
#endif
}
static void gdi_canvas_destroy(SpiceCanvas *spice_canvas)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
@ -1915,7 +1899,6 @@ void gdi_canvas_init() //unsafe global function
gdi_canvas_ops.draw_alpha_blend = gdi_canvas_draw_alpha_blend;
gdi_canvas_ops.put_image = gdi_canvas_put_image;
gdi_canvas_ops.clear = gdi_canvas_clear;
gdi_canvas_ops.set_access_params = gdi_canvas_set_access_params;
gdi_canvas_ops.destroy = gdi_canvas_destroy;
rop3_init();

View File

@ -115,18 +115,14 @@ static GLCPath get_path(GLCanvas *canvas, void *addr)
{
GLCPath path = glc_path_create(canvas->glc);
uint32_t* data_size = (uint32_t*)addr;
access_test(&canvas->base, data_size, sizeof(uint32_t));
uint32_t more = *data_size;
SpicePathSeg* seg = (SpicePathSeg*)(data_size + 1);
do {
access_test(&canvas->base, seg, sizeof(SpicePathSeg));
uint32_t flags = seg->flags;
SpicePointFix* point = (SpicePointFix*)seg->data;
SpicePointFix* end_point = point + seg->count;
access_test(&canvas->base, point, (unsigned long)end_point - (unsigned long)point);
ASSERT(point < end_point);
more -= ((unsigned long)end_point - (unsigned long)seg);
seg = (SpicePathSeg*)end_point;
@ -183,10 +179,8 @@ static void set_clip(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip)
break;
case SPICE_CLIP_TYPE_RECTS: {
uint32_t *n = (uint32_t *)SPICE_GET_ADDRESS(clip->data);
access_test(&canvas->base, n, sizeof(uint32_t));
SpiceRect *now = (SpiceRect *)(n + 1);
SpiceRect *end = now + *n;
access_test(&canvas->base, now, (unsigned long)end - (unsigned long)now);
if (*n == 0) {
rect.x = rect.y = 0;
@ -810,14 +804,6 @@ static void gl_canvas_group_end(SpiceCanvas *spice_canvas)
glc_clear_mask(canvas->glc, GLC_MASK_B);
}
static void gl_canvas_set_access_params(SpiceCanvas *spice_canvas, unsigned long base, unsigned long max)
{
#ifdef SW_CANVAS_ACCESS_TEST
GLCanvas *canvas = (GLCanvas *)spice_canvas;
__canvas_set_access_params(&canvas->base, base, max);
#endif
}
static int need_init = 1;
static SpiceCanvasOps gl_canvas_ops;
@ -926,7 +912,6 @@ void gl_canvas_init() //unsafe global function
gl_canvas_ops.read_bits = gl_canvas_read_bits;
gl_canvas_ops.group_start = gl_canvas_group_start;
gl_canvas_ops.group_end = gl_canvas_group_end;
gl_canvas_ops.set_access_params = gl_canvas_set_access_params;
gl_canvas_ops.destroy = gl_canvas_destroy;
rop3_init();

View File

@ -1144,15 +1144,6 @@ static void canvas_clear(SpiceCanvas *spice_canvas)
0);
}
static void canvas_set_access_params(SpiceCanvas *spice_canvas,
unsigned long base, unsigned long max)
{
#ifdef SW_CANVAS_ACCESS_TEST
SwCanvas *canvas = (SwCanvas *)spice_canvas;
__canvas_set_access_params(&canvas->base, base, max);
#endif
}
static void canvas_destroy(SpiceCanvas *spice_canvas)
{
SwCanvas *canvas = (SwCanvas *)spice_canvas;
@ -1306,7 +1297,6 @@ void sw_canvas_init() //unsafe global function
sw_canvas_ops.put_image = canvas_put_image;
sw_canvas_ops.clear = canvas_clear;
sw_canvas_ops.read_bits = canvas_read_bits;
sw_canvas_ops.set_access_params = canvas_set_access_params;
sw_canvas_ops.destroy = canvas_destroy;
sw_canvas_ops.fill_solid_spans = fill_solid_spans;