diff options
author | runge <runge> | 2005-07-02 02:45:13 +0000 |
---|---|---|
committer | runge <runge> | 2005-07-02 02:45:13 +0000 |
commit | c59929365c6b73d89fd0ccbdcb223c0ec44a4d40 (patch) | |
tree | b1eb874bfde00f93ec5b316f7c48fa2735aebdb9 /x11vnc | |
parent | 462ffd3f3eddd9b428e76b0fd32d3f988660bac0 (diff) | |
download | libtdevnc-c59929365c6b73d89fd0ccbdcb223c0ec44a4d40.tar.gz libtdevnc-c59929365c6b73d89fd0ccbdcb223c0ec44a4d40.zip |
x11vnc: -gui tray mode, httpd.c: check httpListenSock >= 0.
Diffstat (limited to 'x11vnc')
-rw-r--r-- | x11vnc/ChangeLog | 6 | ||||
-rw-r--r-- | x11vnc/README | 52 | ||||
-rwxr-xr-x | x11vnc/tkx11vnc | 718 | ||||
-rw-r--r-- | x11vnc/tkx11vnc.h | 718 | ||||
-rw-r--r-- | x11vnc/x11vnc.1 | 29 | ||||
-rw-r--r-- | x11vnc/x11vnc.c | 369 |
6 files changed, 1719 insertions, 173 deletions
diff --git a/x11vnc/ChangeLog b/x11vnc/ChangeLog index 8751253..42bb335 100644 --- a/x11vnc/ChangeLog +++ b/x11vnc/ChangeLog @@ -1,3 +1,9 @@ +2005-07-01 Karl Runge <runge@karlrunge.com> + * support for simple "-gui tray" mode (small icon like the original + x0rfbserver had). Can't figure how to get a tray to swallow it.. + * passwd, viewpasswd changing in tray mode. + * allow typos like: x11vnc -R -scale 3/4 + 2005-06-26 Karl Runge <runge@karlrunge.com> * track keycode state for heuristics, -sloppy_keys, -wmdt * add -nodbg as option diff --git a/x11vnc/README b/x11vnc/README index c97dec2..8490252 100644 --- a/x11vnc/README +++ b/x11vnc/README @@ -1,5 +1,5 @@ -x11vnc README file Date: Sun Jun 26 22:02:44 EDT 2005 +x11vnc README file Date: Fri Jul 1 21:48:07 EDT 2005 The following information is taken from these URLs: @@ -347,10 +347,12 @@ exec /usr/bin/ssh -t -L 5900:localhost:5900 $gateway \ The x11vnc package is the subset of the libvncserver package needed to build the x11vnc program. Also, you can get a copy of my latest, - bleeding edge [38]x11vnc-0.7.2.tar.gz tarball. + bleeding edge [38]x11vnc-0.7.2.tar.gz tarball to build the most up to + date one. - See the [39]FAQ below for information about where you might obtain a - precompiled x11vnc binary from 3rd parties. + Precompiled Binaries/Packages: See the [39]FAQ below for information + about where you might obtain a precompiled x11vnc binary from 3rd + parties and some ones I create. To obtain VNC viewers for the viewing side (Windows, Mac OS, or Unix) try these links: @@ -575,10 +577,10 @@ make I don't have any formal beta-testers for the releases of x11vnc, so I'd appreciate any additional testing very much! - I'd like to release version 0.7.2 in Jun/2005 sometime, here is the - current tarball: + I'd like to release version 0.7.2 in Jun/Jul/2005 sometime, here is + the current tarball: - RC-3 lastmod: 2005-06-22 [51]x11vnc-0.7.2beta.tar.gz + RC-4 lastmod: 2005-06-25 [51]x11vnc-0.7.2beta.tar.gz There are also some Linux, Solaris, and other OS test binaries [52]here. Please kick the tires and report bugs, performance @@ -1353,9 +1355,8 @@ typedef unsigned int in_addr_t; http://www.sunfreeware.com/ packages are built with libz and libjpeg. If the above binaries don't work and building x11vnc on your OS fails - (and all else fails!) you can try one of my motley collection of - [172]test binaries. Some may be old, some may have extra debugging - output, etc. One of them may work on your OS... + (and all else fails!) you can try one of [172]my collection of + binaries for various OS's and x11vnc releases. As a general note, the x11vnc program is simple enough you don't really need to install a package: the binary will in most cases work @@ -2658,7 +2659,7 @@ xmodmap -e "add Control = Control_L Control_R" The framebuffer is kept in main memory like Xvfb except that the server code is closely correlated with the real XFree86/Xorg Xserver unlike Xvfb. The main drawback to this method (besides requiring extra - configuration and possibly root permission) is that is also does the + configuration and possibly root permission) is that it also does the Linux Virtual Console/Terminal (VC/VT) [278]switching even though it does not need to (since it doesn't use a real framebuffer). There are some "dual headed" (actually multi-headed/multi-user) patches to the X @@ -4541,7 +4542,7 @@ x11vnc: a VNC server for real X displays Here are all of x11vnc command line options: % x11vnc -opts (see below for -help long descriptions) -x11vnc: allow VNC connections to real X11 displays. 0.7.2 lastmod: 2005-06-25 +x11vnc: allow VNC connections to real X11 displays. 0.7.2 lastmod: 2005-07-01 x11vnc options: -display disp -auth file @@ -4641,7 +4642,7 @@ libvncserver options: % x11vnc -help -x11vnc: allow VNC connections to real X11 displays. 0.7.2 lastmod: 2005-06-25 +x11vnc: allow VNC connections to real X11 displays. 0.7.2 lastmod: 2005-07-01 Typical usage is: @@ -5971,8 +5972,8 @@ Options: "gui-opts" can be a comma separated list of items. Currently there are these types of items: 1) a gui mode, - a 2) gui "simplicity", and 3) the X display the gui - should display on. + a 2) gui "simplicity", 3) the X display the gui + should display on, and 4) a "tray" (or icon) mode. 1) The gui mode can be "start", "conn", or "wait" "start" is the default mode above and is not required. @@ -5996,9 +5997,6 @@ Options: the gui to come back to you via your ssh redirected X display (e.g. localhost:10). - Examples: "x11vnc -gui", "x11vnc -gui ez" - "x11vnc -gui localhost:10", "x11vnc -gui conn,host:0" - If you do not specify a gui X display in "gui-opts" then the DISPLAY environment variable and -display option are tried (in that order). Regarding the x11vnc @@ -6006,6 +6004,24 @@ Options: tries -display and then DISPLAY. For example, "x11vnc -display :0 -gui otherhost:0", will remote control an x11vnc polling :0 and display the gui on otherhost:0 + The "tray" mode below reverses this preference. + + 4) When "tray" is specified, the gui presents itself + as a small icon with behavior similar to a "system + tray" or "dock" applet. The color of the icon + indicates status (connected clients) and there is also a + balloon status. Clicking on the icon gives a menu from + which properties, etc, can be set and the full gui is + available under "Advanced". To be fully functional, + the gui mode should be "start" (the default). At some + point it is hoped the icon can be automatically embedded + in common destkop trays/docks. Currently one can only + embed it in a window via, e.g., "tray=0x3600028". + Otherwise the icon is just a normal standalone window. + + Examples: "x11vnc -gui", "x11vnc -gui ez" + "x11vnc -gui localhost:10", "x11vnc -gui conn,host:0" + "x11vnc -gui tray,ez" If you do not intend to start x11vnc from the gui (i.e. just remote control an existing one), then the diff --git a/x11vnc/tkx11vnc b/x11vnc/tkx11vnc index 724b6a1..38ea77d 100755 --- a/x11vnc/tkx11vnc +++ b/x11vnc/tkx11vnc @@ -392,7 +392,7 @@ by selecting any of the Keystrokes, Mouse Motion, or Button Clicks checkboxes and pressing \"OK\". This is like the \"-input\" option but on a per-client basis. -To not change any aspects of the VNC client press \"Skip\". +To not change any aspects of the VNC client press \"Cancel\". " set helptext(solid_color) " @@ -413,6 +413,95 @@ and all possible settings. I.e. toggle between a simple gui and one for power users. " + set helptext(Tray) " +The tray/icon mode (started with \"x11vnc -gui tray ...\") presents a +small icon that indicates the status of a running x11vnc server. + +Depending on your environment, this icon may be embedded in a system +tray or applet dock, or simply be a standalone window. + +When the icon has a light background, that means no VNC viewers are +currently connected to the display. + +When the icon has a dark background (i.e. reverse-video), that means at +least one VNC viewer is connected to the display. + +Moving the mouse pointer over the icon will popup a \"status balloon\" +indicating the VNC display name and the names and other info of any +connected VNC viewers. + +Clicking the right mouse button on the icon displays a menu of actions: + + Properties - Brings up the Properties dialog. The full tkx11vnc + GUI may be accessed via the \"Advanced ...\" button. + + Help - Displays this help text. + + New Client - Presents an entry box where you type in the name + of a computer that is running a VNC viewer in + \"listen\" mode (e.g. vncviewer -listen). For a + non-standard listening port use \"host:port\". + Pressing \"OK\" will initiate the reverse + connection. Use a blank hostname to skip it. + + Disconnect All - Disconnects all current VNC viewers. + + Stop x11vnc - Directs the x11vnc server to disconnect all vncviewers + and then exit. The tray/icon GUI then exits as well. + + +If the x11vnc server stops for any reason, the tray/icon gui will exit. + +If you delete the tray/icon (e.g. X out button), that is the same +as the \"Stop x11vnc\" action in the menu. +" + + set helptext(Properties) " +The Properties dialog allows you to set some basic parameters of a +running x11vnc server. After modifying them press \"OK\" or \"Apply\" +to apply the changes, or press \"Cancel\" to skip applying them. + +\"Accept Connections\" toggles whether VNC viewers are allowed +to connect or not. It corresponds to the \"-R unlock\" and \"-R lock\" +remote-control commands. + +\"Ask for Confirmation\" toggles whether a popup menu will be presented +at the X display when a new VNC viewer attempts to connects. The person +sitting at the X display can chose to accept or reject the connection +or accept the connection in View-Only mode. It corresponds to the +\"-R accept:popup\" and \"-R accept:\" remote-control commands. + +\"All Clients ViewOnly\" toggles whether the entire VNC desktop is +view only. All clients will only be able to watch when this is set +(regardless of how they logged in). It corresponds to the \"-R viewonly\" +and \"-R noviewonly\" remote-control commands. + +\"Shared\" toggles whether multiple simultaneous connections are +allowed or not. It corresponds to the \"-R shared\" and \"-R noshared\" +remote-control commands. + +\"Password\" lets you set the session password viewers may use to gain full +access to the display. + +\"ViewOnly Password\" lets you set the session password viewers may +use to gain view only access to the display. + +NOTE: These passwords only last for the current x11vnc session (they are +not remembered, see the -storepasswd, -passwdfile, and -rfbauth x11vnc +options for using stored passwords). + +If you set \"Password\" to the empty string that makes the \"View-Only +Password\" empty as well and removes the need for any password to log in. + +If you set \"ViewOnly Password\" to the empty string that just removes +the ViewOnly log in aspect: \"Password\" is still required to log in. + +The \"Help ...\" button shows this help text. + +The \"Advanced ...\" button replaces the Properties dialog with the full +tkx11vnc GUI. Any dynamic settings can be modified in the full GUI. +" + set helptext(all) $helpall set helptext(Misc-Tuning:) " @@ -488,7 +577,7 @@ To scroll click in the area and use PageUp/PageDown or the arrow keys. 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 +\"Cancel\" 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. @@ -561,7 +650,7 @@ To scroll click in the area and use PageUp/PageDown or the arrow keys. 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 +\"Cancel\" 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. @@ -607,8 +696,14 @@ proc textheight {text} { } proc set_name {name} { - wm title . "$name" - wm iconname . "$name" + global full_win + if [info exists full_win] { + set w $full_win + } else { + set w "." + } + wm title $w "$name" + wm iconname $w "$name" } proc make_toplevel {w {title ""}} { @@ -726,7 +821,8 @@ proc help_win {item} { set text "Help on $item:\n\n" if {[is_gui_internal $item]} { - if {$item != "gui" && $item != "all" && $item != "Misc-Tuning:"} { + if {$item != "gui" && $item != "all" && $item != "Misc-Tuning:" \ + && $item != "Properties" && $item != "Tray"} { append text " + Is a gui internal Action (cannot be set).\n"; } } elseif {[is_action $item]} { @@ -1167,7 +1263,11 @@ proc push_new_value {item name new {query 1}} { set query_output "" if {!$debug} { - append_text "x11vnc $rargs ..." + if [regexp {passwd} $rargs] { + append_text "x11vnc ..." + } else { + append_text "x11vnc $rargs ..." + } } if {$getout} { @@ -1258,7 +1358,7 @@ proc insert_input_window {} { append_text "\nUse these checkboxes to set the input permissions, " append_text "or type in the \"KMB...\"\n" - append_text "-input string manually. Then press \"OK\" or \"Skip\".\n" + append_text "-input string manually. Then press \"OK\" or \"Cancel\".\n" append_text "(note: an empty setting means use the default behavior, " append_text "see viewonly)\n\n" set w "$text_area.wk_f" @@ -1369,7 +1469,7 @@ proc insert_client_action_window {input} { append_text "\nUse these checkboxes to set the input permissions " append_text "for this client\n-or- whether to disconnect it instead. " - append_text "Then press \"OK\" or \"Skip\".\n\n" + append_text "Then press \"OK\" or \"Cancel\".\n\n" set w "$text_area.ca_f" catch {destroy $w} frame $w -bd 1 -relief ridge -cursor {top_left_arrow} @@ -1414,7 +1514,7 @@ proc cleanup_text_window {} { } } -# For updating a string variable. Also used for simple OK/Skip dialogs +# For updating a string variable. Also used for simple OK/Cancel dialogs # with entry = 0. proc entry_dialog {item {entry 1}} { global menu_var entry_str entry_set entry_dialog_item @@ -1581,6 +1681,9 @@ proc see_if_ok {query item expected} { || $item == "client" || $item == "client_input"} { append_text "\t($msg)\n" return 1 + } elseif {$item == "passwd" || $item == "viewpasswd"} { + append_text "\t($msg)\n" + return 1 } else { append_text "\t*FAILED* $msg\n" return 0 @@ -1804,6 +1907,14 @@ proc detach_from_display {} { set_connected no } +proc do_stop_quit {} { + push_new_value "stop" "stop" 1 0 + set_connected no + update + after 250 + destroy . +} + # Menu item is an action: proc do_action {item} { global menu_var connected_to_x11vnc beginner_mode @@ -1850,11 +1961,7 @@ proc do_action {item} { menu_help "$item" return } elseif {$item == "stop+quit"} { - push_new_value "stop" "stop" 1 0 - set_connected no - update - after 500 - destroy . + do_stop_quit } if {[value_is_string $item]} { @@ -1961,6 +2068,12 @@ proc is_action {item} { } proc is_gui_internal {item} { + if {$item == "Properties"} { + return 1 + } + if {$item == "Tray"} { + return 1 + } return [opt_match G $item] } @@ -2194,7 +2307,7 @@ proc disconnect_dialog {client} { append_text "Invalid client info string: $client\n" return } - append msg "*** To *DISCONNECT* this client press \"OK\", otherwise press \"Skip\"\n" + append msg "*** To *DISCONNECT* this client press \"OK\", otherwise press \"Cancel\"\n" bell if {[warning_dialog $msg "current"]} { push_new_value "disconnect" "disconnect" $cid 1 @@ -2255,7 +2368,7 @@ proc update_clients_menu {list} { regsub {:.*$} $client "" clabel } $subm add command -label "$clabel" \ - -command "client_dialog $client" + -command "client_dialog \{$client\}" incr count } $subm entryconfigure 0 -label "num-clients: $count" @@ -2537,6 +2650,497 @@ proc menu_posted {} { } } +proc props_apply {} { + global props_accept props_confirm props_viewonly props_shared + global props_passwd props_viewpasswd + global prop0_accept prop0_confirm prop0_viewonly prop0_shared + global prop0_passwd prop0_viewpasswd + global menu_var + + if {$props_accept != $prop0_accept} { + if {$props_accept} { + push_new_value "unlock" "unlock" 1 0 + } else { + push_new_value "lock" "lock" 1 0 + } + set prop0_accept $props_accept + after 500 + } + + if {$props_confirm != $prop0_confirm} { + if {$props_confirm} { + push_new_value "accept" "accept" "popup" 1 + } else { + push_new_value "accept" "accept" "" 1 + } + if {$menu_var(accept) == "popup"} { + set props_confirm 1 + } elseif {$menu_var(accept) == ""} { + set props_confirm 0 + } + set prop0_confirm $props_confirm + after 500 + } + + if {$props_viewonly != $prop0_viewonly} { + if {$props_viewonly} { + push_new_value "viewonly" "viewonly" 1 1 + } else { + push_new_value "viewonly" "noviewonly" 1 1 + } + if {$menu_var(viewonly)} { + set props_viewonly 1 + } else { + set props_viewonly 0 + } + set prop0_viewonly $props_viewonly + after 500 + } + + if {$props_shared != $prop0_shared} { + if {$props_shared} { + push_new_value "shared" "shared" 1 1 + } else { + push_new_value "shared" "noshared" 1 1 + } + if {$menu_var(shared)} { + set props_shared 1 + } else { + set props_shared 0 + } + set prop0_shared $props_shared + after 500 + } + + if {$props_passwd != $prop0_passwd} { + push_new_value "passwd" "passwd" "$props_passwd" 0 + set prop0_passwd $props_passwd + if {$props_passwd == ""} { + set props_viewpasswd "" + } + after 500 + } + + if {$props_viewpasswd != $prop0_viewpasswd} { + push_new_value "viewpasswd" "viewpasswd" "$props_viewpasswd" 0 + set prop0_viewpasswd $props_viewpasswd + after 500 + } +} + +proc props_advanced {} { + global tray_mode icon_win props_win full_win + global props_advanced_first + + + if ![info exists props_advanced_first] { + center_win $full_win + set props_advanced_first 1 + set first 1 + } else { + set first 0 + } + wm deiconify $full_win + update + + if {$first} { + set w $full_win + wm minsize $w [winfo width $w] [winfo height $w] + } +} + +proc do_props {} { + global props_accept props_confirm props_viewonly props_shared + global props_passwd props_viewpasswd + global prop0_accept prop0_confirm prop0_viewonly prop0_shared + global prop0_passwd prop0_viewpasswd + global menu_var unset_str + global have_labelframes ffont bfont + + if ![info exists props_accept] { + set props_accept 1 + } + set prop0_accept $props_accept + + if [info exists menu_var(accept)] { + if {$menu_var(accept) == $unset_str || $menu_var(accept) == ""} { + set props_confirm 0 + } else { + set props_confirm 1 + } + } else { + set menu_var(accept) "" + set props_confirm 0 + } + set prop0_confirm $props_confirm + + if [info exists menu_var(viewonly)] { + if {$menu_var(viewonly) == $unset_str || $menu_var(viewonly) == ""} { + set props_viewonly 0 + } elseif ($menu_var(viewonly)) { + set props_viewonly 1 + } else { + set props_viewonly 0 + } + } else { + set menu_var(viewonly) 0 + set props_viewonly 0 + } + set prop0_viewonly $props_viewonly + + if [info exists menu_var(shared)] { + if {$menu_var(shared) == $unset_str || $menu_var(shared) == ""} { + set props_shared 0 + } elseif ($menu_var(shared)) { + set props_shared 1 + } else { + set props_shared 0 + } + } else { + set menu_var(shared) 0 + set props_shared 0 + } + set prop0_shared $props_shared + + if ![info exists props_passwd] { + set props_passwd "" + } + set prop0_passwd $props_passwd + + if ![info exists props_viewpasswd] { + set props_viewpasswd "" + } + set prop0_viewpasswd $props_viewpasswd + + set w .props + catch {destroy $w} + toplevel $w + wm title $w "Properties" + set b1 "$w.buttons1" + frame $b1 + button $b1.ok -text OK -command "props_apply; destroy $w" -font $bfont + button $b1.cancel -text Cancel -command "destroy $w" -font $bfont + button $b1.apply -text Apply -command "props_apply" -font $bfont + + pack $b1.apply $b1.cancel $b1.ok -side right -expand 1 + + set b2 "$w.buttons2" + frame $b2 + + button $b2.advanced -text "Advanced ..." \ + -command "destroy $w; props_advanced" -font $bfont + button $b2.help -text "Help ..." -command "menu_help Properties" -font $bfont + pack $b2.advanced $b2.help -side right -expand 1 + + set vp "$w.viewpw" + if {$have_labelframes} { + labelframe $vp -text "ViewOnly Password" -font $bfont + } else { + frame $vp + set l $vp.l + label $l -text "ViewOnly Password:" -justify left -anchor w -font $bfont + pack $vp.l -fill x -expand 1 -padx 1m -pady 0m -side top + } + entry $vp.e -show "*" -textvariable props_viewpasswd -font $bfont + pack $vp.e -fill x -expand 1 -padx 1m -pady 1m -side top + + set pw "$w.passwd" + if {$have_labelframes} { + labelframe $pw -text "Password" -font $bfont + } else { + frame $pw + set l $pw.l + label $l -text "Password:" -justify left -anchor w -font $bfont + pack $pw.l -fill x -expand 1 -padx 1m -pady 0m -side top + } + entry $pw.e -show "*" -textvariable props_passwd -font $bfont + pack $pw.e -fill x -expand 1 -padx 1m -pady 1m -side top + + set sh "$w.shared" + frame $sh + checkbutton $sh.button -text "Shared" \ + -variable props_shared -anchor w -font $bfont + pack $sh.button -fill x -expand 1 -padx 1m -pady 1m + + set vo "$w.viewonly" + frame $vo + checkbutton $vo.button -text "All Clients ViewOnly" \ + -variable props_viewonly -anchor w -font $bfont + pack $vo.button -fill x -expand 1 -padx 1m -pady 1m + + set cf "$w.confirm" + frame $cf + checkbutton $cf.button -text "Ask for Confirmation" \ + -variable props_confirm -anchor w -font $bfont + pack $cf.button -fill x -expand 1 -padx 1m -pady 1m + + set ac "$w.accept" + frame $ac + checkbutton $ac.button -text "Accept Connections" \ + -variable props_accept -anchor w -font $bfont + pack $ac.button -fill x -expand 1 -padx 1m -pady 1m + + pack $b1 -side bottom -fill x -pady 1m -padx 2m + pack $b2 -side bottom -fill x -pady 1m -padx 2m + pack $vp -side bottom -fill x -pady 1m -padx 2m + pack $pw -side bottom -fill x -pady 1m -padx 2m + pack $sh -side bottom -fill x -pady 0m -padx 2m + pack $vo -side bottom -fill x -pady 0m -padx 2m + pack $cf -side bottom -fill x -pady 0m -padx 2m + pack $ac -side bottom -fill x -pady 0m -padx 2m + + wm resizable $w 1 0 + center_win $w + update + wm minsize $w [winfo width $w] [winfo height $w] + + tkwait window $w +} + +proc do_new_client {} { + global newclient ffont bfont + + set w .newclient + catch {destroy $w} + toplevel $w + label $w.l -text "Hostname: " -font $bfont + set newclient "" + entry $w.e -width 16 -textvariable newclient -font $bfont + button $w.b -text OK -command "destroy $w" -font $bfont + bind $w.e <Return> "update; after 100; destroy $w" + + pack $w.l $w.e $w.b -side left -pady 1m -padx 1m + focus $w.e + center_win $w + update + + tkwait window $w + + if {$newclient != ""} { + push_new_value "connect" "connect" "$newclient" 1 + } +} + +proc do_disconnect_all {} { + push_new_value "disconnect" "disconnect" "all" 1 +} + +proc pmenu {m x y} { + set x [expr $x-10] + set y [expr $y-10] + $m post $x $y +} + +proc set_client_balloon {str} { + global client_balloon vnc_display + + set client_balloon "$vnc_display" + set count 0 + foreach client [split $str ","] { + if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \ + $client m0 m1 m2 m3 m4 m5 m6 m7]} { + # id:ip:port:user:hostname:input:loginvo + set id $m1 + set ip $m2 + set port $m3 + set user $m4 + if {[string length $user] >= 24} { + # weird identd hash... + set user [string range $user 0 8] + set user "${user}..." + } + set host $m5 + set input $m6 + set vo $m7 + if [regexp {^[ ]*$} $host] { + set host $ip + } + set client_balloon "${client_balloon}\n$user\@$host" + if {$vo == "1"} { + set client_balloon "${client_balloon} - view" + } else { + set client_balloon "${client_balloon} - full" + } + } else { + set i [expr $count+1] + set client_balloon "${client_balloon}\nunknown-host$i" + } + incr count + } + if {$count == 0} { + set client_balloon "${client_balloon}\nNo connections." + } + icon_win_cfg $count +} + +proc read_client_info {} { + global x11vnc_client_file client_tail client_str + global unlinked_x11vnc_client_file + if {$client_tail != ""} { + after 100 + set str "" + set count [gets $client_tail str] + + # we can unlink the file early since both processes + # have it open. + if ![info exists unlinked_x11vnc_client_file] { + set unlinked_x11vnc_client_file 0 + } elseif {$unlinked_x11vnc_client_file == ""} { + set unlinked_x11vnc_client_file 0 + } + if {! $unlinked_x11vnc_client_file} { + after 500 + catch {file delete $x11vnc_client_file} + set unlinked_x11vnc_client_file 1 + } + + if {$count == -1} { + close $client_tail + catch {file delete $x11vnc_client_file} + clean_icon_exit + } + if {$count > 0 && ![regexp {^[ ]*$} $str]} { + if {$str == "quit"} { + catch {file delete $x11vnc_client_file} + clean_icon_exit + } elseif {$str != "skip"} { + if {$str == "none"} { + set str "" + } + update_clients_menu $str + set client_str $str + set_client_balloon $str + } + } + } +} + +proc show_client_balloon {} { + global tray_mode icon_win props_win full_win + global client_balloon ffont + + if ![info exists client_balloon] { + set client_balloon "tkx11vnc ..." + } + if {$client_balloon == ""} { + set client_balloon "tkx11vnc ..." + } + + set x [expr [winfo rootx $icon_win] + ([winfo width $icon_win]/2)] + set y [expr [winfo rooty $icon_win] + [winfo height $icon_win] + 4] + + set w .client_balloon + catch {destroy $w} + toplevel $w -bg black -screen [winfo screen $icon_win] + wm overrideredirect $w 1 + label $w.l -text "$client_balloon" -relief flat -bg "#ffffaa" -fg black \ + -padx 2 -pady 0 -anchor w -justify left -font $ffont + pack $w.l -side left -padx 1 -pady 1 + + set w2 [winfo reqwidth $w.l] + set h2 [winfo reqheight $w.l] + + set W [winfo screenwidth $w] + set H [winfo screenheight $w] + + if {[expr $x+$w2] > $W} { + set w3 [winfo width $icon_win] + set x [expr "$W - $w2 - $w3 - 4"] + } + if {[expr $y+$h2] > $H} { + set h3 [winfo height $icon_win] + set y [expr "$H - $h2 - $h3 - 4"] + } + + wm geometry $w +${x}+${y} +} + +proc kill_client_balloon {} { + global client_balloon_id client_balloon_win + if [info exists client_balloon_id] { + catch {after cancel $client_balloon_id} + } + if [winfo exists .client_balloon] { + destroy .client_balloon + } +} + +proc icon_win_cfg {clients} { + global icon_win + if {$clients > 0} { + $icon_win configure -bg black -fg white + } else { + $icon_win configure -bg white -fg black + } +} + +proc make_icon {} { + global tray_mode tray_embed_id icon_win props_win full_win + global x11vnc_client_file client_tail client_str + global client_balloon_id + global bfont ffont + +# if {$tray_embed_id != ""} { +# wm withdraw . +# set top ".icon" +# toplevel $top -use $tray_embed_id +# } + + set l .label + set icon_win $l + label $l -text "x11\nvnc" -borderwidth 5 -font $bfont + icon_win_cfg 0 + + pack $l + set menu "$l.menu" + menu $menu -tearoff 0 + $menu add command -font $bfont -label "Properties" -command do_props + $menu add command -font $bfont -label "Help" -command "menu_help Tray" + $menu add separator + $menu add command -font $bfont -label "New Client" -command do_new_client + $menu add command -font $bfont -label "Disconnect All" -command do_disconnect_all + $menu add separator + $menu add command -font $bfont -label "Stop x11vnc" -command clean_icon_exit + + bind . <Button-1> "pmenu $menu %X %Y" + bind . <Button-3> "pmenu $menu %X %Y" + bind $menu <Leave> "after 200; $menu unpost" + + if {$x11vnc_client_file != "" } { + if ![file exists $x11vnc_client_file] { + set fh [open $x11vnc_client_file "w"] + puts $fh "skip" + close $fh + } + if [file exists $x11vnc_client_file] { + set client_tail [open "|tail -f $x11vnc_client_file" "r"] + } + } + + bind $icon_win <Enter> {set client_balloon_id [after 500 show_client_balloon]} + bind $icon_win <Button> {kill_client_balloon} + bind $icon_win <Leave> {kill_client_balloon} +} + +proc clean_icon_exit {} { + global client_tail + if [info exists client_tail] { + if {$client_tail != ""} { + set p [pid $client_tail] + if {$p != ""} { + catch {exec kill -TERM $p >/dev/null 2>/dev/null} + } + catch {close $client_tail} + set client_tail "" + } + } + push_new_value "stop" "stop" 1 0 + set_connected no + update + destroy . + exit +} + proc make_widgets {} { global template global menu_b menu_m menu_count @@ -2548,10 +3152,24 @@ proc make_widgets {} { global entry_help entry_skip global bfont ffont beginner_mode global helptext helpremote helplabel + global tray_mode icon_win props_win full_win + + if {$tray_mode} { + set top ".advanced" + toplevel $top + wm withdraw $top + set full_win $top + wm protocol $top WM_DELETE_WINDOW "wm withdraw $top" + wm protocol . WM_DELETE_WINDOW "clean_icon_exit" + make_icon + } else { + set top "" + set full_win "." + } # Make the top label set label_width 80 - set info_label .info + set info_label "$top.info" label $info_label -textvariable info_str -bd 2 -relief groove \ -anchor w -width $label_width -font $ffont pack $info_label -side top -fill x -expand 0 @@ -2588,7 +3206,7 @@ proc make_widgets {} { } # Make frames for the rows and make the menu buttons. - set f ".menuframe" + set f "$top.menuframe" frame $f for {set c 0} {$c < $colmax} {incr c} { set colf "$f.menuframe$c" @@ -2621,7 +3239,7 @@ proc make_widgets {} { make_menu_items # Make the x11 and vnc display label bar: - set df .displayframe + set df "$top.displayframe" frame $df -bd 1 -relief groove set df_x11 "$df.xdisplay" @@ -2640,16 +3258,16 @@ proc make_widgets {} { pack $df -side top -fill x # text area - text .text -height 12 -relief ridge -font $ffont - set text_area .text - pack .text -side top -fill both -expand 1 + set text_area "$top.text" + text $text_area -height 12 -relief ridge -font $ffont + pack $text_area -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 + set ef "$top.entryframe" frame $ef -bd 1 -relief groove # Entry Label @@ -2673,7 +3291,7 @@ proc make_widgets {} { # Entry Skip button set ef_skip "$ef.skip" - button $ef_skip -text Skip -pady $bpy -padx $bpx -command {set entry_set 0} \ + button $ef_skip -text Cancel -pady $bpy -padx $bpx -command {set entry_set 0} \ -highlightthickness $hlt \ -font $bfont @@ -2704,13 +3322,13 @@ proc make_widgets {} { set entry_label $ef_label entry_disable - update - wm minsize . [winfo width .] [winfo height .] - - #set w [winfo width .info] - #puts "w1: $w" - #set w [winfo reqwidth .info] - #puts "w2: $w" + if {$top == ""} { + set w "." + } else { + set w $top + } + update idletasks + wm minsize $w [winfo width $w] [winfo height $w] } proc menu_bindings {} { @@ -2797,7 +3415,7 @@ proc double_check_noremote {} { set msg "\n\n" append msg "*** WARNING: setting \"noremote\" will disable ALL remote control commands (i.e.\n" append msg "*** WARNING: *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 "*** WARNING: If so, press \"OK\", otherwise press \"Cancel\"\n" append msg "\n" bell return [warning_dialog $msg "noremote"] @@ -2808,7 +3426,7 @@ proc double_check_start_x11vnc {} { 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" + append msg "*** start x11vnc press \"OK\" otherwise press \"Cancel\".\n" return [warning_dialog $msg "start"] } @@ -3079,16 +3697,18 @@ proc try_connect {} { # main: global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect; +global x11vnc_client_file global x11vnc_auth_file x11vnc_connect_file beginner_mode simple_gui_created 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 menus_disabled -global bfont ffont old_labels +global bfont ffont old_labels have_labelframes global connected_to_x11vnc global delay_sleep extra_sleep extra_sleep_split global cache_all_query_vars global last_query_all_time query_all_freq +global tray_mode tray_embed_id client_tail set unset_str "(unset)" set connected_to_x11vnc 0 @@ -3104,6 +3724,7 @@ set always_update 1 set cache_all_query_vars "" set query_all_freq 120 set last_query_all_time [clock seconds] +set client_tail "" # these are no longer used under x11vnc -sync: set delay_sleep 350 @@ -3115,6 +3736,10 @@ if {[regexp {^[34]} $tk_version] || $tk_version == "8.0"} { } else { set old_labels 0 } +set have_labelframes 1 +if {$tk_version < 8.4} { + set have_labelframes 0 +} if {"$argv" == "-spit"} { set fh [open $argv0 r] @@ -3159,6 +3784,12 @@ if {[info exists env(X11VNC_CONNECT_FILE)]} { set x11vnc_connect_file ""; } +if {[info exists env(X11VNC_CLIENT_FILE)]} { + set x11vnc_client_file $env(X11VNC_CLIENT_FILE); +} else { + set x11vnc_client_file ""; +} + if {[info exists env(X11VNC_XDISPLAY)]} { set x11vnc_xdisplay $env(X11VNC_XDISPLAY); set x11vnc_connect 1 @@ -3186,6 +3817,19 @@ if {[info exists env(X11VNC_SIMPLE_GUI)]} { set beginner_mode 0 } +set tray_mode 0 +if {[info exists env(X11VNC_TRAY_MODE)]} { + set tray_mode 1 +} else { + set tray_mode 0 +} +set tray_mode 1 + +if {[info exists env(X11VNC_TRAY_EMBED_ID)]} { + set tray_embed_id $env(X11VNC_TRAY_EMBED_ID) +} else { + set tray_embed_id "" +} set hostname [exec uname -n] #puts [exec env] @@ -3220,4 +3864,8 @@ if {$x11vnc_connect} { } set_widgets +if {$tray_mode && $client_tail != ""} { + fileevent $client_tail readable read_client_info +} + # main loop. diff --git a/x11vnc/tkx11vnc.h b/x11vnc/tkx11vnc.h index 239b6be..2f52f9c 100644 --- a/x11vnc/tkx11vnc.h +++ b/x11vnc/tkx11vnc.h @@ -398,7 +398,7 @@ "checkboxes and pressing \\\"OK\\\". This is like the \\\"-input\\\" option\n" "but on a per-client basis.\n" "\n" -"To not change any aspects of the VNC client press \\\"Skip\\\".\n" +"To not change any aspects of the VNC client press \\\"Cancel\\\".\n" "\"\n" "\n" " set helptext(solid_color) \"\n" @@ -419,6 +419,95 @@ "and one for power users.\n" "\"\n" "\n" +" set helptext(Tray) \"\n" +"The tray/icon mode (started with \\\"x11vnc -gui tray ...\\\") presents a\n" +"small icon that indicates the status of a running x11vnc server.\n" +"\n" +"Depending on your environment, this icon may be embedded in a system\n" +"tray or applet dock, or simply be a standalone window.\n" +"\n" +"When the icon has a light background, that means no VNC viewers are\n" +"currently connected to the display.\n" +"\n" +"When the icon has a dark background (i.e. reverse-video), that means at\n" +"least one VNC viewer is connected to the display.\n" +"\n" +"Moving the mouse pointer over the icon will popup a \\\"status balloon\\\"\n" +"indicating the VNC display name and the names and other info of any\n" +"connected VNC viewers.\n" +"\n" +"Clicking the right mouse button on the icon displays a menu of actions:\n" +"\n" +" Properties - Brings up the Properties dialog. The full tkx11vnc\n" +" GUI may be accessed via the \\\"Advanced ...\\\" button.\n" +" \n" +" Help - Displays this help text.\n" +" \n" +" New Client - Presents an entry box where you type in the name\n" +" of a computer that is running a VNC viewer in\n" +" \\\"listen\\\" mode (e.g. vncviewer -listen). For a\n" +" non-standard listening port use \\\"host:port\\\".\n" +" Pressing \\\"OK\\\" will initiate the reverse\n" +" connection. Use a blank hostname to skip it.\n" +" \n" +" Disconnect All - Disconnects all current VNC viewers.\n" +" \n" +" Stop x11vnc - Directs the x11vnc server to disconnect all vncviewers\n" +" and then exit. The tray/icon GUI then exits as well.\n" +"\n" +"\n" +"If the x11vnc server stops for any reason, the tray/icon gui will exit.\n" +"\n" +"If you delete the tray/icon (e.g. X out button), that is the same\n" +"as the \\\"Stop x11vnc\\\" action in the menu.\n" +"\"\n" +"\n" +" set helptext(Properties) \"\n" +"The Properties dialog allows you to set some basic parameters of a\n" +"running x11vnc server. After modifying them press \\\"OK\\\" or \\\"Apply\\\"\n" +"to apply the changes, or press \\\"Cancel\\\" to skip applying them.\n" +"\n" +"\\\"Accept Connections\\\" toggles whether VNC viewers are allowed\n" +"to connect or not. It corresponds to the \\\"-R unlock\\\" and \\\"-R lock\\\"\n" +"remote-control commands.\n" +"\n" +"\\\"Ask for Confirmation\\\" toggles whether a popup menu will be presented\n" +"at the X display when a new VNC viewer attempts to connects. The person\n" +"sitting at the X display can chose to accept or reject the connection\n" +"or accept the connection in View-Only mode. It corresponds to the \n" +"\\\"-R accept:popup\\\" and \\\"-R accept:\\\" remote-control commands.\n" +"\n" +"\\\"All Clients ViewOnly\\\" toggles whether the entire VNC desktop is\n" +"view only. All clients will only be able to watch when this is set\n" +"(regardless of how they logged in). It corresponds to the \\\"-R viewonly\\\"\n" +"and \\\"-R noviewonly\\\" remote-control commands.\n" +"\n" +"\\\"Shared\\\" toggles whether multiple simultaneous connections are\n" +"allowed or not. It corresponds to the \\\"-R shared\\\" and \\\"-R noshared\\\"\n" +"remote-control commands.\n" +"\n" +"\\\"Password\\\" lets you set the session password viewers may use to gain full\n" +"access to the display.\n" +"\n" +"\\\"ViewOnly Password\\\" lets you set the session password viewers may\n" +"use to gain view only access to the display.\n" +"\n" +"NOTE: These passwords only last for the current x11vnc session (they are\n" +"not remembered, see the -storepasswd, -passwdfile, and -rfbauth x11vnc\n" +"options for using stored passwords).\n" +"\n" +"If you set \\\"Password\\\" to the empty string that makes the \\\"View-Only\n" +"Password\\\" empty as well and removes the need for any password to log in.\n" +"\n" +"If you set \\\"ViewOnly Password\\\" to the empty string that just removes\n" +"the ViewOnly log in aspect: \\\"Password\\\" is still required to log in.\n" +"\n" +"The \\\"Help ...\\\" button shows this help text.\n" +"\n" +"The \\\"Advanced ...\\\" button replaces the Properties dialog with the full\n" +"tkx11vnc GUI. Any dynamic settings can be modified in the full GUI.\n" +"\" \n" +"\n" " set helptext(all) $helpall\n" "\n" " set helptext(Misc-Tuning:) \"\n" @@ -494,7 +583,7 @@ "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" +"\\\"Cancel\\\" 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" @@ -567,7 +656,7 @@ "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" +"\\\"Cancel\\\" 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" @@ -613,8 +702,14 @@ "}\n" "\n" "proc set_name {name} {\n" -" wm title . \"$name\"\n" -" wm iconname . \"$name\"\n" +" global full_win\n" +" if [info exists full_win] {\n" +" set w $full_win\n" +" } else {\n" +" set w \".\"\n" +" }\n" +" wm title $w \"$name\"\n" +" wm iconname $w \"$name\"\n" "}\n" "\n" "proc make_toplevel {w {title \"\"}} {\n" @@ -732,7 +827,8 @@ " set text \"Help on $item:\\n\\n\"\n" "\n" " if {[is_gui_internal $item]} {\n" -" if {$item != \"gui\" && $item != \"all\" && $item != \"Misc-Tuning:\"} {\n" +" if {$item != \"gui\" && $item != \"all\" && $item != \"Misc-Tuning:\" \\\n" +" && $item != \"Properties\" && $item != \"Tray\"} {\n" " append text \" + Is a gui internal Action (cannot be set).\\n\";\n" " }\n" " } elseif {[is_action $item]} {\n" @@ -1173,7 +1269,11 @@ " set query_output \"\"\n" "\n" " if {!$debug} {\n" -" append_text \"x11vnc $rargs ...\"\n" +" if [regexp {passwd} $rargs] {\n" +" append_text \"x11vnc ...\"\n" +" } else {\n" +" append_text \"x11vnc $rargs ...\"\n" +" }\n" " }\n" "\n" " if {$getout} {\n" @@ -1264,7 +1364,7 @@ "\n" " append_text \"\\nUse these checkboxes to set the input permissions, \"\n" " append_text \"or type in the \\\"KMB...\\\"\\n\"\n" -" append_text \"-input string manually. Then press \\\"OK\\\" or \\\"Skip\\\".\\n\"\n" +" append_text \"-input string manually. Then press \\\"OK\\\" or \\\"Cancel\\\".\\n\"\n" " append_text \"(note: an empty setting means use the default behavior, \"\n" " append_text \"see viewonly)\\n\\n\"\n" " set w \"$text_area.wk_f\"\n" @@ -1375,7 +1475,7 @@ "\n" " append_text \"\\nUse these checkboxes to set the input permissions \"\n" " append_text \"for this client\\n-or- whether to disconnect it instead. \"\n" -" append_text \"Then press \\\"OK\\\" or \\\"Skip\\\".\\n\\n\"\n" +" append_text \"Then press \\\"OK\\\" or \\\"Cancel\\\".\\n\\n\"\n" " set w \"$text_area.ca_f\"\n" " catch {destroy $w}\n" " frame $w -bd 1 -relief ridge -cursor {top_left_arrow}\n" @@ -1420,7 +1520,7 @@ " }\n" "}\n" "\n" -"# For updating a string variable. Also used for simple OK/Skip dialogs\n" +"# For updating a string variable. Also used for simple OK/Cancel dialogs\n" "# with entry = 0.\n" "proc entry_dialog {item {entry 1}} {\n" " global menu_var entry_str entry_set entry_dialog_item\n" @@ -1587,6 +1687,9 @@ " || $item == \"client\" || $item == \"client_input\"} {\n" " append_text \"\\t($msg)\\n\"\n" " return 1\n" +" } elseif {$item == \"passwd\" || $item == \"viewpasswd\"} {\n" +" append_text \"\\t($msg)\\n\"\n" +" return 1\n" " } else {\n" " append_text \"\\t*FAILED* $msg\\n\"\n" " return 0\n" @@ -1810,6 +1913,14 @@ " set_connected no\n" "}\n" "\n" +"proc do_stop_quit {} {\n" +" push_new_value \"stop\" \"stop\" 1 0\n" +" set_connected no\n" +" update\n" +" after 250\n" +" destroy .\n" +"}\n" +"\n" "# Menu item is an action:\n" "proc do_action {item} {\n" " global menu_var connected_to_x11vnc beginner_mode\n" @@ -1856,11 +1967,7 @@ " menu_help \"$item\"\n" " return\n" " } elseif {$item == \"stop+quit\"} {\n" -" push_new_value \"stop\" \"stop\" 1 0\n" -" set_connected no\n" -" update\n" -" after 500\n" -" destroy .\n" +" do_stop_quit\n" " }\n" "\n" " if {[value_is_string $item]} {\n" @@ -1967,6 +2074,12 @@ "}\n" "\n" "proc is_gui_internal {item} {\n" +" if {$item == \"Properties\"} {\n" +" return 1\n" +" }\n" +" if {$item == \"Tray\"} {\n" +" return 1\n" +" }\n" " return [opt_match G $item]\n" "}\n" "\n" @@ -2200,7 +2313,7 @@ " 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" +" append msg \"*** To *DISCONNECT* this client press \\\"OK\\\", otherwise press \\\"Cancel\\\"\\n\"\n" " bell\n" " if {[warning_dialog $msg \"current\"]} {\n" " push_new_value \"disconnect\" \"disconnect\" $cid 1\n" @@ -2261,7 +2374,7 @@ " regsub {:.*$} $client \"\" clabel\n" " }\n" " $subm add command -label \"$clabel\" \\\n" -" -command \"client_dialog $client\"\n" +" -command \"client_dialog \\{$client\\}\"\n" " incr count\n" " }\n" " $subm entryconfigure 0 -label \"num-clients: $count\"\n" @@ -2543,6 +2656,497 @@ " }\n" "}\n" "\n" +"proc props_apply {} {\n" +" global props_accept props_confirm props_viewonly props_shared\n" +" global props_passwd props_viewpasswd\n" +" global prop0_accept prop0_confirm prop0_viewonly prop0_shared\n" +" global prop0_passwd prop0_viewpasswd\n" +" global menu_var\n" +"\n" +" if {$props_accept != $prop0_accept} {\n" +" if {$props_accept} {\n" +" push_new_value \"unlock\" \"unlock\" 1 0\n" +" } else {\n" +" push_new_value \"lock\" \"lock\" 1 0\n" +" }\n" +" set prop0_accept $props_accept\n" +" after 500\n" +" }\n" +"\n" +" if {$props_confirm != $prop0_confirm} {\n" +" if {$props_confirm} {\n" +" push_new_value \"accept\" \"accept\" \"popup\" 1\n" +" } else {\n" +" push_new_value \"accept\" \"accept\" \"\" 1\n" +" }\n" +" if {$menu_var(accept) == \"popup\"} {\n" +" set props_confirm 1\n" +" } elseif {$menu_var(accept) == \"\"} {\n" +" set props_confirm 0\n" +" }\n" +" set prop0_confirm $props_confirm\n" +" after 500\n" +" }\n" +"\n" +" if {$props_viewonly != $prop0_viewonly} {\n" +" if {$props_viewonly} {\n" +" push_new_value \"viewonly\" \"viewonly\" 1 1\n" +" } else {\n" +" push_new_value \"viewonly\" \"noviewonly\" 1 1\n" +" }\n" +" if {$menu_var(viewonly)} {\n" +" set props_viewonly 1\n" +" } else {\n" +" set props_viewonly 0\n" +" }\n" +" set prop0_viewonly $props_viewonly\n" +" after 500\n" +" }\n" +"\n" +" if {$props_shared != $prop0_shared} {\n" +" if {$props_shared} {\n" +" push_new_value \"shared\" \"shared\" 1 1\n" +" } else {\n" +" push_new_value \"shared\" \"noshared\" 1 1\n" +" }\n" +" if {$menu_var(shared)} {\n" +" set props_shared 1\n" +" } else {\n" +" set props_shared 0\n" +" }\n" +" set prop0_shared $props_shared\n" +" after 500\n" +" }\n" +"\n" +" if {$props_passwd != $prop0_passwd} {\n" +" push_new_value \"passwd\" \"passwd\" \"$props_passwd\" 0\n" +" set prop0_passwd $props_passwd\n" +" if {$props_passwd == \"\"} {\n" +" set props_viewpasswd \"\"\n" +" }\n" +" after 500\n" +" }\n" +"\n" +" if {$props_viewpasswd != $prop0_viewpasswd} {\n" +" push_new_value \"viewpasswd\" \"viewpasswd\" \"$props_viewpasswd\" 0\n" +" set prop0_viewpasswd $props_viewpasswd\n" +" after 500\n" +" }\n" +"}\n" +"\n" +"proc props_advanced {} {\n" +" global tray_mode icon_win props_win full_win\n" +" global props_advanced_first\n" +"\n" +"\n" +" if ![info exists props_advanced_first] {\n" +" center_win $full_win\n" +" set props_advanced_first 1\n" +" set first 1\n" +" } else {\n" +" set first 0\n" +" }\n" +" wm deiconify $full_win\n" +" update\n" +"\n" +" if {$first} {\n" +" set w $full_win\n" +" wm minsize $w [winfo width $w] [winfo height $w]\n" +" }\n" +"}\n" +"\n" +"proc do_props {} {\n" +" global props_accept props_confirm props_viewonly props_shared\n" +" global props_passwd props_viewpasswd\n" +" global prop0_accept prop0_confirm prop0_viewonly prop0_shared\n" +" global prop0_passwd prop0_viewpasswd\n" +" global menu_var unset_str\n" +" global have_labelframes ffont bfont\n" +"\n" +" if ![info exists props_accept] {\n" +" set props_accept 1\n" +" }\n" +" set prop0_accept $props_accept\n" +"\n" +" if [info exists menu_var(accept)] {\n" +" if {$menu_var(accept) == $unset_str || $menu_var(accept) == \"\"} {\n" +" set props_confirm 0\n" +" } else {\n" +" set props_confirm 1\n" +" }\n" +" } else {\n" +" set menu_var(accept) \"\"\n" +" set props_confirm 0\n" +" }\n" +" set prop0_confirm $props_confirm\n" +"\n" +" if [info exists menu_var(viewonly)] {\n" +" if {$menu_var(viewonly) == $unset_str || $menu_var(viewonly) == \"\"} {\n" +" set props_viewonly 0\n" +" } elseif ($menu_var(viewonly)) {\n" +" set props_viewonly 1\n" +" } else {\n" +" set props_viewonly 0\n" +" }\n" +" } else {\n" +" set menu_var(viewonly) 0\n" +" set props_viewonly 0\n" +" }\n" +" set prop0_viewonly $props_viewonly\n" +"\n" +" if [info exists menu_var(shared)] {\n" +" if {$menu_var(shared) == $unset_str || $menu_var(shared) == \"\"} {\n" +" set props_shared 0\n" +" } elseif ($menu_var(shared)) {\n" +" set props_shared 1\n" +" } else {\n" +" set props_shared 0\n" +" }\n" +" } else {\n" +" set menu_var(shared) 0\n" +" set props_shared 0\n" +" }\n" +" set prop0_shared $props_shared\n" +"\n" +" if ![info exists props_passwd] {\n" +" set props_passwd \"\"\n" +" }\n" +" set prop0_passwd $props_passwd\n" +"\n" +" if ![info exists props_viewpasswd] {\n" +" set props_viewpasswd \"\"\n" +" }\n" +" set prop0_viewpasswd $props_viewpasswd\n" +"\n" +" set w .props\n" +" catch {destroy $w}\n" +" toplevel $w\n" +" wm title $w \"Properties\"\n" +" set b1 \"$w.buttons1\"\n" +" frame $b1\n" +" button $b1.ok -text OK -command \"props_apply; destroy $w\" -font $bfont\n" +" button $b1.cancel -text Cancel -command \"destroy $w\" -font $bfont\n" +" button $b1.apply -text Apply -command \"props_apply\" -font $bfont\n" +"\n" +" pack $b1.apply $b1.cancel $b1.ok -side right -expand 1\n" +"\n" +" set b2 \"$w.buttons2\"\n" +" frame $b2\n" +"\n" +" button $b2.advanced -text \"Advanced ...\" \\\n" +" -command \"destroy $w; props_advanced\" -font $bfont\n" +" button $b2.help -text \"Help ...\" -command \"menu_help Properties\" -font $bfont\n" +" pack $b2.advanced $b2.help -side right -expand 1\n" +"\n" +" set vp \"$w.viewpw\"\n" +" if {$have_labelframes} {\n" +" labelframe $vp -text \"ViewOnly Password\" -font $bfont\n" +" } else {\n" +" frame $vp\n" +" set l $vp.l\n" +" label $l -text \"ViewOnly Password:\" -justify left -anchor w -font $bfont\n" +" pack $vp.l -fill x -expand 1 -padx 1m -pady 0m -side top\n" +" }\n" +" entry $vp.e -show \"*\" -textvariable props_viewpasswd -font $bfont\n" +" pack $vp.e -fill x -expand 1 -padx 1m -pady 1m -side top\n" +"\n" +" set pw \"$w.passwd\"\n" +" if {$have_labelframes} {\n" +" labelframe $pw -text \"Password\" -font $bfont\n" +" } else {\n" +" frame $pw\n" +" set l $pw.l\n" +" label $l -text \"Password:\" -justify left -anchor w -font $bfont\n" +" pack $pw.l -fill x -expand 1 -padx 1m -pady 0m -side top\n" +" }\n" +" entry $pw.e -show \"*\" -textvariable props_passwd -font $bfont\n" +" pack $pw.e -fill x -expand 1 -padx 1m -pady 1m -side top\n" +"\n" +" set sh \"$w.shared\"\n" +" frame $sh\n" +" checkbutton $sh.button -text \"Shared\" \\\n" +" -variable props_shared -anchor w -font $bfont\n" +" pack $sh.button -fill x -expand 1 -padx 1m -pady 1m\n" +"\n" +" set vo \"$w.viewonly\"\n" +" frame $vo\n" +" checkbutton $vo.button -text \"All Clients ViewOnly\" \\\n" +" -variable props_viewonly -anchor w -font $bfont\n" +" pack $vo.button -fill x -expand 1 -padx 1m -pady 1m\n" +"\n" +" set cf \"$w.confirm\"\n" +" frame $cf\n" +" checkbutton $cf.button -text \"Ask for Confirmation\" \\\n" +" -variable props_confirm -anchor w -font $bfont\n" +" pack $cf.button -fill x -expand 1 -padx 1m -pady 1m\n" +"\n" +" set ac \"$w.accept\"\n" +" frame $ac\n" +" checkbutton $ac.button -text \"Accept Connections\" \\\n" +" -variable props_accept -anchor w -font $bfont\n" +" pack $ac.button -fill x -expand 1 -padx 1m -pady 1m\n" +"\n" +" pack $b1 -side bottom -fill x -pady 1m -padx 2m\n" +" pack $b2 -side bottom -fill x -pady 1m -padx 2m\n" +" pack $vp -side bottom -fill x -pady 1m -padx 2m\n" +" pack $pw -side bottom -fill x -pady 1m -padx 2m\n" +" pack $sh -side bottom -fill x -pady 0m -padx 2m\n" +" pack $vo -side bottom -fill x -pady 0m -padx 2m\n" +" pack $cf -side bottom -fill x -pady 0m -padx 2m\n" +" pack $ac -side bottom -fill x -pady 0m -padx 2m\n" +"\n" +" wm resizable $w 1 0\n" +" center_win $w\n" +" update\n" +" wm minsize $w [winfo width $w] [winfo height $w]\n" +"\n" +" tkwait window $w\n" +"}\n" +"\n" +"proc do_new_client {} {\n" +" global newclient ffont bfont\n" +"\n" +" set w .newclient\n" +" catch {destroy $w}\n" +" toplevel $w\n" +" label $w.l -text \"Hostname: \" -font $bfont\n" +" set newclient \"\"\n" +" entry $w.e -width 16 -textvariable newclient -font $bfont \n" +" button $w.b -text OK -command \"destroy $w\" -font $bfont\n" +" bind $w.e <Return> \"update; after 100; destroy $w\"\n" +"\n" +" pack $w.l $w.e $w.b -side left -pady 1m -padx 1m\n" +" focus $w.e\n" +" center_win $w\n" +" update \n" +" \n" +" tkwait window $w\n" +"\n" +" if {$newclient != \"\"} {\n" +" push_new_value \"connect\" \"connect\" \"$newclient\" 1\n" +" }\n" +"}\n" +"\n" +"proc do_disconnect_all {} {\n" +" push_new_value \"disconnect\" \"disconnect\" \"all\" 1\n" +"}\n" +"\n" +"proc pmenu {m x y} {\n" +" set x [expr $x-10]\n" +" set y [expr $y-10]\n" +" $m post $x $y\n" +"}\n" +"\n" +"proc set_client_balloon {str} {\n" +" global client_balloon vnc_display\n" +" \n" +" set client_balloon \"$vnc_display\"\n" +" set count 0\n" +" foreach client [split $str \",\"] {\n" +" if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \\\n" +" $client m0 m1 m2 m3 m4 m5 m6 m7]} {\n" +" # id:ip:port:user:hostname:input:loginvo\n" +" set id $m1\n" +" set ip $m2\n" +" set port $m3\n" +" set user $m4\n" +" if {[string length $user] >= 24} {\n" +" # weird identd hash...\n" +" set user [string range $user 0 8]\n" +" set user \"${user}...\"\n" +" }\n" +" set host $m5\n" +" set input $m6\n" +" set vo $m7\n" +" if [regexp {^[ ]*$} $host] {\n" +" set host $ip\n" +" }\n" +" set client_balloon \"${client_balloon}\\n$user\\@$host\"\n" +" if {$vo == \"1\"} {\n" +" set client_balloon \"${client_balloon} - view\"\n" +" } else {\n" +" set client_balloon \"${client_balloon} - full\"\n" +" }\n" +" } else {\n" +" set i [expr $count+1]\n" +" set client_balloon \"${client_balloon}\\nunknown-host$i\"\n" +" }\n" +" incr count\n" +" }\n" +" if {$count == 0} {\n" +" set client_balloon \"${client_balloon}\\nNo connections.\"\n" +" }\n" +" icon_win_cfg $count\n" +"}\n" +"\n" +"proc read_client_info {} {\n" +" global x11vnc_client_file client_tail client_str\n" +" global unlinked_x11vnc_client_file\n" +" if {$client_tail != \"\"} {\n" +" after 100\n" +" set str \"\"\n" +" set count [gets $client_tail str]\n" +"\n" +" # we can unlink the file early since both processes\n" +" # have it open.\n" +" if ![info exists unlinked_x11vnc_client_file] {\n" +" set unlinked_x11vnc_client_file 0\n" +" } elseif {$unlinked_x11vnc_client_file == \"\"} {\n" +" set unlinked_x11vnc_client_file 0\n" +" }\n" +" if {! $unlinked_x11vnc_client_file} {\n" +" after 500\n" +" catch {file delete $x11vnc_client_file}\n" +" set unlinked_x11vnc_client_file 1\n" +" }\n" +"\n" +" if {$count == -1} {\n" +" close $client_tail\n" +" catch {file delete $x11vnc_client_file}\n" +" clean_icon_exit\n" +" }\n" +" if {$count > 0 && ![regexp {^[ ]*$} $str]} {\n" +" if {$str == \"quit\"} {\n" +" catch {file delete $x11vnc_client_file}\n" +" clean_icon_exit\n" +" } elseif {$str != \"skip\"} {\n" +" if {$str == \"none\"} {\n" +" set str \"\"\n" +" }\n" +" update_clients_menu $str\n" +" set client_str $str\n" +" set_client_balloon $str\n" +" }\n" +" }\n" +" }\n" +"}\n" +"\n" +"proc show_client_balloon {} {\n" +" global tray_mode icon_win props_win full_win\n" +" global client_balloon ffont\n" +"\n" +" if ![info exists client_balloon] {\n" +" set client_balloon \"tkx11vnc ...\"\n" +" }\n" +" if {$client_balloon == \"\"} {\n" +" set client_balloon \"tkx11vnc ...\"\n" +" }\n" +"\n" +" set x [expr [winfo rootx $icon_win] + ([winfo width $icon_win]/2)]\n" +" set y [expr [winfo rooty $icon_win] + [winfo height $icon_win] + 4]\n" +"\n" +" set w .client_balloon\n" +" catch {destroy $w}\n" +" toplevel $w -bg black -screen [winfo screen $icon_win]\n" +" wm overrideredirect $w 1\n" +" label $w.l -text \"$client_balloon\" -relief flat -bg \"#ffffaa\" -fg black \\\n" +" -padx 2 -pady 0 -anchor w -justify left -font $ffont\n" +" pack $w.l -side left -padx 1 -pady 1\n" +"\n" +" set w2 [winfo reqwidth $w.l]\n" +" set h2 [winfo reqheight $w.l]\n" +"\n" +" set W [winfo screenwidth $w]\n" +" set H [winfo screenheight $w]\n" +"\n" +" if {[expr $x+$w2] > $W} {\n" +" set w3 [winfo width $icon_win]\n" +" set x [expr \"$W - $w2 - $w3 - 4\"] \n" +" }\n" +" if {[expr $y+$h2] > $H} {\n" +" set h3 [winfo height $icon_win]\n" +" set y [expr \"$H - $h2 - $h3 - 4\"] \n" +" }\n" +"\n" +" wm geometry $w +${x}+${y}\n" +"}\n" +"\n" +"proc kill_client_balloon {} {\n" +" global client_balloon_id client_balloon_win\n" +" if [info exists client_balloon_id] {\n" +" catch {after cancel $client_balloon_id}\n" +" }\n" +" if [winfo exists .client_balloon] {\n" +" destroy .client_balloon\n" +" }\n" +"}\n" +"\n" +"proc icon_win_cfg {clients} {\n" +" global icon_win\n" +" if {$clients > 0} {\n" +" $icon_win configure -bg black -fg white\n" +" } else {\n" +" $icon_win configure -bg white -fg black\n" +" }\n" +"}\n" +"\n" +"proc make_icon {} {\n" +" global tray_mode tray_embed_id icon_win props_win full_win\n" +" global x11vnc_client_file client_tail client_str\n" +" global client_balloon_id\n" +" global bfont ffont\n" +" \n" +"# if {$tray_embed_id != \"\"} {\n" +"# wm withdraw .\n" +"# set top \".icon\"\n" +"# toplevel $top -use $tray_embed_id\n" +"# }\n" +"\n" +" set l .label\n" +" set icon_win $l\n" +" label $l -text \"x11\\nvnc\" -borderwidth 5 -font $bfont\n" +" icon_win_cfg 0\n" +"\n" +" pack $l\n" +" set menu \"$l.menu\"\n" +" menu $menu -tearoff 0\n" +" $menu add command -font $bfont -label \"Properties\" -command do_props\n" +" $menu add command -font $bfont -label \"Help\" -command \"menu_help Tray\"\n" +" $menu add separator\n" +" $menu add command -font $bfont -label \"New Client\" -command do_new_client\n" +" $menu add command -font $bfont -label \"Disconnect All\" -command do_disconnect_all\n" +" $menu add separator\n" +" $menu add command -font $bfont -label \"Stop x11vnc\" -command clean_icon_exit\n" +"\n" +" bind . <Button-1> \"pmenu $menu %X %Y\"\n" +" bind . <Button-3> \"pmenu $menu %X %Y\"\n" +" bind $menu <Leave> \"after 200; $menu unpost\"\n" +"\n" +" if {$x11vnc_client_file != \"\" } {\n" +" if ![file exists $x11vnc_client_file] {\n" +" set fh [open $x11vnc_client_file \"w\"]\n" +" puts $fh \"skip\"\n" +" close $fh\n" +" }\n" +" if [file exists $x11vnc_client_file] {\n" +" set client_tail [open \"|tail -f $x11vnc_client_file\" \"r\"]\n" +" }\n" +" }\n" +"\n" +" bind $icon_win <Enter> {set client_balloon_id [after 500 show_client_balloon]}\n" +" bind $icon_win <Button> {kill_client_balloon}\n" +" bind $icon_win <Leave> {kill_client_balloon}\n" +"}\n" +"\n" +"proc clean_icon_exit {} {\n" +" global client_tail\n" +" if [info exists client_tail] {\n" +" if {$client_tail != \"\"} {\n" +" set p [pid $client_tail]\n" +" if {$p != \"\"} {\n" +" catch {exec kill -TERM $p >/dev/null 2>/dev/null}\n" +" }\n" +" catch {close $client_tail}\n" +" set client_tail \"\"\n" +" }\n" +" }\n" +" push_new_value \"stop\" \"stop\" 1 0\n" +" set_connected no\n" +" update\n" +" destroy .\n" +" exit\n" +"}\n" +"\n" "proc make_widgets {} {\n" " global template \n" " global menu_b menu_m menu_count\n" @@ -2554,10 +3158,24 @@ " global entry_help entry_skip\n" " global bfont ffont beginner_mode\n" " global helptext helpremote helplabel\n" +" global tray_mode icon_win props_win full_win\n" +"\n" +" if {$tray_mode} {\n" +" set top \".advanced\"\n" +" toplevel $top\n" +" wm withdraw $top\n" +" set full_win $top\n" +" wm protocol $top WM_DELETE_WINDOW \"wm withdraw $top\"\n" +" wm protocol . WM_DELETE_WINDOW \"clean_icon_exit\"\n" +" make_icon\n" +" } else {\n" +" set top \"\"\n" +" set full_win \".\"\n" +" }\n" "\n" " # Make the top label\n" " set label_width 80\n" -" set info_label .info\n" +" set info_label \"$top.info\"\n" " label $info_label -textvariable info_str -bd 2 -relief groove \\\n" " -anchor w -width $label_width -font $ffont\n" " pack $info_label -side top -fill x -expand 0\n" @@ -2594,7 +3212,7 @@ " }\n" "\n" " # Make frames for the rows and make the menu buttons.\n" -" set f \".menuframe\"\n" +" set f \"$top.menuframe\"\n" " frame $f\n" " for {set c 0} {$c < $colmax} {incr c} {\n" " set colf \"$f.menuframe$c\"\n" @@ -2627,7 +3245,7 @@ " make_menu_items\n" "\n" " # Make the x11 and vnc display label bar:\n" -" set df .displayframe\n" +" set df \"$top.displayframe\"\n" " frame $df -bd 1 -relief groove\n" "\n" " set df_x11 \"$df.xdisplay\"\n" @@ -2646,16 +3264,16 @@ " pack $df -side top -fill x\n" "\n" " # text area\n" -" text .text -height 12 -relief ridge -font $ffont\n" -" set text_area .text\n" -" pack .text -side top -fill both -expand 1\n" +" set text_area \"$top.text\"\n" +" text $text_area -height 12 -relief ridge -font $ffont\n" +" pack $text_area -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" +" set ef \"$top.entryframe\"\n" " frame $ef -bd 1 -relief groove\n" "\n" " # Entry Label\n" @@ -2679,7 +3297,7 @@ "\n" " # Entry Skip button\n" " set ef_skip \"$ef.skip\"\n" -" button $ef_skip -text Skip -pady $bpy -padx $bpx -command {set entry_set 0} \\\n" +" button $ef_skip -text Cancel -pady $bpy -padx $bpx -command {set entry_set 0} \\\n" " -highlightthickness $hlt \\\n" " -font $bfont\n" "\n" @@ -2710,13 +3328,13 @@ " set entry_label $ef_label\n" " entry_disable\n" "\n" -" update\n" -" wm minsize . [winfo width .] [winfo height .]\n" -"\n" -" #set w [winfo width .info]\n" -" #puts \"w1: $w\"\n" -" #set w [winfo reqwidth .info]\n" -" #puts \"w2: $w\"\n" +" if {$top == \"\"} {\n" +" set w \".\"\n" +" } else {\n" +" set w $top\n" +" }\n" +" update idletasks\n" +" wm minsize $w [winfo width $w] [winfo height $w]\n" "}\n" "\n" "proc menu_bindings {} {\n" @@ -2803,7 +3421,7 @@ " set msg \"\\n\\n\"\n" " append msg \"*** WARNING: setting \\\"noremote\\\" will disable ALL remote control commands (i.e.\\n\"\n" " append msg \"*** WARNING: *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 \"*** WARNING: If so, press \\\"OK\\\", otherwise press \\\"Cancel\\\"\\n\"\n" " append msg \"\\n\"\n" " bell\n" " return [warning_dialog $msg \"noremote\"]\n" @@ -2814,7 +3432,7 @@ " 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" +" append msg \"*** start x11vnc press \\\"OK\\\" otherwise press \\\"Cancel\\\".\\n\"\n" " return [warning_dialog $msg \"start\"]\n" "}\n" "\n" @@ -3085,16 +3703,18 @@ "# main:\n" "\n" "global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect;\n" +"global x11vnc_client_file\n" "global x11vnc_auth_file x11vnc_connect_file beginner_mode simple_gui_created\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 menus_disabled\n" -"global bfont ffont old_labels\n" +"global bfont ffont old_labels have_labelframes\n" "global connected_to_x11vnc\n" "global delay_sleep extra_sleep extra_sleep_split\n" "global cache_all_query_vars\n" "global last_query_all_time query_all_freq\n" +"global tray_mode tray_embed_id client_tail\n" "\n" "set unset_str \"(unset)\"\n" "set connected_to_x11vnc 0\n" @@ -3110,6 +3730,7 @@ "set cache_all_query_vars \"\"\n" "set query_all_freq 120\n" "set last_query_all_time [clock seconds]\n" +"set client_tail \"\"\n" "\n" "# these are no longer used under x11vnc -sync:\n" "set delay_sleep 350\n" @@ -3121,6 +3742,10 @@ "} else {\n" " set old_labels 0\n" "}\n" +"set have_labelframes 1\n" +"if {$tk_version < 8.4} {\n" +" set have_labelframes 0\n" +"}\n" "\n" "if {\"$argv\" == \"-spit\"} {\n" " set fh [open $argv0 r]\n" @@ -3165,6 +3790,12 @@ " set x11vnc_connect_file \"\";\n" "}\n" "\n" +"if {[info exists env(X11VNC_CLIENT_FILE)]} {\n" +" set x11vnc_client_file $env(X11VNC_CLIENT_FILE);\n" +"} else {\n" +" set x11vnc_client_file \"\";\n" +"}\n" +"\n" "if {[info exists env(X11VNC_XDISPLAY)]} {\n" " set x11vnc_xdisplay $env(X11VNC_XDISPLAY);\n" " set x11vnc_connect 1\n" @@ -3192,6 +3823,19 @@ " set beginner_mode 0\n" "}\n" "\n" +"set tray_mode 0\n" +"if {[info exists env(X11VNC_TRAY_MODE)]} {\n" +" set tray_mode 1\n" +"} else {\n" +" set tray_mode 0\n" +"}\n" +"set tray_mode 1\n" +"\n" +"if {[info exists env(X11VNC_TRAY_EMBED_ID)]} {\n" +" set tray_embed_id $env(X11VNC_TRAY_EMBED_ID)\n" +"} else {\n" +" set tray_embed_id \"\"\n" +"}\n" "\n" "set hostname [exec uname -n]\n" "#puts [exec env]\n" @@ -3226,5 +3870,9 @@ "}\n" "set_widgets\n" "\n" +"if {$tray_mode && $client_tail != \"\"} {\n" +" fileevent $client_tail readable read_client_info\n" +"}\n" +"\n" "# main loop.\n" ; diff --git a/x11vnc/x11vnc.1 b/x11vnc/x11vnc.1 index 4719a0a..d5243da 100644 --- a/x11vnc/x11vnc.1 +++ b/x11vnc/x11vnc.1 @@ -1,8 +1,8 @@ .\" This file was automatically generated from x11vnc -help output. -.TH X11VNC "1" "June 2005" "x11vnc " "User Commands" +.TH X11VNC "1" "July 2005" "x11vnc " "User Commands" .SH NAME x11vnc - allow VNC connections to real X11 displays - version: 0.7.2, lastmod: 2005-06-25 + version: 0.7.2, lastmod: 2005-07-01 .SH SYNOPSIS .B x11vnc [OPTION]... @@ -1709,8 +1709,8 @@ up on the X display in the environment variable DISPLAY. .IP "gui-opts" can be a comma separated list of items. Currently there are these types of items: 1) a gui mode, -a 2) gui "simplicity", and 3) the X display the gui -should display on. +a 2) gui "simplicity", 3) the X display the gui +should display on, and 4) a "tray" (or icon) mode. .IP 1) The gui mode can be "start", "conn", or "wait" "start" is the default mode above and is not required. @@ -1734,9 +1734,6 @@ 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 ez" -"x11vnc \fB-gui\fR localhost:10", "x11vnc \fB-gui\fR conn,host:0" -.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 @@ -1744,6 +1741,24 @@ 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 +The "tray" mode below reverses this preference. +.IP +4) When "tray" is specified, the gui presents itself +as a small icon with behavior similar to a "system +tray" or "dock" applet. The color of the icon +indicates status (connected clients) and there is also a +balloon status. Clicking on the icon gives a menu from +which properties, etc, can be set and the full gui is +available under "Advanced". To be fully functional, +the gui mode should be "start" (the default). At some +point it is hoped the icon can be automatically embedded +in common destkop trays/docks. Currently one can only +embed it in a window via, e.g., "tray=0x3600028". +Otherwise the icon is just a normal standalone window. +.IP +Examples: "x11vnc \fB-gui",\fR "x11vnc \fB-gui\fR ez" +"x11vnc \fB-gui\fR localhost:10", "x11vnc \fB-gui\fR conn,host:0" +"x11vnc \fB-gui\fR tray,ez" .IP If you do not intend to start x11vnc from the gui (i.e. just remote control an existing one), then the diff --git a/x11vnc/x11vnc.c b/x11vnc/x11vnc.c index dd13bc2..04e02e8 100644 --- a/x11vnc/x11vnc.c +++ b/x11vnc/x11vnc.c @@ -155,7 +155,7 @@ /* * Summary of options to include in CPPFLAGS for custom builds: * - * -DSHARED to have the vnc display shared by default. + * -DVNCSHARED to have the vnc display shared by default. * -DFOREVER to have -forever on by default. * -DNOREPEAT=0 to have -repeat on by default. * -DADDKEYSYMS=0 to have -noadd_keysyms the default. @@ -382,7 +382,7 @@ double xdamage_scheduled_mark = 0.0; sraRegionPtr xdamage_scheduled_mark_region = NULL; /* date +'lastmod: %Y-%m-%d' */ -char lastmod[] = "0.7.2 lastmod: 2005-06-25"; +char lastmod[] = "0.7.2 lastmod: 2005-07-01"; int hack_val = 0; /* X display info */ @@ -792,7 +792,7 @@ char *rc_rcfile = NULL; /* -rc */ int rc_norc = 0; int opts_bg = 0; -#ifndef SHARED +#ifndef VNCSHARED int shared = 0; /* share vnc display. */ #else int shared = 1; @@ -802,6 +802,7 @@ int connect_once = 1; /* disconnect after first connection session. */ #else int connect_once = 0; #endif +int got_connect_once = 0; int deny_all = 0; /* global locking of new clients */ #ifndef REMOTE_DEFAULT #define REMOTE_DEFAULT 1 @@ -841,6 +842,11 @@ int shift_cmap = 0; /* ncells < 256 and needs shift of pixel values */ int force_indexed_color = 0; /* whether to force indexed color for 8bpp */ int launch_gui = 0; /* -gui */ +int tray_mode = 0; /* hack for -gui tray */ +char *tray_mode_file = NULL; +char *tray_mode_params = NULL; +FILE *tray_mode_fh = NULL; + int use_modifier_tweak = 1; /* use the shift/altgr modifier tweak */ int use_iso_level3 = 0; /* ISO_Level3_Shift instead of Mode_switch */ int clear_mods = 0; /* -clear_mods (1) and -clear_keys (2) */ @@ -1055,6 +1061,8 @@ int waitms = 30; double wait_ui = 2.0; int wait_bog = 1; int defer_update = 30; /* deferUpdateTime ms to wait before sends. */ +int got_defer = 0; +int got_deferupdate = 0; int screen_blank = 60; /* number of seconds of no activity to throttle */ /* down the screen polls. zero to disable. */ @@ -4885,12 +4893,29 @@ void clean_shm(int quick) { } } +void clean_tray_mode(void) { + if (tray_mode && tray_mode_fh) { + fprintf(tray_mode_fh, "quit\n"); + fflush(tray_mode_fh); + fclose(tray_mode_fh); + tray_mode_fh = NULL; + if (tray_mode_file) { + unlink(tray_mode_file); + tray_mode_file = NULL; + } + } +} + /* * Normal exiting */ void clean_up_exit (int ret) { exit_flag = 1; + if (tray_mode) { + clean_tray_mode(); + } + /* remove the shm areas: */ clean_shm(0); @@ -5147,6 +5172,9 @@ void interrupted (int sig) { X_UNLOCK; + if (tray_mode) { + clean_tray_mode(); + } /* remove the shm areas with quick=1: */ clean_shm(1); @@ -6605,6 +6633,7 @@ void read_vnc_connect_prop(void) { int format, slen, dlen; unsigned long nitems = 0, bytes_after = 0; unsigned char* data = NULL; + int db = 1; vnc_connect_str[0] = '\0'; slen = 0; @@ -6637,7 +6666,12 @@ void read_vnc_connect_prop(void) { } while (bytes_after > 0); vnc_connect_str[VNC_CONNECT_MAX] = '\0'; - if (strlen(vnc_connect_str) > 38) { + if (! db) { + ; + } else if (strstr(vnc_connect_str, "cmd=") && + strstr(vnc_connect_str, "passwd")) { + rfbLog("read VNC_CONNECT\n"); + } else if (strlen(vnc_connect_str) > 38) { char trim[100]; trim[0] = '\0'; strncat(trim, vnc_connect_str, 38); @@ -6796,10 +6830,15 @@ void check_new_clients(void) { } last_count = client_count; - if (! client_count) { + + if (! screen) { return; } - if (! screen) { + if (! client_count) { + if (tray_mode_fh) { + fprintf(tray_mode_fh, "none\n"); + fflush(tray_mode_fh); + } return; } @@ -6828,6 +6867,13 @@ void check_new_clients(void) { } } rfbReleaseClientIterator(iter); + + if (tray_mode_fh) { + char *str = list_clients(); + fprintf(tray_mode_fh, "%s\n", str); + fflush(tray_mode_fh); + free(str); + } } /* -- keyboard.c -- */ @@ -7530,6 +7576,58 @@ static int kc1_shift, kc1_control, kc1_caplock, kc1_alt; static int kc1_meta, kc1_numlock, kc1_super, kc1_hyper; static int kc1_mode_switch, kc1_iso_level3_shift, kc1_multi_key; +int sloppy_key_check(int key, rfbBool down, rfbKeySym keysym, int *new) { + if (!sloppy_keys) { + return 0; + } + + if (!down && !keycode_state[key] && !IsModifierKey(keysym)) { + int i, cnt = 0, downkey; + int nmods_down = track_mod_state(NoSymbol, FALSE, FALSE); + int mods_down[256]; + + if (nmods_down) { + /* tracking to skip down modifier keycodes. */ + for(i=0; i<256; i++) { + mods_down[i] = 0; + } + i = 0; + while (simple_mods[i] != NoSymbol) { + KeySym ksym = simple_mods[i]; + KeyCode k = XKeysymToKeycode(dpy, ksym); + if (k != NoSymbol && keycode_state[(int) k]) { + mods_down[(int) k] = 1; + } + + i++; + } + } + /* + * the keycode is already up... look for a single one + * (non modifier) that is down + */ + for (i=0; i<256; i++) { + if (keycode_state[i]) { + if (nmods_down && mods_down[i]) { + continue; + } + cnt++; + downkey = i; + } + } + if (cnt == 1) { + if (debug_keyboard) { + fprintf(stderr, " sloppy_keys: %d/0x%x " + "-> %d/0x%x (nmods: %d)\n", (int) key, + (int) key, downkey, downkey, nmods_down); + } + *new = downkey; + return 1; + } + } + return 0; +} + #if !LIBVNCSERVER_HAVE_XKEYBOARD /* empty functions for no xkb */ @@ -8119,58 +8217,6 @@ xkbmodifiers[] For the KeySym bound to this (keycode,group,level) store } } -int sloppy_key_check(int key, rfbBool down, rfbKeySym keysym, int *new) { - if (!sloppy_keys) { - return 0; - } - - if (!down && !keycode_state[key] && !IsModifierKey(keysym)) { - int i, cnt = 0, downkey; - int nmods_down = track_mod_state(NoSymbol, FALSE, FALSE); - int mods_down[256]; - - if (nmods_down) { - /* tracking to skip down modifier keycodes. */ - for(i=0; i<256; i++) { - mods_down[i] = 0; - } - i = 0; - while (simple_mods[i] != NoSymbol) { - KeySym ksym = simple_mods[i]; - KeyCode k = XKeysymToKeycode(dpy, ksym); - if (k != NoSymbol && keycode_state[(int) k]) { - mods_down[(int) k] = 1; - } - - i++; - } - } - /* - * the keycode is already up... look for a single one - * (non modifier) that is down - */ - for (i=0; i<256; i++) { - if (keycode_state[i]) { - if (nmods_down && mods_down[i]) { - continue; - } - cnt++; - downkey = i; - } - } - if (cnt == 1) { - if (debug_keyboard) { - fprintf(stderr, " sloppy_keys: %d/0x%x " - "-> %d/0x%x (nmods: %d)\n", (int) key, - (int) key, downkey, downkey, nmods_down); - } - *new = downkey; - return 1; - } - } - return 0; -} - /* * Called on user keyboard input. Try to solve the reverse mapping * problem: KeySym (from VNC client) => KeyCode(s) to press to generate @@ -12459,6 +12505,12 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto done; } + /* allow var=val usage */ + if (!strchr(p, ':')) { + char *q = strchr(p, '='); + if (q) *q = ':'; + } + /* always call like: COLON_CHECK("foobar:") */ #define COLON_CHECK(str) \ if (strstr(p, str) != p) { \ @@ -13168,16 +13220,26 @@ char *process_remote_cmd(char *cmd, int stringonly) { host_lookup = 0; } else if (strstr(p, "accept") == p) { + int doit = 1; COLON_CHECK("accept:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(accept_cmd)); goto qry; } + p += strlen("accept:"); if (safe_remote_only) { - rfbLog("unsafe: %s\n", p); - } else { - p += strlen("accept:"); + if (tray_mode && !strcmp(p, "")) { + ; + } else if (tray_mode && !strcmp(p, "popup")) { + ; + } else { + rfbLog("unsafe: %s\n", p); + doit = 0; + } + } + + if (doit) { if (accept_cmd) free(accept_cmd); accept_cmd = strdup(p); } @@ -14640,6 +14702,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { if (d < 0) d = 0; rfbLog("remote_cmd: setting defer to %d ms.\n", d); screen->deferUpdateTime = d; + got_defer = 1; } else if (strstr(p, "defer") == p) { int d; @@ -14653,8 +14716,8 @@ char *process_remote_cmd(char *cmd, int stringonly) { d = atoi(p); if (d < 0) d = 0; rfbLog("remote_cmd: setting defer to %d ms.\n", d); - /* XXX not part of API? */ screen->deferUpdateTime = d; + got_defer = 1; } else if (strstr(p, "wait_ui") == p) { double w; @@ -15185,6 +15248,57 @@ char *process_remote_cmd(char *cmd, int stringonly) { rfbLog("remote_cmd: disabling remote commands.\n"); accept_remote_cmds = 0; /* cannot be turned back on. */ + } else if (tray_mode && !query && strstr(p, "passwd") == p) { /* skip-cmd-list */ + char **passwds_new = (char **) malloc(3*sizeof(char *)); + char **passwds_old = (char **) screen->authPasswdData; + + COLON_CHECK("passwd:") + p += strlen("passwd:"); + + passwds_new[0] = strdup(p); + + if (screen->authPasswdData && + screen->passwordCheck == rfbCheckPasswordByList) { + passwds_new[1] = passwds_old[1]; + } else { + passwds_new[1] = NULL; + screen->passwordCheck = rfbCheckPasswordByList; + } + passwds_new[2] = NULL; + + screen->authPasswdData = (void*) passwds_new; + if (*p == '\0') { + screen->authPasswdData = (void*) NULL; + } + rfbLog("remote_cmd: changed full access passwd.\n"); + + } else if (tray_mode && !query && strstr(p, "viewpasswd") == p) { /* skip-cmd-list */ + char **passwds_new = (char **) malloc(3*sizeof(char *)); + char **passwds_old = (char **) screen->authPasswdData; + + COLON_CHECK("viewpasswd:") + p += strlen("viewpasswd:"); + + passwds_new[1] = strdup(p); + + if (screen->authPasswdData && + screen->passwordCheck == rfbCheckPasswordByList) { + passwds_new[0] = passwds_old[0]; + } else { + char *tmp = (char *) malloc(4 + CHALLENGESIZE); + rfbRandomBytes((unsigned char*)tmp); + passwds_new[0] = tmp; + screen->passwordCheck = rfbCheckPasswordByList; + } + passwds_new[2] = NULL; + + if (*p == '\0') { + passwds_new[1] = NULL; + } + + screen->authPasswdData = (void*) passwds_new; + rfbLog("remote_cmd: changed view only passwd.\n"); + } else if (query) { /* read-only variables that can only be queried: */ @@ -19338,13 +19452,11 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { if (shared) { screen->alwaysShared = TRUE; } else { - screen->dontDisconnect = TRUE; screen->neverShared = TRUE; } + screen->dontDisconnect = TRUE; } - /* XXX the following is based on libvncserver defaults. */ - if (screen->deferUpdateTime == 5) { - /* XXX will be fixed someday */ + if (! got_deferupdate) { screen->deferUpdateTime = defer_update; } @@ -23137,6 +23249,13 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, int simple_gui, if (simple_gui) { set_env("X11VNC_SIMPLE_GUI", "1"); } + if (tray_mode && tray_mode_file) { + set_env("X11VNC_TRAY_MODE", "1"); + set_env("X11VNC_CLIENT_FILE", tray_mode_file); + if (tray_mode_params) { + set_env("X11VNC_TRAY_EMBED_ID", tray_mode_params); + } + } if (no_external_cmds) { fprintf(stderr, "cannot run external commands in -nocmds " @@ -23147,10 +23266,15 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, int simple_gui, exit(1); } - sprintf(cmd, "%s -", wish); tmpf = tmpfile(); if (tmpf == NULL) { /* if no tmpfile, use a pipe */ + if (tray_mode_params) { + if (strlen(tray_mode_params) < 20) { + strcat(cmd, " -use "); + strcat(cmd, tray_mode_params); + } + } pipe = popen(cmd, "w"); if (! pipe) { fprintf(stderr, "could not run: %s\n", cmd); @@ -23170,7 +23294,12 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, int simple_gui, rewind(tmpf); dup2(n, 0); close(n); - execlp(wish, wish, "-", (char *) NULL); + if (tray_mode_params) { + execlp(wish, wish, "-", "-use", tray_mode_params, + (char *) NULL); + } else { + execlp(wish, wish, "-", (char *) NULL); + } fprintf(stderr, "could not exec wish: %s -\n", wish); perror("execlp"); } @@ -23181,6 +23310,7 @@ void do_gui(char *opts) { char *s, *p; char *old_xauth = NULL; char *gui_xdisplay = NULL; + int got_gui_xdisplay = 0; int start_x11vnc = 1; int connect_to_x11vnc = 0; int simple_gui = 0; @@ -23209,7 +23339,11 @@ void do_gui(char *opts) { ; } else if (strchr(p, ':') != NULL) { /* best */ + if (gui_xdisplay) { + free(gui_xdisplay); + } gui_xdisplay = strdup(p); + got_gui_xdisplay = 1; } else if (!strcmp(p, "wait")) { start_x11vnc = 0; connect_to_x11vnc = 0; @@ -23218,6 +23352,12 @@ void do_gui(char *opts) { connect_to_x11vnc = 1; } else if (!strcmp(p, "ez") || !strcmp(p, "simple")) { simple_gui = 1; + } else if (strstr(p, "tray") || strstr(p, "icon")) { + char *q; + tray_mode = 1; + if ((q = strchr(p, '=')) != NULL) { + tray_mode_params = strdup(q+1); + } } else { fprintf(stderr, "unrecognized gui opt: %s\n", p); } @@ -23229,6 +23369,16 @@ void do_gui(char *opts) { connect_to_x11vnc = 1; } + if (tray_mode && !got_gui_xdisplay) { + /* for tray mode, prefer the polled DISPLAY */ + if (use_dpy) { + if (gui_xdisplay) { + free(gui_xdisplay); + } + gui_xdisplay = strdup(use_dpy); + } + } + if (! gui_xdisplay) { fprintf(stderr, "error: cannot determine X DISPLAY for gui" " to display on.\n"); @@ -23257,10 +23407,37 @@ void do_gui(char *opts) { XCloseDisplay(test_dpy); if (start_x11vnc) { + #if LIBVNCSERVER_HAVE_FORK /* fork into the background now */ int p; pid_t parent = getpid(); + + if (tray_mode) { + char tf[100]; + struct stat sbuf; + /* FIXME */ + sprintf(tf, "/tmp/x11vnc.tray.%d", (int) getpid()); + unlink(tf); + if (stat(tf, &sbuf) == 0) { + tray_mode = 0; + } else { + tray_mode_fh = fopen(tf, "w"); + if (! tray_mode_fh) { + tray_mode = 0; + } else { + chmod(tf, 0600); + tray_mode_file = strdup(tf); + fprintf(tray_mode_fh, "none\n"); + fflush(tray_mode_fh); + if (! got_connect_once) { + /* want -forever for tray */ + connect_once = 0; + } + } + } + } + if ((p = fork()) > 0) { ; /* parent */ } else if (p == -1) { @@ -29856,8 +30033,8 @@ static void print_help(int mode) { "\n" " \"gui-opts\" can be a comma separated list of items.\n" " Currently there are these types of items: 1) a gui mode,\n" -" a 2) gui \"simplicity\", and 3) the X display the gui\n" -" should display on.\n" +" a 2) gui \"simplicity\", 3) the X display the gui\n" +" should display on, and 4) a \"tray\" (or icon) mode.\n" "\n" " 1) The gui mode can be \"start\", \"conn\", or \"wait\"\n" " \"start\" is the default mode above and is not required.\n" @@ -29881,9 +30058,6 @@ static void print_help(int mode) { " the gui to come back to you via your ssh redirected X\n" " display (e.g. localhost:10).\n" "\n" -" Examples: \"x11vnc -gui\", \"x11vnc -gui ez\"\n" -" \"x11vnc -gui localhost:10\", \"x11vnc -gui conn,host:0\"\n" -"\n" " If you do not specify a gui X display in \"gui-opts\"\n" " then the DISPLAY environment variable and -display\n" " option are tried (in that order). Regarding the x11vnc\n" @@ -29891,6 +30065,24 @@ static void print_help(int mode) { " tries -display and then DISPLAY. For example, \"x11vnc\n" " -display :0 -gui otherhost:0\", will remote control an\n" " x11vnc polling :0 and display the gui on otherhost:0\n" +" The \"tray\" mode below reverses this preference.\n" +"\n" +" 4) When \"tray\" is specified, the gui presents itself\n" +" as a small icon with behavior similar to a \"system\n" +" tray\" or \"dock\" applet. The color of the icon\n" +" indicates status (connected clients) and there is also a\n" +" balloon status. Clicking on the icon gives a menu from\n" +" which properties, etc, can be set and the full gui is\n" +" available under \"Advanced\". To be fully functional,\n" +" the gui mode should be \"start\" (the default). At some\n" +" point it is hoped the icon can be automatically embedded\n" +" in common destkop trays/docks. Currently one can only\n" +" embed it in a window via, e.g., \"tray=0x3600028\".\n" +" Otherwise the icon is just a normal standalone window.\n" +"\n" +" Examples: \"x11vnc -gui\", \"x11vnc -gui ez\"\n" +" \"x11vnc -gui localhost:10\", \"x11vnc -gui conn,host:0\"\n" +" \"x11vnc -gui tray,ez\"\n" "\n" " If you do not intend to start x11vnc from the gui\n" " (i.e. just remote control an existing one), then the\n" @@ -30829,7 +31021,7 @@ int main(int argc, char* argv[]) { int pw_loc = -1, got_passwd = 0, got_rfbauth = 0; int vpw_loc = -1; int dt = 0, bg = 0; - int got_rfbwait = 0, got_deferupdate = 0, got_defer = 0; + int got_rfbwait = 0; int got_httpdir = 0, try_http = 0; /* used to pass args we do not know about to rfbGetScreen(): */ @@ -30954,6 +31146,7 @@ int main(int argc, char* argv[]) { shared = 1; } else if (!strcmp(arg, "-once")) { connect_once = 1; + got_connect_once = 1; } else if (!strcmp(arg, "-many") || !strcmp(arg, "-forever")) { connect_once = 0; } else if (!strcmp(arg, "-timeout")) { @@ -31376,12 +31569,33 @@ int main(int argc, char* argv[]) { } } else if (!strcmp(arg, "-remote") || !strcmp(arg, "-R") || !strcmp(arg, "-r") || !strcmp(arg, "-remote-control")) { + char *str; CHECK_ARGC i++; - if (!strcmp(argv[i], "ping")) { - query_cmd = strdup(argv[i]); + str = argv[i]; + if (*str == '-') { + /* accidental leading '-' */ + str++; + } + if (!strcmp(str, "ping")) { + query_cmd = strdup(str); } else { - remote_cmd = strdup(argv[i]); + remote_cmd = strdup(str); + } + if (remote_cmd && strchr(remote_cmd, ':') == NULL) { + /* interpret -R -scale 3/4 at least */ + if (i < argc-1 && *(argv[i+1]) != '-') { + int n; + + /* it must be the parameter value */ + i++; + n = strlen(remote_cmd) + strlen(argv[i]) + 2; + + str = (char *) malloc(n); + sprintf(str, "%s:%s", remote_cmd, argv[i]); + free(remote_cmd); + remote_cmd = str; + } } quiet = 1; xkbcompat = 0; @@ -31713,7 +31927,6 @@ int main(int argc, char* argv[]) { } if (! got_deferupdate) { char tmp[40]; - /* XXX not working yet in libvncserver */ sprintf(tmp, "%d", defer_update); argv_vnc[argc_vnc++] = strdup("-deferupdate"); argv_vnc[argc_vnc++] = strdup(tmp); |