From 2d6cfb5c76a4de6247c2f5c6162d4d4bb01ed206 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Wed, 6 Dec 2023 15:24:01 +0800 Subject: [PATCH] Support cursor control on MacOS --- src/gui/main.cpp | 57 ++++++++++++++++--- .../macosx/screen_capture_avf.cpp | 4 +- thirdparty/projectx | 2 +- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 904194f..6e77d21 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -6,6 +6,7 @@ #include #include #elif __APPLE__ +#include #include #include #include @@ -407,6 +408,10 @@ void ServerReceiveDataBuffer(const char *data, size_t size, const char *user_id, // std::cout << "remote_action: " << remote_action.type << " " // << remote_action.m.flag << " " << remote_action.m.x << " " // << remote_action.m.y << std::endl; + + int mouse_pos_x = remote_action.m.x * screen_w / 1280; + int mouse_pos_y = remote_action.m.y * screen_h / 720; +#if 1 #ifdef _WIN32 INPUT ip; @@ -428,18 +433,43 @@ void ServerReceiveDataBuffer(const char *data, size_t size, const char *user_id, ip.mi.mouseData = 0; ip.mi.time = 0; -#if MOUSE_CONTROL // Set cursor pos SetCursorPos(ip.mi.dx, ip.mi.dy); // Send the press if (ip.mi.dwFlags != MOUSEEVENTF_MOVE) { SendInput(1, &ip, sizeof(INPUT)); } -#endif + // std::cout << "Receive data from [" << user << "], " << ip.type << " " // << ip.mi.dwFlags << " " << ip.mi.dx << " " << ip.mi.dy // << std::endl; } + +#elif __APPLE__ + if (remote_action.type == ControlType::mouse) { + CGEventRef mouse_event; + CGEventType mouse_type; + + if (remote_action.m.flag == MouseFlag::left_down) { + mouse_type = kCGEventLeftMouseDown; + } else if (remote_action.m.flag == MouseFlag::left_up) { + mouse_type = kCGEventLeftMouseUp; + } else if (remote_action.m.flag == MouseFlag::right_down) { + mouse_type = kCGEventRightMouseDown; + } else if (remote_action.m.flag == MouseFlag::right_up) { + mouse_type = kCGEventRightMouseUp; + } else { + mouse_type = kCGEventMouseMoved; + } + + mouse_event = CGEventCreateMouseEvent(NULL, mouse_type, + CGPointMake(mouse_pos_x, mouse_pos_y), + kCGMouseButtonLeft); + + CGEventPost(kCGHIDEventTap, mouse_event); + CFRelease(mouse_event); + } +#endif #endif } @@ -450,16 +480,20 @@ void ClientReceiveDataBuffer(const char *data, size_t size, const char *user_id, 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; + std::cout << "remote_action: " << remote_action.type << " " + << remote_action.m.flag << " " << remote_action.m.x << " " + << remote_action.m.y << std::endl; + + int mouse_pos_x = remote_action.m.x * screen_w / 1280; + int mouse_pos_y = remote_action.m.y * screen_h / 720; + #ifdef _WIN32 INPUT ip; if (remote_action.type == ControlType::mouse) { ip.type = INPUT_MOUSE; - ip.mi.dx = remote_action.m.x * screen_w / 1280; - ip.mi.dy = remote_action.m.y * screen_h / 720; + ip.mi.dx = mouse_pos_x; + ip.mi.dy = mouse_pos_y; if (remote_action.m.flag == MouseFlag::left_down) { ip.mi.dwFlags = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE; } else if (remote_action.m.flag == MouseFlag::left_up) { @@ -486,6 +520,15 @@ void ClientReceiveDataBuffer(const char *data, size_t size, const char *user_id, // << ip.mi.dwFlags << " " << ip.mi.dx << " " << ip.mi.dy // << std::endl; } + +#elif __APPLE__ + CGEventRef mouse_event; + mouse_event = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, + CGPointMake(mouse_pos_x, mouse_pos_y), + kCGMouseButtonLeft); + CGEventPost(kCGHIDEventTap, mouse_event); + CFRelease(mouse_event); + #endif } diff --git a/src/screen_capture/macosx/screen_capture_avf.cpp b/src/screen_capture/macosx/screen_capture_avf.cpp index 3f5be83..6a7e881 100644 --- a/src/screen_capture/macosx/screen_capture_avf.cpp +++ b/src/screen_capture/macosx/screen_capture_avf.cpp @@ -28,8 +28,10 @@ int ScreenCaptureAvf::Init(const RECORD_DESKTOP_RECT &rect, const int fps, avdevice_register_all(); // grabbing frame rate - av_dict_set(&options_, "framerate", "30", 0); + av_dict_set(&options_, "framerate", "60", 0); av_dict_set(&options_, "pixel_format", "nv12", 0); + // show remote cursor + av_dict_set(&options_, "capture_cursor", "1", 0); // Make the grabbed area follow the mouse // av_dict_set(&options_, "follow_mouse", "centered", 0); // Video frame size. The default is to capture the full screen diff --git a/thirdparty/projectx b/thirdparty/projectx index 62f85bb..d4abc31 160000 --- a/thirdparty/projectx +++ b/thirdparty/projectx @@ -1 +1 @@ -Subproject commit 62f85bb33374ad9815d532c97d3e46cb7b6cfcb8 +Subproject commit d4abc318a4fe28ea23d62d416512415f716fe136