/*
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 .
*/
#include "common.h"
#include "screen.h"
#include "application.h"
#include "screen_layer.h"
#include "utils.h"
#include "debug.h"
#include "monitor.h"
#include "red_pixmap_sw.h"
#include "resource.h"
#include "icon.h"
class UpdateEvent: public Event {
public:
UpdateEvent(int screen) : _screen (screen) {}
virtual void response(AbstractProcessLoop& events_loop)
{
Application* app = static_cast(events_loop.get_owner());
RedScreen* screen = app->find_screen(_screen);
if (screen) {
screen->update();
}
}
private:
int _screen;
};
class LayerChangedEvent: public Event {
public:
LayerChangedEvent (int screen) : _screen (screen) {}
virtual void response(AbstractProcessLoop& events_loop)
{
Application* app = static_cast(events_loop.get_owner());
RedScreen* screen = app->find_screen(_screen);
if (screen) {
Lock lock(screen->_layer_changed_lock);
screen->_active_layer_change_event = false;
lock.unlock();
if (screen->_pointer_on_screen) {
screen->update_pointer_layer();
}
}
}
private:
int _screen;
};
void UpdateTimer::response(AbstractProcessLoop& events_loop)
{
_screen->periodic_update();
}
RedScreen::RedScreen(Application& owner, int id, const std::wstring& name, int width, int height)
: _owner (owner)
, _id (id)
, _refs (1)
, _window (*this)
, _active (false)
, _full_screen (false)
, _out_of_sync (false)
, _frame_area (false)
, _periodic_update (false)
, _key_interception (false)
, _update_by_timer (true)
, _size_locked (false)
, _forec_update_timer (0)
, _update_timer (new UpdateTimer(this))
, _composit_area (NULL)
, _update_mark (1)
, _monitor (NULL)
, _default_cursor (NULL)
, _inactive_cursor (NULL)
, _pixel_format_index (0)
, _update_interrupt_trigger (NULL)
, _pointer_layer (NULL)
, _mouse_captured (false)
, _active_layer_change_event (false)
, _pointer_on_screen (false)
{
region_init(&_dirty_region);
set_name(name);
_size.x = width;
_size.y = height;
_origin.x = _origin.y = 0;
create_composit_area();
_window.resize(_size.x, _size.y);
save_position();
if ((_default_cursor = Platform::create_default_cursor()) == NULL) {
THROW("create default cursor failed");
}
if ((_inactive_cursor = Platform::create_inactive_cursor()) == NULL) {
THROW("create inactive cursor failed");
}
_window.set_cursor(_default_cursor);
AutoRef