summaryrefslogtreecommitdiffstats
path: root/client/display_channel.h
blob: 894c604ffb9800413611fcbca8359a83071e393d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*
   Copyright (C) 2009 Red Hat, Inc.

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of
   the License, or (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  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 "cairo.h"
#include "cache.hpp"
#include "screen_layer.h"
#include "events_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 StreamsTrigger: public EventsLoop::Trigger {
public:
    StreamsTrigger(DisplayChannel& channel);

    virtual void on_event();

private:
    DisplayChannel& _channel;
};

#ifdef USE_OGL
class GLInterruptRecreate: public EventsLoop::Trigger {
public:
    GLInterruptRecreate(DisplayChannel& channel);
    virtual void trigger();
    virtual void on_event();

private:
    DisplayChannel& _channel;
    Mutex _lock;
    Condition _cond;
};
#endif

class InterruptUpdate: public EventsLoop::Trigger {
public:
    InterruptUpdate(DisplayChannel& channel);

    virtual void on_event();

private:
    DisplayChannel& _channel;
};


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();

    static ChannelFactory& Factory();

protected:
    virtual void on_connect();
    virtual void on_disconnect();

private:
    void set_draw_handlers();
    void clear_draw_handlers();
    bool create_cairo_canvas(int width, int height, int depth);
#ifdef USE_OGL
    bool create_ogl_canvas(int width, int height, int depth, bool recreate,
                           RenderType rendertype);
#endif
#ifdef WIN32
    bool create_gdi_canvas(int width, int height, int depth);
#endif
    void destroy_canvas();
    void create_canvas(const std::vector<int>& canvas_type, int width, int height,
                       int depth);
    void destroy_strams();

    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_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 Clip& clip, uint32_t& num_clip_rects, Rect*& clip_rects,
                               unsigned long addr_offset, uint8_t *min, uint8_t *max);
    static void streams_timer_callback(void* opaque, TimerID timer);
    static void reset_timer_callback(void* opaque, TimerID timer);

private:
    std::auto_ptr<Canvas> _canvas;
    PixmapCache& _pixmap_cache;
    PaletteCache _palette_cache;
    GlzDecoderWindow& _glz_window;
    bool _mark;
    int _x_res;
    int _y_res;
    int _depth;
#ifdef USE_OGL
    RenderType _rendertype;
#endif

#ifndef RED64
    Mutex _mark_lock;
#endif
    uint64_t _update_mark;
    Mutex _streams_lock;

    Mutex _timer_lock;
    TimerID _streams_timer;
    uint32_t _next_timer_time;

    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 ActivateTimerEvent;
    friend class VideoStream;
    friend class StreamsTrigger;
    friend class GLInterupt;
    friend void streams_timer_callback(void* opaque, TimerID timer);
};

#endif