diff --git a/src/connection/connection.cpp b/src/connection/connection.cpp deleted file mode 100644 index 00f07c2..0000000 --- a/src/connection/connection.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "connection.h" - -#include -#include -#include - -#include "log.h" -#include "platform.h" - -void ReceiveVideoBufferCb(const char *data, size_t size, const char *user_id, - size_t user_id_size, void *user_data) {} - -void ReceiveAudioBufferCb(const char *data, size_t size, const char *user_id, - size_t user_id_size, void *user_data) {} - -void ReceiveDataBufferCb(const char *data, size_t size, const char *user_id, - size_t user_id_size, void *user_data) {} - -void SignalStatusCb(SignalStatus status, void *user_data) {} - -void ConnectionStatusCb(ConnectionStatus status, void *user_data) {} - -Connection::Connection() {} - -Connection::~Connection() {} - -int Connection::DeskConnectionInit() { - std::string default_cfg_path = "../../../../config/config.ini"; - std::ifstream f(default_cfg_path.c_str()); - - std::string mac_addr_str = GetMac(); - mac_addr_str_ = mac_addr_str; - - params_.cfg_path = f.good() ? "../../../../config/config.ini" : "config.ini"; - params_.on_receive_video_buffer = ReceiveVideoBufferCb; - params_.on_receive_audio_buffer = ReceiveAudioBufferCb; - params_.on_receive_data_buffer = ReceiveDataBufferCb; - - params_.on_signal_status = [](SignalStatus status, void *user_data) { - if (user_data == nullptr) { - return; - } - - Connection *connection = (Connection *)user_data; - connection->signal_status_ = status; - if (SignalStatus::SignalConnecting == status) { - connection->signal_status_str_ = "SignalConnecting"; - } else if (SignalStatus::SignalConnected == status) { - connection->signal_status_str_ = "SignalConnected"; - } else if (SignalStatus::SignalFailed == status) { - connection->signal_status_str_ = "SignalFailed"; - } else if (SignalStatus::SignalClosed == status) { - connection->signal_status_str_ = "SignalClosed"; - } else if (SignalStatus::SignalReconnecting == status) { - connection->signal_status_str_ = "SignalReconnecting"; - } - }; - - params_.on_connection_status = ConnectionStatusCb; - params_.user_data = this; - - peer_ = CreatePeer(¶ms_); - LOG_INFO("Create peer"); - user_id_ = "S-" + mac_addr_str_; - Init(peer_, user_id_.c_str()); - LOG_INFO("Peer init finish"); - - while (SignalStatus::SignalConnected != signal_status_) { - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - -#if 0 - // 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_width; - rect.bottom = screen_height; - - 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_, 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; - } -#endif - - return 0; -} - -int Connection::DeskConnectionCreate(const char *input_password) { - input_password_ = input_password; - 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 deleted file mode 100644 index b30e659..0000000 --- a/src/connection/connection.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * @Author: DI JUNKUN - * @Date: 2024-05-29 - * Copyright (c) 2024 by DI JUNKUN, All Rights Reserved. - */ - -#ifndef _CONNECTION_H_ -#define _CONNECTION_H_ - -#include -#include - -#include "../../thirdparty/projectx/src/interface/x.h" -#include "device_controller_factory.h" -#include "screen_capturer_factory.h" - -class Connection { - public: - Connection(); - ~Connection(); - - public: - int DeskConnectionInit(); - int DeskConnectionCreate(const char *input_password); - - private: - PeerPtr *peer_ = nullptr; - - std::string mac_addr_str_ = ""; - - Params params_; - - std::string user_id_ = ""; - - std::string input_password_ = ""; - - ScreenCapturerFactory *screen_capturer_factory_ = nullptr; - ScreenCapturer *screen_capturer_ = nullptr; - - DeviceControllerFactory *device_controller_factory_ = nullptr; - MouseController *mouse_controller_ = nullptr; - - bool is_created_connection_ = false; - -#ifdef __linux__ - std::chrono::_V2::system_clock::time_point last_frame_time_; -#else - std::chrono::steady_clock::time_point last_frame_time_; -#endif - - public: - ConnectionStatus connection_status_ = ConnectionStatus::Closed; - SignalStatus signal_status_ = SignalStatus::SignalClosed; - - std::string signal_status_str_ = ""; -}; - -#endif \ No newline at end of file diff --git a/src/gui/main.cpp b/src/gui/main.cpp index f1e84b9..47ab36a 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -6,18 +6,12 @@ #endif #endif -#include "connection.h" #include "log.h" #include "main_window.h" int main(int argc, char *argv[]) { LOG_INFO("Remote desk"); MainWindow main_window; - Connection connection; - - connection.DeskConnectionInit(); - connection.DeskConnectionCreate("123456"); - // connection.Create("123456", 800, 600); main_window.Run(); diff --git a/src/gui/mainbak.cpp b/src/gui/mainbak.cpp deleted file mode 100644 index eda6278..0000000 --- a/src/gui/mainbak.cpp +++ /dev/null @@ -1,938 +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 "../../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 server_connection_status_str = "-"; -std::string client_connection_status_str = "-"; -std::string server_signal_status_str = "-"; -std::string client_signal_status_str = "-"; - -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}; - -// 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_client = 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_client, 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_client, 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_client, 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 ("ClientConnected" == client_connection_status_str) { - SendData(peer_client, DATA_TYPE::AUDIO, (const char *)stream, len); - } - - if ("ServerConnected" == server_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 ("ClientConnected" != client_connection_status_str) { - // return; - // } - - 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) {} - -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 ServerSignalStatus(SignalStatus status) { - server_signal_status = status; - if (SignalStatus::SignalConnecting == status) { - server_signal_status_str = "ServerSignalConnecting"; - } else if (SignalStatus::SignalConnected == status) { - server_signal_status_str = "ServerSignalConnected"; - } else if (SignalStatus::SignalFailed == status) { - server_signal_status_str = "ServerSignalFailed"; - } else if (SignalStatus::SignalClosed == status) { - server_signal_status_str = "ServerSignalClosed"; - } else if (SignalStatus::SignalReconnecting == status) { - server_signal_status_str = "ServerSignalReconnecting"; - } -} - -void ClientSignalStatus(SignalStatus status) { - client_signal_status = status; - if (SignalStatus::SignalConnecting == status) { - client_signal_status_str = "ClientSignalConnecting"; - } else if (SignalStatus::SignalConnected == status) { - client_signal_status_str = "ClientSignalConnected"; - } else if (SignalStatus::SignalFailed == status) { - client_signal_status_str = "ClientSignalFailed"; - } else if (SignalStatus::SignalClosed == status) { - client_signal_status_str = "ClientSignalClosed"; - } else if (SignalStatus::SignalReconnecting == status) { - client_signal_status_str = "ClientSignalReconnecting"; - } -} - -void ServerConnectionStatus(ConnectionStatus status) { - server_connection_status = status; - if (ConnectionStatus::Connecting == status) { - server_connection_status_str = "ServerConnecting"; - } else if (ConnectionStatus::Connected == status) { - server_connection_status_str = "ServerConnected"; - } else if (ConnectionStatus::Disconnected == status) { - server_connection_status_str = "ServerDisconnected"; - } else if (ConnectionStatus::Failed == status) { - server_connection_status_str = "ServerFailed"; - } else if (ConnectionStatus::Closed == status) { - server_connection_status_str = "ServerClosed"; - } else if (ConnectionStatus::IncorrectPassword == status) { - server_connection_status_str = "Incorrect password"; - if (connect_button_pressed) { - connect_button_pressed = false; - joined = false; - connect_label = connect_button_pressed ? "Disconnect" : "Connect"; - } - } -} - -void ClientConnectionStatus(ConnectionStatus status) { - client_connection_status = status; - if (ConnectionStatus::Connecting == status) { - client_connection_status_str = "ClientConnecting"; - } else if (ConnectionStatus::Connected == status) { - client_connection_status_str = "ClientConnected"; - joined = true; - } else if (ConnectionStatus::Disconnected == status) { - client_connection_status_str = "ClientDisconnected"; - } else if (ConnectionStatus::Failed == status) { - client_connection_status_str = "ClientFailed"; - } else if (ConnectionStatus::Closed == status) { - client_connection_status_str = "ClientClosed"; - } else if (ConnectionStatus::IncorrectPassword == status) { - client_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) { - client_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 = ServerSignalStatus; - server_params.on_connection_status = ServerConnectionStatus; - - Params client_params; - 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; - - 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"); - - peer_client = CreatePeer(&client_params); - LOG_INFO("Create peer_client"); - std::string 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 && - !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 ("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; - ret = JoinConnection(peer_client, 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_client); - 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_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); - } 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 [" + 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 - - if (is_create_connection) { - LeaveConnection(peer_server); - } - - if (joined) { - LeaveConnection(peer_client); - } - - 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 826e962..038c124 100644 --- a/src/localization/localization.h +++ b/src/localization/localization.h @@ -10,15 +10,17 @@ #include 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 fullscreen = {u8"全屏", "Fullscreen"}; -std::vector exit_fullscreen = {u8"退出全屏", "Exit fullscreen"}; +static std::vector menu = {u8"菜单:", "Menu"}; +static std::vector local_id = {u8"本机ID:", "Local ID:"}; +static std::vector password = {u8"密码:", "Password:"}; +static std::vector max_password_len = {u8"最大6个字符", + "Max 6 chars"}; +static std::vector remote_id = {u8"远端ID:", "Remote ID:"}; +static std::vector connect = {u8"连接", "Connect"}; +static std::vector disconnect = {u8"断开连接", "Disconnect"}; +static std::vector fullscreen = {u8"全屏", "Fullscreen"}; +static std::vector exit_fullscreen = {u8"退出全屏", + "Exit fullscreen"}; } // namespace localization diff --git a/src/main_window/main_window.cpp b/src/main_window/main_window.cpp index 3283334..36ca759 100644 --- a/src/main_window/main_window.cpp +++ b/src/main_window/main_window.cpp @@ -4,13 +4,15 @@ #include #include +#include "device_controller_factory.h" #include "localization.h" #include "log.h" #include "platform.h" +#include "screen_capturer_factory.h" // Refresh Event #define REFRESH_EVENT (SDL_USEREVENT + 1) -#define QUIT_EVENT (SDL_USEREVENT + 2) +#define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2 MainWindow::MainWindow() {} @@ -111,6 +113,97 @@ int MainWindow::Run() { mac_addr_str_ = GetMac(); + std::thread rtc_thread( + [this](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_.cfg_path = + f.good() ? "../../../../config/config.ini" : "config.ini"; + params_.on_receive_video_buffer = OnReceiveVideoBufferCb; + params_.on_receive_audio_buffer = OnReceiveAudioBufferCb; + params_.on_receive_data_buffer = OnReceiveDataBufferCb; + params_.on_signal_status = OnSignalStatusCb; + params_.on_connection_status = OnConnectionStatusCb; + params_.user_data = this; + + std::string transmission_id = "000001"; + + peer_ = CreatePeer(¶ms_); + LOG_INFO("Create peer"); + std::string server_user_id = "S-" + mac_addr_str_; + Init(peer_, server_user_id.c_str()); + LOG_INFO("peer_ init finish"); + + { + while (SignalStatus::SignalConnected != signal_status_ && !exit_) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + + if (exit_) { + return; + } + + std::string user_id = "S-" + mac_addr_str_; + is_create_connection_ = + CreateConnection(peer_, 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_width_; + rect.bottom = screen_height_; + + int screen_capturer_init_ret = screen_capturer_->Init( + rect, 60, + [this](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_, 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_width_, screen_height_); + if (0 != mouse_controller_init_ret) { + mouse_controller_->Destroy(); + mouse_controller_ = nullptr; + } + } + }, + screen_width_, screen_height_); + // Main loop while (!exit_) { localization_language_ = config_center_.GetLanguage(); @@ -122,9 +215,14 @@ int MainWindow::Run() { localization_language_index_last_ = localization_language_index_; } - connect_button_label_ = localization::connect[localization_language_index_]; + connect_button_label_ = + connect_button_pressed_ + ? localization::disconnect[localization_language_index_] + : localization::connect[localization_language_index_]; fullscreen_button_label_ = - localization::fullscreen[localization_language_index_]; + fullscreen_button_pressed_ + ? localization::exit_fullscreen[localization_language_index_] + : localization::fullscreen[localization_language_index_]; // Start the Dear ImGui frame ImGui_ImplSDLRenderer2_NewFrame(); @@ -257,18 +355,28 @@ int MainWindow::Run() { ImGui::Spacing(); if (ImGui::Button(connect_button_label_.c_str())) { - LOG_ERROR("Click connect button"); int ret = -1; - if ("ClientSignalConnected" == client_signal_status_str_) { + if ("SignalConnected" == signal_status_str_) { if (connect_button_label_ == localization::connect[localization_language_index_] && !connection_established_) { std::string user_id = "C-" + mac_addr_str_; + ret = JoinConnection(peer_, remote_id_, client_password_); + if (0 == ret) { + } } else if (connect_button_label_ == localization::disconnect [localization_language_index_] && connection_established_) { + ret = LeaveConnection(peer_); + is_create_connection_ = CreateConnection( + peer_, mac_addr_str_.c_str(), client_password_); + memset(audio_buffer_, 0, 960); + if (0 == ret) { + connection_established_ = false; + received_frame_ = false; + } } if (0 == ret) { @@ -277,7 +385,6 @@ int MainWindow::Run() { connect_button_label_ = connect_button_pressed_ ? localization::disconnect[localization_language_index_] - : localization::connect[localization_language_index_]; } } @@ -294,17 +401,22 @@ int MainWindow::Run() { if (ImGui::Button(fullscreen_button_label_.c_str())) { if (fullscreen_button_label_ == localization::fullscreen[localization_language_index_]) { + main_window_width_before_fullscreen_ = main_window_width_; + main_window_height_before_fullscreen_ = main_window_height_; SDL_SetWindowFullscreen(main_window_, SDL_WINDOW_FULLSCREEN_DESKTOP); + fullscreen_button_pressed_ = true; } else { SDL_SetWindowFullscreen(main_window_, SDL_FALSE); + SDL_SetWindowSize(main_window_, main_window_width_before_fullscreen_, + main_window_height_before_fullscreen_); } fullscreen_button_pressed_ = !fullscreen_button_pressed_; - fullscreen_button_label_ = fullscreen_button_pressed_ ? localization::exit_fullscreen[localization_language_index_] : localization::fullscreen[localization_language_index_]; + fullscreen_button_pressed_ = false; } ImGui::End(); } @@ -343,18 +455,21 @@ int MainWindow::Run() { event.window.windowID == SDL_GetWindowID(main_window_)) { exit_ = true; } else if (event.type == REFRESH_EVENT) { - sdlRect.x = 0; - sdlRect.y = 0; - sdlRect.w = main_window_width_; - sdlRect.h = main_window_height_; + sdl_rect_.x = 0; + sdl_rect_.y = 0; + sdl_rect_.w = main_window_width_; + sdl_rect_.h = main_window_height_; - // SDL_UpdateTexture(sdl_texture_, NULL, dst_buffer, pixel_w); + SDL_UpdateTexture(sdl_texture_, NULL, dst_buffer_, 1280); } else { + if (connection_established_) { + ProcessMouseKeyEven(event); + } } } SDL_RenderClear(sdl_renderer_); - SDL_RenderCopy(sdl_renderer_, sdl_texture_, NULL, &sdlRect); + SDL_RenderCopy(sdl_renderer_, sdl_texture_, NULL, &sdl_rect_); if (!connection_established_ || !received_frame_) { SDL_RenderClear(sdl_renderer_); @@ -373,10 +488,8 @@ int MainWindow::Run() { 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_ + "]"; + "] status [" + connection_status_str_ + "|" + + connection_status_str_ + "]"; // For MacOS, UI frameworks can only be called from the main thread SDL_SetWindowTitle(main_window_, window_title.c_str()); start_time_ = end_time_; @@ -384,6 +497,23 @@ int MainWindow::Run() { } // Cleanup + + if (is_create_connection_) { + LeaveConnection(peer_); + } + + 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(); diff --git a/src/main_window/main_window.h b/src/main_window/main_window.h index 02bee5c..db91bbf 100644 --- a/src/main_window/main_window.h +++ b/src/main_window/main_window.h @@ -10,12 +10,16 @@ #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 "screen_capturer_factory.h" class MainWindow { public: @@ -25,6 +29,28 @@ class MainWindow { public: int Run(); + public: + static void OnReceiveVideoBufferCb(const char *data, size_t size, + const char *user_id, size_t user_id_size, + void *user_data); + + static void OnReceiveAudioBufferCb(const char *data, size_t size, + const char *user_id, size_t user_id_size, + void *user_data); + + static void OnReceiveDataBufferCb(const char *data, size_t size, + const char *user_id, size_t user_id_size, + void *user_data); + + static void OnSignalStatusCb(SignalStatus status, void *user_data); + + static void OnConnectionStatusCb(ConnectionStatus status, void *user_data); + + private: + int ProcessMouseKeyEven(SDL_Event &ev); + void SdlCaptureAudioIn(void *userdata, Uint8 *stream, int len); + void SdlCaptureAudioOut(void *userdata, Uint8 *stream, int len); + private: typedef struct { char password[7]; @@ -42,46 +68,41 @@ class MainWindow { int localization_language_index_ = -1; int localization_language_index_last_ = -1; - private: - int default_main_window_width_ = 1280; - int default_main_window_height_ = 720; - private: std::string window_title = "Remote Desk Client"; + std::string mac_addr_str_ = ""; + std::string connect_button_label_ = "Connect"; + std::string fullscreen_button_label_ = "Fullscreen"; + char input_password_tmp_[7] = ""; + char input_password_[7] = ""; + char remote_id_[20] = ""; + char client_password_[20] = ""; private: int screen_width_ = 1280; int screen_height_ = 720; int main_window_width_ = 1280; int main_window_height_ = 720; + int main_window_width_before_fullscreen_ = 1280; + int main_window_height_before_fullscreen_ = 720; int texture_width_ = 1280; int texture_height_ = 720; SDL_Texture *sdl_texture_ = nullptr; SDL_Renderer *sdl_renderer_ = nullptr; - SDL_Rect sdlRect; + SDL_Rect sdl_rect_; SDL_Window *main_window_; uint32_t pixformat_ = 0; - std::string mac_addr_str_ = ""; - bool exit_ = false; - - std::string connect_button_label_ = "Connect"; - std::string fullscreen_button_label_ = "Fullscreen"; - bool connection_established_ = false; bool menu_hovered_ = false; - - char input_password_tmp_[7] = ""; - char input_password_[7] = ""; - - char remote_id_[20] = ""; - char client_password_[20] = ""; - bool connect_button_pressed_ = false; bool fullscreen_button_pressed_ = false; + bool received_frame_ = false; + bool is_create_connection_ = false; + bool audio_buffer_fresh_ = false; int fps_ = 0; uint32_t start_time_; @@ -89,13 +110,35 @@ class MainWindow { uint32_t elapsed_time_; uint32_t frame_count_ = 0; - bool received_frame_ = false; + private: + ConnectionStatus connection_status_ = ConnectionStatus::Closed; + SignalStatus signal_status_ = SignalStatus::SignalClosed; + std::string signal_status_str_ = ""; + std::string connection_status_str_ = ""; private: - std::string server_connection_status_str_ = "-"; - std::string client_connection_status_str_ = "-"; - std::string server_signal_status_str_ = "-"; - std::string client_signal_status_str_ = "-"; + PeerPtr *peer_ = nullptr; + Params params_; + + private: + SDL_AudioDeviceID input_dev_; + SDL_AudioDeviceID output_dev_; + unsigned char audio_buffer_[960]; + int audio_len_ = 0; + char *nv12_buffer_ = nullptr; + unsigned char *dst_buffer_ = new unsigned char[1280 * 720 * 3]; + + private: + ScreenCapturerFactory *screen_capturer_factory_ = nullptr; + ScreenCapturer *screen_capturer_ = nullptr; + DeviceControllerFactory *device_controller_factory_ = nullptr; + MouseController *mouse_controller_ = nullptr; + +#ifdef __linux__ + std::chrono::_V2::system_clock::time_point last_frame_time_; +#else + std::chrono::steady_clock::time_point last_frame_time_; +#endif }; #endif \ No newline at end of file diff --git a/src/main_window/main_window_callback_func.cpp b/src/main_window/main_window_callback_func.cpp new file mode 100644 index 0000000..b58cfcc --- /dev/null +++ b/src/main_window/main_window_callback_func.cpp @@ -0,0 +1,187 @@ +#include "device_controller.h" +#include "localization.h" +#include "main_window.h" + +// Refresh Event +#define REFRESH_EVENT (SDL_USEREVENT + 1) + +int MainWindow::ProcessMouseKeyEven(SDL_Event &ev) { + float ratio = (float)(1280.0 / main_window_width_); + + 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_, 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_, 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_, 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 MainWindow::SdlCaptureAudioIn(void *userdata, Uint8 *stream, int len) { + if (1) { + if ("Connected" == connection_status_str_) { + SendData(peer_, DATA_TYPE::AUDIO, (const char *)stream, len); + } + } else { + memcpy(audio_buffer_, stream, len); + audio_len_ = len; + SDL_Delay(10); + audio_buffer_fresh_ = true; + } +} + +void MainWindow::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 MainWindow::OnReceiveVideoBufferCb(const char *data, size_t size, + const char *user_id, + size_t user_id_size, void *user_data) { + MainWindow *main_window = (MainWindow *)user_data; + if (main_window->connection_established_) { + memcpy(main_window->dst_buffer_, data, size); + SDL_Event event; + event.type = REFRESH_EVENT; + SDL_PushEvent(&event); + main_window->received_frame_ = true; + } +} + +void MainWindow::OnReceiveAudioBufferCb(const char *data, size_t size, + const char *user_id, + size_t user_id_size, void *user_data) { + MainWindow *main_window = (MainWindow *)user_data; + main_window->audio_buffer_fresh_ = true; + SDL_QueueAudio(main_window->output_dev_, data, (uint32_t)size); +} + +void MainWindow::OnReceiveDataBufferCb(const char *data, size_t size, + const char *user_id, size_t user_id_size, + void *user_data) { + MainWindow *main_window = (MainWindow *)user_data; + std::string user(user_id, user_id_size); + RemoteAction remote_action; + memcpy(&remote_action, data, sizeof(remote_action)); + +#if MOUSE_CONTROL + if (main_window->mouse_controller_) { + main_window->mouse_controller_->SendCommand(remote_action); + } +#endif +} + +void MainWindow::OnSignalStatusCb(SignalStatus status, void *user_data) { + MainWindow *main_window = (MainWindow *)user_data; + main_window->signal_status_ = status; + if (SignalStatus::SignalConnecting == status) { + main_window->signal_status_str_ = "SignalConnecting"; + } else if (SignalStatus::SignalConnected == status) { + main_window->signal_status_str_ = "SignalConnected"; + } else if (SignalStatus::SignalFailed == status) { + main_window->signal_status_str_ = "SignalFailed"; + } else if (SignalStatus::SignalClosed == status) { + main_window->signal_status_str_ = "SignalClosed"; + } else if (SignalStatus::SignalReconnecting == status) { + main_window->signal_status_str_ = "SignalReconnecting"; + } +} + +void MainWindow::OnConnectionStatusCb(ConnectionStatus status, + void *user_data) { + MainWindow *main_window = (MainWindow *)user_data; + main_window->connection_status_ = status; + if (ConnectionStatus::Connecting == status) { + main_window->connection_status_str_ = "Connecting"; + } else if (ConnectionStatus::Connected == status) { + main_window->connection_status_str_ = "Connected"; + main_window->connection_established_ = true; + } else if (ConnectionStatus::Disconnected == status) { + main_window->connection_status_str_ = "Disconnected"; + } else if (ConnectionStatus::Failed == status) { + main_window->connection_status_str_ = "Failed"; + } else if (ConnectionStatus::Closed == status) { + main_window->connection_status_str_ = "Closed"; + } else if (ConnectionStatus::IncorrectPassword == status) { + main_window->connection_status_str_ = "Incorrect password"; + if (main_window->connect_button_pressed_) { + main_window->connect_button_pressed_ = false; + main_window->connection_established_ = false; + main_window->connect_button_label_ = + main_window->connect_button_pressed_ + ? localization::disconnect[main_window + ->localization_language_index_] + : localization::connect[main_window + ->localization_language_index_]; + } + } else if (ConnectionStatus::NoSuchTransmissionId == status) { + main_window->connection_status_str_ = "No such transmission id"; + if (main_window->connect_button_pressed_) { + main_window->connect_button_pressed_ = false; + main_window->connection_established_ = false; + main_window->connect_button_label_ = + main_window->connect_button_pressed_ + ? localization::disconnect[main_window + ->localization_language_index_] + : localization::connect[main_window + ->localization_language_index_]; + } + } +} diff --git a/xmake.lua b/xmake.lua index 963b57c..aaf8808 100644 --- a/xmake.lua +++ b/xmake.lua @@ -99,26 +99,20 @@ target("localization") set_kind("headeronly") add_includedirs("src/localization", {public = true}) -target("connection") +target("main_window") set_kind("object") - add_deps("log", "common", "screen_capturer", "device_controller") + add_deps("log", "common", "localization", "config_center", "projectx", "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}) - -target("main_window") - set_kind("object") - add_deps("log", "common", "localization", "config_center") add_files("src/main_window/*.cpp") add_includedirs("src/main_window", {public = true}) target("remote_desk") set_kind("binary") - add_deps("log", "common", "projectx", "screen_capturer", "device_controller", "main_window", "connection") + add_deps("log", "common", "main_window") if is_os("macosx") then add_packages("ffmpeg") elseif is_os("linux") then @@ -126,24 +120,6 @@ target("remote_desk") end add_files("src/gui/main.cpp") --- target("remote_desk") --- set_kind("binary") --- add_deps("log", "common", "projectx", "screen_capturer", "device_controller", "config_center") --- if is_os("macosx") then --- add_packages("ffmpeg") --- elseif is_os("linux") then --- add_packages("ffmpeg") --- end --- add_files("src/gui/main_single_peer.cpp") - - -- after_install(function (target) - -- os.cp("$(projectdir)/thirdparty/nvcodec/Lib/x64/*.so", "$(projectdir)/out/bin") - -- os.cp("$(projectdir)/thirdparty/nvcodec/Lib/x64/*.so.1", "$(projectdir)/out/bin") - -- os.cp("$(projectdir)/out/lib/*.so", "$(projectdir)/out/bin") - -- os.rm("$(projectdir)/out/include") - -- os.rm("$(projectdir)/out/lib") - -- end) - -- target("screen_capturer") -- set_kind("binary") -- add_packages("sdl2", "imgui", "ffmpeg", "openh264")