/*
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 .
*/
#ifndef _H_SCREEN
#define _H_SCREEN
#include "common.h"
#include "region.h"
#include "red_key.h"
#ifdef USE_OGL
#include "GL/gl.h"
#endif // USE_OGL
#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);
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 ®ion);
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_OGL
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 _layes;
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;
int _forec_update_timer;
AutoRef _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