From 0abd329d6a8dd17b6d0cd28a8f49607c3b03af45 Mon Sep 17 00:00:00 2001 From: runge Date: Tue, 11 Jul 2006 18:20:23 +0000 Subject: x11vnc: more UINPUT mode tweaks. --- x11vnc/uinput.c | 316 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 266 insertions(+), 50 deletions(-) (limited to 'x11vnc/uinput.c') diff --git a/x11vnc/uinput.c b/x11vnc/uinput.c index c3a5166..bdd41c2 100644 --- a/x11vnc/uinput.c +++ b/x11vnc/uinput.c @@ -25,8 +25,10 @@ int check_uinput(void); int initialize_uinput(void); int set_uinput_accel(char *str); +int set_uinput_thresh(char *str); void set_uinput_reset(int ms); char *get_uinput_accel(); +char *get_uinput_thresh(); int get_uinput_reset(); void parse_uinput_str(char *str); void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client); @@ -43,7 +45,7 @@ static void button_click(int down, int btn); static int lookup_code(int keysym); static int fd = -1; -static int db = 1; +static int db = 0; static int bmask = 0; static char *injectable = NULL; @@ -155,6 +157,11 @@ int initialize_uinput(void) { fd = -1; } + if (getenv("X11VNC_UINPUT_DEBUG")) { + db = atoi(getenv("X11VNC_UINPUT_DEBUG")); + rfbLog("set uinput debug to: %d\n", db); + } + init_key_tracker(); if (uinput_dev) { @@ -213,15 +220,21 @@ int initialize_uinput(void) { #endif } +/* these defaults are based on qt-embedded 7/2006 */ static double fudge_x = 0.5; /* accel=2.0 */ static double fudge_y = 0.5; +static int thresh = 5; +static int thresh_or = 1; + static double resid_x = 0.0; static double resid_y = 0.0; -static double zero_delay = 0.5; +static double zero_delay = 0.15; static double last_button_click = 0.0; +static int uinput_always = 0; + static void set_uinput_accel_xy(double fx, double fy) { fudge_x = 1.0/fx; fudge_y = 1.0/fy; @@ -230,6 +243,7 @@ static void set_uinput_accel_xy(double fx, double fy) { } static char *uinput_accel_str = NULL; +static char *uinput_thresh_str = NULL; int set_uinput_accel(char *str) { double fx, fy; @@ -249,18 +263,42 @@ int set_uinput_accel(char *str) { return 1; } +int set_uinput_thresh(char *str) { + rfbLog("set_uinput_thresh: str=%s\n", str); + if (str[0] == '+') { + thresh_or = 0; + } + thresh = atoi(str); + if (uinput_thresh_str) { + free(uinput_thresh_str); + } + uinput_thresh_str = strdup(str); + return 1; +} + void set_uinput_reset(int ms) { zero_delay = (double) ms/1000.; rfbLog("set_uinput_reset: %d\n", ms); } +int set_uinput_always(int a) { + uinput_always = a; +} + char *get_uinput_accel(void) { return uinput_accel_str; } +char *get_uinput_thresh(void) { + return uinput_thresh_str; +} int get_uinput_reset(void) { return (int) (1000 * zero_delay); } +int get_uinput_always(void) { + return uinput_always; +} + void parse_uinput_str(char *in) { char *p, *q, *str = strdup(in); @@ -282,10 +320,16 @@ void parse_uinput_str(char *in) { if (! set_uinput_accel(q)) { clean_up_exit(1); } + } else if (strstr(p, "thresh=") == p) { + q = p + strlen("thresh="); + set_uinput_thresh(q); } else if (strstr(p, "reset=") == p) { int n = atoi(p + strlen("reset=")); set_uinput_reset(n); + } else if (strstr(p, "always=") == p) { + int n = atoi(p + strlen("always=")); + set_uinput_always(n); } else if (strpbrk(p, "KMB") == p) { if (injectable) { free(injectable); @@ -307,19 +351,18 @@ static void ptr_move(int dx, int dy) { if (injectable && strchr(injectable, 'M') == NULL) { return; } -if (0) fprintf(stderr, "ptr_move: %d %d\n", dx, dy); memset(&ev, 0, sizeof(ev)); gettimeofday(&ev.time, NULL); ev.type = EV_REL; - ev.code = REL_X; - ev.value = dx; + ev.code = REL_Y; + ev.value = dy; write(fd, &ev, sizeof(ev)); ev.type = EV_REL; - ev.code = REL_Y; - ev.value = dy; + ev.code = REL_X; + ev.value = dx; write(fd, &ev, sizeof(ev)); ev.type = EV_SYN; @@ -329,36 +372,143 @@ if (0) fprintf(stderr, "ptr_move: %d %d\n", dx, dy); #endif } +static int inside_thresh(int dx, int dy, int thr) { + if (thresh_or) { + /* this is peeking at qt-embedded qmouse_qws.cpp */ + if (nabs(dx) <= thresh && nabs(dy) <= thr) { + return 1; + } + } else { + /* this is peeking at xfree/xorg xf86Xinput.c */ + if (nabs(dx) + nabs(dy) < thr) { + return 1; + } + } + return 0; +} + static void ptr_rel(int dx, int dy) { - int dxf, dyf; + int dxf, dyf, nx, ny, k; + int accel, thresh_high, thresh_mid; + double fx, fy; + static int try_threshes = -1; + + if (try_threshes < 0) { + if (getenv("X11VNC_UINPUT_THRESHOLDS")) { + try_threshes = 1; + } else { + try_threshes = 0; + } + } + + if (try_threshes) { + thresh_high = (int) ( (double) thresh/fudge_x ); + thresh_mid = (int) ( (double) (thresh + thresh_high) / 2.0 ); + + if (thresh_mid <= thresh) { + thresh_mid = thresh + 1; + } + if (thresh_high <= thresh_mid) { + thresh_high = thresh_mid + 1; + } + + if (inside_thresh(dx, dy, thresh)) { + accel = 0; + } else { + accel = 1; + } + nx = nabs(dx); + ny = nabs(dy); - dxf = (int) (fudge_x * (double) dx); - dyf = (int) (fudge_y * (double) dy); + } else { + accel = 1; + thresh_high = 0; + nx = ny = 1; + } + + if (accel && nx + ny > 0 ) { + if (thresh_high > 0 && inside_thresh(dx, dy, thresh_high)) { + double alpha, t; + /* XXX */ + if (1 || inside_thresh(dx, dy, thresh_mid)) { + t = thresh; + accel = 2; + } else { + accel = 3; + t = thresh_high; + } + if (thresh_or) { + if (nx > ny) { + fx = t; + fy = ((double) ny / (double) nx) * t; + } else { + fx = ((double) nx / (double) ny) * t; + fy = t; + } + dxf = (int) fx; + dyf = (int) fy; + fx = dx; + fy = dy; + + } else { + if (t > 1) { + /* XXX */ + t = t - 1.0; + } + alpha = t/(nx + ny); + fx = alpha * dx; + fy = alpha * dy; + dxf = (int) fx; + dyf = (int) fy; + fx = dx; + fy = dy; + } + } else { + fx = fudge_x * (double) dx; + fy = fudge_y * (double) dy; + dxf = (int) fx; + dyf = (int) fy; + } + } else { + fx = dx; + fy = dy; + dxf = dx; + dyf = dy; + } if (db > 1) fprintf(stderr, "old dx dy: %d %d\n", dx, dy); - if (db > 1) fprintf(stderr, "new dx dy: %d %d\n", dxf, dyf); + if (db > 1) fprintf(stderr, "new dx dy: %d %d accel: %d\n", dxf, dyf, accel); ptr_move(dxf, dyf); - resid_x += fudge_x * (double) dx - dxf; - resid_y += fudge_y * (double) dy - dyf; + resid_x += fx - dxf; + resid_y += fy - dyf; + + for (k = 0; k < 4; k++) { + if (resid_x <= -1.0 || resid_x >= 1.0 || resid_y <= -1.0 || resid_y >= 1.0) { + dxf = 0; + dyf = 0; + if (resid_x >= 1.0) { + dxf = (int) resid_x; + dxf = 1; + } else if (resid_x <= -1.0) { + dxf = -((int) (-resid_x)); + dxf = -1; + } + resid_x -= dxf; + if (resid_y >= 1.0) { + dyf = (int) resid_y; + dyf = 1; + } else if (resid_y <= -1.0) { + dyf = -((int) (-resid_y)); + dyf = -1; + } + resid_y -= dyf; - if (resid_x < -1.0 || resid_x > 1.0 || resid_y < -1.0 || resid_y > 1.0) { - dxf = 0; - dyf = 0; - if (resid_x > 1.0) { - dxf = (int) resid_x; - } else if (resid_x < -1.0) { - dxf = -((int) (-resid_x)); - } - resid_x -= dxf; - if (resid_y > 1.0) { - dyf = (int) resid_y; - } else if (resid_y < -1.0) { - dyf = -((int) (-resid_y)); + if (db > 1) fprintf(stderr, "*%s resid: dx dy: %d %d %f %f\n", accel > 1 ? "*" : " ", dxf, dyf, resid_x, resid_y); +if (0) {usleep(100*1000)}; + ptr_move(dxf, dyf); } - resid_y -= dyf; - ptr_move(dxf, dyf); } } @@ -370,7 +520,7 @@ static void button_click(int down, int btn) { return; } - if (db) fprintf(stderr, "down %d btn %d\n", down, btn); + if (db) fprintf(stderr, "button_click: btn %d %s\n", btn, down ? "down" : "up"); memset(&ev, 0, sizeof(ev)); gettimeofday(&ev.time, NULL); @@ -408,8 +558,18 @@ void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client) { static int last_x = -1, last_y = -1, last_mask = -1; static double last_zero = 0.0; allowed_input_t input; - int do_reset; + int do_reset, reset_lower_right = 1; double now; + static int first = 1; + + if (first) { + if (getenv("RESET_ALWAYS")) { + set_uinput_always(1); + } else { + set_uinput_always(0); + } + } + first = 0; if (db) fprintf(stderr, "uinput_pointer_command: %d %d - %d\n", x, y, mask); @@ -436,37 +596,92 @@ void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client) { } } + if (uinput_always && !mask && !bmask && input.motion) { + do_reset = 1; + } + if (do_reset) { static int first = 1; if (zero_delay > 0.0 || first) { /* try to push it to 0,0 */ - int tx = fudge_x * last_x + 40; - int ty = fudge_y * last_y + 40; - int bigjump = 1; + int tx, ty, bigjump = 1; + + if (reset_lower_right) { + tx = fudge_x * (dpy_x - last_x); + ty = fudge_y * (dpy_y - last_y); + } else { + tx = fudge_x * last_x; + ty = fudge_y * last_y; + } + + tx += 50; + ty += 50; if (bigjump) { - ptr_move(-tx, -ty); - ptr_move(-tx, -ty); + if (reset_lower_right) { + ptr_move(0, +ty); + usleep(2*1000); + ptr_move(+tx, +ty); + ptr_move(+tx, +ty); + } else { + ptr_move(0, -ty); + usleep(2*1000); + ptr_move(-tx, -ty); + ptr_move(-tx, -ty); + } } else { int i, step, n = 20; step = dpy_x / n; + if (step < 100) step = 100; + for (i=0; i < n; i++) { - ptr_move(-step, -step); + if (reset_lower_right) { + ptr_move(+step, +step); + } else { + ptr_move(-step, -step); + } } for (i=0; i < n; i++) { - ptr_move(-1, -1); + if (reset_lower_right) { + ptr_move(+1, +1); + } else { + ptr_move(-1, -1); + } + } + } + if (db) { + if (reset_lower_right) { + fprintf(stderr, "uinput_pointer_command: reset -> (W,H) (%d,%d) [%d,%d]\n", x, y, tx, ty); + } else { + fprintf(stderr, "uinput_pointer_command: reset -> (0,0) (%d,%d) [%d,%d]\n", x, y, tx, ty); } } - if (db) fprintf(stderr, "uinput_pointer_command: reset\n"); /* rest a bit for system to absorb the change */ - usleep(30*1000); + if (uinput_always) { + static double last_sleep = 0.0; + double nw = dnow(), delay = zero_delay; + if (delay <= 0.0) delay = 0.1; + if (nw > last_sleep + delay) { + usleep(10*1000); + last_sleep = nw; + } else { + usleep(1*1000); + } + + } else { + usleep(30*1000); + } /* now jump back out */ - ptr_rel(x, y); - if (0) usleep(10*1000); + if (reset_lower_right) { + ptr_rel(x - dpy_x, y - dpy_y); + } else { + ptr_rel(x, y); + } + if (1) {usleep(10*1000)}; last_x = x; last_y = y; @@ -494,12 +709,12 @@ void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client) { last_mask = mask; } -#if 0 -fprintf(stderr, "mask: %s\n", bitprint(mask, 16)); -fprintf(stderr, "bmask: %s\n", bitprint(bmask, 16)); -fprintf(stderr, "last_mask: %s\n", bitprint(last_mask, 16)); -fprintf(stderr, "button_mask: %s\n", bitprint(button_mask, 16)); -#endif + if (db > 2) { + fprintf(stderr, "mask: %s\n", bitprint(mask, 16)); + fprintf(stderr, "bmask: %s\n", bitprint(bmask, 16)); + fprintf(stderr, "last_mask: %s\n", bitprint(last_mask, 16)); + fprintf(stderr, "button_mask: %s\n", bitprint(button_mask, 16)); + } if (mask != last_mask) { int i; @@ -542,7 +757,7 @@ void uinput_key_command(int down, int keysym, rfbClientPtr client) { if (scancode < 0) { return; } - if (db) fprintf(stderr, "uinput_key_command: %d -> %d\n", keysym, scancode); + if (db) fprintf(stderr, "uinput_key_command: %d -> %d %s\n", keysym, scancode, down ? "down" : "up"); memset(&ev, 0, sizeof(ev)); gettimeofday(&ev.time, NULL); @@ -557,7 +772,7 @@ void uinput_key_command(int down, int keysym, rfbClientPtr client) { ev.value = 0; write(fd, &ev, sizeof(ev)); - if (0 <= scancode < 256) { + if (0 <= scancode && scancode < 256) { key_pressed[scancode] = down ? 1 : 0; } #endif @@ -767,7 +982,8 @@ while (<>) { } } -This only handles us kbd, we would need a kbd database in general... +This only handles US kbd, we would need a kbd database in general... +Ugh: parse dumpkeys(1) or -fookeys /usr/share/keymaps/i386/qwerty/dk.kmap.gz XK_Escape KEY_ESC XK_1 KEY_1 -- cgit v1.2.1