Commit 3a84b0cc authored by runge's avatar runge

x11vnc: XFIXES cursorshape, XRANDR resize, remote control, gui

parent 7e13b8a5
2004-12-16 Karl Runge <runge@karlrunge.com>
* test/encodingstest.c: fix decl bug in main()
* x11vnc: use XFIXES extension to show the exact cursor shape.
* remote control nearly everything on the fly, -remote/-query
* tcl/tk gui based on the remote control, -gui
* support screen size changes with XRANDR ext., -xrandr, -padgeom
* Misc: -overlay visual support on IRIX, -id pick, -pointer_mode n,
-sb n, RFB_MODE set in env. under -accept/-gone.
2004-12-02 Johannes E. Schindelin <Johannes.Schindelin@gmx.de> 2004-12-02 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* make LibVNCServer compile & work on MinGW32 * make LibVNCServer compile & work on MinGW32
......
...@@ -287,12 +287,13 @@ int main(int argc,char** argv) ...@@ -287,12 +287,13 @@ int main(int argc,char** argv)
{ {
int i,j; int i,j;
time_t t; time_t t;
rfbScreenInfoPtr server;
rfbClientLog=rfbTestLog; rfbClientLog=rfbTestLog;
rfbClientErr=rfbTestLog; rfbClientErr=rfbTestLog;
/* Initialize server */ /* Initialize server */
rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,width,height,8,3,4); server=rfbGetScreen(&argc,argv,width,height,8,3,4);
server->frameBuffer=malloc(400*300*4); server->frameBuffer=malloc(400*300*4);
for(j=0;j<400*300*4;j++) for(j=0;j<400*300*4;j++)
......
2004-12-16 Karl Runge <runge@karlrunge.com>
* support for XFIXES extension to show the exact cursor shape,
working on Linux/Xorg and Solaris 10. disable with -noxfixes
* remote control mania - nearly everything can be changed dynamically!
see the -remote/-query (aka -R/-Q) options. e.g. -R scale:5/6
* simple gui tkx11vnc based on the remote control mechanism, see -gui
* support for XRANDR extension, if the X screen changes size (see
xrandr(1)), x11vnc will resize the fb. Pays to have NewFBSize viewer
* -overlay support on IRIX with XReadDisplay (not tested).
* RFB_MODE is set to "accept" or "gone" in environment
* "-id pick" will let you pick the window (calls xwininfo(1)...)
* "-pointer_mode n" replaces -old_pointer (n=1) and -old_pointer2 (n=2)
a new mode n=3 is added (similary to nodragging, but dynamic).
* "-sb n" screen blank timeout option is now documented.
* renamed NON_CVS to OLD_TREE
2004-08-31 Karl Runge <runge@karlrunge.com> 2004-08-31 Karl Runge <runge@karlrunge.com>
* new check_user_input() pointer input algorithm, it tries to avoid * new check_user_input() pointer input algorithm, it tries to avoid
extra-draws. still needs tuning, get previous one with -old_pointer2 extra-draws. still needs tuning, get previous one with -old_pointer2
...@@ -20,7 +36,6 @@ ...@@ -20,7 +36,6 @@
* fix misc bugs: missing var types, hardwired blackouts sizes, * fix misc bugs: missing var types, hardwired blackouts sizes,
subwin desktop name crash. subwin desktop name crash.
2004-08-03 Karl Runge <runge@karlrunge.com> 2004-08-03 Karl Runge <runge@karlrunge.com>
* add man page x11vnc.1 autogenerated from x11vnc -help; tweak * add man page x11vnc.1 autogenerated from x11vnc -help; tweak
help output a little bit. Adjust autoconf to pick up manpage. help output a little bit. Adjust autoconf to pick up manpage.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
#!/bin/sh
# the next line restarts using wish. \
exec wish "$0" "$@"
catch {rename send {}}
#
# Copyright (c) 2004 Karl J. Runge <runge@karlrunge.com>
# All rights reserved.
#
# This is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this software; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
# USA.
#
# tkx11vnc v0.1
# This is a simple frontend to x11vnc. It uses the remote control
# and query features (-remote/-query aka -R/-Q) to interact with it.
# It is just a quick-n-dirty hack (it parses -help output, etc), but
# it could be of use playing with or learning about the (way too) many
# parameters x11vnc has.
#
# It can be used to interact with a running x11vnc (see the x11vnc
# -gui option), or to set the parameters and then start up x11vnc.
#
#
# Below is a simple picture of how the gui should be laid out and how
# the menus should be organized. Most menu items correspond to remote
# control commands. A trailing ":" after the item name means it is a string
# to be set rather than a boolean that can be toggled (e.g. the entry
# box must be used).
#
# Some tweak options may be set in the prefix "=" string.
# A means it is an "Action" (not a true variable)
# R means it is an action only valid in remote mode.
# S means it is an action only valid in startup mode.
# Q means it is an action worth querying after running.
# 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)
# P means the string can be +/- appended/deleted (string may not
# be the same after the remote command)
# G means gui internal item
# F means can be set via file browse
# -C:val1,... means it will be a checkbox (radio button)
# the "-" means no other options follow
# 0 means to skip the item.
# -- means add a separator
#
proc set_template {} {
global template
set template "
Row: Actions Clients Permissions Keyboard Pointer Help
Row: Displays Screen Tuning Debugging Misc
Actions
=SA start
=RA stop
=GA attach
=RA detach
--
=RA ping
=RA update-all
=GA clear-all
--
=GA Quit
Help
=GA gui
=GA all
Clients
=RQA current:
=F connect:
=RQA disconnect:
--
accept:
gone:
vncconnect
--
=F httpdir:
httpport:
enablehttpproxy
Displays
display:
=F auth:
desktop:
rfbport:
=0 gui:
Screen
=DRA refresh
=DRA reset
=DRA blacken
--
=D id:
=D sid:
=D scale:
--
=D overlay
overlay_nocursor
--
=D visual:
flashcmap
notruecolor
--
=DP blackout:
=D xinerama
--
= xrandr
=-C:resize,newfbsize,exit xrandr_mode:
padgeom:
Keyboard
norepeat
add_keysyms
modtweak
xkb
skip_keycodes:
--
=FP remap:
--
clear_mods
clear_keys
Pointer
=-C:none,arrow,X,some,most cursor:
noxfixes
--
cursorpos
nocursorshape
--
buttonmap:
--
xwarppointer
Misc
=F rc:
norc
--
nofb
--
nobell
nosel
noprimary
--
bg
=-C:ignore,exit sigpipe:
=0 inetd
--
=RA remote-cmd:
=GA all-settings
Debugging
debug_pointer
debug_keyboard
=F logfile:
quiet
--
=G debug_gui
Permissions
=RQA lock
=RQA unlock
=SQA deny_all
--
=FP allow:
localhost
=RA allowonce:
--
viewonly
shared
forever
--
=RA noremote
--
alwaysshared
nevershared
dontdisconnect
--
viewpasswd:
=F passwdfile:
=0 storepasswd
=F rfbauth:
passwd:
--
safer
unsafe
Tuning
=-C:1,2,3,4 pointer_mode:
input_skip:
nodragging
--
=D noshm
flipbyteorder
onetile
--
wait:
defer:
nap
screen_blank:
--
fs:
gaps:
grow:
fuzz:
--
threads
rfbwait:
--
progressive:
"
}
proc set_internal_help {} {
global helptext helpall
# set some internal item help here:
set helptext(start) "
Launch x11vnc with the settings you have prescribed in the gui.
The x11vnc process is started in an xterm window so you can see the
output, kill it, etc.
"
set helptext(debug_gui) "
Set debug_gui to get more output printed in the text area.
"
set helptext(detach) "
No longer be associated with the x11vnc server. Switch to non-connected
state.
"
set helptext(attach) "
Attach to the x11vnc server, if possible. Switches to connected state
if successful. To change or set the X display use \"Displays -> display\"
"
set helptext(ping) "
Check if x11vnc still responds to \"ping\" remote command.
"
set helptext(update-all) "
Query the x11vnc server for the current values of all variables.
Populate the values into the gui's database.
"
set helptext(clear-all) "
Forget any variable settings either entered in by you or retrieved
from a running x11vnc server. Basically sets everything to 0 or
the string (unset).
"
set helptext(all-settings) "
Displays the gui's database of all of the x11vnc server's current
settings. Use \"Actions -> update-all\" or \"Control+R\" to
refresh this list if it ever gets out of sync.
"
set helptext(remote-cmd) "
Run a remote command (-R) or query (-Q) directly. Only a few
remote commands are not on a menu, but for those few you can
run the command directly this way. Just enter the command into
the Entry box when prompted. Use the prefix \"Q:\" to indicate
a -Q query. Examples: \"zero:20,20,100,100\", \"Q:ext_xfixes\"
"
set helptext(Quit) "
Terminate the tkx11vnc gui. Any x11vnc servers will be left running.
"
set helptext(current) "
Shows a menu of currently connected VNC clients on the x11vnc server.
Allows you to find more information about them or disconnect them.
You will be prompted to confirm any disconnections.
"
set helptext(xrandr_mode) "
Set the -xrandr mode value.
"
set helptext(all) $helpall
set helptext(gui) "
tkx11vnc is a simple frontend to x11vnc. Nothing fancy, it merely
provides an interface to each of the many x11vnc command line options and
remote control commands. See \"Help -> all\" for much info about x11vnc.
Most menu items have a (?) button one can click on to get more information
about the option or command. In most cases it will be text extracted
from that in \"Help -> all\".
There are two states tkx11vnc can be in:
1) Available to control a running x11vnc process.
2) Getting ready to start a x11vnc process.
In state 1) the Menu items available in the menus are those that
correspond to the x11vnc \"remote control\" commands. See the -remote
entry under \"Help -> all\" for a complete list. Also available is
the \"Actions -> stop\" item to shut down the running x11vnc server,
thereby changing to state 2). One could also simply \"Actions -> detach\"
leaving the x11vnc server running. \"Actions -> attach\" would
reestablish the connection.
In state 2) the Menu items available in the menus (Actions, Clients,
etc.) are those that correspond to command line options used in starting
an x11vnc process, and the \"Actions -> start\" item executes
x11vnc thereby changing to state 1). To see what x11vnc startup command
you have built so far, look at the (?) help for \"Actions -> start\"
and it will show you what the command looks like.
There is much overlap between the menu items available in state 1)
and state 2), but it is worth keeping in mind it is not 100%.
For example, you cannot set passwords or password files in state 1).
Also note that there may be *two* separate X displays involved, not just
one: 1) the X display x11vnc will be polling (and making available to
VNC viewers), and 2) the X display this GUI is intended to display on.
For example, one might use ssh to access the remote machine where the
GUI would display on :11 and x11vnc would poll display :0.
GUI components:
--- ----------
At the top of the gui is a info text label where information will
be posted, e.g. when traversing menu items text indicating how to get
help on the item and its current value will be displayed.
Below the info label is the area where the menu buttons, Actions,
Clients, etc., are presented. If a menu item has a checkbox,
it corresponds to a boolean on/off variable. Otherwise it is
either a string variable, or an action not associated with a
variable (for the most part).
Below the menu button area is a text label indicating the current x11vnc
X display being polled and the corresponding VNC display name. Both
will be \"(*none*)\" when there is no connection established.
Below the x11 and vnc displays text label is a text area there scrolling
information about actions being taken and commands being run is displayed.
To scroll use PageUp/PageDown or the arrow keys.
At the bottom is an entry area. When one selects a menu item that
requires supplying a string value, the label will be set to the
parameter name and one types in the new value. Then one presses the
\"OK\" button or presses \"Enter\" to set the value. Or you can press
\"Skip\" or \"Escape\" to avoid changing the variable. Some variables
are boolean toggles (for example, \"Permissions -> viewonly\") or Radio
button selections. Selecting these menu items will not activate the
entry area but rather toggle the variable directly.
Cascades: There is a bug not yet worked around for the cascade menus
where the (?) help button gets in the way. To get the mouse over to
the cascade menu click and release mouse to activate the cascade, then
you can click on its items. Dragging with a mouse button held down
will not work (sorry).
Key Bindings:
In the Text Area: Control-/ selects all of the text.
Anywhere: Control-d invokes \"Actions -> detach\"
Anywhere: Control-a invokes \"Actions -> attach\"
Anywhere: Control-p invokes \"Actions -> ping\"
Anywhere: Control-u and Control-r invoke \"Actions -> update-all\"
"
}
proc center_win {w} {
wm withdraw $w
set x [expr [winfo screenwidth $w]/2 - [winfo reqwidth $w]/2];
set y [expr [winfo screenheight $w]/2 - [winfo reqheight $w]/2];
wm geom $w +$x+$y
wm deiconify $w
update
}
proc textwidth {text} {
set min 0;
foreach line [split $text "\n"] {
set n [string length $line]
if {$n > $min} {
set min $n
}
}
return $min
}
proc textheight {text} {
set count 0;
foreach line [split $text "\n"] {
incr count
}
return $count
}
proc make_toplevel {w {title ""}} {
catch {destroy $w}
toplevel $w;
bind $w <Escape> "destroy $w"
if {$title != ""} {
wm title $w $title
}
}
proc textwin {name title text} {
global max_text_height max_text_width
global bfont
set width [textwidth $text]
incr width
if {$width > $max_text_width} {
set width $max_text_width
}
set height [textheight $text]
if {$height > $max_text_height} {
set height $max_text_height
}
set w ".text_$name"
make_toplevel $w $title
frame $w.f -bd 0;
pack $w.f -fill both -expand 1
text $w.f.t -width $width -height $height -setgrid 1 -bd 2 \
-yscrollcommand "$w.f.y set" -relief ridge -font fixed;
scrollbar $w.f.y -orient v -relief sunken -command "$w.f.t yview";
button $w.f.b -text "Dismiss" -command "destroy $w" -font $bfont
$w.f.t insert 1.0 $text;
bind $w <Enter> "focus $w.f.t"
wm withdraw $w
pack $w.f.b -side bottom -fill x
pack $w.f.y -side right -fill y;
pack $w.f.t -side top -fill both -expand 1;
update
center_win $w
}
proc active_when_connected {item} {
global helpremote helptext
if {[opt_match G $item]} {
return 1
} elseif {[is_action $item]} {
if {[opt_match R $item]} {
return 1
} else {
return 0
}
} elseif {[info exists helpremote($item)]} {
return 1
} else {
return 0
}
}
proc active_when_starting {item} {
global helpremote helptext
if {[opt_match G $item]} {
return 1
} elseif {[is_action $item]} {
if {[opt_match S $item]} {
return 1
} else {
return 0
}
} elseif {[info exists helptext($item)]} {
return 1
} else {
return 0
}
}
proc help_win {item} {
global helptext helpremote
global query_ans query_aro;
set ok 0
set text "Help on $item:\n\n"
if {[is_gui_internal $item]} {
;
} elseif {[is_action $item]} {
append text " + Is a remote control Action (cannot be set).\n";
} elseif {[active_when_connected $item]} {
append text " + Can be changed in a running x11vnc.\n";
} else {
append text " - Cannot be changed in a running x11vnc.\n";
}
if {[is_gui_internal $item]} {
;
} elseif {[active_when_starting $item]} {
append text " + Can be set at x11vnc startup.\n";
} else {
append text " - Cannot be set at x11vnc startup.\n";
}
append text "\n"
if {[info exists helptext($item)]} {
append text "\n"
if {[is_gui_internal $item]} {
append text "==== x11vnc help: ====\n";
} else {
append text "==== x11vnc startup option help: ====\n";
}
append text "\n"
append text $helptext($item)
append text "\n"
set ok 1
}
if {[info exists helpremote($item)]} {
append text "\n"
append text "==== x11vnc remote control help: ====\n";
append text "\n"
append text $helpremote($item)
set ok 1
}
if {$item == "start"} {
set str [get_start_x11vnc_txt]
append text $str
append_text "$str\n"
}
regsub -all { } $item " " name
if {$ok} {
textwin $name "x11vnc help: $item" "$text";
}
return $ok
}
proc parse_help {} {
global env x11vnc_prog;
global helpall helptext;
set helppipe [open "| $x11vnc_prog -help" "r"];
if {$helppipe == ""} {
puts stderr "failed to run $x11vnc_prog -help";
exit 1;
}
set sawopts 0;
set curropt "";
while {[gets $helppipe line] > -1} {
append helpall "$line\n"
# XXX
if {[regexp {^Options:} $line]} {
set sawopts 1;
continue;
}
# XXX
if {[regexp {^These options} $line]} {
continue;
}
if {! $sawopts} {
continue;
}
if {[regexp {^-([A-z_][A-z_]*)} $line match name]} {
set allnames($name) 1;
if {"$curropt" != "no$name" && "no$curropt" != "$name"} {
set curropt $name;
set helptext($curropt) "$line\n";
} else {
append helptext($curropt) "$line\n";
}
} elseif {$curropt != ""} {
append helptext($curropt) "$line\n";
}
}
foreach name [array names allnames] {
if {[regexp {^no} $name]} {
regsub {^no} $name "" pair
} else {
set pair "no$name"
}
if {[info exists helptext($name)]} {
if ![info exists helptext($pair)] {
set helptext($pair) $helptext($name);
}
} elseif {[info exists helptext($pair)]} {
if ![info exists helptext($name)] {
set helptext($name) $helptext($pair);
}
}
}
set_internal_help
}
proc tweak_both {new old} {
tweak_help $new $old
tweak_remote_help $new $old
}
proc tweak_remote_help {new old} {
global helpremote
if ![info exists helpremote($new)] {
if {[info exists helpremote($old)]} {
set helpremote($new) $helpremote($old)
}
}
}
proc tweak_help {new old} {
global helptext
if ![info exists helptext($new)] {
if {[info exists helptext($old)]} {
set helptext($new) $helptext($old)
}
}
}
proc parse_remote_help {} {
global helpremote helptext help_indent remote_name;
set sawopts 0;
set curropt "";
set possopts "";
set offset [expr $help_indent - 1];
foreach line [split $helptext(remote) "\n"] {
set line [string range $line $offset end];
# XXX
if {[regexp {^The following -remote/-R commands} $line]} {
set sawopts 1;
continue;
}
# XXX
if {[regexp {^The vncconnect.*command} $line]} {
set sawopts 0;
}
if {! $sawopts} {
continue;
}
if {[regexp {^([A-z_][A-z_:]*)} $line match name]} {
regsub {:.*$} $name "" popt
lappend possopts $popt
if {"$curropt" != "no$name" && "no$curropt" != "$name"} {
set curropt $name;
regsub {:.*$} $curropt "" curropt
set remote_name($curropt) $name
set helpremote($curropt) "$line\n";
} else {
append helpremote($curropt) "$line\n";
}
} elseif {$curropt != ""} {
append helpremote($curropt) "$line\n";
}
}
foreach popt $possopts {
if {[info exists helpremote($popt)]} {
continue
}
if {[regexp {^no} $popt]} {
regsub {^no} $popt "" try
} else {
set try "no$popt"
}
if {[info exists helpremote($try)]} {
set helpremote($popt) $helpremote($try)
}
}
}
proc parse_query_help {} {
global query_ans query_aro query_ans_list query_aro_list helptext;
set sawans 0;
set sawaro 0;
set ans_str ""
set aro_str ""
foreach line [split $helptext(query) "\n"] {
if {! $sawans && [regexp {^ *ans=} $line]} {
set sawans 1
}
if {! $sawans} {
continue
}
if {[regexp {^ *aro=} $line]} {
set sawaro 1
}
if {$sawaro && [regexp {^[ ]*$} $line]} {
set sawans 0
break
}
regsub {ans=} $line "" line
regsub {aro=} $line "" line
set line [string trim $line]
if {$sawaro} {
set aro_str "$aro_str $line"
} else {
set ans_str "$ans_str $line"
}
}
regsub -all { *} $ans_str " " ans_str
regsub -all { *} $aro_str " " aro_str
set ans_str [string trim $ans_str]
set aro_str [string trim $aro_str]
set query_ans_list [split $ans_str]
set query_aro_list [split $aro_str]
foreach item $query_ans_list {
if {[regexp {^[ ]*$} $item]} {
continue
}
set query_ans($item) 1
}
foreach item $query_aro_list {
if {[regexp {^[ ]*$} $item]} {
continue
}
set query_aro($item) 1
}
}
proc in_debug_mode {} {
global menu_var
if {![info exists menu_var(debug_gui)]} {
return 0
}
return $menu_var(debug_gui)
}
# Menubar utilities:
proc menus_state {state} {
global menu_b
foreach case [array names menu_b] {
set menu_button $menu_b($case)
$menu_button configure -state $state
}
}
proc menus_enable {} {
menus_state "normal"
}
proc menus_disable {} {
menus_state "disabled"
}
# Entry box utilities:
proc entry_state {x state} {
global entry_box entry_label entry_ok entry_help entry_skip entry_browse
if {$x == "all"} {
$entry_label configure -state $state
$entry_box configure -state $state
$entry_ok configure -state $state
$entry_skip configure -state $state
$entry_help configure -state $state
$entry_browse configure -state $state
} elseif {$x == "label"} {
$entry_label configure -state $state
} elseif {$x == "box"} {
$entry_box configure -state $state
} elseif {$x == "ok"} {
$entry_ok configure -state $state
} elseif {$x == "skip"} {
$entry_skip configure -state $state
} elseif {$x == "help"} {
$entry_help configure -state $state
} elseif {$x == "browse"} {
$entry_browse configure -state $state
}
}
proc entry_enable {{x "all"}} {
entry_state $x normal
}
proc entry_disable {{x "all"}} {
entry_state $x disabled
}
proc entry_browse_button {{show 1}} {
global entry_browse
if {$show} {
pack $entry_browse -side left
} else {
pack forget $entry_browse
}
}
proc entry_focus {} {
global entry_box
focus $entry_box
}
proc entry_select {} {
global entry_box
$entry_box selection range 0 end
}
proc entry_get {} {
global entry_box
return [$entry_box get]
}
proc entry_insert {str} {
global entry_box
entry_delete
$entry_box insert end $str
$entry_box icursor end
}
proc entry_delete {} {
global entry_box
$entry_box delete 0 end
}
# Utilities for remote control and updating vars.
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
set debug [in_debug_mode]
set do_query_all 0
set getout 0
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 "-R" "$new"]
set qargs [list "-Q" "$qtmp"]
set getout 1
} else {
set rargs [list "-Q" "$qtmp"]
set qargs [list "-Q" "$qtmp"]
}
} elseif {[value_is_string $item]} {
set rargs [list "-R" "$name:$new"]
set qargs [list "-Q" "$name"]
} else {
set rargs [list "-R" "$name"]
set qargs [list "-Q" "$name"]
}
if {!$debug} {
append_text "x11vnc $rargs ..."
}
set remote_output [run_remote_cmd $rargs]
if {[lindex $rargs 0] == "-Q"} {
append_text "\t$remote_output"
set getout 1
} elseif {! $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
}
if {$getout} {
append_text "\n"
return
}
stop_watch on
after $delay_sleep
if {[opt_match D $item]} {
set s [expr $extra_sleep/$extra_sleep_split]
append_text " "
for {set i 0} {$i<$extra_sleep_split} {incr i} {
after $s
append_text "."
update
}
}
stop_watch off
if {!$debug} {
append_text ", -Q ..."
}
if {$item == "disconnect"} {
set new "N/A"
set do_query_all 1
}
if {$always_update || $do_query_all} {
set query [query_all 1]
} else {
set query [run_remote_cmd $qargs]
}
set query_output $query
if {![see_if_ok $query $item "$name:$new"]} {
# failed
if {[regexp {^a..=} $query]} {
# but some result came back
if {! $always_update} {
# synchronize everything
set query_output [query_all 1]
}
} else {
# server may be dead
if {$item != "ping" && $item != "attach"} {
try_connect
}
}
} else {
# succeeded
if {! $always_update} {
# synchronize this variable
update_menu_vars $query
} else {
# already done in query_all
}
}
}
# For updating a string variable. Also used for simple OK/Skip dialogs
# with entry = 0.
proc entry_dialog {item {entry 1}} {
global menu_var entry_str entry_set entry_dialog_item
global unset_str connected_to_x11vnc
set entry_str "Set $item"
set entry_set 0
set entry_dialog_item $item
entry_enable
menus_disable
if {$entry} {
entry_insert ""
if {[info exists menu_var($item)] &&
$menu_var($item) != $unset_str} {
entry_insert $menu_var($item)
entry_select
}
if {[is_browse $item]} {
entry_browse_button
}
set_info "Set parameter in entry box, "
entry_focus
} else {
entry_disable box
}
update
# wait for user reply:
vwait entry_set
set rc $entry_set
set entry_set 0
set value [entry_get]
update
entry_browse_button 0
set entry_str "Set... :"
entry_delete
entry_disable
menus_enable
update
if {! $entry} {
;
} elseif {$rc} {
set menu_var($item) $value
} else {
if {[in_debug_mode]} {
append_text "skipped setting $item\n"
}
}
return $rc
}
proc warning_dialog {msg {item "gui"} } {
append_text $msg
# just reuse the entry widgets for a yes/no dialog
return [entry_dialog $item 0]
}
# For updating a boolean toggle:
proc check_var {item} {
global menu_var
set inval $menu_var($item);
if {$item == "debug_gui"} {
return "";
}
set rname $item
if {! $inval} {
if {[regexp {^no} $item]} {
regsub {^no} $rname "" rname
} else {
set rname "no$rname"
}
}
return $rname
}
proc see_if_ok {query item expected} {
set ok 0
set found ""
foreach q [split_query $query] {
if {[regexp "^$item:" $q]} {
set found $q
}
if {$q == $expected} {
set ok 1
}
}
if {$found == ""} {
set msg $query
regsub {^a..=} $msg {} msg
if {[string length $msg] > 60} {
set msg [string range $msg 0 60]
}
} else {
set msg $found
}
if {$ok} {
append_text "\tSet OK ($msg)\n"
return 1
} elseif {[opt_match P $item] && [regexp {:(-|\+)} $expected]} {
# e.g. blackout:+30x30+20+20
append_text "\t($msg)\n"
return 1
} else {
append_text "\t*FAILED* $msg\n"
return 0
}
}
proc update_menu_vars {{query ""}} {
global all_settings menu_var
set debug [in_debug_mode]
if {$query == ""} {
set qstr $all_settings
} else {
set qstr $query
}
foreach piece [split_query $qstr] {
if {[regexp {^([^:][^:]*):(.*)$} $piece m0 item val]} {
if {[info exists menu_var($item)]} {
set old $menu_var($item)
if {$val == "N/A"} {
continue
}
if {$debug} {
puts "setting menuvar: $item: $old -> $val"
}
set menu_var($item) $val
}
if {$item == "clients"} {
update_clients_menu $val
}
}
}
}
proc clear_all {} {
global menu_var unset_str
set debug [in_debug_mode]
foreach item [array names menu_var] {
if {$item == "debug_gui"} {
continue
}
if {[info exists menu_var($item)]} {
if [is_action $item] {
set menu_var($item) ""
} elseif {[value_is_bool $item]} {
set menu_var($item) 0
} elseif {[value_is_string $item]} {
set menu_var($item) $unset_str
}
}
}
}
proc all_query_vars {} {
global query_ans_list query_aro_list all_settings
set qry ""
foreach item $query_ans_list {
if {$qry == ""} {
set qry $item
} else {
append qry ",$item"
}
}
foreach item $query_aro_list {
if {$qry == ""} {
set qry $item
} else {
append qry ",$item"
}
}
return $qry
}
proc query_all {{quiet 0}} {
global query_ans_list query_aro_list all_settings
set qry [all_query_vars]
#puts "into query_all $quiet"
set qargs [list "-Q" $qry]
set all [run_remote_cmd $qargs]
if {[regexp {ans=} $all]} {
if {! $quiet} {
append_text "Retrieved all settings.\n"
}
set all_settings $all
update_menu_vars $all
} else {
if {! $quiet} {
append_text "Failed to retrieve settings.\n"
}
}
return $all
}
proc set_info {str} {
global info_str
set info_str "$str"
update
}
proc append_text {str} {
global text_area
$text_area insert end $str
$text_area see end
}
proc show_all_settings {} {
global all_settings
set txt "\nRead-Write setting:\n\n"
foreach item [split_query $all_settings] {
regsub {:} $item {: } item
append txt " $item\n"
if {[regexp {noremote} $item]} {
append txt "\nRead-Only setting:\n\n"
}
}
textwin "Settings" "All Current Settings" $txt
}
proc set_connected {yesno} {
global connected_to_x11vnc
set orig $connected_to_x11vnc
if {$yesno == "yes"} {
set connected_to_x11vnc 1
} else {
set connected_to_x11vnc 0
no_x11_display
no_vnc_display
}
if {$orig != $connected_to_x11vnc} {
set_widgets
}
}
proc detach_from_display {} {
global connected_to_x11vnc reply_xdisplay x11vnc_xdisplay
set str "Detaching from X display."
if {$reply_xdisplay != ""} {
set str "Detaching from $reply_xdisplay."
} elseif {$x11vnc_xdisplay != ""} {
set str "Detaching from $x11vnc_xdisplay."
}
if {$connected_to_x11vnc} {
append_text "$str\n"
}
set_connected no
}
# Menu item is an action:
proc do_action {item} {
global menu_var connected_to_x11vnc
if {[in_debug_mode]} {
append_text "action: \"$item\"\n"
}
if {$item == "ping"} {
try_connect
return
} elseif {$item == "start"} {
start_x11vnc
return
} elseif {$item == "detach"} {
detach_from_display
return
} elseif {$item == "attach"} {
try_connect_and_query_all
return
} elseif {$item == "update-all"} {
query_all
return
} elseif {$item == "clear-all"} {
clear_all
return
} elseif {$item == "all-settings"} {
show_all_settings
return
}
if {[value_is_string $item]} {
if {! [entry_dialog $item]} {
return
}
set new $menu_var($item)
set name $item
} else {
set new 1
set name $item
}
if {! $connected_to_x11vnc} {
;
} elseif {[regexp {^(stop|quit|exit|shutdown)$} $item]} {
# just do -R
append_text "stopping remote x11vnc server...\n"
push_new_value $item $name $new 0
set_connected no
} elseif [opt_match Q $item] {
push_new_value $item $name $new 1
} else {
push_new_value $item $name $new 0
}
}
proc do_var {item} {
global connected_to_x11vnc item_cascade menu_var
set string 0
if {[is_action $item]} {
# Menu item is action:
do_action $item
return
}
if {[value_is_string $item]} {
# Menu item is a string:
if {$item_cascade($item) != ""} {
# Cascade sets variable automatically
} else {
# Otherwise Entry box
if {![entry_dialog $item]} {
return
}
}
set new $menu_var($item)
set name $item
} else {
# Menu item is a boolean:
set name [check_var $item]
if {$name == ""} {
return
}
set new 1
}
if {$connected_to_x11vnc} {
push_new_value $item $name $new 1
}
}
proc menu_help {item} {
if ![help_win $item] {
textwin "nohelp" "No help available" \
"Sorry, no help avaiable for \"$item\""
}
}
proc opt_match {c item} {
global item_opts
if {[info exists item_opts($item)]} {
if {[regexp "^\[A-z\]*$c" $item_opts($item)]} {
return 1
}
}
return 0
}
proc is_action {item} {
return [opt_match A $item]
}
proc is_gui_internal {item} {
return [opt_match G $item]
}
proc is_browse {item} {
return [opt_match F $item]
}
proc value_is_string {item} {
global item_bool
if {! $item_bool($item)} {
return 1
} else {
return 0
}
}
proc value_is_bool {item} {
global item_bool
if {$item_bool($item)} {
return 1
} else {
return 0
}
}
proc split_query {query} {
regsub -all {aro=} $query {ans=} query
set items {}
while {1} {
if {! [regexp {^ans=(.*)$} $query m0 m1]} {
break
}
set item $m1
set m2 ""
regexp {,ans=.*$} $item m2
regsub {,ans=.*$} $item "" item
if {$item != ""} {
lappend items $item
}
set query $m2
regsub {^,} $query "" query
}
return $items
}
proc set_x11_display {name} {
global x11_display
set x11_display "x11vnc X display: $name"
}
proc set_vnc_display {name} {
global vnc_display
set vnc_display "VNC display: $name"
}
proc no_x11_display {} {
set_x11_display "(*none*)"
}
proc no_vnc_display {} {
set_vnc_display "(*none*)"
}
proc fetch_displays {} {
set qargs [list "-Q" "display,vncdisplay"]
set result [run_remote_cmd $qargs]
set got_x11 0
set got_vnc 0
foreach item [split_query $result] {
if {[regexp {^display:(.*)$} $item m0 m1]} {
set_x11_display $m1
set got_x11 1
} elseif {[regexp {^vncdisplay:(.*)$} $item m0 m1]} {
set_vnc_display $m1
set got_vnc 1
}
}
if {! $got_x11} {
no_x11_display
}
if {! $got_vnc} {
no_vnc_display
}
}
proc disconnect_dialog {client} {
set cid ""
set host ""
set msg "\n"
append msg "*** Client info string: $client\n"
if {[regexp {^(.*):(.*)/(.*)-(.*)$} $client m0 m1 m2 m3 m4]} {
if {$m4 == "ro"} {
set view "(viewonly)"
} else {
set view "(interactive)"
}
set host $m1
set cid $m3
append msg "*** Host: $m1, Port: $m2 Id: $m3 $view\n"
}
if {$cid == ""} {
append_text "Invalid client info string: $client\n"
return
}
append msg "*** To disconnect this client press \"OK\", otherwise press \"Skip\"\n"
bell
if [warning_dialog $msg "current"] {
push_new_value "disconnect" "disconnect" $cid 1
} else {
append_text "disconnect cancelled.\n"
}
}
proc update_clients_menu {list} {
global item_cascade
set subm $item_cascade(current);
catch {destroy $subm}
menu $subm -tearoff 0
$subm add command
$subm add separator
set count 0
foreach client [split $list ","] {
regsub {:[0-9][0-9]*/} $client {/} lab
$subm add command -label "$client" \
-command "disconnect_dialog $client"
incr count
}
$subm entryconfigure 0 -label "#clients: $count"
}
proc set_widgets {} {
global connected_to_x11vnc item_case item_entry menu_m
foreach item [array names item_case] {
set case $item_case($item)
set menu $menu_m($case)
set entry $item_entry($item)
set type [$menu type $entry]
if {$type == "separator" || $type == "tearoff"} {
continue
}
if {$connected_to_x11vnc} {
if {[active_when_connected $item]} {
$menu entryconfigure $entry -state normal
} else {
$menu entryconfigure $entry -state disabled
}
} else {
if {[active_when_starting $item]} {
$menu entryconfigure $entry -state normal
} else {
$menu entryconfigure $entry -state disabled
}
}
}
}
proc make_widgets {} {
global template
global menu_b menu_m
global item_opts item_bool item_case item_entry menu_var unset_str
global item_cascade
global info_str x11_display vnc_display
global text_area
global entry_box entry_str entry_set entry_label entry_ok entry_browse
global entry_help entry_skip
global bfont
global helptext helpremote helplabel
set v 0
label .info -textvariable info_str -bd 2 -relief groove -anchor w
pack .info -side top -fill x
# Extract the Rows:
set row 0;
set colmax 0;
foreach line [split $template "\n"] {
if {[regexp {^Row: (.*)} $line rest]} {
set col 0
foreach case [split $rest] {
if {$case == "" || $case == "Row:"} {
continue
}
set menu_row($case) $row
set menu_col($case) $col
set menu_count($case) 0
lappend cases($col) $case;
set len [string length $case]
if {[info exists max_len($col)]} {
if {$len > $max_len($col)} {
set max_len($col) $len
}
} else {
set max_len($col) $len
}
incr col
if {$col > $colmax} {
set colmax $col
}
}
incr row;
}
}
# Make frames for the rows and make the menu buttons.
set f ".menuframe"
frame $f
for {set c 0} {$c < $colmax} {incr c} {
set colf "$f.menuframe$c"
frame $colf
pack $colf -side left -fill y
set fbg [$colf cget -background]
foreach case $cases($c) {
set menub "$colf.menu$case";
set menu "$colf.menu$case.menu";
set menu_b($case) $menub
set menu_m($case) $menu
menubutton $menub -text "$case" -underline 0 \
-anchor w -menu $menu -background $fbg \
-font $bfont
pack $menub -side top -fill x
menu $menu -tearoff 0
}
}
pack $f -side top -fill x
# Now extract the menu items:
set case "";
foreach line [split $template "\n"] {
if {[regexp {^Row:} $line]} {
continue
}
if {[regexp {^[A-z]} $line]} {
set case [string trim $line]
continue;
}
set item [string trim $line]
regsub -all { *} $item " " item
if {$item == ""} {
continue;
}
set opts ""
if {[regexp {^=} $item]} {
set opts [lindex [split $item] 0]
regsub {^=} $opts "" opts
set item [lindex [split $item] 1]
}
if {[regexp {^0} $opts]} {
continue;
}
if {[regexp {:$} $item]} {
set bool 0
} else {
set bool 1
}
regsub {:$} $item {} item
set item_opts($item) $opts
set item_case($item) $case
set item_bool($item) $bool
set item_cascade($item) ""
set item_entry($item) $menu_count($case)
if {$v} { puts "ITEM: $item - $opts - $case - $bool - $menu_count($case)" }
set mvar 0
set m $menu_m($case)
# Create the menu items, its variables, etc., etc.
if {$item == "--"} {
$m add separator
} elseif {$item == "Quit"} {
# Quit item must shut us down:
$m add command -label "$item" -underline 0 \
-command {destroy .; exit 0}
} elseif {$case == "Help"} {
# Help is simple help:
$m add command -label "$item" \
-command "menu_help $item"
} elseif {$item == "current"} {
# Current clients cascade
set subm $m.cascade$menu_count($case)
set item_cascade($item) $subm
update_clients_menu ""
$m add cascade -label "$item" \
-menu $subm
} elseif {[is_action $item]} {
# Action
$m add command -label "$item" \
-command "do_var $item"
set menu_var($item) ""; # for convenience
} elseif {! $item_bool($item)} {
# String
if {[regexp -- {-C:(.*)} $item_opts($item) m0 m1]} {
# Radiobutton select
set subm $m.cascade$menu_count($case)
menu $subm -tearoff 0
foreach val [split $m1 ","] {
$subm add radiobutton -label "$val" \
-command "do_var $item" \
-value "$val" \
-variable menu_var($item)
}
$m add cascade -label "$item" \
-menu $subm
set item_cascade($item) $subm
} else {
# Arbitrary_string
$m add command -label "$item" \
-command "do_var $item"
}
set mvar 1
} else {
# Boolean
$m add checkbutton -label "$item" \
-command "do_var $item" \
-variable menu_var($item)
set menu_var($item) 0
}
incr menu_count($case)
if {$mvar} {
set menu_var($item) $unset_str
}
}
# Now make the litte "(?)" help buttons
foreach case [array names menu_m] {
if {$case == "Help"} {
continue;
}
set m $menu_m($case);
set n [$m index end]
if {$v} { puts "$case end: $n" }
for {set i 0} {$i <= $n} {incr i} {
set type [$m type $i]
if {$type == "separator"} {
$m add separator
} elseif {$type == "tearoff"} {
continue;
} else {
set label [$m entrycget $i -label]
set str ""
if {[info exists helpremote($label)]} {
set str "(?)"
} elseif {[info exists helptext($label)]} {
set str "(?)"
}
$m add command -label $str \
-command "menu_help $label";
if {$v} {
set ht ""; set hr ""
if {[info exists helptext($label)]} { set ht "YES" }
if {[info exists helpremote($label)]} { set hr "YES" }
puts "'$label'\tht='$ht' hr='$hr'"
}
if {$str == ""} {
$m entryconfigure end -state disabled
}
set arg "$m,$i"
set helplabel($arg) $label
set j [$m index end]
set arg "$m,$j"
set helplabel($arg) $label
}
if {$i == 0} {
$m entryconfigure end -columnbreak 1
}
}
}
# Make the x11 and vnc display label bar:
set df .displayframe
frame $df -bd 1 -relief groove
set df_x11 "$df.xdisplay"
no_x11_display
label $df_x11 -textvariable x11_display -width 35 -anchor w
set df_vnc "$df.vdisplay"
no_vnc_display
label $df_vnc -textvariable vnc_display -width 35 -anchor w
pack $df_x11 $df_vnc -side left
pack $df -side top -fill x
# text area
text .text -height 11 -relief ridge
set text_area .text
pack .text -side top -fill both -expand 1
set str "Click Help -> gui for overview."
append_text "\n$str\n\n"
# Make entry box stuff
set ef .entryframe
frame $ef -bd 1 -relief groove
# Label
set ef_label "$ef.label"
label $ef_label -textvariable entry_str -anchor w -font $bfont
set entry_str "Set... : "
set ef_entry "$ef.entry"
entry $ef_entry -relief sunken
bind $ef_entry <KeyPress-Return> {set entry_set 1}
bind $ef_entry <KeyPress-Escape> {set entry_set 0}
# OK button
set ef_ok "$ef.ok"
button $ef_ok -text OK -pady 1 -command {set entry_set 1} \
-font $bfont
# Skip button
set ef_skip "$ef.skip"
button $ef_skip -text Skip -pady 0 -command {set entry_set 0} \
-font $bfont
# Help button
set ef_help "$ef.help"
button $ef_help -text Help -pady 0 -command \
{menu_help $entry_dialog_item} -font $bfont
# Browse button
set ef_browse "$ef.browse"
button $ef_browse -text "Browse..." -pady 0 -font $bfont \
-command {entry_insert [tk_getOpenFile]}
pack $ef_label -side left
pack $ef_entry -side left -fill x -expand 1
pack $ef_ok -side right
pack $ef_skip -side right
pack $ef_help -side right
pack $ef -side bottom -fill x
set entry_ok $ef_ok
set entry_skip $ef_skip
set entry_help $ef_help
set entry_box $ef_entry
set entry_browse $ef_browse
set entry_label $ef_label
entry_disable
update
wm minsize . [winfo width .] [winfo height .]
}
proc menu_bindings {} {
bind Menu <<MenuSelect>> {
#syntax hilite bug \
MenuSelect>>
set n [%W index active]
set label " "
if {$n != "none"} {
set str %W,$n
set which ""
if {[info exists helplabel($str)]} {
set vname [format %%-16s $helplabel($str)]
set label "Click (?) for help on: $vname"
set which $helplabel($str)
}
if {$which == ""} {
;
} elseif {[is_action $which]} {
if {[info exists menu_var($which)]
&& $menu_var($which) != ""} {
set label "$label value: $menu_var($which)"
} else {
set label "$label (is action)"
}
} elseif {[info exists menu_var($which)]} {
set label "$label value: $menu_var($which)"
}
}
set_info $label
}
}
proc key_bindings {} {
global env
if {[info exists env(USER)] && $env(USER) == "runge"} {
# quick restart
bind . <Control-KeyPress-c> {exec $argv0 $argv &; destroy .}
}
bind . <Control-KeyPress-p> {try_connect_and_query_all}
bind . <Control-KeyPress-u> {query_all 0}
bind . <Control-KeyPress-r> {query_all 0}
bind . <Control-KeyPress-d> {detach_from_display}
bind . <Control-KeyPress-a> {try_connect_and_query_all}
}
proc stop_watch {onoff} {
global orig_cursor text_area entry_box
set widgets [list . $text_area $entry_box]
if {$onoff == "on"} {
foreach item $widgets {
$item config -cursor {watch}
}
} else {
foreach item $widgets {
$item config -cursor {}
}
}
update
}
proc double_check_noremote {} {
set msg "\n\n"
append msg "WARNING: setting \"noremote\" will disable ALL remote control commands\n"
append msg "WARNING: (i.e. this gui will be locked out) Do you really want to do this?\n"
append msg "WARNING: If so, press \"OK\", otherwise press \"Skip\"\n"
append msg "\n"
bell
return [warning_dialog $msg "noremote"]
}
proc double_check_start_x11vnc {} {
global hostname
set msg [get_start_x11vnc_txt]
append msg "\n"
append msg "*** To run the above command on machine \"$hostname\" to\n"
append msg "*** start x11vnc press \"OK\" otherwise press \"Skip\".\n"
return [warning_dialog $msg "start"]
}
proc get_start_x11vnc_txt {} {
set cmd [get_start_x11vnc_cmd]
set str [join $cmd]
set msg ""
append msg "\n"
append msg "==== The command built so far is: ====\n";
append msg "\n"
append msg "$str\n"
return $msg
}
proc get_start_x11vnc_cmd {} {
global menu_var unset_str x11vnc_prog
set xterm_cmd "xterm -iconic -geometry 80x35 -title x11vnc-console -e"
set cmd [split $xterm_cmd]
lappend cmd $x11vnc_prog
foreach item [lsort [array names menu_var]] {
if {![active_when_starting $item]} {
continue
}
if {[is_action $item]} {
continue
}
if {[value_is_bool $item]} {
if {[info exists menu_var($item)]} {
if {$menu_var($item)} {
lappend cmd "-$item"
}
}
} elseif {[value_is_string $item]} {
if {[info exists menu_var($item)]} {
if {$menu_var($item) != ""
&& $menu_var($item) != $unset_str} {
lappend cmd "-$item"
lappend cmd $menu_var($item)
}
}
}
}
lappend cmd "2>"
lappend cmd "/dev/null"
lappend cmd "&"
return $cmd
}
proc start_x11vnc {} {
global menu_var unset_str
global x11vnc_prog x11vnc_xdisplay
global connected_to_x11vnc
if {$connected_to_x11vnc} {
append_text "\n"
append_text "WARNING: Still connected to an x11vnc server.\n"
append_text "WARNING: Use \"stop\" or \"detach\" first.\n"
return 0
}
if {![double_check_start_x11vnc]} {
return
}
set x11vnc_xdisplay ""
if {[info exists menu_var(display)]} {
if {$menu_var(display) != "" && $menu_var(display) != $unset_str} {
set x11vnc_xdisplay $menu_var(display)
}
}
set cmd [get_start_x11vnc_cmd]
set str [join $cmd]
regsub { -e} $str " -e \\\n " str
if {0} {
puts "running: $str"
foreach word $cmd {
puts " word: $word"
}
}
append_text "Starting x11vnc in an iconified xterm with command:\n"
append_text " $str\n\n"
catch {[eval exec $cmd]}
after 500
try_connect_and_query_all 3
}
proc run_remote_cmd {opts} {
global menu_var x11vnc_prog x11vnc_cmdline x11vnc_xdisplay
set debug [in_debug_mode]
if {[lindex $opts 0] == "-R" && [lindex $opts 1] == "noremote"} {
set str [join $opts]
if ![double_check_noremote] {
append_text "skipping: x11vnc $str"
return ""
} else {
append_text "running: x11vnc $str (please do \"Actions -> detach\" to clean things up)\n"
append_text "subsequent -R/-Q commands should fail..."
}
}
set cmd ""
lappend cmd $x11vnc_prog;
if {$x11vnc_xdisplay != ""} {
lappend cmd "-display"
lappend cmd $x11vnc_xdisplay
}
foreach word $opts {
lappend cmd $word
}
lappend cmd "2>"
lappend cmd "/dev/null"
if {0} {
set str [join $cmd]
puts "running: $str"
foreach word $cmd {
puts " word: $word"
}
}
set output ""
stop_watch on
catch {set output [eval exec $cmd]}
stop_watch off
if {$debug} {
append_text "output: $output\n"
}
return $output
}
proc try_connect_and_query_all {{n 2}} {
for {set i 0} {$i < $n} {incr i} {
if {$i > 0} {
after 500
append_text "trying again ...\n"
}
if {[try_connect]} {
query_all
break
}
}
}
proc try_connect {} {
global x11vnc_xdisplay connected_to_x11vnc reply_xdisplay
global menu_var unset_str
if {! $connected_to_x11vnc} {
if {[info exists menu_var(display)]} {
set d $menu_var(display)
if {$d != "" && $d != $unset_str && $d != $x11vnc_xdisplay} {
set x11vnc_xdisplay $menu_var(display)
append_text "Setting X display to: $x11vnc_xdisplay\n"
}
}
}
set_info "Pinging $x11vnc_xdisplay ..."
set rargs [list "-Q" "ping"]
set result [run_remote_cmd $rargs]
if {[regexp {^ans=ping:} $result]} {
regsub {^ans=ping:} $result {} reply_xdisplay
set msg "Connected to $reply_xdisplay"
set_info $msg
append_text "$msg\n"
set_connected yes
fetch_displays
return 1
} else {
set str "x11vnc server."
if {$x11vnc_xdisplay != ""} {
set str $x11vnc_xdisplay
}
set msg "No reply from $str"
set_info $msg
append_text "$msg\n"
set_connected no
return 0
}
}
############################################################################
# main:
global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect;
global helpall helptext helpremote helplabel hostname;
global all_settings reply_xdisplay always_update
global max_text_height max_text_width
global menu_var unset_str
global bfont
global connected_to_x11vnc
global delay_sleep extra_sleep extra_sleep_split
set unset_str "(unset)"
set connected_to_x11vnc 0
set max_text_height 40
set max_text_width 90
set bfont -adobe-helvetica-bold-r-*-*-*-120-*-*-*-*-*-*;
set help_indent 24;
set reply_xdisplay ""
set all_settings "None so far."
set always_update 1
#set delay_sleep 500
#set extra_sleep 1500
set delay_sleep 350
set extra_sleep 1000
set extra_sleep_split 4
if {"$argv" == "-spit"} {
set fh [open $argv0 r]
puts "/*"
puts " * tkx11vnc.h: generated by 'tkx11vnc -spit'"
puts " * Abandon all hope, ye who enter here..."
puts " * ...edit tkx11vnc instead."
puts " */"
puts " char gui_code\[\] ="
while {[gets $fh line] > -1} {
regsub -all {\\} $line {\\\\} line
regsub -all {"} $line {\\"} line
puts "\"$line\\n\""
}
close $fh
puts ";"
exit 0
}
# Read environment for clues:
if {[info exists env(X11VNC_PROG)]} {
set x11vnc_prog $env(X11VNC_PROG);
} else {
set x11vnc_prog "x11vnc";
}
if {[info exists env(X11VNC_CMDLINE)]} {
set x11vnc_cmdline $env(X11VNC_CMDLINE);
} else {
set x11vnc_cmdline "";
}
if {[info exists env(X11VNC_CONNECT)]} {
set x11vnc_connect 1
} else {
set x11vnc_connect 0;
}
if {[info exists env(X11VNC_XDISPLAY)]} {
set x11vnc_xdisplay $env(X11VNC_XDISPLAY);
set x11vnc_connect 1
} elseif {$argv != "" && [regexp {:[0-9]} $argv]} {
set x11vnc_xdisplay "$argv"
set x11vnc_connect 1
} elseif {[info exists env(DISPLAY)]} {
set x11vnc_xdisplay $env(DISPLAY);
} else {
set x11vnc_xdisplay ":0";
}
set hostname [exec uname -n]
#puts [exec env]
#puts "x11vnc_xdisplay: $x11vnc_xdisplay"
set env(X11VNC_STD_HELP) 1
# scrape the help output for the text and remote control vars:
parse_help;
parse_remote_help;
parse_query_help;
# tweaks to duplicate help text:
tweak_remote_help lock deny
tweak_remote_help unlock deny
tweak_both quiet q
tweak_help logfile o
tweak_both xwarppointer xwarp
tweak_both screen_blank sb
set_template
wm title . "tkx11vnc"
make_widgets;
menu_bindings;
key_bindings;
if {$x11vnc_connect} {
try_connect_and_query_all
}
set_widgets
# main loop.
/*
* tkx11vnc.h: generated by 'tkx11vnc -spit'
* Abandon all hope, ye who enter here...
* ...edit tkx11vnc instead.
*/
char gui_code[] =
"#!/bin/sh\n"
"# the next line restarts using wish. \\\n"
"exec wish \"$0\" \"$@\"\n"
"catch {rename send {}}\n"
"#\n"
"# Copyright (c) 2004 Karl J. Runge <runge@karlrunge.com>\n"
"# All rights reserved.\n"
"#\n"
"# This is free software; you can redistribute it and/or modify\n"
"# it under the terms of the GNU General Public License as published by\n"
"# the Free Software Foundation; either version 2 of the License, or\n"
"# (at your option) any later version.\n"
"#\n"
"# This software is distributed in the hope that it will be useful,\n"
"# but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
"# GNU General Public License for more details.\n"
"#\n"
"# You should have received a copy of the GNU General Public License\n"
"# along with this software; if not, write to the Free Software\n"
"# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,\n"
"# USA.\n"
"\n"
"#\n"
"# tkx11vnc v0.1\n"
"# This is a simple frontend to x11vnc. It uses the remote control\n"
"# and query features (-remote/-query aka -R/-Q) to interact with it. \n"
"# It is just a quick-n-dirty hack (it parses -help output, etc), but\n"
"# it could be of use playing with or learning about the (way too) many\n"
"# parameters x11vnc has.\n"
"# \n"
"# It can be used to interact with a running x11vnc (see the x11vnc\n"
"# -gui option), or to set the parameters and then start up x11vnc. \n"
"# \n"
"\n"
"#\n"
"# Below is a simple picture of how the gui should be laid out and how\n"
"# the menus should be organized. Most menu items correspond to remote\n"
"# control commands. A trailing \":\" after the item name means it is a string\n"
"# to be set rather than a boolean that can be toggled (e.g. the entry\n"
"# box must be used).\n"
"#\n"
"# Some tweak options may be set in the prefix \"=\" string.\n"
"# A means it is an \"Action\" (not a true variable)\n"
"# R means it is an action only valid in remote mode.\n"
"# S means it is an action only valid in startup mode.\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"
"# (i.e. perhaps it causes x11vnc to do a lot of work, new fb)\n"
"# P means the string can be +/- appended/deleted (string may not\n"
"# be the same after the remote command)\n"
"# G means gui internal item\n"
"# F means can be set via file browse\n"
"# -C:val1,... means it will be a checkbox (radio button)\n"
"# the \"-\" means no other options follow\n"
"# 0 means to skip the item.\n"
"# -- means add a separator\n"
"#\n"
"proc set_template {} {\n"
" global template\n"
" set template \"\n"
"Row: Actions Clients Permissions Keyboard Pointer Help\n"
"Row: Displays Screen Tuning Debugging Misc\n"
"\n"
"Actions\n"
" =SA start\n"
" =RA stop\n"
" =GA attach\n"
" =RA detach\n"
" --\n"
" =RA ping\n"
" =RA update-all\n"
" =GA clear-all\n"
" --\n"
" =GA Quit \n"
"\n"
"Help\n"
" =GA gui\n"
" =GA all\n"
"\n"
"Clients\n"
" =RQA current:\n"
" =F connect:\n"
" =RQA disconnect:\n"
" --\n"
" accept:\n"
" gone:\n"
" vncconnect\n"
" --\n"
" =F httpdir:\n"
" httpport:\n"
" enablehttpproxy\n"
"\n"
"Displays\n"
" display:\n"
" =F auth:\n"
" desktop:\n"
" rfbport:\n"
" =0 gui:\n"
"\n"
"Screen\n"
" =DRA refresh\n"
" =DRA reset\n"
" =DRA blacken\n"
" --\n"
" =D id:\n"
" =D sid:\n"
" =D scale:\n"
" --\n"
" =D overlay\n"
" overlay_nocursor\n"
" --\n"
" =D visual:\n"
" flashcmap\n"
" notruecolor\n"
" --\n"
" =DP blackout:\n"
" =D xinerama\n"
" --\n"
" = xrandr\n"
" =-C:resize,newfbsize,exit xrandr_mode:\n"
" padgeom:\n"
"\n"
"Keyboard\n"
" norepeat\n"
" add_keysyms\n"
" modtweak\n"
" xkb\n"
" skip_keycodes:\n"
" --\n"
" =FP remap:\n"
" --\n"
" clear_mods\n"
" clear_keys\n"
"\n"
"Pointer\n"
" =-C:none,arrow,X,some,most cursor:\n"
" noxfixes\n"
" --\n"
" cursorpos\n"
" nocursorshape\n"
" --\n"
" buttonmap:\n"
" --\n"
" xwarppointer\n"
"\n"
"Misc\n"
" =F rc:\n"
" norc\n"
" --\n"
" nofb\n"
" --\n"
" nobell\n"
" nosel\n"
" noprimary\n"
" --\n"
" bg\n"
" =-C:ignore,exit sigpipe:\n"
" =0 inetd\n"
" --\n"
" =RA remote-cmd:\n"
" =GA all-settings\n"
"\n"
"Debugging\n"
" debug_pointer\n"
" debug_keyboard\n"
" =F logfile:\n"
" quiet\n"
" --\n"
" =G debug_gui\n"
"\n"
"Permissions\n"
" =RQA lock\n"
" =RQA unlock\n"
" =SQA deny_all\n"
" --\n"
" =FP allow:\n"
" localhost\n"
" =RA allowonce:\n"
" --\n"
" viewonly\n"
" shared\n"
" forever\n"
" --\n"
" =RA noremote\n"
" --\n"
" alwaysshared\n"
" nevershared\n"
" dontdisconnect\n"
" --\n"
" viewpasswd:\n"
" =F passwdfile:\n"
" =0 storepasswd\n"
" =F rfbauth:\n"
" passwd:\n"
" --\n"
" safer\n"
" unsafe\n"
"\n"
"Tuning\n"
" =-C:1,2,3,4 pointer_mode:\n"
" input_skip:\n"
" nodragging\n"
" --\n"
" =D noshm\n"
" flipbyteorder\n"
" onetile\n"
" --\n"
" wait:\n"
" defer:\n"
" nap\n"
" screen_blank:\n"
" --\n"
" fs:\n"
" gaps:\n"
" grow:\n"
" fuzz:\n"
" --\n"
" threads\n"
" rfbwait:\n"
" --\n"
" progressive:\n"
"\"\n"
"}\n"
"\n"
"proc set_internal_help {} {\n"
" global helptext helpall\n"
"\n"
" # set some internal item help here:\n"
" set helptext(start) \"\n"
"Launch x11vnc with the settings you have prescribed in the gui.\n"
"The x11vnc process is started in an xterm window so you can see the\n"
"output, kill it, etc.\n"
"\"\n"
"\n"
" set helptext(debug_gui) \"\n"
"Set debug_gui to get more output printed in the text area.\n"
"\"\n"
"\n"
" set helptext(detach) \"\n"
"No longer be associated with the x11vnc server. Switch to non-connected\n"
"state.\n"
"\"\n"
"\n"
" set helptext(attach) \"\n"
"Attach to the x11vnc server, if possible. Switches to connected state\n"
"if successful. To change or set the X display use \\\"Displays -> display\\\"\n"
"\"\n"
"\n"
" set helptext(ping) \"\n"
"Check if x11vnc still responds to \\\"ping\\\" remote command.\n"
"\"\n"
"\n"
" set helptext(update-all) \"\n"
"Query the x11vnc server for the current values of all variables.\n"
"Populate the values into the gui's database.\n"
"\"\n"
"\n"
" set helptext(clear-all) \"\n"
"Forget any variable settings either entered in by you or retrieved\n"
"from a running x11vnc server. Basically sets everything to 0 or\n"
"the string (unset).\n"
"\"\n"
"\n"
" set helptext(all-settings) \"\n"
"Displays the gui's database of all of the x11vnc server's current\n"
"settings. Use \\\"Actions -> update-all\\\" or \\\"Control+R\\\" to\n"
"refresh this list if it ever gets out of sync.\n"
"\"\n"
"\n"
" set helptext(remote-cmd) \"\n"
"Run a remote command (-R) or query (-Q) directly. Only a few\n"
"remote commands are not on a menu, but for those few you can\n"
"run the command directly this way. Just enter the command into\n"
"the Entry box when prompted. Use the prefix \\\"Q:\\\" to indicate\n"
"a -Q query. Examples: \\\"zero:20,20,100,100\\\", \\\"Q:ext_xfixes\\\" \n"
"\"\n"
"\n"
" set helptext(Quit) \"\n"
"Terminate the tkx11vnc gui. Any x11vnc servers will be left running.\n"
"\"\n"
"\n"
" set helptext(current) \"\n"
"Shows a menu of currently connected VNC clients on the x11vnc server.\n"
"\n"
"Allows you to find more information about them or disconnect them.\n"
"You will be prompted to confirm any disconnections.\n"
"\"\n"
"\n"
" set helptext(xrandr_mode) \"\n"
"Set the -xrandr mode value.\n"
"\"\n"
"\n"
" set helptext(all) $helpall\n"
"\n"
" set helptext(gui) \"\n"
"tkx11vnc is a simple frontend to x11vnc. Nothing fancy, it merely\n"
"provides an interface to each of the many x11vnc command line options and\n"
"remote control commands. See \\\"Help -> all\\\" for much info about x11vnc.\n"
"\n"
"Most menu items have a (?) button one can click on to get more information\n"
"about the option or command. In most cases it will be text extracted\n"
"from that in \\\"Help -> all\\\".\n"
"\n"
"There are two states tkx11vnc can be in:\n"
"\n"
" 1) Available to control a running x11vnc process.\n"
" 2) Getting ready to start a x11vnc process.\n"
"\n"
"In state 1) the Menu items available in the menus are those that\n"
"correspond to the x11vnc \\\"remote control\\\" commands. See the -remote\n"
"entry under \\\"Help -> all\\\" for a complete list. Also available is\n"
"the \\\"Actions -> stop\\\" item to shut down the running x11vnc server,\n"
"thereby changing to state 2). One could also simply \\\"Actions -> detach\\\"\n"
"leaving the x11vnc server running. \\\"Actions -> attach\\\" would\n"
"reestablish the connection.\n"
"\n"
"In state 2) the Menu items available in the menus (Actions, Clients,\n"
"etc.) are those that correspond to command line options used in starting\n"
"an x11vnc process, and the \\\"Actions -> start\\\" item executes\n"
"x11vnc thereby changing to state 1). To see what x11vnc startup command\n"
"you have built so far, look at the (?) help for \\\"Actions -> start\\\"\n"
"and it will show you what the command looks like.\n"
"\n"
"There is much overlap between the menu items available in state 1)\n"
"and state 2), but it is worth keeping in mind it is not 100%.\n"
"For example, you cannot set passwords or password files in state 1).\n"
"\n"
"Also note that there may be *two* separate X displays involved, not just\n"
"one: 1) the X display x11vnc will be polling (and making available to\n"
"VNC viewers), and 2) the X display this GUI is intended to display on.\n"
"For example, one might use ssh to access the remote machine where the\n"
"GUI would display on :11 and x11vnc would poll display :0.\n"
"\n"
"\n"
"GUI components: \n"
"--- ----------\n"
"\n"
"At the top of the gui is a info text label where information will\n"
"be posted, e.g. when traversing menu items text indicating how to get\n"
"help on the item and its current value will be displayed.\n"
"\n"
"Below the info label is the area where the menu buttons, Actions,\n"
"Clients, etc., are presented. If a menu item has a checkbox,\n"
"it corresponds to a boolean on/off variable. Otherwise it is\n"
"either a string variable, or an action not associated with a\n"
"variable (for the most part).\n"
"\n"
"Below the menu button area is a text label indicating the current x11vnc\n"
"X display being polled and the corresponding VNC display name. Both\n"
"will be \\\"(*none*)\\\" when there is no connection established.\n"
"\n"
"Below the x11 and vnc displays text label is a text area there scrolling\n"
"information about actions being taken and commands being run is displayed.\n"
"To scroll use PageUp/PageDown or the arrow keys.\n"
"\n"
"At the bottom is an entry area. When one selects a menu item that\n"
"requires supplying a string value, the label will be set to the\n"
"parameter name and one types in the new value. Then one presses the\n"
"\\\"OK\\\" button or presses \\\"Enter\\\" to set the value. Or you can press\n"
"\\\"Skip\\\" or \\\"Escape\\\" to avoid changing the variable. Some variables\n"
"are boolean toggles (for example, \\\"Permissions -> viewonly\\\") or Radio\n"
"button selections. Selecting these menu items will not activate the\n"
"entry area but rather toggle the variable directly.\n"
"\n"
"Cascades: There is a bug not yet worked around for the cascade menus\n"
"where the (?) help button gets in the way. To get the mouse over to\n"
"the cascade menu click and release mouse to activate the cascade, then\n"
"you can click on its items. Dragging with a mouse button held down\n"
"will not work (sorry).\n"
"\n"
"Key Bindings:\n"
"\n"
" In the Text Area: Control-/ selects all of the text.\n"
" Anywhere: Control-d invokes \\\"Actions -> detach\\\"\n"
" Anywhere: Control-a invokes \\\"Actions -> attach\\\"\n"
" Anywhere: Control-p invokes \\\"Actions -> ping\\\"\n"
" Anywhere: Control-u and Control-r invoke \\\"Actions -> update-all\\\"\n"
"\n"
"\"\n"
"}\n"
"\n"
"proc center_win {w} {\n"
" wm withdraw $w\n"
" set x [expr [winfo screenwidth $w]/2 - [winfo reqwidth $w]/2];\n"
" set y [expr [winfo screenheight $w]/2 - [winfo reqheight $w]/2];\n"
" wm geom $w +$x+$y\n"
" wm deiconify $w\n"
" update\n"
"}\n"
"\n"
"proc textwidth {text} {\n"
" set min 0;\n"
" foreach line [split $text \"\\n\"] {\n"
" set n [string length $line]\n"
" if {$n > $min} {\n"
" set min $n\n"
" }\n"
" }\n"
" return $min\n"
"}\n"
"\n"
"proc textheight {text} {\n"
" set count 0;\n"
" foreach line [split $text \"\\n\"] {\n"
" incr count\n"
" }\n"
" return $count\n"
"}\n"
"\n"
"proc make_toplevel {w {title \"\"}} {\n"
" catch {destroy $w}\n"
" toplevel $w;\n"
" bind $w <Escape> \"destroy $w\"\n"
" if {$title != \"\"} {\n"
" wm title $w $title\n"
" }\n"
"}\n"
"\n"
"proc textwin {name title text} {\n"
" global max_text_height max_text_width\n"
" global bfont\n"
"\n"
" set width [textwidth $text]\n"
" incr width\n"
" if {$width > $max_text_width} {\n"
" set width $max_text_width\n"
" }\n"
" set height [textheight $text]\n"
" if {$height > $max_text_height} {\n"
" set height $max_text_height\n"
" }\n"
"\n"
" set w \".text_$name\"\n"
" make_toplevel $w $title\n"
"\n"
" frame $w.f -bd 0;\n"
" pack $w.f -fill both -expand 1\n"
" text $w.f.t -width $width -height $height -setgrid 1 -bd 2 \\\n"
" -yscrollcommand \"$w.f.y set\" -relief ridge -font fixed;\n"
" scrollbar $w.f.y -orient v -relief sunken -command \"$w.f.t yview\";\n"
" button $w.f.b -text \"Dismiss\" -command \"destroy $w\" -font $bfont\n"
"\n"
" $w.f.t insert 1.0 $text;\n"
"\n"
" bind $w <Enter> \"focus $w.f.t\"\n"
"\n"
" wm withdraw $w\n"
" pack $w.f.b -side bottom -fill x \n"
" pack $w.f.y -side right -fill y;\n"
" pack $w.f.t -side top -fill both -expand 1;\n"
" update\n"
"\n"
" center_win $w\n"
"}\n"
"\n"
"proc active_when_connected {item} {\n"
" global helpremote helptext\n"
"\n"
" if {[opt_match G $item]} {\n"
" return 1\n"
" } elseif {[is_action $item]} {\n"
" if {[opt_match R $item]} {\n"
" return 1\n"
" } else {\n"
" return 0\n"
" }\n"
" } elseif {[info exists helpremote($item)]} {\n"
" return 1\n"
" } else {\n"
" return 0\n"
" }\n"
"}\n"
"\n"
"proc active_when_starting {item} {\n"
" global helpremote helptext\n"
"\n"
" if {[opt_match G $item]} {\n"
" return 1\n"
" } elseif {[is_action $item]} {\n"
" if {[opt_match S $item]} {\n"
" return 1\n"
" } else {\n"
" return 0\n"
" }\n"
" } elseif {[info exists helptext($item)]} {\n"
" return 1\n"
" } else {\n"
" return 0\n"
" }\n"
"}\n"
"\n"
"proc help_win {item} {\n"
" global helptext helpremote\n"
" global query_ans query_aro;\n"
"\n"
" set ok 0\n"
" set text \"Help on $item:\\n\\n\"\n"
"\n"
" if {[is_gui_internal $item]} {\n"
" ;\n"
" } elseif {[is_action $item]} {\n"
" append text \" + Is a remote control Action (cannot be set).\\n\";\n"
" } elseif {[active_when_connected $item]} {\n"
" append text \" + Can be changed in a running x11vnc.\\n\";\n"
" } else {\n"
" append text \" - Cannot be changed in a running x11vnc.\\n\";\n"
" }\n"
" if {[is_gui_internal $item]} {\n"
" ;\n"
" } elseif {[active_when_starting $item]} {\n"
" append text \" + Can be set at x11vnc startup.\\n\";\n"
" } else {\n"
" append text \" - Cannot be set at x11vnc startup.\\n\";\n"
" }\n"
" append text \"\\n\"\n"
"\n"
" if {[info exists helptext($item)]} {\n"
" append text \"\\n\"\n"
" if {[is_gui_internal $item]} {\n"
" append text \"==== x11vnc help: ====\\n\";\n"
" } else {\n"
" append text \"==== x11vnc startup option help: ====\\n\";\n"
" }\n"
" append text \"\\n\"\n"
" append text $helptext($item)\n"
" append text \"\\n\"\n"
" set ok 1\n"
" }\n"
"\n"
" if {[info exists helpremote($item)]} {\n"
" append text \"\\n\"\n"
" append text \"==== x11vnc remote control help: ====\\n\";\n"
" append text \"\\n\"\n"
" append text $helpremote($item)\n"
" set ok 1\n"
" }\n"
"\n"
" if {$item == \"start\"} {\n"
" set str [get_start_x11vnc_txt]\n"
" append text $str\n"
" append_text \"$str\\n\"\n"
" }\n"
"\n"
" regsub -all { } $item \" \" name\n"
"\n"
" if {$ok} {\n"
" textwin $name \"x11vnc help: $item\" \"$text\";\n"
" }\n"
" return $ok\n"
"}\n"
"\n"
"proc parse_help {} {\n"
" global env x11vnc_prog;\n"
" global helpall helptext;\n"
"\n"
" set helppipe [open \"| $x11vnc_prog -help\" \"r\"];\n"
" if {$helppipe == \"\"} {\n"
" puts stderr \"failed to run $x11vnc_prog -help\";\n"
" exit 1;\n"
" }\n"
"\n"
" set sawopts 0;\n"
" set curropt \"\";\n"
" while {[gets $helppipe line] > -1} {\n"
" append helpall \"$line\\n\" \n"
"\n"
" # XXX\n"
" if {[regexp {^Options:} $line]} {\n"
" set sawopts 1;\n"
" continue;\n"
" }\n"
" # XXX\n"
" if {[regexp {^These options} $line]} {\n"
" continue;\n"
" }\n"
"\n"
" if {! $sawopts} {\n"
" continue;\n"
" }\n"
" if {[regexp {^-([A-z_][A-z_]*)} $line match name]} {\n"
" set allnames($name) 1;\n"
" if {\"$curropt\" != \"no$name\" && \"no$curropt\" != \"$name\"} {\n"
" set curropt $name;\n"
" set helptext($curropt) \"$line\\n\";\n"
" } else {\n"
" append helptext($curropt) \"$line\\n\";\n"
" }\n"
" } elseif {$curropt != \"\"} {\n"
" append helptext($curropt) \"$line\\n\";\n"
" }\n"
" }\n"
" foreach name [array names allnames] {\n"
" if {[regexp {^no} $name]} {\n"
" regsub {^no} $name \"\" pair\n"
" } else {\n"
" set pair \"no$name\"\n"
" }\n"
" if {[info exists helptext($name)]} {\n"
" if ![info exists helptext($pair)] {\n"
" set helptext($pair) $helptext($name);\n"
" }\n"
" } elseif {[info exists helptext($pair)]} {\n"
" if ![info exists helptext($name)] {\n"
" set helptext($name) $helptext($pair);\n"
" }\n"
" }\n"
" }\n"
"\n"
" set_internal_help\n"
"}\n"
"\n"
"proc tweak_both {new old} {\n"
" tweak_help $new $old\n"
" tweak_remote_help $new $old\n"
"}\n"
"\n"
"proc tweak_remote_help {new old} {\n"
" global helpremote\n"
" if ![info exists helpremote($new)] {\n"
" if {[info exists helpremote($old)]} {\n"
" set helpremote($new) $helpremote($old)\n"
" }\n"
" }\n"
"}\n"
"\n"
"proc tweak_help {new old} {\n"
" global helptext\n"
" if ![info exists helptext($new)] {\n"
" if {[info exists helptext($old)]} {\n"
" set helptext($new) $helptext($old)\n"
" }\n"
" }\n"
"}\n"
"\n"
"proc parse_remote_help {} {\n"
" global helpremote helptext help_indent remote_name;\n"
"\n"
" set sawopts 0;\n"
" set curropt \"\";\n"
" set possopts \"\";\n"
" set offset [expr $help_indent - 1];\n"
" foreach line [split $helptext(remote) \"\\n\"] {\n"
" \n"
" set line [string range $line $offset end];\n"
"\n"
" # XXX\n"
" if {[regexp {^The following -remote/-R commands} $line]} {\n"
" set sawopts 1;\n"
" continue;\n"
" }\n"
" # XXX\n"
" if {[regexp {^The vncconnect.*command} $line]} {\n"
" set sawopts 0;\n"
" }\n"
"\n"
" if {! $sawopts} {\n"
" continue;\n"
" }\n"
" if {[regexp {^([A-z_][A-z_:]*)} $line match name]} {\n"
" regsub {:.*$} $name \"\" popt\n"
" lappend possopts $popt\n"
" if {\"$curropt\" != \"no$name\" && \"no$curropt\" != \"$name\"} {\n"
" set curropt $name;\n"
" regsub {:.*$} $curropt \"\" curropt\n"
" set remote_name($curropt) $name\n"
" set helpremote($curropt) \"$line\\n\";\n"
" } else {\n"
" append helpremote($curropt) \"$line\\n\";\n"
" }\n"
" } elseif {$curropt != \"\"} {\n"
" append helpremote($curropt) \"$line\\n\";\n"
" }\n"
" }\n"
"\n"
" foreach popt $possopts {\n"
" if {[info exists helpremote($popt)]} {\n"
" continue\n"
" }\n"
" if {[regexp {^no} $popt]} {\n"
" regsub {^no} $popt \"\" try\n"
" } else {\n"
" set try \"no$popt\"\n"
" }\n"
" if {[info exists helpremote($try)]} {\n"
" set helpremote($popt) $helpremote($try)\n"
" }\n"
" }\n"
"}\n"
"\n"
"proc parse_query_help {} {\n"
" global query_ans query_aro query_ans_list query_aro_list helptext;\n"
"\n"
" set sawans 0;\n"
" set sawaro 0;\n"
" set ans_str \"\"\n"
" set aro_str \"\"\n"
"\n"
" foreach line [split $helptext(query) \"\\n\"] {\n"
"\n"
" if {! $sawans && [regexp {^ *ans=} $line]} {\n"
" set sawans 1\n"
" }\n"
" if {! $sawans} {\n"
" continue\n"
" }\n"
"\n"
" if {[regexp {^ *aro=} $line]} {\n"
" set sawaro 1\n"
" }\n"
" if {$sawaro && [regexp {^[ ]*$} $line]} {\n"
" set sawans 0\n"
" break\n"
" }\n"
"\n"
" regsub {ans=} $line \"\" line\n"
" regsub {aro=} $line \"\" line\n"
" set line [string trim $line]\n"
"\n"
" if {$sawaro} {\n"
" set aro_str \"$aro_str $line\"\n"
" } else {\n"
" set ans_str \"$ans_str $line\"\n"
" }\n"
" }\n"
"\n"
" regsub -all { *} $ans_str \" \" ans_str\n"
" regsub -all { *} $aro_str \" \" aro_str\n"
"\n"
" set ans_str [string trim $ans_str]\n"
" set aro_str [string trim $aro_str]\n"
" set query_ans_list [split $ans_str]\n"
" set query_aro_list [split $aro_str]\n"
"\n"
" foreach item $query_ans_list {\n"
" if {[regexp {^[ ]*$} $item]} {\n"
" continue\n"
" }\n"
" set query_ans($item) 1\n"
" }\n"
" foreach item $query_aro_list {\n"
" if {[regexp {^[ ]*$} $item]} {\n"
" continue\n"
" }\n"
" set query_aro($item) 1\n"
" }\n"
"}\n"
"\n"
"proc in_debug_mode {} {\n"
" global menu_var\n"
" if {![info exists menu_var(debug_gui)]} {\n"
" return 0\n"
" }\n"
" return $menu_var(debug_gui)\n"
"}\n"
"\n"
"# Menubar utilities:\n"
"proc menus_state {state} {\n"
" global menu_b\n"
"\n"
" foreach case [array names menu_b] {\n"
" set menu_button $menu_b($case)\n"
" $menu_button configure -state $state\n"
" }\n"
"}\n"
"\n"
"proc menus_enable {} {\n"
" menus_state \"normal\"\n"
"}\n"
"\n"
"proc menus_disable {} {\n"
" menus_state \"disabled\"\n"
"}\n"
"\n"
"# Entry box utilities:\n"
"proc entry_state {x state} {\n"
" global entry_box entry_label entry_ok entry_help entry_skip entry_browse\n"
" if {$x == \"all\"} {\n"
" $entry_label configure -state $state\n"
" $entry_box configure -state $state\n"
" $entry_ok configure -state $state\n"
" $entry_skip configure -state $state\n"
" $entry_help configure -state $state\n"
" $entry_browse configure -state $state\n"
" } elseif {$x == \"label\"} {\n"
" $entry_label configure -state $state\n"
" } elseif {$x == \"box\"} {\n"
" $entry_box configure -state $state\n"
" } elseif {$x == \"ok\"} {\n"
" $entry_ok configure -state $state\n"
" } elseif {$x == \"skip\"} {\n"
" $entry_skip configure -state $state\n"
" } elseif {$x == \"help\"} {\n"
" $entry_help configure -state $state\n"
" } elseif {$x == \"browse\"} {\n"
" $entry_browse configure -state $state\n"
" }\n"
"}\n"
"\n"
"proc entry_enable {{x \"all\"}} {\n"
" entry_state $x normal\n"
"}\n"
"\n"
"proc entry_disable {{x \"all\"}} {\n"
" entry_state $x disabled\n"
"}\n"
"\n"
"proc entry_browse_button {{show 1}} {\n"
" global entry_browse\n"
" if {$show} {\n"
" pack $entry_browse -side left\n"
" } else {\n"
" pack forget $entry_browse\n"
" }\n"
"}\n"
"proc entry_focus {} {\n"
" global entry_box\n"
" focus $entry_box\n"
"}\n"
"proc entry_select {} {\n"
" global entry_box\n"
" $entry_box selection range 0 end\n"
"}\n"
"proc entry_get {} {\n"
" global entry_box\n"
" return [$entry_box get]\n"
"}\n"
"proc entry_insert {str} {\n"
" global entry_box\n"
" entry_delete\n"
" $entry_box insert end $str\n"
" $entry_box icursor end\n"
"}\n"
"proc entry_delete {} {\n"
" global entry_box\n"
" $entry_box delete 0 end\n"
"}\n"
"\n"
"\n"
"# Utilities for remote control and updating vars.\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"
"\n"
" set debug [in_debug_mode]\n"
" set do_query_all 0\n"
" set getout 0\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 \"-R\" \"$new\"]\n"
" set qargs [list \"-Q\" \"$qtmp\"]\n"
" set getout 1\n"
" } else {\n"
" set rargs [list \"-Q\" \"$qtmp\"]\n"
" set qargs [list \"-Q\" \"$qtmp\"]\n"
" }\n"
"\n"
" } elseif {[value_is_string $item]} {\n"
" set rargs [list \"-R\" \"$name:$new\"]\n"
" set qargs [list \"-Q\" \"$name\"]\n"
" } else {\n"
" set rargs [list \"-R\" \"$name\"]\n"
" set qargs [list \"-Q\" \"$name\"]\n"
" }\n"
"\n"
" if {!$debug} {\n"
" append_text \"x11vnc $rargs ...\"\n"
" }\n"
" set remote_output [run_remote_cmd $rargs]\n"
"\n"
" if {[lindex $rargs 0] == \"-Q\"} {\n"
" append_text \"\\t$remote_output\"\n"
" set getout 1\n"
" } elseif {! $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"
" if {$getout} {\n"
" append_text \"\\n\"\n"
" return\n"
" }\n"
"\n"
" stop_watch on\n"
" after $delay_sleep\n"
" if {[opt_match D $item]} {\n"
" set s [expr $extra_sleep/$extra_sleep_split] \n"
" append_text \" \"\n"
" for {set i 0} {$i<$extra_sleep_split} {incr i} {\n"
" after $s\n"
" append_text \".\"\n"
" update\n"
" }\n"
" }\n"
" stop_watch off\n"
"\n"
" if {!$debug} {\n"
" append_text \", -Q ...\"\n"
" }\n"
"\n"
" if {$item == \"disconnect\"} {\n"
" set new \"N/A\"\n"
" set do_query_all 1\n"
" }\n"
"\n"
" if {$always_update || $do_query_all} {\n"
" set query [query_all 1]\n"
" } else {\n"
" set query [run_remote_cmd $qargs]\n"
" }\n"
" set query_output $query\n"
"\n"
" if {![see_if_ok $query $item \"$name:$new\"]} {\n"
" # failed\n"
" if {[regexp {^a..=} $query]} {\n"
" # but some result came back\n"
" if {! $always_update} {\n"
" # synchronize everything\n"
" set query_output [query_all 1]\n"
" }\n"
" } else {\n"
" # server may be dead\n"
" if {$item != \"ping\" && $item != \"attach\"} {\n"
" try_connect\n"
" }\n"
" }\n"
" } else {\n"
" # succeeded\n"
" if {! $always_update} {\n"
" # synchronize this variable\n"
" update_menu_vars $query\n"
" } else {\n"
" # already done in query_all\n"
" }\n"
" }\n"
"}\n"
"\n"
"# For updating a string variable. Also used for simple OK/Skip dialogs\n"
"# with entry = 0.\n"
"proc entry_dialog {item {entry 1}} {\n"
" global menu_var entry_str entry_set entry_dialog_item\n"
" global unset_str connected_to_x11vnc\n"
"\n"
" set entry_str \"Set $item\"\n"
" set entry_set 0\n"
" set entry_dialog_item $item\n"
"\n"
" entry_enable\n"
" menus_disable\n"
"\n"
" if {$entry} {\n"
" entry_insert \"\"\n"
" if {[info exists menu_var($item)] &&\n"
" $menu_var($item) != $unset_str} {\n"
" entry_insert $menu_var($item)\n"
" entry_select\n"
" }\n"
"\n"
" if {[is_browse $item]} {\n"
" entry_browse_button\n"
" }\n"
" set_info \"Set parameter in entry box, \"\n"
" entry_focus\n"
" } else {\n"
" entry_disable box\n"
" }\n"
"\n"
" update\n"
"\n"
" # wait for user reply:\n"
" vwait entry_set\n"
"\n"
" set rc $entry_set\n"
" set entry_set 0\n"
"\n"
" set value [entry_get]\n"
" update\n"
"\n"
" entry_browse_button 0\n"
" set entry_str \"Set... :\"\n"
"\n"
" entry_delete\n"
" entry_disable\n"
" menus_enable\n"
" update\n"
"\n"
" if {! $entry} {\n"
" ;\n"
" } elseif {$rc} {\n"
" set menu_var($item) $value\n"
" } else {\n"
" if {[in_debug_mode]} {\n"
" append_text \"skipped setting $item\\n\"\n"
" }\n"
" }\n"
" return $rc\n"
"}\n"
"\n"
"proc warning_dialog {msg {item \"gui\"} } {\n"
" append_text $msg\n"
" # just reuse the entry widgets for a yes/no dialog\n"
" return [entry_dialog $item 0]\n"
"}\n"
"\n"
"# For updating a boolean toggle:\n"
"proc check_var {item} {\n"
" global menu_var\n"
"\n"
" set inval $menu_var($item);\n"
"\n"
" if {$item == \"debug_gui\"} {\n"
" return \"\";\n"
" }\n"
"\n"
" set rname $item\n"
" if {! $inval} {\n"
" if {[regexp {^no} $item]} {\n"
" regsub {^no} $rname \"\" rname\n"
" } else {\n"
" set rname \"no$rname\"\n"
" }\n"
" }\n"
" return $rname\n"
"}\n"
"\n"
"proc see_if_ok {query item expected} {\n"
" set ok 0\n"
" set found \"\"\n"
" foreach q [split_query $query] {\n"
" if {[regexp \"^$item:\" $q]} {\n"
" set found $q\n"
" }\n"
" if {$q == $expected} {\n"
" set ok 1\n"
" }\n"
" }\n"
" if {$found == \"\"} {\n"
" set msg $query\n"
" regsub {^a..=} $msg {} msg\n"
" if {[string length $msg] > 60} {\n"
" set msg [string range $msg 0 60]\n"
" }\n"
" } else {\n"
" set msg $found\n"
" }\n"
" if {$ok} {\n"
" append_text \"\\tSet OK ($msg)\\n\"\n"
" return 1\n"
"\n"
" } elseif {[opt_match P $item] && [regexp {:(-|\\+)} $expected]} {\n"
" # e.g. blackout:+30x30+20+20\n"
" append_text \"\\t($msg)\\n\"\n"
" return 1\n"
" } else {\n"
" append_text \"\\t*FAILED* $msg\\n\"\n"
" return 0\n"
" }\n"
"}\n"
"\n"
"proc update_menu_vars {{query \"\"}} {\n"
" global all_settings menu_var\n"
"\n"
" set debug [in_debug_mode]\n"
"\n"
" if {$query == \"\"} {\n"
" set qstr $all_settings\n"
" } else {\n"
" set qstr $query\n"
" }\n"
" foreach piece [split_query $qstr] {\n"
" if {[regexp {^([^:][^:]*):(.*)$} $piece m0 item val]} {\n"
" if {[info exists menu_var($item)]} {\n"
" set old $menu_var($item)\n"
" if {$val == \"N/A\"} {\n"
" continue\n"
" }\n"
" if {$debug} {\n"
" puts \"setting menuvar: $item: $old -> $val\"\n"
" }\n"
" set menu_var($item) $val\n"
" }\n"
" if {$item == \"clients\"} {\n"
" update_clients_menu $val\n"
" }\n"
" }\n"
" }\n"
"}\n"
"\n"
"proc clear_all {} {\n"
" global menu_var unset_str\n"
"\n"
" set debug [in_debug_mode]\n"
" \n"
" foreach item [array names menu_var] {\n"
" if {$item == \"debug_gui\"} {\n"
" continue\n"
" }\n"
" if {[info exists menu_var($item)]} {\n"
" if [is_action $item] {\n"
" set menu_var($item) \"\"\n"
" } elseif {[value_is_bool $item]} {\n"
" set menu_var($item) 0\n"
" } elseif {[value_is_string $item]} {\n"
" set menu_var($item) $unset_str\n"
" }\n"
" }\n"
" }\n"
"}\n"
"\n"
"proc all_query_vars {} {\n"
" global query_ans_list query_aro_list all_settings\n"
" \n"
" set qry \"\"\n"
" foreach item $query_ans_list {\n"
" if {$qry == \"\"} {\n"
" set qry $item\n"
" } else {\n"
" append qry \",$item\"\n"
" }\n"
" }\n"
" foreach item $query_aro_list {\n"
" if {$qry == \"\"} {\n"
" set qry $item\n"
" } else {\n"
" append qry \",$item\"\n"
" }\n"
" }\n"
" return $qry\n"
"}\n"
"\n"
"proc query_all {{quiet 0}} {\n"
" global query_ans_list query_aro_list all_settings\n"
"\n"
" set qry [all_query_vars]\n"
"\n"
" #puts \"into query_all $quiet\"\n"
"\n"
" set qargs [list \"-Q\" $qry]\n"
" set all [run_remote_cmd $qargs]\n"
"\n"
" if {[regexp {ans=} $all]} {\n"
" if {! $quiet} {\n"
" append_text \"Retrieved all settings.\\n\"\n"
" }\n"
" set all_settings $all\n"
" update_menu_vars $all\n"
" } else {\n"
" if {! $quiet} {\n"
" append_text \"Failed to retrieve settings.\\n\"\n"
" }\n"
" }\n"
" return $all\n"
"}\n"
"\n"
"proc set_info {str} {\n"
" global info_str\n"
" set info_str \"$str\"\n"
" update\n"
"}\n"
"\n"
"proc append_text {str} {\n"
" global text_area\n"
" $text_area insert end $str\n"
" $text_area see end\n"
"}\n"
"\n"
"proc show_all_settings {} {\n"
" global all_settings\n"
" set txt \"\\nRead-Write setting:\\n\\n\"\n"
" foreach item [split_query $all_settings] {\n"
" regsub {:} $item {: } item\n"
" append txt \" $item\\n\"\n"
" if {[regexp {noremote} $item]} {\n"
" append txt \"\\nRead-Only setting:\\n\\n\"\n"
" }\n"
" }\n"
" textwin \"Settings\" \"All Current Settings\" $txt\n"
"}\n"
"\n"
"proc set_connected {yesno} {\n"
" global connected_to_x11vnc\n"
" set orig $connected_to_x11vnc\n"
" \n"
" if {$yesno == \"yes\"} {\n"
" set connected_to_x11vnc 1\n"
" } else {\n"
" set connected_to_x11vnc 0\n"
" no_x11_display\n"
" no_vnc_display\n"
" }\n"
" if {$orig != $connected_to_x11vnc} {\n"
" set_widgets\n"
" }\n"
"}\n"
"\n"
"proc detach_from_display {} {\n"
" global connected_to_x11vnc reply_xdisplay x11vnc_xdisplay\n"
" set str \"Detaching from X display.\"\n"
" if {$reply_xdisplay != \"\"} {\n"
" set str \"Detaching from $reply_xdisplay.\"\n"
" } elseif {$x11vnc_xdisplay != \"\"} {\n"
" set str \"Detaching from $x11vnc_xdisplay.\"\n"
" }\n"
" if {$connected_to_x11vnc} {\n"
" append_text \"$str\\n\"\n"
" }\n"
" set_connected no\n"
"}\n"
"\n"
"# Menu item is an action:\n"
"proc do_action {item} {\n"
" global menu_var connected_to_x11vnc\n"
"\n"
" if {[in_debug_mode]} {\n"
" append_text \"action: \\\"$item\\\"\\n\"\n"
" }\n"
"\n"
" if {$item == \"ping\"} {\n"
" try_connect\n"
" return\n"
" } elseif {$item == \"start\"} {\n"
" start_x11vnc\n"
" return\n"
" } elseif {$item == \"detach\"} {\n"
" detach_from_display\n"
" return\n"
" } elseif {$item == \"attach\"} {\n"
" try_connect_and_query_all\n"
" return\n"
" } elseif {$item == \"update-all\"} {\n"
" query_all\n"
" return\n"
" } elseif {$item == \"clear-all\"} {\n"
" clear_all\n"
" return\n"
" } elseif {$item == \"all-settings\"} {\n"
" show_all_settings\n"
" return\n"
" }\n"
"\n"
" if {[value_is_string $item]} {\n"
" if {! [entry_dialog $item]} {\n"
" return\n"
" }\n"
" set new $menu_var($item)\n"
" set name $item\n"
" } else {\n"
" set new 1\n"
" set name $item\n"
" }\n"
"\n"
" if {! $connected_to_x11vnc} {\n"
" ;\n"
" } elseif {[regexp {^(stop|quit|exit|shutdown)$} $item]} {\n"
" # just do -R\n"
" append_text \"stopping remote x11vnc server...\\n\"\n"
" push_new_value $item $name $new 0\n"
" set_connected no\n"
" \n"
" } elseif [opt_match Q $item] {\n"
" push_new_value $item $name $new 1\n"
" } else {\n"
" push_new_value $item $name $new 0\n"
" }\n"
"}\n"
"\n"
"proc do_var {item} {\n"
" global connected_to_x11vnc item_cascade menu_var\n"
"\n"
" set string 0\n"
" if {[is_action $item]} {\n"
" # Menu item is action:\n"
" do_action $item\n"
" return\n"
" }\n"
"\n"
" if {[value_is_string $item]} {\n"
" # Menu item is a string:\n"
" if {$item_cascade($item) != \"\"} {\n"
" # Cascade sets variable automatically\n"
" } else {\n"
" # Otherwise Entry box\n"
" if {![entry_dialog $item]} {\n"
" return\n"
" }\n"
" }\n"
" set new $menu_var($item)\n"
" set name $item\n"
" } else {\n"
" # Menu item is a boolean:\n"
" set name [check_var $item]\n"
" if {$name == \"\"} {\n"
" return\n"
" }\n"
" set new 1\n"
" }\n"
" if {$connected_to_x11vnc} {\n"
" push_new_value $item $name $new 1\n"
" }\n"
"}\n"
"\n"
"proc menu_help {item} {\n"
" if ![help_win $item] {\n"
" textwin \"nohelp\" \"No help available\" \\\n"
" \"Sorry, no help avaiable for \\\"$item\\\"\"\n"
" }\n"
"}\n"
"\n"
"proc opt_match {c item} {\n"
" global item_opts\n"
" if {[info exists item_opts($item)]} {\n"
" if {[regexp \"^\\[A-z\\]*$c\" $item_opts($item)]} {\n"
" return 1\n"
" }\n"
" }\n"
" return 0\n"
"}\n"
"\n"
"proc is_action {item} {\n"
" return [opt_match A $item]\n"
"}\n"
"\n"
"proc is_gui_internal {item} {\n"
" return [opt_match G $item]\n"
"}\n"
"\n"
"proc is_browse {item} {\n"
" return [opt_match F $item]\n"
"}\n"
"\n"
"proc value_is_string {item} {\n"
" global item_bool\n"
" if {! $item_bool($item)} {\n"
" return 1\n"
" } else {\n"
" return 0\n"
" }\n"
"}\n"
"\n"
"proc value_is_bool {item} {\n"
" global item_bool\n"
" if {$item_bool($item)} {\n"
" return 1\n"
" } else {\n"
" return 0\n"
" }\n"
"}\n"
"\n"
"proc split_query {query} {\n"
" regsub -all {aro=} $query {ans=} query\n"
" set items {}\n"
" while {1} {\n"
" if {! [regexp {^ans=(.*)$} $query m0 m1]} {\n"
" break\n"
" }\n"
" set item $m1\n"
" set m2 \"\"\n"
" regexp {,ans=.*$} $item m2\n"
" regsub {,ans=.*$} $item \"\" item\n"
" if {$item != \"\"} {\n"
" lappend items $item\n"
" }\n"
" set query $m2\n"
" regsub {^,} $query \"\" query\n"
" }\n"
" return $items\n"
"}\n"
"\n"
"proc set_x11_display {name} {\n"
" global x11_display\n"
" set x11_display \"x11vnc X display: $name\"\n"
"}\n"
"proc set_vnc_display {name} {\n"
" global vnc_display\n"
" set vnc_display \"VNC display: $name\"\n"
"}\n"
"proc no_x11_display {} {\n"
" set_x11_display \"(*none*)\"\n"
"}\n"
"proc no_vnc_display {} {\n"
" set_vnc_display \"(*none*)\"\n"
"}\n"
"proc fetch_displays {} {\n"
"\n"
" set qargs [list \"-Q\" \"display,vncdisplay\"]\n"
" set result [run_remote_cmd $qargs]\n"
"\n"
" set got_x11 0\n"
" set got_vnc 0\n"
"\n"
" foreach item [split_query $result] {\n"
" if {[regexp {^display:(.*)$} $item m0 m1]} {\n"
" set_x11_display $m1\n"
" set got_x11 1\n"
" } elseif {[regexp {^vncdisplay:(.*)$} $item m0 m1]} {\n"
" set_vnc_display $m1\n"
" set got_vnc 1\n"
" }\n"
" }\n"
" if {! $got_x11} {\n"
" no_x11_display\n"
" }\n"
" if {! $got_vnc} {\n"
" no_vnc_display\n"
" }\n"
"}\n"
"\n"
"proc disconnect_dialog {client} {\n"
" set cid \"\"\n"
" set host \"\"\n"
" set msg \"\\n\"\n"
" append msg \"*** Client info string: $client\\n\"\n"
" if {[regexp {^(.*):(.*)/(.*)-(.*)$} $client m0 m1 m2 m3 m4]} {\n"
" if {$m4 == \"ro\"} {\n"
" set view \"(viewonly)\"\n"
" } else {\n"
" set view \"(interactive)\"\n"
" }\n"
" set host $m1\n"
" set cid $m3\n"
" append msg \"*** Host: $m1, Port: $m2 Id: $m3 $view\\n\"\n"
" }\n"
" if {$cid == \"\"} {\n"
" append_text \"Invalid client info string: $client\\n\"\n"
" return\n"
" }\n"
" append msg \"*** To disconnect this client press \\\"OK\\\", otherwise press \\\"Skip\\\"\\n\"\n"
" bell\n"
" if [warning_dialog $msg \"current\"] {\n"
" push_new_value \"disconnect\" \"disconnect\" $cid 1\n"
" } else {\n"
" append_text \"disconnect cancelled.\\n\"\n"
" }\n"
"}\n"
"\n"
"proc update_clients_menu {list} {\n"
" global item_cascade\n"
" set subm $item_cascade(current);\n"
" catch {destroy $subm}\n"
" menu $subm -tearoff 0\n"
" $subm add command\n"
" $subm add separator\n"
" set count 0\n"
" foreach client [split $list \",\"] {\n"
" regsub {:[0-9][0-9]*/} $client {/} lab\n"
" $subm add command -label \"$client\" \\\n"
" -command \"disconnect_dialog $client\"\n"
" incr count\n"
" }\n"
" $subm entryconfigure 0 -label \"#clients: $count\"\n"
"}\n"
"\n"
"proc set_widgets {} {\n"
" global connected_to_x11vnc item_case item_entry menu_m\n"
"\n"
" foreach item [array names item_case] {\n"
" set case $item_case($item)\n"
" set menu $menu_m($case)\n"
" set entry $item_entry($item)\n"
" set type [$menu type $entry]\n"
" if {$type == \"separator\" || $type == \"tearoff\"} {\n"
" continue\n"
" }\n"
" if {$connected_to_x11vnc} {\n"
" if {[active_when_connected $item]} {\n"
" $menu entryconfigure $entry -state normal\n"
" } else {\n"
" $menu entryconfigure $entry -state disabled\n"
" }\n"
" } else {\n"
" if {[active_when_starting $item]} {\n"
" $menu entryconfigure $entry -state normal\n"
" } else {\n"
" $menu entryconfigure $entry -state disabled\n"
" }\n"
" }\n"
" }\n"
"}\n"
"\n"
"proc make_widgets {} {\n"
" global template \n"
" global menu_b menu_m\n"
" global item_opts item_bool item_case item_entry menu_var unset_str\n"
" global item_cascade\n"
" global info_str x11_display vnc_display\n"
" global text_area\n"
" global entry_box entry_str entry_set entry_label entry_ok entry_browse\n"
" global entry_help entry_skip\n"
" global bfont\n"
" global helptext helpremote helplabel\n"
"\n"
"set v 0\n"
" \n"
" label .info -textvariable info_str -bd 2 -relief groove -anchor w \n"
" pack .info -side top -fill x \n"
"\n"
" # Extract the Rows:\n"
" set row 0;\n"
" set colmax 0;\n"
" foreach line [split $template \"\\n\"] {\n"
" if {[regexp {^Row: (.*)} $line rest]} {\n"
" set col 0\n"
" foreach case [split $rest] {\n"
" if {$case == \"\" || $case == \"Row:\"} {\n"
" continue\n"
" }\n"
" set menu_row($case) $row\n"
" set menu_col($case) $col\n"
" set menu_count($case) 0\n"
"\n"
" lappend cases($col) $case;\n"
" set len [string length $case]\n"
" if {[info exists max_len($col)]} {\n"
" if {$len > $max_len($col)} {\n"
" set max_len($col) $len\n"
" }\n"
" } else {\n"
" set max_len($col) $len\n"
" }\n"
" incr col\n"
" if {$col > $colmax} {\n"
" set colmax $col\n"
" }\n"
" }\n"
" incr row;\n"
" }\n"
" }\n"
"\n"
" # Make frames for the rows and make the menu buttons.\n"
" set f \".menuframe\"\n"
" frame $f\n"
" for {set c 0} {$c < $colmax} {incr c} {\n"
" set colf \"$f.menuframe$c\"\n"
" frame $colf\n"
" pack $colf -side left -fill y\n"
" set fbg [$colf cget -background]\n"
" foreach case $cases($c) {\n"
" set menub \"$colf.menu$case\";\n"
" set menu \"$colf.menu$case.menu\";\n"
" set menu_b($case) $menub\n"
" set menu_m($case) $menu\n"
" menubutton $menub -text \"$case\" -underline 0 \\\n"
" -anchor w -menu $menu -background $fbg \\\n"
" -font $bfont\n"
" pack $menub -side top -fill x\n"
" menu $menu -tearoff 0\n"
" }\n"
" }\n"
" pack $f -side top -fill x\n"
"\n"
" # Now extract the menu items:\n"
" set case \"\";\n"
" foreach line [split $template \"\\n\"] {\n"
" if {[regexp {^Row:} $line]} {\n"
" continue\n"
" }\n"
" if {[regexp {^[A-z]} $line]} {\n"
" set case [string trim $line]\n"
" continue;\n"
" }\n"
" set item [string trim $line]\n"
" regsub -all { *} $item \" \" item\n"
" if {$item == \"\"} {\n"
" continue;\n"
" }\n"
" set opts \"\"\n"
" if {[regexp {^=} $item]} {\n"
" set opts [lindex [split $item] 0]\n"
" regsub {^=} $opts \"\" opts\n"
" set item [lindex [split $item] 1]\n"
" }\n"
" if {[regexp {^0} $opts]} {\n"
" continue;\n"
" }\n"
" if {[regexp {:$} $item]} {\n"
" set bool 0\n"
" } else {\n"
" set bool 1\n"
" }\n"
" regsub {:$} $item {} item\n"
"\n"
" set item_opts($item) $opts\n"
" set item_case($item) $case\n"
" set item_bool($item) $bool\n"
" set item_cascade($item) \"\"\n"
" set item_entry($item) $menu_count($case)\n"
"\n"
"if {$v} { puts \"ITEM: $item - $opts - $case - $bool - $menu_count($case)\" }\n"
"\n"
" set mvar 0 \n"
" set m $menu_m($case)\n"
"\n"
" # Create the menu items, its variables, etc., etc.\n"
"\n"
" if {$item == \"--\"} {\n"
" $m add separator\n"
"\n"
" } elseif {$item == \"Quit\"} {\n"
" # Quit item must shut us down:\n"
" $m add command -label \"$item\" -underline 0 \\\n"
" -command {destroy .; exit 0}\n"
"\n"
" } elseif {$case == \"Help\"} {\n"
" # Help is simple help:\n"
" $m add command -label \"$item\" \\\n"
" -command \"menu_help $item\"\n"
"\n"
" } elseif {$item == \"current\"} {\n"
" # Current clients cascade\n"
" set subm $m.cascade$menu_count($case)\n"
" set item_cascade($item) $subm\n"
" update_clients_menu \"\"\n"
" $m add cascade -label \"$item\" \\\n"
" -menu $subm\n"
"\n"
" } elseif {[is_action $item]} {\n"
" # Action\n"
" $m add command -label \"$item\" \\\n"
" -command \"do_var $item\"\n"
" set menu_var($item) \"\"; # for convenience\n"
"\n"
" } elseif {! $item_bool($item)} {\n"
" # String\n"
" if {[regexp -- {-C:(.*)} $item_opts($item) m0 m1]} {\n"
" # Radiobutton select\n"
" set subm $m.cascade$menu_count($case)\n"
" menu $subm -tearoff 0\n"
" foreach val [split $m1 \",\"] {\n"
" $subm add radiobutton -label \"$val\" \\\n"
" -command \"do_var $item\" \\\n"
" -value \"$val\" \\\n"
" -variable menu_var($item)\n"
" }\n"
" $m add cascade -label \"$item\" \\\n"
" -menu $subm\n"
" set item_cascade($item) $subm\n"
" } else {\n"
" # Arbitrary_string\n"
" $m add command -label \"$item\" \\\n"
" -command \"do_var $item\"\n"
" }\n"
" set mvar 1\n"
"\n"
" } else {\n"
" # Boolean\n"
" $m add checkbutton -label \"$item\" \\\n"
" -command \"do_var $item\" \\\n"
" -variable menu_var($item)\n"
" set menu_var($item) 0\n"
" }\n"
"\n"
" incr menu_count($case)\n"
" if {$mvar} {\n"
" set menu_var($item) $unset_str\n"
" }\n"
" }\n"
"\n"
" # Now make the litte \"(?)\" help buttons\n"
" foreach case [array names menu_m] {\n"
" if {$case == \"Help\"} {\n"
" continue;\n"
" }\n"
" set m $menu_m($case);\n"
" set n [$m index end]\n"
"\n"
"if {$v} { puts \"$case end: $n\" }\n"
"\n"
" for {set i 0} {$i <= $n} {incr i} {\n"
" set type [$m type $i]\n"
" if {$type == \"separator\"} {\n"
" $m add separator\n"
" } elseif {$type == \"tearoff\"} {\n"
" continue;\n"
" } else {\n"
" set label [$m entrycget $i -label]\n"
" set str \"\"\n"
" if {[info exists helpremote($label)]} {\n"
" set str \"(?)\"\n"
" } elseif {[info exists helptext($label)]} {\n"
" set str \"(?)\"\n"
" }\n"
" $m add command -label $str \\\n"
" -command \"menu_help $label\";\n"
"\n"
"if {$v} {\n"
" set ht \"\"; set hr \"\"\n"
" if {[info exists helptext($label)]} { set ht \"YES\" }\n"
" if {[info exists helpremote($label)]} { set hr \"YES\" }\n"
" puts \"'$label'\\tht='$ht' hr='$hr'\"\n"
"}\n"
"\n"
" if {$str == \"\"} {\n"
" $m entryconfigure end -state disabled\n"
" }\n"
" set arg \"$m,$i\"\n"
" set helplabel($arg) $label\n"
" set j [$m index end]\n"
" set arg \"$m,$j\"\n"
" set helplabel($arg) $label\n"
" }\n"
" if {$i == 0} {\n"
" $m entryconfigure end -columnbreak 1\n"
" }\n"
" }\n"
" }\n"
"\n"
" # Make the x11 and vnc display label bar:\n"
" set df .displayframe\n"
" frame $df -bd 1 -relief groove\n"
"\n"
" set df_x11 \"$df.xdisplay\"\n"
" no_x11_display\n"
" label $df_x11 -textvariable x11_display -width 35 -anchor w\n"
"\n"
" set df_vnc \"$df.vdisplay\"\n"
" no_vnc_display\n"
" label $df_vnc -textvariable vnc_display -width 35 -anchor w\n"
"\n"
" pack $df_x11 $df_vnc -side left \n"
" pack $df -side top -fill x\n"
"\n"
" # text area\n"
" text .text -height 11 -relief ridge\n"
" set text_area .text\n"
" pack .text -side top -fill both -expand 1\n"
"\n"
"\n"
" set str \"Click Help -> gui for overview.\"\n"
" append_text \"\\n$str\\n\\n\"\n"
"\n"
" # Make entry box stuff\n"
" set ef .entryframe\n"
" frame $ef -bd 1 -relief groove\n"
"\n"
" # Label\n"
" set ef_label \"$ef.label\"\n"
" label $ef_label -textvariable entry_str -anchor w -font $bfont\n"
"\n"
" set entry_str \"Set... : \"\n"
" set ef_entry \"$ef.entry\"\n"
" entry $ef_entry -relief sunken\n"
" bind $ef_entry <KeyPress-Return> {set entry_set 1}\n"
" bind $ef_entry <KeyPress-Escape> {set entry_set 0}\n"
"\n"
" # OK button\n"
" set ef_ok \"$ef.ok\"\n"
" button $ef_ok -text OK -pady 1 -command {set entry_set 1} \\\n"
" -font $bfont\n"
"\n"
" # Skip button\n"
" set ef_skip \"$ef.skip\"\n"
" button $ef_skip -text Skip -pady 0 -command {set entry_set 0} \\\n"
" -font $bfont\n"
"\n"
" # Help button\n"
" set ef_help \"$ef.help\"\n"
" button $ef_help -text Help -pady 0 -command \\\n"
" {menu_help $entry_dialog_item} -font $bfont\n"
"\n"
" # Browse button\n"
" set ef_browse \"$ef.browse\"\n"
" button $ef_browse -text \"Browse...\" -pady 0 -font $bfont \\\n"
" -command {entry_insert [tk_getOpenFile]} \n"
"\n"
" pack $ef_label -side left\n"
" pack $ef_entry -side left -fill x -expand 1\n"
" pack $ef_ok -side right\n"
" pack $ef_skip -side right\n"
" pack $ef_help -side right\n"
" pack $ef -side bottom -fill x\n"
"\n"
" set entry_ok $ef_ok\n"
" set entry_skip $ef_skip\n"
" set entry_help $ef_help\n"
" set entry_box $ef_entry\n"
" set entry_browse $ef_browse\n"
" set entry_label $ef_label\n"
" entry_disable\n"
"\n"
" update\n"
" wm minsize . [winfo width .] [winfo height .]\n"
"}\n"
"\n"
"proc menu_bindings {} {\n"
" bind Menu <<MenuSelect>> {\n"
"#syntax hilite bug \\\n"
"MenuSelect>>\n"
" set n [%W index active]\n"
" set label \" \"\n"
" if {$n != \"none\"} {\n"
" set str %W,$n\n"
" set which \"\"\n"
" if {[info exists helplabel($str)]} {\n"
" set vname [format %%-16s $helplabel($str)]\n"
" set label \"Click (?) for help on: $vname\"\n"
" set which $helplabel($str)\n"
" }\n"
" if {$which == \"\"} {\n"
" ;\n"
" } elseif {[is_action $which]} {\n"
" if {[info exists menu_var($which)] \n"
" && $menu_var($which) != \"\"} {\n"
" set label \"$label value: $menu_var($which)\"\n"
" } else {\n"
" set label \"$label (is action)\"\n"
" }\n"
" } elseif {[info exists menu_var($which)]} {\n"
" set label \"$label value: $menu_var($which)\"\n"
" }\n"
" }\n"
" set_info $label\n"
" }\n"
"}\n"
"\n"
"proc key_bindings {} {\n"
" global env\n"
" if {[info exists env(USER)] && $env(USER) == \"runge\"} {\n"
" # quick restart\n"
" bind . <Control-KeyPress-c> {exec $argv0 $argv &; destroy .}\n"
" }\n"
" bind . <Control-KeyPress-p> {try_connect_and_query_all}\n"
" bind . <Control-KeyPress-u> {query_all 0}\n"
" bind . <Control-KeyPress-r> {query_all 0}\n"
" bind . <Control-KeyPress-d> {detach_from_display}\n"
" bind . <Control-KeyPress-a> {try_connect_and_query_all}\n"
"}\n"
"\n"
"proc stop_watch {onoff} {\n"
" global orig_cursor text_area entry_box\n"
"\n"
" set widgets [list . $text_area $entry_box] \n"
"\n"
" if {$onoff == \"on\"} {\n"
" foreach item $widgets {\n"
" $item config -cursor {watch}\n"
" }\n"
" } else {\n"
" foreach item $widgets {\n"
" $item config -cursor {}\n"
" }\n"
" }\n"
" update\n"
"}\n"
"\n"
"proc double_check_noremote {} {\n"
" set msg \"\\n\\n\"\n"
" append msg \"WARNING: setting \\\"noremote\\\" will disable ALL remote control commands\\n\"\n"
" append msg \"WARNING: (i.e. this gui will be locked out) Do you really want to do this?\\n\"\n"
" append msg \"WARNING: If so, press \\\"OK\\\", otherwise press \\\"Skip\\\"\\n\"\n"
" append msg \"\\n\"\n"
" bell\n"
" return [warning_dialog $msg \"noremote\"]\n"
"}\n"
"\n"
"proc double_check_start_x11vnc {} {\n"
" global hostname\n"
" set msg [get_start_x11vnc_txt]\n"
" append msg \"\\n\"\n"
" append msg \"*** To run the above command on machine \\\"$hostname\\\" to\\n\"\n"
" append msg \"*** start x11vnc press \\\"OK\\\" otherwise press \\\"Skip\\\".\\n\"\n"
" return [warning_dialog $msg \"start\"]\n"
"}\n"
"\n"
"proc get_start_x11vnc_txt {} {\n"
" set cmd [get_start_x11vnc_cmd]\n"
" set str [join $cmd]\n"
" set msg \"\"\n"
" append msg \"\\n\"\n"
" append msg \"==== The command built so far is: ====\\n\";\n"
" append msg \"\\n\"\n"
" append msg \"$str\\n\"\n"
" return $msg\n"
"}\n"
"\n"
"proc get_start_x11vnc_cmd {} {\n"
" global menu_var unset_str x11vnc_prog\n"
"\n"
" set xterm_cmd \"xterm -iconic -geometry 80x35 -title x11vnc-console -e\"\n"
"\n"
" set cmd [split $xterm_cmd]\n"
"\n"
" lappend cmd $x11vnc_prog\n"
"\n"
" foreach item [lsort [array names menu_var]] {\n"
" if {![active_when_starting $item]} {\n"
" continue\n"
" }\n"
" if {[is_action $item]} {\n"
" continue\n"
" }\n"
"\n"
" if {[value_is_bool $item]} {\n"
" if {[info exists menu_var($item)]} {\n"
" if {$menu_var($item)} {\n"
" lappend cmd \"-$item\"\n"
" }\n"
" }\n"
" } elseif {[value_is_string $item]} {\n"
" if {[info exists menu_var($item)]} {\n"
" if {$menu_var($item) != \"\"\n"
" && $menu_var($item) != $unset_str} {\n"
" lappend cmd \"-$item\"\n"
" lappend cmd $menu_var($item)\n"
" }\n"
" }\n"
" }\n"
" }\n"
" lappend cmd \"2>\"\n"
" lappend cmd \"/dev/null\"\n"
" lappend cmd \"&\"\n"
" \n"
" return $cmd\n"
"}\n"
"\n"
"proc start_x11vnc {} {\n"
" global menu_var unset_str\n"
" global x11vnc_prog x11vnc_xdisplay\n"
" global connected_to_x11vnc\n"
"\n"
" if {$connected_to_x11vnc} {\n"
" append_text \"\\n\"\n"
" append_text \"WARNING: Still connected to an x11vnc server.\\n\"\n"
" append_text \"WARNING: Use \\\"stop\\\" or \\\"detach\\\" first.\\n\"\n"
" return 0\n"
" }\n"
"\n"
" if {![double_check_start_x11vnc]} {\n"
" return\n"
" }\n"
"\n"
" set x11vnc_xdisplay \"\"\n"
" if {[info exists menu_var(display)]} {\n"
" if {$menu_var(display) != \"\" && $menu_var(display) != $unset_str} {\n"
" set x11vnc_xdisplay $menu_var(display)\n"
" }\n"
" }\n"
"\n"
" set cmd [get_start_x11vnc_cmd]\n"
"\n"
" set str [join $cmd]\n"
" regsub { -e} $str \" -e \\\\\\n \" str\n"
"\n"
" if {0} {\n"
" puts \"running: $str\"\n"
" foreach word $cmd {\n"
" puts \" word: $word\"\n"
" }\n"
" }\n"
"\n"
" append_text \"Starting x11vnc in an iconified xterm with command:\\n\"\n"
" append_text \" $str\\n\\n\"\n"
" catch {[eval exec $cmd]}\n"
" after 500\n"
" try_connect_and_query_all 3\n"
"}\n"
"\n"
"proc run_remote_cmd {opts} {\n"
" global menu_var x11vnc_prog x11vnc_cmdline x11vnc_xdisplay\n"
"\n"
" set debug [in_debug_mode]\n"
"\n"
" if {[lindex $opts 0] == \"-R\" && [lindex $opts 1] == \"noremote\"} {\n"
" set str [join $opts]\n"
" if ![double_check_noremote] {\n"
" append_text \"skipping: x11vnc $str\"\n"
" return \"\"\n"
" } else {\n"
" append_text \"running: x11vnc $str (please do \\\"Actions -> detach\\\" to clean things up)\\n\"\n"
" append_text \"subsequent -R/-Q commands should fail...\"\n"
" }\n"
" }\n"
"\n"
" set cmd \"\"\n"
"\n"
" lappend cmd $x11vnc_prog;\n"
"\n"
" if {$x11vnc_xdisplay != \"\"} {\n"
" lappend cmd \"-display\"\n"
" lappend cmd $x11vnc_xdisplay\n"
" }\n"
" foreach word $opts {\n"
" lappend cmd $word\n"
" }\n"
" lappend cmd \"2>\"\n"
" lappend cmd \"/dev/null\"\n"
"\n"
"if {0} {\n"
" set str [join $cmd]\n"
" puts \"running: $str\"\n"
" foreach word $cmd {\n"
" puts \" word: $word\"\n"
" }\n"
"}\n"
"\n"
" set output \"\"\n"
" stop_watch on\n"
" catch {set output [eval exec $cmd]}\n"
" stop_watch off\n"
" if {$debug} {\n"
" append_text \"output: $output\\n\"\n"
" }\n"
" return $output\n"
"}\n"
"\n"
"proc try_connect_and_query_all {{n 2}} {\n"
" for {set i 0} {$i < $n} {incr i} {\n"
" if {$i > 0} {\n"
" after 500\n"
" append_text \"trying again ...\\n\"\n"
" }\n"
" if {[try_connect]} {\n"
" query_all\n"
" break\n"
" }\n"
" }\n"
"}\n"
"\n"
"proc try_connect {} {\n"
" global x11vnc_xdisplay connected_to_x11vnc reply_xdisplay\n"
" global menu_var unset_str\n"
"\n"
" if {! $connected_to_x11vnc} {\n"
" if {[info exists menu_var(display)]} {\n"
" set d $menu_var(display)\n"
" if {$d != \"\" && $d != $unset_str && $d != $x11vnc_xdisplay} {\n"
" set x11vnc_xdisplay $menu_var(display)\n"
" append_text \"Setting X display to: $x11vnc_xdisplay\\n\"\n"
" }\n"
" }\n"
" }\n"
"\n"
" set_info \"Pinging $x11vnc_xdisplay ...\"\n"
" set rargs [list \"-Q\" \"ping\"]\n"
" set result [run_remote_cmd $rargs]\n"
"\n"
" if {[regexp {^ans=ping:} $result]} {\n"
" regsub {^ans=ping:} $result {} reply_xdisplay\n"
" set msg \"Connected to $reply_xdisplay\"\n"
" set_info $msg\n"
" append_text \"$msg\\n\"\n"
" set_connected yes\n"
" fetch_displays\n"
" return 1\n"
" } else {\n"
" set str \"x11vnc server.\"\n"
" if {$x11vnc_xdisplay != \"\"} {\n"
" set str $x11vnc_xdisplay\n"
" }\n"
" set msg \"No reply from $str\"\n"
" set_info $msg\n"
" append_text \"$msg\\n\"\n"
" set_connected no\n"
" return 0\n"
" }\n"
"}\n"
"\n"
"############################################################################\n"
"# main:\n"
"\n"
"global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect;\n"
"global helpall helptext helpremote helplabel hostname;\n"
"global all_settings reply_xdisplay always_update\n"
"global max_text_height max_text_width\n"
"global menu_var unset_str\n"
"global bfont\n"
"global connected_to_x11vnc\n"
"global delay_sleep extra_sleep extra_sleep_split\n"
"\n"
"set unset_str \"(unset)\"\n"
"set connected_to_x11vnc 0\n"
"set max_text_height 40\n"
"set max_text_width 90\n"
"set bfont -adobe-helvetica-bold-r-*-*-*-120-*-*-*-*-*-*;\n"
"set help_indent 24;\n"
"set reply_xdisplay \"\"\n"
"set all_settings \"None so far.\"\n"
"set always_update 1\n"
"\n"
"#set delay_sleep 500\n"
"#set extra_sleep 1500\n"
"set delay_sleep 350\n"
"set extra_sleep 1000\n"
"set extra_sleep_split 4\n"
"\n"
"if {\"$argv\" == \"-spit\"} {\n"
" set fh [open $argv0 r]\n"
" puts \"/*\"\n"
" puts \" * tkx11vnc.h: generated by 'tkx11vnc -spit'\"\n"
" puts \" * Abandon all hope, ye who enter here...\"\n"
" puts \" * ...edit tkx11vnc instead.\"\n"
" puts \" */\"\n"
" puts \" char gui_code\\[\\] =\"\n"
" while {[gets $fh line] > -1} {\n"
" regsub -all {\\\\} $line {\\\\\\\\} line\n"
" regsub -all {\"} $line {\\\\\"} line\n"
" puts \"\\\"$line\\\\n\\\"\"\n"
" }\n"
" close $fh\n"
" puts \";\"\n"
" exit 0\n"
"}\n"
"\n"
"# Read environment for clues:\n"
"if {[info exists env(X11VNC_PROG)]} {\n"
" set x11vnc_prog $env(X11VNC_PROG);\n"
"} else {\n"
" set x11vnc_prog \"x11vnc\";\n"
"}\n"
"\n"
"if {[info exists env(X11VNC_CMDLINE)]} {\n"
" set x11vnc_cmdline $env(X11VNC_CMDLINE);\n"
"} else {\n"
" set x11vnc_cmdline \"\";\n"
"}\n"
"\n"
"if {[info exists env(X11VNC_CONNECT)]} {\n"
" set x11vnc_connect 1\n"
"} else {\n"
" set x11vnc_connect 0;\n"
"}\n"
"\n"
"if {[info exists env(X11VNC_XDISPLAY)]} {\n"
" set x11vnc_xdisplay $env(X11VNC_XDISPLAY);\n"
" set x11vnc_connect 1\n"
"\n"
"} elseif {$argv != \"\" && [regexp {:[0-9]} $argv]} {\n"
" set x11vnc_xdisplay \"$argv\"\n"
" set x11vnc_connect 1\n"
"\n"
"} elseif {[info exists env(DISPLAY)]} {\n"
" set x11vnc_xdisplay $env(DISPLAY);\n"
"} else {\n"
" set x11vnc_xdisplay \":0\";\n"
"}\n"
"\n"
"set hostname [exec uname -n]\n"
"#puts [exec env]\n"
"#puts \"x11vnc_xdisplay: $x11vnc_xdisplay\"\n"
"\n"
"set env(X11VNC_STD_HELP) 1\n"
"\n"
"# scrape the help output for the text and remote control vars:\n"
"parse_help;\n"
"parse_remote_help;\n"
"parse_query_help;\n"
"\n"
"# tweaks to duplicate help text:\n"
"tweak_remote_help lock deny\n"
"tweak_remote_help unlock deny\n"
"\n"
"tweak_both quiet q\n"
"tweak_help logfile o\n"
"tweak_both xwarppointer xwarp\n"
"tweak_both screen_blank sb\n"
"\n"
"set_template\n"
"\n"
"wm title . \"tkx11vnc\"\n"
"make_widgets;\n"
"\n"
"menu_bindings;\n"
"key_bindings;\n"
"\n"
"if {$x11vnc_connect} {\n"
" try_connect_and_query_all\n"
"}\n"
"set_widgets\n"
"\n"
"# main loop.\n"
;
.\" This file was automatically generated from x11vnc -help output. .\" This file was automatically generated from x11vnc -help output.
.TH X11VNC "1" "August 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-08-31 version: 0.6.3pre, lastmod: 2004-12-17
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
...@@ -19,15 +19,18 @@ Then run this in another window on the machine you are sitting at: ...@@ -19,15 +19,18 @@ Then run this in another window on the machine you are sitting at:
.IP .IP
vncviewer far-host:0 vncviewer far-host:0
.PP .PP
Once x11vnc establishes connections with the X11 server and starts Once x11vnc establishes connections with the X11 server and starts listening
listening as a VNC server it will print out a string: PORT=XXXX where as a VNC server it will print out a string: PORT=XXXX where XXXX is typically
XXXX is typically 5900 (the default VNC port). One would next run something 5900 (the default VNC server port). One would next run something like
like this on the local machine: "vncviewer host:N" where N is XXXX - 5900, this on the local machine: "vncviewer hostname:N" where "hostname" is
i.e. usually "vncviewer host:0" the name of the machine running x11vnc and N is XXXX - 5900, i.e. usually
"vncviewer hostname:0".
.PP .PP
By default x11vnc will not allow the screen to be shared and it will By default x11vnc will not allow the screen to be shared and it will exit
exit as soon as a client disconnects. See \fB-shared\fR and \fB-forever\fR below as soon as a client disconnects. See \fB-shared\fR and \fB-forever\fR below to override
to override these protections. these protections. See the FAQ on how to tunnel the VNC connection through
an encrypted channel such as
.IR ssh (1).
.PP .PP
For additional info see: http://www.karlrunge.com/x11vnc/ For additional info see: http://www.karlrunge.com/x11vnc/
and http://www.karlrunge.com/x11vnc/#faq and http://www.karlrunge.com/x11vnc/#faq
...@@ -35,8 +38,8 @@ and http://www.karlrunge.com/x11vnc/#faq ...@@ -35,8 +38,8 @@ and http://www.karlrunge.com/x11vnc/#faq
Rudimentary config file support: if the file $HOME/.x11vncrc exists then each Rudimentary config file support: if the file $HOME/.x11vncrc exists then each
line in it is treated as a single command line option. Disable with \fB-norc.\fR line in it is treated as a single command line option. Disable with \fB-norc.\fR
For each option name, the leading character "-" is not required. E.g. a For each option name, the leading character "-" is not required. E.g. a
line that is either "nap" or "-nap" may be used and are equivalent. line that is either "nap" or "\fB-nap\fR" may be used and are equivalent.
Likewise "wait 100" or "-wait 100" are acceptable and equivalent lines. Likewise "wait 100" or "\fB-wait\fR \fI100\fR" are acceptable and equivalent lines.
The "#" character comments out to the end of the line in the usual way. The "#" character comments out to the end of the line in the usual way.
Leading and trailing whitespace is trimmed off. Lines may be continued with Leading and trailing whitespace is trimmed off. Lines may be continued with
a "\\" as the last character of a line (it becomes a space character). a "\\" as the last character of a line (it becomes a space character).
...@@ -65,17 +68,24 @@ man pages. ...@@ -65,17 +68,24 @@ man pages.
.IP .IP
Show the window corresponding to \fIwindowid\fR not Show the window corresponding to \fIwindowid\fR not
the entire display. New windows like popup menus, the entire display. New windows like popup menus,
etc may not be seen, or will be clipped. x11vnc may transient toplevels, etc, may not be seen or may be
crash if the window changes size, is iconified, etc. clipped. Disabling SaveUnders or BackingStore in the
Use X server may help show them. x11vnc may crash if the
window is initially partially obscured, changes size,
is iconified, etc. Some steps are taken to avoid this
and the \fB-xrandr\fR mechanism is used to track resizes. Use
.IR xwininfo (1) .IR xwininfo (1)
to get the window id. Primarily useful to get the window id, or use "\fB-id\fR \fIpick\fR"
for exporting very simple applications. to have x11vnc run
.IR xwininfo (1)
for you and extract
the id. The \fB-id\fR option is useful for exporting very
simple applications (e.g. the current view on a webcam).
.PP .PP
\fB-sid\fR \fIwindowid\fR \fB-sid\fR \fIwindowid\fR
.IP .IP
As \fB-id,\fR but instead of using the window directly it As \fB-id,\fR but instead of using the window directly it
shifts a root view to it: this shows saveUnders menus, shifts a root view to it: this shows SaveUnders menus,
etc, although they will be clipped if they extend beyond etc, although they will be clipped if they extend beyond
the window. the window.
.PP .PP
...@@ -89,26 +99,45 @@ as the pointer moves from window to window (slow). ...@@ -89,26 +99,45 @@ as the pointer moves from window to window (slow).
For 8bpp displays, force indexed color (i.e. a colormap) For 8bpp displays, force indexed color (i.e. a colormap)
even if it looks like 8bpp TrueColor. (rare problem) even if it looks like 8bpp TrueColor. (rare problem)
.PP .PP
\fB-visual\fR \fIn\fR
.IP
Experimental option: probably does not do what you
think. It simply *forces* the visual used for the
framebuffer; this may be a bad thing... (e.g. messes
up colors or cause a crash). It is useful for testing
and for some workarounds. n may be a decimal number,
or 0x hex. Run
.IR xdpyinfo (1)
for the values. One may
also use "TrueColor", etc. see <X11/X.h> for a list.
If the string ends in ":m" for better or for worse
the visual depth is forced to be m.
.PP
\fB-overlay\fR \fB-overlay\fR
.IP .IP
Handle multiple depth visuals on one screen, e.g. 8+24 Handle multiple depth visuals on one screen, e.g. 8+24
and 24+8 overlay visuals (the 32 bits per pixel are and 24+8 overlay visuals (the 32 bits per pixel are
packed with 8 for PseudoColor and 24 for TrueColor). packed with 8 for PseudoColor and 24 for TrueColor).
.IP .IP
Currently \fB-overlay\fR only works on Solaris (it uses Currently \fB-overlay\fR only works on Solaris via
XReadScreen(3X11)). There is a problem with image .IR XReadScreen (3X11)
"bleeding" around transient popup menus (but not and IRIX using
for the menu itself): a workaround is to disable .IR XReadDisplay (3).
SaveUnders by passing the "-su" argument to Xsun On Solaris there is a problem with image "bleeding"
(in /etc/dt/config/Xservers, say). Also note that, around transient popup menus (but not for the menu
the mouse cursor shape is exactly correct in this mode. itself): a workaround is to disable SaveUnders
by passing the "\fB-su\fR" argument to Xsun (in
/etc/dt/config/Xservers). Also note that the mouse
cursor shape is exactly correct in this mode.
.IP .IP
Use \fB-overlay\fR as a workaround for situations like these: Use \fB-overlay\fR 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
up in x11vnc unless \fB-overlay\fR is used. up in x11vnc unless \fB-overlay\fR is used. Another use of
\fB-overlay\fR is to enable showing the exact mouse cursor
shape (details below).
.IP .IP
Under \fB-overlay,\fR performance will be somewhat degraded Under \fB-overlay,\fR performance will be somewhat degraded
due to the extra image transformations required. due to the extra image transformations required.
...@@ -122,28 +151,16 @@ visual (some apps have \fB-use24\fR or \fB-visual\fR options). ...@@ -122,28 +151,16 @@ visual (some apps have \fB-use24\fR or \fB-visual\fR options).
Sets \fB-overlay,\fR but does not try to draw the exact mouse Sets \fB-overlay,\fR but does not try to draw the exact mouse
cursor shape using the overlay mechanism. cursor shape using the overlay mechanism.
.PP .PP
\fB-visual\fR \fIn\fR
.IP
Experimental option: probably does not do what you
think. It simply *forces* the visual used for the
framebuffer; this may be a bad thing... It is useful for
testing and for some workarounds. n may be a decimal
number, or 0x hex. Run
.IR xdpyinfo (1)
for the values.
One may also use "TrueColor", etc. see <X11/X.h>
for a list. If the string ends in ":m" for better
or for worse the visual depth is forced to be m.
.PP
\fB-scale\fR \fIfraction\fR \fB-scale\fR \fIfraction\fR
.IP .IP
Scale the framebuffer by factor \fIfraction\fR. Scale the framebuffer by factor \fIfraction\fR. Values
Values less than 1 shrink the fb. Note: image may not less than 1 shrink the fb, larger ones expand it.
be sharp and response may be slower. Currently the Note: image may not be sharp and response may be
cursor shape is not scaled. If \fIfraction\fR contains slower. Currently the cursor shape is not scaled.
a decimal point "." it is taken as a floating point If \fIfraction\fR contains a decimal point "." it
number, alternatively the notation "m/n" may be used is taken as a floating point number, alternatively
to denote fractions exactly, e.g. \fB-scale\fR 2/3. the notation "m/n" may be used to denote fractions
exactly, e.g. \fB-scale\fR 2/3.
.IP .IP
Scaling Options: can be added after \fIfraction\fR via Scaling Options: can be added after \fIfraction\fR via
":", to supply multiple ":" options use commas. ":", to supply multiple ":" options use commas.
...@@ -174,6 +191,15 @@ disconnects, opposite of \fB-forever.\fR This is the Default. ...@@ -174,6 +191,15 @@ disconnects, opposite of \fB-forever.\fR This is the Default.
Keep listening for more connections rather than exiting Keep listening for more connections rather than exiting
as soon as the first client(s) disconnect. Same as \fB-many\fR as soon as the first client(s) disconnect. Same as \fB-many\fR
.PP .PP
\fB-inetd\fR
.IP
Launched by
.IR inetd (1):
stdio instead of listening socket.
Note: if you are not redirecting stderr to a log file
(via shell 2> or \fB-o\fR option) you must also specify the
\fB-q\fR option, otherwise the stderr goes to the viewer.
.PP
\fB-connect\fR \fIstring\fR \fB-connect\fR \fIstring\fR
.IP .IP
For use with "vncviewer -listen" reverse connections. For use with "vncviewer -listen" reverse connections.
...@@ -184,41 +210,29 @@ contains "/" it is instead interpreted as a file to ...@@ -184,41 +210,29 @@ contains "/" it is instead interpreted as a file to
periodically check for new hosts. The first line is periodically check for new hosts. The first line is
read and then the file is truncated. read and then the file is truncated.
.PP .PP
\fB-vncconnect\fR \fB-vncconnect,\fR \fB-novncconnect\fR
.IP .IP
Monitor the VNC_CONNECT X property set by the standard Monitor the VNC_CONNECT X property set by the standard
.PP
\fB-novncconnect\fR
.IP
VNC program VNC program
.IR vncconnect (1) .IR vncconnect (1).
. When the property is When the property is
set to "host" or "host:port" establish a reverse set to "host" or "host:port" establish a reverse
connection. Using connection. Using
.IR xprop (1) .IR xprop (1)
instead of vncconnect may instead of vncconnect may
work, see the FAQ. Default: \fB-vncconnect\fR work (see the FAQ). Default: \fB-vncconnect\fR
.PP
\fB-inetd\fR
.IP
Launched by
.IR inetd (1)
: stdio instead of listening socket.
Note: if you are not redirecting stderr to a log file
(via shell 2> or \fB-o\fR option) you must also specify the
\fB-q\fR option.
.PP .PP
\fB-allow\fR \fIaddr1[,addr2..]\fR \fB-allow\fR \fIhost1[,host2..]\fR
.IP .IP
Only allow client connections from IP addresses matching Only allow client connections from hosts matching
the comma separated list of numerical addresses. the comma separated list of hostnames or IP addresses.
Can be a prefix, e.g. "192.168.100." to match a Can also be a numerical IP prefix, e.g. "192.168.100."
simple subnet, for more control build libvncserver to match a simple subnet, for more control build
with libwrap support. If the list contains a "/" libvncserver with libwrap support (See the FAQ). If the
it instead is a interpreted as a file containing list contains a "/" it instead is a interpreted as a
addresses or prefixes that is re-read each time a new file containing addresses or prefixes that is re-read
client connects. Lines can be commented out with the each time a new client connects. Lines can be commented
"#" character in the usual way. out with the "#" character in the usual way.
.PP .PP
\fB-localhost\fR \fB-localhost\fR
.IP .IP
...@@ -236,13 +250,13 @@ the file \fIfilename\fR instead of via command line. ...@@ -236,13 +250,13 @@ the file \fIfilename\fR instead of via command line.
If a second non blank line exists in the file it is If a second non blank line exists in the file it is
taken as a view-only password (i.e. \fB-viewpasswd)\fR Note: taken as a view-only password (i.e. \fB-viewpasswd)\fR Note:
this is a simple plaintext passwd, see also \fB-rfbauth\fR this is a simple plaintext passwd, see also \fB-rfbauth\fR
and \fB-storepasswd\fR below. and \fB-storepasswd\fR below for obfuscated passwords.
.PP .PP
\fB-storepasswd\fR \fIpass\fR \fIfile\fR \fB-storepasswd\fR \fIpass\fR \fIfile\fR
.IP .IP
Store password \fIpass\fR as the VNC password in the Store password \fIpass\fR as the VNC password in the
file \fIfile\fR. Once the password is stored the file \fIfile\fR. Once the password is stored the
program exits. Use the password via "-rfbauth file" program exits. Use the password via "\fB-rfbauth\fR \fIfile\fR"
.PP .PP
\fB-accept\fR \fIstring\fR \fB-accept\fR \fIstring\fR
.IP .IP
...@@ -253,10 +267,10 @@ an external command run via ...@@ -253,10 +267,10 @@ an external command run via
.IR system (3) .IR system (3)
or some special or some special
cases described below. Be sure to quote \fIstring\fR cases described below. Be sure to quote \fIstring\fR
if it contains spaces, etc. If the external command if it contains spaces, shell characters, etc. If the
returns 0 the client is accepted, otherwise the client external command returns 0 the client is accepted,
is rejected. See below for an extension to accept a otherwise the client is rejected. See below for an
client view-only. extension to accept a client view-only.
.IP .IP
Environment: The RFB_CLIENT_IP environment variable will Environment: The RFB_CLIENT_IP environment variable will
be set to the incoming client IP number and the port be set to the incoming client IP number and the port
...@@ -266,7 +280,7 @@ of the connection), are set to allow identification ...@@ -266,7 +280,7 @@ of the connection), are set to allow identification
of the tcp virtual circuit. The x11vnc process of the tcp virtual circuit. The x11vnc process
id will be in RFB_X11VNC_PID, a client id number in id will be in RFB_X11VNC_PID, a client id number in
RFB_CLIENT_ID, and the number of other connected clients RFB_CLIENT_ID, and the number of other connected clients
in RFB_CLIENT_COUNT. in RFB_CLIENT_COUNT. RFB_MODE will be "accept"
.IP .IP
If \fIstring\fR is "popup" then a builtin popup window If \fIstring\fR is "popup" then a builtin popup window
is used. The popup will time out after 120 seconds, is used. The popup will time out after 120 seconds,
...@@ -275,7 +289,8 @@ use "popup:N" to modify the timeout to N seconds ...@@ -275,7 +289,8 @@ use "popup:N" to modify the timeout to N seconds
.IP .IP
If \fIstring\fR is "xmessage" then an If \fIstring\fR is "xmessage" then an
.IR xmessage (1) .IR xmessage (1)
invocation is used for the command. invocation is used for the command. xmessage must be
installed on the machine for this to work.
.IP .IP
Both "popup" and "xmessage" will present an option Both "popup" and "xmessage" will present an option
for accepting the client "View-Only" (the client for accepting the client "View-Only" (the client
...@@ -291,22 +306,26 @@ respectively. Use "*" instead of a number to indicate ...@@ -291,22 +306,26 @@ respectively. Use "*" instead of a number to indicate
the default action (in case the command returns an the default action (in case the command returns an
unexpected value). E.g. "no:*" is a good choice. unexpected value). E.g. "no:*" is a good choice.
.IP .IP
Note that x11vnc blocks while the external command or Note that x11vnc blocks while the external command
or popup is running (other clients may see no updates or popup is running (other clients may see no updates
during this period). during this period).
.IP .IP
More \fB-accept\fR tricks: use "popupmouse" to only allow More \fB-accept\fR tricks: use "popupmouse" to only allow
mouse clicks in the builtin popup to be recognized. mouse clicks in the builtin popup to be recognized.
Similarly use "popupkey" to only recognize keystroke Similarly use "popupkey" to only recognize
responses. All 3 of the popup keywords can be followed keystroke responses. These are to help avoid the
user accidentally accepting a client by typing or
clicking. All 3 of the popup keywords can be followed
by +N+M to supply a position for the popup window. by +N+M to supply a position for the popup window.
The default is to center the popup window. The default is to center the popup window.
.PP .PP
\fB-gone\fR \fIstring\fR \fB-gone\fR \fIstring\fR
.IP .IP
As \fB-accept,\fR except to run a user supplied command when As \fB-accept,\fR except to run a user supplied command when
a client goes away (disconnects). Unlike \fB-accept,\fR a client goes away (disconnects). RFB_MODE will be
the command return code is not interpreted by x11vnc. set to "gone" and the other RFB_* variables are as
in \fB-accept.\fR Unlike \fB-accept,\fR the command return code
is not interpreted by x11vnc. Example: \fB-gone\fR 'xlock &'
.PP .PP
\fB-noshm\fR \fB-noshm\fR
.IP .IP
...@@ -342,10 +361,53 @@ areas to black out (if your system has libXinerama). ...@@ -342,10 +361,53 @@ areas to black out (if your system has libXinerama).
In general on XINERAMA displays you may need to use the In general on XINERAMA displays you may need to use the
\fB-xwarppointer\fR option if the mouse pointer misbehaves. \fB-xwarppointer\fR option if the mouse pointer misbehaves.
.PP .PP
\fB-xrandr\fR \fI[mode]\fR
.IP
If the display supports the XRANDR (X Resize, Rotate
and Reflection) extension, and you expect XRANDR events
to occur to the display while x11vnc is running, this
options indicates x11vnc should try to respond to
them (as opposed to simply crashing by assuming the
old screen size). See the
.IR xrandr (1)
manpage and run
\'xrandr \fB-q'\fR for more info. [mode] is optional and
described below.
.IP
Since watching for XRANDR events and errors increases
polling overhead, only use this option if XRANDR changes
are expected. For example on a rotatable screen PDA or
laptop, or using a XRANDR-aware Desktop where you resize
often. It is best to be viewing with a vncviewer that
supports the NewFBSize encoding, since it knows how to
react to screen size changes. Otherwise, libvncserver
tries to do so something reasonable for viewers that
cannot do this (portions of the screen may be clipped,
unused, etc).
.IP
"mode" defaults to "resize", which means create a
new, resized, framebuffer and hope all viewers can cope
with the change. "newfbsize" means first disconnect
all viewers that do not support the NewFBSize VNC
encoding, and then resize the framebuffer. "exit"
means disconnect all viewer clients, and then terminate
x11vnc.
.PP
\fB-padgeom\fR \fIWxH\fR
.IP
Whenever a new vncviewer connects, the framebuffer is
replaced with a fake, solid black one of geometry WxH.
Shortly afterwards the framebuffer is replaced with the
real one. This is intended for use with vncviewers
that do not support NewFBSize and one wants to make
sure the initial viewer geometry will be big enough
to handle all subsequent resizes (e.g. under \fB-xrandr,\fR
\fB-remote\fR id:windowid, rescaling, etc.
.PP
\fB-o\fR \fIlogfile\fR \fB-o\fR \fIlogfile\fR
.IP .IP
Write stderr messages to file \fIlogfile\fR instead of Write stderr messages to file \fIlogfile\fR instead of
to the terminal. Same as \fB-logfile\fR "file". to the terminal. Same as "\fB-logfile\fR \fIfile\fR".
.PP .PP
\fB-rc\fR \fIfilename\fR \fB-rc\fR \fIfilename\fR
.IP .IP
...@@ -395,19 +457,21 @@ and "," + "<" keys). Default: \fB-modtweak\fR ...@@ -395,19 +457,21 @@ and "," + "<" keys). Default: \fB-modtweak\fR
.PP .PP
\fB-xkb\fR \fB-xkb\fR
.IP .IP
When in modtweak mode, use the XKEYBOARD extension When in modtweak mode, use the XKEYBOARD extension (if
(if it exists) to do the modifier tweaking. This is the X display supports it) to do the modifier tweaking.
powerful and should be tried if there are still This is powerful and should be tried if there are still
keymapping problems when using the simpler \fB-modtweak.\fR keymapping problems when using \fB-modtweak\fR by itself.
.PP .PP
\fB-skip_keycodes\fR \fIstring\fR \fB-skip_keycodes\fR \fIstring\fR
.IP .IP
Skip keycodes not on your keyboard but your X server Ignore the comma separated list of decimal keycodes.
thinks exist. Currently only applies to \fB-xkb\fR mode. Perhaps these are keycodes not on your keyboard but
\fIstring\fR is a comma separated list of decimal your X server thinks exist. Currently only applies
keycodes. Use this option to help x11vnc in the reverse to \fB-xkb\fR mode. Use this option to help x11vnc in the
problem it tries to solve: Keysym -> Keycode(s) when reverse problem it tries to solve: Keysym -> Keycode(s)
ambiguities exist. E.g. \fB-skip_keycodes\fR 94,114 when ambiguities exist (more than one Keycode per
Keysym). Run 'xmodmap \fB-pk'\fR to see your keymapping.
E.g. "\fB-skip_keycodes\fR \fI94,114\fR"
.PP .PP
\fB-add_keysyms\fR \fB-add_keysyms\fR
.IP .IP
...@@ -437,10 +501,10 @@ or hex value) separated by a space. If no file named ...@@ -437,10 +501,10 @@ or hex value) separated by a space. If no file named
\fIstring\fR exists, it is instead interpreted as this \fIstring\fR exists, it is instead interpreted as this
form: key1-key2,key3-key4,... See <X11/keysymdef.h> form: key1-key2,key3-key4,... See <X11/keysymdef.h>
header file for a list of Keysym names, or use header file for a list of Keysym names, or use
.IR xev (1) .IR xev (1).
. To map a key to a button click, use the To map a key to a button click, use the
fake Keysyms "Button1", ..., etc. fake Keysyms "Button1", ..., etc. E.g. "-remap
E.g. \fB-remap\fR Super_R-Button2 Super_R-Button2" (useful for pasting on a laptop)
.PP .PP
\fB-norepeat,\fR \fB-repeat\fR \fB-norepeat,\fR \fB-repeat\fR
.IP .IP
...@@ -451,7 +515,7 @@ delays between key down and key up client events: ...@@ -451,7 +515,7 @@ delays between key down and key up client events:
either from large screen changes or high latency). either from large screen changes or high latency).
Note: your VNC viewer side will likely do autorepeating, Note: your VNC viewer side will likely do autorepeating,
so this is no loss unless someone is simultaneously at so this is no loss unless someone is simultaneously at
the real X display. Default: \fB-repeat\fR the real X display. Default: \fB-norepeat\fR
.PP .PP
\fB-nofb\fR \fB-nofb\fR
.IP .IP
...@@ -489,27 +553,36 @@ and CursorShapeUpdates extensions (cuts down on ...@@ -489,27 +553,36 @@ and CursorShapeUpdates extensions (cuts down on
network traffic by not having to send the cursor image network traffic by not having to send the cursor image
every time the pointer is moved), in which case these every time the pointer is moved), in which case these
extensions are used (see \fB-nocursorshape\fR and \fB-nocursorpos\fR extensions are used (see \fB-nocursorshape\fR and \fB-nocursorpos\fR
below). For other viewers the cursor shape is written below to disable). For other viewers the cursor shape
directly to the framebuffer every time the pointer is is written directly to the framebuffer every time the
moved or changed and gets sent along with the other pointer is moved or changed and gets sent along with
framebuffer updates. In this case, there will be the other framebuffer updates. In this case, there
some lag between the vnc viewer pointer and the remote will be some lag between the vnc viewer pointer and
cursor position. the remote cursor position.
.IP .IP
If the X display supports retrieving the cursor shape If the X display supports retrieving the cursor shape
information from the X server, then the default information from the X server, then the default is
is to use that mode. On Solaris this requires to use that mode. On Solaris this can be done with
the SUN_OVL extension and the \fB-overlay\fR option to be the SUN_OVL extension using \fB-overlay\fR (see also the
supplied. (see also the \fB-overlay_nomouse\fR option). (Soon) \fB-overlay_nomouse\fR option). A similar overlay scheme
on XFree86/Xorg the XFIXES extension is required. is used on IRIX. Xorg (e.g. Linux) and recent Solaris
Either can be disabled with \fB-nocursor,\fR and also some Xsun servers support the XFIXES extension to retrieve
values of the "mode" option below. the exact cursor shape from the X server. If XFIXES
is present it is preferred over Overlay and is used by
default (see \fB-noxfixes\fR below). This can be disabled
with \fB-nocursor,\fR and also some values of the "mode"
option below.
.IP .IP
The "mode" string can be used to fine-tune the The "mode" string can be used to fine-tune the
displaying of cursor shapes. It can be used the displaying of cursor shapes. It can be used the
following ways: following ways:
.IP .IP
"-cursor X" - when the cursor appears to be on the "\fB-cursor\fR \fIarrow\fR" - just show the standard arrow
nothing more or nothing less.
.IP
"\fB-cursor\fR \fInone\fR" - same as "\fB-nocursor\fR"
.IP
"\fB-cursor\fR \fIX\fR" - when the cursor appears to be on the
root window, draw the familiar X shape. Some desktops root window, draw the familiar X shape. Some desktops
such as GNOME cover up the root window completely, such as GNOME cover up the root window completely,
and so this will not work, try "X1", etc, to try to and so this will not work, try "X1", etc, to try to
...@@ -517,17 +590,23 @@ shift the tree depth. On high latency links or slow ...@@ -517,17 +590,23 @@ shift the tree depth. On high latency links or slow
machines there will be a time lag between expected and machines there will be a time lag between expected and
the actual cursor shape. the actual cursor shape.
.IP .IP
"-cursor some" - like "X" but use additional "\fB-cursor\fR \fIsome\fR" - like "X" but use additional
heuristics to try to guess if the window should have heuristics to try to guess if the window should have
a windowmanager-like resizer cursor or a text input a windowmanager-like resizer cursor or a text input
I-beam cursor. This is a complete hack, but may be I-beam cursor. This is a complete hack, but may be
useful in some situations because it provides a little useful in some situations because it provides a little
more feedback about the cursor shape. more feedback about the cursor shape.
.IP .IP
"-cursor most" - try to show as many cursors as "\fB-cursor\fR \fImost\fR" - try to show as many cursors as
possible. Often this will only be the same as "some". possible. Often this will only be the same as "some"
On Solaris if XFIXES is not available, \fB-overlay\fR mode unless the display has overlay visuals or XFIXES
will be used. extensions available. On Solaris and IRIX if XFIXES
is not available, \fB-overlay\fR mode will be attempted.
.PP
\fB-noxfixes\fR
.IP
Do not use the XFIXES extension to draw the exact cursor
shape even if it is available.
.PP .PP
\fB-nocursorshape\fR \fB-nocursorshape\fR
.IP .IP
...@@ -543,11 +622,13 @@ to see the pointer motions. Default: \fB-cursorpos\fR ...@@ -543,11 +622,13 @@ to see the pointer motions. Default: \fB-cursorpos\fR
.PP .PP
\fB-xwarppointer\fR \fB-xwarppointer\fR
.IP .IP
Move the pointer with XWarpPointer(3X) instead of XTEST Move the pointer with
extension. Use this as a workaround if the pointer .IR XWarpPointer (3X)
motion behaves incorrectly, e.g. on touchscreens or instead of
other non-standard setups. Also sometimes needed on the XTEST extension. Use this as a workaround
XINERAMA displays. if the pointer motion behaves incorrectly, e.g.
on touchscreens or other non-standard setups.
Also sometimes needed on XINERAMA displays.
.PP .PP
\fB-buttonmap\fR \fIstring\fR \fB-buttonmap\fR \fIstring\fR
.IP .IP
...@@ -586,22 +667,29 @@ improves response on slow setups, but you lose all ...@@ -586,22 +667,29 @@ improves response on slow setups, but you lose all
visual feedback for drags, text selection, and some visual feedback for drags, text selection, and some
menu traversals. menu traversals.
.PP .PP
\fB-old_pointer\fR \fB-pointer_mode\fR \fIn\fR
.IP .IP
Use the original pointer input handling mechanism. Various pointer update schemes. The problem is pointer
See check_input() and pointer() in source file for motion can cause rapid changes on the screen, e.g. a
details. window drag. Neither x11vnc nor the bandwidth to the
.PP vncviewers can keep up these rapid screen changes:
\fB-old_pointer2\fR everything bogs down when dragging or scrolling.
.IP Note that most video h/w is optimized for writing, not
The default pointer input handling algorithm was changed reading (a 50X rate difference is possible) and x11vnc
again, this option indicates to use the second one. is reading all the time. So a scheme has to be used to
"eat" much of that pointer input before re-polling the
screen. n can be 1 to 4. n=1 was the original scheme
used to about Jan 2004. n=2 is an improved scheme.
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. The default n is 2.
.PP .PP
\fB-input_skip\fR \fIn\fR \fB-input_skip\fR \fIn\fR
.IP .IP
For the old pointer handling when non-threaded: try to 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.
Default: 10
.PP .PP
\fB-debug_pointer\fR \fB-debug_pointer\fR
.IP .IP
...@@ -629,6 +717,12 @@ down on load. Default: 30 ...@@ -629,6 +717,12 @@ down on load. Default: 30
Monitor activity and if low take longer naps between Monitor activity and if low take longer naps between
polls to really cut down load when idle. Default: off polls to really cut down load when idle. Default: off
.PP .PP
\fB-sb\fR \fItime\fR
.IP
Time in seconds after NO activity (e.g. screen blank)
to really throttle down the screen polls (i.e. sleep
for about 1.5 secs). Use 0 to disable. Default: 60
.PP
\fB-sigpipe\fR \fIstring\fR \fB-sigpipe\fR \fIstring\fR
.IP .IP
Broken pipe (SIGPIPE) handling. \fIstring\fR can be Broken pipe (SIGPIPE) handling. \fIstring\fR can be
...@@ -663,6 +757,444 @@ by checking the tile near the boundary. Default: 3 ...@@ -663,6 +757,444 @@ by checking the tile near the boundary. Default: 3
Tolerance in pixels to mark a tiles edges as changed. Tolerance in pixels to mark a tiles edges as changed.
Default: 2 Default: 2
.PP .PP
\fB-gui\fR \fI[gui-opts]\fR
.IP
Start up a simple tcl/tk gui based on the the remote
control options \fB-remote/-query\fR described below.
Requires the "wish" program to be installed on the
machine. "gui-opts" is not required: the default is
to start up both the gui and x11vnc with the gui showing
up on the X display in the environment variable DISPLAY.
.IP
"gui-opts" can be a comma separated list of items.
Currently there are only two types of items: 1) a gui
mode and 2) the X display the gui should display on.
The gui mode can be "start", "conn", or "wait"
"start" is the default mode above and is not required.
"conn" means do not automatically start up x11vnc,
but instead just try to connect to an existing x11vnc
process. "wait" means just start the gui and nothing
else (you will later instruct the gui to start x11vnc
or connect to an existing one.)
.IP
Note the possible confusion regarding the potentially
two different X displays: x11vnc polls one, but you
may want the gui to appear on another. For example, if
you ssh in and x11vnc is not running yet you may want
the gui to come back to you via your ssh redirected X
display (e.g. localhost:10).
.IP
Examples: "x11vnc \fB-gui",\fR "x11vnc \fB-gui\fR localhost:10",
"x11vnc \fB-gui\fR :10", "x11vnc \fB-gui\fR wait,:10",
"x11vnc \fB-gui\fR <x11vnc-opts...>"
.IP
If you do not specify a gui X display in "gui-opts"
then the DISPLAY environment variable and \fB-display\fR
option are tried (in that order). Regarding the x11vnc
X display the gui will try to connect to, it first
tries \fB-display\fR and then DISPLAY. For example, "x11vnc
\fB-display\fR :0 \fB-gui\fR otherhost:0", will remote control an
x11vnc polling :0 and display the gui on otherhost:0
.IP
If you do not intend to start x11vnc from the gui
(i.e. just remote control an existing one), then the
gui process can run on a different machine from the
x11vnc server as long as X permissions, etc. permit
communication between the two.
.PP
\fB-remote\fR \fIcommand\fR
.IP
Remotely control some aspects of an already running
x11vnc server. "\fB-R\fR" and "\fB-r\fR" are aliases for
"\fB-remote\fR". After the remote control command is
sent to the running server the 'x11vnc \fB-remote\fR ...'
command exits. You can often use the \fB-query\fR command
(see below) to see if the x11vnc server processed your
\fB-remote\fR command.
.IP
The default communication channel is that of X
properties (specifically VNC_CONNECT), and so this
command must be run with correct settings for DISPLAY
and possibly XAUTHORITY to connect to the X server
and set the property. Alternatively, use the \fB-display\fR
and \fB-auth\fR options to set them to the correct values.
The running server cannot use the \fB-novncconnect\fR option
because that disables the communication channel.
See below for alternate channels.
.IP
For example: 'x11vnc \fB-remote\fR stop' (which is the same as
\'x11vnc \fB-R\fR stop') will close down the x11vnc server.
\'x11vnc \fB-R\fR shared' will enable shared connections, and
\'x11vnc \fB-R\fR scale:3/4' will rescale the desktop.
.IP
Note: the more drastic the change induced by the \fB-remote\fR
command, the bigger the chance for bugs or crashes.
Please report reproducible bugs.
.IP
.IP
The following \fB-remote/-R\fR commands are supported:
.IP
stop terminate the server, same as "quit"
"exit" or "shutdown"
.IP
ping see if the x11vnc server responds.
Return is: ans=ping:<xdisplay>
.IP
blacken try to push a black fb update to all
clients (due to timings a client
could miss it). Same as "zero", also
"zero:x1,y1,x2,y2" for a rectangle.
.IP
refresh send the entire fb to all clients.
.IP
reset recreate the fb, polling memory, etc.
.IP
id:windowid set \fB-id\fR window to "windowid". empty
or "root" to go back to root window
.IP
sid:windowid set \fB-sid\fR window to "windowid"
.IP
flashcmap enable \fB-flashcmap\fR mode.
.IP
noflashcmap disable \fB-flashcmap\fR mode.
.IP
notruecolor enable \fB-notruecolor\fR mode.
.IP
truecolor disable \fB-notruecolor\fR mode.
.IP
overlay enable \fB-overlay\fR mode (if applicable).
.IP
nooverlay disable \fB-overlay\fR mode.
.IP
overlay_cursor in \fB-overlay\fR mode, enable cursor drawing.
.IP
overlay_nocursor disable cursor drawing. same as
nooverlay_cursor.
.IP
visual:vis set \fB-visual\fR to "vis"
.IP
scale:frac set \fB-scale\fR to "frac"
.IP
viewonly enable \fB-viewonly\fR mode.
.IP
noviewonly disable \fB-viewonly\fR mode.
.IP
shared enable \fB-shared\fR mode.
.IP
noshared disable \fB-shared\fR mode.
.IP
forever enable \fB-forever\fR mode.
.IP
noforever disable \fB-forever\fR mode.
.IP
deny deny any new connections, same as "lock"
.IP
nodeny allow new connections, same as "unlock"
.IP
connect:host do reverse connection to host, "host"
may be a comma separated list of hosts
or host:ports. See \fB-connect.\fR
.IP
disconnect:host disconnect any clients from "host"
same as "close:host". Use host
"all" to close all current clients.
If you know the client internal hex ID,
e.g. 0x3 (returned by \fB-query\fR clients and
RFB_CLIENT_ID), you can use that too.
.IP
allowonce:host For the next connection only, allow
connection from "host".
.IP
allow:hostlist set \fB-allow\fR list to (comma separated)
"hostlist". See \fB-allow\fR and \fB-localhost.\fR
Do not use with \fB-allow\fR /path/to/file
Use "+host" to add a single host, and
use "\fB-host\fR" to delete a single host
.IP
localhost enable \fB-localhost\fR mode
.IP
nolocalhost disable \fB-localhost\fR mode
.IP
accept:cmd set \fB-accept\fR "cmd" (empty to disable).
.IP
gone:cmd set \fB-gone\fR "cmd" (empty to disable).
.IP
noshm enable \fB-noshm\fR mode.
.IP
shm disable \fB-noshm\fR mode (i.e. use shm).
.IP
flipbyteorder enable \fB-flipbyteorder\fR mode, you may need
to set noshm for this to do something.
.IP
noflipbyteorder disable \fB-flipbyteorder\fR mode.
.IP
onetile enable \fB-onetile\fR mode. (you may need to
set shm for this to do something)
.IP
noonetile disable \fB-onetile\fR mode.
.IP
blackout:str set \fB-blackout\fR "str" (empty to disable).
See \fB-blackout\fR for the form of "str"
(basically: WxH+X+Y,...)
Use "+WxH+X+Y" to append a single
rectangle use "-WxH+X+Y" to delete one
.IP
xinerama enable \fB-xinerama\fR mode. (if applicable)
.IP
noxinerama disable \fB-xinerama\fR mode.
.IP
xrandr enable \fB-xrandr\fR mode. (if applicable)
.IP
noxrandr disable \fB-xrandr\fR mode.
.IP
xrandr_mode:mode set the \fB-xrandr\fR mode to "mode".
.IP
padgeom:WxH set \fB-padgeom\fR to WxH (empty to disable)
If WxH is "force" or "do" the padded
geometry fb is immediately applied.
.IP
quiet enable \fB-quiet\fR mode.
.IP
noquiet disable \fB-quiet\fR mode.
.IP
modtweak enable \fB-modtweak\fR mode.
.IP
nomodtweak enable \fB-nomodtweak\fR mode.
.IP
xkb enable \fB-xkb\fR modtweak mode.
.IP
noxkb disable \fB-xkb\fR modtweak mode.
.IP
skip_keycodes:str enable \fB-xkb\fR \fB-skip_keycodes\fR "str".
.IP
add_keysyms enable \fB-add_keysyms\fR mode.
.IP
noadd_keysyms stop adding keysyms. those added will
still be removed at exit.
.IP
clear_mods enable \fB-clear_mods\fR mode and clear them.
.IP
noclear_mods disable \fB-clear_mods\fR mode.
.IP
clear_keys enable \fB-clear_keys\fR mode and clear them.
.IP
noclear_keys disable \fB-clear_keys\fR mode.
.IP
remap:str set \fB-remap\fR "str" (empty to disable).
See \fB-remap\fR for the form of "str"
(basically: key1-key2,key3-key4,...)
Use "+key1-key2" to append a single
keymapping, use "-key1-key2" to delete.
.IP
norepeat enable \fB-norepeat\fR mode.
.IP
repeat disable \fB-norepeat\fR mode.
.IP
bell enable bell (if supported).
.IP
nobell disable bell.
.IP
sel disable \fB-nosel\fR mode.
.IP
nosel enable \fB-nosel\fR mode.
.IP
primary disable \fB-noprimary\fR mode.
.IP
noprimary enable \fB-noprimary\fR mode.
.IP
cursor:mode enable \fB-cursor\fR "mode".
.IP
show_cursor enable showing a cursor.
.IP
noshow_cursor disable showing a cursor. (same as
"nocursor")
.IP
xfixes enable xfixes cursor shape mode.
.IP
noxfixes disable xfixes cursor shape mode.
.IP
cursorshape disable \fB-nocursorshape\fR mode.
.IP
nocursorshape enable \fB-nocursorshape\fR mode.
.IP
cursorpos disable \fB-nocursorpos\fR mode.
.IP
nocursorpos enable \fB-nocursorpos\fR mode.
.IP
xwarp enable \fB-xwarppointer\fR mode.
.IP
noxwarp disable \fB-xwarppointer\fR mode.
.IP
buttonmap:str set \fB-buttonmap\fR "str", empty to disable
.IP
dragging disable \fB-nodragging\fR mode.
.IP
nodragging enable \fB-nodragging\fR mode.
.IP
pointer_mode n set \fB-pointer_mode\fR to n.
.IP
input_skip n set \fB-input_skip\fR to n.
.IP
debug_pointer enable \fB-debug_pointer,\fR same as "dp"
.IP
nodebug_pointer disable \fB-debug_pointer,\fR same as "nodp"
.IP
debug_keyboard enable \fB-debug_keyboard,\fR same as "dk"
.IP
nodebug_keyboard disable \fB-debug_keyboard,\fR same as "nodk"
.IP
defer:n set \fB-defer\fR to n ms,same as deferupdate:n
.IP
wait:n set \fB-wait\fR to n ms.
.IP
nap enable \fB-nap\fR mode.
.IP
nonap disable \fB-nap\fR mode.
.IP
sb:n set \fB-sb\fR to n s, same as screen_blank:n
.IP
fs:frac set \fB-fs\fR fraction to "frac", e.g. 0.5
.IP
gaps:n set \fB-gaps\fR to n.
.IP
grow:n set \fB-grow\fR to n.
.IP
fuzz:n set \fB-fuzz\fR to n.
.IP
progressive:n set libvncserver \fB-progressive\fR slice
height parameter to n.
.IP
file:name run \fB-remote\fR commands from file "name",
one command per line,blank and # skipped
.IP
noremote disable the \fB-remote\fR command processing,
it cannot be turned back on.
.IP
.IP
The
.IR vncconnect (1)
command from standard VNC
.IP
distributions may also be used if string is prefixed
.IP
with "cmd=" E.g. 'vncconnect cmd=stop'. Under some
.IP
circumstances
.IR xprop (1)
can used if it supports \fB-set\fR
.IP
(see the FAQ).
.IP
.IP
If "\fB-connect\fR \fI/path/to/file\fR" has been supplied to the
.IP
running x11vnc server then that file can be used as a
.IP
communication channel (this is the only way to remote
.IP
control one of many x11vnc's polling the same X display)
.IP
Simply run: 'x11vnc \fB-connect\fR /path/to/file \fB-remote\fR ...'
.IP
or you can directly write to the file via something
.IP
like: "echo cmd=stop > /path/to/file", etc.
.PP
\fB-query\fR \fIvariable\fR
.IP
Like \fB-remote,\fR except just query the value of
\fIvariable\fR. "\fB-Q\fR" is an alias for "\fB-query\fR".
Multiple queries can be done by separating variables
by commas, e.g. \fB-query\fR var1,var2. The results come
back in the form ans=var1:value1,ans=var2:value2,...
to the standard output. If a variable is read-only,
it comes back with prefix "aro=" instead of "ans=".
.IP
Some \fB-remote\fR commands are pure actions that do not make
sense as variables, e.g. "stop" or "disconnect",
in these cases the value returned is "N/A". To direct
a query straight to the VNC_CONNECT property or connect
file use "qry=..." instead of "cmd=..."
.IP
Here is the current list of "variables" that can
be supplied to the \fB-query\fR command. This includes the
"N/A" ones that return no useful info. For variables
names that do not correspond to an x11vnc option or
remote command, we hope the name makes it obvious what
the returned value corresponds to (hint: the ext_*
variables correspond to the presence of X extensions):
.IP
ans= stop quit exit shutdown ping blacken zero refresh
reset close disconnect id sid flashcmap noflashcmap
truecolor notruecolor overlay nooverlay overlay_cursor
overlay_yescursor nooverlay_cursor overlay_nocursor
visual scale viewonly noviewonly shared noshared
forever noforever once deny lock nodeny unlock connect
allowonce allow localhost nolocalhost accept gone shm
noshm flipbyteorder noflipbyteorder onetile noonetile
blackout xinerama noxinerama xrandr noxrandr xrandr_mode
padgeom quiet q noquiet modtweak nomodtweak xkb noxkb
skip_keycodes add_keysyms noadd_keysyms clear_mods
noclear_mods clear_keys noclear_keys remap repeat
norepeat bell nobell sel nosel primary noprimary
cursorshape nocursorshape cursorpos nocursorpos cursor
show_cursor noshow_cursor nocursor xfixes noxfixes xwarp
xwarppointer noxwarp noxwarppointer buttonmap dragging
nodragging pointer_mode input_skip debug_pointer dp
nodebug_pointer nodp debug_keyboard dk nodebug_keyboard
nodk deferupdate defer wait nap nonap sb screen_blank
fs gaps grow fuzz progressive noremote
.IP
aro= display vncdisplay desktopname desktop auth
rootshift scale_str scaled_x scaled_y scale_numer
scale_denom scale_fac scaling_noblend scaling_nomult4
scaling_pad scaling_interpolate inetd safer unsafe
passwdfile using_shm logfile o rc norc h help V version
lastmod bg nofb sigpipe threads clients client_count
pid ext_xtest ext_xkb ext_xshm ext_xinerama ext_overlay
ext_xfixes ext_xdamage ext_xrandr rootwin num_buttons
button_mask mouse_x mouse_y bpp depth indexed_color
dpy_x dpy_y rfbport rfbwait rfbauth passwd alwaysshared
dontdisconnect httpdir enablehttpproxy
.PP
\fB-noremote\fR
.IP
Do not process any remote control commands or queries.
.IP
A note about security wrt remote control commands.
If someone can connect to the X display and change the
property VNC_CONNECT, then they can remotely control
x11vnc. Normally access to the X display is protected.
Note that if they can modify VNC_CONNECT, they could
also run their own x11vnc and have complete control
of the desktop. If the "\fB-connect\fR \fI/path/to/file\fR"
channel is being used, obviously anyone who can write
to /path/to/file can remotely control x11vnc. So be
sure to protect the X display and that file's write
permissions.
.PP
\fB-unsafe\fR
.IP
If x11vnc is running as root (e.g. inetd or Xsetup for
a display manager) a few remote commands are disabled
(currently: id:pick, accept:<cmd>, and gone:<cmd>)
because they are associated with running external
programs. If you specify \fB-unsafe,\fR then these remote
control commands are allowed when running as root.
When running as non-root all commands are allowed.
See \fB-safer\fR below.
.PP
\fB-safer\fR
.IP
Even if not running as root, disable the above unsafe
remote control commands.
.PP
\fB-deny_all\fR
.IP
For use with \fB-remote\fR nodeny: start out denying all
incoming clients until "\fB-remote\fR \fInodeny\fR" is used to
let them in.
.PP
These options are passed to libvncserver: These options are passed to libvncserver:
.PP .PP
\fB-rfbport\fR \fIport\fR \fB-rfbport\fR \fIport\fR
...@@ -736,7 +1268,8 @@ run by \fB-accept\fR and \fB-gone\fR: ...@@ -736,7 +1268,8 @@ run by \fB-accept\fR and \fB-gone\fR:
.IR RFB_SERVER_PORT , .IR RFB_SERVER_PORT ,
.IR RFB_X11VNC_PID , .IR RFB_X11VNC_PID ,
.IR RFB_CLIENT_ID , .IR RFB_CLIENT_ID ,
.IR RFB_CLIENT_COUNT .IR RFB_CLIENT_COUNT ,
.IR RFB_MODE
.SH "SEE ALSO" .SH "SEE ALSO"
.IR vncviewer (1), .IR vncviewer (1),
.IR vncpasswd (1), .IR vncpasswd (1),
...@@ -754,7 +1287,8 @@ run by \fB-accept\fR and \fB-gone\fR: ...@@ -754,7 +1287,8 @@ run by \fB-accept\fR and \fB-gone\fR:
.IR ipcrm (1), .IR ipcrm (1),
.IR http://www.tightvnc.com , .IR http://www.tightvnc.com ,
.IR http://www.realvnc.com , .IR http://www.realvnc.com ,
.IR http://www.karlrunge.com/x11vnc/ .IR http://www.karlrunge.com/x11vnc/ ,
.IR http://www.karlrunge.com/x11vnc/#faq
.SH AUTHORS .SH AUTHORS
x11vnc was written by Karl J. Runge <runge@karlrunge.com>, x11vnc was written by Karl J. Runge <runge@karlrunge.com>,
it is part of the LibVNCServer project <http://sf.net/projects/libvncserver>. it is part of the LibVNCServer project <http://sf.net/projects/libvncserver>.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
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