Commit a5524005 authored by runge's avatar runge

x11vnc: more scrolling, -scr_term, -wait_ui, -nowait_bog

parent 8d116dfa
2005-05-17 Karl Runge <runge@karlrunge.com>
* x11vnc: more scrolling, -scr_term, -wait_ui, -nowait_bog
2005-05-15 Johannes E. Schindelin <Johannes.Schindelin@gmx.de> 2005-05-15 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* almost every file: ANSIfy, fix warnings from Linus' sparse * almost every file: ANSIfy, fix warnings from Linus' sparse
......
2005-05-17 Karl Runge <runge@karlrunge.com>
* more -scrollcopyrect, -scr_term hacks for terminals.
* -wait_ui, -nowait_bog tunables. push cursor sooner.
2005-05-14 Karl Runge <runge@karlrunge.com> 2005-05-14 Karl Runge <runge@karlrunge.com>
* much more work on "-scrollcopyrect" mode... getting usable. * much more work on "-scrollcopyrect" mode... getting usable.
* remove -pointer_mode 3, shift everyone back down * remove -pointer_mode 3, shift everyone back down
......
x11vnc README file Date: Sat May 14 00:07:44 EDT 2005 x11vnc README file Date: Tue May 17 14:39:38 EDT 2005
The following information is taken from these URLs: The following information is taken from these URLs:
...@@ -4238,7 +4238,7 @@ x11vnc: a VNC server for real X displays ...@@ -4238,7 +4238,7 @@ x11vnc: a VNC server for real X displays
Here are all of x11vnc command line options: Here are all of x11vnc command line options:
% x11vnc -opts (see below for -help long descriptions) % x11vnc -opts (see below for -help long descriptions)
x11vnc: allow VNC connections to real X11 displays. 0.7.2 lastmod: 2005-05-14 x11vnc: allow VNC connections to real X11 displays. 0.7.2 lastmod: 2005-05-17
x11vnc options: x11vnc options:
-display disp -auth file -display disp -auth file
...@@ -4288,26 +4288,28 @@ x11vnc options: ...@@ -4288,26 +4288,28 @@ x11vnc options:
-debug_wireframe -scrollcopyrect mode -debug_wireframe -scrollcopyrect mode
-noscrollcopyrect -scr_area n -noscrollcopyrect -scr_area n
-scr_skip list -scr_inc list -scr_skip list -scr_inc list
-scr_keys list -scr_parms string -scr_keys list -scr_term list
-debug_scroll -pointer_mode n -scr_parms string -debug_scroll
-input_skip n -speeds rd,bw,lat -pointer_mode n -input_skip n
-debug_pointer -debug_keyboard -speeds rd,bw,lat -debug_pointer
-defer time -wait time -debug_keyboard -defer time
-readtimeout n -nap -wait time -wait_ui factor
-nonap -sb time -nowait_bog -readtimeout n
-noxdamage -xd_area A -nap -nonap
-xd_mem f -sigpipe string -sb time -noxdamage
-threads -nothreads -xd_area A -xd_mem f
-fs f -gaps n -sigpipe string -threads
-grow n -fuzz n -nothreads -fs f
-debug_tiles -snapfb -gaps n -grow n
-rawfb string -pipeinput cmd -fuzz n -debug_tiles
-gui [gui-opts] -remote command -snapfb -rawfb string
-query variable -sync -pipeinput cmd -gui [gui-opts]
-noremote -yesremote -remote command -query variable
-unsafe -safer -sync -noremote
-privremote -nocmds -yesremote -unsafe
-deny_all -safer -privremote
-nocmds -deny_all
libvncserver options: libvncserver options:
-rfbport port TCP port for RFB protocol -rfbport port TCP port for RFB protocol
...@@ -4333,7 +4335,7 @@ libvncserver options: ...@@ -4333,7 +4335,7 @@ libvncserver options:
% x11vnc -help % x11vnc -help
x11vnc: allow VNC connections to real X11 displays. 0.7.2 lastmod: 2005-05-14 x11vnc: allow VNC connections to real X11 displays. 0.7.2 lastmod: 2005-05-17
Typical usage is: Typical usage is:
...@@ -5243,6 +5245,29 @@ Options: ...@@ -5243,6 +5245,29 @@ Options:
Shift_L, Control_R, etc, are skipped since they almost Shift_L, Control_R, etc, are skipped since they almost
never induce scrolling by themselves. never induce scrolling by themselves.
-scr_term list Yet another cosmetic kludge. Apply shell/terminal
heuristics to applications matching comma separated list
(same as -scr_skip/-scr_inc). For example an annoying
transient under scroll detection is if you hit Enter in
a terminal shell with full text window, the solid text
cursor block will be scrolled up. So for a short time
there are two (or more) block cursors on the screen.
There are similar scenarios, (e.g. an output line is
duplicated).
These transients are induced by the approximation of
scroll detection (e.g. it detects the scroll, but not
the fact that the block cursor was cleared just before
the scroll). In nearly all cases these transient errors
are repaired when the true X framebuffer is consulted
by the normal polling. But they are distracting, so
what this option provides is extra "padding" near the
bottom of the terminal window: a few extra lines near
the bottom will not be scrolled, but rather updated
from the actual X framebuffer. This usually reduces
the annoying artifacts. Use "none" to disable.
Default: "term"
-scr_parms string Set various parameters for the scrollcopyrect mode. -scr_parms string Set various parameters for the scrollcopyrect mode.
The format is similar to that for -wireframe and packed The format is similar to that for -wireframe and packed
with lots of parameters: with lots of parameters:
...@@ -5374,6 +5399,18 @@ Options: ...@@ -5374,6 +5399,18 @@ Options:
(deferUpdateTime) Default: 30 (deferUpdateTime) Default: 30
-wait time Time in ms to pause between screen polls. Used to cut -wait time Time in ms to pause between screen polls. Used to cut
down on load. Default: 30 down on load. Default: 30
-wait_ui factor Factor by which to cut the -wait time if there
has been recent user input (pointer or keyboard).
Improves response, but increases the load whenever you
are moving the mouse or typing. Default: 2.00
-nowait_bog Do not detect if the screen polling is "bogging down"
and sleep more. Some activities with no user input can
slow things down a lot: consider a large terminal window
with a long build running in it continously streaming
text output. By default x11vnc will try to detect this
(3 screen polls in a row each longer than 0.25 sec with
no user input), and sleep up to 1.5 secs to let things
"catch up". Use this option to disable the detection.
-readtimeout n Set libvncserver rfbMaxClientWait to n seconds. On -readtimeout n Set libvncserver rfbMaxClientWait to n seconds. On
slow links that take a long time to paint the first slow links that take a long time to paint the first
screen libvncserver may hit the timeout and drop the screen libvncserver may hit the timeout and drop the
...@@ -5751,6 +5788,7 @@ Options: ...@@ -5751,6 +5788,7 @@ Options:
scr_skip:list set -scr_skip to "list" scr_skip:list set -scr_skip to "list"
scr_inc:list set -scr_inc to "list" scr_inc:list set -scr_inc to "list"
scr_keys:list set -scr_keys to "list" scr_keys:list set -scr_keys to "list"
scr_term:list set -scr_term to "list"
scr_parms:str set -scr_parms parameters. scr_parms:str set -scr_parms parameters.
pointer_mode:n set -pointer_mode to n. same as "pm" pointer_mode:n set -pointer_mode to n. same as "pm"
input_skip:n set -input_skip to n. input_skip:n set -input_skip to n.
...@@ -5761,6 +5799,9 @@ Options: ...@@ -5761,6 +5799,9 @@ Options:
nodebug_keyboard disable -debug_keyboard, same as "nodk" nodebug_keyboard disable -debug_keyboard, same as "nodk"
defer:n set -defer to n ms,same as deferupdate:n defer:n set -defer to n ms,same as deferupdate:n
wait:n set -wait to n ms. wait:n set -wait to n ms.
wait_ui:f set -wait_ui factor to f.
wait_bog disable -nowait_bog mode.
nowait_bog enable -nowait_bog mode.
readtimeout:n set read timeout to n seconds. readtimeout:n set read timeout to n seconds.
nap enable -nap mode. nap enable -nap mode.
nonap disable -nap mode. nonap disable -nap mode.
...@@ -5856,35 +5897,35 @@ Options: ...@@ -5856,35 +5897,35 @@ Options:
forever noforever once timeout deny lock nodeny unlock forever noforever once timeout deny lock nodeny unlock
connect allowonce allow localhost nolocalhost listen connect allowonce allow localhost nolocalhost listen
lookup nolookup accept gone shm noshm flipbyteorder lookup nolookup accept gone shm noshm flipbyteorder
noflipbyteorder onetile noonetile solid_color noflipbyteorder onetile noonetile solid_color solid
solid nosolid blackout xinerama noxinerama xtrap nosolid blackout xinerama noxinerama xtrap noxtrap
noxtrap xrandr noxrandr xrandr_mode padgeom quiet q xrandr noxrandr xrandr_mode padgeom quiet q noquiet
noquiet modtweak nomodtweak xkb noxkb skip_keycodes modtweak nomodtweak xkb noxkb skip_keycodes skip_dups
skip_dups noskip_dups add_keysyms noadd_keysyms noskip_dups add_keysyms noadd_keysyms clear_mods
clear_mods noclear_mods clear_keys noclear_keys noclear_mods clear_keys noclear_keys remap repeat
remap repeat norepeat fb nofb bell nobell sel nosel norepeat fb nofb bell nobell sel nosel primary noprimary
primary noprimary cursorshape nocursorshape cursorpos cursorshape nocursorshape cursorpos nocursorpos cursor
nocursorpos cursor show_cursor noshow_cursor nocursor show_cursor noshow_cursor nocursor arrow xfixes noxfixes
arrow xfixes noxfixes xdamage noxdamage xd_area xd_mem xdamage noxdamage xd_area xd_mem alphacut alphafrac
alphacut alphafrac alpharemove noalpharemove alphablend alpharemove noalpharemove alphablend noalphablend
noalphablend xwarppointer xwarp noxwarppointer noxwarp xwarppointer xwarp noxwarppointer noxwarp buttonmap
buttonmap dragging nodragging wireframe_mode wireframe dragging nodragging wireframe_mode wireframe wf
wf nowireframe nowf wirecopyrect wcr nowirecopyrect nowireframe nowf wirecopyrect wcr nowirecopyrect nowcr
nowcr scr_area scr_skip scr_inc scr_keys scr_parms scr_area scr_skip scr_inc scr_keys scr_term scr_parms
scrollcopyrect scr noscrollcopyrect noscr pointer_mode scrollcopyrect scr noscrollcopyrect noscr pointer_mode
pm input_skip input client_input speeds debug_pointer dp pm input_skip input client_input speeds debug_pointer dp
nodebug_pointer nodp debug_keyboard dk nodebug_keyboard nodebug_pointer nodp debug_keyboard dk nodebug_keyboard
nodk deferupdate defer wait readtimeout nap nonap nodk deferupdate defer wait_ui wait_bog nowait_bog wait
sb screen_blank fs gaps grow fuzz snapfb nosnapfb readtimeout nap nonap sb screen_blank fs gaps grow fuzz
rawfb progressive rfbport http nohttp httpport snapfb nosnapfb rawfb progressive rfbport http nohttp
httpdir enablehttpproxy noenablehttpproxy alwaysshared httpport httpdir enablehttpproxy noenablehttpproxy
noalwaysshared nevershared noalwaysshared dontdisconnect alwaysshared noalwaysshared nevershared noalwaysshared
nodontdisconnect desktop debug_xevents nodebug_xevents dontdisconnect nodontdisconnect desktop debug_xevents
debug_xevents debug_xdamage nodebug_xdamage nodebug_xevents debug_xevents debug_xdamage
debug_xdamage debug_wireframe nodebug_wireframe nodebug_xdamage debug_xdamage debug_wireframe
debug_wireframe debug_scroll nodebug_scroll debug_scroll nodebug_wireframe debug_wireframe debug_scroll
debug_tiles dbt nodebug_tiles nodbt debug_tiles dbg nodebug_scroll debug_scroll debug_tiles dbt
nodbg noremote nodebug_tiles nodbt debug_tiles dbg nodbg noremote
aro= display vncdisplay desktopname http_url auth aro= display vncdisplay desktopname http_url auth
users rootshift clipshift scale_str scaled_x scaled_y users rootshift clipshift scale_str scaled_x scaled_y
......
...@@ -187,6 +187,8 @@ Misc ...@@ -187,6 +187,8 @@ Misc
gaps: gaps:
grow: grow:
fuzz: fuzz:
wait_ui:
nowait_bog
readtimeout: readtimeout:
snapfb snapfb
threads threads
...@@ -263,6 +265,7 @@ Tuning ...@@ -263,6 +265,7 @@ Tuning
scr_skip: scr_skip:
scr_inc: scr_inc:
scr_keys: scr_keys:
scr_term:
scr_parms: scr_parms:
-- D -- D
speeds: speeds:
......
...@@ -193,6 +193,8 @@ ...@@ -193,6 +193,8 @@
" gaps:\n" " gaps:\n"
" grow:\n" " grow:\n"
" fuzz:\n" " fuzz:\n"
" wait_ui:\n"
" nowait_bog\n"
" readtimeout:\n" " readtimeout:\n"
" snapfb\n" " snapfb\n"
" threads\n" " threads\n"
...@@ -269,6 +271,7 @@ ...@@ -269,6 +271,7 @@
" scr_skip:\n" " scr_skip:\n"
" scr_inc:\n" " scr_inc:\n"
" scr_keys:\n" " scr_keys:\n"
" scr_term:\n"
" scr_parms:\n" " scr_parms:\n"
" -- D\n" " -- D\n"
" speeds:\n" " speeds:\n"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
.TH X11VNC "1" "May 2005" "x11vnc " "User Commands" .TH X11VNC "1" "May 2005" "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.7.2, lastmod: 2005-05-14 version: 0.7.2, lastmod: 2005-05-17
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
...@@ -1187,6 +1187,31 @@ to cause scrolls. BTW, by default modifier keys, ...@@ -1187,6 +1187,31 @@ to cause scrolls. BTW, by default modifier keys,
Shift_L, Control_R, etc, are skipped since they almost Shift_L, Control_R, etc, are skipped since they almost
never induce scrolling by themselves. never induce scrolling by themselves.
.PP .PP
\fB-scr_term\fR \fIlist\fR
.IP
Yet another cosmetic kludge. Apply shell/terminal
heuristics to applications matching comma separated
list (same as for \fB-scr_skip/-scr_inc).\fR For example an
annoying transient under scroll detection is if you
hit Enter in a terminal shell with full text window,
the solid text cursor block will be scrolled up.
So for a short time there are two (or more) block
cursors on the screen. There are similar scenarios,
(e.g. an output line is duplicated).
.IP
These transients are induced by the approximation of
scroll detection (e.g. it detects the scroll, but not
the fact that the block cursor was cleared just before
the scroll). In nearly all cases these transient errors
are repaired when the true X framebuffer is consulted
by the normal polling. But they are distracting, so
what this option provides is extra "padding" near the
bottom of the terminal window: a few extra lines near
the bottom will not be scrolled, but rather updated
from the actual X framebuffer. This usually reduces
the annoying artifacts. Use "none" to disable.
Default: "term"
.PP
\fB-scr_parms\fR \fIstring\fR \fB-scr_parms\fR \fIstring\fR
.IP .IP
Set various parameters for the scrollcopyrect mode. Set various parameters for the scrollcopyrect mode.
...@@ -1341,6 +1366,24 @@ Time in ms to wait for updates before sending to client ...@@ -1341,6 +1366,24 @@ Time in ms to wait for updates before sending to client
Time in ms to pause between screen polls. Used to cut Time in ms to pause between screen polls. Used to cut
down on load. Default: 30 down on load. Default: 30
.PP .PP
\fB-wait_ui\fR \fIfactor\fR
.IP
Factor by which to cut the \fB-wait\fR time if there
has been recent user input (pointer or keyboard).
Improves response, but increases the load whenever you
are moving the mouse or typing. Default: 2.00
.PP
\fB-nowait_bog\fR
.IP
Do not detect if the screen polling is "bogging down"
and sleep more. Some activities with no user input can
slow things down a lot: consider a large terminal window
with a long build running in it continously streaming
text output. By default x11vnc will try to detect this
(3 screen polls in a row each longer than 0.25 sec with
no user input), and sleep up to 1.5 secs to let things
"catch up". Use this option to disable the detection.
.PP
\fB-readtimeout\fR \fIn\fR \fB-readtimeout\fR \fIn\fR
.IP .IP
Set libvncserver rfbMaxClientWait to n seconds. On Set libvncserver rfbMaxClientWait to n seconds. On
...@@ -1513,8 +1556,8 @@ with /dev/fb0. ...@@ -1513,8 +1556,8 @@ with /dev/fb0.
.PP .PP
\fB-pipeinput\fR \fIcmd\fR \fB-pipeinput\fR \fIcmd\fR
.IP .IP
Another experimental option: it lets you supply Another experimental option: it lets you supply an
an extern command in \fIcmd\fR that x11vnc will pipe external command in \fIcmd\fR that x11vnc will pipe
all of the user input events to in a simple format. all of the user input events to in a simple format.
In \fB-pipeinput\fR mode by default x11vnc will not process In \fB-pipeinput\fR mode by default x11vnc will not process
any of the user input events. If you prefix \fIcmd\fR any of the user input events. If you prefix \fIcmd\fR
...@@ -1897,6 +1940,8 @@ scr_inc:list set \fB-scr_inc\fR to "list" ...@@ -1897,6 +1940,8 @@ scr_inc:list set \fB-scr_inc\fR to "list"
.IP .IP
scr_keys:list set \fB-scr_keys\fR to "list" scr_keys:list set \fB-scr_keys\fR to "list"
.IP .IP
scr_term:list set \fB-scr_term\fR to "list"
.IP
scr_parms:str set \fB-scr_parms\fR parameters. scr_parms:str set \fB-scr_parms\fR parameters.
.IP .IP
pointer_mode:n set \fB-pointer_mode\fR to n. same as "pm" pointer_mode:n set \fB-pointer_mode\fR to n. same as "pm"
...@@ -1917,6 +1962,12 @@ defer:n set \fB-defer\fR to n ms,same as deferupdate:n ...@@ -1917,6 +1962,12 @@ defer:n set \fB-defer\fR to n ms,same as deferupdate:n
.IP .IP
wait:n set \fB-wait\fR to n ms. wait:n set \fB-wait\fR to n ms.
.IP .IP
wait_ui:f set \fB-wait_ui\fR factor to f.
.IP
wait_bog disable \fB-nowait_bog\fR mode.
.IP
nowait_bog enable \fB-nowait_bog\fR mode.
.IP
readtimeout:n set read timeout to n seconds. readtimeout:n set read timeout to n seconds.
.IP .IP
nap enable \fB-nap\fR mode. nap enable \fB-nap\fR mode.
...@@ -2069,35 +2120,35 @@ scale_cursor viewonly noviewonly shared noshared ...@@ -2069,35 +2120,35 @@ scale_cursor viewonly noviewonly shared noshared
forever noforever once timeout deny lock nodeny unlock forever noforever once timeout deny lock nodeny unlock
connect allowonce allow localhost nolocalhost listen connect allowonce allow localhost nolocalhost listen
lookup nolookup accept gone shm noshm flipbyteorder lookup nolookup accept gone shm noshm flipbyteorder
noflipbyteorder onetile noonetile solid_color noflipbyteorder onetile noonetile solid_color solid
solid nosolid blackout xinerama noxinerama xtrap nosolid blackout xinerama noxinerama xtrap noxtrap
noxtrap xrandr noxrandr xrandr_mode padgeom quiet q xrandr noxrandr xrandr_mode padgeom quiet q noquiet
noquiet modtweak nomodtweak xkb noxkb skip_keycodes modtweak nomodtweak xkb noxkb skip_keycodes skip_dups
skip_dups noskip_dups add_keysyms noadd_keysyms noskip_dups add_keysyms noadd_keysyms clear_mods
clear_mods noclear_mods clear_keys noclear_keys noclear_mods clear_keys noclear_keys remap repeat
remap repeat norepeat fb nofb bell nobell sel nosel norepeat fb nofb bell nobell sel nosel primary noprimary
primary noprimary cursorshape nocursorshape cursorpos cursorshape nocursorshape cursorpos nocursorpos cursor
nocursorpos cursor show_cursor noshow_cursor nocursor show_cursor noshow_cursor nocursor arrow xfixes noxfixes
arrow xfixes noxfixes xdamage noxdamage xd_area xd_mem xdamage noxdamage xd_area xd_mem alphacut alphafrac
alphacut alphafrac alpharemove noalpharemove alphablend alpharemove noalpharemove alphablend noalphablend
noalphablend xwarppointer xwarp noxwarppointer noxwarp xwarppointer xwarp noxwarppointer noxwarp buttonmap
buttonmap dragging nodragging wireframe_mode wireframe dragging nodragging wireframe_mode wireframe wf
wf nowireframe nowf wirecopyrect wcr nowirecopyrect nowireframe nowf wirecopyrect wcr nowirecopyrect nowcr
nowcr scr_area scr_skip scr_inc scr_keys scr_parms scr_area scr_skip scr_inc scr_keys scr_term scr_parms
scrollcopyrect scr noscrollcopyrect noscr pointer_mode scrollcopyrect scr noscrollcopyrect noscr pointer_mode
pm input_skip input client_input speeds debug_pointer dp pm input_skip input client_input speeds debug_pointer dp
nodebug_pointer nodp debug_keyboard dk nodebug_keyboard nodebug_pointer nodp debug_keyboard dk nodebug_keyboard
nodk deferupdate defer wait readtimeout nap nonap nodk deferupdate defer wait_ui wait_bog nowait_bog wait
sb screen_blank fs gaps grow fuzz snapfb nosnapfb readtimeout nap nonap sb screen_blank fs gaps grow fuzz
rawfb progressive rfbport http nohttp httpport snapfb nosnapfb rawfb progressive rfbport http nohttp
httpdir enablehttpproxy noenablehttpproxy alwaysshared httpport httpdir enablehttpproxy noenablehttpproxy
noalwaysshared nevershared noalwaysshared dontdisconnect alwaysshared noalwaysshared nevershared noalwaysshared
nodontdisconnect desktop debug_xevents nodebug_xevents dontdisconnect nodontdisconnect desktop debug_xevents
debug_xevents debug_xdamage nodebug_xdamage nodebug_xevents debug_xevents debug_xdamage
debug_xdamage debug_wireframe nodebug_wireframe nodebug_xdamage debug_xdamage debug_wireframe
debug_wireframe debug_scroll nodebug_scroll debug_scroll nodebug_wireframe debug_wireframe debug_scroll
debug_tiles dbt nodebug_tiles nodbt debug_tiles dbg nodebug_scroll debug_scroll debug_tiles dbt
nodbg noremote nodebug_tiles nodbt debug_tiles dbg nodbg noremote
.IP .IP
aro= display vncdisplay desktopname http_url auth aro= display vncdisplay desktopname http_url auth
users rootshift clipshift scale_str scaled_x scaled_y users rootshift clipshift scale_str scaled_x scaled_y
......
...@@ -170,8 +170,11 @@ ...@@ -170,8 +170,11 @@
* *
* -DWIREFRAME=0 to have -nowireframe as the default. * -DWIREFRAME=0 to have -nowireframe as the default.
* -DWIREFRAME_COPYRECT=0 to have -nowirecopyrect as the default. * -DWIREFRAME_COPYRECT=0 to have -nowirecopyrect as the default.
* -DWIREFRAME_PARMS=... set default -wirecopyrect parameters.
* -DSCROLL_COPYRECT=0 to have -noscrollcopyrect as the default. * -DSCROLL_COPYRECT=0 to have -noscrollcopyrect as the default.
* -DSCROLL_COPYRECT_PARMS=... set default -scrollcopyrect parameters.
* -DXDAMAGE=0 to have -noxdamage as the default. * -DXDAMAGE=0 to have -noxdamage as the default.
* -DSKIDPUPS=0 to have -noskip_dups as the default.
* *
* -DPOINTER_MODE_DEFAULT={0,1,2,3,4} set default -pointer_mode. * -DPOINTER_MODE_DEFAULT={0,1,2,3,4} set default -pointer_mode.
* -DBOLDLY_CLOSE_DISPLAY=0 to not close X DISPLAY under -rawfb. * -DBOLDLY_CLOSE_DISPLAY=0 to not close X DISPLAY under -rawfb.
...@@ -339,6 +342,7 @@ int xrandr_base_event_type = 0; ...@@ -339,6 +342,7 @@ int xrandr_base_event_type = 0;
int xfixes_present = 0; int xfixes_present = 0;
int use_xfixes = 1; int use_xfixes = 1;
int got_xfixes_cursor_notify = 0; int got_xfixes_cursor_notify = 0;
int cursor_changes = 0;
int alpha_threshold = 240; int alpha_threshold = 240;
double alpha_frac = 0.33; double alpha_frac = 0.33;
int alpha_remove = 0; int alpha_remove = 0;
...@@ -364,10 +368,11 @@ int xdamage_base_event_type = 0; ...@@ -364,10 +368,11 @@ int xdamage_base_event_type = 0;
int xdamage_max_area = 20000; /* pixels */ int xdamage_max_area = 20000; /* pixels */
double xdamage_memory = 1.0; /* in units of NSCAN */ double xdamage_memory = 1.0; /* in units of NSCAN */
int xdamage_tile_count, xdamage_direct_count; int xdamage_tile_count, xdamage_direct_count;
double xdamage_scheduled_mark = 0.0;
sraRegionPtr xdamage_scheduled_mark_region = NULL;
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.7.2 lastmod: 2005-05-14"; char lastmod[] = "0.7.2 lastmod: 2005-05-17";
int hack_val = 0; int hack_val = 0;
/* X display info */ /* X display info */
...@@ -590,6 +595,8 @@ void initialize_xdamage(void); ...@@ -590,6 +595,8 @@ void initialize_xdamage(void);
int valid_window(Window, XWindowAttributes *, int); int valid_window(Window, XWindowAttributes *, int);
void create_xdamage_if_needed(void); void create_xdamage_if_needed(void);
void destroy_xdamage_if_needed(void); void destroy_xdamage_if_needed(void);
void mark_for_xdamage(int, int, int, int);
void mark_region_for_xdamage(sraRegionPtr);
void initialize_xrandr(void); void initialize_xrandr(void);
XImage *initialize_xdisplay_fb(void); XImage *initialize_xdisplay_fb(void);
...@@ -630,6 +637,7 @@ void parse_scroll_copyrect(void); ...@@ -630,6 +637,7 @@ void parse_scroll_copyrect(void);
void set_wirecopyrect_mode(char *); void set_wirecopyrect_mode(char *);
void set_scrollcopyrect_mode(char *); void set_scrollcopyrect_mode(char *);
void initialize_scroll_matches(void); void initialize_scroll_matches(void);
void initialize_scroll_term(void);
void initialize_scroll_keys(void); void initialize_scroll_keys(void);
int try_copyrect(Window, int, int, int, int, int, int, int *, sraRegionPtr, int try_copyrect(Window, int, int, int, int, int, int, int *, sraRegionPtr,
double); double);
...@@ -643,7 +651,10 @@ int near_scrollbar_edge(int, int, int, int, int, int); ...@@ -643,7 +651,10 @@ int near_scrollbar_edge(int, int, int, int, int, int);
void read_vnc_connect_prop(void); void read_vnc_connect_prop(void);
void set_vnc_connect_prop(char *); void set_vnc_connect_prop(char *);
void fb_push(void); void fb_push(void);
void fb_push_wait(double); #define FB_COPY 0x1
#define FB_MOD 0x2
#define FB_REQ 0x4
void fb_push_wait(double, int);
char *process_remote_cmd(char *, int); char *process_remote_cmd(char *, int);
void rfbPE(long); void rfbPE(long);
void rfbCFD(long); void rfbCFD(long);
...@@ -652,7 +663,7 @@ void set_colormap(int); ...@@ -652,7 +663,7 @@ void set_colormap(int);
void set_offset(void); void set_offset(void);
void set_rfb_cursor(int); void set_rfb_cursor(int);
void set_visual(char *vstring); void set_visual(char *vstring);
void set_cursor(int, int, int); int set_cursor(int, int, int);
void setup_cursors(void); void setup_cursors(void);
void setup_cursors_and_push(void); void setup_cursors_and_push(void);
void first_cursor(void); void first_cursor(void);
...@@ -671,7 +682,7 @@ void get_client_regions(int *, int *, int *, int *); ...@@ -671,7 +682,7 @@ void get_client_regions(int *, int *, int *, int *);
void shm_clean(XShmSegmentInfo *, XImage *); void shm_clean(XShmSegmentInfo *, XImage *);
void shm_delete(XShmSegmentInfo *); void shm_delete(XShmSegmentInfo *);
void check_x11_pointer(void); int check_x11_pointer(void);
void check_bell_event(void); void check_bell_event(void);
void check_xevents(void); void check_xevents(void);
char *this_host(void); char *this_host(void);
...@@ -942,6 +953,12 @@ char *scroll_skip_str0 = ...@@ -942,6 +953,12 @@ char *scroll_skip_str0 =
"##Soffice.bin" /* big problems, no clips, scrolls outside area */ "##Soffice.bin" /* big problems, no clips, scrolls outside area */
; ;
char **scroll_term = NULL;
char *scroll_term_str = NULL;
char *scroll_term_str0 =
"term"
;
#ifndef NOREPEAT #ifndef NOREPEAT
#define NOREPEAT 1 #define NOREPEAT 1
#endif #endif
...@@ -982,6 +999,8 @@ int flip_byte_order = 0; /* sometimes needed when using_shm = 0 */ ...@@ -982,6 +999,8 @@ int flip_byte_order = 0; /* sometimes needed when using_shm = 0 */
* poll times of 10-35ms, so maybe this value cuts the idle load by 2 or so. * poll times of 10-35ms, so maybe this value cuts the idle load by 2 or so.
*/ */
int waitms = 30; int waitms = 30;
double wait_ui = 2.0;
int wait_bog = 1;
int defer_update = 30; /* deferUpdateTime ms to wait before sends. */ int defer_update = 30; /* deferUpdateTime ms to wait before sends. */
int screen_blank = 60; /* number of seconds of no activity to throttle */ int screen_blank = 60; /* number of seconds of no activity to throttle */
...@@ -1075,9 +1094,22 @@ struct timeval _mysleep; ...@@ -1075,9 +1094,22 @@ struct timeval _mysleep;
* avoid XIO crashes. * avoid XIO crashes.
*/ */
MUTEX(x11Mutex); MUTEX(x11Mutex);
#define X_INIT INIT_MUTEX(x11Mutex)
#if 1
#define X_LOCK LOCK(x11Mutex) #define X_LOCK LOCK(x11Mutex)
#define X_UNLOCK UNLOCK(x11Mutex) #define X_UNLOCK UNLOCK(x11Mutex)
#define X_INIT INIT_MUTEX(x11Mutex) #else
int hxl = 0;
#define X_LOCK fprintf(stderr, "*** X_LOCK**[%05d] %d%s\n", \
__LINE__, hxl, hxl ? " BAD-PRE-LOCK":""); LOCK(x11Mutex); hxl = 1;
#define X_UNLOCK fprintf(stderr, " x_unlock[%05d] %d%s\n", \
__LINE__, hxl, !hxl ? " BAD-PRE-UNLOCK":""); UNLOCK(x11Mutex); hxl = 0;
#endif
MUTEX(scrollMutex);
#define SCR_LOCK if (use_threads) {LOCK(scrollMutex);}
#define SCR_UNLOCK if (use_threads) {UNLOCK(scrollMutex);}
#define SCR_INIT INIT_MUTEX(scrollMutex)
/* -- util.c -- */ /* -- util.c -- */
...@@ -1256,6 +1288,20 @@ int pick_windowid(unsigned long *num) { ...@@ -1256,6 +1288,20 @@ int pick_windowid(unsigned long *num) {
return ok; return ok;
} }
Window query_pointer(Window start) {
Window r, c;
int rx, ry, wx, wy;
unsigned int mask;
if (start == None) {
start = rootwin;
}
if (XQueryPointer(dpy, start, &r, &c, &rx, &ry, &wx, &wy, &mask)) {
return c;
} else {
return None;
}
}
char *bitprint(unsigned int st, int nbits) { char *bitprint(unsigned int st, int nbits) {
static char str[33]; static char str[33];
int i, mask; int i, mask;
...@@ -2835,12 +2881,18 @@ int xrecord_set_by_mouse = 0; ...@@ -2835,12 +2881,18 @@ int xrecord_set_by_mouse = 0;
Window xrecord_focus_window = None; Window xrecord_focus_window = None;
Window xrecord_wm_window = None; Window xrecord_wm_window = None;
Window xrecord_ptr_window = None; Window xrecord_ptr_window = None;
KeySym xrecord_keysym = NoSymbol;
#define NAMEINFO 2048
char xrecord_name_info[NAMEINFO];
void initialize_xrecord(void) { void initialize_xrecord(void) {
use_xrecord = 0; use_xrecord = 0;
if (! xrecord_present) { if (! xrecord_present) {
return; return;
} }
if (nofb) {
return;
}
#if LIBVNCSERVER_HAVE_RECORD #if LIBVNCSERVER_HAVE_RECORD
rr_CA = XRecordAllocRange(); rr_CA = XRecordAllocRange();
rr_CW = XRecordAllocRange(); rr_CW = XRecordAllocRange();
...@@ -2903,9 +2955,40 @@ int xrecord_skip_keysym(rfbKeySym keysym) { ...@@ -2903,9 +2955,40 @@ int xrecord_skip_keysym(rfbKeySym keysym) {
return 0; return 0;
} else if (ok == 0) { } else if (ok == 0) {
return 1; return 1;
} else if (IsModifierKey(sym)) { }
/* apply various heuristics: */
if (IsModifierKey(sym)) {
/* Shift, Control, etc, usu. generate no scrolls */
return 1; return 1;
} }
if (sym == XK_space && scroll_term) {
/* space in a terminal is usu. full page... */
Window win;
static Window prev_top = None;
int size = 256;
static char name[256];
X_LOCK;
win = query_pointer(rootwin);
X_UNLOCK;
if (win != None && win != rootwin) {
if (prev_top != None && win == prev_top) {
; /* use cached result */
} else {
prev_top = win;
X_LOCK;
win = descend_pointer(6, win, name, size);
X_UNLOCK;
}
if (match_str_list(name, scroll_term)) {
return 1;
}
}
}
/* TBD use typing_rate() so */
return 0; return 0;
} }
...@@ -3813,7 +3896,7 @@ void shutdown_record_context(XRecordContext rc, int bequiet, int reopen) { ...@@ -3813,7 +3896,7 @@ void shutdown_record_context(XRecordContext rc, int bequiet, int reopen) {
rfbLog("XRecordDisableContext(0x%lx) failed.\n", rc); rfbLog("XRecordDisableContext(0x%lx) failed.\n", rc);
} }
ret2 = XRecordFreeContext(rdpy_ctrl, rc_scroll); ret2 = XRecordFreeContext(rdpy_ctrl, rc_scroll);
if (!ret2 && ! bequiet && !quiet) { if (!ret2 && !bequiet && !quiet) {
rfbLog("XRecordFreeContext(0x%lx) failed.\n", rc); rfbLog("XRecordFreeContext(0x%lx) failed.\n", rc);
} }
XFlush(rdpy_ctrl); XFlush(rdpy_ctrl);
...@@ -3871,19 +3954,27 @@ XErrorEvent *trapped_record_xerror_event; ...@@ -3871,19 +3954,27 @@ XErrorEvent *trapped_record_xerror_event;
} }
void xrecord_watch(int start, int setby) { void xrecord_watch(int start, int setby) {
Window focus, wm, r, c, clast; Window focus, wm, c, clast;
static double create_time = 0.0; static double create_time = 0.0;
double dnow; double dnow;
static double last_error = 0.0; static double last_error = 0.0;
int rx, ry, wx, wy;
unsigned int m;
int rc, db = debug_scroll; int rc, db = debug_scroll;
int do_shutdown = 0; int do_shutdown = 0;
int reopen_dpys = 1; int reopen_dpys = 1;
char name_info[2048];
XErrorHandler old_handler = NULL; XErrorHandler old_handler = NULL;
static Window last_win = None, last_result = None; static Window last_win = None, last_result = None;
if (nofb) {
xrecording = 0;
return;
}
if (use_threads) {
/* XXX not working */
use_xrecord = 0;
xrecording = 0;
return;
}
dtime0(&dnow); dtime0(&dnow);
if (dnow < last_error + 0.5) { if (dnow < last_error + 0.5) {
return; return;
...@@ -3891,22 +3982,25 @@ void xrecord_watch(int start, int setby) { ...@@ -3891,22 +3982,25 @@ void xrecord_watch(int start, int setby) {
#if LIBVNCSERVER_HAVE_RECORD #if LIBVNCSERVER_HAVE_RECORD
if (! start) { if (! start) {
int shut_reopen = 2; int shut_reopen = 2, shut_time = 25;
if (db) fprintf(stderr, "XRECORD OFF: %d/%d %.4f\n", xrecording, setby, dnow - x11vnc_start); if (db) fprintf(stderr, "XRECORD OFF: %d/%d %.4f\n", xrecording, setby, dnow - x11vnc_start);
xrecording = 0; xrecording = 0;
if (! rc_scroll) { if (! rc_scroll) {
xrecord_focus_window = None; xrecord_focus_window = None;
xrecord_wm_window = None; xrecord_wm_window = None;
xrecord_ptr_window = None; xrecord_ptr_window = None;
xrecord_keysym = NoSymbol;
rcs_scroll = 0; rcs_scroll = 0;
return; return;
} }
if (! do_shutdown && dnow > create_time + 45) { if (! do_shutdown && dnow > create_time + shut_time) {
/* XXX unstable if we keep a RECORD going forever */ /* XXX unstable if we keep a RECORD going forever */
do_shutdown = 1; do_shutdown = 1;
shut_reopen = 1; shut_reopen = 1;
} }
SCR_LOCK;
if (do_shutdown) { if (do_shutdown) {
if (db > 1) fprintf(stderr, "=== shutdown-scroll 0x%lx\n", rc_scroll); if (db > 1) fprintf(stderr, "=== shutdown-scroll 0x%lx\n", rc_scroll);
...@@ -3948,15 +4042,18 @@ if (db > 1) fprintf(stderr, "=== disab-scroll 0x%lx 0x%lx\n", rc_scroll, rcs_scr ...@@ -3948,15 +4042,18 @@ if (db > 1) fprintf(stderr, "=== disab-scroll 0x%lx 0x%lx\n", rc_scroll, rcs_scr
shutdown_record_context(rc_scroll, shutdown_record_context(rc_scroll,
0, reopen_dpys); 0, reopen_dpys);
if (! use_xrecord) return;
last_error = dnow; last_error = dnow;
rc_scroll = 0; rc_scroll = 0;
if (! use_xrecord) return;
} }
XSetErrorHandler(old_handler); XSetErrorHandler(old_handler);
X_UNLOCK; X_UNLOCK;
} }
} }
SCR_UNLOCK;
/* /*
* XXX if we do a XFlush(rdpy_ctrl) here we get: * XXX if we do a XFlush(rdpy_ctrl) here we get:
* *
...@@ -3975,6 +4072,7 @@ if (db > 1) fprintf(stderr, "=== disab-scroll 0x%lx 0x%lx\n", rc_scroll, rcs_scr ...@@ -3975,6 +4072,7 @@ if (db > 1) fprintf(stderr, "=== disab-scroll 0x%lx 0x%lx\n", rc_scroll, rcs_scr
xrecord_focus_window = None; xrecord_focus_window = None;
xrecord_wm_window = None; xrecord_wm_window = None;
xrecord_ptr_window = None; xrecord_ptr_window = None;
xrecord_keysym = NoSymbol;
rcs_scroll = 0; rcs_scroll = 0;
return; return;
} }
...@@ -3998,6 +4096,7 @@ if (db) fprintf(stderr, "XRECORD ON: %d/%d %.4f\n", xrecording, setby, dnow - ...@@ -3998,6 +4096,7 @@ if (db) fprintf(stderr, "XRECORD ON: %d/%d %.4f\n", xrecording, setby, dnow -
xrecord_focus_window = None; xrecord_focus_window = None;
xrecord_wm_window = None; xrecord_wm_window = None;
xrecord_ptr_window = None; xrecord_ptr_window = None;
xrecord_keysym = NoSymbol;
xrecord_set_by_keys = 0; xrecord_set_by_keys = 0;
xrecord_set_by_mouse = 0; xrecord_set_by_mouse = 0;
...@@ -4007,6 +4106,7 @@ if (db) fprintf(stderr, "XRECORD ON: %d/%d %.4f\n", xrecording, setby, dnow - ...@@ -4007,6 +4106,7 @@ if (db) fprintf(stderr, "XRECORD ON: %d/%d %.4f\n", xrecording, setby, dnow -
wm = None; wm = None;
X_LOCK; X_LOCK;
SCR_LOCK;
#if 0 #if 0
/* /*
* xrecord_focus_window / focus not currently used... save a * xrecord_focus_window / focus not currently used... save a
...@@ -4020,7 +4120,7 @@ if (db) fprintf(stderr, "XRECORD ON: %d/%d %.4f\n", xrecording, setby, dnow - ...@@ -4020,7 +4120,7 @@ if (db) fprintf(stderr, "XRECORD ON: %d/%d %.4f\n", xrecording, setby, dnow -
XGetInputFocus(dpy, &focus, &i); XGetInputFocus(dpy, &focus, &i);
#endif #endif
XQueryPointer(dpy, rootwin, &r, &wm, &rx, &ry, &wx, &wy, &m); wm = query_pointer(rootwin);
if (wm) { if (wm) {
c = wm; c = wm;
} else { } else {
...@@ -4033,15 +4133,16 @@ if (db) fprintf(stderr, "XRECORD ON: %d/%d %.4f\n", xrecording, setby, dnow - ...@@ -4033,15 +4133,16 @@ if (db) fprintf(stderr, "XRECORD ON: %d/%d %.4f\n", xrecording, setby, dnow -
clast = last_result; clast = last_result;
} else if (scroll_good_all == NULL && scroll_skip_all == NULL) { } else if (scroll_good_all == NULL && scroll_skip_all == NULL) {
/* more efficient if name info not needed. */ /* more efficient if name info not needed. */
xrecord_name_info[0] = '\0';
clast = descend_pointer(6, c, NULL, 0); clast = descend_pointer(6, c, NULL, 0);
} else { } else {
char *nm; char *nm;
int matched_good = 0, matched_skip = 0; int matched_good = 0, matched_skip = 0;
clast = descend_pointer(6, c, name_info, 2048); clast = descend_pointer(6, c, xrecord_name_info, NAMEINFO);
if (db) fprintf(stderr, "name_info: %s\n", name_info); if (db) fprintf(stderr, "name_info: %s\n", xrecord_name_info);
nm = name_info; nm = xrecord_name_info;
if (scroll_good_all) { if (scroll_good_all) {
matched_good += match_str_list(nm, scroll_good_all); matched_good += match_str_list(nm, scroll_good_all);
...@@ -4075,6 +4176,7 @@ if (db) fprintf(stderr, "name_info: %s\n", name_info); ...@@ -4075,6 +4176,7 @@ if (db) fprintf(stderr, "name_info: %s\n", name_info);
if (!clast || clast == rootwin) { if (!clast || clast == rootwin) {
if (db) fprintf(stderr, "--- xrecord_watch: SKIP.\n"); if (db) fprintf(stderr, "--- xrecord_watch: SKIP.\n");
X_UNLOCK; X_UNLOCK;
SCR_UNLOCK;
return; return;
} }
...@@ -4090,6 +4192,7 @@ if (db) fprintf(stderr, "--- xrecord_watch: SKIP.\n"); ...@@ -4090,6 +4192,7 @@ if (db) fprintf(stderr, "--- xrecord_watch: SKIP.\n");
trapped_record_xerror = 0; trapped_record_xerror = 0;
old_handler = XSetErrorHandler(trap_record_xerror); old_handler = XSetErrorHandler(trap_record_xerror);
if (! rc_scroll) { if (! rc_scroll) {
/* do_shutdown case or first time in */ /* do_shutdown case or first time in */
rcs_scroll = (XRecordClientSpec) clast; rcs_scroll = (XRecordClientSpec) clast;
...@@ -4141,6 +4244,7 @@ if (db) fprintf(stderr, "rc_scroll: 0x%lx\n", rc_scroll); ...@@ -4141,6 +4244,7 @@ if (db) fprintf(stderr, "rc_scroll: 0x%lx\n", rc_scroll);
if (! rc_scroll) { if (! rc_scroll) {
XSetErrorHandler(old_handler); XSetErrorHandler(old_handler);
X_UNLOCK; X_UNLOCK;
SCR_UNLOCK;
use_xrecord = 0; use_xrecord = 0;
rfbLog("failed to create X RECORD context rc_scroll.\n"); rfbLog("failed to create X RECORD context rc_scroll.\n");
rfbLog(" switching to -noscrollcopyrect mode.\n"); rfbLog(" switching to -noscrollcopyrect mode.\n");
...@@ -4154,6 +4258,7 @@ if (db) fprintf(stderr, "rc_scroll: 0x%lx\n", rc_scroll); ...@@ -4154,6 +4258,7 @@ if (db) fprintf(stderr, "rc_scroll: 0x%lx\n", rc_scroll);
XSetErrorHandler(old_handler); XSetErrorHandler(old_handler);
X_UNLOCK; X_UNLOCK;
SCR_UNLOCK;
return; return;
} }
...@@ -4200,6 +4305,7 @@ if (db) fprintf(stderr, "rc_scroll: 0x%lx\n", rc_scroll); ...@@ -4200,6 +4305,7 @@ if (db) fprintf(stderr, "rc_scroll: 0x%lx\n", rc_scroll);
XFlush(rdpy_data); XFlush(rdpy_data);
X_UNLOCK; X_UNLOCK;
SCR_UNLOCK;
#endif #endif
} }
...@@ -4594,7 +4700,7 @@ int wait_until_mapped(Window win) { ...@@ -4594,7 +4700,7 @@ int wait_until_mapped(Window win) {
int get_window_size(Window win, int *x, int *y) { int get_window_size(Window win, int *x, int *y) {
XWindowAttributes attr; XWindowAttributes attr;
/* valid_window? */ /* valid_window? */
if (XGetWindowAttributes(dpy, win, &attr)) { if (valid_window(win, &attr, 1)) {
*x = attr.width; *x = attr.width;
*y = attr.height; *y = attr.height;
return 1; return 1;
...@@ -5000,6 +5106,9 @@ static void client_gone(rfbClientPtr client) { ...@@ -5000,6 +5106,9 @@ static void client_gone(rfbClientPtr client) {
client_count--; client_count--;
if (client_count < 0) client_count = 0; if (client_count < 0) client_count = 0;
speeds_net_rate_measured = 0;
speeds_net_latency_measured = 0;
rfbLog("client_count: %d\n", client_count); rfbLog("client_count: %d\n", client_count);
if (no_autorepeat && client_count == 0) { if (no_autorepeat && client_count == 0) {
...@@ -6059,6 +6168,11 @@ enum rfbNewClientAction new_client(rfbClientPtr client) { ...@@ -6059,6 +6168,11 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
cd->login_viewonly = -1; cd->login_viewonly = -1;
client->clientGoneHook = client_gone; client->clientGoneHook = client_gone;
if (client_count) {
speeds_net_rate_measured = 0;
speeds_net_latency_measured = 0;
}
client_count++; client_count++;
last_keyboard_input = last_pointer_input = time(0); last_keyboard_input = last_pointer_input = time(0);
...@@ -8348,6 +8462,58 @@ typedef struct keyevent { ...@@ -8348,6 +8462,58 @@ typedef struct keyevent {
rfbBool down; rfbBool down;
double time; double time;
} keyevent_t; } keyevent_t;
#define KEY_HIST 256
int key_history_idx = -1;
keyevent_t key_history[KEY_HIST];
double typing_rate(double time_window, int *repeating) {
double dt = 1.0, now = dnow();
KeySym key = NoSymbol;
int i, idx, cnt = 0, diff_keys = 0;
if (key_history_idx == -1) {
if (repeating) {
*repeating = 0;
}
return 0.0;
}
if (time_window > 0.0) {
dt = time_window;
}
for (i=0; i<KEY_HIST; i++) {
idx = key_history_idx - i;
if (idx < 0) {
idx += KEY_HIST;
}
if (! key_history[idx].down) {
continue;
}
if (now > key_history[idx].time + dt) {
break;
}
cnt++;
if (key != NoSymbol && key != key_history[idx].sym) {
diff_keys++;
}
key = key_history[idx].sym;
}
if (repeating) {
if (! diff_keys && cnt > 4) {
*repeating = 1;
} else {
*repeating = 0;
}
}
/*
* n.b. keyrate could seem very high with libvncserver buffering them
* so avoid using small dt.
*/
return ((double) cnt)/dt;
}
/* /*
* key event handler. See the above functions for contortions for * key event handler. See the above functions for contortions for
* running under -modtweak. * running under -modtweak.
...@@ -8356,7 +8522,7 @@ static rfbClientPtr last_keyboard_client = NULL; ...@@ -8356,7 +8522,7 @@ static rfbClientPtr last_keyboard_client = NULL;
void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) { void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
KeyCode k; KeyCode k;
int isbutton = 0; int idx, isbutton = 0;
allowed_input_t input; allowed_input_t input;
time_t now = time(0); time_t now = time(0);
double dnow; double dnow;
...@@ -8388,6 +8554,22 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) { ...@@ -8388,6 +8554,22 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
last_keysym = keysym; last_keysym = keysym;
last_keyboard_time = dnow; last_keyboard_time = dnow;
if (key_history_idx == -1) {
for (idx=0; idx<KEY_HIST; idx++) {
key_history[idx].sym = NoSymbol;
key_history[idx].down = FALSE;
key_history[idx].time = 0.0;
}
}
idx = ++key_history_idx;
if (key_history_idx >= KEY_HIST) {
key_history_idx = 0;
idx = 0;
}
key_history[idx].sym = keysym;
key_history[idx].down = down;
key_history[idx].time = dnow;
if (0 && max_scroll_keyrate) { if (0 && max_scroll_keyrate) {
/* XXX not working... */ /* XXX not working... */
static int hlen = 256, hidx = 0; static int hlen = 256, hidx = 0;
...@@ -8522,6 +8704,7 @@ if (0) fprintf(stderr, "key_dt: %.4f %d %d %.4f\n", key_dt, history[idx].sym, ...@@ -8522,6 +8704,7 @@ if (0) fprintf(stderr, "key_dt: %.4f %d %d %.4f\n", key_dt, history[idx].sym,
snapshot_stack_list(0, 0.25); snapshot_stack_list(0, 0.25);
xrecord_watch(1, SCR_KEY); xrecord_watch(1, SCR_KEY);
xrecord_set_by_keys = 1; xrecord_set_by_keys = 1;
xrecord_keysym = keysym;
} else { } else {
if (debug_scroll) { if (debug_scroll) {
char *str = XKeysymToString(keysym); char *str = XKeysymToString(keysym);
...@@ -8844,8 +9027,8 @@ void initialize_pointer_map(char *pointer_remap) { ...@@ -8844,8 +9027,8 @@ void initialize_pointer_map(char *pointer_remap) {
* to the X server. * to the X server.
*/ */
void snapshot_stack_list(int free_only, double allowed_age) { void snapshot_stack_list(int free_only, double allowed_age) {
static double last_snap = 0.0, last_sync = 0.0, last_free = 0.0; static double last_snap = 0.0, last_free = 0.0;
double now, xsync_max = 0.25; double now;
int num, rc, i; int num, rc, i;
Window r, w; Window r, w;
Window *list; Window *list;
...@@ -8858,6 +9041,7 @@ void snapshot_stack_list(int free_only, double allowed_age) { ...@@ -8858,6 +9041,7 @@ void snapshot_stack_list(int free_only, double allowed_age) {
dtime0(&now); dtime0(&now);
if (free_only) { if (free_only) {
/* we really don't free it, just reset to zero windows */
stack_list_num = 0; stack_list_num = 0;
last_free = now; last_free = now;
return; return;
...@@ -8871,17 +9055,13 @@ void snapshot_stack_list(int free_only, double allowed_age) { ...@@ -8871,17 +9055,13 @@ void snapshot_stack_list(int free_only, double allowed_age) {
last_free = now; last_free = now;
X_LOCK; X_LOCK;
if (0 && now > last_sync + xsync_max) {
XSync(dpy, False);
last_sync = now;
}
rc = XQueryTree(dpy, rootwin, &r, &w, &list, &num); rc = XQueryTree(dpy, rootwin, &r, &w, &list, &num);
X_UNLOCK;
if (! rc) { if (! rc) {
stack_list_num = 0; stack_list_num = 0;
last_free = now; last_free = now;
last_snap = 0.0; last_snap = 0.0;
X_UNLOCK;
return; return;
} }
...@@ -8900,7 +9080,6 @@ void snapshot_stack_list(int free_only, double allowed_age) { ...@@ -8900,7 +9080,6 @@ void snapshot_stack_list(int free_only, double allowed_age) {
} }
stack_list_num = num; stack_list_num = num;
X_LOCK;
XFree(list); XFree(list);
X_UNLOCK; X_UNLOCK;
} }
...@@ -8948,6 +9127,7 @@ if (0) fprintf(stderr, "update_stack_list[%d]: %.4f %.4f\n", stack_list_num, no ...@@ -8948,6 +9127,7 @@ if (0) fprintf(stderr, "update_stack_list[%d]: %.4f %.4f\n", stack_list_num, no
* Send a pointer position event to the X server. * Send a pointer position event to the X server.
*/ */
static void update_x11_pointer_position(int x, int y) { static void update_x11_pointer_position(int x, int y) {
int rc;
if (raw_fb && ! dpy) return; /* raw_fb hack */ if (raw_fb && ! dpy) return; /* raw_fb hack */
...@@ -8972,7 +9152,8 @@ static void update_x11_pointer_position(int x, int y) { ...@@ -8972,7 +9152,8 @@ static void update_x11_pointer_position(int x, int y) {
cursor_position(x, y); cursor_position(x, y);
/* change the cursor shape if necessary */ /* change the cursor shape if necessary */
set_cursor(x, y, get_which_cursor()); rc = set_cursor(x, y, get_which_cursor());
cursor_changes += rc;
last_event = last_input = last_pointer_input = time(0); last_event = last_input = last_pointer_input = time(0);
} }
...@@ -9051,6 +9232,8 @@ static void update_x11_pointer_mask(int mask) { ...@@ -9051,6 +9232,8 @@ static void update_x11_pointer_mask(int mask) {
if (scaling && ! got_scrollcopyrect) { if (scaling && ! got_scrollcopyrect) {
xr_mouse = 0; xr_mouse = 0;
} else if (nofb) {
xr_mouse = 0;
} else if (!strcmp(scroll_copyrect, "never")) { } else if (!strcmp(scroll_copyrect, "never")) {
xr_mouse = 0; xr_mouse = 0;
} else if (!strcmp(scroll_copyrect, "keys")) { } else if (!strcmp(scroll_copyrect, "keys")) {
...@@ -9802,6 +9985,7 @@ void initialize_xrandr(void) { ...@@ -9802,6 +9985,7 @@ void initialize_xrandr(void) {
#if LIBVNCSERVER_HAVE_LIBXRANDR #if LIBVNCSERVER_HAVE_LIBXRANDR
Rotation rot; Rotation rot;
X_LOCK;
xrandr_width = XDisplayWidth(dpy, scr); xrandr_width = XDisplayWidth(dpy, scr);
xrandr_height = XDisplayHeight(dpy, scr); xrandr_height = XDisplayHeight(dpy, scr);
XRRRotations(dpy, scr, &rot); XRRRotations(dpy, scr, &rot);
...@@ -9811,6 +9995,7 @@ void initialize_xrandr(void) { ...@@ -9811,6 +9995,7 @@ void initialize_xrandr(void) {
} else { } else {
XRRSelectInput(dpy, rootwin, 0); XRRSelectInput(dpy, rootwin, 0);
} }
X_UNLOCK;
#endif #endif
} else if (xrandr) { } else if (xrandr) {
rfbLog("-xrandr mode specified, but no RANDR support on\n"); rfbLog("-xrandr mode specified, but no RANDR support on\n");
...@@ -13198,6 +13383,23 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -13198,6 +13383,23 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("remote_cmd: changed -scr_keys to: %s\n", rfbLog("remote_cmd: changed -scr_keys to: %s\n",
scroll_key_list_str); scroll_key_list_str);
initialize_scroll_keys(); initialize_scroll_keys();
} else if (strstr(p, "scr_term") == p) {
char *s = scroll_term_str;
if (!s || *s == '\0') s = scroll_term_str0;
COLON_CHECK("scr_term:")
if (query) {
snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(s));
goto qry;
}
p += strlen("scr_term:");
if (scroll_term_str) {
free(scroll_term_str);
}
scroll_term_str = strdup(p);
rfbLog("remote_cmd: changed -scr_term to: %s\n",
scroll_term_str);
initialize_scroll_term();
} else if (strstr(p, "scr_parms") == p) { } else if (strstr(p, "scr_parms") == p) {
COLON_CHECK("scr_parms:") COLON_CHECK("scr_parms:")
...@@ -13404,6 +13606,35 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -13404,6 +13606,35 @@ char *process_remote_cmd(char *cmd, int stringonly) {
/* XXX not part of API? */ /* XXX not part of API? */
screen->deferUpdateTime = d; screen->deferUpdateTime = d;
} else if (strstr(p, "wait_ui") == p) {
double w;
COLON_CHECK("wait_ui:")
if (query) {
snprintf(buf, bufn, "ans=%s%s%.2f", p, co, wait_ui);
goto qry;
}
p += strlen("wait_ui:");
w = atof(p);
if (w <= 0) w = 1.0;
rfbLog("remote_cmd: setting wait_ui factor %.2f -> %.2f\n",
wait_ui, w);
wait_ui = w;
} else if (!strcmp(p, "wait_bog")) {
if (query) {
snprintf(buf, bufn, "ans=%s%s%d", p, co, wait_bog);
goto qry;
}
wait_bog = 1;
rfbLog("remote_cmd: setting wait_bog to %d\n", wait_bog);
} else if (!strcmp(p, "nowait_bog")) {
if (query) {
snprintf(buf, bufn, "ans=%s%s%d", p, co, !wait_bog);
goto qry;
}
wait_bog = 0;
rfbLog("remote_cmd: setting wait_bog to %d\n", wait_bog);
} else if (strstr(p, "wait") == p) { } else if (strstr(p, "wait") == p) {
int w; int w;
COLON_CHECK("wait:") COLON_CHECK("wait:")
...@@ -14253,6 +14484,7 @@ void clear_xdamage_mark_region(sraRegionPtr markregion, int flush) { ...@@ -14253,6 +14484,7 @@ void clear_xdamage_mark_region(sraRegionPtr markregion, int flush) {
#if LIBVNCSERVER_HAVE_LIBXDAMAGE #if LIBVNCSERVER_HAVE_LIBXDAMAGE
XEvent ev; XEvent ev;
sraRegionPtr tmpregion; sraRegionPtr tmpregion;
int count = 0;
if (! xdamage_present || ! use_xdamage) { if (! xdamage_present || ! use_xdamage) {
return; return;
...@@ -14269,12 +14501,16 @@ void clear_xdamage_mark_region(sraRegionPtr markregion, int flush) { ...@@ -14269,12 +14501,16 @@ void clear_xdamage_mark_region(sraRegionPtr markregion, int flush) {
XFlush(dpy); XFlush(dpy);
} }
while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) { while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {
; count++;
} }
/* clear the whole damage region */ /* clear the whole damage region */
XDamageSubtract(dpy, xdamage, None, None); XDamageSubtract(dpy, xdamage, None, None);
X_UNLOCK; X_UNLOCK;
if (debug_tiles || debug_xdamage) {
fprintf(stderr, "clear_xdamage_mark_region: %d\n", count);
}
if (! markregion) { if (! markregion) {
/* NULL means mark the whole display */ /* NULL means mark the whole display */
tmpregion = sraRgnCreateRect(0, 0, dpy_x, dpy_y); tmpregion = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
...@@ -14298,7 +14534,7 @@ int collect_xdamage(int scancnt, int call) { ...@@ -14298,7 +14534,7 @@ int collect_xdamage(int scancnt, int call) {
time_t now; time_t now;
int x, y, w, h, x2, y2; int x, y, w, h, x2, y2;
int i, dup, next, dup_max = 0; int i, dup, next, dup_max = 0;
#define DUPSZ 16 #define DUPSZ 32
int dup_x[DUPSZ], dup_y[DUPSZ], dup_w[DUPSZ], dup_h[DUPSZ]; int dup_x[DUPSZ], dup_y[DUPSZ], dup_w[DUPSZ], dup_h[DUPSZ];
double tm, dt; double tm, dt;
...@@ -14397,12 +14633,12 @@ if (0) XEventsQueued(dpy, QueuedAfterFlush); ...@@ -14397,12 +14633,12 @@ if (0) XEventsQueued(dpy, QueuedAfterFlush);
x2 = x + w; /* upper point */ x2 = x + w; /* upper point */
x = nfix(x, dpy_x); /* place both in fb area */ x = nfix(x, dpy_x); /* place both in fb area */
x2 = nfix(x2, dpy_x); x2 = nfix(x2, dpy_x+1);
w = x2 - x; /* recompute w */ w = x2 - x; /* recompute w */
y2 = y + h; y2 = y + h;
y = nfix(y, dpy_y); y = nfix(y, dpy_y);
y2 = nfix(y2, dpy_y); y2 = nfix(y2, dpy_y+1);
h = y2 - y; h = y2 - y;
if (w <= 0 || h <= 0) { if (w <= 0 || h <= 0) {
...@@ -14479,6 +14715,7 @@ int xdamage_hint_skip(int y) { ...@@ -14479,6 +14715,7 @@ int xdamage_hint_skip(int y) {
} }
if (! scanline) { if (! scanline) {
/* keep it around to avoid malloc etc, recreate */
scanline = sraRgnCreate(); scanline = sraRgnCreate();
} }
...@@ -14588,6 +14825,18 @@ void check_xdamage_state(void) { ...@@ -14588,6 +14825,18 @@ void check_xdamage_state(void) {
*/ */
if (client_count && use_xdamage) { if (client_count && use_xdamage) {
create_xdamage_if_needed(); create_xdamage_if_needed();
if (xdamage_scheduled_mark > 0.0 && dnow() >
xdamage_scheduled_mark) {
if (xdamage_scheduled_mark_region) {
mark_region_for_xdamage(
xdamage_scheduled_mark_region);
sraRgnDestroy(xdamage_scheduled_mark_region);
xdamage_scheduled_mark_region = NULL;
} else {
mark_for_xdamage(0, 0, dpy_x, dpy_y);
}
xdamage_scheduled_mark = 0.0;
}
} else { } else {
destroy_xdamage_if_needed(); destroy_xdamage_if_needed();
} }
...@@ -15388,6 +15637,7 @@ void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) { ...@@ -15388,6 +15637,7 @@ void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) {
if ( XTestCompareCurrentCursorWithWindow_wr(dpy, c) ) { if ( XTestCompareCurrentCursorWithWindow_wr(dpy, c) ) {
break; break;
} }
/* TBD: query_pointer() */
XQueryPointer(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &mask); XQueryPointer(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &mask);
} }
...@@ -15451,12 +15701,14 @@ void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) { ...@@ -15451,12 +15701,14 @@ void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) {
void initialize_xfixes(void) { void initialize_xfixes(void) {
#if LIBVNCSERVER_HAVE_LIBXFIXES #if LIBVNCSERVER_HAVE_LIBXFIXES
if (xfixes_present) { if (xfixes_present) {
X_LOCK;
if (use_xfixes) { if (use_xfixes) {
XFixesSelectCursorInput(dpy, rootwin, XFixesSelectCursorInput(dpy, rootwin,
XFixesDisplayCursorNotifyMask); XFixesDisplayCursorNotifyMask);
} else { } else {
XFixesSelectCursorInput(dpy, rootwin, 0); XFixesSelectCursorInput(dpy, rootwin, 0);
} }
X_UNLOCK;
} }
#endif #endif
} }
...@@ -16194,29 +16446,34 @@ void set_no_cursor(void) { ...@@ -16194,29 +16446,34 @@ void set_no_cursor(void) {
set_rfb_cursor(CURS_EMPTY); set_rfb_cursor(CURS_EMPTY);
} }
void set_cursor(int x, int y, int which) { int set_cursor(int x, int y, int which) {
static int last = -1; static int last = -1;
int changed_cursor = 0;
if (which < 0) { if (which < 0) {
which = last; which = last;
} }
if (last < 0 || which != last) { if (last < 0 || which != last) {
set_rfb_cursor(which); set_rfb_cursor(which);
changed_cursor = 1;
} }
last = which; last = which;
return changed_cursor;
} }
/* /*
* routine called periodically to update cursor aspects, this catches * routine called periodically to update cursor aspects, this catches
* warps and cursor shape changes. * warps and cursor shape changes.
*/ */
void check_x11_pointer(void) { int check_x11_pointer(void) {
Window root_w, child_w; Window root_w, child_w;
rfbBool ret; rfbBool ret;
int root_x, root_y, win_x, win_y; int root_x, root_y, win_x, win_y;
int x, y; int x, y;
unsigned int mask; unsigned int mask;
if (raw_fb && ! dpy) return; /* raw_fb hack */ if (raw_fb && ! dpy) return 0; /* raw_fb hack */
X_LOCK; X_LOCK;
ret = XQueryPointer(dpy, rootwin, &root_w, &child_w, &root_x, &root_y, ret = XQueryPointer(dpy, rootwin, &root_w, &child_w, &root_x, &root_y,
...@@ -16224,7 +16481,7 @@ void check_x11_pointer(void) { ...@@ -16224,7 +16481,7 @@ void check_x11_pointer(void) {
X_UNLOCK; X_UNLOCK;
if (! ret) { if (! ret) {
return; return 0;
} }
if (debug_pointer) { if (debug_pointer) {
static int last_x = -1, last_y = -1; static int last_x = -1, last_y = -1;
...@@ -16244,7 +16501,7 @@ void check_x11_pointer(void) { ...@@ -16244,7 +16501,7 @@ void check_x11_pointer(void) {
cursor_position(x, y); cursor_position(x, y);
/* change the cursor shape if necessary */ /* change the cursor shape if necessary */
set_cursor(x, y, get_which_cursor()); return set_cursor(x, y, get_which_cursor());
} }
/* -- screen.c -- */ /* -- screen.c -- */
...@@ -16313,14 +16570,12 @@ void set_colormap(int reset) { ...@@ -16313,14 +16570,12 @@ void set_colormap(int reset) {
if (flash_cmap && ! first) { if (flash_cmap && ! first) {
XWindowAttributes attr; XWindowAttributes attr;
Window r, c; Window c;
int rx, ry, wx, wy, tries = 0; int tries = 0;
unsigned int m;
c = window; c = window;
while (c && tries++ < 16) { while (c && tries++ < 16) {
/* XXX XQueryTree somehow? */ c = query_pointer(c);
XQueryPointer(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &m);
if (valid_window(c, &attr, 0)) { if (valid_window(c, &attr, 0)) {
if (attr.colormap && attr.map_installed) { if (attr.colormap && attr.map_installed) {
cmap = attr.colormap; cmap = attr.colormap;
...@@ -16524,6 +16779,8 @@ void set_visual(char *str) { ...@@ -16524,6 +16779,8 @@ void set_visual(char *str) {
void set_nofb_params(void) { void set_nofb_params(void) {
use_xfixes = 0; use_xfixes = 0;
use_xdamage = 0; use_xdamage = 0;
use_xrecord = 0;
wireframe = 0;
use_solid_bg = 0; use_solid_bg = 0;
overlay = 0; overlay = 0;
...@@ -16544,6 +16801,7 @@ void set_nofb_params(void) { ...@@ -16544,6 +16801,7 @@ void set_nofb_params(void) {
if (! quiet) { if (! quiet) {
rfbLog("disabling: xfixes, xdamage, solid, overlay, shm,\n"); rfbLog("disabling: xfixes, xdamage, solid, overlay, shm,\n");
rfbLog(" wireframe, scrollcopyrect,\n");
rfbLog(" noonetile, nap, cursor, %scursorshape\n", rfbLog(" noonetile, nap, cursor, %scursorshape\n",
got_cursorpos ? "" : "cursorpos, " ); got_cursorpos ? "" : "cursorpos, " );
rfbLog(" in -nofb mode.\n"); rfbLog(" in -nofb mode.\n");
...@@ -16979,6 +17237,7 @@ XImage *initialize_raw_fb(void) { ...@@ -16979,6 +17237,7 @@ XImage *initialize_raw_fb(void) {
if (sscanf(str, "shm:%d", &shmid) == 1) { if (sscanf(str, "shm:%d", &shmid) == 1) {
/* shm:N */ /* shm:N */
#if LIBVNCSERVER_HAVE_XSHM
raw_fb_addr = (char *) shmat(shmid, 0, SHM_RDONLY); raw_fb_addr = (char *) shmat(shmid, 0, SHM_RDONLY);
if (! raw_fb_addr) { if (! raw_fb_addr) {
rfbLog("failed to attach to shm: %d, %s\n", shmid, str); rfbLog("failed to attach to shm: %d, %s\n", shmid, str);
...@@ -16988,7 +17247,11 @@ XImage *initialize_raw_fb(void) { ...@@ -16988,7 +17247,11 @@ XImage *initialize_raw_fb(void) {
raw_fb_shm = 1; raw_fb_shm = 1;
rfbLog("rawfb: shm: %d W: %d H: %d B: %d addr: %p\n", rfbLog("rawfb: shm: %d W: %d H: %d B: %d addr: %p\n",
shmid, w, h, b, raw_fb_addr); shmid, w, h, b, raw_fb_addr);
#else
rfbLog("x11vnc was compiled without shm support.\n");
rfbLogPerror("shmat");
clean_up_exit(1);
#endif
} else if (strstr(str, "map:") == str || strstr(str, "mmap:") == str } else if (strstr(str, "map:") == str || strstr(str, "mmap:") == str
|| strstr(str, "file:") == str) { || strstr(str, "file:") == str) {
/* map:/path/... or file:/path */ /* map:/path/... or file:/path */
...@@ -18666,8 +18929,8 @@ void initialize_blackouts(char *list) { ...@@ -18666,8 +18929,8 @@ void initialize_blackouts(char *list) {
y = nfix(y, dpy_y); y = nfix(y, dpy_y);
X = x + w; X = x + w;
Y = y + h; Y = y + h;
X = nfix(X, dpy_x); X = nfix(X, dpy_x+1);
Y = nfix(Y, dpy_y); Y = nfix(Y, dpy_y+1);
if (x > X) { if (x > X) {
t = X; X = x; x = t; t = X; X = x; x = t;
} }
...@@ -20447,10 +20710,15 @@ static int copy_tiles(int tx, int ty, int nt) { ...@@ -20447,10 +20710,15 @@ static int copy_tiles(int tx, int ty, int nt) {
if (nt == 1) { if (nt == 1) {
/* /*
* optimization for tall skinny lines, e.g. wm * optimization for tall skinny lines, e.g. wm
* frame. try to find first_x and last_x * frame. try to find first_x and last_x to limit
* we like to think the above memcpy leaves the * the size of the hint. could help for a slow
* data we use below in the cache... (but it * link. Unfortunately we spent a lot of time
* could be two 128 byte segments at 32bpp) * reading in the many tiles.
*
* BTW, we like to think the above memcpy leaves
* the data we use below in the cache... (but
* it could be two 128 byte segments at 32bpp)
* so this inner loop is not as bad as it seems.
*/ */
int k, kx; int k, kx;
kx = pixelsize; kx = pixelsize;
...@@ -20612,6 +20880,10 @@ static int copy_all_tile_runs(void) { ...@@ -20612,6 +20880,10 @@ static int copy_all_tile_runs(void) {
} }
} }
} }
/*
* Could some activity go here, to emulate threaded
* behavior by servicing some libvncserver tasks?
*/
} }
return diffs; return diffs;
} }
...@@ -21314,6 +21586,7 @@ int scan_for_updates(int count_only) { ...@@ -21314,6 +21586,7 @@ int scan_for_updates(int count_only) {
set_colormap(0); set_colormap(0);
} }
if (use_xdamage) { if (use_xdamage) {
/* first pass collecting DAMAGE events: */
collect_xdamage(scan_count, 0); collect_xdamage(scan_count, 0);
} }
} }
...@@ -21333,7 +21606,9 @@ int scan_for_updates(int count_only) { ...@@ -21333,7 +21606,9 @@ int scan_for_updates(int count_only) {
/* /*
* we do the XDAMAGE here too since after scan_display() * we do the XDAMAGE here too since after scan_display()
* there is a better chance we have received the events from * there is a better chance we have received the events from
* the server. * the X server (otherwise the DAMAGE events will be processed
* in the *next* call, usually too late and wasteful since
* the unchanged tiles are read in again).
*/ */
if (use_xdamage) { if (use_xdamage) {
collect_xdamage(scan_count, 1); collect_xdamage(scan_count, 1);
...@@ -21869,24 +22144,23 @@ Window descend_pointer(int depth, Window start, char *name_info, int len) { ...@@ -21869,24 +22144,23 @@ Window descend_pointer(int depth, Window start, char *name_info, int len) {
clast = c; clast = c;
if (store && ! filled) { if (store && ! filled) {
char *name; char *name;
if (XFetchName(dpy, clast, &name)) { if (XFetchName(dpy, clast, &name) && name != NULL) {
int l = strlen(name); int l = strlen(name);
if (written + l+2 < len) { if (written + l+2 < len) {
strcat(store, "^^"); strcat(store, "^^");
written += 2; written += 2;
strcat(store, name); strcat(store, name);
written += l; written += l;
XFree(name);
} else { } else {
filled = 1; filled = 1;
} }
XFree(name);
} }
} }
if (store && classhint && ! filled) { if (store && classhint && ! filled) {
classhint->res_name = NULL; classhint->res_name = NULL;
classhint->res_class = NULL; classhint->res_class = NULL;
if (XGetClassHint(dpy, clast, classhint)) { if (XGetClassHint(dpy, clast, classhint)) {
char *p;
int l = 0; int l = 0;
if (classhint->res_class) { if (classhint->res_class) {
l += strlen(classhint->res_class); l += strlen(classhint->res_class);
...@@ -21896,21 +22170,25 @@ Window descend_pointer(int depth, Window start, char *name_info, int len) { ...@@ -21896,21 +22170,25 @@ Window descend_pointer(int depth, Window start, char *name_info, int len) {
} }
if (written + l+4 < len) { if (written + l+4 < len) {
strcat(store, "##"); strcat(store, "##");
p = classhint->res_class; if (classhint->res_class) {
if (p) { strcat(store,
strcat(store, p); classhint->res_class);
XFree(p);
} }
strcat(store, "++"); strcat(store, "++");
p = classhint->res_name; if (classhint->res_name) {
if (p) { strcat(store,
strcat(store, p); classhint->res_name);
XFree(p);
} }
written += l+4; written += l+4;
} else { } else {
filled = 1; filled = 1;
} }
if (classhint->res_class) {
XFree(classhint->res_class);
}
if (classhint->res_name) {
XFree(classhint->res_name);
}
} }
} }
if (! XQueryPointer(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &m)) { if (! XQueryPointer(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &m)) {
...@@ -22489,6 +22767,31 @@ void initialize_scroll_matches(void) { ...@@ -22489,6 +22767,31 @@ void initialize_scroll_matches(void) {
} }
} }
void initialize_scroll_term(void) {
char *str;
int n;
destroy_str_list(scroll_term);
scroll_term = NULL;
if (scroll_term_str != NULL && *scroll_term_str != '\0') {
str = scroll_term_str;
} else {
str = scroll_term_str0;
}
if (!strcmp(str, "none")) {
return;
}
scroll_term = create_str_list(str);
n = 0;
while (scroll_term[n] != NULL) {
char *s = scroll_good_all[n++];
/* pull parameters out at some point */
s = NULL;
}
}
typedef struct saveline { typedef struct saveline {
int x0, y0, x1, y1; int x0, y0, x1, y1;
int shift; int shift;
...@@ -22758,8 +23061,8 @@ if (db) dtime0(&tm); ...@@ -22758,8 +23061,8 @@ if (db) dtime0(&tm);
x1 = nfix(x1, dpy_x); x1 = nfix(x1, dpy_x);
y1 = nfix(y1, dpy_y); y1 = nfix(y1, dpy_y);
x2 = nfix(x2, dpy_x); x2 = nfix(x2, dpy_x+1);
y2 = nfix(y2, dpy_y); y2 = nfix(y2, dpy_y+1);
if (x1 == x2) { if (x1 == x2) {
return 1; return 1;
...@@ -22875,7 +23178,6 @@ int do_bdpush(Window wm_win, int x0, int y0, int w0, int h0, int bdx, ...@@ -22875,7 +23178,6 @@ int do_bdpush(Window wm_win, int x0, int y0, int w0, int h0, int bdx,
int do_fb_push = 0; int do_fb_push = 0;
int db = debug_scroll; int db = debug_scroll;
if (wm_win == last_wm_win) { if (wm_win == last_wm_win) {
attr.x = last_x; attr.x = last_x;
attr.y = last_y; attr.y = last_y;
...@@ -22959,6 +23261,119 @@ if (db > 1) fprintf(stderr, " BDP(%d,%d-%d,%d) dt: %.4f\n", tx1, ty1, tx2, ty2 ...@@ -22959,6 +23261,119 @@ if (db > 1) fprintf(stderr, " BDP(%d,%d-%d,%d) dt: %.4f\n", tx1, ty1, tx2, ty2
return do_fb_push; return do_fb_push;
} }
int set_ypad(void) {
int ev, ev_tot = scr_ev_cnt;
static Window last_win = None;
static double last_time = 0.0;
static int y_accum = 0, last_sign = 0;
double now, cut = 0.1;
int dy_sum = 0, ys = 0, sign;
int font_size = 15;
int win_y, scr_y, loc_cut = 4*font_size, y_cut = 10*font_size;
if (!xrecord_set_by_keys || !xrecord_name_info) {
return 0;
}
if (xrecord_name_info[0] == '\0') {
return 0;
}
if (! ev_tot) {
return 0;
}
if (xrecord_keysym == NoSymbol) {
return 0;
}
if (!xrecord_scroll_keysym(xrecord_keysym)) {
return 0;
}
if (!scroll_term) {
return 0;
}
if (!match_str_list(xrecord_name_info, scroll_term)) {
return 0;
}
for (ev=0; ev < ev_tot; ev++) {
dy_sum += nabs(scr_ev[ev].dy);
if (scr_ev[ev].dy < 0) {
ys--;
} else if (scr_ev[ev].dy > 0) {
ys++;
} else {
ys = 0;
break;
}
if (scr_ev[ev].win != scr_ev[0].win) {
ys = 0;
break;
}
if (scr_ev[ev].dx != 0) {
ys = 0;
break;
}
}
if (ys != ev_tot && ys != -ev_tot) {
return 0;
}
if (ys < 0) {
sign = -1;
} else {
sign = 1;
}
if (sign > 0) {
/*
* this case is not as useful as scrolling near the
* bottom of a terminal. But there are problems for it too.
*/
return 0;
}
win_y = scr_ev[0].win_y + scr_ev[0].win_h;
scr_y = scr_ev[0].y + scr_ev[0].h;
if (nabs(scr_y - win_y) > loc_cut) {
/* require it to be near the bottom. */
return 0;
}
now = dnow();
if (now < last_time + cut) {
int ok = 1;
if (last_win && scr_ev[0].win != last_win) {
ok = 0;
}
if (last_sign && sign != last_sign) {
ok = 0;
}
if (! ok) {
last_win = None;
last_sign = 0;
y_accum = 0;
last_time = 0.0;
return 0;
}
} else {
last_win = None;
last_sign = 0;
last_time = 0.0;
y_accum = 0;
}
y_accum += sign * dy_sum;
if (4 * nabs(y_accum) > scr_ev[0].h && y_cut) {
; /* TBD */
}
last_sign = sign;
last_win = scr_ev[0].win;
last_time = now;
return y_accum;
}
#define PUSH_TEST(n) \ #define PUSH_TEST(n) \
if (n) { \ if (n) { \
double dt = 0.0, tm; dtime0(&tm); \ double dt = 0.0, tm; dtime0(&tm); \
...@@ -22979,6 +23394,7 @@ int push_scr_ev(double max_age, int type, int bdpush, int bdx, int bdy, ...@@ -22979,6 +23394,7 @@ int push_scr_ev(double max_age, int type, int bdpush, int bdx, int bdy,
int db = debug_scroll, rrate = get_read_rate(); int db = debug_scroll, rrate = get_read_rate();
sraRegionPtr backfill, whole, tmpregion, tmpregion2; sraRegionPtr backfill, whole, tmpregion, tmpregion2;
int link, latency, netrate; int link, latency, netrate;
int ypad = 0;
if (ev_tot == 0) { if (ev_tot == 0) {
return dret; return dret;
...@@ -23005,6 +23421,10 @@ int push_scr_ev(double max_age, int type, int bdpush, int bdx, int bdy, ...@@ -23005,6 +23421,10 @@ int push_scr_ev(double max_age, int type, int bdpush, int bdx, int bdy,
w0 = scr_ev[0].win_w; w0 = scr_ev[0].win_w;
h0 = scr_ev[0].win_h; h0 = scr_ev[0].win_h;
ypad = set_ypad();
if (db) fprintf(stderr, "ypad: %d dy[0]: %d\n", ypad, scr_ev[0].dy);
for (ev=0; ev < ev_tot; ev++) { for (ev=0; ev < ev_tot; ev++) {
x = scr_ev[ev].x; x = scr_ev[ev].x;
...@@ -23069,13 +23489,9 @@ if (db > 1) fprintf(stderr, "------------ got: %d x: %4d y: %3d" ...@@ -23069,13 +23489,9 @@ if (db > 1) fprintf(stderr, "------------ got: %d x: %4d y: %3d"
frame = xrecord_wm_window; frame = xrecord_wm_window;
} }
if (! frame) { if (! frame) {
Window r; X_LOCK;
int rx, ry, wx, wy; frame = query_pointer(rootwin);
unsigned int m; X_UNLOCK;
if (! XQueryPointer(dpy, rootwin, &r, &frame,
&rx, &ry, &wx, &wy, &m)) {
frame = None;
}
} }
if (! frame) { if (! frame) {
frame = win; frame = win;
...@@ -23121,6 +23537,21 @@ if (db > 1) fprintf(stderr, "------------ got: %d x: %4d y: %3d" ...@@ -23121,6 +23537,21 @@ if (db > 1) fprintf(stderr, "------------ got: %d x: %4d y: %3d"
* ignore for now... probably will make some apps * ignore for now... probably will make some apps
* act very strangely. * act very strangely.
*/ */
if (ypad) {
if (ypad < 0) {
if (h > -ypad) {
h += ypad;
} else {
ypad = 0;
}
} else {
if (h > ypad) {
y += ypad;
} else {
ypad = 0;
}
}
}
if (try_copyrect(frame, x, y, w, h, dx, dy, &obscured, if (try_copyrect(frame, x, y, w, h, dx, dy, &obscured,
tmpregion, waittime)) { tmpregion, waittime)) {
...@@ -23146,6 +23577,15 @@ if (0) fprintf(stderr, " try_copyrect dt: %.4f\n", dt); ...@@ -23146,6 +23577,15 @@ if (0) fprintf(stderr, " try_copyrect dt: %.4f\n", dt);
sraRgnAnd(backfill, whole); sraRgnAnd(backfill, whole);
} }
if (ypad) {
if (ypad < 0) {
ny += ypad;
nh -= ypad;
} else {
;
}
}
tmpregion = sraRgnCreateRect(nx, ny, nx + nw, ny + nh); tmpregion = sraRgnCreateRect(nx, ny, nx + nw, ny + nh);
sraRgnAnd(tmpregion, whole); sraRgnAnd(tmpregion, whole);
sraRgnOr(backfill, tmpregion); sraRgnOr(backfill, tmpregion);
...@@ -23208,8 +23648,8 @@ if (db) fprintf(stderr, " EST_TOO_LARGE"); ...@@ -23208,8 +23648,8 @@ if (db) fprintf(stderr, " EST_TOO_LARGE");
ty2 = rect.y2; ty2 = rect.y2;
tx1 = nfix(tx1, dpy_x); tx1 = nfix(tx1, dpy_x);
ty1 = nfix(ty1, dpy_y); ty1 = nfix(ty1, dpy_y);
tx2 = nfix(tx2, dpy_x); tx2 = nfix(tx2, dpy_x+1);
ty2 = nfix(ty2, dpy_y); ty2 = nfix(ty2, dpy_y+1);
dtime(&tm); dtime(&tm);
if (db) fprintf(stderr, " DFC(%d,%d-%d,%d)", tx1, ty1, tx2, ty2); if (db) fprintf(stderr, " DFC(%d,%d-%d,%d)", tx1, ty1, tx2, ty2);
...@@ -23217,8 +23657,8 @@ if (db) fprintf(stderr, " DFC(%d,%d-%d,%d)", tx1, ty1, tx2, ty2); ...@@ -23217,8 +23657,8 @@ if (db) fprintf(stderr, " DFC(%d,%d-%d,%d)", tx1, ty1, tx2, ty2);
do_fb_push++; do_fb_push++;
PUSH_TEST(0); PUSH_TEST(0);
} }
dt = dtime(&tm);
sraRgnReleaseIterator(iter); sraRgnReleaseIterator(iter);
dt = dtime(&tm);
if (0) fprintf(stderr, " dfc---- dt: %.4f", dt); if (0) fprintf(stderr, " dfc---- dt: %.4f", dt);
} }
...@@ -23341,17 +23781,28 @@ if (debug_scroll > 1) fprintf(stderr, ">>>-rfbDoCopyRect req: %d mod: %d cpy: %d ...@@ -23341,17 +23781,28 @@ if (debug_scroll > 1) fprintf(stderr, ">>>-rfbDoCopyRect req: %d mod: %d cpy: %d
sraRgnReleaseIterator(iter); sraRgnReleaseIterator(iter);
} }
void fb_push_wait(double max_wait) { void fb_push_wait(double max_wait, int flags) {
double tm, dt = 0.0; double tm, dt = 0.0;
int req, mod, cpy, ncli; int req, mod, cpy, ncli;
dtime0(&tm); dtime0(&tm);
while (dt < max_wait) { while (dt < max_wait) {
int done = 1;
rfbCFD(0); rfbCFD(0);
get_client_regions(&req, &mod, &cpy, &ncli); get_client_regions(&req, &mod, &cpy, &ncli);
if (! cpy) { if (flags & FB_COPY && cpy) {
done = 0;
}
if (flags & FB_MOD && mod) {
done = 0;
}
if (flags & FB_REQ && req) {
done = 0;
}
if (done) {
break; break;
} }
usleep(1000); usleep(1000);
fb_push(); fb_push();
dt += dtime(&tm); dt += dtime(&tm);
...@@ -23516,14 +23967,45 @@ void mark_for_xdamage(int x, int y, int w, int h) { ...@@ -23516,14 +23967,45 @@ void mark_for_xdamage(int x, int y, int w, int h) {
tx1 = nfix(x, dpy_x); tx1 = nfix(x, dpy_x);
ty1 = nfix(y, dpy_y); ty1 = nfix(y, dpy_y);
tx2 = nfix(x + w, dpy_x); tx2 = nfix(x + w, dpy_x+1);
ty2 = nfix(y + h, dpy_y); ty2 = nfix(y + h, dpy_y+1);
tmpregion = sraRgnCreateRect(tx1, ty1, tx2, ty2); tmpregion = sraRgnCreateRect(tx1, ty1, tx2, ty2);
add_region_xdamage(tmpregion); add_region_xdamage(tmpregion);
sraRgnDestroy(tmpregion); sraRgnDestroy(tmpregion);
} }
void mark_region_for_xdamage(sraRegionPtr region) {
sraRectangleIterator *iter;
sraRect rect;
iter = sraRgnGetIterator(region);
while (sraRgnIteratorNext(iter, &rect)) {
int x1 = rect.x1;
int y1 = rect.y1;
int x2 = rect.x2;
int y2 = rect.y2;
mark_for_xdamage(x1, y1, x2 - x1, y2 - y1);
}
sraRgnReleaseIterator(iter);
}
void set_xdamage_mark(int x, int y, int w, int h) {
sraRegionPtr region;
mark_for_xdamage(x, y, w, h);
if (xdamage_scheduled_mark == 0.0) {
xdamage_scheduled_mark = dnow() + 2.0;
}
if (xdamage_scheduled_mark_region == NULL) {
xdamage_scheduled_mark_region = sraRgnCreate();
}
region = sraRgnCreateRect(x, y, x + w, y + w);
sraRgnOr(xdamage_scheduled_mark_region, region);
sraRgnDestroy(region);
}
int check_xrecord_keys(void) { int check_xrecord_keys(void) {
static int last_wx, last_wy, last_ww, last_wh; static int last_wx, last_wy, last_ww, last_wh;
double spin = 0.0, tm, tnow; double spin = 0.0, tm, tnow;
...@@ -23621,7 +24103,9 @@ if (db) fprintf(stderr, "check_xrecord: more keys: %.3f\n", spin); ...@@ -23621,7 +24103,9 @@ if (db) fprintf(stderr, "check_xrecord: more keys: %.3f\n", spin);
flush2 = 1; flush2 = 1;
XFlush(dpy); XFlush(dpy);
} }
SCR_LOCK;
XRecordProcessReplies(rdpy_data); XRecordProcessReplies(rdpy_data);
SCR_UNLOCK;
X_UNLOCK; X_UNLOCK;
if (spin >= max_spin * spin_fac) { if (spin >= max_spin * spin_fac) {
...@@ -23659,7 +24143,7 @@ if (db) fprintf(stderr, "check_xrecord: SPIN-OUT: %.3f/%.3f\n", spin, ...@@ -23659,7 +24143,7 @@ if (db) fprintf(stderr, "check_xrecord: SPIN-OUT: %.3f/%.3f\n", spin,
} }
if ((got_one && ret < 2) || persist_count) { if ((got_one && ret < 2) || persist_count) {
mark_for_xdamage(last_wx, last_wy, last_ww, last_wh); set_xdamage_mark(last_wx, last_wy, last_ww, last_wh);
} }
if (fail) { if (fail) {
...@@ -23879,7 +24363,9 @@ if (db) fprintf(stderr, "check_xrecord: BUTTON_UP_SCROLL: %.3f\n", spin); ...@@ -23879,7 +24363,9 @@ if (db) fprintf(stderr, "check_xrecord: BUTTON_UP_SCROLL: %.3f\n", spin);
input++; input++;
} }
X_LOCK; X_LOCK;
SCR_LOCK;
XRecordProcessReplies(rdpy_data); XRecordProcessReplies(rdpy_data);
SCR_UNLOCK;
X_UNLOCK; X_UNLOCK;
if (! input) { if (! input) {
...@@ -23941,12 +24427,12 @@ if (db) fprintf(stderr, "check_xrecord: BUTTON-UP-KEEP-GOING: %.3f/%.3f %d/%d % ...@@ -23941,12 +24427,12 @@ if (db) fprintf(stderr, "check_xrecord: BUTTON-UP-KEEP-GOING: %.3f/%.3f %d/%d %
last_y = cursor_y; last_y = cursor_y;
} }
if (fail) { if (got_one) {
scrollability(xrecord_ptr_window, SCR_FAIL); set_xdamage_mark(last_wx, last_wy, last_ww, last_wh);
} }
if (got_one) { if (fail) {
mark_for_xdamage(last_wx, last_wy, last_ww, last_wh); scrollability(xrecord_ptr_window, SCR_FAIL);
} }
/* flush any remaining pointer events. */ /* flush any remaining pointer events. */
...@@ -24099,7 +24585,7 @@ int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy, ...@@ -24099,7 +24585,7 @@ int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy,
get_client_regions(&req, &mod, &cpy, &ncli); get_client_regions(&req, &mod, &cpy, &ncli);
if (cpy) { if (cpy) {
/* one is still pending... try to force it out: */ /* one is still pending... try to force it out: */
fb_push_wait(max_wait); fb_push_wait(max_wait, FB_COPY);
get_client_regions(&req, &mod, &cpy, &ncli); get_client_regions(&req, &mod, &cpy, &ncli);
} }
...@@ -24131,8 +24617,8 @@ int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy, ...@@ -24131,8 +24617,8 @@ int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy,
/* send the whole thing... */ /* send the whole thing... */
x1 = crfix(nfix(x, dpy_x), dx, dpy_x); x1 = crfix(nfix(x, dpy_x), dx, dpy_x);
y1 = crfix(nfix(y, dpy_y), dy, dpy_y); y1 = crfix(nfix(y, dpy_y), dy, dpy_y);
x2 = crfix(nfix(x+w, dpy_x), dx, dpy_x); x2 = crfix(nfix(x+w, dpy_x+1), dx, dpy_x+1);
y2 = crfix(nfix(y+h, dpy_y), dy, dpy_y); y2 = crfix(nfix(y+h, dpy_y+1), dy, dpy_y+1);
rect = sraRgnCreateRect(x1, y1, x2, y2); rect = sraRgnCreateRect(x1, y1, x2, y2);
do_copyregion(rect, dx, dy); do_copyregion(rect, dx, dy);
...@@ -24155,8 +24641,8 @@ int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy, ...@@ -24155,8 +24641,8 @@ int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy,
tx1 = nfix(orig_x, dpy_x); tx1 = nfix(orig_x, dpy_x);
ty1 = nfix(orig_y, dpy_y); ty1 = nfix(orig_y, dpy_y);
tx2 = nfix(orig_x+w, dpy_x); tx2 = nfix(orig_x+w, dpy_x+1);
ty2 = nfix(orig_y+h, dpy_y); ty2 = nfix(orig_y+h, dpy_y+1);
if (db2) fprintf(stderr, "moved_win: %4d %3d, %4d %3d 0x%lx ---\n", if (db2) fprintf(stderr, "moved_win: %4d %3d, %4d %3d 0x%lx ---\n",
tx1, ty1, tx2, ty2, frame); tx1, ty1, tx2, ty2, frame);
...@@ -24234,8 +24720,8 @@ saw_me = 1; fprintf(stderr, " ----------\n"); ...@@ -24234,8 +24720,8 @@ saw_me = 1; fprintf(stderr, " ----------\n");
/* clip the window to the visible screen: */ /* clip the window to the visible screen: */
tx1 = nfix(attr.x, dpy_x); tx1 = nfix(attr.x, dpy_x);
ty1 = nfix(attr.y, dpy_y); ty1 = nfix(attr.y, dpy_y);
tx2 = nfix(attr.x + attr.width, dpy_x); tx2 = nfix(attr.x + attr.width, dpy_x+1);
ty2 = nfix(attr.y + attr.height, dpy_y); ty2 = nfix(attr.y + attr.height, dpy_y+1);
if (db2) fprintf(stderr, " tmp_win-1: %4d %3d, %4d %3d 0x%lx\n", if (db2) fprintf(stderr, " tmp_win-1: %4d %3d, %4d %3d 0x%lx\n",
tx1, ty1, tx2, ty2, swin); tx1, ty1, tx2, ty2, swin);
...@@ -24262,8 +24748,8 @@ if (db2) fprintf(stderr, " : clips it.\n"); ...@@ -24262,8 +24748,8 @@ if (db2) fprintf(stderr, " : clips it.\n");
/* clip the window to the visible screen: */ /* clip the window to the visible screen: */
tx1 = nfix(attr.x - dx, dpy_x); tx1 = nfix(attr.x - dx, dpy_x);
ty1 = nfix(attr.y - dy, dpy_y); ty1 = nfix(attr.y - dy, dpy_y);
tx2 = nfix(attr.x - dx + attr.width, dpy_x); tx2 = nfix(attr.x - dx + attr.width, dpy_x+1);
ty2 = nfix(attr.y - dy + attr.height, dpy_y); ty2 = nfix(attr.y - dy + attr.height, dpy_y+1);
if (db2) fprintf(stderr, " tmp_win-2: %4d %3d, %4d %3d 0x%lx\n", if (db2) fprintf(stderr, " tmp_win-2: %4d %3d, %4d %3d 0x%lx\n",
tx1, ty1, tx2, ty2, swin); tx1, ty1, tx2, ty2, swin);
...@@ -24457,6 +24943,9 @@ int check_wireframe(void) { ...@@ -24457,6 +24943,9 @@ int check_wireframe(void) {
int near_edge; int near_edge;
DB_SET DB_SET
if (nofb) {
return 0;
}
if (subwin) { if (subwin) {
return 0; /* don't even bother for -id case */ return 0; /* don't even bother for -id case */
} }
...@@ -24843,7 +25332,7 @@ if (db || db2) fprintf(stderr, "NO button_mask\n"); ...@@ -24843,7 +25332,7 @@ if (db || db2) fprintf(stderr, "NO button_mask\n");
} }
/* try to flush the wireframe removal: */ /* try to flush the wireframe removal: */
fb_push_wait(0.1); fb_push_wait(0.1, FB_COPY|FB_MOD);
/* try to send a clipped copyrect of translation: */ /* try to send a clipped copyrect of translation: */
sent_copyrect = try_copyrect(frame, x, y, w, h, dx, dy, sent_copyrect = try_copyrect(frame, x, y, w, h, dx, dy,
...@@ -24853,9 +25342,9 @@ if (db) fprintf(stderr, "send_copyrect: %d\n", sent_copyrect); ...@@ -24853,9 +25342,9 @@ if (db) fprintf(stderr, "send_copyrect: %d\n", sent_copyrect);
if (sent_copyrect) { if (sent_copyrect) {
/* try to push the changes to viewers: */ /* try to push the changes to viewers: */
if (! obscured) { if (! obscured) {
fb_push_wait(0.1); fb_push_wait(0.1, FB_COPY);
} else { } else {
fb_push_wait(0.1); fb_push_wait(0.1, FB_COPY);
} }
} }
} }
...@@ -24880,6 +25369,7 @@ if (db) fprintf(stderr, "send_copyrect: %d\n", sent_copyrect); ...@@ -24880,6 +25369,7 @@ if (db) fprintf(stderr, "send_copyrect: %d\n", sent_copyrect);
if (use_xdamage) { if (use_xdamage) {
/* DAMAGE can queue ~1000 rectangles for a move */ /* DAMAGE can queue ~1000 rectangles for a move */
clear_xdamage_mark_region(NULL, 1); clear_xdamage_mark_region(NULL, 1);
xdamage_scheduled_mark = dnow() + 2.0;
} }
return 1; return 1;
...@@ -25516,12 +26006,21 @@ int get_rate(int which) { ...@@ -25516,12 +26006,21 @@ int get_rate(int which) {
rfbClientPtr cl; rfbClientPtr cl;
int irate, irate_min = 1; /* 1 KB/sec */ int irate, irate_min = 1; /* 1 KB/sec */
int irate_max = 100000; /* 100 MB/sec */ int irate_max = 100000; /* 100 MB/sec */
int count = 0;
double slowest = -1.0, rate; double slowest = -1.0, rate;
static double save_rate = 1000 * NETRATE0; static double save_rate = 1000 * NETRATE0;
iter = rfbGetClientIterator(screen); iter = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(iter)) ) { while( (cl = rfbClientIteratorNext(iter)) ) {
ClientData *cd = (ClientData *) cl->clientData; ClientData *cd = (ClientData *) cl->clientData;
if (cl->state != RFB_NORMAL) {
continue;
}
if (cd->send_cmp_rate == 0.0 || cd->send_raw_rate == 0.0) {
continue;
}
count++;
if (which == 0) { if (which == 0) {
rate = cd->send_cmp_rate; rate = cd->send_cmp_rate;
...@@ -25535,6 +26034,10 @@ int get_rate(int which) { ...@@ -25535,6 +26034,10 @@ int get_rate(int which) {
} }
rfbReleaseClientIterator(iter); rfbReleaseClientIterator(iter);
if (! count) {
return NETRATE0;
}
if (slowest == -1.0) { if (slowest == -1.0) {
slowest = save_rate; slowest = save_rate;
} else { } else {
...@@ -25548,6 +26051,7 @@ int get_rate(int which) { ...@@ -25548,6 +26051,7 @@ int get_rate(int which) {
if (irate > irate_max) { if (irate > irate_max) {
irate = irate_max; irate = irate_max;
} }
if (0) fprintf(stderr, "get_rate(%d) %d %.3f/%.3f\n", which, irate, save_rate, slowest);
return irate; return irate;
} }
...@@ -25559,11 +26063,20 @@ int get_latency(void) { ...@@ -25559,11 +26063,20 @@ int get_latency(void) {
int ilat_max = 2000; /* 2 sec */ int ilat_max = 2000; /* 2 sec */
double slowest = -1.0, lat; double slowest = -1.0, lat;
static double save_lat = ((double) LATENCY0)/1000.0; static double save_lat = ((double) LATENCY0)/1000.0;
int count = 0;
iter = rfbGetClientIterator(screen); iter = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(iter)) ) { while( (cl = rfbClientIteratorNext(iter)) ) {
ClientData *cd = (ClientData *) cl->clientData; ClientData *cd = (ClientData *) cl->clientData;
if (cl->state != RFB_NORMAL) {
continue;
}
if (cd->latency == 0.0) {
continue;
}
count++;
lat = cd->latency; lat = cd->latency;
if (slowest == -1.0 || lat > slowest) { if (slowest == -1.0 || lat > slowest) {
slowest = lat; slowest = lat;
...@@ -25571,6 +26084,10 @@ int get_latency(void) { ...@@ -25571,6 +26084,10 @@ int get_latency(void) {
} }
rfbReleaseClientIterator(iter); rfbReleaseClientIterator(iter);
if (! count) {
return LATENCY0;
}
if (slowest == -1.0) { if (slowest == -1.0) {
slowest = save_lat; slowest = save_lat;
} else { } else {
...@@ -26030,6 +26547,47 @@ if (db) fprintf(stderr, "dt3 calc: num rects req: %d/%d mod: %d/%d " ...@@ -26030,6 +26547,47 @@ if (db) fprintf(stderr, "dt3 calc: num rects req: %d/%d mod: %d/%d "
} }
} }
void check_cursor_changes(void) {
static double last_push = 0.0;
cursor_changes += check_x11_pointer();
if (cursor_changes) {
double tm, max_push = 0.125, multi_push = 0.01, wait = 0.02;
int cursor_shape, dopush = 0, link, latency, netrate;
cursor_shape = cursor_shape_updates_clients(screen);
dtime0(&tm);
link = link_rate(&latency, &netrate);
if (link == LR_DIALUP) {
max_push = 0.2;
wait = 0.05;
} else if (link == LR_BROADBAND) {
max_push = 0.075;
wait = 0.05;
} else if (link == LR_LAN) {
max_push = 0.01;
} else if (latency < 5 && netrate > 200) {
max_push = 0.01;
}
if (tm > last_push + max_push) {
dopush = 1;
} else if (cursor_changes > 1 && tm > last_push + multi_push) {
dopush = 1;
}
if (dopush) {
mark_rect_as_modified(0, 0, 1, 1, 1);
fb_push_wait(wait, FB_MOD);
last_push = tm;
} else {
rfbPE(0);
}
}
cursor_changes = 0;
}
/* /*
* utility wrapper to call rfbProcessEvents * utility wrapper to call rfbProcessEvents
* checks that we are not in threaded mode. * checks that we are not in threaded mode.
...@@ -26060,17 +26618,103 @@ void rfbCFD(long usec) { ...@@ -26060,17 +26618,103 @@ void rfbCFD(long usec) {
} }
} }
int choose_delay(void) { int choose_delay(double dt) {
static double t0 = 0.0, t1 = 0.0, t2 = 0.0; static double t0 = 0.0, t1 = 0.0, t2 = 0.0, now;
static int x0, y0, x1, y1, x2, y2; static int x0, y0, x1, y1, x2, y2, first = 1;
int dx0, dy0, dx1, dy1, dm, ms = waitms; int dx0, dy0, dx1, dy1, dm, i, msec = waitms;
double cut1 = 0.2, cut2 = 0.1, cut3 = 0.25; double cut1 = 0.15, cut2 = 0.075, cut3 = 0.25;
int fac = 1; double bogdown_time = 0.25, bave = 0.0;
int bogdown = 1, bcnt = 0;
int ndt = 8, nave = 3;
double fac = 1.0;
int db = 0;
static double dts[8];
if (waitms == 0) { if (waitms == 0) {
return waitms; return waitms;
} }
if (nofb) {
return waitms;
}
if (first) {
for(i=0; i<ndt; i++) {
dts[i] = 0.0;
}
first = 0;
}
now = dnow();
/*
* first check for bogdown, e.g. lots of activity, scrolling text
* from command output, etc.
*/
if (nap_ok) {
dt = 0.0;
}
if (! wait_bog) {
bogdown = 0;
} else if (button_mask || now < last_keyboard_time + 2*bogdown_time) {
/*
* let scrolls & keyboard input through the normal way
* otherwise, it will likely just annoy them.
*/
bogdown = 0;
} else if (dt > 0.0) {
/*
* inspect recent dt's:
* 0 1 2 3 4 5 6 7 dt
* ^ ^ ^
*/
for (i = ndt - (nave - 1); i < ndt; i++) {
bave += dts[i];
bcnt++;
if (dts[i] < bogdown_time) {
bogdown = 0;
break;
}
}
bave += dt;
bcnt++;
bave = bave / bcnt;
if (dt < bogdown_time) {
bogdown = 0;
}
} else {
bogdown = 0;
}
/* shift for next time */
for (i = 0; i < ndt-1; i++) {
dts[i] = dts[i+1];
}
dts[ndt-1] = dt;
if (0 && dt > 0.0) fprintf(stderr, "dt: %.5f %.4f\n", dt, dnow() - x11vnc_start);
if (bogdown) {
if (use_xdamage) {
/* DAMAGE can queue ~1000 rectangles for a scroll */
clear_xdamage_mark_region(NULL, 0);
}
msec = (int) (1000 * 1.75 * bave);
if (dts[ndt - nave - 1] > 0.75 * bave) {
msec = 1.5 * msec;
}
if (msec > 1500) {
msec = 1500;
}
if (msec < waitms) {
msec = waitms;
}
db = (db || debug_tiles);
if (db) fprintf(stderr, "bogg[%d] %.3f %.3f %.3f %.3f\n",
msec, dts[ndt-4], dts[ndt-3], dts[ndt-2], dts[ndt-1]);
return msec;
}
/* next check for pointer motion, keystrokes, to speed up */
t2 = dnow(); t2 = dnow();
x2 = cursor_x; x2 = cursor_x;
y2 = cursor_y; y2 = cursor_y;
...@@ -26087,18 +26731,18 @@ int choose_delay(void) { ...@@ -26087,18 +26731,18 @@ int choose_delay(void) {
if ((dx0 || dy0) && (dx1 || dy1)) { if ((dx0 || dy0) && (dx1 || dy1)) {
if (t2 < t0 + cut1 || t2 < t1 + cut2 || dm > 20) { if (t2 < t0 + cut1 || t2 < t1 + cut2 || dm > 20) {
fac = 3; fac = wait_ui * 1.25;
} }
} else if ((dx1 || dy1) && dm > 40) { } else if ((dx1 || dy1) && dm > 40) {
fac = 3; fac = wait_ui;
} }
if (fac == 1 && t2 < last_keyboard_time + cut3) { if (fac == 1 && t2 < last_keyboard_time + cut3) {
fac = 2; fac = wait_ui;
} }
ms = waitms / fac; msec = (int) ((double) waitms / fac);
if (ms == 0) { if (msec == 0) {
ms = 1; msec = 1;
} }
x0 = x1; x0 = x1;
...@@ -26109,7 +26753,7 @@ int choose_delay(void) { ...@@ -26109,7 +26753,7 @@ int choose_delay(void) {
y1 = y2; y1 = y2;
t1 = t2; t1 = t2;
return ms; return msec;
} }
/* /*
...@@ -26117,7 +26761,7 @@ int choose_delay(void) { ...@@ -26117,7 +26761,7 @@ int choose_delay(void) {
*/ */
static void watch_loop(void) { static void watch_loop(void) {
int cnt = 0, tile_diffs = 0, skip_pe = 0; int cnt = 0, tile_diffs = 0, skip_pe = 0;
double tm = 0.0, dt = 0.0, dtr = 0.0; double tm, dtr, dt = 0.0;
time_t start = time(0); time_t start = time(0);
if (use_threads) { if (use_threads) {
...@@ -26132,7 +26776,7 @@ static void watch_loop(void) { ...@@ -26132,7 +26776,7 @@ static void watch_loop(void) {
urgent_update = 0; urgent_update = 0;
if (! use_threads) { if (! use_threads) {
dtime(&tm); dtime0(&tm);
if (! skip_pe) { if (! skip_pe) {
measure_send_rates(1); measure_send_rates(1);
rfbPE(-1); rfbPE(-1);
...@@ -26157,8 +26801,14 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret); ...@@ -26157,8 +26801,14 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
continue; continue;
} }
} }
} else if (use_threads && wireframe && button_mask) { } else {
check_wireframe(); if (0 && use_xrecord) {
/* XXX not working */
check_xrecord();
}
if (wireframe && button_mask) {
check_wireframe();
}
} }
skip_pe = 0; skip_pe = 0;
...@@ -26222,11 +26872,19 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret); ...@@ -26222,11 +26872,19 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
X_LOCK; X_LOCK;
XFlush(dpy); XFlush(dpy);
X_UNLOCK; X_UNLOCK;
dt = 0.0;
} else { } else {
static double last_dt = 0.0;
double xdamage_thrash = 0.4;
check_cursor_changes();
/* for timing the scan to try to detect thrashing */ /* for timing the scan to try to detect thrashing */
double tm;
dtime0(&tm);
if (use_xdamage && last_dt > xdamage_thrash) {
clear_xdamage_mark_region(NULL, 0);
}
dtime0(&tm);
if (use_snapfb) { if (use_snapfb) {
int t, tries = 5; int t, tries = 5;
copy_snap(); copy_snap();
...@@ -26237,6 +26895,9 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret); ...@@ -26237,6 +26895,9 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
tile_diffs = scan_for_updates(0); tile_diffs = scan_for_updates(0);
} }
dt = dtime(&tm); dt = dtime(&tm);
if (! nap_ok) {
last_dt = dt;
}
if ((debug_tiles || debug_scroll > 1 || debug_wireframe > 1) if ((debug_tiles || debug_scroll > 1 || debug_wireframe > 1)
&& (tile_diffs > 4 || debug_tiles > 1)) { && (tile_diffs > 4 || debug_tiles > 1)) {
...@@ -26245,13 +26906,18 @@ if ((debug_tiles || debug_scroll > 1 || debug_wireframe > 1) ...@@ -26245,13 +26906,18 @@ if ((debug_tiles || debug_scroll > 1 || debug_wireframe > 1)
" t: %.4f %.2f MB/s\n", tile_diffs, dt, tm - x11vnc_start, " t: %.4f %.2f MB/s\n", tile_diffs, dt, tm - x11vnc_start,
rate/1000000.0); rate/1000000.0);
} }
check_x11_pointer();
} }
/* sleep a bit to lessen load */ /* sleep a bit to lessen load */
if (! urgent_update) { if (! urgent_update) {
int wait = choose_delay(); int wait = choose_delay(dt);
usleep(wait * 1000); if (wait > 2*waitms) {
/* bog case, break it up */
nap_sleep(wait, 10);
} else {
usleep(wait * 1000);
}
} }
cnt++; cnt++;
} }
...@@ -27186,6 +27852,29 @@ static void print_help(int mode) { ...@@ -27186,6 +27852,29 @@ static void print_help(int mode) {
" Shift_L, Control_R, etc, are skipped since they almost\n" " Shift_L, Control_R, etc, are skipped since they almost\n"
" never induce scrolling by themselves.\n" " never induce scrolling by themselves.\n"
"\n" "\n"
"-scr_term list Yet another cosmetic kludge. Apply shell/terminal\n"
" heuristics to applications matching comma separated\n"
" list (same as for -scr_skip/-scr_inc). For example an\n"
" annoying transient under scroll detection is if you\n"
" hit Enter in a terminal shell with full text window,\n"
" the solid text cursor block will be scrolled up.\n"
" So for a short time there are two (or more) block\n"
" cursors on the screen. There are similar scenarios,\n"
" (e.g. an output line is duplicated).\n"
" \n"
" These transients are induced by the approximation of\n"
" scroll detection (e.g. it detects the scroll, but not\n"
" the fact that the block cursor was cleared just before\n"
" the scroll). In nearly all cases these transient errors\n"
" are repaired when the true X framebuffer is consulted\n"
" by the normal polling. But they are distracting, so\n"
" what this option provides is extra \"padding\" near the\n"
" bottom of the terminal window: a few extra lines near\n"
" the bottom will not be scrolled, but rather updated\n"
" from the actual X framebuffer. This usually reduces\n"
" the annoying artifacts. Use \"none\" to disable.\n"
" Default: \"%s\"\n"
"\n"
"-scr_parms string Set various parameters for the scrollcopyrect mode.\n" "-scr_parms string Set various parameters for the scrollcopyrect mode.\n"
" The format is similar to that for -wireframe and packed\n" " The format is similar to that for -wireframe and packed\n"
" with lots of parameters:\n" " with lots of parameters:\n"
...@@ -27317,6 +28006,18 @@ static void print_help(int mode) { ...@@ -27317,6 +28006,18 @@ static void print_help(int mode) {
" (deferUpdateTime) Default: %d\n" " (deferUpdateTime) Default: %d\n"
"-wait time Time in ms to pause between screen polls. Used to cut\n" "-wait time Time in ms to pause between screen polls. Used to cut\n"
" down on load. Default: %d\n" " down on load. Default: %d\n"
"-wait_ui factor Factor by which to cut the -wait time if there\n"
" has been recent user input (pointer or keyboard).\n"
" Improves response, but increases the load whenever you\n"
" are moving the mouse or typing. Default: %.2f\n"
"-nowait_bog Do not detect if the screen polling is \"bogging down\"\n"
" and sleep more. Some activities with no user input can\n"
" slow things down a lot: consider a large terminal window\n"
" with a long build running in it continously streaming\n"
" text output. By default x11vnc will try to detect this\n"
" (3 screen polls in a row each longer than 0.25 sec with\n"
" no user input), and sleep up to 1.5 secs to let things\n"
" \"catch up\". Use this option to disable the detection.\n"
"-readtimeout n Set libvncserver rfbMaxClientWait to n seconds. On\n" "-readtimeout n Set libvncserver rfbMaxClientWait to n seconds. On\n"
" slow links that take a long time to paint the first\n" " slow links that take a long time to paint the first\n"
" screen libvncserver may hit the timeout and drop the\n" " screen libvncserver may hit the timeout and drop the\n"
...@@ -27435,8 +28136,8 @@ static void print_help(int mode) { ...@@ -27435,8 +28136,8 @@ static void print_help(int mode) {
" usage should be very rare, i.e. doing something strange\n" " usage should be very rare, i.e. doing something strange\n"
" with /dev/fb0.\n" " with /dev/fb0.\n"
"\n" "\n"
"-pipeinput cmd Another experimental option: it lets you supply\n" "-pipeinput cmd Another experimental option: it lets you supply an\n"
" an extern command in \"cmd\" that x11vnc will pipe\n" " external command in \"cmd\" that x11vnc will pipe\n"
" all of the user input events to in a simple format.\n" " all of the user input events to in a simple format.\n"
" In -pipeinput mode by default x11vnc will not process\n" " In -pipeinput mode by default x11vnc will not process\n"
" any of the user input events. If you prefix \"cmd\"\n" " any of the user input events. If you prefix \"cmd\"\n"
...@@ -27701,6 +28402,7 @@ static void print_help(int mode) { ...@@ -27701,6 +28402,7 @@ static void print_help(int mode) {
" scr_skip:list set -scr_skip to \"list\"\n" " scr_skip:list set -scr_skip to \"list\"\n"
" scr_inc:list set -scr_inc to \"list\"\n" " scr_inc:list set -scr_inc to \"list\"\n"
" scr_keys:list set -scr_keys to \"list\"\n" " scr_keys:list set -scr_keys to \"list\"\n"
" scr_term:list set -scr_term to \"list\"\n"
" scr_parms:str set -scr_parms parameters.\n" " scr_parms:str set -scr_parms parameters.\n"
" pointer_mode:n set -pointer_mode to n. same as \"pm\"\n" " pointer_mode:n set -pointer_mode to n. same as \"pm\"\n"
" input_skip:n set -input_skip to n.\n" " input_skip:n set -input_skip to n.\n"
...@@ -27711,6 +28413,9 @@ static void print_help(int mode) { ...@@ -27711,6 +28413,9 @@ static void print_help(int mode) {
" nodebug_keyboard disable -debug_keyboard, same as \"nodk\"\n" " nodebug_keyboard disable -debug_keyboard, same as \"nodk\"\n"
" defer:n set -defer to n ms,same as deferupdate:n\n" " defer:n set -defer to n ms,same as deferupdate:n\n"
" wait:n set -wait to n ms.\n" " wait:n set -wait to n ms.\n"
" wait_ui:f set -wait_ui factor to f.\n"
" wait_bog disable -nowait_bog mode.\n"
" nowait_bog enable -nowait_bog mode.\n"
" readtimeout:n set read timeout to n seconds.\n" " readtimeout:n set read timeout to n seconds.\n"
" nap enable -nap mode.\n" " nap enable -nap mode.\n"
" nonap disable -nap mode.\n" " nonap disable -nap mode.\n"
...@@ -27806,35 +28511,35 @@ static void print_help(int mode) { ...@@ -27806,35 +28511,35 @@ static void print_help(int mode) {
" forever noforever once timeout deny lock nodeny unlock\n" " forever noforever once timeout deny lock nodeny unlock\n"
" connect allowonce allow localhost nolocalhost listen\n" " connect allowonce allow localhost nolocalhost listen\n"
" lookup nolookup accept gone shm noshm flipbyteorder\n" " lookup nolookup accept gone shm noshm flipbyteorder\n"
" noflipbyteorder onetile noonetile solid_color\n" " noflipbyteorder onetile noonetile solid_color solid\n"
" solid nosolid blackout xinerama noxinerama xtrap\n" " nosolid blackout xinerama noxinerama xtrap noxtrap\n"
" noxtrap xrandr noxrandr xrandr_mode padgeom quiet q\n" " xrandr noxrandr xrandr_mode padgeom quiet q noquiet\n"
" noquiet modtweak nomodtweak xkb noxkb skip_keycodes\n" " modtweak nomodtweak xkb noxkb skip_keycodes skip_dups\n"
" skip_dups noskip_dups add_keysyms noadd_keysyms\n" " noskip_dups add_keysyms noadd_keysyms clear_mods\n"
" clear_mods noclear_mods clear_keys noclear_keys\n" " noclear_mods clear_keys noclear_keys remap repeat\n"
" remap repeat norepeat fb nofb bell nobell sel nosel\n" " norepeat fb nofb bell nobell sel nosel primary noprimary\n"
" primary noprimary cursorshape nocursorshape cursorpos\n" " cursorshape nocursorshape cursorpos nocursorpos cursor\n"
" nocursorpos cursor show_cursor noshow_cursor nocursor\n" " show_cursor noshow_cursor nocursor arrow xfixes noxfixes\n"
" arrow xfixes noxfixes xdamage noxdamage xd_area xd_mem\n" " xdamage noxdamage xd_area xd_mem alphacut alphafrac\n"
" alphacut alphafrac alpharemove noalpharemove alphablend\n" " alpharemove noalpharemove alphablend noalphablend\n"
" noalphablend xwarppointer xwarp noxwarppointer noxwarp\n" " xwarppointer xwarp noxwarppointer noxwarp buttonmap\n"
" buttonmap dragging nodragging wireframe_mode wireframe\n" " dragging nodragging wireframe_mode wireframe wf\n"
" wf nowireframe nowf wirecopyrect wcr nowirecopyrect\n" " nowireframe nowf wirecopyrect wcr nowirecopyrect nowcr\n"
" nowcr scr_area scr_skip scr_inc scr_keys scr_parms\n" " scr_area scr_skip scr_inc scr_keys scr_term scr_parms\n"
" scrollcopyrect scr noscrollcopyrect noscr pointer_mode\n" " scrollcopyrect scr noscrollcopyrect noscr pointer_mode\n"
" pm input_skip input client_input speeds debug_pointer dp\n" " pm input_skip input client_input speeds debug_pointer dp\n"
" nodebug_pointer nodp debug_keyboard dk nodebug_keyboard\n" " nodebug_pointer nodp debug_keyboard dk nodebug_keyboard\n"
" nodk deferupdate defer wait readtimeout nap nonap\n" " nodk deferupdate defer wait_ui wait_bog nowait_bog wait\n"
" sb screen_blank fs gaps grow fuzz snapfb nosnapfb\n" " readtimeout nap nonap sb screen_blank fs gaps grow fuzz\n"
" rawfb progressive rfbport http nohttp httpport\n" " snapfb nosnapfb rawfb progressive rfbport http nohttp\n"
" httpdir enablehttpproxy noenablehttpproxy alwaysshared\n" " httpport httpdir enablehttpproxy noenablehttpproxy\n"
" noalwaysshared nevershared noalwaysshared dontdisconnect\n" " alwaysshared noalwaysshared nevershared noalwaysshared\n"
" nodontdisconnect desktop debug_xevents nodebug_xevents\n" " dontdisconnect nodontdisconnect desktop debug_xevents\n"
" debug_xevents debug_xdamage nodebug_xdamage\n" " nodebug_xevents debug_xevents debug_xdamage\n"
" debug_xdamage debug_wireframe nodebug_wireframe\n" " nodebug_xdamage debug_xdamage debug_wireframe\n"
" debug_wireframe debug_scroll nodebug_scroll debug_scroll\n" " nodebug_wireframe debug_wireframe debug_scroll\n"
" debug_tiles dbt nodebug_tiles nodbt debug_tiles dbg\n" " nodebug_scroll debug_scroll debug_tiles dbt\n"
" nodbg noremote\n" " nodebug_tiles nodbt debug_tiles dbg nodbg noremote\n"
"\n" "\n"
" aro= display vncdisplay desktopname http_url auth\n" " aro= display vncdisplay desktopname http_url auth\n"
" users rootshift clipshift scale_str scaled_x scaled_y\n" " users rootshift clipshift scale_str scaled_x scaled_y\n"
...@@ -27961,11 +28666,13 @@ static void print_help(int mode) { ...@@ -27961,11 +28666,13 @@ static void print_help(int mode) {
scroll_copyrect_default, scroll_copyrect_default,
scrollcopyrect_min_area, scrollcopyrect_min_area,
scroll_skip_str0 ? scroll_skip_str0 : "(empty)", scroll_skip_str0 ? scroll_skip_str0 : "(empty)",
scroll_term_str0,
SCROLL_COPYRECT_PARMS, SCROLL_COPYRECT_PARMS,
pointer_mode_max, pointer_mode, pointer_mode_max, pointer_mode,
ui_skip, ui_skip,
defer_update, defer_update,
waitms, waitms,
wait_ui,
rfbMaxClientWait/1000, rfbMaxClientWait/1000,
take_naps ? "take naps":"no naps", take_naps ? "take naps":"no naps",
screen_blank, screen_blank,
...@@ -28791,6 +29498,11 @@ int main(int argc, char* argv[]) { ...@@ -28791,6 +29498,11 @@ int main(int argc, char* argv[]) {
} else if (!strcmp(arg, "-wait")) { } else if (!strcmp(arg, "-wait")) {
CHECK_ARGC CHECK_ARGC
waitms = atoi(argv[++i]); waitms = atoi(argv[++i]);
} else if (!strcmp(arg, "-wait_ui")) {
CHECK_ARGC
wait_ui = atof(argv[++i]);
} else if (!strcmp(arg, "-nowait_bog")) {
wait_bog = 0;
} else if (!strcmp(arg, "-readtimeout")) { } else if (!strcmp(arg, "-readtimeout")) {
CHECK_ARGC CHECK_ARGC
rfbMaxClientWait = atoi(argv[++i]) * 1000; rfbMaxClientWait = atoi(argv[++i]) * 1000;
...@@ -29155,6 +29867,7 @@ int main(int argc, char* argv[]) { ...@@ -29155,6 +29867,7 @@ int main(int argc, char* argv[]) {
set_scrollcopyrect_mode(NULL); set_scrollcopyrect_mode(NULL);
} }
initialize_scroll_matches(); initialize_scroll_matches();
initialize_scroll_term();
/* increase rfbwait if threaded */ /* increase rfbwait if threaded */
if (use_threads && ! got_rfbwait) { if (use_threads && ! got_rfbwait) {
...@@ -29338,6 +30051,8 @@ int main(int argc, char* argv[]) { ...@@ -29338,6 +30051,8 @@ int main(int argc, char* argv[]) {
fprintf(stderr, " debug_key: %d\n", debug_keyboard); fprintf(stderr, " debug_key: %d\n", debug_keyboard);
fprintf(stderr, " defer: %d\n", defer_update); fprintf(stderr, " defer: %d\n", defer_update);
fprintf(stderr, " waitms: %d\n", waitms); fprintf(stderr, " waitms: %d\n", waitms);
fprintf(stderr, " wait_ui: %.2f\n", wait_ui);
fprintf(stderr, " nowait_bog: %d\n", !wait_bog);
fprintf(stderr, " readtimeout: %d\n", rfbMaxClientWait/1000); fprintf(stderr, " readtimeout: %d\n", rfbMaxClientWait/1000);
fprintf(stderr, " take_naps: %d\n", take_naps); fprintf(stderr, " take_naps: %d\n", take_naps);
fprintf(stderr, " sb: %d\n", screen_blank); fprintf(stderr, " sb: %d\n", screen_blank);
...@@ -29371,8 +30086,10 @@ int main(int argc, char* argv[]) { ...@@ -29371,8 +30086,10 @@ int main(int argc, char* argv[]) {
rfbLogEnable(0); rfbLogEnable(0);
} }
/* open the X display: */
X_INIT; X_INIT;
SCR_INIT;
/* open the X display: */
if (auth_file) { if (auth_file) {
set_env("XAUTHORITY", auth_file); set_env("XAUTHORITY", auth_file);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment