mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 14:41:25 +00:00
spice client: remove timer interface from platform - use Application (via ProcessLoop interface).
This commit is contained in:
parent
4c72ba138c
commit
ec34856fea
@ -594,6 +594,33 @@ InterruptUpdate::InterruptUpdate(DisplayChannel& channel)
|
||||
{
|
||||
}
|
||||
|
||||
StreamsTimer::StreamsTimer(DisplayChannel& channel)
|
||||
: _channel (channel)
|
||||
{
|
||||
}
|
||||
|
||||
void StreamsTimer::response(AbstractProcessLoop &events_loop)
|
||||
{
|
||||
_channel.streams_time();
|
||||
}
|
||||
|
||||
#define RESET_TIMEOUT (1000 * 5)
|
||||
|
||||
class ResetTimer: public Timer {
|
||||
public:
|
||||
ResetTimer(RedScreen* screen, RedClient& client) : _screen(screen), _client(client) {}
|
||||
virtual void response(AbstractProcessLoop &events_loop);
|
||||
private:
|
||||
RedScreen* _screen;
|
||||
RedClient& _client;
|
||||
};
|
||||
|
||||
void ResetTimer::response(AbstractProcessLoop &events_loop)
|
||||
{
|
||||
_screen->unref();
|
||||
_client.deactivate_interval_timer(this);
|
||||
}
|
||||
|
||||
class DisplayHandler: public MessageHandlerImp<DisplayChannel, RED_DISPLAY_MESSAGES_END> {
|
||||
public:
|
||||
DisplayHandler(DisplayChannel& channel)
|
||||
@ -610,7 +637,7 @@ DisplayChannel::DisplayChannel(RedClient& client, uint32_t id,
|
||||
, _glz_window (glz_window)
|
||||
, _mark (false)
|
||||
, _update_mark (0)
|
||||
, _streams_timer (INVALID_TIMER)
|
||||
, _streams_timer (new StreamsTimer(*this))
|
||||
, _next_timer_time (0)
|
||||
, _active_streams (NULL)
|
||||
, _streams_trigger (*this)
|
||||
@ -817,49 +844,6 @@ void DisplayChannel::copy_pixels(const QRegion& dest_region,
|
||||
_canvas->copy_pixels(dest_region, dest_dc);
|
||||
}
|
||||
|
||||
class CreateTimerEvent: public SyncEvent {
|
||||
public:
|
||||
CreateTimerEvent(timer_proc_t proc, void* user_data)
|
||||
: SyncEvent()
|
||||
, _proc (proc)
|
||||
, _user_data (user_data)
|
||||
, _timer (INVALID_TIMER)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~CreateTimerEvent()
|
||||
{
|
||||
ASSERT(_timer == INVALID_TIMER);
|
||||
}
|
||||
|
||||
virtual void do_response(AbstractProcessLoop& events_loop)
|
||||
{
|
||||
if ((_timer = Platform::create_interval_timer(_proc, _user_data)) == INVALID_TIMER) {
|
||||
THROW("create timer failed");
|
||||
}
|
||||
}
|
||||
|
||||
TimerID release() { TimerID ret = _timer; _timer = INVALID_TIMER; return ret;}
|
||||
|
||||
private:
|
||||
timer_proc_t _proc;
|
||||
void* _user_data;
|
||||
TimerID _timer;
|
||||
};
|
||||
|
||||
class DestroyTimerEvent: public Event {
|
||||
public:
|
||||
DestroyTimerEvent(TimerID timer) : _timer (timer) {}
|
||||
|
||||
virtual void response(AbstractProcessLoop& events_loop)
|
||||
{
|
||||
Platform::destroy_interval_timer(_timer);
|
||||
}
|
||||
|
||||
private:
|
||||
TimerID _timer;
|
||||
};
|
||||
|
||||
class ActivateTimerEvent: public Event {
|
||||
public:
|
||||
ActivateTimerEvent(DisplayChannel& channel)
|
||||
@ -876,19 +860,6 @@ private:
|
||||
DisplayChannel& _channel;
|
||||
};
|
||||
|
||||
void DisplayChannel::streams_timer_callback(void* opaque, TimerID timer)
|
||||
{
|
||||
((DisplayChannel *)opaque)->streams_time();
|
||||
}
|
||||
|
||||
#define RESET_TIMEOUT (1000 * 5)
|
||||
|
||||
void DisplayChannel::reset_timer_callback(void* opaque, TimerID timer)
|
||||
{
|
||||
((RedScreen *)opaque)->unref();
|
||||
Platform::destroy_interval_timer(timer);
|
||||
}
|
||||
|
||||
void DisplayChannel::on_connect()
|
||||
{
|
||||
Message* message = new Message(REDC_DISPLAY_INIT, sizeof(RedcDisplayInit));
|
||||
@ -898,13 +869,6 @@ void DisplayChannel::on_connect()
|
||||
init->glz_dictionary_id = 1;
|
||||
init->glz_dictionary_window_size = get_client().get_glz_window_size();
|
||||
post_message(message);
|
||||
AutoRef<CreateTimerEvent> event(new CreateTimerEvent(streams_timer_callback, this));
|
||||
get_client().push_event(*event);
|
||||
(*event)->wait();
|
||||
_streams_timer = (*event)->release();
|
||||
if (!(*event)->success()) {
|
||||
THROW("create timer failed");
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayChannel::on_disconnect()
|
||||
@ -917,8 +881,7 @@ void DisplayChannel::on_disconnect()
|
||||
screen()->set_update_interrupt_trigger(NULL);
|
||||
}
|
||||
detach_from_screen(get_client().get_application());
|
||||
AutoRef<DestroyTimerEvent> event(new DestroyTimerEvent(_streams_timer));
|
||||
get_client().push_event(*event);
|
||||
get_client().deactivate_interval_timer(*_streams_timer);
|
||||
AutoRef<SyncEvent> sync_event(new SyncEvent());
|
||||
get_client().push_event(*sync_event);
|
||||
(*sync_event)->wait();
|
||||
@ -1096,21 +1059,16 @@ void DisplayChannel::handle_mark(RedPeer::InMessage *message)
|
||||
|
||||
void DisplayChannel::handle_reset(RedPeer::InMessage *message)
|
||||
{
|
||||
TimerID reset_timer;
|
||||
|
||||
screen()->set_update_interrupt_trigger(NULL);
|
||||
|
||||
if (_canvas.get()) {
|
||||
_canvas->clear();
|
||||
}
|
||||
reset_timer = Platform::create_interval_timer(reset_timer_callback, screen()->ref());
|
||||
if (reset_timer == INVALID_TIMER) {
|
||||
THROW("invalid reset timer");
|
||||
}
|
||||
AutoRef<ResetTimer> reset_timer(new ResetTimer(screen()->ref(), get_client()));
|
||||
detach_from_screen(get_client().get_application());
|
||||
_palette_cache.clear();
|
||||
|
||||
Platform::activate_interval_timer(reset_timer, RESET_TIMEOUT);
|
||||
get_client().activate_interval_timer(*reset_timer, RESET_TIMEOUT);
|
||||
}
|
||||
|
||||
void DisplayChannel::handle_inval_list(RedPeer::InMessage* message)
|
||||
@ -1391,10 +1349,10 @@ void DisplayChannel::streams_time()
|
||||
mm_time = get_client().get_mm_time();
|
||||
next_time = mm_time + 15;
|
||||
if (next_time && (!_next_timer_time || int(next_time - _next_timer_time) < 0)) {
|
||||
Platform::activate_interval_timer(_streams_timer, MAX(int(next_time - mm_time), 0));
|
||||
get_client().activate_interval_timer(*_streams_timer, MAX(int(next_time - mm_time), 0));
|
||||
_next_timer_time = next_time;
|
||||
} else if (!_next_timer_time) {
|
||||
Platform::deactivate_interval_timer(_streams_timer);
|
||||
get_client().deactivate_interval_timer(*_streams_timer);
|
||||
}
|
||||
timer_lock.unlock();
|
||||
lock.unlock();
|
||||
@ -1417,7 +1375,7 @@ void DisplayChannel::activate_streams_timer()
|
||||
return;
|
||||
}
|
||||
delta = _next_timer_time - get_client().get_mm_time();
|
||||
Platform::activate_interval_timer(_streams_timer, delta);
|
||||
get_client().activate_interval_timer(*_streams_timer, delta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -70,6 +70,13 @@ private:
|
||||
DisplayChannel& _channel;
|
||||
};
|
||||
|
||||
class StreamsTimer: public Timer {
|
||||
public:
|
||||
StreamsTimer(DisplayChannel& channel);
|
||||
virtual void response(AbstractProcessLoop& events_loop);
|
||||
private:
|
||||
DisplayChannel& _channel;
|
||||
};
|
||||
|
||||
class DisplayChannel: public RedChannel, public ScreenLayer {
|
||||
public:
|
||||
@ -145,9 +152,6 @@ private:
|
||||
|
||||
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;
|
||||
@ -168,7 +172,7 @@ private:
|
||||
Mutex _streams_lock;
|
||||
|
||||
Mutex _timer_lock;
|
||||
TimerID _streams_timer;
|
||||
AutoRef<StreamsTimer> _streams_timer;
|
||||
uint32_t _next_timer_time;
|
||||
|
||||
std::vector<VideoStream*> _streams;
|
||||
@ -183,7 +187,7 @@ private:
|
||||
friend class VideoStream;
|
||||
friend class StreamsTrigger;
|
||||
friend class GLInterupt;
|
||||
friend void streams_timer_callback(void* opaque, TimerID timer);
|
||||
friend class StreamsTimer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -30,13 +30,6 @@ class Icon;
|
||||
class Monitor;
|
||||
typedef std::list<Monitor*> MonitorsList;
|
||||
|
||||
/* TODO: tmp till each channel will handle its own thread
|
||||
timers or directly through the main thread */
|
||||
#define INVALID_TIMER (~TimerID(0))
|
||||
typedef unsigned long TimerID;
|
||||
typedef void (*timer_proc_t)(void* opaque, TimerID timer);
|
||||
|
||||
|
||||
class Platform {
|
||||
public:
|
||||
static void init();
|
||||
@ -98,12 +91,6 @@ public:
|
||||
|
||||
class DisplayModeListner;
|
||||
static void set_display_mode_listner(DisplayModeListner* listener);
|
||||
/* TODO: tmp till each channel will handle its own thread
|
||||
timers or directly through the main thread */
|
||||
static TimerID create_interval_timer(timer_proc_t proc, void* opaque);
|
||||
static bool activate_interval_timer(TimerID timer, unsigned int millisec);
|
||||
static bool deactivate_interval_timer(TimerID timer);
|
||||
static void destroy_interval_timer(TimerID timer);
|
||||
};
|
||||
|
||||
class Platform::EventListener {
|
||||
|
||||
@ -217,9 +217,10 @@ bool Migrate::abort()
|
||||
|
||||
#define AGENT_TIMEOUT (1000 * 30)
|
||||
|
||||
void agent_timer_proc(void *opaque, TimerID timer)
|
||||
void AgentTimer::response(AbstractProcessLoop& events_loop)
|
||||
{
|
||||
Platform::deactivate_interval_timer(timer);
|
||||
Application* app = static_cast<Application*>(events_loop.get_owner());
|
||||
app->deactivate_interval_timer(this);
|
||||
THROW_ERR(SPICEC_ERROR_CODE_AGENT_TIMEOUT, "vdagent timeout");
|
||||
}
|
||||
|
||||
@ -241,7 +242,7 @@ RedClient::RedClient(Application& application)
|
||||
, _agent_msg_data (NULL)
|
||||
, _agent_msg_pos (0)
|
||||
, _agent_tokens (0)
|
||||
, _agent_timer (Platform::create_interval_timer(agent_timer_proc, NULL))
|
||||
, _agent_timer (new AgentTimer())
|
||||
, _migrate (*this)
|
||||
, _glz_window (0, _glz_debug)
|
||||
{
|
||||
@ -273,16 +274,13 @@ RedClient::RedClient(Application& application)
|
||||
message_loop->set_handler(RED_AGENT_DATA, &RedClient::handle_agent_data, 0);
|
||||
message_loop->set_handler(RED_AGENT_TOKEN, &RedClient::handle_agent_tokens,
|
||||
sizeof(RedAgentTokens));
|
||||
if (_agent_timer == INVALID_TIMER) {
|
||||
THROW("invalid agent timer");
|
||||
}
|
||||
start();
|
||||
}
|
||||
|
||||
RedClient::~RedClient()
|
||||
{
|
||||
ASSERT(_channels.empty());
|
||||
Platform::destroy_interval_timer(_agent_timer);
|
||||
_application.deactivate_interval_timer(*_agent_timer);
|
||||
delete _agent_msg;
|
||||
}
|
||||
|
||||
@ -313,6 +311,16 @@ void RedClient::push_event(Event* event)
|
||||
_application.push_event(event);
|
||||
}
|
||||
|
||||
void RedClient::activate_interval_timer(Timer* timer, unsigned int millisec)
|
||||
{
|
||||
_application.activate_interval_timer(timer, millisec);
|
||||
}
|
||||
|
||||
void RedClient::deactivate_interval_timer(Timer* timer)
|
||||
{
|
||||
_application.deactivate_interval_timer(timer);
|
||||
}
|
||||
|
||||
void RedClient::on_connecting()
|
||||
{
|
||||
_notify_disconnect = true;
|
||||
@ -329,7 +337,7 @@ void RedClient::on_disconnect()
|
||||
{
|
||||
_migrate.abort();
|
||||
_connection_id = 0;
|
||||
Platform::deactivate_interval_timer(_agent_timer);
|
||||
_application.deactivate_interval_timer(*_agent_timer);
|
||||
_agent_mon_config_sent = false;
|
||||
delete[] _agent_msg_data;
|
||||
_agent_msg_data = NULL;
|
||||
@ -632,7 +640,7 @@ void RedClient::handle_init(RedPeer::InMessage* message)
|
||||
post_message(msg);
|
||||
}
|
||||
if (_auto_display_res) {
|
||||
Platform::activate_interval_timer(_agent_timer, AGENT_TIMEOUT);
|
||||
_application.activate_interval_timer(*_agent_timer, AGENT_TIMEOUT);
|
||||
if (_agent_connected) {
|
||||
send_agent_monitors_config();
|
||||
}
|
||||
@ -694,7 +702,7 @@ void RedClient::on_agent_reply(VDAgentReply* reply)
|
||||
switch (reply->type) {
|
||||
case VD_AGENT_MONITORS_CONFIG:
|
||||
post_message(new Message(REDC_ATTACH_CHANNELS, 0));
|
||||
Platform::deactivate_interval_timer(_agent_timer);
|
||||
_application.deactivate_interval_timer(*_agent_timer);
|
||||
break;
|
||||
default:
|
||||
THROW("unexpected vdagent reply type");
|
||||
|
||||
@ -112,6 +112,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class AgentTimer: public Timer {
|
||||
virtual void response(AbstractProcessLoop& events_loop);
|
||||
};
|
||||
|
||||
typedef std::map< int, RedPeer::ConnectionOptions::Type> PeerConnectionOptMap;
|
||||
|
||||
class RedClient: public RedChannel {
|
||||
@ -131,6 +135,8 @@ public:
|
||||
virtual bool abort();
|
||||
|
||||
void push_event(Event* event);
|
||||
void activate_interval_timer(Timer* timer, unsigned int millisec);
|
||||
void deactivate_interval_timer(Timer* timer);
|
||||
|
||||
void set_target(const char* host, uint16_t port, uint16_t sport);
|
||||
const char* get_password() { return _password.c_str();}
|
||||
@ -206,7 +212,7 @@ private:
|
||||
uint8_t* _agent_msg_data;
|
||||
uint32_t _agent_msg_pos;
|
||||
uint32_t _agent_tokens;
|
||||
TimerID _agent_timer;
|
||||
AutoRef<AgentTimer> _agent_timer;
|
||||
|
||||
PeerConnectionOptMap _con_opt_map;
|
||||
Migrate _migrate;
|
||||
|
||||
@ -43,11 +43,9 @@ private:
|
||||
int _screen;
|
||||
};
|
||||
|
||||
void periodic_update_proc(void *opaque, TimerID timer)
|
||||
void UpdateTimer::response(AbstractProcessLoop& events_loop)
|
||||
{
|
||||
RedScreen* screen = (RedScreen*)opaque;
|
||||
|
||||
screen->periodic_update();
|
||||
_screen->periodic_update();
|
||||
}
|
||||
|
||||
RedScreen::RedScreen(Application& owner, int id, const std::wstring& name, int width, int height)
|
||||
@ -65,7 +63,7 @@ RedScreen::RedScreen(Application& owner, int id, const std::wstring& name, int w
|
||||
, _key_interception (false)
|
||||
, _update_by_timer (true)
|
||||
, _forec_update_timer (0)
|
||||
, _update_timer (INVALID_TIMER)
|
||||
, _update_timer (new UpdateTimer(this))
|
||||
, _composit_area (NULL)
|
||||
, _update_mark (1)
|
||||
, _monitor (NULL)
|
||||
@ -84,10 +82,6 @@ RedScreen::RedScreen(Application& owner, int id, const std::wstring& name, int w
|
||||
create_composit_area();
|
||||
_window.resize(_size.x, _size.y);
|
||||
save_position();
|
||||
_update_timer = Platform::create_interval_timer(periodic_update_proc, this);
|
||||
if (_update_timer == INVALID_TIMER) {
|
||||
THROW("create timer failed");
|
||||
}
|
||||
if ((_default_cursor = Platform::create_default_cursor()) == NULL) {
|
||||
THROW("create default cursor failed");
|
||||
}
|
||||
@ -106,7 +100,7 @@ RedScreen::~RedScreen()
|
||||
bool captured = is_captured();
|
||||
relase_inputs();
|
||||
destroy_composit_area();
|
||||
Platform::destroy_interval_timer(_update_timer);
|
||||
_owner.deactivate_interval_timer(*_update_timer);
|
||||
_owner.on_screen_destroyed(_id, captured);
|
||||
region_destroy(&_dirty_region);
|
||||
if (_default_cursor) {
|
||||
@ -333,7 +327,7 @@ void RedScreen::periodic_update()
|
||||
need_update = true;
|
||||
} else {
|
||||
if (!_forec_update_timer) {
|
||||
Platform::deactivate_interval_timer(_update_timer);
|
||||
_owner.deactivate_interval_timer(*_update_timer);
|
||||
_periodic_update = false;
|
||||
}
|
||||
need_update = false;
|
||||
@ -357,9 +351,7 @@ void RedScreen::activate_timer()
|
||||
}
|
||||
_periodic_update = true;
|
||||
lock.unlock();
|
||||
if (!Platform::activate_interval_timer(_update_timer, 1000 / 30)) {
|
||||
LOG_WARN("failed");
|
||||
}
|
||||
_owner.activate_interval_timer(*_update_timer, 1000 / 30);
|
||||
}
|
||||
|
||||
void RedScreen::update()
|
||||
|
||||
@ -27,10 +27,12 @@
|
||||
#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,
|
||||
@ -38,6 +40,14 @@ enum {
|
||||
SCREEN_LAYER_GUI,
|
||||
};
|
||||
|
||||
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::wstring& name, int width, int height);
|
||||
@ -87,8 +97,8 @@ public:
|
||||
void update();
|
||||
|
||||
private:
|
||||
friend void periodic_update_proc(void *opaque, TimerID timer);
|
||||
friend class UpdateEvent;
|
||||
friend class UpdateTimer;
|
||||
|
||||
virtual ~RedScreen();
|
||||
void create_composit_area();
|
||||
@ -153,7 +163,7 @@ private:
|
||||
bool _key_interception;
|
||||
bool _update_by_timer;
|
||||
int _forec_update_timer;
|
||||
TimerID _update_timer;
|
||||
AutoRef<UpdateTimer> _update_timer;
|
||||
RedDrawable* _composit_area;
|
||||
uint64_t _update_mark;
|
||||
|
||||
|
||||
@ -618,38 +618,3 @@ Icon* Platform::load_icon(int id)
|
||||
}
|
||||
return new WinIcon(icon);
|
||||
}
|
||||
|
||||
class PlatformTimer: public Timer {
|
||||
public:
|
||||
PlatformTimer(timer_proc_t proc, void* opaque) : _proc (proc), _opaque (opaque) {}
|
||||
void response(AbstractProcessLoop& events_loop) {_proc(_opaque, (TimerID)this);}
|
||||
|
||||
private:
|
||||
timer_proc_t _proc;
|
||||
void* _opaque;
|
||||
};
|
||||
|
||||
TimerID Platform::create_interval_timer(timer_proc_t proc, void* opaque)
|
||||
{
|
||||
return (TimerID)(new PlatformTimer(proc, opaque));
|
||||
}
|
||||
|
||||
bool Platform::activate_interval_timer(TimerID timer, unsigned int millisec)
|
||||
{
|
||||
ASSERT(main_loop);
|
||||
main_loop->activate_interval_timer((PlatformTimer*)timer, millisec);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Platform::deactivate_interval_timer(TimerID timer)
|
||||
{
|
||||
ASSERT(main_loop);
|
||||
main_loop->deactivate_interval_timer((PlatformTimer*)timer);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Platform::destroy_interval_timer(TimerID timer)
|
||||
{
|
||||
deactivate_interval_timer(timer);
|
||||
((PlatformTimer*)timer)->unref();
|
||||
}
|
||||
|
||||
@ -2422,38 +2422,3 @@ LocalCursor* Platform::create_default_cursor()
|
||||
{
|
||||
return new XDefaultCursor();
|
||||
}
|
||||
|
||||
class PlatformTimer: public Timer {
|
||||
public:
|
||||
PlatformTimer(timer_proc_t proc, void* opaque) : _proc(proc), _opaque(opaque) {}
|
||||
void response(AbstractProcessLoop& events_loop) {_proc(_opaque, (TimerID)this);}
|
||||
|
||||
private:
|
||||
timer_proc_t _proc;
|
||||
void* _opaque;
|
||||
};
|
||||
|
||||
TimerID Platform::create_interval_timer(timer_proc_t proc, void* opaque)
|
||||
{
|
||||
return (TimerID)(new PlatformTimer(proc, opaque));
|
||||
}
|
||||
|
||||
bool Platform::activate_interval_timer(TimerID timer, unsigned int millisec)
|
||||
{
|
||||
ASSERT(main_loop);
|
||||
main_loop->activate_interval_timer((PlatformTimer*)timer, millisec);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Platform::deactivate_interval_timer(TimerID timer)
|
||||
{
|
||||
ASSERT(main_loop);
|
||||
main_loop->deactivate_interval_timer((PlatformTimer*)timer);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Platform::destroy_interval_timer(TimerID timer)
|
||||
{
|
||||
deactivate_interval_timer(timer);
|
||||
((PlatformTimer*)timer)->unref();
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user