[Spice-commits] client/application.cpp client/application.h client/red_client.cpp client/red_client.h

Yonit Halperin yhalperi at kemper.freedesktop.org
Mon Jul 19 00:21:28 PDT 2010


 client/application.cpp |   57 ++++++++++++++++++++++++++++++++++
 client/application.h   |    2 +
 client/red_client.cpp  |   80 ++++++++++++++++++++++++++++++++++++++++++++-----
 client/red_client.h    |   25 +++++++++++++++
 4 files changed, 157 insertions(+), 7 deletions(-)

New commits:
commit 9877e7ae8405965463a67171b7408871f949f66f
Author: Yonit Halperin <yhalperi at redhat.com>
Date:   Mon Jul 19 09:36:07 2010 +0300

    client: command line arguments for setting windows guest monitors'
    color depth and disabling some display options (helpful on WAN)

diff --git a/client/application.cpp b/client/application.cpp
index af37ae0..14ac743 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 01ef517..74efed4 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 c2be58c..0268e75 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 52a3456..9603bfe 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;


More information about the Spice-commits mailing list