x11vnc: more UINPUT mode tweaks.

pull/1/head
runge 19 years ago
parent 0afa1da8cc
commit 0abd329d6a

@ -1,3 +1,6 @@
2006-07-11 Karl Runge <runge@karlrunge.com>
* x11vnc: more tweaks to UINPUT, mostly mouse motion.
2006-07-08 Karl Runge <runge@karlrunge.com> 2006-07-08 Karl Runge <runge@karlrunge.com>
* x11vnc: add uinput support (-pipeinput UINPUT:...) for full * x11vnc: add uinput support (-pipeinput UINPUT:...) for full
mouse and key input to linux console (e.g. for qt-embedded apps) mouse and key input to linux console (e.g. for qt-embedded apps)

File diff suppressed because it is too large Load Diff

@ -2528,16 +2528,17 @@ void print_help(int mode) {
" active VT, to indicate one explicitly, use \"cons2\",\n" " active VT, to indicate one explicitly, use \"cons2\",\n"
" etc. using the VT number.\n" " etc. using the VT number.\n"
"\n" "\n"
" If the Linux version seems to be 2.6 or later and the\n" " If the Linux version seems to be 2.6 or later and\n"
" \"uinput\" module appears to be present, then the uinput\n" " the \"uinput\" module appears to be present, then\n"
" method will be used instead of /dev/ttyN. uinput allows\n" " the uinput method will be used instead of /dev/ttyN.\n"
" insertion of BOTH keystrokes and mouse input and so it\n" " uinput allows insertion of BOTH keystrokes and mouse\n"
" preferred when accessing graphical (e.g. QT-embedded)\n" " input and so it preferred when accessing graphical\n"
" linux console apps. See -pipeinput UINPUT below\n" " (e.g. QT-embedded) linux console apps. See -pipeinput\n"
" for more information on this mode (you may want to\n" " UINPUT below for more information on this mode; you\n"
" also use the -nodragging and -cursor none options).\n" " will have to use -pipeinput if you want to tweak any\n"
" Use \"cons0\", etc or -pipeinput CONS to force the\n" " UINPUT parameters. You may also want to also use the\n"
" /dev/ttyN method.\n" " -nodragging and -cursor none options. Use \"cons0\",\n"
" etc or -pipeinput CONS to force the /dev/ttyN method.\n"
"\n" "\n"
" Note you can change VT remotely using the chvt(1)\n" " Note you can change VT remotely using the chvt(1)\n"
" command. Sometimes switching out and back corrects\n" " command. Sometimes switching out and back corrects\n"
@ -2591,7 +2592,7 @@ void print_help(int mode) {
" value is stored in X11VNC_RAWFB_STR for the pipe command\n" " value is stored in X11VNC_RAWFB_STR for the pipe command\n"
" to use if it wants. Do 'env | grep X11VNC' for more.\n" " to use if it wants. Do 'env | grep X11VNC' for more.\n"
"\n" "\n"
" Built-in pipeinput modes:\n" " Built-in pipeinput modes (no external program required):\n"
"\n" "\n"
" If cmd is \"VID\" and you are using the -rawfb for a\n" " If cmd is \"VID\" and you are using the -rawfb for a\n"
" video capture device, then an internal list of keyboard\n" " video capture device, then an internal list of keyboard\n"
@ -2655,16 +2656,25 @@ void print_help(int mode) {
" will get out of sync (probably due to a mouse\n" " will get out of sync (probably due to a mouse\n"
" \"threshold\" setting where the acceleration doe not\n" " \"threshold\" setting where the acceleration doe not\n"
" apply, set xset(1)). The option reset=N sets the\n" " apply, set xset(1)). The option reset=N sets the\n"
" number of ms (default 500) after which the cursor is\n" " number of ms (default 150) after which the cursor is\n"
" attempted to be reset (by forcing the mouse to (0,\n" " attempted to be reset (by forcing the mouse to (0,\n"
" 0) via small increments and then back out to (x, y)\n" " 0) via small increments and then back out to (x, y)\n"
" in 1 jump), This correction seems to be needed but can\n" " in 1 jump), This correction seems to be needed but can\n"
" cause jerkiness or unexpected behavior with menus, etc.\n" " cause jerkiness or unexpected behavior with menus, etc.\n"
" Use reset=0 to disable.\n" " Use reset=0 to disable.\n"
"\n" "\n"
" If you set the env. var X11VNC_UINPUT_THRESHOLDS then\n"
" the thresh=n mode will be enabled. It it currently\n"
" not working well. If |dx| <= thresh and |dy| < thresh\n"
" no acceleration is applied. Use \"thresh=+n\" |dx| +\n"
" |dy| <= thresh to be used instead (X11?)\n"
"\n"
" Example:\n" " Example:\n"
" -pipeinput UINPUT:accel=4.0 -cursor none\n" " -pipeinput UINPUT:accel=4.0 -cursor none\n"
"\n" "\n"
" You can also set the env. var X11VNC_UINPUT_DEBUG=1 or\n"
" higher to get debugging output for UINPUT mode.\n"
"\n"
"-gui [gui-opts] Start up a simple tcl/tk gui based on the the remote\n" "-gui [gui-opts] Start up a simple tcl/tk gui based on the the remote\n"
" control options -remote/-query described below.\n" " control options -remote/-query described below.\n"
" Requires the \"wish\" program to be installed on the\n" " Requires the \"wish\" program to be installed on the\n"
@ -3024,6 +3034,7 @@ void print_help(int mode) {
" rawfb:str set -rawfb mode to \"str\".\n" " rawfb:str set -rawfb mode to \"str\".\n"
" uinput_accel:f set uinput_accel to f.\n" " uinput_accel:f set uinput_accel to f.\n"
" uinput_reset:n set uinput_reset to n ms.\n" " uinput_reset:n set uinput_reset to n ms.\n"
" uinput_always:n set uinput_always to 1/0.\n"
" progressive:n set libvncserver -progressive slice\n" " progressive:n set libvncserver -progressive slice\n"
" height parameter to n.\n" " height parameter to n.\n"
" desktop:str set -desktop name to str for new clients.\n" " desktop:str set -desktop name to str for new clients.\n"
@ -3090,13 +3101,6 @@ void print_help(int mode) {
" query straight to the X11VNC_REMOTE property or connect\n" " query straight to the X11VNC_REMOTE property or connect\n"
" file use \"qry=...\" instead of \"cmd=...\"\n" " file use \"qry=...\" instead of \"cmd=...\"\n"
"\n" "\n"
" Here is the current list of \"variables\" that can\n"
" be supplied to the -query command. This includes the\n"
" \"N/A\" ones that return no useful info. For variables\n"
" names that do not correspond to an x11vnc option or\n"
" remote command, we hope the name makes it obvious what\n"
" the returned value corresponds to (hint: the ext_*\n"
" variables correspond to the presence of X extensions):\n"
" ans= stop quit exit shutdown ping blacken zero\n" " ans= stop quit exit shutdown ping blacken zero\n"
" refresh reset close disconnect id sid waitmapped\n" " refresh reset close disconnect id sid waitmapped\n"
" nowaitmapped clip flashcmap noflashcmap shiftcmap\n" " nowaitmapped clip flashcmap noflashcmap shiftcmap\n"
@ -3127,16 +3131,16 @@ void print_help(int mode) {
" nodragging wireframe_mode wireframe wf nowireframe\n" " nodragging wireframe_mode wireframe wf nowireframe\n"
" nowf wirecopyrect wcr nowirecopyrect nowcr scr_area\n" " nowf wirecopyrect wcr nowirecopyrect nowcr scr_area\n"
" scr_skip scr_inc scr_keys scr_term scr_keyrepeat\n" " scr_skip scr_inc scr_keys scr_term scr_keyrepeat\n"
" scr_parms scrollcopyrect scr noscrollcopyrect\n" " scr_parms scrollcopyrect scr noscrollcopyrect noscr\n"
" noscr fixscreen noxrecord xrecord reset_record\n" " fixscreen noxrecord xrecord reset_record pointer_mode\n"
" pointer_mode pm input_skip allinput noallinput input\n" " pm input_skip allinput noallinput input grabkbd\n"
" grabkbd nograbkbd grabptr nograbptr client_input\n" " nograbkbd grabptr nograbptr client_input speeds wmdt\n"
" speeds wmdt debug_pointer dp nodebug_pointer nodp\n" " debug_pointer dp nodebug_pointer nodp debug_keyboard\n"
" debug_keyboard dk nodebug_keyboard nodk deferupdate\n" " dk nodebug_keyboard nodk deferupdate defer wait_ui\n"
" defer wait_ui wait_bog nowait_bog slow_fb wait\n" " wait_bog nowait_bog slow_fb wait readtimeout nap\n"
" readtimeout nap nonap sb screen_blank fbpm nofbpm\n" " nonap sb screen_blank fbpm nofbpm fs gaps grow\n"
" fs gaps grow fuzz snapfb nosnapfb rawfb uinput_accel\n" " fuzz snapfb nosnapfb rawfb uinput_accel uinput_reset\n"
" uinput_reset progressive rfbport http nohttp httpport\n" " uinput_always progressive rfbport http nohttp httpport\n"
" httpdir enablehttpproxy noenablehttpproxy alwaysshared\n" " httpdir enablehttpproxy noenablehttpproxy alwaysshared\n"
" noalwaysshared nevershared noalwaysshared dontdisconnect\n" " noalwaysshared nevershared noalwaysshared dontdisconnect\n"
" nodontdisconnect desktop debug_xevents nodebug_xevents\n" " nodontdisconnect desktop debug_xevents nodebug_xevents\n"
@ -3162,6 +3166,7 @@ void print_help(int mode) {
" mouse_x mouse_y bpp depth indexed_color dpy_x dpy_y\n" " mouse_x mouse_y bpp depth indexed_color dpy_x dpy_y\n"
" wdpy_x wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y\n" " wdpy_x wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y\n"
" rfbauth passwd viewpasswd\n" " rfbauth passwd viewpasswd\n"
"\n"
"-QD variable Just like -query variable, but returns the default\n" "-QD variable Just like -query variable, but returns the default\n"
" value for that parameter (no running x11vnc server\n" " value for that parameter (no running x11vnc server\n"
" is consulted)\n" " is consulted)\n"

@ -2631,6 +2631,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
static rfbKeySym last_keysym = NoSymbol; static rfbKeySym last_keysym = NoSymbol;
static rfbKeySym max_keyrepeat_last_keysym = NoSymbol; static rfbKeySym max_keyrepeat_last_keysym = NoSymbol;
static double max_keyrepeat_last_time = 0.0; static double max_keyrepeat_last_time = 0.0;
static double max_keyrepeat_always = -1.0;
dtime0(&tnow); dtime0(&tnow);
got_keyboard_calls++; got_keyboard_calls++;
@ -2645,6 +2646,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
unixpw_in_progress, tnow - x11vnc_start); unixpw_in_progress, tnow - x11vnc_start);
} }
if (keysym <= 0) { if (keysym <= 0) {
rfbLog("keyboard: skipping 0x0 keysym\n"); rfbLog("keyboard: skipping 0x0 keysym\n");
return; return;
@ -2768,6 +2770,18 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
} }
} }
#ifdef MAX_KEYREPEAT
if (max_keyrepeat_always < 0.0) {
if (getenv("MAX_KEYREPEAT")) {
max_keyrepeat_always = atof(getenv("MAX_KEYREPEAT"));
} else {
max_keyrepeat_always = 0.0;
}
}
if (max_keyrepeat_always > 0.0) {
max_keyrepeat_time = max_keyrepeat_always;
}
#endif
if (!down && skipped_last_down) { if (!down && skipped_last_down) {
int db = debug_scroll; int db = debug_scroll;
if (keysym == max_keyrepeat_last_keysym) { if (keysym == max_keyrepeat_last_keysym) {

@ -3463,6 +3463,17 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("set_uinput_accel: %s\n", p); rfbLog("set_uinput_accel: %s\n", p);
set_uinput_accel(p); set_uinput_accel(p);
} else if (strstr(p, "uinput_thresh") == p) {
COLON_CHECK("uinput_thresh:")
if (query) {
snprintf(buf, bufn, "ans=%s%s%s", p, co,
NONUL(get_uinput_thresh()));
goto qry;
}
p += strlen("uinput_thresh:");
rfbLog("set_uinput_thresh: %s\n", p);
set_uinput_thresh(p);
} else if (strstr(p, "uinput_reset") == p) { } else if (strstr(p, "uinput_reset") == p) {
COLON_CHECK("uinput_reset:") COLON_CHECK("uinput_reset:")
p += strlen("uinput_reset:"); p += strlen("uinput_reset:");
@ -3474,6 +3485,17 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("set_uinput_reset: %s\n", p); rfbLog("set_uinput_reset: %s\n", p);
set_uinput_reset(atoi(p)); set_uinput_reset(atoi(p));
} else if (strstr(p, "uinput_always") == p) {
COLON_CHECK("uinput_always:")
p += strlen("uinput_always:");
if (query) {
snprintf(buf, bufn, "ans=%s%s%d", p, co,
get_uinput_always());
goto qry;
}
rfbLog("set_uinput_always: %s\n", p);
set_uinput_always(atoi(p));
} else if (strstr(p, "progressive") == p) { } else if (strstr(p, "progressive") == p) {
int f; int f;
COLON_CHECK("progressive:") COLON_CHECK("progressive:")

@ -180,6 +180,7 @@ Screen
pipeinput: pipeinput:
uinput_accel: uinput_accel:
uinput_reset: uinput_reset:
uinput_always:
24to32 24to32
=GAL LOFF =GAL LOFF

@ -191,6 +191,7 @@ char gui_code[] = "";
" pipeinput:\n" " pipeinput:\n"
" uinput_accel:\n" " uinput_accel:\n"
" uinput_reset:\n" " uinput_reset:\n"
" uinput_always:\n"
" 24to32\n" " 24to32\n"
" =GAL LOFF\n" " =GAL LOFF\n"
"\n" "\n"

@ -25,8 +25,10 @@
int check_uinput(void); int check_uinput(void);
int initialize_uinput(void); int initialize_uinput(void);
int set_uinput_accel(char *str); int set_uinput_accel(char *str);
int set_uinput_thresh(char *str);
void set_uinput_reset(int ms); void set_uinput_reset(int ms);
char *get_uinput_accel(); char *get_uinput_accel();
char *get_uinput_thresh();
int get_uinput_reset(); int get_uinput_reset();
void parse_uinput_str(char *str); void parse_uinput_str(char *str);
void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client); 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 lookup_code(int keysym);
static int fd = -1; static int fd = -1;
static int db = 1; static int db = 0;
static int bmask = 0; static int bmask = 0;
static char *injectable = NULL; static char *injectable = NULL;
@ -155,6 +157,11 @@ int initialize_uinput(void) {
fd = -1; fd = -1;
} }
if (getenv("X11VNC_UINPUT_DEBUG")) {
db = atoi(getenv("X11VNC_UINPUT_DEBUG"));
rfbLog("set uinput debug to: %d\n", db);
}
init_key_tracker(); init_key_tracker();
if (uinput_dev) { if (uinput_dev) {
@ -213,15 +220,21 @@ int initialize_uinput(void) {
#endif #endif
} }
/* these defaults are based on qt-embedded 7/2006 */
static double fudge_x = 0.5; /* accel=2.0 */ static double fudge_x = 0.5; /* accel=2.0 */
static double fudge_y = 0.5; static double fudge_y = 0.5;
static int thresh = 5;
static int thresh_or = 1;
static double resid_x = 0.0; static double resid_x = 0.0;
static double resid_y = 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 double last_button_click = 0.0;
static int uinput_always = 0;
static void set_uinput_accel_xy(double fx, double fy) { static void set_uinput_accel_xy(double fx, double fy) {
fudge_x = 1.0/fx; fudge_x = 1.0/fx;
fudge_y = 1.0/fy; 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_accel_str = NULL;
static char *uinput_thresh_str = NULL;
int set_uinput_accel(char *str) { int set_uinput_accel(char *str) {
double fx, fy; double fx, fy;
@ -249,18 +263,42 @@ int set_uinput_accel(char *str) {
return 1; 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) { void set_uinput_reset(int ms) {
zero_delay = (double) ms/1000.; zero_delay = (double) ms/1000.;
rfbLog("set_uinput_reset: %d\n", ms); rfbLog("set_uinput_reset: %d\n", ms);
} }
int set_uinput_always(int a) {
uinput_always = a;
}
char *get_uinput_accel(void) { char *get_uinput_accel(void) {
return uinput_accel_str; return uinput_accel_str;
} }
char *get_uinput_thresh(void) {
return uinput_thresh_str;
}
int get_uinput_reset(void) { int get_uinput_reset(void) {
return (int) (1000 * zero_delay); return (int) (1000 * zero_delay);
} }
int get_uinput_always(void) {
return uinput_always;
}
void parse_uinput_str(char *in) { void parse_uinput_str(char *in) {
char *p, *q, *str = strdup(in); char *p, *q, *str = strdup(in);
@ -282,10 +320,16 @@ void parse_uinput_str(char *in) {
if (! set_uinput_accel(q)) { if (! set_uinput_accel(q)) {
clean_up_exit(1); clean_up_exit(1);
} }
} else if (strstr(p, "thresh=") == p) {
q = p + strlen("thresh=");
set_uinput_thresh(q);
} else if (strstr(p, "reset=") == p) { } else if (strstr(p, "reset=") == p) {
int n = atoi(p + strlen("reset=")); int n = atoi(p + strlen("reset="));
set_uinput_reset(n); 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) { } else if (strpbrk(p, "KMB") == p) {
if (injectable) { if (injectable) {
free(injectable); free(injectable);
@ -307,19 +351,18 @@ static void ptr_move(int dx, int dy) {
if (injectable && strchr(injectable, 'M') == NULL) { if (injectable && strchr(injectable, 'M') == NULL) {
return; return;
} }
if (0) fprintf(stderr, "ptr_move: %d %d\n", dx, dy);
memset(&ev, 0, sizeof(ev)); memset(&ev, 0, sizeof(ev));
gettimeofday(&ev.time, NULL); gettimeofday(&ev.time, NULL);
ev.type = EV_REL; ev.type = EV_REL;
ev.code = REL_X; ev.code = REL_Y;
ev.value = dx; ev.value = dy;
write(fd, &ev, sizeof(ev)); write(fd, &ev, sizeof(ev));
ev.type = EV_REL; ev.type = EV_REL;
ev.code = REL_Y; ev.code = REL_X;
ev.value = dy; ev.value = dx;
write(fd, &ev, sizeof(ev)); write(fd, &ev, sizeof(ev));
ev.type = EV_SYN; ev.type = EV_SYN;
@ -329,36 +372,143 @@ if (0) fprintf(stderr, "ptr_move: %d %d\n", dx, dy);
#endif #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) { 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); } else {
dyf = (int) (fudge_y * (double) dy); 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, "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); ptr_move(dxf, dyf);
resid_x += fudge_x * (double) dx - dxf; resid_x += fx - dxf;
resid_y += fudge_y * (double) dy - dyf; 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) { if (db > 1) fprintf(stderr, "*%s resid: dx dy: %d %d %f %f\n", accel > 1 ? "*" : " ", dxf, dyf, resid_x, resid_y);
dxf = 0; if (0) {usleep(100*1000)};
dyf = 0; ptr_move(dxf, dyf);
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));
} }
resid_y -= dyf;
ptr_move(dxf, dyf);
} }
} }
@ -370,7 +520,7 @@ static void button_click(int down, int btn) {
return; 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)); memset(&ev, 0, sizeof(ev));
gettimeofday(&ev.time, NULL); 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 int last_x = -1, last_y = -1, last_mask = -1;
static double last_zero = 0.0; static double last_zero = 0.0;
allowed_input_t input; allowed_input_t input;
int do_reset; int do_reset, reset_lower_right = 1;
double now; 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); 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) { if (do_reset) {
static int first = 1; static int first = 1;
if (zero_delay > 0.0 || first) { if (zero_delay > 0.0 || first) {
/* try to push it to 0,0 */ /* try to push it to 0,0 */
int tx = fudge_x * last_x + 40; int tx, ty, bigjump = 1;
int ty = fudge_y * last_y + 40;
int 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) { if (bigjump) {
ptr_move(-tx, -ty); if (reset_lower_right) {
ptr_move(-tx, -ty); 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 { } else {
int i, step, n = 20; int i, step, n = 20;
step = dpy_x / n; step = dpy_x / n;
if (step < 100) step = 100; if (step < 100) step = 100;
for (i=0; i < n; i++) { 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++) { 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 */ /* 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 */ /* now jump back out */
ptr_rel(x, y); if (reset_lower_right) {
if (0) usleep(10*1000); ptr_rel(x - dpy_x, y - dpy_y);
} else {
ptr_rel(x, y);
}
if (1) {usleep(10*1000)};
last_x = x; last_x = x;
last_y = y; last_y = y;
@ -494,12 +709,12 @@ void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client) {
last_mask = mask; last_mask = mask;
} }
#if 0 if (db > 2) {
fprintf(stderr, "mask: %s\n", bitprint(mask, 16)); fprintf(stderr, "mask: %s\n", bitprint(mask, 16));
fprintf(stderr, "bmask: %s\n", bitprint(bmask, 16)); fprintf(stderr, "bmask: %s\n", bitprint(bmask, 16));
fprintf(stderr, "last_mask: %s\n", bitprint(last_mask, 16)); fprintf(stderr, "last_mask: %s\n", bitprint(last_mask, 16));
fprintf(stderr, "button_mask: %s\n", bitprint(button_mask, 16)); fprintf(stderr, "button_mask: %s\n", bitprint(button_mask, 16));
#endif }
if (mask != last_mask) { if (mask != last_mask) {
int i; int i;
@ -542,7 +757,7 @@ void uinput_key_command(int down, int keysym, rfbClientPtr client) {
if (scancode < 0) { if (scancode < 0) {
return; 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)); memset(&ev, 0, sizeof(ev));
gettimeofday(&ev.time, NULL); gettimeofday(&ev.time, NULL);
@ -557,7 +772,7 @@ void uinput_key_command(int down, int keysym, rfbClientPtr client) {
ev.value = 0; ev.value = 0;
write(fd, &ev, sizeof(ev)); write(fd, &ev, sizeof(ev));
if (0 <= scancode < 256) { if (0 <= scancode && scancode < 256) {
key_pressed[scancode] = down ? 1 : 0; key_pressed[scancode] = down ? 1 : 0;
} }
#endif #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_Escape KEY_ESC
XK_1 KEY_1 XK_1 KEY_1

@ -6,9 +6,13 @@
extern int check_uinput(void); extern int check_uinput(void);
extern int initialize_uinput(void); extern int initialize_uinput(void);
extern int set_uinput_accel(char *str); extern int set_uinput_accel(char *str);
extern int set_uinput_thresh(char *str);
extern void set_uinput_reset(int ms); extern void set_uinput_reset(int ms);
extern void set_uinput_always(int);
extern char *get_uinput_accel(); extern char *get_uinput_accel();
extern char *get_uinput_thresh();
extern int get_uinput_reset(); extern int get_uinput_reset();
extern int get_uinput_always();
extern void parse_uinput_str(char *str); extern void parse_uinput_str(char *str);
extern void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client); extern void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client);
extern void uinput_key_command(int down, int keysym, rfbClientPtr client); extern void uinput_key_command(int down, int keysym, rfbClientPtr client);

@ -2,7 +2,7 @@
.TH X11VNC "1" "July 2006" "x11vnc " "User Commands" .TH X11VNC "1" "July 2006" "x11vnc " "User Commands"
.SH NAME .SH NAME
x11vnc - allow VNC connections to real X11 displays x11vnc - allow VNC connections to real X11 displays
version: 0.8.2, lastmod: 2006-07-09 version: 0.8.2, lastmod: 2006-07-11
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
@ -2991,16 +2991,17 @@ be root to inject keystrokes. /dev/tty0 refers to the
active VT, to indicate one explicitly, use "cons2", active VT, to indicate one explicitly, use "cons2",
etc. using the VT number. etc. using the VT number.
.IP .IP
If the Linux version seems to be 2.6 or later and the If the Linux version seems to be 2.6 or later and
"uinput" module appears to be present, then the uinput the "uinput" module appears to be present, then
method will be used instead of /dev/ttyN. uinput allows the uinput method will be used instead of /dev/ttyN.
insertion of BOTH keystrokes and mouse input and so it uinput allows insertion of BOTH keystrokes and mouse
preferred when accessing graphical (e.g. QT-embedded) input and so it preferred when accessing graphical
linux console apps. See \fB-pipeinput\fR UINPUT below (e.g. QT-embedded) linux console apps. See \fB-pipeinput\fR
for more information on this mode (you may want to UINPUT below for more information on this mode; you
also use the \fB-nodragging\fR and \fB-cursor\fR none options). will have to use \fB-pipeinput\fR if you want to tweak any
Use "cons0", etc or \fB-pipeinput\fR CONS to force the UINPUT parameters. You may also want to also use the
/dev/ttyN method. \fB-nodragging\fR and \fB-cursor\fR none options. Use "cons0",
etc or \fB-pipeinput\fR CONS to force the /dev/ttyN method.
.IP .IP
Note you can change VT remotely using the Note you can change VT remotely using the
.IR chvt (1) .IR chvt (1)
@ -3059,7 +3060,7 @@ To facilitate this, if \fB-rawfb\fR is in effect then the
value is stored in X11VNC_RAWFB_STR for the pipe command value is stored in X11VNC_RAWFB_STR for the pipe command
to use if it wants. Do 'env | grep X11VNC' for more. to use if it wants. Do 'env | grep X11VNC' for more.
.IP .IP
Built-in pipeinput modes: Built-in pipeinput modes (no external program required):
.IP .IP
If cmd is "VID" and you are using the \fB-rawfb\fR for a If cmd is "VID" and you are using the \fB-rawfb\fR for a
video capture device, then an internal list of keyboard video capture device, then an internal list of keyboard
@ -3125,15 +3126,24 @@ will get out of sync (probably due to a mouse
apply, set apply, set
.IR xset (1) .IR xset (1)
). The option reset=N sets the ). The option reset=N sets the
number of ms (default 500) after which the cursor is number of ms (default 150) after which the cursor is
attempted to be reset (by forcing the mouse to (0, attempted to be reset (by forcing the mouse to (0,
0) via small increments and then back out to (x, y) 0) via small increments and then back out to (x, y)
in 1 jump), This correction seems to be needed but can in 1 jump), This correction seems to be needed but can
cause jerkiness or unexpected behavior with menus, etc. cause jerkiness or unexpected behavior with menus, etc.
Use reset=0 to disable. Use reset=0 to disable.
.IP .IP
If you set the env. var X11VNC_UINPUT_THRESHOLDS then
the thresh=n mode will be enabled. It it currently
not working well. If |dx| <= thresh and |dy| < thresh
no acceleration is applied. Use "thresh=+n" |dx| +
|dy| <= thresh to be used instead (X11?)
.IP
Example: Example:
\fB-pipeinput\fR UINPUT:accel=4.0 \fB-cursor\fR none \fB-pipeinput\fR UINPUT:accel=4.0 \fB-cursor\fR none
.IP
You can also set the env. var X11VNC_UINPUT_DEBUG=1 or
higher to get debugging output for UINPUT mode.
.PP .PP
\fB-gui\fR \fI[gui-opts]\fR \fB-gui\fR \fI[gui-opts]\fR
.IP .IP
@ -3679,6 +3689,8 @@ uinput_accel:f set uinput_accel to f.
.IP .IP
uinput_reset:n set uinput_reset to n ms. uinput_reset:n set uinput_reset to n ms.
.IP .IP
uinput_always:n set uinput_always to 1/0.
.IP
progressive:n set libvncserver \fB-progressive\fR slice progressive:n set libvncserver \fB-progressive\fR slice
height parameter to n. height parameter to n.
.IP .IP
@ -3791,13 +3803,6 @@ these cases the value returned is "N/A". To direct a
query straight to the X11VNC_REMOTE property or connect query straight to the X11VNC_REMOTE property or connect
file use "qry=..." instead of "cmd=..." file use "qry=..." instead of "cmd=..."
.IP .IP
Here is the current list of "variables" that can
be supplied to the \fB-query\fR command. This includes the
"N/A" ones that return no useful info. For variables
names that do not correspond to an x11vnc option or
remote command, we hope the name makes it obvious what
the returned value corresponds to (hint: the ext_*
variables correspond to the presence of X extensions):
ans= stop quit exit shutdown ping blacken zero ans= stop quit exit shutdown ping blacken zero
refresh reset close disconnect id sid waitmapped refresh reset close disconnect id sid waitmapped
nowaitmapped clip flashcmap noflashcmap shiftcmap nowaitmapped clip flashcmap noflashcmap shiftcmap
@ -3828,16 +3833,16 @@ xwarp noxwarppointer noxwarp buttonmap dragging
nodragging wireframe_mode wireframe wf nowireframe nodragging wireframe_mode wireframe wf nowireframe
nowf wirecopyrect wcr nowirecopyrect nowcr scr_area nowf wirecopyrect wcr nowirecopyrect nowcr scr_area
scr_skip scr_inc scr_keys scr_term scr_keyrepeat scr_skip scr_inc scr_keys scr_term scr_keyrepeat
scr_parms scrollcopyrect scr noscrollcopyrect scr_parms scrollcopyrect scr noscrollcopyrect noscr
noscr fixscreen noxrecord xrecord reset_record fixscreen noxrecord xrecord reset_record pointer_mode
pointer_mode pm input_skip allinput noallinput input pm input_skip allinput noallinput input grabkbd
grabkbd nograbkbd grabptr nograbptr client_input nograbkbd grabptr nograbptr client_input speeds wmdt
speeds wmdt debug_pointer dp nodebug_pointer nodp debug_pointer dp nodebug_pointer nodp debug_keyboard
debug_keyboard dk nodebug_keyboard nodk deferupdate dk nodebug_keyboard nodk deferupdate defer wait_ui
defer wait_ui wait_bog nowait_bog slow_fb wait wait_bog nowait_bog slow_fb wait readtimeout nap
readtimeout nap nonap sb screen_blank fbpm nofbpm nonap sb screen_blank fbpm nofbpm fs gaps grow
fs gaps grow fuzz snapfb nosnapfb rawfb uinput_accel fuzz snapfb nosnapfb rawfb uinput_accel uinput_reset
uinput_reset progressive rfbport http nohttp httpport uinput_always progressive rfbport http nohttp httpport
httpdir enablehttpproxy noenablehttpproxy alwaysshared httpdir enablehttpproxy noenablehttpproxy alwaysshared
noalwaysshared nevershared noalwaysshared dontdisconnect noalwaysshared nevershared noalwaysshared dontdisconnect
nodontdisconnect desktop debug_xevents nodebug_xevents nodontdisconnect desktop debug_xevents nodebug_xevents

@ -19,7 +19,7 @@
* USA. * USA.
* *
* *
* This program is based heavily on the following programs: * This program is based on the following programs:
* *
* the originial x11vnc.c in libvncserver (Johannes E. Schindelin) * the originial x11vnc.c in libvncserver (Johannes E. Schindelin)
* x0rfbserver, the original native X vnc server (Jens Wagner) * x0rfbserver, the original native X vnc server (Jens Wagner)

@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0; int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8.2 lastmod: 2006-07-09"; char lastmod[] = "0.8.2 lastmod: 2006-07-11";
/* X display info */ /* X display info */

Loading…
Cancel
Save