Simuler des mouvements de souris absolus sous Linux en utilisant uinput

J’essaie de déplacer le curseur en utilisant des coordonnées absolues. Voici le code:

#include  #include  #include  #include  #include  #include  #include  #include  #include  #define die(str, args...) do { \ perror(str); \ exit(EXIT_FAILURE); \ } while(0) int fd; static void signal_handler(int signo) { printf("\nCaught SIGINT\n"); if(ioctl(fd, UI_DEV_DESTROY) < 0) die("error: cannot destroy uinput device\n"); else printf("Destroyed uinput_user_dev\n\n"); close(fd); exit(EXIT_SUCCESS); } int main(void) { struct uinput_user_dev uidev; struct input_event ev; int x, y; int i; if(signal(SIGINT,signal_handler)==SIG_ERR) { printf("error registering signal handler\n"); exit(EXIT_FAILURE); } fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); if(fd < 0) die("error: open"); if(ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0) die("error: ioctl"); // if(ioctl(fd, UI_SET_KEYBIT, BTN_MOUSE) < 0) // die("error: ioctl"); if(ioctl(fd, UI_SET_KEYBIT, BTN_LEFT) < 0) die("error: ioctl"); if(ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT) < 0) die("error: ioctl"); if(ioctl(fd, UI_SET_EVBIT, EV_REL) < 0) die("error: ioctl"); if(ioctl(fd, UI_SET_RELBIT, REL_X) < 0) die("error: ioctl"); if(ioctl(fd, UI_SET_RELBIT, REL_Y) < 0) die("error: ioctl"); if(ioctl(fd, UI_SET_EVBIT, EV_ABS) < 0) die("error: ioctl"); if(ioctl(fd, UI_SET_ABSBIT,ABS_X) < 0) die("error: ioctl"); if(ioctl(fd, UI_SET_ABSBIT, ABS_Y) < 0) die("error: ioctl"); memset(&uidev, 0, sizeof(uidev)); snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-sample"); uidev.id.bustype = BUS_USB; uidev.id.vendor = 0x1; uidev.id.product = 0x1; uidev.id.version = 1; uidev.absmin[ABS_X]=0; uidev.absmax[ABS_X]=1023; uidev.absfuzz[ABS_X]=0; uidev.absflat[ABS_X ]=0; uidev.absmin[ABS_Y]=0; uidev.absmax[ABS_Y]=767; uidev.absfuzz[ABS_Y]=0; uidev.absflat[ABS_Y ]=0; if(write(fd, &uidev, sizeof(uidev)) < 0) die("error: write0"); if(ioctl(fd, UI_DEV_CREATE) < 0) die("error: ioctl"); sleep(2); while(1) { printf("\nEnter the absoulte x(0-1023) and y(0-767) co-ordinates:"); scanf("%d %d",&x,&y); memset(&ev, 0, sizeof(struct input_event)); gettimeofday(&ev.time,NULL); ev.type = EV_ABS; ev.code = ABS_X; ev.value = x; if(write(fd, &ev, sizeof(struct input_event)) < 0) die("error: write1"); memset(&ev, 0, sizeof(struct input_event)); ev.type = EV_SYN; if(write(fd, &ev, sizeof(struct input_event)) < 0) die("error: write4"); memset(&ev, 0, sizeof(struct input_event)); ev.type = EV_ABS; ev.code = ABS_Y; ev.value = y; if(write(fd, &ev, sizeof(struct input_event)) < 0) die("error: write2"); memset(&ev, 0, sizeof(struct input_event)); ev.type = EV_SYN; if(write(fd, &ev, sizeof(struct input_event)) < 0) die("error: write3"); usleep(15000); printf("\nWritten x:%dy:%d to uinput.Press CTRL-C to quit:",x,y); } if(ioctl(fd, UI_DEV_DESTROY) < 0) die("error: cannot destroy uinput device\n"); close(fd); return 0; } 

Le programme semble envoyer les coordonnées absolues que je tape au kernel d’entrée du kernel via uinput.

Je l’ai vérifié sur dmesg après avoir activé evbug. Mais mon pointeur de souris ne bougera pas à l’écran. Je me demande ce que je gâche.

Peut-être que EV_ABS n’est pas lié au curseur? Je me demande parce que déplacer le curseur en utilisant EV_REL fonctionne bien comme mentionné dans ce tutoriel .

Exemple:

 ravi@linux-lxaf:~/workspace/driver> sudo ./a.out Enter the absoulte x(0-1023) and y(0-767) co-ordinates:100 200 Written x:100 y:200 to uinput.Press CTRL-C to quit: Enter the absoulte x(0-1023) and y(0-767) co-ordinates:10 765 Written x:10 y:765 to uinput.Press CTRL-C to quit: Enter the absoulte x(0-1023) and y(0-767) co-ordinates:^C Caught SIGINT Destroyed uinput_user_dev 

Sortie Dmesg:

 ravi@linux-lxaf:~/workspace/driver> dmesg |grep input16 [ 4750.660420] input: uinput-sample as /devices/virtual/input/input16 [ 4750.660594] evbug.c: Connected device: input16 (uinput-sample at unknown) [ 4761.389036] evbug.c: Event. Dev: input16, Type: 3, Code: 0, Value: 100 [ 4761.389047] evbug.c: Event. Dev: input16, Type: 0, Code: 0, Value: 0 [ 4761.389053] evbug.c: Event. Dev: input16, Type: 3, Code: 1, Value: 200 [ 4761.389058] evbug.c: Event. Dev: input16, Type: 0, Code: 0, Value: 0 [ 4776.893126] evbug.c: Event. Dev: input16, Type: 3, Code: 0, Value: 10 [ 4776.893138] evbug.c: Event. Dev: input16, Type: 0, Code: 0, Value: 0 [ 4776.893144] evbug.c: Event. Dev: input16, Type: 3, Code: 1, Value: 765 [ 4776.893148] evbug.c: Event. Dev: input16, Type: 0, Code: 0, Value: 0 [ 4778.729711] evbug.c: Event. Dev: input16, Type: 0, Code: 0, Value: 1 [ 4778.745506] evbug.c: Disconnected device: input16 

Je viens de découvrir que le kernel d’entrée propage les valeurs EV_ABS en tant que valeurs absolues au nœud de périphérique, comme le montre la lecture de / dev / input / eventX (semble si évidente maintenant !), L’application contrôlant le curseur (X11? ) s’attendait à des mouvements de souris relatifs alors que je lui donnais des valeurs absolues, ce qui l’a probablement dérouté!