blob: c87d7530b64f7a284ebd6e2fb30ead53b69623ad [file] [log] [blame]
San Mehata430b2b2014-09-23 08:30:51 -07001#!/bin/sh
2# the next line restarts using wish. \
3exec wish "$0" "$@"
4catch {rename send {}}
5#
6# Copyright (C) 2004-2009 Karl J. Runge <runge@karlrunge.com>
7# All rights reserved.
8#
9# This is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This software is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this software; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
22# USA.
23
24#
25# tkx11vnc v0.2
26# This is a simple frontend to x11vnc. It uses the remote control
27# and query features (-remote/-query aka -R/-Q) to interact with it.
28# It is just a quick-n-dirty hack (it parses -help output, etc), but
29# it could be of use playing with or learning about the (way too) many
30# parameters x11vnc has.
31#
32# It can be used to interact with a running x11vnc (see the x11vnc
33# -gui option), or to set the parameters and then start up x11vnc.
34#
35
36#
37# Below is a simple picture of how the gui should be laid out and how
38# the menus should be organized. Most menu items correspond to remote
39# control commands. A trailing ":" after the item name means it is a string
40# to be set rather than a boolean that can be toggled (e.g. the entry
41# box must be used).
42#
43# Some tweak options may be set in the prefix "=" string.
44# A means it is an "Action" (not a true variable)
45# R means it is an action only valid in remote mode.
46# S means it is an action only valid in startup mode.
47# Q means it is an action worth querying after running.
48# P means the string can be +/- appended/deleted (string may not
49# be the same after the remote command)
50# G means gui internal item
51# F means can be set via file browse
52# D means for simple gui
53# -C:val1,... means it will be a checkbox (radio button)
54# the "-" means no other options follow
55# 0 means to skip the item.
56# -- means add a separator
57#
58# The =GAL ... =GAL LOFF stuff is to provide submenus.
59#
60
61global env started time_count
62set started ""
63proc dtime {{msg ""}} {
64 global started time_count
65 if {$started == ""} {
66 return
67 }
68 set diff [expr "[exec gtod.bin] - $started"]
69 set diff [format "%.2f" $diff]
70 incr time_count
71 if {$msg == ""} {
72 set msg $time_count
73 }
74 puts -nonewline stderr "$msg $diff "
75 puts stderr [clock format [clock seconds]]
76}
77
78if [info exists env(X11VNC_GUI_TIME)] {
79 global started time_count
80 set started [exec gtod.bin]
81 set time_count 0
82 dtime "S"
83}
84
85proc set_template {} {
86 global template
87 set template "
88Row: Actions Clients Permissions Keyboard Pointer Help
89Row: Displays Screen Tuning Debugging Misc
90
91Actions
92 =SA start
93 =RA stop
94 --
95 =DSA attach
96 =DRA detach
97 --
98 =RA ping
99 =RA update-all
100 =GAL Settings::
101 =GA save-settings
102 =SFA load-settings:
103 =SA defaults-all
104 =0SA clear-all
105 --
106 =F rc:
107 norc
108 =GAL LOFF
109 -- D
110 =DRA stop+quit
111 =DGA Quit
112
113Help
114 =DGA gui
115 =DGA all
116
117Clients
118 =DRQA current:
119 =DF connect:
120 =DRQA disconnect:
121 --
122 accept:
123 afteraccept:
124 gone:
125 vncconnect
126 zeroconf
127 -- D
128 tightfilexfer
129 ultrafilexfer
130 proxy:
131 =GAL Chat::
132 chatwindow
133 =DRA chaton
134 =DRA chatoff
135 =GAL LOFF
136 =GAL Java-applet::
137 =D http
138 httpdir:
139 httpport:
140 https:
141 httpsredir:
142 enablehttpproxy
143 =GAL LOFF
144
145Displays
146 =D display:
147 =F auth:
148 =S reflect:
149 =D desktop:
150 =D rfbport:
151 =S autoport:
152 =0 gui:
153
154Screen
155 =DRA refresh
156 =RA reset
157 =RA blacken
158 -- D
159 =D scale:
160 scale_cursor:
161 --
162 =D solid
163 solid_color:
164 --
165 =GAL OverlayVisuals::
166 overlay
167 overlay_nocursor
168 8to24
169 8to24_opts:
170 =GAL LOFF
171 =GAL 8-Bit-Color::
172 flashcmap
173 shiftcmap:
174 notruecolor
175 =GAL LOFF
176 =GAL SubWindow::
177 id:
178 sid:
179 =RA id_cmd:
180 =GAL LOFF
181 =GAL ResizeRotate::
182 = xrandr
183 =-C:resize,newfbsize,exit xrandr_mode:
184 rotate:
185 padgeom:
186 =GAL LOFF
187 =GAL Clipping::
188 =P blackout:
189 xinerama
190 clip:
191 =GAL LOFF
192 =GAL Misc-Screen::
193 fixscreen:
194 visual:
195 rawfb:
196 pipeinput:
197 uinput_accel:
198 uinput_reset:
199 uinput_always:
200 24to32
201 =GAL LOFF
202
203Keyboard
204 =D norepeat
205 =D add_keysyms
206 modtweak
207 xkb
208 --
209 capslock
210 skip_lockkeys
211 --
212 skip_keycodes:
213 skip_dups
214 sloppy_keys
215 --
216 =FP remap:
217 clear_mods
218 clear_keys
219 clear_all
220 =RA clear_locks
221
222Pointer
223 =D-C:none,arrow,X,some,most cursor:
224 =-C:1,2,3,4,5,6 arrow:
225 --
226 cursorpos
227 =D nocursorshape
228 --
229 noxfixes
230 cursor_drag
231 =GAL AlphaBlending::
232 noalphablend
233 alphacut:
234 alphafrac:
235 alpharemove
236 =GAL LOFF
237 --
238 buttonmap:
239 --
240 xwarppointer
241 always_inject
242
243Misc
244 =GD-C:full,icon,tray WindowView:
245 =GD simple-gui
246 -- D
247 =GA all-settings
248 =RA remote-cmd:
249 =GAL Selection::
250 =D nosel
251 noprimary
252 nosetprimary
253 noclipboard
254 nosetclipboard
255 seldir:
256 =GAL LOFF
257 =GAL X-ext::
258 xtrap
259 noxrecord
260 =RQA reset_record
261 =GAL LOFF
262 =GAL MacOSX::
263 macnosaver
264 macnowait
265 macwheel:
266 macnoswap
267 macnoresize
268 maciconanim:
269 macmenu
270 =GAL LOFF
271 --
272 6
273 noipv6
274 noipv4
275 --
276 nofb
277 =D nobell
278 nolookup
279 rfbversion:
280 bg
281 =S loop
282 =S loopbg
283 =S sleepin:
284 =-C:ignore,exit sigpipe:
285 =0 inetd
286
287Debugging
288 debug_pointer
289 debug_keyboard
290 =F logfile:
291 =GA show-logfile
292 =GA tail-logfile
293 quiet
294 --
295 =GA show-start-cmd
296 =DG debug_gui
297 =GAL Misc-Debug::
298 debug_xevents
299 debug_xdamage
300 =-C:0,1,2,3 debug_wireframe:
301 debug_scroll
302 debug_tiles
303 debug_grabs
304 debug_sel
305 debug_ncache
306 dbg
307 =GAL LOFF
308
309Permissions
310 =DRQA lock
311 =DRQA unlock
312 =D shared
313 =D forever
314 --
315 =DFP allow:
316 =D localhost
317 =RA allowonce:
318 listen:
319 -- D
320 =D viewonly
321 input:
322 --
323 =GAL Passwords::
324 passwd:
325 viewpasswd:
326 =F passwdfile:
327 =F rfbauth:
328 usepw
329 --
330 unixpw
331 unixpw_list:
332 unixpw_nis
333 unixpw_nis_list:
334 =0 storepasswd
335 =GAL LOFF
336 =GAL SSL::
337 ssl
338 =F ssl_pem:
339 stunnel
340 =F stunnel_pem:
341 =F ssldir:
342 =F sslverify:
343 ssltimeout:
344 --
345 enc:
346 =GAL LOFF
347 =GAL Misc-Perms::
348 safer
349 unsafe
350 =RA noremote
351 =0S alwaysshared
352 =0S nevershared
353 =0S dontdisconnect
354 =SQA deny_all
355 timeout:
356 grabkbd
357 grabptr
358 grabalways
359 grablocal:
360 forcedpms
361 clientdpms
362 noserverdpms
363 noultraext
364 =GAL LOFF
365
366Tuning
367 =D-C:0,1,2,3,4 pointer_mode:
368 input_skip:
369 allinput
370 =D nodragging
371 -- D
372 speeds:
373 =D wait:
374 defer:
375 =D nap
376 screen_blank:
377 --
378 =GAL WireFrame::
379 wireframe
380 wireframe_mode:
381 =-C:never,top,always wirecopyrect:
382 =GAL LOFF
383 =GAL ScrollCopyRect::
384 =-C:never,keys,mouse,always scrollcopyrect:
385 scr_area:
386 scr_skip:
387 scr_inc:
388 scr_keys:
389 scr_term:
390 scr_keyrepeat:
391 scr_parms:
392 =GAL LOFF
393 =GAL XDAMAGE::
394 xdamage
395 xd_area:
396 xd_mem:
397 =GAL LOFF
398 =GAL Ncache::
399 ncache
400 ncache_size:
401 ncache_cr
402 ncache_no_moveraise
403 ncache_no_dtchange
404 ncache_old_wm
405 ncache_no_rootpixmap
406 ncache_keep_anims
407 ncache_pad:
408 =RA ncache_reset_rootpixmap
409 =GAL LOFF
410 --
411 =GAL SharedMemory::
412 noshm
413 flipbyteorder
414 onetile
415 =GAL LOFF
416 =GAL Misc-Tuning::
417 progressive:
418 fs:
419 gaps:
420 grow:
421 fuzz:
422 extra_fbur:
423 wait_ui:
424 setdefer:
425 nowait_bog
426 slow_fb:
427 xrefresh:
428 readtimeout:
429 snapfb
430 threads
431 wmdt:
432 rfbwait:
433 nodpms
434 nofbpm
435 =GAL LOFF
436"
437}
438
439proc set_internal_help {} {
440 global helptext helpall
441
442 # set some internal item help here:
443 set helptext(start) "
444Launch x11vnc with the settings you have prescribed in the gui.
445The x11vnc process is started in an xterm window so you can see the
446output, kill it, etc.
447
448By viewing this help item, the command built so far will be displayed
449in the gui text area. Have a look. If you Press start it will be shown
450as well and you will be asked to confirm running it.
451
452If you want to use a saved profile \"rc file\" you can do \"Misc -> rc\" and
453select the file and simply start x11vnc using the rc file. Alternatively,
454you could first use the \"Actions -> load-settings\" action to load in
455an \"rc file\" and then press \"Actions -> start\" to start up x11vnc
456based on those values.
457"
458 set helptext(stop) "
459The \"Actions -> stop\" action sends a signal to the running x11vnc
460server indicating it should shutdown all connections and exit.
461
462The GUI stays running in case you want to start a new x11vnc or attach
463to another one. Use \"Actions -> Quit\" if you then want to have the
464gui exit. Use \"Actions -> stop+quit\" to have both exit at once.
465"
466
467 set helptext(show-start-cmd) "
468Displays in the text area what the x11vnc start command (i.e. the command
469run by \"Actions -> start\") looks like for the current values of the
470settings. This can be done even in the attached state. Intended for
471debugging the gui. The help item for \"Actions -> start\" gives the
472same info.
473
474If you want to load in a saved profile \"rc file\" use \"Misc -> rc\"
475and select the file. \"Actions -> load-settings\" does a similar thing
476with an rc-file, but reading the file and setting the gui variables to
477its values.
478"
479
480 set helptext(debug_gui) "
481Set debug_gui to get more output printed in the text area.
482"
483
484 set helptext(detach) "
485No longer be associated with the x11vnc server. Switch to the
486non-connected state. The x11vnc server keeps running: it does not exit.
487
488You can either later reattach to it \"Actions -> attach\", or start
489up a new x11vnc \"Actions -> start\", or exit \"Actions -> Quit\".
490"
491
492 set helptext(attach) "
493Attach to a running x11vnc server, if possible. Switches to connected
494state if successful. Usually the channel used to attach is via the X
495display (VNC_CONNECT rootwin property) being polled by the x11vnc server.
496To change or set the X display to use do \"Displays -> display\".
497
498Sometimes the \"-connect /path/to/filename\" is used as the communcation
499channel. The running x11vnc has to know that \"/path/to/filename\"
500is the communication channel (i.e. it is using the same -connect option).
501"
502
503 set helptext(ping) "
504Check if x11vnc still responds to \"ping\" remote command.
505"
506
507 set helptext(update-all) "
508Query the x11vnc server for the current values of all variables.
509Populate the values into the gui's database.
510
511Normally the gui will refresh this info every time it interacts with
512the x11vnc server (including after a few minutes of inactivity), so one
513doesn't need to use this action very often (unless something else is
514changing the state of the x11vnc server, or new clients have connected,
515etc).
516"
517
518 set helptext(clear-all) "
519Forget any variable settings either entered in by you or set at the
520default. Basically sets everything to 0 or the string (unset).
521
522This action is only available in \"startup\" mode, not when connected
523to a running x11vnc server (in that case the variable settings reflect
524the state of the running x11vnc). To detach from a running x11vnc
525server use \"Actions -> detach\"; to completely stop the x11vnc server
526use \"Actions -> stop\".
527"
528
529 set helptext(defaults-all) "
530Reset all variable settings to the default values. Basically sets
531everything to the default queries \"x11vnc -QD var\" retrieved at startup.
532
533This action is only available in \"startup\" mode, not when connected
534to a running x11vnc server (in that case the variable settings reflect
535the state of the running x11vnc). To detach from a running x11vnc
536server use \"Actions -> detach\"; to completely stop the x11vnc server
537use \"Actions -> stop\".
538"
539
540 set helptext(load-settings) "
541Read in the \"rc file\" you prescribe in the dialog and then set the
542variables to those in the rc-file. Any variables not mentioned in the
543rc-file are set to their default value.
544
545You could then do \"Actions -> start\" to start x11vnc with these
546parameters. Or you could make some further changes to variables
547using the gui before starting x11vnc.
548
549This action is only available in \"startup\" mode, not when connected
550to a running x11vnc server (in that case the variable settings reflect
551the state of the running x11vnc). To detach from a running x11vnc
552server use \"Actions -> detach\"; to completely stop the x11vnc server
553use \"Actions -> stop\".
554"
555
556 set helptext(save-settings) "
557Construct a ~/.x11vncrc file based on the current settings and
558offer to save it in a file (default ~/.x11vncrc). If saved in a
559file other than the default, you can access the profile by using
560the \"-rc <filename>\" option when starting x11vnc.
561
562If an rc file entry begins with \"#d\" that means the current
563setting is at the Default value and so you probably want to leave
564it commented out with the \"#\" character.
565
566If an rc file entry begins with \"#?\" that means we think
567you probably do not really want to force the value to this setting.
568
569In either case, feel free to uncomment the line and/or change any
570of the parameter values in the file.
571"
572
573 set helptext(all-settings) "
574Displays the gui's database of all of the x11vnc server's current
575settings. Use \"Actions -> update-all\" or \"Control+R\" to
576refresh this list if it ever gets out of sync.
577"
578
579 set helptext(remote-cmd) "
580Run a remote command (-R) or query (-Q) directly. Only a few
581remote commands are not on a menu, but for those few you can
582run the command directly this way. Just enter the command into
583the Entry box when prompted. Use the prefix \"Q:\" to indicate
584a -Q query. Examples: \"zero:20,20,100,100\", \"Q:ext_xfixes\"
585"
586
587 set helptext(stop+quit) "
588Send the stop command to the x11vnc server, then terminate the tkx11vnc gui.
589"
590
591 set helptext(show-logfile) "
592View the current contents of the logfile (if it exists and is accessible
593by the gui process).
594"
595
596 set helptext(tail-logfile) "
597Run the tail(1) command with -f option on the logfile in an xterm.
598(if it exists and is accessible by the gui process).
599"
600
601 set helptext(Quit) "
602Terminate the tkx11vnc gui. Any x11vnc server will be left running.
603"
604
605 set helptext(current) "
606Shows a menu of currently connected VNC clients on the x11vnc server.
607
608Allows you to find more information about them, change their input
609permissions, or disconnect them.
610
611Note that the File transfer permission only applies to UltraVNC
612file transfer, not TightVNC file transfer.
613
614You will be prompted to confirm any disconnections.
615"
616
617 set helptext(client) "
618After selecting a VNC client from the \"Clients -> current\" menu,
619you will be presented with a dialog that shows the information
620about the VNC client.
621
622You can choose to disconnect the client by clicking on the
623\"Disconnect\" checkbox and pressing \"OK\". There will be a
624confirmation dialog to doublecheck.
625
626Alternatively, you can fine tune the VNC client's input permissions
627by selecting any of the Keystrokes, Mouse-Motion, Button-Click,
628Clipboard-Input, or Files checkboxes and pressing \"OK\". This is like
629the \"-input\" option but on a per-client basis.
630
631To not change any aspects of the VNC client press \"Cancel\".
632"
633
634 set helptext(solid_color) "
635Set the -solid color value.
636"
637
638 set helptext(xrandr_mode) "
639Set the -xrandr mode value.
640"
641
642 set helptext(unixpw_list) "
643Set the -unixpw usernames list value.
644"
645
646 set helptext(unixpw_nis_list) "
647Set the -unixpw_nis usernames list value.
648"
649
650 set helptext(stunnel_pem) "
651Set the -stunnel pem filename value.
652"
653
654 set helptext(ssl_pem) "
655Set the -ssl pem filename value.
656"
657
658 set helptext(wireframe_mode) "
659Set the -wireframe mode string value.
660"
661
662 set helptext(simple-gui) "
663Toggle between menu items corresponding the most basic ones
664and all possible settings. I.e. toggle between a simple gui
665and one for power users.
666"
667
668 set helptext(Tray) "
669The tray/icon mode (started with \"x11vnc -gui tray ...\", etc.) presents
670a small icon that indicates the status of the running x11vnc server.
671
672Depending on your environment, this icon may be embedded in a system
673tray or applet dock, or simply be a standalone window. \"-gui tray\"
674will attempt to embed the icon in the system tray, while \"-gui icon\"
675is for a standalone window. Use \"-gui tray=setpass\" (or icon=setpass)
676to be prompted to set the session password at startup.
677
678When the icon has a light background, that means no VNC viewers are
679currently connected to the VNC display.
680
681When the icon has a dark background (i.e. reverse-video), that means at
682least one VNC viewer is connected to the VNC display.
683
684Moving the mouse pointer over the icon will popup a \"status balloon\"
685indicating the VNC display name and the names and info of any connected VNC
686viewers. Press the middle mouse button if the balloon does not appear.
687
688Clicking the left or right mouse button on the icon displays a menu
689of actions:
690
691 Properties - Brings up the Properties dialog to set some basic
692 parameters. The full tkx11vnc GUI may be accessed
693 via the \"Advanced ...\" button. Press \"Help\"
694 in the Properties dialog for more info.
695
696 Help - Displays this help text.
697
698 New Client - Presents an entry box where you type in the name
699 of a computer that is running a VNC viewer in
700 \"listen\" mode (e.g. vncviewer -listen). For a
701 non-standard listening port use \"host:port\".
702
703 Pressing \"OK\" will initiate the reverse
704 connection. Use a blank hostname to skip it.
705
706 Disconnect - Shows a popup menu of connected clients. Click on
707 one to disconnect it, or click on \"All Clients\"
708 disconnect all clients.
709
710 Window View - Switch between the \"full\" gui (also known as
711 \"Advanced\"), \"icon\" mode (small icon window with
712 popups), or \"tray\" mode (small icon embedded in the
713 system tray). This is a shortcut for the action:
714 \"Properties -> Advanced -> Misc -> WindowView\".
715
716 Stop x11vnc - Directs the x11vnc server to disconnect all vncviewers
717 and then exit. The tray/icon GUI then exits as well.
718
719 Logfile - Show the logfile if x11vnc is being run with one.
720
721 Custom - If you have a \$HOME/.x11vnc.gui file each uncommented
722 line in it becomes an additional menu item for this
723 menu. The remote control command is run directly
724 via \"x11vnc -R <command>\", or if prefixed with
725 \"action:\" runs a gui internal action, or if \"sep\"
726 adds a separator. Set X11VNC_CUSTOM_GUI to use
727 a different filename. Example file contents:
728
729 scale:3/4
730 scale:1
731 scale_cursor:1
732 sep
733 action:all-settings
734 #debug_keyboard
735 sep
736 action:Quit
737
738Termination:
739
740If the x11vnc server stops for any reason, the tray/icon gui will exit.
741
742If you delete the tray/icon (e.g. X out button), that is the same
743as the \"Stop x11vnc\" action in the menu. (This will disconnect any
744VNC viewer you are currently using to access the display since the
745x11vnc server is terminated).
746
747To terminate the tray/icon gui window but not the x11vnc server press
748Control-C on the tray/icon window. You can also do this (and much
749more) via Properties -> Advanced -> Actions -> Quit
750"
751
752 set helptext(NewClient) "
753 New Client - Presents an entry box where you type in the name
754 of a computer that is running a VNC viewer in
755 \"listen\" mode (e.g. vncviewer -listen). For a
756 non-standard listening port use \"host:port\".
757
758 Pressing \"OK\" will initiate the reverse
759 connection. Use a blank hostname to skip it, or
760 delete (\"X-out\") the window.
761
762"
763
764 set helptext(Properties) "
765The Properties dialog allows you to set some basic parameters of a
766running x11vnc server. After modifying them press \"OK\" or \"Apply\"
767to apply the changes, or press \"Cancel\" to skip applying them.
768
769 Accept Connections:
770
771 Toggles whether VNC viewers are allowed to connect or not. It corresponds
772 to the \"-R unlock\" and \"-R lock\" remote-control commands.
773
774 Ask for Confirmation:
775
776 Toggles whether a popup menu will be presented at the X display when
777 a new VNC viewer attempts to connect. The person sitting at the X
778 display can choose to accept or reject the connection or accept the
779 connection in ViewOnly mode. It corresponds to the \"-R accept:popup\"
780 and \"-R accept:\" remote-control commands.
781
782 All Clients ViewOnly:
783
784 Toggles whether the entire VNC desktop is view only. All clients
785 will only be able to watch when this is set (regardless of how they
786 logged in). It corresponds to the \"-R viewonly\" and \"-R noviewonly\"
787 remote-control commands.
788
789 Shared:
790
791 Toggles whether multiple simultaneous viewer connections are allowed
792 or not. It corresponds to the \"-R shared\" and \"-R noshared\"
793 remote-control commands.
794
795 Advertise Service (Zeroconf):
796
797 Toggles whether this VNC server should advertize itself via Zeroconf
798 (also called Bonjour, mDNS, and avahi). Then VNC viewers can then find
799 this service on the local network. It corresponds to the \"-R zeroconf\"
800 and \"-R nozeroconf\" remote-control commands.
801
802 Serve Java Viewer Applet:
803
804 Toggles whether this VNC server should serve up a Java VNC Viewer
805 applet via HTTP on http://hostname:5800/ (or port 5800+n for VNC
806 port 5900+n). A java enabled Web Browser can then connect to the
807 desktopby VNC. If SSL is active then the HTTPS URL https://hostname:5900/
808 (etc.) will work as well. This requires the x11vnc java viewer jar file
809 (shared/x11vnc/classes) to be installed. It corresponds to the
810 \"-R http\" and \"-R nohttp\" remote commands.
811
812 Solid Background Color:
813
814 To improve VNC performance, if this option is set, then x11vnc will try
815 to make the desktop background a solid color (which compresses extremely
816 well compared to photo images, etc.) It corresponds to the \"-R solid\"
817 and \"-R nosolid\" remote commands.
818
819 Password:
820
821 Lets you set the session password viewers may use to gain full access
822 to the display. This will only work if x11vnc was started with the
823 -gui icon or -gui tray mode.
824
825 ViewOnly Password:
826
827 Lets you set the session password viewers may use to gain view only
828 access to the display. This will only work if x11vnc was started with
829 the -gui icon or -gui tray mode.
830
831
832 NOTE: These \"session\" passwords only last for the current x11vnc
833 session (they are not remembered, see the -storepasswd, -passwdfile,
834 and -rfbauth x11vnc options for using stored passwords).
835
836 If you set \"Password\" to the empty string that makes the \"ViewOnly
837 Password\" empty as well and removes the need for any password to log in.
838
839 If you set \"ViewOnly Password\" to the empty string that just removes
840 the ViewOnly log in aspect: \"Password\" is still required to log in.
841
842 - The \"Help\" button shows this help text.
843
844 - The \"Advanced ...\" button replaces the Properties dialog with the full
845 tkx11vnc GUI. All dynamic settings can be modified in the full GUI.
846
847
848==========================================================================
849
850Don't Lock Yourself Out:
851
852 If you are sitting at the physical X display you cannot get into too
853 much trouble setting the Properties dialog values.
854
855 However IF you are using a VNC Viewer to REMOTELY access the X display
856 some items in the Properties dialog can lock you out of further access:
857
858 \"Accept Connections\" if you disable this remotely, and
859 accidentally disconnect your VNC viewer then you will not be
860 able to reconnect.
861
862 \"Ask for Confirmation\" if you enable this only someone
863 sitting at the X display can confirm any new VNC connections.
864 Furthermore, any current VNC viewers will be blocked while
865 waiting for the confirmation (times out in 120 sec by default).
866
867 \"All Clients ViewOnly\" if you enable this remotely, well
868 you can no longer provide input to disable it.
869
870 If you do lock yourself out you could log in remotely and start up
871 a second x11vnc and connect to that one to try to fix things in the
872 first one.
873
874 Note that if there are two or more x11vnc's on the same display the
875 use of the GUI may be ill-behaved. Terminate the second x11vnc as
876 soon as you have fixed the setting in the first one. Use of a remote
877 control command, e.g. \"x11vnc -R noviewonly\" or \"x11vnc -R unlock\"
878 is a good way to avoid this problem.
879"
880
881 set helptext(all) $helpall
882
883 set helptext(Misc-Tuning:) "
884x11vnc has what seems like hundreds of tuning parameters! In this
885sub-menu we place some lesser used ones. Most likely you'll want to
886leave them at their default values, but you can try them out quickly
887with the gui to see if they improve things.
888"
889
890 set helptext(Passwords:) "
891The items in this sub-menu pertain to setting passwords. Note that x11vnc
892has two types of password files: RealVNC-style ones (you can create them
893with x11vnc -storepasswd or other VNC utility program) you use these
894via -rfbauth; and plain-text file passwords you use via -passwdfile.
895
896Normally passwords cannot be changed by remote-control (e.g. the gui),
897but for the case of the \"Icon\" and \"Tray\" modes this constraint has
898been relaxed.
899
900In neither the RealVNC-style nor the plain-text file cases should the
901password files be readable by users you do not want to access the VNC
902server. Contrary to popular belief, the RealVNC-style passwords are
903not encrypted, merely obscured.
904
905x11vnc has the even less secure -passwd and -viewpasswd supplied on
906the command line. Be careful with these since they could be read by
907users with something like the ps(1) command. On some operating systems
908x11vnc tries to quickly overwrite them on the command line but it doesn't
909work everywhere.
910
911Regarding ViewOnly passwords (where a VNC client using that password
912can only watch the screen, not interact with it), this is not available
913with -rfbauth, but only with -passwdfile, -passwd, and -viewpasswd.
914"
915
916 set helptext(SSL:) "
917In this sub-menu we provide the options related to SSL encrpytion
918and authentication.
919
920There is a built-in mode (-ssl) using the OpenSSL library, and a 2nd
921using the external stunnel program (-stunnel, that needs to be installed
922on the system). Either may require or benefit from having PEM certificate
923files specified.
924
925"
926
927 set helptext(Misc-Perms:) "
928In this sub-menu we provide some lesser used permission options.
929
930Regarding -alwaysshared, -nevershared, and -dontdisconnect, you probably
931should never use them and just use x11vnc's -shared and -forever options
932instead (these give basically the same functionality and if you mixed
933them too much unexpected things may happen).
934"
935#'
936
937 set helptext(AlphaBlending:) "
938In this sub-menu we provide some tweak parameters for cursors (little
939icon at the mouse pointer) that have transparency (i.e. an Alpha channel
940in addition to Red, Green, and Blue RGB channels). For these cursors,
941some of the graphics underneath the cursor is allowed to be blended in:
942e.g. a drop-shadow (a terrible effect IMNSHO).
943
944AlphaBlending for x11vnc is only available when the XFIXES X extension is
945present (since otherwise it cannot see the cursors at all and so applies
946heuristics to show some fake cursors). AlphaBlending is only a problem
947with x11vnc when the cursors are not opaque.
948
949Opaque cursors (e.g. bitmap or simply colored cursor) are rendered
950correctly by x11vnc. Only when there is transparency does x11vnc have
951to make some approximation to transform the cursor to be opaque (the
952VNC protocol does not provide for an alpha channel in cursors, only RGB).
953
954The items in this sub-menu let you tweak x11vnc's approximation scheme
955for cursors with transparency. Hopefully you won't have to use them.
956Certain cursor \"themes\" may require adjustment however.
957"
958#'
959 set helptext(OverlayVisuals:) "
960In this sub-menu are some options that involve fixing color problems
961for \"Overlay\" or \"Multi-Depth\" visuals. This problem is rare
962since overlay and multi-depth visual video hardware is rare.
963Some Sun, SGI, and HP machines are known to have them.
964
965The short answer is if you have a multi-depth visual display (e.g. 8 and
96624 bits), and you see messed up colors in x11vnc try the \"-overlay\"
967option on Solaris or IRIX.
968
969A brief Background on pixels, color, and visuals:
970
971 Pixels (picture elements) are kept in video memory as a certain number
972 of bits-per-pixel (bpp). Most common are 8bpp, 16bpp, and 32bpp.
973 Less common are 24bpp, 4bpp, and 1bpp (monochrome).
974
975 How pixel values (i.e. values of the bits) are rendered into colors on
976 the screen can be done via different \"Recipes\". These different
977 recipes are referred to as \"visuals\". E.g. for 8bpp there is
978 a PseudoColor visual that maintains a mapping (that can be changed
979 dynamically) of the pixel values (256 possible ones) into RGB values.
980 Other 8bpp visuals, e.g. StaticGrey and TrueColor have fixed, regular
981 mappings and so provide less variation in kinds of colors.
982
983 A visual's \"depth\" is how many of the pixels are used in the
984 actual recipe. This may sound wasteful (i.e. not using some of the
985 bits), but for 32bpp (4 billion colors) that is too much and nearly
986 always only 24 for them are used. The most common Visual seems to
987 be depth 24 TrueColor at 32bpp. This provides 16 million colors
988 which is more than the number of pixels on most screens (1280x1024 =
989 1.3 million pixels). Another sometimes used visual that ignores some
990 bits is depth 15 TrueColor at 16bpp.
991
992OK, now, finally, to the Overlay Visuals. Some hardware (or software
993emulations) allow different depth visuals to be used on the display
994at the same time. The pixels of windows using different depth visuals
995may overlap.
996
997The most common seems to be both 8 and 24 depth visuals on a 32bpp setup.
99824 of the pixels can be used for one visual and the remaining 8 for the
999other. This is sometimes referred to as \"8+24\" mode. Furthermore,
1000a speedup is achieved because writing graphics data to, say, the 8bit
1001visual does not destroy the image data in the 24bit visual. Evidently
1002popup menus can be done very quickly this way: they use the 8bit visual
1003and when the popup goes away the graphics data in the 24bit visual is
1004immediately reexposed without having the application redraw it.
1005
1006Also, some legacy applications can only use 8bpp visuals. But in these
1007days of high color graphics and web browsers one would like the rest
1008of the desktop to use depth 24 visuals. They often work on the multi
1009depth visuals.
1010
1011How does this effect x11vnc? x11vnc nearly always polls the root window
1012(container of all other windows). The root window will be one depth,
1013e.g. 8 or 24. Any windows using the *other* depth will appear to have
1014messed up colors (or just be black or some other solid color) when viewed
1015via x11vnc.
1016
1017How to fix? Solaris and IRIX provide an API to extract the full snapshot
1018of the display with all the colors correct. It comes to x11vnc as depth
101924 TrueColor. To enable this use the \"-overlay\" option. Performance
1020may be slower, but if the colors are correct that is a big improvement.
1021"
1022
1023 set helptext(8-Bit-Color:) "
1024Some older displays (e.g. with limited Video RAM) use 8 bits-per-pixel
1025color. This allows for only 256 different colors on the screen at the
1026same time. This sometimes leads to problems with viewing these 8bpp
1027displays via x11vnc. This sub-menu has some options that correspond to
1028workarounds for this case. If you can configure the machine to use 16bpp
1029it may be worth it to avoid the color problems (e.g. color flashing
1030as the 8bit colormap is switched).
1031"
1032 set helptext(SubWindow:) "
1033This sub-menu has a couple options regarding having x11vnc poll a
1034single window, not the entire display. This way just the window
1035is shared.
1036
1037Note if the application pops up multiple windows they are not tracked
1038and shared. So this is not application sharing. The application has to
1039be very simple (e.g. a simple terminal or the image window on a webcam)
1040for this mode to be usable.
1041"
1042 set helptext(ResizeRotate:) "
1043This sub-menu has some options regarding screens that support the X
1044Resize, Reflection, and Rotation Extension (RANDR), and one expects screen
1045resizing, reflection, or rotation to take place during the x11vnc session.
1046This is pretty rare, but x11vnc seems to handle it reasonably well using
1047this X extension.
1048
1049This mode is on by default in -id mode to try to track the changing
1050size of the SubWindow. It is not on by default for full-screen mode
1051because of the extra overhead, etc.
1052"
1053
1054 set helptext(WireFrame:) "
1055This sub-menu has some options for the x11vnc wireframing speedup scheme.
1056
1057For x11vnc, Wireframing means to watch for toplevel windows being Opaquely
1058Moved or Resized. When x11vnc detects this, it stops polling the screen
1059and simply shows a \"wireframe\" outline of the window as it is being
1060moved or resized. This avoids \"screen polling thrashing\" when the
1061screen is changing so rapidly during this period. For various reasons
1062this is usually much faster then letting the window manager do its
1063own wireframing (you are encouraged to do Opaque moves and resizes
1064when using x11vnc!)
1065
1066Also, once a moved window is released in its new position, x11vnc uses
1067the VNC CopyRect encoding to very efficiently update the VNC viewers
1068(each just copies the image data locally).
1069
1070This sort of scheme was used much in the 1990's on local displays because
1071video hardware was slow at the time. x11vnc tries to use this same trick
1072as a speedup for its activities (the network is much slower than video
1073hardware writes, and the video hardware reads that x11vnc uses to poll
1074the screen are still slow today).
1075"
1076#'"
1077
1078 set helptext(Safe:) "
1079In this sub-menu are some options for making x11vnc operations
1080more, or less, safe. E.g. disable the running of external commands, etc.
1081
1082You can also turn off the Remote control channel (NOTE that doing that
1083will disable the GUI from being able to communicate with x11vnc).
1084"
1085
1086 set helptext(X-ext:) "
1087In this sub-menu are a few rarely used options regarding some X extensions
1088used by x11vnc.
1089"
1090 set helptext(Clipping:) "
1091In this sub-menu are some options regarding clipping or blacking out
1092portions of the Screen. E.g. under XINERAMA when the multiple monitors
1093are not the same size.
1094
1095"
1096 set helptext(Misc-Screen:) "
1097In this sub-menu are some little used options modifying aspects of
1098the screen source.
1099"
1100
1101 set helptext(Settings:) "
1102In this sub-menu are some options for saving and loading option settings.
1103The default file to store settings in is ~/.x11vncrc, but you can save
1104different \"profiles\" in other files for later use.
1105
1106"
1107 set helptext(Java-applet:) "
1108In this sub-menu are some options for running the built-in HTTP server
1109that delivers the TightVNC Java VNC Viewer applet (VncViewer.jar) to
1110clients. The viewer runs in their Web browser.
1111
1112The default port listened on is 5800, so the URL is typically:
1113
1114 http://hostname:5800/
1115
1116but this can be altered by -httpport, etc.
1117"
1118
1119 set helptext(Chat:) "
1120In this sub-menu are some options for enabling a local chat window
1121and starting or stopping the current chat. This is the UltraVNC
1122Text Chat support in x11vnc.
1123"
1124
1125 set helptext(ScrollCopyRect:) "
1126This sub-menu has some options for the x11vnc Scroll detection and
1127CopyRect speedup scheme.
1128
1129For this mode, x11vnc \"spies\" on communication between the X server and
1130applications using the RECORD extension. It looks for various patterns
1131to detect a scrolled window. This only works for some applications,
1132fortunately some important ones.
1133
1134Once the scroll is detected it uses the VNC CopyRect encoding for a
1135big speedup. Screen polling is also sped up for this scheme.
1136
1137There are many tweakable parameters for this mode and they are described
1138in the sub-menu items.
1139"
1140
1141 set helptext(XDAMAGE:) "
1142The DAMAGE X extension allows the X server to send signals to x11vnc
1143telling it which regions of the screen have been changed. This improves
1144x11vnc's performance markedly. The DAMAGE extension must be available
1145on the display for this to work.
1146
1147Unfortunately DAMAGE cannot be trusted completely for the changed regions,
1148because often the reported changed region is much larger than the actual
1149changed regions. Nevertheless, x11vnc uses the DAMAGE information very
1150effectively as hints to improve its performance.
1151
1152The items in the sub-menu allow tweaking x11vnc's DAMAGE algorithm.
1153"
1154
1155 set helptext(Ncache:) "
1156A simple client-side (viewer) caching scheme is enabled with the
1157\"-ncache n\" option. It simply uses \"n\" framebuffer sized areas
1158below the actual display for caching window pixel data.
1159
1160Drawbacks are it uses a lot of RAM (roughly n times more), and the
1161pixels cache area is visible in the viewers.
1162
1163The items in the sub-menu allow tweaking x11vnc's -ncache algorithm.
1164"
1165
1166 set helptext(SharedMemory:) "
1167This sub-menu provides some options regarding SYSV shared memory usage
1168(shm) by x11vnc. Usually you want shm turned on because the x11vnc
1169process is nearly always running on the same machine the X server process
1170is running on. SharedMemory gives a performance speedup. However, if you
1171need to modify this scenario for special usage these options allow you to.
1172"
1173
1174 set helptext(Misc-Debug:) "
1175This sub-menu contains a lot of debugging parameters usually used
1176for debugging x11vnc itself. This is unlike the -debug_pointer and
1177-debug_keyboard options that are useful in learning information, quirks,
1178etc. about your local display and environment.
1179"
1180
1181 set helptext(Selection:) "
1182This sub-menu contains some options centering around the Selection
1183(also referred to as the Clipboard, Cutbuffers, etc). x11vnc will try
1184to exchange the selections between the VNC viewers and the X server.
1185You can adjust that behavior with these options.
1186"
1187
1188 set helptext(WindowView) "
1189Set the Window View Mode for the gui. There are three modes:
1190
1191 - full: Presents the full gui (Actions, Clients, etc, buttons,
1192 and the Text area and Set/Entry box).
1193
1194 - icon: Presents a small icon instead of the full gui. Moving
1195 the mouse over it shows the VNC display name and any
1196 connected clients. Clicking on the icon pops up a menu
1197 of actions to perform. Among them is \"Properties\" that
1198 allows setting more parameters. Clicking on \"Advanced\"
1199 in \"Properties\" brings up the full gui.
1200
1201 - tray: Attempt to embed the small icon in the system tray. If
1202 this fails it will resort to icon mode where the small icon
1203 is a standalone window.
1204
1205Note that in \"full\" mode if you delete the full gui window the gui
1206terminates (but the x11vnc server keeps running). However under \"icon\"
1207or \"tray\" mode if you bring up the full gui window via \"Properties ->
1208Advanced\" and then delete it the gui does NOT terminate.
1209
1210Also note that by default in \"icon\" mode if you delete the icon
1211window both the gui *and* the x11vnc server terminate.
1212"
1213
1214 set helptext(gui) "
1215tkx11vnc is a simple frontend to x11vnc. Nothing fancy, it merely
1216provides an interface to each of the many x11vnc command line options and
1217remote control commands. See \"Help -> all\" for much info about x11vnc.
1218
1219For a simplier gui, run x11vnc in \"tray\" or \"icon\" mode such as
1220\"-gui tray\", \"-gui icon\", or \"-gui tray=setpass\". In that
1221mode the full gui is only available under \"Advanced ...\".
1222
1223Also, \"-gui ez\" will show fewer menu items (toggle via Misc -> simple_gui)
1224
1225All menu items have a (?) button one can click on to get more information
1226about the option or command.
1227
1228There are two states tkx11vnc can be in:
1229
1230 1) Available to control a running x11vnc process.
1231
1232 2) Getting ready to start a x11vnc process.
1233
1234Most people will just use state 1).
1235
1236In state 1) the Menu items available in the menus are those that
1237correspond to the x11vnc \"remote control\" commands. See the -remote
1238entry under \"Help -> all\" for a complete list. Also available is
1239the \"Actions -> stop\" item to shut down the running x11vnc server,
1240thereby changing to state 2). There are other actions available too.
1241
1242In state 2) the Menu items available in the menus (\"Actions\", \"Clients\",
1243etc.) are those that correspond to command line options used in starting
1244an x11vnc process, and the \"Actions -> start\" item executes
1245x11vnc thereby changing to state 1). To see what x11vnc startup command
1246you have built so far, look at the (?) help for \"Actions -> start\"
1247and it will show you what the command looks like.
1248
1249There is much overlap between the menu items available in state 1)
1250and state 2), but it is worth keeping in mind it is not 100%.
1251For example, you cannot set passwords or password files in state 1).
1252(update: simple password setting is now allowed in \"tray\" or \"icon\" mode).
1253
1254
1255Also note that there may be *two* separate X displays involved, not just
1256one: 1) the X display x11vnc will be polling (and making available to
1257VNC viewers), and 2) the X display this GUI is intended to display on.
1258
1259For example, one might use ssh to access the remote machine where the
1260GUI would display on :11 and x11vnc would poll display :0. By default
1261the gui will display on the value in the DISPLAY env. variable followed
1262by the value from the -display option. To override this, use something
1263like: \"-gui otherhost:0\", etc.
1264
1265
1266GUI components:
1267--- ----------
1268
12691) At the top of the gui is a info text label where information will
1270 be posted, e.g. when traversing menu items text indicating how to get
1271 help on the item and its current value will be displayed.
1272
12732) Below the info label is the area where the menu buttons, \"Actions\",
1274 \"Clients\", etc., are presented. If a menu item has a checkbox,
1275 it corresponds to a boolean on/off variable. Otherwise it is
1276 either a string variable, or an action not associated with a
1277 variable (for the most part).
1278
12793) Below the menu button area is a label indicating the current x11vnc
1280 X display being polled and the corresponding VNC display name. Both
1281 will be \"(*none*)\" when there is no connection established.
1282
12834) Below the x11 and vnc displays label is a text area there scrolling
1284 information about actions being taken and commands being run is displayed.
1285 To scroll click in the area and use PageUp/PageDown or the arrow keys.
1286
12875) At the bottom is an entry area. When one selects a menu item that
1288 requires supplying a string value, the label will be set to the
1289 parameter name and one types in the new value. Then one presses the
1290 \"OK\" button or presses \"Enter\" to set the value. Or you can press
1291 \"Cancel\" or \"Escape\" to avoid changing the variable.
1292
1293 Many variables are boolean toggles (for example, \"Permissions ->
1294 viewonly\") or Radio button selections. Selecting these menu items
1295 will NOT activate the entry area but rather toggle the variable
1296 immediately.
1297
1298
1299CASCADES BUG: There is a bug not yet worked around for the cascade menus
1300where the (?) help button gets in the way. To get the mouse over to
1301the cascade menu click and release mouse to activate the cascade, then
1302you can click on its items. Dragging with a mouse button held down will
1303not work (sorry!).
1304
1305
1306Key Bindings:
1307
1308 In the Text Area: Control-/ selects all of the text.
1309 Anywhere: Control-d invokes \"Actions -> detach\"
1310 Anywhere: Control-a invokes \"Actions -> attach\"
1311 Anywhere: Control-p invokes \"Actions -> ping\"
1312 Anywhere: Control-u and Control-r invoke \"Actions -> update-all\"
1313"
1314
1315set under_wally "
1316Misc:
1317
1318Since x11vnc has so many settings and to avoid further confusion,
1319the libvncserver options:
1320
1321 -alwaysshared
1322 -nevershared
1323 -dontdisconnect
1324
1325are not available for changing in a running x11vnc (even though it
1326is feasible). These options overlap with the x11vnc options -shared
1327and -forever which are hopefully enough for most usage. They may be
1328specified for x11vnc startup if desired.
1329
1330"
1331
1332global beginner_mode
1333if {$beginner_mode} {
1334 set helptext(gui) "
1335tkx11vnc is a simple frontend to x11vnc. It is currently running in
1336\"ez\" or \"simple\" mode. For many more options run it in normal
1337mode by toggling \"Misc -> simple_gui\".
1338
1339All menu items have a (?) button one can click on to get more information
1340about the option or command.
1341
1342GUI components:
1343--- ----------
1344
13451) At the top of the gui is a info text label where information will
1346 be posted, e.g. when traversing menu items text indicating how to get
1347 help on the item and its current value will be displayed.
1348
13492) Below the info label is the area where the menu buttons, \"Actions\",
1350 \"Clients\", etc., are presented. If a menu item has a checkbox,
1351 it corresponds to a boolean on/off variable. Otherwise it is
1352 either a string variable, or an action not associated with a
1353 variable (for the most part).
1354
13553) Below the menu button area is a label indicating the current x11vnc
1356 X display being polled and the corresponding VNC display name. Both
1357 will be \"(*none*)\" when there is no connection established.
1358
13594) Below the x11 and vnc displays label is a text area there scrolling
1360 information about actions being taken and commands being run is displayed.
1361 To scroll click in the area and use PageUp/PageDown or the arrow keys.
1362
13635) At the bottom is an entry area. When one selects a menu item that
1364 requires supplying a string value, the label will be set to the
1365 parameter name and one types in the new value. Then one presses the
1366 \"OK\" button or presses \"Enter\" to set the value. Or you can press
1367 \"Cancel\" or \"Escape\" to avoid changing the variable.
1368
1369 Many variables are boolean toggles (for example, \"Permissions ->
1370 viewonly\") or Radio button selections. Selecting these menu items
1371 will NOT activate the entry area but rather toggle the variable
1372 immediately.
1373
1374CASCADES BUG: There is a bug not yet worked around for the cascade menus
1375where the (?) help button gets in the way. To get the mouse over to
1376the cascade menu click and release mouse to activate the cascade, then
1377you can click on its items. Dragging with a mouse button held down will
1378not work (sorry!).
1379
1380"
1381}
1382
1383}
1384
1385proc center_win {w} {
1386 wm withdraw $w
1387 set x [expr [winfo screenwidth $w]/2 - [winfo reqwidth $w]/2];
1388 set y [expr [winfo screenheight $w]/2 - [winfo reqheight $w]/2];
1389 wm geometry $w +$x+$y
1390 wm deiconify $w
1391 update
1392}
1393
1394proc textwidth {text} {
1395 set min 0;
1396 foreach line [split $text "\n"] {
1397 set n [string length $line]
1398 if {$n > $min} {
1399 set min $n
1400 }
1401 }
1402 return $min
1403}
1404
1405proc textheight {text} {
1406 set count 0;
1407 foreach line [split $text "\n"] {
1408 incr count
1409 }
1410 return $count
1411}
1412
1413proc set_name {name} {
1414 global full_win icon_mode
1415 global saved_set_name
1416
1417 if {![info exists saved_set_name]} {
1418 set saved_set_name "tkx11vnc"
1419 }
1420 if {$name == "RESTORE"} {
1421 set name $saved_set_name
1422 } else {
1423 set saved_set_name $name
1424 }
1425 if {![info exists full_win]} {
1426 return
1427 }
1428 set w "."
1429 if {$icon_mode} {
1430 wm title $w "$name"
1431 wm iconname $w "$name"
1432 set w $full_win
1433 }
1434 wm title $w "$name"
1435 wm iconname $w "$name"
1436}
1437
1438proc make_toplevel {w {title ""}} {
1439 catch {destroy $w}
1440 toplevel $w;
1441 bind $w <Escape> "destroy $w"
1442 if {$title != ""} {
1443 wm title $w $title
1444 wm iconname $w $title
1445 }
1446}
1447
1448proc textwin {name title text {entry ""}} {
1449 global max_text_height max_text_width
1450 global bfont ffont
1451
1452 set width [textwidth $text]
1453 incr width
1454 if {$width > $max_text_width} {
1455 set width $max_text_width
1456 }
1457 set height [textheight $text]
1458 if {$height > $max_text_height} {
1459 set height $max_text_height
1460 }
1461
1462 set w ".text_$name"
1463 make_toplevel $w $title
1464
1465 frame $w.f -bd 0;
1466 pack $w.f -fill both -expand 1
1467 text $w.f.t -width $width -height $height -setgrid 1 -bd 2 \
1468 -yscrollcommand "$w.f.y set" -relief ridge \
1469 -font $ffont;
1470 scrollbar $w.f.y -orient v -relief sunken -command "$w.f.t yview";
1471 button $w.f.b -text "Dismiss" -command "destroy $w" -font $bfont \
1472 -pady 2
1473
1474 $w.f.t insert 1.0 $text;
1475
1476 bind $w <Enter> "focus $w.f.t"
1477
1478 if {$entry != ""} {
1479 # varname+Label Name
1480 set list [split $entry "+"]
1481 set varname [lindex $list 0]
1482 set labname [lindex $list 1]
1483 frame $w.f.ef -bd 1 -relief groove
1484 label $w.f.ef.l -text "$labname" -anchor w -font $bfont
1485 entry $w.f.ef.e -relief sunken -font $ffont \
1486 -textvariable $varname
1487 button $w.f.ef.b -text "OK" -font $bfont \
1488 -command "set ${varname}_ok 1; destroy $w"
1489 bind $w.f.ef.e <KeyPress-Return> "set ${varname}_ok 1; destroy $w"
1490
1491 pack $w.f.ef.l -side left
1492 pack $w.f.ef.e -side left -fill x -expand 1
1493 pack $w.f.ef.b -side right
1494 }
1495
1496 wm withdraw $w
1497 pack $w.f.b -side bottom -fill x
1498 if {$entry != ""} {
1499 pack $w.f.ef -side bottom -fill x
1500 bind $w <Enter> "focus $w.f.ef.e"
1501 $w.f.ef.e icursor end
1502 } else {
1503 bind $w <Enter> "focus $w.f.t"
1504 }
1505 pack $w.f.y -side right -fill y;
1506 pack $w.f.t -side top -fill both -expand 1;
1507 update
1508
1509 center_win $w
1510
1511 return $w
1512}
1513
1514proc active_when_connected {item} {
1515 global helpremote helptext
1516 global icon_mode
1517
1518 if {$icon_mode} {
1519 if {$item == "passwd"} {
1520 return 1
1521 }
1522 if {$item == "viewpasswd"} {
1523 return 1
1524 }
1525 }
1526
1527 if {[opt_match G $item]} {
1528 return 1
1529 } elseif {[opt_match R $item]} {
1530 return 1
1531 } elseif {[opt_match S $item]} {
1532 return 0
1533 } elseif {[is_action $item]} {
1534 if {[opt_match R $item]} {
1535 return 1
1536 } else {
1537 return 0
1538 }
1539 } elseif {[info exists helpremote($item)]} {
1540 return 1
1541 } else {
1542 return 0
1543 }
1544}
1545
1546proc active_when_starting {item} {
1547 global helpremote helptext beginner_mode
1548
1549 if {$beginner_mode} {
1550 if {[opt_match G $item]} {
1551 return 1
1552 }
1553 if {$item == "display"} {
1554 return 1
1555 }
1556 if {$item == "attach"} {
1557 return 1
1558 }
1559 if {$item == "debug_gui"} {
1560 return 1
1561 }
1562 return 0
1563 }
1564
1565 if {[opt_match G $item]} {
1566 return 1
1567 } elseif {[opt_match S $item]} {
1568 return 1
1569 } elseif {[opt_match R $item]} {
1570 return 0
1571 } elseif {[is_action $item]} {
1572 if {[opt_match S $item]} {
1573 return 1
1574 } else {
1575 return 0
1576 }
1577 } elseif {[info exists helptext($item)]} {
1578 return 1
1579 } else {
1580 return 0
1581 }
1582}
1583
1584proc help_win {item} {
1585 global helptext helpremote menu_var
1586 global query_ans query_aro
1587 global beginner_mode
1588
1589 set ok 0
1590 set text "Help on $item:\n\n"
1591
1592 if {$item == "NewClient"} {
1593 ;
1594 } elseif {[is_gui_internal $item]} {
1595 if {$item != "gui" && $item != "all" && $item != "Misc-Tuning:" \
1596 && $item != "Properties" && $item != "Tray"} {
1597 append text " + Is a gui internal Action (cannot be set).\n";
1598 }
1599 } elseif {[is_action $item]} {
1600 append text " + Is a remote control Action (cannot be set).\n";
1601 } elseif {[active_when_connected $item]} {
1602 append text " + Can be changed in a running x11vnc.\n";
1603 } else {
1604 append text " - Cannot be changed in a running x11vnc.\n";
1605 }
1606 if {$item == "NewClient"} {
1607 ;
1608 } elseif {[is_gui_internal $item]} {
1609 ;
1610 } elseif {[active_when_starting $item]} {
1611 append text " + Can be set at x11vnc startup.\n";
1612 } else {
1613 if {! $beginner_mode} {
1614 append text " - Cannot be set at x11vnc startup.\n";
1615 }
1616 }
1617 append text "\n"
1618
1619 if {[info exists helptext($item)]} {
1620 append text "\n"
1621 if {[is_gui_internal $item]} {
1622 append text "==== x11vnc help: ====\n";
1623 } else {
1624 append text "==== x11vnc startup option help: ====\n";
1625 }
1626 append text "\n"
1627 append text $helptext($item)
1628 append text "\n"
1629 set ok 1
1630 }
1631
1632 if {[info exists helpremote($item)]} {
1633 append text "\n"
1634 append text "==== x11vnc remote control help: ====\n";
1635 append text "\n"
1636 append text $helpremote($item)
1637 set ok 1
1638 }
1639
1640 if {![is_action $item] && [info exists menu_var($item)]} {
1641 global unset_str
1642 append text "\n\n"
1643 append text "==== current $item value: ====\n";
1644 append text "\n"
1645
1646 if {$item == "passwd" || $item == "viewpasswd"} {
1647 ;
1648 } elseif {$menu_var($item) == ""} {
1649 append text "$unset_str\n"
1650 } else {
1651 append text "$menu_var($item)\n"
1652 }
1653 if {$item == "http" || $item == "httpdir" || $item == "httpport"} {
1654 global vnc_url;
1655 append text "\nURL: $vnc_url\n"
1656 }
1657 }
1658
1659 if {$item == "start"} {
1660 set str [get_start_x11vnc_txt]
1661 append_text "$str\n"
1662# append text "\nPossible \$HOME/.x11vncrc settings for this command:\n\n"
1663# set rctxt [get_start_x11vnc_cmd 1]
1664# append text "$rctxt\n"
1665 }
1666
1667 regsub -all { } $item " " name
1668
1669 if {$ok} {
1670 textwin $name "x11vnc help: $item" "$text";
1671 }
1672 return $ok
1673}
1674
1675proc parse_help {} {
1676 global env x11vnc_prog;
1677 global helpall helptext;
1678
1679 set helppipe [open "| $x11vnc_prog -help" "r"];
1680 if {$helppipe == ""} {
1681 puts stderr "failed to run $x11vnc_prog -help";
1682 exit 1;
1683 }
1684
1685 set sawopts 0;
1686 set curropt "";
1687 while {[gets $helppipe line] > -1} {
1688 append helpall "$line\n"
1689
1690 # XXX
1691 if {[regexp {^Options:} $line]} {
1692 set sawopts 1;
1693 continue;
1694 }
1695 # XXX
1696 if {[regexp {^These options} $line]} {
1697 continue;
1698 }
1699 # tweak aliases:
1700 regsub {^-zeroconf} $line "-zero_conf" line
1701 regsub {^-avahi } $line "-zeroconf" line
1702
1703 if {! $sawopts} {
1704 continue;
1705 }
1706 if {[regexp {^-([0-9A-z_][0-9A-z_]*)} $line match name]} {
1707 set allnames($name) 1;
1708 if {"$curropt" != "no$name" && "no$curropt" != "$name"} {
1709 set curropt $name;
1710 set helptext($curropt) "$line\n";
1711 } else {
1712 append helptext($curropt) "$line\n";
1713 }
1714 } elseif {$curropt != ""} {
1715 append helptext($curropt) "$line\n";
1716 }
1717 }
1718 foreach name [array names allnames] {
1719 if {[regexp {^no} $name]} {
1720 regsub {^no} $name "" pair
1721 } else {
1722 set pair "no$name"
1723 }
1724 if {[info exists helptext($name)]} {
1725 if ![info exists helptext($pair)] {
1726 set helptext($pair) $helptext($name);
1727 }
1728 } elseif {[info exists helptext($pair)]} {
1729 if ![info exists helptext($name)] {
1730 set helptext($name) $helptext($pair);
1731 }
1732 }
1733 }
1734
1735 set_internal_help
1736}
1737
1738proc tweak_both {new old} {
1739 tweak_help $new $old
1740 tweak_remote_help $new $old
1741}
1742
1743proc tweak_remote_help {new old} {
1744 global helpremote
1745 if ![info exists helpremote($new)] {
1746 if {[info exists helpremote($old)]} {
1747 set helpremote($new) $helpremote($old)
1748 }
1749 }
1750}
1751
1752proc tweak_help {new old} {
1753 global helptext
1754 if ![info exists helptext($new)] {
1755 if {[info exists helptext($old)]} {
1756 set helptext($new) $helptext($old)
1757 }
1758 }
1759}
1760
1761proc parse_remote_help {} {
1762 global helpremote helptext help_indent remote_name;
1763
1764 set sawopts 0;
1765 set curropt "";
1766 set possopts "";
1767 set offset [expr $help_indent - 1];
1768 foreach line [split $helptext(remote) "\n"] {
1769
1770 set line [string range $line $offset end];
1771
1772 # XXX
1773 if {[regexp {^The following -remote/-R commands} $line]} {
1774 set sawopts 1;
1775 continue;
1776 }
1777 # XXX
1778 if {[regexp {^The vncconnect.*command} $line]} {
1779 set sawopts 0;
1780 }
1781
1782 if {! $sawopts} {
1783 continue;
1784 }
1785 if {[regexp {^([0-9A-z_][0-9A-z_:]*)} $line match name]} {
1786 regsub {:.*$} $name "" popt
1787 lappend possopts $popt
1788 if {"$curropt" != "no$name" && "no$curropt" != "$name"} {
1789 set curropt $name;
1790 regsub {:.*$} $curropt "" curropt
1791 set remote_name($curropt) $name
1792 set helpremote($curropt) "$line\n";
1793 } else {
1794 append helpremote($curropt) "$line\n";
1795 }
1796 } elseif {$curropt != ""} {
1797 append helpremote($curropt) "$line\n";
1798 }
1799 }
1800
1801 foreach popt $possopts {
1802 if {[info exists helpremote($popt)]} {
1803 continue
1804 }
1805 if {[regexp {^no} $popt]} {
1806 regsub {^no} $popt "" try
1807 } else {
1808 set try "no$popt"
1809 }
1810 if {[info exists helpremote($try)]} {
1811 set helpremote($popt) $helpremote($try)
1812 }
1813 }
1814}
1815
1816proc parse_query_help {} {
1817 global query_ans query_aro query_ans_list query_aro_list helptext;
1818
1819 set sawans 0;
1820 set sawaro 0;
1821 set ans_str ""
1822 set aro_str ""
1823
1824 foreach line [split $helptext(query) "\n"] {
1825
1826 if {! $sawans && [regexp {^ *ans=} $line]} {
1827 set sawans 1
1828 }
1829 if {! $sawans} {
1830 continue
1831 }
1832
1833 if {[regexp {^ *aro=} $line]} {
1834 set sawaro 1
1835 }
1836 if {$sawaro && [regexp {^[ ]*$} $line]} {
1837 set sawans 0
1838 break
1839 }
1840
1841 regsub {ans=} $line "" line
1842 regsub {aro=} $line "" line
1843 set line [string trim $line]
1844
1845 if {$sawaro} {
1846 set aro_str "$aro_str $line"
1847 } else {
1848 set ans_str "$ans_str $line"
1849 }
1850 }
1851
1852 regsub -all { *} $ans_str " " ans_str
1853 regsub -all { *} $aro_str " " aro_str
1854
1855 set ans_str [string trim $ans_str]
1856 set aro_str [string trim $aro_str]
1857 set query_ans_list [split $ans_str]
1858 set query_aro_list [split $aro_str]
1859
1860 foreach item $query_ans_list {
1861 if {[regexp {^[ ]*$} $item]} {
1862 continue
1863 }
1864 set query_ans($item) 1
1865 }
1866 foreach item $query_aro_list {
1867 if {[regexp {^[ ]*$} $item]} {
1868 continue
1869 }
1870 set query_aro($item) 1
1871 }
1872}
1873
1874proc in_debug_mode {} {
1875 global menu_var
1876 if {![info exists menu_var(debug_gui)]} {
1877 return 0
1878 }
1879 return $menu_var(debug_gui)
1880}
1881
1882# Menubar utilities:
1883proc menus_state {state} {
1884 global menu_b
1885
1886 foreach case [array names menu_b] {
1887 set menu_button $menu_b($case)
1888 if {![winfo exists $menu_button]} {
1889 continue
1890 }
1891 $menu_button configure -state $state
1892 }
1893}
1894
1895proc menus_enable {} {
1896 global menus_disabled
1897
1898 menus_state "normal"
1899 set menus_disabled 0
1900}
1901
1902proc menus_disable {} {
1903 global menus_disabled
1904
1905 set menus_disabled 1
1906 menus_state "disabled"
1907}
1908
1909# Entry box utilities:
1910proc entry_state {x state} {
1911 global entry_box entry_label entry_ok entry_help entry_skip entry_browse
1912 global old_labels
1913 if {$x == "all"} {
1914 if {!$old_labels} {
1915 $entry_label configure -state $state
1916 }
1917 $entry_box configure -state $state
1918 $entry_ok configure -state $state
1919 $entry_skip configure -state $state
1920 $entry_help configure -state $state
1921 $entry_browse configure -state $state
1922 } elseif {$x == "label"} {
1923 if {!$old_labels} {
1924 $entry_label configure -state $state
1925 }
1926 } elseif {$x == "box"} {
1927 $entry_box configure -state $state
1928 } elseif {$x == "ok"} {
1929 $entry_ok configure -state $state
1930 } elseif {$x == "skip"} {
1931 $entry_skip configure -state $state
1932 } elseif {$x == "help"} {
1933 $entry_help configure -state $state
1934 } elseif {$x == "browse"} {
1935 $entry_browse configure -state $state
1936 }
1937}
1938
1939proc entry_enable {{x "all"}} {
1940 entry_state $x normal
1941}
1942
1943proc entry_disable {{x "all"}} {
1944 entry_state $x disabled
1945}
1946
1947proc entry_browse_button {{show 1}} {
1948 global entry_browse
1949 if {$show} {
1950 pack $entry_browse -side left
1951 } else {
1952 pack forget $entry_browse
1953 }
1954}
1955proc entry_focus {} {
1956 global entry_box
1957 focus $entry_box
1958}
1959proc entry_select {} {
1960 global entry_box
1961 $entry_box selection range 0 end
1962}
1963proc entry_get {} {
1964 global entry_box
1965 return [$entry_box get]
1966}
1967proc entry_insert {str} {
1968 global entry_box
1969 entry_delete
1970 $entry_box insert end $str
1971 $entry_box icursor end
1972}
1973proc entry_delete {} {
1974 global entry_box
1975 $entry_box delete 0 end
1976}
1977
1978
1979# Utilities for remote control and updating vars.
1980
1981proc push_new_value {item name new {query 1}} {
1982 global menu_var always_update remote_output query_output
1983 global query_result_list
1984
1985 set debug [in_debug_mode]
1986
1987 set getout 0
1988 set print_getout 0;
1989
1990 set do_query_all 0
1991
1992 set newnew ""
1993 if {$item == "disconnect"} {
1994 set newnew "N/A"
1995 set do_query_all 1
1996 } elseif {$always_update} {
1997 set do_query_all 1
1998 }
1999
2000 if {$item == "remote-cmd"} {
2001 # kludge for arbitrary remote command:
2002 if {[regexp {^Q:} $new]} {
2003 # extra kludge for Q:var to mean -Q var
2004 regsub {^Q:} $new "" new
2005 set qonly 1
2006 } else {
2007 set qonly 0
2008 }
2009 # need to extract item from new:
2010 set qtmp $new
2011 regsub {:.*$} $qtmp "" qtmp
2012 if {$qonly} {
2013 set rargs [list "-Q" "$qtmp"]
2014 set print_getout 1
2015 set qargs ""
2016 } else {
2017 set rargs [list "-R" "$new"]
2018 set qargs ""
2019 }
2020 set getout 1
2021
2022 } elseif {[value_is_string $item]} {
2023 # string var:
2024 set rargs [list "-R" "$name:$new"]
2025 set qargs [list "-Q" "$name"]
2026 } else {
2027 # boolean var:
2028 set rargs [list "-R" "$name"]
2029 set qargs [list "-Q" "$name"]
2030 }
2031
2032 if {! $query && ! $always_update} {
2033 set getout 1
2034 } elseif {$item == "noremote"} {
2035 set getout 1
2036 } elseif {[is_action $item] && ![opt_match Q $item] && $rargs != ""} {
2037 set getout 1
2038 } elseif {[regexp {^(sid|id)$} $item] && ![regexp {^0x} $new]} {
2039 set getout 1
2040 }
2041
2042 set remote_output ""
2043 set query_output ""
2044
2045 if {!$debug} {
2046 if [regexp {passwd} $rargs] {
2047 append_text "x11vnc ..."
2048 } else {
2049 append_text "x11vnc $rargs ..."
2050 }
2051 }
2052
2053 if {$getout} {
2054 set remote_output [run_remote_cmd $rargs]
2055 if {$print_getout} {
2056 append_text "\t$remote_output"
2057 }
2058 append_text "\n"
2059 return
2060 }
2061
2062 if {$do_query_all} {
2063 set all [all_query_vars]
2064 set qargs [list "-Q" $all]
2065
2066 global last_query_all_time
2067 set last_query_all_time [clock seconds]
2068 }
2069
2070 set rqargs [concat $rargs $qargs]
2071
2072 set query [run_remote_cmd $rqargs]
2073 set query_output $query
2074
2075 set query_result_list ""
2076
2077 if {$newnew != ""} {
2078 set new $newnew
2079 }
2080
2081 if {![see_if_ok $query $item "$name:$new"]} {
2082 # failed
2083 if {[regexp {^a..=} $query]} {
2084 # but some result came back
2085 # synchronize everything with a 2nd call.
2086 set query_output [query_all 1]
2087 } else {
2088 # server may be dead
2089 if {$item != "ping" && $item != "attach"} {
2090 try_connect
2091 }
2092 }
2093 } else {
2094 # succeeded
2095 # synchronize this variable (or variables)
2096 # for a speedup used the list parsed by see_if_ok.
2097 update_menu_vars "USE_LIST"
2098
2099 if {$do_query_all} {
2100 global all_settings
2101 set all_settings $query
2102 }
2103 }
2104}
2105
2106proc set_kmbc_str {} {
2107 global vl_bk vl_bm vl_bb vl_bc vl_bf vr_bk vr_bm vr_bb vr_bc vr_bf
2108
2109 set str ""
2110 if {$vl_bk} {
2111 append str "K"
2112 }
2113 if {$vl_bm} {
2114 append str "M"
2115 }
2116 if {$vl_bb} {
2117 append str "B"
2118 }
2119 if {$vl_bc} {
2120 append str "C"
2121 }
2122 if {$vl_bf} {
2123 append str "F"
2124 }
2125 if {$vr_bk || $vr_bm || $vr_bb || $vr_bc || $vr_bf} {
2126 append str ","
2127 }
2128 if {$vr_bk} {
2129 append str "K"
2130 }
2131 if {$vr_bm} {
2132 append str "M"
2133 }
2134 if {$vr_bb} {
2135 append str "B"
2136 }
2137 if {$vr_bc} {
2138 append str "C"
2139 }
2140 if {$vr_bf} {
2141 append str "F"
2142 }
2143 entry_insert $str
2144}
2145
2146proc insert_input_window {} {
2147 global text_area cleanup_window
2148 global ffont menu_var
2149 global vl_bk vl_bm vl_bb vl_bc vl_bf vr_bk vr_bm vr_bb vr_bc vr_bf
2150
2151 append_text "\nUse these checkboxes to set the input permissions, "
2152 append_text "or type in the \"KMBCF...\"\n"
2153 append_text "-input string manually. Then press \"OK\" or \"Cancel\".\n"
2154 append_text "(note: an empty setting means use the default behavior, "
2155 append_text "see viewonly)\n\n"
2156 set w "$text_area.wk_f"
2157 catch {destroy $w}
2158 frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
2159 set fl $w.fl
2160 frame $fl
2161 set fr $w.fr
2162 frame $fr
2163 label $fl.l -font $ffont -text "Normal clients: "
2164 checkbutton $fl.bk -pady 1 -font $ffont -anchor w -variable vl_bk \
2165 -pady 1 -command set_kmbc_str -text "Keystrokes"
2166 checkbutton $fl.bm -font $ffont -anchor w -variable vl_bm \
2167 -pady 1 -command set_kmbc_str -text "Mouse-Motion"
2168 checkbutton $fl.bb -font $ffont -anchor w -variable vl_bb \
2169 -pady 1 -command set_kmbc_str -text "Button-Click"
2170 checkbutton $fl.bc -font $ffont -anchor w -variable vl_bc \
2171 -pady 1 -command set_kmbc_str -text "Clipboard-Input"
2172 checkbutton $fl.bf -font $ffont -anchor w -variable vl_bf \
2173 -pady 1 -command set_kmbc_str -text "Files"
2174 label $fr.l -pady 1 -font $ffont -text "View-Only clients:"
2175 checkbutton $fr.bk -font $ffont -anchor w -variable vr_bk \
2176 -pady 1 -command set_kmbc_str -text "Keystrokes"
2177 checkbutton $fr.bm -font $ffont -anchor w -variable vr_bm \
2178 -pady 1 -command set_kmbc_str -text "Mouse-Motion"
2179 checkbutton $fr.bb -font $ffont -anchor w -variable vr_bb \
2180 -pady 1 -command set_kmbc_str -text "Button-Click"
2181 checkbutton $fr.bc -font $ffont -anchor w -variable vr_bc \
2182 -pady 1 -command set_kmbc_str -text "Clipboard-Input"
2183 checkbutton $fr.bf -font $ffont -anchor w -variable vr_bf \
2184 -pady 1 -command set_kmbc_str -text "Files"
2185
2186 if {[info exists menu_var(input)]} {
2187 set input_str $menu_var(input)
2188 } else {
2189 set input_str ""
2190 }
2191
2192 if {[regexp {(.*),(.*)} $input_str match normal viewonly]} {
2193 ;
2194 } else {
2195 set normal $input_str
2196 set viewonly ""
2197 }
2198 set vl_bk 0
2199 set vl_bm 0
2200 set vl_bb 0
2201 set vl_bc 0
2202 set vl_bf 0
2203
2204 set vr_bk 0
2205 set vr_bm 0
2206 set vr_bb 0
2207 set vr_bc 0
2208 set vr_bf 0
2209
2210 if {[regexp -nocase {K} $normal]} {
2211 set vl_bk 1
2212 }
2213 if {[regexp -nocase {M} $normal]} {
2214 set vl_bm 1
2215 }
2216 if {[regexp -nocase {B} $normal]} {
2217 set vl_bb 1
2218 }
2219 if {[regexp -nocase {C} $normal]} {
2220 set vl_bc 1
2221 }
2222 if {[regexp -nocase {F} $normal]} {
2223 set vl_bf 1
2224 }
2225 if {[regexp -nocase {K} $viewonly]} {
2226 set vr_bk 1
2227 }
2228 if {[regexp -nocase {M} $viewonly]} {
2229 set vr_bm 1
2230 }
2231 if {[regexp -nocase {B} $viewonly]} {
2232 set vr_bb 1
2233 }
2234 if {[regexp -nocase {C} $viewonly]} {
2235 set vr_bc 1
2236 }
2237 if {[regexp -nocase {F} $viewonly]} {
2238 set vr_bf 1
2239 }
2240
2241 pack $fl.l $fl.bk $fl.bm $fl.bb $fl.bc $fl.bf -side top -fill x
2242 pack $fr.l $fr.bk $fr.bm $fr.bb $fr.bc $fr.bf -side top -fill x
2243 pack $fl $fr -side left
2244 update
2245 update idletasks
2246 $text_area window create end -window $w
2247 $text_area see end
2248 $text_area insert end "\n"
2249# $text_area insert end "\n\n\n\n\n\n\n\n\n"
2250
2251 set cleanup_window $w
2252}
2253
2254proc set_ca_str {w} {
2255 global ca_bk ca_bm ca_bb ca_bc ca_bf ca_di
2256
2257 if {$ca_di} {
2258 entry_insert "disconnect"
2259 $w.bk configure -state disabled
2260 $w.bm configure -state disabled
2261 $w.bb configure -state disabled
2262 $w.bc configure -state disabled
2263 $w.bf configure -state disabled
2264 return
2265 }
2266
2267 $w.bk configure -state normal
2268 $w.bm configure -state normal
2269 $w.bb configure -state normal
2270 $w.bc configure -state normal
2271 $w.bf configure -state normal
2272
2273 set str ""
2274 if {$ca_bk} {
2275 append str "K"
2276 }
2277 if {$ca_bm} {
2278 append str "M"
2279 }
2280 if {$ca_bb} {
2281 append str "B"
2282 }
2283 if {$ca_bc} {
2284 append str "C"
2285 }
2286 if {$ca_bf} {
2287 append str "F"
2288 }
2289 entry_insert $str
2290}
2291
2292proc insert_client_action_window {input} {
2293 global text_area cleanup_window
2294 global ffont menu_var
2295 global ca_bk ca_bm ca_bb ca_bc ca_bf ca_di
2296
2297 append_text "\nUse these checkboxes to set the input permissions "
2298 append_text "for this client\n-OR- whether to disconnect it instead. "
2299 append_text "Then press \"OK\" or \"Cancel\".\n\n"
2300 set w "$text_area.ca_f"
2301 catch {destroy $w}
2302 frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
2303 checkbutton $w.di -pady 1 -font $ffont -anchor w -variable ca_di \
2304 -pady 1 -command "set_ca_str $w" -text "Disconnect "
2305 checkbutton $w.bk -font $ffont -anchor w -variable ca_bk \
2306 -pady 1 -command "set_ca_str $w" -text "Keystrokes"
2307 checkbutton $w.bm -font $ffont -anchor w -variable ca_bm \
2308 -pady 1 -command "set_ca_str $w" -text "Mouse-Motion"
2309 checkbutton $w.bb -font $ffont -anchor w -variable ca_bb \
2310 -pady 1 -command "set_ca_str $w" -text "Button-Click"
2311 checkbutton $w.bc -font $ffont -anchor w -variable ca_bc \
2312 -pady 1 -command "set_ca_str $w" -text "Clipboard"
2313 checkbutton $w.bf -font $ffont -anchor w -variable ca_bf \
2314 -pady 1 -command "set_ca_str $w" -text "Files"
2315
2316 set ca_di 0
2317 set ca_bk 0
2318 set ca_bm 0
2319 set ca_bb 0
2320 set ca_bf 0
2321 set ca_bc 0
2322
2323 if {[regexp -nocase {K} $input]} {
2324 set ca_bk 1
2325 }
2326 if {[regexp -nocase {M} $input]} {
2327 set ca_bm 1
2328 }
2329 if {[regexp -nocase {B} $input]} {
2330 set ca_bb 1
2331 }
2332 if {[regexp -nocase {C} $input]} {
2333 set ca_bc 1
2334 }
2335 if {[regexp -nocase {F} $input]} {
2336 set ca_bf 1
2337 }
2338
2339 pack $w.di $w.bk $w.bm $w.bb $w.bc $w.bf -side left
2340 update
2341 update idletasks
2342 $text_area window create end -window $w
2343 $text_area see end
2344 $text_area insert end "\n"
2345
2346 set cleanup_window $w
2347}
2348
2349proc cleanup_text_window {} {
2350 global cleanup_window
2351 if {[info exists cleanup_window]} {
2352 catch {destroy $cleanup_window}
2353 }
2354}
2355
2356# For updating a string variable. Also used for simple OK/Cancel dialogs
2357# with entry = 0.
2358proc entry_dialog {item {entry 1}} {
2359 global menu_var entry_str entry_set entry_dialog_item
2360 global unset_str connected_to_x11vnc entry_box
2361
2362 set entry_str "Set $item"
2363 set entry_set 0
2364 set entry_dialog_item $item
2365
2366 entry_enable
2367 menus_disable
2368
2369 if {$item == "passwd" || $item == "viewpasswd"} {
2370 $entry_box configure -show "*"
2371 }
2372
2373 if {$entry} {
2374 entry_insert ""
2375 if {[info exists menu_var($item)] &&
2376 $menu_var($item) != $unset_str} {
2377 entry_insert $menu_var($item)
2378 entry_select
2379 }
2380
2381 if {[is_browse $item]} {
2382 entry_browse_button
2383 }
2384 set_info "Set parameter in entry box, "
2385 entry_focus
2386 } else {
2387 entry_disable box
2388 }
2389
2390 set clean_text_window 0;
2391
2392 if {$item == "input"} {
2393 insert_input_window
2394 set clean_text_window 1
2395 }
2396
2397 update
2398
2399 # wait for user reply:
2400 vwait entry_set
2401
2402 set rc $entry_set
2403 set entry_set 0
2404
2405 set value [entry_get]
2406 update
2407
2408 entry_browse_button 0
2409 set entry_str "Set... :"
2410
2411 entry_delete
2412 entry_disable
2413 menus_enable
2414
2415 if {$clean_text_window} {
2416 cleanup_text_window;
2417 }
2418
2419 update
2420
2421 if {! $entry} {
2422 ;
2423 } elseif {$rc} {
2424 set menu_var($item) $value
2425 } else {
2426 if {[in_debug_mode]} {
2427 append_text "skipped setting $item\n"
2428 }
2429 }
2430
2431 $entry_box configure -show ""
2432
2433 return $rc
2434}
2435
2436proc warning_dialog {msg {item "gui"} } {
2437 append_text $msg
2438 # just reuse the entry widgets for a yes/no dialog
2439 return [entry_dialog $item 0]
2440}
2441
2442# For updating a boolean toggle:
2443proc check_var {item} {
2444 global menu_var
2445
2446 set inval $menu_var($item);
2447
2448 if {$item == "debug_gui"} {
2449 return "";
2450 }
2451
2452 set rname $item
2453 if {! $inval} {
2454 if {[regexp {^no} $item]} {
2455 regsub {^no} $rname "" rname
2456 } else {
2457 set rname "no$rname"
2458 }
2459 }
2460 return $rname
2461}
2462
2463proc see_if_ok {query item expected} {
2464 global query_result_list
2465
2466 set ok 0
2467 set found ""
2468
2469 set query_result_list [split_query $query]
2470
2471 foreach q $query_result_list {
2472 # XXX following will crash if $item is not a good regexp
2473 # need to protect it \Q$item\E style...
2474# if {[regexp "^$item:" $q]} {
2475# set found $q
2476# }
2477 if {[string first "$item:" $q] == 0} {
2478 set found $q
2479 }
2480 if {$q == $expected} {
2481 set ok 1
2482 if {$found != ""} {
2483 break;
2484 }
2485 }
2486 }
2487 if {$found == ""} {
2488 set msg $query
2489 regsub {^a..=} $msg {} msg
2490 if {[string length $msg] > 60} {
2491 set msg [string range $msg 0 60]
2492 }
2493 } else {
2494 set msg $found
2495 }
2496 if {!$ok && $found != ""} {
2497 # check for floating point match:
2498 set v1 ""
2499 set v2 ""
2500 regexp {:([0-9.][0-9.]*)$} $found m0 v1
2501 regexp {:([0-9.][0-9.]*)$} $expected m0 v2
2502 if {$v1 != "" && $v2 != ""} {
2503 set diff ""
2504 catch {set diff [expr "$v1 - $v2"]}
2505 if {$diff != ""} {
2506 if {$diff < 0} {
2507 set diff [expr "0.0 - $diff"]
2508 }
2509 if {$diff < 0.00001} {
2510 set ok 1
2511 }
2512 }
2513 }
2514 }
2515 if {$ok} {
2516 append_text "\tSet OK ($msg)\n"
2517 return 1
2518
2519 } elseif {[opt_match P $item] && [regexp {:(-|\+)} $expected]} {
2520 # e.g. blackout:+30x30+20+20
2521 append_text "\t($msg)\n"
2522 return 1
2523 } elseif {[regexp {:[0-9]\.[0-9]} $expected]} {
2524 append_text "\t($msg)\n"
2525 return 1
2526 } elseif {$item == "connect" || $item == "disconnect"
2527 || $item == "client" || $item == "client_input"} {
2528 append_text "\t($msg)\n"
2529 return 1
2530 } elseif {$item == "passwd" || $item == "viewpasswd"} {
2531 append_text "\t($msg)\n"
2532 return 1
2533 } else {
2534 append_text "\t*FAILED* $msg\n"
2535 return 0
2536 }
2537}
2538
2539proc get_default_vars {} {
2540 global default_var env
2541
2542 set qry [all_query_vars]
2543
2544 append qry ",vncconnect"
2545
2546 set q ""
2547 set i 0
2548 set all ""
2549 foreach s [split $qry ","] {
2550 if {$q != ""} {
2551 append q ","
2552 }
2553 append q $s
2554 incr i
2555 if {$i > 50} {
2556 set qargs [list "-QD" $q]
2557 set a [run_remote_cmd $qargs]
2558 if [info exists env(TKX11VNC_PRINT_ALL_QD)] {
2559 puts $q
2560 puts $a
2561 puts "---------------"
2562 }
2563 if {$all != ""} {
2564 append all ","
2565 }
2566 append all $a
2567 set q ""
2568 set i 0
2569 }
2570 }
2571 if {$q != ""} {
2572 set qargs [list "-QD" $q]
2573 set a [run_remote_cmd $qargs]
2574 if [info exists env(TKX11VNC_PRINT_ALL_QD)] {
2575 puts $q
2576 puts $a
2577 puts "---------------"
2578 }
2579 if {$all != ""} {
2580 append all ","
2581 }
2582 append all $a
2583 }
2584
2585# old way, qry too long...
2586# set qargs [list "-QD" $qry]
2587# set all [run_remote_cmd $qargs]
2588
2589 if {[regexp {ans=} $all]} {
2590 #append_text "Retrieved all default settings.\n"
2591 } else {
2592 #append_text "Failed to retrieve default settings.\n"
2593 }
2594
2595 set query_result_list [split_query $all]
2596
2597 set default_var(gui) ""
2598
2599 foreach piece $query_result_list {
2600 if {[regexp {^([^:][^:]*):(.*)$} $piece m0 item val]} {
2601 if {$val == "N/A"} {
2602 if {$item == "vncconnect"} {
2603 set val 1
2604 } else {
2605 set val ""
2606 }
2607 }
2608 if {$item == "display"} {
2609 set val ""
2610 } elseif {$item == "desktop"} {
2611 set val ""
2612 } elseif {$item == "auth"} {
2613 set val ""
2614 } elseif {$item == "gui"} {
2615 continue
2616 }
2617 # some hacks we do here for now..
2618 if {$item == "cursor" && $val == ""} {
2619 set val "most"
2620 } elseif {$item == "scrollcopyrect" && $val == ""} {
2621 set val "always"
2622 } elseif {$item == "wirecopyrect" && $val == ""} {
2623 set val "always"
2624# } elseif {$item == "overlay_nocursor" && $val == 0} {
2625# set val 1
2626 }
2627
2628 set default_var($item) $val
2629#puts "default: $item -> $val"
2630 }
2631 }
2632}
2633
2634proc tilde_expand {file} {
2635 global env
2636 if {[file exists $file]} {
2637 return $file
2638 }
2639
2640 set user ""
2641 if {[info exists env(USER)]} {
2642 set user $env(USER)
2643 }
2644 if {$user == "" && [info exists env(LOGNAME)]} {
2645 set user $env(LOGNAME)
2646 }
2647
2648 set home ""
2649 if {[info exists env(HOME)]} {
2650 set home $env(HOME)
2651 } elseif {$user != ""} {
2652 set home "/home/$user"
2653 }
2654
2655 if {[regexp {^~} $file]} {
2656 if {[regexp {^~/} $file]} {
2657 if {$home != ""} {
2658 regsub {^~} $file $home file
2659 }
2660 } else {
2661 regsub {^~} $file "/home/" file
2662 }
2663 }
2664 return $file
2665}
2666
2667proc insert_cmdline_vars {} {
2668 global env cmd_var menu_var default_var x11vnc_cmdline
2669 if {![info exists x11vnc_cmdline]} {
2670 return
2671 }
2672 if {$x11vnc_cmdline == ""} {
2673 return
2674 }
2675 set cmd_var(novar) 1
2676 set str [string trim $x11vnc_cmdline]
2677
2678 while {[regexp -- {^-} $str]} {
2679 if {[regexp -- {^--*([^ \t][^ \t]*)(.*)$} $str m var rest]} {
2680 set rest [string trim $rest]
2681 set var [string trim $var]
2682 if {[regexp {^\{\{([^\}]*)\}\}(.*)} $rest m val rest]} {
2683 set str [string trim $rest]
2684 set cmd_var($var) $val
2685 } else {
2686 set str $rest
2687 set cmd_var($var) "boolean"
2688 }
2689 } else {
2690 break
2691 }
2692 }
2693
2694 if {[info exists cmd_var(rc)]} {
2695 load_settings $cmd_var(rc)
2696 } elseif {[info exists cmd_var(norc)]} {
2697 ;
2698 } else {
2699 set filex [tilde_expand "~/.x11vncrc"]
2700 if {[file exists $filex]} {
2701 load_settings $filex
2702 }
2703 }
2704
2705 foreach var [array names cmd_var] {
2706 if {$var == "novar"} {
2707 continue
2708 }
2709 if {[regexp {^[ \t]*$} $var]} {
2710 continue
2711 }
2712 if {[info exists menu_var($var)]} {
2713 if {$cmd_var($var) == "boolean"} {
2714 set menu_var($var) 1
2715 } else {
2716 set menu_var($var) $cmd_var($var)
2717 }
2718 }
2719 }
2720}
2721
2722proc copy_default_vars {} {
2723 global menu_var default_var
2724 foreach item [array names default_var] {
2725 if {[info exists menu_var($item)]} {
2726 if {[info exists default_var($item)]} {
2727 set menu_var($item) $default_var($item)
2728 }
2729 }
2730 }
2731 foreach item [array names menu_var] {
2732 if {[info exists default_var($item)]} {
2733 set menu_var($item) $default_var($item)
2734 }
2735 }
2736}
2737
2738proc update_menu_vars {{query ""}} {
2739 global all_settings menu_var query_result_list
2740 global x11vnc_icon_mode
2741
2742 set debug [in_debug_mode]
2743
2744 if {$query == "USE_LIST"} {
2745 ;
2746 } elseif {$query == ""} {
2747 set query_result_list [split_query $all_settings]
2748 } else {
2749 set query_result_list [split_query $query]
2750 }
2751
2752 foreach piece $query_result_list {
2753#puts stderr "UMV: $piece"
2754 if [regexp {icon_mode:0} $piece] {
2755 set x11vnc_icon_mode 0
2756 #puts stderr "x11vnc_icon_mode: $x11vnc_icon_mode"
2757 }
2758 if [regexp {icon_mode:1} $piece] {
2759 set x11vnc_icon_mode 1
2760 #puts stderr "x11vnc_icon_mode: $x11vnc_icon_mode"
2761 }
2762 # XXX ipv6
2763 if {[regexp {^([^:][^:]*):(.*)$} $piece m0 item val]} {
2764 if {[info exists menu_var($item)]} {
2765 set old $menu_var($item)
2766#puts stderr " $old"
2767 if {$val == "N/A"} {
2768 continue
2769 }
2770 set menu_var($item) $val
2771 }
2772 if {$item == "clients"} {
2773 update_clients_menu $val
2774 } elseif {$item == "display"} {
2775 set_x11_display $val
2776 } elseif {$item == "vncdisplay"} {
2777 set_vnc_display $val
2778 } elseif {$item == "http_url"} {
2779 set_vnc_url $val
2780 }
2781 }
2782 }
2783}
2784
2785proc load_settings {{file ""}} {
2786 global menu_var default_var env
2787
2788 if {$file == ""} {
2789 if {![info exists menu_var(load-settings)]} {
2790 return
2791 }
2792 set file $menu_var(load-settings)
2793 }
2794 if {$file == ""} {
2795 return
2796 }
2797
2798 set fh ""
2799 set filex [tilde_expand $file]
2800 catch {set fh [open $filex "r"]}
2801
2802 if {$fh == ""} {
2803 append_text "load_settings: *** failed to open $filex ***\n"
2804 return
2805 }
2806 copy_default_vars
2807
2808 set str ""
2809 while {[gets $fh line] > -1} {
2810 regsub -all {\\#} $line {__QUOTED_HASH__} line
2811 if {[regexp {^[ \t]*#} $line]} {
2812 continue
2813 }
2814 for {set i 0} {$i < 5} {incr i} {
2815 regsub {#.*$} $line "" line
2816 }
2817 if {[regexp {^[ \t]*$} $line]} {
2818 continue
2819 }
2820 regsub -all {__QUOTED_HASH__} $line {#} line
2821 if {[regexp {\\$} $line]} {
2822 regsub {\\$} $line " " line
2823 append str "$line"
2824 } else {
2825 append str "$line\n"
2826 }
2827 }
2828 close $fh
2829
2830 set count 0
2831 set parms ""
2832
2833 foreach line [split $str "\n"] {
2834 set line [string trim $line]
2835 regsub {^--*} $line "" line
2836 regsub -all {[ \t][ \t]*} $line " " line
2837 set list [split $line]
2838 set item [lindex $list 0]
2839 set value [lindex $list 1]
2840 if {[regexp {^[ \t]*$} $item]} {
2841 continue
2842 }
2843 if {$item == "gui"} {
2844 continue
2845 }
2846 if {[info exists menu_var($item)]} {
2847 if {[value_is_bool $item]} {
2848 set menu_var($item) 1
2849 incr count
2850 append parms " -$item\n"
2851 } elseif {[value_is_string $item]} {
2852 if {$value != ""} {
2853 set menu_var($item) $value
2854 set nitem [get_nitem $item]
2855 append parms " -$nitem $value\n"
2856 incr count
2857 }
2858 }
2859 }
2860 }
2861 append_text "loaded $count parameter settings from $filex"
2862 if {$count > 0} {
2863 append_text ":\n"
2864 append_text $parms
2865 } else {
2866 append_text ".\n"
2867 }
2868}
2869
2870proc save_settings {} {
2871 set rc_text [get_settings_rcfile]
2872
2873 set top "#
2874# This file is based on the current x11vnc settings and can be used as
2875# as a ~/.x11vncrc defaults file. If saved to another filename, these
2876# settings can be passed to x11vnc at startup via \"-rc <filename>\".
2877#
2878# The rc file comment character is \"#\". Use \"\\#\" for the literal char.
2879# You can continue lines using \"\\\" as the last character of a line.
2880#
2881# Lines beginning with \"#d\" indicate the parameter value is at its default
2882# setting and you probably want to leave it commented out.
2883#
2884# Lines beginning with \"#?\" indicate parameters you probably do not
2885# want to hardwire to the current setting (uncomment if you want that).
2886#
2887# Some parameters are boolean, e.g. -forever, and take no value; while
2888# the others, e.g. -wait 50, take a string or numerical value.
2889#
2890# For booleans, the line will end with comment \"default: on\" or
2891# \"default: off\" indicating the default setting. (Note: often
2892# \"-nofoobar\" corresponds to option \"-foobar\" and the former is
2893# \"the default\", e.g. -norepeat).
2894#
2895# For string or numerical options, the value \"\" in a line below
2896# means the default is unset and you will need to supply some non-empty
2897# value to use the parameter. For reference, if the default differs
2898# from your value it placed at the end of the line as a comment.
2899#
2900# Feel free to uncomment or comment any of the lines or to change any
2901# of the values of the parameters. Don't be surprised that most if not
2902# all of the lines below are commented out (x11vnc has so many parameters,
2903# most of them will be at their default values).
2904#-------------------------------------------------------------------------
2905
2906"
2907
2908 set rc_text "$top$rc_text"
2909
2910 global env save_settings_var save_settings_var_ok
2911 if {[info exists env(HOME)]} {
2912 set save_settings_var "$env(HOME)/.x11vncrc"
2913 } else {
2914 set save_settings_var ".x11vncrc"
2915 }
2916 set save_settings_var_ok 0
2917
2918 set w [textwin "save_settings" "Save Settings..." $rc_text \
2919 "save_settings_var+Save as:"]
2920
2921 tkwait window $w
2922
2923 if {$save_settings_var_ok == 1} {
2924 set file $save_settings_var
2925 if {$file == ""} {
2926 return
2927 }
2928 set file [tilde_expand $file]
2929 append_text "\nSaving current settings to $file ...\n"
2930 if {[file exists $file]} {
2931 set backup "${file}~"
2932 append_text "Backing up $file -> $backup ...\n"
2933 catch {file delete -force $backup}
2934 set emsg "*** Backup to $backup failed. ***\n"
2935 if {![file exists $backup]} {
2936 catch {file copy -force $file $backup}
2937 if {![file exists $backup]} {
2938 append_text $emsg
2939 bell
2940 }
2941 } else {
2942 append_text $emsg
2943 bell
2944 }
2945 }
2946 set fh ""
2947 catch {set fh [open $file "w"]}
2948 if {$fh != ""} {
2949 puts $fh $rc_text
2950 close $fh
2951 if {![file exists $file]} {
2952 append_text "*** Saving to $file failed. ***\n"
2953 bell
2954 } else {
2955 append_text "Done.\n"
2956 }
2957 } else {
2958 append_text "*** Open of $file failed. ***\n"
2959 bell
2960 }
2961 }
2962}
2963
2964proc clear_all {} {
2965 global menu_var unset_str
2966
2967 set debug [in_debug_mode]
2968
2969 foreach item [array names menu_var] {
2970 if {$item == "debug_gui"} {
2971 continue
2972 }
2973 if {[info exists menu_var($item)]} {
2974 if {[is_action $item]} {
2975 set menu_var($item) ""
2976 } elseif {[value_is_bool $item]} {
2977 set menu_var($item) 0
2978 } elseif {[value_is_string $item]} {
2979 set menu_var($item) $unset_str
2980 }
2981 }
2982 }
2983 append_text "Cleared all settings.\n"
2984}
2985
2986proc defaults_all {} {
2987 copy_default_vars
2988 append_text "Reset all variables to default values.\n"
2989}
2990
2991proc all_query_vars {} {
2992 global query_ans_list query_aro_list all_settings
2993 global cache_all_query_vars
2994
2995 if {$cache_all_query_vars != ""} {
2996 return $cache_all_query_vars
2997 }
2998
2999 set qry ""
3000 foreach item $query_ans_list {
3001 if {$qry == ""} {
3002 set qry $item
3003 } else {
3004 append qry ",$item"
3005 }
3006 }
3007 foreach item $query_aro_list {
3008 if {$qry == ""} {
3009 set qry $item
3010 } else {
3011 append qry ",$item"
3012 }
3013 }
3014 set cache_all_query_vars $qry
3015
3016 global env
3017 if [info exists env(TKX11VNC_PRINT_ALL_VARS)] {
3018 puts "--------------- BEGIN ALL VARS ---------------"
3019 puts $qry
3020 puts "--------------- END ALL VARS ---------------"
3021 }
3022
3023 return $qry
3024}
3025
3026proc query_all {{quiet 0}} {
3027 global query_ans_list query_aro_list all_settings
3028 global last_query_all_time
3029
3030 dtime 1
3031 set qry [all_query_vars]
3032
3033 set qargs [list "-Q" $qry]
3034 set all [run_remote_cmd $qargs]
3035
3036 if {[regexp {ans=} $all]} {
3037 if {! $quiet} {
3038 append_text "Retrieved all current settings.\n"
3039 }
3040 set all_settings $all
3041 update_menu_vars $all
3042 } else {
3043 if {! $quiet} {
3044 append_text "Failed to retrieve current settings.\n"
3045 }
3046 }
3047 set last_query_all_time [clock seconds]
3048 dtime 2
3049 return $all
3050}
3051
3052proc set_info {str} {
3053 global info_str info_label
3054#set w1 [$info_label cget -width]
3055#set w2 [winfo width $info_label]
3056#puts "set_info: w=$w1 winfo=$w2"
3057#append_text "$str\n"
3058 set info_str "$str"
3059 update
3060}
3061
3062proc append_text {str} {
3063 global text_area text_area_str
3064
3065 if {![info exists text_area_str]} {
3066 set text_area_str ""
3067 }
3068 append text_area_str $str
3069
3070 if {![info exists text_area]} {
3071 puts stderr $str
3072 return
3073 }
3074 if {$text_area == ""} {
3075 puts stderr $str
3076 return
3077 }
3078 if {![winfo exists $text_area]} {
3079 puts stderr $str
3080 return
3081 }
3082
3083 $text_area insert end $str
3084 $text_area see end
3085}
3086
3087proc show_all_settings {} {
3088 global all_settings
3089 global client_sock client_tail
3090 global x11vnc_client_file
3091
3092 set txt "\nRead-Write settings:\n\n"
3093 foreach item [split_query $all_settings] {
3094 regsub {:} $item {: } item
3095 append txt " $item\n"
3096 if {[regexp {noremote} $item]} {
3097 append txt "\nRead-Only settings:\n\n"
3098 }
3099 }
3100 append txt "\nInternal settings:\n\n"
3101 append txt "x11vnc_client_file: $x11vnc_client_file\n"
3102 if {[info exists client_tail]} {
3103 append txt "client_tail: $client_tail\n"
3104 } else {
3105 append txt "client_tail: unset\n"
3106 }
3107 if {[info exists client_sock]} {
3108 append txt "client_sock: $client_sock\n"
3109 } else {
3110 append txt "client_sock: unset\n"
3111 }
3112 set estr ""
3113 catch {set estr [exec env | grep -i X11VNC]}
3114 append txt "$estr\n"
3115 textwin "Settings" "All Current Settings" $txt
3116}
3117
3118proc show_logfile {} {
3119 global menu_var unset_str
3120
3121 set logfile [tilde_expand $menu_var(logfile)]
3122
3123 if {$logfile == "" || $logfile == $unset_str} {
3124 set txt "\nNo logfile was specified at x11vnc startup.\n\n"
3125 } elseif {![file exists $logfile]} {
3126 set txt "\nLogfile \"$logfile\" does not exist.\n\n"
3127 } else {
3128 set fh "-3"
3129 set err ""
3130 catch {set fh [open $logfile "r"]} err
3131 if {$fh == "-3"} {
3132 set txt "\nError opening \"$logfile\" $err.\n\n"
3133 } else {
3134 set txt "\nLogfile \"$logfile\" current contents:\n"
3135 while {[gets $fh line] > -1} {
3136 append txt "$line\n"
3137 }
3138 close $fh
3139 }
3140 }
3141 textwin "Logfile" "Logfile" $txt
3142}
3143
3144proc tail_logfile {} {
3145 global menu_var unset_str ffont
3146 set logfile $menu_var(logfile)
3147
3148 set txt ""
3149 if {$logfile == "" || $logfile == $unset_str} {
3150 set txt "\nNo logfile was specified at x11vnc startup.\n\n"
3151 } elseif {![file exists $logfile]} {
3152 set txt "\nLogfile \"$logfile\" does not exist.\n\n"
3153 } else {
3154 set cmd ""
3155 set xterm_cmd "xterm -sb -fn $ffont -geometry 80x45 -title x11vnc-logfile -e"
3156 set cmd [split $xterm_cmd]
3157 lappend cmd "tail"
3158 lappend cmd "-3000f"
3159 lappend cmd $logfile
3160 lappend cmd "&"
3161 catch {[eval exec $cmd]}
3162 }
3163 if {$txt != ""} {
3164 textwin "Logfile" "Logfile" $txt
3165 }
3166}
3167
3168proc set_connected {yesno} {
3169 global connected_to_x11vnc
3170 set orig $connected_to_x11vnc
3171
3172 if {$yesno == "yes"} {
3173 set connected_to_x11vnc 1
3174 } else {
3175 set connected_to_x11vnc 0
3176 no_x11_display
3177 no_vnc_display
3178 }
3179 if {$orig != $connected_to_x11vnc} {
3180 set_widgets
3181 }
3182}
3183
3184proc detach_from_display {} {
3185 global connected_to_x11vnc reply_xdisplay x11vnc_xdisplay
3186 set str "Detaching from X display."
3187 if {$reply_xdisplay != ""} {
3188 set str "Detaching from $reply_xdisplay."
3189 } elseif {$x11vnc_xdisplay != ""} {
3190 set str "Detaching from $x11vnc_xdisplay."
3191 }
3192 if {$connected_to_x11vnc} {
3193 append_text "$str\n"
3194 }
3195 set_connected no
3196}
3197
3198proc do_stop_quit {} {
3199 push_new_value "stop" "stop" 1 0
3200 set_connected no
3201 update
3202 after 250
3203 destroy .
3204}
3205
3206# Menu item is an action:
3207proc do_action {item} {
3208 global menu_var connected_to_x11vnc beginner_mode
3209
3210 if {[in_debug_mode]} {
3211 append_text "action: \"$item\"\n"
3212 }
3213#puts "action: \"$item\"\n"
3214
3215 if {$item == "ping"} {
3216 if {$beginner_mode} {
3217 try_connect_and_query_all
3218 } else {
3219 try_connect
3220 }
3221 return
3222 } elseif {$item == "start"} {
3223 start_x11vnc
3224 return
3225 } elseif {$item == "detach"} {
3226 detach_from_display
3227 return
3228 } elseif {$item == "attach"} {
3229 try_connect_and_query_all
3230 return
3231 } elseif {$item == "update-all"} {
3232 query_all
3233 return
3234 } elseif {$item == "clear-all"} {
3235 clear_all
3236 return
3237 } elseif {$item == "defaults-all"} {
3238 defaults_all
3239 return
3240 } elseif {$item == "save-settings"} {
3241 save_settings
3242 return
3243 } elseif {$item == "show-start-cmd"} {
3244 show_start_cmd
3245 return
3246 } elseif {$item == "all-settings"} {
3247 show_all_settings
3248 return
3249 } elseif {$item == "show-logfile"} {
3250 show_logfile
3251 return
3252 } elseif {$item == "tail-logfile"} {
3253 tail_logfile
3254 return
3255 } elseif {$item == "Misc-Tuning:"} {
3256 menu_help "$item"
3257 return
3258 } elseif {$item == "WindowView"} {
3259 change_view_state
3260 return
3261 } elseif {$item == "quit" || $item == "Quit"} {
3262 destroy .
3263 exit 0
3264 } elseif {$item == "stop+quit"} {
3265 do_stop_quit
3266 }
3267
3268 if {[value_is_string $item]} {
3269 if {! [entry_dialog $item]} {
3270 return
3271 }
3272 set new $menu_var($item)
3273 set name $item
3274 } else {
3275 set new 1
3276 set name $item
3277 }
3278
3279 if {$item == "load-settings"} {
3280 load_settings
3281 return
3282 }
3283
3284 if {! $connected_to_x11vnc} {
3285 ;
3286 } elseif {[regexp {^(stop|quit|exit|shutdown)$} $item]} {
3287 # just do -R
3288 append_text "stopping remote x11vnc server...\n"
3289 push_new_value $item $name $new 0
3290 set_connected no
3291
3292 } elseif {[opt_match Q $item]} {
3293 push_new_value $item $name $new 1
3294 } else {
3295 push_new_value $item $name $new 0
3296 }
3297}
3298
3299proc ptime {time} {
3300 set usec [lindex [split $time] 0]
3301 set sec [format "%.3f" [expr "$usec / 1000000.0"]]
3302 puts "time: $sec secs."
3303}
3304
3305proc do_var {item} {
3306 global connected_to_x11vnc item_cascade menu_var
3307
3308 set debug [in_debug_mode]
3309
3310 set string 0
3311 if {[is_action $item] || $item == "WindowView"} {
3312 # Menu item is action:
3313 if {$debug} {
3314 ptime [time {do_action $item}]
3315 } else {
3316 do_action $item
3317 }
3318 return
3319 }
3320
3321 if {[value_is_string $item]} {
3322 # Menu item is a string:
3323 if {$item_cascade($item) != ""} {
3324 # Cascade sets variable automatically
3325 } else {
3326 # Otherwise Entry box
3327 if {![entry_dialog $item]} {
3328 return
3329 }
3330 }
3331 set new $menu_var($item)
3332 set name $item
3333 } else {
3334 # Menu item is a boolean:
3335 set name [check_var $item]
3336 if {$name == ""} {
3337 return
3338 }
3339 set new 1
3340 }
3341 if {$connected_to_x11vnc} {
3342 if {$debug} {
3343 ptime [time {push_new_value $item $name $new 1}]
3344 } else {
3345 push_new_value $item $name $new 1
3346 }
3347
3348 if {$item == "http"} {
3349 global vnc_url
3350 append_text " URL: $vnc_url\n"
3351 }
3352 }
3353}
3354
3355proc menu_help {item} {
3356 if ![help_win $item] {
3357 textwin "nohelp" "No help available" \
3358 "Sorry, no help avaiable for \"$item\""
3359 }
3360}
3361
3362proc opt_match {c item} {
3363 global item_opts
3364 if {[info exists item_opts($item)]} {
3365 if {[regexp "^\[A-z\]*$c" $item_opts($item)]} {
3366 return 1
3367 }
3368 }
3369 return 0
3370}
3371
3372proc is_action {item} {
3373 return [opt_match A $item]
3374}
3375
3376proc is_gui_internal {item} {
3377 if {$item == "Properties"} {
3378 return 1
3379 }
3380 if {$item == "Tray"} {
3381 return 1
3382 }
3383 return [opt_match G $item]
3384}
3385
3386proc is_browse {item} {
3387 return [opt_match F $item]
3388}
3389
3390proc value_is_string {item} {
3391 global item_bool
3392 if {![info exists item_bool($item)]} {
3393 return 0
3394 }
3395 if {! $item_bool($item)} {
3396 return 1
3397 } else {
3398 return 0
3399 }
3400}
3401
3402proc value_is_bool {item} {
3403 global item_bool
3404 if {![info exists item_bool($item)]} {
3405 return 0
3406 }
3407 if {$item_bool($item)} {
3408 return 1
3409 } else {
3410 return 0
3411 }
3412}
3413
3414proc split_query0 {query} {
3415 # original slower way with regexp/regsub
3416 regsub -all {aro=} $query {ans=} query
3417 set items {}
3418 while {1} {
3419 if {! [regexp {^ans=(.*)$} $query m0 m1]} {
3420 break
3421 }
3422 set item $m1
3423 set m2 ""
3424 regexp {,ans=.*$} $item m2
3425 regsub {,ans=.*$} $item "" item
3426 if {$item != ""} {
3427 lappend items $item
3428 }
3429 set query $m2
3430 regsub {^,} $query "" query
3431 }
3432 return $items
3433}
3434
3435proc split_query {query} {
3436 regsub -all {aro=} $query {ans=} query
3437 set items {}
3438 while {1} {
3439 set n [string first "ans=" $query]
3440 if {$n < 0} {
3441 break
3442 }
3443 set from [expr $n+4]
3444
3445 set m [string first ",ans=" $query]
3446 if {$m < 0} {
3447 set more 0
3448 set item [string range $query $from end]
3449 } else {
3450 set more 1
3451 set to [expr $m-1]
3452 set item [string range $query $from $to]
3453 }
3454 if {$item != ""} {
3455 lappend items $item
3456 }
3457 if {$more} {
3458 incr m
3459 set query [string range $query $m end]
3460 } else {
3461 set query ""
3462 }
3463 }
3464 return $items
3465}
3466
3467proc set_x11_display {name} {
3468 global x11_display
3469 set x11_display "x11vnc X display: $name"
3470 set_name "tkx11vnc - $name"
3471}
3472proc set_vnc_display {name} {
3473 global vnc_display icon_mode
3474 set vnc_display "VNC display: $name"
3475
3476 if {$icon_mode} {
3477 set_icon_label
3478 }
3479}
3480proc set_vnc_url {name} {
3481 global vnc_url
3482 set vnc_url $name
3483}
3484proc no_x11_display {} {
3485 set_x11_display "(*none*)"
3486 set_name "tkx11vnc"
3487}
3488proc no_vnc_display {} {
3489 set_vnc_display "(*none*)"
3490}
3491proc no_vnc_url {} {
3492 set_vnc_url "(*none*)"
3493}
3494
3495proc get_vnc_display_number {} {
3496 global vnc_display
3497 if ![info exists vnc_display] {
3498 return "none"
3499 }
3500 if {$vnc_display == ""} {
3501 return "none"
3502 }
3503 set str $vnc_display
3504 regsub {VNC display: *} $str "" str
3505 if [regexp {:([0-9][0-9]*)} $str m0 n] {
3506 return $n
3507 }
3508 return "none"
3509}
3510
3511proc fetch_displays {} {
3512
3513 set qargs [list "-Q" "display,vncdisplay"]
3514 set result [run_remote_cmd $qargs]
3515
3516 set got_x11 0
3517 set got_vnc 0
3518 set got_url 0
3519
3520 foreach item [split_query $result] {
3521 if {[regexp {^display:(.*)$} $item m0 m1]} {
3522 set_x11_display $m1
3523 set got_x11 1
3524 } elseif {[regexp {^vncdisplay:(.*)$} $item m0 m1]} {
3525 set_vnc_display $m1
3526 set got_vnc 1
3527 } elseif {[regexp {^http_url:(.*)$} $item m0 m1]} {
3528 set_vnc_url $m1
3529 set got_url 1
3530 }
3531 }
3532 if {! $got_x11} {
3533 no_x11_display
3534 }
3535 if {! $got_vnc} {
3536 no_vnc_display
3537 }
3538 if {! $got_url} {
3539 no_vnc_url
3540 }
3541}
3542
3543proc client_dialog {client} {
3544 set cid ""
3545 set host ""
3546 set ip ""
3547 global menu_var text_area cleanup_window item_bool
3548
3549 #<id>:<ip>:<port>:<user>:<unix>:<hostname>:<input>:<loginview>:<time>
3550 append_text "\nClient info string:\n - $client\n\n"
3551 if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \
3552 $client m0 m1 m2 m3 m4 m5 m6 m7 m8 m9]} {
3553 set cid $m1
3554 set ip $m2
3555 set port $m3
3556 set user $m4
3557 set unix $m5
3558 set host $m6
3559 regsub {\..*$} $host "" host
3560 set input $m7
3561 set logvo $m8
3562 set ltime $m9
3563 append_text "Host: $host, Port: $port, User: $user"
3564 if {$unix != "" && $unix != "none"} {
3565 append_text ", Unix: $unix"
3566 }
3567 append_text ", IP: $ip, Id: $cid\n"
3568 append_text " - originally logged in as: "
3569 if {$logvo == "1" } {
3570 append_text "View-Only Client"
3571 } else {
3572 append_text "Normal Client"
3573 }
3574 if {$ltime != ""} {
3575 set tim [clock format $ltime]
3576 append_text ", $tim"
3577 }
3578 append_text "\n"
3579 append_text " - currently allowed input: "
3580 set sk 0
3581 set sm 0
3582 set sb 0
3583 set sc 0
3584 set sf 0
3585 if {[regexp -nocase {K} $input]} {
3586 append_text "Keystrokes"
3587 set sk 1
3588 }
3589 if {[regexp -nocase {M} $input]} {
3590 if {$sk} {
3591 append_text ", "
3592 }
3593 append_text "Mouse-Motion"
3594 set sm 1
3595 }
3596 if {[regexp -nocase {B} $input]} {
3597 if {$sk || $sm} {
3598 append_text ", "
3599 }
3600 append_text "Button-Click"
3601 set sb 1
3602 }
3603 if {[regexp -nocase {C} $input]} {
3604 if {$sk || $sm || $sb} {
3605 append_text ", "
3606 }
3607 append_text "Clipboard"
3608 set sm 1
3609 }
3610 if {[regexp -nocase {F} $input]} {
3611 if {$sk || $sm || $sb || $sf} {
3612 append_text ", "
3613 }
3614 append_text "Files"
3615 set sf 1
3616 }
3617 if {! $sk && ! $sm && ! $sb && ! $sm && ! $sf} {
3618 append_text "None"
3619 }
3620 append_text "\n"
3621 }
3622 if {$cid == ""} {
3623 append_text "Invalid client info string: $client\n"
3624 return
3625 }
3626
3627 regsub -all {_} $input "" input
3628 set menu_var(client) "$input"
3629 set item_bool(client) 0
3630
3631 insert_client_action_window $input
3632 set rc [entry_dialog client 1]
3633
3634 cleanup_text_window
3635
3636 set val $menu_var(client)
3637 #puts "rc: $rc val: $val"
3638
3639 if {! $rc} {
3640 return;
3641 } elseif {[regexp -nocase {(disconnect|close)} $val]} {
3642 disconnect_dialog $client
3643 } else {
3644 regsub -all -nocase {[^KMBCF]} $val "" val
3645 set item_bool(client_input) 0
3646 push_new_value "client_input" "client_input" "$cid:$val" 0
3647 }
3648}
3649
3650proc disconnect_dialog {client} {
3651 set cid ""
3652 set host ""
3653 set msg "\n"
3654 append msg "*** Client info string:\n $client\n"
3655 if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \
3656 $client m0 m1 m2 m3 m4 m5 m6 m7 m8 m9]} {
3657 set cid $m1
3658 set ip $m2
3659 set port $m3
3660 set user $m4
3661 set unix $m5
3662 set host $m6
3663 regsub {\..*$} $host "" host
3664 set input $m7
3665 set logvo $m8
3666 set ltime $m9
3667 append_text "Host: $host, Port: $port, IP: $ip, User: $user"
3668 if {$unix != "" && $unix != "none"} {
3669 append_text ", Unix: $unix"
3670 }
3671 append_text ", Id: $cid\n"
3672 }
3673 if {$cid == ""} {
3674 append_text "Invalid client info string: $client\n"
3675 return
3676 }
3677 append msg "*** To *DISCONNECT* this client press \"OK\" again, otherwise press \"Cancel\"\n"
3678 bell
3679 if {[warning_dialog $msg "current"]} {
3680 push_new_value "disconnect" "disconnect" $cid 1
3681 } else {
3682 append_text "disconnect cancelled.\n"
3683 }
3684}
3685
3686proc update_clients_and_repost {} {
3687 global item_cascade menu_m menu_b
3688
3689 append_text "Refreshing connected clients list... "
3690 query_all 1
3691 update
3692
3693 set saw 0
3694 set casc $item_cascade(current)
3695 set last [$casc index end]
3696 for {set i 0} {$i <= $last} {incr i} {
3697 if {[$casc type $i] == "separator"} {
3698 continue
3699 }
3700 set name [$casc entrycget $i -label]
3701 if {[regexp {^num-clients} $name]} {
3702 continue
3703 }
3704 if {[regexp {^refresh-list} $name]} {
3705 continue
3706 }
3707 if {! $saw} {
3708 append_text "\n"
3709 }
3710 set saw 1
3711 append_text "client: $name\n"
3712 }
3713 if {! $saw} {
3714 append_text "done.\n"
3715 }
3716}
3717
3718proc update_clients_menu {list} {
3719 global item_cascade ffont
3720 global saved_clients_str
3721
3722 if {![info exists saved_clients_str]} {
3723 set saved_clients_str ""
3724 }
3725 if {$list == "INIT"} {
3726 set list $saved_clients_str
3727 } else {
3728 set saved_clients_str $list
3729 }
3730
3731 set subm $item_cascade(current);
3732 catch {destroy $subm}
3733 menu $subm -tearoff 0 -font $ffont
3734 $subm add command
3735 $subm add command -label "refresh-list" \
3736 -command "update_clients_and_repost"
3737 $subm add separator
3738 set count 0
3739 foreach client [split $list ","] {
3740 if {![regexp {^[a-z0-9]*[a-z0-9]:} $client]} {
3741 #append_text "Skipping client line: "
3742 #append_text $client
3743 #append_text "\n"
3744 continue
3745 }
3746 regsub -all {[{}()~!$&*|;'"`{}<>\[\]]} $client "" client
3747 #'
3748 if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \
3749 $client m0 m1 m2 m3 m4 m5 m6 m7 m8 m9]} {
3750 set id $m1
3751 set user $m4
3752 set unix $m5
3753 set host $m6
3754 regsub {\..*$} $host "" host
3755 set clabel "$host $id"
3756 if {$unix != "" && $unix != "none"} {
3757 set clabel "$unix@$clabel"
3758 } elseif {$user != "unknown-user"} {
3759 set clabel "$user@$clabel"
3760 }
3761 } else {
3762 regsub {:.*$} $client "" clabel
3763 }
3764 $subm add command -label "$clabel" \
3765 -command "client_dialog \{$client\}"
3766 incr count
3767 }
3768 $subm entryconfigure 0 -label "num-clients: $count"
3769}
3770
3771proc set_widgets {} {
3772 global connected_to_x11vnc item_case item_menu item_entry menu_m
3773
3774 foreach item [array names item_case] {
3775 if ![info exists item_case($item)] { continue; }
3776 set case $item_case($item)
3777 if ![info exists item_menu($item)] { continue; }
3778 set menu $item_menu($item)
3779 if ![info exists item_entry($item)] { continue; }
3780 set entry $item_entry($item)
3781 if {$entry < 0} {
3782 # skip case under beginner_mode
3783 continue
3784 }
3785 set type [$menu type $entry]
3786 if {$type == "separator" || $type == "tearoff"} {
3787 continue
3788 }
3789 if {![winfo exists $menu]} {
3790 continue
3791 }
3792 if {$connected_to_x11vnc} {
3793 if {[active_when_connected $item]} {
3794 $menu entryconfigure $entry -state normal
3795 } else {
3796 $menu entryconfigure $entry -state disabled
3797 }
3798 } else {
3799 if {[active_when_starting $item]} {
3800 $menu entryconfigure $entry -state normal
3801 } else {
3802 $menu entryconfigure $entry -state disabled
3803 }
3804 }
3805 }
3806}
3807
3808proc toggle_simple_gui {} {
3809 global beginner_mode simple_gui_created
3810 global connected_to_x11vnc make_gui_count
3811
3812 if {$beginner_mode} {
3813 append_text "\nSwitching to simple-gui mode.\n"
3814 } else {
3815 append_text "\nSwitching to power-user gui mode.\n"
3816 }
3817
3818 if {$make_gui_count == 1} {
3819 incr make_gui_count
3820 }
3821 set simple_gui_created 1
3822 make_menu_items
3823 set_widgets
3824 set_internal_help
3825 append_text "\n"
3826}
3827
3828proc little_qs {m} {
3829 global bfont ffont beginner_mode
3830 global helpremote helptext helplabel
3831 global tk_version osname
3832
3833 if {$tk_version < 8.0} {
3834 return
3835 }
3836 if {$osname == "Darwin"} {
3837 return
3838 }
3839
3840 set n [$m index end]
3841
3842 for {set i 0} {$i <= $n} {incr i} {
3843 set type [$m type $i]
3844#puts "$m - $i - $type"
3845 if {$type == "separator"} {
3846 $m add separator
3847 } elseif {$type == "tearoff"} {
3848 continue;
3849 } else {
3850 set label [$m entrycget $i -label]
3851 set str ""
3852 if {[info exists helpremote($label)]} {
3853 set str "(?)"
3854 } elseif {[info exists helptext($label)]} {
3855 set str "(?)"
3856 }
3857 $m add command -label $str \
3858 -font $ffont \
3859 -command "menu_help $label";
3860
3861 if {$str == ""} {
3862 $m entryconfigure end -state disabled
3863 }
3864 set arg "$m,$i"
3865#puts "helplabel: $arg -> $label"
3866 set helplabel($arg) $label
3867 set j [$m index end]
3868 set arg "$m,$j"
3869 set helplabel($arg) $label
3870 }
3871 if {$i == 0} {
3872 $m entryconfigure end -columnbreak 1
3873 }
3874 }
3875
3876 menu_bindings $m
3877}
3878
3879proc make_menu_items {} {
3880 global template
3881 global menu_b menu_m menu_count
3882 global item_opts item_bool item_case item_menu item_entry menu_var unset_str
3883 global item_cascade
3884 global bfont ffont beginner_mode simple_gui_created
3885 global helptext helpremote helplabel
3886
3887 # some tweaks...
3888 if {![info exists menu_var(deny)]} {
3889 set menu_var(deny) 0
3890 }
3891
3892 set case "";
3893 set L_casc ""
3894 set L_casc_count 0
3895 set L_menus [list]
3896
3897 # Extract the menu items:
3898 foreach line [split $template "\n"] {
3899 if {[regexp {^Row:} $line]} {
3900 continue
3901 }
3902 if {[regexp {^[A-z]} $line]} {
3903 set case [string trim $line]
3904
3905 if {$simple_gui_created} {
3906 set i0 0
3907 #if {$case == "Misc"} { # kludge for simple_gui
3908 # set i0 1
3909 #}
3910 catch {$menu_m($case) delete $i0 end}
3911 }
3912 set menu_count($case) 0
3913 continue;
3914 }
3915
3916 set item [string trim $line]
3917 regsub -all { *} $item " " item
3918 if {$item == ""} {
3919 continue;
3920 }
3921 set opts ""
3922 if {[regexp {^=} $item]} {
3923 set opts [lindex [split $item] 0]
3924 regsub {^=} $opts "" opts
3925 set item [lindex [split $item] 1]
3926 }
3927 if {[regexp {^0} $opts]} {
3928 continue;
3929 }
3930 if {[regexp {:$} $item]} {
3931 set bool 0
3932 } else {
3933 set bool 1
3934 }
3935 regsub {:$} $item {} item
3936
3937 if {$item == "LOFF"} {
3938 set L_casc ""
3939 continue
3940 }
3941
3942 if {$item == "-- D"} {
3943 set beginner_sep 1
3944 set item "--"
3945 } else {
3946 set beginner_sep 0
3947 }
3948
3949 set item_opts($item) $opts
3950 set item_case($item) $case
3951 set item_bool($item) $bool
3952 set item_cascade($item) ""
3953
3954 if {$L_casc == ""} {
3955 set item_entry($item) $menu_count($case)
3956 set m $menu_m($case)
3957 } else {
3958 # hack for cascades for crowded menus. See =GAL opts.
3959 set item_entry($item) $L_casc_count
3960 set m $L_casc
3961 }
3962
3963 set mvar 0
3964
3965 if {$beginner_mode && ! $beginner_sep && ![opt_match D $item]} {
3966 set item_entry($item) "-1"
3967 continue;
3968 }
3969
3970 set item_menu($item) $m
3971
3972 if {0} { puts "ITEM: $item\t- $opts\t- $case\t- \
3973 $bool\t- $menu_count($case)" }
3974
3975 # Create the menu items, its variables, etc., etc.
3976
3977 if {$item == "--"} {
3978 $m add separator
3979
3980 } elseif {$item == "Quit"} {
3981 # Quit item must shut us down:
3982 $m add command -label "$item" -underline 0 \
3983 -font $ffont \
3984 -command {destroy .; exit 0}
3985
3986 } elseif {$case == "Help"} {
3987 # Help is simple help:
3988 $m add command -label "$item" \
3989 -font $ffont \
3990 -command "menu_help $item"
3991
3992 } elseif {[opt_match L $item]} {
3993 # Special sub-menu cascade (=GAL ends with LOFF)
3994 set subm $m.casc_L$menu_count($case)
3995 catch {destroy $subm}
3996 menu $subm -tearoff 0 -font $ffont
3997 set item_cascade($item) $subm
3998 $m add cascade -label "$item" \
3999 -font $ffont \
4000 -menu $subm
4001 set L_casc $subm
4002 set L_casc_count -1
4003 lappend L_menus $L_casc
4004
4005 } elseif {$item == "current"} {
4006 # Current clients cascade
4007 set subm $m.current_cascade
4008 catch {destroy $subm}
4009 set item_cascade($item) $subm
4010 update_clients_menu "INIT"
4011 $m add cascade -label "$item" \
4012 -font $ffont \
4013 -menu $subm
4014
4015 } elseif {[is_action $item]} {
4016 # Action
4017 $m add command -label "$item" \
4018 -font $ffont \
4019 -command "do_var $item"
4020 if {![info exists menu_var($item)]} {
4021 set menu_var($item) ""; # for convenience
4022 }
4023
4024 } elseif {! $item_bool($item)} {
4025 # String
4026 if {[regexp -- {-C:(.*)} $item_opts($item) m0 m1]} {
4027 # Radiobutton select
4028 set subm $m.radio_cascade$menu_count($case)
4029 catch {destroy $subm}
4030 menu $subm -tearoff 0 -font $ffont
4031 foreach val [split $m1 ","] {
4032 $subm add radiobutton -label "$val" \
4033 -command "do_var $item" \
4034 -value "$val" \
4035 -font $ffont \
4036 -variable menu_var($item)
4037 }
4038 $m add cascade -label "$item" \
4039 -font $ffont \
4040 -menu $subm
4041 set item_cascade($item) $subm
4042 } else {
4043 # Arbitrary_string
4044 $m add command -label "$item" \
4045 -font $ffont \
4046 -command "do_var $item"
4047 }
4048 set mvar 1
4049
4050 } elseif {$item == "simple-gui"} {
4051 $m add checkbutton -label "$item" \
4052 -command "toggle_simple_gui" \
4053 -font $ffont \
4054 -variable beginner_mode
4055 } else {
4056 # Boolean
4057 $m add checkbutton -label "$item" \
4058 -command "do_var $item" \
4059 -font $ffont \
4060 -variable menu_var($item)
4061 if {![info exists menu_var($item)]} {
4062 set menu_var($item) 0
4063 }
4064 }
4065
4066 if {$L_casc_count == -1} {
4067 incr menu_count($case)
4068 incr L_casc_count
4069 } elseif {$L_casc != ""} {
4070 incr L_casc_count
4071 } else {
4072 incr menu_count($case)
4073 }
4074
4075 if {$mvar} {
4076 if {![info exists menu_var($item)]} {
4077 set menu_var($item) $unset_str
4078 }
4079 }
4080 }
4081
4082 # Now make the little "(?)" help buttons
4083 global osname
4084 foreach case [array names menu_m] {
4085 if {$case == "Help"} {
4086 continue;
4087 }
4088 little_qs $menu_m($case);
4089 }
4090 foreach m $L_menus {
4091 little_qs $m
4092 }
4093}
4094
4095proc check_update_vars {} {
4096 global last_query_all_time query_all_freq icon_mode
4097 global connected_to_x11vnc client_tail client_sock
4098
4099 set now [clock seconds]
4100
4101 set delay $query_all_freq
4102 if {$client_tail != "" && $client_sock == ""} {
4103 set delay [expr 2 * $query_all_freq]
4104 }
4105
4106 if {$connected_to_x11vnc} {
4107 set quiet 0
4108 set refresh [expr "$last_query_all_time + $delay"]
4109
4110 # puts "menu_posted $now $last_query_all_time"
4111 # puts "menu_posted $refresh"
4112
4113 if {$now > $refresh} {
4114 append_text "Refreshing current settings... "
4115 query_all $quiet
4116 if {$quiet} {
4117 append_text "done\n"
4118 }
4119 }
4120 }
4121}
4122
4123proc menu_posted {} {
4124 check_update_vars
4125}
4126
4127proc props_widgets {state} {
4128 global props_buttons
4129 foreach w $props_buttons {
4130 $w configure -state $state
4131 }
4132 update
4133}
4134
4135proc props_apply {} {
4136 global props_accept props_confirm props_viewonly props_shared
4137 global props_zeroconf props_javaview props_solid
4138 global props_passwd props_viewpasswd
4139 global prop0_accept prop0_confirm prop0_viewonly prop0_shared
4140 global prop0_zeroconf prop0_javaview prop0_solid
4141 global prop0_passwd prop0_viewpasswd
4142 global menu_var
4143 global client_sock
4144
4145 props_widgets disabled
4146
4147 set aft 500
4148 if {[info exists client_sock]} {
4149 if {$client_sock != ""} {
4150 set aft 150
4151 }
4152 }
4153 set did 0
4154
4155 set fail 0
4156
4157 if {$props_confirm != $prop0_confirm} {
4158 if {$did > 0} {after $aft}; incr did
4159 if {$props_confirm} {
4160 push_new_value "accept" "accept" "popup" 1
4161 } else {
4162 push_new_value "accept" "accept" "" 1
4163 }
4164 if {$menu_var(accept) == "popup"} {
4165 set props_confirm 1
4166 } elseif {$menu_var(accept) == ""} {
4167 set props_confirm 0
4168 }
4169 if {$props_confirm == $prop0_confirm} {incr fail}
4170 set prop0_confirm $props_confirm
4171 }
4172
4173 if {$props_viewonly != $prop0_viewonly} {
4174 if {$did > 0} {after $aft}; incr did
4175 if {$props_viewonly} {
4176 push_new_value "viewonly" "viewonly" 1 1
4177 } else {
4178 push_new_value "viewonly" "noviewonly" 1 1
4179 }
4180 if {$menu_var(viewonly)} {
4181 set props_viewonly 1
4182 } else {
4183 set props_viewonly 0
4184 }
4185 if {$props_viewonly == $prop0_viewonly} {incr fail}
4186 set prop0_viewonly $props_viewonly
4187 }
4188
4189 if {$props_shared != $prop0_shared} {
4190 if {$did > 0} {after $aft}; incr did
4191 if {$props_shared} {
4192 push_new_value "shared" "shared" 1 1
4193 } else {
4194 push_new_value "shared" "noshared" 1 1
4195 }
4196 if {$menu_var(shared)} {
4197 set props_shared 1
4198 } else {
4199 set props_shared 0
4200 }
4201 if {$props_shared == $prop0_shared} {incr fail}
4202 set prop0_shared $props_shared
4203 }
4204
4205 if {$props_zeroconf != $prop0_zeroconf} {
4206 if {$did > 0} {after $aft}; incr did
4207 if {$props_zeroconf} {
4208 push_new_value "zeroconf" "zeroconf" 1 1
4209 } else {
4210 push_new_value "zeroconf" "nozeroconf" 1 1
4211 }
4212 if {$menu_var(zeroconf)} {
4213 set props_zeroconf 1
4214 } else {
4215 set props_zeroconf 0
4216 }
4217 if {$props_zeroconf == $prop0_zeroconf} {incr fail}
4218 set prop0_zeroconf $props_zeroconf
4219 }
4220
4221 if {$props_javaview != $prop0_javaview} {
4222 if {$did > 0} {after $aft}; incr did
4223 if {$props_javaview} {
4224 push_new_value "http" "http" 1 1
4225 } else {
4226 push_new_value "http" "nohttp" 1 1
4227 }
4228 if {$menu_var(http)} {
4229 set props_javaview 1
4230 } else {
4231 set props_javaview 0
4232 }
4233 if {$props_javaview == $prop0_javaview} {incr fail}
4234 set prop0_javaview $props_javaview
4235 }
4236
4237 if {$props_solid != $prop0_solid} {
4238 if {$did > 0} {after $aft}; incr did
4239 if {$props_solid} {
4240 push_new_value "solid" "solid" 1 1
4241 } else {
4242 push_new_value "solid" "nosolid" 1 1
4243 }
4244 if {$menu_var(solid)} {
4245 set props_solid 1
4246 } else {
4247 set props_solid 0
4248 }
4249 if {$props_solid == $prop0_solid} {incr fail}
4250 set prop0_solid $props_solid
4251 }
4252
4253 set fpw 0
4254 if {$props_passwd != $prop0_passwd} {
4255 set fpw 1
4256 }
4257 set vpw 0
4258 if {$props_viewpasswd != $prop0_viewpasswd} {
4259 set vpw 1
4260 }
4261
4262 set pw_ord [list]
4263 if {!$fpw && !$vpw } {
4264 # neither change
4265 ;
4266 } elseif {$fpw && !$vpw} {
4267 # full password change
4268 if {$props_passwd == ""} {
4269 if {$prop0_viewpasswd != ""} {
4270 # set view to "" as well and first
4271 set props_viewpasswd ""
4272 set pw_ord [list vpw fpw]
4273 } else {
4274 set pw_ord [list fpw]
4275 }
4276 } else {
4277 # assume view state OK
4278 set pw_ord [list fpw]
4279 }
4280
4281 } elseif {!$fpw && $vpw} {
4282 # view password change
4283 if {$props_viewpasswd == ""} {
4284 # assume full state OK
4285 set pw_ord [list vpw]
4286 } else {
4287 if {$prop0_passwd == ""} {
4288 # could be trouble, x11vnc makes random
4289 # full passwd...
4290 set pw_ord [list vpw]
4291 } else {
4292 # OK, full non-null.
4293 set pw_ord [list vpw]
4294 }
4295 }
4296 } elseif {$fpw && $vpw} {
4297 # both full and view password change
4298 if {$props_passwd == "" && $props_viewpasswd == ""} {
4299 # OK, do view first
4300 set pw_ord [list vpw fpw]
4301 } elseif {$props_passwd == "" && $props_viewpasswd != ""} {
4302 # Not good, do view first anyway x11vnc will fix.
4303 set pw_ord [list vpw fpw]
4304 } elseif {$props_passwd != "" && $props_viewpasswd == ""} {
4305 # OK, view first
4306 set pw_ord [list vpw fpw]
4307 } elseif {$props_passwd != "" && $props_viewpasswd != ""} {
4308 # OK, full first
4309 set pw_ord [list fpw vpw]
4310 }
4311 }
4312
4313 foreach case $pw_ord {
4314 if {$case == "fpw"} {
4315 if {$did > 0} {after $aft}; incr did
4316 push_new_value "passwd" "passwd" "$props_passwd" 1
4317 if {$props_passwd == $prop0_passwd} {incr fail}
4318 set prop0_passwd $props_passwd
4319 }
4320 if {$case == "vpw"} {
4321 if {$did > 0} {after $aft}; incr did
4322 push_new_value "viewpasswd" "viewpasswd" "$props_viewpasswd" 1
4323 if {$props_viewpasswd == $prop0_viewpasswd} {incr fail}
4324 set prop0_viewpasswd $props_viewpasswd
4325 }
4326 }
4327
4328 if {$props_accept != $prop0_accept} {
4329 if {$did > 0} {after $aft}; incr did
4330 if {$props_accept} {
4331 push_new_value "unlock" "unlock" 1 0
4332 } else {
4333 push_new_value "lock" "lock" 1 0
4334 }
4335 if {$props_accept == $prop0_accept} {incr fail}
4336 set prop0_accept $props_accept
4337 }
4338
4339 props_widgets normal
4340 if {$fail > 0} {
4341 return 0
4342 } else {
4343 return 1
4344 }
4345}
4346
4347proc props_advanced {} {
4348 global icon_mode props_win full_win
4349 global props_advanced_first
4350
4351 if ![info exists props_advanced_first] {
4352 center_win $full_win
4353 set props_advanced_first 1
4354 set first 1
4355 } else {
4356 set first 0
4357 }
4358 update
4359 wm deiconify $full_win
4360 update
4361
4362 if {$first} {
4363 set w $full_win
4364 wm minsize $w [winfo width $w] [winfo height $w]
4365 }
4366 push_new_value "remote-cmd" "remote-cmd" "Q:clients" 1
4367}
4368
4369proc do_props {} {
4370 global props_accept props_confirm props_viewonly props_shared
4371 global props_zeroconf props_javaview props_solid
4372 global props_passwd props_viewpasswd
4373 global prop0_accept prop0_confirm prop0_viewonly prop0_shared
4374 global prop0_zeroconf prop0_javaview prop0_solid
4375 global prop0_passwd prop0_viewpasswd
4376 global menu_var unset_str
4377 global have_labelframes ffont bfont
4378 global props_buttons icon_noadvanced
4379 global icon_mode icon_mode_at_startup
4380 global screen_height screen_width
4381 global do_props_msg
4382
4383 set msg ""
4384 if {[info exists do_props_msg]} {
4385 set msg $do_props_msg
4386 }
4387
4388 check_update_vars
4389
4390 set pady 0.5m
4391 set pady 0.3m
4392 if {$screen_height <= 360} {
4393 set pady 0m
4394 }
4395
4396 if [info exists menu_var(deny)] {
4397 if {$menu_var(deny) == $unset_str || $menu_var(deny) == 0} {
4398 set props_accept 1
4399 } else {
4400 set props_accept 0
4401 }
4402 } else {
4403 set menu_var(deny) 0
4404 set props_accept 1
4405 }
4406 set prop0_accept $props_accept
4407
4408 if [info exists menu_var(accept)] {
4409 if {$menu_var(accept) == $unset_str || $menu_var(accept) == ""} {
4410 set props_confirm 0
4411 } else {
4412 set props_confirm 1
4413 }
4414 } else {
4415 set menu_var(accept) ""
4416 set props_confirm 0
4417 }
4418 set prop0_confirm $props_confirm
4419
4420 if [info exists menu_var(viewonly)] {
4421 if {$menu_var(viewonly) == $unset_str || $menu_var(viewonly) == ""} {
4422 set props_viewonly 0
4423 } elseif ($menu_var(viewonly)) {
4424 set props_viewonly 1
4425 } else {
4426 set props_viewonly 0
4427 }
4428 } else {
4429 set menu_var(viewonly) 0
4430 set props_viewonly 0
4431 }
4432 set prop0_viewonly $props_viewonly
4433
4434 if [info exists menu_var(shared)] {
4435 if {$menu_var(shared) == $unset_str || $menu_var(shared) == ""} {
4436 set props_shared 0
4437 } elseif ($menu_var(shared)) {
4438 set props_shared 1
4439 } else {
4440 set props_shared 0
4441 }
4442 } else {
4443 set menu_var(shared) 0
4444 set props_shared 0
4445 }
4446 set prop0_shared $props_shared
4447
4448 if [info exists menu_var(zeroconf)] {
4449 if {$menu_var(zeroconf) == $unset_str || $menu_var(zeroconf) == ""} {
4450 set props_zeroconf 0
4451 } elseif ($menu_var(zeroconf)) {
4452 set props_zeroconf 1
4453 } else {
4454 set props_zeroconf 0
4455 }
4456 } else {
4457 set menu_var(zeroconf) 0
4458 set props_zeroconf 0
4459 }
4460 set prop0_zeroconf $props_zeroconf
4461
4462 if [info exists menu_var(http)] {
4463 if {$menu_var(http) == $unset_str || $menu_var(http) == ""} {
4464 set props_javaview 0
4465 } elseif ($menu_var(http)) {
4466 set props_javaview 1
4467 } else {
4468 set props_javaview 0
4469 }
4470 } else {
4471 set menu_var(http) 0
4472 set props_javaview 0
4473 }
4474 set prop0_javaview $props_javaview
4475
4476 if [info exists menu_var(solid)] {
4477 if {$menu_var(solid) == $unset_str || $menu_var(solid) == ""} {
4478 set props_solid 0
4479 } elseif ($menu_var(solid)) {
4480 set props_solid 1
4481 } else {
4482 set props_solid 0
4483 }
4484 } else {
4485 set menu_var(solid) 0
4486 set props_solid 0
4487 }
4488 set prop0_solid $props_solid
4489
4490 if ![info exists props_passwd] {
4491 set props_passwd ""
4492 }
4493 set prop0_passwd $props_passwd
4494
4495 if ![info exists props_viewpasswd] {
4496 set props_viewpasswd ""
4497 }
4498 set prop0_viewpasswd $props_viewpasswd
4499
4500 if [info exists props_buttons] {
4501 catch {unset props_buttons}
4502 }
4503 set props_buttons [list]
4504
4505 set wp .props
4506 set w $wp
4507 catch {destroy $wp}
4508 toplevel $wp
4509 wm title $wp "x11vnc Properties"
4510 frame $w.lf
4511 set w $w.lf
4512 set b1 "$w.buttons1"
4513 frame $b1
4514 button $b1.ok -text OK -command "if {\[props_apply\]} {destroy $wp}" -font $bfont
4515 button $b1.cancel -text Cancel -command "destroy $wp" -font $bfont
4516 button $b1.apply -text Apply -command "props_apply" -font $bfont
4517
4518 bind $w <KeyPress-Escape> "destroy $wp"
4519
4520 pack $b1.ok $b1.cancel $b1.apply -side left -expand 0
4521 lappend props_buttons $b1.apply $b1.cancel $b1.ok
4522
4523 set b2 "$w.buttons2"
4524 frame $b2
4525
4526 button $b2.advanced -text " Advanced ... " \
4527 -command "destroy $wp; props_advanced" -font $bfont
4528 if {! $icon_noadvanced} {
4529 lappend props_buttons $b2.advanced
4530 pack $b2.advanced -side left -expand 0
4531 }
4532
4533 button $b2.help -text " Help " -command "menu_help Properties" -font $bfont
4534 lappend props_buttons $b2.help
4535 pack $b2.help -side left -expand 0
4536
4537 set pw "$w.passwd"
4538 if {$have_labelframes} {
4539 labelframe $pw -text "Password" -font $bfont
4540 } else {
4541 frame $pw
4542 set l $pw.l
4543 label $l -text "Password:" -justify left -anchor w -font $bfont
4544 pack $pw.l -fill x -expand 1 -padx 1m -pady 0m -side top
4545 }
4546 entry $pw.e -show "*" -textvariable props_passwd -font $bfont
4547 pack $pw.e -fill x -expand 1 -padx 1m -pady $pady -side top
4548
4549 global x11vnc_icon_mode
4550 if {! $x11vnc_icon_mode} {
4551 catch { $pw.e configure -state disabled}
4552 if {! $have_labelframes} {
4553 catch { $pw.l configure -state disabled}
4554 }
4555 } else {
4556 lappend props_buttons $pw.e
4557 }
4558
4559
4560 set vp "$w.viewpw"
4561 if {$have_labelframes} {
4562 labelframe $vp -text "ViewOnly Password" -font $bfont
4563 } else {
4564 frame $vp
4565 set l $vp.l
4566 label $l -text "ViewOnly Password:" -justify left -anchor w -font $bfont
4567 pack $vp.l -fill x -expand 1 -padx 1m -pady 0m -side top
4568 }
4569 entry $vp.e -show "*" -textvariable props_viewpasswd -font $bfont
4570 pack $vp.e -fill x -expand 1 -padx 1m -pady $pady -side top
4571
4572 if {! $x11vnc_icon_mode} {
4573 catch { $vp.e configure -state disabled}
4574 if {! $have_labelframes} {
4575 catch { $vp.l configure -state disabled}
4576 }
4577 } else {
4578 lappend props_buttons $vp.e
4579 }
4580
4581 if {! $icon_mode_at_startup} {
4582 $vp.e configure -state disabled
4583 catch {$vp.l configure -state disabled}
4584 catch {$vp configure -state disabled}
4585 catch {$vp configure -foreground grey60}
4586 $pw.e configure -state disabled
4587 catch {$pw.l configure -state disabled}
4588 catch {$pw configure -state disabled}
4589 catch {$pw configure -foreground grey60}
4590 }
4591
4592 set sb "$w.solid"
4593 frame $sb
4594 checkbutton $sb.button -text "Solid Background Color" \
4595 -variable props_solid -anchor w -font $bfont
4596 pack $sb.button -fill x -expand 1 -padx 1m -pady $pady
4597
4598 set jv "$w.javaview"
4599 frame $jv
4600 checkbutton $jv.button -text "Serve Java Viewer Applet" \
4601 -variable props_javaview -anchor w -font $bfont
4602 pack $jv.button -fill x -expand 1 -padx 1m -pady $pady
4603
4604 set zc "$w.zeroconf"
4605 frame $zc
4606 checkbutton $zc.button -text "Advertise Service (Zeroconf)" \
4607 -variable props_zeroconf -anchor w -font $bfont
4608 pack $zc.button -fill x -expand 1 -padx 1m -pady $pady
4609
4610 set sh "$w.shared"
4611 frame $sh
4612 checkbutton $sh.button -text "Shared" \
4613 -variable props_shared -anchor w -font $bfont
4614 pack $sh.button -fill x -expand 1 -padx 1m -pady $pady
4615
4616 set vo "$w.viewonly"
4617 frame $vo
4618 checkbutton $vo.button -text "All Clients ViewOnly" \
4619 -variable props_viewonly -anchor w -font $bfont
4620 pack $vo.button -fill x -expand 1 -padx 1m -pady $pady
4621
4622 set cf "$w.confirm"
4623 frame $cf
4624 checkbutton $cf.button -text "Ask for Confirmation" \
4625 -variable props_confirm -anchor w -font $bfont
4626 pack $cf.button -fill x -expand 1 -padx 1m -pady $pady
4627
4628 set ac "$w.accept"
4629 frame $ac
4630 checkbutton $ac.button -text "Accept Connections" \
4631 -variable props_accept -anchor w -font $bfont
4632 pack $ac.button -fill x -expand 1 -padx 1m -pady $pady
4633
4634 set px "6m"
4635 pack $b1 -side bottom -fill x -pady $pady -padx $px
4636 pack $b2 -side bottom -fill x -pady $pady -padx $px
4637 pack $vp -side bottom -fill x -pady $pady -padx $px
4638 pack $pw -side bottom -fill x -pady $pady -padx $px
4639 pack $sb -side bottom -fill x -pady 0m -padx $px
4640 pack $jv -side bottom -fill x -pady 0m -padx $px
4641 pack $zc -side bottom -fill x -pady 0m -padx $px
4642 pack $sh -side bottom -fill x -pady 0m -padx $px
4643 pack $vo -side bottom -fill x -pady 0m -padx $px
4644 pack $cf -side bottom -fill x -pady 0m -padx $px
4645 pack $ac -side bottom -fill x -pady 0m -padx $px
4646
4647 global show_props_instructions
4648 if {![info exists show_props_instructions]} {
4649 set show_props_instructions 1
4650 }
4651
4652 wm withdraw .props
4653
4654 set wl $w
4655
4656 pack $wl -side left
4657
4658 if {$msg != ""} {
4659 set tw [textwidth $msg]
4660 set th [textheight $msg]
4661 set th [expr $th - 1]
4662 set ms ".props.msg"
4663 text $ms -font $ffont -relief ridge -width $tw -height $th
4664 $ms insert 1.0 $msg
4665
4666 set si "$wl.instructions"
4667 frame $si
4668 checkbutton $si.button -text "Show Instructions" \
4669 -variable show_props_instructions -anchor w -font $bfont \
4670 -command "toggle_instructions $ms $pady $px"
4671
4672 pack $si.button -fill x -expand 1 -padx 1m -pady $pady
4673 pack $si -side bottom -fill x -pady 0m -padx $px
4674
4675 if {$show_props_instructions} {
4676 pack $ms -side left -fill both
4677 }
4678
4679 update
4680 }
4681
4682
4683 lappend props_buttons $ac.button $cf.button $vo.button $sh.button $zc.button $jv.button $sb.button
4684
4685
4686 set w .props
4687 update
4688 wm resizable $w 1 0
4689 center_win $w
4690 update
4691
4692 #wm minsize $w [winfo width $w] [winfo height $w]
4693
4694 tkwait window $w
4695 set show_props_instructions 0
4696}
4697
4698proc toggle_instructions {ms pady px} {
4699 global show_props_instructions
4700 if {$show_props_instructions} {
4701 pack $ms -side left -fill both
4702 } else {
4703 pack forget $ms
4704 }
4705 catch {pack .props}
4706 update
4707}
4708
4709proc do_new_client {} {
4710 global newclient ffont bfont
4711
4712 set w .newclient
4713 catch {destroy $w}
4714 toplevel $w
4715 label $w.l -text "Hostname: " -font $bfont
4716 set newclient ""
4717 entry $w.e -width 16 -textvariable newclient -font $bfont
4718 button $w.b -text OK -command "destroy $w" -font $bfont
4719 button $w.h -text Help -command "menu_help NewClient" -font $bfont
4720 bind $w.e <Return> "update; after 100; destroy $w"
4721
4722 wm title $w "New Client"
4723
4724 pack $w.l $w.e $w.h $w.b -side left -pady 1m -padx 0.5m
4725 focus $w.e
4726 center_win $w
4727 update
4728
4729 tkwait window $w
4730
4731 regsub -all {[{}()~!$&*|;'"`{}<>\[\]]} $newclient "" newclient
4732 #'
4733 if {$newclient != ""} {
4734 push_new_value "connect" "connect" "$newclient" 1
4735 }
4736}
4737
4738proc do_disconnect_all {} {
4739 push_new_value "disconnect" "disconnect" "all" 1
4740}
4741
4742proc do_disconnect_client {id} {
4743 push_new_value "disconnect" "disconnect" "$id" 1
4744}
4745
4746proc popup_post {m} {
4747 global popup_cascade_posted client_balloon
4748 global client_id_list
4749
4750 set popup_cascade_posted 0
4751
4752 set wd "$m.disconnect"
4753
4754 if {![winfo exists $wd]} {
4755 return
4756 }
4757
4758 catch {$wd delete 0 end}
4759
4760 $wd add command -label "Disconnect client:"
4761 $wd add separator
4762 $wd add command -label "All Clients" -command do_disconnect_all
4763
4764 if {![info exists client_id_list]} {
4765 return
4766 }
4767
4768 foreach client $client_id_list {
4769 if {$client == ""} {
4770 continue
4771 }
4772 if {[regexp {^([^:]*):(.*)$} $client mat id lab]} {
4773 set nid [expr "$id + 0"]
4774 $wd add command -label "$nid $lab" \
4775 -command "do_disconnect_client $id"
4776 }
4777 }
4778}
4779
4780proc pmenu {m x y} {
4781 if {![winfo exists $m]} {
4782 return
4783 }
4784 set x [expr $x-10]
4785 set y [expr $y-10]
4786 $m post $x $y
4787 # XXX more care needed
4788 grab set -global $m
4789}
4790
4791proc set_client_balloon {str} {
4792 global client_balloon vnc_display
4793 global client_id_list
4794
4795 set client_id_list [list]
4796
4797 set client_balloon "$vnc_display"
4798 set count 0
4799 regsub -all {^.*aro=clients:} $str "" str
4800 regsub -all {aro=.*$} $str "" str
4801 regsub -all {ans=.*$} $str "" str
4802 foreach client [split $str ","] {
4803 #puts "client: $client"
4804 if [regexp {^[ ]*$} $client] {
4805 continue
4806 }
4807 if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \
4808 $client m0 m1 m2 m3 m4 m5 m6 m7 m8 m9]} {
4809 set id $m1
4810 set nid [expr "$m1 + 0"]
4811 set ip $m2
4812 set port $m3
4813 set user $m4
4814 set unix $m5
4815 if {[string length $user] >= 24} {
4816 # weird identd hash...
4817 set user [string range $user 0 8]
4818 set user "${user}..."
4819 }
4820 if {$unix != "" && $unix != "none"} {
4821 set user $unix
4822 }
4823 set host $m6
4824 set input $m7
4825 set vo $m8
4826 set ltime $m9
4827 if [regexp {^[ ]*$} $host] {
4828 set host $ip
4829 }
4830 set client_balloon "${client_balloon}\n$nid $user\@$host"
4831 if {$vo == "1"} {
4832 set client_balloon "${client_balloon} - view"
4833 lappend client_id_list "$id:$user\@$host - view"
4834 } else {
4835 set client_balloon "${client_balloon} - full"
4836 lappend client_id_list "$id:$user\@$host - full"
4837 }
4838 } else {
4839 set i [expr $count+1]
4840 if {$i == 1} {
4841 set client_balloon "${client_balloon}\nunknown-host$i"
4842 }
4843 }
4844 incr count
4845 }
4846 if {$count == 0} {
4847 set client_balloon "${client_balloon}\nNo connections."
4848 }
4849 icon_win_cfg $count
4850}
4851
4852proc read_client_info {channel} {
4853 global x11vnc_client_file client_str client_info_read
4854 global read_client_info_lock
4855 global read_clients
4856 set db 0
4857
4858 set read_clients 0
4859
4860 if {![info exists read_client_info_lock]} {
4861 set read_client_info_lock 0
4862 }
4863
4864 if {$channel != ""} {
4865
4866 if {$read_client_info_lock} {
4867 return
4868 }
4869 set read_client_info_lock 1
4870 after 100
4871 set str ""
4872 set count [gets $channel str]
4873 if {$db} {puts stderr "read_client_info-$channel: $str"}
4874
4875 if {$count == -1 || [eof $channel]} {
4876 close $channel
4877 catch {file delete $x11vnc_client_file}
4878 set read_client_info_lock 0
4879 clean_icon_exit
4880 }
4881 if {$count > 0 && ![regexp {^[ ]*$} $str]} {
4882 set client_info_read 1
4883 if {$str == "quit"} {
4884 catch {file delete $x11vnc_client_file}
4885 set read_client_info_lock 0
4886 clean_icon_exit
4887 } elseif {$str == "skip"} {
4888 ;
4889 } elseif [regexp {^clients:} $str] {
4890 regsub {^clients:} $str "" str
4891 set read_clients 1
4892 if {$str == "none"} {
4893 set str ""
4894 }
4895 update_clients_menu $str
4896 set client_str $str
4897 set_client_balloon $str
4898 }
4899 }
4900 set read_client_info_lock 0
4901 }
4902}
4903
4904proc check_set_vnc_display {} {
4905
4906 global read_clients check_set_vnc_display_done
4907
4908 if {[info exists check_set_vnc_display_done]} {
4909 return
4910 }
4911 if {[info exists read_clients]} {
4912 if {$read_clients} {
4913 after 250
4914 query_all
4915 global client_str
4916 set_client_balloon $client_str
4917 set check_set_vnc_display_done 1
4918 }
4919 }
4920}
4921
4922proc read_client_tail {} {
4923 global client_tail
4924
4925 if {$client_tail != ""} {
4926 read_client_info $client_tail
4927 check_set_vnc_display
4928 }
4929}
4930
4931proc read_client_sock {} {
4932 global client_sock
4933
4934 if {$client_sock != ""} {
4935 read_client_info $client_sock
4936 check_set_vnc_display
4937 }
4938}
4939
4940proc show_client_balloon {} {
4941 global icon_mode icon_win props_win full_win
4942 global client_balloon ffont connected_to_x11vnc
4943
4944 set noinfo "tkx11vnc: no client information"
4945 set noinfo "$noinfo\navailable from x11vnc ..."
4946 if ![info exists client_balloon] {
4947 set client_balloon $noinfo
4948 }
4949 if {$client_balloon == ""} {
4950 set client_balloon $noinfo
4951 }
4952 if {! [info exists icon_win]} {
4953 return
4954 } elseif {$icon_win == ""} {
4955 return
4956 } elseif {! [winfo exists $icon_win]} {
4957 return
4958 }
4959
4960 set x [expr [winfo rootx $icon_win] + ([winfo width $icon_win]/2)]
4961 set y [expr [winfo rooty $icon_win] + [winfo height $icon_win] + 4]
4962
4963 set infotext $client_balloon
4964 if {!$connected_to_x11vnc} {
4965 set infotext "Not currently attached to x11vnc\nLast available info:\n$infotext"
4966 }
4967
4968 set w .client_balloon
4969 catch {destroy $w}
4970 toplevel $w -bg black -screen [winfo screen $icon_win]
4971 wm overrideredirect $w 1
4972 label $w.l -text "$infotext" -relief flat -bg "#ffffaa" -fg black \
4973 -padx 2 -pady 0 -anchor w -justify left -font $ffont
4974 pack $w.l -side left -padx 1 -pady 1
4975
4976 set w2 [winfo reqwidth $w.l]
4977 set h2 [winfo reqheight $w.l]
4978
4979 set W [winfo screenwidth $w]
4980 set H [winfo screenheight $w]
4981
4982 if {[expr $x+$w2] > $W} {
4983 set w3 [winfo width $icon_win]
4984 set x [expr "$W - $w2 - $w3 - 4"]
4985 }
4986 if {[expr $y+$h2] > $H} {
4987 set h3 [winfo height $icon_win]
4988 set y [expr "$H - $h2 - $h3 - 4"]
4989 }
4990
4991 wm geometry $w +${x}+${y}
4992}
4993
4994proc kill_client_balloon {} {
4995 global client_balloon_id client_balloon_win
4996 if [info exists client_balloon_id] {
4997 catch {after cancel $client_balloon_id}
4998 }
4999 if [winfo exists .client_balloon] {
5000 destroy .client_balloon
5001 }
5002}
5003
5004proc icon_win_cfg {clients} {
5005 global icon_win client_tail client_sock client_info_read
5006
5007 if {! [info exists icon_win]} {
5008 return
5009 } elseif {$icon_win == ""} {
5010 return
5011 } elseif {! [winfo exists $icon_win]} {
5012 return
5013 }
5014 if {$clients > 0} {
5015 $icon_win configure -bg black -fg white
5016 } else {
5017 $icon_win configure -bg white -fg black
5018 }
5019
5020 if {$client_tail == "" || !$client_info_read} {
5021 if {$client_sock == ""} {
5022 $icon_win configure -fg red
5023 }
5024 }
5025}
5026
5027proc server_accept {sock addr port} {
5028 global socket_cookie server socket_got_callback
5029 global client_tail client_sock
5030 set db 0
5031
5032 if {$db} {puts stderr "sock=$sock addr=$addr port=$port"}
5033
5034 update; update idletasks
5035 after 50
5036 update; update idletasks
5037 set count [gets $sock str]
5038
5039 if {$count >= 0} {
5040 set str [string trim $str]
5041 if {$db} {puts stderr "server_accept: \"$str\""}
5042 if {$str == "COOKIE:$socket_cookie"} {
5043 set client_sock $sock
5044 if {$db} {puts stderr "cookie matched. $client_sock"}
5045 } else {
5046 if {$db} {puts stderr "cookie NO matched."}
5047 }
5048 }
5049 catch {close $server}
5050 set socket_got_callback 1
5051 if {$db} {puts stderr "socket_got_callback $socket_got_callback"}
5052}
5053
5054proc try_client_info_sock {} {
5055 global socket_cookie server socket_got_callback
5056 global x11vnc_started x11vnc_xdisplay hostname client_sock
5057 global x11vnc_xdisplay0 menu_var
5058
5059 set db 0
5060#dtime t1
5061 set start 13037
5062 set tries 100
5063 set socket_got_callback 0
5064
5065 set xd $x11vnc_xdisplay
5066 if {$xd == "" && $x11vnc_xdisplay0 != ""} {
5067 set xd $x11vnc_xdisplay0
5068 }
5069 if {$xd == "" && [info exists menu_var(display)]} {
5070 set xd $menu_var(display)
5071 }
5072
5073 set myaddr ""
5074 regsub {\..*$} $hostname "" shost
5075 if {$x11vnc_started} {
5076 set myaddr "127.0.0.1"
5077 } elseif {$xd != ""} {
5078 if {[regexp {^:} $xd]} {
5079 set myaddr "127.0.0.1"
5080 } elseif {[regexp -nocase "^$shost" $xd]} {
5081 set myaddr "127.0.0.1"
5082 } elseif {[regexp -nocase "^localhost" $xd]} {
5083 set myaddr "127.0.0.1"
5084 } else {
5085 set myaddr $hostname
5086 }
5087 } else {
5088 set myaddr $hostname
5089 }
5090
5091 for {set i 0} {$i <= $tries} {incr i} {
5092 set port [expr $start + $i]
5093 set server [socket -server server_accept -myaddr $myaddr $port]
5094 if {$server == ""} {
5095 continue
5096 }
5097 if {[eof $server]} {
5098 continue
5099 }
5100 set err ""
5101 catch {set err [fconfigure $server -error]}
5102 #puts "err: $server: $err"
5103 if {$err == ""} {
5104 break
5105 }
5106 }
5107 if {$server == ""} {
5108 append_text "try_client_info_sock: server socket failed.\n"
5109 return
5110 }
5111 if {! $x11vnc_started} {
5112 run_remote_cmd [list "-nosync" "-R" "noop"]
5113 if {$db} {dtime A}
5114 after 250
5115 if {$db} {dtime A}
5116 }
5117
5118 # set the cookie to some obscured randomness
5119 set socket_cookie [clock clicks]
5120 set r [expr rand()]
5121 if {$r != ""} {
5122 append socket_cookie $r
5123 }
5124 set r ""
5125 catch {set r [winfo id .]}
5126 if {$r != ""} {
5127 append socket_cookie $r
5128 }
5129 if {[regexp {([0-9])([0-9])$} [clock clicks] m m1 m2]} {
5130 regsub -all {\.} $socket_cookie $m1 socket_cookie
5131 regsub -all {x} $socket_cookie $m2 socket_cookie
5132 }
5133 run_remote_cmd [list "-nosync" "-R" \
5134 "client_info_sock:$myaddr:$port:$socket_cookie"]
5135#dtime t2
5136 if {$db} {puts "client_info_sock:$myaddr:$port:$socket_cookie"}
5137 for {set i 0} {$i < 10} {incr i} {
5138 after 50
5139 update; update idletasks
5140#dtime aa
5141 if {$socket_got_callback != 0} {
5142#puts "break-"
5143 break
5144 }
5145 }
5146#dtime t3
5147
5148 set aftid ""
5149 if {$socket_got_callback == 0} {
5150 set aftid [after 10000 {set socket_got_callback 2}]
5151 tkwait variable socket_got_callback
5152 }
5153
5154 if {$aftid != ""} {
5155 catch {after cancel $aftid}
5156 }
5157
5158 if {$socket_got_callback != 1} {
5159 puts stderr "try_client_info_sock failed: no callback\n"
5160 catch {close $server}
5161 } else {
5162 setup_client_sock 1
5163 }
5164#dtime t4
5165}
5166
5167proc set_icon_label {} {
5168 global icon_win
5169
5170 set lab [get_icon_label]
5171
5172 if {! [info exists icon_win]} {
5173 return
5174 } elseif {$icon_win == ""} {
5175 return
5176 } elseif {! [winfo exists $icon_win]} {
5177 return
5178 }
5179
5180 if {[info exists icon_win]} {
5181 $icon_win configure -text $lab
5182 }
5183}
5184
5185proc get_icon_label {{set 0}} {
5186 global icon_minimal
5187
5188 set lab0 "x11\nvnc"
5189
5190 if {$icon_minimal} {
5191 set lab [get_vnc_display_number]
5192 if {$lab != "none"} {
5193 #set lab " :$lab"
5194 set lab ":$lab"
5195 } else {
5196 set lab "-"
5197 }
5198 } else {
5199 set lab $lab0
5200 }
5201 return $lab
5202}
5203
5204# currently unused
5205proc lmenu {menu} {
5206 global popup_cascade_posted
5207 global left_iconwin_menu
5208 set left_iconwin_menu 1
5209 after 100
5210 update
5211 if {!$popup_cascade_posted && $left_iconwin_menu} {
5212 for {set i 0} {$i < 3} {incr i} {
5213 after 100
5214 update
5215 }
5216 if {!$popup_cascade_posted && $left_iconwin_menu} {
5217 $menu unpost
5218 return
5219 }
5220 }
5221 # kludge for WindowView
5222 if {$popup_cascade_posted} {
5223 focus $menu
5224 }
5225}
5226
5227proc old_balloon {} {
5228 global client_str saved_clients_str
5229 set str ""
5230 if {[info exists client_str]} {
5231 if {$client_str != ""} {
5232 set str $client_str
5233 }
5234 }
5235 if {$str == ""} {
5236 if {[info exists saved_clients_str]} {
5237 set str $saved_clients_str
5238 }
5239 }
5240 if {$str != ""} {
5241 set_client_balloon $str
5242 }
5243}
5244
5245proc get_custom_menu_items {} {
5246 global env custom_last_read
5247
5248 if {![info exists custom_last_read]} {
5249 set custom_last_read 0
5250 }
5251 if {[info exists env(X11VNC_CUSTOM_GUI)]} {
5252 set custom "$env(X11VNC_CUSTOM_GUI)"
5253 } elseif {![info exists env(HOME)]} {
5254 return [list "none"]
5255 } else {
5256 set custom "$env(HOME)/.x11vnc.gui"
5257 }
5258 if {![file exists $custom]} {
5259 return [list "none"]
5260 }
5261
5262# if {[file mtime $custom] <= $custom_last_read} {
5263# return [list "nochange"]
5264# }
5265
5266 set in ""
5267 catch {set in [open $custom "r"]}
5268 if {$in == ""} {
5269 return [list "none"]
5270 }
5271
5272 set custom_last_read [clock seconds]
5273
5274 set count 0
5275 while {[gets $in line] > -1} {
5276 if {[regexp {^[ \t]*#} $line]} {
5277 continue
5278 }
5279 set line [string trim $line]
5280 if {$line != ""} {
5281 lappend items $line
5282 incr count
5283 }
5284 }
5285 close $in
5286
5287 if {$count > 0} {
5288 return $items
5289 } else {
5290 return [list "none"]
5291 }
5292}
5293
5294proc make_custom_menu {menu font} {
5295 set items [get_custom_menu_items]
5296 set i0 [lindex $items 0]
5297 catch {$menu delete 0 end}
5298 if {$i0 != "none"} {
5299 $menu add command -font $font -label "Custom items:"
5300 $menu add separator
5301 foreach item $items {
5302 if {$item == "sep" || $item == "separator"} {
5303 $menu add separator
5304 continue
5305 }
5306 if {[regexp {^action:(.*)$} $item m action]} {
5307 $menu add command -font $font -label "$action" \
5308 -command "do_var $action"
5309 continue
5310 }
5311 $menu add command -font $font -label "$item" \
5312 -command "run_remote_cmd \[list \"-R\" \"$item\"\]"
5313 }
5314 }
5315}
5316
5317proc make_icon {} {
5318 global icon_mode icon_embed_id icon_win props_win full_win
5319 global tray_embed tray_running env
5320 global x11vnc_client_file client_tail client_sock client_str saved_clients_str
5321 global client_balloon_id
5322 global bfont sfont snfont ffont
5323 global icon_minimal gui_start_mode
5324 global popup_cascade_posted menu_var x11vnc_gui_geom
5325 set min_x 24
5326 set min_y 24
5327
5328 set font $bfont
5329 set mfont $font
5330
5331 if {$tray_embed} {
5332 set font $sfont
5333 set mfont $snfont
5334 }
5335 if {[info exists env(X11VNC_ICON_FONT)]} {
5336 set font $env(X11VNC_ICON_FONT)
5337 }
5338 if {[regexp {([0-9][0-9]*)x([0-9][0-9]*)} $x11vnc_gui_geom m mx my]} {
5339 if {$mx < $min_x} {
5340 set min_x $mx
5341 }
5342 if {$my < $min_y} {
5343 set min_y $my
5344 }
5345 }
5346 wm minsize . $min_x $min_y
5347
5348 if {$tray_embed && $tray_running} {
5349 wm withdraw .
5350 }
5351
5352 set l .icon
5353 set icon_win $l
5354 catch destroy {$icon_win}
5355 if {$icon_minimal} {
5356 set bw 1
5357 } else {
5358 set bw 5
5359 }
5360 set lab [get_icon_label]
5361 label $l -text $lab -borderwidth $bw -font $font
5362 icon_win_cfg 0
5363
5364
5365 set popup_cascade_posted 0
5366 pack $l -fill both -expand 1
5367 set menu "$l.menu"
5368 menu $menu -tearoff 0 -postcommand "popup_post $menu"
5369 $menu add command -font $mfont -label "Properties" -command do_props
5370 $menu add command -font $mfont -label "Help" -command "menu_help Tray"
5371 $menu add command -font $mfont -label "Logfile" -command show_logfile
5372 $menu add separator
5373 $menu add command -font $mfont -label "New Client" -command do_new_client
5374
5375 set wd "$menu.disconnect"
5376 catch {destroy $wd}
5377 menu $wd -tearoff 0 -font $ffont \
5378 -postcommand {set popup_cascade_posted 1}
5379 $wd add command -label "Disconnect client:"
5380 $wd add separator
5381 $wd add command -label "All Clients" -command do_disconnect_all
5382 $menu add cascade -font $mfont -label "Disconnect:" -menu $wd
5383
5384 $menu add separator
5385
5386 set wv "$menu.windowview"
5387 catch {destroy $wv}
5388 menu $wv -tearoff 0 -font $ffont \
5389 -postcommand {set popup_cascade_posted 1}
5390 foreach val {full icon tray} {
5391 $wv add radiobutton -label "$val" \
5392 -value "$val" -font $ffont \
5393 -command "do_var WindowView" \
5394 -variable menu_var(WindowView)
5395 }
5396 $menu add cascade -font $mfont -label "Window View:" -menu $wv
5397
5398 $menu add command -font $mfont -label "Dismiss" -command "$menu unpost"
5399 $menu add command -font $mfont -label "Stop x11vnc" -command clean_icon_exit
5400
5401 set items [get_custom_menu_items]
5402 set i0 [lindex $items 0]
5403 if {$i0 != "none" && $i0 != "nochange"} {
5404 $menu add separator
5405 set cm "$menu.custom"
5406 catch {destroy $cm}
5407 menu $cm -tearoff 0 -font $ffont \
5408 -postcommand "set popup_cascade_posted 1; make_custom_menu $cm $ffont"
5409 $menu add cascade -font $mfont -label "Custom:" -menu $cm
5410 }
5411
5412 bind $icon_win <ButtonRelease-1> "pmenu $menu %X %Y"
5413 bind $icon_win <ButtonRelease-3> "pmenu $menu %X %Y"
5414 bind $icon_win <Enter> {set client_balloon_id [after 500 show_client_balloon]}
5415 bind $icon_win <Button> {kill_client_balloon}
5416 bind $icon_win <Leave> {kill_client_balloon}
5417 bind $icon_win <Shift-ButtonRelease-1> {kill_client_balloon; show_client_balloon}
5418 bind $icon_win <ButtonRelease-2> {kill_client_balloon; show_client_balloon}
5419# bind $menu <Leave> "lmenu $menu"
5420# bind $menu <Enter> "set left_iconwin_menu 0"
5421# bind $menu <KeyPress-Escape> "$menu unpost"
5422
5423 bind . <Control-KeyPress-c> {destroy .; exit 0}
5424
5425 if {!$tray_embed || !$tray_running} {
5426 global x11vnc_gui_geom
5427 if {$x11vnc_gui_geom != ""} {
5428 set doit 1
5429 if {[regexp {x} $x11vnc_gui_geom]} {
5430 if {$gui_start_mode == "full"} {
5431 set doit 0
5432 }
5433 }
5434 if {$doit} {
5435 wm geometry . $x11vnc_gui_geom
5436 }
5437 }
5438 }
5439 wm iconname . "tkx11vnc"
5440 wm title . "tkx11vnc"
5441 update
5442 if {$tray_embed && $tray_running} {
5443 #wm deiconify .; # why did we have this???
5444 #after 10000 {wm deiconify .; puts "reqheight [winfo reqheight .]"; puts "reqwidth [winfo reqwidth .]"; puts "height [winfo height .]"; puts "width [winfo width .]"}
5445 } else {
5446 wm deiconify .
5447 }
5448 update
5449
5450#puts "reqheight [winfo reqheight .]"
5451#puts "reqwidth [winfo reqwidth .]"
5452#puts "height [winfo height .]"
5453#puts "width [winfo width .]"
5454#puts "AAA"
5455
5456 old_balloon
5457}
5458
5459proc setup_client_channel {} {
5460 global client_sock client_tail
5461
5462# XXX/setup_client_channel
5463 if {$client_sock == "" } {
5464 stop_watch on
5465 try_client_info_sock
5466 if {$client_sock == "" } {
5467 after 500
5468 try_client_info_sock
5469 }
5470 stop_watch off
5471 }
5472 if {$client_tail == "" && $client_sock == ""} {
5473 set m "\n"
5474 set m "${m}tkx11vnc:\n"
5475 set m "${m}\n"
5476 set m "${m} Warning -- running in icon/tray mode but the\n"
5477 set m "${m} connected client info channel from x11vnc is\n"
5478 set m "${m} not working. The viewer client list and icon\n"
5479 set m "${m} color indicator will not be accurate.\n"
5480 set m "${m}\n"
5481 set m "${m} You may need to restart \"x11vnc -gui tray ...\"\n"
5482 set m "${m} for this to work properly.\n"
5483 set m "${m}\n"
5484 textwin "Warning" "Warning" $m
5485 update
5486 }
5487 dtime C
5488}
5489
5490proc clean_client_tail {} {
5491 global client_tail client_info_read
5492 if [info exists client_tail] {
5493 if {$client_tail != ""} {
5494 set p ""
5495 catch {set p [pid $client_tail]}
5496 if {$p != ""} {
5497 catch {exec kill -TERM $p >/dev/null 2>/dev/null}
5498 }
5499 catch {close $client_tail}
5500 set client_tail ""
5501 }
5502 }
5503 set client_info_read 0
5504}
5505
5506proc clean_icon_exit {} {
5507 clean_client_tail
5508 push_new_value "stop" "stop" 1 0
5509 set_connected no
5510 update
5511 destroy .
5512 exit
5513}
5514
5515proc make_gui {mode} {
5516 global icon_mode tray_embed tray_running full_win icon_win
5517 global top_widget_names x11vnc_gui_geom
5518 global gui_current_state make_gui_count
5519 global x11vnc_connect connected_to_x11vnc
5520 global x11_display
5521 global gui_start_mode
5522
5523 incr make_gui_count
5524
5525 if {$gui_start_mode == ""} {
5526 set gui_start_mode $mode
5527 }
5528
5529 wm withdraw .
5530
5531 set full_geom ""
5532 if {[winfo exists .full]} {
5533 catch {set full_geom [wm geometry .full]}
5534 }
5535
5536 set fw .full
5537 set full_win $fw
5538 catch {pack forget $full_win}
5539 catch {pack forget $icon_win}
5540 catch {destroy $full_win}
5541 catch {destroy $icon_win}
5542
5543 wm minsize . 1 1
5544
5545 set gui_current_state ""
5546
5547 if {$mode == "full"} {
5548 frame $fw
5549 set icon_mode 0
5550
5551 wm protocol . WM_DELETE_WINDOW "destroy .; exit"
5552 make_widgets $fw
5553
5554 set w "."
5555 wm geometry $w ""
5556 if {$x11vnc_gui_geom != ""} {
5557 set doit 1
5558 if {[regexp {x} $x11vnc_gui_geom]} {
5559 if {$gui_start_mode != $mode} {
5560 set doit 0
5561 }
5562 }
5563 if {$doit} {
5564 wm geometry $w $x11vnc_gui_geom
5565 }
5566 }
5567 pack $fw -fill both -expand 1
5568
5569 } elseif {$mode == "icon" || $mode == "tray"} {
5570
5571 toplevel $fw
5572 wm withdraw $fw
5573
5574 wm protocol $fw WM_DELETE_WINDOW "wm withdraw .full"
5575 wm protocol . WM_DELETE_WINDOW "clean_icon_exit"
5576
5577 if {$mode == "icon"} {
5578 set tray_embed 0
5579 } elseif {$mode == "tray"} {
5580 set tray_embed 1
5581 }
5582 set icon_mode 1
5583 make_widgets $fw
5584 set w $fw
5585 make_icon
5586 wm geometry $fw ""
5587 wm geometry . ""
5588 } else {
5589 return
5590 }
5591 set_view_variable $mode
5592 set gui_current_state $mode
5593
5594
5595 update
5596 if {!$tray_embed || !$tray_running} {
5597 wm deiconify .
5598 }
5599 update idletasks
5600 wm minsize $w [winfo width $w] [winfo height $w]
5601 if {$mode == "full" && $make_gui_count > 1} {
5602 center_win .
5603 }
5604
5605
5606 if {$make_gui_count == 1} {
5607 copy_default_vars
5608 if {$x11vnc_connect} {
5609 try_connect_and_query_all
5610 } else {
5611 insert_cmdline_vars
5612 }
5613 } else {
5614 set_name "RESTORE"
5615 }
5616
5617 setup_client_tail
5618
5619 set_widgets
5620
5621 if {$mode == "tray"} {
5622 setup_tray_embed
5623 }
5624}
5625
5626proc make_widgets {top} {
5627 global template make_gui_count
5628 global menu_b menu_m menu_count
5629 global item_opts item_bool item_case item_menu item_entry menu_var unset_str
5630 global item_cascade
5631 global info_label info_str x11_display vnc_display
5632 global text_area text_area_str
5633 global entry_box entry_str entry_set entry_label entry_ok entry_browse
5634 global entry_help entry_skip
5635 global bfont ffont beginner_mode
5636 global helptext helpremote helplabel
5637 global icon_mode icon_win props_win full_win
5638 global top_widget_names
5639 global screen_height screen_width
5640
5641
5642 # Make the top label
5643 set label_width 84
5644 if {$screen_width <= 400} {
5645 set label_width 64
5646 }
5647 set info_label "$top.info"
5648 label $info_label -textvariable info_str -bd 2 -relief groove \
5649 -anchor w -width $label_width -font $ffont
5650 pack $info_label -side top -fill x -expand 0
5651
5652 set top_widget_names(info) $info_label
5653
5654 # Extract the Rows:
5655 set row 0;
5656 set colmax 0;
5657 foreach line [split $template "\n"] {
5658 if {[regexp {^Row: (.*)} $line rest]} {
5659 set col 0
5660 foreach case [split $rest] {
5661 if {$case == "" || $case == "Row:"} {
5662 continue
5663 }
5664 set menu_row($case) $row
5665 set menu_col($case) $col
5666
5667 lappend cases($col) $case;
5668 set len [string length $case]
5669 if {[info exists max_len($col)]} {
5670 if {$len > $max_len($col)} {
5671 set max_len($col) $len
5672 }
5673 } else {
5674 set max_len($col) $len
5675 }
5676 incr col
5677 if {$col > $colmax} {
5678 set colmax $col
5679 }
5680 }
5681 incr row;
5682 }
5683 }
5684
5685 # Make frames for the rows and make the menu buttons.
5686 set f "$top.menuframe"
5687 frame $f
5688 for {set c 0} {$c < $colmax} {incr c} {
5689 set colf "$f.menuframe$c"
5690 frame $colf
5691 pack $colf -side left -fill y
5692 set fbg [$colf cget -background]
5693 foreach case $cases($c) {
5694 set menub "$colf.menu$case";
5695 set menu "$colf.menu$case.menu";
5696 set menu_b($case) $menub
5697 set menu_m($case) $menu
5698 set ul 0
5699 foreach char [split $case ""] {
5700 set char [string tolower $char]
5701 if {![info exists underlined($char)]} {
5702 set underlined($char) 1
5703 break
5704 }
5705 incr ul
5706 }
5707 global osname
5708 set tstr "$case"
5709 if {$osname == "Darwin"} {
5710 #set tstr " $case "
5711 }
5712 menubutton $menub -text "$tstr" -underline $ul \
5713 -anchor w -menu $menu -background $fbg \
5714 -font $bfont
5715 pack $menub -side top -fill x
5716 menu $menu -tearoff 0 -postcommand menu_posted
5717 }
5718 }
5719 pack $f -side top -fill x
5720 set top_widget_names(menuframe) $f
5721
5722 make_menu_items
5723
5724 # Make the x11 and vnc display label bar:
5725 set df "$top.displayframe"
5726 frame $df -bd 1 -relief groove
5727 set top_widget_names(displayframe) $df
5728
5729 set df_x11 "$df.xdisplay"
5730
5731 if {$make_gui_count == 1} {
5732 no_x11_display
5733 }
5734 set lw [expr {$label_width / 2}]
5735 label $df_x11 -textvariable x11_display -width $lw -anchor w \
5736 -font $ffont
5737
5738 set df_vnc "$df.vdisplay"
5739
5740 if {$make_gui_count == 1} {
5741 no_vnc_display
5742 }
5743 label $df_vnc -textvariable vnc_display -width $lw -anchor w \
5744 -font $ffont
5745
5746 pack $df_x11 $df_vnc -side left
5747 pack $df -side top -fill x
5748
5749 # text area
5750 global text_height
5751 set text_area "$top.text"
5752 if {$screen_width <= 400} {
5753 text $text_area -height $text_height -width $label_width \
5754 -relief ridge -font $ffont
5755 } else {
5756 text $text_area -height $text_height -relief ridge -font $ffont
5757 }
5758 pack $text_area -side top -fill both -expand 1
5759 set top_widget_names(text) $text_area
5760
5761
5762 if {$text_area_str == ""} {
5763 set str "Click Help -> gui for overview."
5764 append_text "\n$str\n\n"
5765 } else {
5766 append_text $text_area_str
5767 }
5768
5769 # Make entry box stuff
5770 set ef "$top.entryframe"
5771 frame $ef -bd 1 -relief groove
5772 set top_widget_names(entryframe) $ef
5773
5774 # Entry Label
5775 set ef_label "$ef.label"
5776 label $ef_label -textvariable entry_str -anchor w -font $bfont
5777
5778 set entry_str "Set... : "
5779 set ef_entry "$ef.entry"
5780 entry $ef_entry -relief sunken -font $ffont
5781 bind $ef_entry <KeyPress-Return> {set entry_set 1}
5782 bind $ef_entry <KeyPress-Escape> {set entry_set 0}
5783
5784 set ok_s "OK"
5785 set cancel_s "Cancel"
5786 set help_s "Help"
5787 set browse_s "Browse..."
5788 global osname
5789 if {$osname == "Darwin"} {
5790 set ok_s " OK "
5791 set cancel_s " Cancel "
5792 set help_s " Help "
5793 set browse_s " Browse... "
5794 }
5795
5796 # Entry OK button
5797 set bpx "1m"
5798 set bpy "1"
5799 set hlt "0"
5800 set ef_ok "$ef.ok"
5801 button $ef_ok -text $ok_s -pady $bpy -padx $bpx -command {set entry_set 1} \
5802 -highlightthickness $hlt \
5803 -font $bfont
5804
5805 # Entry Skip button
5806 set ef_skip "$ef.skip"
5807 button $ef_skip -text $cancel_s -pady $bpy -padx $bpx -command {set entry_set 0} \
5808 -highlightthickness $hlt \
5809 -font $bfont
5810
5811 # Entry Help button
5812 set ef_help "$ef.help"
5813 button $ef_help -text $help_s -pady $bpy -padx $bpx -command \
5814 {menu_help $entry_dialog_item} -font $bfont \
5815 -highlightthickness $hlt
5816
5817 # Entry Browse button
5818 set ef_browse "$ef.browse"
5819 button $ef_browse -text $browse_s -pady $bpy -padx $bpx -font $bfont \
5820 -highlightthickness $hlt \
5821 -command {entry_insert [tk_getOpenFile]}
5822
5823 pack $ef_label -side left
5824 pack $ef_entry -side left -fill x -expand 1
5825 pack $ef_ok -side right
5826 pack $ef_skip -side right
5827 pack $ef_help -side right
5828 pack $ef -side bottom -fill x
5829
5830 set entry_ok $ef_ok
5831 set entry_skip $ef_skip
5832 set entry_help $ef_help
5833 set entry_box $ef_entry
5834 set entry_browse $ef_browse
5835 set entry_label $ef_label
5836 entry_disable
5837
5838}
5839
5840proc menu_bindings {m} {
5841 set db 0
5842 if {$db} {puts "menu_bindings $m"}
5843
5844 bind $m <<MenuSelect>> {
5845#syntax hilite bug \
5846MenuSelect>>
5847 set n [%W index active]
5848 set db 0
5849 if {$db} {puts stderr "menu_bindings %W $n"}
5850 set label " "
5851 if {$n != "none"} {
5852 set str %W,$n
5853 set which ""
5854
5855 if {$db} {puts "menu_bindings $str"}
5856 if {[info exists helplabel($str)]} {
5857 set vname [format %%-16s $helplabel($str)]
5858 set label "Click (?) for help on: $vname"
5859 set which $helplabel($str)
5860 }
5861 if {$which == ""} {
5862 ;
5863 } elseif {$which == "passwd" || $which == "viewpasswd"} {
5864 ;
5865 } elseif {[is_action $which]} {
5866 if {[info exists menu_var($which)]
5867 && $menu_var($which) != ""} {
5868 set label "$label value: $menu_var($which)"
5869 } else {
5870 set label "$label (is action)"
5871 }
5872 } elseif {[info exists menu_var($which)]} {
5873 set label "$label value: $menu_var($which)"
5874 if {$which == "http"} {
5875 global vnc_url
5876 set label "$label URL: $vnc_url"
5877 }
5878 }
5879 }
5880 set_info $label
5881 }
5882}
5883
5884proc key_bindings {} {
5885 global env menus_disabled
5886 if {[info exists env(USER)] && $env(USER) == "runge"} {
5887 # quick restart
5888 bind . <Control-KeyPress-k> {exec $argv0 $argv &; destroy .}
5889 }
5890 bind . <Control-KeyPress-p> { \
5891 global menus_disabled; \
5892 if {!$menus_disabled} {try_connect_and_query_all} \
5893 }
5894 bind . <Control-KeyPress-u> { \
5895 global menus_disabled; \
5896 if {!$menus_disabled} {query_all 0} \
5897 }
5898 bind . <Control-KeyPress-r> { \
5899 global menus_disabled; \
5900 if {!$menus_disabled} {query_all 0} \
5901 }
5902 bind . <Control-KeyPress-d> { \
5903 global menus_disabled; \
5904 if {!$menus_disabled} {detach_from_display} \
5905 }
5906 bind . <Control-KeyPress-a> { \
5907 global menus_disabled; \
5908 if {!$menus_disabled} {try_connect_and_query_all} \
5909 }
5910}
5911
5912proc stop_watch {onoff} {
5913 global orig_cursor text_area entry_box
5914
5915 set widgets [list .]
5916 if [info exists text_area] {
5917 if {$text_area != ""} {
5918 lappend widgets $text_area
5919 }
5920 }
5921 if [info exists entry_box] {
5922 if {$entry_box != ""} {
5923 lappend widgets $entry_box
5924 }
5925 }
5926
5927 if {$onoff == "on"} {
5928 foreach item $widgets {
5929 if {![winfo exists $item]} {
5930 continue
5931 }
5932 $item config -cursor {watch}
5933 }
5934 } else {
5935 foreach item $widgets {
5936 if {![winfo exists $item]} {
5937 continue
5938 }
5939 $item config -cursor {}
5940 }
5941 }
5942 update
5943}
5944
5945proc double_check_noremote {} {
5946 set msg "\n\n"
5947 append msg "*** WARNING: setting \"noremote\" will disable ALL remote control commands (i.e.\n"
5948 append msg "*** WARNING: *this* gui will be locked out). Do you really want to do this?\n"
5949 append msg "*** WARNING: If so, press \"OK\", otherwise press \"Cancel\"\n"
5950 append msg "\n"
5951 bell
5952 return [warning_dialog $msg "noremote"]
5953}
5954
5955proc get_settings_rcfile {} {
5956 global menu_var default_var unset_str
5957 global x11vnc_gui_params
5958
5959 set rc_txt ""
5960
5961 set menu_var(gui) $x11vnc_gui_params
5962
5963 foreach item [lsort [array names menu_var]] {
5964 if {$item == "gui"} {
5965 ;
5966 } elseif {![active_when_starting $item]} {
5967 continue
5968 } elseif {[is_action $item]} {
5969 continue
5970 }
5971 if {$item == "debug_gui"} {
5972 continue
5973 } elseif {$item == "WindowView"} {
5974 continue
5975 } elseif {$item == "rc" || $item == "norc"} {
5976 continue
5977 } elseif {$item == "loop"} {
5978 continue
5979 } elseif {$item == "loopbg"} {
5980 continue
5981 }
5982
5983 set def ""
5984 if {[info exists default_var($item)]} {
5985 set def $default_var($item)
5986 }
5987
5988
5989 set qst ""
5990 set hmm "#? "
5991 if {$item == "display"} {
5992 set qst $hmm
5993 } elseif {$item == "desktop"} {
5994 set qst $hmm
5995 } elseif {$item == "dontdisconnect"} {
5996 set qst $hmm
5997 } elseif {$item == "alwaysshared"} {
5998 set qst $hmm
5999 } elseif {$item == "nevershared"} {
6000 set qst $hmm
6001 } elseif {$item == "gui"} {
6002 set qst $hmm
6003 }
6004
6005 if {![info exists menu_var($item)]} {
6006 set mv $def
6007 } else {
6008 set mv $menu_var($item)
6009 }
6010#puts "item=$item def=$def mv=$mv"
6011 if {$mv == $unset_str} {
6012 set mv ""
6013 }
6014 set ntab 3
6015
6016 if {$item == "gui" || [value_is_string $item]} {
6017 set nitem [get_nitem $item]
6018
6019 if {$mv == "" && $def != ""} {
6020 set qst $hmm
6021 }
6022 set n 0
6023 if {$qst != ""} {
6024 append rc_txt $qst
6025 incr n [string length $qst]
6026 } elseif {$mv == $def} {
6027 append rc_txt "#d "
6028 incr n [string length "#d "]
6029 }
6030 set mt $mv
6031 regsub -all {#} $mt {\#} mt
6032 if {$mt == ""} {
6033 set mt {""}
6034 }
6035 append rc_txt "-$nitem $mt"
6036
6037 if {$mv != $def} {
6038 set m [string length "-$nitem $mt"]
6039 incr n $m
6040 set n [expr $n / 8]
6041 set c 0
6042 for {set i $n} {$i <= $ntab} {incr i} {
6043 append rc_txt "\t"
6044 incr c
6045 }
6046 if {$c == 0} {
6047 append rc_txt "\t"
6048 }
6049 regsub -all {#} $def {\#} def
6050 if {$def == ""} {
6051 set def {""}
6052 }
6053 append rc_txt "# default: $def"
6054 }
6055 append rc_txt "\n"
6056
6057 } elseif {[value_is_bool $item]} {
6058 set n 0
6059 if {$qst != ""} {
6060 append rc_txt $qst
6061 incr n [string length $qst]
6062 } elseif {$mv == $def} {
6063 append rc_txt "#d "
6064 incr n [string length "#d "]
6065 }
6066 if {$def == 1} {
6067 set dv "on"
6068 } else {
6069 set dv "off"
6070 }
6071 append rc_txt "-$item"
6072 set m [string length "-$item"]
6073 incr n $m
6074 set n [expr $n / 8]
6075 for {set i $n} {$i <= $ntab} {incr i} {
6076 append rc_txt "\t"
6077 }
6078 append rc_txt "# default: $dv"
6079 append rc_txt "\n"
6080
6081 }
6082 }
6083 return $rc_txt
6084}
6085
6086proc double_check_start_x11vnc {} {
6087 global hostname
6088 set msg [get_start_x11vnc_txt]
6089 bell
6090 append msg "\n"
6091 append msg "*** To run the above command on machine \"$hostname\" (thereby\n"
6092 append msg "*** starting x11vnc) press \"OK\", otherwise press \"Cancel\".\n"
6093 return [warning_dialog $msg "start"]
6094}
6095
6096proc get_start_x11vnc_txt {} {
6097 set cmd [get_start_x11vnc_cmd]
6098 set str [join $cmd]
6099 set msg ""
6100 append msg "\n"
6101 append msg "==== The command built so far is: ====\n";
6102 append msg "\n"
6103 append msg "$str\n"
6104 return $msg
6105}
6106
6107proc show_start_cmd {} {
6108 set msg [get_start_x11vnc_txt]
6109 append_text "$msg\n"
6110}
6111
6112proc get_nitem {item} {
6113 set nitem $item
6114 if {$nitem == "screen_blank"} {
6115 set nitem "sb"
6116 } elseif {$nitem == "xrandr_mode"} {
6117 set nitem "xrandr"
6118 } elseif {$nitem == "unixpw_list"} {
6119 set nitem "unixpw"
6120 } elseif {$nitem == "unixpw_nis_list"} {
6121 set nitem "unixpw_nis"
6122 } elseif {$nitem == "stunnel_pem"} {
6123 set nitem "stunnel"
6124 } elseif {$nitem == "ssl_pem"} {
6125 set nitem "ssl"
6126 } elseif {$nitem == "wireframe_mode"} {
6127 set nitem "wireframe"
6128 } elseif {$nitem == "solid_color"} {
6129 set nitem "solid"
6130 }
6131 return $nitem
6132}
6133
6134proc get_start_x11vnc_cmd {{show_rc 0}} {
6135 global cmd_var menu_var default_var unset_str x11vnc_prog
6136
6137 set xterm_cmd "xterm -iconic -geometry 80x35 -title x11vnc-console -e"
6138
6139 set cmd [split $xterm_cmd]
6140
6141 lappend cmd $x11vnc_prog
6142
6143 lappend cmd "-gui"
6144 lappend cmd "none"
6145
6146 set rc_txt ""
6147
6148 set saw_id 0
6149
6150 foreach item [lsort [array names menu_var]] {
6151 if {$item == "gui"} {
6152 continue
6153 } elseif {![active_when_starting $item]} {
6154 continue
6155 } elseif {[is_action $item]} {
6156 continue
6157 } elseif {$item == "debug_gui"} {
6158 continue
6159 } elseif {$item == "WindowView"} {
6160 continue
6161 }
6162
6163 if {$item == "id" || $item == "sid"} {
6164 set val $menu_var($item);
6165 if {$val == "0x0" || $val == "root"} {
6166 continue
6167 }
6168 }
6169 if {$item == "sid" && $saw_id} {
6170 continue
6171 }
6172 if {$item == "id"} {
6173 set saw_id 1
6174 } elseif {$item == "httpport" && $menu_var($item) == "0"} {
6175 continue
6176 } elseif {$item == "progressive" && $menu_var($item) == "0"} {
6177 continue
6178 } elseif {$item == "dontdisconnect" && $menu_var($item) == "-1"} {
6179 continue
6180 } elseif {$item == "alwaysshared" && $menu_var($item) == "-1"} {
6181 continue
6182 }
6183
6184 if {[value_is_bool $item]} {
6185 if {[info exists menu_var($item)]} {
6186 set add 1
6187 if {[info exists default_var($item)]} {
6188 if {$menu_var($item) == $default_var($item)} {
6189 set add 0;
6190 }
6191 } elseif {! $menu_var($item)} {
6192 set add 0
6193 }
6194 if {$add} {
6195 lappend cmd "-$item"
6196 append rc_txt "-$item\n"
6197 }
6198 }
6199 } elseif {[value_is_string $item]} {
6200 if {![info exists menu_var($item)]} {
6201 continue
6202 }
6203 if {$menu_var($item) != "" && $menu_var($item) != $unset_str} {
6204 set add 1
6205 set nitem [get_nitem $item]
6206
6207 if {[info exists default_var($item)]} {
6208 if {$menu_var($item) == $default_var($item)} {
6209 set add 0;
6210 }
6211 }
6212 if {$add} {
6213 lappend cmd "-$nitem"
6214 set mv $menu_var($item)
6215
6216 if {[regexp {^~} $mv]} {
6217 if {$item == "auth" ||
6218 $item == "rc" ||
6219 $item == "accept" ||
6220 $item == "connect" ||
6221 $item == "allow" ||
6222 $item == "passwdfile" ||
6223 $item == "o" ||
6224 $item == "logfile" ||
6225 $item == "remap" ||
6226 $item == "httpdir"} {
6227 set mv [tilde_expand $mv]
6228 }
6229 }
6230
6231 lappend cmd $mv
6232 set mt $mv
6233 regsub -all {#} $mt {\#} mt
6234 append rc_txt "-$nitem $mt\n"
6235 }
6236 }
6237 }
6238 }
6239 lappend cmd "2>"
6240 lappend cmd "/dev/null"
6241 lappend cmd "&"
6242
6243 if {$show_rc} {
6244 return $rc_txt
6245 } else {
6246 return $cmd
6247 }
6248}
6249
6250proc start_x11vnc {} {
6251 global menu_var unset_str
6252 global x11vnc_prog x11vnc_xdisplay
6253 global connected_to_x11vnc
6254
6255 if {$connected_to_x11vnc} {
6256 append_text "\n"
6257 append_text "WARNING: Still connected to an x11vnc server.\n"
6258 append_text "WARNING: Use \"stop\" or \"detach\" first.\n"
6259 return 0
6260 }
6261
6262 if {![double_check_start_x11vnc]} {
6263 return
6264 }
6265
6266 set x11vnc_xdisplay ""
6267 if {[info exists menu_var(display)]} {
6268 if {$menu_var(display) != "" && $menu_var(display) != $unset_str} {
6269 set x11vnc_xdisplay $menu_var(display)
6270 }
6271 }
6272
6273 set cmd [get_start_x11vnc_cmd]
6274
6275 set str [join $cmd]
6276 regsub { -e} $str " -e \\\n " str
6277
6278 if {0} {
6279 puts "running: $str"
6280 foreach word $cmd {
6281 puts " word: $word"
6282 }
6283 }
6284
6285 append_text "Starting x11vnc in an iconified xterm with command:\n"
6286 append_text " $str\n\n"
6287 catch {[eval exec $cmd]}
6288 after 500
6289 try_connect_and_query_all 3
6290 if {!$connected_to_x11vnc} {
6291 append_text "\nStarting x11vnc seems to have failed.\n"
6292 if {[regexp -- {-o } $str] || [regexp -- {-logfile} $str]} {
6293 append_text "Examine the logfile (Debugging -> show-logfile) for error messages.\n"
6294 } else {
6295 append_text "Rerun with a logfile (if needed) and examine the logfile\n"
6296 append_text "(Debugging -> show-logfile) for error messages.\n"
6297 }
6298 }
6299}
6300
6301proc run_remote_cmd_via_sock {opts} {
6302 global client_sock
6303
6304 set db 0
6305 if {[file channels $client_sock] == ""} {
6306 set client_sock ""
6307 return "fail"
6308 }
6309 if {[eof $client_sock]} {
6310 catch {close $client_sock}
6311 set client_sock ""
6312 return "fail"
6313 }
6314 set result ""
6315
6316 setup_client_sock 0
6317
6318 set docmd ""
6319 foreach opt $opts {
6320 if {$opt == "-R"} {
6321 set docmd "-R"
6322 continue
6323 } elseif {$opt == "-Q"} {
6324 set docmd "-Q"
6325 continue
6326 }
6327
6328 if {$docmd == ""} {
6329 continue
6330 } elseif {$docmd == "-R"} {
6331 set str "cmd=$opt"
6332 } elseif {$docmd == "-Q"} {
6333 set str "qry=$opt"
6334 } else {
6335 set docmd ""
6336 continue
6337 }
6338
6339 if {$db} {puts stderr "run_remote_cmd_via_sock: $docmd \"$str\""}
6340 catch {puts $client_sock $str}
6341 if {$db} {puts stderr "run_remote_cmd_via_sock: flush"}
6342 catch {flush $client_sock}
6343 if {$db} {puts stderr "run_remote_cmd_via_sock: gets"}
6344 catch {gets $client_sock res}
6345 if {$db} {puts stderr "run_remote_cmd_via_sock: \"$res\""}
6346 set res [string trim $res]
6347
6348 if [regexp {=clients:} $res] {
6349 regsub {^.*=clients:} $res "" cres
6350 regsub {,aro=.*$} $cres "" cres
6351 regsub {,ans=.*$} $cres "" cres
6352 if {$cres == "none"} {
6353 set cres ""
6354 }
6355 update_clients_menu $cres
6356 set client_str $cres
6357 set_client_balloon $cres
6358 }
6359
6360 if [regexp {^clients:} $res] {
6361 regsub {^clients:} $res "" tmp
6362 if {$tmp == "none"} {
6363 set tmp ""
6364 }
6365 update_clients_menu $tmp
6366 set client_str $tmp
6367 set_client_balloon $tmp
6368
6369 if ![regexp {^clients} $opt] {
6370 # we could block here...
6371 if {$db} {puts stderr "run_remote_cmd_via_sock: gets"}
6372 gets $client_sock res
6373 if {$db} {puts stderr "run_remote_cmd_via_sock: \"$res\""}
6374 set res [string trim $res]
6375 }
6376 }
6377
6378 set docmd ""
6379
6380 if {$res != ""} {
6381 append result "$res\n"
6382 }
6383 }
6384
6385 setup_client_sock 1
6386
6387 set result [string trim $result]
6388
6389 return $result
6390}
6391
6392proc run_remote_cmd {opts} {
6393 global menu_var x11vnc_prog x11vnc_cmdline x11vnc_xdisplay
6394 global x11vnc_auth_file x11vnc_connect_file
6395 global client_sock
6396
6397 set debug [in_debug_mode]
6398
6399 if {[lindex $opts 0] == "-R" && [lindex $opts 1] == "noremote"} {
6400 set str [join $opts]
6401 if ![double_check_noremote] {
6402 append_text "skipping: x11vnc $str"
6403 return ""
6404 } else {
6405 append_text "running: x11vnc $str (please do \"Actions -> detach\" to clean things up)\n"
6406 append_text "subsequent -R/-Q commands should fail..."
6407 }
6408 }
6409
6410 if {$client_sock != ""} {
6411 menus_disable
6412 stop_watch on
6413 set result [run_remote_cmd_via_sock $opts]
6414 stop_watch off
6415 menus_enable
6416 if {$result != "fail"} {
6417 return $result
6418 }
6419 }
6420
6421 set cmd ""
6422
6423 lappend cmd $x11vnc_prog;
6424
6425 if {$x11vnc_connect_file != ""} {
6426 lappend cmd "-connect"
6427 lappend cmd $x11vnc_connect_file
6428 } else {
6429 if {$x11vnc_xdisplay != ""} {
6430 lappend cmd "-display"
6431 lappend cmd $x11vnc_xdisplay
6432 }
6433 if {$x11vnc_auth_file != ""} {
6434 lappend cmd "-auth"
6435 lappend cmd $x11vnc_auth_file
6436 }
6437 }
6438 lappend cmd "-sync"
6439 foreach word $opts {
6440 lappend cmd $word
6441 }
6442 lappend cmd "2>"
6443 lappend cmd "/dev/null"
6444
6445 if {0 || $debug} {
6446 set str [join $cmd]
6447 puts "running: $str"
6448 foreach word $cmd {
6449 puts " word: $word"
6450 }
6451 }
6452
6453 set output ""
6454 menus_disable
6455
6456 stop_watch on
6457 catch {set output [eval exec $cmd]}
6458 stop_watch off
6459
6460 menus_enable
6461 if {$debug} {
6462 if {[string length $output] > 100} {
6463 set str [string range $output 0 100]
6464 append_text "output: $str ...\n"
6465 } else {
6466 append_text "output: $output\n"
6467 }
6468 }
6469 return $output
6470}
6471
6472proc try_connect_and_query_all {{n 2}} {
6473 for {set i 0} {$i < $n} {incr i} {
6474 if {$i > 0} {
6475 after 500
6476 append_text "trying again ...\n"
6477 }
6478 if {[try_connect]} {
6479 query_all
6480 break
6481 }
6482 }
6483}
6484
6485proc try_connect {} {
6486 global x11vnc_xdisplay connected_to_x11vnc reply_xdisplay
6487 global menu_var unset_str
6488
6489 set db 0
6490#dtime c1
6491
6492 if {! $connected_to_x11vnc} {
6493 if {[info exists menu_var(display)]} {
6494 set d $menu_var(display)
6495 if {$d != "" && $d != $unset_str && $d != $x11vnc_xdisplay} {
6496 set x11vnc_xdisplay $menu_var(display)
6497 append_text "Setting X display to: $x11vnc_xdisplay\n"
6498 }
6499 }
6500 }
6501
6502 set_info "Pinging $x11vnc_xdisplay ..."
6503 set rargs [list "-Q" "ping"]
6504 set result [run_remote_cmd $rargs]
6505#dtime c2a
6506
6507 if {$db} {puts "try_connect: \"$result\""}
6508
6509 if {[regexp {^ans=ping:} $result]} {
6510 regsub {^ans=ping:} $result {} reply_xdisplay
6511 set msg "Connected to $reply_xdisplay"
6512 set_info $msg
6513 append_text "$msg\n"
6514 set_connected yes
6515
6516 setup_client_channel
6517#dtime c2b
6518 setup_client_sock 1
6519 setup_client_tail
6520
6521 fetch_displays
6522#dtime c3a
6523 return 1
6524 } else {
6525 set str "x11vnc server."
6526 if {$x11vnc_xdisplay != ""} {
6527 set str $x11vnc_xdisplay
6528 }
6529 set msg "No reply from $str"
6530 set_info $msg
6531 append_text "$msg\n"
6532 set_connected no
6533 return 0
6534 }
6535}
6536
6537proc set_view_variable {val} {
6538 global menu_var
6539 set menu_var(WindowView) $val
6540}
6541proc get_view_variable {} {
6542 global menu_var
6543 if {![info exists menu_var(WindowView)]} {
6544 set menu_var(WindowView) "none"
6545 }
6546 return $menu_var(WindowView)
6547}
6548
6549proc dono {a b c} {
6550 exit 1;
6551}
6552
6553proc do_port_prompt {} {
6554 global bfont ffont
6555 global port_reply port_set
6556
6557 set guess 5900
6558 for {set i 0} {$i < 50} {incr i} {
6559 set fh ""
6560 set try [expr $guess + $i]
6561 catch {set fh [socket -server dono $try]}
6562 if {$fh != ""} {
6563 catch {close $fh}
6564 set guess $try
6565 break;
6566 }
6567 }
6568 set hn ""
6569 catch {set hn [exec uname -n]}
6570 if {$hn == ""} {
6571 set hn "hostname"
6572 }
6573
6574 set text " Set the x11vnc Listening Port:
6575
6576 VNC Display :0 corresponds to TCP port 5900
6577 VNC Display :1 corresponds to TCP port 5901
6578 etc.
6579
6580 In the Entry below, indicate a Port for x11vnc to listen on.
6581
6582 Note that to connect to x11vnc, a VNC Viewer will need to
6583 know your selection, for example:
6584
6585 vncviewer $hn:0
6586 vncviewer $hn:1
6587 etc.
6588
6589 Your firewall may block incoming connections to TCP ports;
6590 if it does you may need to reconfigure it.
6591
6592 You can also set some additional parameters:
6593
6594 - Enable SSL encryption.
6595 (requires an SSL enabled vncviewer, such as SSVNC)
6596 - Listen only on localhost. (e.g. for an SSH tunnel)
6597 - Enable UltraVNC or TightVNC File transfer.
6598"
6599 set port_set $guess
6600 set port_reply ""
6601
6602 toplevel .pp
6603 wm title .pp "Select x11vnc port"
6604
6605 wm protocol . WM_DELETE_WINDOW "destroy .; exit"
6606 wm protocol .pp WM_DELETE_WINDOW "destroy .pp; exit"
6607
6608 label .pp.m -text "$text" -relief ridge -justify left -font $ffont
6609
6610 global tk_version
6611 set tkold 0
6612 if [info exists tk_version] {
6613 if [regexp {^8\.[0-3]$} $tk_version] {
6614 set tkold 1
6615 }
6616 if [regexp {^[3-7]\.} $tk_version] {
6617 set tkold 1
6618 }
6619 }
6620
6621 if {$tkold} {
6622 frame .pp.f -bd 1 -relief ridge
6623 } else {
6624 frame .pp.f -bd 1 -relief ridge -pady 2
6625 }
6626 label .pp.f.l -text "Port: " -font $bfont
6627 entry .pp.f.e -width 8 -textvariable port_set -font $ffont
6628 global enable_ssl; set enable_ssl 0
6629 if [info exists env(X11VNC_SSL_ENABLED)] {
6630 set enable_ssl 1
6631 }
6632 checkbutton .pp.f.ssl -relief raised -pady 3 -padx 3 -text "Enable SSL" -variable enable_ssl -font $bfont
6633 global localhost; set localhost 0
6634 if [info exists env(X11VNC_LOCALHOST_ENABLED)] {
6635 set localhost 1
6636 }
6637 checkbutton .pp.f.loc -relief raised -pady 3 -padx 3 -text "Listen on localhost" -variable localhost -font $bfont
6638 pack .pp.f.l .pp.f.e -side left
6639 pack .pp.f.loc .pp.f.ssl -side right
6640
6641 if {$tkold} {
6642 frame .pp.t -bd 1 -relief ridge
6643 } else {
6644 frame .pp.t -bd 1 -relief ridge -pady 2
6645 }
6646 global file_transfer; set file_transfer "none"
6647 if [info exists env(X11VNC_FILETRANSFER_ENABLED)] {
6648 set file_transfer $env(X11VNC_FILETRANSFER_ENABLED)
6649 }
6650 label .pp.t.l -text "File Transfer: " -font $bfont
6651 radiobutton .pp.t.none -text "None" -variable file_transfer -value "none" -font $bfont
6652 radiobutton .pp.t.ultra -text "UltraVNC" -variable file_transfer -value "ultra" -font $bfont
6653 radiobutton .pp.t.tight -text "TightVNC" -variable file_transfer -value "tight" -font $bfont
6654 pack .pp.t.l .pp.t.none .pp.t.ultra .pp.t.tight -side left
6655
6656 frame .pp.o -bd 1 -relief ridge
6657 button .pp.o.ok -text "OK" -command "set port_reply 1; destroy .pp" -font $bfont
6658 button .pp.o.cancel -text "Cancel" -command "set port_reply 0; destroy .pp" -font $bfont
6659 pack .pp.o.ok .pp.o.cancel -side left -fill x -expand 1
6660 pack .pp.m -side top -fill x -expand 1
6661 pack .pp.f .pp.t .pp.o -side top -fill x
6662
6663 focus .pp.f.e
6664 .pp.f.e icursor end
6665
6666 wm withdraw .pp
6667 update
6668 center_win .pp
6669
6670 wm minsize .pp [winfo width .pp] [winfo height .pp]
6671
6672 bind .pp.f.e <KeyPress-Return> "set port_reply 1; destroy .pp"
6673
6674 vwait port_reply
6675
6676 if {$port_reply} {
6677 regsub -all {^:} $port_set "" port_set
6678 regsub -all {[ \t]} $port_set "" port_set
6679 if {[regexp {^[0-9][0-9]*$} $port_set]} {
6680 if {$port_set < 0} {
6681 set port_set [expr 0 - $port_set]
6682 } elseif {$port_set < 200} {
6683 set port_set [expr $port_set + 5900]
6684 }
6685 puts "$port_set:ssl${enable_ssl}:localhost$localhost:ft_$file_transfer"
6686 }
6687 }
6688}
6689
6690proc change_view_state {} {
6691 global menu_var gui_current_state
6692
6693 set new [get_view_variable]
6694
6695 if {![info exists gui_current_state]} {
6696 set gui_current_state ""
6697 }
6698 set old $gui_current_state
6699 #puts "$old -> $new"
6700
6701 if {$old == $new} {
6702 return
6703 }
6704
6705 if {$old == "full" || $old == "icon" || $old == "tray"} {
6706 ;
6707 } else {
6708 set old "none"
6709 }
6710
6711 if {$new == "full" || $new == "icon" || $new == "tray"} {
6712 if {$old == "tray"} {
6713 # sigh XReparentWindow would be too easy...
6714 # undo_tray_embed
6715 restart_everything $new
6716 destroy .
6717 exit
6718 }
6719 make_gui $new
6720 if {$new == "tray"} {
6721 wm withdraw .
6722 }
6723 } else {
6724 set_view_variable $old
6725 }
6726}
6727
6728proc setup_client_tail {} {
6729 global client_tail
6730 if {$client_tail != ""} {
6731 fileevent $client_tail readable read_client_tail
6732 }
6733}
6734
6735proc setup_client_sock {{enable 1}} {
6736 global client_sock
6737 if {$client_sock != ""} {
6738 if {$enable} {
6739 fileevent $client_sock readable read_client_sock
6740 } else {
6741 fileevent $client_sock readable ""
6742 }
6743 }
6744}
6745
6746proc setup_tray_embed {} {
6747 update
6748 set w [winfo width .]
6749 set h [winfo height .]
6750 if {$w < 24} {
6751 set w 24
6752 }
6753 if {$h < 24} {
6754 set h 24
6755 }
6756 wm minsize . $w $h
6757 set wid [winfo id .]
6758 push_new_value "remote-cmd" "remote-cmd" "trayembed:$wid" 0
6759}
6760
6761proc restart_everything {gui_mode} {
6762 global env gui_argv0 x11vnc_prog full_win
6763 global icon_mode_at_startup
6764 global tray_embed tray_running
6765 if {$gui_mode == "full"} {
6766 set env(X11VNC_ICON_MODE) 0
6767 } elseif {$gui_mode == "icon"} {
6768 set env(X11VNC_ICON_MODE) 1
6769 } elseif {$gui_mode == "tray"} {
6770 if {$tray_running} {
6771 set env(X11VNC_ICON_MODE) "RUNNING"
6772 } else {
6773 set env(X11VNC_ICON_MODE) "TRAY"
6774 }
6775 }
6776 puts stderr ""
6777 puts stderr "tkx11vnc: restarting gui to leave tray mode."
6778 puts stderr " new gui will be running in the background."
6779 puts stderr " use kill(1) rather than Ctrl-C to kill it."
6780 puts stderr ""
6781 if {[info exists env(X11VNC_RESTART_DEPTH)]} {
6782 set n $env(X11VNC_RESTART_DEPTH)
6783 incr n
6784 set env(X11VNC_RESTART_DEPTH) $n
6785 } else {
6786 set env(X11VNC_RESTART_DEPTH) 0
6787 }
6788 set env(X11VNC_ICON_SETPASS) ""
6789
6790 if {![info exists env(X11VNC_WISHCMD)]} {
6791 puts stderr "failure in restart_everything."
6792 exit 1;
6793 }
6794
6795 set code [exec $x11vnc_prog -printgui]
6796 if {[string length $code] < 20000} {
6797 puts stderr "failure in restart_everything."
6798 exit 1;
6799 }
6800 set tmp "/tmp/x11vnc[pid]"
6801 append tmp [clock clicks]
6802 set tmp2 ""
6803 catch {set tmp2 [exec mktemp $tmp.XXXXXX 2>/dev/null]}
6804 if {$tmp2 != "" && [file exists $tmp2]} {
6805 set tmp $tmp2
6806 } else {
6807 file delete -force $tmp
6808 if {[file exists $tmp]} {
6809 puts stderr "failure in restart_everything."
6810 exit 1;
6811 }
6812 }
6813 set fh [open $tmp "a"]
6814 if {![file owned $tmp]} {
6815 puts stderr "failure in restart_everything."
6816 exit 1;
6817 }
6818 file attributes $tmp -permissions "0400"
6819 puts $fh $code
6820 close $fh
6821
6822 #puts stderr [exec ls -l $tmp]
6823
6824 wm withdraw .
6825 catch {wm withdraw $full_win}
6826 update
6827
6828 exec $env(X11VNC_WISHCMD) $tmp &
6829 after 2000
6830 file delete -force $tmp
6831
6832 destroy .
6833 exit
6834}
6835
6836proc undo_tray_embed {} {
6837 set wid [winfo id .]
6838 push_new_value "remote-cmd" "remote-cmd" "trayunembed:$wid" 0
6839}
6840
6841############################################################################
6842# main:
6843
6844if [info exists env(X11VNC_GUI_TIME)] {
6845 dtime M
6846}
6847
6848wm withdraw .
6849
6850global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect;
6851global x11vnc_xdisplay0
6852global x11vnc_client_file x11vnc_gui_geom x11vnc_started vnc_url
6853global x11vnc_gui_params
6854global x11vnc_auth_file x11vnc_connect_file beginner_mode simple_gui_created
6855global helpall helptext helpremote helplabel hostname osname
6856global all_settings reply_xdisplay always_update
6857global max_text_height max_text_width
6858global text_height
6859global menu_var unset_str menus_disabled
6860global bfont ffont sfont snfont old_labels have_labelframes
6861global connected_to_x11vnc
6862global cache_all_query_vars
6863global last_query_all_time query_all_freq client_tail client_sock client_info_read
6864global icon_mode icon_mode_at_startup x11vnc_icon_mode
6865global tray_embed tray_running icon_setpasswd icon_embed_id
6866global icon_noadvanced icon_minimal
6867global make_gui_count text_area_str
6868global gui_argv0 gui_start_mode
6869global screen_height screen_width
6870
6871set unset_str "(unset)"
6872set vnc_url $unset_str
6873set connected_to_x11vnc 0
6874set menus_disabled 0
6875set max_text_height 40
6876set max_text_width 90
6877set text_height 14
6878set bfont "-adobe-helvetica-bold-r-*-*-*-120-*-*-*-*-*-*"
6879set sfont "-adobe-helvetica-bold-r-*-*-*-100-*-*-*-*-*-*"
6880set snfont "-adobe-helvetica-medium-r-*-*-*-100-*-*-*-*-*-*"
6881set ffont "fixed"
6882
6883set got_helv 0
6884catch {
6885 foreach fam [font families] {
6886 if {$fam == "helvetica"} {
6887 set got_helv 1
6888 }
6889 if {$fam == "Helvetica"} {
6890 set got_helv 1
6891 }
6892 }
6893}
6894
6895if {$got_helv} {
6896 set bfont "Helvetica -12 bold"
6897 set sfont "Helvetica -10 bold"
6898 set snfont "Helvetica -10"
6899}
6900
6901set ls ""
6902catch {set ls [font metrics $bfont -linespace]}
6903if {$ls != "" && $ls > 14} {
6904 # some recent setups have BIG rendering for the above fonts.
6905 # on recent (8/08) debian these are really ragged:
6906 set bfont "-adobe-helvetica-bold-r-*-*-*-90-*-*-*-*-*-*"
6907 set sfont "-adobe-helvetica-bold-r-*-*-*-75-*-*-*-*-*-*"
6908 set snfont "-adobe-helvetica-medium-r-*-*-*-75-*-*-*-*-*-*"
6909
6910 set ls ""
6911 catch {set ls [font metrics $bfont -linespace]}
6912 if {$ls != "" && $ls < 14} {
6913 # these are bigger but look better... but for how long?
6914 set bfont "-adobe-helvetica-bold-r-*-*-*-100-*-*-*-*-*-*"
6915 set sfont "-adobe-helvetica-bold-r-*-*-*-80-*-*-*-*-*-*"
6916 set snfont "-adobe-helvetica-medium-r-*-*-*-80-*-*-*-*-*-*"
6917
6918 # maybe consider... {-font font Font {Helvetica -12 bold} {Helvetica -12 bold}}
6919 # or stick with system font like ssvnc.
6920 }
6921}
6922
6923# need to check if "fixed" font under XFT on tk8.5 is actually fixed width!!
6924set ls ""
6925catch {set ls [font metrics $ffont -linespace]}
6926set fs ""
6927catch {set fs [font metrics $ffont -fixed]}
6928set redo 0
6929if {$fs != "" && $fs != "1"} {
6930 set redo 1
6931}
6932if {$ls != "" && $ls > 14} {
6933 set redo 1
6934}
6935if {$redo} {
6936 foreach fn [font names] {
6937 if {$fn == "TkFixedFont"} {
6938 set ffont $fn
6939 break
6940 }
6941 }
6942}
6943
6944set help_indent 24;
6945set reply_xdisplay ""
6946set all_settings "None so far."
6947set always_update 1
6948set cache_all_query_vars ""
6949set query_all_freq 120
6950set last_query_all_time [clock seconds]
6951set client_tail ""
6952set client_sock ""
6953set client_info_read 0
6954set make_gui_count 0
6955set text_area_str ""
6956set gui_argv0 $argv0
6957set gui_start_mode ""
6958
6959if {$tk_version < 8.0} {
6960 puts stderr ""
6961 puts stderr "*** tkx11vnc: tk version is old $tk_version, please use 8.0 or higher."
6962 puts stderr "*** will try to continue with reduced functionality..."
6963 puts stderr ""
6964}
6965if {[regexp {^[34]} $tk_version] || $tk_version == "8.0"} {
6966 set old_labels 1
6967} else {
6968 set old_labels 0
6969}
6970set have_labelframes 1
6971if {$tk_version < 8.4} {
6972 set have_labelframes 0
6973}
6974
6975set screen_height [winfo screenheight .]
6976set screen_width [winfo screenwidth .]
6977if {$screen_height < 700} {
6978 # short screen, netbook?
6979 set max_text_height 30
6980 if {$screen_height < 500} {
6981 # short screen, PDA?
6982 set max_text_height 22
6983 set text_height 13
6984 if {$screen_height <= 360} {
6985 # very short.
6986 set max_text_height 16
6987 set max_text_width 60
6988 set text_height 11
6989 }
6990 }
6991}
6992if {[info exists env(X11VNC_GUI_TEXT_HEIGHT)]} {
6993 set max_text_height $env(X11VNC_GUI_TEXT_HEIGHT)
6994}
6995if {[info exists env(X11VNC_GUI_TEXT_WIDTH)]} {
6996 set max_text_width $env(X11VNC_GUI_TEXT_WIDTH)
6997}
6998
6999if {"$argv" == "-spit"} {
7000 set fh [open $argv0 r]
7001 puts "#ifndef _TKX11VNC_H"
7002 puts "#define _TKX11VNC_H"
7003 puts "#ifdef NOGUI"
7004 puts "char gui_code\[\] = \"\";"
7005 puts "#else"
7006 puts "/*"
7007 puts " * tkx11vnc.h: generated by 'tkx11vnc -spit'"
7008 puts " * Abandon all hope, ye who enter here..."
7009 puts " * ...edit tkx11vnc instead."
7010 puts " */"
7011 puts " char gui_code\[\] ="
7012 while {[gets $fh line] > -1} {
7013 regsub -all {\\} $line {\\\\} line
7014 regsub -all {"} $line {\\"} line
7015 puts "\"$line\\n\""
7016 }
7017 puts "#endif"
7018 puts "/* ifdef NOGUI */"
7019 puts "#endif"
7020 puts "/* ifndef _TKX11VNC_H */"
7021 close $fh
7022 puts ";"
7023 exit 0
7024}
7025
7026set_view_variable "full"
7027
7028#puts [exec env | grep X11VNC]
7029
7030# Read environment for clues:
7031
7032set x11vnc_client_file "";
7033if {[info exists env(X11VNC_CLIENT_FILE)]} {
7034 set x11vnc_client_file $env(X11VNC_CLIENT_FILE);
7035 set file $x11vnc_client_file
7036
7037 set client_tail ""
7038 if {[file exists $file] && [file isfile $file]} {
7039 if {[file readable $file] && [file owned $file]} {
7040 set client_tail [open "|tail -f $x11vnc_client_file" "r"]
7041 }
7042 }
7043 if {$client_tail != ""} {
7044 gets $client_tail tmp
7045 if [eof $client_tail] {
7046#puts "eof $client_tail"
7047 clean_client_tail
7048 set client_tail ""
7049 }
7050 }
7051 catch {file delete -force $x11vnc_client_file}
7052}
7053
7054if {[info exists env(X11VNC_PROG)]} {
7055 set x11vnc_prog $env(X11VNC_PROG);
7056} else {
7057 set x11vnc_prog "x11vnc";
7058}
7059
7060if {[info exists env(X11VNC_CMDLINE)]} {
7061 set x11vnc_cmdline $env(X11VNC_CMDLINE);
7062} else {
7063 set x11vnc_cmdline "";
7064}
7065
7066if {[info exists env(X11VNC_CONNECT)]} {
7067 set x11vnc_connect 1
7068} else {
7069 set x11vnc_connect 0;
7070}
7071
7072if {[info exists env(X11VNC_GUI_GEOM)]} {
7073 set x11vnc_gui_geom $env(X11VNC_GUI_GEOM);
7074} else {
7075 set x11vnc_gui_geom ""
7076}
7077if {[info exists env(X11VNC_GUI_PARAMS)]} {
7078 set x11vnc_gui_params $env(X11VNC_GUI_PARAMS);
7079} else {
7080 set x11vnc_gui_params ""
7081}
7082
7083if {[info exists env(X11VNC_FONT_BOLD)]} {
7084 set bfont $env(X11VNC_FONT_BOLD)
7085}
7086if {[info exists env(X11VNC_FONT_BOLD_SMALL)]} {
7087 set sfont $env(X11VNC_FONT_BOLD_SMALL)
7088}
7089if {[info exists env(X11VNC_FONT_REG_SMALL)]} {
7090 set snfont $env(X11VNC_FONT_REG_SMALL)
7091}
7092if {[info exists env(X11VNC_FONT_FIXED)]} {
7093 set ffont $env(X11VNC_FONT_FIXED)
7094}
7095
7096if {[info exists env(X11VNC_CONNECT_FILE)]} {
7097 set x11vnc_connect_file $env(X11VNC_CONNECT_FILE);
7098} else {
7099 set x11vnc_connect_file "";
7100}
7101
7102set x11vnc_started 0
7103if {[info exists env(X11VNC_STARTED)]} {
7104 set x11vnc_started 1
7105}
7106
7107set x11vnc_xdisplay ""
7108if {[info exists env(X11VNC_XDISPLAY)]} {
7109 set x11vnc_xdisplay $env(X11VNC_XDISPLAY);
7110 set x11vnc_connect 1
7111
7112} elseif {$argv != "" && [regexp {:[0-9]} $argv]} {
7113 set env(X11VNC_XDISPLAY) "$argv"
7114 set x11vnc_xdisplay "$argv"
7115 set x11vnc_connect 1
7116
7117} elseif {[info exists env(DISPLAY)]} {
7118 set x11vnc_xdisplay $env(DISPLAY);
7119} else {
7120 set x11vnc_xdisplay ":0";
7121}
7122set x11vnc_xdisplay0 $x11vnc_xdisplay
7123
7124if {[info exists env(X11VNC_AUTH_FILE)]} {
7125 set x11vnc_auth_file $env(X11VNC_AUTH_FILE)
7126} else {
7127 set x11vnc_auth_file ""
7128}
7129
7130set simple_gui_created 0
7131if {[info exists env(X11VNC_SIMPLE_GUI)]} {
7132 set beginner_mode 1
7133} else {
7134 set beginner_mode 0
7135}
7136
7137set icon_mode 0
7138set x11vnc_icon_mode 0
7139set tray_embed 0
7140set tray_running 0
7141
7142if {![info exists env(X11VNC_ICON_MODE_AT_STARTUP)]} {
7143 if {[info exists env(X11VNC_ICON_MODE)]} {
7144 if {$env(X11VNC_ICON_MODE) != 0} {
7145 set env(X11VNC_ICON_MODE_AT_STARTUP) 1
7146 } else {
7147 set env(X11VNC_ICON_MODE_AT_STARTUP) 0
7148 }
7149 } else {
7150 set env(X11VNC_ICON_MODE_AT_STARTUP) 0
7151 }
7152}
7153set icon_mode_at_startup $env(X11VNC_ICON_MODE_AT_STARTUP)
7154
7155if {![info exists env(X11VNC_ICON_MODE)]} {
7156 set icon_mode 0
7157} elseif {$env(X11VNC_ICON_MODE) == "" || $env(X11VNC_ICON_MODE) == "0"} {
7158 set icon_mode 0
7159} else {
7160 set icon_mode 1
7161 set_view_variable "icon"
7162 if [regexp -nocase {TRAY} $env(X11VNC_ICON_MODE)] {
7163 set tray_embed 1
7164 }
7165 if [regexp -nocase {RUNNING} $env(X11VNC_ICON_MODE)] {
7166 set tray_running 1
7167 }
7168}
7169
7170set icon_setpasswd 0
7171if {[info exists env(X11VNC_ICON_SETPASS)]} {
7172 if {$env(X11VNC_ICON_SETPASS) != ""} {
7173 set icon_setpasswd 1
7174 }
7175}
7176
7177set icon_noadvanced 0
7178if {[info exists env(X11VNC_ICON_NOADVANCED)]} {
7179 set icon_noadvanced 1
7180}
7181
7182set icon_minimal 0
7183if {[info exists env(X11VNC_ICON_MINIMAL)]} {
7184 set icon_minimal 1
7185}
7186
7187if {[info exists env(X11VNC_ICON_EMBED_ID)]} {
7188 set icon_embed_id $env(X11VNC_ICON_EMBED_ID)
7189} else {
7190 set icon_embed_id ""
7191}
7192
7193
7194set hostname [exec uname -n]
7195set osname [exec uname]
7196
7197if {[regexp -nocase {IRIX} $osname]} {
7198 # IRIX "fixed" font is huge and doublespaced...
7199 set ffont $snfont
7200}
7201if {[regexp -nocase {Darwin} $osname]} {
7202 set ffont {Monaco 10}
7203 set bfont {system}
7204}
7205
7206if {"$argv" == "-portprompt"} {
7207 do_port_prompt
7208 exit 0
7209}
7210
7211#puts [exec env]
7212#puts "x11vnc_xdisplay: $x11vnc_xdisplay"
7213
7214set env(X11VNC_STD_HELP) 1
7215
7216# scrape the help output for the text and remote control vars:
7217parse_help;
7218parse_remote_help;
7219parse_query_help;
7220
7221# tweaks to duplicate help text:
7222tweak_remote_help lock deny
7223tweak_remote_help unlock deny
7224
7225tweak_both quiet q
7226tweak_help logfile o
7227tweak_both xwarppointer xwarp
7228tweak_both screen_blank sb
7229
7230set_template
7231
7232set_name "tkx11vnc"
7233
7234key_bindings;
7235
7236get_default_vars
7237
7238dtime D
7239
7240proc check_setpasswd {} {
7241 global env icon_setpasswd
7242 global do_props_msg
7243 set do_props_msg ""
7244 if {$icon_setpasswd} {
7245 set m "\n"
7246 set m "${m} Note the x11vnc icon in the system tray.\n"
7247 set m "${m} This panel is its 'Properties' dialog.\n"
7248 set m "${m}\n"
7249 set m "${m} To specify a Session Password and to\n"
7250 set m "${m} allow VNC viewers to connect, follow\n"
7251 set m "${m} these steps:\n"
7252 set m "${m}\n"
7253 set m "${m} Enter a passwd in the Password field\n"
7254 set m "${m} (it can be left blank.) You can also\n"
7255 set m "${m} supply a ViewOnly passwd if desired.\n"
7256 set m "${m}\n"
7257 set m "${m} Set 'Accept Connections' and then Press \n"
7258 set m "${m} 'Apply' to allow incoming connections.\n"
7259 set m "${m}\n"
7260 set m "${m} No Viewer can connect until you do this.\n"
7261 set m "${m}\n"
7262 set m "${m} The passwords are only for this x11vnc\n"
7263 set m "${m} session and are not saved. Run x11vnc\n"
7264 set m "${m} manually for more control (e.g. -rfbauth \n"
7265 set m "${m} for a saved password.)\n"
7266 set m "${m}\n"
7267 set m "${m} See 'Help' for details on each option.\n"
7268
7269 global x11vnc_cmdline
7270
7271 set dossl 0
7272 if {[info exists x11vnc_cmdline]} {
7273 if [regexp -- {-ssl} $x11vnc_cmdline] {
7274 set dossl 1
7275 }
7276 }
7277 if {$dossl || [info exists env(X11VNC_GOT_SSL)]} {
7278 set m "${m}\n"
7279 set m "${m} SSL encryption mode active. You can\n"
7280 set m "${m} find your Public Cert in the Logfile\n"
7281 set m "${m} and also the ~/.vnc/certs directory.\n"
7282 }
7283
7284 if {[info exists env(X11VNC_SETPASS_FAIL)]} {
7285 set pp 5900
7286 if {[info exists env(X11VNC_GOT_RFBPORT_VAL)]} {
7287 if {$env(X11VNC_GOT_RFBPORT_VAL) > 0} {
7288 set pp $env(X11VNC_GOT_RFBPORT_VAL)
7289 }
7290 }
7291
7292 set m " The x11vnc program failed to start! \n"
7293 set m "${m}\n"
7294 set m "${m} Maybe there is another VNC server\n"
7295 set m "${m} already listening on port $pp?\n"
7296 set m "${m}\n"
7297 set m "${m} You will need to start over after\n"
7298 set m "${m} you make sure x11vnc can start.\n"
7299 }
7300
7301 set do_props_msg $m
7302 do_props
7303 }
7304}
7305
7306if {0} {
7307 if {[info exists env(X11VNC_ICON_SETPASS)]} {
7308 if {$env(X11VNC_ICON_SETPASS) == "2"} {
7309 global icon_mode_at_startup icon_mode
7310 set icon_mode_at_startup 1
7311 set icon_mode 2
7312 }
7313 }
7314}
7315
7316if {$icon_mode} {
7317 if {$icon_mode == 2} {
7318 make_gui "full"
7319 } elseif {$tray_embed} {
7320 make_gui "tray"
7321 } else {
7322 make_gui "icon"
7323 }
7324 dtime G
7325 old_balloon
7326 check_setpasswd
7327 push_new_value "remote-cmd" "remote-cmd" "Q:clients" 1
7328} else {
7329 make_gui "full"
7330 dtime G
7331 check_setpasswd
7332}
7333
7334
7335# main loop.