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
52ba8bfb
Commit
52ba8bfb
authored
Aug 30, 2004
by
runge
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
x11vnc: -cursor change shape handling, configure.ac: add more macros for X extensions
parent
3a4f41f6
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1653 additions
and
863 deletions
+1653
-863
ChangeLog
ChangeLog
+6
-0
configure.ac
configure.ac
+52
-19
ChangeLog
x11vnc/ChangeLog
+9
-0
README
x11vnc/README
+160
-69
x11vnc.1
x11vnc/x11vnc.1
+114
-47
x11vnc.c
x11vnc/x11vnc.c
+1312
-728
No files found.
ChangeLog
View file @
52ba8bfb
2004-08-29 Karl Runge <runge@karlrunge.com>
* x11vnc: changes in cursor shape handling: use rfbSetCursor()
* cursor shape options: -cursor, -cursor (X|some|most)
* -vncconnect the default.
* configure.ac: add more macros for X extensions.
2004-08-15 Karl Runge <runge@karlrunge.com>
* x11vnc: -overlay to fix colors with Sun 8+24 overlay visuals.
* -sid option.
...
...
configure.ac
View file @
52ba8bfb
...
...
@@ -39,9 +39,30 @@ AM_CONDITIONAL(WITH_FFMPEG, test ! -z "$with_ffmpeg")
# Checks for X libraries
HAVE_X="false"
AC_PATH_XTRA
AH_TEMPLATE(HAVE_XSHM, [MIT-SHM extension build environment present])
AH_TEMPLATE(HAVE_XTEST, [XTEST extension build environment present])
AH_TEMPLATE(HAVE_XKEYBOARD, [XKEYBOARD extension build environment present])
AH_TEMPLATE(HAVE_LIBXINERAMA, [XINERAMA extension build environment present])
AH_TEMPLATE(HAVE_LIBXRANDR, [XRANDR extension build environment present])
AH_TEMPLATE(HAVE_LIBXFIXES, [XFIXES extension build environment present])
AH_TEMPLATE(HAVE_LIBXDAMAGE, [XDAMAGE extension build environment present])
if test "$X_CFLAGS" != "-DX_DISPLAY_MISSING"; then
AC_CHECK_LIB(X11, XGetImage, HAVE_X="true",
HAVE_X="false",
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
if test $HAVE_X = "true"; then
X_PRELIBS="$X_PRELIBS -lXext"
AC_CHECK_LIB(Xext, XShmGetImage,
[AC_DEFINE(HAVE_XSHM)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
AC_CHECK_LIB(Xtst, XTestFakeKeyEvent,
X_PRELIBS="$X_PRELIBS -lXtst"
[AC_DEFINE(HAVE_XTEST)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
AC_CHECK_HEADER(X11/XKBlib.h, HAVE_XKBLIB_H="true",
...
...
@@ -52,16 +73,28 @@ if test "$X_CFLAGS" != "-DX_DISPLAY_MISSING"; then
[AC_DEFINE(HAVE_XKEYBOARD)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
fi
AC_CHECK_LIB(Xinerama, XineramaQueryScreens,
X_PRELIBS="$X_PRELIBS -lXinerama"
[AC_DEFINE(HAVE_LIBXINERAMA)], ,
$X_LIBS $X_PRELIBS -lX11 -lXext $X_EXTRA_LIBS)
AC_CHECK_LIB(Xtst, XTestFakeKeyEvent, HAVE_XTEST="true",
HAVE_XTEST="false",
$X_LIBS $X_PRELIBS -lX11 -lXext $X_EXTRA_LIBS)
if test $HAVE_XTEST = "true"; then
X_LIBS="$X_LIBS $X_PRELIBS -lXtst -lXext -lX11 $X_EXTRA_LIBS"
HAVE_X="true"
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
AC_CHECK_LIB(Xrandr, XRRSelectInput,
X_PRELIBS="$X_PRELIBS -lXrandr"
[AC_DEFINE(HAVE_LIBXRANDR)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
AC_CHECK_LIB(Xfixes, XFixesGetCursorImage,
X_PRELIBS="$X_PRELIBS -lXfixes"
[AC_DEFINE(HAVE_LIBXFIXES)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
AC_CHECK_LIB(Xdamage, XDamageQueryExtension,
X_PRELIBS="$X_PRELIBS -lXdamage"
[AC_DEFINE(HAVE_LIBXDAMAGE)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
X_LIBS="$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS"
fi
fi
AC_SUBST(X_LIBS)
...
...
x11vnc/ChangeLog
View file @
52ba8bfb
2004-08-29 Karl Runge <runge@karlrunge.com>
* remove old mouse patch code, now use rfbSetCursor (+ workarounds)
* changed cursor shape options (no more -mouse, ...) to '-cursor mode'
where 'mode' can be empty "X", "some", or "most". "some" adds
heuristics for two more cursors.
* -nocursorshape added.
* ifdef checks for XSHM and XTEST. Add *_wr wrappers as well.
* -vncconnect is now the default.
2004-08-15 Karl Runge <runge@karlrunge.com>
* -overlay option to fix color problems on Sun machines with 8+24
and 24+8 overlay visuals, uses Solaris XReadScreen().
...
...
x11vnc/README
View file @
52ba8bfb
x11vnc
README
file
Date
:
Sun
Aug
15
16
:
30
:
33
EDT
2004
x11vnc
README
file
Date
:
Sun
Aug
29
15
:
33
:
42
EDT
2004
The
following
information
is
taken
from
these
URLs
:
...
...
@@ -345,6 +345,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"
# Everything needs to built with _REENTRANT for thread safe errno:
CPPFLAGS="$CPPFLAGS -D_REENTRANT"
export PATH CPPFLAGS LDFLAGS
./configure
...
...
@@ -488,14 +491,16 @@ ls -l ./x11vnc/x11vnc
acceleration
at
the
physical
display
and
so
likely
defeats
the
purpose
.
Nevertheless
this
could
be
handy
in
some
circumstances
,
e
.
g
.
if
the
speed
at
the
physical
display
was
tolerable
.
Unfortunately
it
does
not
seem
shadowfb
can
't
be turned on and off
Unfortunately
it
does
not
seem
shadowfb
can
be
turned
on
and
off
dynamically
...
*
Somewhat
surprisingly
,
the
X11
mouse
(
cursor
)
shape
is
write
-
only
and
cannot
be
queried
from
the
X
server
.
So
in
x11vnc
the
cursor
shape stays fixed at an arrow. (see the -mouseX option, however,
for a partial hack for the root window). Also, on Solaris using
the SUN_OVL overlay extension, x11vnc can show the correct mouse
cursor when the -overlay is also supplied.
shape
stays
fixed
at
an
arrow
.
(
see
the
"-cursor X"
and
other
options
,
however
,
for
a
partial
hack
for
the
root
window
,
etc
.).
Also
,
on
Solaris
using
the
SUN_OVL
overlay
extension
,
x11vnc
can
show
the
correct
mouse
cursor
when
the
-
overlay
option
is
also
supplied
.
For
XFree86
/
Xorg
,
the
XFIXES
extension
should
help
this
as
well
.
*
Audio
from
applications
is
of
course
not
redirected
(
separate
redirectors
do
exist
,
e
.
g
.
esd
).
The
XBell
()
"beeps"
will
work
if
the
X
server
supports
the
XKEYBOARD
extension
.
(
Note
that
on
...
...
@@ -546,10 +551,10 @@ ls -l ./x11vnc/x11vnc
start out OK, but after a while the colors are incorrect in certain
windows.
[
36
]
Q
-
10
:
Color
problems
:
Why
are
the
colors
for
some
of
the
windows
messed
up
in
x11vnc
?
BTW
,
I
have
an
X
display
that
has
nice
overlay
visuals
of
multiple
color
depths
.
E
.
g
.
there
are
both
depth
8
and
24
visuals
available
at
the
same
time
.
[36]Q-10: Color problems: Why are the colors for some
windows messed
up in x11vnc? BTW, I have an X display that has nice
overlay/multi-depth visuals of different color depths: e.g. there are
both depth 8 and 24
visuals available at the same time.
[37]Q-11: How do I figure out the window id to supply to the -id
windowid option?
...
...
@@ -909,8 +914,8 @@ display :0
If
so
,
there
are
a
couple
options
.
1
)
Can
you
set
the
default
visual
on
your
display
to
be
depth
24
TrueColor
?
Sun
machines
often
have
8
+
24
overlay
visuals, and you can make the default visual depth 24
TrueColor (see fbconfig(1) and Xsun(1)). 2) As of Feb/2004, in the
overlay
/
multi
-
depth
visuals
,
and
you
can
make
the
default
visual
depth
24
TrueColor
(
see
fbconfig
(
1
)
and
Xsun
(
1
)).
2
)
As
of
Feb
/
2004
,
in
the
libvncserver
CVS
,
x11vnc
has
the
-
visual
option
to
allow
you
to
force
the
framebuffer
visual
to
whatever
you
want
(
this
usually
messes
up
the
colors
unless
you
are
very
careful
).
In
this
case
,
the
option
...
...
@@ -940,16 +945,17 @@ display :0
non
-
zero
in
8
bpp
PseudoColor
on
an
obscure
setup
,
and
this
option
corrected
the
problems
.
Q-10: Color problems: Why are the colors for some
of the windows
messed up in x11vnc? BTW, I have an X display that has nice overlay
visuals of
multiple color depths. E
.g. there are both depth 8 and 24
Q
-
10
:
Color
problems
:
Why
are
the
colors
for
some
windows
messed
up
in
x11vnc
?
BTW
,
I
have
an
X
display
that
has
nice
overlay
/
multi
-
depth
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
[
97
]
previous
question
regarding
8
bpp
PseudoColor
.
If that isn'
t
the
problem
,
run
xdpyinfo
to
see
what
the
default
visual
is
.
Does
it
have
a
depth
of
8
?
If
it
does
,
can
you
possibly
If
that
isn
't the problem, run xdpyinfo(1) to see what the default
visual is and what the depths of the other visuals are. Does the
default visual have a depth of 8? If it does, can you possibly
re-configure your X server to make the depth 24 visual the default? If
you can do it, this will save you a lot of grief WRT colors and x11vnc
(and for general usage too!). Here is how I do this on an old
...
...
@@ -958,12 +964,23 @@ display :0
and it works nicely (note: to log into console from the dtlogin
window, select "Options -> Command Line Login", then login and enter
the
above
command
).
If
you
have
root
permission
,
a
more
permanent
and
convenient
option
is
to
put
a
line
like
:
the above command). See the -dev section of the Xsun(1) manpage for a
description of the above arguments. If you have root permission, a
more permanent and convenient thing to do is to record the arguments
in a line like:
:0 Local local_uid@console root /usr/openwin/bin/Xsun -dev /dev/fb defclass
TrueColor defdepth 24
in
/
etc
/
dt
/
config
/
Xservers
(
see
/
usr
/
dt
/
config
/
Xservers
).
in /etc/dt/config/Xservers (see /usr/dt/config/Xservers). Also look at
the fbconfig(1) and related manpages (e.g. ffbconfig, m64config,
pgxconfig, SUNWjfb_config, etc ...) for hardware framebuffer settings
that may achieve the same effect. In general for non-Sun machines,
look at the "-cc class" and related options in your X server manpage
(perhaps Xserver(1)), it may allow modifying the default visual (e.g.
"-cc 4", see <X11/X.h> for the visual class numbers). On XFree86 some
video card drivers (e.g. Matrox mga) have settings like Option
"Overlay" "24,8" to support multi-depth overlays. For these, use the
"-cc 4" X server command line option to get a depth 24 default visual.
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
...
...
@@ -973,16 +990,15 @@ TrueColor defdepth 24
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
.
not sufficient
for these apps
.
Misc. notes on -overlay mode: An amusing by-product of -overlay mode
is
that
mouse
cursor
shape
(
e
.
g
.
use
-
X
or
-
mouse
options
)
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
).
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).
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
...
...
@@ -1537,7 +1553,7 @@ mp/x11vnc_sh.log
On
Solaris
you
cannot
have
the
bare
number
5900
in
/
etc
/
inetd
.
conf
,
you
'll need to replace it with a word like x11vnc an then put
something
like
x11vnc
5900
/
tcp
in
/
etc
/
services
.
something like
"x11vnc 5900/tcp"
in /etc/services.
Be sure to look at your /etc/hosts.allow and /etc/hosts.deny settings
to limit the machines that can connect to this service (your
...
...
@@ -1589,11 +1605,11 @@ mp/x11vnc_sh.log
believe
this
is
because
the
cursor
shape
is
often
downloaded
to
the
graphics
hardware
(
video
card
),
but
I
could
be
mistaken
.
A simple kludge is provided by the
-mouseX
option that changes the
A
simple
kludge
is
provided
by
the
"-cursor X"
option
that
changes
the
cursor
when
the
mouse
is
on
the
root
background
(
or
any
window
has
the
same
cursor
as
the
root
background
).
Note
that
desktops
like
GNOME
or
KDE
often
cover
up
the
root
background
,
so
this
won
't work for those
cases
.
cases.
Also see the "-cursor some" option for additional kludges.
It should be possible to apply some heuristics where x11vnc tries to
build up a table of cursors for the windows it sees, perhaps using a
...
...
@@ -1602,7 +1618,8 @@ mp/x11vnc_sh.log
Also note that as of Aug/2004 in the libvncserver CVS, on Solaris
using the SUN_OVL overlay extension, x11vnc can show the correct mouse
cursor when the -overlay is also supplied. (-overlay has some other
problems
however
,
and
can
be
slower
).
problems however, and can be slower). Plans are in the works to use
XFIXES for this on XFree86, Xorg, and Xsun.
Q-31: Why does the mouse arrow just stay in one corner in my
vncviewer, whereas my cursor (that does move) is just a dot?
...
...
@@ -1612,6 +1629,10 @@ mp/x11vnc_sh.log
with the -nocursor option to x11vnc if your viewer does not have this
extension.
Note: as of Aug/2004 in the libvncserver CVS this should be fixed: the
default for non-tightvnc viewers will be to draw the moving cursor
into the framebuffer. This can also be disabled via -nocursor.
Q-32: Can I take advantage of the TightVNC extension to the VNC
protocol where Cursor Positions Updates are sent back to all connected
clients (i.e. passive viewers can see the mouse cursor being moved
...
...
@@ -1619,7 +1640,9 @@ mp/x11vnc_sh.log
Use the -cursorpos option when starting x11vnc. A VNC viewer must
support the Cursor Positions Updates for the user to see the mouse
motions
(
the
TightVNC
viewers
support
this
).
motions (the TightVNC viewers support this). As of Aug/2004 in the
libvncserver CVS -cursorpos is the default. See -nocursorpos and
-nocursorshape.
Q-33: Is it possible to swap the mouse buttons (e.g. left-handed
operation), or arbitrarily remap them? How about mapping button clicks
...
...
@@ -1823,8 +1846,8 @@ ied)
* If you just want to watch one (simple) window use -id (cuts down
extraneous polling and updates, but can be buggy or insufficient)
* Set -nosel (disables all clipboard selection exchange)
*
Do
not
use
-
mouse
or
-
mouseX
(
repainting
the
remote
mouse
takes
resources
and
round
trips
)
*
Use -nocursor (repainting the remote cursor position and shape
takes
resources and round trips)
Q-39: How can I get my AltGr and Shift modifiers to work between
keyboards for different languages?
...
...
@@ -2403,8 +2426,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.6.3
pre
lastmod
:
2004
-
08
-
1
5
x11vnc: allow VNC connections to real X11 displays. 0.6.3pre lastmod: 2004-08-
2
9
Typical usage is:
...
...
@@ -2450,11 +2473,15 @@ Options:
setting the XAUTHORITY environment varirable to "file"
before startup. See Xsecurity(7), xauth(1) man pages.
-id windowid Show the window corresponding to "
windowid
" not the
entire display. Warning: bugs! new toplevels missed!...
-id windowid Show the window corresponding to "windowid" not
the entire display. New windows like popup menus,
etc may not be seen, or will be clipped. x11vnc may
crash if the window changes size, is iconified, etc.
Use xwininfo(1) to get the window id. Primarily useful
for exporting very simple applications.
-sid windowid As -id, but instead of using the window directly it
shifts a root view to it:
shows saveUnders menus, etc
,
although they will be clipped if they extend beyond
shifts a root view to it:
this shows saveUnders menus
,
etc,
although they will be clipped if they extend beyond
the window.
-flashcmap In 8bpp indexed color, let the installed colormap flash
as the pointer moves from window to window (slow).
...
...
@@ -2465,11 +2492,12 @@ Options:
packed with 8 for PseudoColor and 24 for TrueColor).
Currently -overlay only works on Solaris (it uses
XReadScreen(3X11)). There are still some problems with
surrounding-region painting for popup menus (but not
for the popup menu itself); a workaround is to disable
SaveUnders (pass -su to Xsun). Amusingly, if -overlay
is used with -mouse, the mouse cursor shape is correct.
XReadScreen(3X11)). There is a problem with image
"bleeding" around transient popup menus (but not
for the menu itself): a workaround is to disable
SaveUnders by passing the "-su" argument to Xsun
(in /etc/dt/config/Xservers, say). Also note that,
the mouse cursor shape is exactly correct in this mode.
Use -overlay as a workaround for situations like these:
Some legacy applications require the default visual
...
...
@@ -2482,7 +2510,10 @@ Options:
due to the extra image transformations required.
For optimal performance do not use -overlay, but rather
configure the X server so that the default visual is
depth 24 TrueColor and have all apps use that visual.
depth 24 TrueColor and try to have all apps use that
visual (some apps have -use24 or -visual options).
-overlay_nocursor Sets -overlay, but does not try to draw the exact mouse
cursor shape using the overlay mechanism.
-visual n Experimental option: probably does not do what you
think. It simply *forces* the visual used for the
framebuffer; this may be a bad thing... It is useful for
...
...
@@ -2492,9 +2523,10 @@ Options:
for a list. If the string ends in ":m" for better
or for worse the visual depth is forced to be m.
-scale fraction Scale the framebuffer by factor "
fraction
". Values
less than 1 shrink the fb. Note: image may not be sharp
and response may be slower. If "
fraction
" contains
-scale fraction Scale the framebuffer by factor "fraction".
Values less than 1 shrink the fb. Note: image may not
be sharp and response may be slower. Currently the
cursor shape is not scaled. If "fraction" contains
a decimal point "." it is taken as a floating point
number, alternatively the notation "m/n" may be used
to denote fractions exactly, e.g. -scale 2/3.
...
...
@@ -2504,7 +2536,7 @@ Options:
If you just want a quick, rough scaling without
blending, append ":nb" to "fraction" (e.g. -scale
1/3:nb). For compatibility with vncviewers the scaled
width is adjusted to be a multiple of 4
,
to disable
width is adjusted to be a multiple of 4
:
to disable
this use ":n4". More esoteric options: ":in" use
interpolation scheme even when shrinking, ":pad",
pad scaled width and height to be multiples of scaling
...
...
@@ -2524,9 +2556,10 @@ Options:
periodically check for new hosts. The first line is
read and then the file is truncated.
-vncconnect Monitor the VNC_CONNECT X property set by the standard
VNC program vncconnect(1). When the property is set
to host or host:port establish a reverse connection.
Using xprop(1) instead of vncconnect may work, see FAQ.
-novncconnect VNC program vncconnect(1). When the property is
set to "host" or "host:port" establish a reverse
connection. Using xprop(1) instead of vncconnect may
work, see the FAQ. Default: -vncconnect
-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
...
...
@@ -2617,16 +2650,18 @@ Options:
-flipbyteorder Sometimes needed if remotely polled host has different
endianness. Ignored unless -noshm is set.
-onetile Do not use the new copy_tiles() framebuffer mechanism,
just use 1 shm tile for polling.
Same as -old_copytile.
Limits shm segments
used to 3.
just use 1 shm tile for polling.
Limits shm segments
used to 3.
-blackout string Black out rectangles on the screen. "string" is a
comma separated list of WxH+X+Y type geometries for
each rectangle.
-xinerama If your screen is composed of multiple monitors
glued together via XINERAMA, and that screen is
non-rectangular this option will try to guess the areas
to black out (if your system has libXinerama).
non-rectangular this option will try to guess the
areas to black out (if your system has libXinerama).
In general on XINERAMA displays you may need to use the
-xwarppointer option if the mouse pointer misbehaves.
-o logfile Write stderr messages to file "logfile" instead of
to the terminal. Same as -logfile "file".
...
...
@@ -2654,7 +2689,9 @@ Options:
where a Keysym is bound to multiple keys (e.g. "<" + ">"
and "," + "<" keys). Default: -modtweak
-xkb When in modtweak mode, use the XKEYBOARD extension
(if it exists) to do the modifier tweaking.
(if it exists) to do the modifier tweaking. This is
powerful and should be tried if there are still
keymapping problems when using the simpler -modtweak.
-skip_keycodes string Skip keycodes not on your keyboard but your X server
thinks exist. Currently only applies to -xkb mode.
"string" is a comma separated list of decimal
...
...
@@ -2701,17 +2738,70 @@ Options:
back
to
clients
.
(
PRIMARY
is
still
set
on
received
changes
,
however
).
-nocursor Do not have the VNC viewer show a local cursor.
-mouse Draw a 2nd cursor at the current X pointer position.
-mouseX As -mouse, but also draw an "
X
" when pointer is on
root background.
-X Shorthand for -mouseX -nocursor.
-xwarppointer Move the pointer with XWarpPointer() instead of XTEST
(try as a workaround if pointer behaves poorly, e.g.
on touchscreens or other non-standard setups).
-
cursor
[
mode
]
Sets
how
the
pointer
cursor
shape
(
little
icon
at
the
-
nocursor
mouse
pointer
)
should
be
handled
.
The
"mode"
string
is
optional
and
is
described
below
.
The
default
is
to
show
some
sort
of
cursor
shape
(
s
).
How
this
is
done
depends
on
the
VNC
viewer
and
the
X
server
.
Use
-
nocursor
to
disable
cursor
shapes
completely
.
Some
VNC
viewers
support
the
TightVNC
CursorPosUpdates
and
CursorShapeUpdates
extensions
(
cuts
down
on
network
traffic
by
not
having
to
send
the
cursor
image
every
time
the
pointer
is
moved
),
in
which
case
these
extensions
are
used
(
see
-
nocursorshape
and
-
nocursorpos
below
).
For
other
viewers
the
cursor
shape
is
written
directly
to
the
framebuffer
every
time
the
pointer
is
moved
or
changed
and
gets
sent
along
with
the
other
framebuffer
updates
.
In
this
case
,
there
will
be
some
lag
between
the
vnc
viewer
pointer
and
the
remote
cursor
position
.
If
the
X
display
supports
retrieving
the
cursor
shape
information
from
the
X
server
,
then
the
default
is
to
use
that
mode
.
On
Solaris
this
requires
the
SUN_OVL
extension
and
the
-
overlay
option
to
be
supplied
.
(
see
also
the
-
overlay_nomouse
option
).
(
Soon
)
on
XFree86
/
Xorg
the
XFIXES
extension
is
required
.
Either
can
be
disabled
with
-
nocursor
,
and
also
some
values
of
the
"mode"
option
below
.
The
"mode"
string
can
be
used
to
fine
-
tune
the
displaying
of
cursor
shapes
.
It
can
be
used
the
following
ways
:
"-cursor X"
-
when
the
cursor
appears
to
be
on
the
root
window
,
draw
the
familiar
X
shape
.
Some
desktops
such
as
GNOME
cover
up
the
root
window
completely
,
and
so
this
will
not
work
,
try
"X1"
,
etc
,
to
try
to
shift
the
tree
depth
.
On
high
latency
links
or
slow
machines
there
will
be
a
time
lag
between
expected
and
the
actual
cursor
shape
.
"-cursor some"
-
like
"X"
but
use
additional
heuristics
to
try
to
guess
if
the
window
should
have
a
windowmanager
-
like
resizer
cursor
or
a
text
input
I
-
beam
cursor
.
This
is
a
complete
hack
,
but
may
be
useful
in
some
situations
because
it
provides
a
little
more
feedback
about
the
cursor
shape
.
"-cursor most"
-
try
to
show
as
many
cursors
as
possible
.
Often
this
will
only
be
the
same
as
"some"
.
On
Solaris
if
XFIXES
is
not
available
,
-
overlay
mode
will
be
used
.
-
nocursorshape
Do
not
use
the
TightVNC
CursorShapeUpdates
extension
even
if
clients
support
it
.
See
-
cursor
above
.
-
cursorpos
Option
-
cursorpos
enables
sending
the
X
cursor
position
-
nocursorpos
back
to
all
vnc
clients
that
support
the
TightVNC
CursorPosUpdates extension. Default: -cursorpos
CursorPosUpdates
extension
.
Other
clients
will
be
able
to
see
the
pointer
motions
.
Default
:
-
cursorpos
-
xwarppointer
Move
the
pointer
with
XWarpPointer
(
3
X
)
instead
of
XTEST
extension
.
Use
this
as
a
workaround
if
the
pointer
motion
behaves
incorrectly
,
e
.
g
.
on
touchscreens
or
other
non
-
standard
setups
.
Also
sometimes
needed
on
XINERAMA
displays
.
-
buttonmap
string
String
to
remap
mouse
buttons
.
Format
:
IJK
-
LMN
,
this
maps
buttons
I
->
L
,
etc
.,
e
.
g
.
-
buttonmap
13
-
31
...
...
@@ -2800,7 +2890,8 @@ These options are passed to libvncserver:
Pretty
wild
huh
?
[
1
]
Contact
me
if
you
have
any
questions
or
problems
.
Personally
,
I
use
:
x11vnc -rfbauth $HOME/.vnc/passwd -nap -flashcmap -cursorpos -norepeat
x11vnc
-
rfbauth
$
HOME
/.
vnc
/
passwd
-
nap
-
flashcmap
-
cursor
X
-
norepeat
-
add_keys
yms
(
the
-
flashcmap
only
matters
on
old
8
-
bit
X
displays
)
...
...
x11vnc/x11vnc.1
View file @
52ba8bfb
...
...
@@ -2,7 +2,7 @@
.TH X11VNC "1" "August 2004" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.6.3pre, lastmod: 2004-08-
15
version: 0.6.3pre, lastmod: 2004-08-
29
.SH SYNOPSIS
.B x11vnc
[OPTION]...
...
...
@@ -63,14 +63,20 @@ man pages.
.PP
\fB-id\fR \fIwindowid\fR
.IP
Show the window corresponding to \fIwindowid\fR not the
entire display. Warning: bugs! new toplevels missed!...
Show the window corresponding to \fIwindowid\fR not
the entire display. New windows like popup menus,
etc may not be seen, or will be clipped. x11vnc may
crash if the window changes size, is iconified, etc.
Use
.IR xwininfo (1)
to get the window id. Primarily useful
for exporting very simple applications.
.PP
\fB-sid\fR \fIwindowid\fR
.IP
As \fB-id,\fR but instead of using the window directly it
shifts a root view to it:
shows saveUnders menus, etc
,
although they will be clipped if they extend beyond
shifts a root view to it:
this shows saveUnders menus
,
etc,
although they will be clipped if they extend beyond
the window.
.PP
\fB-flashcmap\fR
...
...
@@ -90,11 +96,12 @@ and 24+8 overlay visuals (the 32 bits per pixel are
packed with 8 for PseudoColor and 24 for TrueColor).
.IP
Currently \fB-overlay\fR only works on Solaris (it uses
XReadScreen(3X11)). There are still some problems with
surrounding-region painting for popup menus (but not
for the popup menu itself); a workaround is to disable
SaveUnders (pass \fB-su\fR to Xsun). Amusingly, if \fB-overlay\fR
is used with \fB-mouse,\fR the mouse cursor shape is correct.
XReadScreen(3X11)). There is a problem with image
"bleeding" around transient popup menus (but not
for the menu itself): a workaround is to disable
SaveUnders by passing the "-su" argument to Xsun
(in /etc/dt/config/Xservers, say). Also note that,
the mouse cursor shape is exactly correct in this mode.
.IP
Use \fB-overlay\fR as a workaround for situations like these:
Some legacy applications require the default visual
...
...
@@ -107,7 +114,13 @@ Under \fB-overlay,\fR performance will be somewhat degraded
due to the extra image transformations required.
For optimal performance do not use \fB-overlay,\fR but rather
configure the X server so that the default visual is
depth 24 TrueColor and have all apps use that visual.
depth 24 TrueColor and try to have all apps use that
visual (some apps have \fB-use24\fR or \fB-visual\fR options).
.PP
\fB-overlay_nocursor\fR
.IP
Sets \fB-overlay,\fR but does not try to draw the exact mouse
cursor shape using the overlay mechanism.
.PP
\fB-visual\fR \fIn\fR
.IP
...
...
@@ -124,9 +137,10 @@ or for worse the visual depth is forced to be m.
.PP
\fB-scale\fR \fIfraction\fR
.IP
Scale the framebuffer by factor \fIfraction\fR. Values
less than 1 shrink the fb. Note: image may not be sharp
and response may be slower. If \fIfraction\fR contains
Scale the framebuffer by factor \fIfraction\fR.
Values less than 1 shrink the fb. Note: image may not
be sharp and response may be slower. Currently the
cursor shape is not scaled. If \fIfraction\fR contains
a decimal point "." it is taken as a floating point
number, alternatively the notation "m/n" may be used
to denote fractions exactly, e.g. \fB-scale\fR 2/3.
...
...
@@ -136,7 +150,7 @@ Scaling Options: can be added after \fIfraction\fR via
If you just want a quick, rough scaling without
blending, append ":nb" to \fIfraction\fR (e.g. \fB-scale\fR
1/3:nb). For compatibility with vncviewers the scaled
width is adjusted to be a multiple of 4
,
to disable
width is adjusted to be a multiple of 4
:
to disable
this use ":n4". More esoteric options: ":in" use
interpolation scheme even when shrinking, ":pad",
pad scaled width and height to be multiples of scaling
...
...
@@ -173,13 +187,17 @@ read and then the file is truncated.
\fB-vncconnect\fR
.IP
Monitor the VNC_CONNECT X property set by the standard
.PP
\fB-novncconnect\fR
.IP
VNC program
.IR vncconnect (1)
. When the property is
set
to host or host:port establish a reverse connection.
Using
. When the property is
set to "host" or "host:port" establish a reverse
connection.
Using
.IR xprop (1)
instead of vncconnect may work, see FAQ.
instead of vncconnect may
work, see the FAQ. Default: \fB-vncconnect\fR
.PP
\fB-inetd\fR
.IP
...
...
@@ -306,8 +324,8 @@ endianness. Ignored unless \fB-noshm\fR is set.
\fB-onetile\fR
.IP
Do not use the new copy_tiles() framebuffer mechanism,
just use 1 shm tile for polling.
Same as \fB-old_copytile.\fR
Limits shm segments
used to 3.
just use 1 shm tile for polling.
Limits shm segments
used to 3.
.PP
\fB-blackout\fR \fIstring\fR
.IP
...
...
@@ -319,8 +337,10 @@ each rectangle.
.IP
If your screen is composed of multiple monitors
glued together via XINERAMA, and that screen is
non-rectangular this option will try to guess the areas
to black out (if your system has libXinerama).
non-rectangular this option will try to guess the
areas to black out (if your system has libXinerama).
In general on XINERAMA displays you may need to use the
\fB-xwarppointer\fR option if the mouse pointer misbehaves.
.PP
\fB-o\fR \fIlogfile\fR
.IP
...
...
@@ -376,7 +396,9 @@ and "," + "<" keys). Default: \fB-modtweak\fR
\fB-xkb\fR
.IP
When in modtweak mode, use the XKEYBOARD extension
(if it exists) to do the modifier tweaking.
(if it exists) to do the modifier tweaking. This is
powerful and should be tried if there are still
keymapping problems when using the simpler \fB-modtweak.\fR
.PP
\fB-skip_keycodes\fR \fIstring\fR
.IP
...
...
@@ -453,34 +475,79 @@ Do not poll the PRIMARY selection for changes to send
back to clients. (PRIMARY is still set on received
changes, however).
.PP
\fB-nocursor\fR
.IP
Do not have the VNC viewer show a local cursor.
.PP
\fB-mouse\fR
.IP
Draw a 2nd cursor at the current X pointer position.
.PP
\fB-mouseX\fR
.IP
As \fB-mouse,\fR but also draw an "X" when pointer is on
root background.
.PP
\fB-X\fR
.IP
Shorthand for \fB-mouseX\fR \fB-nocursor.\fR
.PP
\fB-xwarppointer\fR
.IP
Move the pointer with XWarpPointer() instead of XTEST
(try as a workaround if pointer behaves poorly, e.g.
on touchscreens or other non-standard setups).
\fB-cursor\fR \fI[mode],\fR \fB-nocursor\fR
.IP
Sets how the pointer cursor shape (little icon at the
mouse pointer) should be handled. The "mode" string
is optional and is described below. The default
is to show some sort of cursor shape(s). How this
is done depends on the VNC viewer and the X server.
Use \fB-nocursor\fR to disable cursor shapes completely.
.IP
Some VNC viewers support the TightVNC CursorPosUpdates
and CursorShapeUpdates extensions (cuts down on
network traffic by not having to send the cursor image
every time the pointer is moved), in which case these
extensions are used (see \fB-nocursorshape\fR and \fB-nocursorpos\fR
below). For other viewers the cursor shape is written
directly to the framebuffer every time the pointer is
moved or changed and gets sent along with the other
framebuffer updates. In this case, there will be
some lag between the vnc viewer pointer and the remote
cursor position.
.IP
If the X display supports retrieving the cursor shape
information from the X server, then the default
is to use that mode. On Solaris this requires
the SUN_OVL extension and the \fB-overlay\fR option to be
supplied. (see also the \fB-overlay_nomouse\fR option). (Soon)
on XFree86/Xorg the XFIXES extension is required.
Either can be disabled with \fB-nocursor,\fR and also some
values of the "mode" option below.
.IP
The "mode" string can be used to fine-tune the
displaying of cursor shapes. It can be used the
following ways:
.IP
"-cursor X" - when the cursor appears to be on the
root window, draw the familiar X shape. Some desktops
such as GNOME cover up the root window completely,
and so this will not work, try "X1", etc, to try to
shift the tree depth. On high latency links or slow
machines there will be a time lag between expected and
the actual cursor shape.
.IP
"-cursor some" - like "X" but use additional
heuristics to try to guess if the window should have
a windowmanager-like resizer cursor or a text input
I-beam cursor. This is a complete hack, but may be
useful in some situations because it provides a little
more feedback about the cursor shape.
.IP
"-cursor most" - try to show as many cursors as
possible. Often this will only be the same as "some".
On Solaris if XFIXES is not available, \fB-overlay\fR mode
will be used.
.PP
\fB-nocursorshape\fR
.IP
Do not use the TightVNC CursorShapeUpdates extension
even if clients support it. See \fB-cursor\fR above.
.PP
\fB-cursorpos,\fR \fB-nocursorpos\fR
.IP
Option \fB-cursorpos\fR enables sending the X cursor position
back to all vnc clients that support the TightVNC
CursorPosUpdates extension. Default: \fB-cursorpos\fR
CursorPosUpdates extension. Other clients will be able
to see the pointer motions. Default: \fB-cursorpos\fR
.PP
\fB-xwarppointer\fR
.IP
Move the pointer with XWarpPointer(3X) instead of XTEST
extension. Use this as a workaround if the pointer
motion behaves incorrectly, e.g. on touchscreens or
other non-standard setups. Also sometimes needed on
XINERAMA displays.
.PP
\fB-buttonmap\fR \fIstring\fR
.IP
...
...
x11vnc/x11vnc.c
View file @
52ba8bfb
...
...
@@ -65,14 +65,10 @@
* cursor, but we cannot extract what the cursor is...
*
* Nevertheless, the current *position* of the remote X mouse pointer
* is shown with the -
mouse option. Further, if -mouse
X or -X is used, a
* is shown with the -
cursor option. Further, if -cursor
X or -X is used, a
* trick is done to at least show the root window cursor vs non-root cursor.
* (perhaps some heuristic can be done to further distinguish cases...)
*
* With -mouse there are occasionally some repainting errors involving
* big areas near the cursor. The mouse painting is in general a bit
* ragged and not very pleasant.
*
* Windows using visuals other than the default X visual may have
* their colors messed up. When using 8bpp indexed color, the colormap
* is attempted to be followed, but may become out of date. Use the
...
...
@@ -82,7 +78,7 @@
* On Sun hardware we try to work around this with -overlay.
*
* Feature -id <windowid> can be picky: it can crash for things like the
* window not sufficiently mapped into server memory, use of -
mouse
, etc.
* window not sufficiently mapped into server memory, use of -
cursor
, etc.
* SaveUnders menus, popups, etc will not be seen.
*
* Occasionally, a few tile updates can be missed leaving a patch of
...
...
@@ -90,7 +86,8 @@
* which is no longer the default.
*
* There seems to be a serious bug with simultaneous clients when
* threaded, currently the only workaround in this case is -nothreads.
* threaded, currently the only workaround in this case is -nothreads
* (which is now the default).
*
*/
...
...
@@ -108,17 +105,46 @@
/* -- x11vnc.h -- */
/*
* At some point beyond 0.7pre remove these two definitions since we
* have them set in configure (for all users of this x11vnc.c file).
* Then move them to the comment below.
*/
#define LIBVNCSERVER_HAVE_XSHM
#define LIBVNCSERVER_HAVE_XTEST
/*
* If you are building in an older libvncserver tree with this newer
* x11vnc.c file you may need to uncomment some of these lines since
* your older libvncserver configure is not setting them.
*
* For LIBVNCSERVER_HAVE_LIBXINERAMA you may also need to add to the
* linking -lXinerama (by setting LDFLAGS=-lXinerama before configure).
*
#define LIBVNCSERVER_HAVE_LIBXINERAMA
#define LIBVNCSERVER_HAVE_XFIXES
#define LIBVNCSERVER_HAVE_XDAMAGE
*
*/
#include <unistd.h>
#include <signal.h>
#include <sys/utsname.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifdef LIBVNCSERVER_HAVE_XSHM
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
#endif
#ifdef LIBVNCSERVER_HAVE_XTEST
#include <X11/extensions/XTest.h>
#endif
#include <X11/keysym.h>
#include <X11/Xatom.h>
...
...
@@ -147,22 +173,12 @@
#include <X11/extensions/transovl.h>
#endif
/*
* Temporary kludge: to run with -xinerama define the following
* macro (uncomment) and be sure to link with -lXinerama
* (e.g. LDFLAGS=-lXinerama before configure). Support for this is
* being added to libvncserver 'configure.ac' so it will all be done
* automatically, but it won't be in users' build trees for a while,
* so one can do it manually here.
#define LIBVNCSERVER_HAVE_LIBXINERAMA
*/
#ifdef LIBVNCSERVER_HAVE_LIBXINERAMA
#include <X11/extensions/Xinerama.h>
#endif
/* date +'lastmod: %Y-%m-%d' */
char
lastmod
[]
=
"0.6.3pre lastmod: 2004-08-
15
"
;
char
lastmod
[]
=
"0.6.3pre lastmod: 2004-08-
29
"
;
/* X display info */
...
...
@@ -182,31 +198,41 @@ XImage *scanline;
XImage
*
fullscreen
;
XImage
**
tile_row
;
/* for all possible row runs */
#ifndef LIBVNCSERVER_HAVE_XSHM
/*
* for simplicity, define these since we'll never use them
* under using_shm = 0.
*/
typedef
struct
{
int
shmid
;
char
*
shmaddr
;
Bool
readOnly
;
}
XShmSegmentInfo
;
#endif
/* corresponding shm structures */
XShmSegmentInfo
scanline_shm
;
XShmSegmentInfo
fullscreen_shm
;
XShmSegmentInfo
*
tile_row_shm
;
/* for all possible row runs */
/* rfb info */
/* rfb
screen
info */
rfbScreenInfoPtr
screen
;
rfbCursorPtr
cursor
;
char
*
main_fb
;
/* our copy of the X11 fb */
char
*
rfb_fb
;
/* same as main_fb unless transformation */
int
rfb_bytes_per_line
;
int
main_bytes_per_line
;
unsigned
long
main_red_mask
,
main_green_mask
,
main_blue_mask
;
unsigned
short
main_red_max
,
main_green_max
,
main_blue_max
;
unsigned
short
main_red_shift
,
main_green_shift
,
main_blue_shift
;
int
rfb_bytes_per_line
;
/* scaling info */
int
scaling
=
0
;
int
scaling_noblend
=
0
;
int
scaling_nomult4
=
0
;
int
scaling_pad
=
0
;
int
scaling_interpolate
=
0
;
/* scaling parameters */
double
scale_fac
=
1
.
0
;
int
scaled_x
=
0
,
scaled_y
=
0
;
int
scale_numer
=
0
,
scale_denom
=
0
;
int
scaling
=
0
;
int
scaling_noblend
=
0
;
/* no blending option (very course) */
int
scaling_nomult4
=
0
;
/* do not require width = n * 4 */
int
scaling_pad
=
0
;
/* pad out scaled sizes to fit denominator */
int
scaling_interpolate
=
0
;
/* use interpolation scheme when shrinking */
int
scaled_x
=
0
,
scaled_y
=
0
;
/* dimensions of scaled display */
int
scale_numer
=
0
,
scale_denom
=
0
;
/* n/m */
/* size of the basic tile unit that is polled for changes: */
int
tile_x
=
32
;
...
...
@@ -216,25 +242,6 @@ int ntiles, ntiles_x, ntiles_y;
/* arrays that indicate changed or checked tiles. */
unsigned
char
*
tile_has_diff
,
*
tile_tried
;
/* blacked-out region (-blackout, -xinerama) */
typedef
struct
bout
{
int
x1
,
y1
,
x2
,
y2
;
}
blackout_t
;
#define BO_MAX 16
typedef
struct
tbout
{
blackout_t
bo
[
BO_MAX
];
/* hardwired max rectangles. */
int
cover
;
int
count
;
}
tile_blackout_t
;
#define BLACKR_MAX 100
blackout_t
blackr
[
BLACKR_MAX
];
/* hardwired max blackouts */
int
blackouts
=
0
;
tile_blackout_t
*
tile_blackout
;
/* saved cursor */
int
cur_save_x
,
cur_save_y
,
cur_save_w
,
cur_save_h
,
cur_saved
=
0
;
/* times of recent events */
time_t
last_event
,
last_input
,
last_client
=
0
;
...
...
@@ -254,7 +261,6 @@ int shut_down = 0;
char
vnc_connect_str
[
VNC_CONNECT_MAX
+
1
];
Atom
vnc_connect_prop
=
None
;
/* function prototypes (see filename comment above) */
int
all_clients_initialized
(
void
);
...
...
@@ -286,7 +292,14 @@ void initialize_xinerama(void);
void
keyboard
(
rfbBool
down
,
rfbKeySym
keysym
,
rfbClientPtr
client
);
void
myXTestFakeKeyEvent
(
Display
*
,
KeyCode
,
Bool
,
time_t
);
void
XTestFakeKeyEvent_wr
(
Display
*
,
KeyCode
,
Bool
,
unsigned
long
);
void
XTestFakeButtonEvent_wr
(
Display
*
,
unsigned
int
,
Bool
,
unsigned
long
);
void
XTestFakeMotionEvent_wr
(
Display
*
,
int
,
int
,
int
,
unsigned
long
);
int
XTestGrabControl_wr
(
Display
*
,
Bool
);
Bool
XTestCompareCurrentCursorWithWindow_wr
(
Display
*
,
Window
);
Bool
XTestCompareCursorWithWindow_wr
(
Display
*
,
Window
,
Cursor
);
Bool
XTestQueryExtension_wr
(
Display
*
,
int
*
,
int
*
,
int
*
,
int
*
);
void
XTestDiscard_wr
(
Display
*
);
typedef
struct
hint
{
/* location x, y, height, and width of a change-rectangle */
...
...
@@ -299,22 +312,24 @@ void mark_rect_as_modified(int x1, int y1, int x2, int y2, int force);
enum
rfbNewClientAction
new_client
(
rfbClientPtr
client
);
void
nofb_hook
(
rfbClientPtr
client
);
void
pointer
(
int
mask
,
int
x
,
int
y
,
rfbClientPtr
client
);
void
cursor_position
(
int
,
int
);
void
read_vnc_connect_prop
(
void
);
void
redraw_mouse
(
void
);
void
restore_mouse_patch
(
void
);
void
rfbPE
(
rfbScreenInfoPtr
,
long
);
void
rfbCFD
(
rfbScreenInfoPtr
,
long
);
void
scan_for_updates
(
void
);
void
set_colormap
(
void
);
void
set_offset
(
void
);
void
set_visual
(
char
*
vstring
);
void
set_cursor
(
int
,
int
,
int
);
int
get_which_cursor
(
void
);
void
shm_clean
(
XShmSegmentInfo
*
,
XImage
*
);
void
shm_delete
(
XShmSegmentInfo
*
);
void
update_mouse
(
void
);
void
watch
_bell_event
(
void
);
void
watch
_xevents
(
void
);
void
check_x11_pointer
(
void
);
void
check
_bell_event
(
void
);
void
check
_xevents
(
void
);
void
xcut_receive
(
char
*
text
,
int
len
,
rfbClientPtr
client
);
...
...
@@ -347,13 +362,14 @@ int xinerama = 0; /* -xinerama */
char
*
client_connect
=
NULL
;
/* strings for -connect option */
char
*
client_connect_file
=
NULL
;
int
vnc_connect
=
0
;
/* -vncconnect option */
int
vnc_connect
=
1
;
/* -vncconnect option */
int
local_cursor
=
1
;
/* whether the viewer draws a local cursor */
int
cursor_pos
=
1
;
/* cursor position updates -cursorpos */
int
show_mouse
=
0
;
/* display a cursor for the real mouse */
int
show_cursor
=
1
;
/* show cursor shapes */
int
show_multiple_cursors
=
0
;
/* show X when on root background, etc */
char
*
multiple_cursors_mode
=
"default"
;
int
cursor_pos_updates
=
1
;
/* cursor position updates -cursorpos */
int
cursor_shape_updates
=
1
;
/* cursor shape updates -nocursorshape */
int
use_xwarppointer
=
0
;
/* use XWarpPointer instead of XTestFake... */
int
show_root_cursor
=
0
;
/* show X when on root background */
int
show_dragging
=
1
;
/* process mouse movement events */
int
no_autorepeat
=
0
;
/* turn off autorepeat with clients */
int
watch_bell
=
1
;
/* watch for the bell using XKEYBOARD */
...
...
@@ -391,8 +407,16 @@ int sigpipe = 1; /* 0=skip, 1=ignore, 2=exit */
/* visual stuff for -visual override or -overlay */
VisualID
visual_id
=
(
VisualID
)
0
;
int
visual_depth
=
0
;
/* for -overlay mode on Solaris. X server draws cursor correctly. */
int
overlay
=
0
;
int
overlay_mouse
=
0
;
int
overlay_cursor
=
1
;
#ifdef LIBVNCSERVER_HAVE_XTEST
int
xtest_present
=
1
;
#else
int
xtest_present
=
0
;
#endif
/* tile heuristics: */
double
fs_frac
=
0
.
75
;
/* threshold tile fraction to do fullscreen updates. */
...
...
@@ -467,6 +491,18 @@ int nfix(int i, int n) {
return
i
;
}
void
lowercase
(
char
*
str
)
{
char
*
p
;
if
(
str
==
NULL
)
{
return
;
}
p
=
str
;
while
(
*
p
!=
'\0'
)
{
*
p
=
tolower
(
*
p
);
p
++
;
}
}
/*
* Kludge to interpose image gets and limit to a subset rectangle of
* the rootwin. This is the -sid option trying to work around invisible
...
...
@@ -481,7 +517,9 @@ int rootshift = 0;
y += off_y; \
}
/* Wrappers for Image related X calls */
/*
* Wrappers for Image related X calls
*/
Status
XShmGetImage_wr
(
Display
*
disp
,
Drawable
d
,
XImage
*
image
,
int
x
,
int
y
,
unsigned
long
mask
)
{
...
...
@@ -489,7 +527,47 @@ Status XShmGetImage_wr(Display *disp, Drawable d, XImage *image, int x, int y,
/* The Solaris overlay stuff is all non-shm (using_shm = 0) */
#ifdef LIBVNCSERVER_HAVE_XSHM
return
XShmGetImage
(
disp
,
d
,
image
,
x
,
y
,
mask
);
#else
return
(
Status
)
0
;
#endif
}
XImage
*
XShmCreateImage_wr
(
Display
*
disp
,
Visual
*
vis
,
unsigned
int
depth
,
int
format
,
char
*
data
,
XShmSegmentInfo
*
shminfo
,
unsigned
int
width
,
unsigned
int
height
)
{
#ifdef LIBVNCSERVER_HAVE_XSHM
return
XShmCreateImage
(
disp
,
vis
,
depth
,
format
,
data
,
shminfo
,
width
,
height
);
#else
return
(
XImage
*
)
0
;
#endif
}
Status
XShmAttach_wr
(
Display
*
disp
,
XShmSegmentInfo
*
shminfo
)
{
#ifdef LIBVNCSERVER_HAVE_XSHM
return
XShmAttach
(
disp
,
shminfo
);
#else
return
(
Status
)
0
;
#endif
}
Status
XShmDetach_wr
(
Display
*
disp
,
XShmSegmentInfo
*
shminfo
)
{
#ifdef LIBVNCSERVER_HAVE_XSHM
return
XShmDetach
(
disp
,
shminfo
);
#else
return
(
Status
)
0
;
#endif
}
Bool
XShmQueryExtension_wr
(
Display
*
disp
)
{
#ifdef LIBVNCSERVER_HAVE_XSHM
return
XShmQueryExtension
(
disp
);
#else
return
False
;
#endif
}
XImage
*
XGetSubImage_wr
(
Display
*
disp
,
Drawable
d
,
int
x
,
int
y
,
...
...
@@ -502,7 +580,7 @@ XImage *XGetSubImage_wr(Display *disp, Drawable d, int x, int y,
if
(
overlay
&&
dest_x
==
0
&&
dest_y
==
0
)
{
size_t
size
=
dest_image
->
height
*
dest_image
->
bytes_per_line
;
XImage
*
xi
=
XReadScreen
(
disp
,
d
,
x
,
y
,
width
,
height
,
(
Bool
)
overlay_
mouse
);
(
Bool
)
overlay_
cursor
);
/*
* There is extra overhead from memcpy and free...
...
...
@@ -529,7 +607,7 @@ XImage *XGetImage_wr(Display *disp, Drawable d, int x, int y,
#ifdef SOLARIS
if
(
overlay
)
{
return
XReadScreen
(
disp
,
d
,
x
,
y
,
width
,
height
,
(
Bool
)
overlay_
mouse
);
(
Bool
)
overlay_
cursor
);
}
#endif
return
XGetImage
(
disp
,
d
,
x
,
y
,
width
,
height
,
plane_mask
,
format
);
...
...
@@ -563,6 +641,100 @@ XImage *XCreateImage_wr(Display *disp, Visual *visual, unsigned int depth,
width
,
height
,
bitmap_pad
,
bytes_per_line
);
}
/*
* wrappers for XTestFakeKeyEvent, etc..
*/
void
XTestFakeKeyEvent_wr
(
Display
*
dpy
,
KeyCode
key
,
Bool
down
,
unsigned
long
delay
)
{
if
(
debug_keyboard
)
{
rfbLog
(
"XTestFakeKeyEvent(dpy, keycode=0x%x
\"
%s
\"
, %s)
\n
"
,
key
,
XKeysymToString
(
XKeycodeToKeysym
(
dpy
,
key
,
0
)),
down
?
"down"
:
"up"
);
}
if
(
!
xtest_present
)
{
return
;
}
if
(
down
)
{
last_keyboard_input
=
-
key
;
}
else
{
last_keyboard_input
=
key
;
}
#ifdef LIBVNCSERVER_HAVE_XTEST
XTestFakeKeyEvent
(
dpy
,
key
,
down
,
delay
);
#endif
}
void
XTestFakeButtonEvent_wr
(
Display
*
dpy
,
unsigned
int
button
,
Bool
is_press
,
unsigned
long
delay
)
{
if
(
!
xtest_present
)
{
return
;
}
#ifdef LIBVNCSERVER_HAVE_XTEST
XTestFakeButtonEvent
(
dpy
,
button
,
is_press
,
delay
);
#endif
}
void
XTestFakeMotionEvent_wr
(
Display
*
dpy
,
int
screen
,
int
x
,
int
y
,
unsigned
long
delay
)
{
if
(
!
xtest_present
)
{
return
;
}
#ifdef LIBVNCSERVER_HAVE_XTEST
XTestFakeMotionEvent
(
dpy
,
screen
,
x
,
y
,
delay
);
#endif
}
Bool
XTestCompareCurrentCursorWithWindow_wr
(
Display
*
dpy
,
Window
w
)
{
if
(
!
xtest_present
)
{
return
False
;
}
#ifdef LIBVNCSERVER_HAVE_XTEST
return
XTestCompareCurrentCursorWithWindow
(
dpy
,
w
);
#else
return
False
;
#endif
}
Bool
XTestCompareCursorWithWindow_wr
(
Display
*
dpy
,
Window
w
,
Cursor
cursor
)
{
if
(
!
xtest_present
)
{
return
False
;
}
#ifdef LIBVNCSERVER_HAVE_XTEST
return
XTestCompareCursorWithWindow
(
dpy
,
w
,
cursor
);
#else
return
False
;
#endif
}
int
XTestGrabControl_wr
(
Display
*
dpy
,
Bool
impervious
)
{
if
(
!
xtest_present
)
{
return
0
;
}
#ifdef LIBVNCSERVER_HAVE_XTEST
return
XTestGrabControl
(
dpy
,
impervious
);
#else
return
0
;
#endif
}
Bool
XTestQueryExtension_wr
(
Display
*
dpy
,
int
*
ev
,
int
*
er
,
int
*
maj
,
int
*
min
)
{
#ifdef LIBVNCSERVER_HAVE_XTEST
return
XTestQueryExtension
(
dpy
,
ev
,
er
,
maj
,
min
);
#else
return
False
;
#endif
}
void
XTestDiscard_wr
(
Display
*
dpy
)
{
if
(
!
xtest_present
)
{
return
;
}
#ifdef LIBVNCSERVER_HAVE_XTEST
XTestDiscard
(
dpy
);
#endif
}
/* -- cleanup.c -- */
/*
...
...
@@ -603,7 +775,7 @@ void clean_up_exit (int ret) {
autorepeat
(
1
);
}
X_LOCK
;
XTestDiscard
(
dpy
);
XTestDiscard
_wr
(
dpy
);
XCloseDisplay
(
dpy
);
X_UNLOCK
;
...
...
@@ -847,54 +1019,6 @@ static int run_user_command(char *cmd, rfbClientPtr client) {
return
rc
;
}
/*
* Kludge for -norepeat option: we turn off keystroke autorepeat in
* the X server when clients are connected. This may annoy people at
* the physical display. We do this because 'key down' and 'key up'
* user input events may be separated by 100s of ms due to screen fb
* processing or link latency, thereby inducing the X server to apply
* autorepeat when it should not. Since the *client* is likely doing
* keystroke autorepeating as well, it kind of makes sense to shut it
* off if no one is at the physical display...
*/
void
autorepeat
(
int
restore
)
{
XKeyboardState
kstate
;
XKeyboardControl
kctrl
;
static
int
save_auto_repeat
=
-
1
;
if
(
restore
)
{
if
(
save_auto_repeat
<
0
)
{
return
;
/* nothing to restore */
}
X_LOCK
;
/* read state and skip restore if equal (e.g. no clients) */
XGetKeyboardControl
(
dpy
,
&
kstate
);
if
(
kstate
.
global_auto_repeat
==
save_auto_repeat
)
{
X_UNLOCK
;
return
;
}
kctrl
.
auto_repeat_mode
=
save_auto_repeat
;
XChangeKeyboardControl
(
dpy
,
KBAutoRepeatMode
,
&
kctrl
);
XFlush
(
dpy
);
X_UNLOCK
;
rfbLog
(
"Restored X server key autorepeat to: %d
\n
"
,
save_auto_repeat
);
}
else
{
X_LOCK
;
XGetKeyboardControl
(
dpy
,
&
kstate
);
save_auto_repeat
=
kstate
.
global_auto_repeat
;
kctrl
.
auto_repeat_mode
=
AutoRepeatModeOff
;
XChangeKeyboardControl
(
dpy
,
KBAutoRepeatMode
,
&
kctrl
);
XFlush
(
dpy
);
X_UNLOCK
;
rfbLog
(
"Disabled X server key autorepeat. (you can run the
\n
"
);
rfbLog
(
"command: 'xset r on' to force it back on)
\n
"
);
}
}
/*
* callback for when a client disconnects
...
...
@@ -1907,7 +2031,7 @@ void clear_modifiers(int init) {
rfbLog
(
"clear_modifiers: up: %-10s (0x%x) "
"keycode=0x%x
\n
"
,
keystrs
[
i
],
keysym
,
keycode
);
}
myXTestFakeKeyEvent
(
dpy
,
keycode
,
False
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
keycode
,
False
,
CurrentTime
);
}
XFlush
(
dpy
);
}
...
...
@@ -1925,12 +2049,61 @@ void clear_keys(void) {
if
(
keystate
[
k
])
{
KeyCode
keycode
=
(
KeyCode
)
k
;
rfbLog
(
"clear_keys: keycode=%d
\n
"
,
keycode
);
myXTestFakeKeyEvent
(
dpy
,
keycode
,
False
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
keycode
,
False
,
CurrentTime
);
}
}
XFlush
(
dpy
);
}
/*
* Kludge for -norepeat option: we turn off keystroke autorepeat in
* the X server when clients are connected. This may annoy people at
* the physical display. We do this because 'key down' and 'key up'
* user input events may be separated by 100s of ms due to screen fb
* processing or link latency, thereby inducing the X server to apply
* autorepeat when it should not. Since the *client* is likely doing
* keystroke autorepeating as well, it kind of makes sense to shut it
* off if no one is at the physical display...
*/
void
autorepeat
(
int
restore
)
{
XKeyboardState
kstate
;
XKeyboardControl
kctrl
;
static
int
save_auto_repeat
=
-
1
;
if
(
restore
)
{
if
(
save_auto_repeat
<
0
)
{
return
;
/* nothing to restore */
}
X_LOCK
;
/* read state and skip restore if equal (e.g. no clients) */
XGetKeyboardControl
(
dpy
,
&
kstate
);
if
(
kstate
.
global_auto_repeat
==
save_auto_repeat
)
{
X_UNLOCK
;
return
;
}
kctrl
.
auto_repeat_mode
=
save_auto_repeat
;
XChangeKeyboardControl
(
dpy
,
KBAutoRepeatMode
,
&
kctrl
);
XFlush
(
dpy
);
X_UNLOCK
;
rfbLog
(
"Restored X server key autorepeat to: %d
\n
"
,
save_auto_repeat
);
}
else
{
X_LOCK
;
XGetKeyboardControl
(
dpy
,
&
kstate
);
save_auto_repeat
=
kstate
.
global_auto_repeat
;
kctrl
.
auto_repeat_mode
=
AutoRepeatModeOff
;
XChangeKeyboardControl
(
dpy
,
KBAutoRepeatMode
,
&
kctrl
);
XFlush
(
dpy
);
X_UNLOCK
;
rfbLog
(
"Disabled X server key autorepeat. (you can run the
\n
"
);
rfbLog
(
"command: 'xset r on' to force it back on)
\n
"
);
}
}
static
KeySym
added_keysyms
[
0x100
];
int
add_keysym
(
KeySym
keysym
)
{
...
...
@@ -2147,25 +2320,6 @@ void initialize_remap(char *infile) {
fclose
(
in
);
}
/*
* debugging wrapper for XTestFakeKeyEvent()
*/
void
myXTestFakeKeyEvent
(
Display
*
dpy
,
KeyCode
key
,
Bool
down
,
time_t
cur_time
)
{
if
(
debug_keyboard
)
{
rfbLog
(
"XTestFakeKeyEvent(dpy, keycode=0x%x
\"
%s
\"
, %s)
\n
"
,
key
,
XKeysymToString
(
XKeycodeToKeysym
(
dpy
,
key
,
0
)),
down
?
"down"
:
"up"
);
}
if
(
down
)
{
last_keyboard_input
=
-
key
;
}
else
{
last_keyboard_input
=
key
;
}
XTestFakeKeyEvent
(
dpy
,
key
,
down
,
cur_time
);
}
/*
* preliminary support for using the Xkb (XKEYBOARD) extension for handling
* user input. inelegant, slow, and incomplete currently... but initial
...
...
@@ -2847,7 +3001,7 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
"inadvertent Multi_key from Shift "
"(doing %03d up now)
\n
"
,
shift_is_down
);
}
myXTestFakeKeyEvent
(
dpy
,
shift_is_down
,
False
,
XTestFakeKeyEvent_wr
(
dpy
,
shift_is_down
,
False
,
CurrentTime
);
}
else
{
involves_multi_key
=
0
;
...
...
@@ -2859,7 +3013,7 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
if
(
sentmods
[
i
]
==
0
)
continue
;
dn
=
(
Bool
)
needmods
[
i
];
if
(
dn
)
continue
;
myXTestFakeKeyEvent
(
dpy
,
sentmods
[
i
],
dn
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
sentmods
[
i
],
dn
,
CurrentTime
);
}
for
(
j
=
0
;
j
<
8
;
j
++
)
{
/* next, do the Mod downs */
...
...
@@ -2867,7 +3021,7 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
if
(
sentmods
[
i
]
==
0
)
continue
;
dn
=
(
Bool
)
needmods
[
i
];
if
(
!
dn
)
continue
;
myXTestFakeKeyEvent
(
dpy
,
sentmods
[
i
],
dn
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
sentmods
[
i
],
dn
,
CurrentTime
);
}
if
(
involves_multi_key
)
{
...
...
@@ -2879,14 +3033,14 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
"inadvertent Multi_key from Shift "
"(doing %03d down now)
\n
"
,
shift_is_down
);
}
myXTestFakeKeyEvent
(
dpy
,
shift_is_down
,
True
,
XTestFakeKeyEvent_wr
(
dpy
,
shift_is_down
,
True
,
CurrentTime
);
}
/*
* With the above modifier work done, send the actual keycode:
*/
myXTestFakeKeyEvent
(
dpy
,
Kc_f
,
(
Bool
)
down
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
Kc_f
,
(
Bool
)
down
,
CurrentTime
);
/*
* Now undo the modifier work:
...
...
@@ -2897,7 +3051,8 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
if
(
sentmods
[
i
]
==
0
)
continue
;
dn
=
(
Bool
)
needmods
[
i
];
if
(
!
dn
)
continue
;
myXTestFakeKeyEvent
(
dpy
,
sentmods
[
i
],
!
dn
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
sentmods
[
i
],
!
dn
,
CurrentTime
);
}
for
(
j
=
7
;
j
>=
0
;
j
--
)
{
/* finally reverse the Mod ups we did */
...
...
@@ -2905,12 +3060,13 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
if
(
sentmods
[
i
]
==
0
)
continue
;
dn
=
(
Bool
)
needmods
[
i
];
if
(
dn
)
continue
;
myXTestFakeKeyEvent
(
dpy
,
sentmods
[
i
],
!
dn
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
sentmods
[
i
],
!
dn
,
CurrentTime
);
}
}
else
{
/* for up case, hopefully just need to pop it up: */
myXTestFakeKeyEvent
(
dpy
,
Kc_f
,
(
Bool
)
down
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
Kc_f
,
(
Bool
)
down
,
CurrentTime
);
}
X_UNLOCK
;
}
...
...
@@ -3059,20 +3215,20 @@ static void tweak_mod(signed char mod, rfbBool down) {
X_LOCK
;
if
(
is_shift
&&
mod
!=
1
)
{
if
(
mod_state
&
LEFTSHIFT
)
{
myXTestFakeKeyEvent
(
dpy
,
left_shift_code
,
!
dn
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
left_shift_code
,
!
dn
,
CurrentTime
);
}
if
(
mod_state
&
RIGHTSHIFT
)
{
myXTestFakeKeyEvent
(
dpy
,
right_shift_code
,
!
dn
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
right_shift_code
,
!
dn
,
CurrentTime
);
}
}
if
(
!
is_shift
&&
mod
==
1
)
{
myXTestFakeKeyEvent
(
dpy
,
left_shift_code
,
dn
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
left_shift_code
,
dn
,
CurrentTime
);
}
if
(
altgr
&&
(
mod_state
&
ALTGR
)
&&
mod
!=
2
)
{
myXTestFakeKeyEvent
(
dpy
,
altgr
,
!
dn
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
altgr
,
!
dn
,
CurrentTime
);
}
if
(
altgr
&&
!
(
mod_state
&
ALTGR
)
&&
mod
==
2
)
{
myXTestFakeKeyEvent
(
dpy
,
altgr
,
dn
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
altgr
,
dn
,
CurrentTime
);
}
X_UNLOCK
;
if
(
debug_keyboard
)
{
...
...
@@ -3141,7 +3297,7 @@ static void modifier_tweak_keyboard(rfbBool down, rfbKeySym keysym,
}
if
(
k
!=
NoSymbol
)
{
X_LOCK
;
myXTestFakeKeyEvent
(
dpy
,
k
,
(
Bool
)
down
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
k
,
(
Bool
)
down
,
CurrentTime
);
X_UNLOCK
;
}
...
...
@@ -3219,8 +3375,8 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
return
;
}
X_LOCK
;
XTestFakeButtonEvent
(
dpy
,
button
,
True
,
CurrentTime
);
XTestFakeButtonEvent
(
dpy
,
button
,
False
,
CurrentTime
);
XTestFakeButtonEvent
_wr
(
dpy
,
button
,
True
,
CurrentTime
);
XTestFakeButtonEvent
_wr
(
dpy
,
button
,
False
,
CurrentTime
);
XFlush
(
dpy
);
X_UNLOCK
;
return
;
...
...
@@ -3252,7 +3408,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
}
if
(
k
!=
NoSymbol
)
{
myXTestFakeKeyEvent
(
dpy
,
k
,
(
Bool
)
down
,
CurrentTime
);
XTestFakeKeyEvent_wr
(
dpy
,
k
,
(
Bool
)
down
,
CurrentTime
);
XFlush
(
dpy
);
}
...
...
@@ -3261,7 +3417,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
/* -- pointer.c -- */
/*
* pointer event handling routines.
* pointer event
(motion and button click)
handling routines.
*/
typedef
struct
ptrremap
{
KeySym
keysym
;
...
...
@@ -3325,7 +3481,9 @@ static void buttonparse(int from, char **s) {
if
(
sscanf
(
t
,
"0x%x"
,
&
i
)
==
1
)
{
ksym
=
(
KeySym
)
i
;
/* hex value */
}
else
{
X_LOCK
;
ksym
=
XStringToKeysym
(
t
);
/* string value */
X_UNLOCK
;
}
if
(
ksym
==
NoSymbol
)
{
/* see if Button<N> "keysym" was used: */
...
...
@@ -3348,6 +3506,7 @@ static void buttonparse(int from, char **s) {
/*
* XXX may not work with -modtweak or -xkb
*/
X_LOCK
;
kcode
=
XKeysymToKeycode
(
dpy
,
ksym
);
pointer_map
[
from
][
n
].
keysym
=
ksym
;
...
...
@@ -3374,6 +3533,7 @@ static void buttonparse(int from, char **s) {
XKeysymToString
(
ksym
),
ksym
,
kcode
,
pointer_map
[
from
][
n
].
down
,
pointer_map
[
from
][
n
].
up
);
X_UNLOCK
;
}
t
=
strtok
(
NULL
,
"+"
);
n
++
;
...
...
@@ -3442,6 +3602,7 @@ void initialize_pointer_map(char *pointer_remap) {
X_LOCK
;
num_buttons
=
XGetPointerMapping
(
dpy
,
map
,
MAX_BUTTONS
);
X_UNLOCK
;
if
(
num_buttons
<
0
)
{
num_buttons
=
0
;
...
...
@@ -3500,30 +3661,37 @@ void initialize_pointer_map(char *pointer_remap) {
}
}
}
X_UNLOCK
;
}
/*
* Send a pointer event to the X server.
*/
static
void
update_pointer
(
int
mask
,
int
x
,
int
y
)
{
static
void
update_
x11_
pointer
(
int
mask
,
int
x
,
int
y
)
{
int
i
,
mb
;
X_LOCK
;
if
(
!
use_xwarppointer
)
{
XTestFakeMotionEvent
(
dpy
,
scr
,
x
+
off_x
,
y
+
off_y
,
CurrentTime
);
}
else
{
if
(
use_xwarppointer
)
{
XWarpPointer
(
dpy
,
None
,
window
,
0
,
0
,
0
,
0
,
x
+
off_x
,
y
+
off_y
);
}
else
{
XTestFakeMotionEvent_wr
(
dpy
,
scr
,
x
+
off_x
,
y
+
off_y
,
CurrentTime
);
}
X_UNLOCK
;
cursor_x
=
x
;
cursor_y
=
y
;
/* record the x, y position for the rfb screen as well. */
cursor_position
(
x
,
y
);
/* change the cursor shape if necessary */
set_cursor
(
x
,
y
,
get_which_cursor
());
last_event
=
last_input
=
time
(
0
);
for
(
i
=
0
;
i
<
MAX_BUTTONS
;
i
++
)
{
X_LOCK
;
/* look for buttons that have be clicked or released: */
for
(
i
=
0
;
i
<
MAX_BUTTONS
;
i
++
)
{
if
(
(
button_mask
&
(
1
<<
i
))
!=
(
mask
&
(
1
<<
i
))
)
{
int
k
;
if
(
debug_pointer
)
{
...
...
@@ -3552,7 +3720,7 @@ static void update_pointer(int mask, int x, int y) {
" %s (event %d)
\n
"
,
mb
,
bmask
?
"down"
:
"up"
,
k
+
1
);
}
XTestFakeButtonEvent
(
dpy
,
mb
,
(
mask
&
(
1
<<
i
))
XTestFakeButtonEvent
_wr
(
dpy
,
mb
,
(
mask
&
(
1
<<
i
))
?
True
:
False
,
CurrentTime
);
}
else
{
/* sent keysym up or down */
...
...
@@ -3574,11 +3742,11 @@ static void update_pointer(int mask, int x, int y) {
dpy
,
key
,
0
)));
}
if
(
down
)
{
myXTestFakeKeyEvent
(
dpy
,
key
,
True
,
XTestFakeKeyEvent_wr
(
dpy
,
key
,
True
,
CurrentTime
);
}
if
(
up
)
{
myXTestFakeKeyEvent
(
dpy
,
key
,
False
,
XTestFakeKeyEvent_wr
(
dpy
,
key
,
False
,
CurrentTime
);
}
}
...
...
@@ -3605,24 +3773,38 @@ static void update_pointer(int mask, int x, int y) {
/*
* Actual callback from libvncserver when it gets a pointer event.
* This may queue pointer events rather than sending them immediately
* to the X server. (see update_x11_pointer())
*/
void
pointer
(
int
mask
,
int
x
,
int
y
,
rfbClientPtr
client
)
{
if
(
debug_pointer
&&
mask
>=
0
)
{
rfbLog
(
"pointer(mask: 0x%x, x:%4d, y:%4d)
\n
"
,
mask
,
x
,
y
);
static
int
show_motion
=
-
1
;
if
(
show_motion
==
-
1
)
{
if
(
getenv
(
"X11VNC_DB_NOMOTION"
))
{
show_motion
=
0
;
}
else
{
show_motion
=
1
;
}
}
if
(
show_motion
)
{
rfbLog
(
"pointer(mask: 0x%x, x:%4d, y:%4d)
\n
"
,
mask
,
x
,
y
);
}
}
if
(
view_only
)
{
return
;
}
if
(
client
->
viewOnly
)
{
if
(
client
&&
client
->
viewOnly
)
{
return
;
}
if
(
scaling
)
{
/* map from rfb size to X11 size: */
x
=
((
double
)
x
/
scaled_x
)
*
dpy_x
;
if
(
x
>=
dpy_x
)
x
=
dpy_x
-
1
;
x
=
nfix
(
x
,
dpy_x
)
;
y
=
((
double
)
y
/
scaled_y
)
*
dpy_y
;
if
(
y
>=
dpy_y
)
y
=
dpy_y
-
1
;
y
=
nfix
(
y
,
dpy_y
)
;
}
if
(
mask
>=
0
)
{
...
...
@@ -3698,7 +3880,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
if
(
debug_pointer
)
{
rfbLog
(
"pointer(): sending event %d
\n
"
,
i
+
1
);
}
update_pointer
(
ev
[
i
][
0
],
ev
[
i
][
1
],
ev
[
i
][
2
]);
update_
x11_
pointer
(
ev
[
i
][
0
],
ev
[
i
][
1
],
ev
[
i
][
2
]);
}
if
(
nevents
&&
dt
>
maxwait
)
{
X_LOCK
;
...
...
@@ -3720,7 +3902,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
}
/* update the X display with the event: */
update_pointer
(
mask
,
x
,
y
);
update_
x11_
pointer
(
mask
,
x
,
y
);
}
/* -- xkb_bell.c -- */
...
...
@@ -3782,7 +3964,7 @@ void initialize_watch_bell(void) {
* We call this periodically to process any bell events that have
* taken place.
*/
void
watch
_bell_event
(
void
)
{
void
check
_bell_event
(
void
)
{
XEvent
xev
;
XkbAnyEvent
*
xkb_ev
;
int
got_bell
=
0
;
...
...
@@ -3804,7 +3986,7 @@ void watch_bell_event(void) {
if
(
got_bell
)
{
if
(
!
all_clients_initialized
())
{
rfbLog
(
"
watch
_bell_event: not sending bell: "
rfbLog
(
"
check
_bell_event: not sending bell: "
"uninitialized clients
\n
"
);
}
else
{
rfbSendBell
(
screen
);
...
...
@@ -3812,7 +3994,7 @@ void watch_bell_event(void) {
}
}
#else
void
watch
_bell_event
(
void
)
{}
void
check
_bell_event
(
void
)
{}
#endif
/* -- selection.c -- */
...
...
@@ -4060,7 +4242,7 @@ static void selection_send(XEvent *ev) {
* This routine is periodically called to check for selection related
* and other X11 events and respond to them as needed.
*/
void
watch
_xevents
(
void
)
{
void
check
_xevents
(
void
)
{
XEvent
xev
;
static
int
first
=
1
,
sent_some_sel
=
0
;
static
time_t
last_request
=
0
;
...
...
@@ -4245,10 +4427,11 @@ typedef struct cursor_info {
int
wx
,
wy
;
/* size of cursor */
int
sx
,
sy
;
/* shift to its centering point */
int
reverse
;
/* swap black and white */
rfbCursorPtr
rfb
;
}
cursor_info_t
;
/* main cursor */
static
char
*
cur_data
=
static
char
*
cur
s_arrow
_data
=
" "
" x "
" xx "
...
...
@@ -4268,7 +4451,7 @@ static char* cur_data =
" "
" "
;
static
char
*
cur_mask
=
static
char
*
cur
s_arrow
_mask
=
"xx "
"xxx "
"xxxx "
...
...
@@ -4287,16 +4470,13 @@ static char* cur_mask =
" xx "
" "
" "
;
#define CUR_SIZE 18
#define CUR_DATA cur_data
#define CUR_MASK cur_mask
static
cursor_info_t
cur0
=
{
NULL
,
NULL
,
CUR_SIZE
,
CUR_SIZE
,
0
,
0
,
0
};
static
cursor_info_t
cur_arrow
=
{
NULL
,
NULL
,
18
,
18
,
0
,
0
,
0
,
NULL
};
/*
* It turns out we can at least detect mouse is on the root window so
* show it (under -
mouse
X or -X) with this familiar cursor...
* show it (under -
cursor
X or -X) with this familiar cursor...
*/
static
char
*
root_data
=
static
char
*
curs_
root_data
=
" "
" "
" xxx xxx "
...
...
@@ -4316,7 +4496,7 @@ static char* root_data =
" "
" "
;
static
char
*
root_mask
=
static
char
*
curs_
root_mask
=
" "
" xxxx xxxx "
" xxxxx xxxxx "
...
...
@@ -4335,75 +4515,179 @@ static char* root_mask =
" xxxxx xxxxx "
" xxxx xxxx "
" "
;
static
cursor_info_t
cur1
=
{
NULL
,
NULL
,
18
,
18
,
8
,
8
,
1
};
static
cursor_info_t
cur_root
=
{
NULL
,
NULL
,
18
,
18
,
8
,
8
,
1
,
NULL
};
static
char
*
curs_fleur_data
=
" "
" xx "
" xxxx "
" xxxxxx "
" xx "
" x xx x "
" xx xx xx "
" xxxxxxxxxxxxxx "
" xxxxxxxxxxxxxx "
" xx xx xx "
" x xx x "
" xx "
" xxxxxx "
" xxxx "
" xx "
" "
;
static
char
*
curs_fleur_mask
=
" xxxx "
" xxxxx "
" xxxxxx "
" xxxxxxxx "
" x xxxxxx x "
" xxx xxxx xxx "
"xxxxxxxxxxxxxxxx"
"xxxxxxxxxxxxxxxx"
"xxxxxxxxxxxxxxxx"
"xxxxxxxxxxxxxxxx"
" xxx xxxx xxx "
" x xxxxxx x "
" xxxxxxxx "
" xxxxxx "
" xxxx "
" xxxx "
;
static
cursor_info_t
cur_fleur
=
{
NULL
,
NULL
,
16
,
16
,
8
,
8
,
1
,
NULL
};
static
char
*
curs_plus_data
=
" "
" xx "
" xx "
" xx "
" xx "
" xxxxxxxxxx "
" xxxxxxxxxx "
" xx "
" xx "
" xx "
" xx "
" "
;
static
char
*
curs_plus_mask
=
" xxxx "
" xxxx "
" xxxx "
" xxxx "
"xxxxxxxxxxxx"
"xxxxxxxxxxxx"
"xxxxxxxxxxxx"
"xxxxxxxxxxxx"
" xxxx "
" xxxx "
" xxxx "
" xxxx "
;
static
cursor_info_t
cur_plus
=
{
NULL
,
NULL
,
12
,
12
,
5
,
6
,
1
,
NULL
};
static
char
*
curs_xterm_data
=
" "
" xxx xxx "
" xxx "
" x "
" x "
" x "
" x "
" x "
" x "
" x "
" x "
" x "
" x "
" xxx "
" xxx xxx "
" "
;
static
cursor_info_t
*
cursors
[
2
];
static
char
*
curs_xterm_mask
=
" xxxx xxxx "
" xxxxxxxxx "
" xxxxxxxxx "
" xxxxx "
" xxx "
" xxx "
" xxx "
" xxx "
" xxx "
" xxx "
" xxx "
" xxx "
" xxxxx "
" xxxxxxxxx "
" xxxxxxxxx "
" xxxx xxxx "
;
static
cursor_info_t
cur_xterm
=
{
NULL
,
NULL
,
16
,
16
,
8
,
8
,
1
,
NULL
};
enum
cursor_names
{
CURS_ARROW
=
0
,
CURS_ROOT
,
CURS_WM
,
CURS_TERM
};
static
cursor_info_t
*
cursors
[
10
];
static
void
setup_cursors
(
void
)
{
/* TODO clean this up if we ever do more cursors... */
rfbCursorPtr
rfb_curs
;
int
i
,
n
=
0
;
cur
0
.
data
=
cur
_data
;
cur
0
.
mask
=
cur
_mask
;
cur
_arrow
.
data
=
curs_arrow
_data
;
cur
_arrow
.
mask
=
curs_arrow
_mask
;
cur
1
.
data
=
root_data
;
cur
1
.
mask
=
root_mask
;
cur
_root
.
data
=
curs_
root_data
;
cur
_root
.
mask
=
curs_
root_mask
;
cursors
[
0
]
=
&
cur0
;
cursors
[
1
]
=
&
cur1
;
}
cur_plus
.
data
=
curs_plus_data
;
cur_plus
.
mask
=
curs_plus_mask
;
/*
* data and functions for -mouse real pointer position updates
*/
static
char
cur_save
[(
4
*
CUR_SIZE
*
CUR_SIZE
)];
static
int
cur_save_cx
,
cur_save_cy
,
cur_save_which
;
cur_fleur
.
data
=
curs_fleur_data
;
cur_fleur
.
mask
=
curs_fleur_mask
;
/*
* save current cursor info and the patch of non-cursor data it covers
*/
static
void
save_mouse_patch
(
int
x
,
int
y
,
int
w
,
int
h
,
int
cx
,
int
cy
,
int
which
)
{
int
pixelsize
=
bpp
>>
3
;
char
*
fbp
=
main_fb
;
int
ly
,
i
=
0
;
cur_xterm
.
data
=
curs_xterm_data
;
cur_xterm
.
mask
=
curs_xterm_mask
;
for
(
ly
=
y
;
ly
<
y
+
h
;
ly
++
)
{
memcpy
(
cur_save
+
i
,
fbp
+
ly
*
main_bytes_per_line
+
x
*
pixelsize
,
w
*
pixelsize
);
cursors
[
CURS_ARROW
]
=
&
cur_arrow
;
n
++
;
cursors
[
CURS_ROOT
]
=
&
cur_root
;
n
++
;
cursors
[
CURS_WM
]
=
&
cur_fleur
;
n
++
;
cursors
[
CURS_TERM
]
=
&
cur_xterm
;
n
++
;
i
+=
w
*
pixelsize
;
}
cur_save_x
=
x
;
/* patch geometry */
cur_save_y
=
y
;
cur_save_w
=
w
;
cur_save_h
=
h
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
cursor_info_t
*
ci
=
cursors
[
i
];
cur_save_which
=
which
;
/* which cursor and its position */
cur_save_cx
=
cx
;
cur_save_cy
=
cy
;
ci
->
data
=
strdup
(
ci
->
data
);
ci
->
mask
=
strdup
(
ci
->
mask
);
cur_saved
=
1
;
}
rfb_curs
=
rfbMakeXCursor
(
ci
->
wx
,
ci
->
wy
,
ci
->
data
,
ci
->
mask
);
/*
* put the non-cursor patch back in the rfb fb
*/
void
restore_mouse_patch
(
void
)
{
int
pixelsize
=
bpp
>>
3
;
char
*
fbp
=
main_fb
;
int
ly
,
i
=
0
;
if
(
!
cur_saved
)
{
return
;
/* not yet saved */
if
(
ci
->
reverse
)
{
rfb_curs
->
foreRed
=
0x0000
;
rfb_curs
->
foreGreen
=
0x0000
;
rfb_curs
->
foreBlue
=
0x0000
;
rfb_curs
->
backRed
=
0xffff
;
rfb_curs
->
backGreen
=
0xffff
;
rfb_curs
->
backBlue
=
0xffff
;
}
rfb_curs
->
xhot
=
ci
->
sx
;
rfb_curs
->
yhot
=
ci
->
sy
;
rfb_curs
->
cleanup
=
FALSE
;
rfb_curs
->
cleanupSource
=
FALSE
;
rfb_curs
->
cleanupMask
=
FALSE
;
rfb_curs
->
cleanupRichSource
=
FALSE
;
for
(
ly
=
cur_save_y
;
ly
<
cur_save_y
+
cur_save_h
;
ly
++
)
{
memcpy
(
fbp
+
ly
*
main_bytes_per_line
+
cur_save_x
*
pixelsize
,
cur_save
+
i
,
cur_save_w
*
pixelsize
);
i
+=
cur_save_w
*
pixelsize
;
ci
->
rfb
=
rfb_curs
;
}
}
typedef
struct
win_str_info
{
char
*
wm_name
;
char
*
res_name
;
char
*
res_class
;
}
win_str_info_t
;
/*
* Descends window tree at pointer until the window cursor matches the current
* cursor. So far only used to detect if mouse is on root background or not.
...
...
@@ -4412,95 +4696,306 @@ void restore_mouse_patch(void) {
* It seems impossible to do, but if the actual cursor could ever be
* determined we might want to hash that info on window ID or something...
*/
static
int
tree_descend_cursor
(
void
)
{
void
tree_descend_cursor
(
int
*
depth
,
Window
*
w
,
win_str_info_t
*
winfo
)
{
Window
r
,
c
;
int
rx
,
ry
,
wx
,
wy
;
int
i
,
rx
,
ry
,
wx
,
wy
;
unsigned
int
mask
;
int
descend
=
0
,
tries
=
0
,
maxtries
=
1
;
Window
wins
[
10
];
int
descend
,
maxtries
=
10
;
char
*
name
,
a
;
static
XClassHint
*
classhint
=
NULL
;
int
nm_info
=
1
;
XErrorHandler
old_handler
;
X_LOCK
;
a
=
multiple_cursors_mode
[
0
];
if
(
a
==
'd'
||
a
==
'X'
)
{
nm_info
=
0
;
}
*
(
winfo
->
wm_name
)
=
'\0'
;
*
(
winfo
->
res_name
)
=
'\0'
;
*
(
winfo
->
res_class
)
=
'\0'
;
/* some times a window can go away before we get to it */
trapped_xerror
=
0
;
old_handler
=
XSetErrorHandler
(
trap_xerror
);
c
=
window
;
descend
=
-
1
;
while
(
c
)
{
if
(
++
tries
>
maxtries
)
{
descend
=
maxtries
;
wins
[
++
descend
]
=
c
;
if
(
descend
>=
maxtries
-
1
)
{
break
;
}
if
(
XTestCompareCurrentCursorWithWindow
(
dpy
,
c
)
)
{
if
(
XTestCompareCurrentCursorWithWindow
_wr
(
dpy
,
c
)
)
{
break
;
}
XQueryPointer
(
dpy
,
c
,
&
r
,
&
c
,
&
rx
,
&
ry
,
&
wx
,
&
wy
,
&
mask
);
descend
++
;
}
X_UNLOCK
;
return
descend
;
if
(
nm_info
)
{
int
got_wm_name
=
0
,
got_res_name
=
0
,
got_res_class
=
0
;
if
(
!
classhint
)
{
classhint
=
XAllocClassHint
();
}
for
(
i
=
descend
;
i
>=
0
;
i
--
)
{
c
=
wins
[
i
];
if
(
!
c
)
{
continue
;
}
if
(
!
got_wm_name
&&
XFetchName
(
dpy
,
c
,
&
name
))
{
if
(
name
)
{
if
(
*
name
!=
'\0'
)
{
strcpy
(
winfo
->
wm_name
,
name
);
got_wm_name
=
1
;
}
XFree
(
name
);
}
}
if
(
classhint
&&
(
!
got_res_name
||
!
got_res_class
))
{
if
(
XGetClassHint
(
dpy
,
c
,
classhint
))
{
char
*
p
;
p
=
classhint
->
res_name
;
if
(
p
)
{
if
(
*
p
!=
'\0'
&&
!
got_res_name
)
{
strcpy
(
winfo
->
res_name
,
p
);
got_res_name
=
1
;
}
XFree
(
p
);
classhint
->
res_name
=
NULL
;
}
p
=
classhint
->
res_class
;
if
(
p
)
{
if
(
*
p
!=
'\0'
&&
!
got_res_class
)
{
strcpy
(
winfo
->
res_class
,
p
);
got_res_class
=
1
;
}
XFree
(
p
);
classhint
->
res_class
=
NULL
;
}
}
}
}
}
XSetErrorHandler
(
old_handler
);
trapped_xerror
=
0
;
X_UNLOCK
;
*
depth
=
descend
;
*
w
=
wins
[
descend
];
}
int
get_which_cursor
(
void
)
{
int
which
=
CURS_ARROW
;
if
(
show_multiple_cursors
)
{
int
depth
;
static
win_str_info_t
winfo
;
static
int
first
=
1
,
depth_cutoff
=
-
1
;
Window
win
;
XErrorHandler
old_handler
;
int
mode
=
0
;
char
a
=
multiple_cursors_mode
[
0
];
if
(
a
==
'd'
)
{
mode
=
0
;
}
else
if
(
a
==
'X'
)
{
mode
=
1
;
}
else
{
mode
=
2
;
}
if
(
depth_cutoff
<
0
)
{
int
din
;
if
(
sscanf
(
multiple_cursors_mode
,
"X%d"
,
&
din
)
==
1
)
{
depth_cutoff
=
din
;
}
else
{
depth_cutoff
=
0
;
}
}
if
(
first
)
{
winfo
.
wm_name
=
(
char
*
)
malloc
(
1024
);
winfo
.
res_name
=
(
char
*
)
malloc
(
1024
);
winfo
.
res_class
=
(
char
*
)
malloc
(
1024
);
}
first
=
0
;
tree_descend_cursor
(
&
depth
,
&
win
,
&
winfo
);
if
(
depth
<=
depth_cutoff
)
{
which
=
CURS_ROOT
;
}
else
if
(
mode
>=
2
)
{
int
which0
=
which
;
if
(
win
)
{
int
ratio
=
10
,
x
,
y
;
unsigned
int
w
,
h
,
bw
,
d
;
Window
r
;
trapped_xerror
=
0
;
old_handler
=
XSetErrorHandler
(
trap_xerror
);
if
(
XGetGeometry
(
dpy
,
win
,
&
r
,
&
x
,
&
y
,
&
w
,
&
h
,
&
bw
,
&
d
))
{
if
(
w
>
ratio
*
h
||
h
>
ratio
*
w
)
{
which
=
CURS_WM
;
}
}
XSetErrorHandler
(
old_handler
);
trapped_xerror
=
0
;
}
if
(
which
==
which0
)
{
lowercase
(
winfo
.
res_name
);
lowercase
(
winfo
.
res_class
);
if
(
strstr
(
winfo
.
res_name
,
"term"
))
{
which
=
CURS_TERM
;
}
else
if
(
strstr
(
winfo
.
res_class
,
"term"
))
{
which
=
CURS_TERM
;
}
}
}
}
return
which
;
}
/*
* Some utilities for marking the little cursor patch region as
* modified, etc.
*/
void
mark_cursor_patch_modified
(
rfbScreenInfoPtr
s
,
int
old
)
{
int
curx
,
cury
,
xhot
,
yhot
,
w
,
h
;
int
x1
,
x2
,
y1
,
y2
;
if
(
!
s
->
cursor
)
{
return
;
}
if
(
old
)
{
/* use oldCursor pos */
curx
=
s
->
oldCursorX
;
cury
=
s
->
oldCursorY
;
}
else
{
curx
=
s
->
cursorX
;
cury
=
s
->
cursorY
;
}
xhot
=
s
->
cursor
->
xhot
;
yhot
=
s
->
cursor
->
yhot
;
w
=
s
->
cursor
->
width
;
h
=
s
->
cursor
->
height
;
x1
=
curx
-
xhot
;
x2
=
x1
+
w
;
x1
=
nfix
(
x1
,
s
->
width
);
x2
=
nfix
(
x2
,
s
->
width
);
y1
=
cury
-
yhot
;
y2
=
y1
+
h
;
y1
=
nfix
(
y1
,
s
->
height
);
y2
=
nfix
(
y2
,
s
->
height
);
rfbMarkRectAsModified
(
s
,
x1
,
y1
,
x1
+
x2
,
y1
+
y2
);
}
void
set_cursor_was_changed
(
rfbScreenInfoPtr
s
)
{
rfbClientIteratorPtr
iter
;
rfbClientPtr
cl
;
iter
=
rfbGetClientIterator
(
s
);
while
(
(
cl
=
rfbClientIteratorNext
(
iter
))
)
{
cl
->
cursorWasChanged
=
TRUE
;
}
rfbReleaseClientIterator
(
iter
);
}
void
set_cursor_was_moved
(
rfbScreenInfoPtr
s
)
{
rfbClientIteratorPtr
iter
;
rfbClientPtr
cl
;
iter
=
rfbGetClientIterator
(
s
);
while
(
(
cl
=
rfbClientIteratorNext
(
iter
))
)
{
cl
->
cursorWasMoved
=
TRUE
;
}
rfbReleaseClientIterator
(
iter
);
}
void
unset_cursor_shape_updates
(
rfbScreenInfoPtr
s
)
{
rfbClientIteratorPtr
iter
;
rfbClientPtr
cl
;
iter
=
rfbGetClientIterator
(
s
);
while
(
(
cl
=
rfbClientIteratorNext
(
iter
))
)
{
cl
->
enableCursorShapeUpdates
=
FALSE
;
cl
->
enableCursorPosUpdates
=
FALSE
;
cl
->
cursorWasChanged
=
FALSE
;
}
rfbReleaseClientIterator
(
iter
);
}
/*
* This is for mouse patch drawing under -xinerama or -blackout
*/
static
void
blackout_nearby_tiles
(
int
x
,
int
y
,
int
dt
)
{
int
sx
,
sy
,
n
,
b
;
int
tx
=
x
/
tile_x
;
int
ty
=
y
/
tile_y
;
int
cursor_pos_updates_clients
(
rfbScreenInfoPtr
s
)
{
rfbClientIteratorPtr
iter
;
rfbClientPtr
cl
;
int
count
=
0
;
if
(
!
blackouts
)
{
return
;
iter
=
rfbGetClientIterator
(
s
);
while
(
(
cl
=
rfbClientIteratorNext
(
iter
))
)
{
if
(
cl
->
enableCursorPosUpdates
)
{
count
++
;
}
if
(
dt
<
1
)
{
dt
=
1
;
}
/* loop over a range of tiles, blacking out as needed */
rfbReleaseClientIterator
(
iter
);
return
count
;
}
for
(
sx
=
tx
-
dt
;
sx
<=
tx
+
dt
;
sx
++
)
{
if
(
sx
<
0
||
sx
>=
tile_x
)
{
continue
;
}
for
(
sy
=
ty
-
dt
;
sy
<=
ty
+
dt
;
sy
++
)
{
if
(
sy
<
0
||
sy
>=
tile_y
)
{
continue
;
}
n
=
sx
+
sy
*
ntiles_x
;
if
(
tile_blackout
[
n
].
cover
==
0
)
{
continue
;
}
for
(
b
=
0
;
b
<=
tile_blackout
[
n
].
count
;
b
++
)
{
int
x1
,
y1
,
x2
,
y2
;
x1
=
tile_blackout
[
n
].
bo
[
b
].
x1
;
y1
=
tile_blackout
[
n
].
bo
[
b
].
y1
;
x2
=
tile_blackout
[
n
].
bo
[
b
].
x2
;
y2
=
tile_blackout
[
n
].
bo
[
b
].
y2
;
zero_fb
(
x1
,
y1
,
x2
,
y2
);
}
int
cursor_shape_updates_clients
(
rfbScreenInfoPtr
s
)
{
rfbClientIteratorPtr
iter
;
rfbClientPtr
cl
;
int
count
=
0
;
iter
=
rfbGetClientIterator
(
s
);
while
(
(
cl
=
rfbClientIteratorNext
(
iter
))
)
{
if
(
cl
->
enableCursorShapeUpdates
)
{
count
++
;
}
}
rfbReleaseClientIterator
(
iter
);
return
count
;
}
/*
* Send rfbCursorPosUpdates back to clients that understand them. This
* seems to be TightVNC specific.
* Record rfb cursor position screen->cursorX, etc (a la defaultPtrAddEvent())
* Then set up for sending rfbCursorPosUpdates back
* to clients that understand them. This seems to be TightVNC specific.
*/
static
void
cursor_pos_updates
(
int
x
,
int
y
)
{
void
cursor_position
(
int
x
,
int
y
)
{
rfbClientIteratorPtr
iter
;
rfbClientPtr
cl
;
int
cnt
=
0
;
int
x_in
=
x
,
y_in
=
y
;
if
(
!
cursor_pos
)
{
return
;
}
int
cnt
=
0
,
nonCursorPosUpdates_clients
=
0
;
int
x_old
,
y_old
,
x_in
=
x
,
y_in
=
y
;
/* x and y are current positions of X11 pointer on the X11 display */
if
(
scaling
)
{
x
=
((
double
)
x
/
dpy_x
)
*
scaled_x
;
if
(
x
>=
scaled_x
)
x
=
scaled_x
-
1
;
x
=
nfix
(
x
,
scaled_x
)
;
y
=
((
double
)
y
/
dpy_y
)
*
scaled_y
;
if
(
y
>=
scaled_y
)
y
=
scaled_y
-
1
;
y
=
nfix
(
y
,
scaled_y
)
;
}
if
(
x
==
screen
->
cursorX
&&
y
==
screen
->
cursorY
)
{
return
;
}
x_old
=
screen
->
oldCursorX
;
y_old
=
screen
->
oldCursorY
;
if
(
screen
->
cursorIsDrawn
)
{
rfbUndrawCursor
(
screen
);
...
...
@@ -4516,6 +5011,10 @@ static void cursor_pos_updates(int x, int y) {
iter
=
rfbGetClientIterator
(
screen
);
while
(
(
cl
=
rfbClientIteratorNext
(
iter
))
)
{
if
(
!
cl
->
enableCursorPosUpdates
)
{
nonCursorPosUpdates_clients
++
;
continue
;
}
if
(
!
cursor_pos_updates
)
{
continue
;
}
if
(
cl
==
last_pointer_client
)
{
...
...
@@ -4528,7 +5027,7 @@ static void cursor_pos_updates(int x, int y) {
}
else
{
/* an X11 app evidently warped the pointer */
if
(
debug_pointer
)
{
rfbLog
(
"cursor_pos
_updates
: warp "
rfbLog
(
"cursor_pos
ition
: warp "
"detected dx=%3d dy=%3d
\n
"
,
cursor_x
-
x
,
cursor_y
-
y
);
}
...
...
@@ -4542,190 +5041,76 @@ static void cursor_pos_updates(int x, int y) {
}
rfbReleaseClientIterator
(
iter
);
if
(
nonCursorPosUpdates_clients
&&
show_cursor
)
{
if
(
x_old
!=
x
||
y_old
!=
y
)
{
mark_cursor_patch_modified
(
screen
,
0
);
}
}
if
(
debug_pointer
&&
cnt
)
{
rfbLog
(
"cursor_pos
_updates
: sent position x=%3d y=%3d to %d"
rfbLog
(
"cursor_pos
ition
: sent position x=%3d y=%3d to %d"
" clients
\n
"
,
x
,
y
,
cnt
);
}
}
/*
* draw one of the mouse cursors into the rfb fb
*/
static
void
draw_mouse
(
int
x
,
int
y
,
int
which
,
int
update
)
{
int
px
,
py
,
i
,
offset
;
int
pixelsize
=
bpp
>>
3
;
char
*
fbp
=
main_fb
;
char
cdata
,
cmask
;
char
*
data
,
*
mask
;
int
white
=
255
,
black
=
0
,
shade
;
int
x0
,
x1
,
x2
,
y0
,
y1
,
y2
;
int
cur_x
,
cur_y
,
cur_sx
,
cur_sy
,
reverse
;
static
int
first
=
1
;
void
set_rfb_cursor
(
int
which
)
{
int
workaround
=
1
;
/* if rfbSetCursor does not mark modified */
if
(
!
show_
mouse
)
{
if
(
!
show_
cursor
)
{
return
;
}
if
(
first
)
{
first
=
0
;
setup_cursors
();
}
data
=
cursors
[
which
]
->
data
;
/* pattern data */
mask
=
cursors
[
which
]
->
mask
;
cur_x
=
cursors
[
which
]
->
wx
;
/* widths */
cur_y
=
cursors
[
which
]
->
wy
;
cur_sx
=
cursors
[
which
]
->
sx
;
/* shifts */
cur_sy
=
cursors
[
which
]
->
sy
;
reverse
=
cursors
[
which
]
->
reverse
;
/* reverse video */
if
(
indexed_colour
)
{
black
=
BlackPixel
(
dpy
,
scr
)
%
256
;
white
=
WhitePixel
(
dpy
,
scr
)
%
256
;
}
if
(
reverse
)
{
int
tmp
=
black
;
black
=
white
;
white
=
tmp
;
}
/*
* notation:
* x0, y0: position after cursor shift (no edge corrections)
* x1, y1: corrected for lower boundary < 0
* x2, y2: position + cursor width and corrected for upper boundary
*/
x0
=
x1
=
x
-
cur_sx
;
/* apply shift */
if
(
x1
<
0
)
x1
=
0
;
y0
=
y1
=
y
-
cur_sy
;
if
(
y1
<
0
)
y1
=
0
;
x2
=
x0
+
cur_x
;
/* apply width for upper endpoints */
if
(
x2
>=
dpy_x
)
x2
=
dpy_x
-
1
;
y2
=
y0
+
cur_y
;
if
(
y2
>=
dpy_y
)
y2
=
dpy_y
-
1
;
/* save the patch and info about which cursor will overwrite it */
save_mouse_patch
(
x1
,
y1
,
x2
-
x1
,
y2
-
y1
,
x
,
y
,
which
);
for
(
py
=
0
;
py
<
cur_y
;
py
++
)
{
if
(
y0
+
py
<
0
||
y0
+
py
>=
dpy_y
)
{
continue
;
/* off screen */
}
for
(
px
=
0
;
px
<
cur_x
;
px
++
)
{
if
(
x0
+
px
<
0
||
x0
+
px
>=
dpy_x
){
continue
;
/* off screen */
}
cdata
=
data
[
px
+
py
*
cur_x
];
cmask
=
mask
[
px
+
py
*
cur_x
];
if
(
cmask
!=
'x'
)
{
continue
;
/* transparent */
}
shade
=
white
;
if
(
cdata
!=
cmask
)
{
shade
=
black
;
}
offset
=
(
y0
+
py
)
*
main_bytes_per_line
+
(
x0
+
px
)
*
pixelsize
;
if
(
workaround
&&
screen
->
cursor
)
{
int
all_are_cursor_pos
=
1
;
rfbClientIteratorPtr
iter
;
rfbClientPtr
cl
;
/* fill in each color byte in the fb */
for
(
i
=
0
;
i
<
pixelsize
;
i
++
)
{
fbp
[
offset
+
i
]
=
(
char
)
shade
;
}
iter
=
rfbGetClientIterator
(
screen
);
while
(
(
cl
=
rfbClientIteratorNext
(
iter
))
)
{
if
(
!
cl
->
enableCursorPosUpdates
)
{
all_are_cursor_pos
=
0
;
}
if
(
!
cl
->
enableCursorShapeUpdates
)
{
all_are_cursor_pos
=
0
;
}
if
(
blackouts
)
{
/*
* loop over a range of tiles, blacking out as needed
* note we currently disable mouse drawing under blackouts.
*/
static
int
mx
=
-
1
,
my
=
-
1
;
int
skip
=
0
;
if
(
mx
<
0
)
{
mx
=
x
;
my
=
y
;
}
else
if
(
mx
==
x
&&
my
==
y
)
{
skip
=
1
;
}
mx
=
x
;
my
=
y
;
rfbReleaseClientIterator
(
iter
);
if
(
!
skip
)
{
blackout_nearby_tiles
(
x
,
y
,
2
);
if
(
!
all_are_cursor_pos
)
{
mark_cursor_patch_modified
(
screen
,
1
);
}
}
if
(
update
)
{
/* x and y of the real (X server) mouse */
static
int
mouse_x
=
-
1
;
static
int
mouse_y
=
-
1
;
if
(
x
!=
mouse_x
||
y
!=
mouse_y
)
{
hint_t
hint
;
hint
.
x
=
x1
;
hint
.
y
=
y2
;
hint
.
w
=
x2
-
x1
;
hint
.
h
=
y2
-
y1
;
rfbSetCursor
(
screen
,
cursors
[
which
]
->
rfb
,
FALSE
);
mark_hint
(
hint
);
if
(
mouse_x
<
0
)
{
mouse_x
=
0
;
}
if
(
mouse_y
<
0
)
{
mouse_y
=
0
;
/* this is a 2nd workaround for rfbSetCursor() */
if
(
screen
->
underCursorBuffer
==
NULL
&&
screen
->
underCursorBufferLen
!=
0
)
{
screen
->
underCursorBufferLen
=
0
;
}
/* XXX this ignores change of shift... */
x1
=
mouse_x
-
cur_sx
;
if
(
x1
<
0
)
x1
=
0
;
y1
=
mouse_y
-
cur_sy
;
if
(
y1
<
0
)
y1
=
0
;
x2
=
mouse_x
-
cur_sx
+
cur_x
;
if
(
x2
>=
dpy_x
)
x2
=
dpy_x
-
1
;
y2
=
mouse_y
-
cur_sy
+
cur_y
;
if
(
y2
>=
dpy_y
)
y2
=
dpy_y
-
1
;
hint
.
x
=
x1
;
hint
.
y
=
y2
;
hint
.
w
=
x2
-
x1
;
hint
.
h
=
y2
-
y1
;
mark_hint
(
hint
);
mouse_x
=
x
;
mouse_y
=
y
;
}
if
(
workaround
)
{
set_cursor_was_changed
(
screen
);
}
}
/*
* wrapper to redraw the mouse patch
*/
void
redraw_mouse
(
void
)
{
if
(
cur_saved
)
{
/* redraw saved mouse from info (save_mouse_patch) */
draw_mouse
(
cur_save_cx
,
cur_save_cy
,
cur_save_which
,
0
);
void
set_cursor
(
int
x
,
int
y
,
int
which
)
{
static
int
last
=
-
1
;
if
(
last
<
0
||
which
!=
last
)
{
set_rfb_cursor
(
which
);
}
last
=
which
;
}
/*
* routine called periodically to update
the mouse aspects (drawn &
*
cursorpos updates)
* routine called periodically to update
cursor aspects, this catches
*
warps and cursor shape changes.
*/
void
update_mouse
(
void
)
{
void
check_x11_pointer
(
void
)
{
Window
root_w
,
child_w
;
rfbBool
ret
;
int
root_x
,
root_y
,
win_x
,
win_y
,
which
=
0
;
int
root_x
,
root_y
,
win_x
,
win_y
;
int
x
,
y
;
unsigned
int
mask
;
X_LOCK
;
...
...
@@ -4736,18 +5121,25 @@ void update_mouse(void) {
if
(
!
ret
)
{
return
;
}
if
(
show_root_cursor
)
{
int
descend
;
if
(
(
descend
=
tree_descend_cursor
())
)
{
which
=
0
;
}
else
{
which
=
1
;
if
(
debug_pointer
)
{
static
int
last_x
=
-
1
,
last_y
=
-
1
;
if
(
root_x
!=
last_x
||
root_y
!=
last_y
)
{
rfbLog
(
"XQueryPointer: x:%4d, y:%4d)
\n
"
,
root_x
,
root_y
);
}
last_x
=
root_x
;
last_y
=
root_y
;
}
cursor_pos_updates
(
root_x
-
off_x
,
root_y
-
off_y
);
draw_mouse
(
root_x
-
off_x
,
root_y
-
off_y
,
which
,
1
);
/* offset subtracted since XQueryPointer relative to rootwin */
x
=
root_x
-
off_x
;
y
=
root_y
-
off_y
;
/* record the cursor position in the rfb screen */
cursor_position
(
x
,
y
);
/* change the cursor shape if necessary */
set_cursor
(
x
,
y
,
get_which_cursor
());
}
/* -- screen.c -- */
...
...
@@ -4945,7 +5337,7 @@ void set_visual(char *str) {
/*
* Presumably under -nofb the clients will never request the framebuffer.
*
But
we have gotten such a request... so let's just give them
*
However,
we have gotten such a request... so let's just give them
* the current view on the display. n.b. x2vnc and perhaps win2vnc
* requests a 1x1 pixel for some workaround so sadly this evidently
* nearly always happens.
...
...
@@ -5065,7 +5457,20 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
for
(
i
=
1
;
i
<
*
argc
;
i
++
)
{
rfbLog
(
"
\t
[%d] %s
\n
"
,
i
,
argv
[
i
]);
}
rfbLog
(
"for a list of options run: x11vnc -help
\n
"
);
rfbLog
(
"For a list of options run: x11vnc -help
\n
"
);
rfbLog
(
"
\n
"
);
rfbLog
(
"Here is a list of removed or obsolete"
" options:
\n
"
);
rfbLog
(
"
\n
"
);
rfbLog
(
"removed: -hints, -nohints
\n
"
);
rfbLog
(
"removed: -cursorposall
\n
"
);
rfbLog
(
"
\n
"
);
rfbLog
(
"renamed: -old_copytile, use -onetile
\n
"
);
rfbLog
(
"renamed: -mouse, use -cursor
\n
"
);
rfbLog
(
"renamed: -mouseX, use -cursor X
\n
"
);
rfbLog
(
"renamed: -X, use -cursor X
\n
"
);
rfbLog
(
"renamed: -nomouse, use -nocursor
\n
"
);
clean_up_exit
(
1
);
}
}
...
...
@@ -5083,14 +5488,28 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
if
(
!
have_masks
&&
screen
->
rfbServerFormat
.
bitsPerPixel
==
8
&&
CellsOfScreen
(
ScreenOfDisplay
(
dpy
,
scr
))
)
{
/* indexed colour */
if
(
!
quiet
)
rfbLog
(
"Using X display with 8bpp indexed color
\n
"
);
if
(
!
quiet
)
{
rfbLog
(
"X display %s is 8bpp indexed color
\n
"
,
DisplayString
(
dpy
));
if
(
!
flash_cmap
&&
!
overlay
)
{
rfbLog
(
"
\n
"
);
rfbLog
(
"In 8bpp PseudoColor mode if you "
"experience color
\n
"
);
rfbLog
(
"problems you may want to enable "
"following the
\n
"
);
rfbLog
(
"changing colormap by using the "
"-flashcmap option.
\n
"
);
rfbLog
(
"
\n
"
);
}
}
indexed_colour
=
1
;
set_colormap
();
}
else
{
/* general case ... */
if
(
!
quiet
)
{
rfbLog
(
"Using X display with %dbpp depth=%d true "
"color
\n
"
,
fb
->
bits_per_pixel
,
fb
->
depth
);
rfbLog
(
"X display %s is %dbpp depth=%d true "
"color
\n
"
,
DisplayString
(
dpy
),
fb
->
bits_per_pixel
,
fb
->
depth
);
}
/* convert masks to bit shifts and max # colors */
...
...
@@ -5130,6 +5549,15 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
main_green_shift
=
screen
->
rfbServerFormat
.
greenShift
;
main_blue_shift
=
screen
->
rfbServerFormat
.
blueShift
;
}
if
(
overlay
&&
!
quiet
)
{
rfbLog
(
"
\n
"
);
rfbLog
(
"Overlay mode enabled: If you experience color
\n
"
);
rfbLog
(
"problems when popup menus are on the screen, try
\n
"
);
rfbLog
(
"disabling SaveUnders in your X server, one way is
\n
"
);
rfbLog
(
"to start the X server with the '-su' option, e.g.:
\n
"
);
rfbLog
(
"Xsun -su ... see Xserver(1), xinit(1) for more info.
\n
"
);
rfbLog
(
"
\n
"
);
}
/* nofb is for pointer/keyboard only handling. */
if
(
nofb
)
{
...
...
@@ -5187,11 +5615,11 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
screen
->
setXCutText
=
xcut_receive
;
}
if
(
local_cursor
)
{
cursor
=
rfbMakeXCursor
(
CUR_SIZE
,
CUR_SIZE
,
CUR_DATA
,
CUR_MASK
);
screen
->
cursor
=
cursor
;
}
else
{
setup_cursors
();
if
(
!
show_cursor
)
{
screen
->
cursor
=
NULL
;
}
else
{
screen
->
cursor
=
cursors
[
0
]
->
rfb
;
}
rfbInitServer
(
screen
);
...
...
@@ -5220,6 +5648,22 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
* routines related to xinerama and blacking out rectangles
*/
/* blacked-out region (-blackout, -xinerama) */
typedef
struct
bout
{
int
x1
,
y1
,
x2
,
y2
;
}
blackout_t
;
#define BO_MAX 16
typedef
struct
tbout
{
blackout_t
bo
[
BO_MAX
];
/* hardwired max rectangles. */
int
cover
;
int
count
;
}
tile_blackout_t
;
#define BLACKR_MAX 100
blackout_t
blackr
[
BLACKR_MAX
];
/* hardwired max blackouts */
tile_blackout_t
*
tile_blackout
;
int
blackouts
=
0
;
/*
* Take a comma separated list of geometries: WxH+X+Y and register them as
* rectangles to black out from the screen.
...
...
@@ -5292,10 +5736,6 @@ void blackout_tiles(void) {
* to simplify things drop down to single copy mode, no vcr, etc...
*/
single_copytile
=
1
;
if
(
show_mouse
)
{
rfbLog
(
"disabling remote mouse drawing due to blackouts
\n
"
);
show_mouse
=
0
;
}
/* loop over all tiles. */
for
(
ty
=
0
;
ty
<
ntiles_y
;
ty
++
)
{
...
...
@@ -5604,6 +6044,20 @@ static void set_fs_factor(int max) {
}
}
char
*
flip_ximage_byte_order
(
XImage
*
xim
)
{
char
*
order
;
if
(
xim
->
byte_order
==
LSBFirst
)
{
order
=
"MSBFirst"
;
xim
->
byte_order
=
MSBFirst
;
xim
->
bitmap_bit_order
=
MSBFirst
;
}
else
{
order
=
"LSBFirst"
;
xim
->
byte_order
=
LSBFirst
;
xim
->
bitmap_bit_order
=
LSBFirst
;
}
return
order
;
}
/*
* set up an XShm image, or if not using shm just create the XImage.
*/
...
...
@@ -5611,6 +6065,7 @@ static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
char
*
name
)
{
XImage
*
xim
;
static
int
reported_flip
=
0
;
shm
->
shmid
=
-
1
;
shm
->
shmaddr
=
(
char
*
)
-
1
;
...
...
@@ -5639,21 +6094,11 @@ static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
return
0
;
}
if
(
flip_byte_order
)
{
static
int
reported
=
0
;
char
*
bo
;
if
(
xim
->
byte_order
==
LSBFirst
)
{
bo
=
"MSBFirst"
;
xim
->
byte_order
=
MSBFirst
;
xim
->
bitmap_bit_order
=
MSBFirst
;
}
else
{
bo
=
"LSBFirst"
;
xim
->
byte_order
=
LSBFirst
;
xim
->
bitmap_bit_order
=
LSBFirst
;
}
if
(
!
reported
&&
!
quiet
)
{
rfbLog
(
"changing XImage byte order"
" to %s
\n
"
,
bo
);
reported
=
1
;
char
*
order
=
flip_ximage_byte_order
(
xim
);
if
(
!
reported_flip
&&
!
quiet
)
{
rfbLog
(
"Changing XImage byte order"
" to %s
\n
"
,
order
);
reported_flip
=
1
;
}
}
...
...
@@ -5661,7 +6106,7 @@ static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
return
1
;
}
xim
=
XShmCreateImage
(
dpy
,
default_visual
,
depth
,
ZPixmap
,
NULL
,
xim
=
XShmCreateImage
_wr
(
dpy
,
default_visual
,
depth
,
ZPixmap
,
NULL
,
shm
,
w
,
h
);
if
(
xim
==
NULL
)
{
...
...
@@ -5672,6 +6117,7 @@ static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
*
ximg_ptr
=
xim
;
#ifdef LIBVNCSERVER_HAVE_XSHM
shm
->
shmid
=
shmget
(
IPC_PRIVATE
,
xim
->
bytes_per_line
*
xim
->
height
,
IPC_CREAT
|
0777
);
...
...
@@ -5704,7 +6150,7 @@ static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
shm
->
readOnly
=
False
;
if
(
!
XShmAttach
(
dpy
,
shm
))
{
if
(
!
XShmAttach
_wr
(
dpy
,
shm
))
{
rfbErr
(
"XShmAttach(%s) failed.
\n
"
,
name
);
XDestroyImage
(
xim
);
*
ximg_ptr
=
NULL
;
...
...
@@ -5718,6 +6164,7 @@ static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
X_UNLOCK
;
return
0
;
}
#endif
X_UNLOCK
;
return
1
;
...
...
@@ -5727,21 +6174,24 @@ void shm_delete(XShmSegmentInfo *shm) {
if
(
!
using_shm
)
{
return
;
}
#ifdef LIBVNCSERVER_HAVE_XSHM
if
(
shm
->
shmaddr
!=
(
char
*
)
-
1
)
{
shmdt
(
shm
->
shmaddr
);
}
if
(
shm
->
shmid
!=
-
1
)
{
shmctl
(
shm
->
shmid
,
IPC_RMID
,
0
);
}
#endif
}
void
shm_clean
(
XShmSegmentInfo
*
shm
,
XImage
*
xim
)
{
if
(
!
using_shm
||
nofb
)
{
if
(
!
using_shm
)
{
return
;
}
#ifdef LIBVNCSERVER_HAVE_XSHM
X_LOCK
;
if
(
shm
->
shmid
!=
-
1
)
{
XShmDetach
(
dpy
,
shm
);
XShmDetach
_wr
(
dpy
,
shm
);
}
if
(
xim
!=
NULL
)
{
XDestroyImage
(
xim
);
...
...
@@ -5749,6 +6199,7 @@ void shm_clean(XShmSegmentInfo *shm, XImage *xim) {
X_UNLOCK
;
shm_delete
(
shm
);
#endif
}
void
initialize_shm
(
void
)
{
...
...
@@ -6446,12 +6897,11 @@ void mark_hint(hint_t hint) {
/*
* copy_tiles() gives a slight improvement over copy_tile() since
* adjacent runs of tiles are done all at once there is some savings
* due to contiguous memory access. Not a great speedup, but in
* some cases it can be up to 2X. Even more on a SunRay where no
* graphics hardware is involved in the read. Generally, graphics
* devices are optimized for write, not read, so we are limited by
* the read bandwidth, sometimes only 5 MB/sec on otherwise fast
* hardware.
* due to contiguous memory access. Not a great speedup, but in some
* cases it can be up to 2X. Even more on a SunRay or ShadowFB where
* no graphics hardware is involved in the read. Generally, graphics
* devices are optimized for write, not read, so we are limited by the
* read bandwidth, sometimes only 5 MB/sec on otherwise fast hardware.
*/
static
int
*
first_line
=
NULL
,
*
last_line
;
static
unsigned
short
*
left_diff
,
*
right_diff
;
...
...
@@ -6464,8 +6914,6 @@ static void copy_tiles(int tx, int ty, int nt) {
int
pixelsize
=
bpp
>>
3
;
int
first_min
,
last_max
;
int
restored_patch
=
0
;
/* for show_mouse */
char
*
src
,
*
dst
,
*
s_src
,
*
s_dst
,
*
m_src
,
*
m_dst
;
char
*
h_src
,
*
h_dst
;
if
(
!
first_line
)
{
...
...
@@ -6554,24 +7002,6 @@ static void copy_tiles(int tx, int ty, int nt) {
}
}
/*
* Some awkwardness wrt the little remote mouse patch we display.
* When threaded we want to have as small a window of time
* as possible when the mouse image is not in the fb, otherwise
* a libvncserver thread may send the uncorrected patch to the
* clients.
*/
if
(
show_mouse
&&
use_threads
&&
cur_saved
)
{
/* check for overlap */
if
(
cur_save_x
+
cur_save_w
>
x
&&
x
+
size_x
>
cur_save_x
&&
cur_save_y
+
cur_save_h
>
y
&&
y
+
size_y
>
cur_save_y
)
{
/* restore the real data to the rfb fb */
restore_mouse_patch
();
restored_patch
=
1
;
}
}
src
=
tile_row
[
nt
]
->
data
;
dst
=
main_fb
+
y
*
main_bytes_per_line
+
x
*
pixelsize
;
...
...
@@ -6624,9 +7054,6 @@ static void copy_tiles(int tx, int ty, int nt) {
for
(
t
=
1
;
t
<=
nt
;
t
++
)
{
tile_has_diff
[
n
+
(
t
-
1
)]
=
0
;
}
if
(
restored_patch
)
{
redraw_mouse
();
}
return
;
}
else
{
/*
...
...
@@ -6753,10 +7180,6 @@ static void copy_tiles(int tx, int ty, int nt) {
s_dst
+=
main_bytes_per_line
;
}
if
(
restored_patch
)
{
redraw_mouse
();
}
/* record all the info in the region array for this tile: */
for
(
t
=
1
;
t
<=
nt
;
t
++
)
{
int
s
=
t
-
1
;
...
...
@@ -7150,7 +7573,7 @@ static void nap_set(int tile_cnt) {
nap_diff_count
=
0
;
}
if
(
show_
mouse
)
{
if
(
show_
cursor
)
{
/* kludge for the up to 4 tiles the mouse patch could occupy */
if
(
tile_cnt
>
4
)
{
last_event
=
time
(
0
);
...
...
@@ -7169,7 +7592,7 @@ static void nap_sleep(int ms, int split) {
for
(
i
=
0
;
i
<
split
;
i
++
)
{
usleep
(
ms
*
1000
/
split
);
if
(
!
use_threads
&&
i
!=
split
-
1
)
{
rfbP
rocessEvents
(
screen
,
-
1
);
rfbP
E
(
screen
,
-
1
);
}
if
(
input
!=
got_user_input
)
{
break
;
...
...
@@ -7482,11 +7905,6 @@ void scan_for_updates(void) {
}
}
if
(
show_mouse
&&
!
use_threads
)
{
/* single-thread is safe to do it here for all scanning */
restore_mouse_patch
();
}
/* scan with the initial y to the jitter value from scanlines: */
scan_in_progress
=
1
;
tile_count
=
scan_display
(
scanlines
[
scan_count
],
0
);
...
...
@@ -7538,12 +7956,6 @@ void scan_for_updates(void) {
if
(
fs_factor
&&
tile_count
>
fs_frac
*
ntiles
)
{
fb_copy_in_progress
=
1
;
copy_screen
();
if
(
show_mouse
||
cursor_pos
)
{
if
(
show_mouse
&&
!
use_threads
)
{
redraw_mouse
();
}
update_mouse
();
}
fb_copy_in_progress
=
0
;
if
(
use_threads
&&
!
old_pointer
)
{
pointer
(
-
1
,
0
,
0
,
NULL
);
...
...
@@ -7616,13 +8028,6 @@ void scan_for_updates(void) {
ping_clients
(
tile_diffs
);
}
/* Handle the remote mouse pointer */
if
(
show_mouse
||
cursor_pos
)
{
if
(
show_mouse
&&
!
use_threads
)
{
redraw_mouse
();
}
update_mouse
();
}
nap_check
(
tile_diffs
);
}
...
...
@@ -7698,7 +8103,11 @@ static int check_user_input(double dt, int *cnt) {
* likely they have all be sent already.
*/
while
(
1
)
{
rfbCheckFds
(
screen
,
1000
);
if
(
show_multiple_cursors
)
{
rfbPE
(
screen
,
1000
);
}
else
{
rfbCFD
(
screen
,
1000
);
}
XFlush
(
dpy
);
spin
+=
dtime
(
&
tm
);
...
...
@@ -7757,7 +8166,11 @@ static int check_user_input(double dt, int *cnt) {
miss
=
0
;
for
(
i
=
0
;
i
<
split
;
i
++
)
{
usleep
(
ms
*
1000
);
rfbCheckFds
(
screen
,
1000
);
if
(
show_multiple_cursors
)
{
rfbPE
(
screen
,
1000
);
}
else
{
rfbCFD
(
screen
,
1000
);
}
spin
+=
dtime
(
&
tm
);
if
(
got_pointer_input
>
g
)
{
XFlush
(
dpy
);
...
...
@@ -7803,10 +8216,17 @@ double dtime(double *t_old) {
/*
* utility wrapper to call rfbProcessEvents
* checks that we are not in threaded mode.
*/
void
rfbPE
(
rfbScreenInfoPtr
scr
,
long
us
)
{
void
rfbPE
(
rfbScreenInfoPtr
scr
,
long
usec
)
{
if
(
!
use_threads
)
{
rfbProcessEvents
(
scr
,
usec
);
}
}
void
rfbCFD
(
rfbScreenInfoPtr
scr
,
long
usec
)
{
if
(
!
use_threads
)
{
rfb
ProcessEvents
(
scr
,
us
);
rfb
CheckFds
(
scr
,
usec
);
}
}
...
...
@@ -7828,7 +8248,10 @@ static void watch_loop(void) {
got_keyboard_input
=
0
;
if
(
!
use_threads
)
{
rfbProcessEvents
(
screen
,
-
1
);
rfbPE
(
screen
,
-
1
);
if
(
!
cursor_shape_updates
)
{
unset_cursor_shape_updates
(
screen
);
}
if
(
check_user_input
(
dt
,
&
cnt
))
{
/* true means loop back for more input */
continue
;
...
...
@@ -7839,7 +8262,7 @@ static void watch_loop(void) {
clean_up_exit
(
0
);
}
watch
_xevents
();
check
_xevents
();
check_connect_inputs
();
if
(
!
screen
->
rfbClientHead
)
{
/* waiting for a client */
...
...
@@ -7847,9 +8270,11 @@ static void watch_loop(void) {
continue
;
}
if
(
nofb
)
{
/* no framebuffer polling needed */
if
(
cursor_pos
)
{
update_mouse
();
if
(
nofb
)
{
/* no framebuffer polling needed */
if
(
cursor_pos_updates
)
{
/* -nofb -cursorpos usage is rare */
check_x11_pointer
();
}
continue
;
}
...
...
@@ -7859,7 +8284,7 @@ static void watch_loop(void) {
* check for any bell events.
* n.b. assumes -nofb folks do not want bell...
*/
watch
_bell_event
();
check
_bell_event
();
}
if
(
!
show_dragging
&&
button_mask
)
{
/* if any button is pressed do not update screen */
...
...
@@ -7874,6 +8299,7 @@ static void watch_loop(void) {
rfbUndrawCursor
(
screen
);
scan_for_updates
();
check_x11_pointer
();
dt
=
dtime
(
&
tm
);
}
...
...
@@ -7936,11 +8362,15 @@ static void print_help(void) {
" setting the XAUTHORITY environment varirable to
\"
file
\"\n
"
" before startup. See Xsecurity(7), xauth(1) man pages.
\n
"
"
\n
"
"-id windowid Show the window corresponding to
\"
windowid
\"
not the
\n
"
" entire display. Warning: bugs! new toplevels missed!...
\n
"
"-id windowid Show the window corresponding to
\"
windowid
\"
not
\n
"
" the entire display. New windows like popup menus,
\n
"
" etc may not be seen, or will be clipped. x11vnc may
\n
"
" crash if the window changes size, is iconified, etc.
\n
"
" Use xwininfo(1) to get the window id. Primarily useful
\n
"
" for exporting very simple applications.
\n
"
"-sid windowid As -id, but instead of using the window directly it
\n
"
" shifts a root view to it:
shows saveUnders menus, etc
,
\n
"
" although they will be clipped if they extend beyond
\n
"
" 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
"
"-flashcmap In 8bpp indexed color, let the installed colormap flash
\n
"
" as the pointer moves from window to window (slow).
\n
"
...
...
@@ -7951,11 +8381,12 @@ static void print_help(void) {
" packed with 8 for PseudoColor and 24 for TrueColor).
\n
"
"
\n
"
" Currently -overlay only works on Solaris (it uses
\n
"
" XReadScreen(3X11)). There are still some problems with
\n
"
" surrounding-region painting for popup menus (but not
\n
"
" for the popup menu itself); a workaround is to disable
\n
"
" SaveUnders (pass -su to Xsun). Amusingly, if -overlay
\n
"
" is used with -mouse, the mouse cursor shape is correct.
\n
"
" XReadScreen(3X11)). There is a problem with image
\n
"
"
\"
bleeding
\"
around transient popup menus (but not
\n
"
" for the menu itself): a workaround is to disable
\n
"
" SaveUnders by passing the
\"
-su
\"
argument to Xsun
\n
"
" (in /etc/dt/config/Xservers, say). Also note that,
\n
"
" the mouse cursor shape is exactly correct in this mode.
\n
"
"
\n
"
" Use -overlay as a workaround for situations like these:
\n
"
" Some legacy applications require the default visual
\n
"
...
...
@@ -7968,7 +8399,10 @@ static void print_help(void) {
" due to the extra image transformations required.
\n
"
" For optimal performance do not use -overlay, but rather
\n
"
" configure the X server so that the default visual is
\n
"
" depth 24 TrueColor and have all apps use that visual.
\n
"
" depth 24 TrueColor and try to have all apps use that
\n
"
" visual (some apps have -use24 or -visual options).
\n
"
"-overlay_nocursor Sets -overlay, but does not try to draw the exact mouse
\n
"
" cursor shape using the overlay mechanism.
\n
"
"-visual n Experimental option: probably does not do what you
\n
"
" think. It simply *forces* the visual used for the
\n
"
" framebuffer; this may be a bad thing... It is useful for
\n
"
...
...
@@ -7978,9 +8412,10 @@ static void print_help(void) {
" for a list. If the string ends in
\"
:m
\"
for better
\n
"
" or for worse the visual depth is forced to be m.
\n
"
"
\n
"
"-scale fraction Scale the framebuffer by factor
\"
fraction
\"
. Values
\n
"
" less than 1 shrink the fb. Note: image may not be sharp
\n
"
" and response may be slower. If
\"
fraction
\"
contains
\n
"
"-scale fraction Scale the framebuffer by factor
\"
fraction
\"
.
\n
"
" Values less than 1 shrink the fb. Note: image may not
\n
"
" be sharp and response may be slower. Currently the
\n
"
" cursor shape is not scaled. If
\"
fraction
\"
contains
\n
"
" a decimal point
\"
.
\"
it is taken as a floating point
\n
"
" number, alternatively the notation
\"
m/n
\"
may be used
\n
"
" to denote fractions exactly, e.g. -scale 2/3.
\n
"
...
...
@@ -7990,7 +8425,7 @@ static void print_help(void) {
" If you just want a quick, rough scaling without
\n
"
" blending, append
\"
:nb
\"
to
\"
fraction
\"
(e.g. -scale
\n
"
" 1/3:nb). For compatibility with vncviewers the scaled
\n
"
" width is adjusted to be a multiple of 4
,
to disable
\n
"
" width is adjusted to be a multiple of 4
:
to disable
\n
"
" this use
\"
:n4
\"
. More esoteric options:
\"
:in
\"
use
\n
"
" interpolation scheme even when shrinking,
\"
:pad
\"
,
\n
"
" pad scaled width and height to be multiples of scaling
\n
"
...
...
@@ -8010,9 +8445,10 @@ static void print_help(void) {
" periodically check for new hosts. The first line is
\n
"
" read and then the file is truncated.
\n
"
"-vncconnect Monitor the VNC_CONNECT X property set by the standard
\n
"
" VNC program vncconnect(1). When the property is set
\n
"
" to host or host:port establish a reverse connection.
\n
"
" Using xprop(1) instead of vncconnect may work, see FAQ.
\n
"
"-novncconnect VNC program vncconnect(1). When the property is
\n
"
" set to
\"
host
\"
or
\"
host:port
\"
establish a reverse
\n
"
" connection. Using xprop(1) instead of vncconnect may
\n
"
" work, see the FAQ. Default: %s
\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
"
...
...
@@ -8103,16 +8539,18 @@ static void print_help(void) {
"-flipbyteorder Sometimes needed if remotely polled host has different
\n
"
" endianness. Ignored unless -noshm is set.
\n
"
"-onetile Do not use the new copy_tiles() framebuffer mechanism,
\n
"
" just use 1 shm tile for polling.
Same as -old_copytile.
\n
"
"
Limits shm segments
used to 3.
\n
"
" just use 1 shm tile for polling.
Limits shm segments
\n
"
" used to 3.
\n
"
"
\n
"
"-blackout string Black out rectangles on the screen.
\"
string
\"
is a
\n
"
" comma separated list of WxH+X+Y type geometries for
\n
"
" each rectangle.
\n
"
"-xinerama If your screen is composed of multiple monitors
\n
"
" glued together via XINERAMA, and that screen is
\n
"
" non-rectangular this option will try to guess the areas
\n
"
" to black out (if your system has libXinerama).
\n
"
" non-rectangular this option will try to guess the
\n
"
" areas to black out (if your system has libXinerama).
\n
"
" In general on XINERAMA displays you may need to use the
\n
"
" -xwarppointer option if the mouse pointer misbehaves.
\n
"
"
\n
"
"-o logfile Write stderr messages to file
\"
logfile
\"
instead of
\n
"
" to the terminal. Same as -logfile
\"
file
\"
.
\n
"
...
...
@@ -8144,7 +8582,9 @@ static void print_help(void) {
" the X server instead of Mode_switch (AltGr).\n"
#endif
"-xkb When in modtweak mode, use the XKEYBOARD extension
\n
"
" (if it exists) to do the modifier tweaking.
\n
"
" (if it exists) to do the modifier tweaking. This is
\n
"
" powerful and should be tried if there are still
\n
"
" keymapping problems when using the simpler -modtweak.
\n
"
"-skip_keycodes string Skip keycodes not on your keyboard but your X server
\n
"
" thinks exist. Currently only applies to -xkb mode.
\n
"
"
\"
string
\"
is a comma separated list of decimal
\n
"
...
...
@@ -8199,17 +8639,70 @@ static void print_help(void) {
" back to clients. (PRIMARY is still set on received
\n
"
" changes, however).
\n
"
"
\n
"
"-nocursor Do not have the VNC viewer show a local cursor.
\n
"
"-mouse Draw a 2nd cursor at the current X pointer position.
\n
"
"-mouseX As -mouse, but also draw an
\"
X
\"
when pointer is on
\n
"
" root background.
\n
"
"-X Shorthand for -mouseX -nocursor.
\n
"
"-xwarppointer Move the pointer with XWarpPointer() instead of XTEST
\n
"
" (try as a workaround if pointer behaves poorly, e.g.
\n
"
" on touchscreens or other non-standard setups).
\n
"
"-cursor [mode] Sets how the pointer cursor shape (little icon at the
\n
"
"-nocursor mouse pointer) should be handled. The
\"
mode
\"
string
\n
"
" is optional and is described below. The default
\n
"
" is to show some sort of cursor shape(s). How this
\n
"
" is done depends on the VNC viewer and the X server.
\n
"
" Use -nocursor to disable cursor shapes completely.
\n
"
"
\n
"
" Some VNC viewers support the TightVNC CursorPosUpdates
\n
"
" and CursorShapeUpdates extensions (cuts down on
\n
"
" network traffic by not having to send the cursor image
\n
"
" every time the pointer is moved), in which case these
\n
"
" extensions are used (see -nocursorshape and -nocursorpos
\n
"
" below). For other viewers the cursor shape is written
\n
"
" directly to the framebuffer every time the pointer is
\n
"
" moved or changed and gets sent along with the other
\n
"
" framebuffer updates. In this case, there will be
\n
"
" some lag between the vnc viewer pointer and the remote
\n
"
" cursor position.
\n
"
"
\n
"
" If the X display supports retrieving the cursor shape
\n
"
" information from the X server, then the default
\n
"
" is to use that mode. On Solaris this requires
\n
"
" the SUN_OVL extension and the -overlay option to be
\n
"
" supplied. (see also the -overlay_nomouse option). (Soon)
\n
"
" on XFree86/Xorg the XFIXES extension is required.
\n
"
" Either can be disabled with -nocursor, and also some
\n
"
" values of the
\"
mode
\"
option below.
\n
"
"
\n
"
" The
\"
mode
\"
string can be used to fine-tune the
\n
"
" displaying of cursor shapes. It can be used the
\n
"
" following ways:
\n
"
"
\n
"
"
\"
-cursor X
\"
- when the cursor appears to be on the
\n
"
" root window, draw the familiar X shape. Some desktops
\n
"
" such as GNOME cover up the root window completely,
\n
"
" and so this will not work, try
\"
X1
\"
, etc, to try to
\n
"
" shift the tree depth. On high latency links or slow
\n
"
" machines there will be a time lag between expected and
\n
"
" the actual cursor shape.
\n
"
"
\n
"
"
\"
-cursor some
\"
- like
\"
X
\"
but use additional
\n
"
" heuristics to try to guess if the window should have
\n
"
" a windowmanager-like resizer cursor or a text input
\n
"
" I-beam cursor. This is a complete hack, but may be
\n
"
" useful in some situations because it provides a little
\n
"
" more feedback about the cursor shape.
\n
"
"
\n
"
"
\"
-cursor most
\"
- try to show as many cursors as
\n
"
" possible. Often this will only be the same as
\"
some
\"
.
\n
"
" On Solaris if XFIXES is not available, -overlay mode
\n
"
" will be used.
\n
"
"
\n
"
"-nocursorshape Do not use the TightVNC CursorShapeUpdates extension
\n
"
" even if clients support it. See -cursor above.
\n
"
"-cursorpos Option -cursorpos enables sending the X cursor position
\n
"
"-nocursorpos back to all vnc clients that support the TightVNC
\n
"
" CursorPosUpdates extension. Default: %s
\n
"
" CursorPosUpdates extension. Other clients will be able
\n
"
" to see the pointer motions. Default: %s
\n
"
"-xwarppointer Move the pointer with XWarpPointer(3X) instead of XTEST
\n
"
" extension. Use this as a workaround if the pointer
\n
"
" motion behaves incorrectly, e.g. on touchscreens or
\n
"
" other non-standard setups. Also sometimes needed on
\n
"
" XINERAMA displays.
\n
"
"
\n
"
"-buttonmap string String to remap mouse buttons. Format: IJK-LMN, this
\n
"
" maps buttons I -> L, etc., e.g. -buttonmap 13-31
\n
"
"
\n
"
...
...
@@ -8284,9 +8777,10 @@ static void print_help(void) {
fprintf
(
stderr
,
help
,
lastmod
,
view_only
?
"on"
:
"off"
,
shared
?
"on"
:
"off"
,
vnc_connect
?
"-vncconnect"
:
"-novncconnect"
,
use_modifier_tweak
?
"-modtweak"
:
"-nomodtweak"
,
no_autorepeat
?
"-norepeat"
:
"-repeat"
,
cursor_pos
?
"-cursorpos"
:
"-nocursorpos"
,
cursor_pos
_updates
?
"-cursorpos"
:
"-nocursorpos"
,
defer_update
,
waitms
,
take_naps
?
"on"
:
"off"
,
...
...
@@ -8536,7 +9030,8 @@ static void check_rcfile(int argc, char **argv) {
int
main
(
int
argc
,
char
*
argv
[])
{
XImage
*
fb
;
int
i
,
ev
,
er
,
maj
,
min
;
int
i
;
int
ev
,
er
,
maj
,
min
;
char
*
use_dpy
=
NULL
;
char
*
auth_file
=
NULL
;
char
*
arg
,
*
visual_str
=
NULL
;
...
...
@@ -8652,8 +9147,10 @@ int main(int argc, char* argv[]) {
scale_denom
=
n
;
}
if
(
scale_fac
==
1
.
0
)
{
fprintf
(
stderr
,
"scaling disabled for factor "
"%f
\n
"
,
scale_fac
);
if
(
!
quiet
)
{
rfbLog
(
"scaling disabled for factor "
" %f
\n
"
,
scale_fac
);
}
}
else
{
scaling
=
1
;
}
...
...
@@ -8662,6 +9159,9 @@ int main(int argc, char* argv[]) {
visual_str
=
argv
[
++
i
];
}
else
if
(
!
strcmp
(
arg
,
"-overlay"
))
{
overlay
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-overlay_nocursor"
))
{
overlay
=
1
;
overlay_cursor
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-flashcmap"
))
{
flash_cmap
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-notruecolor"
))
{
...
...
@@ -8715,6 +9215,8 @@ int main(int argc, char* argv[]) {
}
}
else
if
(
!
strcmp
(
arg
,
"-vncconnect"
))
{
vnc_connect
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-novncconnect"
))
{
vnc_connect
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-inetd"
))
{
inetd
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-noshm"
))
{
...
...
@@ -8760,23 +9262,28 @@ int main(int argc, char* argv[]) {
watch_selection
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-noprimary"
))
{
watch_primary
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-cursor"
))
{
show_cursor
=
1
;
if
(
i
>=
argc
-
1
)
{
;
}
else
{
char
*
s
=
argv
[
i
+
1
];
if
(
*
s
==
'X'
||
!
strcmp
(
s
,
"default"
)
||
!
strcmp
(
s
,
"some"
)
||
!
strcmp
(
s
,
"most"
))
{
multiple_cursors_mode
=
strdup
(
s
);
i
++
;
}
}
}
else
if
(
!
strcmp
(
arg
,
"-nocursor"
))
{
local_cursor
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-mouse"
))
{
show_mouse
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-mouseX"
))
{
show_mouse
=
1
;
show_root_cursor
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-X"
))
{
show_mouse
=
1
;
show_root_cursor
=
1
;
local_cursor
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-xwarppointer"
))
{
use_xwarppointer
=
1
;
show_cursor
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-cursorpos"
))
{
cursor_pos
=
1
;
cursor_pos
_updates
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-nocursorpos"
))
{
cursor_pos
=
0
;
cursor_pos_updates
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-nocursorshape"
))
{
cursor_shape_updates
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-xwarppointer"
))
{
use_xwarppointer
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-buttonmap"
))
{
CHECK_ARGC
pointer_remap
=
argv
[
++
i
];
...
...
@@ -8792,10 +9299,8 @@ int main(int argc, char* argv[]) {
no_autorepeat
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-repeat"
))
{
no_autorepeat
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-onetile"
)
||
!
strcmp
(
arg
,
"-old_copytile"
))
{
}
else
if
(
!
strcmp
(
arg
,
"-onetile"
))
{
single_copytile
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-debug_pointer"
))
{
}
else
if
(
!
strcmp
(
arg
,
"-debug_pointer"
)
||
!
strcmp
(
arg
,
"-dp"
))
{
debug_pointer
++
;
...
...
@@ -8842,9 +9347,6 @@ int main(int argc, char* argv[]) {
}
else
if
(
!
strcmp
(
arg
,
"-fuzz"
))
{
CHECK_ARGC
tile_fuzz
=
atoi
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
arg
,
"-hints"
)
||
!
strcmp
(
arg
,
"-nohints"
))
{
fprintf
(
stderr
,
"warning: -hints/-nohints option "
"has been removed.
\n
"
);
}
else
if
(
!
strcmp
(
arg
,
"-h"
)
||
!
strcmp
(
arg
,
"-help"
)
||
!
strcmp
(
arg
,
"-?"
))
{
print_help
();
...
...
@@ -8907,8 +9409,7 @@ int main(int argc, char* argv[]) {
if
(
!
quiet
&&
!
inetd
)
{
int
i
;
for
(
i
=
1
;
i
<
argc_vnc
;
i
++
)
{
fprintf
(
stderr
,
"passing arg to libvncserver: %s
\n
"
,
argv_vnc
[
i
]);
rfbLog
(
"passing arg to libvncserver: %s
\n
"
,
argv_vnc
[
i
]);
if
(
!
strcmp
(
argv_vnc
[
i
],
"-passwd"
))
{
i
++
;
}
...
...
@@ -8937,9 +9438,8 @@ int main(int argc, char* argv[]) {
FILE
*
in
;
in
=
fopen
(
passwdfile
,
"r"
);
if
(
in
==
NULL
)
{
fprintf
(
stderr
,
"cannot open passwdfile: %s
\n
"
,
passwdfile
);
perror
(
"fopen"
);
rfbLog
(
"cannot open passwdfile: %s
\n
"
,
passwdfile
);
rfbLog
(
"fopen"
);
exit
(
1
);
}
if
(
fgets
(
line
,
1024
,
in
)
!=
NULL
)
{
...
...
@@ -8970,15 +9470,15 @@ int main(int argc, char* argv[]) {
if
(
ok
)
{
viewonly_passwd
=
strdup
(
line
);
}
else
{
fprintf
(
stderr
,
"*** not setting"
rfbLog
(
"*** not setting"
" viewonly password to the 2nd"
" line of %s. (blank or other"
" problem)
\n
"
,
passwdfile
);
}
}
}
else
{
fprintf
(
stderr
,
"cannot read a line from "
"passwdfile: %s
\n
"
,
passwdfile
);
rfbLog
(
"cannot read a line from passwdfile: %s
\n
"
,
passwdfile
);
exit
(
1
);
}
fclose
(
in
);
...
...
@@ -8996,17 +9496,15 @@ int main(int argc, char* argv[]) {
}
}
if
(
viewonly_passwd
&&
pw_loc
<
0
)
{
fprintf
(
stderr
,
"-passwd must be supplied when using "
"-viewpasswd
\n
"
);
rfbLog
(
"-passwd must be supplied when using -viewpasswd
\n
"
);
exit
(
1
);
}
/* fixup settings that do not make sense */
if
(
use_threads
&&
nofb
&&
cursor_pos
)
{
if
(
use_threads
&&
nofb
&&
cursor_pos
_updates
)
{
if
(
!
quiet
)
{
fprintf
(
stderr
,
"disabling -threads under -nofb "
"-cursorpos
\n
"
);
rfbLog
(
"disabling -threads under -nofb -cursorpos
\n
"
);
}
use_threads
=
0
;
}
...
...
@@ -9022,34 +9520,94 @@ int main(int argc, char* argv[]) {
bg
=
0
;
}
if
(
flip_byte_order
&&
using_shm
&&
!
quiet
)
{
rfbLog
(
"warning: -flipbyte order only works with -noshm
\n
"
);
}
/* increase rfbwait if threaded */
if
(
use_threads
&&
!
got_rfbwait
)
{
argv_vnc
[
argc_vnc
++
]
=
"-rfbwait"
;
argv_vnc
[
argc_vnc
++
]
=
"604800000"
;
/* one week... */
}
/* cursor shapes setup */
#ifdef SOLARIS
if
(
show_cursor
&&
!
overlay
&&
overlay_cursor
&&
!
strcmp
(
multiple_cursors_mode
,
"most"
))
{
overlay
=
1
;
if
(
!
quiet
)
{
rfbLog
(
"enabling -overlay mode to achieve "
"'-cursor most'
\n
"
);
rfbLog
(
"disable with: -overlay_nocursor.
\n
"
);
}
}
#endif
if
(
overlay
)
{
#ifdef SOLARIS
using_shm
=
0
;
if
(
flash_cmap
&&
!
quiet
)
{
fprintf
(
stderr
,
"warning: -flashcmap may b
e "
"
incompatible
with -overlay
\n
"
);
rfbLog
(
"warning: -flashcmap may be incompatibl
e "
"with -overlay
\n
"
);
}
if
(
show_mouse
)
{
show_mouse
=
0
;
overlay_mouse
=
1
;
if
(
show_cursor
&&
overlay_cursor
)
{
char
*
s
=
multiple_cursors_mode
;
if
(
*
s
==
'X'
||
!
strcmp
(
s
,
"some"
))
{
/*
* user wants these modes, so disable fb cursor
*/
overlay_cursor
=
0
;
}
else
{
/*
* "default" and "most", we turn off
* show_cursor since it will automatically
* be in the framebuffer.
*/
show_cursor
=
0
;
}
}
#else
if
(
!
quiet
)
{
fprintf
(
stderr
,
"disabling -overlay: currently only
"
"
available on
Solaris Xsun.
\n
"
);
rfbLog
(
"disabling -overlay: only available on
"
"Solaris Xsun.
\n
"
);
}
overlay
=
0
;
#endif
}
if
(
show_cursor
)
{
char
*
s
=
multiple_cursors_mode
;
if
(
*
s
==
'X'
||
!
strcmp
(
s
,
"some"
))
{
show_multiple_cursors
=
1
;
}
else
if
(
!
strcmp
(
s
,
"most"
))
{
/* later check for XFIXES, for now "some" */
show_multiple_cursors
=
1
;
}
}
/* no framebuffer (Win2VNC) mode */
if
(
nofb
)
{
/* disable things that do not make sense */
using_shm
=
0
;
flash_cmap
=
0
;
show_cursor
=
0
;
show_multiple_cursors
=
0
;
overlay
=
0
;
if
(
!
quiet
)
{
rfbLog
(
"disabling -cursor, fb, shm, etc. in "
"-nofb mode.
\n
"
);
}
if
(
!
got_deferupdate
&&
!
got_defer
)
{
/* reduce defer time under -nofb */
defer_update
=
defer_update_nofb
;
}
}
/* check for OS with small shm limits */
if
(
using_shm
&&
!
single_copytile
)
{
if
(
limit_shm
())
{
...
...
@@ -9057,10 +9615,6 @@ int main(int argc, char* argv[]) {
}
}
if
(
nofb
&&
!
got_deferupdate
&&
!
got_defer
)
{
/* reduce defer time under -nofb */
defer_update
=
defer_update_nofb
;
}
if
(
!
got_deferupdate
)
{
char
tmp
[
40
];
/* XXX not working yet in libvncserver */
...
...
@@ -9068,9 +9622,10 @@ int main(int argc, char* argv[]) {
argv_vnc
[
argc_vnc
++
]
=
"-deferupdate"
;
argv_vnc
[
argc_vnc
++
]
=
strdup
(
tmp
);
}
if
(
debug_pointer
||
debug_keyboard
)
{
if
(
bg
||
quiet
)
{
fprintf
(
stderr
,
"disabling -bg/-q under -debug_pointer"
rfbLog
(
"disabling -bg/-q under -debug_pointer"
"/-debug_keyboard
\n
"
);
bg
=
0
;
quiet
=
0
;
...
...
@@ -9079,81 +9634,85 @@ int main(int argc, char* argv[]) {
if
(
!
quiet
)
{
fprintf
(
stderr
,
"
\n
"
);
fprintf
(
stderr
,
"display: %s
\n
"
,
use_dpy
?
use_dpy
fprintf
(
stderr
,
"Settings:
\n
"
);
fprintf
(
stderr
,
" display: %s
\n
"
,
use_dpy
?
use_dpy
:
"null"
);
fprintf
(
stderr
,
"subwin: 0x%x
\n
"
,
subwin
);
fprintf
(
stderr
,
"flashcmap: %d
\n
"
,
flash_cmap
);
fprintf
(
stderr
,
"force_idx: %d
\n
"
,
force_indexed_color
);
fprintf
(
stderr
,
"scaling: %d %.5f
\n
"
,
scaling
,
scale_fac
);
fprintf
(
stderr
,
"visual: %s
\n
"
,
visual_str
?
visual_str
fprintf
(
stderr
,
"
subwin: 0x%x
\n
"
,
subwin
);
fprintf
(
stderr
,
"
flashcmap: %d
\n
"
,
flash_cmap
);
fprintf
(
stderr
,
"
force_idx: %d
\n
"
,
force_indexed_color
);
fprintf
(
stderr
,
"
scaling: %d %.5f
\n
"
,
scaling
,
scale_fac
);
fprintf
(
stderr
,
"
visual: %s
\n
"
,
visual_str
?
visual_str
:
"null"
);
fprintf
(
stderr
,
"overlay: %d
\n
"
,
overlay
);
fprintf
(
stderr
,
"
ovl_mouse: %d
\n
"
,
overlay_mouse
);
fprintf
(
stderr
,
"viewonly: %d
\n
"
,
view_only
);
fprintf
(
stderr
,
"shared: %d
\n
"
,
shared
);
fprintf
(
stderr
,
"conn_once: %d
\n
"
,
connect_once
);
fprintf
(
stderr
,
"connect: %s
\n
"
,
client_connect
fprintf
(
stderr
,
"
overlay: %d
\n
"
,
overlay
);
fprintf
(
stderr
,
"
ovl_cursor: %d
\n
"
,
overlay_cursor
);
fprintf
(
stderr
,
"
viewonly: %d
\n
"
,
view_only
);
fprintf
(
stderr
,
"
shared: %d
\n
"
,
shared
);
fprintf
(
stderr
,
"
conn_once: %d
\n
"
,
connect_once
);
fprintf
(
stderr
,
"
connect: %s
\n
"
,
client_connect
?
client_connect
:
"null"
);
fprintf
(
stderr
,
"connectfile %s
\n
"
,
client_connect_file
fprintf
(
stderr
,
"
connectfile %s
\n
"
,
client_connect_file
?
client_connect_file
:
"null"
);
fprintf
(
stderr
,
"vnc_conn: %d
\n
"
,
vnc_connect
);
fprintf
(
stderr
,
"authfile: %s
\n
"
,
auth_file
?
auth_file
fprintf
(
stderr
,
"
vnc_conn: %d
\n
"
,
vnc_connect
);
fprintf
(
stderr
,
"
authfile: %s
\n
"
,
auth_file
?
auth_file
:
"null"
);
fprintf
(
stderr
,
"allow: %s
\n
"
,
allow_list
?
allow_list
fprintf
(
stderr
,
"
allow: %s
\n
"
,
allow_list
?
allow_list
:
"null"
);
fprintf
(
stderr
,
"passfile: %s
\n
"
,
passwdfile
?
passwdfile
fprintf
(
stderr
,
"
passfile: %s
\n
"
,
passwdfile
?
passwdfile
:
"null"
);
fprintf
(
stderr
,
"accept: %s
\n
"
,
accept_cmd
?
accept_cmd
fprintf
(
stderr
,
"
accept: %s
\n
"
,
accept_cmd
?
accept_cmd
:
"null"
);
fprintf
(
stderr
,
"gone: %s
\n
"
,
gone_cmd
?
gone_cmd
fprintf
(
stderr
,
"
gone: %s
\n
"
,
gone_cmd
?
gone_cmd
:
"null"
);
fprintf
(
stderr
,
"inetd: %d
\n
"
,
inetd
);
fprintf
(
stderr
,
"using_shm: %d
\n
"
,
using_shm
);
fprintf
(
stderr
,
"flipbytes: %d
\n
"
,
flip_byte_order
);
fprintf
(
stderr
,
"blackout: %s
\n
"
,
blackout_string
fprintf
(
stderr
,
"
inetd: %d
\n
"
,
inetd
);
fprintf
(
stderr
,
"
using_shm: %d
\n
"
,
using_shm
);
fprintf
(
stderr
,
"
flipbytes: %d
\n
"
,
flip_byte_order
);
fprintf
(
stderr
,
"
blackout: %s
\n
"
,
blackout_string
?
blackout_string
:
"null"
);
fprintf
(
stderr
,
"xinerama: %d
\n
"
,
xinerama
);
fprintf
(
stderr
,
"logfile: %s
\n
"
,
logfile
?
logfile
fprintf
(
stderr
,
"
xinerama: %d
\n
"
,
xinerama
);
fprintf
(
stderr
,
"
logfile: %s
\n
"
,
logfile
?
logfile
:
"null"
);
fprintf
(
stderr
,
"bg: %d
\n
"
,
bg
);
fprintf
(
stderr
,
"mod_tweak: %d
\n
"
,
use_modifier_tweak
);
fprintf
(
stderr
,
"isolevel3: %d
\n
"
,
use_iso_level3
);
fprintf
(
stderr
,
"xkb: %d
\n
"
,
use_xkb_modtweak
);
fprintf
(
stderr
,
"skipkeys: %s
\n
"
,
skip_keycodes
?
skip_keycodes
fprintf
(
stderr
,
" bg: %d
\n
"
,
bg
);
fprintf
(
stderr
,
" mod_tweak: %d
\n
"
,
use_modifier_tweak
);
fprintf
(
stderr
,
" isolevel3: %d
\n
"
,
use_iso_level3
);
fprintf
(
stderr
,
" xkb: %d
\n
"
,
use_xkb_modtweak
);
fprintf
(
stderr
,
" skipkeys: %s
\n
"
,
skip_keycodes
?
skip_keycodes
:
"null"
);
fprintf
(
stderr
,
" addkeysyms: %d
\n
"
,
add_keysyms
);
fprintf
(
stderr
,
" xkbcompat: %d
\n
"
,
xkbcompat
);
fprintf
(
stderr
,
" clearmods: %d
\n
"
,
clear_mods
);
fprintf
(
stderr
,
" remap: %s
\n
"
,
remap_file
?
remap_file
:
"null"
);
fprintf
(
stderr
,
"addkeysyms: %d
\n
"
,
add_keysyms
);
fprintf
(
stderr
,
"xkbcompat: %d
\n
"
,
xkbcompat
);
fprintf
(
stderr
,
"clearmods: %d
\n
"
,
clear_mods
);
fprintf
(
stderr
,
"remap: %s
\n
"
,
remap_file
?
remap_file
:
"null"
);
fprintf
(
stderr
,
"nofb: %d
\n
"
,
nofb
);
fprintf
(
stderr
,
"watchbell: %d
\n
"
,
watch_bell
);
fprintf
(
stderr
,
"watchsel: %d
\n
"
,
watch_selection
);
fprintf
(
stderr
,
"watchprim: %d
\n
"
,
watch_primary
);
fprintf
(
stderr
,
"loc_curs: %d
\n
"
,
local_cursor
);
fprintf
(
stderr
,
"mouse: %d
\n
"
,
show_mouse
);
fprintf
(
stderr
,
"root_curs: %d
\n
"
,
show_root_cursor
);
fprintf
(
stderr
,
"xwarpptr: %d
\n
"
,
use_xwarppointer
);
fprintf
(
stderr
,
"cursorpos: %d
\n
"
,
cursor_pos
);
fprintf
(
stderr
,
"buttonmap: %s
\n
"
,
pointer_remap
fprintf
(
stderr
,
" nofb: %d
\n
"
,
nofb
);
fprintf
(
stderr
,
" watchbell: %d
\n
"
,
watch_bell
);
fprintf
(
stderr
,
" watchsel: %d
\n
"
,
watch_selection
);
fprintf
(
stderr
,
" watchprim: %d
\n
"
,
watch_primary
);
fprintf
(
stderr
,
" cursor: %d
\n
"
,
show_cursor
);
fprintf
(
stderr
,
" root_curs: %d
\n
"
,
show_multiple_cursors
);
fprintf
(
stderr
,
" curs_mode: %s
\n
"
,
multiple_cursors_mode
?
multiple_cursors_mode
:
"null"
);
fprintf
(
stderr
,
" xwarpptr: %d
\n
"
,
use_xwarppointer
);
fprintf
(
stderr
,
" cursorpos: %d
\n
"
,
cursor_pos_updates
);
fprintf
(
stderr
,
" cursorshp: %d
\n
"
,
cursor_shape_updates
);
fprintf
(
stderr
,
" buttonmap: %s
\n
"
,
pointer_remap
?
pointer_remap
:
"null"
);
fprintf
(
stderr
,
"dragging: %d
\n
"
,
show_dragging
);
fprintf
(
stderr
,
"old_ptr: %d
\n
"
,
old_pointer
);
fprintf
(
stderr
,
"inputskip: %d
\n
"
,
ui_skip
);
fprintf
(
stderr
,
"norepeat: %d
\n
"
,
no_autorepeat
);
fprintf
(
stderr
,
"debug_ptr: %d
\n
"
,
debug_pointer
);
fprintf
(
stderr
,
"debug_key: %d
\n
"
,
debug_keyboard
);
fprintf
(
stderr
,
"defer: %d
\n
"
,
defer_update
);
fprintf
(
stderr
,
"waitms: %d
\n
"
,
waitms
);
fprintf
(
stderr
,
"take_naps: %d
\n
"
,
take_naps
);
fprintf
(
stderr
,
"sigpipe: %d
\n
"
,
sigpipe
);
fprintf
(
stderr
,
"threads: %d
\n
"
,
use_threads
);
fprintf
(
stderr
,
"fs_frac: %.2f
\n
"
,
fs_frac
);
fprintf
(
stderr
,
"onetile: %d
\n
"
,
single_copytile
);
fprintf
(
stderr
,
"gaps_fill: %d
\n
"
,
gaps_fill
);
fprintf
(
stderr
,
"grow_fill: %d
\n
"
,
grow_fill
);
fprintf
(
stderr
,
"tile_fuzz: %d
\n
"
,
tile_fuzz
);
fprintf
(
stderr
,
"version: %s
\n
"
,
lastmod
);
fprintf
(
stderr
,
" dragging: %d
\n
"
,
show_dragging
);
fprintf
(
stderr
,
" old_ptr: %d
\n
"
,
old_pointer
);
fprintf
(
stderr
,
" inputskip: %d
\n
"
,
ui_skip
);
fprintf
(
stderr
,
" norepeat: %d
\n
"
,
no_autorepeat
);
fprintf
(
stderr
,
" debug_ptr: %d
\n
"
,
debug_pointer
);
fprintf
(
stderr
,
" debug_key: %d
\n
"
,
debug_keyboard
);
fprintf
(
stderr
,
" defer: %d
\n
"
,
defer_update
);
fprintf
(
stderr
,
" waitms: %d
\n
"
,
waitms
);
fprintf
(
stderr
,
" take_naps: %d
\n
"
,
take_naps
);
fprintf
(
stderr
,
" sigpipe: %d
\n
"
,
sigpipe
);
fprintf
(
stderr
,
" threads: %d
\n
"
,
use_threads
);
fprintf
(
stderr
,
" fs_frac: %.2f
\n
"
,
fs_frac
);
fprintf
(
stderr
,
" onetile: %d
\n
"
,
single_copytile
);
fprintf
(
stderr
,
" gaps_fill: %d
\n
"
,
gaps_fill
);
fprintf
(
stderr
,
" grow_fill: %d
\n
"
,
grow_fill
);
fprintf
(
stderr
,
" tile_fuzz: %d
\n
"
,
tile_fuzz
);
fprintf
(
stderr
,
"
\n
"
);
rfbLog
(
"x11vnc version: %s
\n
"
,
lastmod
);
}
else
{
rfbLogEnable
(
0
);
}
...
...
@@ -9182,11 +9741,11 @@ int main(int argc, char* argv[]) {
if
(
xkbcompat
)
{
Bool
rc
=
XkbIgnoreExtension
(
True
);
if
(
!
quiet
)
{
fprintf
(
stderr
,
"disabling xkb extension. rc=%d
\n
"
,
rc
);
rfbLog
(
"disabling xkb extension. rc=%d
\n
"
,
rc
);
}
if
(
watch_bell
)
{
watch_bell
=
0
;
fprintf
(
stderr
,
"disabling bell.
\n
"
);
}
if
(
!
quiet
)
rfbLog
(
"disabling bell.
\n
"
);
}
}
#else
...
...
@@ -9194,6 +9753,7 @@ int main(int argc, char* argv[]) {
watch_bell
=
0
;
use_xkb_modtweak
=
0
;
#endif
if
(
use_dpy
)
{
dpy
=
XOpenDisplay
(
use_dpy
);
}
else
if
(
(
use_dpy
=
getenv
(
"DISPLAY"
))
)
{
...
...
@@ -9203,13 +9763,12 @@ int main(int argc, char* argv[]) {
}
if
(
!
dpy
)
{
fprintf
(
stderr
,
"XOpenDisplay failed (%s)
\n
"
,
use_dpy
?
use_dpy
:
"null"
);
rfbLog
(
"XOpenDisplay failed (%s)
\n
"
,
use_dpy
?
use_dpy
:
"null"
);
exit
(
1
);
}
else
if
(
use_dpy
)
{
if
(
!
quiet
)
fprintf
(
stderr
,
"Using X display %s
\n
"
,
use_dpy
);
if
(
!
quiet
)
rfbLog
(
"Using X display %s
\n
"
,
use_dpy
);
}
else
{
if
(
!
quiet
)
fprintf
(
stderr
,
"Using default X display.
\n
"
);
if
(
!
quiet
)
rfbLog
(
"Using default X display.
\n
"
);
}
scr
=
DefaultScreen
(
dpy
);
...
...
@@ -9222,28 +9781,43 @@ int main(int argc, char* argv[]) {
}
/* check for XTEST */
if
(
!
XTestQueryExtension
(
dpy
,
&
ev
,
&
er
,
&
maj
,
&
min
))
{
fprintf
(
stderr
,
"Display does not support XTest extension.
\n
"
);
exit
(
1
);
if
(
!
XTestQueryExtension_wr
(
dpy
,
&
ev
,
&
er
,
&
maj
,
&
min
))
{
rfbLog
(
"warning: XTest extension not available, most user"
" input
\n
"
);
rfbLog
(
"(pointer and keyboard) will be discarded.
\n
"
);
xtest_present
=
0
;
rfbLog
(
"no XTest extension, switching to -xwarppointer mode
\n
"
);
rfbLog
(
"for pointer motion input.
\n
"
);
use_xwarppointer
=
1
;
}
/*
* Window managers will often grab the display during resize, etc.
* To avoid deadlock (our user resize input is not processed)
* we tell the server to process our requests during all grabs:
*/
XTestGrabControl
(
dpy
,
True
);
XTestGrabControl
_wr
(
dpy
,
True
);
/* check for MIT-SHM */
if
(
!
nofb
&&
!
XShmQueryExtension
(
dpy
))
{
if
(
!
nofb
&&
!
XShmQueryExtension
_wr
(
dpy
))
{
if
(
!
using_shm
)
{
if
(
!
quiet
)
{
fprintf
(
stderr
,
"info: display does not
"
"
support
XShm.
\n
"
);
rfbLog
(
"info: display does not support
"
" XShm.
\n
"
);
}
}
else
{
fprintf
(
stderr
,
"Display does not support XShm "
"extension (must be local).
\n
"
);
rfbLog
(
"warning: XShm extension is not available.
\n
"
);
rfbLog
(
"For best performance the X Display should be"
" local. (i.e.
\n
"
);
rfbLog
(
"the x11vnc and X server processes should be"
" running on
\n
"
);
rfbLog
(
"the same machine.)
\n
"
);
#ifdef LIBVNCSERVER_HAVE_XSHM
rfbLog
(
"Restart with -noshm to override this.
\n
"
);
exit
(
1
);
#else
rfbLog
(
"Switching to -noshm mode.
\n
"
);
using_shm
=
0
;
#endif
}
}
...
...
@@ -9286,8 +9860,10 @@ int main(int argc, char* argv[]) {
}
initialize_watch_bell
();
if
(
!
use_xkb
&&
use_xkb_modtweak
)
{
if
(
!
quiet
)
{
fprintf
(
stderr
,
"warning: disabling xkb modtweak."
" XKEYBOARD ext. not present.
\n
"
);
}
use_xkb_modtweak
=
0
;
}
#endif
...
...
@@ -9316,9 +9892,8 @@ int main(int argc, char* argv[]) {
/* this may be overridden via visual_id below */
default_visual
=
attr
.
visual
;
/* show_mouse has some segv crashes as well */
if
(
show_root_cursor
)
{
show_root_cursor
=
0
;
if
(
show_multiple_cursors
)
{
show_multiple_cursors
=
0
;
if
(
!
quiet
)
{
fprintf
(
stderr
,
"disabling root cursor drawing"
" for subwindow
\n
"
);
...
...
@@ -9368,6 +9943,10 @@ int main(int argc, char* argv[]) {
XFree
(
vinfo
);
}
if
(
!
quiet
)
{
rfbLog
(
"default visual ID: 0x%x
\n
"
,
(
int
)
XVisualIDFromVisual
(
default_visual
));
}
if
(
nofb
)
{
/*
...
...
@@ -9388,7 +9967,7 @@ int main(int argc, char* argv[]) {
fb
=
XGetImage_wr
(
dpy
,
window
,
0
,
0
,
dpy_x
,
dpy_y
,
AllPlanes
,
ZPixmap
);
if
(
!
quiet
)
{
fprintf
(
stderr
,
"Read initial data from X display into"
rfbLog
(
"Read initial data from X display into"
" framebuffer.
\n
"
);
}
}
...
...
@@ -9432,6 +10011,7 @@ int main(int argc, char* argv[]) {
if
(
remap_file
!=
NULL
)
{
initialize_remap
(
remap_file
);
}
initialize_pointer_map
(
pointer_remap
);
clear_modifiers
(
1
);
...
...
@@ -9454,7 +10034,7 @@ int main(int argc, char* argv[]) {
if
(
host
!=
NULL
)
{
/* note that vncviewer special cases 5900-5999 */
if
(
inetd
)
{
;
/* should not occur */
;
/* should not occur
(rfbPort)
*/
}
else
if
(
quiet
)
{
if
(
port
>=
5900
)
{
fprintf
(
stderr
,
"The VNC desktop is "
...
...
@@ -9478,7 +10058,11 @@ int main(int argc, char* argv[]) {
}
}
fflush
(
stderr
);
if
(
inetd
)
{
;
/* should not occur (rfbPort) */
}
else
{
fprintf
(
stdout
,
"PORT=%d
\n
"
,
screen
->
rfbPort
);
}
fflush
(
stdout
);
}
...
...
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