mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-01-02 14:28:32 +00:00
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.
249 lines
7.7 KiB
C++
249 lines
7.7 KiB
C++
/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
/*
|
|
Copyright (C) 2009 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_DISPLAY_CHANNEL
|
|
#define _H_DISPLAY_CHANNEL
|
|
|
|
#include "common.h"
|
|
#include "canvas.h"
|
|
#include "region.h"
|
|
#include "red_channel.h"
|
|
#include "cache.hpp"
|
|
#include "screen_layer.h"
|
|
#include "process_loop.h"
|
|
#ifdef USE_OGL
|
|
#include "red_pixmap_gl.h"
|
|
#endif
|
|
#include "glz_decoder_window.h"
|
|
|
|
class RedScreen;
|
|
class ChannelFactory;
|
|
class VideoStream;
|
|
class DisplayChannel;
|
|
class CursorData;
|
|
class InputsChannel;
|
|
|
|
class StreamsTrigger: public EventSources::Trigger {
|
|
public:
|
|
StreamsTrigger(DisplayChannel& channel);
|
|
|
|
virtual void on_event();
|
|
|
|
private:
|
|
DisplayChannel& _channel;
|
|
};
|
|
|
|
#ifdef USE_OGL
|
|
class GLInterruptRecreate: public EventSources::Trigger {
|
|
public:
|
|
GLInterruptRecreate(DisplayChannel& channel);
|
|
virtual void trigger();
|
|
virtual void on_event();
|
|
|
|
private:
|
|
DisplayChannel& _channel;
|
|
Mutex _lock;
|
|
Condition _cond;
|
|
};
|
|
#endif
|
|
|
|
class InterruptUpdate: public EventSources::Trigger {
|
|
public:
|
|
InterruptUpdate(DisplayChannel& channel);
|
|
|
|
virtual void on_event();
|
|
|
|
private:
|
|
DisplayChannel& _channel;
|
|
};
|
|
|
|
class StreamsTimer: public Timer {
|
|
public:
|
|
StreamsTimer(DisplayChannel& channel);
|
|
virtual void response(AbstractProcessLoop& events_loop);
|
|
private:
|
|
DisplayChannel& _channel;
|
|
};
|
|
|
|
class DisplaySurfacesManger {
|
|
public:
|
|
void add_surface(int surface_id, SpiceCanvas *surface);
|
|
void del_surface(int surface_id);
|
|
void add_canvas(int surface_id, Canvas *canvas);
|
|
void del_canvas(int surface_id);
|
|
|
|
CSurfaces& get_surfaces();
|
|
bool is_present_canvas(int surface_id);
|
|
Canvas* get_canvas(int surface_id);
|
|
private:
|
|
CSurfaces surfaces;
|
|
CCanvases canvases;
|
|
};
|
|
|
|
class DisplayChannel: public RedChannel, public ScreenLayer {
|
|
public:
|
|
DisplayChannel(RedClient& client, uint32_t id,
|
|
PixmapCache& pixmap_cache, GlzDecoderWindow& glz_window);
|
|
virtual ~DisplayChannel();
|
|
|
|
virtual void copy_pixels(const QRegion& dest_region, RedDrawable& dest_dc);
|
|
virtual void copy_pixels(const QRegion& dest_region, const PixmapHeader &dest);
|
|
#ifdef USE_OGL
|
|
virtual void recreate_ogl_context();
|
|
virtual void recreate_ogl_context_interrupt();
|
|
virtual void pre_migrate();
|
|
virtual void post_migrate();
|
|
#endif
|
|
virtual void update_interrupt();
|
|
void set_cursor(CursorData* cursor);
|
|
void hide_cursor();
|
|
void set_capture_mode(bool on);
|
|
|
|
virtual bool pointer_test(int x, int y);
|
|
virtual void on_pointer_enter(int x, int y, unsigned int buttons_state);
|
|
virtual void on_pointer_motion(int x, int y, unsigned int buttons_state);
|
|
virtual void on_pointer_leave();
|
|
virtual void on_mouse_button_press(int button, int buttons_state);
|
|
virtual void on_mouse_button_release(int button, int buttons_state);
|
|
|
|
void attach_inputs(InputsChannel* inputs_channel);
|
|
void detach_inputs();
|
|
|
|
static ChannelFactory& Factory();
|
|
|
|
protected:
|
|
virtual void on_connect();
|
|
virtual void on_disconnect();
|
|
|
|
private:
|
|
void set_draw_handlers();
|
|
void clear_draw_handlers();
|
|
bool create_sw_canvas(int surface_id, int width, int height, uint32_t format);
|
|
#ifdef USE_OGL
|
|
bool create_ogl_canvas(int surface_id, int width, int height, uint32_t format, bool recreate,
|
|
RenderType rendertype);
|
|
#endif
|
|
#ifdef WIN32
|
|
bool create_gdi_canvas(int surface_id, int width, int height, uint32_t format);
|
|
#endif
|
|
void destroy_canvas(int surface_id);
|
|
void create_canvas(int surface_id, const std::vector<int>& canvas_type, int width, int height,
|
|
uint32_t format);
|
|
void destroy_strams();
|
|
void update_cursor();
|
|
|
|
void create_primary_surface(int width, int height, uint32_t format);
|
|
void create_surface(int surface_id, int width, int height, uint32_t format);
|
|
void destroy_primary_surface();
|
|
void destroy_surface(int surface_id);
|
|
|
|
void handle_mode(RedPeer::InMessage* message);
|
|
void handle_mark(RedPeer::InMessage* message);
|
|
void handle_reset(RedPeer::InMessage* message);
|
|
|
|
void handle_inval_list(RedPeer::InMessage* message);
|
|
void handle_inval_all_pixmaps(RedPeer::InMessage* message);
|
|
void handle_inval_palette(RedPeer::InMessage* message);
|
|
void handle_inval_all_palettes(RedPeer::InMessage* message);
|
|
void handle_copy_bits(RedPeer::InMessage* message);
|
|
void handle_stream_create(RedPeer::InMessage* message);
|
|
void handle_stream_data(RedPeer::InMessage* message);
|
|
void handle_stream_clip(RedPeer::InMessage* message);
|
|
void handle_stream_destroy(RedPeer::InMessage* message);
|
|
void handle_stream_destroy_all(RedPeer::InMessage* message);
|
|
|
|
void handle_surface_create(RedPeer::InMessage* message);
|
|
void handle_surface_destroy(RedPeer::InMessage* message);
|
|
|
|
void handle_draw_fill(RedPeer::InMessage* message);
|
|
void handle_draw_opaque(RedPeer::InMessage* message);
|
|
void handle_draw_copy(RedPeer::InMessage* message);
|
|
void handle_draw_blend(RedPeer::InMessage* message);
|
|
void handle_draw_blackness(RedPeer::InMessage* message);
|
|
void handle_draw_whiteness(RedPeer::InMessage* message);
|
|
void handle_draw_invers(RedPeer::InMessage* message);
|
|
void handle_draw_rop3(RedPeer::InMessage* message);
|
|
void handle_draw_stroke(RedPeer::InMessage* message);
|
|
void handle_draw_text(RedPeer::InMessage* message);
|
|
void handle_draw_transparent(RedPeer::InMessage* message);
|
|
void handle_draw_alpha_blend(RedPeer::InMessage* message);
|
|
|
|
void on_streams_trigger();
|
|
virtual void on_update_completion(uint64_t mark);
|
|
void streams_time();
|
|
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);
|
|
private:
|
|
DisplaySurfacesManger surfaces_mngr;
|
|
PixmapCache& _pixmap_cache;
|
|
PaletteCache _palette_cache;
|
|
GlzDecoderWindow& _glz_window;
|
|
bool _mark;
|
|
int _x_res;
|
|
int _y_res;
|
|
uint32_t _format;
|
|
#ifdef USE_OGL
|
|
RenderType _rendertype;
|
|
#endif
|
|
|
|
#ifndef RED64
|
|
Mutex _mark_lock;
|
|
#endif
|
|
uint64_t _update_mark;
|
|
Mutex _streams_lock;
|
|
|
|
Mutex _timer_lock;
|
|
AutoRef<StreamsTimer> _streams_timer;
|
|
uint32_t _next_timer_time;
|
|
|
|
AutoRef<CursorData> _cursor;
|
|
bool _cursor_visibal;
|
|
bool _active_pointer;
|
|
bool _capture_mouse_mode;
|
|
InputsChannel* _inputs_channel;
|
|
|
|
SpicePoint _pointer_pos;
|
|
int _buttons_state;
|
|
|
|
std::vector<VideoStream*> _streams;
|
|
VideoStream* _active_streams;
|
|
StreamsTrigger _streams_trigger;
|
|
#ifdef USE_OGL
|
|
GLInterruptRecreate _gl_interrupt_recreate;
|
|
#endif
|
|
InterruptUpdate _interrupt_update;
|
|
|
|
friend class SetModeEvent;
|
|
friend class CreatePrimarySurfaceEvent;
|
|
friend class DestroyPrimarySurfaceEvent;
|
|
friend class CreateSurfaceEvent;
|
|
friend class DestroySurfaceEvent;
|
|
friend class ActivateTimerEvent;
|
|
friend class VideoStream;
|
|
friend class StreamsTrigger;
|
|
friend class GLInterupt;
|
|
friend class StreamsTimer;
|
|
friend class AttachChannelsEvent;
|
|
friend class DetachChannelsEvent;
|
|
};
|
|
|
|
#endif
|
|
|