diff options
Diffstat (limited to 'client/application.cpp')
| -rw-r--r-- | client/application.cpp | 152 |
1 files changed, 129 insertions, 23 deletions
diff --git a/client/application.cpp b/client/application.cpp index c7f19006..52b0be63 100644 --- a/client/application.cpp +++ b/client/application.cpp @@ -290,15 +290,16 @@ enum AppCommands { APP_CMD_INVALID, APP_CMD_SEND_CTL_ALT_DEL, APP_CMD_TOGGLE_FULL_SCREEN, - APP_CMD_RELEASE_CAPTURE, APP_CMD_SEND_TOGGLE_KEYS, APP_CMD_SEND_RELEASE_KEYS, APP_CMD_SEND_CTL_ALT_END, + APP_CMD_RELEASE_CAPTURE, #ifdef RED_DEBUG APP_CMD_CONNECT, APP_CMD_DISCONNECT, #endif APP_CMD_FOREIGN_MENU_MASK = 0x01000000, + APP_CMD_CONTROLLER_MENU_MASK = 0x02000000, }; #define MENU_ID_MASK 0x000000ff @@ -323,6 +324,7 @@ Application::Application() , _splash_mode (true) , _sys_key_intercept_mode (false) , _during_host_switch(false) + , _enable_controller (false) { DBG(0, ""); Platform::set_process_loop(*this); @@ -462,6 +464,10 @@ int Application::run() void Application::on_start_running() { _foreign_menu.reset(new ForeignMenu(this)); + if (_enable_controller) { + _controller.reset(new Controller(this)); + return; + } _client.connect(); } @@ -819,6 +825,9 @@ void Application::do_command(int command) if ((command & APP_CMD_FOREIGN_MENU_MASK) == APP_CMD_FOREIGN_MENU_MASK) { ASSERT(*_foreign_menu); (*_foreign_menu)->on_command(conn_ref, command & MENU_ID_MASK); + } else if ((command & APP_CMD_CONTROLLER_MENU_MASK) == APP_CMD_CONTROLLER_MENU_MASK) { + ASSERT(*_controller); + (*_controller)->on_command(conn_ref, command & MENU_ID_MASK); } } } @@ -852,6 +861,75 @@ void Application::update_menu() } } +void Application::add_controller(int32_t opaque_conn_ref) +{ + _pipe_connections[opaque_conn_ref & MENU_CONN_MASK] = opaque_conn_ref; +} + +void Application::delete_controller(int32_t opaque_conn_ref) +{ + _pipe_connections.erase(opaque_conn_ref & MENU_CONN_MASK); + delete_menu(); +} + +bool Application::connect(const std::string& host, int port, int sport, const std::string& password) +{ + _client.set_target(host, port, sport); + _client.set_password(password); + if (!set_channels_security(port, sport)) { + return false; + } + register_channels(); + connect(); + return true; +} + +void Application::show_me(bool full_screen, bool auto_display_res) +{ + if (auto_display_res) { + Monitor* mon = find_monitor(0); + ASSERT(mon); + Point size = mon->get_size(); + _main_screen->set_mode(size.x, size.y, 32); + } + if (full_screen) { + enter_full_screen(); + } else { + _main_screen->show(true, NULL); + } +} +void Application::hide_me() +{ + if (_full_screen) { + exit_full_screen(); + } + hide(); +} + +void Application::set_hotkeys(const std::string& hotkeys) +{ + std::auto_ptr<HotKeysParser> parser(new HotKeysParser(hotkeys, _commands_map)); + _hot_keys = parser->get(); +} + +int Application::get_controller_menu_item_id(int32_t opaque_conn_ref, uint32_t msg_id) +{ + return APP_CMD_CONTROLLER_MENU_MASK | ((opaque_conn_ref & MENU_CONN_MASK) << MENU_CONN_SHIFT) | + (msg_id & MENU_ID_MASK); +} + +void Application::set_menu(Menu* menu) +{ + _app_menu.reset(menu->ref()); + update_menu(); +} + +void Application::delete_menu() +{ + init_menu(); + update_menu(); +} + #ifdef REDKEY_DEBUG static void show_red_key(RedKey key) @@ -1454,7 +1532,7 @@ uint32_t Application::get_mouse_mode() return _client.get_mouse_mode(); } -void Application::set_title(std::wstring& title) +void Application::set_title(const std::wstring& title) { _title = title; @@ -1737,7 +1815,7 @@ void Application::on_cmd_line_invalid_arg(const char* arg0, const char* what, co bool Application::process_cmd_line(int argc, char** argv) { - std::string host; + std::string host = ""; int sport = -1; int port = -1; bool auto_display_res = false; @@ -1758,12 +1836,12 @@ bool Application::process_cmd_line(int argc, char** argv) SPICE_OPT_ENABLE_CHANNELS, SPICE_OPT_DISABLE_CHANNELS, SPICE_OPT_CANVAS_TYPE, + SPICE_OPT_CONTROLLER, }; CmdLineParser parser("Spice client", false); parser.add(SPICE_OPT_HOST, "host", "spice server address", "host", true, 'h'); - parser.set_reqired(SPICE_OPT_HOST); parser.add(SPICE_OPT_PORT, "port", "spice server port", "port", true, 'p'); parser.add(SPICE_OPT_SPORT, "secure-port", "spice server secure port", "port", true, 's'); parser.add(SPICE_OPT_SECURE_CHANNELS, "secure-channels", @@ -1795,6 +1873,8 @@ 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_CONTROLLER, "controller", "enable external controller"); + _peer_con_opt[RED_CHANNEL_MAIN] = RedPeer::ConnectionOptions::CON_OP_INVALID; _peer_con_opt[RED_CHANNEL_DISPLAY] = RedPeer::ConnectionOptions::CON_OP_INVALID; _peer_con_opt[RED_CHANNEL_INPUTS] = RedPeer::ConnectionOptions::CON_OP_INVALID; @@ -1878,6 +1958,14 @@ bool Application::process_cmd_line(int argc, char** argv) return false; } break; + case SPICE_OPT_CONTROLLER: + if (argc > 2) { + std::cout << "controller cannot be combined with other options\n"; + _exit_code = SPICEC_ERROR_CODE_INVALID_ARG; + return false; + } + _enable_controller = true; + return true; case CmdLineParser::OPTION_HELP: parser.show_help(); return false; @@ -1889,13 +1977,43 @@ bool Application::process_cmd_line(int argc, char** argv) } } + if (host.empty()) { + std::cout << "missing --host\n"; + return false; + } + if (parser.is_set(SPICE_OPT_SECURE_CHANNELS) && !parser.is_set(SPICE_OPT_SPORT)) { Platform::term_printf("%s: missing --secure-port\n", argv[0]); _exit_code = SPICEC_ERROR_CODE_CMD_LINE_ERROR; return false; } + if (!set_channels_security(port, sport)) { + Platform::term_printf("%s: missing --port or --sport\n", argv[0]); + return false; + } + register_channels(); + + _client.init(host.c_str(), port, sport, password.c_str(), auto_display_res); + if (auto_display_res) { + Monitor* mon = find_monitor(0); + ASSERT(mon); + Point size = mon->get_size(); + _main_screen->set_mode(size.x, size.y, 32); + } + + if (full_screen) { + enter_full_screen(); + } else { + _main_screen->show(true, NULL); + } + return true; +} + +bool Application::set_channels_security(int port, int sport) +{ PeerConnectionOptMap::iterator iter = _peer_con_opt.begin(); + for (; iter != _peer_con_opt.end(); iter++) { if ((*iter).second == RedPeer::ConnectionOptions::CON_OP_SECURE) { continue; @@ -1905,26 +2023,29 @@ bool Application::process_cmd_line(int argc, char** argv) continue; } - if (parser.is_set(SPICE_OPT_PORT) && parser.is_set(SPICE_OPT_SPORT)) { + if (port != -1 && sport != -1) { (*iter).second = RedPeer::ConnectionOptions::CON_OP_BOTH; continue; } - if (parser.is_set(SPICE_OPT_PORT)) { + if (port != -1) { (*iter).second = RedPeer::ConnectionOptions::CON_OP_UNSECURE; continue; } - if (parser.is_set(SPICE_OPT_SPORT)) { + if (sport != -1) { (*iter).second = RedPeer::ConnectionOptions::CON_OP_SECURE; continue; } - Platform::term_printf("%s: missing --port or --sport\n", argv[0]); _exit_code = SPICEC_ERROR_CODE_CMD_LINE_ERROR; return false; } + return true; +} +void Application::register_channels() +{ if (_enabled_channels[RED_CHANNEL_DISPLAY]) { _client.register_channel_factory(DisplayChannel::Factory()); } @@ -1944,21 +2065,6 @@ bool Application::process_cmd_line(int argc, char** argv) if (_enabled_channels[RED_CHANNEL_RECORD]) { _client.register_channel_factory(RecordChannel::Factory()); } - - _client.init(host.c_str(), port, sport, password.c_str(), auto_display_res); - if (auto_display_res) { - Monitor* mon = find_monitor(0); - ASSERT(mon); - Point size = mon->get_size(); - _main_screen->set_mode(size.x, size.y, 32); - } - - if (full_screen) { - enter_full_screen(); - } else { - _main_screen->show(true, NULL); - } - return true; } void Application::init_logger() |
