Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
L
libvncserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
rasky
libvncserver
Commits
d2a0e40e
Commit
d2a0e40e
authored
Jan 24, 2005
by
runge
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sync with new cursor mechanism, -timeout, -noalphablend, try :0 if no other info
parent
6fb3752b
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
2424 additions
and
304 deletions
+2424
-304
ChangeLog
ChangeLog
+4
-0
ChangeLog
x11vnc/ChangeLog
+6
-0
README
x11vnc/README
+203
-171
tkx11vnc
x11vnc/tkx11vnc
+54
-15
tkx11vnc.h
x11vnc/tkx11vnc.h
+54
-15
x11vnc.1
x11vnc/x11vnc.1
+36
-27
x11vnc.c
x11vnc/x11vnc.c
+2067
-76
No files found.
ChangeLog
View file @
d2a0e40e
2005-01-23 Karl Runge <runge@karlrunge.com>
* x11vnc: -timeout, -noalphablend. make -R norepeat work.
* sync with new draw cursor mechanism.
2005-01-20 Karl Runge <runge@karlrunge.com>
* libvncserver/{cursor.c,rfbserver.c}: fixed the "disappearing cursor"
problem
...
...
x11vnc/ChangeLog
View file @
d2a0e40e
2005-01-23 Karl Runge <runge@karlrunge.com>
* sync with new draw cursor mechanism, keep old way in OLD_TREE.
* add -timeout option, change -alphablend to be default
* -R norepeat now forces the issue (Xsession may turn it back on).
* try :0 if no other info.
2005-01-15 Karl Runge <runge@karlrunge.com>
* adjust alpha blending parameters, -alphablend, handle 24bpp.
* add -snapfb snapshot fb, not clear how useful it is..
...
...
x11vnc/README
View file @
d2a0e40e
x11vnc
README
file
Date
:
S
at
Jan
15
23
:
37
:
28
EST
2005
x11vnc
README
file
Date
:
S
un
Jan
23
23
:
48
:
41
EST
2005
The
following
information
is
taken
from
these
URLs
:
...
...
@@ -367,7 +367,7 @@ vncviewer -via $host localhost:0 # must be TightVNC vncviewer.
# Build script for Solaris, etc, with gcc, libjpeg and libz in
# non-standard locations.
PATH=/path/to/gcc/bin:/usr/ccs/bin:$PATH # set to get gcc
PATH=/path/to/gcc/bin:/usr/ccs/bin:$PATH # set to get
your
gcc
JPEG=/path/to/jpeg # maybe "/usr/local", "/usr/sfw", or "/opt/sfw"
ZLIB=/path/to/zlib # maybe "/usr/local", "/usr/sfw", or "/opt/sfw"
...
...
@@ -383,7 +383,9 @@ LDFLAGS="-L $JPEG/lib -R $JPEG/lib -L $ZLIB/lib -R $ZLIB/lib"
CPPFLAGS="$CPPFLAGS -I /usr/openwin/include"
LDFLAGS="$LDFLAGS -L /usr/openwin/lib -R /usr/openwin/lib"
# This only applies to Solaris 10 or later (XFIXES and DAMAGE)
# This only applies to Solaris 10 or later (XFIXES, DAMAGE, and RANDR)
CPPFLAGS="$CPPFLAGS -I /usr/X11/include"
LDFLAGS="$LDFLAGS -L /usr/X11/lib -R /usr/X11/lib"
LDFLAGS="$LDFLAGS -L /usr/openwin/sfw/lib -R /usr/openwin/sfw/lib"
# Everything needs to built with _REENTRANT for thread safe errno:
...
...
@@ -786,42 +788,45 @@ ls -l ./x11vnc/x11vnc
[
94
]
Q
-
51
:
When
typing
I
sometimes
get
double
,
triple
,
or
more
of
my
keystrokes
repeated
.
I
'm sure I only typed them once, what can I do?
[95]Q-52: The machine where I run x11vnc has an AltGr key, but the
[95]Q-52: The x11vnc -norepeat mode is in effect, but I still get
repeated keystrokes!!
[96]Q-53: The machine where I run x11vnc has an AltGr key, but the
local machine where I run the VNC viewer does not. Is there a way I
can map a local unused key to send an AltGr? How about a Compose key
as well?
[9
6]Q-53
: I have a Sun machine I run x11vnc on. Its Sun keyboard has
[9
7]Q-54
: I have a Sun machine I run x11vnc on. Its Sun keyboard has
just one Alt key labelled "Alt" and two Meta keys labelled with little
diamonds. The machine where I run the VNC viewer only has Alt keys.
How can I send a Meta keypress? (e.g. emacs needs this)
[9
7]Q-54
: Can I map a keystroke to a mouse button click on the remote
[9
8]Q-55
: Can I map a keystroke to a mouse button click on the remote
machine?
[Screen Related Issues and Features]
[9
8]Q-55
: The remote display is larger (in number of pixels) than the
[9
9]Q-56
: The remote display is larger (in number of pixels) than the
local display I am running the vncviewer on. I don'
t
like
the
vncviewer
scrollbars
,
what
I
can
do
?
[
99
]
Q
-
56
:
Does
x11vnc
support
server
-
side
framebuffer
scaling
?
(
E
.
g
.
[
100
]
Q
-
57
:
Does
x11vnc
support
server
-
side
framebuffer
scaling
?
(
E
.
g
.
to
make
the
desktop
smaller
).
[
10
0
]
Q
-
57
:
Does
x11vnc
work
with
Xinerama
?
(
i
.
e
.
multiple
monitors
[
10
1
]
Q
-
58
:
Does
x11vnc
work
with
Xinerama
?
(
i
.
e
.
multiple
monitors
joined
together
to
form
one
big
,
single
screen
).
[
10
1
]
Q
-
58
:
Can
I
use
x11vnc
on
a
multi
-
headed
display
that
is
not
[
10
2
]
Q
-
59
:
Can
I
use
x11vnc
on
a
multi
-
headed
display
that
is
not
Xinerama
(
i
.
e
.
separate
screens
:
0.0
,
:
0.1
,
...
for
each
monitor
)?
[
10
2
]
Q
-
59
:
Does
x11vnc
support
the
XRANDR
(
X
Resize
,
Rotate
and
[
10
3
]
Q
-
60
:
Does
x11vnc
support
the
XRANDR
(
X
Resize
,
Rotate
and
Reflection
)
extension
?
Whenever
I
rotate
or
resize
the
screen
x11vnc
just
seems
to
crash
.
[
10
3
]
Q
-
60
:
Why
is
the
view
in
my
VNC
viewer
completely
black
?
Or
why
[
10
4
]
Q
-
61
:
Why
is
the
view
in
my
VNC
viewer
completely
black
?
Or
why
is
everything
flashing
around
randomly
?
[
10
4
]
Q
-
61
:
I
use
Linux
Virtual
Consoles
(
VC
's) to implement '
Fast
User
[
10
5
]
Q
-
62
:
I
use
Linux
Virtual
Consoles
(
VC
's) to implement '
Fast
User
Switching
' between users'
sessions
(
e
.
g
.
Betty
is
on
Ctrl
-
Alt
-
F7
,
Bobby
is
on
Ctrl
-
Alt
-
F8
,
and
Sid
is
on
Ctrl
-
Alt
-
F1
:
they
use
those
keystrokes
to
switch
between
their
sessions
).
How
come
the
view
in
a
...
...
@@ -829,7 +834,7 @@ ls -l ./x11vnc/x11vnc
otherwise
all
messed
up
unless
the
X
session
x11vnc
is
attached
to
is
in
the
active
VC
?
[
10
5
]
Q
-
62
:
I
am
using
x11vnc
where
my
local
machine
has
"popup/hidden
[
10
6
]
Q
-
63
:
I
am
using
x11vnc
where
my
local
machine
has
"popup/hidden
taskbars"
(
e
.
g
.
GNOME
or
MacOS
X
)
and
the
remote
display
where
x11vnc
runs
also
has
"popup/hidden taskbars"
(
e
.
g
.
GNOME
).
When
I
move
the
mouse
to
the
edge
of
the
screen
where
the
popups
happen
,
the
taskbars
...
...
@@ -837,10 +842,10 @@ ls -l ./x11vnc/x11vnc
[
Misc
:
Clipboard
,
Beeps
,
etc
.]
[
10
6
]
Q
-
63
:
Does
the
Clipboard
/
Selection
get
transferred
between
the
[
10
7
]
Q
-
64
:
Does
the
Clipboard
/
Selection
get
transferred
between
the
vncviewer
and
the
X
display
?
[
10
7
]
Q
-
64
:
Why
don
't I hear the "Beeps" in my X session (e.g. when
[
10
8
]
Q
-
65
:
Why
don
't I hear the "Beeps" in my X session (e.g. when
typing tput bel in an xterm)?
_________________________________________________________________
...
...
@@ -941,7 +946,7 @@ ls -l ./x11vnc/x11vnc
is a workaround for Solaris 2.5.1 (and perhaps earlier):
First use the environment settings (CPPFLAGS, LDFLAGS, etc.) in the
above [10
8
]Solaris build script to run the configure command. That
above [10
9
]Solaris build script to run the configure command. That
should succeed without failure. Then, you have to hand edit the
autogenerated rfb/rfbconfig.h file in the source tree, and just before
the last #endif at the bottom of that file insert these workaround
...
...
@@ -978,18 +983,18 @@ typedef unsigned int in_addr_t;
Q-4: Where can I get a precompiled x11vnc binary for my Operating
System?
Hopefully the [1
09]build steps above and [110
]FAQ provide enough info
Hopefully the [1
10]build steps above and [111
]FAQ provide enough info
for a painless compile for most environments. Please report problems
with the x11vnc configure, make, etc. on your system (if your system
is known to compile other GNU packages successfully).
There are precompiled x11vnc binaries made by other groups available
at the following locations:
Debian: (.deb) [11
1
]http://packages.debian.org/x11vnc
Debian: (.deb) [11
2
]http://packages.debian.org/x11vnc
Slackware: (.tgz) [11
2
]http://www.linuxpackages.net/ Redhat/Fedora:
(.rpm) [11
3
]http://dag.wieers.com/packages/x11vnc/ wwexptools: (.tgz)
[11
4
]http://www.bell-labs.com/project/wwexptools/packages.html The
Slackware: (.tgz) [11
3
]http://www.linuxpackages.net/ Redhat/Fedora:
(.rpm) [11
4
]http://dag.wieers.com/packages/x11vnc/ wwexptools: (.tgz)
[11
5
]http://www.bell-labs.com/project/wwexptools/packages.html The
last one, wwexptools, provides a variety of Unix binaries (Linux,
Solaris, HP-UX, IRIX, ...) with the intent of being compatible on a
wide range of OS releases. Find x11vnc near the bottom of that page
...
...
@@ -1001,12 +1006,12 @@ typedef unsigned int in_addr_t;
this by looking at the x11vnc output and if it says the encoding for a
client is "hextile" then likely the fast compression encodings are
missing. If you want optimal performance on your OS, you should see
the [11
5
]build notes above for where to download libz and libjpeg, and
the [11
6
]build notes above for where to download libz and libjpeg, and
then build everything with gcc.
If the above binaries don'
t
work
and
building
x11vnc
on
your
OS
fails
(
and
all
else
fails
!) you can try one of my motley collection of
[
11
6
]
test
binaries
.
Some
may
be
old
,
some
may
have
extra
debugging
[
11
7
]
test
binaries
.
Some
may
be
old
,
some
may
have
extra
debugging
output
,
etc
.
One
may
work
on
your
OS
,
but
please
understand
they
are
test
/
experimental
binaries
not
intended
for
general
usage
like
the
above
precompiled
ones
from
3
rd
parties
.
...
...
@@ -1028,14 +1033,14 @@ typedef unsigned int in_addr_t;
To obtain VNC viewers for the viewing side (Windows, Mac OS, or Unix)
try here:
* [11
7
]http://www.tightvnc.com/download.html
* [11
8
]http://www.realvnc.com/download-free.html
* [1
19
]http://sourceforge.net/projects/cotvnc/
* [11
8
]http://www.tightvnc.com/download.html
* [11
9
]http://www.realvnc.com/download-free.html
* [1
20
]http://sourceforge.net/projects/cotvnc/
Q-6: How can I see all of x11vnc'
s
command
line
options
and
documentation
on
how
to
use
them
?
Run
:
x11vnc
-
help
The
output
is
listed
[
12
0
]
here
as
well
.
Run
:
x11vnc
-
help
The
output
is
listed
[
12
1
]
here
as
well
.
Q
-
7
:
I
don
't like typing arcane command line options every time I
start x11vnc. What can I do? Is there a config file? Or a GUI?
...
...
@@ -1090,7 +1095,7 @@ display :0
As of Apr/2004 the above fix only works for BSD signal systems (Linux,
FreeBSD, ...) For SYSV systems there is a workaround in my
[12
1
]x11vnc.c file. It also has an option -sigpipe exit to have x11vnc
[12
2
]x11vnc.c file. It also has an option -sigpipe exit to have x11vnc
clean up and exit upon receiving SIGPIPE.
[Win2VNC Related]
...
...
@@ -1105,16 +1110,16 @@ display :0
secondary display (X11). Then start up Win2VNC on the primary display
(Windows) referring it to the secondary display.
This will also work X11 to X11 using [12
2
]x2vnc, however you would
This will also work X11 to X11 using [12
3
]x2vnc, however you would
probably just want to avoid VNC and use x2x for that.
For reference, here are some links to Win2VNC-like programs for
multiple monitor setups:
* [12
3
]Original Win2VNC
* [12
4]Enhanced Win2VNC and [125
]sourceforge link
* [12
6
]x2vnc
* [12
7]x2x also [128
]here
* [1
29
]zvnc (MorphOS)
* [12
4
]Original Win2VNC
* [12
5]Enhanced Win2VNC and [126
]sourceforge link
* [12
7
]x2vnc
* [12
8]x2x also [129
]here
* [1
30
]zvnc (MorphOS)
All of them (except x2x) will work with x11vnc.
...
...
@@ -1169,7 +1174,7 @@ display :0
visuals of different color depths: e.g. there are both depth 8 and 24
visuals available at the same time.
You may want to review the [13
0
]previous question regarding 8 bpp
You may want to review the [13
1
]previous question regarding 8 bpp
PseudoColor.
On some hardware (Sun/SPARC, Sgi), the -overlay option discussed a
...
...
@@ -1206,24 +1211,24 @@ TrueColor defdepth 24
"-cc 4" X server command line option to get a depth 24 default visual.
The -overlay mode: Another option is if the system with overlay
visuals is a Sun system running Solaris you can use the -overlay
x11vnc option (Aug/2004) to have x11vnc use the Solaris
XReadScreen(3X11) function to poll the "true view" of the whole screen
at depth 24 TrueColor.This is useful for Legacy applications (older
versions of Cadence CAD apps are mentioned by x11vnc users) that
require the default depth be 8bpp, or will use a 8bpp visual even if
depth 24 visuals are available, and so the default depth workaround
described in the previous paragraph is not sufficient for these apps.
The -overlay mode should also work on IRIX machines using
XReadDisplay(3X11).
visuals is a Sun system running Solaris or Sgi running IRIX you can
use the -overlay x11vnc option (Aug/2004) to have x11vnc use the
Solaris XReadScreen(3X11) function to poll the "true view" of the
whole screen at depth 24 TrueColor. XReadDisplay(3X11) is used on
IRIX. This is useful for Legacy applications (older versions of
Cadence CAD apps are mentioned by x11vnc users) that require the
default depth be 8bpp, or will use a 8bpp visual even if depth 24
visuals are available, and so the default depth workaround described
in the previous paragraph is not sufficient for these apps.
Misc. notes on -overlay mode: An amusing by-product of -overlay mode
is that mouse cursor shape is correct. The -overlay mode may be
somewhat slower than normal mode due to the extra framebuffer
manipulations that must be performed. Also, there is a bug in that for
some popup menus, the windows they overlap will have painting problems
while the popup is up (a workaround is to disable SaveUnders by
passing -su to Xsun, e.g. in your /etc/dt/config/Xservers file).
manipulations that must be performed. Also, on Solaris there is a bug
in that for some popup menus, the windows they overlap will have
painting problems while the popup is up (a workaround is to disable
SaveUnders by passing -su to Xsun, e.g. in your
/etc/dt/config/Xservers file).
Still not working? Run xwininfo on the application with the messed up
colors to verify that the depth of its visual is different from the
...
...
@@ -1246,7 +1251,7 @@ TrueColor defdepth 24
the desired application window. After clicking, it will print out much
information, including the window id. Also, the visual and depth of
the window printed out is often useful in debugging x11vnc
[13
1
]problems.
[13
2
]problems.
When using -id windowid, note that some VNC viewers will have problems
rendering screens that have a width that is not a multiple of 4. Try
...
...
@@ -1352,7 +1357,7 @@ central-server> xauth nextract - xterm123:0 | ssh xterm123 xauth nmerge -
xauth(1) manpage for more details.
If the display name needs to be changed between the two hosts, see
[13
2
]this note on the xauth add ... command.
[13
3
]this note on the xauth add ... command.
A less secure option is to run something like "xhost +127.0.0.1" to
allow cookie-free local access for x11vnc.
...
...
@@ -1361,7 +1366,7 @@ central-server> xauth nextract - xterm123:0 | ssh xterm123 xauth nmerge -
accounts
,
NFS
,
etc
.
you
'll need to contact your system administrator
to set something up.
Not recommended, but as a last resort, you could have x11vnc [13
3
]poll
Not recommended, but as a last resort, you could have x11vnc [13
4
]poll
the Xterminal over the network.
Note: use of Display Manager (gdm, kdm, ...) auth cookie files (i.e.
...
...
@@ -1429,10 +1434,10 @@ central-server> xauth nextract - xterm123:0 | ssh xterm123 xauth nmerge -
-
shared
option
to
have
x11vnc
allow
multiple
clients
to
connect
simultaneously
.
Recommended
additional
safety
measures
include
using
ssh
([
13
4
]
see
Recommended
additional
safety
measures
include
using
ssh
([
13
5
]
see
above
),
stunnel
,
or
a
VPN
to
authenticate
and
encrypt
the
viewer
connections
or
to
at
least
use
the
-
rfbauth
passwd
-
file
[
13
5
]
option
to
use
VNC
password
protection
(
or
[
13
6
]-
passwdfile
)
It
is
up
to
you
to
connections
or
to
at
least
use
the
-
rfbauth
passwd
-
file
[
13
6
]
option
to
use
VNC
password
protection
(
or
[
13
7
]-
passwdfile
)
It
is
up
to
you
to
apply
these
security
measures
,
they
will
not
be
done
for
you
automatically
.
...
...
@@ -1468,7 +1473,7 @@ central-server> xauth nextract - xterm123:0 | ssh xterm123 xauth nmerge -
is
"vnc"
,
e
.
g
.:
vnc
:
192.168.100.3
.
example
.
com
Note
that
if
you
run
x11vnc
out
of
[
13
7
]
inetd
you
do
not
need
to
build
Note
that
if
you
run
x11vnc
out
of
[
13
8
]
inetd
you
do
not
need
to
build
x11vnc
with
libwrap
support
because
the
/
usr
/
sbin
/
tcpd
reference
in
/
etc
/
inetd
.
conf
handles
the
tcp_wrappers
stuff
.
...
...
@@ -1512,7 +1517,7 @@ central-server> xauth nextract - xterm123:0 | ssh xterm123 xauth nmerge -
program to prompt the user whether the client should be accepted or
not. This requires that you have xmessage installed and available via
PATH. In case it is not already on your system, the xmessage program
is available at [13
8
]ftp://ftp.x.org/
is available at [13
9
]ftp://ftp.x.org/
To include view-only decisions for the external commands, prefix the
command something like this: "yes:0,no:*,view:3 mycommand ..." This
...
...
@@ -1551,7 +1556,7 @@ elif [ $rc = 4 ]; then
fi
exit 1
Stefan Radman has written a nice dtksh script [1
39
]dtVncPopup for use
Stefan Radman has written a nice dtksh script [1
40
]dtVncPopup for use
in CDE environments to do the same sort of thing. Information on how
to use it is found at the top of the file. He encourages you to
provide feedback to him to help improve the script.
...
...
@@ -1587,14 +1592,14 @@ exit 1
out
for
the
command
winding
up
in
your
shell
's history file (history
-c is often a way to clear it).
x11vnc also has the [14
0
]-passwdfile and -passwd/-viewpasswd plain
x11vnc also has the [14
1
]-passwdfile and -passwd/-viewpasswd plain
text (i.e. not obscured like the -rfbauth VNC passwords) password
options.
Q-26: How can I tunnel my connection to x11vnc via an encrypted SSH
channel between two Unix machines?
See the description earlier on this page on [14
1
]how to tunnel VNC via
See the description earlier on this page on [14
2
]how to tunnel VNC via
SSH from Unix to Unix. A number of ways are described along with some
issues you may encounter.
...
...
@@ -1604,7 +1609,7 @@ exit 1
Q-27: How can I tunnel my connection to x11vnc via an encrypted SSH
channel from Windows using an SSH client like Putty?
[14
2
]Above we described how to tunnel VNC via SSH from Unix to Unix,
[14
3
]Above we described how to tunnel VNC via SSH from Unix to Unix,
you may want to review it. To do this from Windows using Putty it
would go something like this:
* In the Putty dialog window under '
Session
' enter the hostname or
...
...
@@ -1637,7 +1642,7 @@ exit 1
you'
ll
need
to
do
a
second
login
(
ssh
or
rsh
)
to
the
workstation
machine
'otherhost'
and
then
start
up
x11vnc
on
it
.
As
discussed
[
14
3
]
above
another
option
is
to
first
start
the
VNC
As
discussed
[
14
4
]
above
another
option
is
to
first
start
the
VNC
viewer
in
"listen"
mode
,
and
then
launch
x11vnc
with
the
"-connection
localhost"
option
to
establish
the
reverse
connection
.
In
this
case
a
Remote
port
redirection
(
not
Local
)
is
needed
for
port
5500
instead
of
...
...
@@ -1658,7 +1663,7 @@ exit 1
connection
to
make
it
appear
to
emanate
from
the
local
machine
.
As
discussed
above
,
ssh
is
useful
for
this
:
ssh
-
l
username
-
L
5900
:
localhost
:
5900
hostname
...
See
the
ssh
wrapper
scripts
mentioned
[
14
4
]
elsewhere
on
this
page
.
Of
course
a
malicious
user
could
allow
[
14
5
]
elsewhere
on
this
page
.
Of
course
a
malicious
user
could
allow
other
users
to
get
in
through
his
channel
,
but
that
is
a
problem
with
every
method
.
Another
thing
to
watch
out
for
is
a
malicious
user
on
the
viewer
side
(
where
ssh
is
running
)
trying
to
sneak
in
through
the
...
...
@@ -1734,7 +1739,7 @@ exit 1 # reject it
In
any
event
,
as
of
Jun
/
2004
there
is
an
experimental
utility
to
make
it
more
difficult
for
nosey
people
to
see
your
x11vnc
activities
.
The
source
for
it
is
[
14
5
]
blockdpy
.
c
The
idea
behind
it
is
simple
(
but
source
for
it
is
[
14
6
]
blockdpy
.
c
The
idea
behind
it
is
simple
(
but
obviously
not
bulletproof
):
when
a
VNC
client
attaches
to
x11vnc
put
the
display
monitor
in
the
DPMS
"off"
state
,
if
the
DPMS
state
ever
changes
immediately
start
up
the
screen
-
lock
program
.
The
x11vnc
user
...
...
@@ -1781,11 +1786,11 @@ exit 1 # reject it
permissions
.
Here
are
some
ideas
:
*
Use
the
description
under
"Continuously"
in
the
[
14
6
]
FAQ
on
x11vnc
*
Use
the
description
under
"Continuously"
in
the
[
14
7
]
FAQ
on
x11vnc
and
Display
Managers
*
Use
the
description
in
the
[
14
7
]
FAQ
on
x11vnc
and
inetd
(
1
)
*
Use
the
description
in
the
[
14
8
]
FAQ
on
x11vnc
and
inetd
(
1
)
*
Start
x11vnc
from
$
HOME
/.
xsession
(
or
$
HOME
/.
xinitrc
)
*
Although
less
reliable
,
see
the
[
14
8
]
x11vnc_loop
rc
.
local
hack
*
Although
less
reliable
,
see
the
[
14
9
]
x11vnc_loop
rc
.
local
hack
below
.
The
display
manager
scheme
will
not
be
specific
to
which
user
has
the
...
...
@@ -1887,18 +1892,18 @@ x11vnc -logfile $HOME/.x11vnc.log -rfbauth $HOME/.vnc/passwd -forever -bg
Then restart: /usr/sbin/gdm-restart (or reboot). The
KillInitClients=false setting is important: without it x11vnc will be
killed immediately after the user logs in. Here are [1
49
]full details
killed immediately after the user logs in. Here are [1
50
]full details
on how to configure gdm
If you do not want to deal with the display manager startup scripts,
here is a kludgey script that can be run manually or out of a boot
file like rc.local. [15
0
]x11vnc_loop It will need some local
file like rc.local. [15
1
]x11vnc_loop It will need some local
customization before running. Because the XAUTHORITY auth file must be
guessed by this script, use of the display manager script above is
preferred.
If the machine is a traditional Xterminal you may want to read
[15
1
]this FAQ.
[15
2
]this FAQ.
Q-34: Can I run x11vnc out of inetd(1)? How about xinetd(1)?
...
...
@@ -2041,7 +2046,7 @@ xprop -root -f VNC_CONNECT 8s -set VNC_CONNECT "$1"
19
/
03
/
2004
10
:
10
:
58
error
creating
tile
-
row
shm
for
len
=
4
19
/
03
/
2004
10
:
10
:
58
reverting
to
single_copytile
mode
Here
is
a
shell
script
[
15
2
]
shm_clear
to
list
and
prompt
for
removal
Here
is
a
shell
script
[
15
3
]
shm_clear
to
list
and
prompt
for
removal
of
your
unattached
shm
segments
(
attached
ones
are
skipped
).
I
use
it
while
debugging
x11vnc
(
I
use
"shm_clear -y"
to
assume
"yes"
for
each
prompt
).
If
x11vnc
is
regularly
not
cleaning
up
its
shm
segments
,
...
...
@@ -2079,7 +2084,7 @@ ied)
-
fs
1.0
knocks
it
down
to
2
).
If
you
are
having
much
trouble
with
shm
segments
,
consider
disabling
shm
completely
via
the
-
noshm
option
.
Performance
will
be
somewhat
degraded
but
when
done
over
local
machine
sockets
it
should
be
acceptable
(
see
an
[
15
3
]
earlier
question
sockets
it
should
be
acceptable
(
see
an
[
15
4
]
earlier
question
discussing
-
noshm
).
Q
-
38
:
How
can
I
make
x11vnc
use
less
system
resources
?
...
...
@@ -2127,7 +2132,7 @@ ied)
worth
it
,
but
could
be
of
use
in
some
situations
.
VNC
viewer
parameters
:
*
Use
a
[
15
4
]
TightVNC
enabled
viewer
!
*
Use
a
[
15
5
]
TightVNC
enabled
viewer
!
*
Make
sure
the
tight
encoding
is
being
used
(
look
at
vncviewer
and
x11vnc
outputs
)
*
Request
8
bits
per
pixel
using
-
bgr233
(
up
to
4
X
speedup
over
...
...
@@ -2288,7 +2293,7 @@ ied)
hide
the
alpha
data
),
but
it
also
currently
requires
the
client
and
server
to
be
of
the
same
endianness
(
otherwise
the
hidden
alpha
data
gets
reset
to
zero
by
the
translation
function
).
As
an
example
,
for
the
TightVNC
1.3
dev5
Unix
vncviewer
[
15
5
]
this
patch
enables
the
the
TightVNC
1.3
dev5
Unix
vncviewer
[
15
6
]
this
patch
enables
the
TightVNC
viewer
to
do
the
blending
locally
.
You
have
to
set
the
environment
variable
ALPHABLEND
=
1
before
starting
your
modified
viewer
.
The
patch
code
should
give
an
example
on
how
to
change
the
...
...
@@ -2300,7 +2305,7 @@ ied)
Q
-
45
:
Why
does
the
mouse
arrow
just
stay
in
one
corner
in
my
vncviewer
,
whereas
my
cursor
(
that
does
move
)
is
just
a
dot
?
This
default
takes
advantage
of
a
[
15
6
]
tightvnc
extension
This
default
takes
advantage
of
a
[
15
7
]
tightvnc
extension
(
CursorShapeUpdates
)
that
allows
specifying
a
cursor
image
shape
for
the
local
VNC
viewer
.
You
may
disable
it
with
the
-
nocursor
option
to
x11vnc
if
your
viewer
does
not
have
this
extension
.
...
...
@@ -2385,12 +2390,12 @@ ied)
default
(
use
-
nomodtweak
to
get
the
old
behavior
).
This
was
done
because
it
was
noticed
on
newer
XFree86
setups
even
on
bland
"us"
keyboards
like
"pc104 us"
XFree86
included
a
"ghost"
key
with
both
"<"
and
">"
it
.
This
key
does
not
exist
on
the
keyboard
(
see
[
15
7
]
this
FAQ
and
">"
it
.
This
key
does
not
exist
on
the
keyboard
(
see
[
15
8
]
this
FAQ
for
more
info
).
Without
-
modtweak
there
was
then
an
ambiguity
in
the
reverse
map
keysym
=>
keycode
,
making
it
so
the
"<"
symbol
could
not
be
typed
.
Also
see
the
[
15
8
]
FAQ
about
the
-
xkb
option
for
a
more
powerful
method
Also
see
the
[
15
9
]
FAQ
about
the
-
xkb
option
for
a
more
powerful
method
of
modifier
tweaking
for
use
on
X
servers
with
the
XKEYBOARD
extension
.
...
...
@@ -2451,7 +2456,7 @@ ied)
the keysym comma when it comes in from a client (so when Shift is down
the comma press will yield "<").
See also the [1
59
]FAQ about the -xkb option as a possible workaround
See also the [1
60
]FAQ about the -xkb option as a possible workaround
using the XKEYBOARD extension. Note that of Jul/2004 in the
libvncserver CVS the -modtweak option is now that default.
...
...
@@ -2587,7 +2592,23 @@ ied)
someone is also working at the physical display and misses his
autorepeating.
Q-52: The machine where I run x11vnc has an AltGr key, but the local
Q-52: The x11vnc -norepeat mode is in effect, but I still get repeated
keystrokes!!
Are you using x11vnc to log in to an X session? (as described
[161]this FAQ) If so, x11vnc is starting before your session, and then
your session startup could be resetting the autorepeat to be on. Or it
could be something inside your desktop that decides to turn it back
on. x11vnc in -norepeat mode will not battle with things turning
autorepeat back on. (It will, however, turn it off whenever it goes
from a state of zero clients to one client).
Under these circumstances you will have to manually turn autorepeating
off by typing "xset r off" or "x11vnc -R norepeat" or a desktop
utility. If something in your desktop is automatically turning it back
on you will have to disable that somehow.
Q-53: The machine where I run x11vnc has an AltGr key, but the local
machine where I run the VNC viewer does not. Is there a way I can map
a local unused key to send an AltGr? How about a Compose key as well?
...
...
@@ -2601,7 +2622,7 @@ ied)
Super_R-Mode_switch,Menu-Multi_key" or use "-remap filename" to
specify remappings from a file.
Q-5
3
: I have a Sun machine I run x11vnc on. Its Sun keyboard has just
Q-5
4
: I have a Sun machine I run x11vnc on. Its Sun keyboard has just
one Alt key labelled "Alt" and two Meta keys labelled with little
diamonds. The machine where I run the VNC viewer only has Alt keys.
How can I send a Meta keypress? (e.g. emacs needs this)
...
...
@@ -2618,7 +2639,7 @@ ied)
send Alt_L in this case, maybe -remap Super_L-Meta_L would be a better
choice.
Q-5
4
: Can I map a keystroke to a mouse button click on the remote
Q-5
5
: Can I map a keystroke to a mouse button click on the remote
machine?
This can be done directly in some X servers using AccessX and
...
...
@@ -2642,7 +2663,7 @@ ied)
[Screen Related Issues and Features]
Q-5
5
: The remote display is larger (in number of pixels) than the
Q-5
6
: The remote display is larger (in number of pixels) than the
local display I am running the vncviewer on. I don'
t
like
the
vncviewer
scrollbars
,
what
I
can
do
?
...
...
@@ -2660,10 +2681,10 @@ ied)
There
may
also
be
scaling
viewers
out
there
(
e
.
g
.
TightVNC
on
Windows
)
that
automatically
shrink
or
expand
the
remote
framebuffer
to
fit
the
local
display
.
Especially
for
hand
-
held
devices
.
See
also
[
16
0
]
this
local
display
.
Especially
for
hand
-
held
devices
.
See
also
[
16
2
]
this
FAQ
on
x11vnc
scaling
.
Q
-
5
6
:
Does
x11vnc
support
server
-
side
framebuffer
scaling
?
(
E
.
g
.
to
Q
-
5
7
:
Does
x11vnc
support
server
-
side
framebuffer
scaling
?
(
E
.
g
.
to
make
the
desktop
smaller
).
As
of
Jun
/
2004
in
the
libvncserver
CVS
x11vnc
provides
basic
...
...
@@ -2713,7 +2734,7 @@ ied)
different
scalings
listening
on
separate
ports
(-
rfbport
option
,
etc
.).
Q
-
5
7
:
Does
x11vnc
work
with
Xinerama
?
(
i
.
e
.
multiple
monitors
joined
Q
-
5
8
:
Does
x11vnc
work
with
Xinerama
?
(
i
.
e
.
multiple
monitors
joined
together
to
form
one
big
,
single
screen
).
Yes
,
it
should
generally
work
because
it
simply
polls
the
big
...
...
@@ -2740,7 +2761,7 @@ ied)
function
.
(
This
may
be
due
to
a
bug
in
the
X
server
for
XTEST
when
Xinerama
is
enabled
).
Q
-
5
8
:
Can
I
use
x11vnc
on
a
multi
-
headed
display
that
is
not
Xinerama
Q
-
5
9
:
Can
I
use
x11vnc
on
a
multi
-
headed
display
that
is
not
Xinerama
(
i
.
e
.
separate
screens
:
0.0
,
:
0.1
,
...
for
each
monitor
)?
You
can
,
but
it
is
a
little
bit
awkward
:
you
must
start
separate
...
...
@@ -2758,12 +2779,12 @@ ied)
Note
:
if
you
are
running
on
Solaris
8
or
earlier
you
can
easily
hit
up
against
the
maximum
of
6
shm
segments
per
process
(
for
Xsun
in
this
case
)
from
running
multiple
x11vnc
processes
.
You
should
modify
/
etc
/
system
as
mentioned
in
another
[
16
1
]
FAQ
to
increase
the
limit
.
It
/
etc
/
system
as
mentioned
in
another
[
16
3
]
FAQ
to
increase
the
limit
.
It
is
probably
also
a
good
idea
to
run
with
the
-
onetile
option
in
this
case
(
to
limit
each
x11vnc
to
3
shm
segments
),
or
even
-
noshm
to
use
no
shm
segments
.
Q
-
59
:
Does
x11vnc
support
the
XRANDR
(
X
Resize
,
Rotate
and
Reflection
)
Q
-
60
:
Does
x11vnc
support
the
XRANDR
(
X
Resize
,
Rotate
and
Reflection
)
extension
?
Whenever
I
rotate
or
resize
the
screen
x11vnc
just
seems
to
crash
.
...
...
@@ -2783,12 +2804,12 @@ ied)
specify
"-xrandr exit"
then
all
will
be
disconnected
and
x11vnc
will
terminate
.
Q
-
6
0
:
Why
is
the
view
in
my
VNC
viewer
completely
black
?
Or
why
is
Q
-
6
1
:
Why
is
the
view
in
my
VNC
viewer
completely
black
?
Or
why
is
everything
flashing
around
randomly
?
See
the
next
FAQ
for
a
possible
explanation
.
Q
-
6
1
:
I
use
Linux
Virtual
Consoles
(
VC
's) to implement '
Fast
User
Q
-
6
2
:
I
use
Linux
Virtual
Consoles
(
VC
's) to implement '
Fast
User
Switching
' between users'
sessions
(
e
.
g
.
Betty
is
on
Ctrl
-
Alt
-
F7
,
Bobby
is
on
Ctrl
-
Alt
-
F8
,
and
Sid
is
on
Ctrl
-
Alt
-
F1
:
they
use
those
keystrokes
to
switch
between
their
sessions
).
How
come
the
view
in
a
...
...
@@ -2815,7 +2836,7 @@ ied)
x11vnc can poll it), one can use the switchto(1) command, e.g.
"switchto 7" for VC #7.
Q-6
2
: I am using x11vnc where my local machine has "popup/hidden
Q-6
3
: I am using x11vnc where my local machine has "popup/hidden
taskbars" (e.g. GNOME or MacOS X) and the remote display where x11vnc
runs also has "popup/hidden taskbars" (e.g. GNOME). When I move the
mouse to the edge of the screen where the popups happen, the taskbars
...
...
@@ -2829,7 +2850,7 @@ ied)
[Misc: Clipboard, Beeps, etc.]
Q-6
3
: Does the Clipboard/Selection get transferred between the
Q-6
4
: Does the Clipboard/Selection get transferred between the
vncviewer and the X display?
As of Jan/2004 in the libvncserver CVS x11vnc supports the "CutText"
...
...
@@ -2839,7 +2860,11 @@ ied)
want the PRIMARY selection to be polled for changes use the -noprimary
option.
Q-64: Why don'
t
I
hear
the
"Beeps"
in
my
X
session
(
e
.
g
.
when
typing
You may need to watch out for desktop utilities such as KDE'
s
"Klipper"
that
do
odd
things
with
the
selection
,
clipboard
,
and
cutbuffers
.
Q
-
65
:
Why
don
't I hear the "Beeps" in my X session (e.g. when typing
tput bel in an xterm)?
As of Dec/2003 in the libvncserver CVS "Beep" XBell events are tracked
...
...
@@ -2960,60 +2985,62 @@ References
105. http://www.karlrunge.com/x11vnc/index.html#FAQ-62
106. http://www.karlrunge.com/x11vnc/index.html#FAQ-63
107. http://www.karlrunge.com/x11vnc/index.html#FAQ-64
108.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
solarisbuilding
109.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
building
110.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
build
faq
111.
http
://
packages
.
debian
.
org
/
x11vnc
112.
http
://
www
.
linuxpackages
.
net
/
search_view
.
php
?
by
=
name
&
name
=
x11vnc
113.
http
://
dag
.
wieers
.
com
/
packages
/
x11vnc
/
114.
http
://
www
.
bell
-
labs
.
com
/
project
/
wwexptools
/
packages
.
html
115.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
solarisbuilding
116.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
bins
117.
http
://
www
.
tightvnc
.
com
/
download
.
html
118.
http
://
www
.
realvnc
.
com
/
download
-
free
.
html
119.
http
://
sourceforge
.
net
/
projects
/
cotvnc
/
120.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
x11vnc_opts
.
html
121.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
x11vnc
.
c
122.
http
://
fredrik
.
hubbe
.
net
/
x2vnc
.
html
123.
http
://
www
.
hubbe
.
net
/~
hubbe
/
win
2vnc
.
html
124.
http
://
www
.
deboer
.
gmxhome
.
de
/
125.
http
://
sourceforge
.
net
/
projects
/
win2vnc
/
126.
http
://
fredrik
.
hubbe
.
net
/
x2vnc
.
html
127.
http
://
fre
shmeat
.
net
/
projects
/
x2x
/
128.
http
://
f
tp
.
digital
.
com
/
pub
/
Digital
/
SRC
/
x2x
/
129.
http
://
zapek
.
com
/
software
/
zvnc
/
130.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
8
bpp
131.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
overlays
132.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
xauth_pain
133.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
noshm
134.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
tunnelling
135.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
passwd
136.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
passwd
file
137.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
inetd
138.
ftp
://
ftp
.
x
.
org
/
139.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
dtVncPopup
140.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
passwdfile
141.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
tunnelling
108. http://www.karlrunge.com/x11vnc/index.html#
FAQ-65
109. http://www.karlrunge.com/x11vnc/index.html#
solaris
building
110. http://www.karlrunge.com/x11vnc/index.html#build
ing
111. http://
www.karlrunge.com/x11vnc/index.html#buildfaq
112. http://
packages.debian.org/
x11vnc
113. http://
www.linuxpackages.net/search_view.php?by=name&name=x11vnc
114. http://
dag.wieers.com/packages/x11vnc/
115. http://www.
bell-labs.com/project/wwexptools/packages.html
116. http://www.karlrunge.com/x11vnc/
index.html#solarisbuilding
117. http://www.
karlrunge.com/x11vnc/bins
118. http://www.
tightvnc.com/download
.html
119. http://
www.realvnc.com/download-free.html
120. http://
sourceforge.net/projects/cotvnc/
121. http://www.karlrunge.com/x11vnc/x11vnc
_opts.html
122. http://
www.karlrunge.com/x11vnc/x11vnc.c
123. http://
fredrik.hubbe.net/x
2vnc.html
124. http://www.
hubbe.net/~hubbe/win2vnc.html
125. http://
www.deboer.gmxhome.de
/
126. http://
sourceforge.net/projects/win2vnc/
127. http://fre
drik.hubbe.net/x2vnc.html
128. http://f
reshmeat.net/projects
/x2x/
129. http://
ftp.digital.com/pub/Digital/SRC/x2x
/
130. http://
zapek.com/software/zvnc/
131. http://www.karlrunge.com/x11vnc/index.html#
8bpp
132. http://www.karlrunge.com/x11vnc/index.html#
overlays
133. http://www.karlrunge.com/x11vnc/index.html#
xauth_pain
134. http://www.karlrunge.com/x11vnc/index.html#
noshm
135. http://www.karlrunge.com/x11vnc/index.html#
tunnelling
136. http://www.karlrunge.com/x11vnc/index.html#passwd
137. http://www.karlrunge.com/x11vnc/index.html#
passwdfile
138.
http://www.karlrunge.com/x11vnc/index.html#inetd
139.
ftp://ftp.x.org/
140. http://www.karlrunge.com/x11vnc/
dtVncPopup
141. http://www.karlrunge.com/x11vnc/index.html#
passwdfile
142. http://www.karlrunge.com/x11vnc/index.html#tunnelling
143. http://www.karlrunge.com/x11vnc/index.html#tunnelling
144. http://www.karlrunge.com/x11vnc/index.html#tunnelling
145.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
blockdpy
.
c
146.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
display_manager
147.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
inetd
148.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
x11vnc_loop
149.
http
://
www
.
jirka
.
org
/
gdm
-
documentation
/
x241
.
html
150.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
x11vnc_loop
151.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
xterminal_xauth
152.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
shm_clear
153.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
noshm
154.
http
://
www
.
tightvnc
.
com
/
155.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
tight
-
vncviewer
-
alphahack
.
patch
156.
http
://
www
.
tightvnc
.
com
/
157.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
greaterless
158.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
xkbmodtweak
145. http://www.karlrunge.com/x11vnc/
index.html#tunnelling
146. http://www.karlrunge.com/x11vnc/
blockdpy.c
147. http://www.karlrunge.com/x11vnc/index.html#
display_manager
148. http://www.karlrunge.com/x11vnc/index.html#
inetd
149. http://www.
karlrunge.com/x11vnc/index.html#x11vnc_loop
150. http://www.
jirka.org/gdm-documentation/x241.html
151. http://www.karlrunge.com/x11vnc/
x11vnc_loop
152. http://www.karlrunge.com/x11vnc/
index.html#xterminal_xauth
153. http://www.karlrunge.com/x11vnc/
shm_clear
154. http://www.
karlrunge.com/x11vnc/index.html#noshm
155. http://www.
tightvnc.com/
156. http://www.
karlrunge.com/x11vnc/tight-vncviewer-alphahack.patch
157. http://www.
tightvnc.com/
158. http://www.karlrunge.com/x11vnc/index.html#
greaterless
159. http://www.karlrunge.com/x11vnc/index.html#xkbmodtweak
160.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
scaling
161.
http
://
www
.
karlrunge
.
com
/
x11vnc
/
index
.
html
#
solshm
160. http://www.karlrunge.com/x11vnc/index.html#xkbmodtweak
161. http://www.karlrunge.com/x11vnc/index.html#display_manager
162. http://www.karlrunge.com/x11vnc/index.html#scaling
163. http://www.karlrunge.com/x11vnc/index.html#solshm
=======================================================================
...
...
@@ -3026,8 +3053,8 @@ x11vnc: a VNC server for real X displays
Here are all of x11vnc command line options:
% x11vnc -help
x11vnc
:
allow
VNC
connections
to
real
X11
displays
.
0.7.1
pre
lastmod
:
2005
-
01
-
1
6
x11vnc: allow VNC connections to real X11 displays. 0.7.1pre lastmod: 2005-01-
2
3
Typical usage is:
...
...
@@ -3161,6 +3188,8 @@ Options:
disconnects, opposite of -forever. This is the Default.
-forever Keep listening for more connections rather than exiting
as soon as the first client(s) disconnect. Same as -many
-timeout n Exit unless a client connects within the first n seconds
of startup.
-inetd Launched by inetd(1): stdio instead of listening socket.
Note: if you are not redirecting stderr to a log file
(via shell 2> or -o option) you must also specify the
...
...
@@ -3427,9 +3456,9 @@ Options:
with
-
nocursor
,
and
also
some
values
of
the
"mode"
option
below
.
Note that under XFIXES cursors with transparency
(alpha channel) will not be exactly represented and
so Overlay may be preferred
. See also the -alphacut
Note
that
under
XFIXES
cursors
with
transparency
(
alpha
channel
)
will
not
be
exactly
represented
and
one
may
find
Overlay
may
be
preferable
.
See
also
the
-
alphacut
and
-
alphafrac
options
below
as
fudge
factors
to
try
to
improve
the
situation
for
cursors
with
transparency
for
a
given
theme
.
...
...
@@ -3488,14 +3517,14 @@ Options:
black
background
).
Specify
this
option
to
remove
the
alpha
factor
.
(
useful
for
light
colored
semi
-
transparent
cursors
).
-
alphablend In XFIXES mode send cursor alpha channel data to
libvncserver. The blending effect will only b
e
visible in -nocursorshape mode or for clients with
cursorshapeupdates turned off. (However there is a
hack for 32bpp with depth 24, it uses the extra 8 bits
to store cursor transparency for use with a hacked
vncviewer that applies the transparency locally.
See the FAQ for more info).
-
noalphablend
In
XFIXES
mode
do
not
send
cursor
alpha
channel
data
to
libvncserver
.
The
default
is
to
send
it
.
Th
e
alphablend
effect
will
only
be
visible
in
-
nocursorshape
mode
or
for
clients
with
cursorshapeupdates
turned
off
.
(
However
there
is
a
hack
for
32
bpp
with
depth
24
,
it
uses
the
extra
8
bits
to
store
cursor
transparency
for
use
with
a
hacked
vncviewer
that
applies
the
transparency
locally
.
See
the
FAQ
for
more
info
).
-
nocursorshape
Do
not
use
the
TightVNC
CursorShapeUpdates
extension
even
if
clients
support
it
.
See
-
cursor
above
.
...
...
@@ -3759,6 +3788,9 @@ Options:
noshared
disable
-
shared
mode
.
forever
enable
-
forever
mode
.
noforever
disable
-
forever
mode
.
timeout
:
n
reset
-
timeout
to
n
,
if
there
are
currently
no
clients
,
exit
unless
one
connects
in
the
next
n
secs
.
deny
deny
any
new
connections
,
same
as
"lock"
nodeny
allow
new
connections
,
same
as
"unlock"
connect
:
host
do
reverse
connection
to
host
,
"host"
...
...
@@ -3842,8 +3874,8 @@ Options:
alphafrac
:
f
set
-
alphafrac
to
f
.
alpharemove
enable
-
alpharemove
mode
.
noalpharemove
disable
-
alpharemove
mode
.
alphablend
enable -
alphablend mode.
noalphablend
disable -
alphablend mode.
alphablend
disable
-
no
alphablend
mode
.
noalphablend
enable
-
no
alphablend
mode
.
cursorshape
disable
-
nocursorshape
mode
.
nocursorshape
enable
-
nocursorshape
mode
.
cursorpos
disable
-
nocursorpos
mode
.
...
...
@@ -3936,8 +3968,8 @@ Options:
nowaitmapped flashcmap noflashcmap truecolor notruecolor
overlay nooverlay overlay_cursor overlay_yescursor
nooverlay_nocursor nooverlay_cursor nooverlay_yescursor
overlay_nocursor visual scale viewonly noviewonly
shared noshared forever noforever once
deny lock nodeny
overlay_nocursor visual scale viewonly noviewonly
shared
noshared forever noforever once timeout
deny lock nodeny
unlock connect allowonce allow localhost nolocalhost
accept gone shm noshm flipbyteorder noflipbyteorder
onetile noonetile blackout xinerama noxinerama xrandr
...
...
@@ -3959,16 +3991,16 @@ Options:
noalwaysshared nevershared noalwaysshared dontdisconnect
nodontdisconnect desktop noremote
aro= display vncdisplay desktopname
auth rootshift
scale_str scaled_x scaled_y scale_numer scale_denom
scale_
fac scaling_noblend scaling_nomult4 scaling_pad
scaling_
interpolate inetd safer unsafe passwdfil
e
using_shm logfile o rc norc h help V version lastmod
bg sigpipe threads clients client_count pid ext_xtest
ext_x
kb ext_xshm ext_xinerama ext_overlay ext_xfixes
ext_x
damage ext_xrandr rootwin num_buttons button_mask
mouse_x mouse_y bpp depth indexed_color dpy_x dpy_y
rfbauth passwd
aro= display vncdisplay desktopname
http_url auth
rootshift scale_str scaled_x scaled_y scale_numer
scale_
denom scale_fac scaling_noblend scaling_nomult4
scaling_
pad scaling_interpolate inetd safer unsaf
e
passwdfile using_shm logfile o rc norc h help V version
lastmod bg sigpipe threads clients client_count pid
ext_x
test ext_xkb ext_xshm ext_xinerama ext_overlay
ext_x
fixes ext_xdamage ext_xrandr rootwin num_buttons
button_mask mouse_x mouse_y bpp depth indexed_color
dpy_x dpy_y
rfbauth passwd
-sync By default -remote commands are run asynchronously, that
is, the request is posted and the program immediately
...
...
x11vnc/tkx11vnc
View file @
d2a0e40e
...
...
@@ -139,7 +139,7 @@ Keyboard
Pointer
=-C:none,arrow,X,some,most cursor:
noxfixes
alphablend
no
alphablend
--
cursorpos
nocursorshape
...
...
@@ -186,11 +186,12 @@ Permissions
localhost
=RA allowonce:
--
=RA noremote
--
viewonly
shared
forever
--
=RA noremote
timeout:
--
=SA alwaysshared
=SA nevershared
...
...
@@ -359,35 +360,39 @@ There is much overlap between the menu items available in state 1)
and state 2), but it is worth keeping in mind it is not 100%.
For example, you cannot set passwords or password files in state 1).
Also note that there may be *two* separate X displays involved, not just
one: 1) the X display x11vnc will be polling (and making available to
VNC viewers), and 2) the X display this GUI is intended to display on.
For example, one might use ssh to access the remote machine where the
GUI would display on :11 and x11vnc would poll display :0.
GUI would display on :11 and x11vnc would poll display :0. By default
the gui will display on the value in the DISPLAY env. variable followed
by the value from the -display option. To override this, use something
like:
\"
-gui otherhost:0
\"
, etc.
GUI components:
--- ----------
At the top of the gui is a info text label where information will
1)
At the top of the gui is a info text label where information will
be posted, e.g. when traversing menu items text indicating how to get
help on the item and its current value will be displayed.
Below the info label is the area where the menu buttons, Actions,
2)
Below the info label is the area where the menu buttons, Actions,
Clients, etc., are presented. If a menu item has a checkbox,
it corresponds to a boolean on/off variable. Otherwise it is
either a string variable, or an action not associated with a
variable (for the most part).
Below the menu button area is a text label indicating the current x11vnc
3)
Below the menu button area is a text label indicating the current x11vnc
X display being polled and the corresponding VNC display name. Both
will be
\"
(*none*)
\"
when there is no connection established.
Below the x11 and vnc displays text label is a text area there scrolling
4)
Below the x11 and vnc displays text label is a text area there scrolling
information about actions being taken and commands being run is displayed.
To scroll use PageUp/PageDown or the arrow keys.
At the bottom is an entry area. When one selects a menu item that
5)
At the bottom is an entry area. When one selects a menu item that
requires supplying a string value, the label will be set to the
parameter name and one types in the new value. Then one presses the
\"
OK
\"
button or presses
\"
Enter
\"
to set the value. Or you can press
...
...
@@ -396,11 +401,13 @@ are boolean toggles (for example, \"Permissions -> viewonly\") or Radio
button selections. Selecting these menu items will not activate the
entry area but rather toggle the variable directly.
Cascades: There is a bug not yet worked around for the cascade menus
Cascades Bug: There is a bug not yet worked around for the cascade menus
where the (?) help button gets in the way. To get the mouse over to
the cascade menu click and release mouse to activate the cascade, then
you can click on its items. Dragging with a mouse button held down
will not work (sorry).
you can click on its items. Dragging with a mouse button held down will
not work (sorry!).
Key Bindings:
...
...
@@ -410,6 +417,7 @@ Key Bindings:
Anywhere: Control-p invokes
\"
Actions -> ping
\"
Anywhere: Control-u and Control-r invoke
\"
Actions -> update-all
\"
Misc:
Since x11vnc has so many settings and to avoid further confusion,
...
...
@@ -547,7 +555,9 @@ proc help_win {item} {
set
text
"Help on
$item
:
\n\n
"
if
{[
is_gui_internal
$item
]}
{
;
if
{
$item
!=
"gui"
&&
$item
!=
"all"
}
{
append text
" + Is a gui internal Action (cannot be set).
\n
"
;
}
}
elseif
{[
is_action
$item
]}
{
append text
" + Is a remote control Action (cannot be set).
\n
"
;
}
elseif
{[
active_when_connected
$item
]}
{
...
...
@@ -595,6 +605,10 @@ proc help_win {item} {
}
else
{
append text
"
$menu_var
(
$item
)
\n
"
}
if
{
$item
==
"http"
||
$item
==
"httpdir"
||
$item
==
"httpport"
}
{
global vnc_url
;
append text
"
\n
URL:
$vnc_url
\n
"
}
}
if
{
$item
==
"start"
}
{
...
...
@@ -1221,6 +1235,8 @@ proc update_menu_vars {{query ""}} {
set_x11_display
$val
}
elseif
{
$item
==
"vncdisplay"
}
{
set_vnc_display
$val
}
elseif
{
$item
==
"http_url"
}
{
set_vnc_url
$val
}
}
}
...
...
@@ -1353,7 +1369,7 @@ proc show_logfile {} {
}
proc tail_logfile
{}
{
global menu_var unset_str
global menu_var unset_str
ffont
set
logfile
$menu_var
(
logfile
)
set
txt
""
...
...
@@ -1363,7 +1379,7 @@ proc tail_logfile {} {
set
txt
"
\n
Logfile
\"
$logfile
\"
does not exist.
\n\n
"
}
else
{
set
cmd
""
set
xterm_cmd
"xterm -geometry 80x45 -title x11vnc-logfile -e"
set
xterm_cmd
"xterm -
sb -fn
$ffont
-
geometry 80x45 -title x11vnc-logfile -e"
set
cmd
[
split
$xterm_cmd
]
lappend cmd
"tail"
lappend cmd
"+1f"
...
...
@@ -1526,6 +1542,11 @@ proc do_var {item} {
}
else
{
push_new_value
$item
$name
$new
1
}
if
{
$item
==
"http"
}
{
global vnc_url
append_text
" URL:
$vnc_url
\n
"
}
}
}
...
...
@@ -1637,12 +1658,19 @@ proc set_vnc_display {name} {
global vnc_display
set
vnc_display
"VNC display:
$name
"
}
proc set_vnc_url
{
name
}
{
global vnc_url
set
vnc_url
$name
}
proc no_x11_display
{}
{
set_x11_display
"(*none*)"
}
proc no_vnc_display
{}
{
set_vnc_display
"(*none*)"
}
proc no_vnc_url
{}
{
set_vnc_url
"(*none*)"
}
proc fetch_displays
{}
{
...
...
@@ -1651,6 +1679,7 @@ proc fetch_displays {} {
set
got_x11 0
set
got_vnc 0
set
got_url 0
foreach item
[
split_query
$result
]
{
if
{[
regexp
{
^display:
(
.
*
)
$}
$item
m0 m1]
}
{
...
...
@@ -1659,6 +1688,9 @@ proc fetch_displays {} {
}
elseif
{[
regexp
{
^vncdisplay:
(
.
*
)
$}
$item
m0 m1]
}
{
set_vnc_display
$m1
set
got_vnc 1
}
elseif
{[
regexp
{
^http_url:
(
.
*
)
$}
$item
m0 m1]
}
{
set_vnc_url
$m1
set
got_url 1
}
}
if
{!
$got_x11
}
{
...
...
@@ -1667,6 +1699,9 @@ proc fetch_displays {} {
if
{!
$got_vnc
}
{
no_vnc_display
}
if
{!
$got_url
}
{
no_vnc_url
}
}
proc disconnect_dialog
{
client
}
{
...
...
@@ -2130,6 +2165,10 @@ MenuSelect>>
}
} elseif {[info exists menu_var(
$which
)]} {
set label "
$label
value:
$menu_var
(
$which
)"
if {
$which
== "http"} {
global vnc_url
set label "
$label
URL:
$vnc_url
"
}
}
}
set_info
$label
...
...
x11vnc/tkx11vnc.h
View file @
d2a0e40e
...
...
@@ -145,7 +145,7 @@
"Pointer
\n
"
" =-C:none,arrow,X,some,most cursor:
\n
"
" noxfixes
\n
"
" alphablend
\n
"
"
no
alphablend
\n
"
" --
\n
"
" cursorpos
\n
"
" nocursorshape
\n
"
...
...
@@ -192,11 +192,12 @@
" localhost
\n
"
" =RA allowonce:
\n
"
" --
\n
"
" =RA noremote
\n
"
" --
\n
"
" viewonly
\n
"
" shared
\n
"
" forever
\n
"
" --
\n
"
" =RA noremote
\n
"
" timeout:
\n
"
" --
\n
"
" =SA alwaysshared
\n
"
" =SA nevershared
\n
"
...
...
@@ -365,35 +366,39 @@
"and state 2), but it is worth keeping in mind it is not 100%.
\n
"
"For example, you cannot set passwords or password files in state 1).
\n
"
"
\n
"
"
\n
"
"Also note that there may be *two* separate X displays involved, not just
\n
"
"one: 1) the X display x11vnc will be polling (and making available to
\n
"
"VNC viewers), and 2) the X display this GUI is intended to display on.
\n
"
"For example, one might use ssh to access the remote machine where the
\n
"
"GUI would display on :11 and x11vnc would poll display :0.
\n
"
"GUI would display on :11 and x11vnc would poll display :0. By default
\n
"
"the gui will display on the value in the DISPLAY env. variable followed
\n
"
"by the value from the -display option. To override this, use something
\n
"
"like:
\\\"
-gui otherhost:0
\\\"
, etc.
\n
"
"
\n
"
"
\n
"
"GUI components:
\n
"
"--- ----------
\n
"
"
\n
"
"At the top of the gui is a info text label where information will
\n
"
"
1)
At the top of the gui is a info text label where information will
\n
"
"be posted, e.g. when traversing menu items text indicating how to get
\n
"
"help on the item and its current value will be displayed.
\n
"
"
\n
"
"Below the info label is the area where the menu buttons, Actions,
\n
"
"
2)
Below the info label is the area where the menu buttons, Actions,
\n
"
"Clients, etc., are presented. If a menu item has a checkbox,
\n
"
"it corresponds to a boolean on/off variable. Otherwise it is
\n
"
"either a string variable, or an action not associated with a
\n
"
"variable (for the most part).
\n
"
"
\n
"
"Below the menu button area is a text label indicating the current x11vnc
\n
"
"
3)
Below the menu button area is a text label indicating the current x11vnc
\n
"
"X display being polled and the corresponding VNC display name. Both
\n
"
"will be
\\\"
(*none*)
\\\"
when there is no connection established.
\n
"
"
\n
"
"Below the x11 and vnc displays text label is a text area there scrolling
\n
"
"
4)
Below the x11 and vnc displays text label is a text area there scrolling
\n
"
"information about actions being taken and commands being run is displayed.
\n
"
"To scroll use PageUp/PageDown or the arrow keys.
\n
"
"
\n
"
"At the bottom is an entry area. When one selects a menu item that
\n
"
"
5)
At the bottom is an entry area. When one selects a menu item that
\n
"
"requires supplying a string value, the label will be set to the
\n
"
"parameter name and one types in the new value. Then one presses the
\n
"
"
\\\"
OK
\\\"
button or presses
\\\"
Enter
\\\"
to set the value. Or you can press
\n
"
...
...
@@ -402,11 +407,13 @@
"button selections. Selecting these menu items will not activate the
\n
"
"entry area but rather toggle the variable directly.
\n
"
"
\n
"
"Cascades: There is a bug not yet worked around for the cascade menus
\n
"
"
\n
"
"Cascades Bug: There is a bug not yet worked around for the cascade menus
\n
"
"where the (?) help button gets in the way. To get the mouse over to
\n
"
"the cascade menu click and release mouse to activate the cascade, then
\n
"
"you can click on its items. Dragging with a mouse button held down
\n
"
"will not work (sorry).
\n
"
"you can click on its items. Dragging with a mouse button held down will
\n
"
"not work (sorry!).
\n
"
"
\n
"
"
\n
"
"Key Bindings:
\n
"
"
\n
"
...
...
@@ -416,6 +423,7 @@
" Anywhere: Control-p invokes
\\\"
Actions -> ping
\\\"\n
"
" Anywhere: Control-u and Control-r invoke
\\\"
Actions -> update-all
\\\"\n
"
"
\n
"
"
\n
"
"Misc:
\n
"
"
\n
"
"Since x11vnc has so many settings and to avoid further confusion,
\n
"
...
...
@@ -553,7 +561,9 @@
" set text
\"
Help on $item:
\\
n
\\
n
\"\n
"
"
\n
"
" if {[is_gui_internal $item]} {
\n
"
" ;
\n
"
" if {$item !=
\"
gui
\"
&& $item !=
\"
all
\"
} {
\n
"
" append text
\"
+ Is a gui internal Action (cannot be set).
\\
n
\"
;
\n
"
" }
\n
"
" } elseif {[is_action $item]} {
\n
"
" append text
\"
+ Is a remote control Action (cannot be set).
\\
n
\"
;
\n
"
" } elseif {[active_when_connected $item]} {
\n
"
...
...
@@ -601,6 +611,10 @@
" } else {
\n
"
" append text
\"
$menu_var($item)
\\
n
\"\n
"
" }
\n
"
" if {$item ==
\"
http
\"
|| $item ==
\"
httpdir
\"
|| $item ==
\"
httpport
\"
} {
\n
"
" global vnc_url;
\n
"
" append text
\"\\
nURL: $vnc_url
\\
n
\"\n
"
" }
\n
"
" }
\n
"
"
\n
"
" if {$item ==
\"
start
\"
} {
\n
"
...
...
@@ -1227,6 +1241,8 @@
" set_x11_display $val
\n
"
" } elseif {$item ==
\"
vncdisplay
\"
} {
\n
"
" set_vnc_display $val
\n
"
" } elseif {$item ==
\"
http_url
\"
} {
\n
"
" set_vnc_url $val
\n
"
" }
\n
"
" }
\n
"
" }
\n
"
...
...
@@ -1359,7 +1375,7 @@
"}
\n
"
"
\n
"
"proc tail_logfile {} {
\n
"
" global menu_var unset_str
\n
"
" global menu_var unset_str
ffont
\n
"
" set logfile $menu_var(logfile)
\n
"
"
\n
"
" set txt
\"\"\n
"
...
...
@@ -1369,7 +1385,7 @@
" set txt
\"\\
nLogfile
\\\"
$logfile
\\\"
does not exist.
\\
n
\\
n
\"\n
"
" } else {
\n
"
" set cmd
\"\"\n
"
" set xterm_cmd
\"
xterm -geometry 80x45 -title x11vnc-logfile -e
\"\n
"
" set xterm_cmd
\"
xterm -
sb -fn $ffont -
geometry 80x45 -title x11vnc-logfile -e
\"\n
"
" set cmd [split $xterm_cmd]
\n
"
" lappend cmd
\"
tail
\"\n
"
" lappend cmd
\"
+1f
\"\n
"
...
...
@@ -1532,6 +1548,11 @@
" } else {
\n
"
" push_new_value $item $name $new 1
\n
"
" }
\n
"
"
\n
"
" if {$item ==
\"
http
\"
} {
\n
"
" global vnc_url
\n
"
" append_text
\"
URL: $vnc_url
\\
n
\"\n
"
" }
\n
"
" }
\n
"
"}
\n
"
"
\n
"
...
...
@@ -1643,12 +1664,19 @@
" global vnc_display
\n
"
" set vnc_display
\"
VNC display: $name
\"\n
"
"}
\n
"
"proc set_vnc_url {name} {
\n
"
" global vnc_url
\n
"
" set vnc_url $name
\n
"
"}
\n
"
"proc no_x11_display {} {
\n
"
" set_x11_display
\"
(*none*)
\"\n
"
"}
\n
"
"proc no_vnc_display {} {
\n
"
" set_vnc_display
\"
(*none*)
\"\n
"
"}
\n
"
"proc no_vnc_url {} {
\n
"
" set_vnc_url
\"
(*none*)
\"\n
"
"}
\n
"
"
\n
"
"proc fetch_displays {} {
\n
"
"
\n
"
...
...
@@ -1657,6 +1685,7 @@
"
\n
"
" set got_x11 0
\n
"
" set got_vnc 0
\n
"
" set got_url 0
\n
"
"
\n
"
" foreach item [split_query $result] {
\n
"
" if {[regexp {^display:(.*)$} $item m0 m1]} {
\n
"
...
...
@@ -1665,6 +1694,9 @@
" } elseif {[regexp {^vncdisplay:(.*)$} $item m0 m1]} {
\n
"
" set_vnc_display $m1
\n
"
" set got_vnc 1
\n
"
" } elseif {[regexp {^http_url:(.*)$} $item m0 m1]} {
\n
"
" set_vnc_url $m1
\n
"
" set got_url 1
\n
"
" }
\n
"
" }
\n
"
" if {! $got_x11} {
\n
"
...
...
@@ -1673,6 +1705,9 @@
" if {! $got_vnc} {
\n
"
" no_vnc_display
\n
"
" }
\n
"
" if {! $got_url} {
\n
"
" no_vnc_url
\n
"
" }
\n
"
"}
\n
"
"
\n
"
"proc disconnect_dialog {client} {
\n
"
...
...
@@ -2136,6 +2171,10 @@
" }
\n
"
" } elseif {[info exists menu_var($which)]} {
\n
"
" set label
\"
$label value: $menu_var($which)
\"\n
"
" if {$which ==
\"
http
\"
} {
\n
"
" global vnc_url
\n
"
" set label
\"
$label URL: $vnc_url
\"\n
"
" }
\n
"
" }
\n
"
" }
\n
"
" set_info $label
\n
"
...
...
x11vnc/x11vnc.1
View file @
d2a0e40e
...
...
@@ -2,7 +2,7 @@
.TH X11VNC "1" "January 2005" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.7.1pre, lastmod: 2005-01-
16
version: 0.7.1pre, lastmod: 2005-01-
23
.SH SYNOPSIS
.B x11vnc
[OPTION]...
...
...
@@ -191,6 +191,11 @@ disconnects, opposite of \fB-forever.\fR This is the Default.
Keep listening for more connections rather than exiting
as soon as the first client(s) disconnect. Same as \fB-many\fR
.PP
\fB-timeout\fR \fIn\fR
.IP
Exit unless a client connects within the first n seconds
of startup.
.PP
\fB-inetd\fR
.IP
Launched by
...
...
@@ -574,9 +579,9 @@ default (see \fB-noxfixes\fR below). This can be disabled
with \fB-nocursor,\fR and also some values of the "mode"
option below.
.IP
Note that under XFIXES cursors with transparency
(alpha channel) will not be exactly represented and
so Overlay may be preferred
. See also the \fB-alphacut\fR
Note that under XFIXES cursors with transparency
(alpha
channel) will not be exactly represented and one may
find Overlay may be preferable
. See also the \fB-alphacut\fR
and \fB-alphafrac\fR options below as fudge factors to try
to improve the situation for cursors with transparency
for a given theme.
...
...
@@ -647,16 +652,16 @@ black background). Specify this option to remove the
alpha factor. (useful for light colored semi-transparent
cursors).
.PP
\fB-alphablend\fR
\fB-
no
alphablend\fR
.IP
In XFIXES mode
send cursor alpha channel data to
libvncserver. The blending effect will only b
e
visible in \fB-nocursorshape\fR mode or for clients with
cursorshapeupdates turned off. (However there is a
hack for 32bpp with depth 24, it uses the extra 8 bits
to store cursor transparency for use with a hacked
vncviewer that applies the transparency locally.
See the FAQ for more info).
In XFIXES mode
do not send cursor alpha channel data
to libvncserver. The default is to send it. Th
e
alphablend effect will only be visible in \fB-nocursorshape\fR
mode or for clients with cursorshapeupdates turned
off. (However there is a hack for 32bpp with depth 24,
it uses the extra 8 bits to store cursor transparency
for use with a hacked vncviewer that applies the
transparency locally.
See the FAQ for more info).
.PP
\fB-nocursorshape\fR
.IP
...
...
@@ -1010,6 +1015,10 @@ forever enable \fB-forever\fR mode.
.IP
noforever disable \fB-forever\fR mode.
.IP
timeout:n reset \fB-timeout\fR to n, if there are
currently no clients, exit unless one
connects in the next n secs.
.IP
deny deny any new connections, same as "lock"
.IP
nodeny allow new connections, same as "unlock"
...
...
@@ -1150,9 +1159,9 @@ alpharemove enable \fB-alpharemove\fR mode.
.IP
noalpharemove disable \fB-alpharemove\fR mode.
.IP
alphablend
enable \fB-
alphablend\fR mode.
alphablend
disable \fB-no
alphablend\fR mode.
.IP
noalphablend
disable \fB-
alphablend\fR mode.
noalphablend
enable \fB-no
alphablend\fR mode.
.IP
cursorshape disable \fB-nocursorshape\fR mode.
.IP
...
...
@@ -1306,8 +1315,8 @@ refresh reset close disconnect id sid waitmapped
nowaitmapped flashcmap noflashcmap truecolor notruecolor
overlay nooverlay overlay_cursor overlay_yescursor
nooverlay_nocursor nooverlay_cursor nooverlay_yescursor
overlay_nocursor visual scale viewonly noviewonly
shared noshared forever noforever once
deny lock nodeny
overlay_nocursor visual scale viewonly noviewonly
shared
noshared forever noforever once timeout
deny lock nodeny
unlock connect allowonce allow localhost nolocalhost
accept gone shm noshm flipbyteorder noflipbyteorder
onetile noonetile blackout xinerama noxinerama xrandr
...
...
@@ -1329,16 +1338,16 @@ httpdir enablehttpproxy noenablehttpproxy alwaysshared
noalwaysshared nevershared noalwaysshared dontdisconnect
nodontdisconnect desktop noremote
.IP
aro= display vncdisplay desktopname
auth rootshift
scale_str scaled_x scaled_y scale_numer scale_denom
scale_
fac scaling_noblend scaling_nomult4 scaling_pad
scaling_
interpolate inetd safer unsafe passwdfil
e
using_shm logfile o rc norc h help V version lastmod
bg sigpipe threads clients client_count pid ext_xtest
ext_x
kb ext_xshm ext_xinerama ext_overlay ext_xfixes
ext_x
damage ext_xrandr rootwin num_buttons button_mask
mouse_x mouse_y bpp depth indexed_color dpy_x dpy_y
rfbauth passwd
aro= display vncdisplay desktopname
http_url auth
rootshift scale_str scaled_x scaled_y scale_numer
scale_
denom scale_fac scaling_noblend scaling_nomult4
scaling_
pad scaling_interpolate inetd safer unsaf
e
passwdfile using_shm logfile o rc norc h help V version
lastmod bg sigpipe threads clients client_count pid
ext_x
test ext_xkb ext_xshm ext_xinerama ext_overlay
ext_x
fixes ext_xdamage ext_xrandr rootwin num_buttons
button_mask mouse_x mouse_y bpp depth indexed_color
dpy_x dpy_y
rfbauth passwd
.PP
\fB-sync\fR
.IP
...
...
x11vnc/x11vnc.c
View file @
d2a0e40e
...
...
@@ -161,11 +161,11 @@
#include <rfb/rfb.h>
#include <rfb/rfbregion.h>
#if OLD_TREE
/*
* This is another transient for building in older libvncserver trees,
* due to the API change:
*/
#if OLD_TREE
#define dontDisconnect rfbDontDisconnect
#define neverShared rfbNeverShared
#define alwaysShared rfbAlwaysShared
...
...
@@ -178,6 +178,10 @@
#define rfbEncryptAndStorePasswd vncEncryptAndStorePasswd
#define maxClientWait rfbMaxClientWait
#define rfbHttpInitSockets httpInitSockets
#define RFBUNDRAWCURSOR(s) if (s) {rfbUndrawCursor(s);}
#else
#define RFBUNDRAWCURSOR(s)
#endif
#if LIBVNCSERVER_HAVE_XSHM
...
...
@@ -255,7 +259,7 @@ int got_xfixes_cursor_notify = 0;
int
alpha_threshold
=
240
;
double
alpha_frac
=
0
.
33
;
int
alpha_remove
=
0
;
int
alpha_blend
=
0
;
int
alpha_blend
=
1
;
#if LIBVNCSERVER_HAVE_LIBXFIXES
#include <X11/extensions/Xfixes.h>
...
...
@@ -269,7 +273,7 @@ static int xdamage_base_event_type;
#endif
/* date +'lastmod: %Y-%m-%d' */
char
lastmod
[]
=
"0.7.1pre lastmod: 2005-01-
16
"
;
char
lastmod
[]
=
"0.7.1pre lastmod: 2005-01-
23
"
;
/* X display info */
...
...
@@ -545,6 +549,7 @@ int view_only = 0; /* clients can only watch. */
char
*
viewonly_passwd
=
NULL
;
/* view only passwd. */
int
inetd
=
0
;
/* spawned from inetd(1) */
int
connect_once
=
1
;
/* disconnect after first connection session. */
int
first_conn_timeout
=
0
;
/* -timeout */
int
flash_cmap
=
0
;
/* follow installed colormaps */
int
force_indexed_color
=
0
;
/* whether to force indexed color for 8bpp */
int
launch_gui
=
0
;
/* -gui */
...
...
@@ -556,6 +561,7 @@ int nofb = 0; /* do not send any fb updates */
unsigned
long
subwin
=
0x0
;
/* -id, -sid */
int
subwin_wait_mapped
=
0
;
int
no_su
=
0
;
/* -nosu */
int
xinerama
=
0
;
/* -xinerama */
int
xrandr
=
0
;
/* -xrandr */
...
...
@@ -680,6 +686,15 @@ int got_nevershared = 0;
/* -- util.h -- */
// FYI: GB='garbage begin' GE='garbage end'. Lines ending in //G trimmed too.
int
debug
=
0
;
int
libvnc_count
=
0
;
#if defined(__sun)
long
long
libvnc_time
;
#else
double
libvnc_time
;
#endif
#define NONUL(x) ((x) ? (x) : "")
/* XXX usleep(3) is not thread safe on some older systems... */
...
...
@@ -808,6 +823,7 @@ int pick_windowid(unsigned long *num) {
if
(
fgets
(
line
,
512
,
p
)
==
NULL
)
{
break
;
}
if
(
0
)
fprintf
(
stderr
,
"line: %s
\n
"
,
line
);
q
=
strstr
(
line
,
" id: 0x"
);
if
(
q
)
{
q
+=
5
;
...
...
@@ -1179,6 +1195,7 @@ void XTestFakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
rfbLog
(
"XTestFakeKeyEvent(dpy, keycode=0x%x
\"
%s
\"
, %s)
\n
"
,
key
,
XKeysymToString
(
XKeycodeToKeysym
(
dpy
,
key
,
0
)),
down
?
"down"
:
"up"
);
fflush
(
stderr
);
}
if
(
!
xtest_present
)
{
return
;
...
...
@@ -1265,6 +1282,82 @@ void XTestDiscard_wr(Display *dpy) {
}
/* -- vcr.h -- */
/*
* experiment to look for vertical copy rect changes
*/
void
do_vcr
(
void
);
void
initialize_vcr
(
void
);
#define VCR_HACK
#ifdef VCR_HACK
int
vcopyrect
=
0
;
/*
* vcr_map is a pattern of horizontal offsets for vertical scanlines
* within a column of changed tiles. 15 is in the middle of the tile,
* 0 the left edge, 31 the right edge, etc. It is kind of a recursive
* bisection of the tile.
*/
int
vcr_map
[]
=
{
15
,
0
,
31
,
7
,
23
,
3
,
27
,
11
,
19
,
1
,
5
,
9
,
13
,
17
,
21
,
25
,
29
,
2
,
4
,
6
,
8
,
10
,
12
,
14
,
16
,
18
,
20
,
22
,
24
,
26
,
28
,
30
};
/*
* VCR_DEPTH says how far into the vcr_map[] pattern we consider
* e.g. 5 means we consider offsets: 15, 0, 31, 7, 23.
*/
#define VCR_DEPTH 32
//int vcr_depth = VCR_DEPTH;
int
vcr_depth
=
9
;
/*
* fbd_old and fbd_new are the vertical "scan lines" of fb data.
* The "40" is just an index into which column (x value) of tiles it
* corresponds to.
* The VCR_DEPTH is an index for which of the above vcr_map[] offsets.
* The 1024 is how tall the display can possibly be (i.e. 1280x1024)
*
* fdb_old contains framebuffer pixel data before the copy_tiles() update.
* fdb_new contains framebuffer pixel data after the copy_tiles() update.
*
* By comparing these vectors with one shifted by a vertical offset,
* we can look for the offset that gives a long run of perfect coincidence
* of the fb pixel data. If a coincidence found, then we have a verticle
* offset for a potential copyRegion transfer (if we find a number >
* 1 of adjacent scanlines with the same offset to form a rectangle).
*
*/
void
***
fbd_old
;
void
***
fbd_new
;
char
***
fbd_old8
;
char
***
fbd_new8
;
short
***
fbd_old16
;
short
***
fbd_new16
;
int
***
fbd_old32
;
int
***
fbd_new32
;
/* smaller temporary ones to improve horrendous I/O (i.e. fewer pages) */
void
**
fbt_old
;
void
**
fbt_new
;
char
**
fbt_old8
;
char
**
fbt_new8
;
short
**
fbt_old16
;
short
**
fbt_new16
;
int
**
fbt_old32
;
int
**
fbt_new32
;
//int fbd_old[40][VCR_DEPTH][1024];
//int fbd_new[40][VCR_DEPTH][1024];
sraRegionPtr
vcr_change_region
=
NULL
;
sraRegionPtr
vcr_mod_region
=
NULL
;
#endif
/* -- cleanup.c -- */
/*
* Exiting and error handling routines
...
...
@@ -1350,6 +1443,7 @@ void clean_up_exit (int ret) {
static
void
interrupted
(
int
sig
)
{
exit_sig
=
sig
;
if
(
exit_flag
)
{
fprintf
(
stderr
,
"extra[%d] signal: %d
\n
"
,
exit_flag
,
sig
);
exit_flag
++
;
if
(
use_threads
)
{
usleep2
(
250
*
1000
);
...
...
@@ -1366,6 +1460,7 @@ static void interrupted (int sig) {
}
if
(
sig
==
SIGINT
)
{
shut_down
=
1
;
fprintf
(
stderr
,
"interrupted: set shut_down flag for SIGINT
\n
"
);
return
;
}
...
...
@@ -1386,6 +1481,10 @@ static void interrupted (int sig) {
autorepeat
(
1
);
}
if
(
getenv
(
"GDB"
))
{
fprintf
(
stderr
,
"getc> "
);
getc
(
stdin
);
}
if
(
sig
)
{
exit
(
2
);
}
...
...
@@ -1515,6 +1614,31 @@ int get_window_size(Window win, int *x, int *y) {
}
}
int
bs_w
=
0
;
void
remove_backingstore_and_saveunders
(
Window
win
)
{
int
i
,
nchild
;
Window
root
,
parent
;
Window
*
child_list
;
XSetWindowAttributes
sattr
;
for
(
i
=
0
;
i
<
bs_w
;
i
++
)
{
fprintf
(
stderr
,
" "
);
}
bs_w
+=
2
;
fprintf
(
stderr
,
"0x%lx
\n
"
,
win
);
sattr
.
save_under
=
False
;
XChangeWindowAttributes
(
dpy
,
win
,
CWSaveUnder
,
&
sattr
);
if
(
XQueryTree
(
dpy
,
win
,
&
root
,
&
parent
,
&
child_list
,
&
nchild
))
{
if
(
child_list
&&
nchild
)
{
for
(
i
=
0
;
i
<
nchild
;
i
++
)
{
Window
twin
=
child_list
[
i
];
remove_backingstore_and_saveunders
(
twin
);
}
}
XFree
(
child_list
);
}
bs_w
-=
2
;
}
/* signal handlers */
void
initialize_signals
(
void
)
{
signal
(
SIGHUP
,
interrupted
);
...
...
@@ -1948,6 +2072,7 @@ static int check_access(char *addr) {
}
else
{
chk
=
p
;
}
if
(
0
)
fprintf
(
stderr
,
"chk: %s
\n
"
,
chk
);
q
=
strstr
(
addr
,
chk
);
if
(
chk
[
strlen
(
chk
)
-
1
]
!=
'.'
)
{
...
...
@@ -2633,11 +2758,13 @@ static void reverse_connect(char *str) {
p
=
strtok
(
NULL
,
",
\t\r\n
"
);
if
(
p
)
{
t
=
0
;
rfbLog
(
"reverse_connect: start btw.
\n
"
);
while
(
t
<
sleep_between_host
)
{
usleep
(
dt
*
1000
);
rfbPE
(
screen
,
-
1
);
t
+=
dt
;
}
rfbLog
(
"reverse_connect: end btw.
\n
"
);
}
}
free
(
tmp
);
...
...
@@ -2659,12 +2786,14 @@ static void reverse_connect(char *str) {
t
=
sleep_max
-
sleep_min
;
tot
=
sleep_min
+
((
n
-
1
)
*
t
)
/
(
n_max
-
1
);
rfbLog
(
"reverse_connect: start sleeping.
\n
"
);
t
=
0
;
while
(
t
<
tot
)
{
rfbPE
(
screen
,
-
1
);
usleep
(
dt
*
1000
);
t
+=
dt
;
}
rfbLog
(
"reverse_connect: end sleeping.
\n
"
);
}
/*
...
...
@@ -4104,6 +4233,50 @@ void initialize_modtweak(void) {
}
}
}
if
(
0
)
{
if
(
debug_keyboard
)
{
int
kc
,
g
,
l
;
KeySym
ks
;
fprintf
(
stderr
,
"keycodes[] and modifiers[]:
\n
"
);
for
(
keysym
=
0
;
keysym
<
0x100
;
keysym
++
)
{
char
*
str
=
XKeysymToString
(
keysym
);
fprintf
(
stderr
,
"keysym 0x%02lx code=%03d/%03d index=%3d %s
\n
"
,
keysym
,
keycodes
[
keysym
],
XKeysymToKeycode
(
dpy
,
keysym
),
(
int
)
modifiers
[
keysym
],
str
?
str
:
"null"
);
}
for
(
kc
=
0
;
kc
<
0x100
;
kc
++
)
{
unsigned
int
state
=
0
;
int
put
=
0
;
for
(
g
=
1
;
g
<=
4
;
g
++
)
{
for
(
l
=
1
;
l
<=
4
;
l
++
)
{
unsigned
int
ms
;
ks
=
XkbKeycodeToKeysym
(
dpy
,
kc
,
g
-
1
,
l
-
1
);
ms
=
XkbKeysymToModifiers
(
dpy
,
ks
);
if
(
ks
!=
NoSymbol
)
{
char
*
str
=
XKeysymToString
(
ks
);
fprintf
(
stderr
,
"%03d G%d L%d mods=%3d 0x%04lx %s
\n
"
,
kc
,
g
,
l
,
(
int
)
ms
,
ks
,
str
?
str
:
"null"
);
put
=
1
;
}
}
}
fprintf
(
stderr
,
" %03d --
\n
"
,
kc
);
while
(
state
<
256
)
{
unsigned
int
mods
;
if
(
XkbLookupKeySym
(
dpy
,
kc
,
state
,
&
mods
,
&
ks
))
{
char
*
str
=
XKeysymToString
(
ks
);
fprintf
(
stderr
,
" %03d 0x%lx/%s"
,
state
,
ks
,
bitprint
(
state
,
8
));
fprintf
(
stderr
,
"/%s"
,
bitprint
(
mods
,
8
));
fprintf
(
stderr
,
"/%s %s
\n
"
,
bitprint
(
state
&
mods
,
8
),
str
?
str
:
"null"
);
}
state
++
;
}
if
(
put
)
fprintf
(
stderr
,
"
\n
"
);
}
}
}
left_shift_code
=
XKeysymToKeycode
(
dpy
,
XK_Shift_L
);
right_shift_code
=
XKeysymToKeycode
(
dpy
,
XK_Shift_R
);
...
...
@@ -5005,6 +5178,7 @@ int handle_subwin_resize(char *msg) {
int
new_x
,
new_y
;
int
i
,
check
=
10
,
ms
=
250
;
/* 2.5 secs... */
if
(
0
)
fprintf
(
stderr
,
"IN handle_subwin_resize('%s')
\n
"
,
msg
);
if
(
!
subwin
)
{
return
0
;
/* hmmm... */
}
...
...
@@ -5042,6 +5216,7 @@ int handle_subwin_resize(char *msg) {
}
}
if
(
0
)
fprintf
(
stderr
,
"IN handle_subwin_resize('%s')
\n
"
,
msg
);
rfbLog
(
"subwin 0x%lx new size: x: %d -> %d, y: %d -> %d
\n
"
,
subwin
,
dpy_x
,
new_x
,
dpy_y
,
new_y
);
rfbLog
(
"calling handle_xrandr_change() for resizing
\n
"
);
...
...
@@ -5102,6 +5277,7 @@ int check_xrandr_event(char *msg) {
if
(
!
xrandr
||
!
xrandr_present
)
{
return
0
;
}
if
(
0
)
fprintf
(
stderr
,
"IN check_xrandr_event('%s')
\n
"
,
msg
);
if
(
XCheckTypedEvent
(
dpy
,
xrandr_base_event_type
+
RRScreenChangeNotify
,
&
xev
))
{
int
do_change
;
...
...
@@ -5148,9 +5324,11 @@ int check_xrandr_event(char *msg) {
XDisplayWidth
(
dpy
,
scr
),
XDisplayHeight
(
dpy
,
scr
));
rfbLog
(
"check_xrandr_event(): returning control to"
" caller...
\n
"
);
if
(
0
)
fprintf
(
stderr
,
"OUT-%d check_xrandr_event('%s')
\n
"
,
do_change
,
msg
);
return
do_change
;
}
#endif
if
(
0
)
fprintf
(
stderr
,
"OUT-0 check_xrandr_event('%s')
\n
"
,
msg
);
return
0
;
}
...
...
@@ -5243,6 +5421,9 @@ static void selection_request(XEvent *ev) {
}
else
{
length
=
0
;
}
rfbLog
(
"selection_request: owner=0x%x requestor=0x%x sel=%d targ=%d prop=%d
\n
"
,
req_event
->
owner
,
req_event
->
requestor
,
req_event
->
selection
,
req_event
->
target
,
req_event
->
property
);
/* the window may have gone away, so trap errors */
trapped_xerror
=
0
;
...
...
@@ -6486,6 +6667,22 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog
(
"process_remote_cmd: disable -forever mode.
\n
"
);
connect_once
=
1
;
}
else
if
(
strstr
(
p
,
"timeout"
)
==
p
)
{
int
to
;
COLON_CHECK
(
"timeout:"
)
if
(
query
)
{
snprintf
(
buf
,
bufn
,
"ans=%s%s%d"
,
p
,
co
,
first_conn_timeout
);
goto
qry
;
}
p
+=
strlen
(
"timeout:"
);
to
=
atoi
(
p
);
if
(
to
>
0
)
{
to
=
-
to
;
}
first_conn_timeout
=
to
;
rfbLog
(
"process_remote_cmd: set -timeout to %d
\n
"
,
-
to
);
}
else
if
(
!
strcmp
(
p
,
"deny"
)
||
!
strcmp
(
p
,
"lock"
))
{
if
(
query
)
{
snprintf
(
buf
,
bufn
,
"ans=%s:%d"
,
p
,
deny_all
);
...
...
@@ -7062,9 +7259,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
goto
qry
;
}
rfbLog
(
"process_remote_cmd: enabling -repeat mode.
\n
"
);
if
(
no_autorepeat
)
{
autorepeat
(
1
);
}
autorepeat
(
1
);
/* restore initial setting */
no_autorepeat
=
0
;
}
else
if
(
!
strcmp
(
p
,
"norepeat"
))
{
...
...
@@ -7073,11 +7268,10 @@ char *process_remote_cmd(char *cmd, int stringonly) {
goto
qry
;
}
rfbLog
(
"process_remote_cmd: enabling -norepeat mode.
\n
"
);
if
(
!
no_autorepeat
&&
client_count
)
{
no_autorepeat
=
1
;
autorepeat
(
0
);
if
(
client_count
)
{
autorepeat
(
0
);
/* disable if any clients */
}
no_autorepeat
=
1
;
}
else
if
(
!
strcmp
(
p
,
"fb"
))
{
if
(
query
)
{
...
...
@@ -7887,6 +8081,14 @@ char *process_remote_cmd(char *cmd, int stringonly) {
}
else
if
(
!
strcmp
(
p
,
"desktopname"
))
{
snprintf
(
buf
,
bufn
,
"aro=%s:%s"
,
p
,
NONUL
(
rfb_desktop_name
));
}
else
if
(
!
strcmp
(
p
,
"http_url"
))
{
if
(
screen
->
httpListenSock
>
-
1
)
{
snprintf
(
buf
,
bufn
,
"aro=%s:http://%s:%d"
,
p
,
NONUL
(
screen
->
thisHost
),
screen
->
httpPort
);
}
else
{
snprintf
(
buf
,
bufn
,
"aro=%s:%s"
,
p
,
"http_not_active"
);
}
}
else
if
(
!
strcmp
(
p
,
"auth"
))
{
snprintf
(
buf
,
bufn
,
"aro=%s:%s"
,
p
,
NONUL
(
auth_file
));
}
else
if
(
!
strcmp
(
p
,
"rootshift"
))
{
...
...
@@ -8317,6 +8519,7 @@ void setup_cursors(void) {
first
=
0
;
if
(
screen
)
{
RFBUNDRAWCURSOR
(
screen
);
screen
->
cursor
=
NULL
;
LOCK
(
screen
->
cursorMutex
);
}
...
...
@@ -8683,6 +8886,8 @@ int get_xfixes_cursor(int init) {
}
}
RFBUNDRAWCURSOR
(
screen
);
/* we need to create the cursor and overwrite oldest */
use
=
oldest
;
if
(
cursors
[
use
]
->
rfb
)
{
...
...
@@ -8762,7 +8967,9 @@ int get_xfixes_cursor(int init) {
}
if
(
n_opaque
>=
alpha_frac
*
n_alpha
)
{
thresh
=
alpha_threshold
;
fprintf
(
stderr
,
"OK thresh: %d/%d
\n
"
,
n_opaque
,
n_alpha
);
}
else
{
int
o_opaque
=
n_opaque
;
n_opaque
=
0
;
for
(
i
=
255
;
i
>=
0
;
i
--
)
{
n_opaque
+=
histo
[
i
];
...
...
@@ -8771,6 +8978,8 @@ int get_xfixes_cursor(int init) {
break
;
}
}
fprintf
(
stderr
,
"changed thresh: %d -> %d [%d->%d]/%d
\n
"
,
alpha_threshold
,
thresh
,
o_opaque
,
n_opaque
,
n_alpha
);
}
i
=
0
;
...
...
@@ -8977,7 +9186,7 @@ int get_which_cursor(void) {
XErrorHandler
old_handler
;
int
mode
=
0
;
if
(
drag_in_progress
)
{
if
(
drag_in_progress
||
button_mask
)
{
return
-
1
;
}
...
...
@@ -9062,6 +9271,7 @@ int get_which_cursor(void) {
return
which
;
}
#if OLD_TREE
/*
* Some utilities for marking the little cursor patch region as
* modified, etc.
...
...
@@ -9074,12 +9284,11 @@ void mark_cursor_patch_modified(rfbScreenInfoPtr s, int old) {
return
;
}
/* TODO Karl: is this needed any longer? */
/* if (old) {
/* use oldCursor pos *//*
if
(
old
)
{
/* use oldCursor pos */
curx
=
s
->
oldCursorX
;
cury
=
s
->
oldCursorY
;
} else
*/
{
}
else
{
curx
=
s
->
cursorX
;
cury
=
s
->
cursorY
;
}
...
...
@@ -9101,6 +9310,7 @@ void mark_cursor_patch_modified(rfbScreenInfoPtr s, int old) {
rfbMarkRectAsModified
(
s
,
x1
,
y1
,
x1
+
x2
,
y1
+
y2
);
}
#endif
void
set_cursor_was_changed
(
rfbScreenInfoPtr
s
)
{
rfbClientIteratorPtr
iter
;
...
...
@@ -9235,7 +9445,10 @@ void cursor_position(int x, int y) {
rfbClientIteratorPtr
iter
;
rfbClientPtr
cl
;
int
cnt
=
0
,
nonCursorPosUpdates_clients
=
0
;
int
x_old
,
y_old
,
x_in
=
x
,
y_in
=
y
;
int
x_in
=
x
,
y_in
=
y
;
#if OLD_TREE
int
x_old
,
y_old
;
#endif
/* x and y are current positions of X11 pointer on the X11 display */
if
(
!
screen
)
{
...
...
@@ -9252,16 +9465,27 @@ void cursor_position(int x, int y) {
if
(
x
==
screen
->
cursorX
&&
y
==
screen
->
cursorY
)
{
return
;
}
/* TODO Karl: do we really need x_old,y_old? */
/*
#if OLD_TREE
x_old
=
screen
->
oldCursorX
;
y_old
=
screen
->
oldCursorY
;
*/
if
(
screen
->
cursorIsDrawn
)
{
rfbUndrawCursor
(
screen
);
}
LOCK
(
screen
->
cursorMutex
);
if
(
!
screen
->
cursorIsDrawn
)
{
screen
->
cursorX
=
x
;
screen
->
cursorY
=
y
;
}
UNLOCK
(
screen
->
cursorMutex
);
#else
LOCK
(
screen
->
cursorMutex
);
screen
->
cursorX
=
x
;
screen
->
cursorY
=
y
;
UNLOCK
(
screen
->
cursorMutex
);
#endif
iter
=
rfbGetClientIterator
(
screen
);
while
(
(
cl
=
rfbClientIteratorNext
(
iter
))
)
{
...
...
@@ -9296,13 +9520,13 @@ void cursor_position(int x, int y) {
}
rfbReleaseClientIterator
(
iter
);
/* TODO Karl: do we need x_old, y_old? */
/*
#if OLD_TREE
if
(
nonCursorPosUpdates_clients
&&
show_cursor
)
{
if
(
x_old
!=
x
||
y_old
!=
y
)
{
mark_cursor_patch_modified
(
screen
,
0
);
}
}*/
}
#endif
if
(
debug_pointer
&&
cnt
)
{
rfbLog
(
"cursor_position: sent position x=%3d y=%3d to %d"
...
...
@@ -9310,12 +9534,27 @@ void cursor_position(int x, int y) {
}
}
#if !OLD_TREE
void
set_rfb_cursor
(
int
which
)
{
int
workaround
=
1
;
/* if rfbSetCursor does not mark modified */
#if OLD_TREE
workaround
=
2
;
#endif
if
(
!
show_cursor
)
{
return
;
}
if
(
!
screen
)
{
return
;
}
if
(
!
cursors
[
which
]
||
!
cursors
[
which
]
->
rfb
)
{
rfbLog
(
"non-existent cursor: which=%d
\n
"
,
which
);
return
;
}
else
{
rfbSetCursor
(
screen
,
cursors
[
which
]
->
rfb
);
}
}
#else
void
set_rfb_cursor
(
int
which
)
{
if
(
!
show_cursor
)
{
return
;
...
...
@@ -9324,7 +9563,7 @@ void set_rfb_cursor(int which) {
return
;
}
if
(
workaround
&&
screen
->
cursor
)
{
if
(
screen
->
cursor
)
{
int
all_are_cursor_pos
=
1
;
rfbClientIteratorPtr
iter
;
rfbClientPtr
cl
;
...
...
@@ -9349,27 +9588,21 @@ void set_rfb_cursor(int which) {
rfbLog
(
"non-existent cursor: which=%d
\n
"
,
which
);
return
;
}
else
{
rfbSetCursor
(
screen
,
cursors
[
which
]
->
rfb
);
rfbSetCursor
(
screen
,
cursors
[
which
]
->
rfb
,
FALSE
);
}
/* TODO Karl: is this still necessary? */
/* this is a 2nd workaround for rfbSetCursor() */
if
(
workaround
>
1
)
{
if
(
screen
->
underCursorBuffer
==
NULL
&&
screen
->
underCursorBufferLen
!=
0
)
{
LOCK
(
screen
->
cursorMutex
);
screen
->
underCursorBufferLen
=
0
;
UNLOCK
(
screen
->
cursorMutex
);
}
}
/* TODO Karl: is this still necessary? */
if
(
workaround
)
{
set_cursor_was_changed
(
screen
);
}
}
#endif
void
set_no_cursor
(
void
)
{
RFBUNDRAWCURSOR
(
screen
);
set_rfb_cursor
(
CURS_EMPTY
);
}
...
...
@@ -9497,6 +9730,8 @@ void set_colormap(int reset) {
/* XXX XQueryTree somehow? */
XQueryPointer
(
dpy
,
c
,
&
r
,
&
c
,
&
rx
,
&
ry
,
&
wx
,
&
wy
,
&
m
);
if
(
c
&&
XGetWindowAttributes
(
dpy
,
c
,
&
attr
))
{
if
(
debug
)
fprintf
(
stderr
,
"child: %d 0x%x cmap: 0x%x map_installed: %d
\n
"
,
tries
,
(
int
)
c
,
(
int
)
attr
.
colormap
,
attr
.
map_installed
);
if
(
attr
.
colormap
&&
attr
.
map_installed
)
{
cmap
=
attr
.
colormap
;
vis
=
attr
.
visual
;
...
...
@@ -9546,6 +9781,7 @@ void set_colormap(int reset) {
}
if
(
diffs
&&
!
first
)
{
if
(
debug
)
fprintf
(
stderr
,
"set_colormap: %d changed colormap entries.
\n
"
,
diffs
);
if
(
!
all_clients_initialized
())
{
rfbLog
(
"set_colormap: warning: sending cmap "
"with uninitialized clients.
\n
"
);
...
...
@@ -9999,6 +10235,9 @@ XImage *initialize_xdisplay_fb(void) {
usleep
(
250
*
1000
);
goto
again
;
}
if
(
no_su
)
{
remove_backingstore_and_saveunders
(
window
);
}
if
(
use_snapfb
)
{
initialize_snap_fb
();
}
...
...
@@ -10644,6 +10883,14 @@ void blackout_tiles(void) {
* to simplify things drop down to single copy mode, no vcr, etc...
*/
single_copytile
=
1
;
#ifdef VCR_HACK
#if 0
if (vcopyrect) {
rfbLog("disabling vertical copyrect due to blackouts\n");
vcopyrect = 0;
}
#endif
#endif
/* loop over all tiles. */
for
(
ty
=
0
;
ty
<
ntiles_y
;
ty
++
)
{
...
...
@@ -10825,6 +11072,7 @@ void initialize_xinerama (void) {
/* max len is 10000x10000+10000+10000 (23 chars) per geometry */
rcnt
=
(
int
)
sraRgnCountRects
(
black_region
);
fprintf
(
stderr
,
"xinerama: rcnt=%d
\n
"
,
rcnt
);
bstr
=
(
char
*
)
malloc
(
30
*
(
rcnt
+
1
)
*
sizeof
(
char
));
tstr
=
(
char
*
)
malloc
(
30
*
sizeof
(
char
));
bstr
[
0
]
=
'\0'
;
...
...
@@ -10851,6 +11099,7 @@ void initialize_xinerama (void) {
sprintf
(
tstr
,
"%dx%d+%d+%d,"
,
w
,
h
,
x
,
y
);
strcat
(
bstr
,
tstr
);
}
fprintf
(
stderr
,
"xinerama: bstr: %s
\n
"
,
bstr
);
initialize_blackouts
(
bstr
);
free
(
bstr
);
...
...
@@ -10963,6 +11212,47 @@ typedef struct tile_change_region {
/* array to hold the tiles region_t-s. */
static
region_t
*
tile_region
;
/* for measurements: */
static
int
gap_got
,
gap_tot
,
isl_got
,
isl_tot
,
noretry
;
static
int
hints_used
,
hint_cnt
;
static
int
wrote_copy_tile_header
=
0
;
static
int
scan_cnt
=
0
,
scan_cnt2
=
0
;
static
double
scan_ave
=
0
,
scan_ave2
=
0
;
static
int
memcmp_scan
=
0
,
memcmp_copy
=
0
,
memcpy_copy
=
0
;
static
int
xget_scan
=
0
,
xget_copy
=
0
;
static
int
scale_data
=
0
;
#if defined(__sun)
static
long
long
memcpy_copy_time
,
memcmp_copy_time
,
memcmp_scan_time
;
static
long
long
copy_tile_time
,
xshmget_scan_time
,
xshmget_copy_time
;
static
long
long
scale_time
;
static
hrtime_t
beg
,
end
;
static
hrtime_t
beg2
,
end2
;
#define BEG_FAC 1000000000
#define BEG if(debug) {beg = gethrtime();}
#define BEG2 if(debug) {beg2 = gethrtime();}
#define END(x) if(debug) {end = gethrtime(); x += (long long) (end - beg);}
#define END2(x) if(debug) {end2 = gethrtime(); x += (long long) (end2 - beg2);}
#else
/* not very fast or accurate */
static
double
memcpy_copy_time
,
memcmp_copy_time
,
memcmp_scan_time
;
static
double
copy_tile_time
,
xshmget_scan_time
,
xshmget_copy_time
;
static
double
scale_time
;
static
double
doub1
=
0
.
0
,
doub2
=
0
.
0
;
static
double
beg
,
end
;
static
double
beg2
,
end2
;
#define BEG_FAC 1
#define BEG if(debug) {beg = dtime(&doub1);}
#define BEG2 if(debug) {beg2 = dtime(&doub2);}
#define END(x) if(debug) {end = dtime(&doub1); x += (end);}
#define END2(x) if(debug) {end2 = dtime(&doub2); x += (end2);}
#endif
#ifdef VCR_HACK
static
int
vcr_shift
[
VCR_DEPTH
];
/* vcr_map[]*pixelsize, use in copytile */
static
int
vcr_cnt
=
0
;
/* for statistics. */
#endif
/*
* setup tile numbers and allocate the tile and hint arrays:
...
...
@@ -11245,6 +11535,11 @@ void initialize_polling_images(void) {
fs_frac
=
1
.
1
;
fs_factor
=
0
;
}
if
(
debug
)
{
int
fs_tmp
=
fs_factor
?
fs_factor
:
1
;
rfbLog
(
"fs_factor: %d shm: %d
\n
"
,
fs_factor
,
(
bpp
/
8
)
*
dpy_x
*
(
dpy_y
/
fs_tmp
)
);
}
if
(
!
fs_factor
)
{
rfbLog
(
"warning: fullscreen updates are disabled.
\n
"
);
}
else
{
...
...
@@ -11399,7 +11694,82 @@ static void hint_updates(void) {
in_run
=
0
;
}
}
hint_cnt
=
hint_count
;
#ifdef VCR_HACK
if
(
vcopyrect
&&
vcr_change_region
!=
NULL
)
{
static
char
**
pic
=
NULL
;
int
tx2
,
ty2
,
x2
,
y2
;
sraRegionPtr
tmp_region
;
if
(
pic
==
NULL
)
{
int
n
;
pic
=
(
char
**
)
malloc
(
ntiles_x
*
sizeof
(
char
*
));
for
(
n
=
0
;
n
<
ntiles_x
;
n
++
)
{
pic
[
n
]
=
(
char
*
)
malloc
(
ntiles_y
*
sizeof
(
char
));
}
}
for
(
ty2
=
0
;
ty2
<
ntiles_y
;
ty2
++
)
{
for
(
tx2
=
0
;
tx2
<
ntiles_x
;
tx2
++
)
{
char
c
=
' '
;
n
=
tx2
+
ty2
*
ntiles_x
;
if
(
tile_has_diff
[
n
])
{
c
=
'X'
;
}
else
if
(
tile_tried
[
n
])
{
c
=
't'
;
}
x2
=
tx2
*
tile_x
;
y2
=
ty2
*
tile_y
;
tmp_region
=
(
sraRegionPtr
)
sraRgnCreateRect
(
x2
,
y2
,
x2
+
tile_x
,
y2
+
tile_y
);
if
(
sraRgnAnd
(
tmp_region
,
vcr_change_region
))
{
if
(
c
==
'X'
)
{
c
=
'-'
;
}
else
if
(
c
==
't'
)
{
c
=
'_'
;
}
else
{
c
=
'.'
;
}
}
pic
[
tx2
][
ty2
]
=
c
;
sraRgnDestroy
(
tmp_region
);
}
}
fprintf
(
stderr
,
"
\n
"
);
for
(
ty2
=
0
;
ty2
<
ntiles_y
;
ty2
++
)
{
for
(
tx2
=
0
;
tx2
<
ntiles_x
;
tx2
++
)
{
fprintf
(
stderr
,
"%c"
,
pic
[
tx2
][
ty2
]);
}
fprintf
(
stderr
,
"
\n
"
);
}
fprintf
(
stderr
,
"
\n
"
);
fprintf
(
stderr
,
"vcr_change_region: 0x%x Rects: %d "
,
(
int
)
vcr_change_region
,
(
int
)
sraRgnCountRects
(
vcr_change_region
));
fprintf
(
stderr
,
"vcr_mod_region: 0x%x Rects: %d "
,
(
int
)
vcr_mod_region
,
(
int
)
sraRgnCountRects
(
vcr_mod_region
));
for
(
i
=
0
;
i
<
hint_count
;
i
++
)
{
int
x
=
hint_list
[
i
].
x
;
int
y
=
hint_list
[
i
].
y
;
int
w
=
hint_list
[
i
].
w
;
int
h
=
hint_list
[
i
].
h
;
tmp_region
=
(
sraRegionPtr
)
sraRgnCreateRect
(
x
,
y
,
x
+
w
,
y
+
h
);
sraRgnSubtract
(
tmp_region
,
vcr_change_region
);
if
(
!
sraRgnEmpty
(
tmp_region
))
{
fprintf
(
stderr
,
"M"
);
rfbMarkRegionAsModified
(
screen
,
tmp_region
);
}
else
{
fprintf
(
stderr
,
"_"
);
}
sraRgnDestroy
(
tmp_region
);
}
fprintf
(
stderr
,
"
\n
"
);
sraRgnDestroy
(
vcr_change_region
);
vcr_change_region
=
NULL
;
return
;
}
#endif
/* VCR_HACK */
for
(
i
=
0
;
i
<
hint_count
;
i
++
)
{
/* pass update info to vnc: */
...
...
@@ -11581,6 +11951,7 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
int
shrink
;
/* whether shrinking or expanding */
static
int
constant_weights
=
-
1
,
cnt
=
0
;
BEG
if
(
scale_fac
<=
1
.
0
)
{
shrink
=
1
;
}
else
{
...
...
@@ -11688,6 +12059,8 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
constant_weights
=
1
;
}
}
fprintf
(
stderr
,
" scale dx: %.15f
\n
"
,
dx
);
fprintf
(
stderr
,
" scale dy: %.15f
\n
"
,
dy
);
}
/* set these all to 1.0 to begin with */
wx
=
1
.
0
;
...
...
@@ -11741,6 +12114,7 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
I2
=
I1
+
1
;
/* simple interpolation */
ddx
=
x1
-
I1
;
}
//if (first) fprintf(stderr, " I1=%d I2=%d J1=%d J2=%d\n", I1, I2, J1, J2);
/* Zero out accumulators for next pixel average: */
for
(
b
=
0
;
b
<
4
;
b
++
)
{
...
...
@@ -11851,6 +12225,12 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
w
=
wx
*
wy
;
wtot
+=
w
;
#if 0
if (cnt % 37 == 0)
fprintf(stderr, " w=%15.12f wx=%15.12f wy=%15.12f wtot=%8.3f "
"i=%3d j=%3d idx=%8.3f jdy=%8.3f I=%3d J=%3d\n",
w, wx, wy, wtot, i, j, i * dx, j * dy, I, J);
#endif
/*
* We average the unsigned char value
...
...
@@ -11876,6 +12256,7 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
pixave
[
2
]
+=
w
*
(
us
&
main_blue_mask
);
}
src
+=
Bpp
;
scale_data
+=
Bpp
;
}
}
...
...
@@ -11902,6 +12283,7 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
dest
+=
Bpp
;
}
}
END
(
scale_time
)
mark_rect_as_modified
(
i1
,
j1
,
i2
,
j2
,
1
);
}
...
...
@@ -11966,6 +12348,7 @@ static int copy_tiles(int tx, int ty, int nt) {
char
*
src
,
*
dst
,
*
s_src
,
*
s_dst
,
*
m_src
,
*
m_dst
;
char
*
h_src
,
*
h_dst
;
BEG2
if
(
!
first_line
)
{
/* allocate arrays first time in. */
int
n
=
ntiles_x
+
1
;
...
...
@@ -12009,11 +12392,14 @@ static int copy_tiles(int tx, int ty, int nt) {
}
X_LOCK
;
BEG
XRANDR_SET_TRAP_RET
(
-
1
,
"copy_tile-set"
);
/* read in the whole tile run at once: */
copy_image
(
tile_row
[
nt
],
x
,
y
,
size_x
,
size_y
);
XRANDR_CHK_TRAP_RET
(
-
1
,
"copy_tile-chk"
);
xget_copy
+=
size_x
*
size_y
*
pixelsize
;
END
(
xshmget_copy_time
)
X_UNLOCK
;
if
(
blackouts
&&
tile_blackout
[
n
].
cover
==
1
)
{
...
...
@@ -12036,6 +12422,7 @@ static int copy_tiles(int tx, int ty, int nt) {
w
=
(
x2
-
x1
)
*
pixelsize
;
s
=
x1
*
pixelsize
;
//fprintf(stderr, "rbo: %d w=%d s=%d x=%d-%d y=%d-%d b=%d\n", n, w, s, x1, x2, y1, y2, b);
for
(
line
=
0
;
line
<
size_y
;
line
++
)
{
if
(
y1
<=
line
&&
line
<
y2
)
{
memset
(
b_dst
+
s
,
fill
,
(
size_t
)
w
);
...
...
@@ -12054,6 +12441,63 @@ static int copy_tiles(int tx, int ty, int nt) {
for
(
t
=
1
;
t
<=
nt
;
t
++
)
{
first_line
[
t
]
=
-
1
;
}
BEG
#ifdef VCR_HACK
/*
* This is the great copyrect hunt macro. See the comments in copytile()
* for the general description. The only difference here in copy_tiles()
* is we have more than one horizontal tile index, tx+(t-1), to deal
* with.
*/
{
int
k
;
for
(
k
=
0
;
k
<
vcr_depth
;
k
++
)
{
vcr_shift
[
k
]
=
vcr_map
[
k
]
*
pixelsize
;
}
}
#define VCR_FB0(DST,SRC) \
if (vcopyrect) { \
int k, yl = y + line; \
if (bpp == 32) { \
for (k=0; k < vcr_depth; k++) { \
memcpy(fbd_old32[tx+(t-1)][k]+yl, \
((DST)+vcr_shift[k]), 4); \
memcpy(fbd_new32[tx+(t-1)][k]+yl, \
((SRC)+vcr_shift[k]), 4); \
} \
} else if (bpp == 16) {
/* XXX */
\
for (k=0; k < vcr_depth; k++) { \
memcpy(fbd_old16[tx+(t-1)][k]+yl, \
((DST)+vcr_shift[k]), 2); \
memcpy(fbd_new16[tx+(t-1)][k]+yl, \
((SRC)+vcr_shift[k]), 2); \
} \
} else if (bpp == 8) {
/* XXX */
\
for (k=0; k < vcr_depth; k++) { \
memcpy(fbd_old8[tx+(t-1)][k]+yl, \
((DST)+vcr_shift[k]), 1); \
memcpy(fbd_new8[tx+(t-1)][k]+yl, \
((SRC)+vcr_shift[k]), 1); \
} \
} \
vcr_cnt++; \
}
#define VCR_FB(DST,SRC) \
if (vcopyrect) { \
int k, yl = y + line; \
if (bpp == 32) { \
for (k=0; k < vcr_depth; k++) { \
memcpy(fbt_old32[(t-1)*tile_x + k]+(yl % tile_y), \
((DST)+vcr_shift[k]), 4); \
memcpy(fbt_new32[(t-1)*tile_x + k]+(yl % tile_y), \
((SRC)+vcr_shift[k]), 4); \
} \
} \
vcr_cnt++; \
}
#else
#define VCR_FB(DST,SRC)
#endif
/* VCR_HACK */
/* find the first line with difference: */
w1
=
width1
*
pixelsize
;
...
...
@@ -12077,10 +12521,13 @@ static int copy_tiles(int tx, int ty, int nt) {
if
(
memcmp
(
s_dst
+
off
,
s_src
+
off
,
len
))
{
first_line
[
t
]
=
line
;
}
else
{
VCR_FB
(
s_dst
+
off
,
s_src
+
off
);
}
memcmp_copy
+=
len
;
}
s_src
+=
tile_row
[
nt
]
->
bytes_per_line
;
s_dst
+=
main_bytes_per_line
;
}
END
(
memcmp_copy_time
)
/* see if there were any differences for any tile: */
first_min
=
-
1
;
...
...
@@ -12097,6 +12544,7 @@ static int copy_tiles(int tx, int ty, int nt) {
for
(
t
=
1
;
t
<=
nt
;
t
++
)
{
tile_has_diff
[
n
+
(
t
-
1
)]
=
0
;
}
END2
(
copy_tile_time
)
return
(
0
);
}
else
{
/*
...
...
@@ -12113,6 +12561,7 @@ static int copy_tiles(int tx, int ty, int nt) {
}
}
BEG
m_src
=
src
+
(
tile_row
[
nt
]
->
bytes_per_line
*
size_y
);
m_dst
=
dst
+
(
main_bytes_per_line
*
size_y
);
...
...
@@ -12144,9 +12593,11 @@ static int copy_tiles(int tx, int ty, int nt) {
}
else
{
len
=
w1
;
}
memcmp_copy
+=
len
;
if
(
memcmp
(
m_dst
+
off
,
m_src
+
off
,
len
))
{
last_line
[
t
]
=
line
;
}
else
{
VCR_FB
(
m_dst
+
off
,
m_src
+
off
);
}
}
}
...
...
@@ -12199,6 +12650,7 @@ static int copy_tiles(int tx, int ty, int nt) {
dx
=
dx1
;
}
memcmp_copy
+=
(
2
-
left_diff
[
t
]
-
right_diff
[
t
])
*
dw
;
if
(
!
left_diff
[
t
]
&&
memcmp
(
h_dst
+
off
,
h_src
+
off
,
dw
))
{
left_diff
[
t
]
=
1
;
...
...
@@ -12211,17 +12663,50 @@ static int copy_tiles(int tx, int ty, int nt) {
h_src
+=
tile_row
[
nt
]
->
bytes_per_line
;
h_dst
+=
main_bytes_per_line
;
}
END
(
memcmp_copy_time
)
/* now finally copy the difference to the rfb framebuffer: */
BEG
s_src
=
src
+
tile_row
[
nt
]
->
bytes_per_line
*
first_min
;
s_dst
=
dst
+
main_bytes_per_line
*
first_min
;
#ifdef VCR_HACK
if
(
!
vcopyrect
)
{
#endif
for
(
line
=
first_min
;
line
<=
last_max
;
line
++
)
{
/* for I/O speed we do not do this tile by tile */
memcpy
(
s_dst
,
s_src
,
size_x
*
pixelsize
);
memcpy_copy
+=
size_x
*
pixelsize
;
s_src
+=
tile_row
[
nt
]
->
bytes_per_line
;
s_dst
+=
main_bytes_per_line
;
}
#ifdef VCR_HACK
}
else
{
w1
=
width1
*
pixelsize
;
w2
=
width2
*
pixelsize
;
for
(
line
=
first_min
;
line
<=
last_max
;
line
++
)
{
for
(
t
=
1
;
t
<=
nt
;
t
++
)
{
if
(
first_line
[
t
]
==
-
1
)
{
continue
;
}
off
=
(
t
-
1
)
*
w1
;
if
(
t
==
nt
)
{
len
=
w2
;
/* possible short tile */
}
else
{
len
=
w1
;
}
/* here VCR_FB must be done before the memcpy otherwise there'd be no diffs */
VCR_FB
(
s_dst
+
off
,
s_src
+
off
);
memcpy
(
s_dst
+
off
,
s_src
+
off
,
len
);
memcpy_copy
+=
len
;
}
s_src
+=
tile_row
[
nt
]
->
bytes_per_line
;
s_dst
+=
main_bytes_per_line
;
}
}
#endif
/* VCR_HACK */
END
(
memcpy_copy_time
)
/* record all the info in the region array for this tile: */
for
(
t
=
1
;
t
<=
nt
;
t
++
)
{
...
...
@@ -12248,7 +12733,23 @@ static int copy_tiles(int tx, int ty, int nt) {
tile_copied
[
n
+
s
]
=
1
;
}
#ifdef VCR_HACK
if
(
vcopyrect
)
{
int
k
,
ps
=
pixelsize
;
if
(
bpp
==
32
)
{
for
(
t
=
1
;
t
<=
nt
;
t
++
)
{
for
(
k
=
0
;
k
<
vcr_depth
;
k
++
)
{
memcpy
(
fbd_old32
[
tx
+
(
t
-
1
)][
k
]
+
y
,
fbt_old32
[(
t
-
1
)
*
tile_x
+
k
],
tile_y
*
ps
);
memcpy
(
fbd_new32
[
tx
+
(
t
-
1
)][
k
]
+
y
,
fbt_new32
[(
t
-
1
)
*
tile_x
+
k
],
tile_y
*
ps
);
}
}
}
/* XXX */
}
#endif
END2
(
copy_tile_time
)
return
(
1
);
}
...
...
@@ -12364,6 +12865,9 @@ static int copy_all_tile_runs(void) {
}
}
}
if
(
ntcnt
)
{
// fprintf(stderr, " ntave: %.1f\n", ((double) ntave)/ntcnt);
}
return
diffs
;
}
...
...
@@ -12396,6 +12900,8 @@ static int copy_tiles_backward_pass(void) {
tile_has_diff
[
m
]
=
2
;
ct
=
copy_tiles
(
x
,
y
-
1
,
1
);
if
(
ct
<
0
)
return
ct
;
/* fatal */
}
else
{
noretry
++
;
/* only for statistics */
}
}
...
...
@@ -12406,6 +12912,8 @@ static int copy_tiles_backward_pass(void) {
tile_has_diff
[
m
]
=
2
;
ct
=
copy_tiles
(
x
-
1
,
y
,
1
);
if
(
ct
<
0
)
return
ct
;
/* fatal */
}
else
{
noretry
++
;
}
}
}
...
...
@@ -12461,6 +12969,7 @@ static int gap_try(int x, int y, int *run, int *saw, int along_x) {
*
saw
=
1
;
return
0
;
}
gap_tot
+=
*
run
;
for
(
i
=
1
;
i
<=
*
run
;
i
++
)
{
/* iterate thru the run. */
if
(
along_x
)
{
...
...
@@ -12473,11 +12982,16 @@ static int gap_try(int x, int y, int *run, int *saw, int along_x) {
m
=
xt
+
yt
*
ntiles_x
;
if
(
tile_tried
[
m
])
{
/* do not repeat tiles */
gap_tot
--
;
noretry
++
;
continue
;
}
ct
=
copy_tiles
(
xt
,
yt
,
1
);
if
(
ct
<
0
)
return
ct
;
/* fatal */
if
(
tile_has_diff
[
m
])
{
gap_got
++
;
}
}
*
run
=
0
;
*
saw
=
1
;
...
...
@@ -12540,6 +13054,7 @@ static int island_try(int x, int y, int u, int v, int *run) {
/* found a discontinuity */
if
(
tile_tried
[
m
])
{
noretry
++
;
return
0
;
}
else
if
(
*
run
<
grow_fill
)
{
return
0
;
...
...
@@ -12547,6 +13062,10 @@ static int island_try(int x, int y, int u, int v, int *run) {
ct
=
copy_tiles
(
u
,
v
,
1
);
if
(
ct
<
0
)
return
ct
;
/* fatal */
isl_tot
++
;
if
(
tile_has_diff
[
m
])
{
isl_got
++
;
}
}
return
1
;
}
...
...
@@ -12686,10 +13205,84 @@ int copy_snap(void) {
rfbLog
(
"copy_snap: time for -snapfb snapshot: %.3f sec
\n
"
,
dt
);
first
=
0
;
}
fprintf
(
stderr
,
"copy_snap: %.3f sec
\n
"
,
dt
);
return
0
;
}
/* profiling routines */
static
void
do_stats
(
void
)
{
static
double
t
=
0
;
if
(
t
==
0
)
{
dtime
(
&
t
);
}
#ifdef VCR_HACK
if
(
vcr_cnt
&&
scan_count
==
NSCAN
-
1
)
{
// fprintf(stderr, "vcr_cnt: %d\n", vcr_cnt);
vcr_cnt
=
0
;
}
#endif
if
(
scan_count
==
0
)
{
hints_used
=
0
;
gap_got
=
0
;
gap_tot
=
0
;
isl_got
=
0
;
isl_tot
=
0
;
noretry
=
0
;
}
else
if
(
debug
&&
scan_count
==
NSCAN
-
1
)
{
int
ave
=
(
int
)
(
1000
*
(
scan_ave
/
scan_cnt
));
int
ave2
=
(
int
)
(
1000
*
(
scan_ave2
/
scan_cnt2
));
scan_ave
=
0
;
scan_cnt
=
0
;
scan_ave2
=
0
;
scan_cnt2
=
0
;
fprintf
(
stderr
,
"All pix %.2fs (s4u aves: all: %dms scan: "
"%dms). tiles: %4d hints:%3d retry:%3d gaps:%3d/%-3d "
"isl:%3d/%-3d nap_ok=%d
\n
"
,
dtime
(
&
t
),
ave
,
ave2
,
nap_diff_count
,
hints_used
,
noretry
,
gap_got
,
gap_tot
-
gap_got
,
isl_got
,
isl_tot
-
isl_got
,
nap_ok
);
wrote_copy_tile_header
=
0
;
}
}
/*
* debugging: print out a picture of the tiles.
*/
static
void
print_tiles
(
void
)
{
/* hack for viewing tile diffs on the screen. */
static
char
*
prev
=
NULL
;
int
n
,
x
,
y
,
ms
=
1500
;
ms
=
1
;
if
(
!
prev
)
{
prev
=
(
char
*
)
malloc
((
size_t
)
(
ntiles
*
sizeof
(
char
)));
for
(
n
=
0
;
n
<
ntiles
;
n
++
)
{
prev
[
n
]
=
0
;
}
}
fprintf
(
stderr
,
" "
);
for
(
x
=
0
;
x
<
ntiles_x
;
x
++
)
{
fprintf
(
stderr
,
"%1d"
,
x
%
10
);
}
fprintf
(
stderr
,
"
\n
"
);
n
=
0
;
for
(
y
=
0
;
y
<
ntiles_y
;
y
++
)
{
fprintf
(
stderr
,
"%2d "
,
y
);
for
(
x
=
0
;
x
<
ntiles_x
;
x
++
)
{
if
(
tile_has_diff
[
n
])
{
fprintf
(
stderr
,
"X"
);
}
else
if
(
prev
[
n
])
{
fprintf
(
stderr
,
"o"
);
}
else
{
fprintf
(
stderr
,
"."
);
}
n
++
;
}
fprintf
(
stderr
,
"
\n
"
);
}
for
(
n
=
0
;
n
<
ntiles
;
n
++
)
{
prev
[
n
]
=
tile_has_diff
[
n
];
}
usleep
(
ms
*
1000
);
}
/*
* Utilities for managing the "naps" to cut down on amount of polling.
...
...
@@ -12880,6 +13473,9 @@ static int blackout_line_cmpskip(int n, int x, int y, char *dst, char *src,
x1
=
tile_blackout
[
n
].
bo
[
b
].
x1
-
x
;
x2
=
tile_blackout
[
n
].
bo
[
b
].
x2
-
x
;
//fprintf(stderr, "cmpskip[%d]: n=%3d X=%3d Y=%3d y=%d-%d w=%2d ps=%2d "
// "beg=%2d end=%2d x=%d-%d\n", b, n, x, y, y1, y2, w, pixelsize,
// beg, end, x1, x2);
if
(
y1
>
y
||
y
>=
y2
)
{
continue
;
}
...
...
@@ -12932,25 +13528,33 @@ static int scan_display(int ystart, int rescan) {
/* grab the horizontal scanline from the display: */
X_LOCK
;
BEG
XRANDR_SET_TRAP_RET
(
-
1
,
"scan_display-set"
);
copy_image
(
scanline
,
0
,
y
,
0
,
0
);
XRANDR_CHK_TRAP_RET
(
-
1
,
"scan_display-chk"
);
xget_scan
+=
main_bytes_per_line
;
END
(
xshmget_scan_time
)
X_UNLOCK
;
/* for better memory i/o try the whole line at once */
src
=
scanline
->
data
;
dst
=
main_fb
+
y
*
main_bytes_per_line
;
BEG
if
(
whole_line
&&
!
memcmp
(
dst
,
src
,
main_bytes_per_line
))
{
/* no changes anywhere in scan line */
memcmp_scan
+=
main_bytes_per_line
;
nodiffs
=
1
;
if
(
!
rescan
)
{
END
(
memcmp_scan_time
)
y
+=
NSCAN
;
continue
;
}
}
END
(
memcmp_scan_time
)
x
=
0
;
BEG
while
(
x
<
dpy_x
)
{
n
=
(
x
/
tile_x
)
+
(
y
/
tile_y
)
*
ntiles_x
;
...
...
@@ -12995,14 +13599,34 @@ static int scan_display(int ystart, int rescan) {
tile_count
++
;
}
}
}
else
{
memcmp_scan
+=
w
*
pixelsize
;
}
x
+=
NSCAN
;
}
y
+=
NSCAN
;
END
(
memcmp_scan_time
)
}
return
tile_count
;
}
#if 0
void check_key_down(void) {
double t = 0.0;
if (last_keyboard_input < 0) {
rfbCFD(screen, 1000);
if (last_keyboard_input) {
fprintf(stderr, "key *SWITCH*\n");
}
}
dtime(&t);
if (last_keyboard_input < 0) {
fprintf(stderr, "key DOWN: %3d %12.6f\n", -last_keyboard_input, t - 1089481179.0);
} else {
fprintf(stderr, "key up: %3d %12.6f\n", +last_keyboard_input, t - 1089481179.0);
}
}
#endif
/*
* toplevel for the scanning, rescanning, and applying the heuristics.
...
...
@@ -13014,6 +13638,32 @@ int scan_for_updates(int count_only) {
double
frac1
=
0
.
1
;
/* tweak parameter to try a 2nd scan_display() */
double
frac2
=
0
.
35
;
/* or 3rd */
double
frac3
=
0
.
02
;
/* do scan_display() again after copy_tiles() */
double
t
=
0
,
t2
=
0
,
dt2
;
double
d1
,
d2
,
d3
,
d4
,
d
=
0
;
int
full
=
0
;
int
gap_g
,
gap_t
,
isl_g
,
isl_t
,
gap_n
,
isl_n
,
tdiff
;
memcmp_scan
=
0
;
memcmp_copy
=
0
;
memcpy_copy
=
0
;
xget_scan
=
0
;
xget_copy
=
0
;
memcpy_copy_time
=
0
;
memcmp_copy_time
=
0
;
memcmp_scan_time
=
0
;
xshmget_copy_time
=
0
;
xshmget_scan_time
=
0
;
copy_tile_time
=
0
;
scale_time
=
0
;
scale_data
=
0
;
dtime
(
&
t2
);
dtime
(
&
d
);
do_stats
();
if
(
debug
)
{
dtime
(
&
t
);
}
if
(
debug
&&
scan_count
==
0
)
{
fflush
(
stderr
);
fflush
(
stdout
);
}
for
(
i
=
0
;
i
<
ntiles
;
i
++
)
{
tile_has_diff
[
i
]
=
0
;
tile_tried
[
i
]
=
0
;
...
...
@@ -13061,6 +13711,7 @@ int scan_for_updates(int count_only) {
nap_set
(
tile_count
);
dt2
=
dtime
(
&
t2
);
if
(
fs_factor
&&
frac1
>=
fs_frac
)
{
/* make frac1 < fs_frac if fullscreen updates are enabled */
frac1
=
fs_frac
/
2
.
0
;
...
...
@@ -13082,11 +13733,13 @@ int scan_for_updates(int count_only) {
tile_count
=
scan_display
(
scanlines
[
cp
],
1
);
SCAN_FATAL
(
tile_count
);
dt2
+=
dtime
(
&
t2
);
if
(
tile_count
>=
(
1
+
frac2
)
*
tile_count_old
)
{
/* on a roll... do a 3rd scan */
cp
=
(
NSCAN
-
scan_count
+
7
)
%
NSCAN
;
tile_count
=
scan_display
(
scanlines
[
cp
],
1
);
SCAN_FATAL
(
tile_count
);
dt2
+=
dtime
(
&
t2
);
}
}
scan_in_progress
=
0
;
...
...
@@ -13114,11 +13767,16 @@ int scan_for_updates(int count_only) {
if
(
use_threads
&&
pointer_mode
!=
1
)
{
pointer
(
-
1
,
0
,
0
,
NULL
);
}
/* go finish the stats collecting, etc */
full
=
1
;
tile_diffs
=
tile_count
;
goto
finish
;
nap_check
(
tile_count
);
return
tile_count
;
}
}
scan_in_progress
=
0
;
dtime
(
&
d
);
/* copy all tiles with differences from display to rfb framebuffer: */
fb_copy_in_progress
=
1
;
...
...
@@ -13141,6 +13799,7 @@ int scan_for_updates(int count_only) {
}
else
{
tile_diffs
=
copy_all_tile_runs
();
}
d1
=
dtime
(
&
d
);
SCAN_FATAL
(
tile_diffs
);
/*
...
...
@@ -13165,18 +13824,43 @@ int scan_for_updates(int count_only) {
tile_diffs
=
copy_tiles_additional_pass
();
SCAN_FATAL
(
tile_diffs
);
}
d2
=
dtime
(
&
d
);
isl_n
=
noretry
;
isl_g
=
isl_got
;
isl_t
=
isl_tot
;
/* Given enough tile diffs, try the islands: */
if
(
grow_fill
&&
tile_diffs
>
4
)
{
tile_diffs
=
grow_islands
();
}
SCAN_FATAL
(
tile_diffs
);
d3
=
dtime
(
&
d
);
isl_n
=
noretry
-
isl_n
;
isl_g
=
isl_got
-
isl_g
;
isl_t
=
isl_tot
-
isl_t
;
gap_n
=
noretry
;
gap_g
=
gap_got
;
gap_t
=
gap_tot
;
/* Given enough tile diffs, try the gaps: */
if
(
gaps_fill
&&
tile_diffs
>
4
)
{
tile_diffs
=
fill_tile_gaps
();
}
SCAN_FATAL
(
tile_diffs
);
d4
=
dtime
(
&
d
);
gap_n
=
noretry
-
gap_n
;
gap_g
=
gap_got
-
gap_g
;
gap_t
=
gap_tot
-
gap_t
;
if
(
0
)
print_tiles
();
#ifdef VCR_HACK
if
(
vcopyrect
)
{
do_vcr
();
}
#endif
fb_copy_in_progress
=
0
;
if
(
use_threads
&&
pointer_mode
!=
1
)
{
...
...
@@ -13207,18 +13891,150 @@ int scan_for_updates(int count_only) {
ping_clients
(
tile_diffs
);
}
finish:
tdiff
=
0
;
for
(
i
=
0
;
i
<
ntiles
;
i
++
)
{
if
(
tile_has_diff
[
i
])
{
tdiff
++
;
}
}
if
(
debug
)
{
double
dt
=
dtime
(
&
t
);
hints_used
+=
hint_cnt
;
scan_ave
+=
dt
;
scan_cnt
++
;
scan_ave2
+=
dt2
;
scan_cnt2
++
;
if
(
tdiff
>=
4
)
{
double
rat
=
dt
/
(
tdiff
?
tdiff
:
1
);
double
libvnc
=
(
double
)
libvnc_time
/
BEG_FAC
;
if
(
full
)
{
double
rat2
=
dt
/
ntiles
;
double
rat3
=
dpy_x
*
dpy_y
*
(
bpp
/
8
)
/
(
dt
-
dt2
);
rat3
/=
1000000
;
rat3
*=
2
;
/* both XShmGetImage and memcpy to fb */
fprintf
(
stderr
,
"fullscreen: %6.3f %4d %4d %4.1f ms "
"-- (%.3f) T/ntiles %.2f ms rate: %5.1f MB/s "
"vnc: %.3f/%d
\n
"
,
dt
,
tile_count
,
tdiff
,
1000
*
rat
,
dt2
,
1000
*
rat2
,
rat3
,
libvnc
,
libvnc_count
);
}
else
{
/*
* dt = full time
* dt2 = scan_display (sum for both if applicable)
* d1 = copy_all_tiles
* d2 = copy_tiles_backward_pass
* d3 = grow_islands
* d4 = fill_tile_gaps
* memcmp_scan number of bytes; memcmp_scan_time ns
* memcpy_copy number of bytes; memcpy_copy_time ns
* memcmp_copy number of bytes; memcmp_copy_time ns
*/
double
mrat1
=
(
memcmp_scan
)
/
(
dt2
);
double
mrat2
=
(
memcpy_copy
)
/
(
d1
+
d2
+
d3
+
d4
);
double
mrat3
=
(
memcmp_copy
)
/
(
d1
+
d2
+
d3
+
d4
);
double
mrat4
,
mrat5
,
mrat6
,
mrat7
;
double
time4
,
time5
,
time6
,
time7
;
double
xrat1
,
xrat2
;
double
xshm_scan
,
xshm_copy
;
double
scale_tm
,
scale_amt
;
double
ct_time
;
/* convert to (overall func. call) MB/sec */
mrat1
=
mrat1
/
1000000
;
/* scanline memcmp */
mrat2
=
mrat2
/
1000000
;
/* copytile memcpy */
mrat3
=
mrat3
/
1000000
;
/* copytile memcmp */
/* now work out more accurate rates MB/sec */
time4
=
(
double
)
memcpy_copy_time
/
BEG_FAC
;
mrat4
=
memcpy_copy
/
time4
;
mrat4
=
mrat4
/
1000000
;
/* copytile memcpy */
time5
=
(
double
)
memcmp_copy_time
/
BEG_FAC
;
mrat5
=
memcmp_copy
/
time5
;
mrat5
=
mrat5
/
1000000
;
/* copytile memcmp */
time6
=
(
double
)
memcmp_scan_time
/
BEG_FAC
;
mrat6
=
memcmp_scan
/
time6
;
mrat6
=
mrat6
/
1000000
;
/* scanline memcmp */
/* total time in copytile() */
ct_time
=
(
double
)
copy_tile_time
/
BEG_FAC
;
/* total xshmgetimage copytile */
xshm_copy
=
(
double
)
xshmget_copy_time
/
BEG_FAC
;
/* total xshmgetimage scanline */
xshm_scan
=
(
double
)
xshmget_scan_time
/
BEG_FAC
;
/* total scale_and_mark time */
scale_tm
=
(
double
)
scale_time
/
BEG_FAC
;
scale_amt
=
(
double
)
scale_data
/
1000000
;
time7
=
(
double
)
scale_time
/
BEG_FAC
;
if
(
time7
==
0
.
0
)
time7
=
1
.
0
;
mrat7
=
scale_data
/
time7
;
mrat7
=
mrat7
/
1000000
;
/* scale_and_mark rate */
xrat1
=
xget_scan
/
(
1000000
*
xshm_scan
);
xrat2
=
xget_copy
/
(
1000000
*
xshm_copy
);
if
(
!
wrote_copy_tile_header
)
{
fprintf
(
stderr
,
"---------- Time tlcnt tldif "
" T/tld -- (Tscan) - Tcopy Tisl Tgap R "
"Tcp2/cp1 Tisl/cp Tgap/cp Y/N-retry "
"Y/N-retry
\n
"
);
wrote_copy_tile_header
=
1
;
}
fprintf
(
stderr
,
"copy_tile: %6.3f %4d %4d %4.1f ms --"
" (%.3f) - %.3f %.3f %.3f R (%.3f) %.3f %.3f"
" isl=%d/%d-%d
\t
gap=%d/%d-%d
\n
"
"# scanline: cmp=%7d rate=%5.1f MB/s mcmp=%.4f"
" | xshm=%.4f st=%.4f xt/st=%.2f xrate_s=%5.1f "
"MB/s
\n
"
"# copytile: cmp=%7d rate=%5.1f MB/s mcmp=%.4f"
" | vnc: %.4f/%03d scale: %.4f %5.2f MB %5.1f MB/s
\n
"
" cpy=%7d rate=%5.1f MB/s mcpy=%.4f"
" | xshm=%.4f ct=%.4f xt/ct=%.2f xrate_c=%5.1f "
"MB/s
\n
"
,
dt
,
tile_count
,
tdiff
,
1000
*
rat
,
dt2
,
d1
+
d2
,
d3
,
d4
,
d2
/
d1
,
d3
/
(
d1
+
d2
),
d4
/
(
d1
+
d2
),
isl_g
,
isl_t
-
isl_g
,
isl_n
,
gap_g
,
gap_t
-
gap_g
,
gap_n
,
memcmp_scan
,
mrat6
,
time6
,
xshm_scan
,
dt2
,
xshm_scan
/
dt2
,
xrat1
,
memcmp_copy
,
mrat5
,
time5
,
libvnc
,
libvnc_count
,
scale_tm
,
scale_amt
,
mrat7
,
memcpy_copy
,
mrat4
,
time4
,
xshm_copy
,
ct_time
,
xshm_copy
/
ct_time
,
xrat2
);
if
(
0
&&
isl_g
<
5
&&
isl_t
-
isl_g
>
30
)
{
print_tiles
();
}
}
libvnc_time
=
0
;
libvnc_count
=
0
;
}
}
/* end of profile timing junk */
nap_check
(
tile_diffs
);
return
tile_diffs
;
}
/* -- gui.c -- */
#if OLD_TREE
char
gui_code
[]
=
""
;
#else
#include "tkx11vnc.h"
#endif
nap_check
(
tile_diffs
);
return
tile_diffs
;
}
/* -- gui.c -- */
#if OLD_TREE
char
gui_code
[]
=
""
;
#else
#include "tkx11vnc.h"
#endif
void
run_gui
(
char
*
gui_xdisplay
,
int
connect_to_x11vnc
,
pid_t
parent
)
{
char
*
x11vnc_xdisplay
=
NULL
;
char
extra_path
[]
=
":/usr/local/bin:/usr/bin/X11:/usr/sfw/bin"
...
...
@@ -13244,9 +14060,13 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) {
rfbLogEnable
(
0
);
if
(
!
client_connect_file
)
{
dpy
=
XOpenDisplay
(
x11vnc_xdisplay
);
if
(
!
dpy
&&
!
x11vnc_xdisplay
)
{
x11vnc_xdisplay
=
strdup
(
":0"
);
dpy
=
XOpenDisplay
(
x11vnc_xdisplay
);
}
if
(
!
dpy
)
{
fprintf
(
stderr
,
"gui: could not open
display: %s
\n
"
,
x11vnc_xdisplay
);
fprintf
(
stderr
,
"gui: could not open
"
"display: %s
\n
"
,
NONUL
(
x11vnc_xdisplay
)
);
exit
(
1
);
}
scr
=
DefaultScreen
(
dpy
);
...
...
@@ -13254,6 +14074,7 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) {
initialize_vnc_connect_prop
();
}
usleep
(
1000
*
1000
);
fprintf
(
stderr
,
"
\n
"
);
for
(
i
=
0
;
i
<
try_max
;
i
++
)
{
usleep
(
sleep
*
1000
);
fprintf
(
stderr
,
"gui: pinging %s try=%d ...
\n
"
,
...
...
@@ -13293,11 +14114,11 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) {
while
(
p
)
{
char
*
try
;
struct
stat
sbuf
;
char
*
wishes
[]
=
{
"wish"
,
"wish8.3"
,
"wish8.4"
};
char
*
wishes
[]
=
{
"wish"
,
"wish8.3"
,
"wish8.4"
,
"wish8.5"
,
"wish8.0"
};
int
nwishes
=
3
,
i
;
/* strlen("wish8.4") is 7 */
try
=
(
char
*
)
malloc
(
strlen
(
p
)
+
1
+
7
+
1
);
try
=
(
char
*
)
malloc
(
strlen
(
p
)
+
1
+
strlen
(
"wish8.4"
)
+
1
);
for
(
i
=
0
;
i
<
nwishes
;
i
++
)
{
sprintf
(
try
,
"%s/%s"
,
p
,
wishes
[
i
]);
if
(
stat
(
try
,
&
sbuf
)
==
0
)
{
...
...
@@ -13490,7 +14311,9 @@ static void check_user_input2(double dt) {
double
quick_spin_fac
=
0
.
40
;
double
grind_spin_time
=
0
.
175
;
int
gb
=
1
;
if
(
gb
)
fprintf
(
stderr
,
"
\n
GOT dt: %.3f gpi: %d
\n
"
,
dt
,
got_pointer_input
);
dtime
(
&
tm
);
g
=
g_in
=
got_pointer_input
;
...
...
@@ -13519,12 +14342,15 @@ static void check_user_input2(double dt) {
XFlush
(
dpy
);
spin
+=
dtime
(
&
tm
);
if
(
gb
)
fprintf
(
stderr
,
" sp=%.3f "
,
spin
);
if
(
spin
>
quick_spin_fac
*
dt
)
{
/* get out if spin time comparable to last scan time */
if
(
gb
)
fprintf
(
stderr
,
" SPIN-OUT: %.3f qsf * dt: %.3f"
,
spin
,
quick_spin_fac
*
dt
);
break
;
}
if
(
got_pointer_input
>
g
)
{
if
(
gb
)
fprintf
(
stderr
,
"-%d"
,
got_pointer_input
-
g_in
);
g
=
got_pointer_input
;
if
(
eaten
++
<
max_eat
)
{
continue
;
...
...
@@ -13533,10 +14359,13 @@ static void check_user_input2(double dt) {
miss
++
;
}
if
(
miss
>
1
)
{
/* 1 means out on 2nd miss */
if
(
gb
)
fprintf
(
stderr
,
" MISS-BRK: %.3f"
,
spin
);
break
;
}
}
if
(
gb
&&
eaten
>=
max_eat
)
fprintf
(
stderr
,
" +MAX_EAT"
);
if
(
gb
)
fprintf
(
stderr
,
"
\n
"
);
/*
* Probably grinding with a lot of fb I/O if dt is this large.
...
...
@@ -13572,14 +14401,17 @@ static void check_user_input2(double dt) {
g
=
got_pointer_input
;
miss
=
0
;
if
(
gb
)
fprintf
(
stderr
,
" GRIND ms: %d "
,
ms
);
for
(
i
=
0
;
i
<
split
;
i
++
)
{
usleep
(
ms
*
1000
);
if
(
gb
)
fprintf
(
stderr
,
"*"
);
if
(
show_multiple_cursors
)
{
rfbPE
(
screen
,
1000
);
}
else
{
rfbCFD
(
screen
,
1000
);
}
spin
+=
dtime
(
&
tm
);
if
(
gb
)
fprintf
(
stderr
,
"%d"
,
got_pointer_input
-
g_in
);
if
(
got_pointer_input
>
g
)
{
XFlush
(
dpy
);
miss
=
0
;
...
...
@@ -13594,6 +14426,8 @@ static void check_user_input2(double dt) {
break
;
}
}
if
(
gb
&&
i
==
split
)
fprintf
(
stderr
,
" +MAX_GR"
);
if
(
gb
)
fprintf
(
stderr
,
" spin: %.3f
\n
"
,
spin
);
}
}
...
...
@@ -13607,13 +14441,16 @@ static void check_user_input3(double dt, double dtr, int tile_diffs) {
int
gcnt
,
ginput
;
static
int
first
=
1
;
static
int
gb
=
1
;
if
(
first
)
{
char
*
p
=
getenv
(
"SPIN"
);
if
(
p
)
{
double
junk
;
sscanf
(
p
,
"%lf,%lf"
,
&
dt_cut
,
&
junk
);
gb
=
1
;
}
fprintf
(
stderr
,
" dt_cut: %f
\n
"
,
dt_cut
);
first
=
0
;
}
...
...
@@ -13621,6 +14458,7 @@ static void check_user_input3(double dt, double dtr, int tile_diffs) {
return
;
}
if
(
gb
)
fprintf
(
stderr
,
"
\n
GOT dt: %.3f gpi: %d
\n
"
,
dt
,
got_pointer_input
);
if
(
dt
<
dt_cut
)
{
dt
=
dt_cut
;
/* this is to try to avoid early exit */
...
...
@@ -13654,6 +14492,7 @@ static void check_user_input3(double dt, double dtr, int tile_diffs) {
dtm
=
dtime
(
&
tm
);
spin
+=
dtm
;
if
(
gb
)
fprintf
(
stderr
,
" dtm=%.4f"
,
dtm
);
if
(
got_pointer_input
==
g
)
{
if
(
last_was_miss
)
{
...
...
@@ -13671,9 +14510,11 @@ static void check_user_input3(double dt, double dtr, int tile_diffs) {
if
(
spin
>
spin_max
)
{
/* get out if spin time over limit */
if
(
gb
)
fprintf
(
stderr
,
" SPIN-OUT: %.4f"
,
spin
);
break
;
}
else
if
(
got_pointer_input
>
g
)
{
if
(
gb
)
fprintf
(
stderr
,
">>%d/dtp=%.4f, "
,
got_pointer_input
-
g_in
,
tm
-
to
);
to
=
tm
;
/* received some input, flush to display. */
got_input
=
1
;
g
=
got_pointer_input
;
...
...
@@ -13682,9 +14523,11 @@ static void check_user_input3(double dt, double dtr, int tile_diffs) {
X_UNLOCK
;
}
else
if
(
--
allowed_misses
<=
0
)
{
/* too many misses */
if
(
gb
)
fprintf
(
stderr
,
">>*M
\n
MISS-BRK: %.4f"
,
spin
);
break
;
}
else
if
(
consecutive_misses
>=
3
)
{
/* too many misses */
if
(
gb
)
fprintf
(
stderr
,
">>*M
\n
MISS-CONS: %.4f"
,
spin
);
break
;
}
else
{
/* these are misses */
...
...
@@ -13697,9 +14540,12 @@ static void check_user_input3(double dt, double dtr, int tile_diffs) {
* will batch them.
*/
wms
=
50
;
if
(
gb
)
fprintf
(
stderr
,
">>*M-FST, "
);
}
else
if
(
button_mask
)
{
wms
=
10
;
if
(
gb
)
fprintf
(
stderr
,
">>*M, "
);
}
else
{
if
(
gb
)
fprintf
(
stderr
,
">>*M, "
);
}
if
(
wms
)
{
usleep
(
wms
*
1000
);
...
...
@@ -13714,6 +14560,7 @@ static void check_user_input3(double dt, double dtr, int tile_diffs) {
}
}
if
(
gb
)
fprintf
(
stderr
,
"
\n
"
);
drag_in_progress
=
0
;
}
...
...
@@ -13729,6 +14576,7 @@ int fb_update_sent(int *count) {
}
rfbReleaseClientIterator
(
i
);
if
(
sent
!=
last_count
)
{
if
(
0
)
fprintf
(
stderr
,
"
\n
***FB_UPDATE_SENT***
\n
"
);
rc
=
1
;
}
if
(
count
!=
NULL
)
{
...
...
@@ -13740,6 +14588,7 @@ int fb_update_sent(int *count) {
static
void
check_user_input4
(
double
dt
,
double
dtr
,
int
tile_diffs
)
{
static
int
gb
=
1
;
int
g
,
g_in
,
i
,
ginput
,
gcnt
,
tmp
;
int
last_was_miss
,
consecutive_misses
;
int
min_frame_size
=
10
;
/* 10 tiles */
...
...
@@ -13763,7 +14612,9 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
char
*
p
=
getenv
(
"SPIN"
);
if
(
p
)
{
sscanf
(
p
,
"%lf,%lf,%lf,%lf"
,
&
dt_cut
,
&
Tfac_r
,
&
Tfac_v
,
&
Tfac_n
);
gb
=
1
;
}
fprintf
(
stderr
,
"dt_cut: %f Tfac_r/r: %f/%f Tdelay: %f
\n
"
,
dt_cut
,
Tfac_r
,
Tfac_v
,
Tdelay
);
first
=
0
;
ssec
=
time
(
0
);
}
...
...
@@ -13819,11 +14670,16 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
}
/* damn, they didn't push our frame! */
iter
++
;
if
(
gb
&&
iter
==
1
)
fprintf
(
stderr
,
"PUSH_FRAME:"
);
if
(
gb
)
fprintf
(
stderr
,
" %d"
,
iter
);
// measure_send_rates(1);
rfbPE
(
screen
,
rfb_wait_ms
*
1000
);
// measure_send_rates(0);
push_spin
+=
dtime
(
&
tp
);
}
if
(
iter
)
{
if
(
gb
)
fprintf
(
stderr
,
"
\n
"
);
X_LOCK
;
XFlush
(
dpy
);
X_UNLOCK
;
...
...
@@ -13836,6 +14692,7 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
* when we first enter we require some pointer input
*/
if
(
!
got_pointer_input
)
{
if
(
gb
&&
dtr
>
0
.
05
)
fprintf
(
stderr
,
"-- dt: %.3f dtr: %.3f
\n
"
,
dt
,
dtr
);
return
;
}
...
...
@@ -13864,6 +14721,13 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
rpe_last
=
to
=
tc
=
tm
;
/* last time we did rfbPE() */
g
=
g_in
=
got_pointer_input
;
if
(
gb
)
{
fprintf
(
stderr
,
"
\n
GOT dt: %.3f dtr: %.3f gpi: %d dt_min: %.3f"
" dt_max: %.3f TD= %d Ttiletm: %.3f"
" now: %.3f vnccpu_rate: %.2f KB/sec screen_rate: %.2f MB/sec net_rate: %.2f KB/sec Delay: %.4f sec
\n
"
,
dt
,
dtr
,
got_pointer_input
,
dt_min
,
dt_max
,
tile_diffs
,
Ttile
*
tile_diffs
,
tm
-
ssec
,
vnccpu_rate
/
1000
,
screen_rate
/
1000000
,
net_rate
/
1000
,
Tdelay
);
}
tile_diffs
=
0
;
/* reset our knowlegde of tile_diffs to zero */
while
(
1
)
{
...
...
@@ -13885,7 +14749,9 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
if
(
(
gcnt
==
1
&&
got_pointer_input
>
g
)
||
tm
-
tc
>
2
*
dt_min
)
{
tile_diffs
=
scan_for_updates
(
1
);
tc
=
tm
;
if
(
gb
)
fprintf
(
stderr
,
" NewTD%s=%d/%.3f"
,
tile_diffs
>
10
?
"*"
:
""
,
tile_diffs
,
spin
);
}
if
(
gb
)
fprintf
(
stderr
,
" dtm%s=%.4f"
,
dtm
>=
0
.
05
?
"*"
:
""
,
dtm
);
if
(
got_pointer_input
==
g
)
{
if
(
last_was_miss
)
{
...
...
@@ -13900,6 +14766,7 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
if
(
tile_diffs
>
min_frame_size
&&
spin
>
Ttile
*
tile_diffs
+
Tdelay
)
{
/* we think we can push the frame */
if
(
gb
)
fprintf
(
stderr
,
"
\n
##FRAME-OUT: %.4f Btile: %d del: %.3f"
,
spin
,
Btile
*
tile_diffs
,
tm
-
ssec
);
push_frame
=
1
;
fb_update_sent
(
&
update_count
);
break
;
...
...
@@ -13911,9 +14778,11 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
X_LOCK
;
XFlush
(
dpy
);
X_UNLOCK
;
if
(
gb
)
fprintf
(
stderr
,
"++%d/dtp=%.4f, "
,
got_pointer_input
-
g_in
,
tm
-
to
);
to
=
tm
;
}
else
if
(
consecutive_misses
>=
2
)
{
/* too many misses in a row */
if
(
gb
)
fprintf
(
stderr
,
">>*M
\n
MISS-CONS: %.4f del: %.3f"
,
spin
,
tm
-
ssec
);
break
;
}
else
{
...
...
@@ -13927,13 +14796,17 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
* of them for the next read.
*/
wms
=
50
;
if
(
gb
)
fprintf
(
stderr
,
">>*M-FST, "
);
}
else
if
(
button_mask
)
{
wms
=
10
;
if
(
gb
)
fprintf
(
stderr
,
">>*M-DRG, "
);
}
else
{
wms
=
0
;
if
(
gb
)
fprintf
(
stderr
,
">>*M, "
);
}
if
(
wms
)
{
if
(
gb
)
fprintf
(
stderr
,
"wms=%d, "
,
wms
);
usleep
(
wms
*
1000
);
}
}
...
...
@@ -13944,6 +14817,7 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
rfbCFD
(
screen
,
rfb_wait_ms
*
1000
);
}
}
if
(
gb
)
fprintf
(
stderr
,
"
\n
"
);
drag_in_progress
=
0
;
}
...
...
@@ -14166,6 +15040,8 @@ void measure_send_rates(int init) {
ClientData
*
cd
=
(
ClientData
*
)
cl
->
clientData
;
tmp2
=
0
.
0
;
dtime
(
&
tmp2
);
fprintf
(
stderr
,
"client num rects init=%d: req: %d mod: %d time: %.3f
\n
"
,
init
,
(
int
)
sraRgnCountRects
(
cl
->
requestedRegion
),
(
int
)
sraRgnCountRects
(
cl
->
modifiedRegion
),
tmp2
);
if
(
init
)
{
continue
;
}
...
...
@@ -14244,6 +15120,7 @@ if (init) {
dbr
=
rbs
-
cd
->
set_raw_bytes
;
cmp_rate
=
db
/
dt
;
raw_rate
=
dbr
/
dt
;
fprintf
(
stderr
,
"RATE: %11.2f RAW: %11.2f dt: %.3f B: %7d R: %7d
\n
"
,
cmp_rate
,
raw_rate
,
dt
,
db
,
dbr
);
if
(
dbr
>
min_width
*
min_width
*
bpp
/
8
)
{
cd
->
sample
++
;
if
(
cd
->
sample
>=
RATE_SAMPLES
)
{
...
...
@@ -14266,7 +15143,11 @@ void rfbPE(rfbScreenInfoPtr scr, long usec) {
return
;
}
if
(
!
use_threads
)
{
BEG
measure_send_rates
(
1
);
rfbProcessEvents
(
scr
,
usec
);
measure_send_rates
(
0
);
END
(
libvnc_time
);
libvnc_count
++
;
}
}
...
...
@@ -14275,7 +15156,9 @@ void rfbCFD(rfbScreenInfoPtr scr, long usec) {
return
;
}
if
(
!
use_threads
)
{
BEG
rfbCheckFds
(
scr
,
usec
);
END
(
libvnc_time
);
libvnc_count
++
;
}
}
...
...
@@ -14285,6 +15168,7 @@ void rfbCFD(rfbScreenInfoPtr scr, long usec) {
static
void
watch_loop
(
void
)
{
int
cnt
=
0
,
tile_diffs
=
0
;
double
dt
=
0
.
0
,
dtr
=
0
.
0
;
time_t
start
=
time
(
0
);
if
(
use_threads
)
{
rfbRunEventLoop
(
screen
,
-
1
,
TRUE
);
...
...
@@ -14299,7 +15183,9 @@ static void watch_loop(void) {
if
(
!
use_threads
)
{
double
tm
=
0
.
0
;
dtime
(
&
tm
);
// measure_send_rates(1);
rfbPE
(
screen
,
-
1
);
// measure_send_rates(0);
dtr
=
dtime
(
&
tm
);
fb_update_sent
(
NULL
);
...
...
@@ -14327,11 +15213,24 @@ static void watch_loop(void) {
check_connect_inputs
();
check_padded_fb
();
if
(
first_conn_timeout
<
0
)
{
start
=
time
(
0
);
first_conn_timeout
=
-
first_conn_timeout
;
}
if
(
!
screen
||
!
screen
->
clientHead
)
{
/* waiting for a client */
if
(
first_conn_timeout
)
{
if
(
time
(
0
)
-
start
>
first_conn_timeout
)
{
rfbLog
(
"No client after %d secs.
\n
"
,
first_conn_timeout
);
shut_down
=
1
;
continue
;
}
}
usleep
(
200
*
1000
);
continue
;
}
first_conn_timeout
=
0
;
if
(
nofb
)
{
/* no framebuffer polling needed */
...
...
@@ -14362,6 +15261,7 @@ static void watch_loop(void) {
double
tm
=
0
.
0
;
dtime
(
&
tm
);
RFBUNDRAWCURSOR
(
screen
);
if
(
use_snapfb
)
{
int
t
,
tries
=
5
;
copy_snap
();
...
...
@@ -14451,6 +15351,12 @@ static void print_help(void) {
" shifts a root view to it: this shows SaveUnders menus,
\n
"
" etc, although they will be clipped if they extend beyond
\n
"
" the window.
\n
"
#if 0
"-nosu Intended for use with -id windowid. Follow the window\n"
" tree down and *irreversibly* disable BackingStore and\n"
" SaveUnders for all windows. The hope is this will show\n"
" the popups and menus in -id mode. Use with caution.\n"
#endif
"-flashcmap In 8bpp indexed color, let the installed colormap flash
\n
"
" as the pointer moves from window to window (slow).
\n
"
"-notruecolor For 8bpp displays, force indexed color (i.e. a colormap)
\n
"
...
...
@@ -14521,6 +15427,8 @@ static void print_help(void) {
" disconnects, opposite of -forever. This is the Default.
\n
"
"-forever Keep listening for more connections rather than exiting
\n
"
" as soon as the first client(s) disconnect. Same as -many
\n
"
"-timeout n Exit unless a client connects within the first n seconds
\n
"
" of startup.
\n
"
"-inetd Launched by inetd(1): stdio instead of listening socket.
\n
"
" Note: if you are not redirecting stderr to a log file
\n
"
" (via shell 2> or -o option) you must also specify the
\n
"
...
...
@@ -14799,9 +15707,9 @@ static void print_help(void) {
" with -nocursor, and also some values of the
\"
mode
\"\n
"
" option below.
\n
"
"
\n
"
" Note that under XFIXES cursors with transparency
\n
"
"
(alpha channel) will not be exactly represented and
\n
"
"
so Overlay may be preferred
. See also the -alphacut
\n
"
" Note that under XFIXES cursors with transparency
(alpha
\n
"
"
channel) will not be exactly represented and one may
\n
"
"
find Overlay may be preferable
. See also the -alphacut
\n
"
" and -alphafrac options below as fudge factors to try
\n
"
" to improve the situation for cursors with transparency
\n
"
" for a given theme.
\n
"
...
...
@@ -14860,14 +15768,14 @@ static void print_help(void) {
" black background). Specify this option to remove the
\n
"
" alpha factor. (useful for light colored semi-transparent
\n
"
" cursors).
\n
"
"-
alphablend In XFIXES mode send cursor alpha channel data to
\n
"
"
libvncserver. The blending effect will only b
e
\n
"
"
visible in -nocursorshape mode or for clients with
\n
"
"
cursorshapeupdates turned off. (However there is a
\n
"
"
hack for 32bpp with depth 24, it uses the extra 8 bits
\n
"
"
to store cursor transparency for use with a hacked
\n
"
"
vncviewer that applies the transparency locally.
\n
"
" See the FAQ for more info).
\n
"
"-
noalphablend In XFIXES mode do not send cursor alpha channel data
\n
"
"
to libvncserver. The default is to send it. Th
e
\n
"
"
alphablend effect will only be visible in -nocursorshape
\n
"
"
mode or for clients with cursorshapeupdates turned
\n
"
"
off. (However there is a hack for 32bpp with depth 24,
\n
"
"
it uses the extra 8 bits to store cursor transparency
\n
"
"
for use with a hacked vncviewer that applies the
\n
"
"
transparency locally.
See the FAQ for more info).
\n
"
"
\n
"
"-nocursorshape Do not use the TightVNC CursorShapeUpdates extension
\n
"
" even if clients support it. See -cursor above.
\n
"
...
...
@@ -15131,6 +16039,9 @@ static void print_help(void) {
" noshared disable -shared mode.
\n
"
" forever enable -forever mode.
\n
"
" noforever disable -forever mode.
\n
"
" timeout:n reset -timeout to n, if there are
\n
"
" currently no clients, exit unless one
\n
"
" connects in the next n secs.
\n
"
" deny deny any new connections, same as
\"
lock
\"\n
"
" nodeny allow new connections, same as
\"
unlock
\"\n
"
" connect:host do reverse connection to host,
\"
host
\"\n
"
...
...
@@ -15214,8 +16125,8 @@ static void print_help(void) {
" alphafrac:f set -alphafrac to f.
\n
"
" alpharemove enable -alpharemove mode.
\n
"
" noalpharemove disable -alpharemove mode.
\n
"
" alphablend
enable -
alphablend mode.
\n
"
" noalphablend
disable -
alphablend mode.
\n
"
" alphablend
disable -no
alphablend mode.
\n
"
" noalphablend
enable -no
alphablend mode.
\n
"
" cursorshape disable -nocursorshape mode.
\n
"
" nocursorshape enable -nocursorshape mode.
\n
"
" cursorpos disable -nocursorpos mode.
\n
"
...
...
@@ -15307,8 +16218,8 @@ static void print_help(void) {
" nowaitmapped flashcmap noflashcmap truecolor notruecolor
\n
"
" overlay nooverlay overlay_cursor overlay_yescursor
\n
"
" nooverlay_nocursor nooverlay_cursor nooverlay_yescursor
\n
"
" overlay_nocursor visual scale viewonly noviewonly
\n
"
"
shared noshared forever noforever once
deny lock nodeny
\n
"
" overlay_nocursor visual scale viewonly noviewonly
shared
\n
"
"
noshared forever noforever once timeout
deny lock nodeny
\n
"
" unlock connect allowonce allow localhost nolocalhost
\n
"
" accept gone shm noshm flipbyteorder noflipbyteorder
\n
"
" onetile noonetile blackout xinerama noxinerama xrandr
\n
"
...
...
@@ -15330,16 +16241,16 @@ static void print_help(void) {
" noalwaysshared nevershared noalwaysshared dontdisconnect
\n
"
" nodontdisconnect desktop noremote
\n
"
"
\n
"
" aro= display vncdisplay desktopname
auth rootshift
\n
"
"
scale_str scaled_x scaled_y scale_numer scale_denom
\n
"
" scale_
fac scaling_noblend scaling_nomult4 scaling_pad
\n
"
" scaling_
interpolate inetd safer unsafe passwdfil
e
\n
"
"
using_shm logfile o rc norc h help V version lastmod
\n
"
"
bg sigpipe threads clients client_count pid ext_xtest
\n
"
" ext_x
kb ext_xshm ext_xinerama ext_overlay ext_xfixes
\n
"
" ext_x
damage ext_xrandr rootwin num_buttons button_mask
\n
"
"
mouse_x mouse_y bpp depth indexed_color dpy_x dpy_y
\n
"
" rfbauth passwd
\n
"
" aro= display vncdisplay desktopname
http_url auth
\n
"
"
rootshift scale_str scaled_x scaled_y scale_numer
\n
"
" scale_
denom scale_fac scaling_noblend scaling_nomult4
\n
"
" scaling_
pad scaling_interpolate inetd safer unsaf
e
\n
"
"
passwdfile using_shm logfile o rc norc h help V version
\n
"
"
lastmod bg sigpipe threads clients client_count pid
\n
"
" ext_x
test ext_xkb ext_xshm ext_xinerama ext_overlay
\n
"
" ext_x
fixes ext_xdamage ext_xrandr rootwin num_buttons
\n
"
"
button_mask mouse_x mouse_y bpp depth indexed_color
\n
"
"
dpy_x dpy_y
rfbauth passwd
\n
"
"
\n
"
"-sync By default -remote commands are run asynchronously, that
\n
"
" is, the request is posted and the program immediately
\n
"
...
...
@@ -15392,6 +16303,25 @@ static void print_help(void) {
"
\n
"
"These options are passed to libvncserver:
\n
"
"
\n
"
;
//" It also sets -xwarppointer, use -noxwarppointer to undo.\n"
char
help2
[]
=
"but first, here are some experimental ones (your version may not have them):
\n
"
"
\n
"
"-d Turn on debugging and stats output.
\n
"
"-naptile n Cutoff/max number of tile changes per poll to permit
\n
"
" a nap between polls. Use 0 to disable. Default %d
\n
"
"-napfac n Factor by which to multiply the wait ms (see -wait)
\n
"
" to get the nap time. Default: %d times waitms
\n
"
"-napmax time Maximum time in ms for a nap. Default: %d
\n
"
#ifdef VCR_HACK
"-vcr Vertical CopyRect. Enable an experimental hack to detect
\n
"
" vertical displacements (i.e. scrolls) and send them
\n
"
" using the very efficient CopyRect encoding. UNSTABLE!
\n
"
#endif
"
\n
"
"These options are passed to libvncserver:
\n
"
"
\n
"
;
/* have both our help and rfbUsage to stdout for more(1), etc. */
dup2
(
1
,
2
);
...
...
@@ -15417,6 +16347,9 @@ static void print_help(void) {
tile_fuzz
,
""
);
if
(
getenv
(
"X11VNC_STD_HELP"
)
==
NULL
)
{
fprintf
(
stderr
,
help2
,
naptile
,
napfac
,
napmax
);
}
rfbUsage
();
exit
(
1
);
...
...
@@ -15722,6 +16655,9 @@ static void check_rcfile(int argc, char **argv) {
exit
(
1
);
}
}
for
(
i
=
0
;
i
<
argc2
;
i
++
)
{
// fprintf(stderr, "argv2[%d] \"%s\"\n", i, argv2[i]);
}
}
int
main
(
int
argc
,
char
*
argv
[])
{
...
...
@@ -15816,6 +16752,8 @@ int main(int argc, char* argv[]) {
}
}
else
if
(
!
strcmp
(
arg
,
"-waitmapped"
))
{
subwin_wait_mapped
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-nosu"
))
{
no_su
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-flashcmap"
))
{
flash_cmap
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-notruecolor"
))
{
...
...
@@ -15842,6 +16780,9 @@ int main(int argc, char* argv[]) {
connect_once
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-many"
)
||
!
strcmp
(
arg
,
"-forever"
))
{
connect_once
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-timeout"
))
{
CHECK_ARGC
first_conn_timeout
=
atoi
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
arg
,
"-inetd"
))
{
inetd
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-connect"
))
{
...
...
@@ -15993,8 +16934,8 @@ int main(int argc, char* argv[]) {
alpha_frac
=
atof
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
arg
,
"-alpharemove"
))
{
alpha_remove
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-alphablend"
))
{
alpha_blend
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-
no
alphablend"
))
{
alpha_blend
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-nocursorshape"
))
{
cursor_shape_updates
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-cursorpos"
))
{
...
...
@@ -16113,6 +17054,21 @@ int main(int argc, char* argv[]) {
safe_remote_only
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-deny_all"
))
{
deny_all
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-d"
)
||
!
strcmp
(
arg
,
"-debug"
))
{
debug
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-naptile"
))
{
CHECK_ARGC
naptile
=
atoi
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
arg
,
"-napfac"
))
{
CHECK_ARGC
napfac
=
atoi
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
arg
,
"-napmax"
))
{
CHECK_ARGC
napmax
=
atoi
(
argv
[
++
i
]);
#ifdef VCR_HACK
}
else
if
(
!
strcmp
(
arg
,
"-vcr"
))
{
vcopyrect
=
1
;
#endif
}
else
if
(
!
strcmp
(
arg
,
"-httpdir"
))
{
CHECK_ARGC
http_dir
=
strdup
(
argv
[
++
i
]);
...
...
@@ -16381,6 +17337,7 @@ int main(int argc, char* argv[]) {
fprintf
(
stderr
,
" viewonly: %d
\n
"
,
view_only
);
fprintf
(
stderr
,
" shared: %d
\n
"
,
shared
);
fprintf
(
stderr
,
" conn_once: %d
\n
"
,
connect_once
);
fprintf
(
stderr
,
" timeout: %d
\n
"
,
first_conn_timeout
);
fprintf
(
stderr
,
" inetd: %d
\n
"
,
inetd
);
fprintf
(
stderr
,
" connect: %s
\n
"
,
client_connect
?
client_connect
:
"null"
);
...
...
@@ -16409,7 +17366,7 @@ int main(int argc, char* argv[]) {
fprintf
(
stderr
,
" logfile: %s
\n
"
,
logfile
?
logfile
:
"null"
);
fprintf
(
stderr
,
" logappend: %d
\n
"
,
logfile_append
);
fprintf
(
stderr
,
" rc_file: %s
\n
"
,
rc_rcfile
?
rc_rcfile
fprintf
(
stderr
,
" rc_file:
\
%s
\n
"
,
rc_rcfile
?
rc_rcfile
:
"null"
);
fprintf
(
stderr
,
" norc: %d
\n
"
,
rc_norc
);
fprintf
(
stderr
,
" bg: %d
\n
"
,
bg
);
...
...
@@ -16455,6 +17412,8 @@ int main(int argc, char* argv[]) {
fprintf
(
stderr
,
" sb: %d
\n
"
,
screen_blank
);
fprintf
(
stderr
,
" sigpipe: %s
\n
"
,
sigpipe
?
sigpipe
:
"null"
);
fprintf
(
stderr
,
" nap t-f-m: %d/%d/%d
\n
"
,
naptile
,
napfac
,
napmax
);
fprintf
(
stderr
,
" threads: %d
\n
"
,
use_threads
);
fprintf
(
stderr
,
" fs_frac: %.2f
\n
"
,
fs_frac
);
fprintf
(
stderr
,
" gaps_fill: %d
\n
"
,
gaps_fill
);
...
...
@@ -16467,6 +17426,7 @@ int main(int argc, char* argv[]) {
fprintf
(
stderr
,
" noremote: %d
\n
"
,
!
accept_remote_cmds
);
fprintf
(
stderr
,
" safemode: %d
\n
"
,
safe_remote_only
);
fprintf
(
stderr
,
" deny_all: %d
\n
"
,
deny_all
);
fprintf
(
stderr
,
" debug: %d
\n
"
,
debug
);
fprintf
(
stderr
,
"
\n
"
);
rfbLog
(
"x11vnc version: %s
\n
"
,
lastmod
);
}
else
{
...
...
@@ -16514,6 +17474,26 @@ int main(int argc, char* argv[]) {
dpy
=
XOpenDisplay
(
""
);
}
if
(
!
dpy
&&
!
use_dpy
&&
!
getenv
(
"DISPLAY"
))
{
int
i
,
s
=
4
;
rfbLog
(
"
\a\n
"
);
rfbLog
(
"*** XOpenDisplay failed. No -display or DISPLAY.
\n
"
);
rfbLog
(
"*** Trying
\"
:0
\"
in %d seconds. Press Ctrl-C to"
" abort.
\n
"
,
s
);
rfbLog
(
"*** "
);
for
(
i
=
1
;
i
<=
s
;
i
++
)
{
fprintf
(
stderr
,
"%d "
,
i
);
sleep
(
1
);
}
fprintf
(
stderr
,
"
\n
"
);
use_dpy
=
":0"
;
dpy
=
XOpenDisplay
(
use_dpy
);
if
(
dpy
)
{
rfbLog
(
"*** XOpenDisplay of
\"
:0
\"
successful.
\n
"
);
}
rfbLog
(
"
\n
"
);
}
if
(
!
dpy
)
{
rfbLog
(
"XOpenDisplay failed (%s)
\n
"
,
use_dpy
?
use_dpy
:
"null"
);
exit
(
1
);
...
...
@@ -16760,6 +17740,11 @@ int main(int argc, char* argv[]) {
initialize_signals
();
#ifdef VCR_HACK
if
(
vcopyrect
)
{
initialize_vcr
();
}
#endif
initialize_speeds
();
...
...
@@ -16813,3 +17798,1009 @@ int main(int argc, char* argv[]) {
#undef argv
}
/* -- vcr.c -- */
/* ######################################################################## */
/* experiment to look for vertical copy rect changes */
#ifdef VCR_HACK
/*
* vcr_send()
* Takes the copyrect info (currently limited to a single column of
* changed tiles) and schedules the CopyRegion with libvncserver.
*/
static
void
vcr_send
(
int
x0
,
int
y0
,
int
x1
,
int
y1
,
int
del
)
{
sraRegionPtr
copy_region
;
copy_region
=
(
sraRegionPtr
)
sraRgnCreateRect
(
x0
,
y0
,
x1
,
y1
);
rfbScheduleCopyRegion
(
screen
,
copy_region
,
0
,
del
);
sraRgnDestroy
(
copy_region
);
}
/*
* vcr_flush2()
* Current hack to try to force libvncserver to flush the copyRegion
* changes. It splits up the deferUpdateTime into time slices and
* tries to force the rfbSendUpdateBuf for each connected client.
*
* mode = 0 means just try to flush all the copyRegion changes.
* mode = 1 means try to flush both the copyRegion and modifiedRegion changes.
*/
static
void
vcr_flush2
(
int
mode
)
{
int
k1
,
k2
,
j
,
n
,
nfac
=
10
;
rfbClientIteratorPtr
i
;
rfbClientPtr
cl
;
fprintf
(
stderr
,
"vcr_flush2 "
);
/* break up the time into ~nfac slices. */
n
=
screen
->
deferUpdateTime
/
nfac
;
for
(
j
=
0
;
j
<
nfac
+
3
;
j
++
)
{
/* loop over each time slice */
fprintf
(
stderr
,
"."
);
usleep
(
n
*
1000
);
/* give rfbProcessEvents a shot. */
rfbPE
(
screen
,
0
);
/*
* loop over connected clients and examine
* their copyRegion/modifiedRegion regions
* if they exist, try to flush them.
*/
i
=
rfbGetClientIterator
(
screen
);
k1
=
0
;
k2
=
0
;
while
(
(
cl
=
rfbClientIteratorNext
(
i
))
)
{
/* check modifiedRegion */
if
(
sraRgnEmpty
(
cl
->
modifiedRegion
))
{
fprintf
(
stderr
,
" MOD=empty "
);
}
else
{
fprintf
(
stderr
,
" MOD=NOT "
);
if
(
mode
==
1
)
{
rfbSendUpdateBuf
(
cl
);
}
k2
++
;
}
/* check copyRegion */
if
(
sraRgnEmpty
(
cl
->
copyRegion
))
{
fprintf
(
stderr
,
" CR=empty "
);
}
else
{
fprintf
(
stderr
,
" CR=NOT "
);
rfbSendUpdateBuf
(
cl
);
k1
++
;
}
}
rfbReleaseClientIterator
(
i
);
if
(
mode
==
0
)
{
if
(
k1
==
0
)
{
break
;
}
}
else
if
(
mode
==
1
)
{
if
(
k1
==
0
&&
k2
==
0
)
{
break
;
}
}
}
fprintf
(
stderr
,
" k1=%d/k2=%d
\n
"
,
k1
,
k2
);
}
/*
* vcr_flush1()
* simple try; didn't work.
static void vcr_flush1(int mode) {
rfbPE(screen, 0);
}
*/
/* flush wrapper */
static
void
vcr_flush
(
int
mode
)
{
vcr_flush2
(
mode
);
}
/*
* A structure to describe a discovered vertical translation within
* a pair of old/new vertical scanlines.
*/
typedef
struct
displacement
{
int
runlen
;
/* how long the "best" concidence run was */
int
longruns
;
/* how many "long" runs we found altogether */
int
disp
;
/* the verticle displacement of the best run */
int
top
;
/* the top (smallest y-pixel position) */
int
mid
;
/* the middle y-pixel position */
int
bot
;
/* the bottom (highest y-pixel position) */
}
disp_t
;
/*
* A structure for the actual copyrect we find for a bunch of adjacent
* vertical scanlines with the same offest del.
*
* Currently used for a copyrect only within one column of changed
* tiles. libvncserver seems to be pretty good at gluing them
* together horizontally, so we don't bother, but we could use
* this for that too, x1 - x0 would just be bigger.
*/
typedef
struct
copyrect
{
int
x0
;
int
y0
;
int
x1
;
int
y1
;
int
del
;
}
copyrect_t
;
/*
* vcr_run()
* Given a column (at tile column x) of n_run changed tiles with tile
* column y-values y_run[n_run], try to find the offset with optimal
* pixel coincidence/overlap.
*
* Optimal usually means the set of scanlines with same offset giving
* the longest run of coincidence. But see suggested_disp below...
*
* If suggested_disp != 0, that means that vertical displacement is
* highly preferred, presumably being the results found from vcr_run
* for neighboring columns of changed tiles. suggested_disp is a hint
* from do_vcr().
*
* The optimal displacement copyrect is for the tile column is returned
* in the copyrect_t cr.
*/
static
int
vcr_run
(
int
*
y_run
,
int
x
,
int
n_run
,
copyrect_t
*
cr
,
int
suggested_disp
)
{
/* parameter to skip short columns of changed tiles */
int
tile_run_min
=
4
;
/* minimum number of coincident y-pixels to be accepted */
int
match_run_min
=
3
*
tile_y
;
/* variables for the search */
int
x0
,
y0
,
yd
,
del
,
prev_del
;
int
run_up
,
run_dn
,
run
;
int
col
,
n0
;
int
x_left
,
x_right
;
int
y_top
,
y_bot
;
int
i
,
best
;
int
y_min
,
y_max
,
y_mid
;
/* tmp pointers to the old and new vertical scanline fb data */
// int *fb_old;
// int *fb_new;
char
*
fb_old8
;
char
*
fb_new8
;
short
*
fb_old16
;
short
*
fb_new16
;
int
*
fb_old32
;
int
*
fb_new32
;
/* we need a disp_t for each vertical scanline in the tile column */
disp_t
verts
[
VCR_DEPTH
];
if
(
suggested_disp
)
{
fprintf
(
stderr
,
"IN vcr_run col=%2d/%3d row=%2d/%3d tn=%2d nr=%2d pref=%3d
\n
"
,
x
,
x
*
tile_x
,
y_run
[
0
],
y_run
[
0
]
*
tile_y
,
y_run
[
n_run
-
1
],
n_run
,
suggested_disp
);
}
if
(
!
suggested_disp
)
{
/* get out if the run is too short */
if
(
n_run
<
tile_run_min
)
{
if
(
suggested_disp
)
fprintf
(
stderr
,
"OUT vcr_run A
\n
"
);
return
0
;
}
}
else
{
/* be more tolerant of short columns if suggested_disp given */
if
(
n_run
<
tile_run_min
/
2
)
{
if
(
suggested_disp
)
fprintf
(
stderr
,
"OUT vcr_run B
\n
"
);
return
0
;
}
match_run_min
/=
2
;
}
/* initialize each vert scanline to "nothing found" */
for
(
col
=
0
;
col
<
vcr_depth
;
col
++
)
{
verts
[
col
].
runlen
=
0
;
verts
[
col
].
disp
=
0
;
verts
[
col
].
top
=
-
1
;
verts
[
col
].
mid
=
-
1
;
verts
[
col
].
bot
=
-
1
;
verts
[
col
].
longruns
=
0
;
}
/*
* best will be the run length (number of coincident pixels) for
* for out "best find" so far.
*/
best
=
-
1
;
/* we start out in the middle of the tile column and work outwards */
n0
=
n_run
/
2
;
/* y-tile # in run */
y0
=
y_run
[
n0
]
*
tile_y
;
/* pixel position on screen */
/* little shift to y-middle of a tile if n_run is not even */
if
(
n_run
%
2
!=
0
)
{
y0
+=
tile_y
/
2
;
}
/* horizontal pixel position of left edge of tile column */
x0
=
x
*
tile_x
;
/* lowest possible y of the tile column */
y_min
=
y_run
[
0
]
*
tile_y
;
/* highest possible y of the tile column */
y_max
=
(
y_run
[
n_run
-
1
]
+
1
)
*
tile_y
;
fprintf
(
stderr
,
" vcr_run: x== %d
\n
"
,
x
);
/*
* Loop over each vertical scanline, using the vcr_map pattern
* for the order.
*/
for
(
col
=
0
;
col
<
vcr_depth
;
col
++
)
{
/*
* Make pointers to offsets in the before/after vertical
* scanline fb data for the desired scanline.
* (Note: the whole scanline need not be up to date,
* but it is up to date for the changed tile column
* considered here)
*/
if
(
bpp
==
32
)
{
fb_old32
=
fbd_old32
[
x
][
col
];
fb_new32
=
fbd_new32
[
x
][
col
];
}
else
if
(
bpp
==
16
)
{
fb_old16
=
fbd_old16
[
x
][
col
];
fb_new16
=
fbd_new16
[
x
][
col
];
}
else
if
(
bpp
==
8
)
{
fb_old8
=
fbd_old8
[
x
][
col
];
fb_new8
=
fbd_new8
[
x
][
col
];
}
/* start at the middle y-value */
y_mid
=
y0
;
/*
* check if a previous scanline found a displacment
* with high coincidence. store it in prev_del.
* also use its y_mid value.
*/
prev_del
=
0
;
for
(
i
=
col
-
1
;
i
>=
0
;
i
--
)
{
if
(
verts
[
i
].
runlen
>
0
)
{
y_mid
=
verts
[
i
].
mid
;
prev_del
=
verts
[
i
].
disp
;
break
;
}
}
/*
* Now loop over all possible displacements between
* the old and new vertical scanlines.
* That is, y_mid + del < y_max and y_mid - del >
* y_min for relative displacement del.
*
* We work out way out +/- from y_mid (trying to avoid
* ambiguities at the top or bottom of the tile column).
*/
for
(
del
=
1
;
y_mid
+
del
<
y_max
||
y_mid
-
del
>
y_min
;
del
++
)
{
int
i
;
for
(
i
=
0
;
i
<=
1
;
i
++
)
{
/* this is just the +/- plus/minux del aspect */
int
d
=
(
1
-
2
*
i
)
*
del
;
if
(
prev_del
!=
0
&&
d
!=
prev_del
)
{
/*
* If we have a previous del, we want
* to stick to it to greatly shorten
* the time spent in this loop.
*
* But if we have a suggested_disp we
* let that drop through.
*/
if
(
d
!=
suggested_disp
)
{
continue
;
}
}
/*
* Possible speedup: use longruns as a big
* clue the scanlines are basically constant
* (e.g. lies on a solid root background).
*/
if
(
suggested_disp
&&
d
!=
suggested_disp
&&
verts
[
col
].
longruns
>
4
)
{
continue
;
}
/*
* yd will be the displaced midpoint for the
* new fb fb_new.
*
* y_mid will be the midpoint of the old fb
* fb_old.
*/
yd
=
y_mid
+
d
;
if
(
yd
<=
y_min
||
yd
>=
y_max
)
{
/* out of range for fb_new */
continue
;
}
/*
* Loop upwards from these midpoints, but break
* out as soon as there is a pixel difference.
* (i.e. break out at the high-end of the
* coincidence)
*/
if
(
bpp
==
32
)
{
for
(
run_up
=
0
;
yd
+
run_up
<
y_max
&&
y_mid
+
run_up
<
y_max
;
run_up
++
)
{
if
(
*
(
fb_old32
+
(
y_mid
+
run_up
))
!=
*
(
fb_new32
+
(
yd
+
run_up
)))
{
break
;
}
}
}
/*
* Loop downwards from these midpoints, but break
* out as soon as there is a pixel difference.
* (i.e. break out at the low-end of the
* coincidence)
*
* Note: for 16bpp we really check two pixels
* at a time, for 8bpp we check 4 at a time.
*/
if
(
bpp
==
32
)
{
for
(
run_dn
=-
1
;
yd
+
run_dn
>
y_min
&&
y_mid
+
run_dn
>
y_min
;
run_dn
--
)
{
if
(
*
(
fb_old32
+
(
y_mid
+
run_dn
))
!=
*
(
fb_new32
+
(
yd
+
run_dn
)))
{
break
;
}
}
}
/* compute the total number of coincident pixels */
run
=
run_up
-
run_dn
-
1
;
if
(
run
>
match_run_min
)
{
/*
* It is long enough, add to the tally
* of long runs.
*/
verts
[
col
].
longruns
++
;
/*
* Now check if it is the longest one
* so far or matches the suggested_disp.
*
* TODO: what if d == suggested_disp is
* overridden later?
*/
if
(
run
>
verts
[
col
].
runlen
||
d
==
suggested_disp
)
{
if
(
run
>
best
)
{
/* best for any scanline */
best
=
run
;
}
/* record the best for this scanline */
verts
[
col
].
runlen
=
run
;
verts
[
col
].
disp
=
d
;
verts
[
col
].
top
=
y_mid
+
run_dn
;
verts
[
col
].
mid
=
y_mid
;
verts
[
col
].
bot
=
y_mid
+
run_up
;
}
}
}
}
}
if
(
best
<
0
)
{
/* did not find anything. */
fprintf
(
stderr
,
"vcr_run return 0, no best
\n
"
);
return
0
;
}
/*
* Now, not all of the coincidences in the vertical scanlines
* may be the same. The may start and stop at different y-values.
*
* And (we hope not, but) a single displacement may not apply
* to all of the vertical scanlines.
*
* So we loop over the scanlines and try to find
* the minimal/optimal set that applies to most of them.
*
* The result will be the basis of the copyrect rectangle
* we send to libvncserver.
*/
x_left
=
-
1
;
/* furthest left scanline x position */
x_right
=
-
1
;
/* furthest right scanline x position */
y_top
=
-
1
;
/* y-bound from the top (small y) */
y_bot
=
-
1
;
/* y-bound from the bottom (large y) */
del
=
0
;
/* the vertical displacement found */
for
(
col
=
0
;
col
<
vcr_depth
;
col
++
)
{
if
(
verts
[
col
].
runlen
<
1
)
{
/* no concidence found for this scan line */
continue
;
}
if
(
del
==
0
)
{
/* use the first one... */
del
=
verts
[
col
].
disp
;
}
else
if
(
del
!=
verts
[
col
].
disp
)
{
/*
* skip if not equal to first one
* XXX improve
*/
continue
;
}
if
(
y_top
<
0
||
verts
[
col
].
top
>
y_top
)
{
/* trim y_top to include this scanline */
y_top
=
verts
[
col
].
top
;
}
if
(
y_bot
<
0
||
verts
[
col
].
bot
<
y_bot
)
{
/* trim y_bot to include this scanline */
y_bot
=
verts
[
col
].
bot
;
}
if
(
x_left
<
0
||
vcr_map
[
col
]
<
x_left
)
{
/* hmm, correct?... */
x_left
=
vcr_map
[
col
];
}
if
(
x_right
<
0
||
vcr_map
[
col
]
>
x_right
)
{
/* hmm, correct?... */
x_right
=
vcr_map
[
col
];
}
fprintf
(
stderr
,
" vcr_run: m_match: del=%4d run=%3d ymin=%3d ymid=%3d ymax=%3d lruns=%3d col=%d
\n
"
,
verts
[
col
].
disp
,
verts
[
col
].
runlen
,
verts
[
col
].
top
,
verts
[
col
].
mid
,
verts
[
col
].
bot
,
verts
[
col
].
longruns
,
vcr_map
[
col
]);
}
if
(
del
==
0
||
x_left
==
-
1
||
x_right
==
-
1
||
y_top
==
-
1
||
y_bot
==
-
1
)
{
/* not everything agreed/made sense */
return
0
;
}
if
(
x_left
==
x_right
||
y_top
==
y_bot
)
{
/* only one scanline or no y span (line/point not a rectangle) */
return
0
;
}
fprintf
(
stderr
,
" vcr_run: x_left=%2d x_right=%2d y_top=%3d y_bot=%3d
\n
"
,
x_left
,
x_right
,
y_top
,
y_bot
);
/*
* Finally, create the copyrect_t.
* XXX these may still have off by 1 pixel errors...
*/
if
(
del
>
0
)
{
/* new fb is displaced downward from old fb */
cr
->
x0
=
x0
+
x_left
;
cr
->
y0
=
y_top
+
del
+
1
;
cr
->
x1
=
x0
+
x_right
+
1
;
cr
->
y1
=
y_bot
+
del
;
cr
->
del
=
del
;
}
else
{
/* new fb is displaced upward from old fb */
cr
->
x0
=
x0
+
x_left
;
cr
->
y0
=
y_top
+
del
+
1
;
cr
->
x1
=
x0
+
x_right
+
1
;
cr
->
y1
=
y_bot
+
del
;
cr
->
del
=
del
;
}
return
1
;
}
#define WMAX 40
/* max number of horizontal tiles */
#define YMAX 40
/* max number of vertical tiles */
/*
* char fbd_old[ntile_x][tile_x * (bpp/8)][dpy_y];
*/
void
initialize_vcr
(
void
)
{
int
i
,
j
;
if
(
bpp
==
24
)
{
rfbLog
(
"initialize_vcr: disabling -vcr in 24bpp mode
\n
"
);
vcopyrect
=
0
;
return
;
}
if
(
dpy_x
%
tile_x
!=
0
)
{
rfbLog
(
"initialize_vcr: disabling -vcr: display width is not "
"a multiple of %d
\n
"
,
tile_x
);
vcopyrect
=
0
;
return
;
}
if
(
dpy_y
%
tile_y
!=
0
)
{
rfbLog
(
"initialize_vcr: disabling -vcr: display height is not "
"a multiple of %d
\n
"
,
tile_y
);
vcopyrect
=
0
;
return
;
}
if
(
bpp
==
8
)
{
fbd_old8
=
(
char
***
)
malloc
(
ntiles_x
*
sizeof
(
char
**
));
fbd_new8
=
(
char
***
)
malloc
(
ntiles_x
*
sizeof
(
char
**
));
for
(
i
=
0
;
i
<
ntiles_x
;
i
++
)
{
fbd_old8
[
i
]
=
(
char
**
)
malloc
(
tile_x
*
sizeof
(
char
*
));
fbd_new8
[
i
]
=
(
char
**
)
malloc
(
tile_x
*
sizeof
(
char
*
));
for
(
j
=
0
;
j
<
tile_x
;
j
++
)
{
size_t
n
=
(
size_t
)
dpy_y
*
sizeof
(
char
*
);
fbd_old8
[
i
][
j
]
=
(
char
*
)
malloc
(
n
);
fbd_new8
[
i
][
j
]
=
(
char
*
)
malloc
(
n
);
}
}
/* temp array for one tile row */
fbt_old8
=
(
char
**
)
malloc
(
dpy_x
*
sizeof
(
char
*
));
fbt_new8
=
(
char
**
)
malloc
(
dpy_x
*
sizeof
(
char
*
));
for
(
i
=
0
;
i
<
dpy_x
;
i
++
)
{
size_t
n
=
(
size_t
)
tile_y
*
sizeof
(
char
*
);
fbt_old8
[
i
]
=
(
char
*
)
malloc
(
n
);
fbt_new8
[
i
]
=
(
char
*
)
malloc
(
n
);
}
}
else
if
(
bpp
==
16
)
{
fbd_old16
=
(
short
***
)
malloc
(
ntiles_x
*
sizeof
(
short
**
));
fbd_new16
=
(
short
***
)
malloc
(
ntiles_x
*
sizeof
(
short
**
));
for
(
i
=
0
;
i
<
ntiles_x
;
i
++
)
{
fbd_old16
[
i
]
=
(
short
**
)
malloc
(
tile_x
*
sizeof
(
short
*
));
fbd_new16
[
i
]
=
(
short
**
)
malloc
(
tile_x
*
sizeof
(
short
*
));
for
(
j
=
0
;
j
<
tile_x
;
j
++
)
{
size_t
n
=
(
size_t
)
dpy_y
*
sizeof
(
short
*
);
fbd_old16
[
i
][
j
]
=
(
short
*
)
malloc
(
n
);
fbd_new16
[
i
][
j
]
=
(
short
*
)
malloc
(
n
);
}
}
/* temp array for one tile row */
fbt_old16
=
(
short
**
)
malloc
(
dpy_x
*
sizeof
(
short
*
));
fbt_new16
=
(
short
**
)
malloc
(
dpy_x
*
sizeof
(
short
*
));
for
(
i
=
0
;
i
<
dpy_x
;
i
++
)
{
size_t
n
=
(
size_t
)
tile_y
*
sizeof
(
short
*
);
fbt_old16
[
i
]
=
(
short
*
)
malloc
(
n
);
fbt_new16
[
i
]
=
(
short
*
)
malloc
(
n
);
}
}
else
if
(
bpp
==
32
)
{
fbd_old32
=
(
int
***
)
malloc
(
ntiles_x
*
sizeof
(
int
**
));
fbd_new32
=
(
int
***
)
malloc
(
ntiles_x
*
sizeof
(
int
**
));
for
(
i
=
0
;
i
<
ntiles_x
;
i
++
)
{
fbd_old32
[
i
]
=
(
int
**
)
malloc
(
tile_x
*
sizeof
(
int
*
));
fbd_new32
[
i
]
=
(
int
**
)
malloc
(
tile_x
*
sizeof
(
int
*
));
for
(
j
=
0
;
j
<
tile_x
;
j
++
)
{
size_t
n
=
(
size_t
)
dpy_y
*
sizeof
(
int
*
);
fbd_old32
[
i
][
j
]
=
(
int
*
)
malloc
(
n
);
fbd_new32
[
i
][
j
]
=
(
int
*
)
malloc
(
n
);
}
}
/* temp array for one tile row */
fbt_old32
=
(
int
**
)
malloc
(
dpy_x
*
sizeof
(
int
*
));
fbt_new32
=
(
int
**
)
malloc
(
dpy_x
*
sizeof
(
int
*
));
for
(
i
=
0
;
i
<
dpy_x
;
i
++
)
{
size_t
n
=
(
size_t
)
tile_y
*
sizeof
(
int
*
);
fbt_old32
[
i
]
=
(
int
*
)
malloc
(
n
);
fbt_new32
[
i
]
=
(
int
*
)
malloc
(
n
);
}
}
else
{
vcopyrect
=
0
;
}
if
(
getenv
(
"VCR_DEPTH"
))
{
vcr_depth
=
atoi
(
getenv
(
"VCR_DEPTH"
));
fprintf
(
stderr
,
"reset vcr_depth to: %d
\n
"
,
vcr_depth
);
}
else
{
fprintf
(
stderr
,
"vcr_depth is: %d
\n
"
,
vcr_depth
);
}
}
/*
* do_vcr()
* Top level routine for the great vertical copyrect hunt.
*
* It is called shortly after the copy_tiles
* calls finish, so the vertical scan line framebuffer pixel
* data (old and new) is up to date.
*
* It only deals with tiles, looking for vertical runs of
* changed (or tried) ones. It passes off the actual
* fb pixel coincidence checking to vcr_run() and records
* wnat vcr_run finds.
*
* Finally, it determines the copyrects that need to be
* sent to libvncserver, sends them, tries to flush, etc.
*/
void
do_vcr
(
void
)
{
int
x
,
y
,
n
;
int
dx
,
pm
,
x_cm
=
0
,
y_cm
=
0
,
n_cm
=
0
;
int
got
,
in_run
=
0
,
thd
=
0
,
tt
=
0
;
int
cpr_cnt
=
0
,
suggested_disp
;
int
tile_tot
=
0
,
tile_vcr
=
0
;
static
int
vcr_sleep
=
-
1
;
/*
* y_run is an array that holds the tile y indexes
* for a vertical run of adjacent changed tiles.
*/
int
y_run
[
YMAX
];
/*
* some info for each column, x_has_diff[] says the
* column has a tile diff or tried tile somewhere
*
* disps[] records the displacement found by
* vcr_run for this column (XXX: more than one?)
*
*/
int
x_has_diff
[
WMAX
],
disps
[
WMAX
];
/* we store the found copyrects here: */
copyrect_t
cpr
[
4
*
WMAX
],
cr
;
/* zero our arrays. */
for
(
x
=
0
;
x
<
ntiles_x
;
x
++
)
{
x_has_diff
[
x
]
=
0
;
disps
[
x
]
=
0
;
}
/*
* Try to find the "center of mass" of the region of changed
* tiles. Makes the most sense if the changed tiles are
* limited to one window (or subregion of a window). Think
* of a scroll. We are trying to find the middle of the
* changed region and then work our way out from there.
*
* The thought is we have a better chance of discovering
* the "true" vertical displacement if we start in the middle
* rather than at the edges. Even if there is clutter
* around the scrolled region, this could still get us into
* the interior of it.
*/
for
(
x
=
0
;
x
<
ntiles_x
;
x
++
)
{
for
(
y
=
0
;
y
<
ntiles_y
;
y
++
)
{
n
=
x
+
y
*
ntiles_x
;
if
(
tile_has_diff
[
n
]
||
tile_tried
[
n
])
{
/*
* note that this column has a diff,
* and accumulate the cm stuff.
*/
x_has_diff
[
x
]
++
;
x_cm
+=
x
;
y_cm
+=
y
;
n_cm
++
;
}
}
}
if
(
!
n_cm
)
{
/* no changed or tried tiles. */
return
;
}
/*
* Compute center of mass. These are tile indexes, not
* pixel indexes, btw.
*
* We currently only use x_cm the "center of mass" in the
* horizontal direction. We compute y_cm but don't use it yet
*/
x_cm
=
x_cm
/
n_cm
;
y_cm
=
y_cm
/
n_cm
;
fprintf
(
stderr
,
"
\n
do_vcr() x_cm: %d y_cm: %d
\n
"
,
x_cm
,
y_cm
);
/* work our way outward from x_cm, dx is the displacement */
for
(
dx
=
0
;
dx
<=
ntiles_x
;
dx
++
)
{
/* we go +/- (plus or minus) dx */
for
(
pm
=
0
;
pm
<=
1
;
pm
++
)
{
int
x2
,
dx2
,
dx2_best
;
if
(
dx
==
0
&&
pm
==
1
)
{
/* just do dx = 0 once. */
continue
;
}
/* tile x index: */
x
=
x_cm
+
(
1
-
2
*
pm
)
*
dx
;
if
(
x
<
0
||
x
>=
ntiles_x
)
{
/* out of range... */
continue
;
}
/*
* Loop over previously tried columns of tiles looking for
* a preferred y-displacement. This will be used to speed
* up the search (later columns will aim for the same
* vertical translation... keep thinking of a scroll.)
*/
suggested_disp
=
0
;
dx2_best
=
-
1
;
for
(
x2
=
0
;
x2
<
ntiles_x
;
x2
++
)
{
if
(
!
disps
[
x2
])
{
/*
* column with nothing found or
* not yet examined.
*/
continue
;
}
dx2
=
x
-
x2
;
if
(
dx2
<
0
)
{
dx2
=
-
dx2
;
}
if
(
dx2_best
==
-
1
||
dx2
<
dx2_best
)
{
suggested_disp
=
disps
[
x2
];
dx2_best
=
dx2
;
}
}
/*
* Now loop down thru the column looking for
* changed/tried tiles that are adjacent (along y).
* A set of these will be called a "run".
*/
got
=
0
;
in_run
=
0
;
thd
=
0
;
tt
=
0
;
for
(
y
=
0
;
y
<=
ntiles_y
;
y
++
)
{
int
changed
=
0
,
end
=
0
;
n
=
x
+
y
*
ntiles_x
;
if
(
y
==
ntiles_y
)
{
end
=
1
;
}
else
if
(
tile_has_diff
[
n
]
||
tile_tried
[
n
])
{
changed
=
1
;
tile_tot
++
;
}
if
(
changed
)
{
got
++
;
if
(
tile_has_diff
[
n
])
{
thd
++
;
}
if
(
tile_tried
[
n
])
{
tt
++
;
}
if
(
!
in_run
)
{
/* start of a run */
in_run
=
1
;
}
else
{
/* continuation of a run */
in_run
++
;
}
/* store the y tile number */
y_run
[
in_run
-
1
]
=
y
;
}
else
{
/* either tile w/o diff or special end case */
if
(
!
in_run
)
{
continue
;
}
/* this could be the end of a run */
if
(
thd
<=
tt
/
10
)
{
/* not enough have real differences */
;
}
else
if
(
vcr_run
(
y_run
,
x
,
in_run
,
&
cr
,
suggested_disp
))
{
/*
* otherwise we called vcr_run
* to analyse the run. And it
* found one. Record it.
*/
cpr
[
cpr_cnt
].
x0
=
cr
.
x0
;
cpr
[
cpr_cnt
].
y0
=
cr
.
y0
;
cpr
[
cpr_cnt
].
x1
=
cr
.
x1
;
cpr
[
cpr_cnt
].
y1
=
cr
.
y1
;
cpr
[
cpr_cnt
].
del
=
cr
.
del
;
cpr_cnt
++
;
disps
[
x
]
=
cr
.
del
;
tile_vcr
+=
(
cr
.
y1
-
cr
.
y0
)
/
tile_y
;
}
if
(
got
>
3
)
fprintf
(
stderr
,
" do_vcr: run: x: %d pm=%d dx=%d got=%d thd=%d tt=%d in_run=%d
\n
"
,
x
,
pm
,
dx
,
got
,
thd
,
tt
,
in_run
);
/* get ready for a new run */
got
=
0
;
in_run
=
0
;
thd
=
0
;
tt
=
0
;
}
}
}
}
if
(
tile_vcr
)
fprintf
(
stderr
,
" do_vcr: tile_vcr/tile_tot: %d/%d
\n
"
,
tile_vcr
,
tile_tot
);
if
(
cpr_cnt
)
{
/* we got some copyrects! */
int
i
,
j
,
ndel
,
del_shift
[
100
],
del_cnt
[
100
];
int
willdo
=
0
,
min_cnt
=
4
;
int
x
,
y
,
n
;
sraRegionPtr
tmp_region
,
mod_region
;
/*
* There there is too much clutter from other tiles w/o
* a vcr, bail out to try to avoid painting errors.
*/
if
(
tile_vcr
<
0
.
5
*
tile_tot
)
{
fprintf
(
stderr
,
"bad tile_vcr SNR.
\n
"
);
return
;
}
/*
* First tally and do some bookkeepping regarding the
* different y-displacements. Hopefully most of the
* time there will be just one displacement.
*
* One has to take some care... if we send libvncserver
* different displacements, it may treat some of them
* as modifiedRegions instead of copyRegions.
*/
ndel
=
0
;
for
(
i
=
0
;
i
<
cpr_cnt
;
i
++
)
{
int
got
=
0
;
int
d
=
cpr
[
i
].
del
;
for
(
j
=
0
;
j
<
ndel
;
j
++
)
{
if
(
del_shift
[
j
]
==
d
)
{
/*
* a duplicate with the same del
* record it.
*/
del_cnt
[
j
]
++
;
if
(
del_cnt
[
j
]
>=
min_cnt
)
{
/* we know we have least one */
willdo
=
1
;
}
got
=
1
;
}
}
if
(
!
got
)
{
/* no dup, so set it */
del_cnt
[
ndel
]
=
1
;
del_shift
[
ndel
++
]
=
d
;
}
}
fprintf
(
stderr
,
"
\n
"
);
if
(
!
willdo
)
{
fprintf
(
stderr
,
"no willdo, return
\n
"
);
return
;
}
/* now use willdo to count number of different dels */
willdo
=
0
;
for
(
j
=
0
;
j
<
ndel
;
j
++
)
{
int
d
=
del_shift
[
j
];
fprintf
(
stderr
,
"del: %d/%d del_cnt: %d
\n
"
,
d
,
ndel
,
del_cnt
[
j
]);
if
(
del_cnt
[
j
]
>=
min_cnt
)
{
willdo
++
;
}
}
fprintf
(
stderr
,
"willdo number of dels: %d
\n
"
,
willdo
);
/*
* We noted above that we will do at least one copyrect.
* So we prepare a region of all of the changed/tried
* tiles that we can subtract the copyRegion from, etc.
*/
mod_region
=
(
sraRegionPtr
)
sraRgnCreate
();
for
(
x
=
0
;
x
<
ntiles_x
;
x
++
)
{
for
(
y
=
0
;
y
<
ntiles_y
;
y
++
)
{
n
=
x
+
y
*
ntiles_x
;
if
(
!
tile_has_diff
[
n
]
&&
!
tile_tried
[
n
])
{
continue
;
}
/* XXX optimize this somehow? */
tmp_region
=
(
sraRegionPtr
)
sraRgnCreateRect
(
x
*
tile_x
,
y
*
tile_x
,
(
x
+
1
)
*
tile_x
,
(
y
+
1
)
*
tile_y
);
sraRgnOr
(
mod_region
,
tmp_region
);
sraRgnDestroy
(
tmp_region
);
}
}
fprintf
(
stderr
,
"
\n
"
);
/*
* vcr_change_region will be the region corresponding to
* all of our discovered copyrects.
*/
if
(
vcr_change_region
)
{
sraRgnDestroy
(
vcr_change_region
);
}
vcr_change_region
=
(
sraRegionPtr
)
sraRgnCreate
();
if
(
vcr_mod_region
)
{
sraRgnDestroy
(
vcr_mod_region
);
}
vcr_mod_region
=
NULL
;
/*
* Now we go over the different del's (hopefully just
* one) and send the copyrects with the same del out to
* libvncserver and try to XXX
*/
for
(
j
=
0
;
j
<
ndel
;
j
++
)
{
int
d
=
del_shift
[
j
];
if
(
del_cnt
[
j
]
<
min_cnt
)
{
/* too short */
continue
;
}
for
(
i
=
0
;
i
<
cpr_cnt
;
i
++
)
{
if
(
cpr
[
i
].
del
!=
d
)
{
continue
;
}
tmp_region
=
(
sraRegionPtr
)
sraRgnCreateRect
(
cpr
[
i
].
x0
,
cpr
[
i
].
y0
+
cpr
[
i
].
del
,
cpr
[
i
].
x1
,
cpr
[
i
].
y1
+
cpr
[
i
].
del
);
/*
* subtract this from our modifiedRegion
* (see below).
*/
sraRgnSubtract
(
mod_region
,
tmp_region
);
sraRgnOr
(
vcr_change_region
,
tmp_region
);
sraRgnDestroy
(
tmp_region
);
/* tell libvncserver about the copyrect. */
vcr_send
(
cpr
[
i
].
x0
,
cpr
[
i
].
y0
,
cpr
[
i
].
x1
,
cpr
[
i
].
y1
,
cpr
[
i
].
del
);
fprintf
(
stderr
,
"del: %d x0=%3d y0=%3d x1=%3d y1=%3d
\n
"
,
cpr
[
i
].
del
,
cpr
[
i
].
x0
,
cpr
[
i
].
y0
,
cpr
[
i
].
x1
,
cpr
[
i
].
y1
);
}
if
(
willdo
>
1
)
{
/* if more than 1 delta, must flush each one */
vcr_flush
(
0
);
}
}
/*
* tell libvncserver to now flush the modified region
* outside of the copyrect region.
*/
fprintf
(
stderr
,
"rfbMarkRegionAsModified
\n
"
);
rfbMarkRegionAsModified
(
screen
,
mod_region
);
fprintf
(
stderr
,
"vcr_flush for mod_region
\n
"
);
vcr_flush
(
1
);
vcr_mod_region
=
(
sraRegionPtr
)
sraRgnCreateRgn
(
mod_region
);
sraRgnDestroy
(
mod_region
);
rfbPE
(
screen
,
0
);
/* hack to sleep */
if
(
vcr_sleep
<
0
||
vcr_sleep
==
1
)
{
if
(
getenv
(
"VCR_SLEEP"
)
!=
NULL
)
{
vcr_sleep
=
1
;
fprintf
(
stderr
,
"sleep...
\n
"
);
sleep
(
atoi
(
getenv
(
"VCR_SLEEP"
)));
}
else
{
vcr_sleep
=
0
;
}
}
fprintf
(
stderr
,
"done...
\n
"
);
}
}
#endif
/* VCR_HACK */
/* ######################################################################## */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment