Commit 2cc1b1d3 authored by runge's avatar runge

x11vnc: synchronous mode for -remote, string cleanup

parent f28038b2
2004-12-19 Karl Runge <runge@karlrunge.com>
* x11vnc: string cleanup, synchronous remote-control option -sync
* libvncserver/cursor.c: zero underCursorBufferLen when cursor freed.
2004-12-16 Karl Runge <runge@karlrunge.com> 2004-12-16 Karl Runge <runge@karlrunge.com>
* test/encodingstest.c: fix decl bug in main() * test/encodingstest.c: fix decl bug in main()
* x11vnc: use XFIXES extension to show the exact cursor shape. * x11vnc: use XFIXES extension to show the exact cursor shape.
......
...@@ -529,6 +529,7 @@ void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c,rfbBool freeOld) ...@@ -529,6 +529,7 @@ void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c,rfbBool freeOld)
free(rfbScreen->underCursorBuffer); free(rfbScreen->underCursorBuffer);
rfbScreen->underCursorBuffer=0; rfbScreen->underCursorBuffer=0;
rfbScreen->underCursorBufferLen=0;
if(rfbScreen->cursor && (freeOld || rfbScreen->cursor->cleanup)) if(rfbScreen->cursor && (freeOld || rfbScreen->cursor->cleanup))
rfbFreeCursor(rfbScreen->cursor); rfbFreeCursor(rfbScreen->cursor);
......
2004-12-19 Karl Runge <runge@karlrunge.com>
* cleanup putenv, snprint, other string manip.
* add -sync mode to remote control for better control
* allow -remote and -query at same time.
2004-12-16 Karl Runge <runge@karlrunge.com> 2004-12-16 Karl Runge <runge@karlrunge.com>
* support for XFIXES extension to show the exact cursor shape, * support for XFIXES extension to show the exact cursor shape,
working on Linux/Xorg and Solaris 10. disable with -noxfixes working on Linux/Xorg and Solaris 10. disable with -noxfixes
......
x11vnc README file Date: Thu Dec 16 23:32:54 EST 2004 x11vnc README file Date: Sun Dec 19 23:34:22 EST 2004
The following information is taken from these URLs: The following information is taken from these URLs:
...@@ -278,7 +278,8 @@ vncviewer -via $host localhost:0 # must be TightVNC vncviewer. ...@@ -278,7 +278,8 @@ vncviewer -via $host localhost:0 # must be TightVNC vncviewer.
version of x11vnc (Oct 2003) that you likely want to avoid. Also, you version of x11vnc (Oct 2003) that you likely want to avoid. Also, you
can get a copy of my latest, bleeding edge [22]x11vnc.c file to can get a copy of my latest, bleeding edge [22]x11vnc.c file to
replace the one in the above packages or the one in the CVS tree and replace the one in the above packages or the one in the CVS tree and
then rebuild. then rebuild. If you have an older libvncserver source tree, you may
need to switch on the OLD_TREE near the top of the x11vnc.c file.
See the [23]FAQ below for information about where you might obtain a See the [23]FAQ below for information about where you might obtain a
precompiled x11vnc binary from 3rd parties. precompiled x11vnc binary from 3rd parties.
...@@ -349,7 +350,7 @@ vncviewer -via $host localhost:0 # must be TightVNC vncviewer. ...@@ -349,7 +350,7 @@ vncviewer -via $host localhost:0 # must be TightVNC vncviewer.
locations information to the libvncserver configuration: locations information to the libvncserver configuration:
#!/bin/sh #!/bin/sh
# Build script for Solaris, etc, with, gcc, libjpeg and libz in # Build script for Solaris, etc, with gcc, libjpeg and libz in
# non-standard locations. # non-standard locations.
PATH=/path/to/gcc/bin:/usr/ccs/bin:$PATH # set to get gcc PATH=/path/to/gcc/bin:/usr/ccs/bin:$PATH # set to get gcc
...@@ -368,6 +369,9 @@ LDFLAGS="-L $JPEG/lib -R $JPEG/lib -L $ZLIB/lib -R $ZLIB/lib" ...@@ -368,6 +369,9 @@ LDFLAGS="-L $JPEG/lib -R $JPEG/lib -L $ZLIB/lib -R $ZLIB/lib"
CPPFLAGS="$CPPFLAGS -I /usr/openwin/include" CPPFLAGS="$CPPFLAGS -I /usr/openwin/include"
LDFLAGS="$LDFLAGS -L /usr/openwin/lib -R /usr/openwin/lib" LDFLAGS="$LDFLAGS -L /usr/openwin/lib -R /usr/openwin/lib"
# This only applies to Solaris 10 or later (XFIXES and DAMAGE)
LDFLAGS="$LDFLAGS -L /usr/openwin/sfw/lib -R /usr/openwin/sfw/lib"
# Everything needs to built with _REENTRANT for thread safe errno: # Everything needs to built with _REENTRANT for thread safe errno:
CPPFLAGS="$CPPFLAGS -D_REENTRANT" CPPFLAGS="$CPPFLAGS -D_REENTRANT"
...@@ -467,7 +471,8 @@ ls -l ./x11vnc/x11vnc ...@@ -467,7 +471,8 @@ ls -l ./x11vnc/x11vnc
horizontal scanlines. This is a surprisingly effective algorithm for horizontal scanlines. This is a surprisingly effective algorithm for
finding changed regions. For keyboard and mouse user input the XTEST finding changed regions. For keyboard and mouse user input the XTEST
extension is used to pass the input events to the X server. To detect extension is used to pass the input events to the X server. To detect
XBell "beeps" the XKEYBOARD extension is used. XBell "beeps" the XKEYBOARD extension is used. If available, the
XFIXES extension is used to retrieve the current mouse cursor shape.
Barbershop mirrors effect: What if x11vnc is started up, and Barbershop mirrors effect: What if x11vnc is started up, and
vncviewer is then started up on the same machine and displayed on the vncviewer is then started up on the same machine and displayed on the
...@@ -539,12 +544,14 @@ ls -l ./x11vnc/x11vnc ...@@ -539,12 +544,14 @@ ls -l ./x11vnc/x11vnc
dynamically... dynamically...
* Somewhat surprisingly, the X11 mouse (cursor) shape is write-only * Somewhat surprisingly, the X11 mouse (cursor) shape is write-only
and cannot be queried from the X server. So in x11vnc the cursor and cannot be queried from the X server. So in x11vnc the cursor
shape stays fixed at an arrow. (see the "-cursor X" and other shape stays fixed at an arrow. (see the "-cursor X" and "-cursor
options, however, for a partial hack for the root window, etc.). some", however, for a partial hack for the root window, etc.).
Also, on Solaris using the SUN_OVL overlay extension, x11vnc can Also, on Solaris using the SUN_OVL overlay extension, x11vnc can
show the correct mouse cursor when the -overlay option is also show the correct mouse cursor when the -overlay option is also
supplied. For XFree86/Xorg, the XFIXES extension should help this supplied. A similar thing is done on IRIX as well when -overlay is
as well. supplied. As of Dec/2004 x11vnc supports the XFIXES extension (in
Xorg and Solaris 10) to query the X server for the exact cursor
shape, this works pretty well.
* Audio from applications is of course not redirected (separate * Audio from applications is of course not redirected (separate
redirectors do exist, e.g. esd). The XBell() "beeps" will work if redirectors do exist, e.g. esd). The XBell() "beeps" will work if
the X server supports the XKEYBOARD extension. (Note that on the X server supports the XKEYBOARD extension. (Note that on
...@@ -581,7 +588,7 @@ ls -l ./x11vnc/x11vnc ...@@ -581,7 +588,7 @@ ls -l ./x11vnc/x11vnc
documentation on how to use them? documentation on how to use them?
[45]Q-7: I don't like typing arcane command line options every time I [45]Q-7: I don't like typing arcane command line options every time I
start x11vnc. What can I do? Is there a config file? start x11vnc. What can I do? Is there a config file? Is there a GUI?
[46]Q-8: Why does x11vnc exit as soon as the VNC viewer disconnects? [46]Q-8: Why does x11vnc exit as soon as the VNC viewer disconnects?
And why doesn't it allow more than one VNC viewer to connect at the And why doesn't it allow more than one VNC viewer to connect at the
...@@ -623,133 +630,140 @@ ls -l ./x11vnc/x11vnc ...@@ -623,133 +630,140 @@ ls -l ./x11vnc/x11vnc
[55]Q-17: How do I stop x11vnc once it is running in the background? [55]Q-17: How do I stop x11vnc once it is running in the background?
[56]Q-18: Can I limit which machines incoming VNC clients can connect [56]Q-18: Can I change settings in x11vnc without having to restart
it? Is there a way to remote control it?
[57]Q-19: Can I limit which machines incoming VNC clients can connect
from? from?
[57]Q-19: How do I build x11vnc/libvncserver with libwrap [58]Q-20: How do I build x11vnc/libvncserver with libwrap
(tcp_wrappers) support? (tcp_wrappers) support?
[58]Q-20: Can I prompt the user at the local X display whether the [59]Q-21: Can I prompt the user at the local X display whether the
incoming VNC client should be accepted or not? Can I decide to make incoming VNC client should be accepted or not? Can I decide to make
some clients view-only? How about running an arbitrary program to make some clients view-only? How about running an arbitrary program to make
the decisions? the decisions?
[59]Q-21: How do I create a VNC password for use with x11vnc? [60]Q-22: How do I create a VNC password for use with x11vnc?
[60]Q-22: How can I tunnel my connection to x11vnc via an encrypted [61]Q-23: How can I tunnel my connection to x11vnc via an encrypted
SSH channel between two Unix machines? SSH channel between two Unix machines?
[61]Q-23: How can I tunnel my connection to x11vnc via an encrypted [62]Q-24: How can I tunnel my connection to x11vnc via an encrypted
SSH channel from Windows using an SSH client like Putty? SSH channel from Windows using an SSH client like Putty?
[62]Q-24: Does x11vnc support Unix usernames and passwords? Can I [63]Q-25: Does x11vnc support Unix usernames and passwords? Can I
further limit the set of Unix usernames who can connect to the VNC further limit the set of Unix usernames who can connect to the VNC
desktop? desktop?
[63]Q-25: Can I have two passwords for VNC viewers, one for full [64]Q-26: Can I have two passwords for VNC viewers, one for full
access and the other for view-only access to the display? access and the other for view-only access to the display?
[64]Q-26: I use a screen-lock when I leave my workstation (e.g. [65]Q-27: I use a screen-lock when I leave my workstation (e.g.
xscreensaver or xlock). When I remotely access my workstation desktop xscreensaver or xlock). When I remotely access my workstation desktop
via x11vnc I can unlock the desktop fine, but I am worried people will via x11vnc I can unlock the desktop fine, but I am worried people will
see my activities on the physical monitor. What can I do to prevent see my activities on the physical monitor. What can I do to prevent
this, or at least make it more difficult? this, or at least make it more difficult?
[65]Q-27: Can I have x11vnc automatically lock the screen when I [66]Q-28: Can I have x11vnc automatically lock the screen when I
disconnect the VNC viewer? disconnect the VNC viewer?
[66]Q-28: Are reverse connections (i.e. the VNC server connecting to [67]Q-29: Are reverse connections (i.e. the VNC server connecting to
the VNC viewer) using "vncviewer -listen" and vncconnect(1) supported? the VNC viewer) using "vncviewer -listen" and vncconnect(1) supported?
[67]Q-29: Sometimes when a VNC viewer dies abruptly, x11vnc also dies [68]Q-30: Sometimes when a VNC viewer dies abruptly, x11vnc also dies
with the error message like: "Broken pipe". I'm using the -forever with the error message like: "Broken pipe". I'm using the -forever
mode and I want x11vnc to keep running. mode and I want x11vnc to keep running.
[68]Q-30: How can I use x11vnc to connect to an X login screen like [69]Q-31: How can I use x11vnc to connect to an X login screen like
xdm, GNOME gdm, KDE kdm, or CDE dtlogin? (i.e. nobody is logged into xdm, GNOME gdm, KDE kdm, or CDE dtlogin? (i.e. nobody is logged into
an X session yet). an X session yet).
[69]Q-31: Can I run x11vnc out of inetd(1)? [70]Q-32: Can I run x11vnc out of inetd(1)?
[70]Q-32: How do I make x11vnc work with the Java VNC viewer applet in [71]Q-33: How do I make x11vnc work with the Java VNC viewer applet in
a web browser? a web browser?
[71]Q-33: Why isn't the mouse cursor shape (the little icon shape [72]Q-34: Why isn't the mouse cursor shape (the little icon shape
where the mouse pointer is) correct as I move from window to window? where the mouse pointer is) correct as I move from window to window?
[72]Q-34: Why does the mouse arrow just stay in one corner in my [73]Q-35: Why does the mouse arrow just stay in one corner in my
vncviewer, whereas my cursor (that does move) is just a dot? vncviewer, whereas my cursor (that does move) is just a dot?
[73]Q-35: Can I take advantage of the TightVNC extension to the VNC [74]Q-36: Can I take advantage of the TightVNC extension to the VNC
protocol where Cursor Positions Updates are sent back to all connected protocol where Cursor Positions Updates are sent back to all connected
clients (i.e. passive viewers can see the mouse cursor being moved clients (i.e. passive viewers can see the mouse cursor being moved
around by another viewer)? around by another viewer)?
[74]Q-36: Is it possible to swap the mouse buttons (e.g. left-handed [75]Q-37: Is it possible to swap the mouse buttons (e.g. left-handed
operation), or arbitrarily remap them? How about mapping button clicks operation), or arbitrarily remap them? How about mapping button clicks
to keystrokes, e.g. to partially emulate Mouse wheel scrolling? to keystrokes, e.g. to partially emulate Mouse wheel scrolling?
[75]Q-37: When I drag windows around with the mouse or scroll up and [76]Q-38: When I drag windows around with the mouse or scroll up and
down things really bog down (unless I do the drag in a single, quick down things really bog down (unless I do the drag in a single, quick
motion). Is there anything to do to improve things? motion). Is there anything to do to improve things?
[76]Q-38: I have lots of memory, but why does x11vnc fail with [77]Q-39: I have lots of memory, but why does x11vnc fail with
shmget: No space left on device or Minor opcode of failed shmget: No space left on device or Minor opcode of failed
request: 1 (X_ShmAttach)? request: 1 (X_ShmAttach)?
[77]Q-39: How can I make x11vnc use less system resources? [78]Q-40: How can I make x11vnc use less system resources?
[78]Q-40: How can I make x11vnc use MORE system resources? [79]Q-41: How can I make x11vnc use MORE system resources?
[79]Q-41: I use x11vnc over a slow link with high latency (e.g. dialup [80]Q-42: I use x11vnc over a slow link with high latency (e.g. dialup
modem), is there anything I can do to speed things up? modem), is there anything I can do to speed things up?
[80]Q-42: How can I get my AltGr and Shift modifiers to work between [81]Q-43: How can I get my AltGr and Shift modifiers to work between
keyboards for different languages? keyboards for different languages?
[81]Q-43: When I try to type a "<" (i.e. less than) instead I get ">" [82]Q-44: When I try to type a "<" (i.e. less than) instead I get ">"
(i.e. greater than)! Strangely, typing ">" works OK!! (i.e. greater than)! Strangely, typing ">" works OK!!
[82]Q-44: I'm using an "international" keyboard (e.g. German "de", or [83]Q-45: I'm using an "international" keyboard (e.g. German "de", or
Danish "dk") and the -modtweak mode works well if the VNC viewer is Danish "dk") and the -modtweak mode works well if the VNC viewer is
run on a Unix/Linux machine with a similar keyboard. But if I run the run on a Unix/Linux machine with a similar keyboard. But if I run the
VNC viewer on Unix/Linux with a different keyboard (e.g. "us") or VNC viewer on Unix/Linux with a different keyboard (e.g. "us") or
Windows with any keyboard, I can't type some keys like: "@", "$", "<", Windows with any keyboard, I can't type some keys like: "@", "$", "<",
">", etc. How can I fix this? ">", etc. How can I fix this?
[83]Q-45: When typing I sometimes get double, triple, or more of my [84]Q-46: When typing I sometimes get double, triple, or more of my
keystrokes repeated. I'm sure I only typed them once, what can I do? keystrokes repeated. I'm sure I only typed them once, what can I do?
[84]Q-46: The machine where I run x11vnc has an AltGr key, but the [85]Q-47: The machine where I run x11vnc has an AltGr key, but the
local machine where I run the VNC viewer does not. Is there a way I local machine where I run the VNC viewer does not. Is there a way I
can map a local unused key to send an AltGr? How about a Compose key can map a local unused key to send an AltGr? How about a Compose key
as well? as well?
[85]Q-47: I have a Sun machine I run x11vnc on. Its Sun keyboard has [86]Q-48: I have a Sun machine I run x11vnc on. Its Sun keyboard has
just one Alt key labelled "Alt" and two Meta keys labelled with little just one Alt key labelled "Alt" and two Meta keys labelled with little
diamonds. The machine where I run the VNC viewer only has Alt keys. diamonds. The machine where I run the VNC viewer only has Alt keys.
How can I send a Meta keypress? (e.g. emacs needs this) How can I send a Meta keypress? (e.g. emacs needs this)
[86]Q-48: Can I map a keystroke to a mouse button click on the remote [87]Q-49: Can I map a keystroke to a mouse button click on the remote
machine? machine?
[87]Q-49: The remote display is larger (in number of pixels) than the [88]Q-50: The remote display is larger (in number of pixels) than the
local display I am running the vncviewer on. I don't like the local display I am running the vncviewer on. I don't like the
vncviewer scrollbars, what I can do? vncviewer scrollbars, what I can do?
[88]Q-50: Does x11vnc support server-side framebuffer scaling? (E.g. [89]Q-51: Does x11vnc support server-side framebuffer scaling? (E.g.
to make the desktop smaller). to make the desktop smaller).
[89]Q-51: Does x11vnc work with Xinerama? (i.e. multiple monitors [90]Q-52: Does x11vnc work with Xinerama? (i.e. multiple monitors
joined together to form one big, single screen). joined together to form one big, single screen).
[90]Q-52: Can I use x11vnc on a multi-headed display that is not [91]Q-53: Can I use x11vnc on a multi-headed display that is not
Xinerama (i.e. separate screens :0.0, :0.1, ... for each monitor)? Xinerama (i.e. separate screens :0.0, :0.1, ... for each monitor)?
[91]Q-53: Why is the view in my VNC viewer completely black? Or why is [92]Q-54: Does x11vnc support the XRANDR (X Resize, Rotate and
Reflection) extension? Whenever I rotate or resize the screen x11vnc
just seems to crash.
[93]Q-55: Why is the view in my VNC viewer completely black? Or why is
everything flashing around randomly? everything flashing around randomly?
[92]Q-54: I use Linux Virtual Consoles (VC's) to implement 'Fast User [94]Q-56: I use Linux Virtual Consoles (VC's) to implement 'Fast User
Switching' between users' sessions (e.g. Betty is on Ctrl-Alt-F7, Switching' between users' sessions (e.g. Betty is on Ctrl-Alt-F7,
Bobby is on Ctrl-Alt-F8, and Sid is on Ctrl-Alt-F1: they use those Bobby is on Ctrl-Alt-F8, and Sid is on Ctrl-Alt-F1: they use those
keystrokes to switch between their sessions). How come the view in a keystrokes to switch between their sessions). How come the view in a
...@@ -757,13 +771,13 @@ ls -l ./x11vnc/x11vnc ...@@ -757,13 +771,13 @@ ls -l ./x11vnc/x11vnc
otherwise all messed up unless the X session x11vnc is attached to is otherwise all messed up unless the X session x11vnc is attached to is
in the active VC? in the active VC?
[93]Q-55: Does the Clipboard/Selection get transferred between the [95]Q-57: Does the Clipboard/Selection get transferred between the
vncviewer and the X display? vncviewer and the X display?
[94]Q-56: Why don't I hear the "Beeps" in my X session (e.g. when [96]Q-58: Why don't I hear the "Beeps" in my X session (e.g. when
typing tput bel in an xterm)? typing tput bel in an xterm)?
[95]Q-57: I am using x11vnc where my local machine has "popup/hidden [97]Q-59: I am using x11vnc where my local machine has "popup/hidden
taskbars" (e.g. GNOME or MacOS X) and the remote display where x11vnc taskbars" (e.g. GNOME or MacOS X) and the remote display where x11vnc
runs also has "popup/hidden taskbars" (e.g. GNOME). When I move the runs also has "popup/hidden taskbars" (e.g. GNOME). When I move the
mouse to the edge of the screen where the popups happen, the taskbars mouse to the edge of the screen where the popups happen, the taskbars
...@@ -863,7 +877,7 @@ ls -l ./x11vnc/x11vnc ...@@ -863,7 +877,7 @@ ls -l ./x11vnc/x11vnc
is a workaround for Solaris 2.5.1 (and perhaps earlier): is a workaround for Solaris 2.5.1 (and perhaps earlier):
First use the environment settings (CPPFLAGS, LDFLAGS, etc.) in the First use the environment settings (CPPFLAGS, LDFLAGS, etc.) in the
above [96]Solaris build script to run the configure command. That above [98]Solaris build script to run the configure command. That
should succeed without failure. Then, you have to hand edit the should succeed without failure. Then, you have to hand edit the
autogenerated rfb/rfbconfig.h file in the source tree, and just before autogenerated rfb/rfbconfig.h file in the source tree, and just before
the last #endif at the bottom of that file insert these workaround the last #endif at the bottom of that file insert these workaround
...@@ -899,6 +913,10 @@ if (sym >> 8 == 0) { \ ...@@ -899,6 +913,10 @@ if (sym >> 8 == 0) { \
*(upper) -= (XK_oslash - XK_Ooblique); \ *(upper) -= (XK_oslash - XK_Ooblique); \
} }
You will also have to change all the snprint() references to sprintf()
calls x11vnc.c (sorry I don't know how to do this in a macro since
snprint() is varargs).
Then run make with the Solaris build script environment, everything Then run make with the Solaris build script environment, everything
should compile without problems, and the resulting x11vnc binary should compile without problems, and the resulting x11vnc binary
should work OK (but note the above XConvertCase only covers Latin 1). should work OK (but note the above XConvertCase only covers Latin 1).
...@@ -912,18 +930,18 @@ if (sym >> 8 == 0) { \ ...@@ -912,18 +930,18 @@ if (sym >> 8 == 0) { \
Q-4: Where can I get a precompiled x11vnc binary for my Operating Q-4: Where can I get a precompiled x11vnc binary for my Operating
System? System?
Hopefully the [97]build steps above and [98]FAQ provide enough info Hopefully the [99]build steps above and [100]FAQ provide enough info
for a painless compile for most environments. Please report problems for a painless compile for most environments. Please report problems
with the x11vnc configure, make, etc. on your system (if your system with the x11vnc configure, make, etc. on your system (if your system
is known to compile other GNU packages successfully). is known to compile other GNU packages successfully).
There are precompiled x11vnc binaries made by other groups available There are precompiled x11vnc binaries made by other groups available
at the following locations: at the following locations:
Debian: (.deb) [99]http://packages.debian.org/x11vnc Debian: (.deb) [101]http://packages.debian.org/x11vnc
Slackware: (.tgz) [100]http://www.linuxpackages.net/ Redhat/Fedora: Slackware: (.tgz) [102]http://www.linuxpackages.net/ Redhat/Fedora:
(.rpm) [101]http://dag.wieers.com/packages/x11vnc/ wwexptools: (.tgz) (.rpm) [103]http://dag.wieers.com/packages/x11vnc/ wwexptools: (.tgz)
[102]http://www.bell-labs.com/project/wwexptools/packages.html The [104]http://www.bell-labs.com/project/wwexptools/packages.html The
last one, wwexptools, provides a variety of Unix binaries (Linux, last one, wwexptools, provides a variety of Unix binaries (Linux,
Solaris, HP-UX, Irix, ...) with the intent of being compatible on a Solaris, HP-UX, Irix, ...) with the intent of being compatible on a
wide range of OS releases. Find x11vnc near the bottom of that page wide range of OS releases. Find x11vnc near the bottom of that page
...@@ -935,7 +953,7 @@ if (sym >> 8 == 0) { \ ...@@ -935,7 +953,7 @@ if (sym >> 8 == 0) { \
this by looking at the x11vnc output and if it says the encoding for a this by looking at the x11vnc output and if it says the encoding for a
client is "hextile" then likely the fast compression encodings are client is "hextile" then likely the fast compression encodings are
missing. If you want optimal performance on your OS, you should see missing. If you want optimal performance on your OS, you should see
the [103]build notes above for where to download libz and libjpeg, and the [105]build notes above for where to download libz and libjpeg, and
then build everything with gcc. then build everything with gcc.
If any of the above binaries don't work and building x11vnc on your OS If any of the above binaries don't work and building x11vnc on your OS
...@@ -949,8 +967,8 @@ if (sym >> 8 == 0) { \ ...@@ -949,8 +967,8 @@ if (sym >> 8 == 0) { \
above, the x11vnc binary from the above packages has a good chance of above, the x11vnc binary from the above packages has a good chance of
working. You can "install" it by just copying the x11vnc binary to the working. You can "install" it by just copying the x11vnc binary to the
desired directory in your PATH. Tip on extracting files from a Debian desired directory in your PATH. Tip on extracting files from a Debian
package: extract the archive via a command like: ar x package: extract the archive via a command like: "ar x
x11vnc_0.6-2_i386.deb and then you can find the binary in the x11vnc_0.6-2_i386.deb" and then you can find the binary in the
resulting data.tar.gz tar file. Also, rpm2cpio(1) is useful in resulting data.tar.gz tar file. Also, rpm2cpio(1) is useful in
extracting files from rpm packages. extracting files from rpm packages.
...@@ -959,17 +977,17 @@ if (sym >> 8 == 0) { \ ...@@ -959,17 +977,17 @@ if (sym >> 8 == 0) { \
To obtain VNC viewers for the viewing side (Windows, Mac OS, or Unix) To obtain VNC viewers for the viewing side (Windows, Mac OS, or Unix)
try here: try here:
* [104]http://www.tightvnc.com/download.html * [106]http://www.tightvnc.com/download.html
* [105]http://www.realvnc.com/download-free.html * [107]http://www.realvnc.com/download-free.html
* [106]http://sourceforge.net/projects/cotvnc/ * [108]http://sourceforge.net/projects/cotvnc/
Q-6: How can I see all of x11vnc's command line options and Q-6: How can I see all of x11vnc's command line options and
documentation on how to use them? documentation on how to use them?
Run: x11vnc -help The output is listed [107]here as well. Run: x11vnc -help The output is listed [109]here as well.
Q-7: I don't like typing arcane command line options every time I Q-7: I don't like typing arcane command line options every time I
start x11vnc. What can I do? Is there a config file? start x11vnc. What can I do? Is there a config file? Is there a GUI?
You could create a shell script that calls x11vnc with your options: You could create a shell script that calls x11vnc with your options:
#!/bin/sh #!/bin/sh
...@@ -994,6 +1012,14 @@ display :0 ...@@ -994,6 +1012,14 @@ display :0
At some point this config file support will be expanded. At some point this config file support will be expanded.
As of Dec/2004 in the libvncserver CVS there is now a simple tcl/tk
GUI based on the remote-control functionality that was added. It's not
particulary user-friendly, it just provides a point and click mode to
set all the many x11vnc parameters and obtain help on them. See the
-gui for more info. Examples: "x11vnc ... -gui" and "x11vnc ... -gui
other:0" in the latter case the gui is displayed on other:0 not the X
display x11vnc is polling.
Q-8: Why does x11vnc exit as soon as the VNC viewer disconnects? And Q-8: Why does x11vnc exit as soon as the VNC viewer disconnects? And
why doesn't it allow more than one VNC viewer to connect at the same why doesn't it allow more than one VNC viewer to connect at the same
time? time?
...@@ -1005,10 +1031,12 @@ display :0 ...@@ -1005,10 +1031,12 @@ display :0
-shared option to have x11vnc allow multiple clients to connect -shared option to have x11vnc allow multiple clients to connect
simultaneously. simultaneously.
Recommended additional safety measures include using ssh ([108]see Recommended additional safety measures include using ssh ([110]see
above), stunnel, or a VPN to authenticate and encrypt the viewer above), stunnel, or a VPN to authenticate and encrypt the viewer
connections or to at least use the -rfbauth passwd-file [109]option to connections or to at least use the -rfbauth passwd-file [111]option to
use VNC password protection (or [110]-passwdfile) use VNC password protection (or [112]-passwdfile) It is up to you to
apply these security measures, they will not be done for you
automatically.
Q-9: I have two separate machine displays in front of me, one Windows Q-9: I have two separate machine displays in front of me, one Windows
the other X11: can I use x11vnc in combination with Win2VNC in the other X11: can I use x11vnc in combination with Win2VNC in
...@@ -1020,16 +1048,16 @@ display :0 ...@@ -1020,16 +1048,16 @@ display :0
secondary display (X11). Then start up Win2VNC on the primary display secondary display (X11). Then start up Win2VNC on the primary display
(Windows) referring it to the secondary display. (Windows) referring it to the secondary display.
This will also work X11 to X11 using [111]x2vnc, however you would This will also work X11 to X11 using [113]x2vnc, however you would
probably just want to avoid VNC and use x2x for that. probably just want to avoid VNC and use x2x for that.
For reference, here are some links to Win2VNC-like programs for For reference, here are some links to Win2VNC-like programs for
multiple monitor setups: multiple monitor setups:
* [112]Original Win2VNC * [114]Original Win2VNC
* [113]Enhanced Win2VNC and [114]sourceforge link * [115]Enhanced Win2VNC and [116]sourceforge link
* [115]x2vnc * [117]x2vnc
* [116]x2x also [117]here * [118]x2x also [119]here
* [118]zvnc (MorphOS) * [120]zvnc (MorphOS)
All of them (except x2x) will work with x11vnc. All of them (except x2x) will work with x11vnc.
...@@ -1083,7 +1111,7 @@ display :0 ...@@ -1083,7 +1111,7 @@ display :0
visuals of different color depths: e.g. there are both depth 8 and 24 visuals of different color depths: e.g. there are both depth 8 and 24
visuals available at the same time. visuals available at the same time.
You may want to review the [119]previous question regarding 8 bpp You may want to review the [121]previous question regarding 8 bpp
PseudoColor. PseudoColor.
If that isn't the problem, run xdpyinfo(1) to see what the default If that isn't the problem, run xdpyinfo(1) to see what the default
...@@ -1118,12 +1146,13 @@ TrueColor defdepth 24 ...@@ -1118,12 +1146,13 @@ TrueColor defdepth 24
Another option is if the system with overlay visuals is a Sun system 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 running Solaris you can use the -overlay x11vnc option (Aug/2004) to
have x11vnc use the Solaris XReadScreen(3X11) function to poll the have x11vnc use the Solaris XReadScreen(3X11) function to poll the
"true view" of the whole screen at depth 24 TrueColor. This is useful "true view" of the whole screen at depth 24 TrueColor.This is useful
for Legacy applications (older versions of Cadence CAD apps are for Legacy applications (older versions of Cadence CAD apps are
mentioned by x11vnc users) that require the default depth be 8bpp, or 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 will use a 8bpp visual even if depth 24 visuals are available, and so
the default depth workaround described in the previous paragraph is the default depth workaround described in the previous paragraph is
not sufficient for these apps. not sufficient for these apps. The -overlay mode should also work on
IRIX machines.
Misc. notes on -overlay mode: An amusing by-product of -overlay mode Misc. notes on -overlay mode: An amusing by-product of -overlay mode
is that mouse cursor shape is correct. The -overlay mode may be is that mouse cursor shape is correct. The -overlay mode may be
...@@ -1154,12 +1183,17 @@ TrueColor defdepth 24 ...@@ -1154,12 +1183,17 @@ TrueColor defdepth 24
the desired application window. After clicking, it will print out much the desired application window. After clicking, it will print out much
information, including the window id. Also, the visual and depth of information, including the window id. Also, the visual and depth of
the window printed out is often useful in debugging x11vnc the window printed out is often useful in debugging x11vnc
[120]problems. [122]problems.
When using -id windowid, note that some VNC viewers will have problems When using -id windowid, note that some VNC viewers will have problems
rendering screens that have a width that is not a multiple of 4. Try rendering screens that have a width that is not a multiple of 4. Try
to manually adjust the window width before starting x11vnc -id .... to manually adjust the window width before starting x11vnc -id ....
Also, as of Dec/2004 libvncserver CVS you can use "-id pick" to have
x11vnc run xwininfo(1) for you and after you click the window it
extracts the windowid. Besides "pick" there is also "root" to allow
you to go back to root window when doing remote-control.
Q-14: Why don't menus or other transient windows come up when I am Q-14: Why don't menus or other transient windows come up when I am
using the -id windowid option to view a single application window? using the -id windowid option to view a single application window?
...@@ -1168,12 +1202,14 @@ TrueColor defdepth 24 ...@@ -1168,12 +1202,14 @@ TrueColor defdepth 24
way the image is retrieved depends on some aspects of how the X server way the image is retrieved depends on some aspects of how the X server
maintains the display image data and whether other windows are maintains the display image data and whether other windows are
clipping or obscuring it. See the XGetImage man page for more details. clipping or obscuring it. See the XGetImage man page for more details.
If you disable BackingStore and SaveUnders in the X server you should
be able to see these transient windows.
If things are not working and you still want to do the single window If things are not working and you still want to do the single window
polling, try the -sid windowid option ("shifted" windowid). polling, try the -sid windowid option ("shifted" windowid).
x11vnc is known to crash under both -id and -sid, so both modes are x11vnc is known to crash under both -id and -sid, so both modes are
still experimental. still experimental. Please report any reproducible bugs.
Q-15: Can I use x11vnc to view and interact with an Xterminal (e.g. Q-15: Can I use x11vnc to view and interact with an Xterminal (e.g.
NCD) that is not running UNIX and so x11vnc cannot be run on it NCD) that is not running UNIX and so x11vnc cannot be run on it
...@@ -1206,9 +1242,10 @@ TrueColor defdepth 24 ...@@ -1206,9 +1242,10 @@ TrueColor defdepth 24
If the -forever option has not been supplied, x11vnc will If the -forever option has not been supplied, x11vnc will
automatically exit after the first client disconnects. In general you automatically exit after the first client disconnects. In general you
will have to kill the x11vnc process. This can be done via: "kill will have to kill the x11vnc process (however, see the remote-control
NNNNN" (where NNNNN is the x11vnc process id number found from ps(1)), -R option below). This can be done via: "kill NNNNN" (where NNNNN is
or "pkill x11vnc", or "killall x11vnc" (Linux only, IIRC). the x11vnc process id number found from ps(1)), or "pkill x11vnc", or
"killall x11vnc" (Linux only, IIRC).
If you have not put x11vnc in the background via the -bg option or If you have not put x11vnc in the background via the -bg option or
shell & operator, then simply press Ctrl-C in the shell where x11vnc shell & operator, then simply press Ctrl-C in the shell where x11vnc
...@@ -1221,7 +1258,29 @@ TrueColor defdepth 24 ...@@ -1221,7 +1258,29 @@ TrueColor defdepth 24
Ctrl, Shift, and Alt. Alternatively, the -clear_mods and -clear_keys Ctrl, Shift, and Alt. Alternatively, the -clear_mods and -clear_keys
options can be used to release pressed keys at startup and exit. options can be used to release pressed keys at startup and exit.
Q-18: Can I limit which machines incoming VNC clients can connect As of Dec/2004 in the libvncserver CVS there is a remote control
feature. It can change a huge amount of things on the fly: see the
-remote and -query options. To shut down the running x11vnc server
just type "x11vnc -R stop". To disconnect all clients do "x11vnc -R
disconnect:all", etc.
Q-18: Can I change settings in x11vnc without having to restart it? Is
there a way to remote control it?
Look at the -remote (same as -R) and -query (same as -Q) options added
in the Dec/2004 libvncserver CVS. They allow nearly everything to be
changed dynamically and settings to be queried. Examples: "x11vnc -R
shared", "x11vnc -R forever", "x11vnc -R scale:3/4", "x11vnc -Q
modtweak", "x11vnc -R stop", "x11vnc -R disconnect:all", etc.. These
commands do not start a x11vnc server, but rather communicate with one
that is already running. The X display (VNC_CONNECT property) is used
as the communication channel, so the X permissions and DISPLAY must be
set up correctly.
There is also a simple tcl/tk gui based on this remote control
mechanism. See the -gui option for more info.
Q-19: Can I limit which machines incoming VNC clients can connect
from? from?
Yes, look at the -allow and -localhost options to limit connections by Yes, look at the -allow and -localhost options to limit connections by
...@@ -1231,12 +1290,13 @@ TrueColor defdepth 24 ...@@ -1231,12 +1290,13 @@ TrueColor defdepth 24
for those two hosts or for those two hosts or
x11vnc -allow 192.168.0. x11vnc -allow 192.168.0.
for a subnet. Note that -localhost is the same as "-allow 127.0.0.1" for a subnet. For individual hosts you can use the hostname instead of
the IP number. Note that -localhost is the same as "-allow 127.0.0.1"
For more control, build libvncserver with libwrap support For more control, build libvncserver with libwrap support
(tcp_wrappers) and then use /etc/hosts.allow. (tcp_wrappers) and then use /etc/hosts.allow.
Q-19: How do I build x11vnc/libvncserver with libwrap (tcp_wrappers) Q-20: How do I build x11vnc/libvncserver with libwrap (tcp_wrappers)
support? support?
Here is one way to pass this information to the configure script: Here is one way to pass this information to the configure script:
...@@ -1251,11 +1311,11 @@ TrueColor defdepth 24 ...@@ -1251,11 +1311,11 @@ TrueColor defdepth 24
is "vnc", e.g.: is "vnc", e.g.:
vnc: 192.168.100.3 .example.com vnc: 192.168.100.3 .example.com
Note that if you run x11vnc out of [121]inetd you do not need to build Note that if you run x11vnc out of [123]inetd you do not need to build
x11vnc with libwrap support because the /usr/sbin/tcpd reference in x11vnc with libwrap support because the /usr/sbin/tcpd reference in
/etc/inetd.conf handles the tcp_wrappers stuff. /etc/inetd.conf handles the tcp_wrappers stuff.
Q-20: Can I prompt the user at the local X display whether the Q-21: Can I prompt the user at the local X display whether the
incoming VNC client should be accepted or not? Can I decide to make incoming VNC client should be accepted or not? Can I decide to make
some clients view-only? How about running an arbitrary program to make some clients view-only? How about running an arbitrary program to make
the decisions? the decisions?
...@@ -1273,7 +1333,7 @@ TrueColor defdepth 24 ...@@ -1273,7 +1333,7 @@ TrueColor defdepth 24
of the X11 display being polled. Also, RFB_X11VNC_PID is set to the of the X11 display being polled. Also, RFB_X11VNC_PID is set to the
x11vnc process id (e.g. in case you decided to kill it), RFB_CLIENT_ID x11vnc process id (e.g. in case you decided to kill it), RFB_CLIENT_ID
will be an id number, and RFB_CLIENT_COUNT the number of other clients will be an id number, and RFB_CLIENT_COUNT the number of other clients
currently connected. currently connected. RFB_MODE will be "accept".
As a special case, "-accept popup" will instruct x11vnc to create its As a special case, "-accept popup" will instruct x11vnc to create its
own simple popup window. To accept the client press "y" or click mouse own simple popup window. To accept the client press "y" or click mouse
...@@ -1295,7 +1355,7 @@ TrueColor defdepth 24 ...@@ -1295,7 +1355,7 @@ TrueColor defdepth 24
program to prompt the user whether the client should be accepted or program to prompt the user whether the client should be accepted or
not. This requires that you have xmessage installed and available via not. This requires that you have xmessage installed and available via
PATH. In case it is not already on your system, the xmessage program PATH. In case it is not already on your system, the xmessage program
is available at [122]ftp://ftp.x.org/ is available at [124]ftp://ftp.x.org/
To include view-only decisions for the external commands, prefix the To include view-only decisions for the external commands, prefix the
command something like this: "yes:0,no:*,view:3 mycommand ..." This command something like this: "yes:0,no:*,view:3 mycommand ..." This
...@@ -1334,7 +1394,7 @@ elif [ $rc = 4 ]; then ...@@ -1334,7 +1394,7 @@ elif [ $rc = 4 ]; then
fi fi
exit 1 exit 1
Stefan Radman has written a nice dtksh script [123]dtVncPopup for use Stefan Radman has written a nice dtksh script [125]dtVncPopup for use
in CDE environments to do the same sort of thing. Information on how in CDE environments to do the same sort of thing. Information on how
to use it is found at the top of the file. He encourages you to to use it is found at the top of the file. He encourages you to
provide feedback to him to help improve the script. provide feedback to him to help improve the script.
...@@ -1347,9 +1407,10 @@ exit 1 ...@@ -1347,9 +1407,10 @@ exit 1
To run a command when a client disconnects, use the "-gone command" To run a command when a client disconnects, use the "-gone command"
option. This is for the user's convenience only: the return code of option. This is for the user's convenience only: the return code of
the command is not interpreted by x11vnc. The same environment the command is not interpreted by x11vnc. The same environment
variables are set as in "-accept command" variables are set as in "-accept command" (except that RFB_MODE will
be "gone").
Q-21: How do I create a VNC password for use with x11vnc? Q-22: How do I create a VNC password for use with x11vnc?
You may already have one in $HOME/.vnc/passwd if you have used, say, You may already have one in $HOME/.vnc/passwd if you have used, say,
the vncserver program from the regular RealVNC or TightVNC packages the vncserver program from the regular RealVNC or TightVNC packages
...@@ -1369,24 +1430,24 @@ exit 1 ...@@ -1369,24 +1430,24 @@ exit 1
out for the command winding up in your shell's history file (history out for the command winding up in your shell's history file (history
-c is often a way to clear it). -c is often a way to clear it).
x11vnc also has the [124]-passwdfile and -passwd/-viewpasswd plain x11vnc also has the [126]-passwdfile and -passwd/-viewpasswd plain
text (i.e. not obscured like the -rfbauth VNC passwords) password text (i.e. not obscured like the -rfbauth VNC passwords) password
options. options.
Q-22: How can I tunnel my connection to x11vnc via an encrypted SSH Q-23: How can I tunnel my connection to x11vnc via an encrypted SSH
channel between two Unix machines? channel between two Unix machines?
See the description earlier on this page on [125]how to tunnel VNC via See the description earlier on this page on [127]how to tunnel VNC via
SSH from Unix to Unix. A number of ways are described along with some SSH from Unix to Unix. A number of ways are described along with some
issues you may encounter. issues you may encounter.
Other secure encrypted methods exists, e.g. stunnel, IPSEC, various Other secure encrypted methods exists, e.g. stunnel, IPSEC, various
VPNs, etc. VPNs, etc.
Q-23: How can I tunnel my connection to x11vnc via an encrypted SSH Q-24: How can I tunnel my connection to x11vnc via an encrypted SSH
channel from Windows using an SSH client like Putty? channel from Windows using an SSH client like Putty?
[126]Above we described how to tunnel VNC via SSH from Unix to Unix, [128]Above we described how to tunnel VNC via SSH from Unix to Unix,
you may want to review it. To do this from Windows using Putty it you may want to review it. To do this from Windows using Putty it
would go something like this: would go something like this:
* In the Putty dialog window under 'Session' enter the hostname or * In the Putty dialog window under 'Session' enter the hostname or
...@@ -1419,14 +1480,14 @@ exit 1 ...@@ -1419,14 +1480,14 @@ exit 1
you'll need to do a second login (ssh or rsh) to the workstation you'll need to do a second login (ssh or rsh) to the workstation
machine 'otherhost' and then start up x11vnc on it. machine 'otherhost' and then start up x11vnc on it.
As discussed [127]above another option is to first start the VNC As discussed [129]above another option is to first start the VNC
viewer in "listen" mode, and then launch x11vnc with the "-connection viewer in "listen" mode, and then launch x11vnc with the "-connection
localhost" option to establish the reverse connection. In this case a localhost" option to establish the reverse connection. In this case a
Remote port redirection (not Local) is needed for port 5500 instead of Remote port redirection (not Local) is needed for port 5500 instead of
5900 (i.e. 'Source port: 5500' and 'Destination: localhost:5500' for 5900 (i.e. 'Source port: 5500' and 'Destination: localhost:5500' for
a Remote connection). a Remote connection).
Q-24: Does x11vnc support Unix usernames and passwords? Can I further Q-25: Does x11vnc support Unix usernames and passwords? Can I further
limit the set of Unix usernames who can connect to the VNC desktop? limit the set of Unix usernames who can connect to the VNC desktop?
Until the VNC protocol and libvncserver support this things will be Until the VNC protocol and libvncserver support this things will be
...@@ -1440,7 +1501,7 @@ exit 1 ...@@ -1440,7 +1501,7 @@ exit 1
connection to make it appear to emanate from the local machine. As connection to make it appear to emanate from the local machine. As
discussed above, ssh is useful for this: ssh -l username -L discussed above, ssh is useful for this: ssh -l username -L
5900:localhost:5900 hostname ... See the ssh wrapper scripts mentioned 5900:localhost:5900 hostname ... See the ssh wrapper scripts mentioned
[128]elsewhere on this page. Of course a malicious user could allow [130]elsewhere on this page. Of course a malicious user could allow
other users to get in through his channel, but that is a problem with other users to get in through his channel, but that is a problem with
every method. Another thing to watch out for is a malicious user on every method. Another thing to watch out for is a malicious user on
the viewer side (where ssh is running) trying to sneak in through the the viewer side (where ssh is running) trying to sneak in through the
...@@ -1477,7 +1538,7 @@ exit 1 # reject it ...@@ -1477,7 +1538,7 @@ exit 1 # reject it
For this to work with ssh port redirection, the ssh option For this to work with ssh port redirection, the ssh option
UsePrivilegeSeparation must be enabled. UsePrivilegeSeparation must be enabled.
Q-25: Can I have two passwords for VNC viewers, one for full access Q-26: Can I have two passwords for VNC viewers, one for full access
and the other for view-only access to the display? and the other for view-only access to the display?
Yes, as of May/2004 in the libvncserver CVS there is the -viewpasswd Yes, as of May/2004 in the libvncserver CVS there is the -viewpasswd
...@@ -1503,7 +1564,7 @@ exit 1 # reject it ...@@ -1503,7 +1564,7 @@ exit 1 # reject it
plain text passwords from $HOME/.vnc/passwd since it is very plain text passwords from $HOME/.vnc/passwd since it is very
straight-forward to work out what to do from the VNC source code. straight-forward to work out what to do from the VNC source code.
Q-26: I use a screen-lock when I leave my workstation (e.g. Q-27: I use a screen-lock when I leave my workstation (e.g.
xscreensaver or xlock). When I remotely access my workstation desktop xscreensaver or xlock). When I remotely access my workstation desktop
via x11vnc I can unlock the desktop fine, but I am worried people will via x11vnc I can unlock the desktop fine, but I am worried people will
see my activities on the physical monitor. What can I do to prevent see my activities on the physical monitor. What can I do to prevent
...@@ -1516,7 +1577,7 @@ exit 1 # reject it ...@@ -1516,7 +1577,7 @@ exit 1 # reject it
In any event, as of Jun/2004 there is an experimental utility to make In any event, as of Jun/2004 there is an experimental utility to make
it more difficult for nosey people to see your x11vnc activities. The it more difficult for nosey people to see your x11vnc activities. The
source for it is [129]blockdpy.c The idea behind it is simple (but source for it is [131]blockdpy.c The idea behind it is simple (but
obviously not bulletproof): when a VNC client attaches to x11vnc put obviously not bulletproof): when a VNC client attaches to x11vnc put
the display monitor in the DPMS "off" state, if the DPMS state ever the display monitor in the DPMS "off" state, if the DPMS state ever
changes immediately start up the screen-lock program. The x11vnc user changes immediately start up the screen-lock program. The x11vnc user
...@@ -1537,7 +1598,7 @@ exit 1 # reject it ...@@ -1537,7 +1598,7 @@ exit 1 # reject it
re-lock the screen before disconnecting!). Instructions can be found re-lock the screen before disconnecting!). Instructions can be found
in the source code for the utility at the above link. in the source code for the utility at the above link.
Q-27: Can I have x11vnc automatically lock the screen when I Q-28: Can I have x11vnc automatically lock the screen when I
disconnect the VNC viewer? disconnect the VNC viewer?
Yes, a user mentions he uses the -gone option under CDE to run a Yes, a user mentions he uses the -gone option under CDE to run a
...@@ -1549,7 +1610,7 @@ exit 1 # reject it ...@@ -1549,7 +1610,7 @@ exit 1 # reject it
x11vnc -display :0.0 -forever -gone 'kdesktop_lock' x11vnc -display :0.0 -forever -gone 'kdesktop_lock'
x11vnc -display :0.0 -forever -gone 'xlock &' x11vnc -display :0.0 -forever -gone 'xlock &'
Q-28: Are reverse connections (i.e. the VNC server connecting to the Q-29: Are reverse connections (i.e. the VNC server connecting to the
VNC viewer) using "vncviewer -listen" and vncconnect(1) supported? VNC viewer) using "vncviewer -listen" and vncconnect(1) supported?
As of Mar/2004 in the libvncserver CVS x11vnc supports reverse As of Mar/2004 in the libvncserver CVS x11vnc supports reverse
...@@ -1562,12 +1623,12 @@ exit 1 # reject it ...@@ -1562,12 +1623,12 @@ exit 1 # reject it
periodically (about once a second) for new hosts to connect to. periodically (about once a second) for new hosts to connect to.
To use the vncconnect(1) program (from the core VNC package at To use the vncconnect(1) program (from the core VNC package at
www.realvnc.com) specify the -vncconnect option to x11vnc. www.realvnc.com) specify the -vncconnect option to x11vnc (Note: as of
vncconnect(1) must be pointed to the same X11 DISPLAY as x11vnc (since Dec/2004 -vncconnect is now the default). vncconnect(1) must be
it uses X properties to communicate with x11vnc). If you do not have pointed to the same X11 DISPLAY as x11vnc (since it uses X properties
or do not want to get the vncconnect(1) program, the following script to communicate with x11vnc). If you do not have or do not want to get
(named "Vncconnect") may work if your xprop(1) supports the -set the vncconnect(1) program, the following script (named "Vncconnect")
option: may work if your xprop(1) supports the -set option:
#!/bin/sh #!/bin/sh
# usage: Vncconnect <host> # usage: Vncconnect <host>
# Vncconnect <host:port> # Vncconnect <host:port>
...@@ -1575,7 +1636,7 @@ exit 1 # reject it ...@@ -1575,7 +1636,7 @@ exit 1 # reject it
# #
xprop -root -f VNC_CONNECT 8s -set VNC_CONNECT "$1" xprop -root -f VNC_CONNECT 8s -set VNC_CONNECT "$1"
Q-29: Sometimes when a VNC viewer dies abruptly, x11vnc also dies with Q-30: Sometimes when a VNC viewer dies abruptly, x11vnc also dies with
the error message like: "Broken pipe". I'm using the -forever mode and the error message like: "Broken pipe". I'm using the -forever mode and
I want x11vnc to keep running. I want x11vnc to keep running.
...@@ -1583,12 +1644,12 @@ xprop -root -f VNC_CONNECT 8s -set VNC_CONNECT "$1" ...@@ -1583,12 +1644,12 @@ xprop -root -f VNC_CONNECT 8s -set VNC_CONNECT "$1"
So if a viewer client terminates abruptly, libvncserver will notice on So if a viewer client terminates abruptly, libvncserver will notice on
the next I/O operation and will close the connection and continue on. the next I/O operation and will close the connection and continue on.
Currently (Apr/2004) the above fix only works for BSD signal systems As of Apr/2004 the above fix only works for BSD signal systems (Linux,
(Linux, FreeBSD, ...) For SYSV systems there is a workaround in my FreeBSD, ...) For SYSV systems there is a workaround in my
[130]x11vnc.c file. It also has an option -sigpipe exit to have x11vnc [132]x11vnc.c file. It also has an option -sigpipe exit to have x11vnc
clean up and exit upon receiving SIGPIPE. clean up and exit upon receiving SIGPIPE.
Q-30: How can I use x11vnc to connect to an X login screen like xdm, Q-31: How can I use x11vnc to connect to an X login screen like xdm,
GNOME gdm, KDE kdm, or CDE dtlogin? (i.e. nobody is logged into an X GNOME gdm, KDE kdm, or CDE dtlogin? (i.e. nobody is logged into an X
session yet). session yet).
...@@ -1654,7 +1715,7 @@ xprop -root -f VNC_CONNECT 8s -set VNC_CONNECT "$1" ...@@ -1654,7 +1715,7 @@ xprop -root -f VNC_CONNECT 8s -set VNC_CONNECT "$1"
If you do not want to deal with the display manager startup scripts, If you do not want to deal with the display manager startup scripts,
here is a kludgey script that can be run manually or out of a boot here is a kludgey script that can be run manually or out of a boot
file like rc.local. [131]x11vnc_loop It will need some local file like rc.local. [133]x11vnc_loop It will need some local
customization before running. Because the XAUTHORITY auth file must be customization before running. Because the XAUTHORITY auth file must be
guessed by this script, use of the display manager script above is guessed by this script, use of the display manager script above is
preferred. preferred.
...@@ -1677,7 +1738,7 @@ xprop -root -f VNC_CONNECT 8s -set VNC_CONNECT "$1" ...@@ -1677,7 +1738,7 @@ xprop -root -f VNC_CONNECT 8s -set VNC_CONNECT "$1"
See xauth(1) manpage for full details on how to transfer an See xauth(1) manpage for full details on how to transfer an
MIT-MAGIC-COOKIE between machines and displays. MIT-MAGIC-COOKIE between machines and displays.
Q-31: Can I run x11vnc out of inetd(1)? Q-32: Can I run x11vnc out of inetd(1)?
Yes, perhaps a line something like this in /etc/inetd.conf will do it Yes, perhaps a line something like this in /etc/inetd.conf will do it
for you: for you:
...@@ -1723,7 +1784,7 @@ mp/x11vnc_sh.log ...@@ -1723,7 +1784,7 @@ mp/x11vnc_sh.log
connecting to it. Always use a VNC password to further protect against connecting to it. Always use a VNC password to further protect against
unwanted access. unwanted access.
Q-32: How do I make x11vnc work with the Java VNC viewer applet in a Q-33: How do I make x11vnc work with the Java VNC viewer applet in a
web browser? web browser?
To have x11vnc serve up a Java VNC viewer applet to any web browsers To have x11vnc serve up a Java VNC viewer applet to any web browsers
...@@ -1750,7 +1811,7 @@ mp/x11vnc_sh.log ...@@ -1750,7 +1811,7 @@ mp/x11vnc_sh.log
entirely from the viewer-side by having the jar file there and using entirely from the viewer-side by having the jar file there and using
either the java or appletviewer commands to run the program. either the java or appletviewer commands to run the program.
Q-33: Why isn't the mouse cursor shape (the little icon shape where Q-34: Why isn't the mouse cursor shape (the little icon shape where
the mouse pointer is) correct as I move from window to window? the mouse pointer is) correct as I move from window to window?
As mentioned above, the X11 mouse cursor shape (i.e. little picture: As mentioned above, the X11 mouse cursor shape (i.e. little picture:
...@@ -1774,13 +1835,18 @@ mp/x11vnc_sh.log ...@@ -1774,13 +1835,18 @@ mp/x11vnc_sh.log
Also note that as of Aug/2004 in the libvncserver CVS, on Solaris 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 using the SUN_OVL overlay extension, x11vnc can show the correct mouse
cursor when the -overlay is also supplied. (-overlay has some other cursor when the -overlay is also supplied. (-overlay has some other
problems however, and can be slower). Plans are in the works to use problems however, and can be slower). Also as of Dec/2004 in
XFIXES for this on XFree86, Xorg, and Xsun. libvncserver CVS XFIXES X extension support has been added to allow
exact extraction of the mouse cursor shape. This is the preferred way
Q-34: Why does the mouse arrow just stay in one corner in my of viewing the cursor shape, it is available on recent Linux Xorg
based distros and Solaris 10 express (on Solaris you will need to add
"-L /usr/openwin/sfw/lib -R /usr/openwin/sfw/lib" to LDFLAGS for
configure to enable it).
Q-35: Why does the mouse arrow just stay in one corner in my
vncviewer, whereas my cursor (that does move) is just a dot? vncviewer, whereas my cursor (that does move) is just a dot?
This default takes advantage of a [132]tightvnc extension that allows This default takes advantage of a [134]tightvnc extension that allows
specifying a cursor image for the local VNC viewer. You may disable it specifying a cursor image for the local VNC viewer. You may disable it
with the -nocursor option to x11vnc if your viewer does not have this with the -nocursor option to x11vnc if your viewer does not have this
extension. extension.
...@@ -1789,7 +1855,7 @@ mp/x11vnc_sh.log ...@@ -1789,7 +1855,7 @@ mp/x11vnc_sh.log
default for non-tightvnc viewers will be to draw the moving cursor default for non-tightvnc viewers will be to draw the moving cursor
into the framebuffer. This can also be disabled via -nocursor. into the framebuffer. This can also be disabled via -nocursor.
Q-35: Can I take advantage of the TightVNC extension to the VNC Q-36: Can I take advantage of the TightVNC extension to the VNC
protocol where Cursor Positions Updates are sent back to all connected protocol where Cursor Positions Updates are sent back to all connected
clients (i.e. passive viewers can see the mouse cursor being moved clients (i.e. passive viewers can see the mouse cursor being moved
around by another viewer)? around by another viewer)?
...@@ -1800,7 +1866,7 @@ mp/x11vnc_sh.log ...@@ -1800,7 +1866,7 @@ mp/x11vnc_sh.log
libvncserver CVS -cursorpos is the default. See -nocursorpos and libvncserver CVS -cursorpos is the default. See -nocursorpos and
-nocursorshape. -nocursorshape.
Q-36: Is it possible to swap the mouse buttons (e.g. left-handed Q-37: Is it possible to swap the mouse buttons (e.g. left-handed
operation), or arbitrarily remap them? How about mapping button clicks operation), or arbitrarily remap them? How about mapping button clicks
to keystrokes, e.g. to partially emulate Mouse wheel scrolling? to keystrokes, e.g. to partially emulate Mouse wheel scrolling?
...@@ -1849,7 +1915,7 @@ mp/x11vnc_sh.log ...@@ -1849,7 +1915,7 @@ mp/x11vnc_sh.log
(yes, this is getting a little silly). (yes, this is getting a little silly).
Q-37: When I drag windows around with the mouse or scroll up and down Q-38: When I drag windows around with the mouse or scroll up and down
things really bog down (unless I do the drag in a single, quick things really bog down (unless I do the drag in a single, quick
motion). Is there anything to do to improve things? motion). Is there anything to do to improve things?
...@@ -1865,7 +1931,11 @@ mp/x11vnc_sh.log ...@@ -1865,7 +1931,11 @@ mp/x11vnc_sh.log
some circumstances when you want to see the visual feedback while some circumstances when you want to see the visual feedback while
dragging (e.g. menu traversal or text selection). dragging (e.g. menu traversal or text selection).
Q-38: I have lots of memory, but why does x11vnc fail with shmget: As of Dec/2004 in the libvncserver CVS the -pointer_mode n option was
introduced. n=1 is the -old_pointer. See the -pointer_mode n help for
more info.
Q-39: I have lots of memory, but why does x11vnc fail with shmget:
No space left on device or Minor opcode of failed request: 1 No space left on device or Minor opcode of failed request: 1
(X_ShmAttach)? (X_ShmAttach)?
...@@ -1883,7 +1953,7 @@ mp/x11vnc_sh.log ...@@ -1883,7 +1953,7 @@ mp/x11vnc_sh.log
19/03/2004 10:10:58 error creating tile-row shm for len=4 19/03/2004 10:10:58 error creating tile-row shm for len=4
19/03/2004 10:10:58 reverting to single_copytile mode 19/03/2004 10:10:58 reverting to single_copytile mode
Here is a shell script [133]shm_clear to list and prompt for removal Here is a shell script [135]shm_clear to list and prompt for removal
of your unattached shm segments (attached ones are skipped). I use it of your unattached shm segments (attached ones are skipped). I use it
while debugging x11vnc (I use shm_clear -y to assume "yes" for each while debugging x11vnc (I use shm_clear -y to assume "yes" for each
prompt). If x11vnc is regularly not cleaning up its shm segments, prompt). If x11vnc is regularly not cleaning up its shm segments,
...@@ -1921,10 +1991,10 @@ ied) ...@@ -1921,10 +1991,10 @@ ied)
-fs 1.0 knocks it down to 2). If you are having much trouble with shm -fs 1.0 knocks it down to 2). If you are having much trouble with shm
segments, consider disabling shm completely via the -noshm option. segments, consider disabling shm completely via the -noshm option.
Performance will be somewhat degraded but when done over local machine Performance will be somewhat degraded but when done over local machine
sockets it should be acceptable (see an [134]earlier question sockets it should be acceptable (see an [136]earlier question
discussing -noshm). discussing -noshm).
Q-39: How can I make x11vnc use less system resources? Q-40: How can I make x11vnc use less system resources?
The -nap and "-wait n" (where n is the sleep between polls in The -nap and "-wait n" (where n is the sleep between polls in
milliseconds, the default is 30 or so) option are good places to milliseconds, the default is 30 or so) option are good places to
...@@ -1933,7 +2003,7 @@ ied) ...@@ -1933,7 +2003,7 @@ ied)
-onetile option will use less memory and use fewer shared memory slots -onetile option will use less memory and use fewer shared memory slots
(add -fs 1.0 for one less slot). (add -fs 1.0 for one less slot).
Q-40: How can I make x11vnc use MORE system resources? Q-41: How can I make x11vnc use MORE system resources?
You can try -threads and dial down the wait time (e.g. -wait 1) and You can try -threads and dial down the wait time (e.g. -wait 1) and
possibly dial down -defer as well. Note that if you try to increase possibly dial down -defer as well. Note that if you try to increase
...@@ -1945,7 +2015,7 @@ ied) ...@@ -1945,7 +2015,7 @@ ied)
the x11vnc -id option) can be streamed over a LAN or wireless at a the x11vnc -id option) can be streamed over a LAN or wireless at a
reasonable frame rate. reasonable frame rate.
Q-41: I use x11vnc over a slow link with high latency (e.g. dialup Q-42: I use x11vnc over a slow link with high latency (e.g. dialup
modem), is there anything I can do to speed things up? modem), is there anything I can do to speed things up?
Some things you might want to experiment with (most of which will help Some things you might want to experiment with (most of which will help
...@@ -1969,7 +2039,7 @@ ied) ...@@ -1969,7 +2039,7 @@ ied)
worth it, but could be of use in some situations. worth it, but could be of use in some situations.
VNC viewer parameters: VNC viewer parameters:
* Use a [135]TightVNC enabled viewer! * Use a [137]TightVNC enabled viewer!
* Make sure the tight encoding is being used (look at vncviewer and * Make sure the tight encoding is being used (look at vncviewer and
x11vnc outputs) x11vnc outputs)
* Request 8 bits per pixel using -bgr233 (up to 4X speedup over * Request 8 bits per pixel using -bgr233 (up to 4X speedup over
...@@ -2005,7 +2075,7 @@ ied) ...@@ -2005,7 +2075,7 @@ ied)
* Use -nocursor (repainting the remote cursor position and shape * Use -nocursor (repainting the remote cursor position and shape
takes resources and round trips) takes resources and round trips)
Q-42: How can I get my AltGr and Shift modifiers to work between Q-43: How can I get my AltGr and Shift modifiers to work between
keyboards for different languages? keyboards for different languages?
The option -modtweak should be of some use for this. It is a mode that The option -modtweak should be of some use for this. It is a mode that
...@@ -2017,12 +2087,12 @@ ied) ...@@ -2017,12 +2087,12 @@ ied)
default (use -nomodtweak to get the old behavior). This was done default (use -nomodtweak to get the old behavior). This was done
because it was noticed on newer XFree86 setups even on bland "us" because it was noticed on newer XFree86 setups even on bland "us"
keyboards like "pc104 us" XFree86 included a "ghost" key with both "<" keyboards like "pc104 us" XFree86 included a "ghost" key with both "<"
and ">" it. This key does not exist on the keyboard (see [136]this FAQ and ">" it. This key does not exist on the keyboard (see [138]this FAQ
for more info). Without -modtweak there was then an ambiguity in the for more info). Without -modtweak there was then an ambiguity in the
reverse map keysym => keycode, making it so the "<" symbol could not reverse map keysym => keycode, making it so the "<" symbol could not
be typed. be typed.
Also see the [137]FAQ about the -xkb option for a more powerful method Also see the [139]FAQ about the -xkb option for a more powerful method
of modifier tweaking for use on X servers with the XKEYBOARD of modifier tweaking for use on X servers with the XKEYBOARD
extension. extension.
...@@ -2030,7 +2100,7 @@ ied) ...@@ -2030,7 +2100,7 @@ ied)
-debug_keyboard option prints out much info for every keystroke and so -debug_keyboard option prints out much info for every keystroke and so
can be useful debugging things. can be useful debugging things.
Q-43: When I try to type a "<" (i.e. less than) instead I get ">" Q-44: When I try to type a "<" (i.e. less than) instead I get ">"
(i.e. greater than)! Strangely, typing ">" works OK!! (i.e. greater than)! Strangely, typing ">" works OK!!
Does your keyboard have a single key with both "<" and ">" on it? Even Does your keyboard have a single key with both "<" and ">" on it? Even
...@@ -2083,14 +2153,14 @@ ied) ...@@ -2083,14 +2153,14 @@ ied)
the keysym comma when it comes in from a client (so when Shift is down the keysym comma when it comes in from a client (so when Shift is down
the comma press will yield "<"). the comma press will yield "<").
See also the [138]FAQ about the -xkb option as a possible workaround See also the [140]FAQ about the -xkb option as a possible workaround
using the XKEYBOARD extension. Note that of Jul/2004 in the using the XKEYBOARD extension. Note that of Jul/2004 in the
libvncserver CVS the -modtweak option is now that default. libvncserver CVS the -modtweak option is now that default.
Note that the -debug_keyboard option prints out much info for every Note that the -debug_keyboard option prints out much info for every
keystroke to aid debugging keyboard problems. keystroke to aid debugging keyboard problems.
Q-44: I'm using an "international" keyboard (e.g. German "de", or Q-45: I'm using an "international" keyboard (e.g. German "de", or
Danish "dk") and the -modtweak mode works well if the VNC viewer is Danish "dk") and the -modtweak mode works well if the VNC viewer is
run on a Unix/Linux machine with a similar keyboard. But if I run the run on a Unix/Linux machine with a similar keyboard. But if I run the
VNC viewer on Unix/Linux with a different keyboard (e.g. "us") or VNC viewer on Unix/Linux with a different keyboard (e.g. "us") or
...@@ -2178,7 +2248,7 @@ ied) ...@@ -2178,7 +2248,7 @@ ied)
is received from a VNC viewer, and only after that would is received from a VNC viewer, and only after that would
-add_keysyms, or anything else, come into play. -add_keysyms, or anything else, come into play.
Q-45: When typing I sometimes get double, triple, or more of my Q-46: When typing I sometimes get double, triple, or more of my
keystrokes repeated. I'm sure I only typed them once, what can I do? keystrokes repeated. I'm sure I only typed them once, what can I do?
This may be due to an interplay between your X server's key autorepeat This may be due to an interplay between your X server's key autorepeat
...@@ -2188,6 +2258,8 @@ ied) ...@@ -2188,6 +2258,8 @@ ied)
off" on the Xserver where x11vnc is run (restore via "xset r on") or off" on the Xserver where x11vnc is run (restore via "xset r on") or
use the new (Jul/2004) -norepeat x11vnc option. You will still have use the new (Jul/2004) -norepeat x11vnc option. You will still have
autorepeating because that is taken care of on your VNC viewer side. autorepeating because that is taken care of on your VNC viewer side.
Update: as of Dec/2004 -norepeat is now the default. Use -repeat to
disable it.
Details: suppose you press a key DOWN and it generates changes in Details: suppose you press a key DOWN and it generates changes in
large regions of the screen. The CPU and I/O work x11vnc does for the large regions of the screen. The CPU and I/O work x11vnc does for the
...@@ -2216,7 +2288,7 @@ ied) ...@@ -2216,7 +2288,7 @@ ied)
someone is also working at the physical display and misses his someone is also working at the physical display and misses his
autorepeating. autorepeating.
Q-46: The machine where I run x11vnc has an AltGr key, but the local Q-47: The machine where I run x11vnc has an AltGr key, but the local
machine where I run the VNC viewer does not. Is there a way I can map machine where I run the VNC viewer does not. Is there a way I can map
a local unused key to send an AltGr? How about a Compose key as well? a local unused key to send an AltGr? How about a Compose key as well?
...@@ -2230,7 +2302,7 @@ ied) ...@@ -2230,7 +2302,7 @@ ied)
Super_R-Mode_switch,Menu-Multi_key" or use "-remap filename" to Super_R-Mode_switch,Menu-Multi_key" or use "-remap filename" to
specify remappings from a file. specify remappings from a file.
Q-47: I have a Sun machine I run x11vnc on. Its Sun keyboard has just Q-48: I have a Sun machine I run x11vnc on. Its Sun keyboard has just
one Alt key labelled "Alt" and two Meta keys labelled with little one Alt key labelled "Alt" and two Meta keys labelled with little
diamonds. The machine where I run the VNC viewer only has Alt keys. diamonds. The machine where I run the VNC viewer only has Alt keys.
How can I send a Meta keypress? (e.g. emacs needs this) How can I send a Meta keypress? (e.g. emacs needs this)
...@@ -2247,7 +2319,7 @@ ied) ...@@ -2247,7 +2319,7 @@ ied)
send Alt_L in this case, maybe -remap Super_L-Meta_L would be a better send Alt_L in this case, maybe -remap Super_L-Meta_L would be a better
choice. choice.
Q-48: Can I map a keystroke to a mouse button click on the remote Q-49: Can I map a keystroke to a mouse button click on the remote
machine? machine?
This can be done directly in some X servers using AccessX and This can be done directly in some X servers using AccessX and
...@@ -2269,7 +2341,7 @@ ied) ...@@ -2269,7 +2341,7 @@ ied)
are generated immediately on the x11vnc side. When the key is released are generated immediately on the x11vnc side. When the key is released
(i.e. goes up) no events are generated. (i.e. goes up) no events are generated.
Q-49: The remote display is larger (in number of pixels) than the Q-50: The remote display is larger (in number of pixels) than the
local display I am running the vncviewer on. I don't like the local display I am running the vncviewer on. I don't like the
vncviewer scrollbars, what I can do? vncviewer scrollbars, what I can do?
...@@ -2287,10 +2359,10 @@ ied) ...@@ -2287,10 +2359,10 @@ ied)
There may also be scaling viewers out there (e.g. TightVNC on Windows) There may also be scaling viewers out there (e.g. TightVNC on Windows)
that automatically shrink or expand the remote framebuffer to fit the that automatically shrink or expand the remote framebuffer to fit the
local display. Especially for hand-held devices. See also [139]this local display. Especially for hand-held devices. See also [141]this
FAQ FAQ
Q-50: Does x11vnc support server-side framebuffer scaling? (E.g. to Q-51: Does x11vnc support server-side framebuffer scaling? (E.g. to
make the desktop smaller). make the desktop smaller).
As of Jun/2004 in the libvncserver CVS x11vnc provides basic As of Jun/2004 in the libvncserver CVS x11vnc provides basic
...@@ -2337,7 +2409,7 @@ ied) ...@@ -2337,7 +2409,7 @@ ied)
different scalings listening on separate ports (-rfbport option, different scalings listening on separate ports (-rfbport option,
etc.). etc.).
Q-51: Does x11vnc work with Xinerama? (i.e. multiple monitors joined Q-52: Does x11vnc work with Xinerama? (i.e. multiple monitors joined
together to form one big, single screen). together to form one big, single screen).
Yes, it should generally work because it simply polls the big Yes, it should generally work because it simply polls the big
...@@ -2364,7 +2436,7 @@ ied) ...@@ -2364,7 +2436,7 @@ ied)
function. (This may be due to a bug in the X server for XTEST when function. (This may be due to a bug in the X server for XTEST when
Xinerama is enabled). Xinerama is enabled).
Q-52: Can I use x11vnc on a multi-headed display that is not Xinerama Q-53: Can I use x11vnc on a multi-headed display that is not Xinerama
(i.e. separate screens :0.0, :0.1, ... for each monitor)? (i.e. separate screens :0.0, :0.1, ... for each monitor)?
You can, but it is a little bit awkward: you must start separate You can, but it is a little bit awkward: you must start separate
...@@ -2382,17 +2454,37 @@ ied) ...@@ -2382,17 +2454,37 @@ ied)
Note: if you are running on Solaris 8 or earlier you can easily hit up Note: if you are running on Solaris 8 or earlier you can easily hit up
against the maximum of 6 shm segments per process (for Xsun in this against the maximum of 6 shm segments per process (for Xsun in this
case) from running multiple x11vnc processes. You should modify case) from running multiple x11vnc processes. You should modify
/etc/system as mentioned in another [140]FAQ to increase the limit. It /etc/system as mentioned in another [142]FAQ to increase the limit. It
is probably also a good idea to run with the -onetile option in this is probably also a good idea to run with the -onetile option in this
case (to limit each x11vnc to 3 shm segments), or even -noshm to use case (to limit each x11vnc to 3 shm segments), or even -noshm to use
no shm segments. no shm segments.
Q-53: Why is the view in my VNC viewer completely black? Or why is Q-54: Does x11vnc support the XRANDR (X Resize, Rotate and Reflection)
extension? Whenever I rotate or resize the screen x11vnc just seems to
crash.
As of Dec/2004 in the libvncserver CVS x11vnc supports XRANDR. You
enable it with the -xrandr option to make x11vnc monitor XRANDR events
and also trap X server errors if the screen change occurred in the
middle of an X call like XGetImage. Once it traps the screen change it
will create a new framebuffer using the new screen. If the connected
vnc viewers support the NewFBSize VNC extension (Windows TightVNC
viewer and RealVNC 4.0 windows and Unix viewers do) then the viewer
will automatically resize. Otherwise, the new framebuffer is fit as
best as possible into the original viewer size (portions of the screen
may be clipped, unused, etc).
If you specify "-xrandr newfbsize" then vnc viewers that do not
support NewFBSize will be disconnected before the resize. If you
specify "-xrandr exit" then all will be disconnected and x11vnc will
terminate.
Q-55: Why is the view in my VNC viewer completely black? Or why is
everything flashing around randomly? everything flashing around randomly?
See the next FAQ for a possible explanation. See the next FAQ for a possible explanation.
Q-54: I use Linux Virtual Consoles (VC's) to implement 'Fast User Q-56: I use Linux Virtual Consoles (VC's) to implement 'Fast User
Switching' between users' sessions (e.g. Betty is on Ctrl-Alt-F7, Switching' between users' sessions (e.g. Betty is on Ctrl-Alt-F7,
Bobby is on Ctrl-Alt-F8, and Sid is on Ctrl-Alt-F1: they use those Bobby is on Ctrl-Alt-F8, and Sid is on Ctrl-Alt-F1: they use those
keystrokes to switch between their sessions). How come the view in a keystrokes to switch between their sessions). How come the view in a
...@@ -2419,7 +2511,7 @@ ied) ...@@ -2419,7 +2511,7 @@ ied)
x11vnc can poll it), one can use the switchto(1) command, e.g. x11vnc can poll it), one can use the switchto(1) command, e.g.
"switchto 7" for VC #7. "switchto 7" for VC #7.
Q-55: Does the Clipboard/Selection get transferred between the Q-57: Does the Clipboard/Selection get transferred between the
vncviewer and the X display? vncviewer and the X display?
As of Jan/2004 in the libvncserver CVS x11vnc supports the "CutText" As of Jan/2004 in the libvncserver CVS x11vnc supports the "CutText"
...@@ -2429,7 +2521,7 @@ ied) ...@@ -2429,7 +2521,7 @@ ied)
want the PRIMARY selection to be polled for changes use the -noprimary want the PRIMARY selection to be polled for changes use the -noprimary
option. option.
Q-56: Why don't I hear the "Beeps" in my X session (e.g. when typing Q-58: Why don't I hear the "Beeps" in my X session (e.g. when typing
tput bel in an xterm)? tput bel in an xterm)?
As of Dec/2003 in the libvncserver CVS "Beep" XBell events are tracked As of Dec/2003 in the libvncserver CVS "Beep" XBell events are tracked
...@@ -2441,7 +2533,7 @@ ied) ...@@ -2441,7 +2533,7 @@ ied)
want to hear the audio from the remote applications, consider trying a want to hear the audio from the remote applications, consider trying a
redirector such as esd. redirector such as esd.
Q-57: I am using x11vnc where my local machine has "popup/hidden Q-59: I am using x11vnc where my local machine has "popup/hidden
taskbars" (e.g. GNOME or MacOS X) and the remote display where x11vnc taskbars" (e.g. GNOME or MacOS X) and the remote display where x11vnc
runs also has "popup/hidden taskbars" (e.g. GNOME). When I move the runs also has "popup/hidden taskbars" (e.g. GNOME). When I move the
mouse to the edge of the screen where the popups happen, the taskbars mouse to the edge of the screen where the popups happen, the taskbars
...@@ -2550,51 +2642,53 @@ References ...@@ -2550,51 +2642,53 @@ References
93. http://www.karlrunge.com/x11vnc/index.html#FAQ-55 93. http://www.karlrunge.com/x11vnc/index.html#FAQ-55
94. http://www.karlrunge.com/x11vnc/index.html#FAQ-56 94. http://www.karlrunge.com/x11vnc/index.html#FAQ-56
95. http://www.karlrunge.com/x11vnc/index.html#FAQ-57 95. http://www.karlrunge.com/x11vnc/index.html#FAQ-57
96. http://www.karlrunge.com/x11vnc/index.html#solarisbuilding 96. http://www.karlrunge.com/x11vnc/index.html#FAQ-58
97. http://www.karlrunge.com/x11vnc/index.html#building 97. http://www.karlrunge.com/x11vnc/index.html#FAQ-59
98. http://www.karlrunge.com/x11vnc/index.html#buildfaq 98. http://www.karlrunge.com/x11vnc/index.html#solarisbuilding
99. http://packages.debian.org/x11vnc 99. http://www.karlrunge.com/x11vnc/index.html#building
100. http://www.linuxpackages.net/search_view.php?by=name&name=x11vnc 100. http://www.karlrunge.com/x11vnc/index.html#buildfaq
101. http://dag.wieers.com/packages/x11vnc/ 101. http://packages.debian.org/x11vnc
102. http://www.bell-labs.com/project/wwexptools/packages.html 102. http://www.linuxpackages.net/search_view.php?by=name&name=x11vnc
103. http://www.karlrunge.com/x11vnc/index.html#solarisbuilding 103. http://dag.wieers.com/packages/x11vnc/
104. http://www.tightvnc.com/download.html 104. http://www.bell-labs.com/project/wwexptools/packages.html
105. http://www.realvnc.com/download-free.html 105. http://www.karlrunge.com/x11vnc/index.html#solarisbuilding
106. http://sourceforge.net/projects/cotvnc/ 106. http://www.tightvnc.com/download.html
107. http://www.karlrunge.com/x11vnc/x11vnc_opts.html 107. http://www.realvnc.com/download-free.html
108. http://www.karlrunge.com/x11vnc/index.html#tunnelling 108. http://sourceforge.net/projects/cotvnc/
109. http://www.karlrunge.com/x11vnc/index.html#passwd 109. http://www.karlrunge.com/x11vnc/x11vnc_opts.html
110. http://www.karlrunge.com/x11vnc/index.html#passwdfile 110. http://www.karlrunge.com/x11vnc/index.html#tunnelling
111. http://fredrik.hubbe.net/x2vnc.html 111. http://www.karlrunge.com/x11vnc/index.html#passwd
112. http://www.hubbe.net/~hubbe/win2vnc.html 112. http://www.karlrunge.com/x11vnc/index.html#passwdfile
113. http://www.deboer.gmxhome.de/ 113. http://fredrik.hubbe.net/x2vnc.html
114. http://sourceforge.net/projects/win2vnc/ 114. http://www.hubbe.net/~hubbe/win2vnc.html
115. http://fredrik.hubbe.net/x2vnc.html 115. http://www.deboer.gmxhome.de/
116. http://freshmeat.net/projects/x2x/ 116. http://sourceforge.net/projects/win2vnc/
117. http://ftp.digital.com/pub/Digital/SRC/x2x/ 117. http://fredrik.hubbe.net/x2vnc.html
118. http://zapek.com/software/zvnc/ 118. http://freshmeat.net/projects/x2x/
119. http://www.karlrunge.com/x11vnc/index.html#8bpp 119. http://ftp.digital.com/pub/Digital/SRC/x2x/
120. http://www.karlrunge.com/x11vnc/index.html#overlays 120. http://zapek.com/software/zvnc/
121. http://www.karlrunge.com/x11vnc/index.html#inetd 121. http://www.karlrunge.com/x11vnc/index.html#8bpp
122. ftp://ftp.x.org/ 122. http://www.karlrunge.com/x11vnc/index.html#overlays
123. http://www.karlrunge.com/x11vnc/dtVncPopup 123. http://www.karlrunge.com/x11vnc/index.html#inetd
124. http://www.karlrunge.com/x11vnc/index.html#passwdfile 124. ftp://ftp.x.org/
125. http://www.karlrunge.com/x11vnc/index.html#tunnelling 125. http://www.karlrunge.com/x11vnc/dtVncPopup
126. http://www.karlrunge.com/x11vnc/index.html#tunnelling 126. http://www.karlrunge.com/x11vnc/index.html#passwdfile
127. http://www.karlrunge.com/x11vnc/index.html#tunnelling 127. http://www.karlrunge.com/x11vnc/index.html#tunnelling
128. http://www.karlrunge.com/x11vnc/index.html#tunnelling 128. http://www.karlrunge.com/x11vnc/index.html#tunnelling
129. http://www.karlrunge.com/x11vnc/blockdpy.c 129. http://www.karlrunge.com/x11vnc/index.html#tunnelling
130. http://www.karlrunge.com/x11vnc/x11vnc.c 130. http://www.karlrunge.com/x11vnc/index.html#tunnelling
131. http://www.karlrunge.com/x11vnc/x11vnc_loop 131. http://www.karlrunge.com/x11vnc/blockdpy.c
132. http://www.tightvnc.com/ 132. http://www.karlrunge.com/x11vnc/x11vnc.c
133. http://www.karlrunge.com/x11vnc/shm_clear 133. http://www.karlrunge.com/x11vnc/x11vnc_loop
134. http://www.karlrunge.com/x11vnc/index.html#noshm 134. http://www.tightvnc.com/
135. http://www.tightvnc.com/ 135. http://www.karlrunge.com/x11vnc/shm_clear
136. http://www.karlrunge.com/x11vnc/index.html#greaterless 136. http://www.karlrunge.com/x11vnc/index.html#noshm
137. http://www.karlrunge.com/x11vnc/index.html#xkbmodtweak 137. http://www.tightvnc.com/
138. http://www.karlrunge.com/x11vnc/index.html#xkbmodtweak 138. http://www.karlrunge.com/x11vnc/index.html#greaterless
139. http://www.karlrunge.com/x11vnc/index.html#scaling 139. http://www.karlrunge.com/x11vnc/index.html#xkbmodtweak
140. http://www.karlrunge.com/x11vnc/index.html#solshm 140. http://www.karlrunge.com/x11vnc/index.html#xkbmodtweak
141. http://www.karlrunge.com/x11vnc/index.html#scaling
142. http://www.karlrunge.com/x11vnc/index.html#solshm
======================================================================= =======================================================================
...@@ -2608,7 +2702,7 @@ x11vnc: a VNC server for real X displays ...@@ -2608,7 +2702,7 @@ x11vnc: a VNC server for real X displays
% x11vnc -help % x11vnc -help
x11vnc: allow VNC connections to real X11 displays. 0.6.3pre lastmod: 2004-12-1 x11vnc: allow VNC connections to real X11 displays. 0.6.3pre lastmod: 2004-12-1
6 9
Typical usage is: Typical usage is:
...@@ -2699,7 +2793,7 @@ Options: ...@@ -2699,7 +2793,7 @@ Options:
cursor shape is exactly correct in this mode. cursor shape is exactly correct in this mode.
Use -overlay as a workaround for situations like these: Use -overlay as a workaround for situations like these:
Some legacy applications require the default visual Some legacy applications require the default visual to
be 8bpp (8+24), or they will use 8bpp PseudoColor even be 8bpp (8+24), or they will use 8bpp PseudoColor even
when the default visual is depth 24 TrueColor (24+8). when the default visual is depth 24 TrueColor (24+8).
In these cases colors in some windows will be messed In these cases colors in some windows will be messed
...@@ -3074,25 +3168,33 @@ Options: ...@@ -3074,25 +3168,33 @@ Options:
initial state of the modifier is ignored and not reset) initial state of the modifier is ignored and not reset)
To include button events use "Button1", ... etc. To include button events use "Button1", ... etc.
-nodragging Do not update the display during mouse dragging events -nodragging Do not update the display during mouse dragging
(mouse motion with a button held down). Greatly events (mouse motion with a button held down).
improves response on slow setups, but you lose all Greatly improves response on slow setups, but you lose
visual feedback for drags, text selection, and some all visual feedback for drags, text selection, and some
menu traversals. menu traversals. It overrides any -pointer_mode setting
(think of it as pointer_mode 0)
-pointer_mode n Various pointer update schemes. The problem is pointer -pointer_mode n Various pointer update schemes. The problem is pointer
motion can cause rapid changes on the screen, e.g. a motion can cause rapid changes on the screen, e.g. a
window drag. Neither x11vnc nor the bandwidth to the window drag. Neither x11vnc's screen polling nor the
vncviewers can keep up these rapid screen changes: bandwidth to the vncviewers can keep up these rapid
everything bogs down when dragging or scrolling. screen changes: everything bogs down when dragging
Note that most video h/w is optimized for writing, not or scrolling. Note that most video h/w is optimized
reading (a 50X rate difference is possible) and x11vnc for writing, not reading (a 50X rate difference is
is reading all the time. So a scheme has to be used to possible) and x11vnc is reading all the time. So a
"eat" much of that pointer input before re-polling the scheme has to be used to "eat" much of that pointer
screen. n can be 1 to 4. n=1 was the original scheme input before re-polling the screen. n can be 1 to 4.
used to about Jan 2004. n=2 is an improved scheme.
n=3 is basically a dynamic -nodragging mode: it detects n=1 was the original scheme used to about Jan 2004: it
if the mouse drag motion has paused and refreshes basically just skips -input_skip pointer events before
the display. n=4 is TBD. The default n is 2. repolling the screen. n=2 is an improved scheme:
by watching the current rate it tries to detect if
it should try to "eat" more pointer events. n=3 is
basically a dynamic -nodragging mode: it detects if the
mouse drag motion has paused and refreshes the display.
n=4 is TBD, it will try measure screen read and client
write rates and try to insert "frames" between the
on/off states of mode 3. The default n is 2.
-input_skip n For the pointer handling when non-threaded: try to -input_skip n For the pointer handling when non-threaded: try to
read n user input events before scanning display. n < 0 read n user input events before scanning display. n < 0
means to act as though there is always user input. means to act as though there is always user input.
...@@ -3133,9 +3235,10 @@ Options: ...@@ -3133,9 +3235,10 @@ Options:
-gui [gui-opts] Start up a simple tcl/tk gui based on the the remote -gui [gui-opts] Start up a simple tcl/tk gui based on the the remote
control options -remote/-query described below. control options -remote/-query described below.
"gui-opts" is not required: the default is to start Requires the "wish" program to be installed on the
up both the gui and x11vnc with the gui showing up on machine. "gui-opts" is not required: the default is
the X display in the environment variable DISPLAY. to start up both the gui and x11vnc with the gui showing
up on the X display in the environment variable DISPLAY.
"gui-opts" can be a comma separated list of items. "gui-opts" can be a comma separated list of items.
Currently there are only two types of items: 1) a gui Currently there are only two types of items: 1) a gui
...@@ -3146,14 +3249,14 @@ Options: ...@@ -3146,14 +3249,14 @@ Options:
but instead just try to connect to an existing x11vnc but instead just try to connect to an existing x11vnc
process. "wait" means just start the gui and nothing process. "wait" means just start the gui and nothing
else (you will later instruct the gui to start x11vnc else (you will later instruct the gui to start x11vnc
or connect to one.) or connect to an existing one.)
Note the possible confusion regarding the potentially Note the possible confusion regarding the potentially
two X displays: x11vnc polls one, but you may want the two different X displays: x11vnc polls one, but you
gui to appear on another. For example, if you ssh in may want the gui to appear on another. For example, if
and x11vnc is not running yet you may want the gui to you ssh in and x11vnc is not running yet you may want
come back to you via your ssh redirected X display the gui to come back to you via your ssh redirected X
(e.g. localhost:10). display (e.g. localhost:10).
Examples: "x11vnc -gui", "x11vnc -gui localhost:10", Examples: "x11vnc -gui", "x11vnc -gui localhost:10",
"x11vnc -gui :10", "x11vnc -gui wait,:10", "x11vnc -gui :10", "x11vnc -gui wait,:10",
...@@ -3211,8 +3314,9 @@ Options: ...@@ -3211,8 +3314,9 @@ Options:
could miss it). Same as "zero", also could miss it). Same as "zero", also
"zero:x1,y1,x2,y2" for a rectangle. "zero:x1,y1,x2,y2" for a rectangle.
refresh send the entire fb to all clients. refresh send the entire fb to all clients.
reset recreate the fb, polling mem, etc. reset recreate the fb, polling memory, etc.
id:windowid set -id window to "windowid" id:windowid set -id window to "windowid". empty
or "root" to go back to root window
sid:windowid set -sid window to "windowid" sid:windowid set -sid window to "windowid"
flashcmap enable -flashcmap mode. flashcmap enable -flashcmap mode.
noflashcmap disable -flashcmap mode. noflashcmap disable -flashcmap mode.
...@@ -3313,7 +3417,7 @@ Options: ...@@ -3313,7 +3417,7 @@ Options:
nocursorpos enable -nocursorpos mode. nocursorpos enable -nocursorpos mode.
xwarp enable -xwarppointer mode. xwarp enable -xwarppointer mode.
noxwarp disable -xwarppointer mode. noxwarp disable -xwarppointer mode.
buttonmap:str set -buttonmap "str" empty to disable buttonmap:str set -buttonmap "str", empty to disable
dragging disable -nodragging mode. dragging disable -nodragging mode.
nodragging enable -nodragging mode. nodragging enable -nodragging mode.
pointer_mode n set -pointer_mode to n. pointer_mode n set -pointer_mode to n.
...@@ -3407,6 +3511,25 @@ Options: ...@@ -3407,6 +3511,25 @@ Options:
dpy_x dpy_y rfbport rfbwait rfbauth passwd alwaysshared dpy_x dpy_y rfbport rfbwait rfbauth passwd alwaysshared
dontdisconnect httpdir enablehttpproxy dontdisconnect httpdir enablehttpproxy
-sync By default -remote commands are run asynchronously, that
is, the request is posted and the program immediately
exits. Use -sync to have the program wait for an
acknowledgement from the x11vnc server that command
was processed. On the other hand -query requests are
always processed synchronously because they have wait
for the result.
Also note that if both -remote and -query requests are
supplied on the command line, the -remote is processed
first (synchronously: no need for -sync), and then
the -query request is processed in the normal way.
This allows for a reliable way to see if the -remote
command was processed by querying for any new settings.
Note however that there is timeout of a few seconds so
if the x11vnc takes longer than that to process the
requests the requestor will think that a failure has
taken place.
-noremote Do not process any remote control commands or queries. -noremote Do not process any remote control commands or queries.
A note about security wrt remote control commands. A note about security wrt remote control commands.
......
...@@ -47,6 +47,7 @@ catch {rename send {}} ...@@ -47,6 +47,7 @@ catch {rename send {}}
# Q means it is an action worth querying after running. # Q means it is an action worth querying after running.
# D means it is a good idea to delay a little before querying # D means it is a good idea to delay a little before querying
# (i.e. perhaps it causes x11vnc to do a lot of work, new fb) # (i.e. perhaps it causes x11vnc to do a lot of work, new fb)
# No longer used, -sync is used instead.
# P means the string can be +/- appended/deleted (string may not # P means the string can be +/- appended/deleted (string may not
# be the same after the remote command) # be the same after the remote command)
# G means gui internal item # G means gui internal item
...@@ -839,7 +840,8 @@ proc entry_delete {} { ...@@ -839,7 +840,8 @@ proc entry_delete {} {
# Utilities for remote control and updating vars. # Utilities for remote control and updating vars.
proc push_new_value {item name new {query 1}} { proc push_new_value0 {item name new {query 1}} {
# old way w/o -sync
global menu_var always_update remote_output query_output global menu_var always_update remote_output query_output
global delay_sleep extra_sleep extra_sleep_split global delay_sleep extra_sleep extra_sleep_split
...@@ -953,6 +955,125 @@ proc push_new_value {item name new {query 1}} { ...@@ -953,6 +955,125 @@ proc push_new_value {item name new {query 1}} {
} }
} }
proc push_new_value {item name new {query 1}} {
global menu_var always_update remote_output query_output
global delay_sleep extra_sleep extra_sleep_split
global query_result_list
set debug [in_debug_mode]
set getout 0
set print_getout 0;
set do_query_all 0
set newnew ""
if {$item == "disconnect"} {
set newnew "N/A"
set do_query_all 1
} elseif {$always_update} {
set do_query_all 1
}
if {$item == "remote-cmd"} {
# kludge for arbitrary remote command:
if {[regexp {^Q:} $new]} {
# extra kludge for Q:var to mean -Q var
regsub {^Q:} $new "" new
set qonly 1
} else {
set qonly 0
}
# need to extract item from new:
set qtmp $new
regsub {:.*$} $qtmp "" qtmp
if {$qonly} {
set rargs [list "-Q" "$qtmp"]
set print_getout 1
set qargs ""
} else {
set rargs [list "-R" "$new"]
set qargs ""
}
set getout 1
} elseif {[value_is_string $item]} {
# string var:
set rargs [list "-R" "$name:$new"]
set qargs [list "-Q" "$name"]
} else {
# boolean var:
set rargs [list "-R" "$name"]
set qargs [list "-Q" "$name"]
}
if {! $query && ! $always_update} {
set getout 1
} elseif {$item == "noremote"} {
set getout 1
} elseif {[is_action $item] && ![opt_match Q $item] && $rargs != ""} {
set getout 1
} elseif {[regexp {^(sid|id)$} $item] && ![regexp {^0x} $new]} {
set getout 1
}
set remote_output ""
set query_output ""
if {!$debug} {
append_text "x11vnc $rargs ..."
}
if {$getout} {
set remote_output [run_remote_cmd $rargs]
if {$print_getout} {
append_text "\t$remote_output"
}
append_text "\n"
return
}
if {$do_query_all} {
set all [all_query_vars]
set qargs [list "-Q" $all]
}
set rqargs [concat $rargs $qargs]
set query [run_remote_cmd $rqargs]
set query_output $query
set query_result_list ""
if {$newnew != ""} {
set new $newnew
}
if {![see_if_ok $query $item "$name:$new"]} {
# failed
if {[regexp {^a..=} $query]} {
# but some result came back
# synchronize everything with a 2nd call.
set query_output [query_all 1]
} else {
# server may be dead
if {$item != "ping" && $item != "attach"} {
try_connect
}
}
} else {
# succeeded
# synchronize this variable (or variables)
# for a speedup used the list parsed by see_if_ok.
update_menu_vars "USE_LIST"
if {$do_query_all} {
global all_settings
set all_settings $query
}
}
}
# For updating a string variable. Also used for simple OK/Skip dialogs # For updating a string variable. Also used for simple OK/Skip dialogs
# with entry = 0. # with entry = 0.
proc entry_dialog {item {entry 1}} { proc entry_dialog {item {entry 1}} {
...@@ -1042,14 +1163,25 @@ proc check_var {item} { ...@@ -1042,14 +1163,25 @@ proc check_var {item} {
} }
proc see_if_ok {query item expected} { proc see_if_ok {query item expected} {
global query_result_list
set ok 0 set ok 0
set found "" set found ""
foreach q [split_query $query] {
if {[regexp "^$item:" $q]} { set query_result_list [split_query $query]
foreach q $query_result_list {
# if {[regexp "^$item:" $q]} {
# set found $q
# }
if {[string first "$item:" $q] == 0} {
set found $q set found $q
} }
if {$q == $expected} { if {$q == $expected} {
set ok 1 set ok 1
if {$found != ""} {
break;
}
} }
} }
if {$found == ""} { if {$found == ""} {
...@@ -1076,23 +1208,26 @@ proc see_if_ok {query item expected} { ...@@ -1076,23 +1208,26 @@ proc see_if_ok {query item expected} {
} }
proc update_menu_vars {{query ""}} { proc update_menu_vars {{query ""}} {
global all_settings menu_var global all_settings menu_var query_result_list
set debug [in_debug_mode] set debug [in_debug_mode]
if {$query == ""} { if {$query == "USE_LIST"} {
set qstr $all_settings ;
} elseif {$query == ""} {
set query_result_list [split_query $all_settings]
} else { } else {
set qstr $query set query_result_list [split_query $query]
} }
foreach piece [split_query $qstr] {
foreach piece $query_result_list {
if {[regexp {^([^:][^:]*):(.*)$} $piece m0 item val]} { if {[regexp {^([^:][^:]*):(.*)$} $piece m0 item val]} {
if {[info exists menu_var($item)]} { if {[info exists menu_var($item)]} {
set old $menu_var($item) set old $menu_var($item)
if {$val == "N/A"} { if {$val == "N/A"} {
continue continue
} }
if {$debug} { if {0 && $debug} {
puts "setting menuvar: $item: $old -> $val" puts "setting menuvar: $item: $old -> $val"
} }
set menu_var($item) $val set menu_var($item) $val
...@@ -1127,6 +1262,11 @@ proc clear_all {} { ...@@ -1127,6 +1262,11 @@ proc clear_all {} {
proc all_query_vars {} { proc all_query_vars {} {
global query_ans_list query_aro_list all_settings global query_ans_list query_aro_list all_settings
global cache_all_query_vars
if {$cache_all_query_vars != ""} {
return $cache_all_query_vars
}
set qry "" set qry ""
foreach item $query_ans_list { foreach item $query_ans_list {
...@@ -1143,6 +1283,8 @@ proc all_query_vars {} { ...@@ -1143,6 +1283,8 @@ proc all_query_vars {} {
append qry ",$item" append qry ",$item"
} }
} }
set cache_all_query_vars $qry
return $qry return $qry
} }
...@@ -1151,8 +1293,6 @@ proc query_all {{quiet 0}} { ...@@ -1151,8 +1293,6 @@ proc query_all {{quiet 0}} {
set qry [all_query_vars] set qry [all_query_vars]
#puts "into query_all $quiet"
set qargs [list "-Q" $qry] set qargs [list "-Q" $qry]
set all [run_remote_cmd $qargs] set all [run_remote_cmd $qargs]
...@@ -1282,13 +1422,25 @@ proc do_action {item} { ...@@ -1282,13 +1422,25 @@ proc do_action {item} {
} }
} }
proc ptime {time} {
set usec [lindex [split $time] 0]
set sec [format "%.3f" [expr "$usec / 1000000.0"]]
puts "time: $sec secs."
}
proc do_var {item} { proc do_var {item} {
global connected_to_x11vnc item_cascade menu_var global connected_to_x11vnc item_cascade menu_var
set debug [in_debug_mode]
set string 0 set string 0
if {[is_action $item]} { if {[is_action $item]} {
# Menu item is action: # Menu item is action:
if {$debug} {
ptime [time {do_action $item}]
} else {
do_action $item do_action $item
}
return return
} }
...@@ -1313,8 +1465,12 @@ proc do_var {item} { ...@@ -1313,8 +1465,12 @@ proc do_var {item} {
set new 1 set new 1
} }
if {$connected_to_x11vnc} { if {$connected_to_x11vnc} {
if {$debug} {
ptime [time {push_new_value $item $name $new 1}]
} else {
push_new_value $item $name $new 1 push_new_value $item $name $new 1
} }
}
} }
proc menu_help {item} { proc menu_help {item} {
...@@ -1364,7 +1520,8 @@ proc value_is_bool {item} { ...@@ -1364,7 +1520,8 @@ proc value_is_bool {item} {
} }
} }
proc split_query {query} { proc split_query0 {query} {
# original slower way with regexp/regsub
regsub -all {aro=} $query {ans=} query regsub -all {aro=} $query {ans=} query
set items {} set items {}
while {1} { while {1} {
...@@ -1384,6 +1541,38 @@ proc split_query {query} { ...@@ -1384,6 +1541,38 @@ proc split_query {query} {
return $items return $items
} }
proc split_query {query} {
regsub -all {aro=} $query {ans=} query
set items {}
while {1} {
set n [string first "ans=" $query]
if {$n < 0} {
break
}
set from [expr $n+4]
set m [string first ",ans=" $query]
if {$m < 0} {
set more 0
set item [string range $query $from end]
} else {
set more 1
set to [expr $m-1]
set item [string range $query $from $to]
}
if {$item != ""} {
lappend items $item
}
if {$more} {
incr m
set query [string range $query $m end]
} else {
set query ""
}
}
return $items
}
proc set_x11_display {name} { proc set_x11_display {name} {
global x11_display global x11_display
set x11_display "x11vnc X display: $name" set x11_display "x11vnc X display: $name"
...@@ -1398,6 +1587,7 @@ proc no_x11_display {} { ...@@ -1398,6 +1587,7 @@ proc no_x11_display {} {
proc no_vnc_display {} { proc no_vnc_display {} {
set_vnc_display "(*none*)" set_vnc_display "(*none*)"
} }
proc fetch_displays {} { proc fetch_displays {} {
set qargs [list "-Q" "display,vncdisplay"] set qargs [list "-Q" "display,vncdisplay"]
...@@ -1899,6 +2089,8 @@ proc get_start_x11vnc_cmd {} { ...@@ -1899,6 +2089,8 @@ proc get_start_x11vnc_cmd {} {
lappend cmd $x11vnc_prog lappend cmd $x11vnc_prog
set saw_id 0
foreach item [lsort [array names menu_var]] { foreach item [lsort [array names menu_var]] {
if {![active_when_starting $item]} { if {![active_when_starting $item]} {
continue continue
...@@ -1906,6 +2098,27 @@ proc get_start_x11vnc_cmd {} { ...@@ -1906,6 +2098,27 @@ proc get_start_x11vnc_cmd {} {
if {[is_action $item]} { if {[is_action $item]} {
continue continue
} }
if {$item == "debug_gui"} {
continue
}
if {$item == "id" || $item == "sid"} {
set val $menu_var($item);
if {$val == "0x0" || $val == "root"} {
continue
}
}
if {$item == "sid" && $saw_id} {
continue
}
if {$item == "id"} {
set saw_id 1
}
if {$item == "progressive" && $menu_var($item) == "0"} {
continue
}
if {$item == "dontdisconnect" && $menu_var($item) == "-1"} {
continue
}
if {[value_is_bool $item]} { if {[value_is_bool $item]} {
if {[info exists menu_var($item)]} { if {[info exists menu_var($item)]} {
...@@ -1917,7 +2130,11 @@ proc get_start_x11vnc_cmd {} { ...@@ -1917,7 +2130,11 @@ proc get_start_x11vnc_cmd {} {
if {[info exists menu_var($item)]} { if {[info exists menu_var($item)]} {
if {$menu_var($item) != "" if {$menu_var($item) != ""
&& $menu_var($item) != $unset_str} { && $menu_var($item) != $unset_str} {
lappend cmd "-$item" set nitem $item
if {$nitem == "screen_blank"} {
set nitem "sb"
}
lappend cmd "-$nitem"
lappend cmd $menu_var($item) lappend cmd $menu_var($item)
} }
} }
...@@ -1996,6 +2213,7 @@ proc run_remote_cmd {opts} { ...@@ -1996,6 +2213,7 @@ proc run_remote_cmd {opts} {
lappend cmd "-display" lappend cmd "-display"
lappend cmd $x11vnc_xdisplay lappend cmd $x11vnc_xdisplay
} }
lappend cmd "-sync"
foreach word $opts { foreach word $opts {
lappend cmd $word lappend cmd $word
} }
...@@ -2011,12 +2229,19 @@ if {0} { ...@@ -2011,12 +2229,19 @@ if {0} {
} }
set output "" set output ""
menus_disable
stop_watch on stop_watch on
catch {set output [eval exec $cmd]} catch {set output [eval exec $cmd]}
stop_watch off stop_watch off
menus_enable
if {$debug} { if {$debug} {
if {[string length $output] > 100} {
set str [string range $output 0 100]
append_text "output: $str ...\n"
} else {
append_text "output: $output\n" append_text "output: $output\n"
} }
}
return $output return $output
} }
...@@ -2083,6 +2308,7 @@ global menu_var unset_str ...@@ -2083,6 +2308,7 @@ global menu_var unset_str
global bfont global bfont
global connected_to_x11vnc global connected_to_x11vnc
global delay_sleep extra_sleep extra_sleep_split global delay_sleep extra_sleep extra_sleep_split
global cache_all_query_vars
set unset_str "(unset)" set unset_str "(unset)"
set connected_to_x11vnc 0 set connected_to_x11vnc 0
...@@ -2093,9 +2319,9 @@ set help_indent 24; ...@@ -2093,9 +2319,9 @@ set help_indent 24;
set reply_xdisplay "" set reply_xdisplay ""
set all_settings "None so far." set all_settings "None so far."
set always_update 1 set always_update 1
set cache_all_query_vars ""
#set delay_sleep 500 # these are no longer used under x11vnc -sync:
#set extra_sleep 1500
set delay_sleep 350 set delay_sleep 350
set extra_sleep 1000 set extra_sleep 1000
set extra_sleep_split 4 set extra_sleep_split 4
......
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
"# Q means it is an action worth querying after running.\n" "# Q means it is an action worth querying after running.\n"
"# D means it is a good idea to delay a little before querying \n" "# D means it is a good idea to delay a little before querying \n"
"# (i.e. perhaps it causes x11vnc to do a lot of work, new fb)\n" "# (i.e. perhaps it causes x11vnc to do a lot of work, new fb)\n"
"# No longer used, -sync is used instead.\n"
"# P means the string can be +/- appended/deleted (string may not\n" "# P means the string can be +/- appended/deleted (string may not\n"
"# be the same after the remote command)\n" "# be the same after the remote command)\n"
"# G means gui internal item\n" "# G means gui internal item\n"
...@@ -845,7 +846,8 @@ ...@@ -845,7 +846,8 @@
"\n" "\n"
"# Utilities for remote control and updating vars.\n" "# Utilities for remote control and updating vars.\n"
"\n" "\n"
"proc push_new_value {item name new {query 1}} {\n" "proc push_new_value0 {item name new {query 1}} {\n"
" # old way w/o -sync\n"
" global menu_var always_update remote_output query_output\n" " global menu_var always_update remote_output query_output\n"
" global delay_sleep extra_sleep extra_sleep_split\n" " global delay_sleep extra_sleep extra_sleep_split\n"
"\n" "\n"
...@@ -959,6 +961,125 @@ ...@@ -959,6 +961,125 @@
" }\n" " }\n"
"}\n" "}\n"
"\n" "\n"
"proc push_new_value {item name new {query 1}} {\n"
" global menu_var always_update remote_output query_output\n"
" global delay_sleep extra_sleep extra_sleep_split\n"
" global query_result_list\n"
"\n"
" set debug [in_debug_mode]\n"
"\n"
" set getout 0\n"
" set print_getout 0;\n"
"\n"
" set do_query_all 0\n"
"\n"
" set newnew \"\"\n"
" if {$item == \"disconnect\"} {\n"
" set newnew \"N/A\"\n"
" set do_query_all 1\n"
" } elseif {$always_update} {\n"
" set do_query_all 1\n"
" }\n"
"\n"
" if {$item == \"remote-cmd\"} {\n"
" # kludge for arbitrary remote command:\n"
" if {[regexp {^Q:} $new]} {\n"
" # extra kludge for Q:var to mean -Q var\n"
" regsub {^Q:} $new \"\" new\n"
" set qonly 1\n"
" } else {\n"
" set qonly 0\n"
" }\n"
" # need to extract item from new:\n"
" set qtmp $new\n"
" regsub {:.*$} $qtmp \"\" qtmp\n"
" if {$qonly} {\n"
" set rargs [list \"-Q\" \"$qtmp\"]\n"
" set print_getout 1\n"
" set qargs \"\"\n"
" } else {\n"
" set rargs [list \"-R\" \"$new\"]\n"
" set qargs \"\"\n"
" }\n"
" set getout 1\n"
"\n"
" } elseif {[value_is_string $item]} {\n"
" # string var:\n"
" set rargs [list \"-R\" \"$name:$new\"]\n"
" set qargs [list \"-Q\" \"$name\"]\n"
" } else {\n"
" # boolean var:\n"
" set rargs [list \"-R\" \"$name\"]\n"
" set qargs [list \"-Q\" \"$name\"]\n"
" }\n"
"\n"
" if {! $query && ! $always_update} {\n"
" set getout 1\n"
" } elseif {$item == \"noremote\"} {\n"
" set getout 1\n"
" } elseif {[is_action $item] && ![opt_match Q $item] && $rargs != \"\"} {\n"
" set getout 1\n"
" } elseif {[regexp {^(sid|id)$} $item] && ![regexp {^0x} $new]} {\n"
" set getout 1\n"
" }\n"
"\n"
" set remote_output \"\"\n"
" set query_output \"\"\n"
"\n"
" if {!$debug} {\n"
" append_text \"x11vnc $rargs ...\"\n"
" }\n"
"\n"
" if {$getout} {\n"
" set remote_output [run_remote_cmd $rargs]\n"
" if {$print_getout} {\n"
" append_text \"\\t$remote_output\"\n"
" }\n"
" append_text \"\\n\"\n"
" return\n"
" }\n"
"\n"
" if {$do_query_all} {\n"
" set all [all_query_vars]\n"
" set qargs [list \"-Q\" $all]\n"
" }\n"
"\n"
" set rqargs [concat $rargs $qargs]\n"
"\n"
" set query [run_remote_cmd $rqargs]\n"
" set query_output $query\n"
"\n"
" set query_result_list \"\"\n"
"\n"
" if {$newnew != \"\"} {\n"
" set new $newnew\n"
" }\n"
"\n"
" if {![see_if_ok $query $item \"$name:$new\"]} {\n"
" # failed\n"
" if {[regexp {^a..=} $query]} {\n"
" # but some result came back\n"
" # synchronize everything with a 2nd call.\n"
" set query_output [query_all 1]\n"
" } else {\n"
" # server may be dead\n"
" if {$item != \"ping\" && $item != \"attach\"} {\n"
" try_connect\n"
" }\n"
" }\n"
" } else {\n"
" # succeeded\n"
" # synchronize this variable (or variables)\n"
" # for a speedup used the list parsed by see_if_ok.\n"
" update_menu_vars \"USE_LIST\"\n"
"\n"
" if {$do_query_all} {\n"
" global all_settings\n"
" set all_settings $query\n"
" }\n"
" }\n"
"}\n"
"\n"
"# For updating a string variable. Also used for simple OK/Skip dialogs\n" "# For updating a string variable. Also used for simple OK/Skip dialogs\n"
"# with entry = 0.\n" "# with entry = 0.\n"
"proc entry_dialog {item {entry 1}} {\n" "proc entry_dialog {item {entry 1}} {\n"
...@@ -1048,14 +1169,25 @@ ...@@ -1048,14 +1169,25 @@
"}\n" "}\n"
"\n" "\n"
"proc see_if_ok {query item expected} {\n" "proc see_if_ok {query item expected} {\n"
" global query_result_list\n"
"\n"
" set ok 0\n" " set ok 0\n"
" set found \"\"\n" " set found \"\"\n"
" foreach q [split_query $query] {\n" "\n"
" if {[regexp \"^$item:\" $q]} {\n" " set query_result_list [split_query $query]\n"
"\n"
" foreach q $query_result_list {\n"
"# if {[regexp \"^$item:\" $q]} {\n"
"# set found $q\n"
"# }\n"
" if {[string first \"$item:\" $q] == 0} {\n"
" set found $q\n" " set found $q\n"
" }\n" " }\n"
" if {$q == $expected} {\n" " if {$q == $expected} {\n"
" set ok 1\n" " set ok 1\n"
" if {$found != \"\"} {\n"
" break;\n"
" }\n"
" }\n" " }\n"
" }\n" " }\n"
" if {$found == \"\"} {\n" " if {$found == \"\"} {\n"
...@@ -1082,23 +1214,26 @@ ...@@ -1082,23 +1214,26 @@
"}\n" "}\n"
"\n" "\n"
"proc update_menu_vars {{query \"\"}} {\n" "proc update_menu_vars {{query \"\"}} {\n"
" global all_settings menu_var\n" " global all_settings menu_var query_result_list\n"
"\n" "\n"
" set debug [in_debug_mode]\n" " set debug [in_debug_mode]\n"
"\n" "\n"
" if {$query == \"\"} {\n" " if {$query == \"USE_LIST\"} {\n"
" set qstr $all_settings\n" " ;\n"
" } elseif {$query == \"\"} {\n"
" set query_result_list [split_query $all_settings]\n"
" } else {\n" " } else {\n"
" set qstr $query\n" " set query_result_list [split_query $query]\n"
" }\n" " }\n"
" foreach piece [split_query $qstr] {\n" "\n"
" foreach piece $query_result_list {\n"
" if {[regexp {^([^:][^:]*):(.*)$} $piece m0 item val]} {\n" " if {[regexp {^([^:][^:]*):(.*)$} $piece m0 item val]} {\n"
" if {[info exists menu_var($item)]} {\n" " if {[info exists menu_var($item)]} {\n"
" set old $menu_var($item)\n" " set old $menu_var($item)\n"
" if {$val == \"N/A\"} {\n" " if {$val == \"N/A\"} {\n"
" continue\n" " continue\n"
" }\n" " }\n"
" if {$debug} {\n" " if {0 && $debug} {\n"
" puts \"setting menuvar: $item: $old -> $val\"\n" " puts \"setting menuvar: $item: $old -> $val\"\n"
" }\n" " }\n"
" set menu_var($item) $val\n" " set menu_var($item) $val\n"
...@@ -1133,7 +1268,12 @@ ...@@ -1133,7 +1268,12 @@
"\n" "\n"
"proc all_query_vars {} {\n" "proc all_query_vars {} {\n"
" global query_ans_list query_aro_list all_settings\n" " global query_ans_list query_aro_list all_settings\n"
" global cache_all_query_vars\n"
" \n" " \n"
" if {$cache_all_query_vars != \"\"} {\n"
" return $cache_all_query_vars\n"
" }\n"
"\n"
" set qry \"\"\n" " set qry \"\"\n"
" foreach item $query_ans_list {\n" " foreach item $query_ans_list {\n"
" if {$qry == \"\"} {\n" " if {$qry == \"\"} {\n"
...@@ -1149,6 +1289,8 @@ ...@@ -1149,6 +1289,8 @@
" append qry \",$item\"\n" " append qry \",$item\"\n"
" }\n" " }\n"
" }\n" " }\n"
" set cache_all_query_vars $qry\n"
"\n"
" return $qry\n" " return $qry\n"
"}\n" "}\n"
"\n" "\n"
...@@ -1157,8 +1299,6 @@ ...@@ -1157,8 +1299,6 @@
"\n" "\n"
" set qry [all_query_vars]\n" " set qry [all_query_vars]\n"
"\n" "\n"
" #puts \"into query_all $quiet\"\n"
"\n"
" set qargs [list \"-Q\" $qry]\n" " set qargs [list \"-Q\" $qry]\n"
" set all [run_remote_cmd $qargs]\n" " set all [run_remote_cmd $qargs]\n"
"\n" "\n"
...@@ -1288,13 +1428,25 @@ ...@@ -1288,13 +1428,25 @@
" }\n" " }\n"
"}\n" "}\n"
"\n" "\n"
"proc ptime {time} {\n"
" set usec [lindex [split $time] 0]\n"
" set sec [format \"%.3f\" [expr \"$usec / 1000000.0\"]]\n"
" puts \"time: $sec secs.\"\n"
"}\n"
"\n"
"proc do_var {item} {\n" "proc do_var {item} {\n"
" global connected_to_x11vnc item_cascade menu_var\n" " global connected_to_x11vnc item_cascade menu_var\n"
"\n" "\n"
" set debug [in_debug_mode]\n"
"\n"
" set string 0\n" " set string 0\n"
" if {[is_action $item]} {\n" " if {[is_action $item]} {\n"
" # Menu item is action:\n" " # Menu item is action:\n"
" if {$debug} {\n"
" ptime [time {do_action $item}]\n"
" } else {\n"
" do_action $item\n" " do_action $item\n"
" }\n"
" return\n" " return\n"
" }\n" " }\n"
"\n" "\n"
...@@ -1319,8 +1471,12 @@ ...@@ -1319,8 +1471,12 @@
" set new 1\n" " set new 1\n"
" }\n" " }\n"
" if {$connected_to_x11vnc} {\n" " if {$connected_to_x11vnc} {\n"
" if {$debug} {\n"
" ptime [time {push_new_value $item $name $new 1}]\n"
" } else {\n"
" push_new_value $item $name $new 1\n" " push_new_value $item $name $new 1\n"
" }\n" " }\n"
" }\n"
"}\n" "}\n"
"\n" "\n"
"proc menu_help {item} {\n" "proc menu_help {item} {\n"
...@@ -1370,7 +1526,8 @@ ...@@ -1370,7 +1526,8 @@
" }\n" " }\n"
"}\n" "}\n"
"\n" "\n"
"proc split_query {query} {\n" "proc split_query0 {query} {\n"
" # original slower way with regexp/regsub\n"
" regsub -all {aro=} $query {ans=} query\n" " regsub -all {aro=} $query {ans=} query\n"
" set items {}\n" " set items {}\n"
" while {1} {\n" " while {1} {\n"
...@@ -1390,6 +1547,38 @@ ...@@ -1390,6 +1547,38 @@
" return $items\n" " return $items\n"
"}\n" "}\n"
"\n" "\n"
"proc split_query {query} {\n"
" regsub -all {aro=} $query {ans=} query\n"
" set items {}\n"
" while {1} {\n"
" set n [string first \"ans=\" $query]\n"
" if {$n < 0} {\n"
" break\n"
" }\n"
" set from [expr $n+4]\n"
"\n"
" set m [string first \",ans=\" $query]\n"
" if {$m < 0} {\n"
" set more 0\n"
" set item [string range $query $from end]\n"
" } else {\n"
" set more 1\n"
" set to [expr $m-1]\n"
" set item [string range $query $from $to]\n"
" }\n"
" if {$item != \"\"} {\n"
" lappend items $item\n"
" }\n"
" if {$more} {\n"
" incr m\n"
" set query [string range $query $m end]\n"
" } else {\n"
" set query \"\"\n"
" }\n"
" }\n"
" return $items\n"
"}\n"
"\n"
"proc set_x11_display {name} {\n" "proc set_x11_display {name} {\n"
" global x11_display\n" " global x11_display\n"
" set x11_display \"x11vnc X display: $name\"\n" " set x11_display \"x11vnc X display: $name\"\n"
...@@ -1404,6 +1593,7 @@ ...@@ -1404,6 +1593,7 @@
"proc no_vnc_display {} {\n" "proc no_vnc_display {} {\n"
" set_vnc_display \"(*none*)\"\n" " set_vnc_display \"(*none*)\"\n"
"}\n" "}\n"
"\n"
"proc fetch_displays {} {\n" "proc fetch_displays {} {\n"
"\n" "\n"
" set qargs [list \"-Q\" \"display,vncdisplay\"]\n" " set qargs [list \"-Q\" \"display,vncdisplay\"]\n"
...@@ -1905,6 +2095,8 @@ ...@@ -1905,6 +2095,8 @@
"\n" "\n"
" lappend cmd $x11vnc_prog\n" " lappend cmd $x11vnc_prog\n"
"\n" "\n"
" set saw_id 0\n"
"\n"
" foreach item [lsort [array names menu_var]] {\n" " foreach item [lsort [array names menu_var]] {\n"
" if {![active_when_starting $item]} {\n" " if {![active_when_starting $item]} {\n"
" continue\n" " continue\n"
...@@ -1912,6 +2104,27 @@ ...@@ -1912,6 +2104,27 @@
" if {[is_action $item]} {\n" " if {[is_action $item]} {\n"
" continue\n" " continue\n"
" }\n" " }\n"
" if {$item == \"debug_gui\"} {\n"
" continue\n"
" }\n"
" if {$item == \"id\" || $item == \"sid\"} {\n"
" set val $menu_var($item);\n"
" if {$val == \"0x0\" || $val == \"root\"} {\n"
" continue\n"
" }\n"
" }\n"
" if {$item == \"sid\" && $saw_id} {\n"
" continue\n"
" }\n"
" if {$item == \"id\"} {\n"
" set saw_id 1\n"
" }\n"
" if {$item == \"progressive\" && $menu_var($item) == \"0\"} {\n"
" continue\n"
" }\n"
" if {$item == \"dontdisconnect\" && $menu_var($item) == \"-1\"} {\n"
" continue\n"
" }\n"
"\n" "\n"
" if {[value_is_bool $item]} {\n" " if {[value_is_bool $item]} {\n"
" if {[info exists menu_var($item)]} {\n" " if {[info exists menu_var($item)]} {\n"
...@@ -1923,7 +2136,11 @@ ...@@ -1923,7 +2136,11 @@
" if {[info exists menu_var($item)]} {\n" " if {[info exists menu_var($item)]} {\n"
" if {$menu_var($item) != \"\"\n" " if {$menu_var($item) != \"\"\n"
" && $menu_var($item) != $unset_str} {\n" " && $menu_var($item) != $unset_str} {\n"
" lappend cmd \"-$item\"\n" " set nitem $item\n"
" if {$nitem == \"screen_blank\"} {\n"
" set nitem \"sb\"\n"
" }\n"
" lappend cmd \"-$nitem\"\n"
" lappend cmd $menu_var($item)\n" " lappend cmd $menu_var($item)\n"
" }\n" " }\n"
" }\n" " }\n"
...@@ -2002,6 +2219,7 @@ ...@@ -2002,6 +2219,7 @@
" lappend cmd \"-display\"\n" " lappend cmd \"-display\"\n"
" lappend cmd $x11vnc_xdisplay\n" " lappend cmd $x11vnc_xdisplay\n"
" }\n" " }\n"
" lappend cmd \"-sync\"\n"
" foreach word $opts {\n" " foreach word $opts {\n"
" lappend cmd $word\n" " lappend cmd $word\n"
" }\n" " }\n"
...@@ -2017,12 +2235,19 @@ ...@@ -2017,12 +2235,19 @@
"}\n" "}\n"
"\n" "\n"
" set output \"\"\n" " set output \"\"\n"
" menus_disable\n"
" stop_watch on\n" " stop_watch on\n"
" catch {set output [eval exec $cmd]}\n" " catch {set output [eval exec $cmd]}\n"
" stop_watch off\n" " stop_watch off\n"
" menus_enable\n"
" if {$debug} {\n" " if {$debug} {\n"
" if {[string length $output] > 100} {\n"
" set str [string range $output 0 100]\n"
" append_text \"output: $str ...\\n\"\n"
" } else {\n"
" append_text \"output: $output\\n\"\n" " append_text \"output: $output\\n\"\n"
" }\n" " }\n"
" }\n"
" return $output\n" " return $output\n"
"}\n" "}\n"
"\n" "\n"
...@@ -2089,6 +2314,7 @@ ...@@ -2089,6 +2314,7 @@
"global bfont\n" "global bfont\n"
"global connected_to_x11vnc\n" "global connected_to_x11vnc\n"
"global delay_sleep extra_sleep extra_sleep_split\n" "global delay_sleep extra_sleep extra_sleep_split\n"
"global cache_all_query_vars\n"
"\n" "\n"
"set unset_str \"(unset)\"\n" "set unset_str \"(unset)\"\n"
"set connected_to_x11vnc 0\n" "set connected_to_x11vnc 0\n"
...@@ -2099,9 +2325,9 @@ ...@@ -2099,9 +2325,9 @@
"set reply_xdisplay \"\"\n" "set reply_xdisplay \"\"\n"
"set all_settings \"None so far.\"\n" "set all_settings \"None so far.\"\n"
"set always_update 1\n" "set always_update 1\n"
"set cache_all_query_vars \"\"\n"
"\n" "\n"
"#set delay_sleep 500\n" "# these are no longer used under x11vnc -sync:\n"
"#set extra_sleep 1500\n"
"set delay_sleep 350\n" "set delay_sleep 350\n"
"set extra_sleep 1000\n" "set extra_sleep 1000\n"
"set extra_sleep_split 4\n" "set extra_sleep_split 4\n"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
.TH X11VNC "1" "December 2004" "x11vnc " "User Commands" .TH X11VNC "1" "December 2004" "x11vnc " "User Commands"
.SH NAME .SH NAME
x11vnc - allow VNC connections to real X11 displays x11vnc - allow VNC connections to real X11 displays
version: 0.6.3pre, lastmod: 2004-12-17 version: 0.6.3pre, lastmod: 2004-12-19
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
...@@ -661,28 +661,36 @@ To include button events use "Button1", ... etc. ...@@ -661,28 +661,36 @@ To include button events use "Button1", ... etc.
.PP .PP
\fB-nodragging\fR \fB-nodragging\fR
.IP .IP
Do not update the display during mouse dragging events Do not update the display during mouse dragging
(mouse motion with a button held down). Greatly events (mouse motion with a button held down).
improves response on slow setups, but you lose all Greatly improves response on slow setups, but you lose
visual feedback for drags, text selection, and some all visual feedback for drags, text selection, and some
menu traversals. menu traversals. It overrides any \fB-pointer_mode\fR setting
(think of it as pointer_mode 0)
.PP .PP
\fB-pointer_mode\fR \fIn\fR \fB-pointer_mode\fR \fIn\fR
.IP .IP
Various pointer update schemes. The problem is pointer Various pointer update schemes. The problem is pointer
motion can cause rapid changes on the screen, e.g. a motion can cause rapid changes on the screen, e.g. a
window drag. Neither x11vnc nor the bandwidth to the window drag. Neither x11vnc's screen polling nor the
vncviewers can keep up these rapid screen changes: bandwidth to the vncviewers can keep up these rapid
everything bogs down when dragging or scrolling. screen changes: everything bogs down when dragging
Note that most video h/w is optimized for writing, not or scrolling. Note that most video h/w is optimized
reading (a 50X rate difference is possible) and x11vnc for writing, not reading (a 50X rate difference is
is reading all the time. So a scheme has to be used to possible) and x11vnc is reading all the time. So a
"eat" much of that pointer input before re-polling the scheme has to be used to "eat" much of that pointer
screen. n can be 1 to 4. n=1 was the original scheme input before re-polling the screen. n can be 1 to 4.
used to about Jan 2004. n=2 is an improved scheme. .IP
n=3 is basically a dynamic \fB-nodragging\fR mode: it detects n=1 was the original scheme used to about Jan 2004: it
if the mouse drag motion has paused and refreshes basically just skips \fB-input_skip\fR pointer events before
the display. n=4 is TBD. The default n is 2. repolling the screen. n=2 is an improved scheme:
by watching the current rate it tries to detect if
it should try to "eat" more pointer events. n=3 is
basically a dynamic \fB-nodragging\fR mode: it detects if the
mouse drag motion has paused and refreshes the display.
n=4 is TBD, it will try measure screen read and client
write rates and try to insert "frames" between the
on/off states of mode 3. The default n is 2.
.PP .PP
\fB-input_skip\fR \fIn\fR \fB-input_skip\fR \fIn\fR
.IP .IP
...@@ -1157,6 +1165,27 @@ button_mask mouse_x mouse_y bpp depth indexed_color ...@@ -1157,6 +1165,27 @@ button_mask mouse_x mouse_y bpp depth indexed_color
dpy_x dpy_y rfbport rfbwait rfbauth passwd alwaysshared dpy_x dpy_y rfbport rfbwait rfbauth passwd alwaysshared
dontdisconnect httpdir enablehttpproxy dontdisconnect httpdir enablehttpproxy
.PP .PP
\fB-sync\fR
.IP
By default \fB-remote\fR commands are run asynchronously, that
is, the request is posted and the program immediately
exits. Use \fB-sync\fR to have the program wait for an
acknowledgement from the x11vnc server that command
was processed. On the other hand \fB-query\fR requests are
always processed synchronously because they have wait
for the result.
.IP
Also note that if both \fB-remote\fR and \fB-query\fR requests are
supplied on the command line, the \fB-remote\fR is processed
first (synchronously: no need for \fB-sync),\fR and then
the \fB-query\fR request is processed in the normal way.
This allows for a reliable way to see if the \fB-remote\fR
command was processed by querying for any new settings.
Note however that there is timeout of a few seconds so
if the x11vnc takes longer than that to process the
requests the requestor will think that a failure has
taken place.
.PP
\fB-noremote\fR \fB-noremote\fR
.IP .IP
Do not process any remote control commands or queries. Do not process any remote control commands or queries.
......
...@@ -256,7 +256,7 @@ static int xdamage_base_event_type; ...@@ -256,7 +256,7 @@ static int xdamage_base_event_type;
#endif #endif
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.6.3pre lastmod: 2004-12-17"; char lastmod[] = "0.6.3pre lastmod: 2004-12-19";
/* X display info */ /* X display info */
...@@ -310,6 +310,9 @@ typedef struct _ClientData { ...@@ -310,6 +310,9 @@ typedef struct _ClientData {
int had_cursor_shape_updates; int had_cursor_shape_updates;
int had_cursor_pos_updates; int had_cursor_pos_updates;
int uid; int uid;
int client_port;
int server_port;
char *server_ip;
} ClientData; } ClientData;
/* scaling parameters */ /* scaling parameters */
...@@ -697,7 +700,7 @@ int scan_hexdec(char *str, unsigned long *num) { ...@@ -697,7 +700,7 @@ int scan_hexdec(char *str, unsigned long *num) {
void set_env(char *name, char *value) { void set_env(char *name, char *value) {
char *str; char *str;
str = malloc(strlen(name)+strlen(value)+2); str = (char *)malloc(strlen(name)+strlen(value)+2);
sprintf(str, "%s=%s", name, value); sprintf(str, "%s=%s", name, value);
putenv(str); putenv(str);
} }
...@@ -1460,6 +1463,10 @@ char *list_clients(void) { ...@@ -1460,6 +1463,10 @@ char *list_clients(void) {
} }
rfbReleaseClientIterator(iter); rfbReleaseClientIterator(iter);
/*
* each client: 123.123.123.123:60000/0x11111111-rw, = 36 bytes
* so count+1 * 100 should cover it.
*/
list = (char *) malloc((count+1)*100); list = (char *) malloc((count+1)*100);
list[0] = '\0'; list[0] = '\0';
...@@ -1553,18 +1560,10 @@ void close_clients(char *str) { ...@@ -1553,18 +1560,10 @@ void close_clients(char *str) {
*/ */
static int run_user_command(char *cmd, rfbClientPtr client, char *mode) { static int run_user_command(char *cmd, rfbClientPtr client, char *mode) {
char *dpystr = DisplayString(dpy); char *dpystr = DisplayString(dpy);
static char *display_env = NULL; char *old_display = NULL;
static char env_rfb_client_id[100];
static char env_rfb_client_ip[100];
static char env_rfb_client_port[100];
static char env_rfb_server_ip[100];
static char env_rfb_server_port[100];
static char env_rfb_x11vnc_pid[100];
static char env_rfb_client_count[100];
static char env_rfb_mode[100];
char *addr = client->host; char *addr = client->host;
int rc, hport; char str[100];
char *ip_str = NULL; int rc;
ClientData *cd = (ClientData *) client->clientData; ClientData *cd = (ClientData *) client->clientData;
if (addr == NULL || addr[0] == '\0') { if (addr == NULL || addr[0] == '\0') {
...@@ -1573,29 +1572,29 @@ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) { ...@@ -1573,29 +1572,29 @@ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) {
/* set RFB_CLIENT_ID to semi unique id for command to use */ /* set RFB_CLIENT_ID to semi unique id for command to use */
if (cd && cd->uid) { if (cd && cd->uid) {
sprintf(env_rfb_client_id, "RFB_CLIENT_ID=0x%x", cd->uid); sprintf(str, "0x%x", cd->uid);
} else { } else {
/* not accepted yet: */ /* not accepted yet: */
sprintf(env_rfb_client_id, "RFB_CLIENT_ID=0x%x", sprintf(str, "0x%x", clients_served);
clients_served);
} }
putenv(env_rfb_client_id); set_env("RFB_CLIENT_ID", str);
/* set RFB_CLIENT_IP to IP addr for command to use */ /* set RFB_CLIENT_IP to IP addr for command to use */
sprintf(env_rfb_client_ip, "RFB_CLIENT_IP=%s", addr); set_env("RFB_CLIENT_IP", addr);
putenv(env_rfb_client_ip);
/* set RFB_X11VNC_PID to our pid for command to use */ /* set RFB_X11VNC_PID to our pid for command to use */
sprintf(env_rfb_x11vnc_pid, "RFB_X11VNC_PID=%d", (int) getpid()); sprintf(str, "%d", (int) getpid());
putenv(env_rfb_x11vnc_pid); set_env("RFB_X11VNC_PID", str);
/* set RFB_CLIENT_PORT to peer port for command to use */ /* set RFB_CLIENT_PORT to peer port for command to use */
hport = get_remote_port(client->sock); if (cd && cd->client_port > 0) {
sprintf(env_rfb_client_port, "RFB_CLIENT_PORT=%d", hport); sprintf(str, "%d", cd->client_port);
putenv(env_rfb_client_port); } else {
sprintf(str, "%d", get_remote_port(client->sock));
}
set_env("RFB_CLIENT_PORT", str);
sprintf(env_rfb_mode, "RFB_MODE=%s", mode); set_env("RFB_MODE", mode);
putenv(env_rfb_mode);
/* /*
* now do RFB_SERVER_IP and RFB_SERVER_PORT (i.e. us!) * now do RFB_SERVER_IP and RFB_SERVER_PORT (i.e. us!)
...@@ -1603,32 +1602,35 @@ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) { ...@@ -1603,32 +1602,35 @@ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) {
* program can potentially use to work out the virtual circuit * program can potentially use to work out the virtual circuit
* for this connection. * for this connection.
*/ */
ip_str = get_local_host(client->sock); if (cd && cd->server_ip) {
hport = get_local_port(client->sock); set_env("RFB_SERVER_IP", cd->server_ip);
} else {
sprintf(env_rfb_server_ip, "RFB_SERVER_IP=%s", ip_str); set_env("RFB_SERVER_IP", get_local_host(client->sock));
putenv(env_rfb_server_ip); }
sprintf(env_rfb_server_port, "RFB_SERVER_PORT=%d", hport);
putenv(env_rfb_server_port);
if (cd && cd->server_port > 0) {
sprintf(str, "%d", cd->server_port);
} else {
sprintf(str, "%d", get_local_port(client->sock));
}
set_env("RFB_SERVER_PORT", str);
/* /*
* Better set DISPLAY to the one we are polling, if they * Better set DISPLAY to the one we are polling, if they
* want something trickier, they can handle on their own * want something trickier, they can handle on their own
* via environment, etc. XXX really should save/restore old. * via environment, etc.
*/ */
if (display_env == NULL) { if (getenv("DISPLAY")) {
display_env = (char *) malloc(strlen(dpystr)+10); old_display = strdup(getenv("DISPLAY"));
} }
sprintf(display_env, "DISPLAY=%s", dpystr); set_env("DISPLAY", dpystr);
putenv(display_env);
/* /*
* work out the number of clients (have to use client_count * work out the number of clients (have to use client_count
* since there is deadlock in rfbGetClientIterator) * since there is deadlock in rfbGetClientIterator)
*/ */
sprintf(env_rfb_client_count, "RFB_CLIENT_COUNT=%d", client_count); sprintf(str, "%d", client_count);
putenv(env_rfb_client_count); set_env("RFB_CLIENT_COUNT", str);
rfbLog("running command:\n"); rfbLog("running command:\n");
rfbLog(" %s\n", cmd); rfbLog(" %s\n", cmd);
...@@ -1640,6 +1642,11 @@ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) { ...@@ -1640,6 +1642,11 @@ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) {
} }
rfbLog("command returned: %d\n", rc); rfbLog("command returned: %d\n", rc);
if (old_display) {
set_env("DISPLAY", old_display);
free(old_display);
}
return rc; return rc;
} }
...@@ -1651,10 +1658,6 @@ static void client_gone(rfbClientPtr client) { ...@@ -1651,10 +1658,6 @@ static void client_gone(rfbClientPtr client) {
client_count--; client_count--;
rfbLog("client_count: %d\n", client_count); rfbLog("client_count: %d\n", client_count);
if (client->clientData) {
free(client->clientData);
}
if (no_autorepeat && client_count == 0) { if (no_autorepeat && client_count == 0) {
autorepeat(1); autorepeat(1);
} }
...@@ -1663,6 +1666,14 @@ static void client_gone(rfbClientPtr client) { ...@@ -1663,6 +1666,14 @@ static void client_gone(rfbClientPtr client) {
run_user_command(gone_cmd, client, "gone"); run_user_command(gone_cmd, client, "gone");
} }
if (client->clientData) {
ClientData *cd = (ClientData *) client->clientData;
if (cd && cd->server_ip) {
free(cd->server_ip);
}
free(client->clientData);
}
if (inetd) { if (inetd) {
rfbLog("viewer exited.\n"); rfbLog("viewer exited.\n");
clean_up_exit(0); clean_up_exit(0);
...@@ -2543,14 +2554,14 @@ void read_vnc_connect_prop(void) { ...@@ -2543,14 +2554,14 @@ void read_vnc_connect_prop(void) {
} while (bytes_after > 0); } while (bytes_after > 0);
vnc_connect_str[VNC_CONNECT_MAX] = '\0'; vnc_connect_str[VNC_CONNECT_MAX] = '\0';
if (strlen(vnc_connect_str) > 100) { if (strlen(vnc_connect_str) > 38) {
char trim[101]; char trim[100];
trim[0] = '\0'; trim[0] = '\0';
strncat(trim, vnc_connect_str, 100); strncat(trim, vnc_connect_str, 38);
rfbLog("read X property VNC_CONNECT: %s ...\n", trim); rfbLog("read VNC_CONNECT: %s ...\n", trim);
} else { } else {
rfbLog("read X property VNC_CONNECT: %s\n", vnc_connect_str); rfbLog("read VNC_CONNECT: %s\n", vnc_connect_str);
} }
} }
...@@ -2564,6 +2575,8 @@ static void send_client_connect(void) { ...@@ -2564,6 +2575,8 @@ static void send_client_connect(void) {
process_remote_cmd(client_connect, 0); process_remote_cmd(client_connect, 0);
} else if (strstr(str, "ans=") || strstr(str, "aro=") == str) { } else if (strstr(str, "ans=") || strstr(str, "aro=") == str) {
; ;
} else if (strstr(str, "ack=") == str) {
;
} else { } else {
reverse_connect(client_connect); reverse_connect(client_connect);
} }
...@@ -2641,6 +2654,10 @@ enum rfbNewClientAction new_client(rfbClientPtr client) { ...@@ -2641,6 +2654,10 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
cd->uid = clients_served; cd->uid = clients_served;
cd->client_port = get_remote_port(client->sock);
cd->server_port = get_local_port(client->sock);
cd->server_ip = strdup(get_remote_host(client->sock));
client->clientGoneHook = client_gone; client->clientGoneHook = client_gone;
client_count++; client_count++;
...@@ -4419,7 +4436,8 @@ static void update_x11_pointer(int mask, int x, int y) { ...@@ -4419,7 +4436,8 @@ static void update_x11_pointer(int mask, int x, int y) {
X_LOCK; X_LOCK;
if (use_xwarppointer) { if (use_xwarppointer) {
XWarpPointer(dpy, None, window, 0, 0, 0, 0, x+off_x, y+off_y); /* off_x and off_y not needed with XWarpPointer */
XWarpPointer(dpy, None, window, 0, 0, 0, 0, x, y);
} else { } else {
XTestFakeMotionEvent_wr(dpy, scr, x+off_x, y+off_y, XTestFakeMotionEvent_wr(dpy, scr, x+off_x, y+off_y,
CurrentTime); CurrentTime);
...@@ -4820,7 +4838,6 @@ int handle_subwin_resize(char *msg) { ...@@ -4820,7 +4838,6 @@ int handle_subwin_resize(char *msg) {
int new_x, new_y; int new_x, new_y;
int i, check = 10, ms = 250; /* 2.5 secs... */ int i, check = 10, ms = 250; /* 2.5 secs... */
if (0) fprintf(stderr, "IN handle_subwin_resize('%s')\n", msg);
if (! subwin) { if (! subwin) {
return 0; /* hmmm... */ return 0; /* hmmm... */
} }
...@@ -5473,8 +5490,7 @@ void xcut_receive(char *text, int len, rfbClientPtr cl) { ...@@ -5473,8 +5490,7 @@ void xcut_receive(char *text, int len, rfbClientPtr cl) {
/* /*
* for the wild-n-crazy -remote/-R interface. * for the wild-n-crazy -remote/-R interface.
*/ */
int send_remote_cmd(char *cmd, int query) { int send_remote_cmd(char *cmd, int query, int wait) {
char *str;
FILE *in = NULL; FILE *in = NULL;
if (client_connect_file) { if (client_connect_file) {
...@@ -5494,29 +5510,22 @@ int send_remote_cmd(char *cmd, int query) { ...@@ -5494,29 +5510,22 @@ int send_remote_cmd(char *cmd, int query) {
return 1; return 1;
} }
} }
str = (char *) malloc((strlen(cmd)+5));
if (query) {
strcpy(str, "qry=");
} else {
strcpy(str, "cmd=");
}
strcat(str, cmd);
if (in != NULL) { if (in != NULL) {
fprintf(stderr, "sending remote command: \"%s\"\nvia connect" fprintf(stderr, "sending remote command: \"%s\"\nvia connect"
" file: %s\n", cmd, client_connect_file); " file: %s\n", cmd, client_connect_file);
fprintf(in, "%s\n", str); fprintf(in, "%s\n", cmd);
fclose(in); fclose(in);
} else { } else {
fprintf(stderr, "sending remote command: \"%s\" via VNC_CONNECT" fprintf(stderr, "sending remote command: \"%s\" via VNC_CONNECT"
" X property.\n", cmd); " X property.\n", cmd);
set_vnc_connect_prop(str); set_vnc_connect_prop(cmd);
XFlush(dpy); XFlush(dpy);
} }
if (strstr(str, "qry=") == str) { if (query || wait) {
char line[VNC_CONNECT_MAX]; char line[VNC_CONNECT_MAX];
int rc=1, i=0, max=20, ms_sl=100; int rc=1, i=0, max=70, ms_sl=50;
for (i=0; i<max; i++) { for (i=0; i<max; i++) {
usleep(ms_sl * 1000); usleep(ms_sl * 1000);
if (client_connect_file) { if (client_connect_file) {
...@@ -5540,14 +5549,15 @@ int send_remote_cmd(char *cmd, int query) { ...@@ -5540,14 +5549,15 @@ int send_remote_cmd(char *cmd, int query) {
read_vnc_connect_prop(); read_vnc_connect_prop();
strncpy(line, vnc_connect_str, VNC_CONNECT_MAX); strncpy(line, vnc_connect_str, VNC_CONNECT_MAX);
} }
if (strcmp(str, line)){ if (strcmp(cmd, line)){
if (query) {
fprintf(stdout, "%s\n", line); fprintf(stdout, "%s\n", line);
fflush(stdout); fflush(stdout);
}
rc = 0; rc = 0;
break; break;
} }
} }
free(str);
if (rc) { if (rc) {
fprintf(stderr, "error: could not connect to " fprintf(stderr, "error: could not connect to "
"an x11vnc server at %s (rc=%d)\n", "an x11vnc server at %s (rc=%d)\n",
...@@ -5556,10 +5566,42 @@ int send_remote_cmd(char *cmd, int query) { ...@@ -5556,10 +5566,42 @@ int send_remote_cmd(char *cmd, int query) {
} }
return rc; return rc;
} }
free(str);
return 0; return 0;
} }
int do_remote_query(char *remote_cmd, char *query_cmd, int remote_sync) {
char *rcmd = NULL, *qcmd = NULL;
int rc = 1;
if (remote_cmd) {
rcmd = (char *)malloc(strlen(remote_cmd) + 5);
strcpy(rcmd, "cmd=");
strcat(rcmd, remote_cmd);
}
if (query_cmd) {
qcmd = (char *)malloc(strlen(query_cmd) + 5);
strcpy(qcmd, "qry=");
strcat(qcmd, query_cmd);
}
if (rcmd && qcmd) {
rc = send_remote_cmd(rcmd, 0, 1);
if (rc) {
free(rcmd);
free(qcmd);
return(rc);
}
rc = send_remote_cmd(qcmd, 1, 1);
} else if (rcmd) {
rc = send_remote_cmd(rcmd, 0, remote_sync);
free(rcmd);
} else if (qcmd) {
rc = send_remote_cmd(qcmd, 1, 1);
free(qcmd);
}
return rc;
}
char *add_item(char *instr, char *item) { char *add_item(char *instr, char *item) {
char *p, *str; char *p, *str;
int len, saw_item = 0; int len, saw_item = 0;
...@@ -5652,7 +5694,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5652,7 +5694,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
char *p = cmd; char *p = cmd;
char *co = ""; char *co = "";
char buf[VNC_CONNECT_MAX]; char buf[VNC_CONNECT_MAX];
int do_vnc_connect = 0; int bufn = VNC_CONNECT_MAX;
int query = 0; int query = 0;
static char *prev_cursors_mode = NULL; static char *prev_cursors_mode = NULL;
...@@ -5661,6 +5703,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5661,6 +5703,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
return NULL; return NULL;
} }
strcpy(buf, "");
if (strstr(cmd, "cmd=") == cmd) { if (strstr(cmd, "cmd=") == cmd) {
p += strlen("cmd="); p += strlen("cmd=");
} else if (strstr(cmd, "qry=") == cmd) { } else if (strstr(cmd, "qry=") == cmd) {
...@@ -5673,8 +5716,16 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5673,8 +5716,16 @@ char *process_remote_cmd(char *cmd, int stringonly) {
s = strdup(cmd + strlen("qry=")); s = strdup(cmd + strlen("qry="));
q = strtok(s, ","); q = strtok(s, ",");
while (q) { while (q) {
sprintf(tmp, "qry=%s", q); strcpy(tmp, "qry=");
strncat(tmp, q, 500);
res = process_remote_cmd(tmp, 1); res = process_remote_cmd(tmp, 1);
if (res && strlen(buf)+strlen(res)
>= VNC_CONNECT_MAX - 1) {
rfbLog("overflow in process_remote_cmd:"
" %s -- %s\n", buf, res);
free(res);
break;
}
if (res) { if (res) {
strcat(buf, res); strcat(buf, res);
free(res); free(res);
...@@ -5690,48 +5741,9 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5690,48 +5741,9 @@ char *process_remote_cmd(char *cmd, int stringonly) {
p += strlen("qry="); p += strlen("qry=");
} else { } else {
rfbLog("ignoring malformed command: %s\n", cmd); rfbLog("ignoring malformed command: %s\n", cmd);
return NULL; goto done;
} }
if (!query && strstr(p, "file:") == p) {
/* process command from a script file */
FILE *in;
char line[VNC_CONNECT_MAX], cmd[VNC_CONNECT_MAX];
int sz = VNC_CONNECT_MAX - 6;
p += strlen("file:");
in = fopen(p, "r");
if (in == NULL) {
rfbLog("process_remote_cmd: could not open cmd file"
" '%s'\n", p);
return NULL;
}
rfbLog("process_remote_cmd: running command from '%s'\n", p);
while (fgets(line, sz, in) != NULL) {
char *q;
if (strlen(line)) {
q = line + strlen(line) - 1;
if (*q == '\n') {
*q = '\0';
}
while (q > line && isspace(*q)) {
*q = '\0';
q--;
}
}
q = line;
while (isspace(*q)) {
q++;
}
if ( *q == '#' || *q == '\0') {
continue;
}
strcpy(cmd, "cmd=");
strcat(cmd, q);
process_remote_cmd(cmd, 0);
}
fclose(in);
return NULL;
}
/* always call like: COLON_CHECK("foobar:") */ /* always call like: COLON_CHECK("foobar:") */
#define COLON_CHECK(str) \ #define COLON_CHECK(str) \
...@@ -5750,9 +5762,9 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5750,9 +5762,9 @@ char *process_remote_cmd(char *cmd, int stringonly) {
#define NOTAPP \ #define NOTAPP \
if (query) { \ if (query) { \
if (strchr(p, ':')) { \ if (strchr(p, ':')) { \
sprintf(buf, "ans=%sN/A", p); \ snprintf(buf, bufn, "ans=%sN/A", p); \
} else { \ } else { \
sprintf(buf, "ans=%s:N/A", p); \ snprintf(buf, bufn, "ans=%s:N/A", p); \
} \ } \
goto qry; \ goto qry; \
} }
...@@ -5760,9 +5772,9 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5760,9 +5772,9 @@ char *process_remote_cmd(char *cmd, int stringonly) {
#define NOTAPPRO \ #define NOTAPPRO \
if (query) { \ if (query) { \
if (strchr(p, ':')) { \ if (strchr(p, ':')) { \
sprintf(buf, "aro=%sN/A", p); \ snprintf(buf, bufn, "aro=%sN/A", p); \
} else { \ } else { \
sprintf(buf, "aro=%s:N/A", p); \ snprintf(buf, bufn, "aro=%s:N/A", p); \
} \ } \
goto qry; \ goto qry; \
} }
...@@ -5780,9 +5792,9 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5780,9 +5792,9 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "ping")) { } else if (!strcmp(p, "ping")) {
query = 1; query = 1;
if (rfb_desktop_name) { if (rfb_desktop_name) {
sprintf(buf, "ans=%s:%s", p, rfb_desktop_name); snprintf(buf, bufn, "ans=%s:%s", p, rfb_desktop_name);
} else { } else {
sprintf(buf, "ans=%s:%s", p, "unknown"); snprintf(buf, bufn, "ans=%s:%s", p, "unknown");
} }
goto qry; goto qry;
...@@ -5841,7 +5853,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5841,7 +5853,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
Window twin; Window twin;
COLON_CHECK("id:") COLON_CHECK("id:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s0x%lx", p, co, subwin); snprintf(buf, bufn, "ans=%s%s0x%lx", p, co, subwin);
goto qry; goto qry;
} }
p += strlen("id:"); p += strlen("id:");
...@@ -5857,7 +5869,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5857,7 +5869,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
ok = 1; ok = 1;
} }
} else if (! scan_hexdec(p, &twin)) { } else if (! scan_hexdec(p, &twin)) {
rfbLog("-id: incorrect hex/dec number: %s\n", p); rfbLog("-id: skipping incorrect hex/dec number: %s\n", p);
} else { } else {
ok = 1; ok = 1;
} }
...@@ -5877,7 +5889,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5877,7 +5889,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
Window twin; Window twin;
COLON_CHECK("sid:") COLON_CHECK("sid:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s0x%lx", p, co, subwin); snprintf(buf, bufn, "ans=%s%s0x%lx", p, co, subwin);
goto qry; goto qry;
} }
p += strlen("sid:"); p += strlen("sid:");
...@@ -5893,7 +5905,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5893,7 +5905,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
ok = 1; ok = 1;
} }
} else if (! scan_hexdec(p, &twin)) { } else if (! scan_hexdec(p, &twin)) {
rfbLog("-sid: incorrect hex/dec number: %s\n", p); rfbLog("-sid: skipping incorrect hex/dec number: %s\n", p);
} else { } else {
ok = 1; ok = 1;
} }
...@@ -5911,14 +5923,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5911,14 +5923,14 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "flashcmap")) { } else if (!strcmp(p, "flashcmap")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, flash_cmap); snprintf(buf, bufn, "ans=%s:%d", p, flash_cmap);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning on flashcmap mode.\n"); rfbLog("process_remote_cmd: turning on flashcmap mode.\n");
flash_cmap = 1; flash_cmap = 1;
} else if (!strcmp(p, "noflashcmap")) { } else if (!strcmp(p, "noflashcmap")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !flash_cmap); snprintf(buf, bufn, "ans=%s:%d", p, !flash_cmap);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning off flashcmap mode.\n"); rfbLog("process_remote_cmd: turning off flashcmap mode.\n");
...@@ -5927,7 +5939,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5927,7 +5939,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "truecolor")) { } else if (!strcmp(p, "truecolor")) {
int orig = force_indexed_color; int orig = force_indexed_color;
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !force_indexed_color); snprintf(buf, bufn, "ans=%s:%d", p, !force_indexed_color);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning off notruecolor mode.\n"); rfbLog("process_remote_cmd: turning off notruecolor mode.\n");
...@@ -5938,7 +5950,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5938,7 +5950,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "notruecolor")) { } else if (!strcmp(p, "notruecolor")) {
int orig = force_indexed_color; int orig = force_indexed_color;
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, force_indexed_color); snprintf(buf, bufn, "ans=%s:%d", p, force_indexed_color);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning on notruecolor mode.\n"); rfbLog("process_remote_cmd: turning on notruecolor mode.\n");
...@@ -5949,7 +5961,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5949,7 +5961,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "overlay")) { } else if (!strcmp(p, "overlay")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, overlay); snprintf(buf, bufn, "ans=%s:%d", p, overlay);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning on -overlay mode.\n"); rfbLog("process_remote_cmd: turning on -overlay mode.\n");
...@@ -5971,7 +5983,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5971,7 +5983,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "nooverlay")) { } else if (!strcmp(p, "nooverlay")) {
int orig = overlay; int orig = overlay;
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !overlay); snprintf(buf, bufn, "ans=%s:%d", p, !overlay);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning off overlay mode\n"); rfbLog("process_remote_cmd: turning off overlay mode\n");
...@@ -5988,7 +6000,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -5988,7 +6000,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "overlay_cursor") || } else if (!strcmp(p, "overlay_cursor") ||
!strcmp(p, "overlay_yescursor")) { !strcmp(p, "overlay_yescursor")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, overlay_cursor); snprintf(buf, bufn, "ans=%s:%d", p, overlay_cursor);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning on overlay_cursor mode.\n"); rfbLog("process_remote_cmd: turning on overlay_cursor mode.\n");
...@@ -6005,7 +6017,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6005,7 +6017,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "nooverlay_cursor") || } else if (!strcmp(p, "nooverlay_cursor") ||
!strcmp(p, "overlay_nocursor")) { !strcmp(p, "overlay_nocursor")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !overlay_cursor); snprintf(buf, bufn, "ans=%s:%d", p, !overlay_cursor);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning off overlay_cursor mode\n"); rfbLog("process_remote_cmd: turning off overlay_cursor mode\n");
...@@ -6022,7 +6034,8 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6022,7 +6034,8 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (strstr(p, "visual") == p) { } else if (strstr(p, "visual") == p) {
COLON_CHECK("visual:") COLON_CHECK("visual:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%s", p, co, NONUL(visual_str)); snprintf(buf, bufn, "ans=%s%s%s", p, co,
NONUL(visual_str));
goto qry; goto qry;
} }
p += strlen("visual:"); p += strlen("visual:");
...@@ -6032,10 +6045,11 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6032,10 +6045,11 @@ char *process_remote_cmd(char *cmd, int stringonly) {
/* OK, this requires a new fb... */ /* OK, this requires a new fb... */
do_new_fb(0); do_new_fb(0);
} else if (strstr(p, "scale") == p) { } else if (!strcmp(p, "scale") ||
strstr(p, "scale:") == p) { /* skip-cmd-list */
COLON_CHECK("scale:") COLON_CHECK("scale:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%s", p, co, NONUL(scale_str)); snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(scale_str));
goto qry; goto qry;
} }
p += strlen("scale:"); p += strlen("scale:");
...@@ -6048,20 +6062,20 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6048,20 +6062,20 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "viewonly")) { } else if (!strcmp(p, "viewonly")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, view_only); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, view_only); goto qry;
} }
rfbLog("process_remote_cmd: enable viewonly mode.\n"); rfbLog("process_remote_cmd: enable viewonly mode.\n");
view_only = 1; view_only = 1;
} else if (!strcmp(p, "noviewonly")) { } else if (!strcmp(p, "noviewonly")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !view_only); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, !view_only); goto qry;
} }
rfbLog("process_remote_cmd: disable viewonly mode.\n"); rfbLog("process_remote_cmd: disable viewonly mode.\n");
view_only = 0; view_only = 0;
} else if (!strcmp(p, "shared")) { } else if (!strcmp(p, "shared")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, shared); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, shared); goto qry;
} }
rfbLog("process_remote_cmd: enable sharing.\n"); rfbLog("process_remote_cmd: enable sharing.\n");
shared = 1; shared = 1;
...@@ -6069,7 +6083,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6069,7 +6083,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
screen->neverShared = FALSE; screen->neverShared = FALSE;
} else if (!strcmp(p, "noshared")) { } else if (!strcmp(p, "noshared")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !shared); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, !shared); goto qry;
} }
rfbLog("process_remote_cmd: disable sharing.\n"); rfbLog("process_remote_cmd: disable sharing.\n");
shared = 0; shared = 0;
...@@ -6078,26 +6092,28 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6078,26 +6092,28 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "forever")) { } else if (!strcmp(p, "forever")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, 1-connect_once); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, 1-connect_once);
goto qry;
} }
rfbLog("process_remote_cmd: enable -forever mode.\n"); rfbLog("process_remote_cmd: enable -forever mode.\n");
connect_once = 0; connect_once = 0;
} else if (!strcmp(p, "noforever") || !strcmp(p, "once")) { } else if (!strcmp(p, "noforever") || !strcmp(p, "once")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, connect_once); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, connect_once);
goto qry;
} }
rfbLog("process_remote_cmd: disable -forever mode.\n"); rfbLog("process_remote_cmd: disable -forever mode.\n");
connect_once = 1; connect_once = 1;
} else if (!strcmp(p, "deny") || !strcmp(p, "lock")) { } else if (!strcmp(p, "deny") || !strcmp(p, "lock")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, deny_all); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, deny_all); goto qry;
} }
rfbLog("process_remote_cmd: denying new connections.\n"); rfbLog("process_remote_cmd: denying new connections.\n");
deny_all = 1; deny_all = 1;
} else if (!strcmp(p, "nodeny") || !strcmp(p, "unlock")) { } else if (!strcmp(p, "nodeny") || !strcmp(p, "unlock")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !deny_all); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, !deny_all); goto qry;
} }
rfbLog("process_remote_cmd: allowing new connections.\n"); rfbLog("process_remote_cmd: allowing new connections.\n");
deny_all = 0; deny_all = 0;
...@@ -6105,8 +6121,10 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6105,8 +6121,10 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (strstr(p, "connect") == p) { } else if (strstr(p, "connect") == p) {
NOTAPP NOTAPP
COLON_CHECK("connect:") COLON_CHECK("connect:")
p += strlen("connect:"); /* handled at end */ p += strlen("connect:");
do_vnc_connect = 1; /* this is a reverse connection */
strncpy(vnc_connect_str, p, VNC_CONNECT_MAX);
vnc_connect_str[VNC_CONNECT_MAX] = '\0';
} else if (strstr(p, "allowonce") == p) { } else if (strstr(p, "allowonce") == p) {
NOTAPP NOTAPP
...@@ -6119,14 +6137,15 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6119,14 +6137,15 @@ char *process_remote_cmd(char *cmd, int stringonly) {
char *before, *old; char *before, *old;
COLON_CHECK("allow:") COLON_CHECK("allow:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%s", p, co, NONUL(allow_list)); snprintf(buf, bufn, "ans=%s%s%s", p, co,
NONUL(allow_list));
goto qry; goto qry;
} }
p += strlen("allow:"); p += strlen("allow:");
if (allow_list && strchr(allow_list, '/')) { if (allow_list && strchr(allow_list, '/')) {
rfbLog("process_remote_cmd: cannot use allow:host\n"); rfbLog("process_remote_cmd: cannot use allow:host\n");
rfbLog("in '-allow %s' mode.\n", allow_list); rfbLog("in '-allow %s' mode.\n", allow_list);
return NULL; goto done;
} }
if (allow_list) { if (allow_list) {
before = strdup(allow_list); before = strdup(allow_list);
...@@ -6160,7 +6179,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6160,7 +6179,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
if (allow_list && !strcmp(allow_list, "127.0.0.1")) { if (allow_list && !strcmp(allow_list, "127.0.0.1")) {
state = 1; state = 1;
} }
sprintf(buf, "ans=%s:%d", p, state); snprintf(buf, bufn, "ans=%s:%d", p, state);
goto qry; goto qry;
} }
if (allow_list) { if (allow_list) {
...@@ -6186,7 +6205,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6186,7 +6205,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
if (allow_list && !strcmp(allow_list, "127.0.0.1")) { if (allow_list && !strcmp(allow_list, "127.0.0.1")) {
state = 1; state = 1;
} }
sprintf(buf, "ans=%s:%d", p, !state); snprintf(buf, bufn, "ans=%s:%d", p, !state);
goto qry; goto qry;
} }
if (allow_list) { if (allow_list) {
...@@ -6209,7 +6228,8 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6209,7 +6228,8 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (strstr(p, "accept") == p) { } else if (strstr(p, "accept") == p) {
COLON_CHECK("accept:") COLON_CHECK("accept:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%s", p, co, NONUL(accept_cmd)); snprintf(buf, bufn, "ans=%s%s%s", p, co,
NONUL(accept_cmd));
goto qry; goto qry;
} }
if (safe_remote_only) { if (safe_remote_only) {
...@@ -6223,7 +6243,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6223,7 +6243,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (strstr(p, "gone") == p) { } else if (strstr(p, "gone") == p) {
COLON_CHECK("gone:") COLON_CHECK("gone:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%s", p, co, NONUL(gone_cmd)); snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(gone_cmd));
goto qry; goto qry;
} }
if (safe_remote_only) { if (safe_remote_only) {
...@@ -6237,7 +6257,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6237,7 +6257,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "shm")) { } else if (!strcmp(p, "shm")) {
int orig = using_shm; int orig = using_shm;
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, using_shm); snprintf(buf, bufn, "ans=%s:%d", p, using_shm);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning off noshm mode.\n"); rfbLog("process_remote_cmd: turning off noshm mode.\n");
...@@ -6250,7 +6270,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6250,7 +6270,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "noshm")) { } else if (!strcmp(p, "noshm")) {
int orig = using_shm; int orig = using_shm;
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !using_shm); snprintf(buf, bufn, "ans=%s:%d", p, !using_shm);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning on noshm mode.\n"); rfbLog("process_remote_cmd: turning on noshm mode.\n");
...@@ -6264,7 +6284,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6264,7 +6284,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "flipbyteorder")) { } else if (!strcmp(p, "flipbyteorder")) {
int orig = flip_byte_order; int orig = flip_byte_order;
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, flip_byte_order); snprintf(buf, bufn, "ans=%s:%d", p, flip_byte_order);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning on flipbyteorder mode.\n"); rfbLog("process_remote_cmd: turning on flipbyteorder mode.\n");
...@@ -6279,7 +6299,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6279,7 +6299,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "noflipbyteorder")) { } else if (!strcmp(p, "noflipbyteorder")) {
int orig = flip_byte_order; int orig = flip_byte_order;
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !flip_byte_order); snprintf(buf, bufn, "ans=%s:%d", p, !flip_byte_order);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning off flipbyteorder mode.\n"); rfbLog("process_remote_cmd: turning off flipbyteorder mode.\n");
...@@ -6294,13 +6314,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6294,13 +6314,14 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "onetile")) { } else if (!strcmp(p, "onetile")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, single_copytile); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, single_copytile);
goto qry;
} }
rfbLog("process_remote_cmd: enable -onetile mode.\n"); rfbLog("process_remote_cmd: enable -onetile mode.\n");
single_copytile = 1; single_copytile = 1;
} else if (!strcmp(p, "noonetile")) { } else if (!strcmp(p, "noonetile")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !single_copytile); snprintf(buf, bufn, "ans=%s:%d", p, !single_copytile);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: disable -onetile mode.\n"); rfbLog("process_remote_cmd: disable -onetile mode.\n");
...@@ -6315,7 +6336,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6315,7 +6336,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
char *before, *old; char *before, *old;
COLON_CHECK("blackout:") COLON_CHECK("blackout:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%s", p, co, snprintf(buf, bufn, "ans=%s%s%s", p, co,
NONUL(blackout_string)); NONUL(blackout_string));
goto qry; goto qry;
} }
...@@ -6352,7 +6373,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6352,7 +6373,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "xinerama")) { } else if (!strcmp(p, "xinerama")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, xinerama); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, xinerama); goto qry;
} }
rfbLog("process_remote_cmd: enable xinerama mode." rfbLog("process_remote_cmd: enable xinerama mode."
"(if applicable).\n"); "(if applicable).\n");
...@@ -6360,7 +6381,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6360,7 +6381,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
initialize_blackouts_and_xinerama(); initialize_blackouts_and_xinerama();
} else if (!strcmp(p, "noxinerama")) { } else if (!strcmp(p, "noxinerama")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !xinerama); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, !xinerama); goto qry;
} }
rfbLog("process_remote_cmd: disable xinerama mode." rfbLog("process_remote_cmd: disable xinerama mode."
"(if applicable).\n"); "(if applicable).\n");
...@@ -6370,7 +6391,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6370,7 +6391,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "xrandr")) { } else if (!strcmp(p, "xrandr")) {
int orig = xrandr; int orig = xrandr;
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, xrandr); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, xrandr); goto qry;
} }
if (xrandr_present) { if (xrandr_present) {
rfbLog("process_remote_cmd: enable xrandr mode.\n"); rfbLog("process_remote_cmd: enable xrandr mode.\n");
...@@ -6388,7 +6409,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6388,7 +6409,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "noxrandr")) { } else if (!strcmp(p, "noxrandr")) {
int orig = xrandr; int orig = xrandr;
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !xrandr); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, !xrandr); goto qry;
} }
xrandr = 0; xrandr = 0;
if (xrandr_present) { if (xrandr_present) {
...@@ -6404,7 +6425,8 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6404,7 +6425,8 @@ char *process_remote_cmd(char *cmd, int stringonly) {
int orig = xrandr; int orig = xrandr;
COLON_CHECK("xrandr_mode:") COLON_CHECK("xrandr_mode:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%s", p, co, NONUL(xrandr_mode)); snprintf(buf, bufn, "ans=%s%s%s", p, co,
NONUL(xrandr_mode));
goto qry; goto qry;
} }
p += strlen("xrandr_mode:"); p += strlen("xrandr_mode:");
...@@ -6416,7 +6438,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6416,7 +6438,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
xrandr_mode = strdup(p); xrandr_mode = strdup(p);
} else { } else {
rfbLog("skipping unknown xrandr mode: %s\n", p); rfbLog("skipping unknown xrandr mode: %s\n", p);
return NULL; goto done;
} }
xrandr = 1; xrandr = 1;
} }
...@@ -6442,7 +6464,8 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6442,7 +6464,8 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (strstr(p, "padgeom") == p) { } else if (strstr(p, "padgeom") == p) {
COLON_CHECK("padgeom:") COLON_CHECK("padgeom:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%s", p, co, NONUL(pad_geometry)); snprintf(buf, bufn, "ans=%s%s%s", p, co,
NONUL(pad_geometry));
goto qry; goto qry;
} }
p += strlen("padgeom:"); p += strlen("padgeom:");
...@@ -6459,20 +6482,20 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6459,20 +6482,20 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "quiet") || !strcmp(p, "q")) { } else if (!strcmp(p, "quiet") || !strcmp(p, "q")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, quiet); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, quiet); goto qry;
} }
rfbLog("process_remote_cmd: turning on quiet mode.\n"); rfbLog("process_remote_cmd: turning on quiet mode.\n");
quiet = 1; quiet = 1;
} else if (!strcmp(p, "noquiet")) { } else if (!strcmp(p, "noquiet")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !quiet); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, !quiet); goto qry;
} }
rfbLog("process_remote_cmd: turning off quiet mode.\n"); rfbLog("process_remote_cmd: turning off quiet mode.\n");
quiet = 0; quiet = 0;
} else if (!strcmp(p, "modtweak")) { } else if (!strcmp(p, "modtweak")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, use_modifier_tweak); snprintf(buf, bufn, "ans=%s:%d", p, use_modifier_tweak);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: enabling -modtweak mode.\n"); rfbLog("process_remote_cmd: enabling -modtweak mode.\n");
...@@ -6484,7 +6507,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6484,7 +6507,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "nomodtweak")) { } else if (!strcmp(p, "nomodtweak")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !use_modifier_tweak); snprintf(buf, bufn, "ans=%s:%d", p, !use_modifier_tweak);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: enabling -nomodtweak mode.\n"); rfbLog("process_remote_cmd: enabling -nomodtweak mode.\n");
...@@ -6492,13 +6515,13 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6492,13 +6515,13 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "xkb")) { } else if (!strcmp(p, "xkb")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, use_xkb_modtweak); snprintf(buf, bufn, "ans=%s:%d", p, use_xkb_modtweak);
goto qry; goto qry;
} }
if (! xkb_present) { if (! xkb_present) {
rfbLog("process_remote_cmd: cannot enable -xkb " rfbLog("process_remote_cmd: cannot enable -xkb "
"modtweak mode (not supported on X display)\n"); "modtweak mode (not supported on X display)\n");
return NULL; goto done;
} }
rfbLog("process_remote_cmd: enabling -xkb modtweak mode" rfbLog("process_remote_cmd: enabling -xkb modtweak mode"
" (if supported).\n"); " (if supported).\n");
...@@ -6512,13 +6535,13 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6512,13 +6535,13 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "noxkb")) { } else if (!strcmp(p, "noxkb")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !use_xkb_modtweak); snprintf(buf, bufn, "ans=%s:%d", p, !use_xkb_modtweak);
goto qry; goto qry;
} }
if (! xkb_present) { if (! xkb_present) {
rfbLog("process_remote_cmd: cannot disable -xkb " rfbLog("process_remote_cmd: cannot disable -xkb "
"modtweak mode (not supported on X display)\n"); "modtweak mode (not supported on X display)\n");
return NULL; goto done;
} }
rfbLog("process_remote_cmd: disabling -xkb modtweak mode.\n"); rfbLog("process_remote_cmd: disabling -xkb modtweak mode.\n");
use_xkb_modtweak = 0; use_xkb_modtweak = 0;
...@@ -6526,7 +6549,8 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6526,7 +6549,8 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (strstr(p, "skip_keycodes") == p) { } else if (strstr(p, "skip_keycodes") == p) {
COLON_CHECK("skip_keycodes:") COLON_CHECK("skip_keycodes:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%s", p, co, NONUL(skip_keycodes)); snprintf(buf, bufn, "ans=%s%s%s", p, co,
NONUL(skip_keycodes));
goto qry; goto qry;
} }
p += strlen("skip_keycodes:"); p += strlen("skip_keycodes:");
...@@ -6549,7 +6573,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6549,7 +6573,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "add_keysyms")) { } else if (!strcmp(p, "add_keysyms")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, add_keysyms); snprintf(buf, bufn, "ans=%s:%d", p, add_keysyms);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: enabling -add_keysyms mode.\n"); rfbLog("process_remote_cmd: enabling -add_keysyms mode.\n");
...@@ -6557,7 +6581,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6557,7 +6581,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "noadd_keysyms")) { } else if (!strcmp(p, "noadd_keysyms")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !add_keysyms); snprintf(buf, bufn, "ans=%s:%d", p, !add_keysyms);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: disabling -add_keysyms mode.\n"); rfbLog("process_remote_cmd: disabling -add_keysyms mode.\n");
...@@ -6565,7 +6589,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6565,7 +6589,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "clear_mods")) { } else if (!strcmp(p, "clear_mods")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, clear_mods == 1); snprintf(buf, bufn, "ans=%s:%d", p, clear_mods == 1);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: enabling -clear_mods mode.\n"); rfbLog("process_remote_cmd: enabling -clear_mods mode.\n");
...@@ -6574,7 +6598,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6574,7 +6598,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "noclear_mods")) { } else if (!strcmp(p, "noclear_mods")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !(clear_mods == 1)); snprintf(buf, bufn, "ans=%s:%d", p, !(clear_mods == 1));
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: disabling -clear_mods mode.\n"); rfbLog("process_remote_cmd: disabling -clear_mods mode.\n");
...@@ -6582,7 +6606,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6582,7 +6606,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "clear_keys")) { } else if (!strcmp(p, "clear_keys")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, clear_mods == 2); snprintf(buf, bufn, "ans=%s:%d", p, clear_mods == 2);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: enabling -clear_keys mode.\n"); rfbLog("process_remote_cmd: enabling -clear_keys mode.\n");
...@@ -6591,7 +6615,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6591,7 +6615,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "noclear_keys")) { } else if (!strcmp(p, "noclear_keys")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !(clear_mods == 2)); snprintf(buf, bufn, "ans=%s:%d", p, !(clear_mods == 2));
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: disabling -clear_keys mode.\n"); rfbLog("process_remote_cmd: disabling -clear_keys mode.\n");
...@@ -6601,7 +6625,8 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6601,7 +6625,8 @@ char *process_remote_cmd(char *cmd, int stringonly) {
char *before, *old; char *before, *old;
COLON_CHECK("remap:") COLON_CHECK("remap:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%s", p, co, NONUL(remap_file)); snprintf(buf, bufn, "ans=%s%s%s", p, co,
NONUL(remap_file));
goto qry; goto qry;
} }
p += strlen("remap:"); p += strlen("remap:");
...@@ -6609,7 +6634,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6609,7 +6634,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
strchr(remap_file, '/')) { strchr(remap_file, '/')) {
rfbLog("process_remote_cmd: cannot use remap:+/-\n"); rfbLog("process_remote_cmd: cannot use remap:+/-\n");
rfbLog("in '-remap %s' mode.\n", remap_file); rfbLog("in '-remap %s' mode.\n", remap_file);
return NULL; goto done;
} }
if (remap_file) { if (remap_file) {
before = strdup(remap_file); before = strdup(remap_file);
...@@ -6640,7 +6665,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6640,7 +6665,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "repeat")) { } else if (!strcmp(p, "repeat")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !no_autorepeat); snprintf(buf, bufn, "ans=%s:%d", p, !no_autorepeat);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: enabling -repeat mode.\n"); rfbLog("process_remote_cmd: enabling -repeat mode.\n");
...@@ -6651,7 +6676,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6651,7 +6676,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "norepeat")) { } else if (!strcmp(p, "norepeat")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, no_autorepeat); snprintf(buf, bufn, "ans=%s:%d", p, no_autorepeat);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: enabling -norepeat mode.\n"); rfbLog("process_remote_cmd: enabling -norepeat mode.\n");
...@@ -6663,7 +6688,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6663,7 +6688,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "bell")) { } else if (!strcmp(p, "bell")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, sound_bell); snprintf(buf, bufn, "ans=%s:%d", p, sound_bell);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: enabling bell (if supported).\n"); rfbLog("process_remote_cmd: enabling bell (if supported).\n");
...@@ -6671,7 +6696,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6671,7 +6696,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "nobell")) { } else if (!strcmp(p, "nobell")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !sound_bell); snprintf(buf, bufn, "ans=%s:%d", p, !sound_bell);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: disabling bell.\n"); rfbLog("process_remote_cmd: disabling bell.\n");
...@@ -6679,7 +6704,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6679,7 +6704,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "sel")) { } else if (!strcmp(p, "sel")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, watch_selection); snprintf(buf, bufn, "ans=%s:%d", p, watch_selection);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: enabling watch_selection.\n"); rfbLog("process_remote_cmd: enabling watch_selection.\n");
...@@ -6687,7 +6712,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6687,7 +6712,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "nosel")) { } else if (!strcmp(p, "nosel")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !watch_selection); snprintf(buf, bufn, "ans=%s:%d", p, !watch_selection);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: disabling watch_selection.\n"); rfbLog("process_remote_cmd: disabling watch_selection.\n");
...@@ -6695,7 +6720,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6695,7 +6720,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "primary")) { } else if (!strcmp(p, "primary")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, watch_primary); snprintf(buf, bufn, "ans=%s:%d", p, watch_primary);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: enabling watch_primary.\n"); rfbLog("process_remote_cmd: enabling watch_primary.\n");
...@@ -6703,7 +6728,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6703,7 +6728,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "noprimary")) { } else if (!strcmp(p, "noprimary")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !watch_primary); snprintf(buf, bufn, "ans=%s:%d", p, !watch_primary);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: disabling watch_primary.\n"); rfbLog("process_remote_cmd: disabling watch_primary.\n");
...@@ -6715,7 +6740,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6715,7 +6740,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "cursorshape")) { } else if (!strcmp(p, "cursorshape")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, cursor_shape_updates); snprintf(buf, bufn, "ans=%s:%d", p, cursor_shape_updates);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning on cursorshape mode.\n"); rfbLog("process_remote_cmd: turning on cursorshape mode.\n");
...@@ -6727,7 +6752,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6727,7 +6752,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "nocursorshape")) { } else if (!strcmp(p, "nocursorshape")) {
int i, max = 5; int i, max = 5;
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !cursor_shape_updates); snprintf(buf, bufn, "ans=%s:%d", p, !cursor_shape_updates);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning off cursorshape mode.\n"); rfbLog("process_remote_cmd: turning off cursorshape mode.\n");
...@@ -6743,14 +6768,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6743,14 +6768,14 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "cursorpos")) { } else if (!strcmp(p, "cursorpos")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, cursor_pos_updates); snprintf(buf, bufn, "ans=%s:%d", p, cursor_pos_updates);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning on cursorpos mode.\n"); rfbLog("process_remote_cmd: turning on cursorpos mode.\n");
cursor_pos_updates = 1; cursor_pos_updates = 1;
} else if (!strcmp(p, "nocursorpos")) { } else if (!strcmp(p, "nocursorpos")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !cursor_pos_updates); snprintf(buf, bufn, "ans=%s:%d", p, !cursor_pos_updates);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning off cursorpos mode.\n"); rfbLog("process_remote_cmd: turning off cursorpos mode.\n");
...@@ -6759,7 +6784,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6759,7 +6784,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (strstr(p, "cursor") == p) { } else if (strstr(p, "cursor") == p) {
COLON_CHECK("cursor:") COLON_CHECK("cursor:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%s", p, co, snprintf(buf, bufn, "ans=%s%s%s", p, co,
NONUL(multiple_cursors_mode)); NONUL(multiple_cursors_mode));
goto qry; goto qry;
} }
...@@ -6783,7 +6808,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6783,7 +6808,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "show_cursor")) { } else if (!strcmp(p, "show_cursor")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, show_cursor); snprintf(buf, bufn, "ans=%s:%d", p, show_cursor);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: enabling show_cursor.\n"); rfbLog("process_remote_cmd: enabling show_cursor.\n");
...@@ -6803,7 +6828,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6803,7 +6828,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
initialize_cursors_mode(); initialize_cursors_mode();
} else if (!strcmp(p, "noshow_cursor") || !strcmp(p, "nocursor")) { } else if (!strcmp(p, "noshow_cursor") || !strcmp(p, "nocursor")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !show_cursor); snprintf(buf, bufn, "ans=%s:%d", p, !show_cursor);
goto qry; goto qry;
} }
if (prev_cursors_mode) free(prev_cursors_mode); if (prev_cursors_mode) free(prev_cursors_mode);
...@@ -6815,13 +6840,13 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6815,13 +6840,13 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "xfixes")) { } else if (!strcmp(p, "xfixes")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, use_xfixes); snprintf(buf, bufn, "ans=%s:%d", p, use_xfixes);
goto qry; goto qry;
} }
if (! xfixes_present) { if (! xfixes_present) {
rfbLog("process_remote_cmd: cannot enable xfixes " rfbLog("process_remote_cmd: cannot enable xfixes "
"(not supported on X display)\n"); "(not supported on X display)\n");
return NULL; goto done;
} }
rfbLog("process_remote_cmd: enabling -xfixes" rfbLog("process_remote_cmd: enabling -xfixes"
" (if supported).\n"); " (if supported).\n");
...@@ -6829,28 +6854,28 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6829,28 +6854,28 @@ char *process_remote_cmd(char *cmd, int stringonly) {
initialize_xfixes(); initialize_xfixes();
} else if (!strcmp(p, "noxfixes")) { } else if (!strcmp(p, "noxfixes")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !use_xfixes); snprintf(buf, bufn, "ans=%s:%d", p, !use_xfixes);
goto qry; goto qry;
} }
if (! xfixes_present) { if (! xfixes_present) {
rfbLog("process_remote_cmd: disabling xfixes " rfbLog("process_remote_cmd: disabling xfixes "
"(but not supported on X display)\n"); "(but not supported on X display)\n");
return NULL; goto done;
} }
rfbLog("process_remote_cmd: disabling -xfixes.\n"); rfbLog("process_remote_cmd: disabling -xfixes.\n");
use_xfixes = 0; use_xfixes = 0;
initialize_xfixes(); initialize_xfixes();
} else if (strstr(p, "xwarp") == p || strstr(p, "xwarppointer")) { } else if (strstr(p, "xwarp") == p || strstr(p, "xwarppointer") == p) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, use_xwarppointer); snprintf(buf, bufn, "ans=%s:%d", p, use_xwarppointer);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning on xwarppointer mode.\n"); rfbLog("process_remote_cmd: turning on xwarppointer mode.\n");
use_xwarppointer = 1; use_xwarppointer = 1;
} else if (strstr(p, "noxwarp") == p || strstr(p, "noxwarppointer")) { } else if (strstr(p, "noxwarp") == p || strstr(p, "noxwarppointer") == p) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !use_xwarppointer); snprintf(buf, bufn, "ans=%s:%d", p, !use_xwarppointer);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning off xwarppointer mode.\n"); rfbLog("process_remote_cmd: turning off xwarppointer mode.\n");
...@@ -6859,7 +6884,8 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6859,7 +6884,8 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (strstr(p, "buttonmap") == p) { } else if (strstr(p, "buttonmap") == p) {
COLON_CHECK("buttonmap:") COLON_CHECK("buttonmap:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%s", p, co, NONUL(pointer_remap)); snprintf(buf, bufn, "ans=%s%s%s", p, co,
NONUL(pointer_remap));
goto qry; goto qry;
} }
p += strlen("buttonmap:"); p += strlen("buttonmap:");
...@@ -6872,14 +6898,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6872,14 +6898,14 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "dragging")) { } else if (!strcmp(p, "dragging")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, show_dragging); snprintf(buf, bufn, "ans=%s:%d", p, show_dragging);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: enabling mouse dragging mode.\n"); rfbLog("process_remote_cmd: enabling mouse dragging mode.\n");
show_dragging = 1; show_dragging = 1;
} else if (!strcmp(p, "nodragging")) { } else if (!strcmp(p, "nodragging")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !show_dragging); snprintf(buf, bufn, "ans=%s:%d", p, !show_dragging);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: enabling mouse nodragging mode.\n"); rfbLog("process_remote_cmd: enabling mouse nodragging mode.\n");
...@@ -6889,7 +6915,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6889,7 +6915,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
int pm; int pm;
COLON_CHECK("pointer_mode:") COLON_CHECK("pointer_mode:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%d", p, co, pointer_mode); snprintf(buf, bufn, "ans=%s%s%d", p, co, pointer_mode);
goto qry; goto qry;
} }
p += strlen("pointer_mode:"); p += strlen("pointer_mode:");
...@@ -6906,7 +6932,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6906,7 +6932,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
int is; int is;
COLON_CHECK("input_skip:") COLON_CHECK("input_skip:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%d", p, co, ui_skip); snprintf(buf, bufn, "ans=%s%s%d", p, co, ui_skip);
goto qry; goto qry;
} }
p += strlen("input_skip:"); p += strlen("input_skip:");
...@@ -6916,14 +6942,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6916,14 +6942,14 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "debug_pointer") || !strcmp(p, "dp")) { } else if (!strcmp(p, "debug_pointer") || !strcmp(p, "dp")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, debug_pointer); snprintf(buf, bufn, "ans=%s:%d", p, debug_pointer);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning on debug_pointer.\n"); rfbLog("process_remote_cmd: turning on debug_pointer.\n");
debug_pointer = 1; debug_pointer = 1;
} else if (!strcmp(p, "nodebug_pointer") || !strcmp(p, "nodp")) { } else if (!strcmp(p, "nodebug_pointer") || !strcmp(p, "nodp")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !debug_pointer); snprintf(buf, bufn, "ans=%s:%d", p, !debug_pointer);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning off debug_pointer.\n"); rfbLog("process_remote_cmd: turning off debug_pointer.\n");
...@@ -6931,14 +6957,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6931,14 +6957,14 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "debug_keyboard") || !strcmp(p, "dk")) { } else if (!strcmp(p, "debug_keyboard") || !strcmp(p, "dk")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, debug_keyboard); snprintf(buf, bufn, "ans=%s:%d", p, debug_keyboard);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning on debug_keyboard.\n"); rfbLog("process_remote_cmd: turning on debug_keyboard.\n");
debug_keyboard = 1; debug_keyboard = 1;
} else if (!strcmp(p, "nodebug_keyboard") || !strcmp(p, "nodk")) { } else if (!strcmp(p, "nodebug_keyboard") || !strcmp(p, "nodk")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !debug_keyboard); snprintf(buf, bufn, "ans=%s:%d", p, !debug_keyboard);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: turning off debug_keyboard.\n"); rfbLog("process_remote_cmd: turning off debug_keyboard.\n");
...@@ -6948,7 +6974,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6948,7 +6974,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
int d; int d;
COLON_CHECK("deferupdate:") COLON_CHECK("deferupdate:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%d", p, co, snprintf(buf, bufn, "ans=%s%s%d", p, co,
screen->deferUpdateTime); screen->deferUpdateTime);
goto qry; goto qry;
} }
...@@ -6962,7 +6988,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6962,7 +6988,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
int d; int d;
COLON_CHECK("defer:") COLON_CHECK("defer:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%d", p, co, snprintf(buf, bufn, "ans=%s%s%d", p, co,
screen->deferUpdateTime); screen->deferUpdateTime);
goto qry; goto qry;
} }
...@@ -6977,7 +7003,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6977,7 +7003,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
int w; int w;
COLON_CHECK("wait:") COLON_CHECK("wait:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%d", p, co, waitms); snprintf(buf, bufn, "ans=%s%s%d", p, co, waitms);
goto qry; goto qry;
} }
p += strlen("wait:"); p += strlen("wait:");
...@@ -6989,13 +7015,13 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -6989,13 +7015,13 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "nap")) { } else if (!strcmp(p, "nap")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, take_naps); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, take_naps); goto qry;
} }
rfbLog("process_remote_cmd: turning on nap mode.\n"); rfbLog("process_remote_cmd: turning on nap mode.\n");
take_naps = 1; take_naps = 1;
} else if (!strcmp(p, "nonap")) { } else if (!strcmp(p, "nonap")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !take_naps); goto qry; snprintf(buf, bufn, "ans=%s:%d", p, !take_naps); goto qry;
} }
rfbLog("process_remote_cmd: turning off nap mode.\n"); rfbLog("process_remote_cmd: turning off nap mode.\n");
take_naps = 0; take_naps = 0;
...@@ -7004,7 +7030,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -7004,7 +7030,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
int w; int w;
COLON_CHECK("sb:") COLON_CHECK("sb:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%d", p, co, screen_blank); snprintf(buf, bufn, "ans=%s%s%d", p, co, screen_blank);
goto qry; goto qry;
} }
p += strlen("sb:"); p += strlen("sb:");
...@@ -7017,7 +7043,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -7017,7 +7043,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
int w; int w;
COLON_CHECK("screen_blank:") COLON_CHECK("screen_blank:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%d", p, co, screen_blank); snprintf(buf, bufn, "ans=%s%s%d", p, co, screen_blank);
goto qry; goto qry;
} }
p += strlen("screen_blank:"); p += strlen("screen_blank:");
...@@ -7030,7 +7056,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -7030,7 +7056,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (strstr(p, "fs") == p) { } else if (strstr(p, "fs") == p) {
COLON_CHECK("fs:") COLON_CHECK("fs:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%f", p, co, fs_frac); snprintf(buf, bufn, "ans=%s%s%f", p, co, fs_frac);
goto qry; goto qry;
} }
p += strlen("fs:"); p += strlen("fs:");
...@@ -7041,7 +7067,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -7041,7 +7067,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
int g; int g;
COLON_CHECK("gaps:") COLON_CHECK("gaps:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%d", p, co, gaps_fill); snprintf(buf, bufn, "ans=%s%s%d", p, co, gaps_fill);
goto qry; goto qry;
} }
p += strlen("gaps:"); p += strlen("gaps:");
...@@ -7054,7 +7080,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -7054,7 +7080,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
int g; int g;
COLON_CHECK("grow:") COLON_CHECK("grow:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%d", p, co, grow_fill); snprintf(buf, bufn, "ans=%s%s%d", p, co, grow_fill);
goto qry; goto qry;
} }
p += strlen("grow:"); p += strlen("grow:");
...@@ -7067,7 +7093,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -7067,7 +7093,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
int f; int f;
COLON_CHECK("fuzz:") COLON_CHECK("fuzz:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%d", p, co, tile_fuzz); snprintf(buf, bufn, "ans=%s%s%d", p, co, tile_fuzz);
goto qry; goto qry;
} }
p += strlen("fuzz:"); p += strlen("fuzz:");
...@@ -7081,7 +7107,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -7081,7 +7107,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
int f; int f;
COLON_CHECK("progressive:") COLON_CHECK("progressive:")
if (query) { if (query) {
sprintf(buf, "ans=%s%s%d", p, co, snprintf(buf, bufn, "ans=%s%s%d", p, co,
screen->progressiveSliceHeight); screen->progressiveSliceHeight);
goto qry; goto qry;
} }
...@@ -7094,7 +7120,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -7094,7 +7120,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "noremote")) { } else if (!strcmp(p, "noremote")) {
if (query) { if (query) {
sprintf(buf, "ans=%s:%d", p, !accept_remote_cmds); snprintf(buf, bufn, "ans=%s:%d", p, !accept_remote_cmds);
goto qry; goto qry;
} }
rfbLog("process_remote_cmd: disabling remote commands.\n"); rfbLog("process_remote_cmd: disabling remote commands.\n");
...@@ -7107,114 +7133,119 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -7107,114 +7133,119 @@ char *process_remote_cmd(char *cmd, int stringonly) {
char *d = DisplayString(dpy); char *d = DisplayString(dpy);
if (! d) d = "unknown"; if (! d) d = "unknown";
if (*d == ':') { if (*d == ':') {
sprintf(buf, "aro=%s:%s%s", p, this_host(), d); snprintf(buf, bufn, "aro=%s:%s%s", p,
this_host(), d);
} else { } else {
sprintf(buf, "aro=%s:%s", p, d); snprintf(buf, bufn, "aro=%s:%s", p, d);
} }
} else if (!strcmp(p, "vncdisplay")) { } else if (!strcmp(p, "vncdisplay")) {
sprintf(buf, "aro=%s:%s", p, NONUL(vnc_desktop_name)); snprintf(buf, bufn, "aro=%s:%s", p,
NONUL(vnc_desktop_name));
} else if (!strcmp(p, "desktopname")) { } else if (!strcmp(p, "desktopname")) {
sprintf(buf, "aro=%s:%s", p, NONUL(rfb_desktop_name)); snprintf(buf, bufn, "aro=%s:%s", p,
NONUL(rfb_desktop_name));
} else if (!strcmp(p, "desktop")) { } else if (!strcmp(p, "desktop")) {
sprintf(buf, "aro=%s:%s", p, NONUL(rfb_desktop_name)); snprintf(buf, bufn, "aro=%s:%s", p,
NONUL(rfb_desktop_name));
} else if (!strcmp(p, "auth")) { } else if (!strcmp(p, "auth")) {
sprintf(buf, "aro=%s:%s", p, NONUL(auth_file)); snprintf(buf, bufn, "aro=%s:%s", p, NONUL(auth_file));
} else if (!strcmp(p, "rootshift")) { } else if (!strcmp(p, "rootshift")) {
sprintf(buf, "aro=%s:%d", p, rootshift); snprintf(buf, bufn, "aro=%s:%d", p, rootshift);
} else if (!strcmp(p, "scale_str")) { } else if (!strcmp(p, "scale_str")) {
sprintf(buf, "aro=%s:%s", p, NONUL(scale_str)); snprintf(buf, bufn, "aro=%s:%s", p, NONUL(scale_str));
} else if (!strcmp(p, "scaled_x")) { } else if (!strcmp(p, "scaled_x")) {
sprintf(buf, "aro=%s:%d", p, scaled_x); snprintf(buf, bufn, "aro=%s:%d", p, scaled_x);
} else if (!strcmp(p, "scaled_y")) { } else if (!strcmp(p, "scaled_y")) {
sprintf(buf, "aro=%s:%d", p, scaled_y); snprintf(buf, bufn, "aro=%s:%d", p, scaled_y);
} else if (!strcmp(p, "scale_numer")) { } else if (!strcmp(p, "scale_numer")) {
sprintf(buf, "aro=%s:%d", p, scale_numer); snprintf(buf, bufn, "aro=%s:%d", p, scale_numer);
} else if (!strcmp(p, "scale_denom")) { } else if (!strcmp(p, "scale_denom")) {
sprintf(buf, "aro=%s:%d", p, scale_denom); snprintf(buf, bufn, "aro=%s:%d", p, scale_denom);
} else if (!strcmp(p, "scale_fac")) { } else if (!strcmp(p, "scale_fac")) {
sprintf(buf, "aro=%s:%f", p, scale_fac); snprintf(buf, bufn, "aro=%s:%f", p, scale_fac);
} else if (!strcmp(p, "scaling_noblend")) { } else if (!strcmp(p, "scaling_noblend")) {
sprintf(buf, "aro=%s:%d", p, scaling_noblend); snprintf(buf, bufn, "aro=%s:%d", p, scaling_noblend);
} else if (!strcmp(p, "scaling_nomult4")) { } else if (!strcmp(p, "scaling_nomult4")) {
sprintf(buf, "aro=%s:%d", p, scaling_nomult4); snprintf(buf, bufn, "aro=%s:%d", p, scaling_nomult4);
} else if (!strcmp(p, "scaling_pad")) { } else if (!strcmp(p, "scaling_pad")) {
sprintf(buf, "aro=%s:%d", p, scaling_pad); snprintf(buf, bufn, "aro=%s:%d", p, scaling_pad);
} else if (!strcmp(p, "scaling_interpolate")) { } else if (!strcmp(p, "scaling_interpolate")) {
sprintf(buf, "aro=%s:%d", p, scaling_interpolate); snprintf(buf, bufn, "aro=%s:%d", p, scaling_interpolate);
} else if (!strcmp(p, "inetd")) { } else if (!strcmp(p, "inetd")) {
sprintf(buf, "aro=%s:%d", p, inetd); snprintf(buf, bufn, "aro=%s:%d", p, inetd);
} else if (!strcmp(p, "safer")) { } else if (!strcmp(p, "safer")) {
sprintf(buf, "aro=%s:%d", p, safe_remote_only); snprintf(buf, bufn, "aro=%s:%d", p, safe_remote_only);
} else if (!strcmp(p, "unsafe")) { } else if (!strcmp(p, "unsafe")) {
sprintf(buf, "aro=%s:%d", p, !safe_remote_only); snprintf(buf, bufn, "aro=%s:%d", p, !safe_remote_only);
} else if (!strcmp(p, "passwdfile")) { } else if (!strcmp(p, "passwdfile")) {
sprintf(buf, "aro=%s:%s", p, NONUL(passwdfile)); snprintf(buf, bufn, "aro=%s:%s", p, NONUL(passwdfile));
} else if (!strcmp(p, "using_shm")) { } else if (!strcmp(p, "using_shm")) {
sprintf(buf, "aro=%s:%d", p, !using_shm); snprintf(buf, bufn, "aro=%s:%d", p, !using_shm);
} else if (!strcmp(p, "logfile") || !strcmp(p, "o")) { } else if (!strcmp(p, "logfile") || !strcmp(p, "o")) {
sprintf(buf, "aro=%s:%s", p, NONUL(logfile)); snprintf(buf, bufn, "aro=%s:%s", p, NONUL(logfile));
} else if (!strcmp(p, "rc")) { } else if (!strcmp(p, "rc")) {
sprintf(buf, "aro=%s:%s", p, NONUL(rc_rcfile)); snprintf(buf, bufn, "aro=%s:%s", p, NONUL(rc_rcfile));
} else if (!strcmp(p, "norc")) { } else if (!strcmp(p, "norc")) {
sprintf(buf, "aro=%s:%d", p, rc_norc); snprintf(buf, bufn, "aro=%s:%d", p, rc_norc);
} else if (!strcmp(p, "h") || !strcmp(p, "help") || } else if (!strcmp(p, "h") || !strcmp(p, "help") ||
!strcmp(p, "V") || !strcmp(p, "version") || !strcmp(p, "V") || !strcmp(p, "version") ||
!strcmp(p, "lastmod")) { !strcmp(p, "lastmod")) {
sprintf(buf, "aro=%s:%s", p, NONUL(lastmod)); snprintf(buf, bufn, "aro=%s:%s", p, NONUL(lastmod));
} else if (!strcmp(p, "bg")) { } else if (!strcmp(p, "bg")) {
sprintf(buf, "aro=%s:%d", p, opts_bg); snprintf(buf, bufn, "aro=%s:%d", p, opts_bg);
} else if (!strcmp(p, "nofb")) { } else if (!strcmp(p, "nofb")) {
sprintf(buf, "aro=%s:%d", p, nofb); snprintf(buf, bufn, "aro=%s:%d", p, nofb);
} else if (!strcmp(p, "sigpipe")) { } else if (!strcmp(p, "sigpipe")) {
sprintf(buf, "aro=%s:%s", p, NONUL(sigpipe)); snprintf(buf, bufn, "aro=%s:%s", p, NONUL(sigpipe));
} else if (!strcmp(p, "threads")) { } else if (!strcmp(p, "threads")) {
sprintf(buf, "aro=%s:%d", p, use_threads); snprintf(buf, bufn, "aro=%s:%d", p, use_threads);
} else if (!strcmp(p, "clients")) { } else if (!strcmp(p, "clients")) {
char *str = list_clients(); char *str = list_clients();
sprintf(buf, "aro=%s:%s", p, str); snprintf(buf, bufn, "aro=%s:%s", p, str);
free(str); free(str);
} else if (!strcmp(p, "client_count")) { } else if (!strcmp(p, "client_count")) {
sprintf(buf, "aro=%s:%d", p, client_count); snprintf(buf, bufn, "aro=%s:%d", p, client_count);
} else if (!strcmp(p, "pid")) { } else if (!strcmp(p, "pid")) {
sprintf(buf, "aro=%s:%d", p, (int) getpid()); snprintf(buf, bufn, "aro=%s:%d", p, (int) getpid());
} else if (!strcmp(p, "ext_xtest")) { } else if (!strcmp(p, "ext_xtest")) {
sprintf(buf, "aro=%s:%d", p, xtest_present); snprintf(buf, bufn, "aro=%s:%d", p, xtest_present);
} else if (!strcmp(p, "ext_xkb")) { } else if (!strcmp(p, "ext_xkb")) {
sprintf(buf, "aro=%s:%d", p, xkb_present); snprintf(buf, bufn, "aro=%s:%d", p, xkb_present);
} else if (!strcmp(p, "ext_xshm")) { } else if (!strcmp(p, "ext_xshm")) {
sprintf(buf, "aro=%s:%d", p, xshm_present); snprintf(buf, bufn, "aro=%s:%d", p, xshm_present);
} else if (!strcmp(p, "ext_xinerama")) { } else if (!strcmp(p, "ext_xinerama")) {
sprintf(buf, "aro=%s:%d", p, xinerama_present); snprintf(buf, bufn, "aro=%s:%d", p, xinerama_present);
} else if (!strcmp(p, "ext_overlay")) { } else if (!strcmp(p, "ext_overlay")) {
sprintf(buf, "aro=%s:%d", p, overlay_present); snprintf(buf, bufn, "aro=%s:%d", p, overlay_present);
} else if (!strcmp(p, "ext_xfixes")) { } else if (!strcmp(p, "ext_xfixes")) {
sprintf(buf, "aro=%s:%d", p, xfixes_present); snprintf(buf, bufn, "aro=%s:%d", p, xfixes_present);
} else if (!strcmp(p, "ext_xdamage")) { } else if (!strcmp(p, "ext_xdamage")) {
sprintf(buf, "aro=%s:%d", p, xdamage_present); snprintf(buf, bufn, "aro=%s:%d", p, xdamage_present);
} else if (!strcmp(p, "ext_xrandr")) { } else if (!strcmp(p, "ext_xrandr")) {
sprintf(buf, "aro=%s:%d", p, xrandr_present); snprintf(buf, bufn, "aro=%s:%d", p, xrandr_present);
} else if (!strcmp(p, "rootwin")) { } else if (!strcmp(p, "rootwin")) {
sprintf(buf, "aro=%s:0x%x", p, (unsigned int) rootwin); snprintf(buf, bufn, "aro=%s:0x%x", p,
(unsigned int) rootwin);
} else if (!strcmp(p, "num_buttons")) { } else if (!strcmp(p, "num_buttons")) {
sprintf(buf, "aro=%s:%d", p, num_buttons); snprintf(buf, bufn, "aro=%s:%d", p, num_buttons);
} else if (!strcmp(p, "button_mask")) { } else if (!strcmp(p, "button_mask")) {
sprintf(buf, "aro=%s:%d", p, button_mask); snprintf(buf, bufn, "aro=%s:%d", p, button_mask);
} else if (!strcmp(p, "mouse_x")) { } else if (!strcmp(p, "mouse_x")) {
sprintf(buf, "aro=%s:%d", p, cursor_x); snprintf(buf, bufn, "aro=%s:%d", p, cursor_x);
} else if (!strcmp(p, "mouse_y")) { } else if (!strcmp(p, "mouse_y")) {
sprintf(buf, "aro=%s:%d", p, cursor_y); snprintf(buf, bufn, "aro=%s:%d", p, cursor_y);
} else if (!strcmp(p, "bpp")) { } else if (!strcmp(p, "bpp")) {
sprintf(buf, "aro=%s:%d", p, bpp); snprintf(buf, bufn, "aro=%s:%d", p, bpp);
} else if (!strcmp(p, "depth")) { } else if (!strcmp(p, "depth")) {
sprintf(buf, "aro=%s:%d", p, depth); snprintf(buf, bufn, "aro=%s:%d", p, depth);
} else if (!strcmp(p, "indexed_color")) { } else if (!strcmp(p, "indexed_color")) {
sprintf(buf, "aro=%s:%d", p, indexed_color); snprintf(buf, bufn, "aro=%s:%d", p, indexed_color);
} else if (!strcmp(p, "dpy_x")) { } else if (!strcmp(p, "dpy_x")) {
sprintf(buf, "aro=%s:%d", p, dpy_x); snprintf(buf, bufn, "aro=%s:%d", p, dpy_x);
} else if (!strcmp(p, "dpy_y")) { } else if (!strcmp(p, "dpy_y")) {
sprintf(buf, "aro=%s:%d", p, dpy_y); snprintf(buf, bufn, "aro=%s:%d", p, dpy_y);
} else if (!strcmp(p, "rfbport")) { } else if (!strcmp(p, "rfbport")) {
sprintf(buf, "aro=%s:%d", p, screen->port); snprintf(buf, bufn, "aro=%s:%d", p, screen->port);
} else if (!strcmp(p, "rfbwait")) { } else if (!strcmp(p, "rfbwait")) {
NOTAPPRO NOTAPPRO
} else if (!strcmp(p, "rfbauth")) { } else if (!strcmp(p, "rfbauth")) {
...@@ -7222,33 +7253,34 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -7222,33 +7253,34 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "passwd")) { } else if (!strcmp(p, "passwd")) {
NOTAPPRO NOTAPPRO
} else if (!strcmp(p, "alwaysshared")) { } else if (!strcmp(p, "alwaysshared")) {
sprintf(buf, "aro=%s:%d", p, screen->alwaysShared); snprintf(buf, bufn, "aro=%s:%d", p, screen->alwaysShared);
} else if (!strcmp(p, "dontdisconnect")) { } else if (!strcmp(p, "dontdisconnect")) {
sprintf(buf, "aro=%s:%d", p, screen->dontDisconnect); snprintf(buf, bufn, "aro=%s:%d", p,
screen->dontDisconnect);
} else if (!strcmp(p, "httpdir")) { } else if (!strcmp(p, "httpdir")) {
sprintf(buf, "aro=%s:%s", p, NONUL(screen->httpDir)); snprintf(buf, bufn, "aro=%s:%s", p,
NONUL(screen->httpDir));
} else if (!strcmp(p, "enablehttpproxy")) { } else if (!strcmp(p, "enablehttpproxy")) {
sprintf(buf, "aro=%s:%d", p, snprintf(buf, bufn, "aro=%s:%d", p,
screen->httpEnableProxyConnect); screen->httpEnableProxyConnect);
} else { } else {
NOTAPP NOTAPP
} }
goto qry; goto qry;
} else { } else {
char tmp[100];
NOTAPP NOTAPP
rfbLog("process_remote_cmd: warning unknown\n"); rfbLog("process_remote_cmd: warning unknown\n");
rfbLog("command \"%s\"\n", p); strncpy(tmp, p, 90);
return NULL; rfbLog("command \"%s\"\n", tmp);
} goto done;
if (*p != '\0' && do_vnc_connect) {
/* this is a reverse connection */
strncpy(vnc_connect_str, p, VNC_CONNECT_MAX);
vnc_connect_str[VNC_CONNECT_MAX] = '\0';
} }
done: done:
return NULL;
if (*buf == '\0') {
sprintf(buf, "ack=1");
}
qry: qry:
...@@ -7259,7 +7291,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -7259,7 +7291,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
if (out != NULL) { if (out != NULL) {
fprintf(out, "%s\n", buf); fprintf(out, "%s\n", buf);
fclose(out); fclose(out);
usleep(200*1000); usleep(20*1000);
} }
} else { } else {
set_vnc_connect_prop(buf); set_vnc_connect_prop(buf);
...@@ -8418,7 +8450,11 @@ void cursor_position(int x, int y) { ...@@ -8418,7 +8450,11 @@ void cursor_position(int x, int y) {
} }
void set_rfb_cursor(int which) { void set_rfb_cursor(int which) {
int workaround = 2; /* if rfbSetCursor does not mark modified */ int workaround = 1; /* if rfbSetCursor does not mark modified */
#if OLD_TREE
workaround = 2;
#endif
if (! show_cursor) { if (! show_cursor) {
return; return;
...@@ -8711,6 +8747,7 @@ void set_visual(char *str) { ...@@ -8711,6 +8747,7 @@ void set_visual(char *str) {
return; return;
} }
rfbLog("bad -visual arg: %s\n", vstring); rfbLog("bad -visual arg: %s\n", vstring);
X_UNLOCK;
clean_up_exit(1); clean_up_exit(1);
} }
visual_id = (VisualID) v_in; visual_id = (VisualID) v_in;
...@@ -8725,6 +8762,7 @@ void set_visual(char *str) { ...@@ -8725,6 +8762,7 @@ void set_visual(char *str) {
; ;
} else { } else {
rfbLog("could not find visual: %s\n", vstring); rfbLog("could not find visual: %s\n", vstring);
X_UNLOCK;
clean_up_exit(1); clean_up_exit(1);
} }
free(vstring); free(vstring);
...@@ -12197,13 +12235,13 @@ char gui_code[] = ""; ...@@ -12197,13 +12235,13 @@ char gui_code[] = "";
void run_gui(char *gui_xdisplay, int connect_to_x11vnc) { void run_gui(char *gui_xdisplay, int connect_to_x11vnc) {
char *x11vnc_xdisplay = NULL; char *x11vnc_xdisplay = NULL;
char extra_path[] = ":/usr/local/bin:/usr/sfw/bin:/usr/X11R6/bin"; char extra_path[] = ":/usr/local/bin:/usr/bin/X11:/usr/sfw/bin"
":/usr/X11R6/bin:/usr/openwin/bin:/usr/dt/bin";
char cmd[100]; char cmd[100];
char *wish, *orig_path, *full_path, *tpath, *p; char *wish = NULL, *orig_path, *full_path, *tpath, *p;
int try_max = 9, sleep = 300; int try_max = 9, sleep = 300;
FILE *pipe; FILE *pipe;
if (getenv("DISPLAY") != NULL) { if (getenv("DISPLAY") != NULL) {
x11vnc_xdisplay = strdup(getenv("DISPLAY")); x11vnc_xdisplay = strdup(getenv("DISPLAY"));
} }
...@@ -12212,10 +12250,11 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc) { ...@@ -12212,10 +12250,11 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc) {
} }
if (connect_to_x11vnc) { if (connect_to_x11vnc) {
int rc, i; int rc, i;
rfbLogEnable(0);
if (! client_connect_file) { if (! client_connect_file) {
dpy = XOpenDisplay(x11vnc_xdisplay); dpy = XOpenDisplay(x11vnc_xdisplay);
if (! dpy) { if (! dpy) {
fprintf(stderr, "could not open display: %s\n", fprintf(stderr, "gui: could not open display: %s\n",
x11vnc_xdisplay); x11vnc_xdisplay);
exit(1); exit(1);
} }
...@@ -12223,22 +12262,23 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc) { ...@@ -12223,22 +12262,23 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc) {
rootwin = RootWindow(dpy, scr); rootwin = RootWindow(dpy, scr);
initialize_vnc_connect_prop(); initialize_vnc_connect_prop();
} }
usleep(1000*1000);
for (i=0; i<try_max; i++) { for (i=0; i<try_max; i++) {
usleep(sleep*1000); usleep(sleep*1000);
fprintf(stderr, "pinging %s ...\n", fprintf(stderr, "gui: pinging %s try=%d ...\n",
NONUL(x11vnc_xdisplay)); NONUL(x11vnc_xdisplay), i+1);
rc = send_remote_cmd("ping", 1); rc = send_remote_cmd("qry=ping", 1, 1);
if (rc == 0) { if (rc == 0) {
break; break;
} }
} }
if (rc == 0) { if (rc == 0) {
fprintf(stderr, "success.\n"); fprintf(stderr, "gui: ping succeeded.\n");
set_env("X11VNC_XDISPLAY", x11vnc_xdisplay); set_env("X11VNC_XDISPLAY", x11vnc_xdisplay);
set_env("X11VNC_CONNECT", "1"); set_env("X11VNC_CONNECT", "1");
} else { } else {
fprintf(stderr, "could not connect to: '%s', try again" fprintf(stderr, "gui: could not connect to: '%s', try"
" in the gui.\n", x11vnc_xdisplay); " again manually.\n", x11vnc_xdisplay);
} }
} }
...@@ -12262,9 +12302,9 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc) { ...@@ -12262,9 +12302,9 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc) {
try = (char *)malloc(strlen(p) + 10); try = (char *)malloc(strlen(p) + 10);
for (i=0; i<nwishes; i++) { for (i=0; i<nwishes; i++) {
sprintf(try, "%s/%s", p, wishes[i]); sprintf(try, "%s/%s", p, wishes[i]);
if (stat(try, &sbuf)) { if (stat(try, &sbuf) == 0) {
/* assume executable, should check mode */
wish = wishes[i]; wish = wishes[i];
break;
} }
} }
free(try); free(try);
...@@ -12282,7 +12322,6 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc) { ...@@ -12282,7 +12322,6 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc) {
set_env("X11VNC_PROG", program_name); set_env("X11VNC_PROG", program_name);
set_env("X11VNC_CMDLINE", program_cmdline); set_env("X11VNC_CMDLINE", program_cmdline);
if (0) system("env");
sprintf(cmd, "%s -", wish); sprintf(cmd, "%s -", wish);
pipe = popen(cmd, "w"); pipe = popen(cmd, "w");
if (! pipe) { if (! pipe) {
...@@ -13332,25 +13371,33 @@ static void print_help(void) { ...@@ -13332,25 +13371,33 @@ static void print_help(void) {
" initial state of the modifier is ignored and not reset)\n" " initial state of the modifier is ignored and not reset)\n"
" To include button events use \"Button1\", ... etc.\n" " To include button events use \"Button1\", ... etc.\n"
"\n" "\n"
"-nodragging Do not update the display during mouse dragging events\n" "-nodragging Do not update the display during mouse dragging\n"
" (mouse motion with a button held down). Greatly\n" " events (mouse motion with a button held down).\n"
" improves response on slow setups, but you lose all\n" " Greatly improves response on slow setups, but you lose\n"
" visual feedback for drags, text selection, and some\n" " all visual feedback for drags, text selection, and some\n"
" menu traversals.\n" " menu traversals. It overrides any -pointer_mode setting\n"
" (think of it as pointer_mode 0)\n"
"-pointer_mode n Various pointer update schemes. The problem is pointer\n" "-pointer_mode n Various pointer update schemes. The problem is pointer\n"
" motion can cause rapid changes on the screen, e.g. a\n" " motion can cause rapid changes on the screen, e.g. a\n"
" window drag. Neither x11vnc nor the bandwidth to the\n" " window drag. Neither x11vnc's screen polling nor the\n"
" vncviewers can keep up these rapid screen changes:\n" " bandwidth to the vncviewers can keep up these rapid\n"
" everything bogs down when dragging or scrolling.\n" " screen changes: everything bogs down when dragging\n"
" Note that most video h/w is optimized for writing, not\n" " or scrolling. Note that most video h/w is optimized\n"
" reading (a 50X rate difference is possible) and x11vnc\n" " for writing, not reading (a 50X rate difference is\n"
" is reading all the time. So a scheme has to be used to\n" " possible) and x11vnc is reading all the time. So a\n"
" \"eat\" much of that pointer input before re-polling the\n" " scheme has to be used to \"eat\" much of that pointer\n"
" screen. n can be 1 to %d. n=1 was the original scheme\n" " input before re-polling the screen. n can be 1 to %d.\n"
" used to about Jan 2004. n=2 is an improved scheme.\n" "\n"
" n=3 is basically a dynamic -nodragging mode: it detects\n" " n=1 was the original scheme used to about Jan 2004: it\n"
" if the mouse drag motion has paused and refreshes\n" " basically just skips -input_skip pointer events before\n"
" the display. n=4 is TBD. The default n is %d.\n" " repolling the screen. n=2 is an improved scheme:\n"
" by watching the current rate it tries to detect if\n"
" it should try to \"eat\" more pointer events. n=3 is\n"
" basically a dynamic -nodragging mode: it detects if the\n"
" mouse drag motion has paused and refreshes the display.\n"
" n=4 is TBD, it will try measure screen read and client\n"
" write rates and try to insert \"frames\" between the\n"
" on/off states of mode 3. The default n is %d.\n"
"-input_skip n For the pointer handling when non-threaded: try to\n" "-input_skip n For the pointer handling when non-threaded: try to\n"
" read n user input events before scanning display. n < 0\n" " read n user input events before scanning display. n < 0\n"
" means to act as though there is always user input.\n" " means to act as though there is always user input.\n"
...@@ -13667,6 +13714,25 @@ static void print_help(void) { ...@@ -13667,6 +13714,25 @@ static void print_help(void) {
" dpy_x dpy_y rfbport rfbwait rfbauth passwd alwaysshared\n" " dpy_x dpy_y rfbport rfbwait rfbauth passwd alwaysshared\n"
" dontdisconnect httpdir enablehttpproxy\n" " dontdisconnect httpdir enablehttpproxy\n"
"\n" "\n"
"-sync By default -remote commands are run asynchronously, that\n"
" is, the request is posted and the program immediately\n"
" exits. Use -sync to have the program wait for an\n"
" acknowledgement from the x11vnc server that command\n"
" was processed. On the other hand -query requests are\n"
" always processed synchronously because they have wait\n"
" for the result.\n"
"\n"
" Also note that if both -remote and -query requests are\n"
" supplied on the command line, the -remote is processed\n"
" first (synchronously: no need for -sync), and then\n"
" the -query request is processed in the normal way.\n"
" This allows for a reliable way to see if the -remote\n"
" command was processed by querying for any new settings.\n"
" Note however that there is timeout of a few seconds so\n"
" if the x11vnc takes longer than that to process the\n"
" requests the requestor will think that a failure has\n"
" taken place.\n"
"\n"
"-noremote Do not process any remote control commands or queries.\n" "-noremote Do not process any remote control commands or queries.\n"
"\n" "\n"
" A note about security wrt remote control commands.\n" " A note about security wrt remote control commands.\n"
...@@ -13825,6 +13891,7 @@ static void check_rcfile(int argc, char **argv) { ...@@ -13825,6 +13891,7 @@ static void check_rcfile(int argc, char **argv) {
} }
} }
rc_norc = norc; rc_norc = norc;
rc_rcfile = strdup("");
if (norc) { if (norc) {
; ;
} else if (infile != NULL) { } else if (infile != NULL) {
...@@ -13842,9 +13909,10 @@ static void check_rcfile(int argc, char **argv) { ...@@ -13842,9 +13909,10 @@ static void check_rcfile(int argc, char **argv) {
strcat(rcfile, "/.x11vncrc"); strcat(rcfile, "/.x11vncrc");
infile = rcfile; infile = rcfile;
rc = fopen(rcfile, "r"); rc = fopen(rcfile, "r");
rc_rcfile = strdup(rcfile);
if (rc == NULL) { if (rc == NULL) {
norc = 1; norc = 1;
} else {
rc_rcfile = strdup(rcfile);
} }
} }
...@@ -13980,9 +14048,10 @@ int main(int argc, char* argv[]) { ...@@ -13980,9 +14048,10 @@ int main(int argc, char* argv[]) {
int i, len; int i, len;
int ev, er, maj, min; int ev, er, maj, min;
char *arg; char *arg;
int remote_sync = 0;
char *remote_cmd = NULL; char *remote_cmd = NULL;
char *query_cmd = NULL;
char *gui_string = NULL; char *gui_string = NULL;
int remote_query = 0;
int pw_loc = -1; int pw_loc = -1;
int vpw_loc = -1; int vpw_loc = -1;
int dt = 0, bg = 0; int dt = 0, bg = 0;
...@@ -14317,18 +14386,21 @@ int main(int argc, char* argv[]) { ...@@ -14317,18 +14386,21 @@ int main(int argc, char* argv[]) {
} else if (!strcmp(arg, "-remote") || !strcmp(arg, "-R") } else if (!strcmp(arg, "-remote") || !strcmp(arg, "-R")
|| !strcmp(arg, "-r")) { || !strcmp(arg, "-r")) {
CHECK_ARGC CHECK_ARGC
remote_cmd = strdup(argv[++i]); i++;
if (!strcmp(remote_cmd, "ping")) { if (!strcmp(argv[i], "ping")) {
remote_query = 1; query_cmd = strdup(argv[i]);
} else {
remote_cmd = strdup(argv[i]);
} }
quiet = 1; quiet = 1;
xkbcompat = 0; xkbcompat = 0;
} else if (!strcmp(arg, "-query") || !strcmp(arg, "-Q")) { } else if (!strcmp(arg, "-query") || !strcmp(arg, "-Q")) {
CHECK_ARGC CHECK_ARGC
remote_cmd = strdup(argv[++i]); query_cmd = strdup(argv[++i]);
remote_query = 1;
quiet = 1; quiet = 1;
xkbcompat = 0; xkbcompat = 0;
} else if (!strcmp(arg, "-sync")) {
remote_sync = 1;
} else if (!strcmp(arg, "-noremote")) { } else if (!strcmp(arg, "-noremote")) {
accept_remote_cmds = 0; accept_remote_cmds = 0;
} else if (!strcmp(arg, "-unsafe")) { } else if (!strcmp(arg, "-unsafe")) {
...@@ -14396,15 +14468,16 @@ int main(int argc, char* argv[]) { ...@@ -14396,15 +14468,16 @@ int main(int argc, char* argv[]) {
} }
} }
if (client_connect_file && remote_cmd) { if (client_connect_file && (remote_cmd || query_cmd)) {
/* no need to open DISPLAY, just write it to the file now */ /* no need to open DISPLAY, just write it to the file now */
int rc = send_remote_cmd(remote_cmd, remote_query); int rc = do_remote_query(remote_cmd, query_cmd, remote_sync);
fflush(stderr); fflush(stderr);
fflush(stdout); fflush(stdout);
exit(rc); exit(rc);
} }
/* /*
* If -passwd was used, clear it out of argv. This does not * If -passwd was used, clear it out of argv. This does not
* work on all UNIX, have to use execvp() in general... * work on all UNIX, have to use execvp() in general...
...@@ -14654,11 +14727,7 @@ int main(int argc, char* argv[]) { ...@@ -14654,11 +14727,7 @@ int main(int argc, char* argv[]) {
/* open the X display: */ /* open the X display: */
X_INIT; X_INIT;
if (auth_file) { if (auth_file) {
char *tmp; set_env("XAUTHORITY", auth_file);
int len = strlen("XAUTHORITY=") + strlen(auth_file) + 1;
tmp = (char *) malloc((size_t) len);
sprintf(tmp, "XAUTHORITY=%s", auth_file);
putenv(tmp);
} }
if (watch_bell || use_xkb_modtweak) { if (watch_bell || use_xkb_modtweak) {
/* we need XKEYBOARD for these: */ /* we need XKEYBOARD for these: */
...@@ -14708,10 +14777,11 @@ int main(int argc, char* argv[]) { ...@@ -14708,10 +14777,11 @@ int main(int argc, char* argv[]) {
scr = DefaultScreen(dpy); scr = DefaultScreen(dpy);
rootwin = RootWindow(dpy, scr); rootwin = RootWindow(dpy, scr);
if (remote_cmd) { if (remote_cmd || query_cmd) {
int rc = send_remote_cmd(remote_cmd, remote_query); int rc = do_remote_query(remote_cmd, query_cmd, remote_sync);
XFlush(dpy); XFlush(dpy);
fflush(stderr); fflush(stderr);
fflush(stdout);
usleep(30 * 1000); /* still needed? */ usleep(30 * 1000); /* still needed? */
XCloseDisplay(dpy); XCloseDisplay(dpy);
exit(rc); exit(rc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment