From 2163aa87d4c767f1124a02afc1c0b86f7f49833a Mon Sep 17 00:00:00 2001 From: dijunkun Date: Thu, 30 May 2024 16:12:53 +0800 Subject: [PATCH] The connection can use only one peer to realize server and client --- src/connection/connection.cpp | 78 +-- src/connection/connection.h | 22 +- src/gui/main.cpp | 2 +- src/gui/main_single_peer.cpp | 874 ++++++++++++++++++++++++++++++++ src/localization/localization.h | 23 +- src/render/render.cpp | 395 --------------- src/render/render.h | 100 ---- thirdparty/projectx | 2 +- xmake.lua | 15 +- 9 files changed, 927 insertions(+), 584 deletions(-) create mode 100644 src/gui/main_single_peer.cpp delete mode 100644 src/render/render.cpp delete mode 100644 src/render/render.h diff --git a/src/connection/connection.cpp b/src/connection/connection.cpp index ba39ee7..8d08691 100644 --- a/src/connection/connection.cpp +++ b/src/connection/connection.cpp @@ -7,31 +7,18 @@ #include "log.h" #include "platform.h" -void ServerReceiveVideoBuffer(const char *data, size_t size, - const char *user_id, size_t user_id_size) {} +void ReceiveVideoBuffer(const char *data, size_t size, const char *user_id, + size_t user_id_size) {} -void ClientReceiveVideoBuffer(const char *data, size_t size, - const char *user_id, size_t user_id_size) {} +void ReceiveAudioBuffer(const char *data, size_t size, const char *user_id, + size_t user_id_size) {} -void ServerReceiveAudioBuffer(const char *data, size_t size, - const char *user_id, size_t user_id_size) {} +void ReceiveDataBuffer(const char *data, size_t size, const char *user_id, + size_t user_id_size) {} -void ClientReceiveAudioBuffer(const char *data, size_t size, - const char *user_id, size_t user_id_size) {} +void SignalStatus(SignalStatus status) {} -void ServerReceiveDataBuffer(const char *data, size_t size, const char *user_id, - size_t user_id_size) {} - -void ClientReceiveDataBuffer(const char *data, size_t size, const char *user_id, - size_t user_id_size) {} - -void ServerSignalStatus(SignalStatus status) {} - -void ClientSignalStatus(SignalStatus status) {} - -void ServerConnectionStatus(ConnectionStatus status) {} - -void ClientConnectionStatus(ConnectionStatus status) {} +void ConnectionStatus(ConnectionStatus status) {} Connection::Connection() {} @@ -44,35 +31,20 @@ int Connection::DeskConnectionInit() { std::string mac_addr_str = GetMac(); mac_addr_str_ = mac_addr_str; - server_params_.cfg_path = - f.good() ? "../../../../config/config.ini" : "config.ini"; - server_params_.on_receive_video_buffer = ServerReceiveVideoBuffer; - server_params_.on_receive_audio_buffer = ServerReceiveAudioBuffer; - server_params_.on_receive_data_buffer = ServerReceiveDataBuffer; - server_params_.on_signal_status = ServerSignalStatus; - server_params_.on_connection_status = ServerConnectionStatus; + params_.cfg_path = f.good() ? "../../../../config/config.ini" : "config.ini"; + params_.on_receive_video_buffer = ReceiveVideoBuffer; + params_.on_receive_audio_buffer = ReceiveAudioBuffer; + params_.on_receive_data_buffer = ReceiveDataBuffer; + params_.on_signal_status = SignalStatus; + params_.on_connection_status = ConnectionStatus; - client_params_.cfg_path = - f.good() ? "../../../../config/config.ini" : "config.ini"; - client_params_.on_receive_video_buffer = ClientReceiveVideoBuffer; - client_params_.on_receive_audio_buffer = ClientReceiveAudioBuffer; - client_params_.on_receive_data_buffer = ClientReceiveDataBuffer; - client_params_.on_signal_status = ClientSignalStatus; - client_params_.on_connection_status = ClientConnectionStatus; + peer_ = CreatePeer(¶ms_); + LOG_INFO("Create peer"); + user_id_ = "S-" + mac_addr_str_; + Init(peer_, user_id_.c_str()); + LOG_INFO("Peer init finish"); - peer_server_ = CreatePeer(&server_params_); - LOG_INFO("Create peer_server_"); - server_user_id_ = "S-" + mac_addr_str_; - Init(peer_server_, server_user_id_.c_str()); - LOG_INFO("peer_server_ init finish"); - - peer_client_ = CreatePeer(&client_params_); - LOG_INFO("Create peer_client_"); - client_user_id_ = "C-" + mac_addr_str_; - Init(peer_client_, client_user_id_.c_str()); - LOG_INFO("peer_client_ init finish"); - - while (SignalStatus::SignalConnected != server_signal_status_) { + while (SignalStatus::SignalConnected != signal_status_) { std::this_thread::sleep_for(std::chrono::seconds(1)); } @@ -96,7 +68,7 @@ int Connection::DeskConnectionInit() { auto tc = duration.count() * 1000; if (tc >= 0) { - SendData(peer_server_, DATA_TYPE::VIDEO, (const char *)data, + SendData(peer_, DATA_TYPE::VIDEO, (const char *)data, NV12_BUFFER_SIZE); last_frame_time_ = now_time; } @@ -125,9 +97,9 @@ int Connection::DeskConnectionInit() { int Connection::DeskConnectionCreate(const char *input_password) { input_password_ = input_password; - is_created_connection_ = CreateConnection(peer_server_, mac_addr_str_.c_str(), - input_password_.c_str()) - ? false - : true; + is_created_connection_ = + CreateConnection(peer_, mac_addr_str_.c_str(), input_password_.c_str()) + ? false + : true; return 0; } \ No newline at end of file diff --git a/src/connection/connection.h b/src/connection/connection.h index 2ab881c..ea2d20c 100644 --- a/src/connection/connection.h +++ b/src/connection/connection.h @@ -20,21 +20,17 @@ class Connection { ~Connection(); public: - int DeskConnectionInit(const char *input_password, int screen_width, - int screen_height); - int DeskConnectionCreate(); + int DeskConnectionInit(); + int DeskConnectionCreate(const char *input_password); private: - PeerPtr *peer_server_ = nullptr; - PeerPtr *peer_client_ = nullptr; + PeerPtr *peer_ = nullptr; std::string mac_addr_str_ = ""; - Params server_params_; - Params client_params_; + Params params_; - std::string server_user_id_ = ""; - std::string client_user_id_ = ""; + std::string user_id_ = ""; std::string input_password_ = ""; @@ -52,12 +48,8 @@ class Connection { std::chrono::steady_clock::time_point last_frame_time_; #endif - std::atomic server_connection_status_{ - ConnectionStatus::Closed}; - std::atomic client_connection_status_{ - ConnectionStatus::Closed}; - std::atomic server_signal_status_{SignalStatus::SignalClosed}; - std::atomic client_signal_status_{SignalStatus::SignalClosed}; + std::atomic connection_status_{ConnectionStatus::Closed}; + std::atomic signal_status_{SignalStatus::SignalClosed}; }; #endif \ No newline at end of file diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 347c823..1c9d906 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -8,7 +8,7 @@ int main(int argc, char *argv[]) { Connection connection; connection.DeskConnectionInit(); - connection.DeskConnectionCreate(); + connection.DeskConnectionCreate("123456"); // connection.Create("123456", 800, 600); main_window.Run(); diff --git a/src/gui/main_single_peer.cpp b/src/gui/main_single_peer.cpp new file mode 100644 index 0000000..0c4283b --- /dev/null +++ b/src/gui/main_single_peer.cpp @@ -0,0 +1,874 @@ +#include +#include +#ifdef _WIN32 +#ifdef REMOTE_DESK_DEBUG +#pragma comment(linker, "/subsystem:\"console\"") +#else +#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") +#endif +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../../thirdparty/projectx/src/interface/x.h" +#include "config_center.h" +#include "device_controller_factory.h" +#include "imgui.h" +#include "imgui_impl_sdl2.h" +#include "imgui_impl_sdlrenderer2.h" +#include "log.h" +#include "platform.h" +#include "screen_capturer_factory.h" + +#define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2 + +#ifdef REMOTE_DESK_DEBUG +#define MOUSE_CONTROL 0 +#else +#define MOUSE_CONTROL 1 +#endif + +#define CHINESE_FONT 1 + +int screen_w = 1280, screen_h = 720; +int window_w = 1280, window_h = 720; +const int pixel_w = 1280, pixel_h = 720; + +unsigned char dst_buffer[pixel_w * pixel_h * 3 / 2]; +unsigned char audio_buffer[960]; +SDL_Texture *sdlTexture = nullptr; +SDL_Renderer *sdlRenderer = nullptr; +SDL_Rect sdlRect; +SDL_Window *window; +static SDL_AudioDeviceID input_dev; +static SDL_AudioDeviceID output_dev; + +uint32_t start_time, end_time, elapsed_time; +uint32_t frame_count = 0; +int fps = 0; + +static std::atomic audio_buffer_fresh{false}; +static uint32_t last_ts = 0; + +int dst_bufsize; +struct SwrContext *swr_ctx; + +int ret; + +int audio_len = 0; + +std::string window_title = "Remote Desk Client"; +std::string connection_status_str = "-"; +std::string signal_status_str = "-"; + +std::atomic signal_status{SignalStatus::SignalClosed}; +std::atomic connection_status{ConnectionStatus::Closed}; + +// Refresh Event +#define REFRESH_EVENT (SDL_USEREVENT + 1) +#define QUIT_EVENT (SDL_USEREVENT + 2) + +typedef struct { + char password[7]; +} CDCache; + +int thread_exit = 0; +PeerPtr *peer_server = nullptr; +// PeerPtr *peer_server = nullptr; +bool joined = false; +bool received_frame = false; +bool menu_hovered = false; + +static bool connect_button_pressed = false; +static bool fullscreen_button_pressed = false; + +#if CHINESE_FONT +static const char *connect_label = u8"连接"; +static const char *fullscreen_label = u8"全屏"; +#else +static const char *connect_label = "Connect"; +static const char *fullscreen_label = "FULLSCREEN"; +#endif +static char input_password[7] = ""; +static FILE *cd_cache_file = nullptr; +static CDCache cd_cache; + +static bool is_create_connection = false; +static bool done = false; + +ScreenCapturerFactory *screen_capturer_factory = nullptr; +ScreenCapturer *screen_capturer = nullptr; + +DeviceControllerFactory *device_controller_factory = nullptr; +MouseController *mouse_controller = nullptr; + +ConfigCenter config_center; + +char *nv12_buffer = nullptr; + +#ifdef __linux__ +std::chrono::_V2::system_clock::time_point last_frame_time_; +#else +std::chrono::steady_clock::time_point last_frame_time_; +#endif + +inline int ProcessMouseKeyEven(SDL_Event &ev) { + float ratio = (float)(1280.0 / window_w); + + RemoteAction remote_action; + remote_action.m.x = (size_t)(ev.button.x * ratio); + remote_action.m.y = (size_t)(ev.button.y * ratio); + + if (SDL_KEYDOWN == ev.type) // SDL_KEYUP + { + // printf("SDLK_DOWN: %d\n", SDL_KeyCode(ev.key.keysym.sym)); + if (SDLK_DOWN == ev.key.keysym.sym) { + // printf("SDLK_DOWN \n"); + + } else if (SDLK_UP == ev.key.keysym.sym) { + // printf("SDLK_UP \n"); + + } else if (SDLK_LEFT == ev.key.keysym.sym) { + // printf("SDLK_LEFT \n"); + + } else if (SDLK_RIGHT == ev.key.keysym.sym) { + // printf("SDLK_RIGHT \n"); + } + } else if (SDL_MOUSEBUTTONDOWN == ev.type) { + remote_action.type = ControlType::mouse; + if (SDL_BUTTON_LEFT == ev.button.button) { + remote_action.m.flag = MouseFlag::left_down; + } else if (SDL_BUTTON_RIGHT == ev.button.button) { + remote_action.m.flag = MouseFlag::right_down; + } + SendData(peer_server, DATA_TYPE::DATA, (const char *)&remote_action, + sizeof(remote_action)); + } else if (SDL_MOUSEBUTTONUP == ev.type) { + remote_action.type = ControlType::mouse; + if (SDL_BUTTON_LEFT == ev.button.button) { + remote_action.m.flag = MouseFlag::left_up; + } else if (SDL_BUTTON_RIGHT == ev.button.button) { + remote_action.m.flag = MouseFlag::right_up; + } + SendData(peer_server, DATA_TYPE::DATA, (const char *)&remote_action, + sizeof(remote_action)); + } else if (SDL_MOUSEMOTION == ev.type) { + remote_action.type = ControlType::mouse; + remote_action.m.flag = MouseFlag::move; + SendData(peer_server, DATA_TYPE::DATA, (const char *)&remote_action, + sizeof(remote_action)); + } else if (SDL_QUIT == ev.type) { + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); + printf("SDL_QUIT\n"); + return 0; + } + + return 0; +} + +void SdlCaptureAudioIn(void *userdata, Uint8 *stream, int len) { + if (1) { + if ("Connected" == connection_status_str) { + SendData(peer_server, DATA_TYPE::AUDIO, (const char *)stream, len); + } + } else { + memcpy(audio_buffer, stream, len); + audio_len = len; + SDL_Delay(10); + audio_buffer_fresh = true; + } +} + +void SdlCaptureAudioOut(void *userdata, Uint8 *stream, int len) { + if (!audio_buffer_fresh) { + return; + } + + SDL_memset(stream, 0, len); + + if (audio_len == 0) { + return; + } else { + } + + len = (len > audio_len ? audio_len : len); + SDL_MixAudioFormat(stream, audio_buffer, AUDIO_S16LSB, len, + SDL_MIX_MAXVOLUME); + audio_buffer_fresh = false; +} + +void ServerReceiveVideoBuffer(const char *data, size_t size, + const char *user_id, size_t user_id_size) { + if (joined) { + memcpy(dst_buffer, data, size); + + SDL_Event event; + event.type = REFRESH_EVENT; + SDL_PushEvent(&event); + received_frame = true; + } +} + +void ClientReceiveVideoBuffer(const char *data, size_t size, + const char *user_id, size_t user_id_size) { + // std::cout << "Receive: [" << user_id << "] " << std::endl; + if (joined) { + memcpy(dst_buffer, data, size); + + SDL_Event event; + event.type = REFRESH_EVENT; + SDL_PushEvent(&event); + received_frame = true; + } +} + +void ServerReceiveAudioBuffer(const char *data, size_t size, + const char *user_id, size_t user_id_size) { + // memset(audio_buffer, 0, size); + // memcpy(audio_buffer, data, size); + // audio_len = size; + audio_buffer_fresh = true; + + SDL_QueueAudio(output_dev, data, (Uint32)size); + // printf("queue audio\n"); +} + +void ClientReceiveAudioBuffer(const char *data, size_t size, + const char *user_id, size_t user_id_size) { + // std::cout << "Client receive audio, size " << size << ", user [" << user_id + // << "] " << std::endl; + SDL_QueueAudio(output_dev, data, (Uint32)size); +} + +void ServerReceiveDataBuffer(const char *data, size_t size, const char *user_id, + size_t user_id_size) { + std::string user(user_id, user_id_size); + + RemoteAction remote_action; + memcpy(&remote_action, data, sizeof(remote_action)); + + // std::cout << "remote_action: " << remote_action.type << " " + // << remote_action.m.flag << " " << remote_action.m.x << " " + // << remote_action.m.y << std::endl; +#if MOUSE_CONTROL + if (mouse_controller) { + mouse_controller->SendCommand(remote_action); + } +#endif +} + +void ClientReceiveDataBuffer(const char *data, size_t size, const char *user_id, + size_t user_id_size) {} + +void SignalStatus(SignalStatus status) { + signal_status = status; + if (SignalStatus::SignalConnecting == status) { + signal_status_str = "SignalConnecting"; + } else if (SignalStatus::SignalConnected == status) { + signal_status_str = "SignalConnected"; + } else if (SignalStatus::SignalFailed == status) { + signal_status_str = "SignalFailed"; + } else if (SignalStatus::SignalClosed == status) { + signal_status_str = "SignalClosed"; + } else if (SignalStatus::SignalReconnecting == status) { + signal_status_str = "SignalReconnecting"; + } +} + +void ConnectionStatus(ConnectionStatus status) { + connection_status = status; + if (ConnectionStatus::Connecting == status) { + connection_status_str = "Connecting"; + } else if (ConnectionStatus::Connected == status) { + connection_status_str = "Connected"; + joined = true; + } else if (ConnectionStatus::Disconnected == status) { + connection_status_str = "Disconnected"; + } else if (ConnectionStatus::Failed == status) { + connection_status_str = "Failed"; + } else if (ConnectionStatus::Closed == status) { + connection_status_str = "Closed"; + } else if (ConnectionStatus::IncorrectPassword == status) { + connection_status_str = "Incorrect password"; + if (connect_button_pressed) { + connect_button_pressed = false; + joined = false; + connect_label = connect_button_pressed ? "Disconnect" : "Connect"; + } + } else if (ConnectionStatus::NoSuchTransmissionId == status) { + connection_status_str = "No such transmission id"; + if (connect_button_pressed) { + connect_button_pressed = false; + joined = false; + connect_label = connect_button_pressed ? "Disconnect" : "Connect"; + } + } +} + +int main(int argc, char *argv[]) { + LOG_INFO("Remote desk"); + + last_ts = static_cast( + std::chrono::duration_cast( + std::chrono::high_resolution_clock::now().time_since_epoch()) + .count()); + + cd_cache_file = fopen("cache.cd", "r+"); + if (cd_cache_file) { + fseek(cd_cache_file, 0, SEEK_SET); + fread(&cd_cache.password, sizeof(cd_cache.password), 1, cd_cache_file); + fclose(cd_cache_file); + strncpy(input_password, cd_cache.password, sizeof(cd_cache.password)); + } + + // Setup SDL + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | + SDL_INIT_GAMECONTROLLER) != 0) { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // From 2.0.18: Enable native IME. +#ifdef SDL_HINT_IME_SHOW_UI + SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); +#endif + + // Create window with SDL_Renderer graphics context + SDL_WindowFlags window_flags = + (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + window = SDL_CreateWindow("Remote Desk", SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, window_w, window_h, + window_flags); + + SDL_DisplayMode DM; + SDL_GetCurrentDisplayMode(0, &DM); + screen_w = DM.w; + screen_h = DM.h; + + sdlRenderer = SDL_CreateRenderer( + window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); + if (sdlRenderer == nullptr) { + SDL_Log("Error creating SDL_Renderer!"); + return 0; + } + + Uint32 pixformat = 0; + pixformat = SDL_PIXELFORMAT_NV12; + + sdlTexture = SDL_CreateTexture(sdlRenderer, pixformat, + SDL_TEXTUREACCESS_STREAMING, pixel_w, pixel_h); + + // Audio + SDL_AudioSpec want_in, have_in, want_out, have_out; + SDL_zero(want_in); + want_in.freq = 48000; + want_in.format = AUDIO_S16LSB; + want_in.channels = 1; + want_in.samples = 480; + want_in.callback = SdlCaptureAudioIn; + + input_dev = SDL_OpenAudioDevice(NULL, 1, &want_in, &have_in, 0); + if (input_dev == 0) { + SDL_Log("Failed to open input: %s", SDL_GetError()); + // return 1; + } + + SDL_zero(want_out); + want_out.freq = 48000; + want_out.format = AUDIO_S16LSB; + want_out.channels = 1; + // want_out.silence = 0; + want_out.samples = 480; + want_out.callback = NULL; + + output_dev = SDL_OpenAudioDevice(NULL, 0, &want_out, &have_out, 0); + if (output_dev == 0) { + SDL_Log("Failed to open input: %s", SDL_GetError()); + // return 1; + } + + SDL_PauseAudioDevice(input_dev, 0); + SDL_PauseAudioDevice(output_dev, 0); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO &io = ImGui::GetIO(); + + io.ConfigFlags |= + ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= + ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + +#if CHINESE_FONT + // Load Fonts +#ifdef _WIN32 + std::string default_font_path = "c:/windows/fonts/simhei.ttf"; + std::ifstream font_path_f(default_font_path.c_str()); + std::string font_path = + font_path_f.good() ? "c:/windows/fonts/simhei.ttf" : ""; + if (!font_path.empty()) { + io.Fonts->AddFontFromFileTTF(font_path.c_str(), 13.0f, NULL, + io.Fonts->GetGlyphRangesChineseFull()); + } +#elif __APPLE__ + std::string default_font_path = "/System/Library/Fonts/PingFang.ttc"; + std::ifstream font_path_f(default_font_path.c_str()); + std::string font_path = + font_path_f.good() ? "/System/Library/Fonts/PingFang.ttc" : ""; + if (!font_path.empty()) { + io.Fonts->AddFontFromFileTTF(font_path.c_str(), 13.0f, NULL, + io.Fonts->GetGlyphRangesChineseFull()); + } +#elif __linux__ + io.Fonts->AddFontFromFileTTF("c:/windows/fonts/msyh.ttc", 13.0f, NULL, + io.Fonts->GetGlyphRangesChineseFull()); +#endif +#endif + + // Setup Dear ImGui style + // ImGui::StyleColorsDark(); + ImGui::StyleColorsLight(); + + // Setup Platform/Renderer backends + ImGui_ImplSDL2_InitForSDLRenderer(window, sdlRenderer); + ImGui_ImplSDLRenderer2_Init(sdlRenderer); + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + std::string mac_addr_str = GetMac(); + + std::thread rtc_thread( + [](int screen_width, int screen_height) { + std::string default_cfg_path = "../../../../config/config.ini"; + std::ifstream f(default_cfg_path.c_str()); + + std::string mac_addr_str = GetMac(); + + Params server_params; + server_params.cfg_path = + f.good() ? "../../../../config/config.ini" : "config.ini"; + server_params.on_receive_video_buffer = ServerReceiveVideoBuffer; + server_params.on_receive_audio_buffer = ServerReceiveAudioBuffer; + server_params.on_receive_data_buffer = ServerReceiveDataBuffer; + server_params.on_signal_status = SignalStatus; + server_params.on_connection_status = ConnectionStatus; + + std::string transmission_id = "000001"; + + peer_server = CreatePeer(&server_params); + LOG_INFO("Create peer_server"); + std::string server_user_id = "S-" + mac_addr_str; + Init(peer_server, server_user_id.c_str()); + LOG_INFO("peer_server init finish"); + + { + while (SignalStatus::SignalConnected != signal_status && !done) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + + if (done) { + return; + } + + std::string user_id = "S-" + mac_addr_str; + is_create_connection = + CreateConnection(peer_server, mac_addr_str.c_str(), + input_password) + ? false + : true; + + nv12_buffer = new char[NV12_BUFFER_SIZE]; + + // Screen capture + screen_capturer_factory = new ScreenCapturerFactory(); + screen_capturer = (ScreenCapturer *)screen_capturer_factory->Create(); + + last_frame_time_ = std::chrono::high_resolution_clock::now(); + ScreenCapturer::RECORD_DESKTOP_RECT rect; + rect.left = 0; + rect.top = 0; + rect.right = screen_w; + rect.bottom = screen_h; + + int screen_capturer_init_ret = screen_capturer->Init( + rect, 60, + [](unsigned char *data, int size, int width, int height) -> void { + auto now_time = std::chrono::high_resolution_clock::now(); + std::chrono::duration duration = + now_time - last_frame_time_; + auto tc = duration.count() * 1000; + + if (tc >= 0) { + SendData(peer_server, DATA_TYPE::VIDEO, (const char *)data, + NV12_BUFFER_SIZE); + last_frame_time_ = now_time; + } + }); + + if (0 == screen_capturer_init_ret) { + screen_capturer->Start(); + } else { + screen_capturer->Destroy(); + screen_capturer = nullptr; + } + + // Mouse control + device_controller_factory = new DeviceControllerFactory(); + mouse_controller = + (MouseController *)device_controller_factory->Create( + DeviceControllerFactory::Device::Mouse); + int mouse_controller_init_ret = + mouse_controller->Init(screen_w, screen_h); + if (0 != mouse_controller_init_ret) { + mouse_controller->Destroy(); + mouse_controller = nullptr; + } + } + }, + screen_w, screen_h); + + // Main loop + while (!done) { + // Start the Dear ImGui frame + ImGui_ImplSDLRenderer2_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + ImGui::NewFrame(); + + if (joined && !menu_hovered) { + ImGui::SetMouseCursor(ImGuiMouseCursor_None); + } + + { + static float f = 0.0f; + static int counter = 0; + + const ImGuiViewport *main_viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Once); + + // ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); + +#if CHINESE_FONT + ImGui::SetNextWindowSize(ImVec2(160, 210)); +#else + ImGui::SetNextWindowSize(ImVec2(180, 210)); +#endif + +#if CHINESE_FONT + if (!joined) { + ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); + ImGui::Begin(u8"菜单", nullptr, + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | + ImGuiWindowFlags_NoMove); + } else { + ImGui::SetNextWindowCollapsed(true, ImGuiCond_Once); + ImGui::Begin(u8"菜单", nullptr, ImGuiWindowFlags_None); + } +#else + if (!joined) { + ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); + ImGui::Begin("Menu", nullptr, + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | + ImGuiWindowFlags_NoMove); + } else { + ImGui::SetNextWindowCollapsed(true, ImGuiCond_Once); + ImGui::Begin("Menu", nullptr, ImGuiWindowFlags_None); + } +#endif + + { + menu_hovered = ImGui::IsWindowHovered(); +#if CHINESE_FONT + ImGui::Text(u8"本机ID:"); +#else + ImGui::Text("LOCAL ID:"); +#endif + ImGui::SameLine(); + ImGui::SetNextItemWidth(90); +#if CHINESE_FONT + ImGui::SetCursorPosX(60.0f); +#else + ImGui::SetCursorPosX(80.0f); +#endif + ImGui::InputText( + "##local_id", (char *)mac_addr_str.c_str(), + mac_addr_str.length() + 1, + ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_ReadOnly); + +#if CHINESE_FONT + ImGui::Text(u8"密码:"); +#else + ImGui::Text("PASSWORD:"); +#endif + ImGui::SameLine(); + char input_password_tmp[7] = ""; + std::string input_password_str = "123456"; + strncpy(input_password_tmp, input_password, sizeof(input_password)); + ImGui::SetNextItemWidth(90); +#if CHINESE_FONT + ImGui::SetCursorPosX(60.0f); + ImGui::InputTextWithHint("##server_pwd", u8"最长6个字符", + input_password, IM_ARRAYSIZE(input_password), + ImGuiInputTextFlags_CharsNoBlank); +#else + ImGui::SetCursorPosX(80.0f); + ImGui::InputTextWithHint("##server_pwd", "max 6 chars", input_password, + IM_ARRAYSIZE(input_password), + ImGuiInputTextFlags_CharsNoBlank); +#endif + if (strcmp(input_password_tmp, input_password)) { + cd_cache_file = fopen("cache.cd", "w+"); + if (cd_cache_file) { + fseek(cd_cache_file, 0, SEEK_SET); + strncpy(cd_cache.password, input_password, sizeof(input_password)); + fwrite(&cd_cache.password, sizeof(cd_cache.password), 1, + cd_cache_file); + fclose(cd_cache_file); + } + LeaveConnection(peer_server); + CreateConnection(peer_server, mac_addr_str.c_str(), input_password); + } + + ImGui::Spacing(); + + ImGui::Separator(); + + ImGui::Spacing(); + { + { + static char remote_id[20] = ""; +#if CHINESE_FONT + ImGui::Text(u8"远端ID:"); +#else + ImGui::Text("REMOTE ID:"); +#endif + ImGui::SameLine(); + ImGui::SetNextItemWidth(90); +#if CHINESE_FONT + ImGui::SetCursorPosX(60.0f); +#else + ImGui::SetCursorPosX(80.0f); +#endif + ImGui::InputTextWithHint("##remote_id", mac_addr_str.c_str(), + remote_id, IM_ARRAYSIZE(remote_id), + ImGuiInputTextFlags_CharsUppercase | + ImGuiInputTextFlags_CharsNoBlank); + + ImGui::Spacing(); + +#if CHINESE_FONT + ImGui::Text(u8"密码:"); +#else + ImGui::Text("PASSWORD:"); +#endif + ImGui::SameLine(); + ImGui::SetNextItemWidth(90); + static char client_password[20] = ""; +#if CHINESE_FONT + ImGui::SetCursorPosX(60.0f); + ImGui::InputTextWithHint("##client_pwd", u8"最长6个字符", + client_password, + IM_ARRAYSIZE(client_password), + ImGuiInputTextFlags_CharsNoBlank); +#else + ImGui::SetCursorPosX(80.0f); + ImGui::InputTextWithHint("##client_pwd", "max 6 chars", + client_password, + IM_ARRAYSIZE(client_password), + ImGuiInputTextFlags_CharsNoBlank); +#endif + + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + if (ImGui::Button(connect_label)) { + int ret = -1; + if ("SignalConnected" == signal_status_str) { +#if CHINESE_FONT + if (strcmp(connect_label, u8"连接") == 0 && !joined) { +#else + if (strcmp(connect_label, "Connect") == 0 && !joined) { +#endif + std::string user_id = "C-" + mac_addr_str; + ret = JoinConnection(peer_server, remote_id, client_password); + if (0 == ret) { + // joined = true; + } +#if CHINESE_FONT + } else if (strcmp(connect_label, u8"断开连接") == 0 && joined) { +#else + } else if (strcmp(connect_label, "Disconnect") == 0 && joined) { +#endif + ret = LeaveConnection(peer_server); + CreateConnection(peer_server, mac_addr_str.c_str(), + input_password); + memset(audio_buffer, 0, 960); + if (0 == ret) { + joined = false; + received_frame = false; + } + } + + if (0 == ret) { + connect_button_pressed = !connect_button_pressed; +#if CHINESE_FONT + connect_label = + connect_button_pressed ? u8"断开连接" : u8"连接"; +#else + connect_label = + connect_button_pressed ? "Disconnect" : "Connect"; +#endif + } + } + } + } + } + } + + ImGui::Spacing(); + + ImGui::Separator(); + + ImGui::Spacing(); + +#if CHINESE_FONT + if (ImGui::Button(fullscreen_label)) { + if (strcmp(fullscreen_label, u8"全屏") == 0) { +#else + if (ImGui::Button(fullscreen_label)) { + if (strcmp(fullscreen_label, "FULLSCREEN") == 0) { +#endif + SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); + } else { + SDL_SetWindowFullscreen(window, SDL_FALSE); + } + fullscreen_button_pressed = !fullscreen_button_pressed; +#if CHINESE_FONT + fullscreen_label = fullscreen_button_pressed ? u8"退出全屏" : u8"全屏"; +#else + fullscreen_label = + fullscreen_button_pressed ? "EXIT FULLSCREEN" : "FULLSCREEN"; +#endif + } + ImGui::End(); + } + + // Rendering + ImGui::Render(); + SDL_RenderSetScale(sdlRenderer, io.DisplayFramebufferScale.x, + io.DisplayFramebufferScale.y); + + SDL_Event event; + while (SDL_PollEvent(&event)) { + ImGui_ImplSDL2_ProcessEvent(&event); + if (event.type == SDL_QUIT) { + done = true; + } else if (event.type == SDL_WINDOWEVENT && + event.window.event == SDL_WINDOWEVENT_RESIZED) { + // SDL_GetWindowSize(window, &window_w, &window_h); + + int window_w_last = window_w; + int window_h_last = window_h; + + SDL_GetWindowSize(window, &window_w, &window_h); + + int w_change_ratio = abs(window_w - window_w_last) / 16; + int h_change_ratio = abs(window_h - window_h_last) / 9; + + if (w_change_ratio > h_change_ratio) { + window_h = window_w * 9 / 16; + } else { + window_w = window_h * 16 / 9; + } + + SDL_SetWindowSize(window, window_w, window_h); + } else if (event.type == SDL_WINDOWEVENT && + event.window.event == SDL_WINDOWEVENT_CLOSE && + event.window.windowID == SDL_GetWindowID(window)) { + done = true; + } else if (event.type == REFRESH_EVENT) { + sdlRect.x = 0; + sdlRect.y = 0; + sdlRect.w = window_w; + sdlRect.h = window_h; + + SDL_UpdateTexture(sdlTexture, NULL, dst_buffer, pixel_w); + } else { + if (joined) { + ProcessMouseKeyEven(event); + } + } + } + + SDL_RenderClear(sdlRenderer); + SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect); + + if (!joined || !received_frame) { + SDL_RenderClear(sdlRenderer); + SDL_SetRenderDrawColor( + sdlRenderer, (Uint8)(clear_color.x * 0), (Uint8)(clear_color.y * 0), + (Uint8)(clear_color.z * 0), (Uint8)(clear_color.w * 0)); + } + + ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData()); + SDL_RenderPresent(sdlRenderer); + + frame_count++; + end_time = SDL_GetTicks(); + elapsed_time = end_time - start_time; + if (elapsed_time >= 1000) { + fps = frame_count / (elapsed_time / 1000); + frame_count = 0; + window_title = "Remote Desk Client FPS [" + std::to_string(fps) + + "] status [" + signal_status_str + "|" + + connection_status_str + "]"; + // For MacOS, UI frameworks can only be called from the main thread + SDL_SetWindowTitle(window, window_title.c_str()); + start_time = end_time; + } + } + + // Cleanup + + if (is_create_connection) { + LeaveConnection(peer_server); + } + + rtc_thread.join(); + SDL_CloseAudioDevice(output_dev); + SDL_CloseAudioDevice(input_dev); + + if (screen_capturer) { + screen_capturer->Destroy(); + } + + if (mouse_controller) { + mouse_controller->Destroy(); + } + + ImGui_ImplSDLRenderer2_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + ImGui::DestroyContext(); + + SDL_DestroyRenderer(sdlRenderer); + SDL_DestroyWindow(window); + + SDL_CloseAudio(); + SDL_Quit(); + + return 0; +} \ No newline at end of file diff --git a/src/localization/localization.h b/src/localization/localization.h index 6608756..e21f3ad 100644 --- a/src/localization/localization.h +++ b/src/localization/localization.h @@ -1,4 +1,4 @@ -/* +/* * @Author: DI JUNKUN * @Date: 2024-05-29 * Copyright (c) 2024 by DI JUNKUN, All Rights Reserved. @@ -12,16 +12,17 @@ namespace localization { -std::vector menu = {u8"˵", "Menu"}; -std::vector local_id = {u8"ID:", "Local ID:"}; -std::vector password = {u8":", "Password:"}; -std::vector max_password_len = {u8"6ַ", "Max 6 chars"}; -std::vector remote_id = {u8"ԶID:", "Remote ID:"}; -std::vector connect = {u8"", "Connect"}; -std::vector disconnect = {u8"Ͽ", "Disconnect"}; -std::vector reset_ratio = {u8"ñ", "Reset ratio"}; -std::vector fullscreen = {u8"ȫ", "Fullscreen"}; -std::vector exit_fullscreen = {u8"˳ȫ", "Exit fullscreen"}; +std::vector menu = {u8"菜单", "Menu"}; +std::vector local_id = {u8"本机ID:", "Local ID:"}; +std::vector password = {u8"密码:", "Password:"}; +std::vector max_password_len = {u8"最大6个租房字符", + "Max 6 chars"}; +std::vector remote_id = {u8"远端ID:", "Remote ID:"}; +std::vector connect = {u8"连接", "Connect"}; +std::vector disconnect = {u8"断开连接", "Disconnect"}; +std::vector reset_ratio = {u8"重置窗口", "Reset ratio"}; +std::vector fullscreen = {u8"全屏", "Fullscreen"}; +std::vector exit_fullscreen = {u8"退出全屏", "Exit fullscreen"}; } // namespace localization diff --git a/src/render/render.cpp b/src/render/render.cpp deleted file mode 100644 index 6a56764..0000000 --- a/src/render/render.cpp +++ /dev/null @@ -1,395 +0,0 @@ -#include "render.h" - -int RenderMainWindow(int argc, char *argv[]) { - LOG_INFO("Remote desk"); - - last_ts = static_cast( - std::chrono::duration_cast( - std::chrono::high_resolution_clock::now().time_since_epoch()) - .count()); - - cd_cache_file = fopen("cache.cd", "r+"); - if (cd_cache_file) { - fseek(cd_cache_file, 0, SEEK_SET); - fread(&cd_cache.password, sizeof(cd_cache.password), 1, cd_cache_file); - fclose(cd_cache_file); - strncpy(input_password, cd_cache.password, sizeof(cd_cache.password)); - } - - // Setup SDL - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | - SDL_INIT_GAMECONTROLLER) != 0) { - printf("Error: %s\n", SDL_GetError()); - return -1; - } - - // From 2.0.18: Enable native IME. -#ifdef SDL_HINT_IME_SHOW_UI - SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); -#endif - - // Create window with SDL_Renderer graphics context - SDL_WindowFlags window_flags = - (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); - window = SDL_CreateWindow("Remote Desk", SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, window_w, window_h, - window_flags); - - SDL_DisplayMode DM; - SDL_GetCurrentDisplayMode(0, &DM); - screen_w = DM.w; - screen_h = DM.h; - - sdlRenderer = SDL_CreateRenderer( - window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); - if (sdlRenderer == nullptr) { - SDL_Log("Error creating SDL_Renderer!"); - return 0; - } - - Uint32 pixformat = 0; - pixformat = SDL_PIXELFORMAT_NV12; - - sdlTexture = SDL_CreateTexture(sdlRenderer, pixformat, - SDL_TEXTUREACCESS_STREAMING, pixel_w, pixel_h); - - // Setup Dear ImGui context - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - ImGuiIO &io = ImGui::GetIO(); - - io.ConfigFlags |= - ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - io.ConfigFlags |= - ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls - -#if CHINESE_FONT - // Load Fonts -#ifdef _WIN32 - std::string default_font_path = "c:/windows/fonts/simhei.ttf"; - std::ifstream font_path_f(default_font_path.c_str()); - std::string font_path = - font_path_f.good() ? "c:/windows/fonts/simhei.ttf" : ""; - if (!font_path.empty()) { - io.Fonts->AddFontFromFileTTF(font_path.c_str(), 13.0f, NULL, - io.Fonts->GetGlyphRangesChineseFull()); - } -#elif __APPLE__ - std::string default_font_path = "/System/Library/Fonts/PingFang.ttc"; - std::ifstream font_path_f(default_font_path.c_str()); - std::string font_path = - font_path_f.good() ? "/System/Library/Fonts/PingFang.ttc" : ""; - if (!font_path.empty()) { - io.Fonts->AddFontFromFileTTF(font_path.c_str(), 13.0f, NULL, - io.Fonts->GetGlyphRangesChineseFull()); - } -#elif __linux__ - io.Fonts->AddFontFromFileTTF("c:/windows/fonts/msyh.ttc", 13.0f, NULL, - io.Fonts->GetGlyphRangesChineseFull()); -#endif -#endif - - // Setup Dear ImGui style - // ImGui::StyleColorsDark(); - ImGui::StyleColorsLight(); - - // Setup Platform/Renderer backends - ImGui_ImplSDL2_InitForSDLRenderer(window, sdlRenderer); - ImGui_ImplSDLRenderer2_Init(sdlRenderer); - - // Our state - bool show_demo_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); - - std::string mac_addr_str = GetMac(); - - // Main loop - while (!done) { - // Start the Dear ImGui frame - ImGui_ImplSDLRenderer2_NewFrame(); - ImGui_ImplSDL2_NewFrame(); - ImGui::NewFrame(); - - if (joined && !menu_hovered) { - ImGui::SetMouseCursor(ImGuiMouseCursor_None); - } - - { - static float f = 0.0f; - static int counter = 0; - - const ImGuiViewport *main_viewport = ImGui::GetMainViewport(); - ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Once); - - // ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); - -#if CHINESE_FONT - ImGui::SetNextWindowSize(ImVec2(160, 210)); -#else - ImGui::SetNextWindowSize(ImVec2(180, 210)); -#endif - -#if CHINESE_FONT - if (!joined) { - ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); - ImGui::Begin(u8"˵", nullptr, - ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | - ImGuiWindowFlags_NoMove); - } else { - ImGui::SetNextWindowCollapsed(true, ImGuiCond_Once); - ImGui::Begin(u8"˵", nullptr, ImGuiWindowFlags_None); - } -#else - if (!joined) { - ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); - ImGui::Begin("Menu", nullptr, - ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | - ImGuiWindowFlags_NoMove); - } else { - ImGui::SetNextWindowCollapsed(true, ImGuiCond_Once); - ImGui::Begin("Menu", nullptr, ImGuiWindowFlags_None); - } -#endif - - { - menu_hovered = ImGui::IsWindowHovered(); -#if CHINESE_FONT - ImGui::Text(u8"ID:"); -#else - ImGui::Text("LOCAL ID:"); -#endif - ImGui::SameLine(); - ImGui::SetNextItemWidth(90); -#if CHINESE_FONT - ImGui::SetCursorPosX(60.0f); -#else - ImGui::SetCursorPosX(80.0f); -#endif - ImGui::InputText( - "##local_id", (char *)mac_addr_str.c_str(), - mac_addr_str.length() + 1, - ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_ReadOnly); - -#if CHINESE_FONT - ImGui::Text(u8":"); -#else - ImGui::Text("PASSWORD:"); -#endif - ImGui::SameLine(); - char input_password_tmp[7] = ""; - std::string input_password_str = "123456"; - strncpy(input_password_tmp, input_password, sizeof(input_password)); - ImGui::SetNextItemWidth(90); -#if CHINESE_FONT - ImGui::SetCursorPosX(60.0f); - ImGui::InputTextWithHint("##server_pwd", u8"6ַ", - input_password, IM_ARRAYSIZE(input_password), - ImGuiInputTextFlags_CharsNoBlank); -#else - ImGui::SetCursorPosX(80.0f); - ImGui::InputTextWithHint("##server_pwd", "max 6 chars", input_password, - IM_ARRAYSIZE(input_password), - ImGuiInputTextFlags_CharsNoBlank); -#endif - if (strcmp(input_password_tmp, input_password)) { - cd_cache_file = fopen("cache.cd", "w+"); - if (cd_cache_file) { - fseek(cd_cache_file, 0, SEEK_SET); - strncpy(cd_cache.password, input_password, sizeof(input_password)); - fwrite(&cd_cache.password, sizeof(cd_cache.password), 1, - cd_cache_file); - fclose(cd_cache_file); - } - } - - ImGui::Spacing(); - - ImGui::Separator(); - - ImGui::Spacing(); - { - { - static char remote_id[20] = ""; -#if CHINESE_FONT - ImGui::Text(u8"ԶID:"); -#else - ImGui::Text("REMOTE ID:"); -#endif - ImGui::SameLine(); - ImGui::SetNextItemWidth(90); -#if CHINESE_FONT - ImGui::SetCursorPosX(60.0f); -#else - ImGui::SetCursorPosX(80.0f); -#endif - ImGui::InputTextWithHint("##remote_id", mac_addr_str.c_str(), - remote_id, IM_ARRAYSIZE(remote_id), - ImGuiInputTextFlags_CharsUppercase | - ImGuiInputTextFlags_CharsNoBlank); - - ImGui::Spacing(); - -#if CHINESE_FONT - ImGui::Text(u8":"); -#else - ImGui::Text("PASSWORD:"); -#endif - ImGui::SameLine(); - ImGui::SetNextItemWidth(90); - static char client_password[20] = ""; -#if CHINESE_FONT - ImGui::SetCursorPosX(60.0f); - ImGui::InputTextWithHint("##client_pwd", u8"6ַ", - client_password, - IM_ARRAYSIZE(client_password), - ImGuiInputTextFlags_CharsNoBlank); -#else - ImGui::SetCursorPosX(80.0f); - ImGui::InputTextWithHint("##client_pwd", "max 6 chars", - client_password, - IM_ARRAYSIZE(client_password), - ImGuiInputTextFlags_CharsNoBlank); -#endif - - ImGui::Spacing(); - ImGui::Separator(); - ImGui::Spacing(); - - if (ImGui::Button(connect_label)) { - int ret = -1; - if ("ClientSignalConnected" == client_signal_status_str) { -#if CHINESE_FONT - if (strcmp(connect_label, u8"") == 0 && !joined) { -#else - if (strcmp(connect_label, "Connect") == 0 && !joined) { -#endif - std::string user_id = "C-" + mac_addr_str; - -#if CHINESE_FONT - } else if (strcmp(connect_label, u8"Ͽ") == 0 && joined) { -#else - } else if (strcmp(connect_label, "Disconnect") == 0 && joined) { -#endif - - memset(audio_buffer, 0, 960); - if (0 == ret) { - joined = false; - received_frame = false; - } - } - - if (0 == ret) { - connect_button_pressed = !connect_button_pressed; -#if CHINESE_FONT - connect_label = - connect_button_pressed ? u8"Ͽ" : u8""; -#else - connect_label = - connect_button_pressed ? "Disconnect" : "Connect"; -#endif - } - } - } - } - } - } - - ImGui::Spacing(); - - ImGui::Separator(); - - ImGui::Spacing(); - - { -#if CHINESE_FONT - if (ImGui::Button(u8"ô")) { -#else - if (ImGui::Button("Resize Window")) { -#endif - SDL_GetWindowSize(window, &window_w, &window_h); - - if (window_h != window_w * 9 / 16) { - window_w = window_h * 16 / 9; - } - - SDL_SetWindowSize(window, window_w, window_h); - } - } - - ImGui::SameLine(); - -#if CHINESE_FONT - if (ImGui::Button(fullscreen_label)) { - if (strcmp(fullscreen_label, u8"ȫ") == 0) { -#else - if (ImGui::Button(fullscreen_label)) { - if (strcmp(fullscreen_label, "FULLSCREEN") == 0) { -#endif - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); - } else { - SDL_SetWindowFullscreen(window, SDL_FALSE); - } - fullscreen_button_pressed = !fullscreen_button_pressed; -#if CHINESE_FONT - fullscreen_label = fullscreen_button_pressed ? u8"˳ȫ" : u8"ȫ"; -#else - fullscreen_label = - fullscreen_button_pressed ? "EXIT FULLSCREEN" : "FULLSCREEN"; -#endif - } - ImGui::End(); - } - - // Rendering - ImGui::Render(); - SDL_RenderSetScale(sdlRenderer, io.DisplayFramebufferScale.x, - io.DisplayFramebufferScale.y); - - SDL_RenderClear(sdlRenderer); - SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect); - - if (!joined || !received_frame) { - SDL_RenderClear(sdlRenderer); - SDL_SetRenderDrawColor( - sdlRenderer, (Uint8)(clear_color.x * 0), (Uint8)(clear_color.y * 0), - (Uint8)(clear_color.z * 0), (Uint8)(clear_color.w * 0)); - } - - ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData()); - SDL_RenderPresent(sdlRenderer); - - frame_count++; - end_time = SDL_GetTicks(); - elapsed_time = end_time - start_time; - if (elapsed_time >= 1000) { - fps = frame_count / (elapsed_time / 1000); - frame_count = 0; - window_title = "Remote Desk Client FPS [" + std::to_string(fps) + - "] status [" + server_signal_status_str + "|" + - client_signal_status_str + "|" + - server_connection_status_str + "|" + - client_connection_status_str + "]"; - // For MacOS, UI frameworks can only be called from the main thread - SDL_SetWindowTitle(window, window_title.c_str()); - start_time = end_time; - } - } - - // Cleanup - - SDL_CloseAudioDevice(output_dev); - SDL_CloseAudioDevice(input_dev); - - ImGui_ImplSDLRenderer2_Shutdown(); - ImGui_ImplSDL2_Shutdown(); - ImGui::DestroyContext(); - - SDL_DestroyRenderer(sdlRenderer); - SDL_DestroyWindow(window); - - SDL_CloseAudio(); - SDL_Quit(); - - return 0; -} \ No newline at end of file diff --git a/src/render/render.h b/src/render/render.h deleted file mode 100644 index 27f077b..0000000 --- a/src/render/render.h +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include -#ifdef _WIN32 -#ifdef REMOTE_DESK_DEBUG -#pragma comment(linker, "/subsystem:\"console\"") -#else -#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") -#endif -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "config_center.h" -#include "imgui.h" -#include "imgui_impl_sdl2.h" -#include "imgui_impl_sdlrenderer2.h" -#include "log.h" -#include "platform.h" - -#define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2 - -#ifdef REMOTE_DESK_DEBUG -#define MOUSE_CONTROL 0 -#else -#define MOUSE_CONTROL 1 -#endif - -#define CHINESE_FONT 1 - -int screen_w = 1280, screen_h = 720; -int window_w = 1280, window_h = 720; -const int pixel_w = 1280, pixel_h = 720; - -unsigned char dst_buffer[pixel_w * pixel_h * 3 / 2]; -unsigned char audio_buffer[960]; -SDL_Texture *sdlTexture = nullptr; -SDL_Renderer *sdlRenderer = nullptr; -SDL_Rect sdlRect; -SDL_Window *window; -static SDL_AudioDeviceID input_dev; -static SDL_AudioDeviceID output_dev; - -uint32_t start_time, end_time, elapsed_time; -uint32_t frame_count = 0; -int fps = 0; - -static std::atomic audio_buffer_fresh{false}; -static uint32_t last_ts = 0; - -int dst_bufsize; -struct SwrContext *swr_ctx; - -int ret; - -int audio_len = 0; - -std::string window_title = "Remote Desk Client"; -std::string server_connection_status_str = "-"; -std::string client_connection_status_str = "-"; -std::string server_signal_status_str = "-"; -std::string client_signal_status_str = "-"; - -// Refresh Event -#define REFRESH_EVENT (SDL_USEREVENT + 1) -#define QUIT_EVENT (SDL_USEREVENT + 2) - -typedef struct { - char password[7]; -} CDCache; - -bool joined = false; -bool received_frame = false; -bool menu_hovered = false; - -static bool connect_button_pressed = false; -static bool fullscreen_button_pressed = false; - -#if CHINESE_FONT -static const char *connect_label = u8""; -static const char *fullscreen_label = u8"ȫ"; -#else -static const char *connect_label = "Connect"; -static const char *fullscreen_label = "FULLSCREEN"; -#endif -static char input_password[7] = ""; -static FILE *cd_cache_file = nullptr; -static CDCache cd_cache; - -static bool is_create_connection = false; -static bool done = false; - -ConfigCenter config_center; \ No newline at end of file diff --git a/thirdparty/projectx b/thirdparty/projectx index 9122d0d..2c640db 160000 --- a/thirdparty/projectx +++ b/thirdparty/projectx @@ -1 +1 @@ -Subproject commit 9122d0d15f3b3094e613cdfc372c7f8a0f6b6d62 +Subproject commit 2c640db2553d1e9e4da396857abf706c18049015 diff --git a/xmake.lua b/xmake.lua index 74f8f01..963b57c 100644 --- a/xmake.lua +++ b/xmake.lua @@ -95,12 +95,6 @@ target("config_center") add_files("src/config_center/*.cpp") add_includedirs("src/config_center", {public = true}) -target("render") - set_kind("object") - add_deps("log", "common", "config_center") - add_files("src/render/*.cpp") - add_includedirs("src/render", {public = true}) - target("localization") set_kind("headeronly") add_includedirs("src/localization", {public = true}) @@ -108,6 +102,11 @@ target("localization") target("connection") set_kind("object") add_deps("log", "common", "screen_capturer", "device_controller") + if is_os("macosx") then + add_packages("ffmpeg") + elseif is_os("linux") then + add_packages("ffmpeg") + end add_files("src/connection/*.cpp") add_includedirs("src/connection", {public = true}) @@ -119,7 +118,7 @@ target("main_window") target("remote_desk") set_kind("binary") - add_deps("log", "common", "projectx", "screen_capturer", "device_controller", "render", "main_window", "connection") + add_deps("log", "common", "projectx", "screen_capturer", "device_controller", "main_window", "connection") if is_os("macosx") then add_packages("ffmpeg") elseif is_os("linux") then @@ -135,7 +134,7 @@ target("remote_desk") -- elseif is_os("linux") then -- add_packages("ffmpeg") -- end --- add_files("src/gui/main.cpp") +-- add_files("src/gui/main_single_peer.cpp") -- after_install(function (target) -- os.cp("$(projectdir)/thirdparty/nvcodec/Lib/x64/*.so", "$(projectdir)/out/bin")