summaryrefslogtreecommitdiffstats
path: root/x11vnc/uinput.c
diff options
context:
space:
mode:
Diffstat (limited to 'x11vnc/uinput.c')
-rw-r--r--x11vnc/uinput.c134
1 files changed, 131 insertions, 3 deletions
diff --git a/x11vnc/uinput.c b/x11vnc/uinput.c
index 656d7c5..758419a 100644
--- a/x11vnc/uinput.c
+++ b/x11vnc/uinput.c
@@ -28,9 +28,15 @@ int initialize_uinput(void);
int set_uinput_accel(char *str);
int set_uinput_thresh(char *str);
void set_uinput_reset(int ms);
+void set_uinput_always(int);
+void set_uinput_touchscreen(int);
+void set_uinput_abs(int);
char *get_uinput_accel();
char *get_uinput_thresh();
int get_uinput_reset();
+int get_uinput_always();
+int get_uinput_touchscreen();
+int get_uinput_abs();
void parse_uinput_str(char *str);
void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client);
void uinput_key_command(int down, int keysym, rfbClientPtr client);
@@ -51,6 +57,9 @@ static int bmask = 0;
static char *injectable = NULL;
static char *uinput_dev = NULL;
+static int uinput_touchscreen = 0;
+static int uinput_abs = 0;
+static int abs_x = 0, abs_y = 0;
static char *devs[] = {
"/dev/misc/uinput",
@@ -78,9 +87,12 @@ int check_uinput(void) {
if (maj < 2) {
return 0;
} else if (maj == 2) {
+ /* hmmm IPAQ 2.4.19-rmk6-pxa1-hh37 works... */
+#if 0
if (min < 6) {
return 0;
}
+#endif
}
}
}
@@ -210,6 +222,35 @@ int initialize_uinput(void) {
ioctl(fd, UI_SET_KEYBIT, BTN_FORWARD);
ioctl(fd, UI_SET_KEYBIT, BTN_BACK);
+ if (uinput_touchscreen) {
+ ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH);
+ rfbLog("uinput: touchscreen enabled.\n");
+ }
+ if (uinput_touchscreen || uinput_abs) {
+ int gw = abs_x, gh = abs_y;
+ if (! gw || ! gh) {
+ gw = fb_x; gh = fb_y;
+ }
+ if (! gw || ! gh) {
+ gw = dpy_x; gh = dpy_y;
+ }
+ abs_x = gw;
+ abs_y = gh;
+ ioctl(fd, UI_SET_EVBIT, EV_ABS);
+ ioctl(fd, UI_SET_ABSBIT, ABS_X);
+ ioctl(fd, UI_SET_ABSBIT, ABS_Y);
+ udev.absmin[ABS_X] = 0;
+ udev.absmax[ABS_X] = gw;
+ udev.absfuzz[ABS_X] = 0;
+ udev.absflat[ABS_X] = 0;
+ udev.absmin[ABS_Y] = 0;
+ udev.absmax[ABS_Y] = gh;
+ udev.absfuzz[ABS_Y] = 0;
+ udev.absflat[ABS_Y] = 0;
+ rfbLog("uinput: absolute pointer enabled at %dx%d.\n", abs_x, abs_y);
+ set_uinput_accel_xy(1.0, 1.0);
+ }
+
write(fd, &udev, sizeof(udev));
if (ioctl(fd, UI_DEV_CREATE) != 0) {
@@ -287,6 +328,14 @@ void set_uinput_always(int a) {
uinput_always = a;
}
+void set_uinput_touchscreen(int b) {
+ uinput_touchscreen = b;
+}
+
+void set_uinput_abs(int b) {
+ uinput_abs = b;
+}
+
char *get_uinput_accel(void) {
return uinput_accel_str;
}
@@ -301,6 +350,14 @@ int get_uinput_always(void) {
return uinput_always;
}
+int get_uinput_touchscreen(void) {
+ return uinput_touchscreen;
+}
+
+int get_uinput_abs(void) {
+ return uinput_abs;
+}
+
void parse_uinput_str(char *in) {
char *p, *q, *str = strdup(in);
@@ -309,6 +366,10 @@ void parse_uinput_str(char *in) {
injectable = strdup("KMB");
}
+ uinput_touchscreen = 0;
+ uinput_abs = 0;
+ abs_x = abs_y = 0;
+
p = strtok(str, ",");
while (p) {
if (p[0] == '/') {
@@ -336,6 +397,24 @@ void parse_uinput_str(char *in) {
free(injectable);
}
injectable = strdup(p);
+ } else if (strstr(p, "touch") == p) {
+ int gw, gh;
+ q = strchr(p, '=');
+ set_uinput_touchscreen(1);
+ set_uinput_abs(1);
+ if (q && sscanf(q+1, "%dx%d", &gw, &gh) == 2) {
+ abs_x = gw;
+ abs_y = gh;
+ }
+ } else if (strstr(p, "abs") == p) {
+ int gw, gh;
+ q = strchr(p, '=');
+ set_uinput_abs(1);
+ if (q && sscanf(q+1, "%dx%d", &gw, &gh) == 2) {
+ abs_x = gw;
+ abs_y = gh;
+ }
+
} else {
rfbLog("invalid UINPUT option: %s\n", p);
clean_up_exit(1);
@@ -373,6 +452,36 @@ static void ptr_move(int dx, int dy) {
#endif
}
+static void ptr_abs(int x, int y) {
+#ifdef UINPUT_OK
+ struct input_event ev;
+
+ if (injectable && strchr(injectable, 'M') == NULL) {
+ return;
+ }
+
+ memset(&ev, 0, sizeof(ev));
+
+ if (db) fprintf(stderr, "ptr_abs(%d, %d)\n", x, y);
+
+ gettimeofday(&ev.time, NULL);
+ ev.type = EV_ABS;
+ ev.code = ABS_Y;
+ ev.value = y;
+ write(fd, &ev, sizeof(ev));
+
+ ev.type = EV_ABS;
+ ev.code = ABS_X;
+ ev.value = x;
+ write(fd, &ev, sizeof(ev));
+
+ ev.type = EV_SYN;
+ ev.code = SYN_REPORT;
+ ev.value = 0;
+ write(fd, &ev, sizeof(ev));
+#endif
+}
+
static int inside_thresh(int dx, int dy, int thr) {
if (thresh_or) {
/* this is peeking at qt-embedded qmouse_qws.cpp */
@@ -528,7 +637,10 @@ static void button_click(int down, int btn) {
ev.type = EV_KEY;
ev.value = down;
- if (btn == 1) {
+ if (uinput_touchscreen) {
+ ev.code = BTN_TOUCH;
+ if (db) fprintf(stderr, "set code to BTN_TOUCH\n");
+ } else if (btn == 1) {
ev.code = BTN_LEFT;
} else if (btn == 2) {
ev.code = BTN_MIDDLE;
@@ -583,7 +695,7 @@ void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client) {
do_reset = 1;
if (mask || bmask) {
- do_reset = 0; /* do not do reset if moust button down */
+ do_reset = 0; /* do not do reset if mouse button down */
} else if (! input.motion) {
do_reset = 0;
} else if (now < last_zero + zero_delay) {
@@ -600,6 +712,18 @@ void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client) {
if (uinput_always && !mask && !bmask && input.motion) {
do_reset = 1;
}
+ if (uinput_abs) {
+#if 0
+ /* this is a bad idea... need to do something else */
+ if (do_reset) {
+ ptr_abs(dpy_x, dpy_y);
+ usleep(10*1000);
+ ptr_abs(x, y);
+ usleep(10*1000);
+ }
+#endif
+ do_reset = 0;
+ }
if (do_reset) {
static int first = 1;
@@ -696,7 +820,11 @@ void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client) {
if (input.motion) {
if (x != last_x || y != last_y) {
- ptr_rel(x - last_x, y - last_y);
+ if (uinput_abs) {
+ ptr_abs(x, y);
+ } else {
+ ptr_rel(x - last_x, y - last_y);
+ }
last_x = x;
last_y = y;
}