1#!/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. 7336