Você pode usar uinput ( linux/uinput.h). Ele funciona tanto no X quanto no Wayland.
A página de documentação acima tem um exemplo que inclui a criação de um dispositivo virtual que se comporta como um mouse:
#include <linux/uinput.h>
void emit(int fd, int type, int code, int val)
{
struct input_event ie;
ie.type = type;
ie.code = code;
ie.value = val;
/* timestamp values below are ignored */
ie.time.tv_sec = 0;
ie.time.tv_usec = 0;
write(fd, &ie, sizeof(ie));
}
int main(void)
{
struct uinput_setup usetup;
int i = 50;
int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
/* enable mouse button left and relative events */
ioctl(fd, UI_SET_EVBIT, EV_KEY);
ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
ioctl(fd, UI_SET_EVBIT, EV_REL);
ioctl(fd, UI_SET_RELBIT, REL_X);
ioctl(fd, UI_SET_RELBIT, REL_Y);
memset(&usetup, 0, sizeof(usetup));
usetup.id.bustype = BUS_USB;
usetup.id.vendor = 0x1234; /* sample vendor */
usetup.id.product = 0x5678; /* sample product */
strcpy(usetup.name, "Example device");
ioctl(fd, UI_DEV_SETUP, &usetup);
ioctl(fd, UI_DEV_CREATE);
/*
* On UI_DEV_CREATE the kernel will create the device node for this
* device. We are inserting a pause here so that userspace has time
* to detect, initialize the new device, and can start listening to
* the event, otherwise it will not notice the event we are about
* to send. This pause is only needed in our example code!
*/
sleep(1);
/* Move the mouse diagonally, 5 units per axis */
while (i--) {
emit(fd, EV_REL, REL_X, 5);
emit(fd, EV_REL, REL_Y, 5);
emit(fd, EV_SYN, SYN_REPORT, 0);
usleep(15000);
}
/*
* Give userspace some time to read the events before we destroy the
* device with UI_DEV_DESTOY.
*/
sleep(1);
ioctl(fd, UI_DEV_DESTROY);
close(fd);
return 0;
}
Se você não quiser escrever código C para uinput , existem pacotes python e até mesmo alguns utilitários de depuração e teste existentes que funcionam no mesmo nível
evdevevemu-describe , ou seja , evemu-device, , evemu-play, evemu-record, e
evemu-eventdo pacote evemu. Você precisa ser root para usá-los. Aqui está um exemplo que localiza o dispositivo de mouse e os eventos que ele gera e, em seguida, gera artificialmente um evento para ele.
Primeiro listamos os dispositivos evdev:
$ sudo evemu-describe
Available devices:
...
/dev/input/event5: Logitech USB Optical Mouse
...
Este é um comando interativo, que após listar os dispositivos físicos nos pede para escolher um para maiores detalhes sobre ele. Nós escolhemos 5, o mouse:
Normalmente, para um movimento do mouse existe o tipo de evento EV_REL, o código de evento REL_X e/ou REL_Y para o eixo de movimento relativo e o valor do evento distância movida (4, 7, 1 acima). Os eventos são seguidos por um evento de sincronização do tipo EV_SYN com o código SYN_REPORT para sinalizar o fim do evento.
Podemos injetar nosso próprio evento (digamos, um movimento de 20,10) com outro dos comandos de teste:
A --syncopção adiciona o evento SYN_REPORT ao final (o equivalente a --type EV_SYN --code SYN_REPORT).
Por fim, outro comando de teste evemu-devicepermite criar um novo dispositivo de entrada, fornecendo uma descrição como as que já vimos para o mouse. Ele usa /dev/uinpute cria um novo /dev/input/event*dispositivo, que podemos usar para enviar eventos.
Portanto, mesmo se você não tiver um mouse, poderá adicionar um dinamicamente e depois controlá-lo como desejar. Não tenho um dispositivo com eventos de posição absoluta para fornecer um exemplo, mas você pode adicionar um dispositivo semelhante a um tablet e enviar eventos de movimentos absolutos por meio dele.
Você pode usar uinput (
linux/uinput.h
). Ele funciona tanto no X quanto no Wayland.A página de documentação acima tem um exemplo que inclui a criação de um dispositivo virtual que se comporta como um mouse:
Se você não quiser escrever código C para uinput , existem pacotes python e até mesmo alguns utilitários de depuração e teste existentes que funcionam no mesmo nível evdev
evemu-describe
, ou seja ,evemu-device
, ,evemu-play
,evemu-record
, eevemu-event
do pacote evemu. Você precisa ser root para usá-los. Aqui está um exemplo que localiza o dispositivo de mouse e os eventos que ele gera e, em seguida, gera artificialmente um evento para ele.Primeiro listamos os dispositivos evdev:
Este é um comando interativo, que após listar os dispositivos físicos nos pede para escolher um para maiores detalhes sobre ele. Nós escolhemos 5, o mouse:
Outro dos comandos de teste do evemu nos mostrará os eventos que estão sendo gerados quando movemos o mouse:
Normalmente, para um movimento do mouse existe o tipo de evento EV_REL, o código de evento REL_X e/ou REL_Y para o eixo de movimento relativo e o valor do evento distância movida (4, 7, 1 acima). Os eventos são seguidos por um evento de sincronização do tipo EV_SYN com o código SYN_REPORT para sinalizar o fim do evento.
Podemos injetar nosso próprio evento (digamos, um movimento de 20,10) com outro dos comandos de teste:
A
--sync
opção adiciona o evento SYN_REPORT ao final (o equivalente a--type EV_SYN --code SYN_REPORT
).Por fim, outro comando de teste
evemu-device
permite criar um novo dispositivo de entrada, fornecendo uma descrição como as que já vimos para o mouse. Ele usa/dev/uinput
e cria um novo/dev/input/event*
dispositivo, que podemos usar para enviar eventos.Portanto, mesmo se você não tiver um mouse, poderá adicionar um dinamicamente e depois controlá-lo como desejar. Não tenho um dispositivo com eventos de posição absoluta para fornecer um exemplo, mas você pode adicionar um dispositivo semelhante a um tablet e enviar eventos de movimentos absolutos por meio dele.
Da resposta de meuh , escrevi este pequeno
mousemove
script bash, para executarXREL YREL
como argumentos.Como
root
ou através desudo
:Devido ao conceito de aceleração do mouse , o movimento real não corresponde a valores exatos, exceto para valores muito baixos.