main.cc (4617B)
1 /* 2 * Copyright 2012 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 // clang-format off 12 // clang formating would change include order. 13 #include <windows.h> 14 #include <shellapi.h> // must come after windows.h 15 // clang-format on 16 17 #include <cstddef> 18 #include <cstdio> 19 #include <cwchar> 20 #include <memory> 21 #include <string> 22 #include <vector> 23 24 #include "absl/flags/flag.h" 25 #include "absl/flags/parse.h" 26 #include "api/environment/environment.h" 27 #include "api/environment/environment_factory.h" 28 #include "api/field_trials.h" 29 #include "api/make_ref_counted.h" 30 #include "examples/peerconnection/client/conductor.h" 31 #include "examples/peerconnection/client/flag_defs.h" 32 #include "examples/peerconnection/client/main_wnd.h" 33 #include "examples/peerconnection/client/peer_connection_client.h" 34 #include "rtc_base/checks.h" 35 #include "rtc_base/physical_socket_server.h" 36 #include "rtc_base/ssl_adapter.h" 37 #include "rtc_base/string_utils.h" // For ToUtf8 38 #include "rtc_base/thread.h" 39 #include "rtc_base/win32_socket_init.h" 40 41 namespace { 42 // A helper class to translate Windows command line arguments into UTF8, 43 // which then allows us to just pass them to the flags system. 44 // This encapsulates all the work of getting the command line and translating 45 // it to an array of 8-bit strings; all you have to do is create one of these, 46 // and then call argc() and argv(). 47 class WindowsCommandLineArguments { 48 public: 49 WindowsCommandLineArguments(); 50 51 WindowsCommandLineArguments(const WindowsCommandLineArguments&) = delete; 52 WindowsCommandLineArguments& operator=(WindowsCommandLineArguments&) = delete; 53 54 int argc() { return argv_.size(); } 55 char** argv() { return argv_.data(); } 56 57 private: 58 // Owned argument strings. 59 std::vector<std::string> args_; 60 // Pointers, to get layout compatible with char** argv. 61 std::vector<char*> argv_; 62 }; 63 64 WindowsCommandLineArguments::WindowsCommandLineArguments() { 65 // start by getting the command line. 66 LPCWSTR command_line = ::GetCommandLineW(); 67 // now, convert it to a list of wide char strings. 68 int argc; 69 LPWSTR* wide_argv = ::CommandLineToArgvW(command_line, &argc); 70 71 // iterate over the returned wide strings; 72 for (int i = 0; i < argc; ++i) { 73 args_.push_back(webrtc::ToUtf8(wide_argv[i], wcslen(wide_argv[i]))); 74 // make sure the argv array points to the string data. 75 argv_.push_back(const_cast<char*>(args_.back().c_str())); 76 } 77 LocalFree(wide_argv); 78 } 79 80 } // namespace 81 int PASCAL wWinMain(HINSTANCE instance, 82 HINSTANCE prev_instance, 83 wchar_t* cmd_line, 84 int cmd_show) { 85 webrtc::WinsockInitializer winsock_init; 86 webrtc::PhysicalSocketServer ss; 87 webrtc::AutoSocketServerThread main_thread(&ss); 88 89 WindowsCommandLineArguments win_args; 90 int argc = win_args.argc(); 91 char** argv = win_args.argv(); 92 93 absl::ParseCommandLine(argc, argv); 94 95 webrtc::Environment env = 96 webrtc::CreateEnvironment(std::make_unique<webrtc::FieldTrials>( 97 absl::GetFlag(FLAGS_force_fieldtrials))); 98 99 // Abort if the user specifies a port that is outside the allowed 100 // range [1, 65535]. 101 if ((absl::GetFlag(FLAGS_port) < 1) || (absl::GetFlag(FLAGS_port) > 65535)) { 102 printf("Error: %i is not a valid port.\n", absl::GetFlag(FLAGS_port)); 103 return -1; 104 } 105 106 const std::string server = absl::GetFlag(FLAGS_server); 107 MainWnd wnd(server.c_str(), absl::GetFlag(FLAGS_port), 108 absl::GetFlag(FLAGS_autoconnect), absl::GetFlag(FLAGS_autocall)); 109 if (!wnd.Create()) { 110 RTC_DCHECK_NOTREACHED(); 111 return -1; 112 } 113 114 webrtc::InitializeSSL(); 115 PeerConnectionClient client; 116 auto conductor = webrtc::make_ref_counted<Conductor>(env, &client, &wnd); 117 118 // Main loop. 119 MSG msg; 120 BOOL gm; 121 while ((gm = ::GetMessage(&msg, NULL, 0, 0)) != 0 && gm != -1) { 122 if (!wnd.PreTranslateMessage(&msg)) { 123 ::TranslateMessage(&msg); 124 ::DispatchMessage(&msg); 125 } 126 } 127 128 if (conductor->connection_active() || client.is_connected()) { 129 while ((conductor->connection_active() || client.is_connected()) && 130 (gm = ::GetMessage(&msg, NULL, 0, 0)) != 0 && gm != -1) { 131 if (!wnd.PreTranslateMessage(&msg)) { 132 ::TranslateMessage(&msg); 133 ::DispatchMessage(&msg); 134 } 135 } 136 } 137 138 webrtc::CleanupSSL(); 139 return 0; 140 }