Skip to content

Instantly share code, notes, and snippets.

@regular-dev
Created October 24, 2019 09:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save regular-dev/7a214f8b52911a63afe803693d467863 to your computer and use it in GitHub Desktop.
Save regular-dev/7a214f8b52911a63afe803693d467863 to your computer and use it in GitHub Desktop.
Uinput Mouse Click and movement
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <sstream>
#include <cstring>
#include <stdlib.h>
#include <stdio.h>
#include <linux/uinput.h>
#include <X11/Xlib.h>
using namespace std;
int fd;
Display *dpy;
void initMouse();
void destroyMouse();
void mouseLeftClick();
void mouseRightClick();
void mouseGetPosition(int &x, int &y);
void mouseMove(int xdelta, int ydelta);
void initMouse()
{
fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
ioctl(fd, UI_SET_EVBIT, EV_KEY);
ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT);
ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
ioctl(fd, UI_SET_EVBIT, EV_ABS);
ioctl(fd, UI_SET_ABSBIT, ABS_X);
ioctl(fd, UI_SET_ABSBIT, ABS_Y);
ioctl(fd, UI_SET_EVBIT, EV_REL);
struct uinput_user_dev uidev;
memset(&uidev,0,sizeof(uidev));
snprintf(uidev.name,UINPUT_MAX_NAME_SIZE,"VirtualMouse");
uidev.id.bustype = BUS_USB;
uidev.id.version = 1;
uidev.id.vendor = 0x1;
uidev.id.product = 0x1;
uidev.absmin[ABS_X] = 0;
uidev.absmax[ABS_X] = 3200;
uidev.absmin[ABS_Y] = 0;
uidev.absmax[ABS_Y] = 900;
write(fd, &uidev, sizeof(uidev));
ioctl(fd, UI_DEV_CREATE);
sleep(2);
}
void mouseLeftClick()
{
struct input_event ev_click, ev_sync;
memset(&ev_click, 0, sizeof(ev_click));
memset(&ev_sync, 0, sizeof(ev_sync));
ev_click.type = EV_KEY;
ev_click.code = BTN_LEFT;
ev_click.value = 1;
//write left click event
write(fd, &ev_click, sizeof(ev_click));
//sync left click event
ev_sync.type = EV_SYN;
write(fd, &ev_sync, sizeof(ev_sync));
}
void mouseRightClick()
{
struct input_event ev_click, ev_sync;
memset(&ev_click, 0, sizeof(ev_click));
memset(&ev_sync, 0, sizeof(ev_sync));
ev_click.type = EV_KEY;
ev_click.code = BTN_RIGHT;
ev_click.value = 1;
//write right click event
write(fd, &ev_click, sizeof(ev_click));
//sync right click event
ev_sync.type = EV_SYN;
write(fd, &ev_sync, sizeof(ev_sync));
}
void mouseSetPosition(int x, int y)
{
struct input_event ev[2], ev_sync;
memset(ev, 0, sizeof(ev));
memset(&ev_sync, 0, sizeof(ev_sync));
ev[0].type = EV_ABS;
ev[0].code = ABS_X;
ev[0].value = x;
ev[1].type = EV_ABS;
ev[1].code = ABS_Y;
ev[1].value = y;
int res_w = write(fd, ev, sizeof(ev));
std::cout << "res w : " << res_w << "\n";
ev_sync.type = EV_SYN;
ev_sync.value = 0;
ev_sync.code = 0;
int res_ev_sync = write(fd, &ev_sync, sizeof(ev_sync));
std::cout << "res syn : " << res_ev_sync << "\n";
}
void initDisplay()
{
dpy = XOpenDisplay(NULL);
}
void destroyMouse()
{
ioctl(fd, UI_DEV_DESTROY);
}
void mouseMove(int xdelta, int ydelta)
{
int xx, yy;
mouseGetPosition(xx, yy);
mouseSetPosition(xx + xdelta, yy + ydelta);
}
void mouseGetPosition(int &x, int &y)
{
Window root, child;
int rootX, rootY, winX, winY;
unsigned int mask;
XQueryPointer(dpy,DefaultRootWindow(dpy),&root,&child,
&rootX,&rootY,&winX,&winY,&mask);
std::cout << "root x : " << rootX << "\n";
std::cout << "root y : " << rootY << "\n";
x = rootX;
y = rootY;
}
int main()
{
initMouse();
initDisplay();
int tempx, tempy;
for (int i = 0 ; i < 5 ; ++i)
{
mouseMove(100, 100);
sleep(1);
std::cout << "i : " << i << "\n";
}
destroyMouse();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment