/* 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_REDCLIENT #define _H_REDCLIENT #include #include "common.h" #include "red_peer.h" #include "red_channel.h" #include "display_channel.h" #include "inputs_channel.h" #include "cursor_channel.h" #include "audio_channels.h" #include "messages.h" #include #include "process_loop.h" class Application; class MigChannel: public RedChannelBase { public: MigChannel(uint32_t type, uint32_t id, const ChannelCaps& common_caps, const ChannelCaps& caps) : RedChannelBase(type, id, common_caps, caps) , _valid(false) {} bool is_valid() { return _valid;} void set_valid(bool val) { _valid = val;} private: bool _valid; }; class Migrate { public: Migrate(RedClient& client); ~Migrate(); void start(const SpiceMsgMainMigrationBegin* migrate); bool abort(); void add_channel(MigChannel* channel); void clear_channels(); void swap_peer(RedChannelBase& other); private: void connect_one(MigChannel& channel, const RedPeer::ConnectionOptions& options, uint32_t connection_id); void disconnect_channels(); void close_channels(); void delete_channels(); void run(); static void* worker_main(void *data); private: RedClient& _client; typedef std::list MigChannels; MigChannels _channels; bool _running; bool _aborting; bool _connected; std::string _password; std::string _host; int _port; int _sport; RedPeer::HostAuthOptions _auth_options; std::string _con_ciphers; Thread* _thread; Mutex _lock; Condition _cond; int _pending_con; }; class ChannelFactory { public: ChannelFactory(uint32_t type) : _type (type) {} virtual ~ChannelFactory() {} uint32_t type() { return _type;} virtual RedChannel* construct(RedClient& client, uint32_t id) = 0; private: uint32_t _type; }; class GlzDecoderWindowDebug: public GlzDecoderDebug { public: virtual void error(const std::string& str) { throw Exception(str); } virtual void warn(const std::string& str) { LOG_WARN("%s", str.c_str()); } virtual void info(const std::string& str) { LOG_INFO("%s", str.c_str()); } }; class AgentTimer: public Timer { virtual void response(AbstractProcessLoop& events_loop); }; typedef std::map< int, RedPeer::ConnectionOptions::Type> PeerConnectionOptMap; class ForEachChannelFunc { public: virtual bool operator() (RedChannel& channel) = 0; }; class RedClient: public RedChannel { public: friend class RedChannel; friend class Migrate; RedClient(Application& application); ~RedClient(); void register_channel_factory(ChannelFactory& factory); virtual void connect(); virtual void disconnect(); virtual bool abort(); void connect(bool wait_main_disconnect); void push_event(Event* event); void activate_interval_timer(Timer* timer, unsigned int millisec); void deactivate_interval_timer(Timer* timer); void set_target(const std::string&, int port, int sport); void set_password(const std::string& password) { _password = password;} void set_auto_display_res(bool auto_display_res) { _auto_display_res = auto_display_res;} const std::string& get_password() { return _password;} const std::string& get_host() { return _host;} int get_port() { return _port;} int get_sport() { return _sport;} virtual uint32_t get_connection_id() { return _connection_id;} uint32_t get_mouse_mode() { return _mouse_mode;} Application& get_application() { return _application;} bool is_auto_display_res() { return _auto_display_res;} RedPeer::ConnectionOptions::Type get_connection_options(uint32_t channel_type); RedPeer::HostAuthOptions& get_host_auth_options() { return _host_auth_opt;} const std::string& get_connection_ciphers() { return _con_ciphers;} void get_sync_info(uint8_t channel_type, uint8_t channel_id, SyncInfo& info); void wait_for_channels(int wait_list_size, SpiceWaitForChannel* wait_list); PixmapCache& get_pixmap_cache() {return _pixmap_cache;} uint64_t get_pixmap_cache_size() { return _pixmap_cache_size;} void on_display_mode_change(); void for_each_channel(ForEachChannelFunc& func); void on_mouse_capture_trigger(RedScreen& screen); GlzDecoderWindow& get_glz_window() {return _glz_window;} int get_glz_window_size() { return _glz_window_size;} void set_mm_time(uint32_t time); uint32_t get_mm_time(); protected: virtual void on_connecting(); virtual void on_connect(); virtual void on_disconnect(); private: void on_channel_disconnected(RedChannel& channel); void migrate_channel(RedChannel& channel); void send_agent_monitors_config(); void calc_pixmap_cach_and_glz_window_size(uint32_t display_channels_hint, uint32_t pci_mem_hint); void set_mouse_mode(uint32_t supported_modes, uint32_t current_mode); void handle_migrate_begin(RedPeer::InMessage* message); void handle_migrate_cancel(RedPeer::InMessage* message); void handle_init(RedPeer::InMessage* message); void handle_channels(RedPeer::InMessage* message); void handle_mouse_mode(RedPeer::InMessage* message); void handle_mm_time(RedPeer::InMessage* message); void handle_agent_connected(RedPeer::InMessage* message); void handle_agent_disconnected(RedPeer::InMessage* message); void handle_agent_data(RedPeer::InMessage* message); void handle_agent_tokens(RedPeer::InMessage* message); void handle_migrate_switch_host(RedPeer::InMessage* message); void on_agent_reply(VDAgentReply* reply); ChannelFactory* find_factory(uint32_t type); void create_channel(uint32_t type, uint32_t id); void disconnect_channels(); void delete_channels(); bool abort_channels(); private: Application& _application; std::string _host; int _port; int _sport; std::string _password; uint32_t _connection_id; uint32_t _mouse_mode; Mutex _notify_lock; bool _notify_disconnect; bool _auto_display_res; bool _aborting; bool _agent_connected; bool _agent_mon_config_sent; VDAgentMessage* _agent_msg; uint8_t* _agent_msg_data; uint32_t _agent_msg_pos; uint32_t _agent_tokens; AutoRef _agent_timer; PeerConnectionOptMap _con_opt_map; RedPeer::HostAuthOptions _host_auth_opt; std::string _con_ciphers; Migrate _migrate; Mutex _channels_lock; typedef std::list Factorys; Factorys _factorys; typedef std::list Channels; Channels _channels; PixmapCache _pixmap_cache; uint64_t _pixmap_cache_size; Mutex _sync_lock; Condition _sync_condition; uint64_t _sync_info[SPICE_END_CHANNEL][256]; GlzDecoderWindowDebug _glz_debug; GlzDecoderWindow _glz_window; int _glz_window_size; // in pixels Mutex _mm_clock_lock; uint64_t _mm_clock_last_update; uint32_t _mm_time; }; #endif