source: liacs/mms/project/uinput.c@ 43

Last change on this file since 43 was 17, checked in by Rick van der Zwet, 15 years ago

Bit hacky, but uinput did not do the trick. Using the X11Test does the trick

File size: 4.6 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <fcntl.h>
5#include <linux/input.h>
6#include <linux/uinput.h>
7#include <signal.h>
8#include <X11/Xlib.h>
9
10static int fd;
11
12struct coords {
13 int x;
14 int y;
15};
16
17void close_pointer() {
18 ioctl(fd, UI_DEV_DESTROY);
19 close(fd);
20}
21
22// Close stuff nicely in case of issues
23void ex_program(int sig) {
24 close_pointer();
25 printf("Terminated signal: %d\n", sig);
26 (void) signal(SIGINT, SIG_DFL);
27 exit(-1);
28}
29
30// Wrapper to send cool stuff over the wire
31int send_event(int fd, __u16 type, __u16 code, __s32 value)
32{
33 struct input_event event;
34
35 memset(&event, 0, sizeof(event));
36 event.type = type;
37 event.code = code;
38 event.value = value;
39 gettimeofday(&event.time, NULL);
40
41 if (write(fd, &event, sizeof(event)) != sizeof(event)) {
42 fprintf(stderr, "Error on send_event");
43 return -1;
44 }
45
46 return 0;
47}
48
49//XXX: Make me more effient
50struct coords
51get_coords() {
52 Display *dsp = XOpenDisplay( NULL );
53
54 struct coords xy_current = { -1, -1 };
55 if( !dsp ){ return xy_current; }
56
57 int screenNumber = DefaultScreen(dsp);
58
59 XEvent event;
60
61 /* get info about current pointer position */
62 XQueryPointer(dsp, RootWindow(dsp, screenNumber),
63 &event.xbutton.root, &event.xbutton.window,
64 &event.xbutton.x_root, &event.xbutton.y_root,
65 &event.xbutton.x, &event.xbutton.y,
66 &event.xbutton.state);
67
68 printf("Mouse Coordinates: %d %d\n", event.xbutton.x, event.xbutton.y);
69 XCloseDisplay( dsp );
70 xy_current.x = event.xbutton.x;
71 xy_current.y = event.xbutton.y;
72 return(xy_current);
73}
74
75
76// Set the pointer to a certain location
77int
78init_pointer()
79{
80 int i;
81 struct uinput_user_dev device;
82 memset(&device, 0, sizeof device);
83
84 fd=open("/dev/uinput",O_WRONLY | O_NDELAY);
85 strcpy(device.name,"test mouse");
86
87 device.id.bustype=BUS_USB;
88 device.id.vendor= 0x0001;
89 device.id.product=0x0001;
90 device.id.version=UINPUT_VERSION;
91
92 //for (i=0; i < ABS_MAX; i++) {
93 // device.absmax[i] = -1;
94 // device.absmin[i] = -1;
95 // device.absfuzz[i] = -1;
96 // device.absflat[i] = -1;
97 //}
98
99 if (write(fd,&device,sizeof(device)) != sizeof(device))
100 {
101 fprintf(stderr, "error setup\n");
102 return -1;
103 }
104
105 (void) signal(SIGINT, ex_program);
106
107 /* mousedev only recognize our device as a mouse
108 * if it has at least two axis and one left button.
109 * Also, mouse buttons have to send sync events.
110 */
111 //ioctl(fd, UI_SET_EVBIT, EV_KEY);
112 ioctl(fd, UI_SET_EVBIT, EV_REL);
113 ioctl(fd, UI_SET_EVBIT, EV_SYN);
114
115 ioctl(fd, UI_SET_RELBIT, REL_X);
116 ioctl(fd, UI_SET_RELBIT, REL_Y);
117 //ioctl(fd, UI_SET_RELBIT, REL_WHEEL);
118
119 ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
120 //ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT);
121 //ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE);
122
123 //for (i=0; i < 256; i++) {
124 // ioctl(fd, UI_SET_KEYBIT, i);
125 //}
126
127 ioctl(fd, UI_DEV_CREATE, NULL);
128
129}
130
131int set_pointer(const struct coords xy_target) {
132 struct coords xy_diff, xy_prev;
133 struct coords xy_current = { -1 , -1 }; // Bogus inital value
134 char c;
135 // Force pointer to absolute location on the screen
136 while ( 1 ) {
137 //XXX: Screen pointer get updated really slow
138 xy_prev.x = xy_current.x;
139 xy_prev.y = xy_current.y;
140 while ( 1 ) {
141 xy_current = get_coords();
142 // Found ourself an update
143 printf("old->new coordinates %ix%i -> %ix%i\n",
144 xy_prev.x,xy_prev.y,
145 xy_current.x,xy_current.y);
146 if (xy_prev.x != xy_current.x || xy_prev.y != xy_current.y) {
147 //ex_program(1);
148 break;
149 }
150 usleep(200000);
151 }
152
153 xy_diff.x = (xy_target.x - xy_current.x);
154 xy_diff.y = (xy_target.y - xy_current.y);
155 if (xy_diff.x == 0 && xy_diff.y == 0) {
156 printf("Location %ix%i\n", xy_current.x, xy_current.y);
157 break;
158 } else {
159 printf("Trying to sync current:%ix%i target:%ix%i diff:%ix%i\n",
160 xy_current.x, xy_current.y,
161 xy_target.x, xy_target.y,
162 xy_diff.x, xy_diff.y);
163 send_event(fd, EV_REL, REL_X, xy_diff.x);
164 send_event(fd, EV_REL, REL_Y, xy_diff.y);
165 send_event(fd, EV_SYN, SYN_REPORT, 0);
166 // Wait some small period of time to get it populated (and the screen get updated)
167 usleep(200000);
168 }
169 }
170}
171
172int
173main() {
174 struct coords xy_target = { 200,200 };
175 init_pointer();
176 set_pointer(xy_target);
177 xy_target.x = 500;
178 xy_target.y = 500;
179 set_pointer(xy_target);
180 close_pointer();
181 return(0);
182}
Note: See TracBrowser for help on using the repository browser.