From 4fdb4cc67f1563156593e5b3deca80acf35f39ed Mon Sep 17 00:00:00 2001 From: runge Date: Sun, 4 Jan 2009 03:10:39 +0000 Subject: [PATCH] x11vnc: add -rmflag option, -rawfb vt support, bpp < 8 support for rawfb, find /dev/video better. Fix reverse SSL connection for DH. Some improvements for CUPS TS helper, restart if needed. --- x11vnc/ChangeLog | 5 + x11vnc/README | 570 ++++++++++++++++++++++++++----------------- x11vnc/cleanup.c | 26 +- x11vnc/connections.c | 2 - x11vnc/help.c | 163 +++++++++---- x11vnc/linuxfb.c | 67 ++++- x11vnc/options.c | 2 + x11vnc/options.h | 2 + x11vnc/pointer.c | 2 + x11vnc/remote.c | 4 + x11vnc/scan.c | 222 ++++++++++++++++- x11vnc/screen.c | 204 ++++++++++++---- x11vnc/sslhelper.c | 41 +++- x11vnc/v4l.c | 14 +- x11vnc/x11vnc.1 | 167 +++++++++---- x11vnc/x11vnc.c | 99 +++++++- x11vnc/x11vnc.h | 6 + x11vnc/x11vnc_defs.c | 8 +- x11vnc/xwrappers.c | 162 ++++++++++++ 19 files changed, 1374 insertions(+), 392 deletions(-) diff --git a/x11vnc/ChangeLog b/x11vnc/ChangeLog index 5a289b7..128ca49 100644 --- a/x11vnc/ChangeLog +++ b/x11vnc/ChangeLog @@ -1,3 +1,8 @@ +2009-01-03 Karl Runge + * x11vnc: add -rmflag option, -rawfb vt support, bpp < 8 support + for rawfb, find /dev/video better. Fix reverse SSL connection + for DH. Some improvements for CUPS TS helper, restart if needed. + 2008-12-10 Karl Runge * x11vnc: 0.9.6 release. Some strtok bugfixes. rename -tlsvnc to -anontls. Disable ssl caching. No cert creation prompting diff --git a/x11vnc/README b/x11vnc/README index 3b86207..8d4ed68 100644 --- a/x11vnc/README +++ b/x11vnc/README @@ -1,5 +1,5 @@ -x11vnc README file Date: Mon Dec 8 22:48:46 EST 2008 +x11vnc README file Date: Sat Jan 3 19:10:09 EST 2009 The following information is taken from these URLs: @@ -573,12 +573,12 @@ vncviewer -via $host localhost:0 # must be TightVNC vncviewer. SourceForge.net. I use libvncserver for all of the VNC aspects; I couldn't have done without it. The full source code may be found and downloaded (either file-release tarball or CVS tree) from the above - link. As of Oct 2008, the [90]x11vnc-0.9.5.tar.gz source package is - released (recommended download). The [91]x11vnc 0.9.5 release notes. + link. As of Dec 2008, the [90]x11vnc-0.9.6.tar.gz source package is + released (recommended download). The [91]x11vnc 0.9.6 release notes. The x11vnc package is the subset of the libvncserver package needed to build the x11vnc program. Also, you can get a copy of my latest, - bleeding edge [92]x11vnc-0.9.6.tar.gz tarball to build the most up to + bleeding edge [92]x11vnc-0.9.7.tar.gz tarball to build the most up to date one. Precompiled Binaries/Packages: See the [93]FAQ below for information @@ -616,13 +616,13 @@ vncviewer -via $host localhost:0 # must be TightVNC vncviewer. them by default.) If your OS has libjpeg.so and libz.so in standard locations you can - build as follows (example given for the 0.9.5 release of x11vnc: + build as follows (example given for the 0.9.6 release of x11vnc: replace with the version you downloaded): (un-tar the x11vnc+libvncserver tarball) -# gzip -dc x11vnc-0.9.5.tar.gz | tar -xvf - +# gzip -dc x11vnc-0.9.6.tar.gz | tar -xvf - (cd to the source directory) -# cd x11vnc-0.9.5 +# cd x11vnc-0.9.6 (run configure and then run make) # ./configure @@ -864,13 +864,13 @@ make I'd appreciate any additional testing very much. Thanks to those who suggested features and helped beta test x11vnc - 0.9.5 released in Oct 2008! + 0.9.6 released in Dec 2008! - Please help test and debug the 0.9.6 version for release sometime in + Please help test and debug the 0.9.7 version for release sometime in Spring 2009. - The version 0.9.6 beta tarball is kept here: - [113]x11vnc-0.9.6.tar.gz + The version 0.9.7 beta tarball is kept here: + [113]x11vnc-0.9.7.tar.gz There are also some Linux, Solaris, Mac OS X, and other OS test binaries [114]here. Please kick the tires and report bugs, performance @@ -879,7 +879,7 @@ make To aid testing of the [116]built-in SSL/TLS support for x11vnc, a number of VNC Viewer packages for Unix, Mac OS X, and Windows have been created that provide SSL Support for the TightVNC Viewer (this is - done by [117]wrapper scripts and a GUI that start [118]STUNNEL). It + done by [117]wrapper scripts and a GUI that starts [118]STUNNEL). It should be pretty convenient for automatic SSL and SSH connections. It is described in detail at and can be downloaded from the [119]Enhanced TightVNC Viewer (SSVNC) page. The SSVNC Unix viewer also supports @@ -887,7 +887,11 @@ make Encryption Plugin' settings panel.) - Here are some features that will appear in the 0.9.6 release: + Here are some features that will appear in the 0.9.7 release: + * Coming Soon! + + + Here are some features that appeared in the 0.9.6 release: * Support for [121]VeNCrypt SSL/TLS encrypted connections. It is enabled by default in the [122]-ssl mode. VNC Viewers like vinagre, gvncviewer/gtk-vnc, the vencrypt package, and others @@ -917,8 +921,8 @@ make access deployment using a central Certificate Authority (CA) via [131]-sslGenCA and [132]-sslGenCert. This way if a user has his laptop lost or stolen, you only have to revoke his key instead of - creating a new Certificate Authority and redeploying keys to all - of the users. + creating a new Certificate Authority and redeploying new keys to + all users. * The default SSL/TLS mode, "[133]-ssl" (no pem file parameter supplied), is now the same as "-ssl SAVE" and will save the generated self-signed cert in "~/.vnc/certs/server.pem". @@ -7670,16 +7674,24 @@ rm -f $tmp Installation so the Installation can be done remotely? This can be done, but it doesn't always work because it depends on how - the OS does its install. We have to "sneak in" somehow. Usually the OS - install will have to be a network-install in order to have networking - up during the install. Otherwise, you may have a chance to configure - the networking manually (ifconfig(8) and route(8)). + the OS does its install. We have to "sneak in" somehow. Note that some + OS's have a remote install (ssh etc.) built in and so you might want + to use that instead. + + Usually the OS install will have to be a network-install in order to + have networking up during the install. Otherwise, you may have a + (slim) chance to configure the networking manually (ifconfig(8) and + route(8)). To avoid library dependencies problems in the typical minimal (e.g. busybox) installation OS it is a good idea to build a statically linked x11vnc binary. A way that often works is to do a normal build and then paste the final x11vnc link line into a shell script. Then - change the "gcc" to "gcc -static" and run the shell script. + change the "gcc" to "gcc -static" and run the shell script. You may + need to disable features (e.g. "--without-xfixes") if there is not a + static library for the feature available. You may also need to add + extra link options (e.g. "-lXrender") to complete library dependencies + manually. Let's call the binary x11vnc.static. Place it on a webserver somewhere. It may be possible to retrieve it via scp(1) too. @@ -7694,7 +7706,7 @@ rm -f $tmp If it is a Linux install that uses an X server (e.g. SuSE and probably Fedora), then you can often get a shell by pressing Ctrl-Alt-F2 or - similar. Then get the x11vnc binary something like this: + similar. Then get the x11vnc binary via something like this: cd /tmp wget http://192.168.0.22/x11vnc.static chmod 755 ./x11vnc.static @@ -7707,21 +7719,32 @@ rm -f $tmp to connect via a vnc viewer and continue the install. Watch out for the display being :1, etc. + If there is a firewall blocking incoming connections during the + install, use the [932]"-connect hostname" option option for a reverse + connection to the hostname running the VNC viewer in listen mode. + Debian based installs are either console-text or console-framebuffer based. These are install (or expert) and installgui (or expertgui) boot lines, respectively. For the console-text based installs you - probably need to add a boot cmd line option like vga=0x314 to get the - console-text to use the linux framebuffer device properly. + probably need to add a boot cmd line option like vga=0x314 (which is + 800x600x16) to get the console-text to use the linux framebuffer + device properly. For a Debian console-text based install after the network is - configured press Ctrl-Alt-F2 to get a shell. Retrieve via wget as - above. Run it something like this: + configured press Ctrl-Alt-F2 to get a shell. Retrieve the binary via + wget as above and chmod 755 it. Then run it something like this: sleep 10; ./x11vnc.static -forever -nopw -rawfb console then before the sleep is over press Alt-F1 to get back to the install virtual console. You should be able to connect via a VNC viewer and continue with the install. + For a recent (2009) Debian install we booted with "expert vga=0x301" + and "expert vga=0x311" to get console text based installs at 640x480x8 + and 640x480x16, respectively (replace "expert" with "install" if you + like.) Otherwise it was giving a 16 color 640x480x4 (4 bit per pixel) + display which x11vnc could not handle. + For Debian console-framebuffer GUI based installs (installgui or expertgui) we have not be able to enter keystrokes or mouse motions. This may be resolved if the install had the Linux kernel module @@ -7730,8 +7753,8 @@ rm -f $tmp that, you can only do the GUI view-only, which can be handy to watch a long network install from your desk instead of in front of the machine being installed. For these, after the network is configured press - Ctrl-Alt-F2 to get a shell. Retrieve via wget as above. Run it - something like this: + Ctrl-Alt-F2 to get a shell. Retrieve the binary via wget as above and + chmod 755 it. Then run it something like this: sleep 10; ./x11vnc.static -forever -nopw -rawfb console then before the sleep is over press Alt-F5 to get back to the GUI @@ -7746,11 +7769,11 @@ rm -f $tmp As of Jan/2004 x11vnc supports the "CutText" part of the rfb protocol. Furthermore, x11vnc is able to hold the PRIMARY and CLIPBOARD selection (Xvnc does not seem to do this). If you don't want the - Clipboard/Selection exchanged use the [932]-nosel option. If you don't + Clipboard/Selection exchanged use the [933]-nosel option. If you don't want the PRIMARY selection to be polled for changes use the - [933]-noprimary option. (with a similar thing for CLIPBOARD). You can - also fine-tune it a bit with the [934]-seldir dir option and also - [935]-input. + [934]-noprimary option. (with a similar thing for CLIPBOARD). You can + also fine-tune it a bit with the [935]-seldir dir option and also + [936]-input. You may need to watch out for desktop utilities such as KDE's "Klipper" that do odd things with the selection, clipboard, and @@ -7762,7 +7785,7 @@ rm -f $tmp Yes, it is possible with a number of tools that record VNC and transform it to swf format or others. One such popular tool is - [936]pyvnc2swf. There are a number of [937]tutorials on how to do + [937]pyvnc2swf. There are a number of [938]tutorials on how to do this. Another option is to use the vnc2mpg that comes in the LibVNCServer package. An important thing to remember when doing this is that tuning @@ -7777,11 +7800,11 @@ rm -f $tmp (and Windows viewers only support filetransfer it appears... but they do work to some degree under Wine on Linux). - The [938]SSVNC Unix VNC viewer supports UltraVNC file transfer by use + The [939]SSVNC Unix VNC viewer supports UltraVNC file transfer by use of a Java helper program. TightVNC file transfer is off by default, if you want to enable it use - the [939]-tightfilexfer option. + the [940]-tightfilexfer option. UltraVNC file transfer is off by default, to enable it use something like "-rfbversion 3.6 -permitfiletransfer" @@ -7804,7 +7827,7 @@ rm -f $tmp IMPORTANT: please understand if -ultrafilexfer or -tightfilexfer is specified and you run x11vnc as root for, say, inetd or display manager (gdm, kdm, ...) access and you do not have it switch users via - the [940]-users option, then VNC Viewers that connect are able to do + the [941]-users option, then VNC Viewers that connect are able to do filetransfer reads and writes as *root*. The UltraVNC and TightVNC settings can be toggled on and off inside @@ -7823,7 +7846,7 @@ rm -f $tmp these extensions you will need to supply this option to x11vnc: -rfbversion 3.6 - Or use [941]-ultrafilexfer which is an alias for the above option and + Or use [942]-ultrafilexfer which is an alias for the above option and "-permitfiletransfer". UltraVNC evidently treats any other RFB version number as non-UltraVNC. @@ -7835,14 +7858,14 @@ rm -f $tmp * 1/n Server Scaling * rfbEncodingUltra compression encoding - The [942]SSVNC Unix VNC viewer supports these UltraVNC extensions. + The [943]SSVNC Unix VNC viewer supports these UltraVNC extensions. - To disable SingleWindow and ServerInput use [943]-noultraext (the + To disable SingleWindow and ServerInput use [944]-noultraext (the others are managed by LibVNCServer). See this option too: - [944]-noserverdpms. + [945]-noserverdpms. - Also, the [945]UltraVNC repeater proxy is supported for use with - reverse connections: "[946]-connect repeater://host:port+ID:NNNN". Use + Also, the [946]UltraVNC repeater proxy is supported for use with + reverse connections: "[947]-connect repeater://host:port+ID:NNNN". Use it for both plaintext and SSL connections. This mode can send any string before switching to the VNC protocol, and so could be used with other proxy/gateway tools. @@ -7853,12 +7876,12 @@ rm -f $tmp reverse vnc connection from their Unix desktop to a helpdesk operator's VNC Viewer. - Yes, UltraVNC's [947]Single Click (SC) mode can be done fairly well on + Yes, UltraVNC's [948]Single Click (SC) mode can be done fairly well on Unix. We use the term "helpdesk" below, but it could be any sort of remote assistance you want to set up, e.g. something for Unix-using friends - or family to use. This includes [948]Mac OS X. + or family to use. This includes [949]Mac OS X. Assume you create a helpdesk directory "hd" on your website: http://www.mysite.com/hd (any website that you can upload files to @@ -7914,7 +7937,7 @@ chmod 755 ./x11vnc # platform, use $webhost/`uname`/x11vnc So I guess this is about 3-4 clicks (start a terminal and paste) and pressing "Enter" instead of "single click"... - See [949]this page for some variations on this method, e.g. how to add + See [950]this page for some variations on this method, e.g. how to add a password, SSL Certificates, etc. @@ -7926,11 +7949,11 @@ chmod 755 ./x11vnc # platform, use $webhost/`uname`/x11vnc A bit of obscurity security could be put in with a -passwd, -rfbauth options, etc. (note that x11vnc will require a password even for - reverse connections). More info [950]here. + reverse connections). More info [951]here. Firewalls: If the helpdesk (you) with the vncviewer is behind a - NAT/Firewall/Router the [951]router will have to be configured to + NAT/Firewall/Router the [952]router will have to be configured to redirect a port (i.e. 5500 or maybe different one if you like) to the vncviewer machine. If the vncviewer machine also has its own host-level firewall, you will have to open up the port there as well. @@ -7940,7 +7963,7 @@ chmod 755 ./x11vnc # platform, use $webhost/`uname`/x11vnc configuring a router to do a port redirection (i.e. on your side, the HelpDesk). To avoid modifying either firewall/router, one would need some public (IP address reachable on the internet) redirection/proxy - service. Perhaps such a thing exists. [952]http://sc.uvnc.com provides + service. Perhaps such a thing exists. [953]http://sc.uvnc.com provides this service for their UltraVNC Single Click users. @@ -7976,7 +7999,7 @@ chmod 755 ./x11vnc # platform, use $webhost/`uname`/x11vnc As of Apr/2007 x11vnc supports reverse connections in SSL and so we can do this. On the Helpdesk side (Viewer) you will need STUNNEL or - better use the [953]Enhanced TightVNC Viewer (SSVNC) package we + better use the [954]Enhanced TightVNC Viewer (SSVNC) package we provide that automates all of the SSL for you. To do this create a file named "vncs" in the website "hd" directory @@ -8006,11 +8029,11 @@ chmod 755 ./x11vnc # platform, use $webhost/`uname`/x11vnc with the hostnames or IP addresses customized to your case. - The only change from the "vnc" above is the addition of the [954]-ssl + The only change from the "vnc" above is the addition of the [955]-ssl option to x11vnc. This will create a temporary SSL cert: openssl(1) will need to be installed on the user's end. A fixed SSL cert file could be used to avoid this (and provide some authentication; more - info [955]here.) + info [956]here.) The naive user will be doing this: wget -qO - http://www.mysite.com/hd/vncs | sh - @@ -8019,7 +8042,7 @@ chmod 755 ./x11vnc # platform, use $webhost/`uname`/x11vnc But before that, the helpdesk operator needs to have "vncviewer -listen" running as before, however he needs an SSL tunnel at his end. - The easiest way to do this is use [956]Enhanced TightVNC Viewer + The easiest way to do this is use [957]Enhanced TightVNC Viewer (SSVNC). Start it, and select Options -> 'Reverse VNC Connection (-listen)'. Then UN-select 'Verify All Certs' (this can be enabled later if you want; you'll need the x11vnc SSL certificate), and click @@ -8049,7 +8072,7 @@ connect = localhost:5501 answer the prompts with whatever you want; you can take the default for all of them if you like. The openssl(1) package must be installed. - See [957]this link and [958]this one too for more info on SSL certs. + See [958]this link and [959]this one too for more info on SSL certs. This creates $HOME/.vnc/certs/server-self:mystunnel.pem, then you would change the "stunnel.cfg" to look something like: foreground = yes @@ -8070,7 +8093,7 @@ connect = localhost:5501 then all bets are off!. More SSL variations and info about certificates can be found - [959]here. + [960]here. OpenSSL libssl.so.0.9.7 problems: @@ -8080,7 +8103,7 @@ connect = localhost:5501 distros are currently a bit of a mess regarding which version of libssl is installed. - You will find the [960]details here. + You will find the [961]details here. Q-120: Can I (temporarily) mount my local (viewer-side) Windows/Samba @@ -8089,7 +8112,7 @@ connect = localhost:5501 You will have to use an external network redirection for this. Filesystem mounting is not part of the VNC protocol. - We show a simple [961]Samba example here. + We show a simple [962]Samba example here. First you will need a tunnel to redirect the SMB requests from the remote machine to the one you sitting at. We use an ssh tunnel: @@ -8129,7 +8152,7 @@ d,ip=127.0.0.1,port=1139 far-away> smbumount /home/fred/smb-haystack-pub At some point we hope to fold some automation for SMB ssh redir setup - into the [962]Enhanced TightVNC Viewer (SSVNC) package we provide (as + into the [963]Enhanced TightVNC Viewer (SSVNC) package we provide (as of Sep 2006 it is there for testing). @@ -8139,7 +8162,7 @@ d,ip=127.0.0.1,port=1139 You will have to use an external network redirection for this. Printing is not part of the VNC protocol. - We show a simple Unix to Unix [963]CUPS example here. Non-CUPS port + We show a simple Unix to Unix [964]CUPS example here. Non-CUPS port redirections (e.g. LPD) should also be possible, but may be a bit more tricky. If you are viewing on Windows SMB and don't have a local cups server it may be trickier still (see below). @@ -8173,34 +8196,44 @@ d,ip=127.0.0.1,port=1139 for Host and 6631 for Port). The main setting you want to convey is the host is localhost and the port is non-standard (e.g. 6631). Some configuration utilities will take an Internet Printing Protocol (IPP) - URI, e.g. http://localhost:6631/ipp/, - http://localhost:6631/ipp/printer-name, - ipp://localhost:6631/ipp/printer-name, etc. - - If you do not have root privileges, but are running a recent (version - 1.2 or greater) of the Cups client software, then an easy way to - temporarily switch Cups servers is to create: $HOME/.cupsrc on the - remote side with a line like: + URI, e.g. http://localhost:6631/printers/, + ipp://localhost:6631/printers/printer-name, + ipp://localhost:6631/ipp/printer-name, etc. Check your CUPS + documentation and admin interfaces to find what the syntax is and what + the "printer name" is. + + If you do not have root or print admin privileges, but are running a + recent (version 1.2 or greater) of the Cups client software, then an + easy way to temporarily switch Cups servers is to create the directory + and file: $HOME/.cups/client.conf on the remote side with a line like: ServerName localhost:6631 When not using x11vnc for remote access you can comment the above line - out with a '#' (or rename the cupsrc file), to have normal cups + out with a '#' (or rename the client.conf file), to have normal cups operation. - Sadly, Cups client software that is older (1.1) does not support - appending the port number, and for newer ones there is a bug - preventing it from always working (fixed in 1.2.3). Kludges like these - at the command line will work: + Unfortunately, running applications may need to be restarted to notice + the new printers (libcups does not track changes in client.conf). + Depending on circumstances, a running application may actually notice + the new printers without restarting (e.g. no print dialog has taken + place yet, or there are no CUPS printers configured on the remote + side.) + + Cups client software that is older (1.1) does not support appending + the port number, and for newer ones there is a bug preventing it from + always working (fixed in 1.2.3). Kludges like these at the command + line will work: far-away> env CUPS_SERVER=localhost IPP_PORT=6631 lpstat -p -d far-away> env CUPS_SERVER=localhost IPP_PORT=6631 lpr -P myprinter file.ps far-away> env CUPS_SERVER=localhost IPP_PORT=6631 firefox but are somewhat awkward since you have to retroactively set the env. var IPP_PORT. Its value cannot be broadcast to already running apps - (like the $HOME/.cupsrc trick does). A common workaround for an - already running app is to somehow get it to "Print To File", e.g. - file.ps and then use something like the lpr example above. Also, the - option "-h host:port" works with CUPS lp(1) and lpr(1). + (like the $HOME/.cups/client.conf trick sometimes does). A common + workaround for an already running app is to somehow get it to "Print + To File", e.g. file.ps and then use something like the lpr example + above. Also, the option "-h host:port" works with CUPS lp(1) and + lpr(1). You can also print to Windows shares printers in principle. You may do this with the smbspool(8) command, or configure the remote CUPS via @@ -8211,7 +8244,7 @@ d,ip=127.0.0.1,port=1139 "localhost". At some point we hope to fold some automation for CUPS ssh redir setup - into the [964]Enhanced TightVNC Viewer (SSVNC) package we provide (as + into the [965]Enhanced TightVNC Viewer (SSVNC) package we provide (as of Sep 2006 it is there for testing). @@ -8312,7 +8345,7 @@ or: the applications will fail to run because LD_PRELOAD will point to libraries of the wrong wordsize. * At some point we hope to fold some automation for esd or artsd ssh - redir setup into the [965]Enhanced TightVNC Viewer (SSVNC) package + redir setup into the [966]Enhanced TightVNC Viewer (SSVNC) package we provide (as of Sep/2006 it is there for testing). @@ -8324,14 +8357,14 @@ or: in Solaris, see Xserver(1) for how to turn it on via +kb), and so you won't hear them if the extension is not present. - If you don't want to hear the beeps use the [966]-nobell option. If + If you don't want to hear the beeps use the [967]-nobell option. If you want to hear the audio from the remote applications, consider - trying a [967]redirector such as esd. + trying a [968]redirector such as esd. Q-124: Does x11vnc work with IPv6? - Currently the only way to do this is via [968]inetd. You configure + Currently the only way to do this is via [969]inetd. You configure x11vnc to be run from inetd or xinetd and instruct it to listen on an IPv6 address. For xinetd the setting "flags = IPv6" will be needed. @@ -8340,7 +8373,7 @@ or: connection). Some sort of ipv4-to-ipv6 redirector tool (perhaps even a perl script) could be useful to avoid this. - Also note that not all VNC Viewers are [969]IPv6 enabled, so a + Also note that not all VNC Viewers are [970]IPv6 enabled, so a redirector could even be needed on the client side. @@ -8355,7 +8388,7 @@ or: anything) and thank you for your support! Click on the PayPal button below for more info. - [PayPal] + [x-click-but04.gif]-Submit References @@ -8448,9 +8481,9 @@ References 87. http://www.karlrunge.com/x11vnc/index.html#faq-ssl-tunnel-int 88. http://www.karlrunge.com/x11vnc/ssvnc.html 89. http://sourceforge.net/projects/libvncserver/ - 90. http://sourceforge.net/project/showfiles.php?group_id=32584&package_id=119006&release_id=635593 - 91. http://sourceforge.net/project/shownotes.php?release_id=635593&group_id=32584 - 92. http://www.karlrunge.com/x11vnc/x11vnc-0.9.6.tar.gz + 90. http://sourceforge.net/project/showfiles.php?group_id=32584&package_id=119006&release_id=646288 + 91. http://sourceforge.net/project/shownotes.php?release_id=646288&group_id=32584 + 92. http://www.karlrunge.com/x11vnc/x11vnc-0.9.7.tar.gz 93. http://www.karlrunge.com/x11vnc/index.html#faq-binaries 94. http://www.tightvnc.com/download.html 95. http://www.realvnc.com/download-free.html @@ -8471,7 +8504,7 @@ References 110. http://www.karlrunge.com/x11vnc/index.html#faq-solaris251build 111. http://www.karlrunge.com/x11vnc/index.html#faq-macosx 112. http://www.karlrunge.com/x11vnc/index.html#faq-ssl-tunnel-int - 113. http://www.karlrunge.com/x11vnc/x11vnc-0.9.6.tar.gz + 113. http://www.karlrunge.com/x11vnc/x11vnc-0.9.7.tar.gz 114. http://www.karlrunge.com/x11vnc/bins 115. mailto:xvml@karlrunge.com 116. http://www.karlrunge.com/x11vnc/index.html#faq-ssl-tunnel-int @@ -9290,44 +9323,45 @@ References 929. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-connect 930. http://www.karlrunge.com/x11vnc/index.html#faq-display-manager 931. http://www.karlrunge.com/x11vnc/index.html#faq-display-manager - 932. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-nosel - 933. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-noprimary - 934. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-seldir - 935. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-input - 936. http://www.unixuser.org/~euske/vnc2swf/ - 937. http://wolphination.com/linux/2006/06/30/how-to-record-videos-of-your-desktop/ - 938. http://www.karlrunge.com/x11vnc/ssvnc.html - 939. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-tightfilexfer - 940. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-users - 941. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-ultrafilexfer - 942. http://www.karlrunge.com/x11vnc/ssvnc.html - 943. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-noultraext - 944. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-noserverdpms - 945. http://www.uvnc.com/addons/repeater.html - 946. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-connect - 947. http://www.uvnc.com/addons/singleclick.html - 948. http://www.karlrunge.com/x11vnc/index.html#faq-macosx - 949. http://www.karlrunge.com/x11vnc/single-click.html + 932. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-connect + 933. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-nosel + 934. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-noprimary + 935. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-seldir + 936. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-input + 937. http://www.unixuser.org/~euske/vnc2swf/ + 938. http://wolphination.com/linux/2006/06/30/how-to-record-videos-of-your-desktop/ + 939. http://www.karlrunge.com/x11vnc/ssvnc.html + 940. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-tightfilexfer + 941. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-users + 942. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-ultrafilexfer + 943. http://www.karlrunge.com/x11vnc/ssvnc.html + 944. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-noultraext + 945. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-noserverdpms + 946. http://www.uvnc.com/addons/repeater.html + 947. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-connect + 948. http://www.uvnc.com/addons/singleclick.html + 949. http://www.karlrunge.com/x11vnc/index.html#faq-macosx 950. http://www.karlrunge.com/x11vnc/single-click.html - 951. http://www.karlrunge.com/x11vnc/index.html#firewalls - 952. http://sc.uvnc.com/ - 953. http://www.karlrunge.com/x11vnc/ssvnc.html - 954. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-ssl - 955. http://www.karlrunge.com/x11vnc/single-click.html - 956. http://www.karlrunge.com/x11vnc/ssvnc.html - 957. http://www.karlrunge.com/x11vnc/single-click.html - 958. http://www.karlrunge.com/x11vnc/ssl.html - 959. http://www.karlrunge.com/x11vnc/single-click.html - 960. http://www.karlrunge.com/x11vnc/single-click.html#libssl-problems - 961. http://www.samba.org/ - 962. http://www.karlrunge.com/x11vnc/ssvnc.html - 963. http://www.cups.org/ - 964. http://www.karlrunge.com/x11vnc/ssvnc.html + 951. http://www.karlrunge.com/x11vnc/single-click.html + 952. http://www.karlrunge.com/x11vnc/index.html#firewalls + 953. http://sc.uvnc.com/ + 954. http://www.karlrunge.com/x11vnc/ssvnc.html + 955. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-ssl + 956. http://www.karlrunge.com/x11vnc/single-click.html + 957. http://www.karlrunge.com/x11vnc/ssvnc.html + 958. http://www.karlrunge.com/x11vnc/single-click.html + 959. http://www.karlrunge.com/x11vnc/ssl.html + 960. http://www.karlrunge.com/x11vnc/single-click.html + 961. http://www.karlrunge.com/x11vnc/single-click.html#libssl-problems + 962. http://www.samba.org/ + 963. http://www.karlrunge.com/x11vnc/ssvnc.html + 964. http://www.cups.org/ 965. http://www.karlrunge.com/x11vnc/ssvnc.html - 966. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-nobell - 967. http://www.karlrunge.com/x11vnc/index.html#faq-sound - 968. http://www.karlrunge.com/x11vnc/index.html#faq-inetd - 969. http://jungla.dit.upm.es/~acosta/paginas/vncIPv6.html + 966. http://www.karlrunge.com/x11vnc/ssvnc.html + 967. http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-nobell + 968. http://www.karlrunge.com/x11vnc/index.html#faq-sound + 969. http://www.karlrunge.com/x11vnc/index.html#faq-inetd + 970. http://jungla.dit.upm.es/~acosta/paginas/vncIPv6.html ======================================================================= http://www.karlrunge.com/x11vnc/chainingssh.html: @@ -11267,7 +11301,7 @@ Enhanced TightVNC Viewer (SSVNC: SSL/SSH VNC viewer) connecting. * Support for native MacOS X usage with bundled Chicken of the VNC viewer (the Unix X11 viewer is also provided for MacOS X, and is - better IMHO). + better IMHO. It is now the default on MacOS X.) * [15]Dynamic VNC Server Port determination and redirection (using ssh's builtin SOCKS proxy, ssh -D) for servers like x11vnc that print out PORT= at startup. @@ -11741,12 +11775,27 @@ Enhanced TightVNC viewer (SSVNC) options: a floating point ratio, e.g. "0.9", or a fraction, e.g. "3/4", or WxH, e.g. 1280x1024. Use "fit" to fit in the current screen size. Use "auto" to - fit in the window size. - - Note that scaling is done in software and can be slow - and requires more memory. "str" can also be set by + fit in the window size. "str" can also be set by the env. var. SSVNC_SCALE. + If you observe mouse trail painting errors, enable + X11 Cursor mode (either via Popup or -x11cursor.) + + Note that scaling is done in software and so can be + slow and requires more memory. Some speedup Tips: + + ZRLE is faster than Tight in this mode. When + scaling is first detected, the encoding will + be automatically switched to ZRLE. Use the + Popup menu if you want to go back to Tight. + Set SSVNC_PRESERVE_ENCODING=1 to disable this. + + Use a solid background on the remote side. + (e.g. manually or via x11vnc -solid ...) + + If the remote server is x11vnc, try client + side caching: x11vnc -ncache 10 ... + -ycrop n Only show the top n rows of the framebuffer. For use with x11vnc -ncache client caching option to help "hide" the pixel cache region. @@ -12217,7 +12266,7 @@ x11vnc: a VNC server for real X displays Here are all of x11vnc command line options: % x11vnc -opts (see below for -help long descriptions) -x11vnc: allow VNC connections to real X11 displays. 0.9.6 lastmod: 2008-12-08 +x11vnc: allow VNC connections to real X11 displays. 0.9.7 lastmod: 2009-01-03 x11vnc options: -display disp -auth file -N @@ -12257,57 +12306,57 @@ x11vnc options: -blackout string -xinerama -noxinerama -xtrap -xrandr [mode] -rotate string -padgeom WxH -o logfile -flag file - -rc filename -norc -env VAR=VALUE - -prog /path/to/x11vnc -h, -help -?, -opts - -V, -version -license -dbg - -q, -quiet -v, -verbose -bg - -modtweak -nomodtweak -xkb - -noxkb -capslock -skip_lockkeys - -skip_keycodes string -sloppy_keys -skip_dups - -noskip_dups -add_keysyms -noadd_keysyms - -clear_mods -clear_keys -clear_all - -remap string -norepeat -repeat - -nofb -nobell -nosel - -noprimary -nosetprimary -noclipboard - -nosetclipboard -seldir string -cursor [mode] - -nocursor -cursor_drag -arrow n - -noxfixes -alphacut n -alphafrac fraction - -alpharemove -noalphablend -nocursorshape - -cursorpos -nocursorpos -xwarppointer - -noxwarppointer -buttonmap string -nodragging - -ncache n -ncache_cr -ncache_no_moveraise - -ncache_no_dtchange -ncache_no_rootpixmap -ncache_keep_anims - -ncache_old_wm -ncache_pad n -debug_ncache - -wireframe [str] -nowireframe -nowireframelocal - -wirecopyrect mode -nowirecopyrect -debug_wireframe - -scrollcopyrect mode -noscrollcopyrect -scr_area n - -scr_skip list -scr_inc list -scr_keys list - -scr_term list -scr_keyrepeat lo-hi -scr_parms string - -fixscreen string -debug_scroll -noxrecord - -grab_buster -nograb_buster -debug_grabs - -debug_sel -pointer_mode n -input_skip n - -allinput -speeds rd,bw,lat -wmdt string - -debug_pointer -debug_keyboard -defer time - -wait time -wait_ui factor -setdefer n - -nowait_bog -slow_fb time -xrefresh time - -nap -nonap -sb time - -readtimeout n -ping n -nofbpm - -fbpm -nodpms -dpms - -forcedpms -clientdpms -noserverdpms - -noultraext -chatwindow -noxdamage - -xd_area A -xd_mem f -sigpipe string - -threads -nothreads -fs f - -gaps n -grow n -fuzz n - -debug_tiles -snapfb -rawfb string - -freqtab file -pipeinput cmd -macnodim - -macnosleep -macnosaver -macnowait - -macwheel n -macnoswap -macnoresize - -maciconanim n -macmenu -macuskbd - -gui [gui-opts] -remote command -query variable - -QD variable -sync -noremote - -yesremote -unsafe -safer - -privremote -nocmds -allowedcmds list - -deny_all + -rmflag file -rc filename -norc + -env VAR=VALUE -prog /path/to/x11vnc -h, -help + -?, -opts -V, -version -license + -dbg -q, -quiet -v, -verbose + -bg -modtweak -nomodtweak + -xkb -noxkb -capslock + -skip_lockkeys -skip_keycodes string -sloppy_keys + -skip_dups -noskip_dups -add_keysyms + -noadd_keysyms -clear_mods -clear_keys + -clear_all -remap string -norepeat + -repeat -nofb -nobell + -nosel -noprimary -nosetprimary + -noclipboard -nosetclipboard -seldir string + -cursor [mode] -nocursor -cursor_drag + -arrow n -noxfixes -alphacut n + -alphafrac fraction -alpharemove -noalphablend + -nocursorshape -cursorpos -nocursorpos + -xwarppointer -noxwarppointer -buttonmap string + -nodragging -ncache n -ncache_cr + -ncache_no_moveraise -ncache_no_dtchange -ncache_no_rootpixmap + -ncache_keep_anims -ncache_old_wm -ncache_pad n + -debug_ncache -wireframe [str] -nowireframe + -nowireframelocal -wirecopyrect mode -nowirecopyrect + -debug_wireframe -scrollcopyrect mode -noscrollcopyrect + -scr_area n -scr_skip list -scr_inc list + -scr_keys list -scr_term list -scr_keyrepeat lo-hi + -scr_parms string -fixscreen string -debug_scroll + -noxrecord -grab_buster -nograb_buster + -debug_grabs -debug_sel -pointer_mode n + -input_skip n -allinput -speeds rd,bw,lat + -wmdt string -debug_pointer -debug_keyboard + -defer time -wait time -wait_ui factor + -setdefer n -nowait_bog -slow_fb time + -xrefresh time -nap -nonap + -sb time -readtimeout n -ping n + -nofbpm -fbpm -nodpms + -dpms -forcedpms -clientdpms + -noserverdpms -noultraext -chatwindow + -noxdamage -xd_area A -xd_mem f + -sigpipe string -threads -nothreads + -fs f -gaps n -grow n + -fuzz n -debug_tiles -snapfb + -rawfb string -freqtab file -pipeinput cmd + -macnodim -macnosleep -macnosaver + -macnowait -macwheel n -macnoswap + -macnoresize -maciconanim n -macmenu + -macuskbd -gui [gui-opts] -remote command + -query variable -QD variable -sync + -noremote -yesremote -unsafe + -safer -privremote -nocmds + -allowedcmds list -deny_all libvncserver options: -rfbport port TCP port for RFB protocol @@ -12341,7 +12390,7 @@ libvncserver-tight-extension options: % x11vnc -help -x11vnc: allow VNC connections to real X11 displays. 0.9.6 lastmod: 2008-12-08 +x11vnc: allow VNC connections to real X11 displays. 0.9.7 lastmod: 2009-01-03 (type "x11vnc -opts" to just list the options.) @@ -14786,6 +14835,13 @@ t "file" in addition to stdout. This option could be useful by wrapper script to detect when x11vnc is ready. +-rmflag file Remove "file" at exit to signal when x11vnc is done. + The file is created at startup if it does not already + exist or if "file" is prefixed with "create:". + If the file is created, the x11vnc PID is placed in + the file. Otherwise the files contents is not changed. + Use prefix "nocreate:" to prevent creation. + -rc filename Use "filename" instead of $HOME/.x11vncrc for rc file. -norc Do not process any .x11vncrc file for options. @@ -15914,16 +15970,18 @@ t -rawfb string Instead of polling X, poll the memory object specified in "string". - For file polling to memory map mmap(2) a file use: + For file polling, to memory map mmap(2) a file use: "map:/path/to/a/file@WxHxB", with framebuffer Width, Height, and Bits per pixel. "mmap:..." is the same. - If there is trouble with mmap, use "file:/..." - for slower lseek(2) based reading. Use "snap:..." - to imply -snapfb mode and the "file:" access (this - is for unseekable devices that only provide the fb all - at once, e.g. a video camera provides the whole frame). + If there is trouble with mmap, use "file:/..." + for slower lseek(2) based reading. + + Use "snap:..." to imply -snapfb mode and the "file:" + access (this is for unseekable devices that only provide + the fb all at once, e.g. a video camera provides the + whole frame). For shared memory segments string is of the form: "shm:N@WxHxB" which specifies a shmid N and with @@ -15943,25 +16001,29 @@ t discussion below where the device may be queried for (and possibly set) the framebuffer parameters. - If the string begins with "console", "/dev/fb", or - "fb", see the LINUX CONSOLE discussion below where - the framebuffer device is opened and keystrokes (and - possibly mouse events) are inserted into the console. + If the string begins with "console", "/dev/fb", + "fb", or "vt", see the LINUX CONSOLE discussion + below where the framebuffer device is opened and + keystrokes (and possibly mouse events) are inserted + into the console. If the string begins with "vnc", see the VNC HOST discussion below where the framebuffer is taken as that of another remote VNC server. Optional suffixes are ":R/G/B" and "+O" to specify - red, green, and blue masks and an offset into the - memory object. If the masks are not provided x11vnc - guesses them based on the bpp. + red, green, and blue masks (in hex) and an offset into + the memory object. If the masks are not provided x11vnc + guesses them based on the bpp (if the colors look wrong, + you need to provide the masks.) Another optional suffix is the Bytes Per Line which in - some cases is not WxB/4. Specify it as WxHxB-BPL + some cases is not WxB/8. Specify it as WxHxB-BPL e.g. 800x600x16-2048. This could be a normal width 1024 at 16bpp fb, but only width 800 shows up. + So the full format is: mode:file@WxHxB:R/G/B+O-BPL + Examples: -rawfb shm:210337933@800x600x32:ff/ff00/ff0000 -rawfb map:/dev/fb0@1024x768x32 @@ -15972,6 +16034,7 @@ t -rawfb video0 -rawfb video -pipeinput VID -rawfb console + -rawfb vt2 -rawfb vnc:somehost:0 (see ipcs(1) and fbset(1) for the first two examples) @@ -15995,7 +16058,7 @@ t If the device is not "seekable" (e.g. webcam) try reading it all at once in full snaps via the "snap:" mode (note: this is a resource hog). If you are using - file: or map: and the device needs to be reopened for + file: or map: AND the device needs to be reopened for *every* snapfb snapshot, set the environment variable: SNAPFB_RAWFB_RESET=1 as well. @@ -16006,6 +16069,25 @@ t 24bpp packed RGB. This is the default under "video" mode if the bpp is 24. + Normally the bits per pixel, B, is 8, 16, or 32 (or + rarely 24), however there is also some support for + B < 8 (e.g. old graphics displays 4 bpp or 1 bpp). + In this case you certainly must supply the masks as + well: WxHxB:R/G/B. The pixels will be padded out to + 8 bpp using depth 8 truecolor. The scheme currently + does not work with snap fb (ask if interested.) B=1 + monochrome example: file:/dev/urandom@128x128x1:1/1/1 + Some other like this are 128x128x2:3/3/3 128x128x4:7/7/7 + + For B < 8 framebuffers you can also set the env. var + RAWFB_CGA=1 to try a CGA mapping for B=4 (e.g. linux + vga16fb driver.) Note with low bpp and/or resolution + VGA and VGA16 modes on the Linux console one's attempt + to export them via x11vnc can often be thwarted due to + special color palettes, pixel packings, and even video + painting buffering. OTOH, often experimenting with the + RGB masks can yield something recognizable. + VIDEO4LINUX: on Linux some attempt is made to handle video devices (webcams or TV tuners) automatically. The idea is the WxHxB will be extracted from the @@ -16092,37 +16174,76 @@ t is not queried for the current values. Otherwise the device will be queried. - LINUX CONSOLE: If the libvncserver LinuxVNC program - is on your system you may want to use that instead of - the following method because it will be faster and more - accurate for Linux text console. + LINUX CONSOLE: The following describes some ways to + view and possibly interact with the Linux text/graphics + console (i.e. not X11 XFree86/Xorg) + + Note: If the libvncserver LinuxVNC program is on your + system you may want to use that instead of the following + method because it will be faster and more accurate + for the Linux text console and includes mouse support. + There is, however, the basic LinuxVNC functionality in + x11vnc if you replace "console" with "vt" in the + examples below. If the rawfb string begins with "console" the - framebuffer device /dev/fb0 is opened (this requires - the appropriate kernel modules to be installed) and so - is /dev/tty0. The latter is used to inject keystrokes + framebuffer device /dev/fb0 is opened and /dev/tty0 is + opened too. The latter is used to inject keystrokes (not all are supported, but the basic ones are). - You will need to be root to inject keystrokes. - /dev/tty0 refers to the active VT, to indicate one - explicitly, use "console2", etc. using the VT number. - - If the Linux version seems to be 2.6 or later and the - "uinput" module appears to be present, then the uinput - method will be used instead of /dev/ttyN. uinput allows - insertion of BOTH keystrokes and mouse input and so it - preferred when accessing graphical (e.g. QT-embedded) - linux console apps. See -pipeinput UINPUT below for - more information on this mode; you will have to use - -pipeinput if you want to tweak any UINPUT parameters. - You may also want to also use the -nodragging and - -cursor none options. Use "console0", etc or - -pipeinput CONSOLE to force the /dev/ttyN method. - - Note you can change VT remotely using the chvt(1) - command. Sometimes switching out and back corrects - the framebuffer state. - - To skip input injecting entirely use "consolex". + You will need to be root to inject keystrokes, but + not necessarily to open /dev/fb0. /dev/tty0 refers to + the active VT, to indicate one explicitly, use, e.g., + "console2" for /dev/tty2, etc. by indicating the + specific VT number. + + For the Linux framebuffer device, /dev/fb0, (fb1, + etc) to be enabled the appropriate kernel drivers must + be loaded. E.g. vesafb or vga16fb and also by setting + the boot parameter vga=0x301 (or 0x314, 0x317, etc.) + (The vga=... method is the preferred way; set your + machines up that way.) Otherwise there will be a + 'No such device' error. You can also load a Linux + framebuffer driver specific to your make of video card + for more functionality. Once the machine is booted one + can often 'modprobe' the fb driver as root to obtain + a framebuffer device. + + If you cannot get /dev/fb0 working on Linux, try + using the LinuxVNC emulation mode by "-rawfb vtN" + where N = 1, ... 6 is the Linux Virtual Terminal (aka + virtual console) you wish to view, e.g. "-rawfb vt2". + Unlike /dev/fb mode, it need not be the active Virtual + Terminal. Note that this mode can only show text and + not graphics. x11vnc polls the text in /dev/vcsaN + + Set the env. var. RAWFB_VCSA_BW=1 to disable colors in + the "vtN" mode (i.e. black and white only.) If you + do not prefer the default 16bpp set RAWFB_VCSA_BPP to + 8 or 32. If you need to tweak the rawfb parameters by + using the 'console_guess' string printed at startup, + be sure to indicate the snap: method. + + uinput: If the Linux version appears to be 2.6 or + later and the "uinput" module appears to be present + (modprobe uinput), then the uinput method will be used + instead of /dev/ttyN. uinput allows insertion of BOTH + keystrokes and mouse input and so it preferred when + accessing graphical (e.g. QT-embedded) linux console + apps. See -pipeinput UINPUT below for more information + on this mode; you will have to use -pipeinput if you + want to tweak any UINPUT parameters. You may also want + to also use the -nodragging and -cursor none options. + Use "console0", etc or -pipeinput CONSOLE to force + the /dev/ttyN method. + + Note you can change the Linux VT remotely using the + chvt(1) command to make the one you want be the active + one (e.g. 'chvt 3'). Sometimes switching out and back + corrects the framebuffer's graphics state. For the + "-rawfb vtN" mode there is no need to switch the VT's. + + To skip input injecting entirely use "consolex" + or "vtx". The string "/dev/fb0" (1, etc.) can be used instead of "console". This can be used to specify a different @@ -16132,8 +16253,8 @@ t If you do not want x11vnc to guess the framebuffer's WxHxB and masks automatically (sometimes the kernel - gives inaccurate information), specify them with a - @WxHxB at the end of the string. + gives incorrect information), specify them with a @WxHxB + (and optional :R/G/B masks) at the end of the string. Examples: -rawfb console @@ -16142,6 +16263,7 @@ t -rawfb consolex (no keystrokes or mouse) -rawfb console:/dev/nonstd -rawfb console -pipeinput UINPUT:accel=4.0 + -rawfb vt3 (/dev/tty3 w/o /dev/fb0) VNC HOST: if the -rawfb string is of the form "vnc:host:N" then the VNC display "N" on the remote diff --git a/x11vnc/cleanup.c b/x11vnc/cleanup.c index 610aa62..08a4e1f 100644 --- a/x11vnc/cleanup.c +++ b/x11vnc/cleanup.c @@ -155,7 +155,13 @@ void clean_up_exit(int ret) { pipeinput_fh = NULL; } - if (! dpy) exit(ret); /* raw_rb hack */ + if (! dpy) { /* raw_rb hack */ + if (rm_flagfile) { + unlink(rm_flagfile); + rm_flagfile = NULL; + } + exit(ret); + } /* X keyboard cleanups */ delete_added_keycodes(0); @@ -195,6 +201,12 @@ void clean_up_exit(int ret) { X_UNLOCK; fflush(stderr); + + if (rm_flagfile) { + unlink(rm_flagfile); + rm_flagfile = NULL; + } + exit(ret); } @@ -452,6 +464,10 @@ static void interrupted (int sig) { } else if (exit_flag <= 2) { return; } + if (rm_flagfile) { + unlink(rm_flagfile); + rm_flagfile = NULL; + } exit(4); } exit_flag++; @@ -482,6 +498,10 @@ static void interrupted (int sig) { if (sig == -1) { /* not worth trying any more cleanup, X server probably gone */ + if (rm_flagfile) { + unlink(rm_flagfile); + rm_flagfile = NULL; + } exit(3); } @@ -512,6 +532,10 @@ static void interrupted (int sig) { } if (sig) { + if (rm_flagfile) { + unlink(rm_flagfile); + rm_flagfile = NULL; + } exit(2); } } diff --git a/x11vnc/connections.c b/x11vnc/connections.c index 52b3f2a..e759707 100644 --- a/x11vnc/connections.c +++ b/x11vnc/connections.c @@ -2263,8 +2263,6 @@ char *get_repeater_string(char *str, int *len) { * Do a reverse connect for a single "host" or "host:port" */ -extern int ssl_client_mode; - static int do_reverse_connect(char *str_in) { rfbClientPtr cl; char *host, *p, *str = str_in, *s = NULL; diff --git a/x11vnc/help.c b/x11vnc/help.c index fbedbff..fa955cd 100644 --- a/x11vnc/help.c +++ b/x11vnc/help.c @@ -2471,6 +2471,13 @@ void print_help(int mode) { " \"file\" in addition to stdout. This option could be\n" " useful by wrapper script to detect when x11vnc is ready.\n" "\n" +"-rmflag file Remove \"file\" at exit to signal when x11vnc is done.\n" +" The file is created at startup if it does not already\n" +" exist or if \"file\" is prefixed with \"create:\".\n" +" If the file is created, the x11vnc PID is placed in\n" +" the file. Otherwise the files contents is not changed.\n" +" Use prefix \"nocreate:\" to prevent creation.\n" +"\n" "-rc filename Use \"filename\" instead of $HOME/.x11vncrc for rc file.\n" "-norc Do not process any .x11vncrc file for options.\n" "\n" @@ -3599,16 +3606,18 @@ void print_help(int mode) { "-rawfb string Instead of polling X, poll the memory object specified\n" " in \"string\".\n" "\n" -" For file polling to memory map mmap(2) a file use:\n" +" For file polling, to memory map mmap(2) a file use:\n" " \"map:/path/to/a/file@WxHxB\", with framebuffer Width,\n" " Height, and Bits per pixel. \"mmap:...\" is the\n" " same.\n" "\n" -" If there is trouble with mmap, use \"file:/...\"\n" -" for slower lseek(2) based reading. Use \"snap:...\"\n" -" to imply -snapfb mode and the \"file:\" access (this\n" -" is for unseekable devices that only provide the fb all\n" -" at once, e.g. a video camera provides the whole frame).\n" +" If there is trouble with mmap, use \"file:/...\"\n" +" for slower lseek(2) based reading.\n" +"\n" +" Use \"snap:...\" to imply -snapfb mode and the \"file:\"\n" +" access (this is for unseekable devices that only provide\n" +" the fb all at once, e.g. a video camera provides the\n" +" whole frame).\n" "\n" " For shared memory segments string is of the form:\n" " \"shm:N@WxHxB\" which specifies a shmid N and with\n" @@ -3628,25 +3637,29 @@ void print_help(int mode) { " discussion below where the device may be queried for\n" " (and possibly set) the framebuffer parameters.\n" "\n" -" If the string begins with \"console\", \"/dev/fb\", or\n" -" \"fb\", see the LINUX CONSOLE discussion below where\n" -" the framebuffer device is opened and keystrokes (and\n" -" possibly mouse events) are inserted into the console.\n" +" If the string begins with \"console\", \"/dev/fb\",\n" +" \"fb\", or \"vt\", see the LINUX CONSOLE discussion\n" +" below where the framebuffer device is opened and\n" +" keystrokes (and possibly mouse events) are inserted\n" +" into the console.\n" "\n" " If the string begins with \"vnc\", see the VNC HOST\n" " discussion below where the framebuffer is taken as that\n" " of another remote VNC server.\n" "\n" " Optional suffixes are \":R/G/B\" and \"+O\" to specify\n" -" red, green, and blue masks and an offset into the\n" -" memory object. If the masks are not provided x11vnc\n" -" guesses them based on the bpp.\n" +" red, green, and blue masks (in hex) and an offset into\n" +" the memory object. If the masks are not provided x11vnc\n" +" guesses them based on the bpp (if the colors look wrong,\n" +" you need to provide the masks.)\n" "\n" " Another optional suffix is the Bytes Per Line which in\n" -" some cases is not WxB/4. Specify it as WxHxB-BPL\n" +" some cases is not WxB/8. Specify it as WxHxB-BPL\n" " e.g. 800x600x16-2048. This could be a normal width\n" " 1024 at 16bpp fb, but only width 800 shows up.\n" "\n" +" So the full format is: mode:file@WxHxB:R/G/B+O-BPL\n" +"\n" " Examples:\n" " -rawfb shm:210337933@800x600x32:ff/ff00/ff0000\n" " -rawfb map:/dev/fb0@1024x768x32\n" @@ -3657,6 +3670,7 @@ void print_help(int mode) { " -rawfb video0\n" " -rawfb video -pipeinput VID\n" " -rawfb console\n" +" -rawfb vt2\n" " -rawfb vnc:somehost:0\n" "\n" " (see ipcs(1) and fbset(1) for the first two examples)\n" @@ -3680,7 +3694,7 @@ void print_help(int mode) { " If the device is not \"seekable\" (e.g. webcam) try\n" " reading it all at once in full snaps via the \"snap:\"\n" " mode (note: this is a resource hog). If you are using\n" -" file: or map: and the device needs to be reopened for\n" +" file: or map: AND the device needs to be reopened for\n" " *every* snapfb snapshot, set the environment variable:\n" " SNAPFB_RAWFB_RESET=1 as well.\n" "\n" @@ -3691,6 +3705,25 @@ void print_help(int mode) { " 24bpp packed RGB. This is the default under \"video\"\n" " mode if the bpp is 24.\n" "\n" +" Normally the bits per pixel, B, is 8, 16, or 32 (or\n" +" rarely 24), however there is also some support for\n" +" B < 8 (e.g. old graphics displays 4 bpp or 1 bpp).\n" +" In this case you certainly must supply the masks as\n" +" well: WxHxB:R/G/B. The pixels will be padded out to\n" +" 8 bpp using depth 8 truecolor. The scheme currently\n" +" does not work with snap fb (ask if interested.) B=1\n" +" monochrome example: file:/dev/urandom@128x128x1:1/1/1\n" +" Some other like this are 128x128x2:3/3/3 128x128x4:7/7/7\n" +"\n" +" For B < 8 framebuffers you can also set the env. var\n" +" RAWFB_CGA=1 to try a CGA mapping for B=4 (e.g. linux\n" +" vga16fb driver.) Note with low bpp and/or resolution\n" +" VGA and VGA16 modes on the Linux console one's attempt\n" +" to export them via x11vnc can often be thwarted due to\n" +" special color palettes, pixel packings, and even video\n" +" painting buffering. OTOH, often experimenting with the\n" +" RGB masks can yield something recognizable.\n" +"\n" " VIDEO4LINUX: on Linux some attempt is made to handle\n" " video devices (webcams or TV tuners) automatically.\n" " The idea is the WxHxB will be extracted from the\n" @@ -3777,37 +3810,76 @@ void print_help(int mode) { " is not queried for the current values. Otherwise the\n" " device will be queried.\n" "\n" -" LINUX CONSOLE: If the libvncserver LinuxVNC program\n" -" is on your system you may want to use that instead of\n" -" the following method because it will be faster and more\n" -" accurate for Linux text console.\n" +" LINUX CONSOLE: The following describes some ways to\n" +" view and possibly interact with the Linux text/graphics\n" +" console (i.e. not X11 XFree86/Xorg)\n" +"\n" +" Note: If the libvncserver LinuxVNC program is on your\n" +" system you may want to use that instead of the following\n" +" method because it will be faster and more accurate\n" +" for the Linux text console and includes mouse support.\n" +" There is, however, the basic LinuxVNC functionality in\n" +" x11vnc if you replace \"console\" with \"vt\" in the\n" +" examples below.\n" "\n" " If the rawfb string begins with \"console\" the\n" -" framebuffer device /dev/fb0 is opened (this requires\n" -" the appropriate kernel modules to be installed) and so\n" -" is /dev/tty0. The latter is used to inject keystrokes\n" +" framebuffer device /dev/fb0 is opened and /dev/tty0 is\n" +" opened too. The latter is used to inject keystrokes\n" " (not all are supported, but the basic ones are).\n" -" You will need to be root to inject keystrokes.\n" -" /dev/tty0 refers to the active VT, to indicate one\n" -" explicitly, use \"console2\", etc. using the VT number.\n" -"\n" -" If the Linux version seems to be 2.6 or later and the\n" -" \"uinput\" module appears to be present, then the uinput\n" -" method will be used instead of /dev/ttyN. uinput allows\n" -" insertion of BOTH keystrokes and mouse input and so it\n" -" preferred when accessing graphical (e.g. QT-embedded)\n" -" linux console apps. See -pipeinput UINPUT below for\n" -" more information on this mode; you will have to use\n" -" -pipeinput if you want to tweak any UINPUT parameters.\n" -" You may also want to also use the -nodragging and\n" -" -cursor none options. Use \"console0\", etc or\n" -" -pipeinput CONSOLE to force the /dev/ttyN method.\n" -"\n" -" Note you can change VT remotely using the chvt(1)\n" -" command. Sometimes switching out and back corrects\n" -" the framebuffer state.\n" -"\n" -" To skip input injecting entirely use \"consolex\".\n" +" You will need to be root to inject keystrokes, but\n" +" not necessarily to open /dev/fb0. /dev/tty0 refers to\n" +" the active VT, to indicate one explicitly, use, e.g.,\n" +" \"console2\" for /dev/tty2, etc. by indicating the\n" +" specific VT number.\n" +"\n" +" For the Linux framebuffer device, /dev/fb0, (fb1,\n" +" etc) to be enabled the appropriate kernel drivers must\n" +" be loaded. E.g. vesafb or vga16fb and also by setting\n" +" the boot parameter vga=0x301 (or 0x314, 0x317, etc.)\n" +" (The vga=... method is the preferred way; set your\n" +" machines up that way.) Otherwise there will be a\n" +" 'No such device' error. You can also load a Linux\n" +" framebuffer driver specific to your make of video card\n" +" for more functionality. Once the machine is booted one\n" +" can often 'modprobe' the fb driver as root to obtain\n" +" a framebuffer device.\n" +"\n" +" If you cannot get /dev/fb0 working on Linux, try\n" +" using the LinuxVNC emulation mode by \"-rawfb vtN\"\n" +" where N = 1, ... 6 is the Linux Virtual Terminal (aka\n" +" virtual console) you wish to view, e.g. \"-rawfb vt2\".\n" +" Unlike /dev/fb mode, it need not be the active Virtual\n" +" Terminal. Note that this mode can only show text and\n" +" not graphics. x11vnc polls the text in /dev/vcsaN\n" +"\n" +" Set the env. var. RAWFB_VCSA_BW=1 to disable colors in\n" +" the \"vtN\" mode (i.e. black and white only.) If you\n" +" do not prefer the default 16bpp set RAWFB_VCSA_BPP to\n" +" 8 or 32. If you need to tweak the rawfb parameters by\n" +" using the 'console_guess' string printed at startup,\n" +" be sure to indicate the snap: method.\n" +"\n" +" uinput: If the Linux version appears to be 2.6 or\n" +" later and the \"uinput\" module appears to be present\n" +" (modprobe uinput), then the uinput method will be used\n" +" instead of /dev/ttyN. uinput allows insertion of BOTH\n" +" keystrokes and mouse input and so it preferred when\n" +" accessing graphical (e.g. QT-embedded) linux console\n" +" apps. See -pipeinput UINPUT below for more information\n" +" on this mode; you will have to use -pipeinput if you\n" +" want to tweak any UINPUT parameters. You may also want\n" +" to also use the -nodragging and -cursor none options.\n" +" Use \"console0\", etc or -pipeinput CONSOLE to force\n" +" the /dev/ttyN method.\n" +"\n" +" Note you can change the Linux VT remotely using the\n" +" chvt(1) command to make the one you want be the active\n" +" one (e.g. 'chvt 3'). Sometimes switching out and back\n" +" corrects the framebuffer's graphics state. For the\n" +" \"-rawfb vtN\" mode there is no need to switch the VT's.\n" +"\n" +" To skip input injecting entirely use \"consolex\"\n" +" or \"vtx\".\n" "\n" " The string \"/dev/fb0\" (1, etc.) can be used instead\n" " of \"console\". This can be used to specify a different\n" @@ -3817,8 +3889,8 @@ void print_help(int mode) { "\n" " If you do not want x11vnc to guess the framebuffer's\n" " WxHxB and masks automatically (sometimes the kernel\n" -" gives inaccurate information), specify them with a\n" -" @WxHxB at the end of the string.\n" +" gives incorrect information), specify them with a @WxHxB\n" +" (and optional :R/G/B masks) at the end of the string.\n" "\n" " Examples:\n" " -rawfb console\n" @@ -3827,6 +3899,7 @@ void print_help(int mode) { " -rawfb consolex (no keystrokes or mouse)\n" " -rawfb console:/dev/nonstd\n" " -rawfb console -pipeinput UINPUT:accel=4.0\n" +" -rawfb vt3 (/dev/tty3 w/o /dev/fb0)\n" "\n" " VNC HOST: if the -rawfb string is of the form\n" " \"vnc:host:N\" then the VNC display \"N\" on the remote\n" diff --git a/x11vnc/linuxfb.c b/x11vnc/linuxfb.c index 8adfe6b..aac17b9 100644 --- a/x11vnc/linuxfb.c +++ b/x11vnc/linuxfb.c @@ -22,6 +22,9 @@ char *console_guess(char *str, int *fd); void console_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client); void console_pointer_command(int mask, int x, int y, rfbClientPtr client); + +void linux_dev_fb_msg(char *); + char *console_guess(char *str, int *fd) { char *q, *in = strdup(str); char *atparms = NULL, *file = NULL; @@ -40,6 +43,10 @@ char *console_guess(char *str, int *fd) { free(in); in = (char *) malloc(strlen("console:/dev/") + strlen(str) + 1); sprintf(in, "console:/dev/%s", str); + } else if (strstr(in, "vt") == in) { + free(in); + in = (char *) malloc(strlen("console_") + strlen(str) + 1); + sprintf(in, "console_%s", str); } if (strstr(in, "console") != in) { @@ -75,7 +82,6 @@ char *console_guess(char *str, int *fd) { file = strdup("/dev/fb0"); } } - rfbLog("console_guess: file is %s\n", file); do_input = 1; if (pipeinput_str) { @@ -84,9 +90,15 @@ char *console_guess(char *str, int *fd) { } else { have_uinput = check_uinput(); } + if (strstr(in, "console_vt")) { + have_uinput = 0; + } if (!strcmp(in, "consolex")) { do_input = 0; + } else if (strstr(in, "console_vtx")) { + have_uinput = 0; + do_input = 0; } else if (!strcmp(in, "console")) { /* current active VT: */ if (! have_uinput) { @@ -94,11 +106,44 @@ char *console_guess(char *str, int *fd) { } } else { int n; - if (sscanf(in, "console%d", &n) != 1) { + if (sscanf(in, "console%d", &n) == 1) { + tty = n; + have_uinput = 0; + } else if (sscanf(in, "console_vt%d", &n) == 1) { tty = n; have_uinput = 0; } } + if (strstr(in, "console_vt") == in) { + char tmp[100]; + int fd, rows = 30, cols = 80, w, h; + sprintf(tmp, "/dev/vcsa%d", tty); + file = strdup(tmp); + fd = open(file, O_RDWR); + if (fd >= 0) { + read(fd, tmp, 4); + rows = (unsigned char) tmp[0]; + cols = (unsigned char) tmp[1]; + close(fd); + } + w = cols * 8; + h = rows * 16; + rfbLog("%s %dx%d\n", file, cols, rows); + if (getenv("RAWFB_VCSA_BPP")) { + /* 8bpp, etc */ + int bt = atoi(getenv("RAWFB_VCSA_BPP")); + if (bt > 0 && bt <=32) { + sprintf(tmp, "%dx%dx%d", w, h, bt); + } else { + sprintf(tmp, "%dx%dx16", w, h); + } + } else { + /* default 16bpp */ + sprintf(tmp, "%dx%dx16", w, h); + } + atparms = strdup(tmp); + } + rfbLog("console_guess: file is %s\n", file); if (! atparms) { #if LIBVNCSERVER_HAVE_LINUX_FB_H @@ -126,6 +171,13 @@ char *console_guess(char *str, int *fd) { gm = 0x38; bm = 0xc0; } + if (b <= 8 && (rm == gm && gm == bm)) { + if (b == 4) { + rm = 0x07; + gm = 0x38; + bm = 0xc0; + } + } /* @66666x66666x32:0xffffffff:... */ atparms = (char *) malloc(200); @@ -138,7 +190,8 @@ char *console_guess(char *str, int *fd) { } } else { rfbLog("could not open: %s\n", file); - perror("open"); + rfbLogPerror("open"); + linux_dev_fb_msg(file); close(d); } #endif @@ -174,8 +227,12 @@ char *console_guess(char *str, int *fd) { return NULL; } - q = (char *) malloc(strlen("map:") + strlen(file) + 1 + strlen(atparms) + 1); - sprintf(q, "map:%s@%s", file, atparms); + q = (char *) malloc(strlen("mmap:") + strlen(file) + 1 + strlen(atparms) + 1); + if (strstr(in, "console_vt")) { + sprintf(q, "snap:%s@%s", file, atparms); + } else { + sprintf(q, "map:%s@%s", file, atparms); + } return q; } diff --git a/x11vnc/options.c b/x11vnc/options.c index 6377184..920c184 100644 --- a/x11vnc/options.c +++ b/x11vnc/options.c @@ -17,6 +17,7 @@ int set_visual_str_to_something = 0; char *logfile = NULL; /* -o, -logfile */ int logfile_append = 0; char *flagfile = NULL; /* -flag */ +char *rm_flagfile = NULL; /* -rmflag */ char *passwdfile = NULL; /* -passwdfile */ int unixpw = 0; /* -unixpw */ int unixpw_nis = 0; /* -unixpw_nis */ @@ -145,6 +146,7 @@ int clear_mods = 0; /* -clear_mods (1) and -clear_keys (2) -clear_locks (3) */ int nofb = 0; /* do not send any fb updates */ char *raw_fb_str = NULL; /* used under -rawfb */ char *raw_fb_pixfmt = NULL; +char *raw_fb_full_str = NULL; char *freqtab = NULL; char *pipeinput_str = NULL; /* -pipeinput [tee,reopen,keycodes:]cmd */ char *pipeinput_opts = NULL; diff --git a/x11vnc/options.h b/x11vnc/options.h index e0bc299..04ac4b6 100644 --- a/x11vnc/options.h +++ b/x11vnc/options.h @@ -17,6 +17,7 @@ extern int set_visual_str_to_something; extern char *logfile; extern int logfile_append; extern char *flagfile; +extern char *rm_flagfile; extern char *passwdfile; extern int unixpw; extern int unixpw_nis; @@ -117,6 +118,7 @@ extern int clear_mods; extern int nofb; extern char *raw_fb_str; extern char *raw_fb_pixfmt; +extern char *raw_fb_full_str; extern char *freqtab; extern char *pipeinput_str; extern char *pipeinput_opts; diff --git a/x11vnc/pointer.c b/x11vnc/pointer.c index 100496b..aa5ecea 100644 --- a/x11vnc/pointer.c +++ b/x11vnc/pointer.c @@ -993,6 +993,8 @@ if (0) fprintf(stderr, "initialize_pipeinput: %s -- %s\n", pipeinput_str, p); } else { rfbLog("pipeinput: could not open: %s\n", dev); rfbLogPerror("open"); + rfbLog("You may need to be root to open %s.\n", dev); + rfbLog("\n"); } return; } else if (strstr(p, "UINPUT") == p) { diff --git a/x11vnc/remote.c b/x11vnc/remote.c index 689f9b0..8aada19 100644 --- a/x11vnc/remote.c +++ b/x11vnc/remote.c @@ -5248,6 +5248,10 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(flagfile)); goto qry; } + if (!strcmp(p, "rmflag")) { + snprintf(buf, bufn, "aro=%s:%s", p, NONUL(rm_flagfile)); + goto qry; + } if (!strcmp(p, "rc")) { char *s = rc_rcfile; if (rc_rcfile_default) { diff --git a/x11vnc/scan.c b/x11vnc/scan.c index 12b94d9..864e16a 100644 --- a/x11vnc/scan.c +++ b/x11vnc/scan.c @@ -2421,6 +2421,224 @@ int copy_screen(void) { return 0; } +#include + +/* + * Color values from the vcsadump program. + * void dumpcss(FILE *fp, char *attribs_used) + * char *colormap[] = { + * "#000000", "#0000AA", "#00AA00", "#00AAAA", "#AA0000", "#AA00AA", "#AA5500", "#AAAAAA", + * "#555555", "#5555AA", "#55FF55", "#55FFFF", "#FF5555", "#FF55FF", "#FFFF00", "#FFFFFF" }; + */ + +static unsigned char console_cmap[16*3]={ +/* 0 */ 0x00, 0x00, 0x00, +/* 1 */ 0x00, 0x00, 0xAA, +/* 2 */ 0x00, 0xAA, 0x00, +/* 3 */ 0x00, 0xAA, 0xAA, +/* 4 */ 0xAA, 0x00, 0x00, +/* 5 */ 0xAA, 0x00, 0xAA, +/* 6 */ 0xAA, 0x55, 0x00, +/* 7 */ 0xAA, 0xAA, 0xAA, +/* 8 */ 0x55, 0x55, 0x55, +/* 9 */ 0x55, 0x55, 0xAA, +/* 10 */ 0x55, 0xFF, 0x55, +/* 11 */ 0x55, 0xFF, 0xFF, +/* 12 */ 0xFF, 0x55, 0x55, +/* 13 */ 0xFF, 0x55, 0xFF, +/* 14 */ 0xFF, 0xFF, 0x00, +/* 15 */ 0xFF, 0xFF, 0xFF +}; + +static void snap_vcsa_rawfb(void) { + int n; + char *dst; + char buf[32]; + int i, len, del; + unsigned char rows, cols, xpos, ypos; + static int prev_rows = -1, prev_cols = -1; + static unsigned char prev_xpos = -1, prev_ypos = -1; + static char *vcsabuf = NULL; + static char *vcsabuf0 = NULL; + static unsigned int color_tab[16]; + static int Cw = 8, Ch = 16; + static int db = -1, first = 1; + int created = 0; + rfbScreenInfo s; + rfbScreenInfoPtr fake_screen = &s; + int Bpp = raw_fb_native_bpp / 8; + + if (db < 0) { + if (getenv("X11VNC_DEBUG_VCSA")) { + db = atoi(getenv("X11VNC_DEBUG_VCSA")); + } else { + db = 0; + } + } + + if (first) { + unsigned int rm = raw_fb_native_red_mask; + unsigned int gm = raw_fb_native_green_mask; + unsigned int bm = raw_fb_native_blue_mask; + unsigned int rs = raw_fb_native_red_shift; + unsigned int gs = raw_fb_native_green_shift; + unsigned int bs = raw_fb_native_blue_shift; + unsigned int rx = raw_fb_native_red_max; + unsigned int gx = raw_fb_native_green_max; + unsigned int bx = raw_fb_native_blue_max; + + for (i=0; i < 16; i++) { + int r = console_cmap[3*i+0]; + int g = console_cmap[3*i+1]; + int b = console_cmap[3*i+2]; + r = rx * r / 255; + g = gx * g / 255; + b = bx * b / 255; + color_tab[i] = (r << rs) | (g << gs) | (b << bs); + if (db) fprintf(stderr, "cmap[%02d] 0x%08x %04d %04d %04d\n", i, color_tab[i], r, g, b); + if (i != 0 && getenv("RAWFB_VCSA_BW")) { + color_tab[i] = rm | gm | bm; + } + } + } + first = 0; + + lseek(raw_fb_fd, 0, SEEK_SET); + len = 4; + del = 0; + memset(buf, 0, sizeof(buf)); + while (len > 0) { + n = read(raw_fb_fd, buf + del, len); + if (n > 0) { + del += n; + len -= n; + } else if (n == 0) { + break; + } else if (errno != EINTR && errno != EAGAIN) { + break; + } + } + + rows = (unsigned char) buf[0]; + cols = (unsigned char) buf[1]; + xpos = (unsigned char) buf[2]; + ypos = (unsigned char) buf[3]; + + if (db) fprintf(stderr, "rows=%d cols=%d xpos=%d ypos=%d Bpp=%d\n", rows, cols, xpos, ypos, Bpp); + if (rows == 0 || cols == 0) { + usleep(100 * 1000); + return; + } + + if (vcsabuf == NULL || prev_rows != rows || prev_cols != cols) { + if (vcsabuf) { + free(vcsabuf); + free(vcsabuf0); + } + vcsabuf = (char *) calloc(2 * rows * cols, 1); + vcsabuf0 = (char *) calloc(2 * rows * cols, 1); + created = 1; + + if (prev_rows != -1 && prev_cols != -1) { + do_new_fb(1); + } + + prev_rows = rows; + prev_cols = cols; + } + + if (!rfbEndianTest) { + unsigned char tc = rows; + rows = cols; + cols = tc; + + tc = xpos; + xpos = ypos; + ypos = tc; + } + + len = 2 * rows * cols; + del = 0; + memset(vcsabuf, 0, len); + while (len > 0) { + n = read(raw_fb_fd, vcsabuf + del, len); + if (n > 0) { + del += n; + len -= n; + } else if (n == 0) { + break; + } else if (errno != EINTR && errno != EAGAIN) { + break; + } + } + + fake_screen->frameBuffer = snap->data; + fake_screen->paddedWidthInBytes = snap->bytes_per_line; + fake_screen->serverFormat.bitsPerPixel = raw_fb_native_bpp; + + for (i=0; i < rows * cols; i++) { + int ix, iy, x, y, w, h; + unsigned char chr = 0; + unsigned char attr; + unsigned int fore, back; + unsigned short *usp; + unsigned int *uip; + chr = (unsigned char) vcsabuf[2*i]; + attr = vcsabuf[2*i+1]; + + iy = i / cols; + ix = i - iy * cols; + + if (ix == prev_xpos && iy == prev_ypos) { + ; + } else if (ix == xpos && iy == ypos) { + ; + } else if (!created && chr == vcsabuf0[2*i] && attr == vcsabuf0[2*i+1]) { + continue; + } + + if (!rfbEndianTest) { + unsigned char tc = chr; + chr = attr; + attr = tc; + } + + y = iy * Ch; + x = ix * Cw; + dst = snap->data + y * snap->bytes_per_line + x * Bpp; + + fore = color_tab[attr & 0xf]; + back = color_tab[(attr >> 4) & 0x7]; + + if (ix == xpos && iy == ypos) { + unsigned int ti = fore; + fore = back; + back = ti; + } + + for (h = 0; h < Ch; h++) { + if (Bpp == 1) { + memset(dst, back, Cw); + } else if (Bpp == 2) { + for (w = 0; w < Cw; w++) { + usp = (unsigned short *) (dst + w*Bpp); + *usp = (unsigned short) back; + } + } else if (Bpp == 4) { + for (w = 0; w < Cw; w++) { + uip = (unsigned int *) (dst + w*Bpp); + *uip = (unsigned int) back; + } + } + dst += snap->bytes_per_line; + } + rfbDrawChar(fake_screen, &default8x16Font, x, y + Ch, chr, fore); + } + memcpy(vcsabuf0, vcsabuf, 2 * rows * cols); + prev_xpos = xpos; + prev_ypos = ypos; +} + static void snap_all_rawfb(void) { int pixelsize = bpp/8; int n, sz; @@ -2513,7 +2731,9 @@ int copy_snap(void) { if (raw_fb_bytes_per_line != snap->bytes_per_line) { read_all_at_once = 0; } - if (read_all_at_once) { + if (raw_fb_full_str && strstr(raw_fb_full_str, "/dev/vcsa")) { + snap_vcsa_rawfb(); + } else if (read_all_at_once) { snap_all_rawfb(); } else { /* this goes line by line, XXX not working for video */ diff --git a/x11vnc/screen.c b/x11vnc/screen.c index 05da0df..2d7ed73 100644 --- a/x11vnc/screen.c +++ b/x11vnc/screen.c @@ -1165,6 +1165,24 @@ void vnc_reflect_process_client(void) { } } +void linux_dev_fb_msg(char* q) { + if (strstr(q, "/dev/fb") && strstr(UT.sysname, "Linux")) { + rfbLog("\n"); + rfbLog("On Linux you may need to load a kernel module to enable\n"); + rfbLog("the framebuffer device /dev/fb*; e.g.:\n"); + rfbLog(" vga=0x303 (and others) kernel boot parameter\n"); + rfbLog(" modprobe uvesafb\n"); + rfbLog(" modprobe radeonfb (card specific)\n"); + rfbLog(" modprobe nvidiafb (card specific, others)\n"); + rfbLog(" modprobe vesafb (?)\n"); + rfbLog(" modprobe vga16fb\n"); + rfbLog("\n"); + rfbLog("You may also need root permission to open /dev/fb*\n"); + rfbLog("and/or /dev/tty*.\n"); + rfbLog("\n"); + } +} + #define RAWFB_MMAP 1 #define RAWFB_FILE 2 #define RAWFB_SHM 3 @@ -1414,7 +1432,7 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n"); } else if (strstr(str, "dev/video")) { rawfb_dev_video = 1; } else if (strstr(str, "console") == str || strstr(str, "fb") == str || - strstr(str, "/dev/fb") == str) { + strstr(str, "/dev/fb") == str || strstr(str, "vt") == str) { char *str2 = console_guess(str, &raw_fb_fd); if (str2 == NULL) { rfbLog("console_guess failed for: %s\n", str); @@ -1467,6 +1485,11 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n"); * -rawfb file:/path/to/file@640x480x32:ff/ff00/ff0000 */ + if (raw_fb_full_str) { + free(raw_fb_full_str); + } + raw_fb_full_str = strdup(str); + /* +O offset */ if ((q = strrchr(str, '+')) != NULL) { @@ -1509,6 +1532,93 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n"); } *q = '\0'; + if (rm == 0 && gm == 0 && bm == 0) { + /* guess masks... */ + if (b == 24 || b == 32) { + rm = 0xff0000; + gm = 0x00ff00; + bm = 0x0000ff; + } else if (b == 16) { + rm = 0xf800; + gm = 0x07e0; + bm = 0x001f; + } else if (b == 8) { + rm = 0x07; + gm = 0x38; + bm = 0xc0; + } + } + /* we can fake -flipbyteorder to some degree... */ + if (flip_byte_order) { + if (b == 24 || b == 32) { + tm = rm; + rm = bm; + bm = tm; + } else if (b == 16) { + unsigned short s1, s2; + s1 = (unsigned short) rm; + s2 = ((0xff & s1) << 8) | ((0xff00 & s1) >> 8); + rm = (unsigned long) s2; + s1 = (unsigned short) gm; + s2 = ((0xff & s1) << 8) | ((0xff00 & s1) >> 8); + gm = (unsigned long) s2; + s1 = (unsigned short) bm; + s2 = ((0xff & s1) << 8) | ((0xff00 & s1) >> 8); + bm = (unsigned long) s2; + } + } + + /* native fb stuff for bpp < 8 only */ + raw_fb_native_bpp = b; + raw_fb_native_red_mask = rm; + raw_fb_native_green_mask = gm; + raw_fb_native_blue_mask = bm; + raw_fb_native_red_shift = 100; + raw_fb_native_green_shift = 100; + raw_fb_native_blue_shift = 100; + raw_fb_native_red_max = 1; + raw_fb_native_green_max = 1; + raw_fb_native_blue_max = 1; + m = 1; + for (i=0; i<32; i++) { + if (raw_fb_native_red_mask & m) { + if (raw_fb_native_red_shift == 100) { + raw_fb_native_red_shift = i; + } + raw_fb_native_red_max *= 2; + } + if (raw_fb_native_green_mask & m) { + if (raw_fb_native_green_shift == 100) { + raw_fb_native_green_shift = i; + } + raw_fb_native_green_max *= 2; + } + if (raw_fb_native_blue_mask & m) { + if (raw_fb_native_blue_shift == 100) { + raw_fb_native_blue_shift = i; + } + raw_fb_native_blue_max *= 2; + } + m = m << 1; + } + raw_fb_native_red_max -= 1; + raw_fb_native_green_max -= 1; + raw_fb_native_blue_max -= 1; + + if (b < 8) { + /* e.g. VGA16 */ + rfbLog("raw_fb_native_bpp: %d 0x%02lx 0x%02lx 0x%02lx %d/%d/%d %d/%d/%d\n", raw_fb_native_bpp, + raw_fb_native_red_mask, raw_fb_native_green_mask, raw_fb_native_blue_mask, + raw_fb_native_red_max, raw_fb_native_green_max, raw_fb_native_blue_max, + raw_fb_native_red_shift, raw_fb_native_green_shift, raw_fb_native_blue_shift); + raw_fb_expand_bytes = 1; + b = 8; + rm = 0x07; + gm = 0x38; + bm = 0xc0; + } + /* end of stuff for bpp < 8 */ + dpy_x = wdpy_x = w; dpy_y = wdpy_y = h; off_x = 0; @@ -1609,11 +1719,14 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n"); rfbLogEnable(1); rfbLog("failed to open file: %s, %s\n", q, str); rfbLogPerror("open"); + linux_dev_fb_msg(q); clean_up_exit(1); } raw_fb_fd = fd; - if (xform24to32) { + if (raw_fb_native_bpp < 8) { + size = w*h*raw_fb_native_bpp/8 + raw_fb_offset; + } else if (xform24to32) { size = w*h*24/8 + raw_fb_offset; } else { size = w*h*b/8 + raw_fb_offset; @@ -1650,14 +1763,20 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n"); rfbLog("failed to mmap file: %s, %s\n", q, str); rfbLog(" raw_fb_addr: %p\n", raw_fb_addr); rfbLogPerror("mmap"); - clean_up_exit(1); - } - raw_fb_mmap = size; - rfbLog("rawfb: mmap file: %s\n", q); - rfbLog(" w: %d h: %d b: %d addr: %p sz: %d\n", w, h, - b, raw_fb_addr, size); - last_mode = RAWFB_MMAP; + raw_fb_addr = NULL; + rfbLog("mmap(2) failed, trying slower lseek(2)\n"); + raw_fb_seek = size; + last_mode = RAWFB_FILE; + + } else { + raw_fb_mmap = size; + + rfbLog("rawfb: mmap file: %s\n", q); + rfbLog(" w: %d h: %d b: %d addr: %p sz: %d\n", w, h, + b, raw_fb_addr, size); + last_mode = RAWFB_MMAP; + } #else rfbLog("mmap(2) not supported on system, using" " slower lseek(2)\n"); @@ -1739,42 +1858,6 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n"); snap->bitmap_unit = -1; } - if (rm == 0 && gm == 0 && bm == 0) { - /* guess masks... */ - if (b == 24 || b == 32) { - rm = 0xff0000; - gm = 0x00ff00; - bm = 0x0000ff; - } else if (b == 16) { - rm = 0xf800; - gm = 0x07e0; - bm = 0x001f; - } else if (b == 8) { - rm = 0x07; - gm = 0x38; - bm = 0xc0; - } - } - /* we can fake -flipbyteorder to some degree... */ - if (flip_byte_order) { - if (b == 24 || b == 32) { - tm = rm; - rm = bm; - bm = tm; - } else if (b == 16) { - unsigned short s1, s2; - s1 = (unsigned short) rm; - s2 = ((0xff & s1) << 8) | ((0xff00 & s1) >> 8); - rm = (unsigned long) s2; - s1 = (unsigned short) gm; - s2 = ((0xff & s1) << 8) | ((0xff00 & s1) >> 8); - gm = (unsigned long) s2; - s1 = (unsigned short) bm; - s2 = ((0xff & s1) << 8) | ((0xff00 & s1) >> 8); - bm = (unsigned long) s2; - } - } - raw_fb_image->red_mask = rm; raw_fb_image->green_mask = gm; @@ -1794,6 +1877,9 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n"); } m = m << 1; } + if (raw_fb_native_bpp < 8) { + raw_fb_image->depth = raw_fb_expand_bytes * 8; + } if (! raw_fb_image->depth) { raw_fb_image->depth = (b == 32) ? 24 : b; } @@ -1805,7 +1891,7 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n"); depth++; } - if (clipshift) { + if (clipshift || raw_fb_native_bpp < 8) { memset(raw_fb, 0xff, dpy_y * raw_fb_image->bytes_per_line); } else if (raw_fb_addr && ! xform24to32) { memcpy(raw_fb, raw_fb_addr + raw_fb_offset, dpy_y * raw_fb_image->bytes_per_line); @@ -1814,7 +1900,6 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n"); } if (verbose) { - rfbLog("\n"); rfbLog("rawfb: raw_fb %p\n", raw_fb); rfbLog(" format %d\n", raw_fb_image->format); @@ -3273,6 +3358,31 @@ void set_vnc_desktop_name(void) { flagfile); } } + if (rm_flagfile) { + int create = 0; + struct stat sb; + if (strstr(rm_flagfile, "create:") == rm_flagfile) { + char *s = rm_flagfile; + create = 1; + rm_flagfile = strdup(rm_flagfile + strlen("create:")); + free(s); + } + if (strstr(rm_flagfile, "nocreate:") == rm_flagfile) { + char *s = rm_flagfile; + create = 0; + rm_flagfile = strdup(rm_flagfile + strlen("nocreate:")); + free(s); + } else if (stat(rm_flagfile, &sb) != 0) { + create = 1; + } + if (create) { + FILE *flag = fopen(rm_flagfile, "w"); + if (flag) { + fprintf(flag, "%d\n", getpid()); + fclose(flag); + } + } + } } fflush(stdout); } diff --git a/x11vnc/sslhelper.c b/x11vnc/sslhelper.c index b121f91..7e1fffd 100644 --- a/x11vnc/sslhelper.c +++ b/x11vnc/sslhelper.c @@ -980,6 +980,7 @@ void openssl_init(int isclient) { " be used in -sslCRL mode.\n"); clean_up_exit(1); } + /* n.b. new ctx */ if (!switch_to_anon_dh()) { rfbLog("openssl_init: Anonymous Diffie-Hellman setup" " failed.\n"); @@ -2746,10 +2747,17 @@ static int switch_to_anon_dh(void) { rfbLog("Using Anonymous Diffie-Hellman mode.\n"); rfbLog("WARNING: Anonymous Diffie-Hellman uses encryption but is\n"); rfbLog("WARNING: susceptible to a Man-In-The-Middle attack.\n"); - ctx = SSL_CTX_new( SSLv23_server_method() ); + if (ssl_client_mode) { + ctx = SSL_CTX_new( SSLv23_client_method() ); + } else { + ctx = SSL_CTX_new( SSLv23_server_method() ); + } if (ctx == NULL) { return 0; } + if (ssl_client_mode) { + return 1; + } if (!SSL_CTX_set_cipher_list(ctx, "ADH:@STRENGTH")) { return 0; } @@ -2959,10 +2967,12 @@ static int check_vnc_tls_mode(int s_in, int s_out) { if (ssl_client_mode) { /* XXX check if this can be done in SSL client mode. */ if (vencrypt_mode == VENCRYPT_FORCE || anontls_mode == ANONTLS_FORCE) { - rfbLog("check_vnc_tls_mode: VENCRYPT_FORCE/ANONTLS_FORCE prevents normal SSL\n"); - return 0; + rfbLog("check_vnc_tls_mode: VENCRYPT_FORCE/ANONTLS_FORCE in client\n"); + rfbLog("check_vnc_tls_mode: connect mode prevents normal SSL.\n"); + //return 0; + } else { + return 1; } - return 1; } if (ssl_verify && vencrypt_mode != VENCRYPT_FORCE && anontls_mode == ANONTLS_FORCE) { rfbLog("check_vnc_tls_mode: Cannot use ANONTLS_FORCE with -sslverify (Anon DH only)\n"); @@ -3194,14 +3204,15 @@ static int ssl_init(int s_in, int s_out, int skip_vnc_tls) { if (db > 1) fprintf(stderr, "ssl_init: 4\n"); while (1) { - if (db) fprintf(stderr, "calling SSL_accept...\n"); signal(SIGALRM, ssl_timeout); alarm(timeout); if (ssl_client_mode) { + if (db) fprintf(stderr, "calling SSL_connect...\n"); rc = SSL_connect(ssl); } else { + if (db) fprintf(stderr, "calling SSL_accept...\n"); rc = SSL_accept(ssl); } err = SSL_get_error(ssl, rc); @@ -3209,7 +3220,11 @@ static int ssl_init(int s_in, int s_out, int skip_vnc_tls) { alarm(0); signal(SIGALRM, SIG_DFL); - if (db) fprintf(stderr, "SSL_accept %d/%d\n", rc, err); + if (ssl_client_mode) { + if (db) fprintf(stderr, "SSL_connect %d/%d\n", rc, err); + } else { + if (db) fprintf(stderr, "SSL_accept %d/%d\n", rc, err); + } if (err == SSL_ERROR_NONE) { break; } else if (err == SSL_ERROR_WANT_READ) { @@ -3283,7 +3298,11 @@ static int ssl_init(int s_in, int s_out, int skip_vnc_tls) { usleep(10 * 1000); } - rfbLog("SSL: ssl_helper[%d]: SSL_accept() succeeded for: %s:%d\n", getpid(), name, peerport); + if (ssl_client_mode) { + rfbLog("SSL: ssl_helper[%d]: SSL_connect() succeeded for: %s:%d\n", getpid(), name, peerport); + } else { + rfbLog("SSL: ssl_helper[%d]: SSL_accept() succeeded for: %s:%d\n", getpid(), name, peerport); + } pr_ssl_info(0); @@ -3848,13 +3867,13 @@ void raw_xfer(int csock, int s_in, int s_out) { /* change buf size some direction. */ } - /* this is for testing, no SSL just socket redir */ - if (pid < 0) { - exit(1); - } if (getenv("X11VNC_DEBUG_RAW_XFER")) { db = atoi(getenv("X11VNC_DEBUG_RAW_XFER")); } + if (pid < 0) { + exit(1); + } + /* this is for testing or special helper usage, no SSL just socket redir */ if (pid) { if (db) rfbLog("raw_xfer start: %d -> %d/%d\n", csock, s_in, s_out); diff --git a/x11vnc/v4l.c b/x11vnc/v4l.c index 7dc7889..b4f3de8 100644 --- a/x11vnc/v4l.c +++ b/x11vnc/v4l.c @@ -1287,12 +1287,24 @@ static void parse_str(char *str, char **dev, char **settings, char **atparms) { } if (*dev == NULL) { - s = (char *) malloc(strlen("/dev/") + strlen(str) + 1); + struct stat sbuf; + s = (char *) malloc(strlen("/dev/") + strlen(str) + 2); if (strstr(str, "/dev/") == str) { sprintf(s, "%s", str); } else { sprintf(s, "/dev/%s", str); + } + rfbLog("Checking existence of '%s'\n", s); + if (stat(s, &sbuf) != 0) { + rfbLogPerror("stat"); + strcat(s, "0"); + rfbLog("switching to '%s'\n", s); } + if (stat(s, &sbuf) != 0) { + rfbLogPerror("stat"); + rfbLog("You will need to specify the video device more explicity.\n"); + } + *dev = s; rfbLog("set video device to: '%s'\n", *dev); } diff --git a/x11vnc/x11vnc.1 b/x11vnc/x11vnc.1 index a3d35bb..313c3fa 100644 --- a/x11vnc/x11vnc.1 +++ b/x11vnc/x11vnc.1 @@ -1,8 +1,8 @@ .\" This file was automatically generated from x11vnc -help output. -.TH X11VNC "1" "December 2008" "x11vnc " "User Commands" +.TH X11VNC "1" "January 2009" "x11vnc " "User Commands" .SH NAME x11vnc - allow VNC connections to real X11 displays - version: 0.9.6, lastmod: 2008-12-08 + version: 0.9.7, lastmod: 2009-01-03 .SH SYNOPSIS .B x11vnc [OPTION]... @@ -2802,6 +2802,15 @@ Write the "PORT=NNNN" (e.g. PORT=5900) string to \fIfile\fR in addition to stdout. This option could be useful by wrapper script to detect when x11vnc is ready. .PP +\fB-rmflag\fR \fIfile\fR +.IP +Remove \fIfile\fR at exit to signal when x11vnc is done. +The file is created at startup if it does not already +exist or if \fIfile\fR is prefixed with "create:". +If the file is created, the x11vnc PID is placed in +the file. Otherwise the files contents is not changed. +Use prefix "nocreate:" to prevent creation. +.PP \fB-rc\fR \fIfilename\fR .IP Use \fIfilename\fR instead of $HOME/.x11vncrc for rc file. @@ -4209,20 +4218,22 @@ webcams, or where window tearing is a problem. Instead of polling X, poll the memory object specified in \fIstring\fR. .IP -For file polling to memory map +For file polling, to memory map .IR mmap (2) a file use: "map:/path/to/a/file@WxHxB", with framebuffer Width, Height, and Bits per pixel. "mmap:..." is the same. .IP -If there is trouble with mmap, use "file:/..." +If there is trouble with mmap, use "file:/..." for slower .IR lseek (2) -based reading. Use "snap:..." -to imply \fB-snapfb\fR mode and the "file:" access (this -is for unseekable devices that only provide the fb all -at once, e.g. a video camera provides the whole frame). +based reading. +.IP +Use "snap:..." to imply \fB-snapfb\fR mode and the "file:" +access (this is for unseekable devices that only provide +the fb all at once, e.g. a video camera provides the +whole frame). .IP For shared memory segments string is of the form: "shm:N@WxHxB" which specifies a shmid N and with @@ -4245,25 +4256,29 @@ If the string begins with "video", see the VIDEO4LINUX discussion below where the device may be queried for (and possibly set) the framebuffer parameters. .IP -If the string begins with "console", "/dev/fb", or -"fb", see the LINUX CONSOLE discussion below where -the framebuffer device is opened and keystrokes (and -possibly mouse events) are inserted into the console. +If the string begins with "console", "/dev/fb", +"fb", or "vt", see the LINUX CONSOLE discussion +below where the framebuffer device is opened and +keystrokes (and possibly mouse events) are inserted +into the console. .IP If the string begins with "vnc", see the VNC HOST discussion below where the framebuffer is taken as that of another remote VNC server. .IP Optional suffixes are ":R/G/B" and "+O" to specify -red, green, and blue masks and an offset into the -memory object. If the masks are not provided x11vnc -guesses them based on the bpp. +red, green, and blue masks (in hex) and an offset into +the memory object. If the masks are not provided x11vnc +guesses them based on the bpp (if the colors look wrong, +you need to provide the masks.) .IP Another optional suffix is the Bytes Per Line which in -some cases is not WxB/4. Specify it as WxHxB-BPL +some cases is not WxB/8. Specify it as WxHxB-BPL e.g. 800x600x16-2048. This could be a normal width 1024 at 16bpp fb, but only width 800 shows up. .IP +So the full format is: mode:file@WxHxB:R/G/B+O-BPL +.IP Examples: .IP \fB-rawfb\fR shm:210337933@800x600x32:ff/ff00/ff0000 @@ -4279,6 +4294,7 @@ Examples: \fB-rawfb\fR video0 \fB-rawfb\fR video \fB-pipeinput\fR VID \fB-rawfb\fR console +\fB-rawfb\fR vt2 \fB-rawfb\fR vnc:somehost:0 .IP (see @@ -4306,7 +4322,7 @@ something strange with /dev/fb0. If the device is not "seekable" (e.g. webcam) try reading it all at once in full snaps via the "snap:" mode (note: this is a resource hog). If you are using -file: or map: and the device needs to be reopened for +file: or map: AND the device needs to be reopened for *every* snapfb snapshot, set the environment variable: SNAPFB_RAWFB_RESET=1 as well. .IP @@ -4317,6 +4333,25 @@ say, a video camera that delivers the pixel data as 24bpp packed RGB. This is the default under "video" mode if the bpp is 24. .IP +Normally the bits per pixel, B, is 8, 16, or 32 (or +rarely 24), however there is also some support for +B < 8 (e.g. old graphics displays 4 bpp or 1 bpp). +In this case you certainly must supply the masks as +well: WxHxB:R/G/B. The pixels will be padded out to +8 bpp using depth 8 truecolor. The scheme currently +does not work with snap fb (ask if interested.) B=1 +monochrome example: file:/dev/urandom@128x128x1:1/1/1 +Some other like this are 128x128x2:3/3/3 128x128x4:7/7/7 +.IP +For B < 8 framebuffers you can also set the env. var +RAWFB_CGA=1 to try a CGA mapping for B=4 (e.g. linux +vga16fb driver.) Note with low bpp and/or resolution +VGA and VGA16 modes on the Linux console one's attempt +to export them via x11vnc can often be thwarted due to +special color palettes, pixel packings, and even video +painting buffering. OTOH, often experimenting with the +RGB masks can yield something recognizable. +.IP VIDEO4LINUX: on Linux some attempt is made to handle video devices (webcams or TV tuners) automatically. The idea is the WxHxB will be extracted from the @@ -4405,38 +4440,77 @@ As above, if you specify a "@WxHxB..." after the is not queried for the current values. Otherwise the device will be queried. .IP -LINUX CONSOLE: If the libvncserver LinuxVNC program -is on your system you may want to use that instead of -the following method because it will be faster and more -accurate for Linux text console. +LINUX CONSOLE: The following describes some ways to +view and possibly interact with the Linux text/graphics +console (i.e. not X11 XFree86/Xorg) +.IP +Note: If the libvncserver LinuxVNC program is on your +system you may want to use that instead of the following +method because it will be faster and more accurate +for the Linux text console and includes mouse support. +There is, however, the basic LinuxVNC functionality in +x11vnc if you replace "console" with "vt" in the +examples below. .IP If the rawfb string begins with "console" the -framebuffer device /dev/fb0 is opened (this requires -the appropriate kernel modules to be installed) and so -is /dev/tty0. The latter is used to inject keystrokes +framebuffer device /dev/fb0 is opened and /dev/tty0 is +opened too. The latter is used to inject keystrokes (not all are supported, but the basic ones are). -You will need to be root to inject keystrokes. -/dev/tty0 refers to the active VT, to indicate one -explicitly, use "console2", etc. using the VT number. -.IP -If the Linux version seems to be 2.6 or later and the -"uinput" module appears to be present, then the uinput -method will be used instead of /dev/ttyN. uinput allows -insertion of BOTH keystrokes and mouse input and so it -preferred when accessing graphical (e.g. QT-embedded) -linux console apps. See \fB-pipeinput\fR UINPUT below for -more information on this mode; you will have to use -\fB-pipeinput\fR if you want to tweak any UINPUT parameters. -You may also want to also use the \fB-nodragging\fR and -\fB-cursor\fR none options. Use "console0", etc or -\fB-pipeinput\fR CONSOLE to force the /dev/ttyN method. -.IP -Note you can change VT remotely using the +You will need to be root to inject keystrokes, but +not necessarily to open /dev/fb0. /dev/tty0 refers to +the active VT, to indicate one explicitly, use, e.g., +"console2" for /dev/tty2, etc. by indicating the +specific VT number. +.IP +For the Linux framebuffer device, /dev/fb0, (fb1, +etc) to be enabled the appropriate kernel drivers must +be loaded. E.g. vesafb or vga16fb and also by setting +the boot parameter vga=0x301 (or 0x314, 0x317, etc.) +(The vga=... method is the preferred way; set your +machines up that way.) Otherwise there will be a +\'No such device' error. You can also load a Linux +framebuffer driver specific to your make of video card +for more functionality. Once the machine is booted one +can often 'modprobe' the fb driver as root to obtain +a framebuffer device. +.IP +If you cannot get /dev/fb0 working on Linux, try +using the LinuxVNC emulation mode by "\fB-rawfb\fR \fIvtN\fR" +where N = 1, ... 6 is the Linux Virtual Terminal (aka +virtual console) you wish to view, e.g. "\fB-rawfb\fR \fIvt2\fR". +Unlike /dev/fb mode, it need not be the active Virtual +Terminal. Note that this mode can only show text and +not graphics. x11vnc polls the text in /dev/vcsaN +.IP +Set the env. var. RAWFB_VCSA_BW=1 to disable colors in +the "vtN" mode (i.e. black and white only.) If you +do not prefer the default 16bpp set RAWFB_VCSA_BPP to +8 or 32. If you need to tweak the rawfb parameters by +using the 'console_guess' string printed at startup, +be sure to indicate the snap: method. +.IP +uinput: If the Linux version appears to be 2.6 or +later and the "uinput" module appears to be present +(modprobe uinput), then the uinput method will be used +instead of /dev/ttyN. uinput allows insertion of BOTH +keystrokes and mouse input and so it preferred when +accessing graphical (e.g. QT-embedded) linux console +apps. See \fB-pipeinput\fR UINPUT below for more information +on this mode; you will have to use \fB-pipeinput\fR if you +want to tweak any UINPUT parameters. You may also want +to also use the \fB-nodragging\fR and \fB-cursor\fR none options. +Use "console0", etc or \fB-pipeinput\fR CONSOLE to force +the /dev/ttyN method. +.IP +Note you can change the Linux VT remotely using the .IR chvt (1) -command. Sometimes switching out and back corrects -the framebuffer state. +command to make the one you want be the active +one (e.g. 'chvt 3'). Sometimes switching out and back +corrects the framebuffer's graphics state. For the +"\fB-rawfb\fR \fIvtN\fR" mode there is no need to switch the VT's. .IP -To skip input injecting entirely use "consolex". +To skip input injecting entirely use "consolex" +or "vtx". .IP The string "/dev/fb0" (1, etc.) can be used instead of "console". This can be used to specify a different @@ -4446,8 +4520,8 @@ nonstandard, use "console:/dev/foofb" .IP If you do not want x11vnc to guess the framebuffer's WxHxB and masks automatically (sometimes the kernel -gives inaccurate information), specify them with a -@WxHxB at the end of the string. +gives incorrect information), specify them with a @WxHxB +(and optional :R/G/B masks) at the end of the string. .IP Examples: \fB-rawfb\fR console @@ -4456,6 +4530,7 @@ Examples: \fB-rawfb\fR consolex (no keystrokes or mouse) \fB-rawfb\fR console:/dev/nonstd \fB-rawfb\fR console \fB-pipeinput\fR UINPUT:accel=4.0 +\fB-rawfb\fR vt3 (/dev/tty3 w/o /dev/fb0) .IP VNC HOST: if the \fB-rawfb\fR string is of the form "vnc:host:N" then the VNC display "N" on the remote diff --git a/x11vnc/x11vnc.c b/x11vnc/x11vnc.c index b654ec8..dd9f69a 100644 --- a/x11vnc/x11vnc.c +++ b/x11vnc/x11vnc.c @@ -194,17 +194,19 @@ int tsdo(int port, int lsock, int *conn) { *conn = csock; } else { csock = *conn; - if (db) rfbLog("tsdo: using exiting csock: %d, port: %d\n", csock, port); + if (db) rfbLog("tsdo: using existing csock: %d, port: %d\n", csock, port); } rsock = rfbConnectToTcpAddr("127.0.0.1", port); if (rsock < 0) { if (db) rfbLog("tsdo: rfbConnectToTcpAddr(port=%d) failed.\n", port); + close(csock); return 2; } pid = fork(); if (pid < 0) { + close(csock); close(rsock); return 3; } @@ -212,8 +214,8 @@ int tsdo(int port, int lsock, int *conn) { ts_taskn = (ts_taskn+1) % TASKMAX; ts_tasks[ts_taskn] = pid; close(csock); - *conn = -1; close(rsock); + *conn = -1; return 0; } if (pid == 0) { @@ -225,15 +227,21 @@ int tsdo(int port, int lsock, int *conn) { #if LIBVNCSERVER_HAVE_SETSID if (setsid() == -1) { perror("setsid"); + close(csock); + close(rsock); exit(1); } #else if (setpgrp() == -1) { perror("setpgrp"); + close(csock); + close(rsock); exit(1); } #endif /* SETSID */ raw_xfer(rsock, csock, csock); + close(csock); + close(rsock); exit(0); } return 0; @@ -245,11 +253,13 @@ void set_redir_properties(void); #define TSSTK 16 void terminal_services(char *list) { - int i, j, n = 0, db = 1; - char *p, *q, *r, *str = strdup(list); + int i, j, n, db = 1; + char *p, *q, *r, *str; #if !NO_X11 char *tag[TSMAX]; int listen[TSMAX], redir[TSMAX][TSSTK], socks[TSMAX], tstk[TSSTK]; + double rate_start; + int rate_count; Atom at, atom[TSMAX]; fd_set rd; Window rwin; @@ -265,6 +275,7 @@ void terminal_services(char *list) { if (! dpy) { return; } + rwin = RootWindow(dpy, DefaultScreen(dpy)); at = XInternAtom(dpy, "TS_REDIR_LIST", False); @@ -275,15 +286,24 @@ void terminal_services(char *list) { } if (db) fprintf(stderr, "TS_REDIR_LIST Atom: %d.\n"); + oh_restart_it_all: + for (i=0; i= 0) { + if (db) fprintf(stderr, " listen succeeded: %d\n", listen[i]); + break; + } + if (db) fprintf(stderr, " listen failed***: %d\n", listen[i]); + usleep(k * 2000*1000); + } } if (getenv("TSD_RESTART")) { @@ -385,6 +414,7 @@ void terminal_services(char *list) { continue; } if (nfd > 0) { + int did_ts = 0; for(i=0; i rate_start + 10.0) { + rate_start = dnow(); + rate_count = 0; + } + rate_count++; + rc = tsdo(p, s, &conn); + did_ts++; + if (rc == 0) { /* AOK */ if (db) fprintf(stderr, "tsdo[%d] OK: %d\n", i, p); @@ -452,16 +491,18 @@ if (tstk[j] != 0) fprintf(stderr, "B redir[%d][%d] = %d %s\n", i, j, tstk[j], t break; } else if (rc == 1) { /* accept failed */ - if (db) fprintf(stderr, "tsdo[%d] accept failed: %d\n", i, p); + if (db) fprintf(stderr, "tsdo[%d] accept failed: %d, sleep 50ms\n", i, p); + usleep(50*1000); break; } else if (rc == 2) { /* connect failed */ - if (db) fprintf(stderr, "tsdo[%d] connect failed: %d\n", i, p); + if (db) fprintf(stderr, "tsdo[%d] connect failed: %d, sleep 50ms rate: %d/10s\n", i, p, rate_count); redir[i][j] = 0; + usleep(50*1000); continue; } else if (rc == 3) { /* fork failed */ - usleep(250*1000); + usleep(500*1000); break; } } @@ -470,6 +511,41 @@ if (tstk[j] != 0) fprintf(stderr, "B redir[%d][%d] = %d %s\n", i, j, tstk[j], t } } } + if (did_ts && rate_count > 100) { + int k, db_netstat = 1; + char dcmd[100]; + + if (no_external_cmds) { + db_netstat = 0; + } + + rfbLog("terminal_services: throttling high connect rate %d/10s\n", rate_count); + usleep(2*1000*1000); + rfbLog("terminal_services: stopping ts services.\n"); + for(i=0; i= 0 && db_netstat) { + sprintf(dcmd, "netstat -an | grep -w '%d'", listen[i]); + fprintf(stderr, "#1 %s\n", dcmd); + system(dcmd); + } + close(s); + socks[i] = -1; + usleep(2*1000*1000); + if (listen[i] >= 0 && db_netstat) { + fprintf(stderr, "#2 %s\n", dcmd); + system(dcmd); + } + } + usleep(10*1000*1000); + + rfbLog("terminal_services: restarting ts services\n"); + goto oh_restart_it_all; + } } for (i=0; i X */ +int raw_fb_native_bpp = 0; +int raw_fb_expand_bytes = 1; +unsigned long raw_fb_native_red_mask = 0, raw_fb_native_green_mask = 0, raw_fb_native_blue_mask = 0; +unsigned short raw_fb_native_red_max = 0, raw_fb_native_green_max = 0, raw_fb_native_blue_max = 0; +unsigned short raw_fb_native_red_shift = 0, raw_fb_native_green_shift = 0, raw_fb_native_blue_shift = 0; + int rfb_bytes_per_line = 0; int main_bytes_per_line = 0; int rot_bytes_per_line = 0; diff --git a/x11vnc/xwrappers.c b/x11vnc/xwrappers.c index 160c76d..95e9e9f 100644 --- a/x11vnc/xwrappers.c +++ b/x11vnc/xwrappers.c @@ -352,6 +352,164 @@ XImage *XCreateImage_wr(Display *disp, Visual *visual, unsigned int depth, #endif /* NO_X11 */ } +static void copy_raw_fb_low_bpp(XImage *dest, int x, int y, unsigned int w, + unsigned int h) { + char *src, *dst; + unsigned int line; + static char *buf = NULL; + static int buflen = -1; + int bpl = wdpy_x * raw_fb_native_bpp / 8; + int n, ix, len, del, sz = wdpy_x * raw_fb_expand_bytes; + + unsigned int rm_n = raw_fb_native_red_mask; + unsigned int gm_n = raw_fb_native_green_mask; + unsigned int bm_n = raw_fb_native_blue_mask; + unsigned int rm_f = main_red_mask; + unsigned int gm_f = main_green_mask; + unsigned int bm_f = main_blue_mask; + + unsigned int rs_n = raw_fb_native_red_shift; + unsigned int gs_n = raw_fb_native_green_shift; + unsigned int bs_n = raw_fb_native_blue_shift; + unsigned int rs_f = main_red_shift; + unsigned int gs_f = main_green_shift; + unsigned int bs_f = main_blue_shift; + + unsigned int rx_n = raw_fb_native_red_max; + unsigned int gx_n = raw_fb_native_green_max; + unsigned int bx_n = raw_fb_native_blue_max; + unsigned int rx_f = main_red_max; + unsigned int gx_f = main_green_max; + unsigned int bx_f = main_blue_max; + + static unsigned int msk[8]; + static int last_bpp = -1; + static int cga = -1; + + if (cga < 0) { + if (getenv("RAWFB_CGA")) { + cga = 1; + } else { + cga = 0; + } + } + + if (sz > buflen || buf == NULL) { + if (buf) { + free(buf); + } + buflen = sz + 1000; + buf = (char *) malloc(buflen); + } + + if (clipshift && ! use_snapfb) { + x += coff_x; + y += coff_y; + } + + if (last_bpp != raw_fb_native_bpp) { + int br; + for (br = 0; br < 8; br++) { + unsigned int pbit, k, m = 0; + + for (k=0; k < raw_fb_native_bpp; k++) { + pbit = 1 << (br+k); + m |= pbit; + } + msk[br] = m; + } + last_bpp = raw_fb_native_bpp; + } + + dst = dest->data; +if (0) fprintf(stderr, "x=%d y=%d w=%d h=%d bpl=%d d_bpl=%d-%dx%dx%d/%d %p\n", + x, y, w, h, bpl, dest->bytes_per_line, dest->width, dest->height, dest->bits_per_pixel, dest->depth, dst); + + for (line = 0; line < h; line++) { + +//fprintf(stderr, "w=%d h=%d x=%d y+line=%d\n", w, h, x, y+line); + + if (! raw_fb_seek) { + /* mmap */ + src = raw_fb_addr + raw_fb_offset + bpl*(y+line); + + memcpy(buf, src, bpl); + } else { + /* lseek */ + off_t off; + off = (off_t) (raw_fb_offset + bpl*(y+line)); + + lseek(raw_fb_fd, off, SEEK_SET); + + len = bpl; + del = 0; + while (len > 0) { + n = read(raw_fb_fd, buf + del, len); + + if (n > 0) { + del += n; + len -= n; + } else if (n == 0) { + break; + } else if (errno != EINTR && errno != EAGAIN) { + break; + } + } + } + for (ix = 0; ix < w; ix++) { + int bx = (x + ix) * raw_fb_native_bpp; + int ib = bx / 8; + int br = bx - ib * 8; + unsigned char val; + +//fprintf(stderr, "%d\n", ix); + + val = *((unsigned char*) (buf + ib)); + + val = msk[br] & val; + val = val >> br; + + if (cga) { + /* this is expt for CGA */ + double r, g, b; + int ir, ig, ib; + r = (2./3)*(val & 4) + (1./3)*(val & 8); + g = (2./3)*(val & 2) + (1./3)*(val & 8); + b = (2./3)*(val & 1) + (1./3)*(val & 8); + if (val == 6) { + g = g/2.; + } + ir = rx_f * r; + ig = gx_f * g; + ib = bx_f * b; + val = (ib << bs_f) | (ig << gs_f) | (ir << rs_f); + } else { + unsigned char rval, gval, bval; + + rval = (val & rm_n) >> rs_n; + gval = (val & gm_n) >> gs_n; + bval = (val & bm_n) >> bs_n; + + rval = (rx_f * rval) / rx_n; + gval = (gx_f * gval) / gx_n; + bval = (bx_f * bval) / bx_n; + + rval = rval << rs_f; + gval = gval << gs_f; + bval = bval << bs_f; + + val = rval | gval | bval; + } + + *(dst+ix) = (char) val; + } + +//fprintf(stderr, "\n", ix); + + dst += dest->bytes_per_line; + } +} + static void copy_raw_fb_24_to_32(XImage *dest, int x, int y, unsigned int w, unsigned int h) { /* @@ -491,6 +649,10 @@ void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h) { copy_raw_fb_24_to_32(dest, x, y, w, h); return; } + if (raw_fb_native_bpp < 8) { + copy_raw_fb_low_bpp(dest, x, y, w, h); + return; + } if (clipshift && ! use_snapfb) { x += coff_x;