diff options
author | Yonit Halperin <yhalperi@redhat.com> | 2010-07-19 09:36:07 +0300 |
---|---|---|
committer | Yonit Halperin <yhalperi@redhat.com> | 2010-07-19 09:40:11 +0300 |
commit | 9877e7ae8405965463a67171b7408871f949f66f (patch) | |
tree | 4733494cfeb3e5e3fe625d9b1e53dd24523875cb /client | |
parent | 7df548358ca44b2c2194b4ee0bfada04475f4e49 (diff) | |
download | spice-9877e7ae8405965463a67171b7408871f949f66f.tar.gz spice-9877e7ae8405965463a67171b7408871f949f66f.tar.xz spice-9877e7ae8405965463a67171b7408871f949f66f.zip |
client: command line arguments for setting windows guest monitors'
color depth and disabling some display options (helpful on WAN)
Diffstat (limited to 'client')
-rw-r--r-- | client/application.cpp | 57 | ||||
-rw-r--r-- | client/application.h | 2 | ||||
-rw-r--r-- | client/red_client.cpp | 80 | ||||
-rw-r--r-- | client/red_client.h | 25 |
4 files changed, 157 insertions, 7 deletions
diff --git a/client/application.cpp b/client/application.cpp index af37ae02..14ac7433 100644 --- a/client/application.cpp +++ b/client/application.cpp @@ -1896,6 +1896,36 @@ bool Application::set_enable_channels(CmdLineParser& parser, bool enable, char * return true; } +bool Application::set_disabled_display_effects(CmdLineParser& parser, char *val, const char* arg0, + DisplaySetting& disp_setting) +{ + if (!strcmp(val, "all")) { + if ((val = parser.next_argument())) { + Platform::term_printf("%s: \"all\" is exclusive\n", arg0); + _exit_code = SPICEC_ERROR_CODE_INVALID_ARG; + return false; + } + disp_setting._disable_wallpaper = true; + disp_setting._disable_font_smooth = true; + disp_setting._disable_animation = true; + return true; + } + + do { + if (!strcmp(val, "wallpaper")) { + disp_setting._disable_wallpaper = true; + } else if (!strcmp(val, "font-smooth")) { + disp_setting._disable_font_smooth = true; + } else if (!strcmp(val, "animation")) { + disp_setting._disable_animation = true; + } else { + Platform::term_printf("%s: bad display effect type \"%s\"\n", arg0, val); + } + } while ((val = parser.next_argument())); + + return true; +} + void Application::on_cmd_line_invalid_arg(const char* arg0, const char* what, const char* val) { Platform::term_printf("%s: invalid %s value %s\n", arg0, what, val); @@ -1939,6 +1969,7 @@ bool Application::process_cmd_line(int argc, char** argv) bool auto_display_res = false; bool full_screen = false; std::string password; + DisplaySetting display_setting; enum { SPICE_OPT_HOST = CmdLineParser::OPTION_FIRST_AVILABLE, @@ -1954,6 +1985,8 @@ bool Application::process_cmd_line(int argc, char** argv) SPICE_OPT_ENABLE_CHANNELS, SPICE_OPT_DISABLE_CHANNELS, SPICE_OPT_CANVAS_TYPE, + SPICE_OPT_DISPLAY_COLOR_DEPTH, + SPICE_OPT_DISABLE_DISPLAY_EFFECTS, }; #ifdef USE_GUI @@ -2004,6 +2037,13 @@ bool Application::process_cmd_line(int argc, char** argv) parser.add(SPICE_OPT_CANVAS_TYPE, "canvas-type", "set rendering canvas", "canvas_type", true); parser.set_multi(SPICE_OPT_CANVAS_TYPE, ','); + parser.add(SPICE_OPT_DISPLAY_COLOR_DEPTH, "color-depth", "guest display color depth", + "16/32", true); + + parser.add(SPICE_OPT_DISABLE_DISPLAY_EFFECTS, "disable-effects", + "disable guest display effects", "wallpaper/font-smooth/animation/all", true); + parser.set_multi(SPICE_OPT_DISABLE_DISPLAY_EFFECTS, ','); + for (int i = SPICE_CHANNEL_MAIN; i < SPICE_END_CHANNEL; i++) { _peer_con_opt[i] = RedPeer::ConnectionOptions::CON_OP_INVALID; } @@ -2084,6 +2124,22 @@ bool Application::process_cmd_line(int argc, char** argv) return false; } break; + case SPICE_OPT_DISPLAY_COLOR_DEPTH: + display_setting._set_color_depth = true; + if (!strcmp(val, "16")) { + display_setting._color_depth = 16; + } else if (!strcmp(val, "32")) { + display_setting._color_depth = 32; + } else { + on_cmd_line_invalid_arg(argv[0], "color depth", val); + return false; + } + break; + case SPICE_OPT_DISABLE_DISPLAY_EFFECTS: + if (!set_disabled_display_effects(parser, val, argv[0], display_setting)) { + return false; + } + break; case CmdLineParser::OPTION_HELP: parser.show_help(); return false; @@ -2136,6 +2192,7 @@ bool Application::process_cmd_line(int argc, char** argv) _client.set_target(host, port, sport); _client.set_password(password); _client.set_auto_display_res(auto_display_res); + _client.set_display_setting(display_setting); if (full_screen) { enter_full_screen(); diff --git a/client/application.h b/client/application.h index 01ef517d..74efed4d 100644 --- a/client/application.h +++ b/client/application.h @@ -246,6 +246,8 @@ private: bool set_host_cert_subject(const char* subject, const char* arg0); bool set_enable_channels(CmdLineParser& parser, bool enable, char *val, const char* arg0); bool set_canvas_option(CmdLineParser& parser, char *val, const char* arg0); + bool set_disabled_display_effects(CmdLineParser& parser, char *val, const char* arg0, + DisplaySetting& disp_setting); void on_cmd_line_invalid_arg(const char* arg0, const char* what, const char* val); bool process_cmd_line(int argc, char** argv); void register_channels(); diff --git a/client/red_client.cpp b/client/red_client.cpp index c2be58c3..0268e754 100644 --- a/client/red_client.cpp +++ b/client/red_client.cpp @@ -312,9 +312,11 @@ RedClient::RedClient(Application& application) , _mouse_mode (SPICE_MOUSE_MODE_SERVER) , _notify_disconnect (false) , _auto_display_res (false) + , _agent_reply_wait_type (-1) , _aborting (false) , _agent_connected (false) , _agent_mon_config_sent (false) + , _agent_disp_config_sent (false) , _agent_msg (new VDAgentMessage) , _agent_msg_data (NULL) , _agent_msg_pos (0) @@ -395,7 +397,10 @@ void RedClient::on_disconnect() _migrate.abort(); _connection_id = 0; _application.deactivate_interval_timer(*_agent_timer); + // todo: if migration remains not seemless, we shouldn't + // resend monitors and display setting to the agent _agent_mon_config_sent = false; + _agent_disp_config_sent = false; delete[] _agent_msg_data; _agent_msg_data = NULL; _agent_msg_pos = 0; @@ -625,6 +630,51 @@ void RedClient::send_agent_monitors_config() _agent_tokens--; post_message(message); _agent_mon_config_sent = true; + _agent_reply_wait_type = VD_AGENT_MONITORS_CONFIG; +} + +void RedClient::send_agent_display_config() +{ + Message* message = new Message(SPICE_MSGC_MAIN_AGENT_DATA); + VDAgentMessage* msg = (VDAgentMessage*) + spice_marshaller_reserve_space(message->marshaller(), sizeof(VDAgentMessage)); + VDAgentDisplayConfig* disp_config; + + DBG(0,""); + msg->protocol = VD_AGENT_PROTOCOL; + msg->type = VD_AGENT_DISPLAY_CONFIG; + msg->opaque = 0; + msg->size = sizeof(VDAgentDisplayConfig); + + disp_config = (VDAgentDisplayConfig*) + spice_marshaller_reserve_space(message->marshaller(), sizeof(VDAgentDisplayConfig)); + + disp_config->flags = 0; + if (_display_setting._disable_wallpaper) { + disp_config->flags |= VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_WALLPAPER; + } + + if (_display_setting._disable_font_smooth) { + disp_config->flags |= VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_FONT_SMOOTH; + } + + if (_display_setting._disable_animation) { + disp_config->flags |= VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_ANIMATION; + } + + if (_display_setting._set_color_depth) { + disp_config->flags |= VD_AGENT_DISPLAY_CONFIG_FLAG_SET_COLOR_DEPTH; + disp_config->depth = _display_setting._color_depth; + } + + ASSERT(_agent_tokens) + _agent_tokens--; + post_message(message); + _agent_disp_config_sent = true; + + if (!_display_setting.is_empty()) { + _agent_reply_wait_type = VD_AGENT_DISPLAY_CONFIG; + } } #define MIN_DISPLAY_PIXMAP_CACHE (1024 * 1024 * 20) @@ -729,13 +779,20 @@ void RedClient::handle_init(RedPeer::InMessage* message) _marshallers->msgc_main_agent_start(msg->marshaller(), &agent_start); post_message(msg); } - if (_auto_display_res) { - _application.activate_interval_timer(*_agent_timer, AGENT_TIMEOUT); - if (_agent_connected) { - send_agent_monitors_config(); + + if (_agent_connected) { + if (_auto_display_res) { + send_agent_monitors_config(); } - } else { + // not sending the color depth through send_agent_monitors_config, since + // it applies only for attached screens. + send_agent_display_config(); + } + + if (!_auto_display_res && _display_setting.is_empty()) { post_message(new Message(SPICE_MSGC_MAIN_ATTACH_CHANNELS)); + } else { + _application.activate_interval_timer(*_agent_timer, AGENT_TIMEOUT); } } @@ -772,6 +829,10 @@ void RedClient::handle_agent_connected(RedPeer::InMessage* message) if (_auto_display_res && !_agent_mon_config_sent) { send_agent_monitors_config(); } + + if (!_agent_disp_config_sent) { + send_agent_display_config(); + } } void RedClient::handle_agent_disconnected(RedPeer::InMessage* message) @@ -782,6 +843,7 @@ void RedClient::handle_agent_disconnected(RedPeer::InMessage* message) void RedClient::on_agent_reply(VDAgentReply* reply) { + DBG(0, "agent reply type: %d", reply->type); switch (reply->error) { case VD_AGENT_SUCCESS: break; @@ -792,8 +854,12 @@ void RedClient::on_agent_reply(VDAgentReply* reply) } switch (reply->type) { case VD_AGENT_MONITORS_CONFIG: - post_message(new Message(SPICE_MSGC_MAIN_ATTACH_CHANNELS)); - _application.deactivate_interval_timer(*_agent_timer); + case VD_AGENT_DISPLAY_CONFIG: + if (_agent_reply_wait_type == reply->type) { + post_message(new Message(SPICE_MSGC_MAIN_ATTACH_CHANNELS)); + _application.deactivate_interval_timer(*_agent_timer); + _agent_reply_wait_type = -1; + } break; default: THROW("unexpected vdagent reply type"); diff --git a/client/red_client.h b/client/red_client.h index 52a3456b..9603bfe7 100644 --- a/client/red_client.h +++ b/client/red_client.h @@ -125,6 +125,25 @@ public: virtual bool operator() (RedChannel& channel) = 0; }; +class DisplaySetting { +public: + DisplaySetting() : _disable_wallpaper (false) + , _disable_font_smooth (false) + , _disable_animation (false) + , _set_color_depth (false) + {} + + bool is_empty() {return !(_disable_wallpaper || _disable_font_smooth || + _disable_animation || _set_color_depth);} + +public: + bool _disable_wallpaper; + bool _disable_font_smooth; + bool _disable_animation; + bool _set_color_depth; + uint32_t _color_depth; +}; + class RedClient: public RedChannel { public: friend class RedChannel; @@ -148,6 +167,7 @@ public: 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;} + void set_display_setting(DisplaySetting& setting) { _display_setting = setting;} const std::string& get_password() { return _password;} const std::string& get_host() { return _host;} int get_port() { return _port;} @@ -184,6 +204,7 @@ private: void on_channel_disconnected(RedChannel& channel); void migrate_channel(RedChannel& channel); void send_agent_monitors_config(); + void send_agent_display_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); @@ -221,10 +242,14 @@ private: Mutex _notify_lock; bool _notify_disconnect; bool _auto_display_res; + DisplaySetting _display_setting; + int _agent_reply_wait_type; + bool _aborting; bool _agent_connected; bool _agent_mon_config_sent; + bool _agent_disp_config_sent; VDAgentMessage* _agent_msg; uint8_t* _agent_msg_data; uint32_t _agent_msg_pos; |