summaryrefslogtreecommitdiffstats
path: root/client/screen.h
blob: 4093006f2c107dae07fb06415d75ed794706b597 (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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*
   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_SCREEN
#define _H_SCREEN

#include "common/region.h"

#include "common.h"
#include "red_key.h"
#ifdef USE_OPENGL
#include "GL/gl.h"
#endif // USE_OPENGL

#include "red_window.h"
#include "platform.h"
#include "process_loop.h"
#include "threads.h"
#include "utils.h"

class Application;
class ScreenLayer;
class Monitor;
class RedScreen;

enum {
    SCREEN_LAYER_DISPLAY,
    SCREEN_LAYER_CURSOR,
    SCREEN_LAYER_GUI_BARIER,
    SCREEN_LAYER_GUI,
    SCREEN_LAYER_INFO,
};

class UpdateTimer: public Timer {
public:
    UpdateTimer(RedScreen* screen) : _screen (screen) {}
    virtual void response(AbstractProcessLoop& events_loop);
private:
    RedScreen* _screen;
};

class RedScreen: public RedWindow::Listener {
public:
    RedScreen(Application& owner, int id, const std::string& name, int width, int height);

    RedScreen* ref();
    void unref();

    void attach_layer(ScreenLayer& layer);
    void detach_layer(ScreenLayer& layer);
    void on_layer_changed(ScreenLayer& layer);
    /* When resizing on full screen mode, the monitor must be configured
     * correctly before calling resize*/
    void resize(int width, int height);
    void set_name(const std::string& name);
    uint64_t invalidate(const SpiceRect& rect, bool urgent);
    void invalidate(const QRegion &region);
    void capture_mouse();
    void relase_mouse();
    bool is_mouse_captured() { return _mouse_captured;}
    bool intercepts_sys_key() { return _key_interception;}
    SpicePoint get_size() { return _size;}
    bool has_monitor() { return _monitor != 0;}
    void lock_size();
    void unlock_size();
    bool is_size_locked() { return _size_locked;}
    void set_monitor(Monitor *monitor) { _monitor = monitor;}
    Monitor* get_monitor() { return _monitor;}
    RedWindow* get_window() { return &_window;}
    bool is_out_of_sync() { return _out_of_sync;}
    void set_cursor(LocalCursor* cursor);
    void hide_cursor();
    void exit_full_screen();
    void minimize();
    void show(bool activate, RedScreen* pos);
    void show_full_screen();
    void position_full_screen(const SpicePoint& position);
    void hide();
    void show();
    void activate();
    void external_show();
    void update_menu();

    int get_id() { return _id;}
    int get_screen_id();

#ifdef USE_OPENGL
    void untouch_context();
    bool need_recreate_context_gl();
    void set_type_gl();
    void unset_type_gl();
#endif
    void set_update_interrupt_trigger(EventSources::Trigger *trigger);
    bool update_by_interrupt();
    void interrupt_update();

    void update();

private:
    friend class UpdateEvent;
    friend class UpdateTimer;

    virtual ~RedScreen();
    void create_composit_area();

    void destroy_composit_area();
    void erase_background(RedDrawable& dc, const QRegion& region);
    void notify_new_size();
    void adjust_window_rect(int x, int y);
    void save_position();
    void __show_full_screen();

    bool _invalidate(const SpiceRect& rect, bool urgent, uint64_t& update_mark);
    void begin_update(QRegion& direct_rgn, QRegion& composit_rgn, QRegion& frame_rgn);
    void update_composit(QRegion& composit_rgn);
    void draw_direct(RedDrawable& win_dc, QRegion& direct_rgn, QRegion& composit_rgn,
                     QRegion& frame_rgn);
    void activate_timer();
    void update_done();
    void periodic_update();
    bool is_dirty() {return !region_is_empty(&_dirty_region);}
    void composit_to_screen(RedDrawable& win_dc, const QRegion& region);

    void reset_mouse_pos();
    ScreenLayer* find_pointer_layer();
    bool update_pointer_layer();

    virtual void on_exposed_rect(const SpiceRect& area);
    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();
    void on_mouse_motion(int x, int y, unsigned int buttons_state);
    virtual void on_mouse_button_press(SpiceMouseButton button, unsigned int buttons_state);
    virtual void on_mouse_button_release(SpiceMouseButton button, unsigned int buttons_state);

    virtual void on_key_press(RedKey key);
    virtual void on_key_release(RedKey key);
    virtual void on_char(uint32_t ch);

    virtual void on_deactivate();
    virtual void on_activate();

    virtual void on_start_key_interception();
    virtual void on_stop_key_interception();
    virtual void enter_modal_loop();
    virtual void exit_modal_loop();

    virtual void pre_migrate();
    virtual void post_migrate();

private:
    Application& _owner;
    int _id;
    AtomicCount _refs;
    std::string _name;
    RedWindow _window;
    std::vector<ScreenLayer*> _layers;
    QRegion _dirty_region;
    RecurciveMutex _update_lock;
    bool _active;
    bool _full_screen;
    bool _out_of_sync;
    bool _frame_area;
    bool _periodic_update;
    bool _key_interception;
    bool _update_by_timer;
    bool _size_locked;
    bool _menu_needs_update;
    int _force_update_timer;
    AutoRef<UpdateTimer> _update_timer;
    RedDrawable* _composit_area;
    uint64_t _update_mark;

    SpicePoint _size;
    SpicePoint _origin;
    SpicePoint _mouse_anchor_point;
    SpicePoint _save_pos;
    Monitor* _monitor;

    LocalCursor* _default_cursor;
    LocalCursor* _inactive_cursor;

    int _pixel_format_index;
    EventSources::Trigger *_update_interrupt_trigger;

    ScreenLayer* _pointer_layer;
    bool _mouse_captured;
    Mutex _layer_changed_lock;
    bool _active_layer_change_event;
    bool _pointer_on_screen;
    SpicePoint _pointer_pos;
    unsigned int _mouse_botton_state;

    friend class LayerChangedEvent;
};

#endif