mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
Use uinput to control mouse and keyboard on Linux
This commit is contained in:
134
src/gui/main.cpp
134
src/gui/main.cpp
@@ -13,6 +13,8 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <linux/uinput.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@@ -75,6 +77,9 @@ SDL_Rect sdlRect;
|
|||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
static SDL_AudioDeviceID input_dev;
|
static SDL_AudioDeviceID input_dev;
|
||||||
static SDL_AudioDeviceID output_dev;
|
static SDL_AudioDeviceID output_dev;
|
||||||
|
static int uinput_fd;
|
||||||
|
static int fd_mouse = -1;
|
||||||
|
static int fd_kbd = -1;
|
||||||
|
|
||||||
uint32_t start_time, end_time, elapsed_time;
|
uint32_t start_time, end_time, elapsed_time;
|
||||||
uint32_t frame_count = 0;
|
uint32_t frame_count = 0;
|
||||||
@@ -398,6 +403,55 @@ void ClientReceiveAudioBuffer(const char *data, size_t size,
|
|||||||
SDL_QueueAudio(output_dev, data, size);
|
SDL_QueueAudio(output_dev, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void simulate_key(int fd, int kval) {
|
||||||
|
struct input_event event;
|
||||||
|
gettimeofday(&event.time, 0);
|
||||||
|
// <20><><EFBFBD><EFBFBD>kval<61><6C>
|
||||||
|
event.type = EV_KEY;
|
||||||
|
event.value = 1;
|
||||||
|
event.code = kval;
|
||||||
|
write(fd, &event, sizeof(event));
|
||||||
|
// ͬ<><CDAC><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ
|
||||||
|
event.type = EV_SYN;
|
||||||
|
event.value = 0;
|
||||||
|
event.code = SYN_REPORT;
|
||||||
|
write(fd, &event, sizeof(event));
|
||||||
|
|
||||||
|
memset(&event, 0, sizeof(event));
|
||||||
|
gettimeofday(&event.time, 0);
|
||||||
|
// <20>ɿ<EFBFBD>kval<61><6C>
|
||||||
|
event.type = EV_KEY;
|
||||||
|
event.value = 0;
|
||||||
|
event.code = kval;
|
||||||
|
write(fd, &event, sizeof(event));
|
||||||
|
// ͬ<><CDAC><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ
|
||||||
|
event.type = EV_SYN;
|
||||||
|
event.value = 0;
|
||||||
|
event.code = SYN_REPORT;
|
||||||
|
write(fd, &event, sizeof(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD>ģ<EFBFBD><C4A3>
|
||||||
|
void simulate_mouse(int fd, int rel_x, int rel_y) {
|
||||||
|
struct input_event event;
|
||||||
|
gettimeofday(&event.time, 0);
|
||||||
|
// x<><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||||
|
event.type = EV_REL;
|
||||||
|
event.value = rel_x;
|
||||||
|
event.code = REL_X;
|
||||||
|
write(fd, &event, sizeof(event));
|
||||||
|
// y<><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||||
|
event.type = EV_REL;
|
||||||
|
event.value = rel_y;
|
||||||
|
event.code = REL_Y;
|
||||||
|
write(fd, &event, sizeof(event));
|
||||||
|
// ͬ<><CDAC>
|
||||||
|
event.type = EV_SYN;
|
||||||
|
event.value = 0;
|
||||||
|
event.code = SYN_REPORT;
|
||||||
|
write(fd, &event, sizeof(event));
|
||||||
|
}
|
||||||
|
|
||||||
void ServerReceiveDataBuffer(const char *data, size_t size, const char *user_id,
|
void ServerReceiveDataBuffer(const char *data, size_t size, const char *user_id,
|
||||||
size_t user_id_size) {
|
size_t user_id_size) {
|
||||||
std::string user(user_id, user_id_size);
|
std::string user(user_id, user_id_size);
|
||||||
@@ -405,9 +459,9 @@ void ServerReceiveDataBuffer(const char *data, size_t size, const char *user_id,
|
|||||||
RemoteAction remote_action;
|
RemoteAction remote_action;
|
||||||
memcpy(&remote_action, data, sizeof(remote_action));
|
memcpy(&remote_action, data, sizeof(remote_action));
|
||||||
|
|
||||||
// std::cout << "remote_action: " << remote_action.type << " "
|
std::cout << "remote_action: " << remote_action.type << " "
|
||||||
// << remote_action.m.flag << " " << remote_action.m.x << " "
|
<< remote_action.m.flag << " " << remote_action.m.x << " "
|
||||||
// << remote_action.m.y << std::endl;
|
<< remote_action.m.y << std::endl;
|
||||||
|
|
||||||
int mouse_pos_x = remote_action.m.x * screen_w / 1280;
|
int mouse_pos_x = remote_action.m.x * screen_w / 1280;
|
||||||
int mouse_pos_y = remote_action.m.y * screen_h / 720;
|
int mouse_pos_y = remote_action.m.y * screen_h / 720;
|
||||||
@@ -469,6 +523,24 @@ void ServerReceiveDataBuffer(const char *data, size_t size, const char *user_id,
|
|||||||
CGEventPost(kCGHIDEventTap, mouse_event);
|
CGEventPost(kCGHIDEventTap, mouse_event);
|
||||||
CFRelease(mouse_event);
|
CFRelease(mouse_event);
|
||||||
}
|
}
|
||||||
|
#elif __linux__
|
||||||
|
if (remote_action.type == ControlType::mouse) {
|
||||||
|
struct input_event event;
|
||||||
|
memset(&event, 0, sizeof(event));
|
||||||
|
gettimeofday(&event.time, NULL);
|
||||||
|
|
||||||
|
if (remote_action.m.flag == MouseFlag::left_down) {
|
||||||
|
simulate_key(fd_mouse, BTN_LEFT);
|
||||||
|
} else if (remote_action.m.flag == MouseFlag::left_up) {
|
||||||
|
simulate_key(fd_mouse, BTN_LEFT);
|
||||||
|
} else if (remote_action.m.flag == MouseFlag::right_down) {
|
||||||
|
simulate_key(fd_mouse, BTN_RIGHT);
|
||||||
|
} else if (remote_action.m.flag == MouseFlag::right_up) {
|
||||||
|
simulate_key(fd_mouse, BTN_RIGHT);
|
||||||
|
} else {
|
||||||
|
simulate_mouse(fd_mouse, mouse_pos_x, mouse_pos_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -881,6 +953,57 @@ int main() {
|
|||||||
screen_capture->Start();
|
screen_capture->Start();
|
||||||
|
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
|
{
|
||||||
|
uinput_fd = open("/dev/uinput", O_WRONLY | O_NDELAY);
|
||||||
|
if (uinput_fd < 0) {
|
||||||
|
perror("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> /dev/uinput");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_kbd = open("/dev/input/event3", O_RDWR);
|
||||||
|
if (fd_kbd <= 0) {
|
||||||
|
printf("Can not open keyboard input file\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_mouse = open("/dev/input/event2", O_RDWR);
|
||||||
|
if (fd_mouse <= 0) {
|
||||||
|
printf("Can not open mouse input file\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD>uinput<75>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
struct uinput_user_dev uidev;
|
||||||
|
ioctl(uinput_fd, UI_SET_EVBIT, EV_ABS);
|
||||||
|
ioctl(uinput_fd, UI_SET_ABSBIT, ABS_X);
|
||||||
|
ioctl(uinput_fd, UI_SET_ABSBIT, ABS_Y);
|
||||||
|
ioctl(uinput_fd, UI_SET_EVBIT, EV_KEY);
|
||||||
|
ioctl(uinput_fd, UI_SET_KEYBIT, BTN_LEFT);
|
||||||
|
ioctl(uinput_fd, UI_SET_KEYBIT, BTN_RIGHT);
|
||||||
|
ioctl(uinput_fd, UI_SET_KEYBIT, BTN_MIDDLE);
|
||||||
|
ioctl(uinput_fd, UI_SET_EVBIT, EV_REL);
|
||||||
|
ioctl(uinput_fd, UI_SET_RELBIT, REL_X);
|
||||||
|
ioctl(uinput_fd, UI_SET_RELBIT, REL_Y);
|
||||||
|
|
||||||
|
memset(&uidev, 0, sizeof(uidev));
|
||||||
|
strncpy(uidev.name, "Virtual Mouse", UINPUT_MAX_NAME_SIZE);
|
||||||
|
uidev.id.bustype = BUS_USB;
|
||||||
|
uidev.id.vendor = 0x1234; // <20>Զ<EFBFBD><D4B6>峧<EFBFBD><E5B3A7>ID
|
||||||
|
uidev.id.product = 0x5678; // <20>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>ƷID
|
||||||
|
uidev.absmin[ABS_X] = 0;
|
||||||
|
uidev.absmax[ABS_X] = 1280;
|
||||||
|
uidev.absfuzz[ABS_X] = 0;
|
||||||
|
uidev.absflat[ABS_X] = 0;
|
||||||
|
uidev.absmin[ABS_Y] = 0;
|
||||||
|
uidev.absmax[ABS_Y] = 720;
|
||||||
|
uidev.absfuzz[ABS_Y] = 0;
|
||||||
|
uidev.absflat[ABS_Y] = 0;
|
||||||
|
|
||||||
|
ioctl(uinput_fd, UI_DEV_SETUP, &uidev);
|
||||||
|
|
||||||
|
ioctl(uinput_fd, UI_DEV_CREATE);
|
||||||
|
}
|
||||||
|
|
||||||
screen_capture = new ScreenCaptureX11();
|
screen_capture = new ScreenCaptureX11();
|
||||||
|
|
||||||
RECORD_DESKTOP_RECT rect;
|
RECORD_DESKTOP_RECT rect;
|
||||||
@@ -1227,6 +1350,11 @@ int main() {
|
|||||||
SDL_CloseAudioDevice(output_dev);
|
SDL_CloseAudioDevice(output_dev);
|
||||||
SDL_CloseAudioDevice(input_dev);
|
SDL_CloseAudioDevice(input_dev);
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
ioctl(uinput_fd, UI_DEV_DESTROY);
|
||||||
|
close(uinput_fd);
|
||||||
|
#endif
|
||||||
|
|
||||||
ImGui_ImplSDLRenderer2_Shutdown();
|
ImGui_ImplSDLRenderer2_Shutdown();
|
||||||
ImGui_ImplSDL2_Shutdown();
|
ImGui_ImplSDL2_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|||||||
Reference in New Issue
Block a user